2017-08-02 3 views
0

VulkanでHTC Viveに何かを描画しようとしています。vkCreatePipelineが失敗し、バリデーションレイヤのセグメントエラーが発生する

バリデーションレイヤが有効になっていて、プログラムがvkCreateGraphicsPipelineの中にセグメントフォルトを与えました。セグメント障害はVkLayer_core_validation.dllで発生しました。それが十分に奇妙でなかった場合、セグメント障害が発生した機能はvkEmurateInstanceExtensionsでした。したがって、検証レイヤーなしでテストしたところ、vkCreateGraphicsPipelineVK_ERROR_VALIDATION_FAILED_EXTで失敗しました。

私はこのチュートリアルのパイプラインのセクションを何度も読んでいますが、間違ったことは何も見つかりませんでした。また、私はVulkan SDKの古いバージョンを試しましたが、唯一の違いは、vkCreateGraphicsPipelinevkGetInstanceProcAddrにそのセグメントの不具合が発生することです。

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); 
} 

EDIT 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を使用してください)
  • &&の短絡のために1つのシェーダモジュールがロードされません(||代わりに)

有効にしてくださいあなたのバリデーション層("VK_LAYER_LUNARG_standard_validation")+ を報告し、は意図したとおり、彼らが働くことを確認します。プログラムをコンパイルしてコンパイル・デバッグ・モードでテストしてください(初期化されていない値に、より検出可能なパターンを埋め込むことで、あなたの助けになります)。私にとっては、その3人は逮捕され、クラッシュ前に適切に報告されました。

私は最初の修正の途中です。うまくいけば、次の層のリリースに着陸します。

+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を返すなら'; 'module'はフラグメントシェーダーのためにはnullです。 – lohikaarme2

関連する問題