VULKAN – 统一缓冲区(动态) – 渲染卡顿并且应用程序崩溃

huangapple go评论100阅读模式
英文:

VULKAN - Uniform Buffers (Dynamic) - Rendering freezes and app crashes

问题

我昨晚成功实现了动态统一缓冲区。

在下面的代码中,我初始化了一个动态偏移量,最初设置了投影/视图,然后在循环中将动态偏移量设置为i * bufferSize,ubo的pvm矩阵,然后绑定描述符集并绘制。

这个方法对我来说非常有效,我尝试了一个非常随机的魔术数字(21),它运行得很顺利。但是,如果我尝试22或更高的数字,程序就会冻结和崩溃。只是好奇,我的方法是否不正确?如果我无法超过21个循环,肯定是我遗漏了什么。我使用的是GTX 3060。

context中的bufferSize是uniformBufferObject结构的大小,它只包含三个mat4矩阵(64 * 3 = 192)。

尝试使用动态UBO渲染数百个球体,但当我尝试访问uniformBufferObject[索引= bufferSize(192)* 21(4032)]时,应用程序会崩溃。

创建统一缓冲区的代码如下:

创建缓冲区的函数:

findMemoryType函数:

UBO结构体,描述符集布局,描述符池,描述符写入:

英文:

I got dynamic uniform buffers working last night.

In the code below, I initialize a dynamic offset, set the projection/view initially, then in a loop, set the dynamic offset to be i * the bufferSize, ubo's pvm matricies, then bind the descriptor set and draw.

This thing worked like a charm with a very random magic number I tried (21). But if I try 22 or higher, the thing just freezes and crashes. Just curious, is my approach to this incorrect? I must be missing something if I can't go over 21 loops. I have a GTX 3060 as well.

bufferSize for context is the size of the uniformBufferObject struct, which is just three mat4s (64 * 3 = 192).

  1. uint32_t dynamicOffset = 0;
  2. glm::mat4 proj = glm::perspective(fov, (float)screenWidth / (float)screenHeight, zNear, zFar);
  3. proj[1][1] *= -1;
  4. glm::mat4 view = glm::lookAt(glm::vec3(0.0f, 0.0f, 2.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f));
  5. for (int i = 0; i < 21; i++)
  6. {
  7. dynamicOffset = bufferSize * i;
  8. // Update and draw the cube
  9. uniformBufferObject[i].proj = proj;
  10. uniformBufferObject[i].view = view;
  11. uniformBufferObject[i].model = glm::mat4(1.0f);
  12. uniformBufferObject[i].model = glm::translate(uniformBufferObject[i].model, glm::vec3(0.0f, 0.0f, -3.0f));
  13. uniformBufferObject[i].model = glm::rotate(uniformBufferObject[i].model, 0.0f, glm::vec3(1.0f, 1.0f, 1.0f));
  14. uniformBufferObject[i].model = glm::scale(uniformBufferObject[i].model, glm::vec3(0.45f));
  15. vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipelineLayout, 0, 1, &descriptorSet, 1, &dynamicOffset);
  16. vkCmdDraw(commandBuffer, static_cast<uint32_t>(vertices.size()), 1, 0, 0);
  17. }

Trying to render hundreds of spheres using a dynamic UBO but when I try to access uniformBufferObject[where index = bufferSize (192) * 21 (4032)], the application crashes.

Uniform buffer creation code is here:

  1. void createUniformBuffer()
  2. {
  3. createBuffer(bufferSize, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, uniformBuffer, uniformBufferMemory);
  4. vkMapMemory(device, uniformBufferMemory, 0, bufferSize, 0, &uniformBufferMapped);
  5. uniformBufferObject = static_cast<UniformBufferObject*>(uniformBufferMapped);
  6. }

Create buffer function:

  1. void createBuffer(VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags properties, VkBuffer& buffer, VkDeviceMemory& bufferMemory)
  2. {
  3. VkBufferCreateInfo bufferInfo{};
  4. bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
  5. bufferInfo.size = size;
  6. bufferInfo.usage = usage;
  7. bufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
  8. vkCreateBuffer(device, &bufferInfo, nullptr, &buffer);
  9. VkMemoryRequirements memRequirements;
  10. vkGetBufferMemoryRequirements(device, buffer, &memRequirements);
  11. VkMemoryAllocateInfo allocInfo{};
  12. allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
  13. allocInfo.allocationSize = memRequirements.size;
  14. allocInfo.memoryTypeIndex = findMemoryType(memRequirements.memoryTypeBits, properties);
  15. vkAllocateMemory(device, &allocInfo, nullptr, &bufferMemory);
  16. vkBindBufferMemory(device, buffer, bufferMemory, 0);
  17. }

findMemoryType function:

  1. uint32_t findMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags properties) {
  2. VkPhysicalDeviceMemoryProperties memProperties;
  3. vkGetPhysicalDeviceMemoryProperties(physicalDevice, &memProperties);
  4. for (uint32_t i = 0; i < memProperties.memoryTypeCount; i++) {
  5. if ((typeFilter & (1 << i)) && (memProperties.memoryTypes[i].propertyFlags & properties) == properties) {
  6. return i;
  7. }
  8. }
  9. }

ubo struct, descriptorsetlayout, descriptorpool, descriptorwrite:

  1. struct UniformBufferObject
  2. {
  3. glm::mat4 model;
  4. glm::mat4 view;
  5. glm::mat4 proj;
  6. };
  7. VkDescriptorSetLayoutBinding uboLayoutBinding{};
  8. uboLayoutBinding.binding = 0;
  9. uboLayoutBinding.descriptorCount = 1;
  10. uboLayoutBinding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
  11. uboLayoutBinding.stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
  12. std::array<VkDescriptorPoolSize, 2> poolSizes{};
  13. poolSizes[0].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
  14. poolSizes[0].descriptorCount = static_cast<uint32_t>(1);
  15. poolSizes[1].type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
  16. poolSizes[1].descriptorCount = static_cast<uint32_t>(1);
  17. descriptorWrites[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
  18. descriptorWrites[0].dstSet = descriptorSet;
  19. descriptorWrites[0].dstBinding = 0;
  20. descriptorWrites[0].dstArrayElement = 0;
  21. descriptorWrites[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
  22. descriptorWrites[0].descriptorCount = 1;
  23. descriptorWrites[0].pBufferInfo = &bufferInfo;

答案1

得分: 1

createBuffer(bufferSize, ...

假设这个bufferSize与填充结构的循环中使用的bufferSize相同,那么它需要变成

createBuffer(bufferSize * <你想要激活的绘制数量>, ...)

你正在分配一个单一的192字节缓冲区,恰好位于页面的开头,所以你可以在缓冲区的末尾之前写入,直到触及页面的末尾,然后出现错误。

英文:

> createBuffer(bufferSize, ...

Assuming this is the same bufferSize as your loop that populates the structure, this needs to be

createBuffer(bufferSize * &lt;whatever number of draws you want active&gt;, ...

You're allocating a single 192 byte buffer, which happens to be at the start of a page, and so you you are able write over the end of the buffer until you hit the end of the page which then faults.

huangapple
  • 本文由 发表于 2023年6月16日 01:41:07
  • 转载请务必保留本文链接:https://go.coder-hub.com/76484236.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定