• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright (c) 2020-2024 Huawei Technologies Co. Ltd.
2//
3// SPDX-License-Identifier: CC-BY-4.0
4
5include::{generated}/meta/{refprefix}VK_HUAWEI_subpass_shading.adoc[]
6
7=== Other Extension Metadata
8
9*Last Modified Date*::
10    2021-06-01
11*Interactions and External Dependencies*::
12  - This extension provides API support for
13    {GLSLregistry}/huawei/GLSL_HUAWEI_subpass_shading.txt[`GL_HUAWEI_subpass_shading`].
14*Contributors*::
15  - Hueilong Wang
16  - Juntao Li, Huawei
17  - Renmiao Lu, Huawei
18  - Pan Gao, Huawei
19
20=== Description
21
22This extension allows applications to execute a subpass shading pipeline in
23a subpass of a render pass in order to save memory bandwidth for algorithms
24like tile-based deferred rendering and forward plus.
25A subpass shading pipeline is a pipeline with the compute pipeline ability,
26allowed to read values from input attachments, and only allowed to be
27dispatched inside a stand-alone subpass.
28Its work dimension is defined by the render pass's render area size.
29Its workgroup size (width, height) shall be a power-of-two number in width
30or height, with minimum value from 8, and maximum value shall be decided
31from the render pass attachments and sample counts but depends on
32implementation.
33
34The code:GlobalInvocationId.xy of a subpass shading pipeline is equal to the
35code:FragCoord.xy of a graphic pipeline in the same render pass subtracted
36the <<VkRect2D,pname:offset>> of the
37slink:VkRenderPassBeginInfo::pname:renderArea.
38code:GlobalInvocationId.z is mapped to the Layer if
39`apiext:VK_EXT_shader_viewport_index_layer` is supported.
40The code:GlobalInvocationId.xy is equal to the index of the local workgroup
41multiplied by the size of the local workgroup plus the
42code:LocalInvocationId and the <<VkRect2D,pname:offset>> of the
43slink:VkRenderPassBeginInfo::pname:renderArea.
44
45This extension allows a subpass's pipeline bind point to be
46ename:VK_PIPELINE_BIND_POINT_SUBPASS_SHADING_HUAWEI.
47
48include::{generated}/interfaces/VK_HUAWEI_subpass_shading.adoc[]
49
50
51=== Sample Code
52
53Example of subpass shading in a GLSL shader
54
55[source,c]
56----
57#extension GL_HUAWEI_subpass_shading: enable
58#extension GL_KHR_shader_subgroup_arithmetic: enable
59
60layout(constant_id = 0) const uint tileWidth = 8;
61layout(constant_id = 1) const uint tileHeight = 8;
62layout(local_size_x_id = 0, local_size_y_id = 1, local_size_z = 1) in;
63layout(set=0, binding=0, input_attachment_index=0) uniform subpassInput depth;
64
65void main()
66{
67  float d = subpassLoad(depth).x;
68  float minD = subgroupMin(d);
69  float maxD = subgroupMax(d);
70}
71----
72
73Example of subpass shading dispatching in a subpass
74
75[source,c]
76----
77vkCmdNextSubpass(commandBuffer, VK_SUBPASS_CONTENTS_INLINE);
78vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_SUBPASS_SHADING_HUAWEI, subpassShadingPipeline);
79vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_SUBPASS_SHADING_HUAWEI, subpassShadingPipelineLayout,
80  firstSet, descriptorSetCount, pDescriptorSets, dynamicOffsetCount, pDynamicOffsets);
81vkCmdSubpassShadingHUAWEI(commandBuffer)
82vkCmdEndRenderPass(commandBuffer);
83----
84
85Example of subpass shading render pass creation
86
87[source,c]
88----
89VkAttachmentDescription2 attachments[] = {
90  {
91    VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2, NULL,
92    0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT,
93    VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_STORE_OP_DONT_CARE,
94    VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_LOAD_OP_DONT_CARE,
95    VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
96  },
97  {
98    VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2, NULL,
99    0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT,
100    VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_STORE_OP_DONT_CARE,
101    VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_LOAD_OP_DONT_CARE,
102    VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
103  },
104  {
105    VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2, NULL,
106    0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT,
107    VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_STORE_OP_DONT_CARE,
108    VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_LOAD_OP_DONT_CARE,
109    VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
110  },
111  {
112    VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2, NULL,
113    0, VK_FORMAT_D24_UNORM_S8_UINT, VK_SAMPLE_COUNT_1_BIT,
114    VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_STORE_OP_DONT_CARE,
115    VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_LOAD_OP_DONT_CARE,
116    VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
117  },
118  {
119    VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2, NULL,
120    0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT,
121    VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_STORE_OP_STORE,
122    VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_LOAD_OP_DONT_CARE,
123    VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
124  }
125};
126
127VkAttachmentReference2 gBufferAttachmentReferences[] = {
128  { VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2, NULL, 0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_ASPECT_COLOR_BIT },
129  { VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2, NULL, 1, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_ASPECT_COLOR_BIT },
130  { VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2, NULL, 2, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_ASPECT_COLOR_BIT }
131};
132VkAttachmentReference2 gBufferDepthStencilAttachmentReferences =
133  { VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2, NULL, 3, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_ASPECT_DEPTH_BIT|VK_IMAGE_ASPECT_STENCIL_BIT };
134VkAttachmentReference2 depthInputAttachmentReferences[] = {
135  { VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2, NULL, 3, VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL, VK_IMAGE_ASPECT_DEPTH_BIT|VK_IMAGE_ASPECT_STENCIL_BIT };
136};
137VkAttachmentReference2 preserveAttachmentReferences[] = {
138  { VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2, NULL, 0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_ASPECT_COLOR_BIT },
139  { VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2, NULL, 1, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_ASPECT_COLOR_BIT },
140  { VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2, NULL, 2, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_ASPECT_COLOR_BIT },
141  { VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2, NULL, 3, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_ASPECT_DEPTH_BIT|VK_IMAGE_ASPECT_STENCIL_BIT }
142}; // G buffer including depth/stencil
143VkAttachmentReference2 colorAttachmentReferences[] = {
144  { VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2, NULL, 4, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_ASPECT_COLOR_BIT }
145};
146VkAttachmentReference2 resolveAttachmentReference =
147  { VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2, NULL, 4, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_ASPECT_COLOR_BIT };
148
149VkSubpassDescription2 subpasses[] = {
150  {
151    VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2, NULL, 0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0,
152    0, NULL, // input
153    sizeof(gBufferAttachmentReferences)/sizeof(gBufferAttachmentReferences[0]), gBufferAttachmentReferences, // color
154    NULL, &gBufferDepthStencilAttachmentReferences, // resolve & DS
155    0, NULL
156  },
157  {
158    VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2, NULL, 0, VK_PIPELINE_BIND_POINT_SUBPASS_SHADING_HUAWEI , 0,
159    sizeof(depthInputAttachmentReferences)/sizeof(depthInputAttachmentReferences[0]), depthInputAttachmentReferences, // input
160    0, NULL, // color
161    NULL, NULL, // resolve & DS
162    sizeof(preserveAttachmentReferences)/sizeof(preserveAttachmentReferences[0]), preserveAttachmentReferences,
163  },
164  {
165    VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2, NULL, 0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0,
166    sizeof(gBufferAttachmentReferences)/sizeof(gBufferAttachmentReferences[0]), gBufferAttachmentReferences, // input
167    sizeof(colorAttachmentReferences)/sizeof(colorAttachmentReferences[0]), colorAttachmentReferences, // color
168    &resolveAttachmentReference, &gBufferDepthStencilAttachmentReferences, // resolve & DS
169    0, NULL
170  },
171};
172
173VkMemoryBarrier2KHR fragmentToSubpassShading = {
174  VK_STRUCTURE_TYPE_MEMORY_BARRIER_2_KHR, NULL,
175  VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT_KHR, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT|VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
176  VK_PIPELINE_STAGE_2_SUBPASS_SHADER_BIT_HUAWEI, VK_ACCESS_INPUT_ATTACHMENT_READ_BIT
177};
178
179VkMemoryBarrier2KHR subpassShadingToFragment = {
180  VK_STRUCTURE_TYPE_MEMORY_BARRIER_2_KHR, NULL,
181  VK_PIPELINE_STAGE_2_SUBPASS_SHADER_BIT_HUAWEI, VK_ACCESS_SHADER_WRITE_BIT,
182  VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT_KHR, VK_ACCESS_SHADER_READ_BIT
183};
184
185VkSubpassDependency2 dependencies[] = {
186  {
187    VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2, &fragmentToSubpassShading,
188    0, 1,
189    0, 0, 0, 0,
190    0, 0
191  },
192  {
193    VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2, &subpassShadingToFragment,
194    1, 2,
195    0, 0, 0, 0,
196    0, 0
197  },
198};
199
200VkRenderPassCreateInfo2 renderPassCreateInfo = {
201  VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2, NULL, 0,
202    sizeof(attachments)/sizeof(attachments[0]), attachments,
203    sizeof(subpasses)/sizeof(subpasses[0]), subpasses,
204    sizeof(dependencies)/sizeof(dependencies[0]), dependencies,
205    0, NULL
206};
207VKRenderPass renderPass;
208vkCreateRenderPass2(device, &renderPassCreateInfo, NULL, &renderPass);
209----
210
211Example of subpass shading pipeline creation
212
213[source,c]
214----
215VkExtent2D maxWorkgroupSize;
216
217VkSpecializationMapEntry subpassShadingConstantMapEntries[] = {
218  { 0, 0 * sizeof(uint32_t), sizeof(uint32_t) },
219  { 1, 1 * sizeof(uint32_t), sizeof(uint32_t) }
220};
221
222VkSpecializationInfo subpassShadingConstants = {
223  2, subpassShadingConstantMapEntries,
224  sizeof(VkExtent2D), &maxWorkgroupSize
225};
226
227VkSubpassShadingPipelineCreateInfoHUAWEI subpassShadingPipelineCreateInfo {
228  VK_STRUCTURE_TYPE_SUBPASSS_SHADING_PIPELINE_CREATE_INFO_HUAWEI, NULL,
229  renderPass, 1
230};
231
232VkPipelineShaderStageCreateInfo subpassShadingPipelineStageCreateInfo {
233  VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, NULL,
234  0, VK_SHADER_STAGE_SUBPASS_SHADING_BIT_HUAWEI,
235  shaderModule, "main",
236  &subpassShadingConstants
237};
238
239VkComputePipelineCreateInfo subpassShadingComputePipelineCreateInfo = {
240  VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, &subpassShadingPipelineCreateInfo,
241  0, &subpassShadingPipelineStageCreateInfo,
242  pipelineLayout, basePipelineHandle, basePipelineIndex
243};
244
245VKPipeline pipeline;
246
247vkGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI(device, renderPass, &maxWorkgroupSize);
248vkCreateComputePipelines(device, pipelineCache, 1, &subpassShadingComputePipelineCreateInfo, NULL, &pipeline);
249
250----
251
252
253=== Version History
254
255  * Revision 3, 2023-06-19 (Pan Gao)
256  ** Rename `VK_PIPELINE_STAGE_2_SUBPASS_SHADING_BIT_HUAWEI` to
257     `VK_PIPELINE_STAGE_2_SUBPASS_SHADER_BIT_HUAWEI` to better aligned with
258     naming of other pipeline stages
259  * Revision 2, 2021-06-28 (Hueilong Wang)
260  ** Change vkGetSubpassShadingMaxWorkgroupSizeHUAWEI to
261     vkGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI to resolve issue
262     https://github.com/KhronosGroup/Vulkan-Docs/issues/1564[`pub1564`]
263  * Revision 1, 2020-12-15 (Hueilong Wang)
264  ** Initial draft.
265