Confused by descriptor set errors - vulkan

I am working on a modular way to specify additional uniforms and samplers (e.g. descriptor sets) for use by Vulkan shaders (using generics etc.), but I am receiving multiple validation errors and I can't decipher their meaning or which Vulkan calls/data to examine.
I can't see where I triggered a mismatch or why a global descriptor requires (none) component type.
UNASSIGNED-CoreValidation-Shader-DescriptorTypeMismatch(ERROR / SPEC): msgNum: 0 - Type mismatch on descriptor slot 0.0 (expected `VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT`) but descriptor of type VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER
Objects: 1
[0] 0, type: 0, name: NULL
UNASSIGNED-CoreValidation-DrawState-DescriptorSetNotUpdated(ERROR / SPEC): msgNum: 0 - Descriptor set 0x52 bound as set #0 encountered the following validation error at vkCmdDrawIndexed() time: Descriptor in binding #0 at global descriptor index 0 requires (none) component type, but bound descriptor format is VK_FORMAT_R8G8B8A8_UNORM.
Objects: 1
[0] 0x52, type: 23, name: NULL
...
UNASSIGNED-CoreValidation-DrawState-DescriptorSetNotUpdated(ERROR / SPEC): msgNum: 0 - Descriptor set 0xa4 bound as set #0 encountered the following validation error at vkCmdDrawIndexed() time: Descriptor in binding #0 at global descriptor index 0 requires (none) component type, but bound descriptor format is VK_FORMAT_R8G8B8A8_UNORM.
Objects: 1
[0] 0xa4, type: 23, name: NULL

UNASSIGNED-CoreValidation-Shader-DescriptorTypeMismatch(ERROR / SPEC): msgNum: 0 - Type mismatch on descriptor slot 0.0 (expected `VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT`) but descriptor of type VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER
Your shader interface differs from the descriptor type in your currently bound descriptor set at set 0, binding 0.
The shader expects some kind of uniform buffer, but you're providing a combined image sampler.
Maybe you're confusing a vertex shader with a fragment shader.
UNASSIGNED-CoreValidation-DrawState-DescriptorSetNotUpdated(ERROR / SPEC): msgNum: 0 - Descriptor set 0x52 bound as set #0 encountered the following validation error at vkCmdDrawIndexed() time: Descriptor in binding #0 at global descriptor index 0 requires (none) component type, but bound descriptor format is VK_FORMAT_R8G8B8A8_UNORM.
You're either providing an image descriptor with a format for something that expects e.g. a buffer descriptor, or you're running into a known validation layer bug that is described here.
Tracking validation layer errors in a big code base can be a bit tricky, so if you're unsure about how to fix them I'd recommend running your application through RenderDoc, examining the pipeline state at the point where that layer error occurs or just step through the validation layers themselves. Using e.g. Visual Studio's locals watch window will help you locate the Vulkan objects that trigger these messages.

Related

what's the difference between .descriptorCount in VkDescriptorPoolSize and in VkDescriptorSetLayoutBinding(VkDescriptorSetLayoutCreateInfo)? how set?

what's the difference between .descriptorCount in VkDescriptorPoolSize and in VkDescriptorSetLayoutBinding(VkDescriptorSetLayoutCreateInfo)?
how to set them when there are many shaders, how to set them correctly?
eg.
layout(binding = 0) uniform Buffers {
uint x[];
} buffers[5];
then:
VkDescriptorSetLayoutBinding.descriptorCount = 5,//not 1,
VkDescriptorPoolSize.descriptorCount = 5,//not 1,
what if this same uniform Buffers are in many shaders? should add 5 to descriptorCount when it exist in 1 more shader?
In the case of VkDescriptorSetLayoutBinding::descriptorCount. The spec says:
descriptorCount is the number of descriptors contained in the binding,
accessed in a shader as an array, except if descriptorType is
VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK in which case descriptorCount
is the size in bytes of the inline uniform block. If descriptorCount
is zero this binding entry is reserved and the resource must not be
accessed from any stage via this binding within any pipeline using the
set layout.
So most likely be 1, unless you have an array of textures or array of uniform buffers (which is not very common).
VkDescriptorPoolSize::descriptorCount has nothing to do with the previous one. A descriptor pool is used for allocating descriptors. So descriptorCount here is how many descriptors this pool can provide. The spec says:
descriptorCount is the number of descriptors of that type to allocate.
If type is VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK then
descriptorCount is the number of bytes to allocate for descriptors of
this type.
You can use the same pool for allocating multiple descriptor sets of multiple different layouts. So this most likely needs to be a fairly large number.
Anyways, I think you need to keep studying the general basic concepts around descriptors!

