Flora
Flora

Reputation: 309

Vulkan error: Cannot submit cmd buffer using deleted buffer 0x0

When submitting work to my graphics queue this way:

void Renderer::Render() {
  VkSemaphore wait_semaphore = vulkan()->image_available_semaphore();
  VkSemaphore signal_semaphore = vulkan()->rendering_finished_semaphore();
  VkPipelineStageFlags wait_stage = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
  VkCommandBuffer cmd_buff =
    vulkan()->graphics_queue_cmd_buffers()[current_swapchain_img_];
  VkSubmitInfo submit_info = tools::inits::SubmitInfo();
  submit_info.waitSemaphoreCount = 1U;
  submit_info.pWaitSemaphores = &wait_semaphore;
  submit_info.pWaitDstStageMask = &wait_stage;
  submit_info.commandBufferCount = 1U;
  submit_info.pCommandBuffers = &cmd_buff;
  submit_info.signalSemaphoreCount = 1U;
  submit_info.pSignalSemaphores = &signal_semaphore;

  VK_CHECK_RESULT(vkQueueSubmit(
      vulkan()->device().graphics_queue().queue,
      1U,
      &submit_info,
      nullptr));
}

I get the following error from the validation layers:

Cannot submit cmd buffer using deleted buffer 0x0.

Repeated for 10 times.

My cmd buffers are generated this way:

void Renderer::SetupCommandBuffers(const VulkanDevice &device) {
  // Cache common settings to all command buffers 
  VkCommandBufferBeginInfo cmd_buff_begin_info =
    tools::inits::CommandBufferBeginInfo(
        VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT);
  cmd_buff_begin_info.pInheritanceInfo = nullptr;

  std::vector<VkClearValue> clear_values;
  VkClearValue clear_value;
  clear_value.color = {{0.f, 0.f, 0.f, 0.f}};
  clear_values.push_back(clear_value);
  clear_value.color = {{1.f, 0.f, 0.f, 1.f}};
  clear_values.push_back(clear_value);
  clear_value.depthStencil = {1.f, 0U};
  clear_values.push_back(clear_value);

  VkImageSubresourceRange image_subresource_range;
  image_subresource_range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
  image_subresource_range.baseMipLevel = 0U;
  image_subresource_range.levelCount = 1U;
  image_subresource_range.baseArrayLayer = 0U;
  image_subresource_range.layerCount = 1U;

  // Record command buffers
  const std::vector<VkCommandBuffer> &graphics_buffs =
    vulkan()->graphics_queue_cmd_buffers();
  uint32_t num_swapchain_images = vulkan()->swapchain().GetNumImages();
  for (uint32_t i = 0U; i < num_swapchain_images; i++) {
    VK_CHECK_RESULT(vkBeginCommandBuffer(
        graphics_buffs[i], &cmd_buff_begin_info));

    VkRenderPassBeginInfo render_pass_begin_info =
      tools::inits::RenderPassBeginInfo();
    render_pass_begin_info.renderPass = render_pass_;
    render_pass_begin_info.framebuffer = framebuffers_[i];
    render_pass_begin_info.renderArea = {0U, 0U, kWindowWidth, kWindowHeight};
    render_pass_begin_info.clearValueCount = SCAST_U32(clear_values.size());
    render_pass_begin_info.pClearValues = clear_values.data();

    vkCmdBeginRenderPass(graphics_buffs[i], &render_pass_begin_info,
                         VK_SUBPASS_CONTENTS_INLINE);

    vis_store_material_.BindPipeline(graphics_buffs[i],
                                     VK_PIPELINE_BIND_POINT_GRAPHICS);

    vkCmdBindDescriptorSets(
        graphics_buffs[i],
        VK_PIPELINE_BIND_POINT_GRAPHICS,
        pipe_layout_vis_,
        0U,
        SCAST_U32(desc_sets_.size()),
        desc_sets_.data(),
        0U,
        nullptr);

    fullscreenquad_->BindVertexBuffer(graphics_buffs[i]);  
    fullscreenquad_->BindIndexBuffer(graphics_buffs[i]);  

    vkCmdDrawIndexed(
        graphics_buffs[i],
        6U,
        1U,
        0U,
        0U,
        0U);

    // Fullscreen quad
    vkCmdNextSubpass(graphics_buffs[i], VK_SUBPASS_CONTENTS_INLINE);

    vis_shade_material_.BindPipeline(graphics_buffs[i],
                                     VK_PIPELINE_BIND_POINT_GRAPHICS);

    fullscreenquad_->BindVertexBuffer(graphics_buffs[i]);  
    fullscreenquad_->BindIndexBuffer(graphics_buffs[i]);  

    vkCmdDrawIndexed(
        graphics_buffs[i],
        6U,
        1U,
        0U,
        0U,
        0U);

    vkCmdEndRenderPass(graphics_buffs[i]);

    VK_CHECK_RESULT(vkEndCommandBuffer(graphics_buffs[i]));
  }
}

Having tried to debug it for a while, commenting out the vkCmdDrawIndexed calls removes the error report. I have noticed that removing only one draw call reduces the list of error report from 10 to 5. Also, even when the error is reported, rendering happens correctly anyway.

I have checked with my debugger that all the values I am passing to the functions are not VK_NULL_HANDLE or uninitialised variables, and that my cmd buffers exist; in fact, the validation layers don't throw any errors when I build the command buffers.

Moreover, I made sure that the list of per-framebuffer-image cmd buffers exists fully and I am not getting a simple Segfault because of uninitialised vector members.

I cannot figure out the relationship between this error report and the building of the command buffers, so I'd really appreciate if you could help me. Thanks in advance to anyone.

Upvotes: 1

Views: 1142

Answers (1)

krOoze
krOoze

Reputation: 13246

Cannot submit cmd buffer using deleted buffer 0x0.

This error is logged when any of the VkBuffer objects (not Command buffers though) used by the vkQueueSubmit (that is any recorded in the submitted Command buffer(s) ) is already destroyed (or perhaps not created yet). In this case seems to be VK_NULL_HANDLE even.

Remember vkQueueSubmit is asynchronous. The buffers need to be alive for the duration of vkQueueSubmit and after that too until the fence is signalled (or e.g. vkDeviceWaitIdle).

In this code sample I see only two VkBuffers used. The bound vertex and index buffer. And as it turned out it was tied to the vertex buffer (see Question comments for details).

As any good validator, its error messages are often unreadable to puny humans.
But Validation Layers are open source in Khronos repository:
https://github.com/KhronosGroup/Vulkan-LoaderAndValidationLayers/tree/master/layers

It can help to look there to interpret any error messages that prove to be hard to decipher. Usually (but not always) the error message is in core_validation.cpp (being implementation of the VK_LAYER_LUNARG_core_validation layer).

Upvotes: 3

Related Questions