Reputation: 73
I'm trying to implement a dynamic uniform buffer object to my project taking this code as an example. I'm new to the API, I have done the core of the program following this tutorial. At the moment I'm stuck with this issue:
validation layer: VkDescriptorSet 0x42bf70000000032[] bound as set #0 encountered the following validation error at vkCmdDrawIndexed() time: Dynamic descriptor in binding #2 index 0 uses buffer 9A90CE000000002B with dynamic offset 768 combined with offset 0 and range 32000 that oversteps the buffer size of 32000.
The error occurs for every occurance from this for loop (from createCommandBuffers()) (except the first one) :
for (uint32_t j = 0; j < OBJECT_INSTANCES; j++)
{
uint32_t dynamicOffset = j * static_cast<uint32_t>(dynamicAlignment);
std::cout << dynamicOffset << std::endl;
vkCmdBindDescriptorSets(commandBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, &descriptorSets[i], 1, &dynamicOffset);
vkCmdDrawIndexed(commandBuffers[i], static_cast<uint32_t>(indices.size()), 1, 0, 0, 0);
std::cout << "done" << std::endl;
}
(dynamicOffset seems correct and get incremented well by 256)
I really don't see what I have done wrong.. Do someone has an idea?
How the VkDescriptorSets are created:
void createDescriptorSets() {
std::vector<VkDescriptorSetLayout> layouts(swapChainImages.size(), descriptorSetLayout);
VkDescriptorSetAllocateInfo allocInfo = {};
allocInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
allocInfo.descriptorPool = descriptorPool;
allocInfo.descriptorSetCount = static_cast<uint32_t>(swapChainImages.size());
allocInfo.pSetLayouts = layouts.data();
descriptorSets.resize(swapChainImages.size());
if (vkAllocateDescriptorSets(device, &allocInfo, descriptorSets.data()) != VK_SUCCESS) {
throw std::runtime_error("failed to allocate descriptor sets!");
}
size_t dubo_size = OBJECT_INSTANCES * dynamicAlignment;
std::cout << dubo_size << std::endl;
for (size_t i = 0; i < swapChainImages.size(); i++) {
VkDescriptorBufferInfo uniformBufferInfo = {};
uniformBufferInfo.buffer = uniformBuffers[i];
uniformBufferInfo.offset = 0;
uniformBufferInfo.range = sizeof(UniformBufferObject);
VkDescriptorImageInfo imageInfo{};
imageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
imageInfo.imageView = textureImageView;
imageInfo.sampler = textureSampler;
VkDescriptorBufferInfo dynamicUniformBufferInfo = {};
dynamicUniformBufferInfo.buffer = dynamicUniformBuffers[i];
dynamicUniformBufferInfo.offset = 0;
dynamicUniformBufferInfo.range = dubo_size;
std::array<VkWriteDescriptorSet, 3> descriptorWrites{};
descriptorWrites[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
descriptorWrites[0].dstSet = descriptorSets[i];
descriptorWrites[0].dstBinding = 0;
descriptorWrites[0].dstArrayElement = 0;
descriptorWrites[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
descriptorWrites[0].descriptorCount = 1;
descriptorWrites[0].pBufferInfo = &uniformBufferInfo;
descriptorWrites[1].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
descriptorWrites[1].dstSet = descriptorSets[i];
descriptorWrites[1].dstBinding = 1;
descriptorWrites[1].dstArrayElement = 0;
descriptorWrites[1].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
descriptorWrites[1].descriptorCount = 1;
descriptorWrites[1].pImageInfo = &imageInfo;
descriptorWrites[2].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
descriptorWrites[2].dstSet = descriptorSets[i];
descriptorWrites[2].dstBinding = 2;
descriptorWrites[2].dstArrayElement = 0;
descriptorWrites[2].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
descriptorWrites[2].descriptorCount = 1;
descriptorWrites[2].pBufferInfo = &dynamicUniformBufferInfo;
vkUpdateDescriptorSets(device, static_cast<uint32_t>(descriptorWrites.size()), descriptorWrites.data(), 0, nullptr);
}
}
How the buffers are created:
void createDynamicUniformBuffers()
{
VkPhysicalDeviceProperties prop;
vkGetPhysicalDeviceProperties(physicalDevice, &prop);
size_t minUboAlignment = prop.limits.minUniformBufferOffsetAlignment;
dynamicAlignment = sizeof(glm::mat4);
if (minUboAlignment > 0) {
dynamicAlignment = (dynamicAlignment + minUboAlignment - 1) & ~(minUboAlignment - 1);
}
VkDeviceSize bufferSize = OBJECT_INSTANCES * dynamicAlignment;
uboDataDynamic.model = (glm::mat4*)alignedAlloc(bufferSize, dynamicAlignment);
assert(uboDataDynamic.model);
std::cout << "minUniformBufferOffsetAlignment = " << minUboAlignment << std::endl;
std::cout << "dynamicAlignment = " << dynamicAlignment << std::endl;
dynamicUniformBuffers.resize(swapChainImages.size());
dynamicUniformBuffersMemory.resize(swapChainImages.size());
for (size_t i = 0; i < swapChainImages.size(); i++) {
createBuffer(bufferSize, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, dynamicUniformBuffers[i], dynamicUniformBuffersMemory[i]);
}
}
And finally and bit more of the terminal:
minUniformBufferOffsetAlignment = 256
dynamicAlignment = 256
32000
0
done
256
validation layer: VkDescriptorSet 0x42bf70000000032[] bound as set #0 encountered the following validation error at vkCmdDrawIndexed() time: Dynamic descriptor in binding #2 index 0 uses buffer 9A90CE000000002B with dynamic offset 256 combined with offset 0 and range 32000 that oversteps the buffer size of 32000.
done
512
validation layer: VkDescriptorSet 0x42bf70000000032[] bound as set #0 encountered the following validation error at vkCmdDrawIndexed() time: Dynamic descriptor in binding #2 index 0 uses buffer 9A90CE000000002B with dynamic offset 512 combined with offset 0 and range 32000 that oversteps the buffer size of 32000.
done
768
validation layer: VkDescriptorSet 0x42bf70000000032[] bound as set #0 encountered the following validation error at vkCmdDrawIndexed() time: Dynamic descriptor in binding #2 index 0 uses buffer 9A90CE000000002B with dynamic offset 768 combined with offset 0 and range 32000 that oversteps the buffer size of 32000.
done
1024
validation layer: VkDescriptorSet 0x42bf70000000032[] bound as set #0 encountered the following validation error at vkCmdDrawIndexed() time: Dynamic descriptor in binding #2 index 0 uses buffer 9A90CE000000002B with dynamic offset 1024 combined with offset 0 and range 32000 that oversteps the buffer size of 32000.
done
1280
validation layer: VkDescriptorSet 0x42bf70000000032[] bound as set #0 encountered the following validation error at vkCmdDrawIndexed() time: Dynamic descriptor in binding #2 index 0 uses buffer 9A90CE000000002B with dynamic offset 1280 combined with offset 0 and range 32000 that oversteps the buffer size of 32000.
done
Upvotes: 0
Views: 340
Reputation: 73
Fix: The range given to the VkDescriptorBufferInfo for the dynamic UBO was the issue. Works out when using dynamicUniformBufferInfo.range = VK_WHOLE_SIZE
instead.
Upvotes: 2