What is the valid way to bind per-object uniform buffers (e.g. camera matrices)?

I have some simple vulkan app which have:
3 command buffers for each swapchain image (#1, #2, #3)
1 uniform buffer with projection matrix data
I want to bind uniform buffer once. i'm using command buffer #1 to bind uniform buffer:
begin();
bindDescriptorSets();
end();
submit();
waitIdle();
reset();
Then i record commands for each swapchain image (3 times):
begin()
bindVertexBuffers()
beginRenderPass()
bindPipeline()
draw()
endRenderPass()
end();
Drawing works as expected, but validation layer logs an error:
[ UNASSIGNED-CoreValidation-DrawState-DescriptorSetNotBound ] Object: 0x1a57aad7910 (Type = 6) | VkPipeline 0x21 uses set #0 but that set is not bound.
If i move the bindDescriptorSets(); line to the second recording block, like this:
begin()
bindDescriptorSets();
bindVertexBuffers()
beginRenderPass()
bindPipeline()
draw()
endRenderPass()
end();
Validation is OK, but there is no difference in rendering.
So, the question is: do i have to bind descriptor sets for each buffer recording? If yes, why does the app work fine when i'm binding descriptor sets once?
I believe it relates to the current state of the Vulkan application. Let's see what specification says about the state:
2.2.1. Queue Operation
Commands recorded in command buffers either perform actions (...), set state (bind pipelines, descriptor sets,
and buffers, set dynamic state, push constants, set render
pass/subpass state), or perform synchronization (...). Some commands
perform more than one of these tasks. State setting commands update
the current state of the command buffer.
Notice I marked in bold that binding a descriptor set is a state command.
You bind descriptor set to a command buffer end that buffer and submit. Next, you start other command buffers. Let's see again what specification tells us about the command buffers:
Command Buffers
Each command buffer manages state independently of other command buffers. There is no inheritance of state across primary
and secondary command buffers, or between secondary command buffers.
When a command buffer begins recording, all state in that command
buffer is undefined.
So the specification and layers tell you that you have to bind descriptors to every command buffer that uses that state. Why it works even with warnings? I don't know, probably your implementation allows it, but I wouldn't recommend to keep it as it is.

vkQueueSubmit() call includes a stageMask with VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT bit set when device does not have geometryShader feature enabled

First of all, I'm a total newbie with Vulkan (I'm using the binding provided by LWJGL). I know I should copy/paste more code, but I don't even know what would be relevant for now (so don't hesitate to ask me some specific piece of code).
I try to make something like that :
Use a ComputeShader to compute a buffer of pixel.
Use vkCmdCopyBufferToImage to directly copy this array into a framebuffer image.
So, no vertex/fragment shaders for now.
I allocated a Compute Pipeline, and a FrameBuffer. I have one {Queue/CommandPool/CommandBuffer} for Computation, and one other for Rendering.
When I try to submit the graphic queue with:
vkQueueSubmit(graphicQueue, renderPipeline.getFrameSubmission().getSubmitInfo(imageIndex));
I obtain the following error message (from validation) :
ERROR OCCURED: Object: VK_NULL_HANDLE (Type = 0) | vkQueueSubmit() call includes a stageMask with VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT bit set when device does not have geometryShader feature enabled. The spec valid usage text states 'If the geometry shaders feature is not enabled, each element of pWaitDstStageMask must not contain VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#VUID-VkSubmitInfo-pWaitDstStageMask-00076)
ERROR OCCURED: Object: VK_NULL_HANDLE (Type = 0) | vkQueueSubmit() call includes a stageMask with VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT and/or VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT bit(s) set when device does not have tessellationShader feature enabled. The spec valid usage text states 'If the tessellation shaders feature is not enabled, each element of pWaitDstStageMask must not contain VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT or VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#VUID-VkSubmitInfo-pWaitDstStageMask-00077)
I tried to change the VkSubmitInfo.pWaitDstStageMask to different values (like VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT...) but nothing change.
So, what would be the best pWaitDstStageMask for my use case ?
Ok, I found my problem:
The pWaitDstStageMask must be an array with the same size than pWaitSemaphores.
I only putted 1 stage mask, for 2 semaphores.

Why multiple vertex buffer bindings should be consecutive?

