<p>I was not creating a command buffer properly. I added one line pertaining to the screenshot command buffer, and it all works now, using an image memory barrier:</p>
<pre><code>if (num_cams_wide == 1)
{
    // This is the line that I added to make it all work...
    VkCommandBuffer screenshotCmdBuffer = vulkanDevice-&gt;createCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY, true);

    memcpy(screenshotStagingBuffer.mapped, &amp;uc_output_data[0], size);

    VkImageSubresourceRange subresourceRange = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 };

    vks::tools::setImageLayout(
        screenshotCmdBuffer,
        screenshotStorageImage.image,
        VK_IMAGE_LAYOUT_UNDEFINED,
        VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
        subresourceRange);

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

    VkImageMemoryBarrier imageMemoryBarrier;
    imageMemoryBarrier.image = screenshotStorageImage.image;
    imageMemoryBarrier.subresourceRange = subresourceRange;
    imageMemoryBarrier.srcAccessMask = VK_ACCESS_HOST_READ_BIT;
    imageMemoryBarrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
    imageMemoryBarrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
    imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
    imageMemoryBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;

    vkCmdCopyBufferToImage(
        screenshotCmdBuffer,
        screenshotStagingBuffer.buffer,
        screenshotStorageImage.image,
        VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
        1,
        &amp;copyRegion);

    vkCmdPipelineBarrier(
        screenshotCmdBuffer,
        VK_PIPELINE_STAGE_HOST_BIT,
        VK_PIPELINE_STAGE_TRANSFER_BIT,
        0,
        0, nullptr,
        0, nullptr,
        1, &amp;imageMemoryBarrier);

    vulkanDevice-&gt;flushCommandBuffer(screenshotCmdBuffer, queue);
}
</code></pre>
<p>The results are a denoised on screen image:</p>
<p><a href="https://i.sstatic.net/JvDIv.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/JvDIv.png" alt="enter image description here" /></a></p>

CC BY-SA 4.0
2024-07-15T10:51:33.660Z
Great that you could find a solution. Please mark your answer as accepted
Tare
CC BY-SA 4.0
2024-02-12T18:58:45.480Z
2024-02-12T18:58:45.480Z
shawn_halayka
<p>Using Vulkan, I am reading from an image to a vector of unsigned char. It works great.</p>
<pre><code>vkCmdTraceRaysKHR(
    screenshotCmdBuffer,
    &amp;shaderBindingTables.raygen.stridedDeviceAddressRegion,
    &amp;shaderBindingTables.miss.stridedDeviceAddressRegion,
    &amp;shaderBindingTables.hit.stridedDeviceAddressRegion,
    &amp;emptySbtEntry,
    size_x,
    size_y,
    1);

vks::tools::setImageLayout(
    screenshotCmdBuffer,
    screenshotStorageImage.image,
    VK_IMAGE_LAYOUT_GENERAL,
    VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
    subresourceRange);

VkBufferImageCopy copyRegion{};
copyRegion.bufferOffset = 0;
copyRegion.bufferRowLength = 0;
copyRegion.bufferImageHeight = 0;

copyRegion.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
copyRegion.imageSubresource.mipLevel = 0;
copyRegion.imageSubresource.baseArrayLayer = 0;
copyRegion.imageSubresource.layerCount = 1;

copyRegion.imageOffset = { 0, 0, 0 };
copyRegion.imageExtent.width = size_x;
copyRegion.imageExtent.height = size_y;
copyRegion.imageExtent.depth = 1;

vkCmdCopyImageToBuffer(screenshotCmdBuffer, screenshotStorageImage.image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, screenshotStagingBuffer.buffer, 1, &amp;copyRegion);

VkBufferMemoryBarrier barrier = {};
barrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER;
barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
barrier.dstAccessMask = VK_ACCESS_HOST_READ_BIT;
barrier.buffer = screenshotStagingBuffer.buffer;
barrier.size = screenshotStagingBuffer.size;

