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