• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2015-2021 The Khronos Group, Inc.
2//
3// SPDX-License-Identifier: CC-BY-4.0
4
5[[fragops]]
6= Fragment Operations
7
8Fragments produced by rasterization go through a number of operations to
9determine whether or how values produced by fragment shading are written to
10the framebuffer.
11
12The following fragment operations adhere to <<primsrast-order,rasterization
13order>>, and are typically performed in this order:
14
15ifdef::VK_EXT_discard_rectangles[]
16  . <<fragops-discard-rectangles,Discard rectangles test>>
17endif::VK_EXT_discard_rectangles[]
18  . <<fragops-scissor,Scissor test>>
19ifdef::VK_NV_scissor_exclusive[]
20  . <<fragops-exclusive-scissor,Exclusive scissor test>>
21endif::VK_NV_scissor_exclusive[]
22  . <<fragops-samplemask,Sample mask test>>
23  . Certain <<fragops-shader,Fragment shading>> operations:
24  ** <<fragops-shader-samplemask, Sample Mask Accesses>>
25  ** <<fragops-shader-depthreplacement, Depth Replacement>>
26ifdef::VK_EXT_shader_stencil_export[]
27  ** <<fragops-shader-stencilrefreplacement, Stencil Reference Replacement>>
28endif::VK_EXT_shader_stencil_export[]
29ifdef::VK_EXT_fragment_shader_interlock[]
30  ** <<fragops-shader-interlock, Interlocked Operations>>
31endif::VK_EXT_fragment_shader_interlock[]
32  . <<fragops-covg, Multisample coverage>>
33  . <<fragops-dbt, Depth bounds test>>
34  . <<fragops-stencil, Stencil test>>
35  . <<fragops-depth, Depth test>>
36ifdef::VK_NV_representative_fragment_test[]
37  . <<fragops-rep-frag-test, Representative fragment test>>
38endif::VK_NV_representative_fragment_test[]
39  . <<fragops-samplecount, Sample counting>>
40ifdef::VK_NV_fragment_coverage_to_color[]
41  . <<fragops-coverage-to-color, Coverage to color>>
42endif::VK_NV_fragment_coverage_to_color[]
43  . <<fragops-coverage-reduction, Coverage reduction>>
44ifdef::VK_NV_framebuffer_mixed_samples[]
45  . <<fragops-coverage-modulation, Coverage modulation>>
46endif::VK_NV_framebuffer_mixed_samples[]
47
48The <<primsrast-multisampling-coverage-mask, coverage mask>> generated by
49rasterization describes the initial coverage of each sample covered by the
50fragment.
51Fragment operations will update the coverage mask to add or subtract
52coverage where appropriate.
53If a fragment operation results in all bits of the coverage mask being `0`,
54the fragment is discarded, and no further operations are performed.
55Fragments can also be programmatically discarded in a fragment shader by
56executing one of
57
58ifdef::VK_KHR_shader_terminate_invocation[]
59  * code:OpTerminateInvocation
60endif::VK_KHR_shader_terminate_invocation[]
61ifdef::VK_EXT_shader_demote_to_helper_invocation[]
62  * code:OpDemoteToHelperInvocationEXT
63endif::VK_EXT_shader_demote_to_helper_invocation[]
64  * code:OpKill.
65
66When one of the fragment operations in this chapter is described as
67"`replacing`" a fragment shader output, that output is replaced
68unconditionally, even if no fragment shader previously wrote to that output.
69
70ifdef::VK_EXT_post_depth_coverage[]
71If the <<fragops-shader, fragment shader>> declares the
72code:PostDepthCoverage execution mode, the <<fragops-samplemask, sample mask
73test>> is instead performed after the <<fragops-depth, depth test>>.
74endif::VK_EXT_post_depth_coverage[]
75
76If the <<fragops-shader, fragment shader>> declares the
77code:EarlyFragmentTests execution mode, <<fragops-shader,fragment shading>>
78and <<fragops-covg, multisample coverage>> operations are instead performed
79after <<fragops-samplecount, sample counting>>.
80
81Once all fragment operations have completed, fragment shader outputs for
82covered color attachment samples pass through <<framebuffer, framebuffer
83operations>>.
84
85
86ifdef::VK_EXT_discard_rectangles[]
87[[fragops-discard-rectangles]]
88== Discard Rectangles Test
89
90The discard rectangle test compares the framebuffer coordinates
91[eq]#(x~f~,y~f~)# of each sample covered by a fragment against a set of
92_discard rectangles_.
93
94Each discard rectangle is defined by a slink:VkRect2D.
95These values are either set by the
96slink:VkPipelineDiscardRectangleStateCreateInfoEXT structure during pipeline
97creation, or dynamically by the flink:vkCmdSetDiscardRectangleEXT command.
98
99A given sample is considered inside a discard rectangle if the [eq]#x~f~# is
100in the range [eq]#[slink:VkRect2D::offset.x, slink:VkRect2D::offset.x {plus}
101slink:VkRect2D::extent.x)#, and [eq]#y~f~# is in the range
102[eq]#[slink:VkRect2D::offset.y, slink:VkRect2D::offset.y {plus}
103slink:VkRect2D::extent.y)#.
104If the test is set to be inclusive, samples that are not inside any of the
105discard rectangles will have their coverage set to `0`.
106If the test is set to be exclusive, samples that are inside any of the
107discard rectangles will have their coverage set to `0`.
108
109If no discard rectangles are specified, the coverage mask is unmodified by
110this operation.
111
112[open,refpage='VkPipelineDiscardRectangleStateCreateInfoEXT',desc='Structure specifying discard rectangle',type='structs']
113--
114The sname:VkPipelineDiscardRectangleStateCreateInfoEXT structure is defined
115as:
116
117include::{generated}/api/structs/VkPipelineDiscardRectangleStateCreateInfoEXT.txt[]
118
119  * pname:sType is the type of this structure.
120  * pname:pNext is `NULL` or a pointer to a structure extending this
121    structure.
122  * pname:flags is reserved for future use.
123  * pname:discardRectangleMode is a elink:VkDiscardRectangleModeEXT value
124    determining whether the discard rectangle test is inclusive or
125    exclusive.
126  * pname:discardRectangleCount is the number of discard rectangles to use.
127  * pname:pDiscardRectangles is a pointer to an array of slink:VkRect2D
128    structures defining discard rectangles.
129
130If the ename:VK_DYNAMIC_STATE_DISCARD_RECTANGLE_EXT dynamic state is enabled
131for a pipeline, the pname:pDiscardRectangles member is ignored.
132
133When this structure is included in the pname:pNext chain of
134slink:VkGraphicsPipelineCreateInfo, it defines parameters of the discard
135rectangle test.
136If this structure is not included in the pname:pNext chain, it is equivalent
137to specifying this structure with a pname:discardRectangleCount of `0`.
138
139.Valid Usage
140****
141  * [[VUID-VkPipelineDiscardRectangleStateCreateInfoEXT-discardRectangleCount-00582]]
142    pname:discardRectangleCount must: be less than or equal to
143    sname:VkPhysicalDeviceDiscardRectanglePropertiesEXT::pname:maxDiscardRectangles
144****
145
146include::{generated}/validity/structs/VkPipelineDiscardRectangleStateCreateInfoEXT.txt[]
147--
148
149[open,refpage='VkPipelineDiscardRectangleStateCreateFlagsEXT',desc='Reserved for future use',type='flags']
150--
151include::{generated}/api/flags/VkPipelineDiscardRectangleStateCreateFlagsEXT.txt[]
152
153tname:VkPipelineDiscardRectangleStateCreateFlagsEXT is a bitmask type for
154setting a mask, but is currently reserved for future use.
155--
156
157[open,refpage='VkDiscardRectangleModeEXT',desc='Specify the discard rectangle mode',type='enums']
158--
159ename:VkDiscardRectangleModeEXT values are:
160
161include::{generated}/api/enums/VkDiscardRectangleModeEXT.txt[]
162
163  * ename:VK_DISCARD_RECTANGLE_MODE_INCLUSIVE_EXT specifies that the discard
164    rectangle test is inclusive.
165  * ename:VK_DISCARD_RECTANGLE_MODE_EXCLUSIVE_EXT specifies that the discard
166    rectangle test is exclusive.
167--
168
169[open,refpage='vkCmdSetDiscardRectangleEXT',desc='Set discard rectangles dynamically for a command buffer',type='protos']
170--
171To <<pipelines-dynamic-state, dynamically set>> the discard rectangles,
172call:
173
174include::{generated}/api/protos/vkCmdSetDiscardRectangleEXT.txt[]
175
176  * pname:commandBuffer is the command buffer into which the command will be
177    recorded.
178  * pname:firstDiscardRectangle is the index of the first discard rectangle
179    whose state is updated by the command.
180  * pname:discardRectangleCount is the number of discard rectangles whose
181    state are updated by the command.
182  * pname:pDiscardRectangles is a pointer to an array of slink:VkRect2D
183    structures specifying discard rectangles.
184
185The discard rectangle taken from element [eq]#i# of pname:pDiscardRectangles
186replace the current state for the discard rectangle at index
187[eq]#pname:firstDiscardRectangle {plus} i#, for [eq]#i# in [eq]#[0,
188pname:discardRectangleCount)#.
189
190This command sets the discard rectangles for subsequent drawing commands
191when the graphics pipeline is created with
192ename:VK_DYNAMIC_STATE_DISCARD_RECTANGLE_EXT set in
193slink:VkPipelineDynamicStateCreateInfo::pname:pDynamicStates.
194Otherwise, this state is specified by the
195slink:VkPipelineDiscardRectangleStateCreateInfoEXT::pname:pDiscardRectangles
196values used to create the currently active pipeline.
197
198.Valid Usage
199****
200  * [[VUID-vkCmdSetDiscardRectangleEXT-firstDiscardRectangle-00585]]
201    The sum of pname:firstDiscardRectangle and pname:discardRectangleCount
202    must: be less than or equal to
203    slink:VkPhysicalDeviceDiscardRectanglePropertiesEXT::pname:maxDiscardRectangles
204  * [[VUID-vkCmdSetDiscardRectangleEXT-x-00587]]
205    The pname:x and pname:y member of pname:offset in each slink:VkRect2D
206    element of pname:pDiscardRectangles must: be greater than or equal to
207    `0`
208  * [[VUID-vkCmdSetDiscardRectangleEXT-offset-00588]]
209    Evaluation of [eq]#(pname:offset.x {plus} pname:extent.width)# in each
210    slink:VkRect2D element of pname:pDiscardRectangles must: not cause a
211    signed integer addition overflow
212  * [[VUID-vkCmdSetDiscardRectangleEXT-offset-00589]]
213    Evaluation of [eq]#(pname:offset.y {plus} pname:extent.height)# in each
214    slink:VkRect2D element of pname:pDiscardRectangles must: not cause a
215    signed integer addition overflow
216ifdef::VK_NV_inherited_viewport_scissor[]
217  * [[VUID-vkCmdSetDiscardRectangleEXT-viewportScissor2D-04788]]
218    If this command is recorded in a secondary command buffer with
219    slink:VkCommandBufferInheritanceViewportScissorInfoNV::pname:viewportScissor2D
220    enabled, then this function must: not be called
221endif::VK_NV_inherited_viewport_scissor[]
222****
223
224include::{generated}/validity/protos/vkCmdSetDiscardRectangleEXT.txt[]
225--
226endif::VK_EXT_discard_rectangles[]
227
228
229[[fragops-scissor]]
230== Scissor Test
231
232The scissor test compares the framebuffer coordinates [eq]#(x~f~,y~f~)# of
233each sample covered by a fragment against a _scissor rectangle_ at the index
234equal to the fragment's <<interfaces-builtin-variables-viewportindex,
235code:ViewportIndex>>.
236
237Each scissor rectangle is defined by a slink:VkRect2D.
238These values are either set by the slink:VkPipelineViewportStateCreateInfo
239structure during pipeline creation, or dynamically by the
240flink:vkCmdSetScissor command.
241
242A given sample is considered inside a scissor rectangle if [eq]#x~f~# is in
243the range [eq]#[slink:VkRect2D::offset.x, slink:VkRect2D::offset.x {plus}
244slink:VkRect2D::extent.x)#, and [eq]#y~f~# is in the range
245[eq]#[slink:VkRect2D::offset.y, slink:VkRect2D::offset.y {plus}
246slink:VkRect2D::extent.y)#.
247Samples with coordinates outside the scissor rectangle at the corresponding
248code:ViewportIndex will have their coverage set to `0`.
249
250ifdef::VK_QCOM_render_pass_transform[]
251If a render pass transform is enabled, the (pname:offset.x and
252pname:offset.y) and (pname:extent.width and pname:extent.height) values are
253transformed as described in <<vertexpostproc-renderpass-transform, render
254pass transform>> before participating in the scissor test.
255endif::VK_QCOM_render_pass_transform[]
256
257[open,refpage='vkCmdSetScissor',desc='Set scissor rectangles dynamically for a command buffer',type='protos']
258--
259To <<pipelines-dynamic-state, dynamically set>> the scissor rectangles,
260call:
261
262include::{generated}/api/protos/vkCmdSetScissor.txt[]
263
264  * pname:commandBuffer is the command buffer into which the command will be
265    recorded.
266  * pname:firstScissor is the index of the first scissor whose state is
267    updated by the command.
268  * pname:scissorCount is the number of scissors whose rectangles are
269    updated by the command.
270  * pname:pScissors is a pointer to an array of slink:VkRect2D structures
271    defining scissor rectangles.
272
273The scissor rectangles taken from element [eq]#i# of pname:pScissors replace
274the current state for the scissor index [eq]#pname:firstScissor {plus} i#,
275for [eq]#i# in [eq]#[0, pname:scissorCount)#.
276
277This command sets the scissor rectangles for subsequent drawing commands
278when the graphics pipeline is created with ename:VK_DYNAMIC_STATE_SCISSOR
279set in slink:VkPipelineDynamicStateCreateInfo::pname:pDynamicStates.
280Otherwise, this state is specified by the
281slink:VkPipelineViewportStateCreateInfo::pname:pScissors values used to
282create the currently active pipeline.
283
284.Valid Usage
285****
286  * [[VUID-vkCmdSetScissor-firstScissor-00592]]
287    The sum of pname:firstScissor and pname:scissorCount must: be between
288    `1` and sname:VkPhysicalDeviceLimits::pname:maxViewports, inclusive
289  * [[VUID-vkCmdSetScissor-firstScissor-00593]]
290    If the <<features-multiViewport,multiple viewports>> feature is not
291    enabled, pname:firstScissor must: be `0`
292  * [[VUID-vkCmdSetScissor-scissorCount-00594]]
293    If the <<features-multiViewport,multiple viewports>> feature is not
294    enabled, pname:scissorCount must: be `1`
295  * [[VUID-vkCmdSetScissor-x-00595]]
296    The pname:x and pname:y members of pname:offset member of any element of
297    pname:pScissors must: be greater than or equal to `0`
298  * [[VUID-vkCmdSetScissor-offset-00596]]
299    Evaluation of [eq]#(pname:offset.x {plus} pname:extent.width)# must: not
300    cause a signed integer addition overflow for any element of
301    pname:pScissors
302  * [[VUID-vkCmdSetScissor-offset-00597]]
303    Evaluation of [eq]#(pname:offset.y {plus} pname:extent.height)# must:
304    not cause a signed integer addition overflow for any element of
305    pname:pScissors
306ifdef::VK_NV_inherited_viewport_scissor[]
307  * [[VUID-vkCmdSetScissor-viewportScissor2D-04789]]
308    If this command is recorded in a secondary command buffer with
309    slink:VkCommandBufferInheritanceViewportScissorInfoNV::pname:viewportScissor2D
310    enabled, then this function must: not be called
311endif::VK_NV_inherited_viewport_scissor[]
312****
313
314include::{generated}/validity/protos/vkCmdSetScissor.txt[]
315--
316
317
318ifdef::VK_NV_scissor_exclusive[]
319[[fragops-exclusive-scissor]]
320== Exclusive Scissor Test
321
322The exclusive scissor test compares the framebuffer coordinates
323[eq]#(x~f~,y~f~)# of each sample covered by a fragment against an _exclusive
324scissor rectangle_ at the index equal to the fragment's
325<<interfaces-builtin-variables-viewportindex, code:ViewportIndex>>.
326
327Each exclusive scissor rectangle is defined by a slink:VkRect2D.
328These values are either set by the
329slink:VkPipelineViewportExclusiveScissorStateCreateInfoNV structure during
330pipeline creation, or dynamically by the flink:vkCmdSetExclusiveScissorNV
331command.
332
333A given sample is considered inside an exclusive scissor rectangle if
334[eq]#x~f~# is in the range [eq]#[slink:VkRect2D::offset.x,
335slink:VkRect2D::offset.x {plus} slink:VkRect2D::extent.x)#, and [eq]#y~f~#
336is in the range [eq]#[slink:VkRect2D::offset.y, slink:VkRect2D::offset.y
337{plus} slink:VkRect2D::extent.y)#.
338Samples with coordinates inside the exclusive scissor rectangle at the
339corresponding code:ViewportIndex will have their coverage set to `0`.
340
341If no exclusive scissor rectangles are specified, the coverage mask is
342unmodified by this operation.
343
344[open,refpage='VkPipelineViewportExclusiveScissorStateCreateInfoNV',desc='Structure specifying parameters controlling exclusive scissor testing',type='structs']
345--
346The sname:VkPipelineViewportExclusiveScissorStateCreateInfoNV structure is
347defined as:
348
349include::{generated}/api/structs/VkPipelineViewportExclusiveScissorStateCreateInfoNV.txt[]
350
351  * pname:sType is the type of this structure.
352  * pname:pNext is `NULL` or a pointer to a structure extending this
353    structure.
354  * pname:exclusiveScissorCount is the number of exclusive scissor
355    rectangles.
356  * pname:pExclusiveScissors is a pointer to an array of slink:VkRect2D
357    structures defining exclusive scissor rectangles.
358
359If the ename:VK_DYNAMIC_STATE_EXCLUSIVE_SCISSOR_NV dynamic state is enabled
360for a pipeline, the pname:pExclusiveScissors member is ignored.
361
362When this structure is included in the pname:pNext chain of
363slink:VkGraphicsPipelineCreateInfo, it defines parameters of the exclusive
364scissor test.
365If this structure is not included in the pname:pNext chain, it is equivalent
366to specifying this structure with a pname:exclusiveScissorCount of `0`.
367
368.Valid Usage
369****
370  * [[VUID-VkPipelineViewportExclusiveScissorStateCreateInfoNV-exclusiveScissorCount-02027]]
371    If the <<features-multiViewport,multiple viewports>> feature is not
372    enabled, pname:exclusiveScissorCount must: be `0` or `1`
373  * [[VUID-VkPipelineViewportExclusiveScissorStateCreateInfoNV-exclusiveScissorCount-02028]]
374    pname:exclusiveScissorCount must: be less than or equal to
375    sname:VkPhysicalDeviceLimits::pname:maxViewports
376  * [[VUID-VkPipelineViewportExclusiveScissorStateCreateInfoNV-exclusiveScissorCount-02029]]
377    pname:exclusiveScissorCount must: be `0` or greater than or equal to the
378    pname:viewportCount member of slink:VkPipelineViewportStateCreateInfo
379
380****
381include::{generated}/validity/structs/VkPipelineViewportExclusiveScissorStateCreateInfoNV.txt[]
382--
383
384[open,refpage='vkCmdSetExclusiveScissorNV',desc='Set exclusive scissor rectangles dynamically for a command buffer',type='protos']
385--
386To <<pipelines-dynamic-state, dynamically set>> the exclusive scissor
387rectangles, call:
388
389include::{generated}/api/protos/vkCmdSetExclusiveScissorNV.txt[]
390
391  * pname:commandBuffer is the command buffer into which the command will be
392    recorded.
393  * pname:firstExclusiveScissor is the index of the first exclusive scissor
394    rectangle whose state is updated by the command.
395  * pname:exclusiveScissorCount is the number of exclusive scissor
396    rectangles updated by the command.
397  * pname:pExclusiveScissors is a pointer to an array of slink:VkRect2D
398    structures defining exclusive scissor rectangles.
399
400The scissor rectangles taken from element [eq]#i# of
401pname:pExclusiveScissors replace the current state for the scissor index
402[eq]#pname:firstExclusiveScissor {plus} i#, for [eq]#i# in [eq]#[0,
403pname:exclusiveScissorCount)#.
404
405This command sets the exclusive scissor rectangles for subsequent drawing
406commands when the graphics pipeline is created with
407ename:VK_DYNAMIC_STATE_EXCLUSIVE_SCISSOR_NV set in
408slink:VkPipelineDynamicStateCreateInfo::pname:pDynamicStates.
409Otherwise, this state is specified by the
410slink:VkPipelineViewportExclusiveScissorStateCreateInfoNV::pname:pExclusiveScissors
411values used to create the currently active pipeline.
412
413.Valid Usage
414****
415  * [[VUID-vkCmdSetExclusiveScissorNV-None-02031]]
416    The <<features-exclusiveScissor,exclusive scissor>> feature must: be
417    enabled
418  * [[VUID-vkCmdSetExclusiveScissorNV-firstExclusiveScissor-02034]]
419    The sum of pname:firstExclusiveScissor and pname:exclusiveScissorCount
420    must: be between `1` and
421    sname:VkPhysicalDeviceLimits::pname:maxViewports, inclusive
422  * [[VUID-vkCmdSetExclusiveScissorNV-firstExclusiveScissor-02035]]
423    If the <<features-multiViewport,multiple viewports>> feature is not
424    enabled, pname:firstExclusiveScissor must: be `0`
425  * [[VUID-vkCmdSetExclusiveScissorNV-exclusiveScissorCount-02036]]
426    If the <<features-multiViewport,multiple viewports>> feature is not
427    enabled, pname:exclusiveScissorCount must: be `1`
428  * [[VUID-vkCmdSetExclusiveScissorNV-x-02037]]
429    The pname:x and pname:y members of pname:offset in each member of
430    pname:pExclusiveScissors must: be greater than or equal to `0`
431  * [[VUID-vkCmdSetExclusiveScissorNV-offset-02038]]
432    Evaluation of [eq]#(pname:offset.x {plus} pname:extent.width)# for each
433    member of pname:pExclusiveScissors must: not cause a signed integer
434    addition overflow
435  * [[VUID-vkCmdSetExclusiveScissorNV-offset-02039]]
436    Evaluation of [eq]#(pname:offset.y {plus} pname:extent.height)# for each
437    member of pname:pExclusiveScissors must: not cause a signed integer
438    addition overflow
439****
440
441include::{generated}/validity/protos/vkCmdSetExclusiveScissorNV.txt[]
442--
443endif::VK_NV_scissor_exclusive[]
444
445
446[[fragops-samplemask]]
447== Sample Mask Test
448
449The sample mask test compares the <<primsrast-multisampling-coverage-mask,
450coverage mask>> for a fragment with the _sample mask_ defined by
451slink:VkPipelineMultisampleStateCreateInfo::pname:pSampleMask.
452
453Each bit of the coverage mask is associated with a sample index as described
454in the <<primsrast-multisampling-coverage-mask, rasterization chapter>>.
455If the bit in slink:VkPipelineMultisampleStateCreateInfo::pname:pSampleMask
456which is associated with that same sample index is set to `0`, the coverage
457mask bit is set to `0`.
458
459
460[[fragops-shader]]
461== Fragment Shading
462
463<<shaders-fragment, Fragment shaders>> are invoked for each fragment, or as
464<<shaders-helper-invocations, helper invocations>>.
465
466Most operations in the fragment shader are not performed in
467<<primsrast-order, rasterization order>>, with exceptions called out in the
468following sections.
469
470For fragment shaders invoked by fragments, the following rules apply:
471
472  * A fragment shader must: not be executed if a <<fragops, fragment
473    operation>> that executes before fragment shading discards the fragment.
474  * A fragment shader may: not be executed if:
475  ** An implementation determines that another fragment shader, invoked by a
476     subsequent primitive in <<drawing-primitive-order, primitive order>>,
477     overwrites all results computed by the shader (including writes to
478     storage resources).
479  ** Any other <<fragops, fragment operation>> discards the fragment, and
480     the shader does not write to any storage resources.
481  * Otherwise, at least one fragment shader must: be executed.
482  ** If <<primsrast-sampleshading,sample shading>> is enabled and multiple
483     invocations per fragment are required:, additional invocations must: be
484     executed as specified.
485ifdef::VK_NV_shading_rate_image[]
486  ** If a <<primsrast-shading-rate-image,shading rate image>> is used and
487     multiple invocations per fragment are required:, additional invocations
488     must: be executed as specified.
489endif::VK_NV_shading_rate_image[]
490  ** Each covered sample must: be included in at least one fragment shader
491     invocation.
492
493
494[NOTE]
495.Note
496====
497Multiple fragment shader invocations may be executed for the same fragment
498for any number of implementation-dependent reasons.
499When there is more than one fragment shader invocation per fragment, the
500association of samples to invocations is implementation-dependent.
501Stores and atomics performed by these additional invocations have the normal
502effect.
503
504ifdef::VK_VERSION_1_1,VK_KHR_multiview[]
505For example, if the subpass includes multiple views in its view mask, a
506fragment shader may be invoked separately for each view.
507endif::VK_VERSION_1_1,VK_KHR_multiview[]
508
509ifdef::VK_EXT_fragment_density_map[]
510Similarly, if the render pass has a fragment density map attachment, more
511than one fragment shader invocation may be invoked for each covered sample.
512Such additional invocations are only produced if
513sname:VkPhysicalDeviceFragmentDensityMapPropertiesEXT::pname:fragmentDensityInvocations
514is ename:VK_TRUE.
515Implementations may generate these additional fragment shader invocations in
516order to make transitions between fragment areas with different fragment
517densities more smooth.
518endif::VK_EXT_fragment_density_map[]
519====
520
521
522[[fragops-shader-samplemask]]
523=== Sample Mask
524
525Reading from the <<interfaces-builtin-variables-samplemask,
526code:SampleMask>> built-in in the code:Input storage class will return the
527coverage mask for the current fragment as calculated by fragment operations
528that executed prior to fragment shading.
529
530If <<primsrast-sampleshading, sample shading>> is enabled, fragment shaders
531will only see values of `1` for samples being shaded - other bits will be
532`0`.
533
534Each bit of the coverage mask is associated with a sample index as described
535in the <<primsrast-multisampling-coverage-mask, rasterization chapter>>.
536If the bit in code:SampleMask which is associated with that same sample
537index is set to `0`, that coverage mask bit is set to `0`.
538
539Values written to the <<interfaces-builtin-variables-samplemask,
540code:SampleMask>> built-in in the code:Output storage class will be used by
541the <<fragops-covg, multisample coverage>> operation, with the same encoding
542as the input built-in.
543
544
545[[fragops-shader-depthreplacement]]
546=== Depth Replacement
547
548Writing to the <<interfaces-builtin-variables-fragdepth,code:FragDepth>>
549built-in will replace the fragment's calculated depth values for each sample
550in the input code:SampleMask.
551<<fragops-depth, Depth testing>> performed after the fragment shader for
552this fragment will use this new value as [eq]#z~f~#.
553
554
555ifdef::VK_EXT_shader_stencil_export[]
556[[fragops-shader-stencilrefreplacement]]
557=== Stencil Reference Replacement
558
559Writing to the
560<<interfaces-builtin-variables-fragdepth,code:FragStencilRefEXT>> built-in
561will replace the fragment's stencil reference value for each sample in the
562input code:SampleMask.
563<<fragops-stencil, Stencil testing>> performed after the fragment shader for
564this fragment will use this new value as [eq]#s~r~#.
565endif::VK_EXT_shader_stencil_export[]
566
567
568ifdef::VK_EXT_fragment_shader_interlock[]
569[[fragops-shader-interlock]]
570=== Interlocked Operations
571
572code:OpBeginInvocationInterlockEXT and code:OpEndInvocationInterlockEXT
573define a section of a fragment shader which imposes additional ordering
574constraints on operations performed within them.
575These operations are defined as _interlocked operations_.
576How interlocked operations are ordered against other fragment shader
577invocations depends on the specified execution modes.
578
579ifdef::VK_NV_shading_rate_image,VK_KHR_fragment_shading_rate[]
580If the code:ShadingRateInterlockOrderedEXT execution mode is specified, any
581interlocked operations in a fragment shader must: happen before interlocked
582operations in fragment shader invocations that execute later in
583<<primsrast-order, rasterization order>> and cover at least one sample in
584the same fragment area, and must: happen after interlocked operations in a
585fragment shader that executes earlier in <<primsrast-order, rasterization
586order>> and cover at least one sample in the same fragment area.
587
588If the code:ShadingRateInterlockUnorderedEXT execution mode is specified,
589any interlocked operations in a fragment shader must: happen before or after
590interlocked operations in fragment shader invocations that execute earlier
591or later in <<primsrast-order, rasterization order>> and cover at least one
592sample in the same fragment area.
593endif::VK_NV_shading_rate_image,VK_KHR_fragment_shading_rate[]
594
595If the code:PixelInterlockOrderedEXT execution mode is specified, any
596interlocked operations in a fragment shader must: happen before interlocked
597operations in fragment shader invocations that execute later in
598<<primsrast-order, rasterization order>> and cover at least one sample in
599the same pixel, and must: happen after interlocked operations in a fragment
600shader that executes earlier in <<primsrast-order, rasterization order>> and
601cover at least one sample in the same pixel.
602
603If the code:PixelInterlockUnorderedEXT execution mode is specified, any
604interlocked operations in a fragment shader must: happen before or after
605interlocked operations in fragment shader invocations that execute earlier
606or later in <<primsrast-order, rasterization order>> and cover at least one
607sample in the same pixel.
608
609If the code:SampleInterlockOrderedEXT execution mode is specified, any
610interlocked operations in a fragment shader must: happen before interlocked
611operations in fragment shader invocations that execute later in
612<<primsrast-order, rasterization order>> and cover at least one of the same
613samples, and must: happen after interlocked operations in a fragment shader
614that executes earlier in <<primsrast-order, rasterization order>> and cover
615at least one of the same samples.
616
617If the code:SampleInterlockUnorderedEXT execution mode is specified, any
618interlocked operations in a fragment shader must: happen before or after
619interlocked operations in fragment shader invocations that execute earlier
620or later in <<primsrast-order, rasterization order>> and cover at least one
621of the same samples.
622endif::VK_EXT_fragment_shader_interlock[]
623
624
625[[fragops-covg]]
626== Multisample Coverage
627
628If a fragment shader is active and its entry point's interface includes a
629built-in output variable decorated with code:SampleMask,
630ifdef::VK_NV_sample_mask_override_coverage[]
631but not code:OverrideCoverageNV,
632endif::VK_NV_sample_mask_override_coverage[]
633the coverage mask is code:ANDed with the bits of the code:SampleMask
634built-in to generate a new coverage mask.
635ifdef::VK_NV_sample_mask_override_coverage[]
636If the code:SampleMask built-in is also decorated with
637code:OverrideCoverageNV, the coverage mask is replaced with the mask bits
638set in the shader.
639endif::VK_NV_sample_mask_override_coverage[]
640If <<primsrast-sampleshading,sample shading>> is enabled, bits written to
641code:SampleMask corresponding to samples that are not being shaded by the
642fragment shader invocation are ignored.
643If no fragment shader is active, or if the active fragment shader does not
644include code:SampleMask in its interface, the coverage mask is not modified.
645
646Next, the fragment alpha value and coverage mask are modified based on the
647ifdef::VK_EXT_line_rasterization[]
648line coverage factor if the pname:lineRasterizationMode member of the
649slink:VkPipelineRasterizationStateCreateInfo structure is
650ename:VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT, and the
651endif::VK_EXT_line_rasterization[]
652pname:alphaToCoverageEnable and pname:alphaToOneEnable members of the
653slink:VkPipelineMultisampleStateCreateInfo structure.
654
655All alpha values in this section refer only to the alpha component of the
656fragment shader output that has a code:Location and code:Index decoration of
657zero (see the <<interfaces-fragmentoutput,Fragment Output Interface>>
658section).
659If that shader output has an integer or unsigned integer type, then these
660operations are skipped.
661
662ifdef::VK_EXT_line_rasterization[]
663If the pname:lineRasterizationMode member of the
664slink:VkPipelineRasterizationStateCreateInfo structure is
665ename:VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT and the fragment
666came from a line segment, then the alpha value is replaced by multiplying it
667by the coverage factor for the fragment computed during
668<<primsrast-lines-smooth,smooth line rasterization>>.
669endif::VK_EXT_line_rasterization[]
670
671If pname:alphaToCoverageEnable is enabled, a temporary coverage mask is
672generated where each bit is determined by the fragment's alpha value, which
673is ANDed with the fragment coverage mask.
674
675No specific algorithm is specified for converting the alpha value to a
676temporary coverage mask.
677It is intended that the number of 1's in this value be proportional to the
678alpha value (clamped to [eq]#[0,1]#), with all 1's corresponding to a value
679of 1.0 and all 0's corresponding to 0.0.
680The algorithm may: be different at different framebuffer coordinates.
681
682[NOTE]
683.Note
684====
685Using different algorithms at different framebuffer coordinates may: help to
686avoid artifacts caused by regular coverage sample locations.
687====
688
689Finally, if pname:alphaToOneEnable is enabled, each alpha value is replaced
690by the maximum representable alpha value for fixed-point color buffers, or
691by 1.0 for floating-point buffers.
692Otherwise, the alpha values are not changed.
693
694
695[[fragops-ds-state]]
696== Depth and Stencil Operations
697
698Pipeline state controlling the <<fragops-dbt,depth bounds tests>>,
699<<fragops-stencil,stencil test>>, and <<fragops-depth,depth test>> is
700specified through the members of the
701sname:VkPipelineDepthStencilStateCreateInfo structure.
702
703[open,refpage='VkPipelineDepthStencilStateCreateInfo',desc='Structure specifying parameters of a newly created pipeline depth stencil state',type='structs']
704--
705The sname:VkPipelineDepthStencilStateCreateInfo structure is defined as:
706
707include::{generated}/api/structs/VkPipelineDepthStencilStateCreateInfo.txt[]
708
709  * pname:sType is the type of this structure.
710  * pname:pNext is `NULL` or a pointer to a structure extending this
711    structure.
712  * pname:flags is reserved for future use.
713  * pname:depthTestEnable controls whether <<fragops-depth,depth testing>>
714    is enabled.
715  * pname:depthWriteEnable controls whether <<fragops-depth-write,depth
716    writes>> are enabled when pname:depthTestEnable is ename:VK_TRUE.
717    Depth writes are always disabled when pname:depthTestEnable is
718    ename:VK_FALSE.
719  * pname:depthCompareOp is the comparison operator used in the
720    <<fragops-depth,depth test>>.
721  * pname:depthBoundsTestEnable controls whether <<fragops-dbt,depth bounds
722    testing>> is enabled.
723  * pname:stencilTestEnable controls whether <<fragops-stencil,stencil
724    testing>> is enabled.
725  * pname:front and pname:back control the parameters of the
726    <<fragops-stencil,stencil test>>.
727  * pname:minDepthBounds is the minimum depth bound used in the
728    <<fragops-dbt, depth bounds test>>.
729  * pname:maxDepthBounds is the maximum depth bound used in the
730    <<fragops-dbt, depth bounds test>>.
731
732.Valid Usage
733****
734  * [[VUID-VkPipelineDepthStencilStateCreateInfo-depthBoundsTestEnable-00598]]
735    If the <<features-depthBounds,depth bounds testing>> feature is not
736    enabled, pname:depthBoundsTestEnable must: be ename:VK_FALSE
737ifdef::VK_KHR_portability_subset[]
738  * [[VUID-VkPipelineDepthStencilStateCreateInfo-separateStencilMaskRef-04453]]
739    If the `apiext:VK_KHR_portability_subset` extension is enabled, and
740    slink:VkPhysicalDevicePortabilitySubsetFeaturesKHR::pname:separateStencilMaskRef
741    is ename:VK_FALSE, and the value of
742    slink:VkPipelineDepthStencilStateCreateInfo::pname:stencilTestEnable is
743    ename:VK_TRUE, and the value of
744    slink:VkPipelineRasterizationStateCreateInfo::pname:cullMode is
745    ename:VK_CULL_MODE_NONE, the value of pname:reference in each of the
746    slink:VkStencilOpState structs in pname:front and pname:back must: be
747    the same
748endif::VK_KHR_portability_subset[]
749****
750
751include::{generated}/validity/structs/VkPipelineDepthStencilStateCreateInfo.txt[]
752--
753
754[open,refpage='VkPipelineDepthStencilStateCreateFlags',desc='Reserved for future use',type='flags']
755--
756include::{generated}/api/flags/VkPipelineDepthStencilStateCreateFlags.txt[]
757
758tname:VkPipelineDepthStencilStateCreateFlags is a bitmask type for setting a
759mask, but is currently reserved for future use.
760--
761
762
763[[fragops-dbt]]
764== Depth Bounds Test
765
766The depth bounds test compares the depth value [eq]#z~a~# in the
767depth/stencil attachment at each sample's framebuffer coordinates
768[eq]#(x~f~,y~f~)# and <<primsrast-multisampling-coverage-mask, sample
769index>> [eq]#i# against a set of _depth bounds_.
770
771The depth bounds are determined by two floating point values defining a
772minimum (pname:minDepthBounds) and maximum (pname:maxDepthBounds) depth
773value.
774These values are either set by the
775slink:VkPipelineDepthStencilStateCreateInfo structure during pipeline
776creation, or dynamically by
777ifdef::VK_EXT_extended_dynamic_state[]
778flink:vkCmdSetDepthBoundsTestEnableEXT and
779endif::VK_EXT_extended_dynamic_state[]
780flink:vkCmdSetDepthBounds.
781
782A given sample is considered within the depth bounds if [eq]#z~a~# is in the
783range [eq]#[pname:minDepthBounds,pname:maxDepthBounds]#.
784Samples with depth attachment values outside of the depth bounds will have
785their coverage set to `0`.
786
787If the depth bounds test is disabled, or if there is no depth attachment,
788the coverage mask is unmodified by this operation.
789
790ifdef::VK_EXT_extended_dynamic_state[]
791[open,refpage='vkCmdSetDepthBoundsTestEnableEXT',desc='Set depth bounds test enable dynamically for a command buffer',type='protos']
792--
793To <<pipelines-dynamic-state, dynamically enable or disable>> the depth
794bounds test, call:
795
796include::{generated}/api/protos/vkCmdSetDepthBoundsTestEnableEXT.txt[]
797
798  * pname:commandBuffer is the command buffer into which the command will be
799    recorded.
800  * pname:depthBoundsTestEnable specifies if the depth bounds test is
801    enabled.
802
803This command sets the depth bounds enable for subsequent drawing commands
804when the graphics pipeline is created with
805ename:VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE_EXT set in
806slink:VkPipelineDynamicStateCreateInfo::pname:pDynamicStates.
807Otherwise, this state is specified by the
808slink:VkPipelineDepthStencilStateCreateInfo::pname:depthBoundsTestEnable
809value used to create the currently active pipeline.
810
811.Valid Usage
812****
813  * [[VUID-vkCmdSetDepthBoundsTestEnableEXT-None-03349]]
814    The <<features-extendedDynamicState, extendedDynamicState>> feature
815    must: be enabled
816****
817
818include::{generated}/validity/protos/vkCmdSetDepthBoundsTestEnableEXT.txt[]
819--
820endif::VK_EXT_extended_dynamic_state[]
821
822[open,refpage='vkCmdSetDepthBounds',desc='Set depth bounds range dynamically for a command buffer',type='protos']
823--
824To <<pipelines-dynamic-state, dynamically set>> the depth bounds range,
825call:
826
827include::{generated}/api/protos/vkCmdSetDepthBounds.txt[]
828
829  * pname:commandBuffer is the command buffer into which the command will be
830    recorded.
831  * pname:minDepthBounds is the minimum depth bound.
832  * pname:maxDepthBounds is the maximum depth bound.
833
834This command sets the depth bounds range for subsequent drawing commands
835when the graphics pipeline is created with
836ename:VK_DYNAMIC_STATE_DEPTH_BOUNDS set in
837slink:VkPipelineDynamicStateCreateInfo::pname:pDynamicStates.
838Otherwise, this state is specified by the
839slink:VkPipelineDepthStencilStateCreateInfo::pname:minDepthBounds and
840slink:VkPipelineDepthStencilStateCreateInfo::pname:maxDepthBounds values
841used to create the currently active pipeline.
842
843.Valid Usage
844****
845ifdef::VK_EXT_depth_range_unrestricted[]
846  * [[VUID-vkCmdSetDepthBounds-minDepthBounds-00600]]
847    Unless the `apiext:VK_EXT_depth_range_unrestricted` extension is enabled
848    pname:minDepthBounds must: be between `0.0` and `1.0`, inclusive
849endif::VK_EXT_depth_range_unrestricted[]
850ifndef::VK_EXT_depth_range_unrestricted[]
851  * [[VUID-vkCmdSetDepthBounds-minDepthBounds-02508]]
852    pname:minDepthBounds must: be between `0.0` and `1.0`, inclusive
853endif::VK_EXT_depth_range_unrestricted[]
854ifdef::VK_EXT_depth_range_unrestricted[]
855  * [[VUID-vkCmdSetDepthBounds-maxDepthBounds-00601]]
856    Unless the `apiext:VK_EXT_depth_range_unrestricted` extension is enabled
857    pname:maxDepthBounds must: be between `0.0` and `1.0`, inclusive
858endif::VK_EXT_depth_range_unrestricted[]
859ifndef::VK_EXT_depth_range_unrestricted[]
860  * [[VUID-vkCmdSetDepthBounds-maxDepthBounds-02509]]
861    pname:maxDepthBounds must: be between `0.0` and `1.0`, inclusive
862endif::VK_EXT_depth_range_unrestricted[]
863****
864
865include::{generated}/validity/protos/vkCmdSetDepthBounds.txt[]
866--
867
868
869[[fragops-stencil]]
870== Stencil Test
871
872The stencil test compares the stencil attachment value [eq]#s~a~# in the
873depth/stencil attachment at each sample's framebuffer coordinates
874[eq]#(x~f~,y~f~)# and <<primsrast-multisampling-coverage-mask, sample
875index>> [eq]#i# against a _stencil reference value_.
876
877ifdef::VK_EXT_fragment_density_map[]
878If the render pass has a fragment density map attachment and the fragment
879covers multiple pixels, there is an implementation-dependent association of
880coverage samples to stencil attachment samples within the fragment.
881However, if all samples in the fragment are covered, and the stencil
882attachment value is updated as a result of this test, all stencil attachment
883samples will be updated.
884endif::VK_EXT_fragment_density_map[]
885
886If the stencil test is not enabled, as specified by
887ifdef::VK_EXT_extended_dynamic_state[]
888flink:vkCmdSetStencilTestEnableEXT or
889endif::VK_EXT_extended_dynamic_state[]
890slink:VkPipelineDepthStencilStateCreateInfo::pname:stencilTestEnable, or if
891there is no stencil attachment, the coverage mask is unmodified by this
892operation.
893
894The stencil test is controlled by one of two sets of stencil-related state,
895the front stencil state and the back stencil state.
896Stencil tests and writes use the back stencil state when processing
897fragments generated by <<primsrast-polygons-basic,back-facing>>
898<<primsrast-polygons,polygons>>, and the front stencil state when processing
899fragments generated by <<primsrast-polygons-basic,front-facing polygons>> or
900any other primitives.
901
902The comparison performed is based on the elink:VkCompareOp, compare mask
903[eq]#s~c~# , and stencil reference value [eq]#s~r~# of the relevant state
904set.
905The compare mask and stencil reference value are set by either the
906slink:VkPipelineDepthStencilStateCreateInfo structure during pipeline
907creation, or by the flink:vkCmdSetStencilCompareMask and
908flink:vkCmdSetStencilReference commands respectively.
909The compare operation is set by slink:VkStencilOpState::pname:compareOp
910during pipeline creation.
911
912The stencil reference and attachment values [eq]#s~r~# and [eq]#s~a~# are
913each independently combined with the compare mask [eq]#s~c~# using a logical
914code:AND operation to create masked reference and attachment values
915[eq]#s'~r~# and [eq]#s'~a~#.
916[eq]#s'~r~# and [eq]#s'~a~# are used as [eq]#A# and [eq]#B#, respectively,
917in the operation specified by elink:VkCompareOp.
918
919If the comparison evaluates to false, the coverage for the sample is set to
920`0`.
921
922A new stencil value [eq]#s~g~# is generated according to a stencil operation
923defined by elink:VkStencilOp parameters set by
924ifdef::VK_EXT_extended_dynamic_state[]
925flink:vkCmdSetStencilOpEXT or
926endif::VK_EXT_extended_dynamic_state[]
927slink:VkPipelineDepthStencilStateCreateInfo.
928If the stencil test fails, pname:failOp defines the stencil operation used.
929If the stencil test passes however, the stencil op used is based on the
930<<fragops-depth, depth test>> - if it passes,
931slink:VkPipelineDepthStencilStateCreateInfo::pname:passOp is used, otherwise
932slink:VkPipelineDepthStencilStateCreateInfo::pname:depthFailOp is used.
933
934The stencil attachment value [eq]#s~a~# is then updated with the generated
935stencil value [eq]#s~g~# according to the write mask [eq]#s~w~# defined by
936slink:VkPipelineDepthStencilStateCreateInfo::pname:writeMask as:
937
938  {empty}:: [eq]#s~a~ = (s~a~ & ¬s~w~) | (s~g~ & s~w~)#
939
940If there is no stencil attachment, no value is written.
941
942ifdef::VK_EXT_extended_dynamic_state[]
943
944[open,refpage='vkCmdSetStencilTestEnableEXT',desc='Set stencil test enable dynamically for a command buffer',type='protos']
945--
946To <<pipelines-dynamic-state, dynamically enable or disable>> the stencil
947test, call:
948
949include::{generated}/api/protos/vkCmdSetStencilTestEnableEXT.txt[]
950
951  * pname:commandBuffer is the command buffer into which the command will be
952    recorded.
953  * pname:stencilTestEnable specifies if the stencil test is enabled.
954
955This command sets the stencil test enable for subsequent drawing commands
956when the graphics pipeline is created with
957ename:VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE_EXT set in
958slink:VkPipelineDynamicStateCreateInfo::pname:pDynamicStates.
959Otherwise, this state is specified by the
960slink:VkPipelineDepthStencilStateCreateInfo::pname:stencilTestEnable value
961used to create the currently active pipeline.
962
963.Valid Usage
964****
965  * [[VUID-vkCmdSetStencilTestEnableEXT-None-03350]]
966    The <<features-extendedDynamicState, extendedDynamicState>> feature
967    must: be enabled
968****
969
970include::{generated}/validity/protos/vkCmdSetStencilTestEnableEXT.txt[]
971--
972
973[open,refpage='vkCmdSetStencilOpEXT',desc='Set stencil operation dynamically for a command buffer',type='protos']
974--
975To <<pipelines-dynamic-state, dynamically set>> the stencil operation, call:
976
977include::{generated}/api/protos/vkCmdSetStencilOpEXT.txt[]
978
979  * pname:commandBuffer is the command buffer into which the command will be
980    recorded.
981  * pname:faceMask is a bitmask of elink:VkStencilFaceFlagBits specifying
982    the set of stencil state for which to update the stencil operation.
983  * pname:failOp is a elink:VkStencilOp value specifying the action
984    performed on samples that fail the stencil test.
985  * pname:passOp is a elink:VkStencilOp value specifying the action
986    performed on samples that pass both the depth and stencil tests.
987  * pname:depthFailOp is a elink:VkStencilOp value specifying the action
988    performed on samples that pass the stencil test and fail the depth test.
989  * pname:compareOp is a elink:VkCompareOp value specifying the comparison
990    operator used in the stencil test.
991
992This command sets the stencil operation for subsequent drawing commands when
993the graphics pipeline is created with ename:VK_DYNAMIC_STATE_STENCIL_OP_EXT
994set in slink:VkPipelineDynamicStateCreateInfo::pname:pDynamicStates.
995Otherwise, this state is specified by the corresponding
996sname:VkPipelineDepthStencilStateCreateInfo::pname:failOp, pname:passOp,
997pname:depthFailOp, and pname:compareOp values used to create the currently
998active pipeline, for both front and back faces.
999
1000.Valid Usage
1001****
1002  * [[VUID-vkCmdSetStencilOpEXT-None-03351]]
1003    The <<features-extendedDynamicState, extendedDynamicState>> feature
1004    must: be enabled
1005****
1006
1007include::{generated}/validity/protos/vkCmdSetStencilOpEXT.txt[]
1008--
1009
1010endif::VK_EXT_extended_dynamic_state[]
1011
1012[open,refpage='VkStencilOpState',desc='Structure specifying stencil operation state',type='structs']
1013--
1014The sname:VkStencilOpState structure is defined as:
1015
1016include::{generated}/api/structs/VkStencilOpState.txt[]
1017
1018  * pname:failOp is a elink:VkStencilOp value specifying the action
1019    performed on samples that fail the stencil test.
1020  * pname:passOp is a elink:VkStencilOp value specifying the action
1021    performed on samples that pass both the depth and stencil tests.
1022  * pname:depthFailOp is a elink:VkStencilOp value specifying the action
1023    performed on samples that pass the stencil test and fail the depth test.
1024  * pname:compareOp is a elink:VkCompareOp value specifying the comparison
1025    operator used in the stencil test.
1026  * pname:compareMask selects the bits of the unsigned integer stencil
1027    values participating in the stencil test.
1028  * pname:writeMask selects the bits of the unsigned integer stencil values
1029    updated by the stencil test in the stencil framebuffer attachment.
1030  * pname:reference is an integer reference value that is used in the
1031    unsigned stencil comparison.
1032
1033include::{generated}/validity/structs/VkStencilOpState.txt[]
1034--
1035
1036[open,refpage='vkCmdSetStencilCompareMask',desc='Set stencil compare mask dynamically for a command buffer',type='protos']
1037--
1038To <<pipelines-dynamic-state, dynamically set>> the stencil compare mask
1039call:
1040
1041include::{generated}/api/protos/vkCmdSetStencilCompareMask.txt[]
1042
1043  * pname:commandBuffer is the command buffer into which the command will be
1044    recorded.
1045  * pname:faceMask is a bitmask of elink:VkStencilFaceFlagBits specifying
1046    the set of stencil state for which to update the compare mask.
1047  * pname:compareMask is the new value to use as the stencil compare mask.
1048
1049This command sets the stencil compare mask for subsequent drawing commands
1050when the graphics pipeline is created with
1051ename:VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK set in
1052slink:VkPipelineDynamicStateCreateInfo::pname:pDynamicStates.
1053Otherwise, this state is specified by the
1054slink:VkPipelineDepthStencilStateCreateInfo::pname:compareMask value used to
1055create the currently active pipeline, for both front and back faces.
1056
1057include::{generated}/validity/protos/vkCmdSetStencilCompareMask.txt[]
1058--
1059
1060[open,refpage='VkStencilFaceFlagBits',desc='Bitmask specifying sets of stencil state for which to update the compare mask',type='enums']
1061--
1062ename:VkStencilFaceFlagBits values are:
1063
1064include::{generated}/api/enums/VkStencilFaceFlagBits.txt[]
1065
1066  * ename:VK_STENCIL_FACE_FRONT_BIT specifies that only the front set of
1067    stencil state is updated.
1068  * ename:VK_STENCIL_FACE_BACK_BIT specifies that only the back set of
1069    stencil state is updated.
1070  * ename:VK_STENCIL_FACE_FRONT_AND_BACK is the combination of
1071    ename:VK_STENCIL_FACE_FRONT_BIT and ename:VK_STENCIL_FACE_BACK_BIT, and
1072    specifies that both sets of stencil state are updated.
1073
1074--
1075
1076[open,refpage='VkStencilFaceFlags',desc='Bitmask of VkStencilFaceFlagBits',type='flags']
1077--
1078include::{generated}/api/flags/VkStencilFaceFlags.txt[]
1079
1080tname:VkStencilFaceFlags is a bitmask type for setting a mask of zero or
1081more elink:VkStencilFaceFlagBits.
1082--
1083
1084[open,refpage='vkCmdSetStencilWriteMask',desc='Set stencil write mask dynamically for a command buffer',type='protos']
1085--
1086To <<pipelines-dynamic-state, dynamically set>> the stencil write mask,
1087call:
1088
1089include::{generated}/api/protos/vkCmdSetStencilWriteMask.txt[]
1090
1091  * pname:commandBuffer is the command buffer into which the command will be
1092    recorded.
1093  * pname:faceMask is a bitmask of elink:VkStencilFaceFlagBits specifying
1094    the set of stencil state for which to update the write mask, as
1095    described above for flink:vkCmdSetStencilCompareMask.
1096  * pname:writeMask is the new value to use as the stencil write mask.
1097
1098This command sets the stencil write mask for subsequent drawing commands
1099when the graphics pipeline is created with
1100ename:VK_DYNAMIC_STATE_STENCIL_WRITE_MASK set in
1101slink:VkPipelineDynamicStateCreateInfo::pname:pDynamicStates.
1102Otherwise, this state is specified by the
1103slink:VkPipelineDepthStencilStateCreateInfo::pname:writeMask value used to
1104create the currently active pipeline, for both front and back faces.
1105
1106include::{generated}/validity/protos/vkCmdSetStencilWriteMask.txt[]
1107--
1108
1109[open,refpage='vkCmdSetStencilReference',desc='Set stencil reference value dynamically for a command buffer',type='protos']
1110--
1111To <<pipelines-dynamic-state, dynamically set>> the stencil reference value,
1112call:
1113
1114include::{generated}/api/protos/vkCmdSetStencilReference.txt[]
1115
1116  * pname:commandBuffer is the command buffer into which the command will be
1117    recorded.
1118  * pname:faceMask is a bitmask of elink:VkStencilFaceFlagBits specifying
1119    the set of stencil state for which to update the reference value, as
1120    described above for flink:vkCmdSetStencilCompareMask.
1121  * pname:reference is the new value to use as the stencil reference value.
1122
1123This command sets the stencil reference value for subsequent drawing
1124commands when the graphics pipeline is created with
1125ename:VK_DYNAMIC_STATE_STENCIL_REFERENCE set in
1126slink:VkPipelineDynamicStateCreateInfo::pname:pDynamicStates.
1127Otherwise, this state is specified by the
1128slink:VkPipelineDepthStencilStateCreateInfo::pname:reference value used to
1129create the currently active pipeline, for both front and back faces.
1130
1131include::{generated}/validity/protos/vkCmdSetStencilReference.txt[]
1132--
1133
1134[open,refpage='VkCompareOp',desc='Stencil comparison function',type='enums']
1135--
1136Possible values of slink:VkStencilOpState::pname:compareOp, specifying the
1137stencil comparison function, are:
1138
1139include::{generated}/api/enums/VkCompareOp.txt[]
1140
1141  * ename:VK_COMPARE_OP_NEVER specifies that the test evaluates to false.
1142  * ename:VK_COMPARE_OP_LESS specifies that the test evaluates [eq]#A < B#.
1143  * ename:VK_COMPARE_OP_EQUAL specifies that the test evaluates [eq]#A = B#.
1144  * ename:VK_COMPARE_OP_LESS_OR_EQUAL specifies that the test evaluates
1145    [eq]#A {leq} B#.
1146  * ename:VK_COMPARE_OP_GREATER specifies that the test evaluates [eq]#A >
1147    B#.
1148  * ename:VK_COMPARE_OP_NOT_EQUAL specifies that the test evaluates [eq]#A
1149    {neq} B#.
1150  * ename:VK_COMPARE_OP_GREATER_OR_EQUAL specifies that the test evaluates
1151    [eq]#A {geq} B#.
1152  * ename:VK_COMPARE_OP_ALWAYS specifies that the test evaluates to true.
1153--
1154
1155[open,refpage='VkStencilOp',desc='Stencil comparison function',type='enums']
1156--
1157Possible values of the pname:failOp, pname:passOp, and pname:depthFailOp
1158members of slink:VkStencilOpState, specifying what happens to the stored
1159stencil value if this or certain subsequent tests fail or pass, are:
1160
1161include::{generated}/api/enums/VkStencilOp.txt[]
1162
1163  * ename:VK_STENCIL_OP_KEEP keeps the current value.
1164  * ename:VK_STENCIL_OP_ZERO sets the value to 0.
1165  * ename:VK_STENCIL_OP_REPLACE sets the value to pname:reference.
1166  * ename:VK_STENCIL_OP_INCREMENT_AND_CLAMP increments the current value and
1167    clamps to the maximum representable unsigned value.
1168  * ename:VK_STENCIL_OP_DECREMENT_AND_CLAMP decrements the current value and
1169    clamps to 0.
1170  * ename:VK_STENCIL_OP_INVERT bitwise-inverts the current value.
1171  * ename:VK_STENCIL_OP_INCREMENT_AND_WRAP increments the current value and
1172    wraps to 0 when the maximum value would have been exceeded.
1173  * ename:VK_STENCIL_OP_DECREMENT_AND_WRAP decrements the current value and
1174    wraps to the maximum possible value when the value would go below 0.
1175
1176For purposes of increment and decrement, the stencil bits are considered as
1177an unsigned integer.
1178--
1179
1180
1181[[fragops-depth]]
1182== Depth Test
1183
1184The depth test compares the depth value [eq]#z~a~# in the depth/stencil
1185attachment at each sample's framebuffer coordinates [eq]#(x~f~,y~f~)# and
1186<<primsrast-multisampling-coverage-mask, sample index>> [eq]#i# against the
1187sample's depth value [eq]#z~f~#.
1188If there is no depth attachment then the depth test is skipped.
1189
1190ifdef::VK_EXT_fragment_density_map[]
1191If the render pass has a fragment density map attachment and the fragment
1192covers multiple pixels, there is an implementation-dependent association of
1193rasterization samples to depth attachment samples within the fragment.
1194However, if all samples in the fragment are covered, and the depth
1195attachment value is updated as a result of this test, all depth attachment
1196samples will be updated.
1197endif::VK_EXT_fragment_density_map[]
1198
1199The depth test occurs in three stages, as detailed in the following
1200sections.
1201
1202=== Depth Clamping and Range Adjustment
1203
1204If slink:VkPipelineRasterizationStateCreateInfo::pname:depthClampEnable is
1205enabled, before the sample's [eq]#z~f~# is compared to [eq]#z~a~#,
1206[eq]#z~f~# is clamped to [eq]#[min(n,f),max(n,f)]#, where [eq]#n# and
1207[eq]#f# are the pname:minDepth and pname:maxDepth depth range values of the
1208viewport used by this fragment, respectively.
1209
1210If depth clamping is not enabled and [eq]#z~f~# is not in the range [eq]#[0,
12111]#
1212ifdef::VK_EXT_depth_range_unrestricted[]
1213and either apiext:VK_EXT_depth_range_unrestricted is not enabled, or the
1214depth attachment has a fixed-point format,
1215endif::VK_EXT_depth_range_unrestricted[]
1216then [eq]#z~f~# is undefined: following this step.
1217
1218
1219=== Depth Comparison
1220
1221If the depth test is not enabled, as specified by
1222ifdef::VK_EXT_extended_dynamic_state[]
1223flink:vkCmdSetDepthTestEnableEXT or
1224endif::VK_EXT_extended_dynamic_state[]
1225slink:VkPipelineDepthStencilStateCreateInfo::pname:depthTestEnable, then
1226this step is skipped.
1227
1228The comparison performed is based on the elink:VkCompareOp, set by
1229ifdef::VK_EXT_extended_dynamic_state[]
1230flink:vkCmdSetDepthCompareOpEXT or
1231endif::VK_EXT_extended_dynamic_state[]
1232slink:VkPipelineDepthStencilStateCreateInfo::pname:depthCompareOp during
1233pipeline creation.
1234[eq]#z~f~# and [eq]#z~a~# are used as [eq]#A# and [eq]#B#, respectively, in
1235the operation specified by the elink:VkCompareOp.
1236
1237If the comparison evaluates to false, the coverage for the sample is set to
1238`0`.
1239
1240
1241[[fragops-depth-write]]
1242=== Depth Buffer Writes
1243
1244If depth writes are enabled, as specified by
1245ifdef::VK_EXT_extended_dynamic_state[]
1246flink:vkCmdSetDepthWriteEnableEXT or
1247endif::VK_EXT_extended_dynamic_state[]
1248slink:VkPipelineDepthStencilStateCreateInfo::pname:depthWriteEnable, and the
1249comparison evaluated to true, the depth attachment value [eq]#z~a~# is set
1250to the sample's depth value [eq]#z~f~#.
1251If there is no depth attachment, no value is written.
1252
1253
1254
1255ifdef::VK_EXT_extended_dynamic_state[]
1256[open,refpage='vkCmdSetDepthTestEnableEXT',desc='Set depth test enable dynamically for a command buffer',type='protos']
1257--
1258To <<pipelines-dynamic-state, dynamically enable or disable>> the depth
1259test, call:
1260
1261include::{generated}/api/protos/vkCmdSetDepthTestEnableEXT.txt[]
1262
1263  * pname:commandBuffer is the command buffer into which the command will be
1264    recorded.
1265  * pname:depthTestEnable specifies if the depth test is enabled.
1266
1267This command sets the depth test enable for subsequent drawing commands when
1268the graphics pipeline is created with
1269ename:VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE_EXT set in
1270slink:VkPipelineDynamicStateCreateInfo::pname:pDynamicStates.
1271Otherwise, this state is specified by the
1272slink:VkPipelineDepthStencilStateCreateInfo::pname:depthTestEnable value
1273used to create the currently active pipeline.
1274
1275.Valid Usage
1276****
1277  * [[VUID-vkCmdSetDepthTestEnableEXT-None-03352]]
1278    The <<features-extendedDynamicState, extendedDynamicState>> feature
1279    must: be enabled
1280****
1281
1282include::{generated}/validity/protos/vkCmdSetDepthTestEnableEXT.txt[]
1283--
1284
1285[open,refpage='vkCmdSetDepthCompareOpEXT',desc='Set depth comparison operator dynamically for a command buffer',type='protos']
1286--
1287To <<pipelines-dynamic-state, dynamically set>> the depth compare operator,
1288call:
1289
1290include::{generated}/api/protos/vkCmdSetDepthCompareOpEXT.txt[]
1291
1292  * pname:commandBuffer is the command buffer into which the command will be
1293    recorded.
1294  * pname:depthCompareOp specifies the depth comparison operator.
1295
1296This command sets the depth comparison operator for subsequent drawing
1297commands when the graphics pipeline is created with
1298ename:VK_DYNAMIC_STATE_DEPTH_COMPARE_OP_EXT set in
1299slink:VkPipelineDynamicStateCreateInfo::pname:pDynamicStates.
1300Otherwise, this state is specified by the
1301slink:VkPipelineDepthStencilStateCreateInfo::pname:depthCompareOp value used
1302to create the currently active pipeline.
1303
1304.Valid Usage
1305****
1306  * [[VUID-vkCmdSetDepthCompareOpEXT-None-03353]]
1307    The <<features-extendedDynamicState, extendedDynamicState>> feature
1308    must: be enabled
1309****
1310
1311include::{generated}/validity/protos/vkCmdSetDepthCompareOpEXT.txt[]
1312--
1313
1314[open,refpage='vkCmdSetDepthWriteEnableEXT',desc='Set depth write enable dynamically for a command buffer',type='protos']
1315--
1316To <<pipelines-dynamic-state, dynamically set>> the depth write enable,
1317call:
1318
1319include::{generated}/api/protos/vkCmdSetDepthWriteEnableEXT.txt[]
1320
1321  * pname:commandBuffer is the command buffer into which the command will be
1322    recorded.
1323  * pname:depthWriteEnable specifies if depth writes are enabled.
1324
1325This command sets the depth write enable for subsequent drawing commands
1326when the graphics pipeline is created with
1327ename:VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE_EXT set in
1328slink:VkPipelineDynamicStateCreateInfo::pname:pDynamicStates.
1329Otherwise, this state is specified by the
1330slink:VkPipelineDepthStencilStateCreateInfo::pname:depthWriteEnable value
1331used to create the currently active pipeline.
1332
1333.Valid Usage
1334****
1335  * [[VUID-vkCmdSetDepthWriteEnableEXT-None-03354]]
1336    The <<features-extendedDynamicState, extendedDynamicState>> feature
1337    must: be enabled
1338****
1339
1340include::{generated}/validity/protos/vkCmdSetDepthWriteEnableEXT.txt[]
1341--
1342endif::VK_EXT_extended_dynamic_state[]
1343
1344
1345ifdef::VK_NV_representative_fragment_test[]
1346[[fragops-rep-frag-test]]
1347== Representative Fragment Test
1348
1349The representative fragment test allows implementations to reduce the amount
1350of rasterization and fragment processing work performed for each point,
1351line, or triangle primitive.
1352For any primitive that produces one or more fragments that pass all prior
1353early fragment tests, the implementation may: choose one or more
1354"`representative`" fragments for processing and discard all other fragments.
1355For draw calls rendering multiple points, lines, or triangles arranged in
1356lists, strips, or fans, the representative fragment test is performed
1357independently for each of those primitives.
1358The set of fragments discarded by the representative fragment test is
1359implementation-dependent.
1360In some cases, the representative fragment test may not discard any
1361fragments for a given primitive.
1362
1363[open,refpage='VkPipelineRepresentativeFragmentTestStateCreateInfoNV',desc='Structure specifying representative fragment test',type='structs']
1364--
1365If the pname:pNext chain of slink:VkGraphicsPipelineCreateInfo includes a
1366sname:VkPipelineRepresentativeFragmentTestStateCreateInfoNV structure, then
1367that structure includes parameters that control the representative fragment
1368test.
1369
1370The sname:VkPipelineRepresentativeFragmentTestStateCreateInfoNV structure is
1371defined as:
1372
1373include::{generated}/api/structs/VkPipelineRepresentativeFragmentTestStateCreateInfoNV.txt[]
1374
1375  * pname:sType is the type of this structure.
1376  * pname:pNext is `NULL` or a pointer to a structure extending this
1377    structure.
1378  * pname:representativeFragmentTestEnable controls whether the
1379    representative fragment test is enabled.
1380
1381If this structure is not included in the pname:pNext chain,
1382pname:representativeFragmentTestEnable is considered to be ename:VK_FALSE,
1383and the representative fragment test is disabled.
1384
1385If the active fragment shader specifies the code:EarlyFragmentTests
1386execution mode, the representative fragment shader test has no effect, even
1387if enabled.
1388
1389include::{generated}/validity/structs/VkPipelineRepresentativeFragmentTestStateCreateInfoNV.txt[]
1390--
1391
1392endif::VK_NV_representative_fragment_test[]
1393
1394
1395[[fragops-samplecount]]
1396== Sample Counting
1397
1398Occlusion queries use query pool entries to track the number of samples that
1399pass all the per-fragment tests.
1400The mechanism of collecting an occlusion query value is described in
1401<<queries-occlusion,Occlusion Queries>>.
1402
1403The occlusion query sample counter increments by one for each sample with a
1404coverage value of 1 in each fragment that survives all the per-fragment
1405tests, including scissor,
1406ifdef::VK_NV_scissor_exclusive[]
1407exclusive scissor,
1408endif::VK_NV_scissor_exclusive[]
1409sample mask, alpha to coverage, stencil, and depth tests.
1410
1411
1412ifdef::VK_NV_fragment_coverage_to_color[]
1413[[fragops-coverage-to-color]]
1414== Fragment Coverage To Color
1415
1416[open,refpage='VkPipelineCoverageToColorStateCreateInfoNV',desc='Structure specifying whether fragment coverage replaces a color',type='structs']
1417--
1418The sname:VkPipelineCoverageToColorStateCreateInfoNV structure is defined
1419as:
1420
1421include::{generated}/api/structs/VkPipelineCoverageToColorStateCreateInfoNV.txt[]
1422
1423  * pname:sType is the type of this structure.
1424  * pname:pNext is `NULL` or a pointer to a structure extending this
1425    structure.
1426  * pname:flags is reserved for future use.
1427  * pname:coverageToColorEnable controls whether the fragment coverage value
1428    replaces a fragment color output.
1429  * pname:coverageToColorLocation controls which fragment shader color
1430    output value is replaced.
1431
1432If the pname:pNext chain of slink:VkPipelineMultisampleStateCreateInfo
1433includes a sname:VkPipelineCoverageToColorStateCreateInfoNV structure, then
1434that structure controls whether the fragment coverage is substituted for a
1435fragment color output and, if so, which output is replaced.
1436
1437If pname:coverageToColorEnable is ename:VK_TRUE, the
1438<<primsrast-multisampling-coverage-mask, coverage mask>> replaces the first
1439component of the color value corresponding to the fragment shader output
1440location with code:Location equal to pname:coverageToColorLocation and
1441code:Index equal to zero.
1442If the color attachment format has fewer bits than the coverage mask, the
1443low bits of the sample coverage mask are taken without any clamping.
1444If the color attachment format has more bits than the coverage mask, the
1445high bits of the sample coverage mask are filled with zeros.
1446
1447If pname:coverageToColorEnable is ename:VK_FALSE, these operations are
1448skipped.
1449If this structure is not included in the pname:pNext chain, it is as if
1450pname:coverageToColorEnable is ename:VK_FALSE.
1451
1452.Valid Usage
1453****
1454  * [[VUID-VkPipelineCoverageToColorStateCreateInfoNV-coverageToColorEnable-01404]]
1455    If pname:coverageToColorEnable is ename:VK_TRUE, then the render pass
1456    subpass indicated by
1457    slink:VkGraphicsPipelineCreateInfo::pname:renderPass and
1458    slink:VkGraphicsPipelineCreateInfo::pname:subpass must: have a color
1459    attachment at the location selected by pname:coverageToColorLocation,
1460    with a elink:VkFormat of ename:VK_FORMAT_R8_UINT,
1461    ename:VK_FORMAT_R8_SINT, ename:VK_FORMAT_R16_UINT,
1462    ename:VK_FORMAT_R16_SINT, ename:VK_FORMAT_R32_UINT, or
1463    ename:VK_FORMAT_R32_SINT
1464****
1465
1466include::{generated}/validity/structs/VkPipelineCoverageToColorStateCreateInfoNV.txt[]
1467--
1468
1469[open,refpage='VkPipelineCoverageToColorStateCreateFlagsNV',desc='Reserved for future use',type='flags']
1470--
1471include::{generated}/api/flags/VkPipelineCoverageToColorStateCreateFlagsNV.txt[]
1472
1473tname:VkPipelineCoverageToColorStateCreateFlagsNV is a bitmask type for
1474setting a mask, but is currently reserved for future use.
1475--
1476endif::VK_NV_fragment_coverage_to_color[]
1477
1478
1479[[fragops-coverage-reduction]]
1480== Coverage Reduction
1481
1482Coverage reduction takes the coverage information for a fragment and
1483converts that to a boolean coverage value for each color sample in each
1484pixel covered by the fragment.
1485
1486
1487=== Pixel Coverage
1488
1489Coverage for each pixel is first extracted from the total fragment coverage
1490mask.
1491This consists of pname:rasterizationSamples unique coverage samples for each
1492pixel in the fragment area, each with a unique
1493<<primsrast-multisampling-coverage-mask, sample index>>.
1494If the fragment only contains a single pixel, coverage for the pixel is
1495equivalent to the fragment coverage.
1496
1497ifdef::VK_EXT_fragment_density_map[]
1498If the render pass has a fragment density map attachment and the fragment
1499covers multiple pixels, pixel coverage is generated in an
1500implementation-dependent manner.
1501If all samples in the fragment are covered, all samples will be covered in
1502each pixel coverage.
1503endif::VK_EXT_fragment_density_map[]
1504
1505ifdef::VK_NV_shading_rate_image[]
1506If a <<primsrast-shading-rate-image,shading rate image>> is used, and the
1507fragment covers multiple pixels, each pixel's coverage consists of the
1508coverage samples corresponding to that pixel, and each sample retains its
1509unique <<primsrast-multisampling-coverage-mask, sample index [eq]#i#>>.
1510endif::VK_NV_shading_rate_image[]
1511
1512ifdef::VK_KHR_fragment_shading_rate[]
1513If the <<primsrast-fragment-shading-rate, fragment shading rate>> is set,
1514and the fragment covers multiple pixels, each pixel's coverage consists of
1515the coverage samples with a <<primsrast-multisampling-coverage-mask-vrfs,
1516pixel index>> matching that pixel, and each sample retains its unique
1517<<primsrast-multisampling-coverage-mask, sample index [eq]#i#>>.
1518endif::VK_KHR_fragment_shading_rate[]
1519
1520=== Color Sample Coverage
1521
1522Once pixel coverage is determined, coverage for each individual color sample
1523corresponding to that pixel is determined.
1524
1525ifdef::VK_AMD_mixed_attachment_samples,VK_NV_framebuffer_mixed_samples,VK_NV_coverage_reduction_mode[If the]
1526ifndef::VK_AMD_mixed_attachment_samples,VK_NV_framebuffer_mixed_samples,VK_NV_coverage_reduction_mode[The]
1527number of pname:rasterizationSamples is identical to the number of samples
1528in the color attachments.
1529A color sample is covered if the pixel coverage sample with the same
1530<<primsrast-multisampling-coverage-mask, sample index>> [eq]#i# is covered.
1531
1532ifdef::VK_AMD_mixed_attachment_samples,VK_NV_framebuffer_mixed_samples,VK_NV_coverage_reduction_mode[]
1533Otherwise, the coverage for each color sample is computed from the pixel
1534coverage as follows.
1535endif::VK_AMD_mixed_attachment_samples,VK_NV_framebuffer_mixed_samples,VK_NV_coverage_reduction_mode[]
1536
1537ifdef::VK_AMD_mixed_attachment_samples[]
1538If the `apiext:VK_AMD_mixed_attachment_samples` extension is enabled, for
1539color samples present in the color attachments, a color sample is covered if
1540the pixel coverage sample with the same
1541<<primsrast-multisampling-coverage-mask, sample index>> [eq]#i# is covered;
1542additional pixel coverage samples are discarded.
1543endif::VK_AMD_mixed_attachment_samples[]
1544
1545ifdef::VK_NV_framebuffer_mixed_samples[]
1546
1547ifndef::VK_NV_coverage_reduction_mode[]
1548When the `apiext:VK_NV_framebuffer_mixed_samples` extension is enabled, if
1549the pipeline's
1550slink:VkPipelineMultisampleStateCreateInfo::pname:rasterizationSamples is
1551greater than the slink:VkAttachmentDescription::pname:samples of the color
1552attachments in the subpass, each color sample will be associated with an
1553implementation-dependent subset of samples in the pixel coverage.
1554If any of those associated samples are covered, the color sample is covered.
1555endif::VK_NV_coverage_reduction_mode[]
1556
1557ifdef::VK_NV_coverage_reduction_mode[]
1558When the `apiext:VK_NV_coverage_reduction_mode` extension is enabled, the
1559pipeline state controlling coverage reduction is specified through the
1560members of the sname:VkPipelineCoverageReductionStateCreateInfoNV structure.
1561
1562[open,refpage='VkPipelineCoverageReductionStateCreateInfoNV',desc='Structure specifying parameters controlling coverage reduction',type='structs']
1563--
1564The sname:VkPipelineCoverageReductionStateCreateInfoNV structure is defined
1565as:
1566
1567include::{generated}/api/structs/VkPipelineCoverageReductionStateCreateInfoNV.txt[]
1568
1569  * pname:sType is the type of this structure.
1570  * pname:pNext is `NULL` or a pointer to a structure extending this
1571    structure.
1572  * pname:flags is reserved for future use.
1573  * pname:coverageReductionMode is a elink:VkCoverageReductionModeNV value
1574    controlling how color sample coverage is generated from pixel coverage.
1575
1576If this structure is not included in the pname:pNext chain, or if the
1577extension is not enabled, the default coverage reduction mode is inferred as
1578follows:
1579
1580  * If the `apiext:VK_NV_framebuffer_mixed_samples` extension is enabled,
1581    then it is as if the pname:coverageReductionMode is
1582    ename:VK_COVERAGE_REDUCTION_MODE_MERGE_NV.
1583  * If the `apiext:VK_AMD_mixed_attachment_samples` extension is enabled,
1584    then it is as if the pname:coverageReductionMode is
1585    ename:VK_COVERAGE_REDUCTION_MODE_TRUNCATE_NV.
1586  * If both `apiext:VK_NV_framebuffer_mixed_samples` and
1587    `apiext:VK_AMD_mixed_attachment_samples` are enabled, then the default
1588    coverage reduction mode is implementation-dependent.
1589
1590include::{generated}/validity/structs/VkPipelineCoverageReductionStateCreateInfoNV.txt[]
1591--
1592
1593[open,refpage='VkPipelineCoverageReductionStateCreateFlagsNV',desc='Reserved for future use',type='flags']
1594--
1595include::{generated}/api/flags/VkPipelineCoverageReductionStateCreateFlagsNV.txt[]
1596
1597tname:VkPipelineCoverageReductionStateCreateFlagsNV is a bitmask type for
1598setting a mask, but is currently reserved for future use.
1599--
1600
1601[open,refpage='VkCoverageReductionModeNV',desc='Specify the coverage reduction mode',type='enums']
1602--
1603Possible values of
1604slink:VkPipelineCoverageReductionStateCreateInfoNV::pname:coverageReductionMode,
1605specifying how color sample coverage is generated from pixel coverage, are:
1606
1607include::{generated}/api/enums/VkCoverageReductionModeNV.txt[]
1608
1609  * ename:VK_COVERAGE_REDUCTION_MODE_MERGE_NV specifies that each color
1610    sample will be associated with an implementation-dependent subset of
1611    samples in the pixel coverage.
1612    If any of those associated samples are covered, the color sample is
1613    covered.
1614  * ename:VK_COVERAGE_REDUCTION_MODE_TRUNCATE_NV specifies that for color
1615    samples present in the color attachments, a color sample is covered if
1616    the pixel coverage sample with the same
1617    <<primsrast-multisampling-coverage-mask, sample index>> [eq]#i# is
1618    covered; other pixel coverage samples are discarded.
1619--
1620
1621[open,refpage='vkGetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV',desc='Query supported sample count combinations',type='protos']
1622--
1623To query the set of mixed sample combinations of coverage reduction mode,
1624rasterization samples and color, depth, stencil attachment sample counts
1625that are supported by a physical device, call:
1626
1627include::{generated}/api/protos/vkGetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV.txt[]
1628
1629  * pname:physicalDevice is the physical device from which to query the set
1630    of combinations.
1631  * pname:pCombinationCount is a pointer to an integer related to the number
1632    of combinations available or queried, as described below.
1633  * pname:pCombinations is either `NULL` or a pointer to an array of
1634    slink:VkFramebufferMixedSamplesCombinationNV values, indicating the
1635    supported combinations of coverage reduction mode, rasterization
1636    samples, and color, depth, stencil attachment sample counts.
1637
1638If pname:pCombinations is `NULL`, then the number of supported combinations
1639for the given pname:physicalDevice is returned in pname:pCombinationCount.
1640Otherwise, pname:pCombinationCount must: point to a variable set by the user
1641to the number of elements in the pname:pCombinations array, and on return
1642the variable is overwritten with the number of values actually written to
1643pname:pCombinations.
1644If the value of pname:pCombinationCount is less than the number of
1645combinations supported for the given pname:physicalDevice, at most
1646pname:pCombinationCount values will be written to pname:pCombinations, and
1647ename:VK_INCOMPLETE will be returned instead of ename:VK_SUCCESS, to
1648indicate that not all the supported values were returned.
1649
1650include::{generated}/validity/protos/vkGetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV.txt[]
1651--
1652
1653[open,refpage='VkFramebufferMixedSamplesCombinationNV',desc='Structure specifying a supported sample count combination',type='structs']
1654--
1655The sname:VkFramebufferMixedSamplesCombinationNV structure is defined as:
1656
1657include::{generated}/api/structs/VkFramebufferMixedSamplesCombinationNV.txt[]
1658
1659  * pname:sType is the type of this structure.
1660  * pname:pNext is `NULL` or a pointer to a structure extending this
1661    structure.
1662  * pname:coverageReductionMode is a elink:VkCoverageReductionModeNV value
1663    specifying the coverage reduction mode.
1664  * pname:rasterizationSamples is a elink:VkSampleCountFlagBits specifying
1665    the number of rasterization samples in the supported combination.
1666  * pname:depthStencilSamples specifies the number of samples in the depth
1667    stencil attachment in the supported combination.
1668    A value of 0 indicates the combination does not have a depth stencil
1669    attachment.
1670  * pname:colorSamples specifies the number of color samples in a color
1671    attachment in the supported combination.
1672    A value of 0 indicates the combination does not have a color attachment.
1673
1674include::{generated}/validity/structs/VkFramebufferMixedSamplesCombinationNV.txt[]
1675--
1676endif::VK_NV_coverage_reduction_mode[]
1677
1678
1679[[fragops-coverage-modulation]]
1680=== Coverage Modulation
1681
1682[open,refpage='VkPipelineCoverageModulationStateCreateInfoNV',desc='Structure specifying parameters controlling coverage modulation',type='structs']
1683--
1684As part of coverage reduction, fragment color values can: also be modulated
1685(multiplied) by a value that is a function of fraction of covered
1686rasterization samples associated with that color sample.
1687
1688Pipeline state controlling coverage modulation is specified through the
1689members of the sname:VkPipelineCoverageModulationStateCreateInfoNV
1690structure.
1691
1692The sname:VkPipelineCoverageModulationStateCreateInfoNV structure is defined
1693as:
1694
1695include::{generated}/api/structs/VkPipelineCoverageModulationStateCreateInfoNV.txt[]
1696
1697  * pname:sType is the type of this structure.
1698  * pname:pNext is `NULL` or a pointer to a structure extending this
1699    structure.
1700  * pname:flags is reserved for future use.
1701  * pname:coverageModulationMode is a elink:VkCoverageModulationModeNV value
1702    controlling which color components are modulated.
1703  * pname:coverageModulationTableEnable controls whether the modulation
1704    factor is looked up from a table in pname:pCoverageModulationTable.
1705  * pname:coverageModulationTableCount is the number of elements in
1706    pname:pCoverageModulationTable.
1707  * pname:pCoverageModulationTable is a table of modulation factors
1708    containing a value for each number of covered samples.
1709
1710If pname:coverageModulationTableEnable is ename:VK_FALSE, then for each
1711color sample the associated bits of the pixel coverage are counted and
1712divided by the number of associated bits to produce a modulation factor
1713[eq]#R# in the range [eq]#(0,1]# (a value of zero would have been killed due
1714to a color coverage of 0).
1715Specifically:
1716
1717  * [eq]#N# = value of pname:rasterizationSamples
1718  * [eq]#M# = value of slink:VkAttachmentDescription::pname:samples for any
1719    color attachments
1720  * [eq]#R = popcount(associated coverage bits) / (N / M)#
1721
1722If pname:coverageModulationTableEnable is ename:VK_TRUE, the value [eq]#R#
1723is computed using a programmable lookup table.
1724The lookup table has [eq]#N / M# elements, and the element of the table is
1725selected by:
1726
1727  * [eq]#R = pname:pCoverageModulationTable[popcount(associated coverage
1728    bits)-1]#
1729
1730Note that the table does not have an entry for [eq]#popcount(associated
1731coverage bits) = 0#, because such samples would have been killed.
1732
1733The values of pname:pCoverageModulationTable may: be rounded to an
1734implementation-dependent precision, which is at least as fine as [eq]#1 /
1735N#, and clamped to [eq]#[0,1]#.
1736
1737For each color attachment with a floating point or normalized color format,
1738each fragment output color value is replicated to [eq]#M# values which can:
1739each be modulated (multiplied) by that color sample's associated value of
1740[eq]#R#.
1741Which components are modulated is controlled by
1742pname:coverageModulationMode.
1743
1744If this structure is not included in the pname:pNext chain, it is as if
1745pname:coverageModulationMode is ename:VK_COVERAGE_MODULATION_MODE_NONE_NV.
1746
1747ifdef::VK_NV_coverage_reduction_mode[]
1748If the <<fragops-coverage-reduction, coverage reduction mode>> is
1749ename:VK_COVERAGE_REDUCTION_MODE_TRUNCATE_NV, each color sample is
1750associated with only a single coverage sample.
1751In this case, it is as if pname:coverageModulationMode is
1752ename:VK_COVERAGE_MODULATION_MODE_NONE_NV.
1753endif::VK_NV_coverage_reduction_mode[]
1754
1755.Valid Usage
1756****
1757  * [[VUID-VkPipelineCoverageModulationStateCreateInfoNV-coverageModulationTableEnable-01405]]
1758    If pname:coverageModulationTableEnable is ename:VK_TRUE,
1759    pname:coverageModulationTableCount must: be equal to the number of
1760    rasterization samples divided by the number of color samples in the
1761    subpass
1762****
1763
1764include::{generated}/validity/structs/VkPipelineCoverageModulationStateCreateInfoNV.txt[]
1765--
1766
1767[open,refpage='VkPipelineCoverageModulationStateCreateFlagsNV',desc='Reserved for future use',type='flags']
1768--
1769include::{generated}/api/flags/VkPipelineCoverageModulationStateCreateFlagsNV.txt[]
1770
1771tname:VkPipelineCoverageModulationStateCreateFlagsNV is a bitmask type for
1772setting a mask, but is currently reserved for future use.
1773--
1774
1775[open,refpage='VkCoverageModulationModeNV',desc='Specify the coverage modulation mode',type='enums']
1776--
1777Possible values of
1778slink:VkPipelineCoverageModulationStateCreateInfoNV::pname:coverageModulationMode,
1779specifying which color components are modulated, are:
1780
1781include::{generated}/api/enums/VkCoverageModulationModeNV.txt[]
1782
1783  * ename:VK_COVERAGE_MODULATION_MODE_NONE_NV specifies that no components
1784    are multiplied by the modulation factor.
1785  * ename:VK_COVERAGE_MODULATION_MODE_RGB_NV specifies that the red, green,
1786    and blue components are multiplied by the modulation factor.
1787  * ename:VK_COVERAGE_MODULATION_MODE_ALPHA_NV specifies that the alpha
1788    component is multiplied by the modulation factor.
1789  * ename:VK_COVERAGE_MODULATION_MODE_RGBA_NV specifies that all components
1790    are multiplied by the modulation factor.
1791--
1792
1793endif::VK_NV_framebuffer_mixed_samples[]
1794