Vk error - descriptor not accessib le from stage

Hello!

I’m just starting out with Vulkan, so don’t kick me please.
I keep getting the same error in my application:

error: VK error: SC code: 14 : Shader uses descriptor slot 0.0 (used as type pt r to const uniform sampler+image(dim=1, sampled=1)) but descriptor not accessib
le from stage VK_SHADER_STAGE_FRAGMENT_BIT object: 0, location: 2623

Unfortunately, this error doesn’t tell any useful information I could use to fix this.
Is there any chance I could get more detailed info on this, or some help at least? =)

      • Updated - - -

I’ve set stageFlags of VkDescriptorSetLayoutBinding to VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT

Please post at least the relevant code parts (at least the whole descriptor setup and matching shader bindings) so we can see if you maybe forgot to set the correct dstBinding.

Okay, I’ll try to extract all the necessary code from classes.

This is how pipeline layout is created:


mGraphicsPipelineCreateInfo.sType               = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
    mGraphicsPipelineCreateInfo.pVertexInputState   = &mPipelineVertexInputStateCreateInfo;
    mGraphicsPipelineCreateInfo.pInputAssemblyState = &mPipelineInputAssemblyStateCreateInfo;
    mGraphicsPipelineCreateInfo.pRasterizationState = &mPipelineRasterizationStateCreateInfo;
    mGraphicsPipelineCreateInfo.pDepthStencilState  = &mPipelineDepthStencilStateCreateInfo;
    mGraphicsPipelineCreateInfo.pViewportState      = &mPipelineViewportStateCreateInfo;
    mGraphicsPipelineCreateInfo.basePipelineHandle  = VK_NULL_HANDLE;
    mGraphicsPipelineCreateInfo.basePipelineIndex   = 0;

    mPipelineMultisampleStateCreateInfo.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
    mGraphicsPipelineCreateInfo.pMultisampleState = &mPipelineMultisampleStateCreateInfo;

    mPipelineRasterizationStateCreateInfo.lineWidth = 1.0F;
    mPipelineRasterizationStateCreateInfo.polygonMode = VK_POLYGON_MODE_FILL;

    mGraphicsPipelineCreateInfo.pColorBlendState = &mPipelineColorBlendStateCreateInfo;
	
	VkDescriptorType type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
    mPoolSizes[type].descriptorCount++;

    VkDescriptorSetLayoutBinding binding = {};
    binding.binding         = slot;
    binding.descriptorType  = type;
    binding.descriptorCount = 1;
    binding.stageFlags      = stages;
    mSetLayoutBindings.push_back(binding);

    DescriptorInfo descriptorInfo = {};
    descriptorInfo.isBuffer                 = false;
    descriptorInfo.slot                     = slot;
    descriptorInfo.imageInfo.sampler        = sampler;
    descriptorInfo.imageInfo.imageView      = image;
    descriptorInfo.imageInfo.imageLayout    = layout;
    mDescriptorInfos[type].push_back(descriptorInfo);
	
	
	
	VkResult err = VK_SUCCESS;

    mPoolSizes[VK_DESCRIPTOR_TYPE_SAMPLER].type                 = VK_DESCRIPTOR_TYPE_SAMPLER;
    mPoolSizes[VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER].type  = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
    mPoolSizes[VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE].type           = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
    mPoolSizes[VK_DESCRIPTOR_TYPE_STORAGE_IMAGE].type           = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
    mPoolSizes[VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER].type    = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER;
    mPoolSizes[VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER].type    = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
    mPoolSizes[VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER].type          = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
    mPoolSizes[VK_DESCRIPTOR_TYPE_STORAGE_BUFFER].type          = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
    mPoolSizes[VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC].type  = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
    mPoolSizes[VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC].type  = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC;
    mPoolSizes[VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT].type        = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT;

    VkDescriptorPoolCreateInfo descriptorPoolCreateInfo = {};
    descriptorPoolCreateInfo.sType          = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
    descriptorPoolCreateInfo.poolSizeCount  = uint32_t(mPoolSizes.size());
    descriptorPoolCreateInfo.pPoolSizes     = mPoolSizes.data();
    descriptorPoolCreateInfo.maxSets        = 1;

    err = vkCreateDescriptorPool(VKDevice(), &descriptorPoolCreateInfo, VKAlloc(), layout.descriptorPool.replace());
    AssertVK(err);

    VkDescriptorSetLayoutCreateInfo descriptorSetLayoutCreateInfo = {};
    descriptorSetLayoutCreateInfo.sType         = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
    descriptorSetLayoutCreateInfo.bindingCount  = uint32_t(mSetLayoutBindings.size());
    descriptorSetLayoutCreateInfo.pBindings     = mSetLayoutBindings.data();

    err = vkCreateDescriptorSetLayout(VKDevice(), &descriptorSetLayoutCreateInfo, VKAlloc(), layout.descriptorSetLayout.replace());
    AssertVK(err);

    VkDescriptorSetAllocateInfo descriptorSetAllocInfo = {};
    descriptorSetAllocInfo.sType                = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
    descriptorSetAllocInfo.descriptorPool       = layout.descriptorPool.get();
    descriptorSetAllocInfo.descriptorSetCount   = 1;
    descriptorSetAllocInfo.pSetLayouts          = layout.descriptorSetLayout.pointer();

    err = vkAllocateDescriptorSets(VKDevice(), &descriptorSetAllocInfo, &layout.descriptorSet);
    AssertVK(err);

    std::vector<VkWriteDescriptorSet> writeSets;
    for (size_t i = 0; i < mDescriptorInfos.size(); ++i) {

        auto& infos = mDescriptorInfos[i];
        for (size_t j = 0; j < infos.size(); ++j) {
            VkWriteDescriptorSet set = {};
            set.sType           = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
            set.dstSet          = layout.descriptorSet;
            set.dstBinding      = infos[j].slot;
            set.dstArrayElement = 0;
            set.descriptorType  = VkDescriptorType(i);
            set.descriptorCount = 1;
            if (infos[j].isBuffer) {
                set.pBufferInfo = &infos[j].bufferInfo;
            } else {
                set.pImageInfo  = &infos[j].imageInfo;
            }
            set.pTexelBufferView = nullptr;

            writeSets.push_back(set);
        }
    }
    if (!writeSets.empty()) {
        vkUpdateDescriptorSets(VKDevice(), uint32_t(writeSets.size()), writeSets.data(), 0, nullptr);
    }

    VkPipelineLayoutCreateInfo layoutCreateInfo = {};
    layoutCreateInfo.sType                  = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
    layoutCreateInfo.setLayoutCount         = 1;
    layoutCreateInfo.pSetLayouts            = layout.descriptorSetLayout.pointer();
    layoutCreateInfo.pushConstantRangeCount = uint32_t(mPushConstantRanges.size());
    layoutCreateInfo.pPushConstantRanges    = mPushConstantRanges.data();
    
    err = vkCreatePipelineLayout(VKDevice(), &layoutCreateInfo, VKAlloc(), layout.pipelineLayout.replace());
    AssertVK(err);

