2017-04-22 160 views
-1

编辑创建命令缓冲区时: 这里是Valgrind的输出:段错误在vkCmdDrawIndexed了第二次

==6785== 
==6785== Process terminating with default action of signal 11 (SIGSEGV) 
==6785== Access not within mapped region at address 0xE0 
==6785== at 0xA138542: cvdescriptorset::DescriptorSet::ValidateDrawState(std::map<unsigned int, descriptor_req, std::less<unsigned int>, std::allocator<std::pair<unsigned int const, descriptor_req> > > const&, std::vector<unsigned int, std::allocator<unsigned int> > const&, std::string*) const (in /home/user/VulkanSDK/1.0.37.0/x86_64/lib/libVkLayer_core_validation.so) 
==6785== by 0xA0D9A06: core_validation::validate_and_update_draw_state(core_validation::layer_data*, GLOBAL_CB_NODE*, bool, VkPipelineBindPoint, char const*) (in /home/user/VulkanSDK/1.0.37.0/x86_64/lib/libVkLayer_core_validation.so) 
==6785== by 0xA0EE4F3: core_validation::CmdDrawIndexed(VkCommandBuffer_T*, unsigned int, unsigned int, unsigned int, int, unsigned int) (in /home/user/VulkanSDK/1.0.37.0/x86_64/lib/libVkLayer_core_validation.so) 
==6785== by 0xA8B6F23: object_tracker::CmdDrawIndexed(VkCommandBuffer_T*, unsigned int, unsigned int, unsigned int, int, unsigned int) (in /home/user/VulkanSDK/1.0.37.0/x86_64/lib/libVkLayer_object_tracker.so) 
==6785== by 0xB3AD421: threading::CmdDrawIndexed(VkCommandBuffer_T*, unsigned int, unsigned int, unsigned int, int, unsigned int) (in /home/user/VulkanSDK/1.0.37.0/x86_64/lib/libVkLayer_threading.so) 
==6785== by 0x13B147: VulkanRenderer::createCommandBuffers(ObjectInRAM*, ObjectInRAM*) (in /home/wobbi/git/Code/Implementierungen/Vulkan/VulkanTest) 
==6785== by 0x13F1FF: VulkanRenderer::mainLoop() (in /home/wobbi/git/Code/Implementierungen/Vulkan/VulkanTest) 
==6785== by 0x110716: main (in /home/wobbi/git/Code/Implementierungen/Vulkan/VulkanTest) 

我总算得到vkCmdDrawIndexed期间段错误在我福尔康应用。 我想要做的是我想绘制两个对象。第一个只有一次,第二个对象在不同位置可变的次数(没有实例化)。我通过pushConstants得到不同的位置,一切正常。

当按下按钮时,我想增加第二个对象的绘制次数,所以我等到设备空闲,然后用新的绘制调用数重新创建命令缓冲区。

但是在命令缓冲区的重新创建过程中,我得到一个段错误: vkCmdDrawIndexed(commandBuffers [i],obj2-> indices.size(),1,0,0,0);

我的代码基于Vulkan-Tutorial.com,所以我只是再次调用createCommandBuffers()函数。

我为我的池分配了: poolInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;

为什么我得到段错误任何帮助,将不胜感激

代码:

void VulkanRenderer::mainLoop() 
{ 
    float lastTextureChange = glfwGetTime(); 
    float lastFPSUpdate = glfwGetTime(); 
    int numFrames = 0; 
    int lastGPULoad = 1; 

    while (!glfwWindowShouldClose(window)) { 
     glfwPollEvents(); 

     //adjust camera values 
     //if frames are further apart then movement between frames has to be faster 
     float currentFrame = glfwGetTime(); 
     deltaTime = currentFrame - lastFrame; 
     lastFrame = currentFrame; 


     do_movement(); 

     updateUniformBuffer(glm::vec3(0.0f), 0.1f); 


     if(lastGPULoad != GPULoad) 
     {   
      lastGPULoad = GPULoad; 
      recreateSwapChain(); 
     } 

     drawFrame(); 

    } 

    vkDeviceWaitIdle(device); 

    glfwDestroyWindow(window); 
} 


void VulkanRenderer::recreateSwapChain() 
{ 
    vkDeviceWaitIdle(device); 

    createSwapChain(); 
    createImageViews(); 
    createRenderPass(); 
    createGraphicsPipeline(); 
    createDepthResources(); 
    createFramebuffers(); 
    createCommandBuffers(&male, &cube); 
} 


