2017-08-02 142 views
0

我試圖用Vulkan繪製HTC Vive的東西。vkCreatePipeline失敗並驗證層段錯誤

我啓用了驗證層並且程序給了我vkCreateGraphicsPipeline內部的段錯誤。段錯誤發生在VkLayer_core_validation.dll。如果這不夠奇怪,則發生段錯誤的功能是vkEmurateInstanceExtensions。所以,我測試了沒有驗證層,然後vkCreateGraphicsPipeline失敗,結果是VK_ERROR_VALIDATION_FAILED_EXT

我現在已經閱讀了本教程的管道部分,我接下來幾次都沒有發現任何錯誤。另外我嘗試了較老版本的Vulkan SDK,但唯一的區別在於vkCreateGraphicsPipeline內部的vkGetInstanceProcAddr中發生了段錯誤。

static int loadShader(VrDevice *device,VkShaderModule *module,char *filename){ 
    // load the shader 
     . 
     . 
     . 
    // Create the VkShaderModule 
    VkShaderModuleCreateInfo shadermodule; 
    shadermodule.sType=VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; 
    shadermodule.flags=0; 
    shadermodule.pNext=NULL; 
    shadermodule.codeSize=buffersize; 
    shadermodule.pCode=(const uint32_t *)buffer; 
    VkResult result=vkCreateShaderModule(device->logicaldevice,&shadermodule,NULL,module); 

    // Check for vulkan error and free allocated memory before exiting 
    delete[] buffer; 
    if(result==VK_SUCCESS) return 1; 
    else return 0; 
} 

