Vulkan VMA使用致黑屏问题排查:uniform缓冲区配置错误
Vulkan VMA 集成后黑屏问题排查与解决
我在应用中集成Vulkan Memory Allocator(VMA)后出现黑屏,采用延迟渲染+HDR管线,所有附件均通过VMA分配。测试时片段着色器输出纯色显示正常,最初推测是顶点/索引缓冲区为空。
尝试的顶点缓冲区填充方案
- 使用暂存缓冲区复制数据:
void* data; vmaMapMemory(_allocator, stagingAllocation, &data); memcpy(data, bufferData, bufferSize); vmaUnmapMemory(_allocator, stagingAllocation);
- 跳过暂存缓冲区,直接配置标志后写入:
allocCreateInfo.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT;
memcpy(allocInfo.pMappedData, bufferData, bufferSize);
完整缓冲区创建代码
顶点缓冲区创建流程
VkBuffer stagingBuffer; VkBuffer vertexBuffer; VmaAllocation stagingAllocation = createBuffer(bufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VMA_MEMORY_USAGE_CPU_ONLY, stagingBuffer); void* data; vmaMapMemory(_allocator, stagingAllocation, &data); memcpy(data, bufferData, bufferSize); vmaUnmapMemory(_allocator, stagingAllocation); VmaAllocation allocation = createBuffer(bufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, VMA_MEMORY_USAGE_GPU_ONLY, vertexBuffer); copyBuffer(stagingBuffer, vertexBuffer, bufferSize); vmaDestroyBuffer(_allocator, stagingBuffer, stagingAllocation);
createBuffer函数实现
VmaAllocation createBuffer(VkDeviceSize size, VkBufferUsageFlags usage, VmaMemoryUsage memoryUsage, VkBuffer &buffer) { VkBufferCreateInfo bufferInfo{}; bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; bufferInfo.size = size; bufferInfo.usage = usage; bufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; VmaAllocationCreateInfo allocCreateInfo = {}; allocCreateInfo.usage = memoryUsage; VmaAllocation allocation; if (vmaCreateBuffer(_allocation, &bufferInfo, & allocCreateInfo, &buffer, &allocation, nullptr) != VK_SUCCESS) { throw std::runtime_error("Failed to create buffer"); } return allocation; }
其他异常现象
- 若将
allocCreateInfo.flags设为0,会出现奇怪的闪烁 - 切换到VMA前程序运行正常,仅修改了缓冲区和镜像创建代码(镜像部分无异常)
- 使用环境:MacOS + Vulkan 1.2
编辑1:初步定位问题
经过数小时调试,发现问题并非顶点缓冲区,而是uniform缓冲区配置错误:原本使用VMA_MEMORY_USAGE_CPU_TO_GPU标志,改为VMA_MEMORY_USAGE_CPU_ONLY后程序可正常运行,但这只是临时解决方案,不希望将所有uniform缓冲区存储在CPU内存中,求问问题根源。
编辑2:最终解决方案
最终发现,当设置usage为VMA_MEMORY_USAGE_CPU_TO_GPU时,VMA不会自动启用VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT或VK_MEMORY_PROPERTY_HOST_COHERENT_BIT标志,必须手动在allocCreateInfo.requiredFlags中添加这两个标志,添加后程序运行正常。但未在VMA文档中找到相关说明,调试过程十分困难。
内容的提问来源于stack exchange,提问作者Samo77
相关产品推荐
相关产品推荐

