【问题标题】:Vulkan copying image from swap chainVulkan 从交换链复制图像
【发布时间】:2017-06-22 14:45:41
【问题描述】:

我正在使用 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 设置,但没有任何帮助。

【问题讨论】:

  • 什么是“交换链缓冲区”?这不是 Vulkan 定义的概念。
  • 这些对象映射到 fpGetSwapchainImagesKHR() 函数检索到的交换链图像。如果我没有正确获取交换链图像,请告诉我。

标签: image copy buffer vulkan


【解决方案1】:

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

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

【讨论】:

  • 我查看了我的代码,并且 vkCmdBeginRenderPass 并未指示 VkImage 目标选项。信息中的 renderpass 对象也没有任何目标信息。这表明交换链的图像是默认目标。完成渲染通道后,如何手动渲染到 vkImage。如果可以请提供示例代码或指向我做同样事情的教程。
  • @AnthonyDaniels:关于 Vulkan 的第 3 条规则:没有默认值。您必须指定有关系统的所有内容。在这种情况下,在渲染过程实例中用作附件的图像由您传递给 vkCmdBeginRenderPassVkFramebuffer 对象指定。
猜你喜欢
  • 1970-01-01
  • 2020-02-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多