You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
It should have the same resolution as the color attachment, defined by the swap chain extent, an image usage appropriate for a depth attachment, optimal tiling and device local memory.
158
162
The only question is: what is the right format for a depth image?
159
-
The format must contain a depth component, indicated by `_D??_` in the `VK_FORMAT_`.
163
+
The format must contain a depth component, indicated by `_D??_` in the `vk::Format`.
160
164
161
165
Unlike the texture image, we don't necessarily need a specific format, because we won't be directly accessing the texels from the program.
162
166
It just needs to have a reasonable accuracy, at least 24 bits is common in real-world applications.
163
167
There are several formats that fit this requirement:
164
168
165
-
* `VK_FORMAT_D32_SFLOAT`: 32-bit float for depth
166
-
* `VK_FORMAT_D32_SFLOAT_S8_UINT`: 32-bit signed float for depth and 8 bit stencil component
167
-
* `VK_FORMAT_D24_UNORM_S8_UINT`: 24-bit float for depth and 8 bit stencil component
169
+
* `vk::Format::eD32Sfloat`: 32-bit float for depth
170
+
* `vk::Format::eD32SfloatS8Uint`: 32-bit signed float for depth and 8 bit stencil component
171
+
* `vk::Format::eD24UnormS8Uint`: 24-bit float for depth and 8 bit stencil component
168
172
169
173
The stencil component is used for https://en.wikipedia.org/wiki/Stencil_buffer[stencil tests], which is an additional test that can be combined with depth testing.
170
174
We'll look at this in a future chapter.
171
175
172
-
We could simply go for the `VK_FORMAT_D32_SFLOAT` format, because support for it is extremely common (see the hardware database), but it's nice to add some extra flexibility to our application where possible.
176
+
We could simply go for the `vk::Format::eD32Sfloat` format, because support for it is extremely common (see the hardware database), but it's nice to add some extra flexibility to our application where possible.
173
177
We're going to write a function `findSupportedFormat` that takes a list of candidate formats in order from most desirable to least desirable, and checks which is the first one that is supported:
However, the `createImageView` function currently assumes that the subresource is always the `VK_IMAGE_ASPECT_COLOR_BIT`, so we will need to turn that field into a parameter:
274
+
However, the `createImageView` function currently assumes that the subresource is always the `vk::ImageAspectFlagBits::eColor`, so we will need to turn that field into a parameter:
271
275
272
276
[,c++]
273
277
----
274
278
vk::raii::ImageView createImageView(vk::raii::Image& image, vk::Format format, vk::ImageAspectFlags aspectFlags) {
Although we're not using the stencil component, we do need to include it in the layout transitions of the depth image.
303
+
=== Clear values
325
304
326
-
Finally, add the correct access masks and pipeline stages:
305
+
Because we now have multiple attachments that will be cleared to `vk::AttachmentLoadOp::eClear` (color and depth), we also need to specify multiple clear values.
306
+
Go to `recordCommandBuffer` and create and add an additional `vk::ClearValue` variable called `clearDepth`:
327
307
328
308
[,c++]
329
309
----
330
-
if (oldLayout == VK_IMAGE_LAYOUT_UNDEFINED && newLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) {
The depth buffer will be read from to perform depth tests to see if a fragment is visible, and will be written to when a new fragment is drawn.
354
-
The reading happens in the `VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT` stage and the writing in the `VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT`.
355
-
You should pick the earliest pipeline stage that matches the specified operations, so that it is ready for usage as depth attachment when it needs to be.
314
+
The range of depths in the depth buffer is `0.0` to `1.0` in Vulkan, where `1.0` lies at the far view plane and `0.0` at the near view plane.
315
+
The initial value at each point in the depth buffer should be the furthest possible depth, which is `1.0`.
356
316
357
-
== Render pass
317
+
=== Dynamic rendering
358
318
359
-
We're now going to modify `createRenderPass` to include a depth attachment.
360
-
First specify the `VkAttachmentDescription`:
319
+
Now that we have our depth image set up, we need to make use of it in `recordCommandBuffer`.
320
+
This will be part of dynamic rendering and is similar to setting up our color output image.
Just like the color attachment, the depth attachment needs to be in the correct layout for the intended use case. For this we need to issue an additional barriers to ensure that the depth image can be used as a depth attachment during rendering.
346
+
The depth image is first accessed in the early fragment test pipeline stage and because we have a load operation that _clears_, we should specify the access mask for writes.
394
347
395
-
Next, update the `VkSubpassDependency` struct to refer to both attachments.
348
+
As we now deal with an additional image type (depth), first add a new argument to the `transition_image_layout` function for the image aspect:
Finally, we need to extend our subpass dependencies to make sure that there is no conflict between the transitioning of the depth image and it being cleared as part of its load operation.
408
-
The depth image is first accessed in the early fragment test pipeline stage and because we have a load operation that _clears_, we should specify the access mask for writes.
409
-
410
-
== Framebuffer
411
-
412
-
The next step is to modify the framebuffer creation to bind the depth image to the depth attachment.
413
-
Go to `createFramebuffers` and specify the depth image view as second attachment:
367
+
Now add new image layout transition at the start of the command buffer in `recordCommandBuffer`:
The color attachment differs for every swap chain image, but the same depth image can be used by all of them because only a single subpass is running at the same time due to our semaphores.
388
+
Unlike as with the color image we don't need multiple barriers here. As we don't care for the contents of the depth attachment once the frame is finished, we can always translate from `k::ImageLayout::eUndefined`. What's special about this layout, is the fact that you can always use it as a source without having to care what happens before.
422
389
423
-
You'll also need to move the call to `createFramebuffers` to make sure that it is called after the depth image view has actually been created:
390
+
Also make sure you adjust all other calls to the `transition_image_layout` function call to pass the correct image aspect:
424
391
425
392
[,c++]
426
393
----
427
-
void initVulkan() {
428
-
...
429
-
createDepthResources();
430
-
createFramebuffers();
394
+
// Before starting rendering, transition the swapchain image to COLOR_ATTACHMENT_OPTIMAL
395
+
transition_image_layout(
431
396
...
432
-
}
397
+
// Also need to specify this for color images
398
+
vk::ImageAspectFlagBits::eColor);
433
399
----
434
400
435
-
== Clear values
401
+
== Depth and stencil state
436
402
437
-
Because we now have multiple attachments with `VK_ATTACHMENT_LOAD_OP_CLEAR`, we also need to specify multiple clear values.
438
-
Go to `recordCommandBuffer` and create an array of `VkClearValue` structs:
403
+
The depth attachment is ready to be used now, but depth testing still needs to be enabled in the graphics pipeline.
404
+
It is configured through the `PipelineDepthStencilStateCreateInfo` struct:
The range of depths in the depth buffer is `0.0` to `1.0` in Vulkan, where `1.0` lies at the far view plane and `0.0` at the near view plane.
447
-
The initial value at each point in the depth buffer should be the furthest possible depth, which is `1.0`.
448
-
449
-
Note that the order of `clearValues` should be identical to the order of your attachments.
450
-
451
-
== Depth and stencil state
452
-
453
-
The depth attachment is ready to be used now, but depth testing still needs to be enabled in the graphics pipeline.
454
-
It is configured through the `VkPipelineDepthStencilStateCreateInfo` struct:
455
-
456
416
The `depthTestEnable` field specifies if the depth of new fragments should be compared to the depth buffer to see if they should be discarded.
457
417
The `depthWriteEnable` field specifies if the new depth of fragments that pass the depth test should actually be written to the depth buffer.
458
418
@@ -466,8 +426,19 @@ We won't be using this functionality.
466
426
The last three fields configure stencil buffer operations, which we also won't be using in this tutorial.
467
427
If you want to use these operations, then you will have to make sure that the format of the depth/stencil image contains a stencil component.
468
428
469
-
Update the `VkGraphicsPipelineCreateInfo` struct to reference the depth stencil state we just filled in.
470
-
A depth stencil state must always be specified if the render pass contains a depth stencil attachment.
429
+
A depth stencil state must always be specified if the dynamic rendering setup contains a depth stencil attachment:
430
+
431
+
Update the `pipelineCreateInfoChain` structure chain to reference the depth stencil state we just filled in and also add a reference to the depth format we're using:
0 commit comments