Vulkan从交换链复制图像

问题描述:

我已经看到了关于此的其他问题,但他们不回答我的问题,所以在这里。我正在使用vkCmdCopyImageToBuffer函数并获取内存访问冲突,并且不明白为什么。这是代码。Vulkan从交换链复制图像

  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); 

的swapchain图像在这里创造了初始化代码:

// 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。使用设置,但没有帮助。

+0

什么是“交换链缓冲区”?这不是Vulkan定义的概念。 –

+0

这些是映射到由fpGetSwapchainImagesKHR()函数检索的交换链图像的对象。如果我没有正确地获取交换链图像,请告诉我。 –

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

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

+0

我看了一下我的代码,vkCmdBeginRenderPass并不指示VkImage目标选项。信息中的renderpass对象也没有任何目标信息。这表示交换链的图像是默认目标。我的renderpass完成后,如何手动呈现给vkImage。如果你可以请提供示例代码或者指向一个做相同事情的教程。 –

+0

@AnthonyDaniels:关于Vulkan的规则3:有*没有默认*。您必须指定关于系统的* everything *。在这种情况下,在渲染过程实例中用作附件的图像由传递给'vkCmdBeginRenderPass'的'VkFramebuffer'对象指定。 –