Vulkan从交换链复制图像

时间:2017-06-22 14:45:41

标签: image copy buffer vulkan

我正在使用vkCmdCopyImageToBuffer函数并获取内存访问冲突并且不明白原因。

以下是代码:

VkBufferImageCopy region = {};
region.bufferOffset = 0;
region.bufferRowLength = width;
region.bufferImageHeight = height;
region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
region.imageSubresource.mipLevel = 0;
region.imageSubresource.baseArrayLayer = 0;
region.imageSubresource.layerCount = 1;
region.imageOffset = { 0, 0, 0 };
region.imageExtent = {
    width,
    height,
    1
};

vkCmdCopyImageToBuffer(m_drawCmdBuffers[i], m_swapChain.buffers[i].image,
    VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, m_renderImage, 1, &region);

交换链图像在初始化代码中创建:

// Get the swap chain images
images.resize(imageCount);
VK_CHECK_RESULT(fpGetSwapchainImagesKHR(device, swapChain, &imageCount, images.data()));

// Get the swap chain buffers containing the image and imageview
buffers.resize(imageCount);
for (uint32_t i = 0; i < imageCount; i++)
{
    VkImageViewCreateInfo colorAttachmentView = {};
    colorAttachmentView.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
    colorAttachmentView.pNext = NULL;
    colorAttachmentView.format = colorFormat;
    colorAttachmentView.components = {
        VK_COMPONENT_SWIZZLE_R,
        VK_COMPONENT_SWIZZLE_G,
        VK_COMPONENT_SWIZZLE_B,
        VK_COMPONENT_SWIZZLE_A
    };
    colorAttachmentView.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
    colorAttachmentView.subresourceRange.baseMipLevel = 0;
    colorAttachmentView.subresourceRange.levelCount = 1;
    colorAttachmentView.subresourceRange.baseArrayLayer = 0;
    colorAttachmentView.subresourceRange.layerCount = 1;
    colorAttachmentView.viewType = VK_IMAGE_VIEW_TYPE_2D;
    colorAttachmentView.flags = 0;

    buffers[i].image = images[i];

    colorAttachmentView.image = buffers[i].image;

    VK_CHECK_RESULT(vkCreateImageView(device, &colorAttachmentView, nullptr, &buffers[i].view));
}

我的缓冲区同样在这里创建:

VkBufferCreateInfo createinfo = {};
createinfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
createinfo.size = width * height * 4 * sizeof(int8_t);
createinfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
createinfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;

//create the image copy buffer
vkCreateBuffer(m_device, &createinfo, NULL, &m_renderImage);

我尝试了不同的像素格式和不同的createinfo.usage设置但没有帮助。

1 个答案:

答案 0 :(得分:1)

VkSurfaceCapabilitiesKHR::supportedUsageFlags定义了您可以使用交换链创建的VkImage的方式的限制。唯一支持保证的是颜色附件;所有其他的包括传输src,都是可选的。

因此,您不应该假设您可以从可呈现的图像进行复制。如果您发现自己需要这样做,则必须首先查询该值。如果它不允许复制,则必须渲染到您自己复制的图像。当你打算呈现它时,你可以从那个图像渲染成可呈现的图像。