UBO bindings to different stages

Hi! I am slowly moving from triangle example, and I’ve successfully binded uniform buffer object to vertex shader. Now I am unable to make 2 bindings - 1 for vertex shader, and 1 for fragment - I get incorrect even vertex binding.
Everything compiles and runs, but does not work.

So, I am trying to expand binding to vertex shader (works finto bindinf to vertex and fragment shader

  1. Changing binding count
    VkPipelineVertexInputStateCreateInfo::vertexAttributeDescriptionCount 1 => 2

  2. Adding vertex input binding description
    demo->vertices.vi_bindings[0].binding = VERTEX_BUFFER_BIND_ID;
    demo->vertices.vi_bindings[0].stride = sizeof(vb[0]);
    demo->vertices.vi_bindings[0].inputRate = VK_VERTEX_INPUT_RATE_VERTEX;

adding =>

demo->vertices.vi_bindings[1].binding = 0;
demo->vertices.vi_bindings[1].stride = sizeof(vb[0]);
demo->vertices.vi_bindings[1].inputRate = VK_VERTEX_INPUT_RATE_VERTEX;

  1. Adding device-mapped buffer with helper (simply has set(…) method with embedded mapping/unmapping)

context->uboVert = new vk_buffer_proxy<vertex_uniform_t>(context->device);

adding =>

context->uboFrag = new vk_buffer_proxy<fragment_uniform_t>(context->device);

  1. Adding one more VkWriteDescriptorSet element

writes[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
writes[0].dstSet = context->desc_set;
writes[0].descriptorCount = 1;
writes[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
writes[0].pBufferInfo = &context->uboVert->descriptor;
writes[0].dstBinding = 0;

adding =>

writes[1].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
writes[1].dstSet = context->desc_set;
writes[1].descriptorCount = 1;
writes[1].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
writes[1].pBufferInfo = &context->uboFrag->descriptor;
writes[1].dstBinding = 0;

and calling vkUpdateDescriptorSets with 2

  1. Now shaders have

vert:

layout(set = 0, binding = 0) uniform MainBlock
{
mat4 mvMatrix;
float green_uni;
float sc;
} ubo;

frag:

layout(set = 0, binding = 0) uniform MainBlock
{
vec3 color;
} ubo;

Before each frame I set values of both buffer mappings, and even vertex ubo is not correct on the shader side. Please tell me what’s wrong, I am really new to Vulkan and after Opengl 1.2-2 it seems too different.
And after these changes vertex ubo is not

Changing binding count

The number of vertex shader attributes is irrelevant to the number of uniform buffers you use. So I have no idea what you’re trying to do with that. The same goes for your vertex input changes.

UBOs are descriptors, not attributes.

Adding one more VkWriteDescriptorSet element

… Did you change your descriptor set layout to include another UBO?

vert:

layout(set = 0, binding = 0) uniform MainBlock
{
mat4 mvMatrix;
float green_uni;
float sc;
} ubo;

frag:

layout(set = 0, binding = 0) uniform MainBlock
{
vec3 color;
} ubo;

You gave them both the same descriptor binding index. That’s not going to work, since they store different data and come from different buffer regions.

So, firstly should I change shaders code to:

layout(set = 0, binding = 0) uniform MainBlock
{
mat4 mvMatrix;
float green_uni;
float sc;
} ubo;

frag:

layout(set = 0, binding = 1) uniform MainBlock
{
vec3 color;
} ubo

?

  1. OK, I changed shader so now vertex has 0-binding, and fragment 1-binding.

  2. Next, I removed second VkVertexInputBindingDescription. (but it is not attribute binding, it is VkVertexInputBindingDescription, or it is the corresponding entity?)

  3. In the first post I forgot to add, that I also added an element to descriptor set layout:

layout_bindings[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
layout_bindings[0].descriptorCount = 1;
layout_bindings[0].stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
layout_bindings[0].pImmutableSamplers = NULL;

added =>

layout_bindings[1].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
layout_bindings[1].descriptorCount = 1;
layout_bindings[1].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
layout_bindings[1].pImmutableSamplers = NULL;

  1. changed
    layout(set = 0, binding = 1) uniform MainBlock
    {
    vec3 color;
    } ubo

=>

layout(set = 0, binding = 1) uniform MainBlock
{
vec4 color;
} ubo

due to suspiction of not using strict 4-byte alignment

  1. Now the last line of updating descriptor sets crashes:

VkWriteDescriptorSet writes[2];
memset(writes, 0, sizeof(writes));

writes[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
writes[0].dstSet = context-&gt;desc_set;
writes[0].descriptorCount = 1;
writes[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
writes[0].pBufferInfo = &context-&gt;uboVert-&gt;descriptor;
writes[0].dstBinding = 0;

writes[1].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
writes[1].dstSet = context-&gt;desc_set;
writes[1].descriptorCount = 1;
writes[1].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
writes[1].pBufferInfo = &context-&gt;uboFrag-&gt;descriptor;
writes[1].dstBinding = 1;

vkUpdateDescriptorSets(context-&gt;device, 2, writes, 0, NULL);

Ha! Finally found the problem, the following lines were missing:

VkDescriptorSetLayoutBinding layout_bindings[2];

layout_bindings[0].binding = 0;
layout_bindings[1].binding = 1;

Now it works!