mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-01-30 12:32:43 +00:00
vk: Preliminary support for debug markers
This commit is contained in:
parent
bd09dc8ea8
commit
d894ccb4ea
@ -98,6 +98,14 @@ namespace vk
|
||||
g_last_completed_event = std::max(event_id, g_last_completed_event.load());
|
||||
}
|
||||
|
||||
void print_debug_markers()
|
||||
{
|
||||
for (const auto marker : g_resource_manager.gather_debug_markers())
|
||||
{
|
||||
marker->dump();
|
||||
}
|
||||
}
|
||||
|
||||
static constexpr f32 size_in_GiB(u64 size)
|
||||
{
|
||||
return size / (1024.f * 1024.f * 1024.f);
|
||||
|
@ -57,6 +57,7 @@ namespace vk
|
||||
u64 eid;
|
||||
const vk::render_device* m_device;
|
||||
std::vector<disposable_t> m_disposables;
|
||||
std::vector<std::unique_ptr<device_debug_marker>> m_debug_markers;
|
||||
|
||||
eid_scope_t(u64 _eid):
|
||||
eid(_eid), m_device(g_render_device)
|
||||
@ -72,11 +73,13 @@ namespace vk
|
||||
std::swap(eid, other.eid);
|
||||
std::swap(m_device, other.m_device);
|
||||
std::swap(m_disposables, other.m_disposables);
|
||||
std::swap(m_debug_markers, other.m_debug_markers);
|
||||
}
|
||||
|
||||
void discard()
|
||||
{
|
||||
m_disposables.clear();
|
||||
m_debug_markers.clear();
|
||||
}
|
||||
};
|
||||
|
||||
@ -187,6 +190,13 @@ namespace vk
|
||||
get_current_eid_scope().m_disposables.emplace_back(std::move(disposable));
|
||||
}
|
||||
|
||||
inline void dispose(std::unique_ptr<vk::device_debug_marker>& object)
|
||||
{
|
||||
// Special case as we may need to read these out.
|
||||
// FIXME: We can manage these markers better and remove this exception.
|
||||
get_current_eid_scope().m_debug_markers.emplace_back(std::move(object));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline void dispose(std::unique_ptr<T>& object)
|
||||
{
|
||||
@ -221,6 +231,19 @@ namespace vk
|
||||
}
|
||||
|
||||
void trim();
|
||||
|
||||
std::vector<const device_debug_marker*> gather_debug_markers() const
|
||||
{
|
||||
std::vector<const device_debug_marker*> result;
|
||||
for (const auto& scope : m_eid_map)
|
||||
{
|
||||
for (const auto& item : scope.m_debug_markers)
|
||||
{
|
||||
result.push_back(item.get());
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
struct vmm_allocation_t
|
||||
|
@ -7,6 +7,8 @@
|
||||
|
||||
namespace vk
|
||||
{
|
||||
extern void print_debug_markers();
|
||||
|
||||
void die_with_error(VkResult error_code, std::string message,
|
||||
const char* file,
|
||||
const char* func,
|
||||
@ -103,6 +105,8 @@ namespace vk
|
||||
{
|
||||
default:
|
||||
case 0:
|
||||
print_debug_markers();
|
||||
|
||||
if (!message.empty()) message += "\n\n";
|
||||
fmt::throw_exception("%sAssertion Failed! Vulkan API call failed with unrecoverable error: %s%s", message, error_message, src_loc{line, col, file, func});
|
||||
case 1:
|
||||
|
@ -10,6 +10,9 @@
|
||||
#include "util/sysinfo.hpp"
|
||||
#include "util/asm.hpp"
|
||||
|
||||
// FIXME: namespace pollution
|
||||
#include "../VKResourceManager.h"
|
||||
|
||||
namespace vk
|
||||
{
|
||||
fence::fence(VkDevice dev)
|
||||
@ -169,6 +172,135 @@ namespace vk
|
||||
}
|
||||
}
|
||||
|
||||
device_marker_pool::device_marker_pool(const vk::render_device& dev, u32 count)
|
||||
: pdev(&dev), m_count(count)
|
||||
{}
|
||||
|
||||
std::tuple<VkBuffer, u64, volatile u32*> device_marker_pool::allocate()
|
||||
{
|
||||
if (!m_buffer || m_offset >= m_count)
|
||||
{
|
||||
create_impl();
|
||||
}
|
||||
|
||||
const auto out_offset = m_offset;
|
||||
m_offset ++;
|
||||
return { m_buffer->value, out_offset * 4, m_mapped + out_offset };
|
||||
}
|
||||
|
||||
void device_marker_pool::create_impl()
|
||||
{
|
||||
if (m_buffer)
|
||||
{
|
||||
m_buffer->unmap();
|
||||
vk::get_resource_manager()->dispose(m_buffer);
|
||||
}
|
||||
|
||||
m_buffer = std::make_unique<buffer>
|
||||
(
|
||||
*pdev,
|
||||
m_count * 4,
|
||||
pdev->get_memory_mapping().host_visible_coherent,
|
||||
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
|
||||
VK_BUFFER_USAGE_TRANSFER_DST_BIT,
|
||||
0,
|
||||
VMM_ALLOCATION_POOL_SYSTEM
|
||||
);
|
||||
|
||||
m_mapped = reinterpret_cast<volatile u32*>(m_buffer->map(0, VK_WHOLE_SIZE));
|
||||
m_offset = 0;
|
||||
}
|
||||
|
||||
device_debug_marker::device_debug_marker(device_marker_pool& pool, std::string message)
|
||||
: m_device(*pool.pdev), m_message(std::move(message))
|
||||
{
|
||||
std::tie(m_buffer, m_buffer_offset, m_value) = pool.allocate();
|
||||
*m_value = 0xCAFEBABE;
|
||||
}
|
||||
|
||||
device_debug_marker::~device_debug_marker()
|
||||
{
|
||||
if (!m_printed)
|
||||
{
|
||||
dump();
|
||||
}
|
||||
|
||||
m_value = nullptr;
|
||||
}
|
||||
|
||||
void device_debug_marker::signal(const command_buffer& cmd, VkPipelineStageFlags stages, VkAccessFlags access)
|
||||
{
|
||||
insert_global_memory_barrier(cmd, stages, VK_PIPELINE_STAGE_TRANSFER_BIT, access, VK_ACCESS_TRANSFER_WRITE_BIT);
|
||||
vkCmdFillBuffer(cmd, m_buffer, m_buffer_offset, 4, 0xDEADBEEF);
|
||||
}
|
||||
|
||||
void device_debug_marker::dump()
|
||||
{
|
||||
if (*m_value == 0xCAFEBABE)
|
||||
{
|
||||
rsx_log.error("DEBUG MARKER NOT REACHED: %s", m_message);
|
||||
}
|
||||
|
||||
m_printed = true;
|
||||
}
|
||||
|
||||
void device_debug_marker::dump() const
|
||||
{
|
||||
if (*m_value == 0xCAFEBABE)
|
||||
{
|
||||
rsx_log.error("DEBUG MARKER NOT REACHED: %s", m_message);
|
||||
}
|
||||
else
|
||||
{
|
||||
rsx_log.error("DEBUG MARKER: %s", m_message);
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME
|
||||
static std::unique_ptr<device_marker_pool> g_device_marker_pool;
|
||||
|
||||
device_marker_pool& get_shared_marker_pool(const vk::render_device& dev)
|
||||
{
|
||||
if (!g_device_marker_pool)
|
||||
{
|
||||
g_device_marker_pool = std::make_unique<device_marker_pool>(dev, 65536);
|
||||
}
|
||||
return *g_device_marker_pool;
|
||||
}
|
||||
|
||||
void device_debug_marker::insert(
|
||||
const vk::render_device& dev,
|
||||
const vk::command_buffer& cmd,
|
||||
std::string message,
|
||||
VkPipelineStageFlags stages,
|
||||
VkAccessFlags access)
|
||||
{
|
||||
auto result = std::make_unique<device_debug_marker>(get_shared_marker_pool(dev), message);
|
||||
result->signal(cmd, stages, access);
|
||||
vk::get_resource_manager()->dispose(result);
|
||||
}
|
||||
|
||||
debug_marker_scope::debug_marker_scope(const vk::command_buffer& cmd, const std::string& message)
|
||||
: dev(&cmd.get_command_pool().get_owner()), cb(&cmd), message(message)
|
||||
{
|
||||
vk::device_debug_marker::insert(
|
||||
*dev,
|
||||
*cb,
|
||||
fmt::format("0x%x: Enter %s", rsx::get_shared_tag(), message)
|
||||
);
|
||||
}
|
||||
|
||||
debug_marker_scope::~debug_marker_scope()
|
||||
{
|
||||
ensure(cb && cb->is_recording());
|
||||
|
||||
vk::device_debug_marker::insert(
|
||||
*dev,
|
||||
*cb,
|
||||
fmt::format("0x%x: Exit %s", rsx::get_shared_tag(), message)
|
||||
);
|
||||
}
|
||||
|
||||
VkResult wait_for_fence(fence* pFence, u64 timeout)
|
||||
{
|
||||
pFence->wait_flush();
|
||||
|
@ -87,6 +87,60 @@ namespace vk
|
||||
operator VkSemaphore() const;
|
||||
};
|
||||
|
||||
class device_marker_pool
|
||||
{
|
||||
std::unique_ptr<buffer> m_buffer;
|
||||
volatile u32* m_mapped = nullptr;
|
||||
u64 m_offset = 0;
|
||||
u32 m_count = 0;
|
||||
|
||||
void create_impl();
|
||||
|
||||
public:
|
||||
device_marker_pool(const vk::render_device& dev, u32 count);
|
||||
std::tuple<VkBuffer, u64, volatile u32*> allocate();
|
||||
|
||||
const vk::render_device* pdev = nullptr;
|
||||
};
|
||||
|
||||
class device_debug_marker
|
||||
{
|
||||
std::string m_message;
|
||||
bool m_printed = false;
|
||||
|
||||
VkDevice m_device = VK_NULL_HANDLE;
|
||||
VkBuffer m_buffer = VK_NULL_HANDLE;
|
||||
u64 m_buffer_offset = 0;
|
||||
volatile u32* m_value = nullptr;
|
||||
|
||||
public:
|
||||
device_debug_marker(device_marker_pool& pool, std::string message);
|
||||
~device_debug_marker();
|
||||
device_debug_marker(const event&) = delete;
|
||||
|
||||
void signal(const command_buffer& cmd, VkPipelineStageFlags stages, VkAccessFlags access);
|
||||
void dump();
|
||||
void dump() const;
|
||||
|
||||
static void insert(
|
||||
const vk::render_device& dev,
|
||||
const vk::command_buffer& cmd,
|
||||
std::string message,
|
||||
VkPipelineStageFlags stages = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
|
||||
VkAccessFlags access = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT);
|
||||
};
|
||||
|
||||
class debug_marker_scope
|
||||
{
|
||||
const vk::render_device* dev;
|
||||
const vk::command_buffer* cb;
|
||||
std::string message;
|
||||
|
||||
public:
|
||||
debug_marker_scope(const vk::command_buffer& cmd, const std::string& text);
|
||||
~debug_marker_scope();
|
||||
};
|
||||
|
||||
VkResult wait_for_fence(fence* pFence, u64 timeout = 0ull);
|
||||
VkResult wait_for_event(event* pEvent, u64 timeout = 0ull);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user