Skip to content

Commit 4f4395d

Browse files
Add a Descriptor Array chapter (#317)
* Add a Descriptor Array chapter * Update chapters/descriptor_arrays.adoc
1 parent afbf5b2 commit 4f4395d

File tree

10 files changed

+208
-0
lines changed

10 files changed

+208
-0
lines changed

README.adoc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,10 @@ The Vulkan Guide can be built as a single page using `asciidoctor guide.adoc`
190190

191191
// include::{chapters}vertex_input_data_processing.adoc[]
192192

193+
=== xref:{chapters}descriptor_arrays.adoc[Descriptor Arrays]
194+
195+
// include::{chapters}descriptor_arrays.adoc[]
196+
193197
=== xref:{chapters}descriptor_dynamic_offset.adoc[Descriptor Dynamic Offset]
194198

195199
// include::{chapters}descriptor_dynamic_offset.adoc[]

antora/modules/ROOT/nav.adoc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
** xref:{chapters}primitive_topology.adoc[]
4444
** xref:{chapters}mapping_data_to_shaders.adoc[]
4545
*** xref:{chapters}vertex_input_data_processing.adoc[]
46+
*** xref:{chapters}descriptor_arrays.adoc[]
4647
*** xref:{chapters}descriptor_dynamic_offset.adoc[]
4748
*** xref:{chapters}location_component_interface.adoc[]
4849
*** xref:{chapters}push_constants.adoc[]

chapters/descriptor_arrays.adoc

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
// Copyright 2025 The Khronos Group, Inc.
2+
// SPDX-License-Identifier: CC-BY-4.0
3+
4+
ifndef::chapters[:chapters:]
5+
ifndef::images[:images: images/]
6+
7+
[[descriptor-arrays]]
8+
= Descriptor Arrays
9+
10+
This chapter is to help explain about how you can create an array of descriptors.
11+
12+
== Bindings vs Arrays
13+
14+
Inside a single descriptor set there can be multiple bindings. The main advantage of bindings is if you have different types of descriptors in the descriptor set (samplers, uniform buffers, etc).
15+
16+
When you have multiple of the same descriptor type, you might want to use an array of descriptors instead.
17+
18+
As a simple example, if we have 4 `VkBuffer` that we want to turn into 4 different Uniform Buffers, we could represent this as 4 different bindings in the descriptor set:
19+
20+
[source,glsl]
21+
----
22+
layout(set = 0, binding = 0) uniform UBO0 {
23+
uint data_0;
24+
};
25+
layout(set = 0, binding = 1) uniform UBO1 {
26+
uint data_1;
27+
};
28+
layout(set = 0, binding = 2) uniform UBO2 {
29+
uint data_2;
30+
};
31+
layout(set = 0, binding = 3) uniform UBO3 {
32+
uint data_3;
33+
};
34+
----
35+
36+
We could also represent this as an array of 4 descriptors:
37+
38+
[source,glsl]
39+
----
40+
layout(set = 0, binding = 0) uniform UBO0 {
41+
uint data;
42+
} buffers[4];
43+
----
44+
45+
If you have the `runtimeDescriptorArray` feature found in xref:{chapters}extensions/VK_EXT_descriptor_indexing.adoc[VK_EXT_descriptor_indexing] you can also tell the shader the array size will be known at runtime
46+
47+
[source,glsl]
48+
----
49+
layout(set = 0, binding = 0) uniform UBO0 {
50+
uint data;
51+
} buffers[];
52+
----
53+
54+
== Setting up a Descriptor Array
55+
56+
Using the example of
57+
58+
[source,glsl]
59+
----
60+
layout(set = 0, binding = 0) uniform UBO0 {
61+
uint data;
62+
} buffers[4];
63+
----
64+
65+
it is pretty easy to set up. You just need to set your `VkDescriptorSetLayoutBinding::descriptorCount` to `4`.
66+
67+
When you update you have 2 options
68+
69+
1. Use an array of 4 `VkDescriptorBufferInfo` (likely easier way)
70+
71+
[source,c++]
72+
----
73+
VkDescriptorBufferInfo buffer_infos[4];
74+
buffer_infos[0] = {buffer_0, 0, VK_WHOLE_SIZE};
75+
buffer_infos[1] = {buffer_1, 0, VK_WHOLE_SIZE};
76+
buffer_infos[2] = {buffer_2, 0, VK_WHOLE_SIZE};
77+
buffer_infos[3] = {buffer_3, 0, VK_WHOLE_SIZE};
78+
79+
VkWriteDescriptorSet writes;
80+
writes.dstBinding = 0;
81+
writes.dstArrayElement = 0;
82+
writes.descriptorCount = 4; // will consume 4 items in pBufferInfo
83+
writes.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
84+
writes.pBufferInfo = buffer_infos;
85+
----
86+
87+
2. Use an array of 4 `VkWriteDescriptorSet`
88+
89+
[source,c++]
90+
----
91+
VkWriteDescriptorSet writes[4];
92+
writes[0].dstArrayElement = 0; // points which descriptor in the array
93+
writes[0].descriptorCount = 1;
94+
writes[0].pBufferInfo = buffer_info_0;
95+
96+
writes[1].dstArrayElement = 1;
97+
writes[1].descriptorCount = 1;
98+
writes[1].pBufferInfo = buffer_info_1;
99+
100+
writes[2].dstArrayElement = 2;
101+
writes[2].descriptorCount = 1;
102+
writes[2].pBufferInfo = buffer_info_2;
103+
104+
writes[3].dstArrayElement = 3;
105+
writes[3].descriptorCount = 1;
106+
writes[3].pBufferInfo = buffer_info_3;
107+
----
108+
109+
== Consecutive Binding Updates
110+
111+
When updating multiple bindings at once there is a concept of link:https://docs.vulkan.org/spec/latest/chapters/descriptorsets.html#descriptorsets-updates-consecutive[Consecutive Binding Updates in the Vulkan Spec].
112+
113+
The follow is an example to help illustrate how it works. We will have 5 descriptors spread across for 3 different bindings. The shader code is expressed as:
114+
115+
[source,glsl]
116+
----
117+
layout(set = 0, binding = 1) uniform sampler Samplers_A[2];
118+
119+
layout(set = 0, binding = 2) uniform sampler Samplers_B;
120+
121+
layout(set = 0, binding = 6) uniform sampler Samplers_C[2];
122+
----
123+
124+
The API is expressed as:
125+
126+
[source,c++]
127+
----
128+
VkDescriptorSetLayoutBinding sampler_a;
129+
sampler_a.binding = 1;
130+
sampler_a.descriptorCount = 2;
131+
132+
VkDescriptorSetLayoutBinding sampler_b;
133+
sampler_b.binding = 2;
134+
sampler_b.descriptorCount = 1;
135+
136+
VkDescriptorSetLayoutBinding sampler_c;
137+
sampler_c.binding = 6;
138+
sampler_c.descriptorCount = 2;
139+
----
140+
141+
If we try to update the descriptors together, the `VkWriteDescriptorSet` will look like:
142+
143+
[source,c++]
144+
----
145+
VkDescriptorImageInfo image_infos[5];
146+
147+
VkWriteDescriptorSet writes;
148+
writes.dstBinding = 1;
149+
writes.dstArrayElement = 0;
150+
writes.descriptorCount = 5;
151+
writes.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
152+
writes.pImageInfo = image_infos;
153+
----
154+
155+
Here the `VkWriteDescriptorSet::descriptorCount` is `5`. It will set the following:
156+
157+
- `image_infos[0]` to binding 1, index 0
158+
- `image_infos[1]` to binding 1, index 1
159+
- `image_infos[2]` to binding 2, index 0
160+
- `image_infos[3]` to binding 6, index 0
161+
- `image_infos[4]` to binding 6, index 1

guide.adoc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,10 @@ include::{chapters}mapping_data_to_shaders.adoc[]
185185

186186
include::{chapters}vertex_input_data_processing.adoc[]
187187

188+
// === Descriptor Array
189+
190+
include::{chapters}descriptor_arrays.adoc[]
191+
188192
// === Descriptor Dynamic Offset
189193

190194
include::{chapters}descriptor_dynamic_offset.adoc[]

lang/jp/README-jp.adoc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,10 @@ Vulkan Guide は、`asciidoctor guide.adoc` を使って1つのページとし
176176

177177
// include::{chapters}vertex_input_data_processing.adoc[]
178178

179+
=== xref:{chapters}descriptor_arrays.adoc[Descriptor Arrays]
180+
181+
// include::{chapters}descriptor_arrays.adoc[]
182+
179183
=== xref:{chapters}descriptor_dynamic_offset.adoc[ディスクリプタ動的オフセット]
180184

181185
// include::{chapters}descriptor_dynamic_offset.adoc[]
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// Copyright 2025 The Khronos Group, Inc.
2+
// SPDX-License-Identifier: CC-BY-4.0
3+
4+
// Required for both single-page and combined guide xrefs to work
5+
ifndef::chapters[:chapters:]
6+
ifndef::images[:images: images/]
7+
8+
[[descriptor-arrays]]
9+
= Descriptor Arrays
10+
11+
すみません!まだまだ翻訳が必要!

lang/jp/guide.adoc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,10 @@ include::{chapters}mapping_data_to_shaders.adoc[]
178178

179179
include::{chapters}vertex_input_data_processing.adoc[]
180180

181+
// === Descriptor Array
182+
183+
include::{chapters}descriptor_arrays.adoc[]
184+
181185
// === Descriptor Dynamic Offset
182186

183187
include::{chapters}descriptor_dynamic_offset.adoc[]

lang/kor/README-kor.adoc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,10 @@ Vulkan에서 사용하는 특수한 용어에 대한 혼란을 막기 위해 명
191191

192192
// include::{chapters}vertex_input_data_processing.adoc[]
193193

194+
=== xref:{chapters}descriptor_arrays.adoc[Descriptor Arrays]
195+
196+
// include::{chapters}descriptor_arrays.adoc[]
197+
194198
=== xref:{chapters}descriptor_dynamic_offset.adoc[디스크립터 동적 오프셋]
195199

196200
// include::{chapters}descriptor_dynamic_offset.adoc[]
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// Copyright 2025 The Khronos Group, Inc.
2+
// SPDX-License-Identifier: CC-BY-4.0
3+
4+
// Required for both single-page and combined guide xrefs to work
5+
ifndef::chapters[:chapters:]
6+
ifndef::images[:images: images/]
7+
8+
[[descriptor-arrays]]
9+
= Descriptor Arrays
10+
11+
죄송합니다, 아직 번역이 필요합니다.

lang/kor/guide.adoc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,10 @@ include::{chapters}mapping_data_to_shaders.adoc[]
181181

182182
include::{chapters}vertex_input_data_processing.adoc[]
183183

184+
// === Descriptor Array
185+
186+
include::{chapters}descriptor_arrays.adoc[]
187+
184188
// === Descriptor Dynamic Offset
185189

186190
include::{chapters}descriptor_dynamic_offset.adoc[]

0 commit comments

Comments
 (0)