vkCmdPipelineBarrier(
    screenshotCmdBuffer,
    VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT,
    0,
    0, nullptr,
    1, &amp;barrier,
    0, nullptr
);

vulkanDevice-&gt;flushCommandBuffer(screenshotCmdBuffer, queue);

memcpy(&amp;fbpixels[0], screenshotStagingBuffer.mapped, size);
</code></pre>
<p>How would I go about writing from a vector of unsigned char to an image?</p>
<p>This is a code that I've been trying, but it does not work:</p>
<pre><code>memcpy(screenshotStagingBuffer.mapped, &amp;uc_output_data[0], size);

VkImageSubresourceRange subresourceRange = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 };

vks::tools::setImageLayout(
    screenshotCmdBuffer,
    screenshotStorageImage.image,
    VK_IMAGE_LAYOUT_GENERAL,
    VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
    subresourceRange);

VkBufferImageCopy copyRegion{};
copyRegion.bufferOffset = 0;
copyRegion.bufferRowLength = 0;
copyRegion.bufferImageHeight = 0;

copyRegion.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
copyRegion.imageSubresource.mipLevel = 0;
copyRegion.imageSubresource.baseArrayLayer = 0;
copyRegion.imageSubresource.layerCount = 1;

copyRegion.imageOffset = { 0, 0, 0 };
copyRegion.imageExtent.width = size_x;
copyRegion.imageExtent.height = size_y;
copyRegion.imageExtent.depth = 1;

vkCmdCopyBufferToImage(
    screenshotCmdBuffer,
    screenshotStagingBuffer.buffer,
    screenshotStorageImage.image,
    VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
    1,
    &amp;copyRegion);

VkBufferMemoryBarrier barrier = {};
barrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER;
barrier.srcAccessMask = VK_ACCESS_HOST_READ_BIT;
barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
barrier.buffer = screenshotStagingBuffer.buffer;
barrier.size = screenshotStagingBuffer.size;

vkCmdPipelineBarrier(
    screenshotCmdBuffer,
    VK_PIPELINE_STAGE_HOST_BIT,
    VK_PIPELINE_STAGE_TRANSFER_BIT,
    0,
    0, nullptr,
    1, &amp;barrier,
    0, nullptr);

