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
Fix typos and improve clarity in compute shader documentation
Corrected grammatical mistakes and improved phrasing for better readability in compute shader documentation. Adjusted links to use `.adoc` extension and reformatted lines for consistency and clarity. No functional changes were made to the content.
```
Copy file name to clipboardExpand all lines: en/11_Compute_Shader.adoc
+25-15Lines changed: 25 additions & 15 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -90,7 +90,7 @@ The biggest differences are that you can alias other buffer types to SSBOs and t
90
90
Going back to the GPU-based particle system, you might now wonder how to deal with vertices being updated (written) by the compute shader and read (drawn) by the vertex shader, as both usages would seemingly require different buffer types.
91
91
92
92
But that's not the case.
93
-
In Vulkan you can specify multiple usages for buffers and images.
93
+
In Vulkan, you can specify multiple usages for buffers and images.
94
94
So for the particle vertex buffer to be used as a vertex buffer (in the graphics pass) and as a storage buffer (in the compute pass), you simply create the buffer with those two usage flags:
The two flags `VK_BUFFER_USAGE_VERTEX_BUFFER_BIT` and `VK_BUFFER_USAGE_STORAGE_BUFFER_BIT` set with `bufferInfo.usage` tell the implementation that we want to use this buffer for two different scenarios: as a vertex buffer in the vertex shader and as a store buffer.
107
107
Note that we also added the `VK_BUFFER_USAGE_TRANSFER_DST_BIT` flag in here so we can transfer data from the host to the GPU.
108
-
This is crucial as we want the shader storage buffer to stay in GPU memory only (`VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT`) we need to to transfer data from the host to this buffer.
108
+
This is crucial as we want the shader storage buffer to stay in GPU memory only (`VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT`) we need to transfer data from the host to this buffer.
109
109
110
-
Here is the same code using using the `createBuffer` helper function:
110
+
Here is the same code using the `createBuffer` helper function:
In the link:03_Drawing_a_triangle/00_Setup/03_Physical_devices_and_queue_families.md#page_Queue-families[physical device and queue families chapter], we have already learned about queue families and how to select a graphics queue family.
202
+
In the link:03_Drawing_a_triangle/00_Setup/03_Physical_devices_and_queue_families.adoc[physical device and queue families chapter],
203
+
we have already learned about queue families and how to select a graphics queue family.
203
204
Compute uses the queue family properties flag bit `VK_QUEUE_COMPUTE_BIT`.
204
205
So if we want to do compute work, we need to get a queue from a queue family that supports compute.
In the `createShaderStorageBuffers` we then clear those vectors to cleanup
270
+
In the `createShaderStorageBuffers` we then clear those vectors to clean up
270
271
any objects already created in their as is our RAII practice.
271
272
272
273
[,c++]
@@ -342,7 +343,7 @@ The only difference is that descriptors need to have the `VK_SHADER_STAGE_COMPUT
342
343
...
343
344
----
344
345
345
-
Note that you can combine shader stages here, so if you want the descriptor to be accessible from the vertex and compute stage, e.g.
346
+
Note that you can combine shader stages here, so if you want the descriptor to be accessible from the vertex and compute stage, e.g.,
346
347
for a uniform buffer with parameters shared across them, you set the bits for both stages:
347
348
348
349
[,c++]
@@ -406,7 +407,7 @@ We need to double the number of `VK_DESCRIPTOR_TYPE_STORAGE_BUFFER` types reques
406
407
== Compute pipelines
407
408
408
409
As compute is not a part of the graphics pipeline, we can't use `vkCreateGraphicsPipelines`.
409
-
Instead we need to create a dedicated compute pipeline with `vkCreateComputePipelines` for running our compute commands.
410
+
Instead, we need to create a dedicated compute pipeline with `vkCreateComputePipelines` for running our compute commands.
410
411
Since a compute pipeline does not touch any of the rasterization state, it has a lot less state than a graphics pipeline:
411
412
412
413
[,c++]
@@ -587,13 +588,20 @@ Synchronization is an important part of Vulkan, even more so when doing compute
587
588
Wrong or lacking synchronization may result in the vertex stage starting to draw (=read) particles while the compute shader hasn't finished updating (=write) them (read-after-write hazard), or the compute shader could start updating particles that are still in use by the vertex part of the pipeline (write-after-read hazard).
588
589
589
590
So we must make sure that those cases don't happen by properly synchronizing the graphics and the compute load.
590
-
There are different ways of doing so, depending on how you submit your compute workload but in our case with two separate submits, we'll be using link:03_Drawing_a_triangle/03_Drawing/02_Rendering_and_presentation.md#page_Semaphores[semaphores] and link:03_Drawing_a_triangle/03_Drawing/02_Rendering_and_presentation.md#page_Fences[fences] to ensure that the vertex shader won't start fetching vertices until the compute shader has finished updating them.
591
+
There are different ways of doing so, depending on how you submit your
592
+
compute workload, but in our case with two separate submits, we'll be using
593
+
link:03_Drawing_a_triangle/03_Drawing/02_Rendering_and_presentation.adoc[semaphores] and
594
+
link:03_Drawing_a_triangle/03_Drawing/02_Rendering_and_presentation.adoc[fences] to ensure that the vertex shader won't start fetching
595
+
vertices until the compute shader has finished updating them.
591
596
592
597
This is necessary as even though the two submits are ordered one-after-another, there is no guarantee that they execute on the GPU in this order.
593
598
Adding in wait and signal semaphores ensures this execution order.
594
599
595
600
So we first add a new set of synchronization primitives for the compute work in `createSyncObjects`.
596
-
The compute fences, just like the graphics fences, are created in the signaled state because otherwise, the first draw would time out while waiting for the fences to be signaled as detailed link:03_Drawing_a_triangle/03_Drawing/02_Rendering_and_presentation.md#page_Waiting-for-the-previous-frame[here]:
601
+
The compute fences, just like the graphics fences, are created in the
602
+
signaled state because otherwise, the first draw would time out while waiting
Similar to the sample in the link:03_Drawing_a_triangle/03_Drawing/02_Rendering_and_presentation.md#page_Semaphores[semaphores chapter], this setup will immediately run the compute shader as we haven't specified any wait semaphores.
646
-
Note, that we're using scoping braces above to ensure that the RAII temporary
653
+
Similar to the sample in the
654
+
link:03_Drawing_a_triangle/03_Drawing/02_Rendering_and_presentation.adoc[semaphore chapter], this setup will immediately run the
655
+
compute shader as we haven't specified any wait semaphores.
656
+
Note that we're using scoping braces above to ensure that the RAII temporary
647
657
variables we use get a chance to clean themselves up between the compute and
648
658
the graphics stage.
649
659
This is fine, as we are waiting for the compute command buffer of the current frame to finish execution before the compute submission with the `vkWaitForFences` command.
@@ -656,7 +666,7 @@ So we also wait on the `imageAvailableSemaphores` on the current frame at the `V
656
666
657
667
== Drawing the particle system
658
668
659
-
Earlier on, we learned that buffers in Vulkan can have multiple use-cases and so we created the shader storage buffer that contains our particles with both the shader storage buffer bit and the vertex buffer bit.
669
+
Earlier on, we learned that buffers in Vulkan can have multiple use-cases, and so we created the shader storage buffer that contains our particles with both the shader storage buffer bit and the vertex buffer bit.
660
670
This means that we can use the shader storage buffer for drawing just as we used "pure" vertex buffers in the previous chapters.
661
671
662
672
We first set up the vertex input state to match our particle structure:
0 commit comments