1e5c31af7Sopenharmony_ci// Copyright 2015-2024 The Khronos Group Inc.
2e5c31af7Sopenharmony_ci//
3e5c31af7Sopenharmony_ci// SPDX-License-Identifier: CC-BY-4.0
4e5c31af7Sopenharmony_ci
5e5c31af7Sopenharmony_ci[appendix]
6e5c31af7Sopenharmony_ci[[invariance]]
7e5c31af7Sopenharmony_ci= Invariance
8e5c31af7Sopenharmony_ci
9e5c31af7Sopenharmony_ciThe Vulkan specification is not pixel exact.
10e5c31af7Sopenharmony_ciIt therefore does not guarantee an exact match between images produced by
11e5c31af7Sopenharmony_cidifferent Vulkan implementations.
12e5c31af7Sopenharmony_ciHowever, the specification does specify exact matches, in some cases, for
13e5c31af7Sopenharmony_ciimages produced by the same implementation.
14e5c31af7Sopenharmony_ciThe purpose of this appendix is to identify and provide justification for
15e5c31af7Sopenharmony_cithose cases that require exact matches.
16e5c31af7Sopenharmony_ci
17e5c31af7Sopenharmony_ci== Repeatability
18e5c31af7Sopenharmony_ci
19e5c31af7Sopenharmony_ciThe obvious and most fundamental case is repeated issuance of a series of
20e5c31af7Sopenharmony_ciVulkan commands.
21e5c31af7Sopenharmony_ciFor any given Vulkan and framebuffer state vector, and for any Vulkan
22e5c31af7Sopenharmony_cicommand, the resulting Vulkan and framebuffer state must: be identical
23e5c31af7Sopenharmony_ciwhenever the command is executed on that initial Vulkan and framebuffer
24e5c31af7Sopenharmony_cistate.
25e5c31af7Sopenharmony_ciThis repeatability requirement does not apply when using shaders containing
26e5c31af7Sopenharmony_ciside effects (image and buffer variable stores and atomic operations),
27e5c31af7Sopenharmony_cibecause these memory operations are not guaranteed to be processed in a
28e5c31af7Sopenharmony_cidefined order.
29e5c31af7Sopenharmony_ci
30e5c31af7Sopenharmony_ciifdef::VK_AMD_rasterization_order[]
31e5c31af7Sopenharmony_ciThe repeatability requirement does not apply for rendering done using a
32e5c31af7Sopenharmony_cigraphics pipeline that uses ename:VK_RASTERIZATION_ORDER_RELAXED_AMD.
33e5c31af7Sopenharmony_ciendif::VK_AMD_rasterization_order[]
34e5c31af7Sopenharmony_ci
35e5c31af7Sopenharmony_ciOne purpose of repeatability is avoidance of visual artifacts when a
36e5c31af7Sopenharmony_cidouble-buffered scene is redrawn.
37e5c31af7Sopenharmony_ciIf rendering is not repeatable, swapping between two buffers rendered with
38e5c31af7Sopenharmony_cithe same command sequence may: result in visible changes in the image.
39e5c31af7Sopenharmony_ciSuch false motion is distracting to the viewer.
40e5c31af7Sopenharmony_ciAnother reason for repeatability is testability.
41e5c31af7Sopenharmony_ci
42e5c31af7Sopenharmony_ciRepeatability, while important, is a weak requirement.
43e5c31af7Sopenharmony_ciGiven only repeatability as a requirement, two scenes rendered with one
44e5c31af7Sopenharmony_ci(small) polygon changed in position might differ at every pixel.
45e5c31af7Sopenharmony_ciSuch a difference, while within the law of repeatability, is certainly not
46e5c31af7Sopenharmony_ciwithin its spirit.
47e5c31af7Sopenharmony_ciAdditional invariance rules are desirable to ensure useful operation.
48e5c31af7Sopenharmony_ci
49e5c31af7Sopenharmony_ci
50e5c31af7Sopenharmony_ci== Multi-pass Algorithms
51e5c31af7Sopenharmony_ci
52e5c31af7Sopenharmony_ciInvariance is necessary for a whole set of useful multi-pass algorithms.
53e5c31af7Sopenharmony_ciSuch algorithms render multiple times, each time with a different Vulkan
54e5c31af7Sopenharmony_cimode vector, to eventually produce a result in the framebuffer.
55e5c31af7Sopenharmony_ciExamples of these algorithms include:
56e5c31af7Sopenharmony_ci
57e5c31af7Sopenharmony_ci  * "`Erasing`" a primitive from the framebuffer by redrawing it, either in
58e5c31af7Sopenharmony_ci    a different color or using the XOR logical operation.
59e5c31af7Sopenharmony_ci  * Using stencil operations to compute capping planes.
60e5c31af7Sopenharmony_ci
61e5c31af7Sopenharmony_ci
62e5c31af7Sopenharmony_ci== Invariance Rules
63e5c31af7Sopenharmony_ci
64e5c31af7Sopenharmony_ciFor a given Vulkan device:
65e5c31af7Sopenharmony_ci
66e5c31af7Sopenharmony_ci*Rule 1* _For any given Vulkan and framebuffer state vector, and for any
67e5c31af7Sopenharmony_cigiven Vulkan command, the resulting Vulkan and framebuffer state must: be
68e5c31af7Sopenharmony_ciidentical each time the command is executed on that initial Vulkan and
69e5c31af7Sopenharmony_ciframebuffer state._
70e5c31af7Sopenharmony_ci
71e5c31af7Sopenharmony_ci*Rule 2* _Changes to the following state values have no side effects (the
72e5c31af7Sopenharmony_ciuse of any other state value is not affected by the change):_
73e5c31af7Sopenharmony_ci
74e5c31af7Sopenharmony_ci*Required:*
75e5c31af7Sopenharmony_ci
76e5c31af7Sopenharmony_ci  * _Color and depth/stencil attachment contents_
77e5c31af7Sopenharmony_ci  * _Scissor parameters (other than enable)_
78e5c31af7Sopenharmony_ci  * _Write masks (color, depth, stencil)_
79e5c31af7Sopenharmony_ci  * _Clear values (color, depth, stencil)_
80e5c31af7Sopenharmony_ci
81e5c31af7Sopenharmony_ci*Strongly suggested:*
82e5c31af7Sopenharmony_ci
83e5c31af7Sopenharmony_ci  * _Stencil parameters (other than enable)_
84e5c31af7Sopenharmony_ci  * _Depth test parameters (other than enable)_
85e5c31af7Sopenharmony_ci  * _Blend parameters (other than enable)_
86e5c31af7Sopenharmony_ci  * _Logical operation parameters (other than enable)_
87e5c31af7Sopenharmony_ci
88e5c31af7Sopenharmony_ci*Corollary 1* _Fragment generation is invariant with respect to the state
89e5c31af7Sopenharmony_civalues listed in Rule 2._
90e5c31af7Sopenharmony_ci
91e5c31af7Sopenharmony_ci*Rule 3* _The arithmetic of each per-fragment operation is invariant except
92e5c31af7Sopenharmony_ciwith respect to parameters that directly control it._
93e5c31af7Sopenharmony_ci
94e5c31af7Sopenharmony_ci*Corollary 2* _Images rendered into different color attachments of the same
95e5c31af7Sopenharmony_ciframebuffer, either simultaneously or separately using the same command
96e5c31af7Sopenharmony_cisequence, are pixel identical._
97e5c31af7Sopenharmony_ci
98e5c31af7Sopenharmony_ci*Rule 4* _Identical pipelines will produce the same result when run multiple
99e5c31af7Sopenharmony_citimes with the same input.
100e5c31af7Sopenharmony_ciThe wording "`Identical pipelines`" means slink:VkPipeline objects that have
101e5c31af7Sopenharmony_cibeen created with identical SPIR-V binaries and identical state, which are
102e5c31af7Sopenharmony_cithen used by commands executed using the same Vulkan state vector.
103e5c31af7Sopenharmony_ciInvariance is relaxed for shaders with side effects, such as performing
104e5c31af7Sopenharmony_cistores or atomics._
105e5c31af7Sopenharmony_ci
106e5c31af7Sopenharmony_ci*Rule 5* _All fragment shaders that either conditionally or unconditionally
107e5c31af7Sopenharmony_ciassign_ code:FragCoord.z _to_ code:FragDepth _are depth-invariant with
108e5c31af7Sopenharmony_cirespect to each other, for those fragments where the assignment to_
109e5c31af7Sopenharmony_cicode:FragDepth _actually is done._
110e5c31af7Sopenharmony_ci
111e5c31af7Sopenharmony_ciIf a sequence of Vulkan commands specifies primitives to be rendered with
112e5c31af7Sopenharmony_cishaders containing side effects (image and buffer variable stores and atomic
113e5c31af7Sopenharmony_cioperations), invariance rules are relaxed.
114e5c31af7Sopenharmony_ciIn particular, rule 1, corollary 2, and rule 4 do not apply in the presence
115e5c31af7Sopenharmony_ciof shader side effects.
116e5c31af7Sopenharmony_ci
117e5c31af7Sopenharmony_ciThe following weaker versions of rules 1 and 4 apply to Vulkan commands
118e5c31af7Sopenharmony_ciinvolving shader side effects:
119e5c31af7Sopenharmony_ci
120e5c31af7Sopenharmony_ci*Rule 6* _For any given Vulkan and framebuffer state vector, and for any
121e5c31af7Sopenharmony_cigiven Vulkan command, the contents of any framebuffer state not directly or
122e5c31af7Sopenharmony_ciindirectly affected by results of shader image or buffer variable stores or
123e5c31af7Sopenharmony_ciatomic operations must: be identical each time the command is executed on
124e5c31af7Sopenharmony_cithat initial Vulkan and framebuffer state._
125e5c31af7Sopenharmony_ci
126e5c31af7Sopenharmony_ci*Rule 7* _Identical pipelines will produce the same result when run multiple
127e5c31af7Sopenharmony_citimes with the same input as long as:_
128e5c31af7Sopenharmony_ci
129e5c31af7Sopenharmony_ci  * _shader invocations do not use image atomic operations;_
130e5c31af7Sopenharmony_ci  * _no framebuffer memory is written to more than once by image stores,
131e5c31af7Sopenharmony_ci    unless all such stores write the same value; and_
132e5c31af7Sopenharmony_ci  * _no shader invocation, or other operation performed to process the
133e5c31af7Sopenharmony_ci    sequence of commands, reads memory written to by an image store._
134e5c31af7Sopenharmony_ci
135e5c31af7Sopenharmony_ci
136e5c31af7Sopenharmony_ci[NOTE]
137e5c31af7Sopenharmony_ci.Note
138e5c31af7Sopenharmony_ci====
139e5c31af7Sopenharmony_ciThe OpenGL specification has the following invariance rule: Consider a
140e5c31af7Sopenharmony_ciprimitive p' obtained by translating a primitive p through an offset (x, y)
141e5c31af7Sopenharmony_ciin window coordinates, where x and y are integers.
142e5c31af7Sopenharmony_ciAs long as neither p' nor p is clipped, it must: be the case that each
143e5c31af7Sopenharmony_cifragment f' produced from p' is identical to a corresponding fragment f from
144e5c31af7Sopenharmony_cip except that the center of f' is offset by (x, y) from the center of f.
145e5c31af7Sopenharmony_ci
146e5c31af7Sopenharmony_ciThis rule does not apply to Vulkan and is an intentional difference from
147e5c31af7Sopenharmony_ciOpenGL.
148e5c31af7Sopenharmony_ci====
149e5c31af7Sopenharmony_ci
150e5c31af7Sopenharmony_ciWhen any sequence of Vulkan commands triggers shader invocations that
151e5c31af7Sopenharmony_ciperform image stores or atomic operations, and subsequent Vulkan commands
152e5c31af7Sopenharmony_ciread the memory written by those shader invocations, these operations must:
153e5c31af7Sopenharmony_cibe explicitly synchronized.
154e5c31af7Sopenharmony_ci
155e5c31af7Sopenharmony_ci
156e5c31af7Sopenharmony_ci== Tessellation Invariance
157e5c31af7Sopenharmony_ci
158e5c31af7Sopenharmony_ciWhen using a pipeline containing tessellation evaluation shaders, the
159e5c31af7Sopenharmony_cifixed-function tessellation primitive generator consumes the input patch
160e5c31af7Sopenharmony_cispecified by an application and emits a new set of primitives.
161e5c31af7Sopenharmony_ciThe following invariance rules are intended to provide repeatability
162e5c31af7Sopenharmony_ciguarantees.
163e5c31af7Sopenharmony_ciAdditionally, they are intended to allow an application with a carefully
164e5c31af7Sopenharmony_cicrafted tessellation evaluation shader to ensure that the sets of triangles
165e5c31af7Sopenharmony_cigenerated for two adjacent patches have identical vertices along shared
166e5c31af7Sopenharmony_cipatch edges, avoiding "`cracks`" caused by minor differences in the
167e5c31af7Sopenharmony_cipositions of vertices along shared edges.
168e5c31af7Sopenharmony_ci
169e5c31af7Sopenharmony_ci*Rule 1* _When processing two patches with identical outer and inner
170e5c31af7Sopenharmony_citessellation levels, the tessellation primitive generator will emit an
171e5c31af7Sopenharmony_ciidentical set of point, line, or triangle primitives as long as the pipeline
172e5c31af7Sopenharmony_ciused to process the patch primitives has tessellation evaluation shaders
173e5c31af7Sopenharmony_cispecifying the same tessellation mode, spacing, vertex order, and point mode
174e5c31af7Sopenharmony_cidecorations.
175e5c31af7Sopenharmony_ciTwo sets of primitives are considered identical if and only if they contain
176e5c31af7Sopenharmony_cithe same number and type of primitives and the generated tessellation
177e5c31af7Sopenharmony_cicoordinates for the vertex numbered m of the primitive numbered n are
178e5c31af7Sopenharmony_ciidentical for all values of m and n._
179e5c31af7Sopenharmony_ci
180e5c31af7Sopenharmony_ci*Rule 2* _The set of vertices generated along the outer edge of the
181e5c31af7Sopenharmony_cisubdivided primitive in triangle and quad tessellation, and the tessellation
182e5c31af7Sopenharmony_cicoordinates of each, depend only on the corresponding outer tessellation
183e5c31af7Sopenharmony_cilevel and the spacing decorations in the tessellation shaders of the
184e5c31af7Sopenharmony_cipipeline._
185e5c31af7Sopenharmony_ci
186e5c31af7Sopenharmony_ci*Rule 3* _The set of vertices generated when subdividing any outer primitive
187e5c31af7Sopenharmony_ciedge is always symmetric.
188e5c31af7Sopenharmony_ciFor triangle tessellation, if the subdivision generates a vertex with
189e5c31af7Sopenharmony_citessellation coordinates of the form (0, x, 1-x), (x, 0, 1-x), or (x, 1-x,
190e5c31af7Sopenharmony_ci0), it will also generate a vertex with coordinates of exactly (0, 1-x, x),
191e5c31af7Sopenharmony_ci(1-x, 0, x), or (1-x, x, 0), respectively.
192e5c31af7Sopenharmony_ciFor quad tessellation, if the subdivision generates a vertex with
193e5c31af7Sopenharmony_cicoordinates of (x, 0) or (0, x), it will also generate a vertex with
194e5c31af7Sopenharmony_cicoordinates of exactly (1-x, 0) or (0, 1-x), respectively.
195e5c31af7Sopenharmony_ciFor isoline tessellation, if it generates vertices at (0, x) and (1, x)
196e5c31af7Sopenharmony_ciwhere x is not zero, it will also generate vertices at exactly (0, 1-x) and
197e5c31af7Sopenharmony_ci(1, 1-x), respectively._
198e5c31af7Sopenharmony_ci
199e5c31af7Sopenharmony_ci*Rule 4* _The set of vertices generated when subdividing outer edges in
200e5c31af7Sopenharmony_citriangular and quad tessellation must: be independent of the specific edge
201e5c31af7Sopenharmony_cisubdivided, given identical outer tessellation levels and spacing.
202e5c31af7Sopenharmony_ciFor example, if vertices at (x, 1 - x, 0) and (1-x, x, 0) are generated when
203e5c31af7Sopenharmony_cisubdividing the w = 0 edge in triangular tessellation, vertices must: be
204e5c31af7Sopenharmony_cigenerated at (x, 0, 1-x) and (1-x, 0, x) when subdividing an otherwise
205e5c31af7Sopenharmony_ciidentical v = 0 edge.
206e5c31af7Sopenharmony_ciFor quad tessellation, if vertices at (x, 0) and (1-x, 0) are generated when
207e5c31af7Sopenharmony_cisubdividing the v = 0 edge, vertices must: be generated at (0, x) and (0,
208e5c31af7Sopenharmony_ci1-x) when subdividing an otherwise identical u = 0 edge._
209e5c31af7Sopenharmony_ci
210e5c31af7Sopenharmony_ci*Rule 5* _When processing two patches that are identical in all respects
211e5c31af7Sopenharmony_cienumerated in rule 1 except for vertex order, the set of triangles generated
212e5c31af7Sopenharmony_cifor triangle and quad tessellation must: be identical except for vertex and
213e5c31af7Sopenharmony_citriangle order.
214e5c31af7Sopenharmony_ciFor each triangle n1 produced by processing the first patch, there must: be
215e5c31af7Sopenharmony_cia triangle n2 produced when processing the second patch each of whose
216e5c31af7Sopenharmony_civertices has the same tessellation coordinates as one of the vertices in
217e5c31af7Sopenharmony_cin1._
218e5c31af7Sopenharmony_ci
219e5c31af7Sopenharmony_ci*Rule 6* _When processing two patches that are identical in all respects
220e5c31af7Sopenharmony_cienumerated in rule 1 other than matching outer tessellation levels and/or
221e5c31af7Sopenharmony_civertex order, the set of interior triangles generated for triangle and quad
222e5c31af7Sopenharmony_citessellation must: be identical in all respects except for vertex and
223e5c31af7Sopenharmony_citriangle order.
224e5c31af7Sopenharmony_ciFor each interior triangle n1 produced by processing the first patch, there
225e5c31af7Sopenharmony_cimust: be a triangle n2 produced when processing the second patch each of
226e5c31af7Sopenharmony_ciwhose vertices has the same tessellation coordinates as one of the vertices
227e5c31af7Sopenharmony_ciin n1.
228e5c31af7Sopenharmony_ciA triangle produced by the tessellator is considered an interior triangle if
229e5c31af7Sopenharmony_cinone of its vertices lie on an outer edge of the subdivided primitive._
230e5c31af7Sopenharmony_ci
231e5c31af7Sopenharmony_ci*Rule 7* _For quad and triangle tessellation, the set of triangles
232e5c31af7Sopenharmony_ciconnecting an inner and outer edge depends only on the inner and outer
233e5c31af7Sopenharmony_citessellation levels corresponding to that edge and the spacing decorations._
234e5c31af7Sopenharmony_ci
235e5c31af7Sopenharmony_ci*Rule 8* _The value of all defined components of_ code:TessCoord _will be in
236e5c31af7Sopenharmony_cithe range [0, 1].
237e5c31af7Sopenharmony_ciAdditionally, for any defined component x of_ code:TessCoord, _the results
238e5c31af7Sopenharmony_ciof computing 1.0-x in a tessellation evaluation shader will be exact.
239e5c31af7Sopenharmony_ciIf any floating-point values in the range [0, 1] fail to satisfy this
240e5c31af7Sopenharmony_ciproperty, such values must: not be used as tessellation coordinate
241e5c31af7Sopenharmony_cicomponents._
242