vulkanDevice-&gt;flushCommandBuffer(screenshotCmdBuffer, queue);
</code></pre>
<p>Should I be using an image memory barrier instead of a buffer memory barrier?</p>
<p>The validation layers says that:</p>
<pre><code>ERROR: [1458672316][VUID-VkSamplerCreateInfo-anisotropyEnable-01070] : Validation Error: [ VUID-VkSamplerCreateInfo-anisotropyEnable-01070 ] | MessageID = 0x56f192bc | vkCreateSampler(): Anisotropic sampling feature is not enabled, pCreateInfo-&gt;anisotropyEnable must be VK_FALSE. The Vulkan spec states: If the samplerAnisotropy feature is not enabled, anisotropyEnable must be VK_FALSE (https://vulkan.lunarg.com/doc/view/1.3.261.1/windows/1.3-extensions/vkspec.html#VUID-VkSamplerCreateInfo-anisotropyEnable-01070)

ERROR: [1458672316][VUID-VkSamplerCreateInfo-anisotropyEnable-01070] : Validation Error: [ VUID-VkSamplerCreateInfo-anisotropyEnable-01070 ] | MessageID = 0x56f192bc | vkCreateSampler(): Anisotropic sampling feature is not enabled, pCreateInfo-&gt;anisotropyEnable must be VK_FALSE. The Vulkan spec states: If the samplerAnisotropy feature is not enabled, anisotropyEnable must be VK_FALSE (https://vulkan.lunarg.com/doc/view/1.3.261.1/windows/1.3-extensions/vkspec.html#VUID-VkSamplerCreateInfo-anisotropyEnable-01070)

ERROR: [706474367][VUID-VkShaderModuleCreateInfo-pCode-01379] : Validation Error: [ VUID-VkShaderModuleCreateInfo-pCode-01379 ] | MessageID = 0x2a1bf17f | SPIR-V module not valid: Invalid SPIR-V binary version 1.5 for target environment SPIR-V 1.4 (under Vulkan 1.1 semantics). The Vulkan spec states: If pCode is a pointer to GLSL code, it must be valid GLSL code written to the GL_KHR_vulkan_glsl GLSL extension specification (https://vulkan.lunarg.com/doc/view/1.3.261.1/windows/1.3-extensions/vkspec.html#VUID-VkShaderModuleCreateInfo-pCode-01379)

ERROR: [706474367][VUID-VkShaderModuleCreateInfo-pCode-01379] : Validation Error: [ VUID-VkShaderModuleCreateInfo-pCode-01379 ] | MessageID = 0x2a1bf17f | SPIR-V module not valid: Invalid SPIR-V binary version 1.5 for target environment SPIR-V 1.4 (under Vulkan 1.1 semantics). The Vulkan spec states: If pCode is a pointer to GLSL code, it must be valid GLSL code written to the GL_KHR_vulkan_glsl GLSL extension specification (https://vulkan.lunarg.com/doc/view/1.3.261.1/windows/1.3-extensions/vkspec.html#VUID-VkShaderModuleCreateInfo-pCode-01379)

ERROR: [706474367][VUID-VkShaderModuleCreateInfo-pCode-01379] : Validation Error: [ VUID-VkShaderModuleCreateInfo-pCode-01379 ] | MessageID = 0x2a1bf17f | SPIR-V module not valid: Invalid SPIR-V binary version 1.5 for target environment SPIR-V 1.4 (under Vulkan 1.1 semantics). The Vulkan spec states: If pCode is a pointer to GLSL code, it must be valid GLSL code written to the GL_KHR_vulkan_glsl GLSL extension specification (https://vulkan.lunarg.com/doc/view/1.3.261.1/windows/1.3-extensions/vkspec.html#VUID-VkShaderModuleCreateInfo-pCode-01379)

ERROR: [706474367][VUID-VkShaderModuleCreateInfo-pCode-01379] : Validation Error: [ VUID-VkShaderModuleCreateInfo-pCode-01379 ] | MessageID = 0x2a1bf17f | SPIR-V module not valid: Invalid SPIR-V binary version 1.5 for target environment SPIR-V 1.4 (under Vulkan 1.1 semantics). The Vulkan spec states: If pCode is a pointer to GLSL code, it must be valid GLSL code written to the GL_KHR_vulkan_glsl GLSL extension specification (https://vulkan.lunarg.com/doc/view/1.3.261.1/windows/1.3-extensions/vkspec.html#VUID-VkShaderModuleCreateInfo-pCode-01379)

ERROR: [1132206547][VUID-VkPipelineShaderStageCreateInfo-pSpecializationInfo-06849] : Validation Error: [ VUID-VkPipelineShaderStageCreateInfo-pSpecializationInfo-06849 ] | MessageID = 0x437c19d3 | vkCreateRayTracingPipelinesKHR(): pCreateInfos[0] After specialization was applied, VkShaderModule 0x5011aa0000000066[] does not contain valid spirv for stage VK_SHADER_STAGE_RAYGEN_BIT_KHR. The Vulkan spec states: If a shader module identifier is not specified, the shader code used by the pipeline must be valid as described by the Khronos SPIR-V Specification after applying the specializations provided in pSpecializationInfo, if any, and then converting all specialization constants into fixed constants (https://vulkan.lunarg.com/doc/view/1.3.261.1/windows/1.3-extensions/vkspec.html#VUID-VkPipelineShaderStageCreateInfo-pSpecializationInfo-06849)

ERROR: [-507995293][VUID-vkCmdBindDescriptorSets-pDescriptorSets-00358] : Validation Error: [ VUID-vkCmdBindDescriptorSets-pDescriptorSets-00358 ] Object 0: handle = 0x612f93000000004e, type = VK_OBJECT_TYPE_DESCRIPTOR_SET; | MessageID = 0xe1b89b63 | vkCmdBindDescriptorSets(): descriptorSet #1 being bound is not compatible with overlapping descriptorSetLayout at index 1 of VkPipelineLayout 0x5dbcf90000000065[] due to: Binding 0 for VkDescriptorSetLayout 0x9f58380000000064[] from pipeline layout has stageFlags VK_SHADER_STAGE_RAYGEN_BIT_KHR|VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR but binding 0 for VkDescriptorSetLayout 0x73a850000000004d[], which is bound, has stageFlags VK_SHADER_STAGE_FRAGMENT_BIT. The Vulkan spec states: Each element of pDescriptorSets must have been allocated with a VkDescriptorSetLayout that matches (is the same as, or identically defined as) the VkDescriptorSetLayout at set n in layout, where n is the sum of firstSet and the index into pDescriptorSets (https://vulkan.lunarg.com/doc/view/1.3.261.1/windows/1.3-extensions/vkspec.html#VUID-vkCmdBindDescriptorSets-pDescriptorSets-00358)

ERROR: [387543851][VUID-vkCmdCopyImageToBuffer-srcImageLayout-00189] : Validation Error: [ VUID-vkCmdCopyImageToBuffer-srcImageLayout-00189 ] Object 0: handle = 0x1f51f40a150, type = VK_OBJECT_TYPE_COMMAND_BUFFER; Object 1: handle = 0x421a0f0000000074, type = VK_OBJECT_TYPE_IMAGE; | MessageID = 0x1719732b | vkCmdCopyImageToBuffer: Cannot use VkImage 0x421a0f0000000074[] (layer=0 mip=0) with specific layout VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL that doesn't match the previous known layout VK_IMAGE_LAYOUT_GENERAL. The Vulkan spec states: srcImageLayout must specify the layout of the image subresources of srcImage specified in pRegions at the time this command is executed on a VkDevice (https://vulkan.lunarg.com/doc/view/1.3.261.1/windows/1.3-extensions/vkspec.html#VUID-vkCmdCopyImageToBuffer-srcImageLayout-00189)

ERROR: [455308668][VUID-vkCmdPipelineBarrier-commandBuffer-parameter] : Validation Error: [ VUID-vkCmdPipelineBarrier-commandBuffer-parameter ] Object 0: handle = 0x1f50c70d820, type = VK_OBJECT_TYPE_INSTANCE; | MessageID = 0x1b23757c | vkCmdPipelineBarrier(): Invalid VkCommandBuffer Object 0x1f51f40a150. The Vulkan spec states: commandBuffer must be a valid VkCommandBuffer handle (https://vulkan.lunarg.com/doc/view/1.3.261.1/windows/1.3-extensions/vkspec.html#VUID-vkCmdPipelineBarrier-commandBuffer-parameter)
</code></pre>
<p>Any help is much appreciated.</p>

CC BY-SA 4.0
2024-02-12T07:46:43.540Z
Judging by the validation layer output, you have quite a bit of clean up work to do. It's hard to see from that, but I believe the very last layer message relates to your problem, there seems to be something off with your command buffer, though with the source code given I have no way to say what may be not working. If you add code to set debug names with `vkSetDebugUtilsObjectNameEXT`, it would be a bit easier to interpret the layer messages, as they add those names.
Perhaps also have a look with RenderDoc, see if that gives you more information.
Tare
CC BY-SA 4.0
2024-02-12T15:59:30.353Z
Hi @Tare, thank you for your input. Do you know, should I be using an image memory barrier instead of a buffer memory barrier?
shawn_halayka
CC BY-SA 4.0
2024-02-12T20:07:00.900Z
Sorry, but I don't know if it is "illegal" - but if it were, I'd expect the validation layers to throw an error. You could try to do it without a memory barrier and put a few "vkDeviceWaitIdle` before attempting to copy. In one of my projects I use `vkCmdCopyBufferToImage`, but I don't flush like you do. Instead, I use the `beginSingleTimeCommands` technique from the tutorial, see: https://vulkan-tutorial.com/Texture_mapping/Images (i.e. submit to a queue and then wait for the queue to finish with `vkQueueWaitIdle`). Inefficient to wait this way, but perhaps try for testing
Tare
<c++><vulkan>
Vulkan memcpy from image works, but memcpy to image not working
shawn_halayka
# Vulkan memcpy from image works, but memcpy to image not working

(Asked by: username_0 on 2024-02-11)

Using Vulkan, I am reading from an image to a vector of unsigned char. It works great.

```
vkCmdTraceRaysKHR(
    screenshotCmdBuffer,
    &shaderBindingTables.raygen.stridedDeviceAddressRegion,
    &shaderBindingTables.miss.stridedDeviceAddressRegion,
    &shaderBindingTables.hit.stridedDeviceAddressRegion,
    &emptySbtEntry,
    size_x,
    size_y,
    1);

vks::tools::setImageLayout(
    screenshotCmdBuffer,
    screenshotStorageImage.image,
    VK_IMAGE_LAYOUT_GENERAL,
    VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
    subresourceRange);

VkBufferImageCopy copyRegion{};
copyRegion.bufferOffset = 0;
copyRegion.bufferRowLength = 0;
copyRegion.bufferImageHeight = 0;

copyRegion.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
copyRegion.imageSubresource.mipLevel = 0;
copyRegion.imageSubresource.baseArrayLayer = 0;
copyRegion.imageSubresource.layerCount = 1;

copyRegion.imageOffset = { 0, 0, 0 };
copyRegion.imageExtent.width = size_x;
copyRegion.imageExtent.height = size_y;
copyRegion.imageExtent.depth = 1;

vkCmdCopyImageToBuffer(screenshotCmdBuffer, screenshotStorageImage.image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, screenshotStagingBuffer.buffer, 1, &copyRegion);

VkBufferMemoryBarrier barrier = {};
barrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER;
barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
barrier.dstAccessMask = VK_ACCESS_HOST_READ_BIT;
barrier.buffer = screenshotStagingBuffer.buffer;
barrier.size = screenshotStagingBuffer.size;

vkCmdPipelineBarrier(
    screenshotCmdBuffer,
    VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT,
    0,
    0, nullptr,
    1, &barrier,
    0, nullptr
);

vulkanDevice->flushCommandBuffer(screenshotCmdBuffer, queue);

memcpy(&fbpixels[0], screenshotStagingBuffer.mapped, size);

```

How would I go about writing from a vector of unsigned char to an image?

This is a code that I've been trying, but it does not work:

```
memcpy(screenshotStagingBuffer.mapped, &uc_output_data[0], size);

VkImageSubresourceRange subresourceRange = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 };

vks::tools::setImageLayout(
    screenshotCmdBuffer,
    screenshotStorageImage.image,
    VK_IMAGE_LAYOUT_GENERAL,
    VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
    subresourceRange);

VkBufferImageCopy copyRegion{};
copyRegion.bufferOffset = 0;
copyRegion.bufferRowLength = 0;
copyRegion.bufferImageHeight = 0;

copyRegion.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
copyRegion.imageSubresource.mipLevel = 0;
copyRegion.imageSubresource.baseArrayLayer = 0;
copyRegion.imageSubresource.layerCount = 1;

copyRegion.imageOffset = { 0, 0, 0 };
copyRegion.imageExtent.width = size_x;
copyRegion.imageExtent.height = size_y;
copyRegion.imageExtent.depth = 1;

vkCmdCopyBufferToImage(
    screenshotCmdBuffer,
    screenshotStagingBuffer.buffer,
    screenshotStorageImage.image,
    VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
    1,
    &copyRegion);

VkBufferMemoryBarrier barrier = {};
barrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER;
barrier.srcAccessMask = VK_ACCESS_HOST_READ_BIT;
barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
barrier.buffer = screenshotStagingBuffer.buffer;
barrier.size = screenshotStagingBuffer.size;

vkCmdPipelineBarrier(
    screenshotCmdBuffer,
    VK_PIPELINE_STAGE_HOST_BIT,
    VK_PIPELINE_STAGE_TRANSFER_BIT,
    0,
    0, nullptr,
    1, &barrier,
    0, nullptr);

vulkanDevice->flushCommandBuffer(screenshotCmdBuffer, queue);

```

Should I be using an image memory barrier instead of a buffer memory barrier?

The validation layers says that:

```
ERROR: [1458672316][VUID-VkSamplerCreateInfo-anisotropyEnable-01070] : Validation Error: [ VUID-VkSamplerCreateInfo-anisotropyEnable-01070 ] | MessageID = 0x56f192bc | vkCreateSampler(): Anisotropic sampling feature is not enabled, pCreateInfo->anisotropyEnable must be VK_FALSE. The Vulkan spec states: If the samplerAnisotropy feature is not enabled, anisotropyEnable must be VK_FALSE (https://vulkan.lunarg.com/doc/view/1.3.261.1/windows/1.3-extensions/vkspec.html#VUID-VkSamplerCreateInfo-anisotropyEnable-01070)

ERROR: [1458672316][VUID-VkSamplerCreateInfo-anisotropyEnable-01070] : Validation Error: [ VUID-VkSamplerCreateInfo-anisotropyEnable-01070 ] | MessageID = 0x56f192bc | vkCreateSampler(): Anisotropic sampling feature is not enabled, pCreateInfo->anisotropyEnable must be VK_FALSE. The Vulkan spec states: If the samplerAnisotropy feature is not enabled, anisotropyEnable must be VK_FALSE (https://vulkan.lunarg.com/doc/view/1.3.261.1/windows/1.3-extensions/vkspec.html#VUID-VkSamplerCreateInfo-anisotropyEnable-01070)

ERROR: [706474367][VUID-VkShaderModuleCreateInfo-pCode-01379] : Validation Error: [ VUID-VkShaderModuleCreateInfo-pCode-01379 ] | MessageID = 0x2a1bf17f | SPIR-V module not valid: Invalid SPIR-V binary version 1.5 for target environment SPIR-V 1.4 (under Vulkan 1.1 semantics). The Vulkan spec states: If pCode is a pointer to GLSL code, it must be valid GLSL code written to the GL_KHR_vulkan_glsl GLSL extension specification (https://vulkan.lunarg.com/doc/view/1.3.261.1/windows/1.3-extensions/vkspec.html#VUID-VkShaderModuleCreateInfo-pCode-01379)

ERROR: [706474367][VUID-VkShaderModuleCreateInfo-pCode-01379] : Validation Error: [ VUID-VkShaderModuleCreateInfo-pCode-01379 ] | MessageID = 0x2a1bf17f | SPIR-V module not valid: Invalid SPIR-V binary version 1.5 for target environment SPIR-V 1.4 (under Vulkan 1.1 semantics). The Vulkan spec states: If pCode is a pointer to GLSL code, it must be valid GLSL code written to the GL_KHR_vulkan_glsl GLSL extension specification (https://vulkan.lunarg.com/doc/view/1.3.261.1/windows/1.3-extensions/vkspec.html#VUID-VkShaderModuleCreateInfo-pCode-01379)

ERROR: [706474367][VUID-VkShaderModuleCreateInfo-pCode-01379] : Validation Error: [ VUID-VkShaderModuleCreateInfo-pCode-01379 ] | MessageID = 0x2a1bf17f | SPIR-V module not valid: Invalid SPIR-V binary version 1.5 for target environment SPIR-V 1.4 (under Vulkan 1.1 semantics). The Vulkan spec states: If pCode is a pointer to GLSL code, it must be valid GLSL code written to the GL_KHR_vulkan_glsl GLSL extension specification (https://vulkan.lunarg.com/doc/view/1.3.261.1/windows/1.3-extensions/vkspec.html#VUID-VkShaderModuleCreateInfo-pCode-01379)

ERROR: [706474367][VUID-VkShaderModuleCreateInfo-pCode-01379] : Validation Error: [ VUID-VkShaderModuleCreateInfo-pCode-01379 ] | MessageID = 0x2a1bf17f | SPIR-V module not valid: Invalid SPIR-V binary version 1.5 for target environment SPIR-V 1.4 (under Vulkan 1.1 semantics). The Vulkan spec states: If pCode is a pointer to GLSL code, it must be valid GLSL code written to the GL_KHR_vulkan_glsl GLSL extension specification (https://vulkan.lunarg.com/doc/view/1.3.261.1/windows/1.3-extensions/vkspec.html#VUID-VkShaderModuleCreateInfo-pCode-01379)

ERROR: [1132206547][VUID-VkPipelineShaderStageCreateInfo-pSpecializationInfo-06849] : Validation Error: [ VUID-VkPipelineShaderStageCreateInfo-pSpecializationInfo-06849 ] | MessageID = 0x437c19d3 | vkCreateRayTracingPipelinesKHR(): pCreateInfos[0] After specialization was applied, VkShaderModule 0x5011aa0000000066[] does not contain valid spirv for stage VK_SHADER_STAGE_RAYGEN_BIT_KHR. The Vulkan spec states: If a shader module identifier is not specified, the shader code used by the pipeline must be valid as described by the Khronos SPIR-V Specification after applying the specializations provided in pSpecializationInfo, if any, and then converting all specialization constants into fixed constants (https://vulkan.lunarg.com/doc/view/1.3.261.1/windows/1.3-extensions/vkspec.html#VUID-VkPipelineShaderStageCreateInfo-pSpecializationInfo-06849)

ERROR: [-507995293][VUID-vkCmdBindDescriptorSets-pDescriptorSets-00358] : Validation Error: [ VUID-vkCmdBindDescriptorSets-pDescriptorSets-00358 ] Object 0: handle = 0x612f93000000004e, type = VK_OBJECT_TYPE_DESCRIPTOR_SET; | MessageID = 0xe1b89b63 | vkCmdBindDescriptorSets(): descriptorSet #1 being bound is not compatible with overlapping descriptorSetLayout at index 1 of VkPipelineLayout 0x5dbcf90000000065[] due to: Binding 0 for VkDescriptorSetLayout 0x9f58380000000064[] from pipeline layout has stageFlags VK_SHADER_STAGE_RAYGEN_BIT_KHR|VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR but binding 0 for VkDescriptorSetLayout 0x73a850000000004d[], which is bound, has stageFlags VK_SHADER_STAGE_FRAGMENT_BIT. The Vulkan spec states: Each element of pDescriptorSets must have been allocated with a VkDescriptorSetLayout that matches (is the same as, or identically defined as) the VkDescriptorSetLayout at set n in layout, where n is the sum of firstSet and the index into pDescriptorSets (https://vulkan.lunarg.com/doc/view/1.3.261.1/windows/1.3-extensions/vkspec.html#VUID-vkCmdBindDescriptorSets-pDescriptorSets-00358)

ERROR: [387543851][VUID-vkCmdCopyImageToBuffer-srcImageLayout-00189] : Validation Error: [ VUID-vkCmdCopyImageToBuffer-srcImageLayout-00189 ] Object 0: handle = 0x1f51f40a150, type = VK_OBJECT_TYPE_COMMAND_BUFFER; Object 1: handle = 0x421a0f0000000074, type = VK_OBJECT_TYPE_IMAGE; | MessageID = 0x1719732b | vkCmdCopyImageToBuffer: Cannot use VkImage 0x421a0f0000000074[] (layer=0 mip=0) with specific layout VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL that doesn't match the previous known layout VK_IMAGE_LAYOUT_GENERAL. The Vulkan spec states: srcImageLayout must specify the layout of the image subresources of srcImage specified in pRegions at the time this command is executed on a VkDevice (https://vulkan.lunarg.com/doc/view/1.3.261.1/windows/1.3-extensions/vkspec.html#VUID-vkCmdCopyImageToBuffer-srcImageLayout-00189)

ERROR: [455308668][VUID-vkCmdPipelineBarrier-commandBuffer-parameter] : Validation Error: [ VUID-vkCmdPipelineBarrier-commandBuffer-parameter ] Object 0: handle = 0x1f50c70d820, type = VK_OBJECT_TYPE_INSTANCE; | MessageID = 0x1b23757c | vkCmdPipelineBarrier(): Invalid VkCommandBuffer Object 0x1f51f40a150. The Vulkan spec states: commandBuffer must be a valid VkCommandBuffer handle (https://vulkan.lunarg.com/doc/view/1.3.261.1/windows/1.3-extensions/vkspec.html#VUID-vkCmdPipelineBarrier-commandBuffer-parameter)

```

Any help is much appreciated.

**Tags:** c++, vulkan

> **Comments:**
> **username_1**: Judging by the validation layer output, you have quite a bit of clean up work to do. It's hard to see from that, but I believe the very last layer message relates to your problem, there seems to be something off with your command buffer, though with the source code given I have no way to say what may be not working. If you add code to set debug names with `vkSetDebugUtilsObjectNameEXT`, it would be a bit easier to interpret the layer messages, as they add those names. Perhaps also have a look with RenderDoc, see if that gives you more information.  
> **username_0**: Hi @username_1, thank you for your input. Do you know, should I be using an image memory barrier instead of a buffer memory barrier?  
> **username_1**: Sorry, but I don't know if it is "illegal" - but if it were, I'd expect the validation layers to throw an error. You could try to do it without a memory barrier and put a few "vkDeviceWaitIdle` before attempting to copy. In one of my projects I use `vkCmdCopyBufferToImage`, but I don't flush like you do. Instead, I use the `beginSingleTimeCommands` technique from the tutorial, see: https://vulkan-tutorial.com/Texture_mapping/Images (i.e. submit to a queue and then wait for the queue to finish with `vkQueueWaitIdle`). Inefficient to wait this way, but perhaps try for testing  

---

## 1 answers

### Answer by username_0 on 2024-02-12. Score: 0

I was not creating a command buffer properly. I added one line pertaining to the screenshot command buffer, and it all works now, using an image memory barrier:

```
if (num_cams_wide == 1)
{
    // This is the line that I added to make it all work...
    VkCommandBuffer screenshotCmdBuffer = vulkanDevice->createCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY, true);

    memcpy(screenshotStagingBuffer.mapped, &uc_output_data[0], size);

    VkImageSubresourceRange subresourceRange = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 };

    vks::tools::setImageLayout(
        screenshotCmdBuffer,
        screenshotStorageImage.image,
        VK_IMAGE_LAYOUT_UNDEFINED,
        VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
        subresourceRange);

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

    VkImageMemoryBarrier imageMemoryBarrier;
    imageMemoryBarrier.image = screenshotStorageImage.image;
    imageMemoryBarrier.subresourceRange = subresourceRange;
    imageMemoryBarrier.srcAccessMask = VK_ACCESS_HOST_READ_BIT;
    imageMemoryBarrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
    imageMemoryBarrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
    imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
    imageMemoryBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;

    vkCmdCopyBufferToImage(
        screenshotCmdBuffer,
        screenshotStagingBuffer.buffer,
        screenshotStorageImage.image,
        VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
        1,
        &copyRegion);

    vkCmdPipelineBarrier(
        screenshotCmdBuffer,
        VK_PIPELINE_STAGE_HOST_BIT,
        VK_PIPELINE_STAGE_TRANSFER_BIT,
        0,
        0, nullptr,
        0, nullptr,
        1, &imageMemoryBarrier);

    vulkanDevice->flushCommandBuffer(screenshotCmdBuffer, queue);
}

```

The results are a denoised on screen image:

[![enter image description here](https://i.sstatic.net/JvDIv.png)](https://i.sstatic.net/JvDIv.png)

> **Comments:**
> **username_1**: Great that you could find a solution. Please mark your answer as accepted  

---