int renderingInit(VrDevice *device,char *appname){ 
    . 
    . 
    . 

    VkApplicationInfo appinfo; 
    appinfo.sType=VK_STRUCTURE_TYPE_APPLICATION_INFO; 
    appinfo.pNext=NULL; 
    appinfo.apiVersion=VK_MAKE_VERSION(1,0,0); 
    appinfo.pApplicationName=appname; 
    appinfo.applicationVersion=1; 
    appinfo.pEngineName=appname; 
    appinfo.engineVersion=1; 

    VkInstanceCreateInfo instanceinfo; 
    instanceinfo.sType=VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; 
    instanceinfo.pNext=NULL; 
    instanceinfo.flags=0; 
    instanceinfo.pApplicationInfo=&appinfo; 
    instanceinfo.enabledExtensionCount=numextension; 
    instanceinfo.ppEnabledExtensionNames=extensions; 
    instanceinfo.enabledLayerCount=layercount; 
    instanceinfo.ppEnabledLayerNames=debuglayers; 

    if(vkCreateInstance(&instanceinfo,NULL,&device->instance)!=VK_SUCCESS) return 0; 
    . 
    . 
    . 

    // Graphics card related matters 
    uint32_t devicecount=1; 
    result=vkEnumeratePhysicalDevices(device->instance,&devicecount,&device->physicaldevice); 
    if(result==VK_SUCCESS || result==VK_INCOMPLETE){  
     vkGetPhysicalDeviceProperties(device->physicaldevice,&device->physicaldeviceprop); 
     vkGetPhysicalDeviceMemoryProperties(device->physicaldevice,&device->physicaldevicememprop); 
     vkGetPhysicalDeviceFeatures(device->physicaldevice,&device->physicaldevicefeatures); 
    } 
    else return 0 

    uint32_t queuecount; 
    vkGetPhysicalDeviceQueueFamilyProperties(device->physicaldevice,&queuecount,NULL); 
    if(queuecount>0){ 
     VkQueueFamilyProperties *queues=new VkQueueFamilyProperties[queuecount]; 
     vkGetPhysicalDeviceQueueFamilyProperties(device->physicaldevice,&queuecount,queues); 
     uint32_t queue; 
     for(queue=0;queue<queuecount;queue++){ 
      if(queues[queue].queueFlags&VK_QUEUE_GRAPHICS_BIT) break; 
     } 

     delete[] queues; 

     device->queuefamily=queue; 

    } 
    else return 0; 
    . 
    . 
    .     
    // Make logical device 
    VkDeviceQueueCreateInfo queueinfo; 
    queueinfo.sType=VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; 
    queueinfo.pNext=NULL; 
    queueinfo.flags=0; 
    queueinfo.queueCount=1; 
    queueinfo.queueFamilyIndex=device->queuefamily; 
    float priority=1.0f; 
    queueinfo.pQueuePriorities=&priority; 

    VkDeviceCreateInfo createinfo; 
    createinfo.sType=VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; 
    createinfo.pNext=NULL; 
    createinfo.flags=0; 
    createinfo.pQueueCreateInfos=&queueinfo; 
    createinfo.queueCreateInfoCount=1; 
    createinfo.ppEnabledExtensionNames=extensions; 
    createinfo.enabledExtensionCount=numextensions; 
    createinfo.ppEnabledLayerNames=NULL; 
    createinfo.enabledLayerCount=0; 
    createinfo.pEnabledFeatures=&device->physicaldevicefeatures; 

    if(vkCreateDevice(device->physicaldevice,&createinfo,NULL,&device->logicaldevice)!=VK_SUCCESS) return 0; 
    vkGetDeviceQueue(device->logicaldevice,device->queuefamily,0,&device->queue); 

    // Create the frame image for the Vive 

    . 
    . 
    .  

    // Create renderpass 
    VkAttachmentDescription colorattachment; 
    colorattachment.format = VK_FORMAT_R8G8B8A8_SRGB; 
    colorattachment.samples = VK_SAMPLE_COUNT_1_BIT; 
    colorattachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; 
    colorattachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; 
    colorattachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; 
    colorattachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; 
    colorattachment.initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; 
    colorattachment.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; 

    VkAttachmentReference attachreferences; 
    attachreferences.attachment=0; 
    attachreferences.layout=VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; 

    VkSubpassDescription subpass; 
    subpass.flags=0; 
    subpass.pipelineBindPoint=VK_PIPELINE_BIND_POINT_GRAPHICS; 
    subpass.inputAttachmentCount=0; 
    subpass.pInputAttachments=NULL; 
    subpass.colorAttachmentCount=1; 
    subpass.pColorAttachments=&attachreferences; 
    subpass.pResolveAttachments=0; 
    subpass.pDepthStencilAttachment=0; 
    subpass.preserveAttachmentCount=0; 
    subpass.pPreserveAttachments=0; 

    VkRenderPassCreateInfo renderpassinfo; 
    renderpassinfo.sType=VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; 
    renderpassinfo.pNext=NULL; 
    renderpassinfo.flags=0; 
    renderpassinfo.attachmentCount=1; 
    renderpassinfo.pAttachments=&colorattachment; 
    renderpassinfo.subpassCount=1; 
    renderpassinfo.pSubpasses=&subpass; 
    renderpassinfo.dependencyCount=0; 
    renderpassinfo.pDependencies=NULL; 

    if(vkCreateRenderPass(device->logicaldevice,&renderpassinfo,NULL,&device->renderpass)!=VK_SUCCESS) return 0; 

    //** Load shaders and handle pipeline creation **// 

    // Pipeline layout 
    VkPipelineLayoutCreateInfo createinfo; 
    createinfo.sType=VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; 
    createinfo.pNext=NULL; 
    createinfo.flags=0; 
    createinfo.setLayoutCount=0; 
    createinfo.pSetLayouts=NULL; 
    createinfo.pushConstantRangeCount=0; 
    createinfo.pPushConstantRanges=NULL; 
    if(vkCreatePipelineLayout(device->logicaldevice,&createinfo,NULL,&device->pipelinelayout)!=VK_SUCCESS) return 0; 


    // Shader modules. 
    VkPipelineShaderStageCreateInfo shaderstages[2]; 
    if(loadShader(device,&shaderstages[0].module,VERTEX_SHADER_NAME)==0 && loadShader(device,&shaderstages[1].module,FRAGMENT_SHADER_NAME)==0) return 0; 

    shaderstages[0].sType=VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; 
    shaderstages[0].pNext=NULL; 
    shaderstages[0].flags=0; 
    shaderstages[0].stage=VK_SHADER_STAGE_VERTEX_BIT; 
    shaderstages[0].pSpecializationInfo=NULL; 
    shaderstages[0].pName="main"; 
    shaderstages[1].sType=VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; 
    shaderstages[1].pNext=NULL; 
    shaderstages[1].flags=0; 
    shaderstages[1].stage=VK_SHADER_STAGE_FRAGMENT_BIT; 
    shaderstages[1].pSpecializationInfo=NULL; 
    shaderstages[1].pName="main"; 

    // Descripte the vertex input to pipeline. 
    VkPipelineVertexInputStateCreateInfo vertexinfo; 
    vertexinfo.sType=VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; 
    vertexinfo.pNext=NULL; 
    vertexinfo.flags=0; 
    vertexinfo.pVertexAttributeDescriptions=NULL; 
    vertexinfo.vertexAttributeDescriptionCount=0; 
    vertexinfo.pVertexBindingDescriptions=NULL; 
    vertexinfo.vertexBindingDescriptionCount=0; 

    VkPipelineInputAssemblyStateCreateInfo inputassembly; 
    inputassembly.sType=VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; 
    inputassembly.pNext=NULL; 
    inputassembly.flags=0; 
    inputassembly.topology=VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; 
    inputassembly.primitiveRestartEnable=VK_FALSE; 

    // Viewport decide what reqion of framebuffer is used. 
    VkViewport viewport = {0.0f,0.0f,(float)device->renderwidth,(float)device->renderheight,0.0f,1.0f}; 
    // Scissors decide how much pippeline covers the window (how much info goes to rasterizing). 
    VkRect2D scissor = {0,0,device->renderwidth,device->renderheight}; 

    VkPipelineViewportStateCreateInfo viewportstate; 
    viewportstate.sType=VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; 
    viewportstate.pNext=NULL; 
    viewportstate.flags=0; 
    viewportstate.pScissors=&scissor; 
    viewportstate.scissorCount=1; 
    viewportstate.pViewports=&viewport; 
    viewportstate.viewportCount=1; 

    // Rasterization infomration 
    VkPipelineRasterizationStateCreateInfo rasterization; 
    rasterization.sType=VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; 
    rasterization.pNext=NULL; 
    rasterization.flags=0; 
    rasterization.depthClampEnable=VK_FALSE; 
    rasterization.rasterizerDiscardEnable=VK_FALSE; 
    rasterization.polygonMode=VK_POLYGON_MODE_FILL; 
    rasterization.cullMode=VK_CULL_MODE_BACK_BIT; 
    rasterization.frontFace=VK_FRONT_FACE_CLOCKWISE; 
    rasterization.depthBiasEnable=VK_FALSE; 
    rasterization.depthBiasConstantFactor=0.0f; 
    rasterization.depthBiasClamp=0.0f; 
    rasterization.lineWidth=1.0f; 

    // Multisampling 
    VkPipelineMultisampleStateCreateInfo multisampling; 
    multisampling.sType=VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; 
    multisampling.pNext=NULL; 
    multisampling.flags=0; 
    multisampling.rasterizationSamples=VK_SAMPLE_COUNT_1_BIT; 
    multisampling.sampleShadingEnable=VK_FALSE; 
    multisampling.minSampleShading=0.0f; 
    multisampling.pSampleMask=NULL; 
    multisampling.alphaToCoverageEnable=VK_FALSE; 
    multisampling.alphaToOneEnable=VK_FALSE; 

    // Color blending 
    VkPipelineColorBlendAttachmentState colorblendattachment; 
    colorblendattachment.colorWriteMask=VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; 
    colorblendattachment.blendEnable=VK_FALSE; 
    colorblendattachment.srcAlphaBlendFactor=VK_BLEND_FACTOR_ONE; 
    colorblendattachment.dstAlphaBlendFactor=VK_BLEND_FACTOR_ZERO; 
    colorblendattachment.colorBlendOp=VK_BLEND_OP_ADD; 
    colorblendattachment.srcColorBlendFactor=VK_BLEND_FACTOR_ONE; 
    colorblendattachment.dstColorBlendFactor=VK_BLEND_FACTOR_ZERO; 
    colorblendattachment.alphaBlendOp=VK_BLEND_OP_ADD; 
    VkPipelineColorBlendStateCreateInfo colorblend; 
    colorblend.sType=VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; 
    colorblend.pNext=NULL; 
    colorblend.flags=0; 
    colorblend.logicOpEnable=VK_FALSE; 
    colorblend.logicOp=VK_LOGIC_OP_COPY; 
    colorblend.attachmentCount=1; 
    colorblend.pAttachments=&colorblendattachment; 
    colorblend.blendConstants[0]=0; 
    colorblend.blendConstants[1]=0; 
    colorblend.blendConstants[2]=0; 
    colorblend.blendConstants[3]=0; 

    // If tuo want to change viewport, line width, blend constants you have to change it in this data type. 
    VkPipelineDynamicStateCreateInfo dynamicstateinfo; 
    dynamicstateinfo.sType=VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; 
    dynamicstateinfo.pNext=NULL; 
    dynamicstateinfo.flags=0; 
    dynamicstateinfo.dynamicStateCount=0; 
    dynamicstateinfo.pDynamicStates=NULL; 

    VkGraphicsPipelineCreateInfo pipelineinfo; 
    pipelineinfo.sType=VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; 
    pipelineinfo.pNext=NULL; 
    pipelineinfo.flags=0; 
    pipelineinfo.stageCount=2; 
    pipelineinfo.pStages=shaderstages; 
    pipelineinfo.pVertexInputState=&vertexinfo; 
    pipelineinfo.pInputAssemblyState=&inputassembly; 
    pipelineinfo.pViewportState=&viewportstate; 
    pipelineinfo.pRasterizationState=&rasterization; 
    pipelineinfo.pMultisampleState=&multisampling; 
    pipelineinfo.pDepthStencilState=NULL; 
    pipelineinfo.pColorBlendState=&colorblend; 
    pipelineinfo.pDynamicState=&dynamicstateinfo; 
    pipelineinfo.layout=device->pipelinelayout; 
    pipelineinfo.renderPass=device->renderpass; 
    pipelineinfo.subpass=0; 
    pipelineinfo.basePipelineHandle=VK_NULL_HANDLE; 
    pipelineinfo.basePipelineIndex=0; 

    // ** TODO: SEGMENT FAULT WHILE DEBUG LAYER IS ON! ** // 
    if((result=vkCreateGraphicsPipelines(device->logicaldevice,VK_NULL_HANDLE,1,&pipelineinfo,NULL,&device->pipeline))!=VK_SUCCESS) return 0; 

    // Destroy shaders after pipeline creation 
    vkDestroyShaderModule(device->logicaldevice,shaderstages[0].module,NULL); 
    vkDestroyShaderModule(device->logicaldevice,shaderstages[1].module,NULL); 
} 

