title: How to render to texture in Vulkan?
body: <p>I need render to textrue in my project.</p>
  
  <p>Pass1 : Draw a color square that color is (0.5,0.5,0.5,1.0) and render target is a texture.</p>
  
  <p>Pass2 : Draw a textured square that use pass1's texture and render target is a surface.</p>
  
  <p>Expected result:</p>
  
  <p><a href="https://i.stack.imgur.com/B9VKL.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/B9VKL.png" alt="enter image description here"></a></p>
  
  <p>But I got strange result as follow:</p>
  
  <p><a href="https://i.stack.imgur.com/MOXG6.gif" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/MOXG6.gif" alt="enter image description here"></a></p>
  
  <p>Create image using the following:</p>
  
  <pre><code>  VkImage hImageTexture = VK_NULL_HANDLE;
    VkImageCreateInfo imageCreateInfo = {0};
    imageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
    imageCreateInfo.pNext = nullptr;
    imageCreateInfo.flags = 0;
    imageCreateInfo.imageType = VK_IMAGE_TYPE_2D;
    imageCreateInfo.format = VK_FORMAT_B8G8R8A8_UNORM;
    imageCreateInfo.extent.width = width;
    imageCreateInfo.extent.height = height;
    imageCreateInfo.extent.depth = 1;
    imageCreateInfo.mipLevels = 1;
    imageCreateInfo.arrayLayers = 1;
    imageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT;
    imageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
    imageCreateInfo.usage =
      VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
      VK_IMAGE_USAGE_TRANSFER_DST_BIT |
      VK_IMAGE_USAGE_SAMPLED_BIT;
    imageCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
    imageCreateInfo.queueFamilyIndexCount = 0;
    imageCreateInfo.pQueueFamilyIndices = nullptr;
    imageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
    //
    VkResult res = vkCreateImage(hDevice , &amp;imageCreateInfo , nullptr , &amp;hImageTexture);
  </code></pre>
  
  <p>Create image view using the following:</p>
  
  <pre><code>  VkImageView hImageViewTexture = VK_NULL_HANDLE;
    VkImageViewCreateInfo imageViewCreateInfo = {0};
    imageViewCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
    imageViewCreateInfo.pNext = nullptr;
    imageViewCreateInfo.flags = 0;
    imageViewCreateInfo.image = hImageTexture;
    imageViewCreateInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
    imageViewCreateInfo.format = VK_FORMAT_B8G8R8A8_UNORM;
    imageViewCreateInfo.components.r = VK_COMPONENT_SWIZZLE_R;
    imageViewCreateInfo.components.g = VK_COMPONENT_SWIZZLE_G;
    imageViewCreateInfo.components.b = VK_COMPONENT_SWIZZLE_B;
    imageViewCreateInfo.components.a = VK_COMPONENT_SWIZZLE_A;
    imageViewCreateInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
    imageViewCreateInfo.subresourceRange.baseMipLevel = 0;
    imageViewCreateInfo.subresourceRange.levelCount = 1;
    imageViewCreateInfo.subresourceRange.baseArrayLayer = 0;
    imageViewCreateInfo.subresourceRange.layerCount = 1;
    VkResult res=vkCreateImageView(
      hDevice,
      &amp;imageViewCreateInfo,
      NULL,
      &amp;hImageViewTexture);
  </code></pre>
  
  <p>Render loop as follows:</p>
  
  <pre><code>  //Pass1
    //Clear texture  color
    vkCmdPipelineBarrier();//Transition layout to VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
    vkCmdClearColorImage();//Clear color(0.0 , 0.0 ,0.0 , 1.0)
    vkCmdPipelineBarrier();//Transition layout to VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
    //Change texture's barrier
    VkImageMemoryBarrier imageMemoryBarrierForOutput = {0};
    imageMemoryBarrierForOutput.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
    imageMemoryBarrierForOutput.pNext = nullptr;
    imageMemoryBarrierForOutput.srcAccessMask = 0;
    imageMemoryBarrierForOutput.dstAccessMask = 
      VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
    imageMemoryBarrierForOutput.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
    imageMemoryBarrierForOutput.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
    imageMemoryBarrierForOutput.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
    imageMemoryBarrierForOutput.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
    imageMemoryBarrierForOutput.image = hImageTexture;
    imageMemoryBarrierForOutput.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
    imageMemoryBarrierForOutput.subresourceRange.baseMipLevel = 0;
    imageMemoryBarrierForOutput.subresourceRange.levelCount = 1;
    imageMemoryBarrierForOutput.subresourceRange.baseArrayLayer = 0;
    imageMemoryBarrierForOutput.subresourceRange.layerCount = 1;
    vkCmdPipelineBarrier(
      hCommandBuffer,
      VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
      VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
      0,
      0,
      nullptr,
      0,
      nullptr,
      1,
      &amp;imageMemoryBarrierForOutput);
    //draw
    vkCmdBeginRenderPass();
    vkCmdSetViewport();
    vkCmdSetScissor();
    vkCmdBindPipeline();
    vkCmdBindDescriptorSets();
    vkCmdBindVertexBuffers();
    vkCmdBindIndexBuffer();
    vkCmdDrawIndexed();
    vkCmdEndRenderPass();
    //
    //Pass2
    //Clear surface color
    vkCmdPipelineBarrier();//Transition layout to VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
    vkCmdClearColorImage();//Clear color(0.5 , 0.5 ,1.0 , 1.0)
    vkCmdPipelineBarrier();//Transition layout to VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
    //Change texture's barrier
    VkImageMemoryBarrier imageMemoryBarrierForInput = {0};
    imageMemoryBarrierForInput.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
    imageMemoryBarrierForInput.pNext = nullptr;
    imageMemoryBarrierForInput.srcAccessMask = 0;
    imageMemoryBarrierForInput.dstAccessMask = 
      VK_ACCESS_SHADER_READ_BIT |
      VK_ACCESS_INPUT_ATTACHMENT_READ_BIT;
    imageMemoryBarrierForInput.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
    imageMemoryBarrierForInput.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
    imageMemoryBarrierForInput.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
    imageMemoryBarrierForInput.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
    imageMemoryBarrierForInput.image = hImageTexture;
    imageMemoryBarrierForInput.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
    imageMemoryBarrierForInput.subresourceRange.baseMipLevel = 0;
    imageMemoryBarrierForInput.subresourceRange.levelCount = 1;
    imageMemoryBarrierForInput.subresourceRange.baseArrayLayer = 0;
    imageMemoryBarrierForInput.subresourceRange.layerCount = 1;
    vkCmdPipelineBarrier(
      hCommandBuffer,
      VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
      VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
      0,
      0,
      nullptr,
      0,
      nullptr,
      1,
      &amp;imageMemoryBarrierForInput);
    //draw
    vkCmdBeginRenderPass();
    vkCmdSetViewport();
    vkCmdSetScissor();
    vkCmdBindPipeline();
    vkCmdBindDescriptorSets();
    vkCmdBindVertexBuffers();
    vkCmdBindIndexBuffer();
    vkCmdDrawIndexed();
    vkCmdEndRenderPass();
  </code></pre>
  
  <p>Pass1 vertex shader:</p>
  
  <pre><code>#version 450
  
  layout (location=0) in vec4 inPos;
  layout (location=0) out vec4 outPos;
  
  void main(void)
  {
    outPos = float4(inPos.xy , 0.0 , 1.0);  
    gl_Position = outPos;
  }
  </code></pre>
  
  <p>Pass1 fragment shader:</p>
  
  <pre><code>#version 450
  
  layout (location=0) in vec4 inPos;
  layout (location=0) out vec4 outColor;
  
  void main(void)
  {
    outColor = float4(0.5 , 0.5 , 0.5 , 1.0);    
  }
  </code></pre>
  
  <p>Pass2 vertex shader:</p>
  
  <pre><code>#version 450
  
  layout (location=0) in vec4 inPos;
  layout (location=1) in vec2 inUV;
  //
  layout (location=0) out vec4 outPos;
  layout (location=1) out vec2 outUV;
  //
  void main(void)
  {
    outPos = inPos;
    outUV = inUV;
    //
    gl_Position=outPos;
  }
  </code></pre>
  
  <p>Pass2 fragment shader:</p>
  
  <pre><code>#version 450
  //
  layout (location=0) in vec4 inPos;
  layout (location=1) in vec2 inUV;
  //
  layout (binding=1) uniform sampler2D inTex;
  layout (location=0) out vec4 outColor;
  void main(void)
  {
    outColor = texture(inTex , inUV);
  }
  </code></pre>
  
  <p>If I change image tiling to <code>VK_IMAGE_TILING_LINEAR</code> then I get the following:</p>
  
  <p><a href="https://i.stack.imgur.com/wRL5V.gif" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/wRL5V.gif" alt="enter image description here"></a></p>
  
  <p>If change image tiling to <code>VK_IMAGE_TILING_LINEAR</code> without clear(pass1's clear), the result was correct!</p>
  
  <p>What mistakes have I made?</p>
  
  <p><strong>EDIT:</strong>
  I add some code that how i change texture's barrier in render loop .</p>
  
  <p><strong>EDIT:</strong>
  I set dependency when create render pass as follow</p>
  
  <pre><code>  VkSubpassDependency subpassDependency[2];
    subpassDependency[0].srcSubpass = VK_SUBPASS_EXTERNAL;
    subpassDependency[0].dstSubpass = 0;
    subpassDependency[0].srcStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
    subpassDependency[0].dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
    subpassDependency[0].srcAccessMask = VK_ACCESS_SHADER_READ_BIT;
    subpassDependency[0].dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
    subpassDependency[0].dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;
    //
    subpassDependency[1].srcSubpass = 0;
    subpassDependency[1].dstSubpass = VK_SUBPASS_EXTERNAL;
    subpassDependency[1].srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
    subpassDependency[1].dstStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
    subpassDependency[1].srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
    subpassDependency[1].dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
    subpassDependency[1].dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;
  </code></pre>
  
  <p>but nothing to changed.</p>