You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 06:24:25