Я пытаюсь реализовать динамический c однородный буферный объект в моем проекте, взяв этот код в качестве примера. Я новичок в API, я сделал ядро программы, следуя этому руководству . На данный момент я застрял с этой проблемой:
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.
Ошибка возникает для каждого случая из этого для l oop (from createCommandBuffers ()) (кроме первого):
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 кажется правильным и хорошо увеличивается на 256)
Я действительно не понимаю, что я сделал не так ... У кого-то есть идея?
Как VkDescriptorSets создаются:
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);
}
}
Как создаются буферы:
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]);
}
}
И, наконец, и еще немного терминала:
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