[vulkan] Add a debug stack to the vulkan instance

The stack is arbitrary strings that the validation layer debug callback
prints in reverse order after each message. This makes it easy to work
out what nodes in a pipeline/render pass plist are causing validation
errors. Still have to narrow down the actual line, but the messages seem
to help with that.
Putting qfvPushDebug/qfvPopDebug around other calls to vulkan should
help out a lot, tool.
As a bonus, the stack is printed before debug_breakpoint is called, so
it's immediately visible in gdb.
This commit is contained in:
Bill Currie 2021-11-30 12:24:45 +09:00
parent a961111b2e
commit 8b85e422d7
5 changed files with 50 additions and 2 deletions

View file

@ -28,6 +28,7 @@
#include <vulkan/vulkan.h>
#include "QF/darray.h"
#include "QF/qtypes.h"
typedef struct qfv_instfuncs_s {
@ -36,6 +37,8 @@ typedef struct qfv_instfuncs_s {
#include "QF/Vulkan/funclist.h"
} qfv_instfuncs_t;
typedef struct DARRAY_TYPE(const char *) qfv_debugstack_t;
typedef struct qfv_physdev_s {
struct qfv_instance_s *instance;
VkPhysicalDevice dev;
@ -52,6 +55,7 @@ typedef struct qfv_instance_s {
VkDebugUtilsMessengerEXT debug_handle;
uint32_t numDevices;
qfv_physdev_t *devices;
qfv_debugstack_t debug_stack;
} qfv_instance_t;
struct vulkan_ctx_s;

View file

@ -110,4 +110,18 @@ typedef struct vulkan_ctx_s {
#include "QF/Vulkan/funclist.h"
} vulkan_ctx_t;
#define qfvPushDebug(ctx, x) \
do { \
if (developer->int_val & SYS_vulkan) { \
DARRAY_APPEND(&(ctx)->instance->debug_stack, (x)); \
} \
} while (0)
#define qfvPopDebug(ctx) \
do { \
if (developer->int_val & SYS_vulkan) { \
__auto_type ds = &(ctx)->instance->debug_stack; \
DARRAY_REMOVE_AT(ds, ds->size - 1); \
} \
} while (0)
#endif//__vid_vulkan_h

View file

@ -136,6 +136,7 @@ debug_callback (VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
const VkDebugUtilsMessengerCallbackDataEXT* callbackData,
void *data)
{
qfv_instance_t *instance = data;
if (!(messageSeverity & vulkan_use_validation->int_val)) {
return 0;
}
@ -154,6 +155,9 @@ debug_callback (VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
}
fprintf (stderr, "validation layer: %s%s\n", msgSev,
callbackData->pMessage);
for (size_t i = instance->debug_stack.size; i-- > 0; ) {
fprintf (stderr, " %s\n", instance->debug_stack.a[i]);
}
debug_breakpoint (messageSeverity);
return VK_FALSE;
}
@ -264,6 +268,7 @@ QFV_CreateInstance (vulkan_ctx_t *ctx,
inst->funcs = (qfv_instfuncs_t *)(inst + 1);
inst->enabled_extensions = new_strset (ext);
inst->extension_enabled = instance_extension_enabled;
DARRAY_INIT (&inst->debug_stack, 8);
ctx->instance = inst;
load_instance_funcs (ctx);

View file

@ -480,7 +480,10 @@ parse_VkShaderModule (const plitem_t *item, void **data,
if (*handle) {
return 1;
}
if (!(*handle = QFV_CreateShaderModule (device, name))) {
qfvPushDebug (ctx, va (ctx->va_ctx, "parse_VkShaderModule: %d", PL_Line (item)));
*handle = QFV_CreateShaderModule (device, name);
qfvPopDebug (ctx);
if (!*handle) {
PL_Message (messages, item, "could not find shader %s", name);
return 0;
}
@ -1030,10 +1033,12 @@ QFV_ParseRenderPass (vulkan_ctx_t *ctx, plitem_t *plist, plitem_t *properties)
}
VkRenderPass renderpass;
qfvPushDebug (ctx, va (ctx->va_ctx, "QFV_ParseRenderPass: %d", PL_Line (plist)));
renderpass = QFV_CreateRenderPass (device,
renderpass_data.attachments,
renderpass_data.subpasses,
renderpass_data.dependencies);
qfvPopDebug (ctx);
delete_memsuper (memsuper);
return renderpass;
@ -1055,7 +1060,9 @@ QFV_ParsePipeline (vulkan_ctx_t *ctx, plitem_t *plist, plitem_t *properties)
}
cInfo->a[0].renderPass = ctx->renderpass;
qfvPushDebug (ctx, va (ctx->va_ctx, "QFV_ParsePipeline: %d", PL_Line (plist)));
__auto_type plSet = QFV_CreateGraphicsPipelines (device, 0, cInfo);
qfvPopDebug (ctx);
VkPipeline pipeline = plSet->a[0];
free (plSet);
delete_memsuper (memsuper);
@ -1079,7 +1086,9 @@ QFV_ParseDescriptorPool (vulkan_ctx_t *ctx, plitem_t *plist,
}
VkDescriptorPool pool;
qfvPushDebug (ctx, va (ctx->va_ctx, "QFV_ParseDescriptorPool: %d", PL_Line (plist)));
dfunc->vkCreateDescriptorPool (device->dev, &cInfo, 0, &pool);
qfvPopDebug (ctx);
delete_memsuper (memsuper);
return pool;
@ -1103,10 +1112,12 @@ QFV_ParseDescriptorSetLayout (vulkan_ctx_t *ctx, plitem_t *plist,
}
VkDescriptorSetLayout setLayout;
qfvPushDebug (ctx, va (ctx->va_ctx, "QFV_ParseDescriptorSetLayout: %d", PL_Line (plist)));
dfunc->vkCreateDescriptorSetLayout (device->dev, &cInfo, 0, &setLayout);
QFV_duSetObjectName (device, VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT,
setLayout, va (ctx->va_ctx, "descriptorSetLayout:%d",
PL_Line (plist)));
qfvPopDebug (ctx);
delete_memsuper (memsuper);
return setLayout;
@ -1129,10 +1140,12 @@ QFV_ParsePipelineLayout (vulkan_ctx_t *ctx, plitem_t *plist,
}
VkPipelineLayout layout;
qfvPushDebug (ctx, va (ctx->va_ctx, "QFV_ParsePipelineLayout: %d", PL_Line (plist)));
dfunc->vkCreatePipelineLayout (device->dev, &cInfo, 0, &layout);
QFV_duSetObjectName (device, VK_OBJECT_TYPE_PIPELINE_LAYOUT,
layout, va (ctx->va_ctx, "pipelineLayout:%d",
PL_Line (plist)));
qfvPopDebug (ctx);
delete_memsuper (memsuper);
return layout;
@ -1154,7 +1167,9 @@ QFV_ParseSampler (vulkan_ctx_t *ctx, plitem_t *plist, plitem_t *properties)
}
VkSampler sampler;
qfvPushDebug (ctx, va (ctx->va_ctx, "QFV_ParseSampler: %d", PL_Line (plist)));
dfunc->vkCreateSampler (device->dev, &cInfo, 0, &sampler);
qfvPopDebug (ctx);
delete_memsuper (memsuper);
return sampler;
@ -1176,7 +1191,9 @@ QFV_ParseImage (vulkan_ctx_t *ctx, plitem_t *plist, plitem_t *properties)
}
VkImage image;
qfvPushDebug (ctx, va (ctx->va_ctx, "QFV_ParseImage: %d", PL_Line (plist)));
dfunc->vkCreateImage (device->dev, &cInfo, 0, &image);
qfvPopDebug (ctx);
delete_memsuper (memsuper);
return image;
@ -1198,7 +1215,9 @@ QFV_ParseImageView (vulkan_ctx_t *ctx, plitem_t *plist, plitem_t *properties)
}
VkImageView imageView;
qfvPushDebug (ctx, va (ctx->va_ctx, "QFV_ParseImageView: %d", PL_Line (plist)));
dfunc->vkCreateImageView (device->dev, &cInfo, 0, &imageView);
qfvPopDebug (ctx);
delete_memsuper (memsuper);
return imageView;
@ -1295,11 +1314,13 @@ QFV_ParseImageSet (vulkan_ctx_t *ctx, plitem_t *item, plitem_t *properties)
__auto_type set = QFV_AllocImages (create.count, malloc);
for (uint32_t i = 0; i < create.count; i++) {
qfvPushDebug (ctx, va (ctx->va_ctx, "QFV_ParseImageSet: %d", PL_Line (item)));
dfunc->vkCreateImage (device->dev, &create.info[i], 0, &set->a[i]);
const char *name = PL_KeyAtIndex (item, i);
QFV_duSetObjectName (device, VK_OBJECT_TYPE_IMAGE, set->a[i],
va (ctx->va_ctx, "image:%s", name));
qfvPopDebug (ctx);
name = resource_path (ctx, "images", name);
QFV_AddHandle (ctx->images, name, (uint64_t) set->a[i]);
}
@ -1334,7 +1355,9 @@ QFV_ParseImageViewSet (vulkan_ctx_t *ctx, plitem_t *item,
__auto_type set = QFV_AllocImageViews (create.count, malloc);
for (uint32_t i = 0; i < create.count; i++) {
qfvPushDebug (ctx, va (ctx->va_ctx, "QFV_ParseImageViewSet: %d", PL_Line (item)));
dfunc->vkCreateImageView (device->dev, &create.info[i], 0, &set->a[i]);
qfvPopDebug (ctx);
const char *name = PL_KeyAtIndex (item, i);
name = resource_path (ctx, "imageViews", name);
@ -1361,7 +1384,9 @@ QFV_ParseFramebuffer (vulkan_ctx_t *ctx, plitem_t *plist, plitem_t *properties)
}
VkFramebuffer framebuffer;
qfvPushDebug (ctx, va (ctx->va_ctx, "QFV_ParseFramebuffer: %d", PL_Line (plist)));
dfunc->vkCreateFramebuffer (device->dev, &cInfo, 0, &framebuffer);
qfvPopDebug (ctx);
Sys_MaskPrintf (SYS_vulkan_parse, "framebuffer, renderPass: %#zx, %#zx\n",
(size_t) framebuffer, (size_t) cInfo.renderPass);

View file

@ -217,7 +217,7 @@ X11_Vulkan_Context (void)
ctx->create_window = x11_vulkan_create_window;
ctx->create_surface = x11_vulkan_create_surface;
ctx->required_extensions = required_extensions;
ctx->va_ctx = va_create_context (4);
ctx->va_ctx = va_create_context (32);
return ctx;
}