mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-09-22 21:55:52 +00:00
Add option to fetch debug messages at runtime and display them in the UI
* By default this is off as it will continually add more and more messages each time the frame is replayed. It could be useful to turn on to * We also enable VK_EXT_debug_report any time it's available, not just when we're enabling the validation layers.
This commit is contained in:
@@ -63,19 +63,28 @@
|
||||
#include "serialise/serialiser.h"
|
||||
#include "vk_dispatchtables.h"
|
||||
|
||||
// uncomment this to cause every internal QueueSubmit to immediately call
|
||||
// DeviceWaitIdle(), and to only submit one command buffer at once to narrow
|
||||
// down the cause of device lost errors
|
||||
// enable this to cause every internal QueueSubmit to immediately call DeviceWaitIdle(), and to only
|
||||
// submit one command buffer at once to narrow down the cause of device lost errors
|
||||
#define SINGLE_FLUSH_VALIDATE OPTION_OFF
|
||||
|
||||
// uncomment this to get verbose debugging about when/where/why partial command
|
||||
// buffer replay is happening
|
||||
// enable this to get verbose debugging about when/where/why partial command buffer replay is
|
||||
// happening
|
||||
#define VERBOSE_PARTIAL_REPLAY OPTION_OFF
|
||||
|
||||
// uncomment this to enable validation layers on replay, useful for debugging
|
||||
// enable this to enable validation layers on replay, useful for debugging
|
||||
// problems with new replay code
|
||||
#define FORCE_VALIDATION_LAYERS OPTION_OFF
|
||||
|
||||
// enable this to send replay-time validation layer messages to the UI.
|
||||
// By default we only display saved validation layer messages from capture, and then any runtime
|
||||
// messages we generate ourselves. With this option, every time the catpure is replayed, any
|
||||
// messages will be bubbled up and added to the list in the UI - there is no deduplication so this
|
||||
// will be an ever-growing list.
|
||||
// This is independent of FORCE_VALIDATION_LAYERS above. We will listen to debug report if it's
|
||||
// available whether or not we enabled the validation layers, and output any messages. This allows
|
||||
// the ICD to generate messages for display
|
||||
#define DISPLAY_RUNTIME_DEBUG_MESSAGES OPTION_OFF
|
||||
|
||||
ResourceFormat MakeResourceFormat(VkFormat fmt);
|
||||
VkFormat MakeVkFormat(ResourceFormat fmt);
|
||||
Topology MakePrimitiveTopology(VkPrimitiveTopology Topo, uint32_t patchControlPoints);
|
||||
|
||||
@@ -1807,7 +1807,28 @@ bool WrappedVulkan::ContextProcessChunk(ReadSerialiser &ser, VulkanChunk chunk)
|
||||
{
|
||||
m_AddedDrawcall = false;
|
||||
|
||||
bool success = ProcessChunk(ser, chunk);
|
||||
bool success = false;
|
||||
|
||||
#if ENABLED(DISPLAY_RUNTIME_DEBUG_MESSAGES)
|
||||
// see the definition of DISPLAY_RUNTIME_DEBUG_MESSAGES for more information. During replay, add a
|
||||
// debug sink to catch any replay-time messages
|
||||
{
|
||||
ScopedDebugMessageSink sink(this);
|
||||
|
||||
success = ProcessChunk(ser, chunk);
|
||||
|
||||
if(IsActiveReplaying(m_State))
|
||||
{
|
||||
std::vector<DebugMessage> DebugMessages;
|
||||
DebugMessages.swap(sink.msgs);
|
||||
|
||||
for(const DebugMessage &msg : DebugMessages)
|
||||
AddDebugMessage(msg);
|
||||
}
|
||||
}
|
||||
#else
|
||||
success = ProcessChunk(ser, chunk);
|
||||
#endif
|
||||
|
||||
if(!success)
|
||||
return false;
|
||||
@@ -2465,7 +2486,6 @@ VkBool32 WrappedVulkan::DebugCallback(VkDebugReportFlagsEXT flags,
|
||||
else if(!strcmp(pLayerPrefix, "PARAMCHECK") || !strcmp(pLayerPrefix, "ParameterValidation"))
|
||||
isPARAM = true;
|
||||
|
||||
if(IsCaptureMode(m_State))
|
||||
{
|
||||
ScopedDebugMessageSink *sink = GetDebugMessageSink();
|
||||
|
||||
@@ -2480,6 +2500,17 @@ VkBool32 WrappedVulkan::DebugCallback(VkDebugReportFlagsEXT flags,
|
||||
msg.messageID = messageCode;
|
||||
msg.source = MessageSource::API;
|
||||
|
||||
// during replay we can get an eventId to correspond to this message.
|
||||
if(IsActiveReplaying(m_State))
|
||||
{
|
||||
// look up the EID this drawcall came from
|
||||
DrawcallUse use(m_CurChunkOffset, 0);
|
||||
auto it = std::lower_bound(m_DrawcallUses.begin(), m_DrawcallUses.end(), use);
|
||||
|
||||
if(it != m_DrawcallUses.end())
|
||||
msg.eventId = it->eventId;
|
||||
}
|
||||
|
||||
if(flags & VK_DEBUG_REPORT_INFORMATION_BIT_EXT)
|
||||
msg.severity = MessageSeverity::Info;
|
||||
else if(flags & VK_DEBUG_REPORT_DEBUG_BIT_EXT)
|
||||
|
||||
@@ -102,8 +102,6 @@ ReplayStatus WrappedVulkan::Initialise(VkInitParams ¶ms, uint64_t sectionVer
|
||||
|
||||
#if ENABLED(FORCE_VALIDATION_LAYERS) && DISABLED(RDOC_ANDROID)
|
||||
params.Layers.push_back("VK_LAYER_LUNARG_standard_validation");
|
||||
|
||||
params.Extensions.push_back("VK_EXT_debug_report");
|
||||
#endif
|
||||
|
||||
// strip out any WSI/direct display extensions. We'll add the ones we want for creating windows
|
||||
@@ -181,6 +179,13 @@ ReplayStatus WrappedVulkan::Initialise(VkInitParams ¶ms, uint64_t sectionVer
|
||||
}
|
||||
}
|
||||
|
||||
// we always want this extension if it's available
|
||||
if(supportedExtensions.find(VK_EXT_DEBUG_REPORT_EXTENSION_NAME) != supportedExtensions.end())
|
||||
{
|
||||
RDCLOG("Enabling VK_EXT_debug_report");
|
||||
params.Extensions.push_back(VK_EXT_DEBUG_REPORT_EXTENSION_NAME);
|
||||
}
|
||||
|
||||
const char **layerscstr = new const char *[params.Layers.size()];
|
||||
for(size_t i = 0; i < params.Layers.size(); i++)
|
||||
layerscstr[i] = params.Layers[i].c_str();
|
||||
@@ -955,10 +960,6 @@ bool WrappedVulkan::Serialise_vkCreateDevice(SerialiserType &ser, VkPhysicalDevi
|
||||
RDCLOG("Enabling VK_AMD_shader_info");
|
||||
}
|
||||
|
||||
#if ENABLED(FORCE_VALIDATION_LAYERS) && DISABLED(RDOC_ANDROID)
|
||||
Layers.push_back("VK_LAYER_LUNARG_standard_validation");
|
||||
#endif
|
||||
|
||||
createInfo.enabledLayerCount = (uint32_t)Layers.size();
|
||||
|
||||
const char **layerArray = NULL;
|
||||
|
||||
@@ -150,6 +150,16 @@ bool WrappedVulkan::Serialise_vkQueueSubmit(SerialiserType &ser, VkQueue queue,
|
||||
if(doWait)
|
||||
ObjDisp(queue)->QueueWaitIdle(Unwrap(queue));
|
||||
|
||||
// add a drawcall use for this submission, to tally up with any debug messages that come from it
|
||||
if(IsLoading(m_State))
|
||||
{
|
||||
DrawcallUse use(m_CurChunkOffset, m_RootEventID);
|
||||
|
||||
// insert in sorted location
|
||||
auto drawit = std::lower_bound(m_DrawcallUses.begin(), m_DrawcallUses.end(), use);
|
||||
m_DrawcallUses.insert(drawit, use);
|
||||
}
|
||||
|
||||
for(uint32_t sub = 0; sub < submitCount; sub++)
|
||||
{
|
||||
VkSubmitInfo submitInfo = pSubmits[sub];
|
||||
@@ -382,11 +392,14 @@ void WrappedVulkan::InsertDrawsAndRefreshIDs(vector<VulkanDrawcallTreeNode> &cmd
|
||||
m_Events.push_back(ev);
|
||||
}
|
||||
|
||||
DrawcallUse use(m_Events.back().fileOffset, n.draw.eventId);
|
||||
if(!n.draw.events.empty())
|
||||
{
|
||||
DrawcallUse use(n.draw.events.back().fileOffset, n.draw.eventId);
|
||||
|
||||
// insert in sorted location
|
||||
auto drawit = std::lower_bound(m_DrawcallUses.begin(), m_DrawcallUses.end(), use);
|
||||
m_DrawcallUses.insert(drawit, use);
|
||||
// insert in sorted location
|
||||
auto drawit = std::lower_bound(m_DrawcallUses.begin(), m_DrawcallUses.end(), use);
|
||||
m_DrawcallUses.insert(drawit, use);
|
||||
}
|
||||
|
||||
RDCASSERT(n.children.empty());
|
||||
|
||||
|
||||
Reference in New Issue
Block a user