Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/sharepoint/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从vulkan帧缓冲区下载的图像失真_Vulkan - Fatal编程技术网

从vulkan帧缓冲区下载的图像失真

从vulkan帧缓冲区下载的图像失真,vulkan,Vulkan,我正在用vulkan进行屏幕外渲染。因为我在设备内存中获得了渲染图像,所以我将其下载到主机内存以用于其他目的。一切正常,直到图像的宽度是8的倍数,否则图像会失真 这是一个vulkan功能,还是我在某个地方犯了一个错误 帧缓冲区代码: colorImageInfo = VkImageCreateInfo( imageType=VK_IMAGE_TYPE_2D, format=VK_FORMAT_B8G8R8A8_UNORM, mipLevel

我正在用vulkan进行屏幕外渲染。因为我在设备内存中获得了渲染图像,所以我将其下载到主机内存以用于其他目的。一切正常,直到图像的宽度是8的倍数,否则图像会失真

这是一个vulkan功能,还是我在某个地方犯了一个错误

帧缓冲区代码:

    colorImageInfo = VkImageCreateInfo(
        imageType=VK_IMAGE_TYPE_2D,
        format=VK_FORMAT_B8G8R8A8_UNORM,
        mipLevels=1,
        arrayLayers=1,
        samples=1,
        tiling=VK_IMAGE_TILING_OPTIMAL,
        usage=VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
        initialLayout=VK_IMAGE_LAYOUT_UNDEFINED,
        extent=[self.width, self.height, 1]
    )

    colorImage = vkCreateImage(self.inst.device, colorImageInfo, None)
    self.colorImage = colorImage
    memReqs = vkGetImageMemoryRequirements(self.inst.device, colorImage)
    memReqs = cdh.cdata_dict(memReqs)
    memProps = cdh.cdata_dict(self.inst.memoryProperties)
    memoryType = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT
    typeBits = memReqs["memoryTypeBits"]

    for i in range(32):
        if (typeBits & 1) == 1:

            if (memProps["memoryTypes"][i]["propertyFlags"] & memoryType) == memoryType:
                memType = i
                break
        typeBits >>= 1

    memAllocInfo = VkMemoryAllocateInfo(
        memoryTypeIndex=memType,
        allocationSize=memReqs["size"]
    )
    memAlloc = vkAllocateMemory(self.inst.device, memAllocInfo, None)
    # print(memAlloc)
    vkBindImageMemory(self.inst.device, colorImage, memAlloc, 0)

    subresourceRange = VkImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1)

    imageViewInfo = VkImageViewCreateInfo(
        viewType=VK_IMAGE_VIEW_TYPE_2D,
        format=VK_FORMAT_B8G8R8A8_UNORM,
        image=colorImage,
        subresourceRange=subresourceRange

    )
    colorImageView = vkCreateImageView(self.inst.device, imageViewInfo, None)
    # print(colorImageView)
    # depth Image

    #   create frame buffer
    framebuffferCreateInfo = VkFramebufferCreateInfo(
        pAttachments=[colorImageView],
        width=self.width,
        height=self.height,
        layers=1,
        renderPass=self.inst.renderPass
    )
    self.fb = vkCreateFramebuffer(self.inst.device, framebuffferCreateInfo, None)
