我需要在帧的每一帧下载每帧的深度图像。这就是我使用
创建深度图像的原因VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT |
VK_IMAGE_USAGE_TRANSFER_SRC_BIT
然后我使用vkCmdPipelineBarrier将深度图像布局转换为VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL而不是VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL。
这是执行深度下载的功能(整个文件 - https://pastebin.com/vfZCYNf9):
s32 vkdepth_get_depth_data(r32 *outData) {
VkDevice device = vgmain_get_device();
VkQueue graphicsQueue = vgmain_get_graphics_queue();
VkImage depthImage = vgmain_get_depth_image();
VkExtent2D extent = vgmain_get_swap_chain_extent();
VkDeviceSize imageSize = extent.width * extent.height * 4;
VkBuffer stagingBuffer;
VkDeviceMemory stagingBufferMemory;
//create staging buffer as src for image
vmem_createBuffer(&stagingBuffer, &stagingBufferMemory, imageSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
VkCommandPool commandPool = vgmain_get_prim_command_pool();
VkCommandBuffer commandBuffer = vkcmd_beginSingleTimeCommands(commandPool, device);
VkBufferImageCopy region = {};
region.bufferOffset = 0;
region.bufferRowLength = 0;
region.bufferImageHeight = 0;
region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
region.imageSubresource.mipLevel = 0;
region.imageSubresource.baseArrayLayer = 0;
region.imageSubresource.layerCount = 1;
region.imageOffset = (VkOffset3D){0, 0, 0};
region.imageExtent = (VkExtent3D){
extent.width,
extent.height,
1
};
vkCmdCopyImageToBuffer(commandBuffer, depthImage,
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
stagingBuffer, 1, ®ion);
vkcmd_endSingleTimeCommands(commandBuffer, commandPool, device, graphicsQueue);
void *data;
vkMapMemory(device, stagingBufferMemory, 0, imageSize, 0, &data);
memcpy(outData, data, imageSize);
vkUnmapMemory(device, stagingBufferMemory);
vkDestroyBuffer(device, stagingBuffer, nullptr);
vkFreeMemory(device, stagingBufferMemory, nullptr);
}
第一帧的函数执行会产生验证错误:
验证层:vkCmdCopyImageToBuffer():无法读取无效区域 对于绑定的Image对象0x8d的内存分配0x8e,请填写 使用前的记忆。
第二帧告诉我:
验证层:无法使用图像提交cmd缓冲区(0x8d) [sub-resource:aspectMask 0x2 array layer 0,mip level 0],带布局 首次使用时为VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL。 验证层: vkCmdCopyImageToBuffer():无法读取无效的内存区域 为绑定的Image对象0x8d分配0x8e,请填写内存 在使用之前。
0x8d是depthImage,0x8e是depthImageMemory。