I created a couple of vertex buffers and bindings for them:
VkVertexInputBindingDescription binding1{0, stride1, VK_VERTEX_INPUT_RATE_VERTEX};
VkVertexInputBindingDescription binding2{1, stride2, VK_VERTEX_INPUT_RATE_VERTEX};
Here you can see the consecutive 0 and 1 binding indices.
Next I record a command buffer:
vkCmdBindVertexBuffers(commandBuffer, 0, 1, &buffer1, &offset);
vkCmdBindVertexBuffers(commandBuffer, 1, 1, &buffer2, &offset);
It can be done in one call, I know, but stay with me.
Now I'm trying non-consecutive bindings:
VkVertexInputBindingDescription binding1{0, stride1, VK_VERTEX_INPUT_RATE_VERTEX};
VkVertexInputBindingDescription binding2{2, stride2, VK_VERTEX_INPUT_RATE_VERTEX};
vkCmdBindVertexBuffers(commandBuffer, 0, 1, &buffer1, &offset);
vkCmdBindVertexBuffers(commandBuffer, 2, 1, &buffer2, &offset);
Notice 0 and 2 non-consecutive binding indices.
The rendered model is indeed correct in both cases but in the second case I'm getting validation layer: Cannot submit cmd buffer using deleted buffer 0x0. warning. Why?
This looks like a bug in the validation layers. They track the currently bound buffers in bindings zero through the highest binding that's been set, and when submitting a command buffer they just check that all of those bindings have valid buffers bound. But the spec only requires that bindings that are actually referenced by vertex input variables have valid buffers bound. It would be great if you could file a bug at https://github.com/KhronosGroup/Vulkan-LoaderAndValidationLayers.

NaCl GL ERROR :GL_INVALID_OPERATION

I am porting a game engine that works perfectly on different platforms (Windows, iOS, Playbook, BB10, Android) to NaCl
2d renders correctly but some 3d Objects don't show or are rendered really strange and i get the following con
[.PPAPIContext]GL ERROR :GL_INVALID_FRAMEBUFFER_OPERATION : BackTexture::AllocateStorage: <- error from previous GL command (index):1
[.PPAPIContext]GL ERROR :GL_INVALID_OPERATION : glVertexAttribPointer: stride not valid for type (index):1
[.PPAPIContext]GL ERROR :GL_INVALID_OPERATION : glVertexAttribPointer: offset not valid for type (index):1
[.PPAPIContext]GL ERROR :GL_INVALID_OPERATION : glDrawElements: attempt to access out of range vertices in attribute 0 (index):1
[.PPAPIContext]GL ERROR :GL_INVALID_OPERATION : glVertexAttribPointer: stride not valid for type (index):1
[.PPAPIContext]GL ERROR :GL_INVALID_OPERATION : glVertexAttribPointer: offset not valid for type (index):1
[.PPAPIContext]GL ERROR :GL_INVALID_OPERATION : glVertexAttribPointer: stride not valid for type (index):1
[.PPAPIContext]GL ERROR :GL_INVALID_OPERATION : glVertexAttribPointer: offset not valid for type (index):1
[.PPAPIContext]GL ERROR :GL_INVALID_OPERATION : glVertexAttribPointer: stride not valid for type
And it repeats indefinitely.
Again, the same render code is used for different platforms and it works just fine. Is there a special consideration to be taken into account when porting to NaCl? Any ideas about what i should focus on to try find the issue?
As far as i can understand, there's a problem with the shader 0 (the vertex shader) and indeed the vertices of some objects are all over the place.
Thanks! :)
For security reasons, Chrome validates many GL operations that other drivers may not. It's a bit of work, but you might try searching the Chromium codebase using http://cs.chromium.org to find the error messages.
Here's what I found:
BackTexture::AllocateStorage: <- error from previous GL command
This one is tricky to follow. As it says, some previous GL command failed before BackTexture::AllocateStorage was called. I looked through the rest of the file, and it's not clear to me what command is failing here, but from the error value it is framebuffer related.
glVertexAttribPointer: stride not valid for type and glVertexAttribPointer: offset not valid for type
These are pretty clear -- the stride and offset values are not divisible by the component size. It would be useful to see your calls to glVertexAttribPointer.
glDrawElements: attempt to access out of range vertices in attribute 0
VertexAttrib::CanAccess is failing, which checks whether the attrib is enabled, not deleted, and if the vertex index that you're trying to access is valid. As the error says, you are likely referencing a vertex outside of the valid range.
To debug this, I'd narrow down the calls to glDrawElements and glVertexAttribPointer and try to find which one is failing, then I'd add some printf calls to see what values are being passed.
Good luck!