renderer_vulkan: Simplify debug marker settings. (#2159)

* renderer_vulkan: Simplify debug marker settings.

* liverpool: Add scope markers for graphics/compute queues.

* liverpool: Remove unneeded extra label from command buffer markers.

* vk_rasterizer: Add scopes around filtered draw passes.
This commit is contained in:
squidbus 2025-01-16 02:14:34 -08:00 committed by GitHub
parent 1c3048ccc2
commit b3739bea92
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
14 changed files with 132 additions and 98 deletions

View file

@ -92,15 +92,13 @@ std::string GetReadableVersion(u32 version) {
Instance::Instance(bool enable_validation, bool enable_crash_diagnostic)
: instance{CreateInstance(Frontend::WindowSystemType::Headless, enable_validation,
enable_crash_diagnostic)},
physical_devices{EnumeratePhysicalDevices(instance)},
crash_diagnostic{enable_crash_diagnostic} {}
physical_devices{EnumeratePhysicalDevices(instance)} {}
Instance::Instance(Frontend::WindowSDL& window, s32 physical_device_index,
bool enable_validation /*= false*/, bool enable_crash_diagnostic /*= false*/)
: instance{CreateInstance(window.GetWindowInfo().type, enable_validation,
enable_crash_diagnostic)},
physical_devices{EnumeratePhysicalDevices(instance)},
crash_diagnostic{enable_crash_diagnostic} {
physical_devices{EnumeratePhysicalDevices(instance)} {
if (enable_validation) {
debug_callback = CreateDebugCallback(*instance);
}
@ -562,10 +560,7 @@ void Instance::CollectToolingInfo() {
return;
}
for (const vk::PhysicalDeviceToolProperties& tool : tools) {
const std::string_view name = tool.name;
LOG_INFO(Render_Vulkan, "Attached debugging tool: {}", name);
has_renderdoc = has_renderdoc || name == "RenderDoc";
has_nsight_graphics = has_nsight_graphics || name == "NVIDIA Nsight Graphics";
LOG_INFO(Render_Vulkan, "Attached debugging tool: {}", tool.name);
}
}

View file

@ -79,11 +79,6 @@ public:
return profiler_context;
}
/// Returns true when a known debugging tool is attached.
bool HasDebuggingToolAttached() const {
return crash_diagnostic || has_renderdoc || has_nsight_graphics;
}
/// Returns true if anisotropic filtering is supported
bool IsAnisotropicFilteringSupported() const {
return features.samplerAnisotropy;
@ -340,13 +335,9 @@ private:
bool legacy_vertex_attributes{};
bool image_load_store_lod{};
bool amd_gcn_shader{};
bool tooling_info{};
u64 min_imported_host_pointer_alignment{};
u32 subgroup_size{};
bool tooling_info{};
bool debug_utils_supported{};
bool crash_diagnostic{};
bool has_nsight_graphics{};
bool has_renderdoc{};
};
} // namespace Vulkan

View file

@ -7,6 +7,7 @@
#include <variant>
#include <fmt/format.h>
#include "common/config.h"
#include "common/logging/log.h"
#include "common/types.h"
#include "video_core/renderer_vulkan/vk_common.h"
@ -32,6 +33,9 @@ concept VulkanHandleType = vk::isVulkanHandleType<T>::value;
template <VulkanHandleType HandleType>
void SetObjectName(vk::Device device, const HandleType& handle, std::string_view debug_name) {
if (!Config::vkHostMarkersEnabled()) {
return;
}
const vk::DebugUtilsObjectNameInfoEXT name_info = {
.objectType = HandleType::objectType,
.objectHandle = reinterpret_cast<u64>(static_cast<typename HandleType::NativeType>(handle)),
@ -46,6 +50,9 @@ void SetObjectName(vk::Device device, const HandleType& handle, std::string_view
template <VulkanHandleType HandleType, typename... Args>
void SetObjectName(vk::Device device, const HandleType& handle, const char* format,
const Args&... args) {
if (!Config::vkHostMarkersEnabled()) {
return;
}
const std::string debug_name = fmt::vformat(format, fmt::make_format_args(args...));
SetObjectName(device, handle, debug_name);
}

View file

@ -58,6 +58,7 @@ bool Rasterizer::FilterDraw() {
if (regs.color_control.mode == Liverpool::ColorControl::OperationMode::FmaskDecompress) {
// TODO: check for a valid MRT1 to promote the draw to the resolve pass.
LOG_TRACE(Render_Vulkan, "FMask decompression pass skipped");
ScopedMarkerInsert("FmaskDecompress");
return false;
}
if (regs.color_control.mode == Liverpool::ColorControl::OperationMode::Resolve) {
@ -67,6 +68,7 @@ bool Rasterizer::FilterDraw() {
}
if (regs.primitive_type == AmdGpu::PrimitiveType::None) {
LOG_TRACE(Render_Vulkan, "Primitive type 'None' skipped");
ScopedMarkerInsert("PrimitiveTypeNone");
return false;
}
@ -244,10 +246,13 @@ void Rasterizer::EliminateFastClear() {
.layerCount = col_buf.view.slice_max - col_buf.view.slice_start + 1,
};
scheduler.EndRendering();
ScopeMarkerBegin(fmt::format("EliminateFastClear:MRT={:#x}:M={:#x}", col_buf.Address(),
col_buf.CmaskAddress()));
image.Transit(vk::ImageLayout::eTransferDstOptimal, vk::AccessFlagBits2::eTransferWrite, {});
scheduler.CommandBuffer().clearColorImage(image.image, image.last_state.layout,
LiverpoolToVK::ColorBufferClearValue(col_buf).color,
range);
ScopeMarkerEnd();
}
void Rasterizer::Draw(bool is_indexed, u32 index_offset) {
@ -842,8 +847,6 @@ void Rasterizer::BeginRendering(const GraphicsPipeline& pipeline, RenderState& s
}
void Rasterizer::Resolve() {
const auto cmdbuf = scheduler.CommandBuffer();
// Read from MRT0, average all samples, and write to MRT1, which is one-sample
const auto& mrt0_hint = liverpool->last_cb_extent[0];
const auto& mrt1_hint = liverpool->last_cb_extent[1];
@ -863,9 +866,12 @@ void Rasterizer::Resolve() {
mrt1_range.base.layer = liverpool->regs.color_buffers[1].view.slice_start;
mrt1_range.extent.layers = liverpool->regs.color_buffers[1].NumSlices() - mrt1_range.base.layer;
ScopeMarkerBegin(fmt::format("Resolve:MRT0={:#x}:MRT1={:#x}",
liverpool->regs.color_buffers[0].Address(),
liverpool->regs.color_buffers[1].Address()));
mrt0_image.Transit(vk::ImageLayout::eTransferSrcOptimal, vk::AccessFlagBits2::eTransferRead,
mrt0_range);
mrt1_image.Transit(vk::ImageLayout::eTransferDstOptimal, vk::AccessFlagBits2::eTransferWrite,
mrt1_range);
@ -892,8 +898,9 @@ void Rasterizer::Resolve() {
.dstOffset = {0, 0, 0},
.extent = {mrt1_image.info.size.width, mrt1_image.info.size.height, 1},
};
cmdbuf.copyImage(mrt0_image.image, vk::ImageLayout::eTransferSrcOptimal, mrt1_image.image,
vk::ImageLayout::eTransferDstOptimal, region);
scheduler.CommandBuffer().copyImage(mrt0_image.image, vk::ImageLayout::eTransferSrcOptimal,
mrt1_image.image, vk::ImageLayout::eTransferDstOptimal,
region);
} else {
vk::ImageResolve region = {
.srcSubresource =
@ -914,9 +921,12 @@ void Rasterizer::Resolve() {
.dstOffset = {0, 0, 0},
.extent = {mrt1_image.info.size.width, mrt1_image.info.size.height, 1},
};
cmdbuf.resolveImage(mrt0_image.image, vk::ImageLayout::eTransferSrcOptimal,
mrt1_image.image, vk::ImageLayout::eTransferDstOptimal, region);
scheduler.CommandBuffer().resolveImage(
mrt0_image.image, vk::ImageLayout::eTransferSrcOptimal, mrt1_image.image,
vk::ImageLayout::eTransferDstOptimal, region);
}
ScopeMarkerEnd();
}
void Rasterizer::DepthStencilCopy(bool is_depth, bool is_stencil) {
@ -936,6 +946,11 @@ void Rasterizer::DepthStencilCopy(bool is_depth, bool is_stencil) {
sub_range.base.layer = liverpool->regs.depth_view.slice_start;
sub_range.extent.layers = liverpool->regs.depth_view.NumSlices() - sub_range.base.layer;
ScopeMarkerBegin(fmt::format(
"DepthStencilCopy:DR={:#x}:SR={:#x}:DW={:#x}:SW={:#x}", regs.depth_buffer.DepthAddress(),
regs.depth_buffer.StencilAddress(), regs.depth_buffer.DepthWriteAddress(),
regs.depth_buffer.StencilWriteAddress()));
read_image.Transit(vk::ImageLayout::eTransferSrcOptimal, vk::AccessFlagBits2::eTransferRead,
sub_range);
write_image.Transit(vk::ImageLayout::eTransferDstOptimal, vk::AccessFlagBits2::eTransferWrite,
@ -967,9 +982,11 @@ void Rasterizer::DepthStencilCopy(bool is_depth, bool is_stencil) {
.dstOffset = {0, 0, 0},
.extent = {write_image.info.size.width, write_image.info.size.height, 1},
};
const auto cmdbuf = scheduler.CommandBuffer();
cmdbuf.copyImage(read_image.image, vk::ImageLayout::eTransferSrcOptimal, write_image.image,
vk::ImageLayout::eTransferDstOptimal, region);
scheduler.CommandBuffer().copyImage(read_image.image, vk::ImageLayout::eTransferSrcOptimal,
write_image.image, vk::ImageLayout::eTransferDstOptimal,
region);
ScopeMarkerEnd();
}
void Rasterizer::InlineData(VAddr address, const void* value, u32 num_bytes, bool is_gds) {
@ -1195,42 +1212,43 @@ void Rasterizer::UpdateViewportScissorState() {
cmdbuf.setScissorWithCountEXT(scissors);
}
void Rasterizer::ScopeMarkerBegin(const std::string_view& str) {
if (Config::nullGpu() || !Config::vkMarkersEnabled()) {
void Rasterizer::ScopeMarkerBegin(const std::string_view& str, bool from_guest) {
if ((from_guest && !Config::vkGuestMarkersEnabled()) ||
(!from_guest && !Config::vkHostMarkersEnabled())) {
return;
}
const auto cmdbuf = scheduler.CommandBuffer();
cmdbuf.beginDebugUtilsLabelEXT(vk::DebugUtilsLabelEXT{
.pLabelName = str.data(),
});
}
void Rasterizer::ScopeMarkerEnd() {
if (Config::nullGpu() || !Config::vkMarkersEnabled()) {
void Rasterizer::ScopeMarkerEnd(bool from_guest) {
if ((from_guest && !Config::vkGuestMarkersEnabled()) ||
(!from_guest && !Config::vkHostMarkersEnabled())) {
return;
}
const auto cmdbuf = scheduler.CommandBuffer();
cmdbuf.endDebugUtilsLabelEXT();
}
void Rasterizer::ScopedMarkerInsert(const std::string_view& str) {
if (Config::nullGpu() || !Config::vkMarkersEnabled()) {
void Rasterizer::ScopedMarkerInsert(const std::string_view& str, bool from_guest) {
if ((from_guest && !Config::vkGuestMarkersEnabled()) ||
(!from_guest && !Config::vkHostMarkersEnabled())) {
return;
}
const auto cmdbuf = scheduler.CommandBuffer();
cmdbuf.insertDebugUtilsLabelEXT(vk::DebugUtilsLabelEXT{
.pLabelName = str.data(),
});
}
void Rasterizer::ScopedMarkerInsertColor(const std::string_view& str, const u32 color) {
if (Config::nullGpu() || !Config::vkMarkersEnabled()) {
void Rasterizer::ScopedMarkerInsertColor(const std::string_view& str, const u32 color,
bool from_guest) {
if ((from_guest && !Config::vkGuestMarkersEnabled()) ||
(!from_guest && !Config::vkHostMarkersEnabled())) {
return;
}
const auto cmdbuf = scheduler.CommandBuffer();
cmdbuf.insertDebugUtilsLabelEXT(vk::DebugUtilsLabelEXT{
.pLabelName = str.data(),

View file

@ -47,10 +47,11 @@ public:
void DispatchDirect();
void DispatchIndirect(VAddr address, u32 offset, u32 size);
void ScopeMarkerBegin(const std::string_view& str);
void ScopeMarkerEnd();
void ScopedMarkerInsert(const std::string_view& str);
void ScopedMarkerInsertColor(const std::string_view& str, const u32 color);
void ScopeMarkerBegin(const std::string_view& str, bool from_guest = false);
void ScopeMarkerEnd(bool from_guest = false);
void ScopedMarkerInsert(const std::string_view& str, bool from_guest = false);
void ScopedMarkerInsertColor(const std::string_view& str, const u32 color,
bool from_guest = false);
void InlineData(VAddr address, const void* value, u32 num_bytes, bool is_gds);
u32 ReadDataFromGds(u32 gsd_offset);

View file

@ -73,9 +73,7 @@ CommandPool::CommandPool(const Instance& instance, MasterSemaphore* master_semap
ASSERT_MSG(pool_result == vk::Result::eSuccess, "Failed to create command pool: {}",
vk::to_string(pool_result));
cmd_pool = std::move(pool);
if (instance.HasDebuggingToolAttached()) {
SetObjectName(device, *cmd_pool, "CommandPool");
}
SetObjectName(device, *cmd_pool, "CommandPool");
}
CommandPool::~CommandPool() = default;
@ -94,10 +92,8 @@ void CommandPool::Allocate(std::size_t begin, std::size_t end) {
device.allocateCommandBuffers(&buffer_alloc_info, cmd_buffers.data() + begin);
ASSERT(result == vk::Result::eSuccess);
if (instance.HasDebuggingToolAttached()) {
for (std::size_t i = begin; i < end; ++i) {
SetObjectName(device, cmd_buffers[i], "CommandPool: Command Buffer {}", i);
}
for (std::size_t i = begin; i < end; ++i) {
SetObjectName(device, cmd_buffers[i], "CommandPool: Command Buffer {}", i);
}
}

View file

@ -4,6 +4,7 @@
#include <algorithm>
#include <limits>
#include "common/assert.h"
#include "common/config.h"
#include "common/logging/log.h"
#include "sdl_window.h"
#include "video_core/renderer_vulkan/vk_instance.h"
@ -235,11 +236,9 @@ void Swapchain::RefreshSemaphores() {
semaphore = sem;
}
if (instance.HasDebuggingToolAttached()) {
for (u32 i = 0; i < image_count; ++i) {
SetObjectName(device, image_acquired[i], "Swapchain Semaphore: image_acquired {}", i);
SetObjectName(device, present_ready[i], "Swapchain Semaphore: present_ready {}", i);
}
for (u32 i = 0; i < image_count; ++i) {
SetObjectName(device, image_acquired[i], "Swapchain Semaphore: image_acquired {}", i);
SetObjectName(device, present_ready[i], "Swapchain Semaphore: present_ready {}", i);
}
}
@ -251,10 +250,8 @@ void Swapchain::SetupImages() {
images = std::move(imgs);
image_count = static_cast<u32>(images.size());
if (instance.HasDebuggingToolAttached()) {
for (u32 i = 0; i < image_count; ++i) {
SetObjectName(device, images[i], "Swapchain Image {}", i);
}
for (u32 i = 0; i < image_count; ++i) {
SetObjectName(device, images[i], "Swapchain Image {}", i);
}
}