Skip to content
This repository was archived by the owner on May 15, 2026. It is now read-only.
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 19 additions & 6 deletions layer/layer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ static std::unique_ptr<perfetto::TracingSession> gTracingSession;
if (!strcmp(pName, "vk" #func)) \
return (PFN_vkVoidFunction) & vksp_##func;

#define GET_PROC_ADDR_DEV(func) \
if (!strcmp(pName, "vk" #func) && gDeviceDispatch[device].func != nullptr) \
return (PFN_vkVoidFunction) & vksp_##func;

#define SET_DISPATCH_TABLE(table, func, pointer, gpa, str, statement) \
table.func = (PFN_vk##func)gpa(*pointer, "vk" #func); \
if (dispatchTable.func == nullptr) { \
Expand Down Expand Up @@ -779,17 +783,23 @@ void VKAPI_CALL vksp_GetDeviceQueue(VkDevice device, uint32_t queueFamilyIndex,

gDeviceDispatch[device].GetDeviceQueue(device, queueFamilyIndex, queueIndex, pQueue);

auto info = new ThreadInfo(device, *pQueue);
QueueToDevice[*pQueue] = device;
QueueToThreadInfo[*pQueue] = info;
QueueThreadPool[device].emplace_back(std::make_pair(*pQueue, [info] { QueueThreadFct(info); }));
if (DeviceNotToTrace.count(device) == 0) {
auto info = new ThreadInfo(device, *pQueue);
QueueToThreadInfo[*pQueue] = info;
QueueThreadPool[device].emplace_back(std::make_pair(*pQueue, [info] { QueueThreadFct(info); }));
}
}

VkResult VKAPI_CALL vksp_QueueSubmit(VkQueue queue, uint32_t submitCount, const VkSubmitInfo *pSubmits, VkFence fence)
{
std::lock_guard<std::mutex> lock(glock);
TRACE_EVENT(VKSP_PERFETTO_CATEGORY, "vkQueueSubmit", "queue", (void *)queue, "submitCount", submitCount);

if (DeviceNotToTrace.count(QueueToDevice[queue])) {
return gDeviceDispatch[QueueToDevice[queue]].QueueSubmit(queue, submitCount, pSubmits, fence);
}

auto info = QueueToThreadInfo[queue];
ThreadJob *job = new ThreadJob();
{
Expand Down Expand Up @@ -1513,6 +1523,11 @@ VkResult VKAPI_CALL vksp_CreateDevice(VkPhysicalDevice physicalDevice, const VkD
gDeviceDispatch[*pDevice] = dispatchTable;
DeviceToPhysicalDevice[*pDevice] = physicalDevice;

if (DeviceNotToTrace.count(*pDevice)) {
TRACE_EVENT_INSTANT(
VKSP_PERFETTO_CATEGORY, "vkCreateDevice-submissions-not-tracked", "device", (void *)*pDevice);
}

extract_buffers_setup(*pDevice, physicalDevice);

return VK_SUCCESS;
Expand Down Expand Up @@ -1584,10 +1599,8 @@ PFN_vkVoidFunction VKAPI_CALL vksp_GetDeviceProcAddr(VkDevice device, const char
{
std::lock_guard<std::mutex> lock(glock);

if (DeviceNotToTrace.count(device) == 0) {

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand that even if we don't want to follow the submissions, we still want to trace as much as possible.

But what would happen if vksp_GetDeviceProcAddr is looking for something we don't have. It feels like, it will call the vksp_<X> function, which itself will try to call the function from the dispatch table which has not been filled. So a potential segfault could occur.

Am I missing something? Should we protect against that?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, good catch. Yes. I've added a commit that should protect against that.

#define FUNC_DEV GET_PROC_ADDR
#define FUNC_DEV GET_PROC_ADDR_DEV
#include "functions.def"
}

return gDeviceDispatch[device].GetDeviceProcAddr(device, pName);
}
Expand Down
Loading