bombomby / optick

C++ Profiler For Games
https://optick.dev
MIT License
2.95k stars 296 forks source link

OPTICK_GPU_EVENT crashes the app with Vulkan validation error? #164

Closed GasimGasimzada closed 2 years ago

GasimGasimzada commented 2 years ago

I have initialized the a Vulkan GPU, setup context, and flipped the swapchain at the end. However, when I add OPTICK_GPU_EVENT the app crashes when I click the "Play" button in Optick app to connect to my application. The error that I get is coming from Vulkan with the following validation error:

Validation Error: [ UNASSIGNED-CoreValidation-DrawState-QueryNotReset ] Object 0: handle = 0x1b144d98860, type = VK_OBJECT_TYPE_COMMAND_BUFFER; | MessageID = 0x9cacd67a | vkCmdWriteTimestamp(): VkQueryPool 0xd175b40000000013[] and query 0: query not reset. After query pool creation, each query must be reset before it is used. Queries must also be reset between uses.

What am I doing wrong here? Here is a simplified version of my code:

// in constructor
OPTICK_GPU_INIT_VULKAN(&device, &physicalDeviceHandle, &graphicsQueue, &queueIndex, 1, nullptr);

// in render execution
vkWaitForFences(...);
vkResetFences(...);

auto *commandBuffer = getCommandBufferForCurrentFrame();
OPTICK_GPU_CONTEXT(commandBuffer);

vkBeginCommandBuffer(...);

OPTICK_EVENT("RenderGraphEvaluator::build");
for (auto &pass: passes) {
  OPTICK_GPU_EVENT(pass.getName().c_str());
  // command recording here
}
vkEndCommandBuffer(...);
VkQueueSubmit(...);

OPTICK_GPU_FLIP(&mSwapchain);
present();

I found out that I need to enable query reset feature:

VkPhysicalDeviceHostQueryResetFeatures queryResetFeatures{};
queryResetFeatures.sType =
    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES;
queryResetFeatures.pNext = nullptr;
queryResetFeatures.hostQueryReset = VK_TRUE;

deviceInfo->pNext = &queryResetFeatures;

However, this also did not solve my problem

GasimGasimzada commented 2 years ago

I foudn the error, The GPU CONTEXT function was inside another function that was causing it to get destroyed before the command recoding began. So, I moved the function call to the scope where both the begin and end commnad buffer is in the same scope.