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