編輯1:將調試圖層更改爲驗證圖層。

附加信息: 福爾康SDK版本1.0.54.0

+1

一些更多的細節會有幫助:你使用的是什麼版本的SDK,Vulkan運行時的版本,'vulkaninfo'的輸出顯示什麼可怕,你的圖形驅動程序是最新的? – skalarproduktraum

回答

0

在圖層中存在一個錯誤(並且可能在驅動程序—中,它至少使我的AMD崩潰)。 而不是未初始化的值爲pipelineinfo.pTessellationState(有效,但顯然崩潰)嘗試NULL

您應該由層如果在調試模式下編譯捕獲其他錯誤:

  • 初始化colorattachment.flags(大概應該是0
  • dynamicstateinfo.dynamicStateCount必須0(如果要禁用動態完全使用pipelineinfo.pDynamicState=NULL代替)
  • 由於&&發生短路,所以一個着色器模塊將不會被加載(我想你的意思是使用||代替)

請啓用您的驗證層("VK_LAYER_LUNARG_standard_validation")+報告驗證他們工作打算。在編譯器調試模式下編譯並測試你的程序(它會通過填充更多可檢測的模式填充未初始化的值來幫助你)。對於我來說,這三人在事故發生之前已經妥善報告。

我正在修復第一個,並希望它會着陸在下一個版本的層。

+0

感謝它開始工作,當&&''「腦屁」被修復。 – lohikaarme2

1

最有可能的解釋是,你要離開一個指針未分配和含有無效非NULL指針值。儘管看起來您已經試圖填充代碼中的每個結構成員字段,但有人可能會忽視它。在運行代碼設置成員之前,可能需要清除整個結構。

希望您使用「調試圖層」意味着啓用標準驗證圖層。標準驗證層是一個元層,支持多個與驗證相關的層,包括「參數檢查」和「核心驗證」。

如果參數檢查層發現應該有一個有效指針的NULL指針,它通常會報告一條錯誤消息。這就是爲什麼我建議清理你的結構。這可以使該層產生有意義的消息。

core_validation層假定參數檢查「已通過」,因此在解除引用之前並不總是測試NULL的指針。它不能避免解引用不良的非NULL指針。目的是參數檢查層將成功報告一個很有用的錯誤消息,即使應用程序稍後可能會在覈心驗證中崩潰。程序員應該解決由參數檢查報告的錯誤,然後允許核心驗證工作。

所以,底線,我建議清理所有的結構之前填入零。確保您使用的標準驗證元層包括參數檢查。然後觀察驗證錯誤消息。

如果所有這些都失敗了,那麼您可能希望捕獲驗證層中的seg故障,以獲取有關導致故障的數據結構的線索。看起來您可能在圖層代碼和符號文件之間有符號不匹配。可能值得嘗試解決這個問題,或者建立你自己的圖層,以便你有準確的符號。

+0

這是一個潛在的不好的建議,事先清除一個結構體,在未初始化的值的時候,當我忘記設置一個值時,它至少有時會失敗(尤其是在調試模式下)。在C++中,可能有更好的方法來處理這方面的問題。 – krOoze

+0

在編譯驗證層後,我知道在'validate_pipeline_shader_stage'中發生了段錯誤。 1290行if(!module-> has_valid_spirv)返回false;'。片段着色器的「模塊」爲空。 – lohikaarme2