@@ -239,7 +239,7 @@ buffer instead of a staging image, so this won't be necessary. We will be using
239239` VK_IMAGE_TILING_OPTIMAL ` for efficient access from the shader.
240240
241241``` c++
242- imageInfo.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED ;
242+ imageInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED ;
243243```
244244
245245There are only two possible values for the ` initialLayout ` of an image:
@@ -249,11 +249,14 @@ transition will discard the texels.
249249* ` VK_IMAGE_LAYOUT_PREINITIALIZED ` : Not usable by the GPU, but the first
250250transition will preserve the texels.
251251
252- An initially undefined layout is suitable for images that will be used as
253- attachments, like color and depth buffers. In that case we don't care about any
254- initial data, because it'll probably be cleared by a render pass before use. If
255- you want to fill it with data, like a texture, then you should use the
256- preinitialized layout.
252+ There are few situations where it is necessary for the texels to be preserved
253+ during the first transition. One example, however, would be if you wanted to use
254+ an image as a staging image in combination with the ` VK_IMAGE_TILING_LINEAR `
255+ layout. In that case, you'd want to upload the texel data to it and then
256+ transition the image to be a transfer source without losing the data. In our
257+ case, however, we're first going to transition the image to be a transfer
258+ destination and then copy texel data to it from a buffer object, so we don't
259+ need this property and can safely use ` VK_IMAGE_LAYOUT_UNDEFINED ` .
257260
258261``` c++
259262imageInfo.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
@@ -337,7 +340,7 @@ void createImage(uint32_t width, uint32_t height, VkFormat format, VkImageTiling
337340 imageInfo.arrayLayers = 1;
338341 imageInfo.format = format;
339342 imageInfo.tiling = tiling;
340- imageInfo.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED ;
343+ imageInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED ;
341344 imageInfo.usage = usage;
342345 imageInfo.samples = VK_SAMPLE_COUNT_1_BIT;
343346 imageInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
@@ -619,13 +622,14 @@ buffer to the texture image. This involves two steps:
619622This is easy to do with the functions we just created:
620623
621624``` c++
622- transitionImageLayout (textureImage, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_LAYOUT_PREINITIALIZED , VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
625+ transitionImageLayout (textureImage, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_LAYOUT_UNDEFINED , VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
623626copyBufferToImage(stagingBuffer, textureImage, static_cast<uint32_t>(texWidth), static_cast<uint32_t>(texHeight));
624627```
625628
626- Both `VK_IMAGE_LAYOUT_PREINITIALIZED` and `VK_IMAGE_LAYOUT_UNDEFINED` are valid
627- values for old layout when transitioning `textureImage`, because we don't care
628- about its contents before the copy operation.
629+ The image was created with the `VK_IMAGE_LAYOUT_UNDEFINED` layout, so that one
630+ should be specified as old layout when transitioning `textureImage`. Remember
631+ that we can do this because we don't care about its contents before performing
632+ the copy operation.
629633
630634To be able to start sampling from the texture image in the shader, we need one
631635last transition to prepare it for shader access:
@@ -640,19 +644,17 @@ If run your application with validation layers enabled now, then you'll see that
640644it complains about the access masks in ` transitionImageLayout ` being invalid.
641645We still need to set those based on the layouts in the transition.
642646
643- There are three transitions we need to handle:
647+ There are two transitions we need to handle:
644648
645- * Preinitialized → transfer source: transfer reads should wait on host writes
646- * Preinitialized → transfer destination: transfer writes should wait on host
647- writes
649+ * Undefined → transfer destination: transfer writes that don't need to wait
648650* Transfer destination → shader reading: shader reads should wait on transfer
649651writes
650652
651653These rules are specified using the following access masks:
652654
653655``` c++
654- if (oldLayout == VK_IMAGE_LAYOUT_PREINITIALIZED && newLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) {
655- barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT ;
656+ if (oldLayout == VK_IMAGE_LAYOUT_UNDEFINED && newLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) {
657+ barrier.srcAccessMask = 0 ;
656658 barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
657659} else if (oldLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL && newLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) {
658660 barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
@@ -664,13 +666,15 @@ if (oldLayout == VK_IMAGE_LAYOUT_PREINITIALIZED && newLayout == VK_IMAGE_LAYOUT_
664666
665667If we need to do more transitions in the future, then we'll extend the function.
666668The application should now run successfully, although there are of course no
667- visual changes yet. One thing to note is that command buffer submission results
668- in implicit ` VK_ACCESS_HOST_WRITE_BIT ` synchronization at the beginning. Since
669- the ` transitionImageLayout ` function executes a command buffer with only a
670- single command, we can use this implicit synchronization and set ` srcAccessMask `
671- to ` 0 ` for the first two types of transitions. It's up to you if you want to be
672- explicit about it or not, but I'm personally not a fan of relying on these
673- OpenGL-like "hidden" operations.
669+ visual changes yet.
670+
671+ One thing to note is that command buffer submission results in implicit
672+ ` VK_ACCESS_HOST_WRITE_BIT ` synchronization at the beginning. Since the
673+ ` transitionImageLayout ` function executes a command buffer with only a single
674+ command, you could use this implicit synchronization and set ` srcAccessMask ` to
675+ ` 0 ` if you ever needed a ` VK_ACCESS_HOST_WRITE_BIT ` dependency in a layout
676+ transition. It's up to you if you want to be explicit about it or not, but I'm
677+ personally not a fan of relying on these OpenGL-like "hidden" operations.
674678
675679There is actually a special type of image layout that supports all operations,
676680` VK_IMAGE_LAYOUT_GENERAL ` . The problem with it, of course, is that it doesn't
0 commit comments