2017-06-22 5 views
-1

J'ai vu les autres questions à ce sujet, mais ils ne répondent pas à ma question alors voilà. J'utilise la fonction vkCmdCopyImageToBuffer et obtenir une violation d'accès à la mémoire et je ne comprends pas pourquoi. Voici le code.Vulkan copie l'image de la chaîne d'échange

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

Les images swapchain sont créées ici dans le code d'initialisation:

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

Et mon tampon est créé Similairement ici:

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

J'ai essayé différents formats de pixels et différents createinfo. paramètres d'utilisation mais aucune aide.

+0

Qu'est-ce qu'un "tampon de chaîne d'échange"? Ce n'est pas un concept défini par Vulkan. –

+0

Il s'agit d'objets mappés aux images swapchain récupérées par la fonction fpGetSwapchainImagesKHR(). Si je ne reçois pas les images de la chaîne d'échange correctement faites le moi savoir. –

Répondre

0

VkSurfaceCapabilitiesKHR::supportedUsageFlags définit les limitations sur la façon dont vous pouvez utiliser les VkImage créés par la chaîne d'échange. Le seul garanti à prendre en charge est la pièce jointe en couleur; tous les autres, y compris transfert src, sont facultatifs.

Par conséquent, vous ne devez pas supposer que vous pouvez copier à partir d'une image présentable. Si vous avez besoin de faire cela, vous devez d'abord interroger cette valeur. S'il n'autorise pas les copies, vous devez effectuer un rendu sur votre propre image, à partir de laquelle vous copiez. Vous pouvez rendre de cette image dans la présentable lorsque vous avez l'intention de la présenter.

+0

J'ai regardé mon code et le vkCmdBeginRenderPass n'indique pas une option cible VkImage. L'objet renderpass qui se trouve dans l'info n'a pas non plus d'informations sur la cible. Cela indique que les images de la chaîne d'échange sont la cible par défaut. Comment est-ce que je rends à un vkImage manuellement après que mon renderpass soit fait. Si vous pouviez s'il vous plaît fournir un exemple de code ou me diriger vers un tutoriel qui fait la même chose. –

+0

@AnthonyDaniels: Règle n ° 3 sur Vulkan: il n'y a pas de valeurs par défaut *. Vous devez spécifier * tout * sur le système. Dans ce cas, les images utilisées comme pièces jointes dans une instance de rendu sont spécifiées par l'objet 'VkFramebuffer' que vous avez passé à' vkCmdBeginRenderPass'. –