如何在vulkan下载深度图像?

时间:2018-03-03 08:27:28

标签: vulkan

我需要在帧的每一帧下载每帧的深度图像。这就是我使用

创建深度图像的原因
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, &region);

    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。

  1. 为什么我的地区出错了?
  2. 为什么抱怨布局?我将depthImage布局转换为transfer_src_optimal,并且我得到了depth_stencil_attachment_optimal的错误。
  3. 还有另一种下载深度的方法吗?通过渲染传递store_op?

0 个答案:

没有答案