void VulkanRenderer::createCommandBuffers(ObjectInRAM* obj, ObjectInRAM* obj2) 
{ 
    //check if old command buffers are still around and free them 
    if (commandBuffers.size() > 0) 
    { 
     vkFreeCommandBuffers(device, commandPool, commandBuffers.size(), commandBuffers.data()); 
    } 

    commandBuffers.resize(swapChainFramebuffers.size()); 
    std::cout <<"creating new command buffers:" <<commandBuffers.size() <<std::endl; 

    VkCommandBufferAllocateInfo allocInfo = {}; 
    allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; 
    allocInfo.commandPool = commandPool; 
    allocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; 
    allocInfo.commandBufferCount = (uint32_t) commandBuffers.size(); 

    if (vkAllocateCommandBuffers(device, &allocInfo, commandBuffers.data()) != VK_SUCCESS) { 
     throw std::runtime_error("failed to allocate command buffers!"); 
    } 

    for (size_t i = 0; i < commandBuffers.size(); i++) { 
     VkCommandBufferBeginInfo beginInfo = {}; 
     beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; 
     beginInfo.flags = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT; 
     beginInfo.pInheritanceInfo = nullptr; // Optional 

     vkBeginCommandBuffer(commandBuffers[i], &beginInfo); 

      VkRenderPassBeginInfo renderPassInfo = {}; 
      renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; 
      renderPassInfo.renderPass = renderPass; 
      renderPassInfo.framebuffer = swapChainFramebuffers[i]; 

      renderPassInfo.renderArea.offset = {0}; 
      renderPassInfo.renderArea.extent = swapChainExtent; 

      std::array<VkClearValue, 2> clearValues = {}; 
      clearValues[0].color = {0.0f, 0.0f, 0.0f, 1.0f}; 
      clearValues[1].depthStencil = {1.0f, 0}; 

      renderPassInfo.clearValueCount = clearValues.size(); 
      renderPassInfo.pClearValues = clearValues.data(); 

      updateUniformBuffer(glm::vec3(80.0f, 80.0f, 80.0f), 10.0f); 

      vkCmdBeginRenderPass(commandBuffers[i], &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE);   

       pushUBO.model = glm::mat4(); 
       pushUBO.model = glm::scale(pushUBO.model, glm::vec3(1.0f)); 

       // Submit via push constant (rather than a UBO) 
       vkCmdPushConstants(
        commandBuffers[i], 
        pipelineLayout, 
        VK_SHADER_STAGE_VERTEX_BIT, 
        0, 
        sizeof(pushUBO), 
        &pushUBO 
       ); 


       vkCmdBindPipeline(commandBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipeline); 

       vkCmdBindDescriptorSets(commandBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, &descriptorSet, 0, nullptr);     
       //Binding vertex buffers      
       VkBuffer vertexBuffers[] = {obj2->vertexBuffer}; 
       VkDeviceSize offsets[] = {0}; 
       vkCmdBindVertexBuffers(commandBuffers[i], 0, 1, vertexBuffers, offsets); 
       vkCmdBindIndexBuffer(commandBuffers[i], obj2->indexBuffer, 0, VK_INDEX_TYPE_UINT32); 
       std::cout <<"bound index: " <<obj2->indices.size() <<std::endl; 

       vkCmdDrawIndexed(commandBuffers[i], obj2->indices.size(), 1,0,0,0); 

       std::cout <<"before crowd cmd recording " <<std::endl; 
       //render crowd 
       vertexBuffers[0] = obj->vertexBuffer;    
       vkCmdBindVertexBuffers(commandBuffers[i], 0, 1, vertexBuffers, offsets); 
       vkCmdBindIndexBuffer(commandBuffers[i], obj->indexBuffer, 0, VK_INDEX_TYPE_UINT32); 


       int drawCmdCounter = 0; 
       while(drawCmdCounter < GPULoad) 
       { 
        pushUBO.model = glm::mat4(); 
        pushUBO.model = glm::translate(pushUBO.model, glm::vec3(drawCmdCounter*5.0f, 0.0f,0.0f)); 
        // Submit via push constant (rather than a UBO) 
        vkCmdPushConstants(
         commandBuffers[i], 
         pipelineLayout, 
         VK_SHADER_STAGE_VERTEX_BIT, 
         0, 
         sizeof(pushUBO), 
         &pushUBO 
        ); 

        vkCmdDrawIndexed(commandBuffers[i], obj->indices.size(), 1,0,0,0); 
        drawCmdCounter++; 
       }    

      vkCmdEndRenderPass(commandBuffers[i]); 
     if (vkEndCommandBuffer(commandBuffers[i]) != VK_SUCCESS) { 
      throw std::runtime_error("failed to record command buffer!"); 
     }   
    } 
} 
+1

欢迎来到StackOverflow。请参阅[如何创建一个最小,完整和可验证的示例](https://stackoverflow.com/help/mcve)以明确问题。 – lnman

+1

您是否有适当的同步以确保您在覆盖命令缓冲区的同时仍在进行中?还启用验证图层并检查其输出是否有任何错误。如果你有适当的同步和验证是干净的,发布一个调用栈, –

+0

'void VulkanRenderer :: recreateSwapChain() { vkDeviceWaitIdle(device); //重建交换链 createCommandBuffers(); }' 当我注意到我需要更多/更少的绘制调用时,我在主循环中调用了这个函数。是否正在等待设备足够空闲以确保没有更多命令缓冲区正在运行? – wobbi

回答

0

从它看起来像层内崩溃调用堆栈。

1)(总是)使用updated SDK!你知道,我可以看到你正在使用过时的SDK。在撰写本文时,有四个更新的版本,可能是bambillion错误修正。

2)尝试运行层关闭。这将验证它是层中的一个错误。 3)如果1)没有帮助,并且2)你确定它是图层,那么你可以尝试trunk version图层(或者至少扫描最新的提交以获取相关内容),然后查找现有的问题或报告一个新的。

4)可能可以通过设置VK_LAYER_PATH变量来使用SDK/Source/lib中各层的调试版本。这将启用图层本身的断点/步骤调试。