| // Copyright 2015-2021 The Khronos Group, Inc. |
| // |
| // SPDX-License-Identifier: CC-BY-4.0 |
| |
| [appendix] |
| [[spirvenv]] |
| = Vulkan Environment for SPIR-V |
| |
| Shaders for Vulkan are defined by the <<spirv-spec,Khronos SPIR-V |
| Specification>> as well as the <<spirv-extended,Khronos SPIR-V Extended |
| Instructions for GLSL>> Specification. |
| This appendix defines additional SPIR-V requirements applying to Vulkan |
| shaders. |
| |
| == Versions and Formats |
| |
| A Vulkan |
| ifdef::VK_VERSION_1_2[] |
| 1.2 implementation must: support the 1.0, 1.1, 1.2, 1.3, 1.4, and 1.5 |
| versions |
| endif::VK_VERSION_1_2[] |
| ifndef::VK_VERSION_1_2[] |
| ifdef::VK_VERSION_1_1[] |
| 1.1 implementation must: support the 1.0, 1.1, 1.2, and 1.3 versions |
| endif::VK_VERSION_1_1[] |
| ifndef::VK_VERSION_1_1[] |
| 1.0 implementation must: support the 1.0 version |
| endif::VK_VERSION_1_1[] |
| endif::VK_VERSION_1_2[] |
| of SPIR-V and the 1.0 version of the SPIR-V Extended Instructions for GLSL. |
| ifndef::VK_VERSION_1_2[] |
| ifdef::VK_KHR_spirv_1_4[] |
| If the `apiext:VK_KHR_spirv_1_4` extension is enabled, the implementation |
| must: additionally support the 1.4 version of SPIR-V. |
| endif::VK_KHR_spirv_1_4[] |
| endif::VK_VERSION_1_2[] |
| |
| A SPIR-V module passed into flink:vkCreateShaderModule is interpreted as a |
| series of 32-bit words in host endianness, with literal strings packed as |
| described in section 2.2 of the SPIR-V Specification. |
| The first few words of the SPIR-V module must: be a magic number and a |
| SPIR-V version number, as described in section 2.3 of the SPIR-V |
| Specification. |
| |
| |
| [[spirvenv-capabilities]] |
| == Capabilities |
| |
| The <<spirvenv-capabilities-table,table below>> lists the set of SPIR-V |
| capabilities that may: be supported in Vulkan implementations. |
| The application must: not use any of these capabilities in SPIR-V passed to |
| flink:vkCreateShaderModule unless one of the following conditions is met for |
| the slink:VkDevice specified in the pname:device parameter of |
| flink:vkCreateShaderModule: |
| |
| * The corresponding field in the table is blank. |
| * Any corresponding Vulkan feature is enabled. |
| * Any corresponding Vulkan extension is enabled. |
| * Any corresponding Vulkan property is supported. |
| * The corresponding core version is supported (as returned by |
| slink:VkPhysicalDeviceProperties::pname:apiVersion). |
| |
| :captableindent: {nbsp} {nbsp} {nbsp} {nbsp} {nbsp} {nbsp} {nbsp} {nbsp} |
| [[spirvenv-capabilities-table]] |
| .List of SPIR-V Capabilities and corresponding Vulkan features, extensions, or core version |
| [options="header"] |
| |==== |
| | SPIR-V code:OpCapability + |
| {captableindent} Vulkan feature, extension, or core version |
| include::{generated}/spirvcap/captable.txt[] |
| |==== |
| |
| The application must: not pass a SPIR-V module containing any of the |
| following to flink:vkCreateShaderModule: |
| |
| * any code:OpCapability not listed above, |
| * an unsupported capability, or |
| * a capability which corresponds to a Vulkan feature or extension which |
| has not been enabled. |
| |
| |
| [[spirvenv-extensions]] |
| === SPIR-V Extensions |
| |
| The <<spirvenv-extensions-table,following table>> lists SPIR-V extensions |
| that implementations may: support. |
| The application must: not pass a SPIR-V module to flink:vkCreateShaderModule |
| that uses the following SPIR-V extensions unless one of the following |
| conditions is met for the slink:VkDevice specified in the pname:device |
| parameter of flink:vkCreateShaderModule: |
| |
| * Any corresponding Vulkan extension is enabled. |
| * The corresponding core version is supported (as returned by |
| slink:VkPhysicalDeviceProperties::pname:apiVersion). |
| |
| [[spirvenv-extensions-table]] |
| .List of SPIR-V Extensions and corresponding Vulkan extensions or core version |
| [options="header"] |
| |==== |
| | SPIR-V code:OpExtension + |
| {captableindent} Vulkan extension or core version |
| include::{generated}/spirvcap/exttable.txt[] |
| |==== |
| |
| |
| [[spirvenv-module-validation]] |
| == Validation Rules within a Module |
| |
| A SPIR-V module passed to flink:vkCreateShaderModule must: conform to the |
| following rules: |
| |
| |
| [[spirvenv-module-validation-standalone]] |
| === Standalone SPIR-V Validation |
| |
| [open,refpage='StandaloneSpirv',desc='Standalone SPIR-V Validation',type='spirv'] |
| -- |
| :refpage: StandaloneSpirv |
| |
| The following rules can: be validated with only the SPIR-V module itself. |
| They do not depend on knowledge of the implementation and its capabilities |
| or knowledge of runtime information, such as enabled features. |
| |
| .Valid Usage |
| **** |
| // NOTE: Do not conditionalize the "standalone" VUs. |
| // Write as though all extensions were enabled. |
| // Add any needed conditional logic to the runtime section if needed. |
| * [[VUID-{refpage}-None-04633]] |
| Every entry point must: have no return value and accept no arguments |
| * [[VUID-{refpage}-None-04634]] |
| The static function-call graph for an entry point must: not contain |
| cycles; that is, static recursion is not allowed |
| * [[VUID-{refpage}-None-04635]] |
| The *Logical* or *PhysicalStorageBuffer64* addressing model must: be |
| selected |
| * [[VUID-{refpage}-None-04636]] |
| *Scope* for execution must: be limited to *Workgroup* or *Subgroup* |
| * [[VUID-{refpage}-None-04637]] |
| If the *Scope* for execution is *Workgroup*, then it must: only be used |
| in the task, mesh, tessellation control, or compute execution models |
| * [[VUID-{refpage}-None-04638]] |
| *Scope* for memory must: be limited to *Device*, *QueueFamily*, |
| *Workgroup*, *ShaderCallKHR*, *Subgroup*, or *Invocation* |
| * [[VUID-{refpage}-None-04639]] |
| If the *Scope* for memory is *Workgroup*, then it must: only be used in |
| the task, mesh, or compute execution models |
| * [[VUID-{refpage}-None-04640]] |
| If the *Scope* for memory is *ShaderCallKHR*, then it must: only be used |
| in ray generation, intersection, closest hit, any-hit, miss, and |
| callable execution models |
| * [[VUID-{refpage}-None-04641]] |
| If the *Scope* for memory is *Invocation*, then memory semantics must: |
| be *None* |
| ifdef::VK_VERSION_1_1[] |
| * [[VUID-{refpage}-None-04642]] |
| *Scope* for <<shaders-group-operations,group operations>> must: be |
| limited to *Subgroup* |
| endif::VK_VERSION_1_1[] |
| * [[VUID-{refpage}-None-04643]] |
| *Storage Class* must: be limited to *UniformConstant*, *Input*, |
| *Uniform*, *Output*, *Workgroup*, *Private*, *Function*, *PushConstant*, |
| *Image*, *StorageBuffer*, *RayPayloadKHR*, *IncomingRayPayloadKHR*, |
| *HitAttributeKHR*, *CallableDataKHR*, *IncomingCallableDataKHR*, |
| *ShaderRecordBufferKHR*, or *PhysicalStorageBuffer* |
| * [[VUID-{refpage}-None-04644]] |
| If the *Storage Class* is *Output*, then it must: not be used in the |
| *GlCompute*, *RayGenerationKHR*, *IntersectionKHR*, *AnyHitKHR*, |
| *ClosestHitKHR*, *MissKHR*, or *CallableKHR* execution models |
| * [[VUID-{refpage}-None-04645]] |
| If the *Storage Class* is *Workgroup*, then it must: only be used in the |
| task, mesh, or compute execution models |
| * [[VUID-{refpage}-OpAtomicStore-04730]] |
| code:OpAtomicStore must: not use *Acquire*, *AcquireRelease*, or |
| *SequentiallyConsistent* memory semantics |
| * [[VUID-{refpage}-OpAtomicLoad-04731]] |
| code:OpAtomicLoad must: not use *Release*, *AcquireRelease*, or |
| *SequentiallyConsistent* memory semantics |
| * [[VUID-{refpage}-OpMemoryBarrier-04732]] |
| code:OpMemoryBarrier must: use one of *Acquire*, *Release*, |
| *AcquireRelease*, or *SequentiallyConsistent* memory semantics |
| * [[VUID-{refpage}-OpMemoryBarrier-04733]] |
| code:OpMemoryBarrier must: include at least one storage class |
| * [[VUID-{refpage}-OpControlBarrier-04650]] |
| If the semantics for code:OpControlBarrier includes one of *Acquire*, |
| *Release*, *AcquireRelease*, or *SequentiallyConsistent* memory |
| semantics, then it must: include at least one storage class |
| * [[VUID-{refpage}-OpVariable-04651]] |
| Any code:OpVariable with an code:Initializer operand must: have |
| *Output*, *Private*, *Function*, or *Workgroup* as its *Storage Class* |
| operand |
| * [[VUID-{refpage}-OpVariable-04734]] |
| Any code:OpVariable with an code:Initializer operand and *Workgroup* as |
| its *Storage Class* operand must: use code:OpConstantNull as the |
| initializer |
| * [[VUID-{refpage}-OpReadClockKHR-04652]] |
| *Scope* for code:OpReadClockKHR must: be limited to *Subgroup* or |
| *Device* |
| * [[VUID-{refpage}-OriginLowerLeft-04653]] |
| The code:OriginLowerLeft execution mode must: not be used; fragment |
| entry points must: declare code:OriginUpperLeft |
| * [[VUID-{refpage}-PixelCenterInteger-04654]] |
| The code:PixelCenterInteger execution mode must: not be used (pixels are |
| always centered at half-integer coordinates) |
| * [[VUID-{refpage}-UniformConstant-04655]] |
| Any variable in the code:UniformConstant storage class must: be typed as |
| either code:OpTypeImage, code:OpTypeSampler, code:OpTypeSampledImage, |
| code:OpTypeAccelerationStructureKHR, or an array of one of these types |
| * [[VUID-{refpage}-OpTypeImage-04656]] |
| code:OpTypeImage must: declare a scalar 32-bit float, 64-bit integer, or |
| 32-bit integer type for the "`Sampled Type`" (code:RelaxedPrecision can: |
| be applied to a sampling instruction and to the variable holding the |
| result of a sampling instruction) |
| * [[VUID-{refpage}-OpTypeImage-04657]] |
| code:OpTypeImage must: have a "`Sampled`" operand of 1 (sampled image) |
| or 2 (storage image) |
| * [[VUID-{refpage}-Image-04965]] |
| The converted bit width, signedness, and numeric type of the code:Image |
| code:Format operand of an code:OpTypeImage must: match the code:Sampled |
| code:Type, as defined in <<spirvenv-format-type-matching>> |
| * [[VUID-{refpage}-OpImageTexelPointer-04658]] |
| If an code:OpImageTexelPointer is used in an atomic operation, the image |
| type of the code:image parameter to code:OpImageTexelPointer must: have |
| an image format of code:R64i, code:R64ui, code:R32f, code:R32i, or |
| code:R32ui |
| * [[VUID-{refpage}-OpImageQuerySizeLod-04659]] |
| code:OpImageQuerySizeLod, code:OpImageQueryLod, and |
| code:OpImageQueryLevels must: only consume an "`Image`" operand whose |
| type has its "`Sampled`" operand set to 1 |
| * [[VUID-{refpage}-OpTypeImage-06214]] |
| An code:OpTypeImage with a "`Dim`" operand of code:SubpassData must: |
| have an "`Arrayed`" operand of 0 (non-arrayed) and a "`Sampled`" operand |
| of 2 (storage image) |
| * [[VUID-{refpage}-SubpassData-04660]] |
| The [eq]#(u,v)# coordinates used for a code:SubpassData must: be the |
| <id> of a constant vector [eq]#(0,0)#, or if a layer coordinate is used, |
| must: be a vector that was formed with constant 0 for the [eq]#u# and |
| [eq]#v# components |
| * [[VUID-{refpage}-OpTypeImage-04661]] |
| Objects of types code:OpTypeImage, code:OpTypeSampler, |
| code:OpTypeSampledImage, and arrays of these types must: not be stored |
| to or modified |
| * [[VUID-{refpage}-Offset-04662]] |
| Any image operation must: use at most one of the code:Offset, |
| code:ConstOffset, and code:ConstOffsets image operands |
| * [[VUID-{refpage}-Offset-04663]] |
| Image operand code:Offset must: only be used with code:OpImage*Gather |
| instructions |
| * [[VUID-{refpage}-Offset-04865]] |
| Any image instruction which uses an code:Offset, code:ConstOffset, or |
| code:ConstOffsets image operand, must only consume a "`Sampled Image`" |
| operand whose type has its "`Sampled`" operand set to 1 |
| * [[VUID-{refpage}-OpImageGather-04664]] |
| The "`Component`" operand of code:OpImageGather, and |
| code:OpImageSparseGather must: be the <id> of a constant instruction |
| * [[VUID-{refpage}-OpImage-04777]] |
| code:OpImage*Dref must: not consume an image whose `Dim` is 3D |
| * [[VUID-{refpage}-OpTypeAccelerationStructureKHR-04665]] |
| Objects of types code:OpTypeAccelerationStructureKHR and arrays of this |
| type must: not be stored to or modified |
| * [[VUID-{refpage}-OpReportIntersectionKHR-04666]] |
| The value of the "`Hit Kind`" operand of code:OpReportIntersectionKHR |
| must: be in the range [eq]#[0,127]# |
| * [[VUID-{refpage}-None-04667]] |
| Structure types must: not contain opaque types |
| * [[VUID-{refpage}-BuiltIn-04668]] |
| Any code:BuiltIn decoration not listed in |
| <<interfaces-builtin-variables>> must: not be used |
| * [[VUID-{refpage}-Location-04915]] |
| The code:Location or code:Component decorations must: not be used with |
| code:BuiltIn |
| * [[VUID-{refpage}-Location-04916]] |
| The code:Location decorations must: be used on |
| <<interfaces-iointerfaces-user,user-defined variables>> |
| * [[VUID-{refpage}-Location-04917]] |
| The code:Location decorations must: be used on an code:OpVariable with a |
| structure type that is not a block |
| * [[VUID-{refpage}-Location-04918]] |
| The code:Location decorations must: not be used on the members of |
| code:OpVariable with a structure type that is decorated with |
| code:Location |
| * [[VUID-{refpage}-Location-04919]] |
| The code:Location decorations must: be used on each member of |
| code:OpVariable with a structure type that is a block not decorated with |
| code:Location |
| * [[VUID-{refpage}-Component-04920]] |
| The code:Component decoration value must: not be greater than 3 |
| * [[VUID-{refpage}-Component-04921]] |
| If the code:Component decoration is used on an code:OpVariable that has |
| a code:OpTypeVector type with a code:Component code:Type with a |
| code:Width that is less than or equal to 32, the sum of its |
| code:Component code:Count and the code:Component decoration value must: |
| be less than 4 |
| * [[VUID-{refpage}-Component-04922]] |
| If the code:Component decoration is used on an code:OpVariable that has |
| a code:OpTypeVector type with a code:Component code:Type with a |
| code:Width that is equal to 64, the sum of two times its code:Component |
| code:Count and the code:Component decoration value must: be less than 4 |
| * [[VUID-{refpage}-Component-04923]] |
| The code:Component decorations value must: not be 1 or 3 for scalar or |
| two-component 64-bit data types |
| * [[VUID-{refpage}-Component-04924]] |
| The code:Component decorations must: not used with any type that is not |
| a scalar or vector |
| * [[VUID-{refpage}-GLSLShared-04669]] |
| The code:GLSLShared and code:GLSLPacked decorations must: not be used |
| * [[VUID-{refpage}-Flat-04670]] |
| The code:Flat, code:NoPerspective, code:Sample, and code:Centroid |
| decorations must: only be used on variables with the code:Output or |
| code:Input storage class |
| * [[VUID-{refpage}-Flat-06201]] |
| The code:Flat, code:NoPerspective, code:Sample, and code:Centroid |
| decorations must: not be used on variables with the code:Output storage |
| class in a fragment shader |
| * [[VUID-{refpage}-Flat-06202]] |
| The code:Flat, code:NoPerspective, code:Sample, and code:Centroid |
| decorations must: not be used on variables with the code:Input storage |
| class in a vertex shader |
| * [[VUID-{refpage}-Flat-04744]] |
| Any variable with integer or double-precision floating-point type and |
| with code:Input storage class in a fragment shader, must: be decorated |
| code:Flat |
| * [[VUID-{refpage}-ViewportRelativeNV-04672]] |
| The code:ViewportRelativeNV decoration must: only be used on a variable |
| decorated with code:Layer in the vertex, tessellation evaluation, or |
| geometry shader stages |
| * [[VUID-{refpage}-ViewportRelativeNV-04673]] |
| The code:ViewportRelativeNV decoration must: not be used unless a |
| variable decorated with one of code:ViewportIndex or code:ViewportMaskNV |
| is also statically used by the same code:OpEntryPoint |
| * [[VUID-{refpage}-ViewportMaskNV-04674]] |
| The code:ViewportMaskNV and code:ViewportIndex decorations must: not |
| both be statically used by one or more code:OpEntryPoint's that form the |
| <<pipeline-graphics-subsets-pre-rasterization,pre-rasterization shader |
| stages>> of a graphics pipeline |
| * [[VUID-{refpage}-FPRoundingMode-04675]] |
| Rounding modes other than round-to-nearest-even and round-towards-zero |
| must: not be used for the code:FPRoundingMode decoration |
| * [[VUID-{refpage}-FPRoundingMode-04676]] |
| The code:FPRoundingMode decoration must: only be used for a width-only |
| conversion instruction whose only uses are code:Object operands of |
| code:OpStore instructions storing through a pointer to a 16-bit |
| floating-point object in the code:StorageBuffer, |
| code:PhysicalStorageBuffer, code:Uniform, or code:Output storage class |
| * [[VUID-{refpage}-Invariant-04677]] |
| Variables decorated with code:Invariant and variables with structure |
| types that have any members decorated with code:Invariant must: be in |
| the code:Output or code:Input storage class, code:Invariant used on an |
| code:Input storage class variable or structure member has no effect |
| * [[VUID-{refpage}-VulkanMemoryModel-04678]] |
| [[builtin-volatile-semantics]] If the code:VulkanMemoryModel capability |
| is not declared, the code:Volatile decoration must: be used on any |
| variable declaration that includes one of the code:SMIDNV, |
| code:WarpIDNV, code:SubgroupSize, code:SubgroupLocalInvocationId, |
| code:SubgroupEqMask, code:SubgroupGeMask, code:SubgroupGtMask, |
| code:SubgroupLeMask, or code:SubgroupLtMask code:BuiltIn decorations |
| when used in the ray generation, closest hit, miss, intersection, or |
| callable shaders, or with the code:RayTmaxKHR code:Builtin decoration |
| when used in an intersection shader |
| * [[VUID-{refpage}-VulkanMemoryModel-04679]] |
| If the code:VulkanMemoryModel capability is declared, the code:OpLoad |
| instruction must: use the code:Volatile memory semantics when it |
| accesses into any variable that includes one of the code:SMIDNV, |
| code:WarpIDNV, code:SubgroupSize, code:SubgroupLocalInvocationId, |
| code:SubgroupEqMask, code:SubgroupGeMask, code:SubgroupGtMask, |
| code:SubgroupLeMask, or code:SubgroupLtMask code:BuiltIn decorations |
| when used in the ray generation, closest hit, miss, intersection, or |
| callable shaders, or with the code:RayTmaxKHR code:Builtin decoration |
| when used in an intersection shader |
| * [[VUID-{refpage}-OpTypeRuntimeArray-04680]] |
| code:OpTypeRuntimeArray must: only be used for the last member of an |
| code:OpTypeStruct that is in the code:StorageBuffer or |
| code:PhysicalStorageBuffer storage class decorated as code:Block, or |
| that is in the code:Uniform storage class decorated as code:BufferBlock |
| * [[VUID-{refpage}-Function-04681]] |
| A type _T_ that is an array sized with a specialization constant must: |
| neither be, nor be contained in, the type _T2_ of a variable _V_, unless |
| either: a) _T_ is equal to _T2_, b) _V_ is declared in the |
| code:Function, or code:Private storage classes, c) _V_ is a non-Block |
| variable in the code:Workgroup storage class, or d) _V_ is an interface |
| variable with an additional level of arrayness, |
| <<interfaces-iointerfaces-matching, as described in interface |
| matching>>, and _T_ is the member type of the array type _T2_ |
| * [[VUID-{refpage}-OpControlBarrier-04682]] |
| If code:OpControlBarrier is used in ray generation, intersection, |
| any-hit, closest hit, miss, fragment, vertex, tessellation evaluation, |
| or geometry shaders, the execution Scope must: be code:Subgroup |
| * [[VUID-{refpage}-LocalSize-06426]] |
| For each compute shader entry point, either a code:LocalSize or |
| code:LocalSizeId execution mode, or an object decorated with the |
| code:WorkgroupSize decoration must: be specified |
| * [[VUID-{refpage}-DerivativeGroupQuadsNV-04684]] |
| For compute shaders using the code:DerivativeGroupQuadsNV execution |
| mode, the first two dimensions of the local workgroup size must: be a |
| multiple of two |
| * [[VUID-{refpage}-DerivativeGroupLinearNV-04778]] |
| For compute shaders using the code:DerivativeGroupLinearNV execution |
| mode, the product of the dimensions of the local workgroup size must: be |
| a multiple of four |
| * [[VUID-{refpage}-OpGroupNonUniformBallotBitCount-04685]] |
| If code:OpGroupNonUniformBallotBitCount is used, the group operation |
| must: be limited to *Reduce*, *InclusiveScan*, or *ExclusiveScan* |
| * [[VUID-{refpage}-None-04686]] |
| The _Pointer_ operand of all atomic instructions must: have a *Storage |
| Class* limited to *Uniform*, *Workgroup*, *Image*, *StorageBuffer*, or |
| *PhysicalStorageBuffer* |
| * [[VUID-{refpage}-Offset-04687]] |
| Output variables or block members decorated with code:Offset that have a |
| 64-bit type, or a composite type containing a 64-bit type, must: specify |
| an code:Offset value aligned to a 8 byte boundary |
| * [[VUID-{refpage}-Offset-04689]] |
| The size of any output block containing any member decorated with |
| code:Offset that is a 64-bit type must: be a multiple of 8 |
| * [[VUID-{refpage}-Offset-04690]] |
| The first member of an output block that specifies a code:Offset |
| decoration must: specify a code:Offset value that is aligned to an 8 |
| byte boundary if that block contains any member decorated with |
| code:Offset and is a 64-bit type |
| * [[VUID-{refpage}-Offset-04691]] |
| Output variables or block members decorated with code:Offset that have a |
| 32-bit type, or a composite type contains a 32-bit type, must: specify |
| an code:Offset value aligned to a 4 byte boundary |
| * [[VUID-{refpage}-Offset-04692]] |
| Output variables, blocks or block members decorated with code:Offset |
| must: only contain base types that have components that are either |
| 32-bit or 64-bit in size |
| * [[VUID-{refpage}-Offset-04716]] |
| Only variables or block members in the output interface decorated with |
| code:Offset can: be captured for transform feedback, and those variables |
| or block members must: also be decorated with code:XfbBuffer and |
| code:XfbStride, or inherit code:XfbBuffer and code:XfbStride decorations |
| from a block containing them |
| * [[VUID-{refpage}-XfbBuffer-04693]] |
| All variables or block members in the output interface of the entry |
| point being compiled decorated with a specific code:XfbBuffer value |
| must: all be decorated with identical code:XfbStride values |
| * [[VUID-{refpage}-Stream-04694]] |
| If any variables or block members in the output interface of the entry |
| point being compiled are decorated with code:Stream, then all variables |
| belonging to the same code:XfbBuffer must: specify the same code:Stream |
| value |
| * [[VUID-{refpage}-XfbBuffer-04696]] |
| For any two variables or block members in the output interface of the |
| entry point being compiled with the same code:XfbBuffer value, the |
| ranges determined by the code:Offset decoration and the size of the type |
| must: not overlap |
| * [[VUID-{refpage}-XfbBuffer-04697]] |
| All block members in the output interface of the entry point being |
| compiled that are in the same block and have a declared or inherited |
| code:XfbBuffer decoration must: specify the same code:XfbBuffer value |
| * [[VUID-{refpage}-RayPayloadKHR-04698]] |
| code:RayPayloadKHR storage class must: only be used in ray generation, |
| closest hit or miss shaders |
| * [[VUID-{refpage}-IncomingRayPayloadKHR-04699]] |
| code:IncomingRayPayloadKHR storage class must: only be used in closest |
| hit, any-hit, or miss shaders |
| * [[VUID-{refpage}-IncomingRayPayloadKHR-04700]] |
| There must: be at most one variable with the code:IncomingRayPayloadKHR |
| storage class in the input interface of an entry point |
| * [[VUID-{refpage}-HitAttributeKHR-04701]] |
| code:HitAttributeKHR storage class must: only be used in intersection, |
| any-hit, or closest hit shaders |
| * [[VUID-{refpage}-HitAttributeKHR-04702]] |
| There must: be at most one variable with the code:HitAttributeKHR |
| storage class in the input interface of an entry point |
| * [[VUID-{refpage}-HitAttributeKHR-04703]] |
| A variable with code:HitAttributeKHR storage class must: only be written |
| to in an intersection shader |
| * [[VUID-{refpage}-CallableDataKHR-04704]] |
| code:CallableDataKHR storage class must: only be used in ray generation, |
| closest hit, miss, and callable shaders |
| * [[VUID-{refpage}-IncomingCallableDataKHR-04705]] |
| code:IncomingCallableDataKHR storage class must: only be used in |
| callable shaders |
| * [[VUID-{refpage}-IncomingCallableDataKHR-04706]] |
| There must: be at most one variable with the |
| code:IncomingCallableDataKHR storage class in the input interface of an |
| entry point |
| * [[VUID-{refpage}-Base-04707]] |
| The code:Base operand of code:OpPtrAccessChain must: point to one of the |
| following: *Workgroup*, if code:VariablePointers is enabled; |
| *StorageBuffer*, if code:VariablePointers or |
| code:VariablePointersStorageBuffer is enabled; *PhysicalStorageBuffer*, |
| if the code:PhysicalStorageBuffer64 addressing model is enabled |
| * [[VUID-{refpage}-PhysicalStorageBuffer64-04708]] |
| If the code:PhysicalStorageBuffer64 addressing model is enabled, all |
| instructions that support memory access operands and that use a physical |
| pointer must: include the code:Aligned operand |
| * [[VUID-{refpage}-PhysicalStorageBuffer64-04709]] |
| If the code:PhysicalStorageBuffer64 addressing model is enabled, any |
| access chain instruction that accesses into a code:RowMajor matrix must: |
| only be used as the code:Pointer operand to code:OpLoad or code:OpStore |
| * [[VUID-{refpage}-PhysicalStorageBuffer64-04710]] |
| If the code:PhysicalStorageBuffer64 addressing model is enabled, |
| code:OpConvertUToPtr and code:OpConvertPtrToU must: use an integer type |
| whose code:Width is 64 |
| * [[VUID-{refpage}-OpTypeForwardPointer-04711]] |
| code:OpTypeForwardPointer must: have a storage class of |
| code:PhysicalStorageBuffer |
| * [[VUID-{refpage}-None-04745]] |
| All variables with a storage class of *PushConstant* declared as an |
| array must: only be accessed by dynamically uniform indices |
| * [[VUID-{refpage}-Result-04780]] |
| The code:Result code:Type operand of any code:OpImageRead or |
| code:OpImageSparseRead instruction must: be a vector of four components |
| * [[VUID-{refpage}-Base-04781]] |
| The code:Base operand of any code:OpBitCount, code:OpBitReverse, |
| code:OpBitFieldInsert, code:OpBitFieldSExtract, or |
| code:OpBitFieldUExtract instruction must: be a 32-bit integer scalar or |
| a vector of 32-bit integers |
| **** |
| -- |
| |
| [[spirvenv-module-validation-runtime]] |
| === Runtime SPIR-V Validation |
| |
| [open,refpage='RuntimeSpirv',desc='Runtime SPIR-V Validation',type='spirv'] |
| -- |
| :refpage: RuntimeSpirv |
| |
| The following rules must: be validated at runtime. |
| These rules depend on knowledge of the implementation and its capabilities |
| and knowledge of runtime information, such as enabled features. |
| |
| .Valid Usage |
| **** |
| ifdef::VK_VERSION_1_2,VK_KHR_vulkan_memory_model[] |
| * [[VUID-{refpage}-vulkanMemoryModel-06265]] |
| If <<features-vulkanMemoryModel,pname:vulkanMemoryModel>> is enabled and |
| <<features-vulkanMemoryModelDeviceScope,pname:vulkanMemoryModelDeviceScope>> |
| is not enabled, *Device* memory scope must: not be used. |
| endif::VK_VERSION_1_2,VK_KHR_vulkan_memory_model[] |
| ifdef::VK_VERSION_1_2,VK_KHR_vulkan_memory_model[] |
| * [[VUID-{refpage}-vulkanMemoryModel-06266]] |
| If <<features-vulkanMemoryModel,pname:vulkanMemoryModel>> is not |
| enabled, *QueueFamily* memory scope must: not be used. |
| endif::VK_VERSION_1_2,VK_KHR_vulkan_memory_model[] |
| ifdef::VK_KHR_shader_clock[] |
| * [[VUID-{refpage}-shaderSubgroupClock-06267]] |
| If <<features-shaderSubgroupClock,pname:shaderSubgroupClock>> is not |
| enabled, the code:Subgroup scope must: not be used for |
| code:OpReadClockKHR. |
| * [[VUID-{refpage}-shaderDeviceClock-06268]] |
| If <<features-shaderDeviceClock,pname:shaderDeviceClock>> is not |
| enabled, the code:Device scope must: not be used for |
| code:OpReadClockKHR. |
| endif::VK_KHR_shader_clock[] |
| ifndef::VK_KHR_format_feature_flags2[] |
| * [[VUID-{refpage}-OpTypeImage-06269]] |
| If |
| <<features-shaderStorageImageWriteWithoutFormat,shaderStorageImageWriteWithoutFormat>> |
| is not enabled, any variable created with a "`Type`" of code:OpTypeImage |
| that has a "`Sampled`" operand of 2 and an "`Image Format`" operand of |
| code:Unknown must: be decorated with code:NonWritable. |
| * [[VUID-{refpage}-OpTypeImage-06270]] |
| If |
| <<features-shaderStorageImageReadWithoutFormat,shaderStorageImageReadWithoutFormat>> |
| is not enabled, any variable created with a "`Type`" of code:OpTypeImage |
| that has a "`Sampled`" operand of 2 and an "`Image Format`" operand of |
| code:Unknown must: be decorated with code:NonReadable. |
| * [[VUID-{refpage}-BuiltIn-06271]] |
| Any code:BuiltIn decoration that corresponds only to Vulkan features or |
| endif::VK_KHR_format_feature_flags2[] |
| extensions that have not been enabled must: not be used. |
| * [[VUID-{refpage}-Location-06272]] |
| The sum of code:Location and the number of locations the variable it |
| decorates consumes must: be less than or equal to the value for the |
| matching {ExecutionModel} defined in <<interfaces-iointerfaces-limits>> |
| * [[VUID-{refpage}-Fragment-06427]] |
| When blending is enabled and one of the dual source blend modes is in |
| use, the maximum number of output attachments written to in the |
| code:Fragment {ExecutionModel} must: be less than or equal to |
| <<limits-maxFragmentDualSrcAttachments,pname:maxFragmentDualSrcAttachments>> |
| * [[VUID-{refpage}-Location-06428]] |
| The maximum number of storage buffers, storage images, and output |
| code:Location decorated color attachments written to in the |
| code:Fragment {ExecutionModel} must: be less than or equal to |
| <<limits-maxFragmentCombinedOutputResources,pname:maxFragmentCombinedOutputResources>> |
| ifdef::VK_VERSION_1_2,VK_EXT_descriptor_indexing[] |
| * [[VUID-{refpage}-OpTypeRuntimeArray-06273]] |
| code:OpTypeRuntimeArray must: only be used for an array of variables |
| with storage class code:Uniform, code:StorageBuffer, or |
| code:UniformConstant, or for the outermost dimension of an array of |
| arrays of such variables if the |
| <<features-runtimeDescriptorArray,runtimeDescriptorArray>> feature is |
| enabled, |
| * [[VUID-{refpage}-NonUniform-06274]] |
| If an instruction loads from or stores to a resource (including atomics |
| and image instructions) and the resource descriptor being accessed is |
| not dynamically uniform, then the operand corresponding to that resource |
| (e.g. the pointer or sampled image operand) must: be decorated with |
| code:NonUniform. |
| endif::VK_VERSION_1_2,VK_EXT_descriptor_indexing[] |
| ifdef::VK_VERSION_1_1[] |
| ifdef::VK_VERSION_1_2,VK_KHR_shader_subgroup_extended_types[] |
| * [[VUID-{refpage}-None-06275]] |
| <<features-subgroup-extended-types,shaderSubgroupExtendedTypes>> must: |
| be enabled for <<shaders-group-operations,group operations>> to use |
| 8-bit integer, 16-bit integer, 64-bit integer, 16-bit floating-point, |
| and vectors of these types |
| endif::VK_VERSION_1_2,VK_KHR_shader_subgroup_extended_types[] |
| endif::VK_VERSION_1_1[] |
| ifdef::VK_VERSION_1_2[] |
| * [[VUID-{refpage}-subgroupBroadcastDynamicId-06276]] |
| If |
| <<features-subgroupBroadcastDynamicId,code:subgroupBroadcastDynamicId>> |
| is ename:VK_TRUE, and the shader module version is 1.5 or higher, the |
| "`Index`" for code:OpGroupNonUniformQuadBroadcast must: be dynamically |
| uniform within the derivative group. |
| Otherwise, "`Index`" must: be a constant. |
| * [[VUID-{refpage}-subgroupBroadcastDynamicId-06277]] |
| If |
| <<features-subgroupBroadcastDynamicId,code:subgroupBroadcastDynamicId>> |
| is ename:VK_TRUE, and the shader module version is 1.5 or higher, the |
| "`Id`" for code:OpGroupNonUniformBroadcast must: be dynamically uniform |
| within the subgroup. |
| Otherwise, "`Id`" must: be a constant. |
| endif::VK_VERSION_1_2[] |
| ifdef::VK_KHR_shader_atomic_int64[] |
| * [[VUID-{refpage}-None-06278]] |
| <<features-shaderBufferInt64Atomics,shaderBufferInt64Atomics>> must: be |
| enabled for 64-bit integer atomic operations to be supported on a |
| _Pointer_ with a *Storage Class* of *StorageBuffer* or *Uniform*. |
| * [[VUID-{refpage}-None-06279]] |
| <<features-shaderSharedInt64Atomics,shaderSharedInt64Atomics>> must: be |
| enabled for 64-bit integer atomic operations to be supported on a |
| _Pointer_ with a *Storage Class* of *Workgroup*. |
| endif::VK_KHR_shader_atomic_int64[] |
| ifdef::VK_EXT_shader_atomic_float[] |
| ifndef::VK_EXT_shader_atomic_float2[] |
| * [[VUID-{refpage}-None-06280]] |
| <<features-shaderBufferFloat32Atomics,shaderBufferFloat32Atomics>>, or |
| <<features-shaderBufferFloat32AtomicAdd,shaderBufferFloat32AtomicAdd>>, |
| or <<features-shaderBufferFloat64Atomics,shaderBufferFloat64Atomics>>, |
| or |
| <<features-shaderBufferFloat64AtomicAdd,shaderBufferFloat64AtomicAdd>> |
| must: be enabled for floating-point atomic operations to be supported on |
| a _Pointer_ with a *Storage Class* of *StorageBuffer*. |
| * [[VUID-{refpage}-None-06281]] |
| <<features-shaderSharedFloat32Atomics,shaderSharedFloat32Atomics>>, or |
| <<features-shaderSharedFloat32AtomicAdd,shaderSharedFloat32AtomicAdd>>, |
| or <<features-shaderSharedFloat64Atomics,shaderSharedFloat64Atomics>>, |
| or |
| <<features-shaderSharedFloat64AtomicAdd,shaderSharedFloat64AtomicAdd>> |
| must: be enabled for floating-point atomic operations to be supported on |
| a _Pointer_ with a *Storage Class* of *Workgroup*. |
| * [[VUID-{refpage}-None-06282]] |
| <<features-shaderImageFloat32Atomics,shaderImageFloat32Atomics>> or |
| <<features-shaderImageFloat32AtomicAdd,shaderImageFloat32AtomicAdd>> |
| must: be enabled for 32-bit floating-point atomic operations to be |
| supported on a _Pointer_ with a *Storage Class* of *Image*. |
| * [[VUID-{refpage}-None-06283]] |
| <<features-sparseImageFloat32Atomics,sparseImageFloat32Atomics>> or |
| <<features-sparseImageFloat32AtomicAdd,sparseImageFloat32AtomicAdd>> |
| must: be enabled for 32-bit floating-point atomics to be supported on |
| sparse images. |
| endif::VK_EXT_shader_atomic_float2[] |
| endif::VK_EXT_shader_atomic_float[] |
| ifdef::VK_EXT_shader_atomic_float2[] |
| * [[VUID-{refpage}-None-06284]] |
| <<features-shaderBufferFloat32Atomics,shaderBufferFloat32Atomics>>, or |
| <<features-shaderBufferFloat32AtomicAdd,shaderBufferFloat32AtomicAdd>>, |
| or <<features-shaderBufferFloat64Atomics,shaderBufferFloat64Atomics>>, |
| or |
| <<features-shaderBufferFloat64AtomicAdd,shaderBufferFloat64AtomicAdd>>, |
| or |
| <<features-shaderBufferFloat16AtomicMinMax,shaderBufferFloat16Atomics>>, |
| or |
| <<features-shaderBufferFloat16AtomicMinMax,shaderBufferFloat16AtomicAdd>>, |
| or |
| <<features-shaderBufferFloat16AtomicMinMax,shaderBufferFloat16AtomicMinMax>>, |
| or |
| <<features-shaderBufferFloat32AtomicMinMax,shaderBufferFloat32AtomicMinMax>>, |
| or |
| <<features-shaderBufferFloat64AtomicMinMax,shaderBufferFloat64AtomicMinMax>> |
| must: be enabled for floating-point atomic operations to be supported on |
| a _Pointer_ with a *Storage Class* of *StorageBuffer*. |
| * [[VUID-{refpage}-None-06285]] |
| <<features-shaderSharedFloat32Atomics,shaderSharedFloat32Atomics>>, or |
| <<features-shaderSharedFloat32AtomicAdd,shaderSharedFloat32AtomicAdd>>, |
| or <<features-shaderSharedFloat64Atomics,shaderSharedFloat64Atomics>>, |
| or |
| <<features-shaderSharedFloat64AtomicAdd,shaderSharedFloat64AtomicAdd>>, |
| or |
| <<features-shaderBufferFloat16AtomicMinMax,shaderSharedFloat16Atomics>>, |
| or |
| <<features-shaderBufferFloat16AtomicMinMax,shaderSharedFloat16AtomicAdd>>, |
| or |
| <<features-shaderBufferFloat16AtomicMinMax,shaderSharedFloat16AtomicMinMax>>, |
| or |
| <<features-shaderSharedFloat32AtomicMinMax,shaderSharedFloat32AtomicMinMax>>, |
| or |
| <<features-shaderSharedFloat64AtomicMinMax,shaderSharedFloat64AtomicMinMax>> |
| must: be enabled for floating-point atomic operations to be supported on |
| a _Pointer_ with a *Storage Class* of *Workgroup*. |
| * [[VUID-{refpage}-None-06286]] |
| <<features-shaderImageFloat32Atomics,shaderImageFloat32Atomics>>, or |
| <<features-shaderImageFloat32AtomicAdd,shaderImageFloat32AtomicAdd>>, or |
| <<features-shaderImageFloat32AtomicMinMax,shaderImageFloat32AtomicMinMax>> |
| must: be enabled for 32-bit floating-point atomic operations to be |
| supported on a _Pointer_ with a *Storage Class* of *Image*. |
| * [[VUID-{refpage}-None-06287]] |
| <<features-sparseImageFloat32Atomics,sparseImageFloat32Atomics>>, or |
| <<features-sparseImageFloat32AtomicAdd,sparseImageFloat32AtomicAdd>>, or |
| <<features-sparseImageFloat32AtomicMinMax,sparseImageFloat32AtomicMinMax>> |
| must: be enabled for 32-bit floating-point atomics to be supported on |
| sparse images. |
| endif::VK_EXT_shader_atomic_float2[] |
| ifdef::VK_EXT_shader_image_atomic_int64[] |
| * [[VUID-{refpage}-None-06288]] |
| <<features-shaderImageInt64Atomics,shaderImageInt64Atomics>> must: be |
| enabled for 64-bit integer atomic operations to be supported on a |
| _Pointer_ with a *Storage Class* of *Image*. |
| endif::VK_EXT_shader_image_atomic_int64[] |
| ifdef::VK_VERSION_1_2,VK_KHR_shader_float_controls[] |
| * [[VUID-{refpage}-denormBehaviorIndependence-06289]] |
| If |
| <<features-denormBehaviorIndependence,pname:denormBehaviorIndependence>> |
| is ename:VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_32_BIT_ONLY, then the |
| entry point must: use the same denormals execution mode for both 16-bit |
| and 64-bit floating-point types. |
| * [[VUID-{refpage}-denormBehaviorIndependence-06290]] |
| If |
| <<features-denormBehaviorIndependence,pname:denormBehaviorIndependence>> |
| is ename:VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_NONE, then the entry |
| point must: use the same denormals execution mode for all floating-point |
| types. |
| * [[VUID-{refpage}-roundingModeIndependence-06291]] |
| If <<features-roundingModeIndependence,pname:roundingModeIndependence>> |
| is ename:VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_32_BIT_ONLY, then the |
| entry point must: use the same rounding execution mode for both 16-bit |
| and 64-bit floating-point types. |
| * [[VUID-{refpage}-roundingModeIndependence-06292]] |
| If <<features-roundingModeIndependence,pname:roundingModeIndependence>> |
| is ename:VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_NONE, then the entry |
| point must: use the same rounding execution mode for all floating-point |
| types. |
| * [[VUID-{refpage}-shaderSignedZeroInfNanPreserveFloat16-06293]] |
| If |
| <<limits-shaderSignedZeroInfNanPreserveFloat16,pname:shaderSignedZeroInfNanPreserveFloat16>> |
| is ename:VK_FALSE, then code:SignedZeroInfNanPreserve for 16-bit |
| floating-point type must: not be used. |
| * [[VUID-{refpage}-shaderSignedZeroInfNanPreserveFloat32-06294]] |
| If |
| <<limits-shaderSignedZeroInfNanPreserveFloat32,pname:shaderSignedZeroInfNanPreserveFloat32>> |
| is ename:VK_FALSE, then code:SignedZeroInfNanPreserve for 32-bit |
| floating-point type must: not be used. |
| * [[VUID-{refpage}-shaderSignedZeroInfNanPreserveFloat64-06295]] |
| If |
| <<limits-shaderSignedZeroInfNanPreserveFloat64,pname:shaderSignedZeroInfNanPreserveFloat64>> |
| is ename:VK_FALSE, then code:SignedZeroInfNanPreserve for 64-bit |
| floating-point type must: not be used. |
| * [[VUID-{refpage}-shaderDenormPreserveFloat16-06296]] |
| If |
| <<limits-shaderDenormPreserveFloat16,pname:shaderDenormPreserveFloat16>> |
| is ename:VK_FALSE, then code:DenormPreserve for 16-bit floating-point |
| type must: not be used. |
| * [[VUID-{refpage}-shaderDenormPreserveFloat32-06297]] |
| If |
| <<limits-shaderDenormPreserveFloat32,pname:shaderDenormPreserveFloat32>> |
| is ename:VK_FALSE, then code:DenormPreserve for 32-bit floating-point |
| type must: not be used. |
| * [[VUID-{refpage}-shaderDenormPreserveFloat64-06298]] |
| If |
| <<limits-shaderDenormPreserveFloat64,pname:shaderDenormPreserveFloat64>> |
| is ename:VK_FALSE, then code:DenormPreserve for 64-bit floating-point |
| type must: not be used. |
| * [[VUID-{refpage}-shaderDenormFlushToZeroFloat16-06299]] |
| If |
| <<limits-shaderDenormFlushToZeroFloat16,pname:shaderDenormFlushToZeroFloat16>> |
| is ename:VK_FALSE, then code:DenormFlushToZero for 16-bit floating-point |
| type must: not be used. |
| * [[VUID-{refpage}-shaderDenormFlushToZeroFloat32-06300]] |
| If |
| <<limits-shaderDenormFlushToZeroFloat32,pname:shaderDenormFlushToZeroFloat32>> |
| is ename:VK_FALSE, then code:DenormFlushToZero for 32-bit floating-point |
| type must: not be used. |
| * [[VUID-{refpage}-shaderDenormFlushToZeroFloat64-06301]] |
| If |
| <<limits-shaderDenormFlushToZeroFloat64,pname:shaderDenormFlushToZeroFloat64>> |
| is ename:VK_FALSE, then code:DenormFlushToZero for 64-bit floating-point |
| type must: not be used. |
| * [[VUID-{refpage}-shaderRoundingModeRTEFloat16-06302]] |
| If |
| <<limits-shaderRoundingModeRTEFloat16,pname:shaderRoundingModeRTEFloat16>> |
| is ename:VK_FALSE, then code:RoundingModeRTE for 16-bit floating-point |
| type must: not be used. |
| * [[VUID-{refpage}-shaderRoundingModeRTEFloat32-06303]] |
| If |
| <<limits-shaderRoundingModeRTEFloat32,pname:shaderRoundingModeRTEFloat32>> |
| is ename:VK_FALSE, then code:RoundingModeRTE for 32-bit floating-point |
| type must: not be used. |
| * [[VUID-{refpage}-shaderRoundingModeRTEFloat64-06304]] |
| If |
| <<limits-shaderRoundingModeRTEFloat64,pname:shaderRoundingModeRTEFloat64>> |
| is ename:VK_FALSE, then code:RoundingModeRTE for 64-bit floating-point |
| type must: not be used. |
| * [[VUID-{refpage}-shaderRoundingModeRTZFloat16-06305]] |
| If |
| <<limits-shaderRoundingModeRTZFloat16,pname:shaderRoundingModeRTZFloat16>> |
| is ename:VK_FALSE, then code:RoundingModeRTZ for 16-bit floating-point |
| type must: not be used. |
| * [[VUID-{refpage}-shaderRoundingModeRTZFloat32-06306]] |
| If |
| <<limits-shaderRoundingModeRTZFloat32,pname:shaderRoundingModeRTZFloat32>> |
| is ename:VK_FALSE, then code:RoundingModeRTZ for 32-bit floating-point |
| type must: not be used. |
| * [[VUID-{refpage}-shaderRoundingModeRTZFloat64-06307]] |
| If |
| <<limits-shaderRoundingModeRTZFloat64,pname:shaderRoundingModeRTZFloat64>> |
| is ename:VK_FALSE, then code:RoundingModeRTZ for 64-bit floating-point |
| type must: not be used. |
| endif::VK_VERSION_1_2,VK_KHR_shader_float_controls[] |
| ifdef::VK_EXT_transform_feedback[] |
| * [[VUID-{refpage}-Offset-06308]] |
| The code:Offset plus size of the type of each variable, in the output |
| interface of the entry point being compiled, decorated with |
| code:XfbBuffer must: not be greater than |
| sname:VkPhysicalDeviceTransformFeedbackPropertiesEXT::pname:maxTransformFeedbackBufferDataSize |
| * [[VUID-{refpage}-XfbBuffer-06309]] |
| For any given code:XfbBuffer value, define the buffer data size to be |
| smallest number of bytes such that, for all outputs decorated with the |
| same code:XfbBuffer value, the size of the output interface variable |
| plus the code:Offset is less than or equal to the buffer data size. |
| For a given code:Stream, the sum of all the buffer data sizes for all |
| buffers writing to that stream the must: not exceed |
| sname:VkPhysicalDeviceTransformFeedbackPropertiesEXT::pname:maxTransformFeedbackStreamDataSize |
| * [[VUID-{refpage}-OpEmitStreamVertex-06310]] |
| The Stream value to code:OpEmitStreamVertex and |
| code:OpEndStreamPrimitive must: be less than |
| sname:VkPhysicalDeviceTransformFeedbackPropertiesEXT::pname:maxTransformFeedbackStreams |
| * [[VUID-{refpage}-transformFeedbackStreamsLinesTriangles-06311]] |
| If the geometry shader emits to more than one vertex stream and |
| sname:VkPhysicalDeviceTransformFeedbackPropertiesEXT::pname:transformFeedbackStreamsLinesTriangles |
| is ename:VK_FALSE, then execution mode must: be code:OutputPoints |
| * [[VUID-{refpage}-Stream-06312]] |
| The stream number value to code:Stream must: be less than |
| sname:VkPhysicalDeviceTransformFeedbackPropertiesEXT::pname:maxTransformFeedbackStreams |
| * [[VUID-{refpage}-XfbStride-06313]] |
| The XFB Stride value to code:XfbStride must: be less than or equal to |
| sname:VkPhysicalDeviceTransformFeedbackPropertiesEXT::pname:maxTransformFeedbackBufferDataStride |
| endif::VK_EXT_transform_feedback[] |
| ifdef::VK_VERSION_1_2,VK_EXT_buffer_device_address,VK_KHR_buffer_device_address[] |
| * [[VUID-{refpage}-PhysicalStorageBuffer64-06314]] |
| If the code:PhysicalStorageBuffer64 addressing model is enabled any load |
| or store through a physical pointer type must: be aligned to a multiple |
| of the size of the largest scalar type in the pointed-to type. |
| * [[VUID-{refpage}-PhysicalStorageBuffer64-06315]] |
| If the code:PhysicalStorageBuffer64 addressing model is enabled the |
| pointer value of a memory access instruction must: be at least as |
| aligned as specified by the code:Aligned memory access operand. |
| endif::VK_VERSION_1_2,VK_EXT_buffer_device_address,VK_KHR_buffer_device_address[] |
| ifdef::VK_NV_cooperative_matrix[] |
| * [[VUID-{refpage}-OpTypeCooperativeMatrixNV-06316]] |
| For code:OpTypeCooperativeMatrixNV, the component type, scope, number of |
| rows, and number of columns must: match one of the matrices in any of |
| the supported slink:VkCooperativeMatrixPropertiesNV. |
| * [[VUID-{refpage}-OpCooperativeMatrixMulAddNV-06317]] |
| For code:OpCooperativeMatrixMulAddNV, the type of code:A must: have |
| slink:VkCooperativeMatrixPropertiesNV::pname:MSize rows and |
| slink:VkCooperativeMatrixPropertiesNV::pname:KSize columns and have a |
| component type that matches |
| slink:VkCooperativeMatrixPropertiesNV::pname:AType. |
| * [[VUID-{refpage}-OpCooperativeMatrixMulAddNV-06318]] |
| For code:OpCooperativeMatrixMulAddNV, the type of code:B must: have |
| slink:VkCooperativeMatrixPropertiesNV::pname:KSize rows and |
| slink:VkCooperativeMatrixPropertiesNV::pname:NSize columns and have a |
| component type that matches |
| slink:VkCooperativeMatrixPropertiesNV::pname:BType. |
| * [[VUID-{refpage}-OpCooperativeMatrixMulAddNV-06319]] |
| For code:OpCooperativeMatrixMulAddNV, the type of code:C must: have |
| slink:VkCooperativeMatrixPropertiesNV::pname:MSize rows and |
| slink:VkCooperativeMatrixPropertiesNV::pname:NSize columns and have a |
| component type that matches |
| slink:VkCooperativeMatrixPropertiesNV::pname:CType. |
| * [[VUID-{refpage}-OpCooperativeMatrixMulAddNV-06320]] |
| For code:OpCooperativeMatrixMulAddNV, the type of code:Result must: have |
| slink:VkCooperativeMatrixPropertiesNV::pname:MSize rows and |
| slink:VkCooperativeMatrixPropertiesNV::pname:NSize columns and have a |
| component type that matches |
| slink:VkCooperativeMatrixPropertiesNV::pname:DType. |
| * [[VUID-{refpage}-OpCooperativeMatrixMulAddNV-06321]] |
| For code:OpCooperativeMatrixMulAddNV, the type of code:A, code:B, |
| code:C, and code:Result must: all have a scope of pname:scope. |
| * [[VUID-{refpage}-OpTypeCooperativeMatrixNV-06322]] |
| code:OpTypeCooperativeMatrixNV and code:OpCooperativeMatrix* |
| instructions must: not be used in shader stages not included in |
| slink:VkPhysicalDeviceCooperativeMatrixPropertiesNV::pname:cooperativeMatrixSupportedStages. |
| endif::VK_NV_cooperative_matrix[] |
| * [[VUID-{refpage}-DescriptorSet-06323]] |
| code:DescriptorSet and code:Binding decorations must: obey the |
| constraints on storage class, type, and descriptor type described in |
| <<interfaces-resources-setandbinding,DescriptorSet and Binding |
| Assignment>> |
| ifdef::VK_NV_cooperative_matrix[] |
| * [[VUID-{refpage}-OpCooperativeMatrixLoadNV-06324]] |
| For code:OpCooperativeMatrixLoadNV and code:OpCooperativeMatrixStoreNV |
| instructions, the code:Pointer and code:Stride operands must: be aligned |
| to at least the lesser of 16 bytes or the natural alignment of a row or |
| column (depending on code:ColumnMajor) of the matrix (where the natural |
| alignment is the number of columns/rows multiplied by the component |
| size). |
| endif::VK_NV_cooperative_matrix[] |
| ifdef::VK_KHR_portability_subset[] |
| * [[VUID-{refpage}-shaderSampleRateInterpolationFunctions-06325]] |
| If the `apiext:VK_KHR_portability_subset` extension is enabled, and |
| slink:VkPhysicalDevicePortabilitySubsetFeaturesKHR::pname:shaderSampleRateInterpolationFunctions |
| is ename:VK_FALSE, then `GLSL.std.450` fragment interpolation functions |
| are not supported by the implementation and code:OpCapability must: not |
| be set to code:InterpolationFunction. |
| * [[VUID-{refpage}-tessellationShader-06326]] |
| If <<features-tessellationShader,pname:tessellationShader>> is enabled, |
| and the `apiext:VK_KHR_portability_subset` extension is enabled, and |
| slink:VkPhysicalDevicePortabilitySubsetFeaturesKHR::pname:tessellationIsolines |
| is ename:VK_FALSE, then code:OpExecutionMode must: not be set to |
| code:IsoLines. |
| * [[VUID-{refpage}-tessellationShader-06327]] |
| If <<features-tessellationShader,pname:tessellationShader>> is enabled, |
| and the `apiext:VK_KHR_portability_subset` extension is enabled, and |
| slink:VkPhysicalDevicePortabilitySubsetFeaturesKHR::pname:tessellationPointMode |
| is ename:VK_FALSE, then code:OpExecutionMode must: not be set to |
| code:PointMode. |
| endif::VK_KHR_portability_subset[] |
| ifdef::VK_KHR_8bit_storage[] |
| * [[VUID-{refpage}-storageBuffer8BitAccess-06328]] |
| If <<features-storageBuffer8BitAccess,pname:storageBuffer8BitAccess>> is |
| ename:VK_FALSE, then objects containing an 8-bit integer element must: |
| not have storage class of *StorageBuffer*, *ShaderRecordBufferKHR*, or |
| *PhysicalStorageBuffer*. |
| * [[VUID-{refpage}-uniformAndStorageBuffer8BitAccess-06329]] |
| If |
| <<features-uniformAndStorageBuffer8BitAccess,pname:uniformAndStorageBuffer8BitAccess>> |
| is ename:VK_FALSE, then objects in the *Uniform* storage class with the |
| *Block* decoration must: not have an 8-bit integer member. |
| * [[VUID-{refpage}-storagePushConstant8-06330]] |
| If <<features-storagePushConstant8,pname:storagePushConstant8>> is |
| ename:VK_FALSE, then objects containing an 8-bit integer element must: |
| not have storage class of *PushConstant*. |
| endif::VK_KHR_8bit_storage[] |
| ifdef::VK_KHR_16bit_storage[] |
| * [[VUID-{refpage}-storageBuffer16BitAccess-06331]] |
| If <<features-storageBuffer16BitAccess,pname:storageBuffer16BitAccess>> |
| is ename:VK_FALSE, then objects containing 16-bit integer or 16-bit |
| floating-point elements must: not have storage class of *StorageBuffer*, |
| *ShaderRecordBufferKHR*, or *PhysicalStorageBuffer*. |
| * [[VUID-{refpage}-uniformAndStorageBuffer16BitAccess-06332]] |
| If |
| <<features-uniformAndStorageBuffer16BitAccess,pname:uniformAndStorageBuffer16BitAccess>> |
| is ename:VK_FALSE, then objects in the *Uniform* storage class with the |
| *Block* decoration must: not have 16-bit integer or 16-bit |
| floating-point members. |
| * [[VUID-{refpage}-storagePushConstant16-06333]] |
| If <<features-storagePushConstant16,pname:storagePushConstant16>> is |
| ename:VK_FALSE, then objects containing 16-bit integer or 16-bit |
| floating-point elements must: not have storage class of *PushConstant*. |
| * [[VUID-{refpage}-storageInputOutput16-06334]] |
| If <<features-storageInputOutput16,pname:storageInputOutput16>> is |
| ename:VK_FALSE, then objects containing 16-bit integer or 16-bit |
| floating-point elements must: not have storage class of *Input* or |
| *Output*. |
| endif::VK_KHR_16bit_storage[] |
| ifdef::VK_EXT_shader_atomic_float[] |
| ifndef::VK_EXT_shader_atomic_float2[] |
| * [[VUID-{refpage}-None-06335]] |
| <<features-shaderBufferFloat32Atomics,shaderBufferFloat32Atomics>>, or |
| <<features-shaderBufferFloat32AtomicAdd,shaderBufferFloat32AtomicAdd>>, |
| or <<features-shaderSharedFloat32Atomics,shaderSharedFloat32Atomics>>, |
| or |
| <<features-shaderSharedFloat32AtomicAdd,shaderSharedFloat32AtomicAdd>>, |
| or <<features-shaderImageFloat32Atomics,shaderImageFloat32Atomics>>, or |
| <<features-shaderImageFloat32AtomicAdd,shaderImageFloat32AtomicAdd>> |
| must: be enabled for 32-bit floating point atomic operations |
| * [[VUID-{refpage}-None-06336]] |
| <<features-shaderBufferFloat64Atomics,shaderBufferFloat64Atomics>>, or |
| <<features-shaderBufferFloat64AtomicAdd,shaderBufferFloat64AtomicAdd>>, |
| or <<features-shaderSharedFloat64Atomics,shaderSharedFloat64Atomics>>, |
| or |
| <<features-shaderSharedFloat64AtomicAdd,shaderSharedFloat64AtomicAdd>> |
| must: be enabled for 64-bit floating point atomic operations |
| endif::VK_EXT_shader_atomic_float2[] |
| endif::VK_EXT_shader_atomic_float[] |
| ifdef::VK_EXT_shader_atomic_float2[] |
| * [[VUID-{refpage}-None-06337]] |
| <<features-shaderBufferFloat16Atomics,shaderBufferFloat16Atomics>>, or |
| <<features-shaderBufferFloat16AtomicAdd,shaderBufferFloat16AtomicAdd>>, |
| or |
| <<features-shaderBufferFloat16AtomicMinMax,shaderBufferFloat16AtomicMinMax>>, |
| or <<features-shaderSharedFloat16Atomics,shaderSharedFloat16Atomics>>, |
| or |
| <<features-shaderSharedFloat16AtomicAdd,shaderSharedFloat16AtomicAdd>>, |
| or |
| <<features-shaderSharedFloat16AtomicMinMax,shaderSharedFloat16AtomicMinMax>> |
| must: be enabled for 16-bit floating point atomic operations |
| * [[VUID-{refpage}-None-06338]] |
| <<features-shaderBufferFloat32Atomics,shaderBufferFloat32Atomics>>, or |
| <<features-shaderBufferFloat32AtomicAdd,shaderBufferFloat32AtomicAdd>>, |
| or <<features-shaderSharedFloat32Atomics,shaderSharedFloat32Atomics>>, |
| or |
| <<features-shaderSharedFloat32AtomicAdd,shaderSharedFloat32AtomicAdd>>, |
| or <<features-shaderImageFloat32Atomics,shaderImageFloat32Atomics>>, or |
| <<features-shaderImageFloat32AtomicAdd,shaderImageFloat32AtomicAdd>> or |
| <<features-shaderBufferFloat32AtomicMinMax,shaderBufferFloat32AtomicMinMax>>, |
| or |
| <<features-shaderSharedFloat32AtomicMinMax,shaderSharedFloat32AtomicMinMax>>, |
| or |
| <<features-shaderImageFloat32AtomicMinMax,shaderImageFloat32AtomicMinMax>> |
| must: be enabled for 32-bit floating point atomic operations |
| * [[VUID-{refpage}-None-06339]] |
| <<features-shaderBufferFloat64Atomics,shaderBufferFloat64Atomics>>, or |
| <<features-shaderBufferFloat64AtomicAdd,shaderBufferFloat64AtomicAdd>>, |
| or <<features-shaderSharedFloat64Atomics,shaderSharedFloat64Atomics>>, |
| or |
| <<features-shaderSharedFloat64AtomicAdd,shaderSharedFloat64AtomicAdd>>, |
| or |
| <<features-shaderBufferFloat64AtomicMinMax,shaderBufferFloat64AtomicMinMax>>, |
| or |
| <<features-shaderSharedFloat64AtomicMinMax,shaderSharedFloat64AtomicMinMax>>, |
| must: be enabled for 64-bit floating point atomic operations |
| endif::VK_EXT_shader_atomic_float2[] |
| * [[VUID-{refpage}-NonWritable-06340]] |
| If <<features-fragmentStoresAndAtomics, fragmentStoresAndAtomics>> is |
| not enabled, then all storage image, storage texel buffer, and storage |
| buffer variables in the fragment stage must: be decorated with the |
| code:NonWritable decoration. |
| * [[VUID-{refpage}-NonWritable-06341]] |
| If <<features-vertexPipelineStoresAndAtomics, |
| vertexPipelineStoresAndAtomics>> is not enabled, then all storage image, |
| storage texel buffer, and storage buffer variables in the vertex, |
| tessellation, and geometry stages must: be decorated with the |
| code:NonWritable decoration. |
| * [[VUID-{refpage}-None-06342]] |
| If <<limits-subgroupQuadOperationsInAllStages, |
| subgroupQuadOperationsInAllStages>> is ename:VK_FALSE, then |
| <<features-subgroup-quad,quad subgroup operations>> must: not be used |
| except for in fragment and compute stages. |
| ifdef::VK_VERSION_1_1[] |
| * [[VUID-{refpage}-None-06343]] |
| <<shaders-group-operations,Group operations>> with |
| <<shaders-scope-subgroup, subgroup scope>> must: not be used if the |
| shader stage is not in <<limits-subgroupSupportedStages, |
| subgroupSupportedStages>>. |
| endif::VK_VERSION_1_1[] |
| * [[VUID-{refpage}-Offset-06344]] |
| The first element of the code:Offset operand of code:InterpolateAtOffset |
| must: be greater than or equal to: |
| {empty}:: [eq]#frag~width~ {times} <<limits-minInterpolationOffset, |
| pname:minInterpolationOffset>># |
| + |
| where [eq]#frag~width~# is the width of the current fragment in pixels. |
| * [[VUID-{refpage}-Offset-06345]] |
| The first element of the code:Offset operand of code:InterpolateAtOffset |
| must: be less than or equal to: |
| {empty}:: [eq]#frag~width~ {times} (<<limits-maxInterpolationOffset, |
| pname:maxInterpolationOffset>> {plus} ULP ) - ULP# |
| + |
| where [eq]#frag~width~# is the width of the current fragment in pixels and |
| [eq]#ULP = 1 / |
| 2^<<limits-subPixelInterpolationOffsetBits,pname:subPixelInterpolationOffsetBits>>^#. |
| * [[VUID-{refpage}-Offset-06346]] |
| The second element of the code:Offset operand of |
| code:InterpolateAtOffset must: be greater than or equal to: |
| {empty}:: [eq]#frag~height~ {times} <<limits-minInterpolationOffset, |
| pname:minInterpolationOffset>># |
| + |
| where [eq]#frag~height~# is the height of the current fragment in pixels. |
| * [[VUID-{refpage}-Offset-06347]] |
| The second element of the code:Offset operand of |
| code:InterpolateAtOffset must: be less than or equal to: |
| {empty}:: [eq]#frag~height~ {times} (<<limits-maxInterpolationOffset, |
| pname:maxInterpolationOffset>> {plus} ULP ) - ULP# |
| + |
| where [eq]#frag~height~# is the height of the current fragment in pixels and |
| [eq]#ULP = 1 / |
| 2^<<limits-subPixelInterpolationOffsetBits,pname:subPixelInterpolationOffsetBits>>^#. |
| |
| ifdef::VK_KHR_ray_query[] |
| * [[VUID-{refpage}-OpRayQueryInitializeKHR-06348]] |
| For code:OpRayQueryInitializeKHR instructions, all components of the |
| code:RayOrigin and code:RayDirection operands must: be finite |
| floating-point values. |
| * [[VUID-{refpage}-OpRayQueryInitializeKHR-06349]] |
| For code:OpRayQueryInitializeKHR instructions, the code:RayTmin and |
| code:RayTmax operands must: be non-negative floating-point values. |
| * [[VUID-{refpage}-OpRayQueryInitializeKHR-06350]] |
| For code:OpRayQueryInitializeKHR instructions, the code:RayTmin operand |
| must: be less than or equal to the code:RayTmax operand. |
| * [[VUID-{refpage}-OpRayQueryInitializeKHR-06351]] |
| For code:OpRayQueryInitializeKHR instructions, code:RayOrigin, |
| code:RayDirection, code:RayTmin, and code:RayTmax operands must: not |
| contain NaNs. |
| * [[VUID-{refpage}-OpRayQueryInitializeKHR-06352]] |
| For code:OpRayQueryInitializeKHR instructions, code:Acceleration |
| code:Structure must: be an acceleration structure built as a |
| <<acceleration-structure-top-level, top-level acceleration structure>>. |
| * [[VUID-{refpage}-OpRayQueryGenerateIntersectionKHR-06353]] |
| For code:OpRayQueryGenerateIntersectionKHR instructions, code:Hit code:T |
| must: satisfy the condition [eq]##code:RayTmin {leq} code:Hit code:T |
| {leq} code:RayTmax##, where code:RayTmin is equal to the value returned |
| by code:OpRayQueryGetRayTMinKHR with the same ray query object, and |
| code:RayTmax is equal to the value of code:OpRayQueryGetIntersectionTKHR |
| for the current committed intersection with the same ray query object. |
| ifdef::VK_NV_ray_tracing_motion_blur[] |
| * [[VUID-{refpage}-OpRayQueryGenerateIntersectionKHR-06354]] |
| For code:OpRayQueryGenerateIntersectionKHR instructions, |
| code:Acceleration code:Structure must: not be built with |
| ename:VK_BUILD_ACCELERATION_STRUCTURE_MOTION_BIT_NV in pname:flags. |
| endif::VK_NV_ray_tracing_motion_blur[] |
| endif::VK_KHR_ray_query[] |
| ifdef::VK_KHR_ray_tracing_pipeline[] |
| * [[VUID-{refpage}-OpTraceRayKHR-06355]] |
| For code:OpTraceRayKHR instructions, all components of the |
| code:RayOrigin and code:RayDirection operands must: be finite |
| floating-point values. |
| * [[VUID-{refpage}-OpTraceRayKHR-06356]] |
| For code:OpTraceRayKHR instructions, the code:RayTmin and code:RayTmax |
| operands must: be non-negative floating-point values. |
| * [[VUID-{refpage}-OpTraceRayKHR-06357]] |
| For code:OpTraceRayKHR instructions, the code:RayTmin operand must: be |
| less than or equal to the code:RayTmax operand. |
| * [[VUID-{refpage}-OpTraceRayKHR-06358]] |
| For code:OpTraceRayKHR instructions, code:RayOrigin, code:RayDirection, |
| code:RayTmin, and code:RayTmax operands must: not contain NaNs. |
| * [[VUID-{refpage}-OpTraceRayKHR-06359]] |
| For code:OpTraceRayKHR instructions, code:Acceleration code:Structure |
| must: be an acceleration structure built as a |
| <<acceleration-structure-top-level, top-level acceleration structure>>. |
| endif::VK_KHR_ray_tracing_pipeline[] |
| ifdef::VK_NV_ray_tracing_motion_blur[] |
| * [[VUID-{refpage}-OpTraceRayKHR-06360]] |
| For code:OpTraceRayKHR instructions, if code:Acceleration code:Structure |
| was built with ename:VK_BUILD_ACCELERATION_STRUCTURE_MOTION_BIT_NV in |
| pname:flags, the pipeline must: have been created with |
| ename:VK_PIPELINE_CREATE_RAY_TRACING_ALLOW_MOTION_BIT_NV set |
| * [[VUID-{refpage}-OpTraceRayMotionNV-06361]] |
| For code:OpTraceRayMotionNV instructions, all components of the |
| code:RayOrigin and code:RayDirection operands must: be finite |
| floating-point values. |
| * [[VUID-{refpage}-OpTraceRayMotionNV-06362]] |
| For code:OpTraceRayMotionNV instructions, the code:RayTmin and |
| code:RayTmax operands must: be non-negative floating-point values. |
| * [[VUID-{refpage}-OpTraceRayMotionNV-06363]] |
| For code:OpTraceRayMotionNV instructions, the code:RayTmin operand must: |
| be less than or equal to the code:RayTmax operand. |
| * [[VUID-{refpage}-OpTraceRayMotionNV-06364]] |
| For code:OpTraceRayMotionNV instructions, code:RayOrigin, |
| code:RayDirection, code:RayTmin, and code:RayTmax operands must: not |
| contain NaNs. |
| * [[VUID-{refpage}-OpTraceRayMotionNV-06365]] |
| For code:OpTraceRayMotionNV instructions, code:Acceleration |
| code:Structure must: be an acceleration structure built as a |
| <<acceleration-structure-top-level, top-level acceleration structure>> |
| with ename:VK_BUILD_ACCELERATION_STRUCTURE_MOTION_BIT_NV in pname:flags |
| * [[VUID-{refpage}-OpTraceRayMotionNV-06366]] |
| For code:OpTraceRayMotionNV instructions the code:time operand must: be |
| between 0.0 and 1.0 |
| * [[VUID-{refpage}-OpTraceRayMotionNV-06367]] |
| For code:OpTraceRayMotionNV instructions the pipeline must: have been |
| created with ename:VK_PIPELINE_CREATE_RAY_TRACING_ALLOW_MOTION_BIT_NV |
| set |
| endif::VK_NV_ray_tracing_motion_blur[] |
| * [[VUID-{refpage}-x-06429]] |
| The pname:x size in code:LocalSize or code:LocalSizeId must: be less |
| than or equal to |
| sname:VkPhysicalDeviceLimits::pname:maxComputeWorkGroupSize[0] |
| * [[VUID-{refpage}-y-06430]] |
| The pname:y size in code:LocalSize or code:LocalSizeId must: be less |
| than or equal to |
| sname:VkPhysicalDeviceLimits::pname:maxComputeWorkGroupSize[1] |
| * [[VUID-{refpage}-z-06431]] |
| The pname:z size in code:LocalSize or code:LocalSizeId must: be less |
| than or equal to |
| sname:VkPhysicalDeviceLimits::pname:maxComputeWorkGroupSize[2] |
| * [[VUID-{refpage}-x-06432]] |
| The product of pname:x size, pname:y size, and pname:z size in |
| code:LocalSize or code:LocalSizeId must: be less than or equal to |
| sname:VkPhysicalDeviceLimits::pname:maxComputeWorkGroupInvocations |
| ifndef::VK_KHR_maintenance4[] |
| * [[VUID-{refpage}-LocalSizeId-06433]] |
| The execution mode code:LocalSizeId must: not be used |
| endif::VK_KHR_maintenance4[] |
| ifdef::VK_KHR_maintenance4[] |
| * [[VUID-{refpage}-LocalSizeId-06434]] |
| if execution mode code:LocalSizeId is used, <<features-maintenance4, |
| pname:maintenance4>> must: be enabled |
| endif::VK_KHR_maintenance4[] |
| ifdef::VK_KHR_zero_initialize_workgroup_memory[] |
| * [[VUID-{refpage}-shaderZeroInitializeWorkgroupMemory-06372]] |
| If |
| <<features-shaderZeroInitializeWorkgroupMemory,pname:shaderZeroInitializeWorkgroupMemory>> |
| is not enabled, any code:OpVariable with *Workgroup* as its *Storage |
| Class* must: not have an code:Initializer operand |
| endif::VK_KHR_zero_initialize_workgroup_memory[] |
| ifndef::VK_KHR_zero_initialize_workgroup_memory[] |
| * [[VUID-{refpage}-OpVariable-06373]] |
| Any code:OpVariable with *Workgroup* as its *Storage Class* must: not |
| have an code:Initializer operand |
| endif::VK_KHR_zero_initialize_workgroup_memory[] |
| ifdef::VK_KHR_workgroup_memory_explicit_layout[] |
| * [[VUID-{refpage}-workgroupMemoryExplicitLayout8BitAccess-06374]] |
| If |
| <<features-workgroupMemoryExplicitLayout8BitAccess,pname:workgroupMemoryExplicitLayout8BitAccess>> |
| is ename:VK_FALSE, objects in the code:Workgroup storage class with the |
| code:Block decoration must: not contain 8-bit integer members. |
| * [[VUID-{refpage}-workgroupMemoryExplicitLayout16BitAccess-06375]] |
| If |
| <<features-workgroupMemoryExplicitLayout16BitAccess,pname:workgroupMemoryExplicitLayout16BitAccess>> |
| is ename:VK_FALSE, objects in the code:Workgroup storage class with the |
| code:Block decoration must: not contain 16-bit integer or 16-bit |
| floating-point members. |
| endif::VK_KHR_workgroup_memory_explicit_layout[] |
| * [[VUID-{refpage}-OpImage-06376]] |
| If an code:OpImage*Gather operation has an image operand of code:Offset, |
| code:ConstOffset, or code:ConstOffsets the offset value must: be greater |
| than or equal to <<limits-minTexelGatherOffset,minTexelGatherOffset>> |
| * [[VUID-{refpage}-OpImage-06377]] |
| If an code:OpImage*Gather operation has an image operand of code:Offset, |
| code:ConstOffset, or code:ConstOffsets the offset value must: be less |
| than or equal to <<limits-maxTexelGatherOffset,maxTexelGatherOffset>> |
| * [[VUID-{refpage}-OpImageSample-06435]] |
| If an code:OpImageSample* or code:OpImageFetch* operation has an image |
| operand of code:ConstOffset then the offset value must: be greater than |
| or equal to <<limits-minTexelOffset,minTexelOffset>> |
| * [[VUID-{refpage}-OpImageSample-06436]] |
| If an code:OpImageSample* or code:OpImageFetch* operation has an image |
| operand of code:ConstOffset then the offset value must: be less than or |
| equal to <<limits-maxTexelOffset,maxTexelOffset>> |
| ifdef::VK_QCOM_render_pass_shader_resolve[] |
| * [[VUID-{refpage}-SampleRateShading-06378]] |
| If the subpass description contains |
| ename:VK_SUBPASS_DESCRIPTION_FRAGMENT_REGION_BIT_QCOM, then the SPIR-V |
| fragment shader Capability code:SampleRateShading must: not be enabled. |
| endif::VK_QCOM_render_pass_shader_resolve[] |
| ifdef::VK_KHR_shader_subgroup_uniform_control_flow[] |
| * [[VUID-{refpage}-SubgroupUniformControlFlowKHR-06379]] |
| The execution mode code:SubgroupUniformControlFlowKHR must: not be |
| applied to an entry point unless |
| <<features-shaderSubgroupUniformControlFlow, |
| pname:shaderSubgroupUniformControlFlow>> is enabled and the |
| corresponding shader stage bit is set in subgroup |
| <<limits-subgroup-supportedStages, pname:supportedStages>> and the entry |
| point does not execute any <<ray-tracing-repack,_invocation repack |
| instructions_>>. |
| endif::VK_KHR_shader_subgroup_uniform_control_flow[] |
| **** |
| -- |
| |
| [[spirvenv-precision-operation]] |
| == Precision and Operation of SPIR-V Instructions |
| |
| The following rules apply to half, single, and double-precision floating |
| point instructions: |
| |
| * Positive and negative infinities and positive and negative zeros are |
| generated as dictated by <<ieee-754,IEEE 754>>, but subject to the |
| precisions allowed in the following table. |
| * Dividing a non-zero by a zero results in the appropriately signed |
| <<ieee-754,IEEE 754>> infinity. |
| * Signaling [eq]##NaN##s are not required to be generated and exceptions |
| are never raised. |
| Signaling [eq]##NaN## may: be converted to quiet [eq]##NaN##s values by |
| any floating point instruction. |
| * By default, the implementation may: perform optimizations on half, |
| single, or double-precision floating-point instructions that ignore sign |
| of a zero, or assume that arguments and results are not NaNs or |
| infinities. |
| ifdef::VK_VERSION_1_2,VK_KHR_shader_float_controls[] |
| If the entry point is declared with the code:SignedZeroInfNanPreserve |
| execution mode, then NaNs, infinities, and the sign of zero must: not be |
| ignored. |
| ** The following core SPIR-V instructions must: respect the |
| code:SignedZeroInfNanPreserve execution mode: code:OpPhi, |
| code:OpSelect, code:OpReturnValue, code:OpVectorExtractDynamic, |
| code:OpVectorInsertDynamic, code:OpVectorShuffle, |
| code:OpCompositeConstruct, code:OpCompositeExtract, |
| code:OpCompositeInsert, code:OpCopyObject, code:OpTranspose, |
| code:OpFConvert, code:OpFNegate, code:OpFAdd, code:OpFSub, code:OpFMul, |
| code:OpStore. |
| This execution mode must: also be respected by code:OpLoad except for |
| loads from the code:Input storage class in the fragment shader stage |
| with the floating-point result type. |
| Other SPIR-V instructions may: also respect the |
| code:SignedZeroInfNanPreserve execution mode. |
| endif::VK_VERSION_1_2,VK_KHR_shader_float_controls[] |
| * The following instructions must: not flush denormalized values: |
| code:OpConstant, code:OpConstantComposite, code:OpSpecConstant, |
| code:OpSpecConstantComposite, code:OpLoad, code:OpStore, code:OpBitcast, |
| code:OpPhi, code:OpSelect, code:OpFunctionCall, code:OpReturnValue, |
| code:OpVectorExtractDynamic, code:OpVectorInsertDynamic, |
| code:OpVectorShuffle, code:OpCompositeConstruct, |
| code:OpCompositeExtract, code:OpCompositeInsert, code:OpCopyMemory, |
| code:OpCopyObject. |
| ifndef::VK_VERSION_1_2,VK_KHR_shader_float_controls[] |
| * Any denormalized value input into a shader or potentially generated by |
| any instruction in a shader (except those listed above) may: be flushed |
| to 0. |
| * The rounding mode cannot: be set, and results will be |
| <<spirvenv-correctly-rounded, correctly rounded>>, as described below. |
| * [eq]##NaN##s may: not be generated. |
| Instructions that operate on a [eq]#NaN# may: not result in a [eq]#NaN#. |
| endif::VK_VERSION_1_2,VK_KHR_shader_float_controls[] |
| ifdef::VK_VERSION_1_2,VK_KHR_shader_float_controls[] |
| * Denormalized values are supported. |
| ** By default, any half, single, or double-precision denormalized value |
| input into a shader or potentially generated by any instruction (except |
| those listed above) or any extended instructions for GLSL in a shader |
| may: be flushed to zero. |
| ** If the entry point is declared with the code:DenormFlushToZero |
| execution mode then for the affected instuctions the denormalized |
| result must: be flushed to zero and the denormalized operands may: be |
| flushed to zero. |
| Denormalized values obtained via unpacking an integer into a vector of |
| values with smaller bit width and interpreting those values as |
| floating-point numbers must: be flushed to zero. |
| ** The following core SPIR-V instructions must: respect the |
| code:DenormFlushToZero execution mode: code:OpSpecConstantOp (with |
| opcode code:OpFConvert), code:OpFConvert, code:OpFNegate, code:OpFAdd, |
| code:OpFSub, code:OpFMul, code:OpFDiv, code:OpFRem, code:OpFMod, |
| code:OpVectorTimesScalar, code:OpMatrixTimesScalar, |
| code:OpVectorTimesMatrix, code:OpMatrixTimesVector, |
| code:OpMatrixTimesMatrix, code:OpOuterProduct, code:OpDot; and the |
| following extended instructions for GLSL: code:Round, code:RoundEven, |
| code:Trunc, code:FAbs, code:Floor, code:Ceil, code:Fract, code:Radians, |
| code:Degrees, code:Sin, code:Cos, code:Tan, code:Asin, code:Acos, |
| code:Atan, code:Sinh, code:Cosh, code:Tanh, code:Asinh, code:Acosh, |
| code:Atanh, code:Atan2, code:Pow, code:Exp, code:Log, code:Exp2, |
| code:Log2, code:Sqrt, code:InverseSqrt, code:Determinant, |
| code:MatrixInverse, code:Modf, code:ModfStruct, code:FMin, code:FMax, |
| code:FClamp, code:FMix, code:Step, code:SmoothStep, code:Fma, |
| code:UnpackHalf2x16, code:UnpackDouble2x32, code:Length, code:Distance, |
| code:Cross, code:Normalize, code:FaceForward, code:Reflect, |
| code:Refract, code:NMin, code:NMax, code:NClamp. |
| Other SPIR-V instructions (except those excluded above) may: also flush |
| denormalized values. |
| ** The following core SPIR-V instructions must: respect the |
| code:DenormPreserve execution mode: code:OpTranspose, |
| code:OpSpecConstantOp, code:OpFConvert, code:OpFNegate, code:OpFAdd, |
| code:OpFSub, code:OpFMul, code:OpVectorTimesScalar, |
| code:OpMatrixTimesScalar, code:OpVectorTimesMatrix, |
| code:OpMatrixTimesVector, code:OpMatrixTimesMatrix, |
| code:OpOuterProduct, code:OpDot, code:OpFOrdEqual, code:OpFUnordEqual, |
| code:OpFOrdNotEqual, code:OpFUnordNotEqual, code:OpFOrdLessThan, |
| code:OpFUnordLessThan, code:OpFOrdGreaterThan, |
| code:OpFUnordGreaterThan, code:OpFOrdLessThanEqual, |
| code:OpFUnordLessThanEqual, code:OpFOrdGreaterThanEqual, |
| code:OpFUnordGreaterThanEqual; and the following extended instructions |
| for GLSL: code:FAbs, code:FSign, code:Radians, code:Degrees, code:FMin, |
| code:FMax, code:FClamp, code:FMix, code:Fma, code:PackHalf2x16, |
| code:PackDouble2x32, code:UnpackHalf2x16, code:UnpackDouble2x32, |
| code:NMin, code:NMax, code:NClamp. |
| Other SPIR-V instructions may: also preserve denorm values. |
| endif::VK_VERSION_1_2,VK_KHR_shader_float_controls[] |
| |
| The precision of double-precision instructions is at least that of single |
| precision. |
| |
| The precision of operations is defined either in terms of rounding, as an |
| error bound in ULP, or as inherited from a formula as follows. |
| |
| [[spirvenv-correctly-rounded]] |
| .Correctly Rounded |
| Operations described as "`correctly rounded`" will return the infinitely |
| precise result, [eq]#x#, rounded so as to be representable in |
| floating-point. |
| ifdef::VK_VERSION_1_2,VK_KHR_shader_float_controls[] |
| The rounding mode is not specified, unless the entry point is declared with |
| the code:RoundingModeRTE or the code:RoundingModeRTZ execution mode. |
| These execution modes affect only correctly rounded SPIR-V instructions. |
| These execution modes do not affect code:OpQuantizeToF16. |
| If the rounding mode is not specified then this rounding is implementation |
| specific, subject to the following rules. |
| endif::VK_VERSION_1_2,VK_KHR_shader_float_controls[] |
| ifndef::VK_VERSION_1_2,VK_KHR_shader_float_controls[] |
| The rounding mode used is not defined but must: obey the following rules. |
| endif::VK_VERSION_1_2,VK_KHR_shader_float_controls[] |
| If [eq]#x# is exactly representable then [eq]#x# will be returned. |
| Otherwise, either the floating-point value closest to and no less than |
| [eq]#x# or the value closest to and no greater than [eq]#x# will be |
| returned. |
| |
| .ULP |
| Where an error bound of [eq]#n# ULP (units in the last place) is given, for |
| an operation with infinitely precise result #x# the value returned must: be |
| in the range [eq]#[x - n {times} ulp(x), x {plus} n {times} ulp(x)]#. |
| The function [eq]#ulp(x)# is defined as follows: |
| |
| {empty}:: If there exist non-equal floating-point numbers #a# and #b# such |
| that [eq]#a {leq} x {leq} b# then [eq]#ulp(x)# is the minimum possible |
| distance between such numbers, latexmath:[ulp(x) = \mathrm{min}_{a,b} | |
| b - a |]. |
| If such numbers do not exist then [eq]#ulp(x)# is defined to be the |
| difference between the two finite floating-point numbers nearest to |
| [eq]#x#. |
| |
| Where the range of allowed return values includes any value of magnitude |
| larger than that of the largest representable finite floating-point number, |
| operations may:, additionally, return either an infinity of the appropriate |
| sign or the finite number with the largest magnitude of the appropriate |
| sign. |
| If the infinitely precise result of the operation is not mathematically |
| defined then the value returned is undefined:. |
| |
| .Inherited From ... |
| Where an operation's precision is described as being inherited from a |
| formula, the result returned must: be at least as accurate as the result of |
| computing an approximation to [eq]#x# using a formula equivalent to the |
| given formula applied to the supplied inputs. |
| Specifically, the formula given may be transformed using the mathematical |
| associativity, commutativity and distributivity of the operators involved to |
| yield an equivalent formula. |
| The SPIR-V precision rules, when applied to each such formula and the given |
| input values, define a range of permitted values. |
| If [eq]#NaN# is one of the permitted values then the operation may return |
| any result, otherwise let the largest permitted value in any of the ranges |
| be [eq]#F~max~# and the smallest be [eq]#F~min~#. |
| The operation must: return a value in the range [eq]#[x - E, x {plus} E]# |
| where latexmath:[E = \mathrm{max} \left( | x - F_{\mathrm{min}} |, | x - |
| F_{\mathrm{max}} | \right) ]. |
| ifdef::VK_VERSION_1_2,VK_KHR_shader_float_controls[] |
| If the entry point is declared with the code:DenormFlushToZero execution |
| mode, then any intermediate denormal value(s) while evaluating the formula |
| may: be flushed to zero. |
| Denormal final results must: be flushed to zero. |
| If the entry point is declared with the code:DenormPreserve execution mode, |
| then denormals must: be preserved throughout the formula. |
| endif::VK_VERSION_1_2,VK_KHR_shader_float_controls[] |
| |
| ifdef::VK_VERSION_1_2,VK_KHR_shader_float16_int8[] |
| For half- (16 bit) and single- (32 bit) precision instructions, precisions |
| are required: to be at least as follows: |
| |
| .Precision of core SPIR-V Instructions |
| [options="header", cols=",,"] |
| |==== |
| | Instruction |
| | Single precision, unless decorated with RelaxedPrecision | Half precision |
| | code:OpFAdd |
| 2+| Correctly rounded. |
| | code:OpFSub |
| 2+| Correctly rounded. |
| | code:OpFMul, code:OpVectorTimesScalar, code:OpMatrixTimesScalar |
| 2+| Correctly rounded. |
| | code:OpDot(x, y) |
| 2+a| Inherited from latexmath:[\sum_{i = 0}^{n - 1} x_{i} \times y_{i}]. |
| | code:OpFOrdEqual, code:OpFUnordEqual |
| 2+| Correct result. |
| | code:OpFOrdLessThan, code:OpFUnordLessThan |
| 2+| Correct result. |
| | code:OpFOrdGreaterThan, code:OpFUnordGreaterThan |
| 2+| Correct result. |
| | code:OpFOrdLessThanEqual, code:OpFUnordLessThanEqual |
| 2+| Correct result. |
| | code:OpFOrdGreaterThanEqual, code:OpFUnordGreaterThanEqual |
| 2+| Correct result. |
| | code:OpFDiv(x,y) |
| | 2.5 ULP for [eq]#{vert}y{vert}# in the range [2^-126^, 2^126^]. | 2.5 ULP for [eq]#{vert}y{vert}# in the range [2^-14^, 2^14^]. |
| | code:OpFRem(x,y) |
| 2+| Inherited from [eq]#x - y {times} trunc(x/y)#. |
| | code:OpFMod(x,y) |
| 2+| Inherited from [eq]#x - y {times} floor(x/y)#. |
| | conversions between types |
| 2+| Correctly rounded. |
| |==== |
| |
| [NOTE] |
| .Note |
| ==== |
| The code:OpFRem and code:OpFMod instructions use cheap approximations of |
| remainder, and the error can be large due to the discontinuity in trunc() |
| and floor(). |
| This can produce mathematically unexpected results in some cases, such as |
| FMod(x,x) computing x rather than 0, and can also cause the result to have a |
| different sign than the infinitely precise result. |
| ==== |
| |
| .Precision of GLSL.std.450 Instructions |
| [options="header", cols=",,"] |
| |==== |
| |Instruction |
| | Single precision, unless decorated with RelaxedPrecision | Half precision |
| | code:fma() |
| 2+| Inherited from code:OpFMul followed by code:OpFAdd. |
| | code:exp(x), code:exp2(x) |
| a| latexmath:[3 + 2 \times \vert x \vert] ULP. a| latexmath:[1 + 2 \times \vert x \vert] ULP. |
| | code:log(), code:log2() |
| a| 3 ULP outside the range latexmath:[[0.5, 2.0\]]. Absolute error < latexmath:[2^{-21}] inside the range latexmath:[[0.5, 2.0\]]. |
| a| 3 ULP outside the range latexmath:[[0.5, 2.0\]]. Absolute error < latexmath:[2^{-7}] inside the range latexmath:[[0.5, 2.0\]]. |
| | code:pow(x, y) |
| 2+| Inherited from code:exp2(y {times} code:log2(x)). |
| | code:sqrt() |
| 2+| Inherited from 1.0 / code:inversesqrt(). |
| | code:inversesqrt() |
| 2+| 2 ULP. |
| | code:radians(x) |
| 2+a| Inherited from latexmath:[x \times \frac{\pi}{180}]. |
| | code:degrees(x) |
| 2+a| Inherited from latexmath:[x \times \frac{180}{\pi}]. |
| | code:sin() |
| a| Absolute error latexmath:[\leq 2^{-11}] inside the range latexmath:[[-\pi, \pi\]]. a| Absolute error latexmath:[\leq 2^{-7}] inside the range latexmath:[[-\pi, \pi\]]. |
| | code:cos() |
| a| Absolute error latexmath:[\leq 2^{-11}] inside the range latexmath:[[-\pi, \pi\]]. a| Absolute error latexmath:[\leq 2^{-7}] inside the range latexmath:[[-\pi, \pi\]]. |
| | code:tan() |
| 2+a| Inherited from latexmath:[\frac{\sin()}{\cos()}]. |
| | code:asin(x) |
| 2+a| Inherited from latexmath:[\mathrm{atan2}(x, sqrt(1.0 - x \times x))]. |
| | code:acos(x) |
| 2+a| Inherited from latexmath:[\mathrm{atan2}(sqrt(1.0 - x \times x), x)]. |
| | code:atan(), code:atan2() |
| | 4096 ULP | 5 ULP. |
| | code:sinh(x) |
| 2+a| Inherited from latexmath:[(\exp(x) - \exp(-x)) \times 0.5]. |
| | code:cosh(x) |
| 2+a| Inherited from latexmath:[(\exp(x) + \exp(-x)) \times 0.5]. |
| | code:tanh() |
| 2+a| Inherited from latexmath:[\frac{\sinh()}{\cosh()}]. |
| | code:asinh(x) |
| 2+a| Inherited from latexmath:[\log(x + sqrt(x \times x + 1.0))]. |
| | code:acosh(x) |
| 2+a| Inherited from latexmath:[\log(x + sqrt(x \times x - 1.0))]. |
| | code:atanh(x) |
| 2+a| Inherited from latexmath:[\log(\frac{1.0 + x}{1.0 - x}) \times 0.5]. |
| | code:frexp() |
| 2+| Correctly rounded. |
| | code:ldexp() |
| 2+| Correctly rounded. |
| | code:length(x) |
| 2+a| Inherited from latexmath:[sqrt(dot(x, x))]. |
| | code:distance(x, y) |
| 2+a| Inherited from latexmath:[length(x - y)]. |
| | code:cross() |
| 2+| Inherited from [eq]#code:OpFSub(code:OpFMul, code:OpFMul)#. |
| | code:normalize(x) |
| 2+a| Inherited from latexmath:[\frac{x}{length(x)}]. |
| | code:faceforward(N, I, NRef) |
| 2+| Inherited from [eq]#code:dot(NRef, I) < 0.0 ? N : -N#. |
| | code:reflect(x, y) |
| 2+| Inherited from [eq]#x - 2.0 {times} code:dot(y, x) {times} y#. |
| | code:refract(I, N, eta) |
| 2+| Inherited from [eq]#k < 0.0 ? 0.0 : eta {times} I - (eta {times} code:dot(N, I) {plus} code:sqrt(k)) {times} N#, where [eq]#k = 1 - eta {times} eta {times} (1.0 - code:dot(N, I) {times} code:dot(N, I))#. |
| | code:round |
| 2+| Correctly rounded. |
| | code:roundEven |
| 2+| Correctly rounded. |
| | code:trunc |
| 2+| Correctly rounded. |
| | code:fabs |
| 2+| Correctly rounded. |
| | code:fsign |
| 2+| Correctly rounded. |
| | code:floor |
| 2+| Correctly rounded. |
| | code:ceil |
| 2+| Correctly rounded. |
| | code:fract |
| 2+| Correctly rounded. |
| | code:modf |
| 2+| Correctly rounded. |
| | code:fmin |
| 2+| Correctly rounded. |
| | code:fmax |
| 2+| Correctly rounded. |
| | code:fclamp |
| 2+| Correctly rounded. |
| | code:fmix(x, y, a) |
| 2+a| Inherited from latexmath:[x \times (1.0 - a) + y \times a]. |
| | code:step |
| 2+| Correctly rounded. |
| | code:smoothStep(edge0, edge1, x) |
| 2+a| Inherited from latexmath:[t \times t \times (3.0 - 2.0 \times t)], |
| where latexmath:[t = clamp(\frac{x - edge0}{edge1 - edge0}, 0.0, 1.0)]. |
| | code:nmin |
| 2+| Correctly rounded. |
| | code:nmax |
| 2+| Correctly rounded. |
| | code:nclamp |
| 2+| Correctly rounded. |
| |==== |
| endif::VK_VERSION_1_2,VK_KHR_shader_float16_int8[] |
| |
| ifndef::VK_VERSION_1_2,VK_KHR_shader_float16_int8[] |
| For single precision (32 bit) instructions, precisions are required: to be |
| at least as follows, unless decorated with RelaxedPrecision: |
| |
| .Precision of core SPIR-V Instructions |
| [options="header"] |
| |==== |
| | Instruction | Precision |
| | code:OpFAdd | Correctly rounded. |
| | code:OpFSub | Correctly rounded. |
| | code:OpFMul, code:OpVectorTimesScalar, code:OpMatrixTimesScalar | Correctly rounded. |
| | code:OpFOrdEqual, code:OpFUnordEqual | Correct result. |
| | code:OpFOrdLessThan, code:OpFUnordLessThan | Correct result. |
| | code:OpFOrdGreaterThan, code:OpFUnordGreaterThan | Correct result. |
| | code:OpFOrdLessThanEqual, code:OpFUnordLessThanEqual | Correct result. |
| | code:OpFOrdGreaterThanEqual, code:OpFUnordGreaterThanEqual | Correct result. |
| | code:OpFDiv(x,y) | 2.5 ULP for [eq]#{vert}y{vert}# in the range [2^-126^, 2^126^]. |
| | conversions between types | Correctly rounded. |
| |==== |
| |
| .Precision of GLSL.std.450 Instructions |
| [options="header"] |
| |==== |
| |Instruction | Precision |
| | code:fma() | Inherited from code:OpFMul followed by code:OpFAdd. |
| | code:exp(x), code:exp2(x) | [eq]#3 {plus} 2 {times} {vert}x{vert}# ULP. |
| | code:log(), code:log2() | 3 ULP outside the range [eq]#[0.5, 2.0]#. Absolute error < [eq]#2^-21^# inside the range [eq]#[0.5, 2.0]#. |
| | code:pow(x, y) | Inherited from code:exp2(y {times} code:log2(x)). |
| | code:sqrt() | Inherited from 1.0 / code:inversesqrt(). |
| | code:inversesqrt() | 2 ULP. |
| |==== |
| endif::VK_VERSION_1_2,VK_KHR_shader_float16_int8[] |
| |
| GLSL.std.450 extended instructions specifically defined in terms of the |
| above instructions inherit the above errors. |
| GLSL.std.450 extended instructions not listed above and not defined in terms |
| of the above have undefined: precision. |
| |
| For the code:OpSRem and code:OpSMod instructions, if either operand is |
| negative the result is undefined:. |
| |
| [NOTE] |
| .Note |
| ==== |
| While the code:OpSRem and code:OpSMod instructions are supported by the |
| Vulkan environment, they require non-negative values and thus do not enable |
| additional functionality beyond what code:OpUMod provides. |
| ==== |
| |
| ifdef::VK_NV_cooperative_matrix[] |
| code:OpCooperativeMatrixMulAddNV performs its operations in an |
| implementation-dependent order and internal precision. |
| endif::VK_NV_cooperative_matrix[] |
| |
| [[spirvenv-image-signedness]] |
| == Signedness of SPIR-V Image Accesses |
| |
| SPIR-V associates a signedness with all integer image accesses. |
| This is required in certain parts of the SPIR-V and the Vulkan image access |
| pipeline to ensure defined results. |
| The signedness is determined from a combination of the access instruction's |
| code:Image code:Operands and the underlying image's code:Sampled code:Type |
| as follows: |
| |
| 1. If the instruction's code:Image code:Operands contains the |
| code:SignExtend operand then the access is signed. |
| 2. If the instruction's code:Image code:Operands contains the |
| code:ZeroExtend operand then the access is unsigned. |
| 3. Otherwise, the image accesses signedness matches that of the |
| code:Sampled code:Type of the code:OpTypeImage being accessed. |
| |
| [[spirvenv-format-type-matching]] |
| == Image Format and Type Matching |
| |
| When specifying the code:Image code:Format of an code:OpTypeImage, the |
| converted bit width and type, as shown in the table below, must: match the |
| code:Sampled code:Type. |
| The signedness must: match the <<spirvenv-image-signedness,signedness of any |
| access>> to the image. |
| |
| [NOTE] |
| .Note |
| ==== |
| Formatted accesses are always converted from a shader readable type to the |
| resource's format or vice versa via <<textures-format-conversion>> for reads |
| and <<textures-output-format-conversion>> for writes. |
| As such, the bit width and format below do not necessarily match 1:1 with |
| what might be expected for some formats. |
| ==== |
| |
| For a given code:Image code:Format, the code:Sampled code:Type must: be the |
| type described in the _Type_ column of the below table, with its |
| code:Literal code:Width set to that in the _Bit Width_ column. |
| Every access that is made to the image must: have a signedness equal to that |
| in the _Signedness_ column (where applicable). |
| |
| [options="autowidth"] |
| |=== |
| | Image Format | Type | Bit Width | Signedness |
| |
| | code:Unknown | Any | Any | Any |
| | code:Rgba32f .20+| code:OpTypeFloat .20+| 32 .20+| N/A |
| | code:Rg32f |
| | code:R32f |
| | code:Rgba16f |
| | code:Rg16f |
| | code:R16f |
| | code:Rgba16 |
| | code:Rg16 |
| | code:R16 |
| | code:Rgba16Snorm |
| | code:Rg16Snorm |
| | code:R16Snorm |
| | code:Rgb10A2 |
| | code:R11fG11fB10f |
| | code:Rgba8 |
| | code:Rg8 |
| | code:R8 |
| | code:Rgba8Snorm |
| | code:Rg8Snorm |
| | code:R8Snorm |
| | code:Rgba32i .19+| code:OpTypeInt .19+| 32 .9+| 1 |
| | code:Rg32i |
| | code:R32i |
| | code:Rgba16i |
| | code:Rg16i |
| | code:R16i |
| | code:Rgba8i |
| | code:Rg8i |
| | code:R8i |
| | code:Rgba32ui .10+| 0 |
| | code:Rg32ui |
| | code:R32ui |
| | code:Rgba16ui |
| | code:Rg16ui |
| | code:R16ui |
| | code:Rgb10a2ui |
| | code:Rgba8ui |
| | code:Rg8ui |
| | code:R8ui |
| | code:R64i .2+| code:OpTypeInt .2+| 64 | 1 |
| | code:R64ui | 0 |
| |=== |
| |
| [[spirvenv-image-formats]] |
| == Compatibility Between SPIR-V Image Formats And Vulkan Formats |
| |
| SPIR-V code:Image code:Format values are compatible with elink:VkFormat |
| values as defined below: |
| |
| .SPIR-V and Vulkan Image Format Compatibility |
| [cols="2*", options="header"] |
| |==== |
| |SPIR-V Image Format |Compatible Vulkan Format |
| |code:Unknown |Any |
| |code:Rgba32f |ename:VK_FORMAT_R32G32B32A32_SFLOAT |
| |code:Rgba16f |ename:VK_FORMAT_R16G16B16A16_SFLOAT |
| |code:R32f |ename:VK_FORMAT_R32_SFLOAT |
| |code:Rgba8 |ename:VK_FORMAT_R8G8B8A8_UNORM |
| |code:Rgba8Snorm |ename:VK_FORMAT_R8G8B8A8_SNORM |
| |code:Rg32f |ename:VK_FORMAT_R32G32_SFLOAT |
| |code:Rg16f |ename:VK_FORMAT_R16G16_SFLOAT |
| |code:R11fG11fB10f |ename:VK_FORMAT_B10G11R11_UFLOAT_PACK32 |
| |code:R16f |ename:VK_FORMAT_R16_SFLOAT |
| |code:Rgba16 |ename:VK_FORMAT_R16G16B16A16_UNORM |
| |code:Rgb10A2 |ename:VK_FORMAT_A2B10G10R10_UNORM_PACK32 |
| |code:Rg16 |ename:VK_FORMAT_R16G16_UNORM |
| |code:Rg8 |ename:VK_FORMAT_R8G8_UNORM |
| |code:R16 |ename:VK_FORMAT_R16_UNORM |
| |code:R8 |ename:VK_FORMAT_R8_UNORM |
| |code:Rgba16Snorm |ename:VK_FORMAT_R16G16B16A16_SNORM |
| |code:Rg16Snorm |ename:VK_FORMAT_R16G16_SNORM |
| |code:Rg8Snorm |ename:VK_FORMAT_R8G8_SNORM |
| |code:R16Snorm |ename:VK_FORMAT_R16_SNORM |
| |code:R8Snorm |ename:VK_FORMAT_R8_SNORM |
| |code:Rgba32i |ename:VK_FORMAT_R32G32B32A32_SINT |
| |code:Rgba16i |ename:VK_FORMAT_R16G16B16A16_SINT |
| |code:Rgba8i |ename:VK_FORMAT_R8G8B8A8_SINT |
| |code:R32i |ename:VK_FORMAT_R32_SINT |
| |code:Rg32i |ename:VK_FORMAT_R32G32_SINT |
| |code:Rg16i |ename:VK_FORMAT_R16G16_SINT |
| |code:Rg8i |ename:VK_FORMAT_R8G8_SINT |
| |code:R16i |ename:VK_FORMAT_R16_SINT |
| |code:R8i |ename:VK_FORMAT_R8_SINT |
| |code:Rgba32ui |ename:VK_FORMAT_R32G32B32A32_UINT |
| |code:Rgba16ui |ename:VK_FORMAT_R16G16B16A16_UINT |
| |code:Rgba8ui |ename:VK_FORMAT_R8G8B8A8_UINT |
| |code:R32ui |ename:VK_FORMAT_R32_UINT |
| |code:Rgb10a2ui |ename:VK_FORMAT_A2B10G10R10_UINT_PACK32 |
| |code:Rg32ui |ename:VK_FORMAT_R32G32_UINT |
| |code:Rg16ui |ename:VK_FORMAT_R16G16_UINT |
| |code:Rg8ui |ename:VK_FORMAT_R8G8_UINT |
| |code:R16ui |ename:VK_FORMAT_R16_UINT |
| |code:R8ui |ename:VK_FORMAT_R8_UINT |
| |code:R64i |ename:VK_FORMAT_R64_SINT |
| |code:R64ui |ename:VK_FORMAT_R64_UINT |
| |==== |