将映像复制到主机可见内存代码:

    colorImageInfo = VkImageCreateInfo(
        imageType=VK_IMAGE_TYPE_2D,
        format=self.inst.colorFormat,
        mipLevels=1,
        arrayLayers=1,
        samples=1,
        tiling=VK_IMAGE_TILING_LINEAR,
        usage=VK_IMAGE_USAGE_TRANSFER_DST_BIT,
        initialLayout=VK_IMAGE_LAYOUT_UNDEFINED,
        extent=[self.width, self.height, 1]
    )

    colorImage = vkCreateImage(self.inst.device, colorImageInfo, None)
    memReqs = vkGetImageMemoryRequirements(self.inst.device, colorImage)
    memReqs = cdh.cdata_dict(memReqs)
    memProps = cdh.cdata_dict(self.inst.memoryProperties)
    memoryType = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
    typeBits = memReqs["memoryTypeBits"]
    for i in range(32):
        if (typeBits & 1) == 1:
            if (memProps["memoryTypes"][i]["propertyFlags"] & memoryType) == memoryType:
                memType = i
                break
        typeBits >>= 1
    memAllocInfo = VkMemoryAllocateInfo(
        memoryTypeIndex=memType,
        allocationSize=memReqs["size"]
    )
    memAlloc = vkAllocateMemory(self.inst.device, memAllocInfo, None)
    vkBindImageMemory(self.inst.device, colorImage, memAlloc, 0)

    commandBufferAllocateInfo = VkCommandBufferAllocateInfo(
        commandPool=self.inst.commandPool,
        level=VK_COMMAND_BUFFER_LEVEL_PRIMARY,
        commandBufferCount=1
    )

    cmdBuff = vkAllocateCommandBuffers(self.inst.device, commandBufferAllocateInfo)
    cmdBuff = ffi.addressof(cmdBuff, 0)[0]

    beginInfo = VkCommandBufferBeginInfo(
        sType=VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
        flags=VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT
    )

    vkBeginCommandBuffer(cmdBuff, beginInfo)
    subresourceRange = VkImageSubresourceRange(
        aspectMask=VK_IMAGE_ASPECT_COLOR_BIT,
        baseMipLevel=0,
        levelCount=1,
        baseArrayLayer=0,
        layerCount=1
    )
    barrier = VkImageMemoryBarrier(
        oldLayout=VK_IMAGE_LAYOUT_UNDEFINED,
        newLayout=VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
        srcQueueFamilyIndex=VK_QUEUE_FAMILY_IGNORED,
        dstQueueFamilyIndex=VK_QUEUE_FAMILY_IGNORED,
        image=colorImage,
        srcAccessMask=0,
        dstAccessMask=VK_ACCESS_TRANSFER_WRITE_BIT,
        subresourceRange=subresourceRange
    )
    vkCmdPipelineBarrier(cmdBuff, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, None, 0,
                         None, 1, barrier)
    # source image barrier
    barrier = VkImageMemoryBarrier(
        oldLayout=VK_IMAGE_LAYOUT_GENERAL,
        newLayout=VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
        srcQueueFamilyIndex=VK_QUEUE_FAMILY_IGNORED,
        dstQueueFamilyIndex=VK_QUEUE_FAMILY_IGNORED,
        image=self.colorImage,
        srcAccessMask=VK_ACCESS_MEMORY_READ_BIT,
        dstAccessMask=VK_ACCESS_TRANSFER_READ_BIT,
        subresourceRange=subresourceRange
    )
    vkCmdPipelineBarrier(cmdBuff, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, None, 0,
                         None,
                         1, barrier)

    srcSubresource = VkImageSubresourceLayers(
        aspectMask=VK_IMAGE_ASPECT_COLOR_BIT,
        layerCount=1
    )
    dstSubresource = VkImageSubresourceLayers(
        aspectMask=VK_IMAGE_ASPECT_COLOR_BIT,
        layerCount=1
    )
    imageCopy = VkImageCopy(
        srcSubresource,
        VkOffset3D(0, 0, 0),
        dstSubresource,
        VkOffset3D(0, 0, 0),
        VkExtent3D(self.width, self.height)
    )

    vkCmdCopyImage(cmdBuff, self.colorImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
                   colorImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, imageCopy)

    barrier = VkImageMemoryBarrier(
        oldLayout=VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
        newLayout=VK_IMAGE_LAYOUT_GENERAL,
        srcQueueFamilyIndex=VK_QUEUE_FAMILY_IGNORED,
        dstQueueFamilyIndex=VK_QUEUE_FAMILY_IGNORED,
        image=colorImage,
        srcAccessMask=VK_ACCESS_TRANSFER_WRITE_BIT,
        dstAccessMask=VK_ACCESS_MEMORY_READ_BIT,
        subresourceRange=subresourceRange
    )
    vkCmdPipelineBarrier(cmdBuff, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, None, 0,
                         None,
                         1, barrier)

    barrier = VkImageMemoryBarrier(
        oldLayout=VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
        newLayout=VK_IMAGE_LAYOUT_GENERAL,
        srcQueueFamilyIndex=VK_QUEUE_FAMILY_IGNORED,
        dstQueueFamilyIndex=VK_QUEUE_FAMILY_IGNORED,
        image=self.colorImage,
        srcAccessMask=VK_ACCESS_TRANSFER_READ_BIT,
        dstAccessMask=VK_ACCESS_MEMORY_READ_BIT,
        subresourceRange=subresourceRange
    )
    vkCmdPipelineBarrier(cmdBuff, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, None, 0,
                         None,
                         1, barrier)
    vkEndCommandBuffer(cmdBuff)

    self.getImageSubmitInfo = VkSubmitInfo(
        pCommandBuffers=[cmdBuff]
    )
    self.imageMemory = memAlloc
下载图像代码:

    vkQueueSubmit(self.inst.graphicsQueue, 1, self.getImageSubmitInfo, VK_NULL_HANDLE)
    vkQueueWaitIdle(self.inst.graphicsQueue)
    pb = vkMapMemory(self.inst.device, self.imageMemory, 0, self.width * self.height * 4, 0)

    out = np.frombuffer(pb, np.uint8)
    out = out.reshape((self.height, self.width, 4))
    vkUnmapMemory(self.inst.device, self.imageMemory)
这就是我发现的

这是vkCmdCopyImage复制压缩数据的方式:

rowLength = region->bufferRowLength;
if (rowLength == 0)
    rowLength = region->imageExtent.width;

imageHeight = region->bufferImageHeight;
if (imageHeight == 0)
    imageHeight = region->imageExtent.height;

compressedTexelBlockSizeInBytes = <compressed texel block size taken from the src/dstImage>;
rowLength /= compressedTexelBlockWidth;
imageHeight /= compressedTexelBlockHeight;

address of (x,y,z) = region->bufferOffset + (((z * imageHeight) + y) * rowLength + x) * compressedTexelBlockSizeInBytes;

where x,y,z range from (0,0,0) to region->imageExtent.{width/compressedTexelBlockWidth,height/compressedTexelBlockHeight,depth/compressedTexelBlockDepth}.
rowLength=region->bufferRowLength;
if(rowLength==0)
rowLength=区域->imageExtent.width;
imageHeight=区域->缓冲imageHeight;
如果(imageHeight==0)
imageHeight=区域->imageExtent.height;
压缩的ExelBlockSizeInBytes=;
rowLength/=压缩的ExelblockWidth;
imageHeight/=压缩的ExelblockHeight;
(x,y,z)的地址=区域->缓冲区偏移量+((z*图像高度)+y)*行长+x)*压缩的ExelBlockSizeInBytes;
其中x,y,z的范围从(0,0,0)到区域->图像范围。{width/compressedtexlblockwidth,height/compressedtexlblockheight,depth/compressedtexlblockdepth}。

因此,如果我假设具有最佳布局的图像已被压缩,但具有线性布局的图像未被压缩,这就解释了问题。

如果不查看相关代码部分,则不可能说出任何巧妙的话。如果这解决了问题,请接受您自己的答案。