and this is how VkPipeline is created (vkCreateGraphicsPipelines is the one that crashes)


mGraphicsPipelineCreateInfo.sType               = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
    mGraphicsPipelineCreateInfo.pVertexInputState   = &mPipelineVertexInputStateCreateInfo;
    mGraphicsPipelineCreateInfo.pInputAssemblyState = &mPipelineInputAssemblyStateCreateInfo;
    mGraphicsPipelineCreateInfo.pRasterizationState = &mPipelineRasterizationStateCreateInfo;
    mGraphicsPipelineCreateInfo.pDepthStencilState  = &mPipelineDepthStencilStateCreateInfo;
    mGraphicsPipelineCreateInfo.pViewportState      = &mPipelineViewportStateCreateInfo;
    mGraphicsPipelineCreateInfo.basePipelineHandle  = VK_NULL_HANDLE;
    mGraphicsPipelineCreateInfo.basePipelineIndex   = 0;

    mPipelineMultisampleStateCreateInfo.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
    mGraphicsPipelineCreateInfo.pMultisampleState = &mPipelineMultisampleStateCreateInfo;

    mPipelineRasterizationStateCreateInfo.lineWidth = 1.0F;
    mPipelineRasterizationStateCreateInfo.polygonMode = VK_POLYGON_MODE_FILL;

    mGraphicsPipelineCreateInfo.pColorBlendState = &mPipelineColorBlendStateCreateInfo;
	
	
	mGraphicsPipelineCreateInfo.stageCount          = uint32_t(uberShader.GetPipelineStageCreateInfoCount());
    mGraphicsPipelineCreateInfo.pStages             = uberShader.GetPipelineStageCreateInfo();
    mGraphicsPipelineCreateInfo.pTessellationState  = uberShader.HasTessellationStage() ? &mPipelineTessellationStateCreateInfo : nullptr;
    
	
	
	mGraphicsPipelineCreateInfo.layout = layout.pipelineLayout.get();
	
	
	
	mGraphicsPipelineCreateInfo.renderPass = renderPass;
    mGraphicsPipelineCreateInfo.subpass = subpass;
	
	
	mPipelineColorBlendStateCreateInfo.attachmentCount = uint32_t(count);
    mPipelineColorBlendStateCreateInfo.pAttachments = attachments;
	
	
	mPipelineInputAssemblyStateCreateInfo.topology = topology;
	
	
	mEnabledDynamicStates[mPipelineDynamicStateCreateInfo.dynamicStateCount] = state;
    mGraphicsPipelineCreateInfo.pDynamicState = &mPipelineDynamicStateCreateInfo;
    mPipelineDynamicStateCreateInfo.dynamicStateCount++;
    mPipelineDynamicStateCreateInfo.pDynamicStates = mEnabledDynamicStates;
    if (state == VK_DYNAMIC_STATE_VIEWPORT) {
        mPipelineViewportStateCreateInfo.viewportCount++;
    }
    if (state == VK_DYNAMIC_STATE_SCISSOR) {
        mPipelineViewportStateCreateInfo.scissorCount++;
    }
	
	
	mEnabledDynamicStates[mPipelineDynamicStateCreateInfo.dynamicStateCount] = state;
    mGraphicsPipelineCreateInfo.pDynamicState = &mPipelineDynamicStateCreateInfo;
    mPipelineDynamicStateCreateInfo.dynamicStateCount++;
    mPipelineDynamicStateCreateInfo.pDynamicStates = mEnabledDynamicStates;
    if (state == VK_DYNAMIC_STATE_VIEWPORT) {
        mPipelineViewportStateCreateInfo.viewportCount++;
    }
    if (state == VK_DYNAMIC_STATE_SCISSOR) {
        mPipelineViewportStateCreateInfo.scissorCount++;
    }
	
	
	VkPipeline pipeline = VK_NULL_HANDLE;
    VkResult res = vkCreateGraphicsPipelines(VKDevice(), VK_NULL_HANDLE, 1, &mGraphicsPipelineCreateInfo,
        VKAlloc(), &pipeline);
    AssertVK(res);

I understand, that its hard to read this sheet of code and deduce something particular, but maybe you could provide at least
possible reasons for that, based on your experience with vulkan

    VkDescriptorSetLayoutBinding binding = {};
    binding.binding         = slot;
    binding.descriptorType  = type;
    binding.descriptorCount = 1;
    binding.stageFlags      = stages;
    mSetLayoutBindings.push_back(binding);

What value is stages? Where do you set it? Pretty hard to see what values are set when with only a few pieces of the code base.

And I also noticed this in your first post:

I’ve set stageFlags of VkDescriptorSetLayoutBinding to VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT

That’s wrong. You’re supposed to pass VkShaderStageFlagBits to stageFlags, not VkPipelineStageFlagBits.

Damn, you’re a god of vulkan =) I spent 4 hours looking for error, and it was so obvious…
Man, I owe you a beer

I advice you to use some tools like vulkan-hpp to avoid this kind of error.