Updated spirv-tools.
This commit is contained in:
parent
2ca2bbc20e
commit
ba632e83b8
@ -1 +1 @@
|
||||
"v2024.2", "SPIRV-Tools v2024.2 v2024.2.rc1-12-g1e0a7201"
|
||||
"v2024.2", "SPIRV-Tools v2024.2 v2024.2.rc1-28-gf2bbb12a"
|
||||
|
@ -62,6 +62,7 @@ static const spv::Capability pygen_variable_caps_RayTracingMotionBlurNV[] = {spv
|
||||
static const spv::Capability pygen_variable_caps_RayTracingNV[] = {spv::Capability::RayTracingNV};
|
||||
static const spv::Capability pygen_variable_caps_RayTracingNVRayTracingKHR[] = {spv::Capability::RayTracingNV, spv::Capability::RayTracingKHR};
|
||||
static const spv::Capability pygen_variable_caps_RayTracingNVRayTracingKHRRayQueryKHR[] = {spv::Capability::RayTracingNV, spv::Capability::RayTracingKHR, spv::Capability::RayQueryKHR};
|
||||
static const spv::Capability pygen_variable_caps_ReplicatedCompositesEXT[] = {spv::Capability::ReplicatedCompositesEXT};
|
||||
static const spv::Capability pygen_variable_caps_Shader[] = {spv::Capability::Shader};
|
||||
static const spv::Capability pygen_variable_caps_ShaderBitInstructions[] = {spv::Capability::Shader, spv::Capability::BitInstructions};
|
||||
static const spv::Capability pygen_variable_caps_ShaderClockKHR[] = {spv::Capability::ShaderClockKHR};
|
||||
@ -109,6 +110,7 @@ static const spvtools::Extension pygen_variable_exts_SPV_KHR_integer_dot_product
|
||||
static const spvtools::Extension pygen_variable_exts_SPV_KHR_ray_query[] = {spvtools::Extension::kSPV_KHR_ray_query};
|
||||
static const spvtools::Extension pygen_variable_exts_SPV_KHR_ray_tracing[] = {spvtools::Extension::kSPV_KHR_ray_tracing};
|
||||
static const spvtools::Extension pygen_variable_exts_SPV_KHR_ray_tracingSPV_KHR_ray_query[] = {spvtools::Extension::kSPV_KHR_ray_tracing, spvtools::Extension::kSPV_KHR_ray_query};
|
||||
static const spvtools::Extension pygen_variable_exts_SPV_KHR_relaxed_extended_instruction[] = {spvtools::Extension::kSPV_KHR_relaxed_extended_instruction};
|
||||
static const spvtools::Extension pygen_variable_exts_SPV_KHR_shader_ballot[] = {spvtools::Extension::kSPV_KHR_shader_ballot};
|
||||
static const spvtools::Extension pygen_variable_exts_SPV_KHR_subgroup_vote[] = {spvtools::Extension::kSPV_KHR_subgroup_vote};
|
||||
static const spvtools::Extension pygen_variable_exts_SPV_KHR_terminate_invocation[] = {spvtools::Extension::kSPV_KHR_terminate_invocation};
|
||||
@ -477,6 +479,7 @@ static const spv_opcode_desc_t kOpcodeTableEntries[] = {
|
||||
{"SubgroupAllEqualKHR", spv::Op::OpSubgroupAllEqualKHR, 1, pygen_variable_caps_SubgroupVoteKHR, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_KHR_subgroup_vote, 0xffffffffu, 0xffffffffu},
|
||||
{"GroupNonUniformRotateKHR", spv::Op::OpGroupNonUniformRotateKHR, 1, pygen_variable_caps_GroupNonUniformRotateKHR, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
|
||||
{"SubgroupReadInvocationKHR", spv::Op::OpSubgroupReadInvocationKHR, 1, pygen_variable_caps_SubgroupBallotKHR, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_KHR_shader_ballot, 0xffffffffu, 0xffffffffu},
|
||||
{"ExtInstWithForwardRefsKHR", spv::Op::OpExtInstWithForwardRefsKHR, 0, nullptr, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER, SPV_OPERAND_TYPE_VARIABLE_ID}, 1, 1, 1, pygen_variable_exts_SPV_KHR_relaxed_extended_instruction, 0xffffffffu, 0xffffffffu},
|
||||
{"TraceRayKHR", spv::Op::OpTraceRayKHR, 1, pygen_variable_caps_RayTracingKHR, 11, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 1, pygen_variable_exts_SPV_KHR_ray_tracing, 0xffffffffu, 0xffffffffu},
|
||||
{"ExecuteCallableKHR", spv::Op::OpExecuteCallableKHR, 1, pygen_variable_caps_RayTracingKHR, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 1, pygen_variable_exts_SPV_KHR_ray_tracing, 0xffffffffu, 0xffffffffu},
|
||||
{"ConvertUToAccelerationStructureKHR", spv::Op::OpConvertUToAccelerationStructureKHR, 2, pygen_variable_caps_RayTracingKHRRayQueryKHR, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_KHR_ray_query, 0xffffffffu, 0xffffffffu},
|
||||
@ -499,6 +502,9 @@ static const spv_opcode_desc_t kOpcodeTableEntries[] = {
|
||||
{"CooperativeMatrixStoreKHR", spv::Op::OpCooperativeMatrixStoreKHR, 1, pygen_variable_caps_CooperativeMatrixKHR, 5, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu},
|
||||
{"CooperativeMatrixMulAddKHR", spv::Op::OpCooperativeMatrixMulAddKHR, 1, pygen_variable_caps_CooperativeMatrixKHR, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_COOPERATIVE_MATRIX_OPERANDS}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
|
||||
{"CooperativeMatrixLengthKHR", spv::Op::OpCooperativeMatrixLengthKHR, 1, pygen_variable_caps_CooperativeMatrixKHR, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
|
||||
{"ConstantCompositeReplicateEXT", spv::Op::OpConstantCompositeReplicateEXT, 1, pygen_variable_caps_ReplicatedCompositesEXT, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
|
||||
{"SpecConstantCompositeReplicateEXT", spv::Op::OpSpecConstantCompositeReplicateEXT, 1, pygen_variable_caps_ReplicatedCompositesEXT, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
|
||||
{"CompositeConstructReplicateEXT", spv::Op::OpCompositeConstructReplicateEXT, 1, pygen_variable_caps_ReplicatedCompositesEXT, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
|
||||
{"TypeRayQueryKHR", spv::Op::OpTypeRayQueryKHR, 1, pygen_variable_caps_RayQueryKHR, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 1, pygen_variable_exts_SPV_KHR_ray_query, 0xffffffffu, 0xffffffffu},
|
||||
{"RayQueryInitializeKHR", spv::Op::OpRayQueryInitializeKHR, 1, pygen_variable_caps_RayQueryKHR, 8, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 1, pygen_variable_exts_SPV_KHR_ray_query, 0xffffffffu, 0xffffffffu},
|
||||
{"RayQueryTerminateKHR", spv::Op::OpRayQueryTerminateKHR, 1, pygen_variable_caps_RayQueryKHR, 1, {SPV_OPERAND_TYPE_ID}, 0, 0, 1, pygen_variable_exts_SPV_KHR_ray_query, 0xffffffffu, 0xffffffffu},
|
||||
|
File diff suppressed because one or more lines are too long
@ -10,6 +10,7 @@ kSPV_AMD_shader_fragment_mask,
|
||||
kSPV_AMD_shader_image_load_store_lod,
|
||||
kSPV_AMD_shader_trinary_minmax,
|
||||
kSPV_AMD_texture_gather_bias_lod,
|
||||
kSPV_ARM_cooperative_matrix_layouts,
|
||||
kSPV_ARM_core_builtins,
|
||||
kSPV_EXT_demote_to_helper_invocation,
|
||||
kSPV_EXT_descriptor_indexing,
|
||||
@ -19,6 +20,7 @@ kSPV_EXT_fragment_shader_interlock,
|
||||
kSPV_EXT_mesh_shader,
|
||||
kSPV_EXT_opacity_micromap,
|
||||
kSPV_EXT_physical_storage_buffer,
|
||||
kSPV_EXT_replicated_composites,
|
||||
kSPV_EXT_shader_atomic_float16_add,
|
||||
kSPV_EXT_shader_atomic_float_add,
|
||||
kSPV_EXT_shader_atomic_float_min_max,
|
||||
@ -94,6 +96,7 @@ kSPV_KHR_ray_cull_mask,
|
||||
kSPV_KHR_ray_query,
|
||||
kSPV_KHR_ray_tracing,
|
||||
kSPV_KHR_ray_tracing_position_fetch,
|
||||
kSPV_KHR_relaxed_extended_instruction,
|
||||
kSPV_KHR_shader_atomic_counter_ops,
|
||||
kSPV_KHR_shader_ballot,
|
||||
kSPV_KHR_shader_clock,
|
||||
|
@ -152,6 +152,7 @@ static const spvtools::Extension pygen_variable_exts_SPV_AMD_shader_explicit_ver
|
||||
static const spvtools::Extension pygen_variable_exts_SPV_AMD_shader_fragment_mask[] = {spvtools::Extension::kSPV_AMD_shader_fragment_mask};
|
||||
static const spvtools::Extension pygen_variable_exts_SPV_AMD_shader_image_load_store_lod[] = {spvtools::Extension::kSPV_AMD_shader_image_load_store_lod};
|
||||
static const spvtools::Extension pygen_variable_exts_SPV_AMD_texture_gather_bias_lod[] = {spvtools::Extension::kSPV_AMD_texture_gather_bias_lod};
|
||||
static const spvtools::Extension pygen_variable_exts_SPV_ARM_cooperative_matrix_layouts[] = {spvtools::Extension::kSPV_ARM_cooperative_matrix_layouts};
|
||||
static const spvtools::Extension pygen_variable_exts_SPV_ARM_core_builtins[] = {spvtools::Extension::kSPV_ARM_core_builtins};
|
||||
static const spvtools::Extension pygen_variable_exts_SPV_EXT_demote_to_helper_invocation[] = {spvtools::Extension::kSPV_EXT_demote_to_helper_invocation};
|
||||
static const spvtools::Extension pygen_variable_exts_SPV_EXT_descriptor_indexing[] = {spvtools::Extension::kSPV_EXT_descriptor_indexing};
|
||||
@ -163,6 +164,7 @@ static const spvtools::Extension pygen_variable_exts_SPV_EXT_mesh_shaderSPV_KHR_
|
||||
static const spvtools::Extension pygen_variable_exts_SPV_EXT_mesh_shaderSPV_NV_mesh_shader[] = {spvtools::Extension::kSPV_EXT_mesh_shader, spvtools::Extension::kSPV_NV_mesh_shader};
|
||||
static const spvtools::Extension pygen_variable_exts_SPV_EXT_opacity_micromap[] = {spvtools::Extension::kSPV_EXT_opacity_micromap};
|
||||
static const spvtools::Extension pygen_variable_exts_SPV_EXT_physical_storage_bufferSPV_KHR_physical_storage_buffer[] = {spvtools::Extension::kSPV_EXT_physical_storage_buffer, spvtools::Extension::kSPV_KHR_physical_storage_buffer};
|
||||
static const spvtools::Extension pygen_variable_exts_SPV_EXT_replicated_composites[] = {spvtools::Extension::kSPV_EXT_replicated_composites};
|
||||
static const spvtools::Extension pygen_variable_exts_SPV_EXT_shader_atomic_float16_add[] = {spvtools::Extension::kSPV_EXT_shader_atomic_float16_add};
|
||||
static const spvtools::Extension pygen_variable_exts_SPV_EXT_shader_atomic_float_add[] = {spvtools::Extension::kSPV_EXT_shader_atomic_float_add};
|
||||
static const spvtools::Extension pygen_variable_exts_SPV_EXT_shader_atomic_float_min_max[] = {spvtools::Extension::kSPV_EXT_shader_atomic_float_min_max};
|
||||
@ -444,18 +446,18 @@ static const spv_operand_desc_t pygen_variable_ExecutionModelEntries[] = {
|
||||
{"Kernel", 6, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu},
|
||||
{"TaskNV", 5267, 1, pygen_variable_caps_MeshShadingNV, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"MeshNV", 5268, 1, pygen_variable_caps_MeshShadingNV, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"RayGenerationNV", 5313, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"RayGenerationKHR", 5313, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"IntersectionNV", 5314, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"RayGenerationNV", 5313, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"IntersectionKHR", 5314, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"AnyHitNV", 5315, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"IntersectionNV", 5314, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"AnyHitKHR", 5315, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"ClosestHitNV", 5316, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"AnyHitNV", 5315, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"ClosestHitKHR", 5316, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"MissNV", 5317, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"ClosestHitNV", 5316, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"MissKHR", 5317, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"CallableNV", 5318, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"MissNV", 5317, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"CallableKHR", 5318, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"CallableNV", 5318, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"TaskEXT", 5364, 1, pygen_variable_caps_MeshShadingEXT, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"MeshEXT", 5365, 1, pygen_variable_caps_MeshShadingEXT, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}
|
||||
};
|
||||
@ -540,14 +542,14 @@ static const spv_operand_desc_t pygen_variable_ExecutionModeEntries[] = {
|
||||
{"StencilRefLessBackAMD", 5084, 1, pygen_variable_caps_StencilExportEXT, 2, pygen_variable_exts_SPV_AMD_shader_early_and_late_fragment_testsSPV_EXT_shader_stencil_export, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"QuadDerivativesKHR", 5088, 1, pygen_variable_caps_QuadControlKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"RequireFullQuadsKHR", 5089, 1, pygen_variable_caps_QuadControlKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"OutputLinesNV", 5269, 2, pygen_variable_caps_MeshShadingNVMeshShadingEXT, 2, pygen_variable_exts_SPV_EXT_mesh_shaderSPV_NV_mesh_shader, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"OutputLinesEXT", 5269, 2, pygen_variable_caps_MeshShadingNVMeshShadingEXT, 2, pygen_variable_exts_SPV_EXT_mesh_shaderSPV_NV_mesh_shader, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"OutputPrimitivesNV", 5270, 2, pygen_variable_caps_MeshShadingNVMeshShadingEXT, 2, pygen_variable_exts_SPV_EXT_mesh_shaderSPV_NV_mesh_shader, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu},
|
||||
{"OutputLinesNV", 5269, 2, pygen_variable_caps_MeshShadingNVMeshShadingEXT, 2, pygen_variable_exts_SPV_EXT_mesh_shaderSPV_NV_mesh_shader, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"OutputPrimitivesEXT", 5270, 2, pygen_variable_caps_MeshShadingNVMeshShadingEXT, 2, pygen_variable_exts_SPV_EXT_mesh_shaderSPV_NV_mesh_shader, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu},
|
||||
{"OutputPrimitivesNV", 5270, 2, pygen_variable_caps_MeshShadingNVMeshShadingEXT, 2, pygen_variable_exts_SPV_EXT_mesh_shaderSPV_NV_mesh_shader, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu},
|
||||
{"DerivativeGroupQuadsNV", 5289, 1, pygen_variable_caps_ComputeDerivativeGroupQuadsNV, 1, pygen_variable_exts_SPV_NV_compute_shader_derivatives, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"DerivativeGroupLinearNV", 5290, 1, pygen_variable_caps_ComputeDerivativeGroupLinearNV, 1, pygen_variable_exts_SPV_NV_compute_shader_derivatives, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"OutputTrianglesNV", 5298, 2, pygen_variable_caps_MeshShadingNVMeshShadingEXT, 2, pygen_variable_exts_SPV_EXT_mesh_shaderSPV_NV_mesh_shader, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"OutputTrianglesEXT", 5298, 2, pygen_variable_caps_MeshShadingNVMeshShadingEXT, 2, pygen_variable_exts_SPV_EXT_mesh_shaderSPV_NV_mesh_shader, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"OutputTrianglesNV", 5298, 2, pygen_variable_caps_MeshShadingNVMeshShadingEXT, 2, pygen_variable_exts_SPV_EXT_mesh_shaderSPV_NV_mesh_shader, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"PixelInterlockOrderedEXT", 5366, 1, pygen_variable_caps_FragmentShaderPixelInterlockEXT, 1, pygen_variable_exts_SPV_EXT_fragment_shader_interlock, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"PixelInterlockUnorderedEXT", 5367, 1, pygen_variable_caps_FragmentShaderPixelInterlockEXT, 1, pygen_variable_exts_SPV_EXT_fragment_shader_interlock, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"SampleInterlockOrderedEXT", 5368, 1, pygen_variable_caps_FragmentShaderSampleInterlockEXT, 1, pygen_variable_exts_SPV_EXT_fragment_shader_interlock, {}, 0xffffffffu, 0xffffffffu},
|
||||
@ -591,18 +593,18 @@ static const spv_operand_desc_t pygen_variable_StorageClassEntries[] = {
|
||||
{"TileImageEXT", 4172, 1, pygen_variable_caps_TileImageColorReadAccessEXT, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"NodePayloadAMDX", 5068, 1, pygen_variable_caps_ShaderEnqueueAMDX, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"NodeOutputPayloadAMDX", 5076, 1, pygen_variable_caps_ShaderEnqueueAMDX, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"CallableDataNV", 5328, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"CallableDataKHR", 5328, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"IncomingCallableDataNV", 5329, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"CallableDataNV", 5328, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"IncomingCallableDataKHR", 5329, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"RayPayloadNV", 5338, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"IncomingCallableDataNV", 5329, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"RayPayloadKHR", 5338, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"HitAttributeNV", 5339, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"RayPayloadNV", 5338, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"HitAttributeKHR", 5339, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"IncomingRayPayloadNV", 5342, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"HitAttributeNV", 5339, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"IncomingRayPayloadKHR", 5342, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"ShaderRecordBufferNV", 5343, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"IncomingRayPayloadNV", 5342, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"ShaderRecordBufferKHR", 5343, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"ShaderRecordBufferNV", 5343, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"PhysicalStorageBuffer", 5349, 1, pygen_variable_caps_PhysicalStorageBufferAddresses, 2, pygen_variable_exts_SPV_EXT_physical_storage_bufferSPV_KHR_physical_storage_buffer, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu},
|
||||
{"PhysicalStorageBufferEXT", 5349, 1, pygen_variable_caps_PhysicalStorageBufferAddresses, 2, pygen_variable_exts_SPV_EXT_physical_storage_bufferSPV_KHR_physical_storage_buffer, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu},
|
||||
{"HitObjectAttributeNV", 5385, 1, pygen_variable_caps_ShaderInvocationReorderNV, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
|
||||
@ -854,8 +856,8 @@ static const spv_operand_desc_t pygen_variable_DecorationEntries[] = {
|
||||
{"PassthroughNV", 5250, 1, pygen_variable_caps_GeometryShaderPassthroughNV, 1, pygen_variable_exts_SPV_NV_geometry_shader_passthrough, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"ViewportRelativeNV", 5252, 1, pygen_variable_caps_ShaderViewportMaskNV, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"SecondaryViewportRelativeNV", 5256, 1, pygen_variable_caps_ShaderStereoViewNV, 1, pygen_variable_exts_SPV_NV_stereo_view_rendering, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu},
|
||||
{"PerPrimitiveNV", 5271, 2, pygen_variable_caps_MeshShadingNVMeshShadingEXT, 2, pygen_variable_exts_SPV_EXT_mesh_shaderSPV_NV_mesh_shader, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"PerPrimitiveEXT", 5271, 2, pygen_variable_caps_MeshShadingNVMeshShadingEXT, 2, pygen_variable_exts_SPV_EXT_mesh_shaderSPV_NV_mesh_shader, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"PerPrimitiveNV", 5271, 2, pygen_variable_caps_MeshShadingNVMeshShadingEXT, 2, pygen_variable_exts_SPV_EXT_mesh_shaderSPV_NV_mesh_shader, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"PerViewNV", 5272, 1, pygen_variable_caps_MeshShadingNV, 1, pygen_variable_exts_SPV_NV_mesh_shader, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"PerTaskNV", 5273, 2, pygen_variable_caps_MeshShadingNVMeshShadingEXT, 2, pygen_variable_exts_SPV_EXT_mesh_shaderSPV_NV_mesh_shader, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"PerVertexKHR", 5285, 2, pygen_variable_caps_FragmentBarycentricNVFragmentBarycentricKHR, 2, pygen_variable_exts_SPV_KHR_fragment_shader_barycentricSPV_NV_fragment_shader_barycentric, {}, 0xffffffffu, 0xffffffffu},
|
||||
@ -1040,37 +1042,37 @@ static const spv_operand_desc_t pygen_variable_BuiltInEntries[] = {
|
||||
{"PrimitiveLineIndicesEXT", 5295, 1, pygen_variable_caps_MeshShadingEXT, 1, pygen_variable_exts_SPV_EXT_mesh_shader, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"PrimitiveTriangleIndicesEXT", 5296, 1, pygen_variable_caps_MeshShadingEXT, 1, pygen_variable_exts_SPV_EXT_mesh_shader, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"CullPrimitiveEXT", 5299, 1, pygen_variable_caps_MeshShadingEXT, 1, pygen_variable_exts_SPV_EXT_mesh_shader, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"LaunchIdNV", 5319, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"LaunchIdKHR", 5319, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"LaunchSizeNV", 5320, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"LaunchIdNV", 5319, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"LaunchSizeKHR", 5320, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"WorldRayOriginNV", 5321, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"LaunchSizeNV", 5320, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"WorldRayOriginKHR", 5321, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"WorldRayDirectionNV", 5322, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"WorldRayOriginNV", 5321, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"WorldRayDirectionKHR", 5322, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"ObjectRayOriginNV", 5323, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"WorldRayDirectionNV", 5322, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"ObjectRayOriginKHR", 5323, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"ObjectRayDirectionNV", 5324, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"ObjectRayOriginNV", 5323, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"ObjectRayDirectionKHR", 5324, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"RayTminNV", 5325, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"ObjectRayDirectionNV", 5324, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"RayTminKHR", 5325, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"RayTmaxNV", 5326, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"RayTminNV", 5325, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"RayTmaxKHR", 5326, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"InstanceCustomIndexNV", 5327, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"RayTmaxNV", 5326, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"InstanceCustomIndexKHR", 5327, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"ObjectToWorldNV", 5330, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"InstanceCustomIndexNV", 5327, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"ObjectToWorldKHR", 5330, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"WorldToObjectNV", 5331, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"ObjectToWorldNV", 5330, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"WorldToObjectKHR", 5331, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"WorldToObjectNV", 5331, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"HitTNV", 5332, 1, pygen_variable_caps_RayTracingNV, 1, pygen_variable_exts_SPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"HitKindNV", 5333, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"HitKindKHR", 5333, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"HitKindNV", 5333, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"CurrentRayTimeNV", 5334, 1, pygen_variable_caps_RayTracingMotionBlurNV, 1, pygen_variable_exts_SPV_NV_ray_tracing_motion_blur, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"HitTriangleVertexPositionsKHR", 5335, 1, pygen_variable_caps_RayTracingPositionFetchKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"HitMicroTriangleVertexPositionsNV", 5337, 1, pygen_variable_caps_RayTracingDisplacementMicromapNV, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"HitMicroTriangleVertexBarycentricsNV", 5344, 1, pygen_variable_caps_RayTracingDisplacementMicromapNV, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"IncomingRayFlagsNV", 5351, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"IncomingRayFlagsKHR", 5351, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"IncomingRayFlagsNV", 5351, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"RayGeometryIndexKHR", 5352, 1, pygen_variable_caps_RayTracingKHR, 1, pygen_variable_exts_SPV_KHR_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"WarpsPerSMNV", 5374, 1, pygen_variable_caps_ShaderSMBuiltinsNV, 1, pygen_variable_exts_SPV_NV_shader_sm_builtins, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"SMCountNV", 5375, 1, pygen_variable_caps_ShaderSMBuiltinsNV, 1, pygen_variable_exts_SPV_NV_shader_sm_builtins, {}, 0xffffffffu, 0xffffffffu},
|
||||
@ -1183,6 +1185,7 @@ static const spv_operand_desc_t pygen_variable_CapabilityEntries[] = {
|
||||
{"TileImageColorReadAccessEXT", 4166, 0, nullptr, 1, pygen_variable_exts_SPV_EXT_shader_tile_image, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"TileImageDepthReadAccessEXT", 4167, 0, nullptr, 1, pygen_variable_exts_SPV_EXT_shader_tile_image, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"TileImageStencilReadAccessEXT", 4168, 0, nullptr, 1, pygen_variable_exts_SPV_EXT_shader_tile_image, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"CooperativeMatrixLayoutsARM", 4201, 0, nullptr, 1, pygen_variable_exts_SPV_ARM_cooperative_matrix_layouts, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"FragmentShadingRateKHR", 4422, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_KHR_fragment_shading_rate, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"SubgroupBallotKHR", 4423, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_shader_ballot, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"DrawParameters", 4427, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_KHR_shader_draw_parameters, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu},
|
||||
@ -1346,6 +1349,7 @@ static const spv_operand_desc_t pygen_variable_CapabilityEntries[] = {
|
||||
{"DotProductKHR", 6019, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_integer_dot_product, {}, SPV_SPIRV_VERSION_WORD(1,6), 0xffffffffu},
|
||||
{"RayCullMaskKHR", 6020, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_ray_cull_mask, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"CooperativeMatrixKHR", 6022, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_cooperative_matrix, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"ReplicatedCompositesEXT", 6024, 0, nullptr, 1, pygen_variable_exts_SPV_EXT_replicated_composites, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"BitInstructions", 6025, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_bit_instructions, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"GroupNonUniformRotateKHR", 6026, 1, pygen_variable_caps_GroupNonUniform, 1, pygen_variable_exts_SPV_KHR_subgroup_rotate, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"FloatControls2", 6029, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_float_controls2, {}, 0xffffffffu, 0xffffffffu},
|
||||
@ -1402,7 +1406,9 @@ static const spv_operand_desc_t pygen_variable_CooperativeMatrixOperandsEntries[
|
||||
|
||||
static const spv_operand_desc_t pygen_variable_CooperativeMatrixLayoutEntries[] = {
|
||||
{"RowMajorKHR", 0, 0, nullptr, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"ColumnMajorKHR", 1, 0, nullptr, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}
|
||||
{"ColumnMajorKHR", 1, 0, nullptr, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"RowBlockedInterleavedARM", 4202, 0, nullptr, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
|
||||
{"ColumnBlockedInterleavedARM", 4203, 0, nullptr, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}
|
||||
};
|
||||
|
||||
static const spv_operand_desc_t pygen_variable_CooperativeMatrixUseEntries[] = {
|
||||
|
@ -856,6 +856,12 @@ Optimizer::PassToken CreateAmdExtToKhrPass();
|
||||
// propagated into their final positions.
|
||||
Optimizer::PassToken CreateInterpolateFixupPass();
|
||||
|
||||
// Replace OpExtInst instructions with OpExtInstWithForwardRefsKHR when
|
||||
// the instruction contains a forward reference to another debug instuction.
|
||||
// Replace OpExtInstWithForwardRefsKHR with OpExtInst when there are no forward
|
||||
// reference to another debug instruction.
|
||||
Optimizer::PassToken CreateOpExtInstWithForwardReferenceFixupPass();
|
||||
|
||||
// Removes unused components from composite input variables. Current
|
||||
// implementation just removes trailing unused components from input arrays
|
||||
// and structs. The pass performs best after maximizing dead code removal.
|
||||
|
4
3rdparty/spirv-tools/source/binary.cpp
vendored
4
3rdparty/spirv-tools/source/binary.cpp
vendored
@ -473,7 +473,7 @@ spv_result_t Parser::parseOperand(size_t inst_offset,
|
||||
if (!word) return diagnostic(SPV_ERROR_INVALID_ID) << "Id is 0";
|
||||
parsed_operand.type = SPV_OPERAND_TYPE_ID;
|
||||
|
||||
if (opcode == spv::Op::OpExtInst && parsed_operand.offset == 3) {
|
||||
if (spvIsExtendedInstruction(opcode) && parsed_operand.offset == 3) {
|
||||
// The current word is the extended instruction set Id.
|
||||
// Set the extended instruction set type for the current instruction.
|
||||
auto ext_inst_type_iter = _.import_id_to_ext_inst_type.find(word);
|
||||
@ -494,7 +494,7 @@ spv_result_t Parser::parseOperand(size_t inst_offset,
|
||||
break;
|
||||
|
||||
case SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER: {
|
||||
assert(spv::Op::OpExtInst == opcode);
|
||||
assert(spvIsExtendedInstruction(opcode));
|
||||
assert(inst->ext_inst_type != SPV_EXT_INST_TYPE_NONE);
|
||||
spv_ext_inst_desc ext_inst;
|
||||
if (grammar_.lookupExtInst(inst->ext_inst_type, word, &ext_inst) ==
|
||||
|
222
3rdparty/spirv-tools/source/disassemble.cpp
vendored
222
3rdparty/spirv-tools/source/disassemble.cpp
vendored
@ -194,7 +194,27 @@ spv_result_t DisassembleTargetInstruction(
|
||||
return SPV_SUCCESS;
|
||||
}
|
||||
|
||||
uint32_t GetLineLengthWithoutColor(const std::string line) {
|
||||
// Currently, every added color is in the form \x1b...m, so instead of doing a
|
||||
// lot of string comparisons with spvtools::clr::* strings, we just ignore
|
||||
// those ranges.
|
||||
uint32_t length = 0;
|
||||
for (size_t i = 0; i < line.size(); ++i) {
|
||||
if (line[i] == '\x1b') {
|
||||
do {
|
||||
++i;
|
||||
} while (line[i] != 'm');
|
||||
continue;
|
||||
}
|
||||
|
||||
++length;
|
||||
}
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
constexpr int kStandardIndent = 15;
|
||||
constexpr uint32_t kCommentColumn = 50;
|
||||
} // namespace
|
||||
|
||||
namespace disassemble {
|
||||
@ -212,7 +232,8 @@ InstructionDisassembler::InstructionDisassembler(const AssemblyGrammar& grammar,
|
||||
comment_(spvIsInBitfield(SPV_BINARY_TO_TEXT_OPTION_COMMENT, options)),
|
||||
show_byte_offset_(
|
||||
spvIsInBitfield(SPV_BINARY_TO_TEXT_OPTION_SHOW_BYTE_OFFSET, options)),
|
||||
name_mapper_(std::move(name_mapper)) {}
|
||||
name_mapper_(std::move(name_mapper)),
|
||||
last_instruction_comment_alignment_(0) {}
|
||||
|
||||
void InstructionDisassembler::EmitHeaderSpirv() { stream_ << "; SPIR-V\n"; }
|
||||
|
||||
@ -246,47 +267,119 @@ void InstructionDisassembler::EmitInstruction(
|
||||
const spv_parsed_instruction_t& inst, size_t inst_byte_offset) {
|
||||
auto opcode = static_cast<spv::Op>(inst.opcode);
|
||||
|
||||
// To better align the comments (if any), write the instruction to a line
|
||||
// first so its length can be readily available.
|
||||
std::ostringstream line;
|
||||
|
||||
if (inst.result_id) {
|
||||
SetBlue();
|
||||
const std::string id_name = name_mapper_(inst.result_id);
|
||||
if (indent_)
|
||||
stream_ << std::setw(std::max(0, indent_ - 3 - int(id_name.size())));
|
||||
stream_ << "%" << id_name;
|
||||
line << std::setw(std::max(0, indent_ - 3 - int(id_name.size())));
|
||||
line << "%" << id_name;
|
||||
ResetColor();
|
||||
stream_ << " = ";
|
||||
line << " = ";
|
||||
} else {
|
||||
stream_ << std::string(indent_, ' ');
|
||||
line << std::string(indent_, ' ');
|
||||
}
|
||||
|
||||
stream_ << "Op" << spvOpcodeString(opcode);
|
||||
line << "Op" << spvOpcodeString(opcode);
|
||||
|
||||
for (uint16_t i = 0; i < inst.num_operands; i++) {
|
||||
const spv_operand_type_t type = inst.operands[i].type;
|
||||
assert(type != SPV_OPERAND_TYPE_NONE);
|
||||
if (type == SPV_OPERAND_TYPE_RESULT_ID) continue;
|
||||
stream_ << " ";
|
||||
EmitOperand(inst, i);
|
||||
line << " ";
|
||||
EmitOperand(line, inst, i);
|
||||
}
|
||||
|
||||
// For the sake of comment generation, store information from some
|
||||
// instructions for the future.
|
||||
if (comment_) {
|
||||
GenerateCommentForDecoratedId(inst);
|
||||
}
|
||||
|
||||
std::ostringstream comments;
|
||||
const char* comment_separator = "";
|
||||
|
||||
if (show_byte_offset_) {
|
||||
SetGrey(comments);
|
||||
auto saved_flags = comments.flags();
|
||||
auto saved_fill = comments.fill();
|
||||
comments << comment_separator << "0x" << std::setw(8) << std::hex
|
||||
<< std::setfill('0') << inst_byte_offset;
|
||||
comments.flags(saved_flags);
|
||||
comments.fill(saved_fill);
|
||||
ResetColor(comments);
|
||||
comment_separator = ", ";
|
||||
}
|
||||
|
||||
if (comment_ && opcode == spv::Op::OpName) {
|
||||
const spv_parsed_operand_t& operand = inst.operands[0];
|
||||
const uint32_t word = inst.words[operand.offset];
|
||||
stream_ << " ; id %" << word;
|
||||
comments << comment_separator << "id %" << word;
|
||||
comment_separator = ", ";
|
||||
}
|
||||
|
||||
if (show_byte_offset_) {
|
||||
SetGrey();
|
||||
auto saved_flags = stream_.flags();
|
||||
auto saved_fill = stream_.fill();
|
||||
stream_ << " ; 0x" << std::setw(8) << std::hex << std::setfill('0')
|
||||
<< inst_byte_offset;
|
||||
stream_.flags(saved_flags);
|
||||
stream_.fill(saved_fill);
|
||||
ResetColor();
|
||||
if (comment_ && inst.result_id && id_comments_.count(inst.result_id) > 0) {
|
||||
comments << comment_separator << id_comments_[inst.result_id].str();
|
||||
comment_separator = ", ";
|
||||
}
|
||||
|
||||
stream_ << line.str();
|
||||
|
||||
if (!comments.str().empty()) {
|
||||
// Align the comments
|
||||
const uint32_t line_length = GetLineLengthWithoutColor(line.str());
|
||||
uint32_t align = std::max(
|
||||
{line_length + 2, last_instruction_comment_alignment_, kCommentColumn});
|
||||
// Round up the alignment to a multiple of 4 for more niceness.
|
||||
align = (align + 3) & ~0x3u;
|
||||
last_instruction_comment_alignment_ = align;
|
||||
|
||||
stream_ << std::string(align - line_length, ' ') << "; " << comments.str();
|
||||
} else {
|
||||
last_instruction_comment_alignment_ = 0;
|
||||
}
|
||||
|
||||
stream_ << "\n";
|
||||
}
|
||||
|
||||
void InstructionDisassembler::GenerateCommentForDecoratedId(
|
||||
const spv_parsed_instruction_t& inst) {
|
||||
assert(comment_);
|
||||
auto opcode = static_cast<spv::Op>(inst.opcode);
|
||||
|
||||
std::ostringstream partial;
|
||||
uint32_t id = 0;
|
||||
const char* separator = "";
|
||||
|
||||
switch (opcode) {
|
||||
case spv::Op::OpDecorate:
|
||||
// Take everything after `OpDecorate %id` and associate it with id.
|
||||
id = inst.words[inst.operands[0].offset];
|
||||
for (uint16_t i = 1; i < inst.num_operands; i++) {
|
||||
partial << separator;
|
||||
separator = " ";
|
||||
EmitOperand(partial, inst, i);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (id == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Add the new comment to the comments of this id
|
||||
std::ostringstream& id_comment = id_comments_[id];
|
||||
if (!id_comment.str().empty()) {
|
||||
id_comment << ", ";
|
||||
}
|
||||
id_comment << partial.str();
|
||||
}
|
||||
|
||||
void InstructionDisassembler::EmitSectionComment(
|
||||
const spv_parsed_instruction_t& inst, bool& inserted_decoration_space,
|
||||
bool& inserted_debug_space, bool& inserted_type_space) {
|
||||
@ -316,36 +409,37 @@ void InstructionDisassembler::EmitSectionComment(
|
||||
}
|
||||
}
|
||||
|
||||
void InstructionDisassembler::EmitOperand(const spv_parsed_instruction_t& inst,
|
||||
const uint16_t operand_index) {
|
||||
void InstructionDisassembler::EmitOperand(std::ostream& stream,
|
||||
const spv_parsed_instruction_t& inst,
|
||||
const uint16_t operand_index) const {
|
||||
assert(operand_index < inst.num_operands);
|
||||
const spv_parsed_operand_t& operand = inst.operands[operand_index];
|
||||
const uint32_t word = inst.words[operand.offset];
|
||||
switch (operand.type) {
|
||||
case SPV_OPERAND_TYPE_RESULT_ID:
|
||||
assert(false && "<result-id> is not supposed to be handled here");
|
||||
SetBlue();
|
||||
stream_ << "%" << name_mapper_(word);
|
||||
SetBlue(stream);
|
||||
stream << "%" << name_mapper_(word);
|
||||
break;
|
||||
case SPV_OPERAND_TYPE_ID:
|
||||
case SPV_OPERAND_TYPE_TYPE_ID:
|
||||
case SPV_OPERAND_TYPE_SCOPE_ID:
|
||||
case SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID:
|
||||
SetYellow();
|
||||
stream_ << "%" << name_mapper_(word);
|
||||
SetYellow(stream);
|
||||
stream << "%" << name_mapper_(word);
|
||||
break;
|
||||
case SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER: {
|
||||
spv_ext_inst_desc ext_inst;
|
||||
SetRed();
|
||||
SetRed(stream);
|
||||
if (grammar_.lookupExtInst(inst.ext_inst_type, word, &ext_inst) ==
|
||||
SPV_SUCCESS) {
|
||||
stream_ << ext_inst->name;
|
||||
stream << ext_inst->name;
|
||||
} else {
|
||||
if (!spvExtInstIsNonSemantic(inst.ext_inst_type)) {
|
||||
assert(false && "should have caught this earlier");
|
||||
} else {
|
||||
// for non-semantic instruction sets we can just print the number
|
||||
stream_ << word;
|
||||
stream << word;
|
||||
}
|
||||
}
|
||||
} break;
|
||||
@ -353,27 +447,27 @@ void InstructionDisassembler::EmitOperand(const spv_parsed_instruction_t& inst,
|
||||
spv_opcode_desc opcode_desc;
|
||||
if (grammar_.lookupOpcode(spv::Op(word), &opcode_desc))
|
||||
assert(false && "should have caught this earlier");
|
||||
SetRed();
|
||||
stream_ << opcode_desc->name;
|
||||
SetRed(stream);
|
||||
stream << opcode_desc->name;
|
||||
} break;
|
||||
case SPV_OPERAND_TYPE_LITERAL_INTEGER:
|
||||
case SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER:
|
||||
case SPV_OPERAND_TYPE_LITERAL_FLOAT: {
|
||||
SetRed();
|
||||
EmitNumericLiteral(&stream_, inst, operand);
|
||||
ResetColor();
|
||||
SetRed(stream);
|
||||
EmitNumericLiteral(&stream, inst, operand);
|
||||
ResetColor(stream);
|
||||
} break;
|
||||
case SPV_OPERAND_TYPE_LITERAL_STRING: {
|
||||
stream_ << "\"";
|
||||
SetGreen();
|
||||
stream << "\"";
|
||||
SetGreen(stream);
|
||||
|
||||
std::string str = spvDecodeLiteralStringOperand(inst, operand_index);
|
||||
for (char const& c : str) {
|
||||
if (c == '"' || c == '\\') stream_ << '\\';
|
||||
stream_ << c;
|
||||
if (c == '"' || c == '\\') stream << '\\';
|
||||
stream << c;
|
||||
}
|
||||
ResetColor();
|
||||
stream_ << '"';
|
||||
ResetColor(stream);
|
||||
stream << '"';
|
||||
} break;
|
||||
case SPV_OPERAND_TYPE_CAPABILITY:
|
||||
case SPV_OPERAND_TYPE_SOURCE_LANGUAGE:
|
||||
@ -415,7 +509,7 @@ void InstructionDisassembler::EmitOperand(const spv_parsed_instruction_t& inst,
|
||||
spv_operand_desc entry;
|
||||
if (grammar_.lookupOperand(operand.type, word, &entry))
|
||||
assert(false && "should have caught this earlier");
|
||||
stream_ << entry->name;
|
||||
stream << entry->name;
|
||||
} break;
|
||||
case SPV_OPERAND_TYPE_FP_FAST_MATH_MODE:
|
||||
case SPV_OPERAND_TYPE_FUNCTION_CONTROL:
|
||||
@ -426,26 +520,27 @@ void InstructionDisassembler::EmitOperand(const spv_parsed_instruction_t& inst,
|
||||
case SPV_OPERAND_TYPE_DEBUG_INFO_FLAGS:
|
||||
case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_INFO_FLAGS:
|
||||
case SPV_OPERAND_TYPE_RAW_ACCESS_CHAIN_OPERANDS:
|
||||
EmitMaskOperand(operand.type, word);
|
||||
EmitMaskOperand(stream, operand.type, word);
|
||||
break;
|
||||
default:
|
||||
if (spvOperandIsConcreteMask(operand.type)) {
|
||||
EmitMaskOperand(operand.type, word);
|
||||
EmitMaskOperand(stream, operand.type, word);
|
||||
} else if (spvOperandIsConcrete(operand.type)) {
|
||||
spv_operand_desc entry;
|
||||
if (grammar_.lookupOperand(operand.type, word, &entry))
|
||||
assert(false && "should have caught this earlier");
|
||||
stream_ << entry->name;
|
||||
stream << entry->name;
|
||||
} else {
|
||||
assert(false && "unhandled or invalid case");
|
||||
}
|
||||
break;
|
||||
}
|
||||
ResetColor();
|
||||
ResetColor(stream);
|
||||
}
|
||||
|
||||
void InstructionDisassembler::EmitMaskOperand(const spv_operand_type_t type,
|
||||
const uint32_t word) {
|
||||
void InstructionDisassembler::EmitMaskOperand(std::ostream& stream,
|
||||
const spv_operand_type_t type,
|
||||
const uint32_t word) const {
|
||||
// Scan the mask from least significant bit to most significant bit. For each
|
||||
// set bit, emit the name of that bit. Separate multiple names with '|'.
|
||||
uint32_t remaining_word = word;
|
||||
@ -457,8 +552,8 @@ void InstructionDisassembler::EmitMaskOperand(const spv_operand_type_t type,
|
||||
spv_operand_desc entry;
|
||||
if (grammar_.lookupOperand(type, mask, &entry))
|
||||
assert(false && "should have caught this earlier");
|
||||
if (num_emitted) stream_ << "|";
|
||||
stream_ << entry->name;
|
||||
if (num_emitted) stream << "|";
|
||||
stream << entry->name;
|
||||
num_emitted++;
|
||||
}
|
||||
}
|
||||
@ -467,28 +562,35 @@ void InstructionDisassembler::EmitMaskOperand(const spv_operand_type_t type,
|
||||
// of the 0 value. In many cases, that's "None".
|
||||
spv_operand_desc entry;
|
||||
if (SPV_SUCCESS == grammar_.lookupOperand(type, 0, &entry))
|
||||
stream_ << entry->name;
|
||||
stream << entry->name;
|
||||
}
|
||||
}
|
||||
|
||||
void InstructionDisassembler::ResetColor() {
|
||||
if (color_) stream_ << spvtools::clr::reset{print_};
|
||||
void InstructionDisassembler::ResetColor(std::ostream& stream) const {
|
||||
if (color_) stream << spvtools::clr::reset{print_};
|
||||
}
|
||||
void InstructionDisassembler::SetGrey() {
|
||||
if (color_) stream_ << spvtools::clr::grey{print_};
|
||||
void InstructionDisassembler::SetGrey(std::ostream& stream) const {
|
||||
if (color_) stream << spvtools::clr::grey{print_};
|
||||
}
|
||||
void InstructionDisassembler::SetBlue() {
|
||||
if (color_) stream_ << spvtools::clr::blue{print_};
|
||||
void InstructionDisassembler::SetBlue(std::ostream& stream) const {
|
||||
if (color_) stream << spvtools::clr::blue{print_};
|
||||
}
|
||||
void InstructionDisassembler::SetYellow() {
|
||||
if (color_) stream_ << spvtools::clr::yellow{print_};
|
||||
void InstructionDisassembler::SetYellow(std::ostream& stream) const {
|
||||
if (color_) stream << spvtools::clr::yellow{print_};
|
||||
}
|
||||
void InstructionDisassembler::SetRed() {
|
||||
if (color_) stream_ << spvtools::clr::red{print_};
|
||||
void InstructionDisassembler::SetRed(std::ostream& stream) const {
|
||||
if (color_) stream << spvtools::clr::red{print_};
|
||||
}
|
||||
void InstructionDisassembler::SetGreen() {
|
||||
if (color_) stream_ << spvtools::clr::green{print_};
|
||||
void InstructionDisassembler::SetGreen(std::ostream& stream) const {
|
||||
if (color_) stream << spvtools::clr::green{print_};
|
||||
}
|
||||
|
||||
void InstructionDisassembler::ResetColor() { ResetColor(stream_); }
|
||||
void InstructionDisassembler::SetGrey() { SetGrey(stream_); }
|
||||
void InstructionDisassembler::SetBlue() { SetBlue(stream_); }
|
||||
void InstructionDisassembler::SetYellow() { SetYellow(stream_); }
|
||||
void InstructionDisassembler::SetRed() { SetRed(stream_); }
|
||||
void InstructionDisassembler::SetGreen() { SetGreen(stream_); }
|
||||
} // namespace disassemble
|
||||
|
||||
std::string spvInstructionBinaryToText(const spv_target_env env,
|
||||
|
26
3rdparty/spirv-tools/source/disassemble.h
vendored
26
3rdparty/spirv-tools/source/disassemble.h
vendored
@ -16,6 +16,7 @@
|
||||
#define SOURCE_DISASSEMBLE_H_
|
||||
|
||||
#include <iosfwd>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
#include "source/name_mapper.h"
|
||||
@ -74,13 +75,25 @@ class InstructionDisassembler {
|
||||
void SetGreen();
|
||||
|
||||
private:
|
||||
void ResetColor(std::ostream& stream) const;
|
||||
void SetGrey(std::ostream& stream) const;
|
||||
void SetBlue(std::ostream& stream) const;
|
||||
void SetYellow(std::ostream& stream) const;
|
||||
void SetRed(std::ostream& stream) const;
|
||||
void SetGreen(std::ostream& stream) const;
|
||||
|
||||
// Emits an operand for the given instruction, where the instruction
|
||||
// is at offset words from the start of the binary.
|
||||
void EmitOperand(const spv_parsed_instruction_t& inst,
|
||||
const uint16_t operand_index);
|
||||
void EmitOperand(std::ostream& stream, const spv_parsed_instruction_t& inst,
|
||||
const uint16_t operand_index) const;
|
||||
|
||||
// Emits a mask expression for the given mask word of the specified type.
|
||||
void EmitMaskOperand(const spv_operand_type_t type, const uint32_t word);
|
||||
void EmitMaskOperand(std::ostream& stream, const spv_operand_type_t type,
|
||||
const uint32_t word) const;
|
||||
|
||||
// Generate part of the instruction as a comment to be added to
|
||||
// |id_comments_|.
|
||||
void GenerateCommentForDecoratedId(const spv_parsed_instruction_t& inst);
|
||||
|
||||
const spvtools::AssemblyGrammar& grammar_;
|
||||
std::ostream& stream_;
|
||||
@ -90,6 +103,13 @@ class InstructionDisassembler {
|
||||
const int comment_; // Should we comment the source
|
||||
const bool show_byte_offset_; // Should we print byte offset, in hex?
|
||||
spvtools::NameMapper name_mapper_;
|
||||
|
||||
// Some comments are generated as instructions (such as OpDecorate) are
|
||||
// visited so that when the instruction with that result id is visited, the
|
||||
// comment can be output.
|
||||
std::unordered_map<uint32_t, std::ostringstream> id_comments_;
|
||||
// Align the comments in consecutive lines for more readability.
|
||||
uint32_t last_instruction_comment_alignment_;
|
||||
};
|
||||
|
||||
} // namespace disassemble
|
||||
|
13
3rdparty/spirv-tools/source/opcode.cpp
vendored
13
3rdparty/spirv-tools/source/opcode.cpp
vendored
@ -225,6 +225,7 @@ int32_t spvOpcodeIsSpecConstant(const spv::Op opcode) {
|
||||
case spv::Op::OpSpecConstantFalse:
|
||||
case spv::Op::OpSpecConstant:
|
||||
case spv::Op::OpSpecConstantComposite:
|
||||
case spv::Op::OpSpecConstantCompositeReplicateEXT:
|
||||
case spv::Op::OpSpecConstantOp:
|
||||
return true;
|
||||
default:
|
||||
@ -238,6 +239,7 @@ int32_t spvOpcodeIsConstant(const spv::Op opcode) {
|
||||
case spv::Op::OpConstantFalse:
|
||||
case spv::Op::OpConstant:
|
||||
case spv::Op::OpConstantComposite:
|
||||
case spv::Op::OpConstantCompositeReplicateEXT:
|
||||
case spv::Op::OpConstantSampler:
|
||||
case spv::Op::OpConstantNull:
|
||||
case spv::Op::OpConstantFunctionPointerINTEL:
|
||||
@ -245,6 +247,7 @@ int32_t spvOpcodeIsConstant(const spv::Op opcode) {
|
||||
case spv::Op::OpSpecConstantFalse:
|
||||
case spv::Op::OpSpecConstant:
|
||||
case spv::Op::OpSpecConstantComposite:
|
||||
case spv::Op::OpSpecConstantCompositeReplicateEXT:
|
||||
case spv::Op::OpSpecConstantOp:
|
||||
return true;
|
||||
default:
|
||||
@ -717,6 +720,16 @@ bool spvOpcodeIsImageSample(const spv::Op opcode) {
|
||||
}
|
||||
}
|
||||
|
||||
bool spvIsExtendedInstruction(const spv::Op opcode) {
|
||||
switch (opcode) {
|
||||
case spv::Op::OpExtInst:
|
||||
case spv::Op::OpExtInstWithForwardRefsKHR:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<uint32_t> spvOpcodeMemorySemanticsOperandIndices(spv::Op opcode) {
|
||||
switch (opcode) {
|
||||
case spv::Op::OpMemoryBarrier:
|
||||
|
3
3rdparty/spirv-tools/source/opcode.h
vendored
3
3rdparty/spirv-tools/source/opcode.h
vendored
@ -146,6 +146,9 @@ bool spvOpcodeIsLinearAlgebra(spv::Op opcode);
|
||||
// Returns true for opcodes that represent image sample instructions.
|
||||
bool spvOpcodeIsImageSample(spv::Op opcode);
|
||||
|
||||
// Returns true if the opcode is either OpExtInst or OpExtInstWithForwardRefsKHR
|
||||
bool spvIsExtendedInstruction(spv::Op opcode);
|
||||
|
||||
// Returns a vector containing the indices of the memory semantics <id>
|
||||
// operands for |opcode|.
|
||||
std::vector<uint32_t> spvOpcodeMemorySemanticsOperandIndices(spv::Op opcode);
|
||||
|
8
3rdparty/spirv-tools/source/operand.cpp
vendored
8
3rdparty/spirv-tools/source/operand.cpp
vendored
@ -582,11 +582,13 @@ std::function<bool(unsigned)> spvOperandCanBeForwardDeclaredFunction(
|
||||
}
|
||||
|
||||
std::function<bool(unsigned)> spvDbgInfoExtOperandCanBeForwardDeclaredFunction(
|
||||
spv_ext_inst_type_t ext_type, uint32_t key) {
|
||||
spv::Op opcode, spv_ext_inst_type_t ext_type, uint32_t key) {
|
||||
// The Vulkan debug info extended instruction set is non-semantic so allows no
|
||||
// forward references ever
|
||||
// forward references except if used through OpExtInstWithForwardRefsKHR.
|
||||
if (ext_type == SPV_EXT_INST_TYPE_NONSEMANTIC_SHADER_DEBUGINFO_100) {
|
||||
return [](unsigned) { return false; };
|
||||
return [opcode](unsigned) {
|
||||
return opcode == spv::Op::OpExtInstWithForwardRefsKHR;
|
||||
};
|
||||
}
|
||||
|
||||
// TODO(https://gitlab.khronos.org/spirv/SPIR-V/issues/532): Forward
|
||||
|
2
3rdparty/spirv-tools/source/operand.h
vendored
2
3rdparty/spirv-tools/source/operand.h
vendored
@ -140,6 +140,6 @@ std::function<bool(unsigned)> spvOperandCanBeForwardDeclaredFunction(
|
||||
// of the operand can be forward declared. This function will
|
||||
// used in the SSA validation stage of the pipeline
|
||||
std::function<bool(unsigned)> spvDbgInfoExtOperandCanBeForwardDeclaredFunction(
|
||||
spv_ext_inst_type_t ext_type, uint32_t key);
|
||||
spv::Op opcode, spv_ext_inst_type_t ext_type, uint32_t key);
|
||||
|
||||
#endif // SOURCE_OPERAND_H_
|
||||
|
@ -329,12 +329,10 @@ bool ConvertToSampledImagePass::ConvertImageVariableToSampledImage(
|
||||
if (sampled_image_type == nullptr) return false;
|
||||
auto storage_class = GetStorageClass(*image_variable);
|
||||
if (storage_class == spv::StorageClass::Max) return false;
|
||||
analysis::Pointer sampled_image_pointer(sampled_image_type, storage_class);
|
||||
|
||||
// Make sure |image_variable| is behind its type i.e., avoid the forward
|
||||
// reference.
|
||||
uint32_t type_id =
|
||||
context()->get_type_mgr()->GetTypeInstruction(&sampled_image_pointer);
|
||||
uint32_t type_id = context()->get_type_mgr()->FindPointerToType(
|
||||
sampled_image_type_id, storage_class);
|
||||
MoveInstructionNextToType(image_variable, type_id);
|
||||
return true;
|
||||
}
|
||||
|
@ -92,16 +92,19 @@ void EliminateDeadOutputStoresPass::KillAllDeadStoresOfLocRef(
|
||||
});
|
||||
// Compute offset and final type of reference. If no location found
|
||||
// or any stored locations are live, return without removing stores.
|
||||
auto ptr_type = type_mgr->GetType(var->type_id())->AsPointer();
|
||||
|
||||
Instruction* ptr_type = get_def_use_mgr()->GetDef(var->type_id());
|
||||
assert(ptr_type && "unexpected var type");
|
||||
auto var_type = ptr_type->pointee_type();
|
||||
const uint32_t kPointerTypePointeeIdx = 1;
|
||||
uint32_t var_type_id =
|
||||
ptr_type->GetSingleWordInOperand(kPointerTypePointeeIdx);
|
||||
uint32_t ref_loc = start_loc;
|
||||
auto curr_type = var_type;
|
||||
if (ref->opcode() == spv::Op::OpAccessChain ||
|
||||
ref->opcode() == spv::Op::OpInBoundsAccessChain) {
|
||||
live_mgr->AnalyzeAccessChainLoc(ref, &curr_type, &ref_loc, &no_loc,
|
||||
is_patch, /* input */ false);
|
||||
var_type_id = live_mgr->AnalyzeAccessChainLoc(
|
||||
ref, var_type_id, &ref_loc, &no_loc, is_patch, /* input */ false);
|
||||
}
|
||||
const analysis::Type* curr_type = type_mgr->GetType(var_type_id);
|
||||
if (no_loc || AnyLocsAreLive(ref_loc, live_mgr->GetLocSize(curr_type)))
|
||||
return;
|
||||
// Kill all stores based on this reference
|
||||
|
@ -1607,27 +1607,26 @@ bool CompositeConstructFeedingExtract(
|
||||
}
|
||||
|
||||
// Walks the indexes chain from |start| to |end| of an OpCompositeInsert or
|
||||
// OpCompositeExtract instruction, and returns the type of the final element
|
||||
// being accessed.
|
||||
const analysis::Type* GetElementType(uint32_t type_id,
|
||||
Instruction::iterator start,
|
||||
Instruction::iterator end,
|
||||
const analysis::TypeManager* type_mgr) {
|
||||
const analysis::Type* type = type_mgr->GetType(type_id);
|
||||
// OpCompositeExtract instruction, and returns the type id of the final element
|
||||
// being accessed. Returns 0 if a valid type could not be found.
|
||||
uint32_t GetElementType(uint32_t type_id, Instruction::iterator start,
|
||||
Instruction::iterator end,
|
||||
const analysis::DefUseManager* def_use_manager) {
|
||||
for (auto index : make_range(std::move(start), std::move(end))) {
|
||||
const Instruction* type_inst = def_use_manager->GetDef(type_id);
|
||||
assert(index.type == SPV_OPERAND_TYPE_LITERAL_INTEGER &&
|
||||
index.words.size() == 1);
|
||||
if (auto* array_type = type->AsArray()) {
|
||||
type = array_type->element_type();
|
||||
} else if (auto* matrix_type = type->AsMatrix()) {
|
||||
type = matrix_type->element_type();
|
||||
} else if (auto* struct_type = type->AsStruct()) {
|
||||
type = struct_type->element_types()[index.words[0]];
|
||||
if (type_inst->opcode() == spv::Op::OpTypeArray) {
|
||||
type_id = type_inst->GetSingleWordInOperand(0);
|
||||
} else if (type_inst->opcode() == spv::Op::OpTypeMatrix) {
|
||||
type_id = type_inst->GetSingleWordInOperand(0);
|
||||
} else if (type_inst->opcode() == spv::Op::OpTypeStruct) {
|
||||
type_id = type_inst->GetSingleWordInOperand(index.words[0]);
|
||||
} else {
|
||||
type = nullptr;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return type;
|
||||
return type_id;
|
||||
}
|
||||
|
||||
// Returns true of |inst_1| and |inst_2| have the same indexes that will be used
|
||||
@ -1712,16 +1711,11 @@ bool CompositeExtractFeedingConstruct(
|
||||
// The last check it to see that the object being extracted from is the
|
||||
// correct type.
|
||||
Instruction* original_inst = def_use_mgr->GetDef(original_id);
|
||||
analysis::TypeManager* type_mgr = context->get_type_mgr();
|
||||
const analysis::Type* original_type =
|
||||
uint32_t original_type_id =
|
||||
GetElementType(original_inst->type_id(), first_element_inst->begin() + 3,
|
||||
first_element_inst->end() - 1, type_mgr);
|
||||
first_element_inst->end() - 1, def_use_mgr);
|
||||
|
||||
if (original_type == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (inst->type_id() != type_mgr->GetId(original_type)) {
|
||||
if (inst->type_id() != original_type_id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -2011,13 +2005,15 @@ bool DoInsertedValuesCoverEntireObject(
|
||||
return true;
|
||||
}
|
||||
|
||||
// Returns the type of the element that immediately contains the element being
|
||||
// inserted by the OpCompositeInsert instruction |inst|.
|
||||
const analysis::Type* GetContainerType(Instruction* inst) {
|
||||
// Returns id of the type of the element that immediately contains the element
|
||||
// being inserted by the OpCompositeInsert instruction |inst|. Returns 0 if it
|
||||
// could not be found.
|
||||
uint32_t GetContainerTypeId(Instruction* inst) {
|
||||
assert(inst->opcode() == spv::Op::OpCompositeInsert);
|
||||
analysis::TypeManager* type_mgr = inst->context()->get_type_mgr();
|
||||
return GetElementType(inst->type_id(), inst->begin() + 4, inst->end() - 1,
|
||||
type_mgr);
|
||||
analysis::DefUseManager* def_use_manager = inst->context()->get_def_use_mgr();
|
||||
uint32_t container_type_id = GetElementType(
|
||||
inst->type_id(), inst->begin() + 4, inst->end() - 1, def_use_manager);
|
||||
return container_type_id;
|
||||
}
|
||||
|
||||
// Returns an OpCompositeConstruct instruction that build an object with
|
||||
@ -2064,18 +2060,20 @@ bool CompositeInsertToCompositeConstruct(
|
||||
if (inst->NumInOperands() < 3) return false;
|
||||
|
||||
std::map<uint32_t, uint32_t> values_inserted = GetInsertedValues(inst);
|
||||
const analysis::Type* container_type = GetContainerType(inst);
|
||||
if (container_type == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!DoInsertedValuesCoverEntireObject(container_type, values_inserted)) {
|
||||
uint32_t container_type_id = GetContainerTypeId(inst);
|
||||
if (container_type_id == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
analysis::TypeManager* type_mgr = context->get_type_mgr();
|
||||
Instruction* construct = BuildCompositeConstruct(
|
||||
type_mgr->GetId(container_type), values_inserted, inst);
|
||||
const analysis::Type* container_type = type_mgr->GetType(container_type_id);
|
||||
assert(container_type && "GetContainerTypeId returned a bad id.");
|
||||
if (!DoInsertedValuesCoverEntireObject(container_type, values_inserted)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Instruction* construct =
|
||||
BuildCompositeConstruct(container_type_id, values_inserted, inst);
|
||||
InsertConstructedObject(inst, construct);
|
||||
return true;
|
||||
}
|
||||
|
5
3rdparty/spirv-tools/source/opt/ir_context.h
vendored
5
3rdparty/spirv-tools/source/opt/ir_context.h
vendored
@ -202,8 +202,9 @@ class IRContext {
|
||||
inline IteratorRange<Module::const_inst_iterator> debugs3() const;
|
||||
|
||||
// Iterators for debug info instructions (excluding OpLine & OpNoLine)
|
||||
// contained in this module. These are OpExtInst for DebugInfo extension
|
||||
// placed between section 9 and 10.
|
||||
// contained in this module. These are OpExtInst &
|
||||
// OpExtInstWithForwardRefsKHR for DebugInfo extension placed between section
|
||||
// 9 and 10.
|
||||
inline Module::inst_iterator ext_inst_debuginfo_begin();
|
||||
inline Module::inst_iterator ext_inst_debuginfo_end();
|
||||
inline IteratorRange<Module::inst_iterator> ext_inst_debuginfo();
|
||||
|
10
3rdparty/spirv-tools/source/opt/ir_loader.cpp
vendored
10
3rdparty/spirv-tools/source/opt/ir_loader.cpp
vendored
@ -42,7 +42,7 @@ IrLoader::IrLoader(const MessageConsumer& consumer, Module* m)
|
||||
bool IsLineInst(const spv_parsed_instruction_t* inst) {
|
||||
const auto opcode = static_cast<spv::Op>(inst->opcode);
|
||||
if (IsOpLineInst(opcode)) return true;
|
||||
if (opcode != spv::Op::OpExtInst) return false;
|
||||
if (!spvIsExtendedInstruction(opcode)) return false;
|
||||
if (inst->ext_inst_type != SPV_EXT_INST_TYPE_NONSEMANTIC_SHADER_DEBUGINFO_100)
|
||||
return false;
|
||||
const uint32_t ext_inst_index = inst->words[kExtInstSetIndex];
|
||||
@ -65,7 +65,7 @@ bool IrLoader::AddInstruction(const spv_parsed_instruction_t* inst) {
|
||||
// create a new instruction, but simply keep the information in
|
||||
// struct DebugScope.
|
||||
const auto opcode = static_cast<spv::Op>(inst->opcode);
|
||||
if (opcode == spv::Op::OpExtInst &&
|
||||
if (spvIsExtendedInstruction(opcode) &&
|
||||
spvExtInstIsDebugInfo(inst->ext_inst_type)) {
|
||||
const uint32_t ext_inst_index = inst->words[kExtInstSetIndex];
|
||||
if (inst->ext_inst_type == SPV_EXT_INST_TYPE_OPENCL_DEBUGINFO_100 ||
|
||||
@ -209,10 +209,10 @@ bool IrLoader::AddInstruction(const spv_parsed_instruction_t* inst) {
|
||||
} else if (IsConstantInst(opcode) || opcode == spv::Op::OpVariable ||
|
||||
opcode == spv::Op::OpUndef) {
|
||||
module_->AddGlobalValue(std::move(spv_inst));
|
||||
} else if (opcode == spv::Op::OpExtInst &&
|
||||
} else if (spvIsExtendedInstruction(opcode) &&
|
||||
spvExtInstIsDebugInfo(inst->ext_inst_type)) {
|
||||
module_->AddExtInstDebugInfo(std::move(spv_inst));
|
||||
} else if (opcode == spv::Op::OpExtInst &&
|
||||
} else if (spvIsExtendedInstruction(opcode) &&
|
||||
spvExtInstIsNonSemantic(inst->ext_inst_type)) {
|
||||
// If there are no functions, add the non-semantic instructions to the
|
||||
// global values. Otherwise append it to the list of the last function.
|
||||
@ -235,7 +235,7 @@ bool IrLoader::AddInstruction(const spv_parsed_instruction_t* inst) {
|
||||
last_dbg_scope_ = DebugScope(kNoDebugScope, kNoInlinedAt);
|
||||
if (last_dbg_scope_.GetLexicalScope() != kNoDebugScope)
|
||||
spv_inst->SetDebugScope(last_dbg_scope_);
|
||||
if (opcode == spv::Op::OpExtInst &&
|
||||
if (spvIsExtendedInstruction(opcode) &&
|
||||
spvExtInstIsDebugInfo(inst->ext_inst_type)) {
|
||||
const uint32_t ext_inst_index = inst->words[kExtInstSetIndex];
|
||||
if (inst->ext_inst_type == SPV_EXT_INST_TYPE_OPENCL_DEBUGINFO_100) {
|
||||
|
106
3rdparty/spirv-tools/source/opt/liveness.cpp
vendored
106
3rdparty/spirv-tools/source/opt/liveness.cpp
vendored
@ -123,21 +123,29 @@ uint32_t LivenessManager::GetLocSize(const analysis::Type* type) const {
|
||||
return 1;
|
||||
}
|
||||
|
||||
const analysis::Type* LivenessManager::GetComponentType(
|
||||
uint32_t index, const analysis::Type* agg_type) const {
|
||||
auto arr_type = agg_type->AsArray();
|
||||
if (arr_type) return arr_type->element_type();
|
||||
auto struct_type = agg_type->AsStruct();
|
||||
if (struct_type) return struct_type->element_types()[index];
|
||||
auto mat_type = agg_type->AsMatrix();
|
||||
if (mat_type) return mat_type->element_type();
|
||||
auto vec_type = agg_type->AsVector();
|
||||
assert(vec_type && "unexpected non-aggregate type");
|
||||
return vec_type->element_type();
|
||||
uint32_t LivenessManager::GetComponentType(uint32_t index,
|
||||
uint32_t agg_type_id) const {
|
||||
analysis::DefUseManager* def_use_mgr = context()->get_def_use_mgr();
|
||||
Instruction* agg_type_inst = def_use_mgr->GetDef(agg_type_id);
|
||||
|
||||
const uint32_t kArrayElementInIdx = 0;
|
||||
switch (agg_type_inst->opcode()) {
|
||||
case spv::Op::OpTypeArray:
|
||||
case spv::Op::OpTypeMatrix:
|
||||
case spv::Op::OpTypeVector:
|
||||
return agg_type_inst->GetSingleWordInOperand(kArrayElementInIdx);
|
||||
case spv::Op::OpTypeStruct:
|
||||
return agg_type_inst->GetSingleWordInOperand(index);
|
||||
default:
|
||||
assert(false && "unexpected aggregate type");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t LivenessManager::GetLocOffset(uint32_t index,
|
||||
const analysis::Type* agg_type) const {
|
||||
uint32_t agg_type_id) const {
|
||||
analysis::TypeManager* type_mgr = context()->get_type_mgr();
|
||||
const analysis::Type* agg_type = type_mgr->GetType(agg_type_id);
|
||||
auto arr_type = agg_type->AsArray();
|
||||
if (arr_type) return index * GetLocSize(arr_type->element_type());
|
||||
auto struct_type = agg_type->AsStruct();
|
||||
@ -161,12 +169,11 @@ uint32_t LivenessManager::GetLocOffset(uint32_t index,
|
||||
return 0;
|
||||
}
|
||||
|
||||
void LivenessManager::AnalyzeAccessChainLoc(const Instruction* ac,
|
||||
const analysis::Type** curr_type,
|
||||
uint32_t* offset, bool* no_loc,
|
||||
bool is_patch, bool input) {
|
||||
uint32_t LivenessManager::AnalyzeAccessChainLoc(const Instruction* ac,
|
||||
uint32_t curr_type_id,
|
||||
uint32_t* offset, bool* no_loc,
|
||||
bool is_patch, bool input) {
|
||||
analysis::DefUseManager* def_use_mgr = context()->get_def_use_mgr();
|
||||
analysis::TypeManager* type_mgr = context()->get_type_mgr();
|
||||
analysis::DecorationManager* deco_mgr = context()->get_decoration_mgr();
|
||||
// For tesc, tese and geom input variables, and tesc output variables,
|
||||
// first array index does not contribute to offset.
|
||||
@ -178,15 +185,18 @@ void LivenessManager::AnalyzeAccessChainLoc(const Instruction* ac,
|
||||
(!input && stage == spv::ExecutionModel::TessellationControl))
|
||||
skip_first_index = !is_patch;
|
||||
uint32_t ocnt = 0;
|
||||
ac->WhileEachInOperand([this, &ocnt, def_use_mgr, type_mgr, deco_mgr,
|
||||
curr_type, offset, no_loc,
|
||||
ac->WhileEachInOperand([this, &ocnt, def_use_mgr, deco_mgr, &curr_type_id,
|
||||
offset, no_loc,
|
||||
skip_first_index](const uint32_t* opnd) {
|
||||
if (ocnt >= 1) {
|
||||
// Skip first index's contribution to offset if indicated
|
||||
Instruction* curr_type_inst = def_use_mgr->GetDef(curr_type_id);
|
||||
if (ocnt == 1 && skip_first_index) {
|
||||
auto arr_type = (*curr_type)->AsArray();
|
||||
assert(arr_type && "unexpected wrapper type");
|
||||
*curr_type = arr_type->element_type();
|
||||
assert(curr_type_inst->opcode() == spv::Op::OpTypeArray &&
|
||||
"unexpected wrapper type");
|
||||
const uint32_t kArrayElementTypeInIdx = 0;
|
||||
curr_type_id =
|
||||
curr_type_inst->GetSingleWordInOperand(kArrayElementTypeInIdx);
|
||||
ocnt++;
|
||||
return true;
|
||||
}
|
||||
@ -196,12 +206,10 @@ void LivenessManager::AnalyzeAccessChainLoc(const Instruction* ac,
|
||||
// If current type is struct, look for location decoration on member and
|
||||
// reset offset if found.
|
||||
auto index = idx_inst->GetSingleWordInOperand(0);
|
||||
auto str_type = (*curr_type)->AsStruct();
|
||||
if (str_type) {
|
||||
if (curr_type_inst->opcode() == spv::Op::OpTypeStruct) {
|
||||
uint32_t loc = 0;
|
||||
auto str_type_id = type_mgr->GetId(str_type);
|
||||
bool no_mem_loc = deco_mgr->WhileEachDecoration(
|
||||
str_type_id, uint32_t(spv::Decoration::Location),
|
||||
curr_type_id, uint32_t(spv::Decoration::Location),
|
||||
[&loc, index, no_loc](const Instruction& deco) {
|
||||
assert(deco.opcode() == spv::Op::OpMemberDecorate &&
|
||||
"unexpected decoration");
|
||||
@ -216,19 +224,20 @@ void LivenessManager::AnalyzeAccessChainLoc(const Instruction* ac,
|
||||
});
|
||||
if (!no_mem_loc) {
|
||||
*offset = loc;
|
||||
*curr_type = GetComponentType(index, *curr_type);
|
||||
curr_type_id = curr_type_inst->GetSingleWordInOperand(index);
|
||||
ocnt++;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Update offset and current type based on constant index.
|
||||
*offset += GetLocOffset(index, *curr_type);
|
||||
*curr_type = GetComponentType(index, *curr_type);
|
||||
*offset += GetLocOffset(index, curr_type_id);
|
||||
curr_type_id = GetComponentType(index, curr_type_id);
|
||||
}
|
||||
ocnt++;
|
||||
return true;
|
||||
});
|
||||
return curr_type_id;
|
||||
}
|
||||
|
||||
void LivenessManager::MarkRefLive(const Instruction* ref, Instruction* var) {
|
||||
@ -268,8 +277,15 @@ void LivenessManager::MarkRefLive(const Instruction* ref, Instruction* var) {
|
||||
// through constant indices and mark those locs live. Assert if no location
|
||||
// found.
|
||||
uint32_t offset = loc;
|
||||
auto curr_type = var_type;
|
||||
AnalyzeAccessChainLoc(ref, &curr_type, &offset, &no_loc, is_patch);
|
||||
Instruction* ptr_type_inst =
|
||||
context()->get_def_use_mgr()->GetDef(var->type_id());
|
||||
assert(ptr_type && "unexpected var type");
|
||||
const uint32_t kPointerTypePointeeIdx = 1;
|
||||
uint32_t var_type_id =
|
||||
ptr_type_inst->GetSingleWordInOperand(kPointerTypePointeeIdx);
|
||||
uint32_t curr_type_id =
|
||||
AnalyzeAccessChainLoc(ref, var_type_id, &offset, &no_loc, is_patch);
|
||||
auto curr_type = type_mgr->GetType(curr_type_id);
|
||||
assert(!no_loc && "missing input variable location");
|
||||
MarkLocsLive(offset, GetLocSize(curr_type));
|
||||
}
|
||||
@ -277,15 +293,18 @@ void LivenessManager::MarkRefLive(const Instruction* ref, Instruction* var) {
|
||||
void LivenessManager::ComputeLiveness() {
|
||||
InitializeAnalysis();
|
||||
analysis::DefUseManager* def_use_mgr = context()->get_def_use_mgr();
|
||||
analysis::TypeManager* type_mgr = context()->get_type_mgr();
|
||||
// Process all input variables
|
||||
for (auto& var : context()->types_values()) {
|
||||
if (var.opcode() != spv::Op::OpVariable) {
|
||||
continue;
|
||||
}
|
||||
analysis::Type* var_type = type_mgr->GetType(var.type_id());
|
||||
analysis::Pointer* ptr_type = var_type->AsPointer();
|
||||
if (ptr_type->storage_class() != spv::StorageClass::Input) {
|
||||
Instruction* var_type_inst = def_use_mgr->GetDef(var.type_id());
|
||||
assert(var_type_inst->opcode() == spv::Op::OpTypePointer &&
|
||||
"Expected a pointer type");
|
||||
const uint32_t kPointerTypeStorageClassInIdx = 0;
|
||||
spv::StorageClass sc = static_cast<spv::StorageClass>(
|
||||
var_type_inst->GetSingleWordInOperand(kPointerTypeStorageClassInIdx));
|
||||
if (sc != spv::StorageClass::Input) {
|
||||
continue;
|
||||
}
|
||||
// If var is builtin, mark live if analyzed and continue to next variable
|
||||
@ -295,14 +314,15 @@ void LivenessManager::ComputeLiveness() {
|
||||
// continue to next variable. Input interface blocks will only appear
|
||||
// in tesc, tese and geom shaders. Will need to strip off one level of
|
||||
// arrayness to get to block type.
|
||||
auto pte_type = ptr_type->pointee_type();
|
||||
auto arr_type = pte_type->AsArray();
|
||||
if (arr_type) {
|
||||
auto elt_type = arr_type->element_type();
|
||||
auto str_type = elt_type->AsStruct();
|
||||
if (str_type) {
|
||||
auto str_type_id = type_mgr->GetId(str_type);
|
||||
if (AnalyzeBuiltIn(str_type_id)) continue;
|
||||
const uint32_t kPointerTypePointeeTypeInIdx = 1;
|
||||
uint32_t pte_type_id =
|
||||
var_type_inst->GetSingleWordInOperand(kPointerTypePointeeTypeInIdx);
|
||||
Instruction* pte_type_inst = def_use_mgr->GetDef(pte_type_id);
|
||||
if (pte_type_inst->opcode() == spv::Op::OpTypeArray) {
|
||||
uint32_t array_elt_type_id = pte_type_inst->GetSingleWordInOperand(0);
|
||||
Instruction* arr_elt_type = def_use_mgr->GetDef(array_elt_type_id);
|
||||
if (arr_elt_type->opcode() == spv::Op::OpTypeStruct) {
|
||||
if (AnalyzeBuiltIn(array_elt_type_id)) continue;
|
||||
}
|
||||
}
|
||||
// Mark all used locations of var live
|
||||
|
25
3rdparty/spirv-tools/source/opt/liveness.h
vendored
25
3rdparty/spirv-tools/source/opt/liveness.h
vendored
@ -41,13 +41,13 @@ class LivenessManager {
|
||||
// Return true if builtin |bi| is being analyzed.
|
||||
bool IsAnalyzedBuiltin(uint32_t bi);
|
||||
|
||||
// Determine starting loc |offset| and the type |cur_type| of
|
||||
// access chain |ac|. Set |no_loc| to true if no loc found.
|
||||
// |is_patch| indicates if patch variable. |input| is true
|
||||
// if input variable, otherwise output variable.
|
||||
void AnalyzeAccessChainLoc(const Instruction* ac,
|
||||
const analysis::Type** curr_type, uint32_t* offset,
|
||||
bool* no_loc, bool is_patch, bool input = true);
|
||||
// Return the result type of |ac| when applied to |cur_type_id|. Set
|
||||
// |no_loc| to true if no loc found. Set |is_patch| indicates if the variable
|
||||
// is a patch variable. Set |input| if the variable is an input variable.
|
||||
// Otherwise it is assumed that the variable is an output variable.
|
||||
uint32_t AnalyzeAccessChainLoc(const Instruction* ac, uint32_t curr_type_id,
|
||||
uint32_t* offset, bool* no_loc, bool is_patch,
|
||||
bool input = true);
|
||||
|
||||
// Return size of |type_id| in units of locations
|
||||
uint32_t GetLocSize(const analysis::Type* type) const;
|
||||
@ -68,13 +68,12 @@ class LivenessManager {
|
||||
// Mark |count| locations starting at location |start|.
|
||||
void MarkLocsLive(uint32_t start, uint32_t count);
|
||||
|
||||
// Return type of component of aggregate type |agg_type| at |index|
|
||||
const analysis::Type* GetComponentType(uint32_t index,
|
||||
const analysis::Type* agg_type) const;
|
||||
// Return type of the member |index| in the aggregate type |agg_type_id|.
|
||||
uint32_t GetComponentType(uint32_t index, uint32_t agg_type_id) const;
|
||||
|
||||
// Return offset of |index| into aggregate type |agg_type| in units of
|
||||
// input locations
|
||||
uint32_t GetLocOffset(uint32_t index, const analysis::Type* agg_type) const;
|
||||
// Return offset of member |index| in the aggregate type |agg_type_id| in
|
||||
// units of input locations.
|
||||
uint32_t GetLocOffset(uint32_t index, uint32_t agg_type_id) const;
|
||||
|
||||
// Populate live_locs_ and live_builtins_
|
||||
void ComputeLiveness();
|
||||
|
112
3rdparty/spirv-tools/source/opt/opextinst_forward_ref_fixup_pass.cpp
vendored
Normal file
112
3rdparty/spirv-tools/source/opt/opextinst_forward_ref_fixup_pass.cpp
vendored
Normal file
@ -0,0 +1,112 @@
|
||||
// Copyright (c) 2024 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "source/opt/opextinst_forward_ref_fixup_pass.h"
|
||||
|
||||
#include <string>
|
||||
#include <unordered_set>
|
||||
|
||||
#include "source/extensions.h"
|
||||
#include "source/opt/ir_context.h"
|
||||
#include "source/opt/module.h"
|
||||
#include "type_manager.h"
|
||||
|
||||
namespace spvtools {
|
||||
namespace opt {
|
||||
namespace {
|
||||
|
||||
// Returns true if the instruction |inst| has a forward reference to another
|
||||
// debug instruction.
|
||||
// |debug_ids| contains the list of IDs belonging to debug instructions.
|
||||
// |seen_ids| contains the list of IDs already seen.
|
||||
bool HasForwardReference(const Instruction& inst,
|
||||
const std::unordered_set<uint32_t>& debug_ids,
|
||||
const std::unordered_set<uint32_t>& seen_ids) {
|
||||
const uint32_t num_in_operands = inst.NumInOperands();
|
||||
for (uint32_t i = 0; i < num_in_operands; ++i) {
|
||||
const Operand& op = inst.GetInOperand(i);
|
||||
if (!spvIsIdType(op.type)) continue;
|
||||
|
||||
if (debug_ids.count(op.AsId()) == 0) continue;
|
||||
|
||||
if (seen_ids.count(op.AsId()) == 0) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Replace |inst| opcode with OpExtInstWithForwardRefsKHR or OpExtInst
|
||||
// if required to comply with forward references.
|
||||
bool ReplaceOpcodeIfRequired(Instruction& inst, bool hasForwardReferences) {
|
||||
if (hasForwardReferences &&
|
||||
inst.opcode() != spv::Op::OpExtInstWithForwardRefsKHR)
|
||||
inst.SetOpcode(spv::Op::OpExtInstWithForwardRefsKHR);
|
||||
else if (!hasForwardReferences && inst.opcode() != spv::Op::OpExtInst)
|
||||
inst.SetOpcode(spv::Op::OpExtInst);
|
||||
else
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Returns all the result IDs of the instructions in |range|.
|
||||
std::unordered_set<uint32_t> gatherResultIds(
|
||||
const IteratorRange<Module::inst_iterator>& range) {
|
||||
std::unordered_set<uint32_t> output;
|
||||
for (const auto& it : range) output.insert(it.result_id());
|
||||
return output;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
Pass::Status OpExtInstWithForwardReferenceFixupPass::Process() {
|
||||
std::unordered_set<uint32_t> seen_ids =
|
||||
gatherResultIds(get_module()->ext_inst_imports());
|
||||
std::unordered_set<uint32_t> debug_ids =
|
||||
gatherResultIds(get_module()->ext_inst_debuginfo());
|
||||
for (uint32_t id : seen_ids) debug_ids.insert(id);
|
||||
|
||||
bool moduleChanged = false;
|
||||
bool hasAtLeastOneForwardReference = false;
|
||||
IRContext* ctx = context();
|
||||
for (Instruction& inst : get_module()->ext_inst_debuginfo()) {
|
||||
if (inst.opcode() != spv::Op::OpExtInst &&
|
||||
inst.opcode() != spv::Op::OpExtInstWithForwardRefsKHR)
|
||||
continue;
|
||||
|
||||
seen_ids.insert(inst.result_id());
|
||||
bool hasForwardReferences = HasForwardReference(inst, debug_ids, seen_ids);
|
||||
hasAtLeastOneForwardReference |= hasForwardReferences;
|
||||
|
||||
if (ReplaceOpcodeIfRequired(inst, hasForwardReferences)) {
|
||||
moduleChanged = true;
|
||||
ctx->AnalyzeUses(&inst);
|
||||
}
|
||||
}
|
||||
|
||||
if (hasAtLeastOneForwardReference !=
|
||||
ctx->get_feature_mgr()->HasExtension(
|
||||
kSPV_KHR_relaxed_extended_instruction)) {
|
||||
if (hasAtLeastOneForwardReference)
|
||||
ctx->AddExtension("SPV_KHR_relaxed_extended_instruction");
|
||||
else
|
||||
ctx->RemoveExtension(Extension::kSPV_KHR_relaxed_extended_instruction);
|
||||
moduleChanged = true;
|
||||
}
|
||||
|
||||
return moduleChanged ? Status::SuccessWithChange
|
||||
: Status::SuccessWithoutChange;
|
||||
}
|
||||
|
||||
} // namespace opt
|
||||
} // namespace spvtools
|
48
3rdparty/spirv-tools/source/opt/opextinst_forward_ref_fixup_pass.h
vendored
Normal file
48
3rdparty/spirv-tools/source/opt/opextinst_forward_ref_fixup_pass.h
vendored
Normal file
@ -0,0 +1,48 @@
|
||||
// Copyright (c) 2024 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef SOURCE_OPT_OPEXTINST_FORWARD_REF_FIXUP_H
|
||||
#define SOURCE_OPT_OPEXTINST_FORWARD_REF_FIXUP_H
|
||||
|
||||
#include "source/opt/ir_context.h"
|
||||
#include "source/opt/module.h"
|
||||
#include "source/opt/pass.h"
|
||||
|
||||
namespace spvtools {
|
||||
namespace opt {
|
||||
|
||||
class OpExtInstWithForwardReferenceFixupPass : public Pass {
|
||||
public:
|
||||
const char* name() const override { return "fix-opextinst-opcodes"; }
|
||||
Status Process() override;
|
||||
|
||||
IRContext::Analysis GetPreservedAnalyses() override {
|
||||
return IRContext::kAnalysisInstrToBlockMapping |
|
||||
IRContext::kAnalysisDecorations | IRContext::kAnalysisCombinators |
|
||||
IRContext::kAnalysisCFG | IRContext::kAnalysisDominatorAnalysis |
|
||||
IRContext::kAnalysisLoopAnalysis | IRContext::kAnalysisNameMap |
|
||||
IRContext::kAnalysisScalarEvolution |
|
||||
IRContext::kAnalysisRegisterPressure |
|
||||
IRContext::kAnalysisValueNumberTable |
|
||||
IRContext::kAnalysisStructuredCFG |
|
||||
IRContext::kAnalysisBuiltinVarId |
|
||||
IRContext::kAnalysisIdToFuncMapping | IRContext::kAnalysisTypes |
|
||||
IRContext::kAnalysisDefUse | IRContext::kAnalysisConstants;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace opt
|
||||
} // namespace spvtools
|
||||
|
||||
#endif // SOURCE_OPT_OPEXTINST_FORWARD_REF_FIXUP_H
|
11
3rdparty/spirv-tools/source/opt/optimizer.cpp
vendored
11
3rdparty/spirv-tools/source/opt/optimizer.cpp
vendored
@ -169,7 +169,8 @@ Optimizer& Optimizer::RegisterLegalizationPasses(bool preserve_interface) {
|
||||
.RegisterPass(CreateAggressiveDCEPass(preserve_interface))
|
||||
.RegisterPass(CreateRemoveUnusedInterfaceVariablesPass())
|
||||
.RegisterPass(CreateInterpolateFixupPass())
|
||||
.RegisterPass(CreateInvocationInterlockPlacementPass());
|
||||
.RegisterPass(CreateInvocationInterlockPlacementPass())
|
||||
.RegisterPass(CreateOpExtInstWithForwardReferenceFixupPass());
|
||||
}
|
||||
|
||||
Optimizer& Optimizer::RegisterLegalizationPasses() {
|
||||
@ -323,6 +324,8 @@ bool Optimizer::RegisterPassFromFlag(const std::string& flag,
|
||||
RegisterPass(CreateStripReflectInfoPass());
|
||||
} else if (pass_name == "strip-nonsemantic") {
|
||||
RegisterPass(CreateStripNonSemanticInfoPass());
|
||||
} else if (pass_name == "fix-opextinst-opcodes") {
|
||||
RegisterPass(CreateOpExtInstWithForwardReferenceFixupPass());
|
||||
} else if (pass_name == "set-spec-const-default-value") {
|
||||
if (pass_args.size() > 0) {
|
||||
auto spec_ids_vals =
|
||||
@ -1146,6 +1149,12 @@ Optimizer::PassToken CreateModifyMaximalReconvergencePass(bool add) {
|
||||
return MakeUnique<Optimizer::PassToken::Impl>(
|
||||
MakeUnique<opt::ModifyMaximalReconvergence>(add));
|
||||
}
|
||||
|
||||
Optimizer::PassToken CreateOpExtInstWithForwardReferenceFixupPass() {
|
||||
return MakeUnique<Optimizer::PassToken::Impl>(
|
||||
MakeUnique<opt::OpExtInstWithForwardReferenceFixupPass>());
|
||||
}
|
||||
|
||||
} // namespace spvtools
|
||||
|
||||
extern "C" {
|
||||
|
1
3rdparty/spirv-tools/source/opt/passes.h
vendored
1
3rdparty/spirv-tools/source/opt/passes.h
vendored
@ -65,6 +65,7 @@
|
||||
#include "source/opt/merge_return_pass.h"
|
||||
#include "source/opt/modify_maximal_reconvergence.h"
|
||||
#include "source/opt/null_pass.h"
|
||||
#include "source/opt/opextinst_forward_ref_fixup_pass.h"
|
||||
#include "source/opt/private_to_local_pass.h"
|
||||
#include "source/opt/reduce_load_size.h"
|
||||
#include "source/opt/redundancy_elimination.h"
|
||||
|
@ -43,7 +43,7 @@ Pass::Status StripDebugInfoPass::Process() {
|
||||
// see if this string is used anywhere by a non-semantic instruction
|
||||
bool no_nonsemantic_use =
|
||||
def_use->WhileEachUser(&inst, [def_use](Instruction* use) {
|
||||
if (use->opcode() == spv::Op::OpExtInst) {
|
||||
if (spvIsExtendedInstruction(use->opcode())) {
|
||||
auto ext_inst_set =
|
||||
def_use->GetDef(use->GetSingleWordInOperand(0u));
|
||||
const std::string extension_name =
|
||||
|
@ -96,7 +96,7 @@ Pass::Status StripNonSemanticInfoPass::Process() {
|
||||
if (!non_semantic_sets.empty()) {
|
||||
context()->module()->ForEachInst(
|
||||
[&non_semantic_sets, &to_remove](Instruction* inst) {
|
||||
if (inst->opcode() == spv::Op::OpExtInst) {
|
||||
if (spvIsExtendedInstruction(inst->opcode())) {
|
||||
if (non_semantic_sets.find(inst->GetSingleWordInOperand(0)) !=
|
||||
non_semantic_sets.end()) {
|
||||
to_remove.push_back(inst);
|
||||
|
@ -399,6 +399,33 @@ ExtensionSet getExtensionsRelatedTo(const CapabilitySet& capabilities,
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
bool hasOpcodeConflictingCapabilities(spv::Op opcode) {
|
||||
switch (opcode) {
|
||||
case spv::Op::OpBeginInvocationInterlockEXT:
|
||||
case spv::Op::OpEndInvocationInterlockEXT:
|
||||
case spv::Op::OpGroupNonUniformIAdd:
|
||||
case spv::Op::OpGroupNonUniformFAdd:
|
||||
case spv::Op::OpGroupNonUniformIMul:
|
||||
case spv::Op::OpGroupNonUniformFMul:
|
||||
case spv::Op::OpGroupNonUniformSMin:
|
||||
case spv::Op::OpGroupNonUniformUMin:
|
||||
case spv::Op::OpGroupNonUniformFMin:
|
||||
case spv::Op::OpGroupNonUniformSMax:
|
||||
case spv::Op::OpGroupNonUniformUMax:
|
||||
case spv::Op::OpGroupNonUniformFMax:
|
||||
case spv::Op::OpGroupNonUniformBitwiseAnd:
|
||||
case spv::Op::OpGroupNonUniformBitwiseOr:
|
||||
case spv::Op::OpGroupNonUniformBitwiseXor:
|
||||
case spv::Op::OpGroupNonUniformLogicalAnd:
|
||||
case spv::Op::OpGroupNonUniformLogicalOr:
|
||||
case spv::Op::OpGroupNonUniformLogicalXor:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
TrimCapabilitiesPass::TrimCapabilitiesPass()
|
||||
@ -416,10 +443,7 @@ TrimCapabilitiesPass::TrimCapabilitiesPass()
|
||||
void TrimCapabilitiesPass::addInstructionRequirementsForOpcode(
|
||||
spv::Op opcode, CapabilitySet* capabilities,
|
||||
ExtensionSet* extensions) const {
|
||||
// Ignoring OpBeginInvocationInterlockEXT and OpEndInvocationInterlockEXT
|
||||
// because they have three possible capabilities, only one of which is needed
|
||||
if (opcode == spv::Op::OpBeginInvocationInterlockEXT ||
|
||||
opcode == spv::Op::OpEndInvocationInterlockEXT) {
|
||||
if (hasOpcodeConflictingCapabilities(opcode)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -81,6 +81,11 @@ class TrimCapabilitiesPass : public Pass {
|
||||
spv::Capability::FragmentShaderPixelInterlockEXT,
|
||||
spv::Capability::FragmentShaderSampleInterlockEXT,
|
||||
spv::Capability::FragmentShaderShadingRateInterlockEXT,
|
||||
spv::Capability::GroupNonUniform,
|
||||
spv::Capability::GroupNonUniformArithmetic,
|
||||
spv::Capability::GroupNonUniformClustered,
|
||||
spv::Capability::GroupNonUniformPartitionedNV,
|
||||
spv::Capability::GroupNonUniformVote,
|
||||
spv::Capability::Groups,
|
||||
spv::Capability::ImageMSArray,
|
||||
spv::Capability::Int16,
|
||||
@ -99,7 +104,6 @@ class TrimCapabilitiesPass : public Pass {
|
||||
spv::Capability::StorageUniform16,
|
||||
spv::Capability::StorageUniformBufferBlock16,
|
||||
spv::Capability::VulkanMemoryModelDeviceScope,
|
||||
spv::Capability::GroupNonUniformPartitionedNV
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
|
@ -454,12 +454,7 @@ uint32_t TypeManager::FindPointerToType(uint32_t type_id,
|
||||
spv::StorageClass storage_class) {
|
||||
Type* pointeeTy = GetType(type_id);
|
||||
Pointer pointerTy(pointeeTy, storage_class);
|
||||
if (pointeeTy->IsUniqueType()) {
|
||||
// Non-ambiguous type. Get the pointer type through the type manager.
|
||||
return GetTypeInstruction(&pointerTy);
|
||||
}
|
||||
|
||||
// Ambiguous type, do a linear search.
|
||||
Module::inst_iterator type_itr = context()->module()->types_values_begin();
|
||||
for (; type_itr != context()->module()->types_values_end(); ++type_itr) {
|
||||
const Instruction* type_inst = &*type_itr;
|
||||
@ -472,8 +467,10 @@ uint32_t TypeManager::FindPointerToType(uint32_t type_id,
|
||||
}
|
||||
|
||||
// Must create the pointer type.
|
||||
// TODO(1841): Handle id overflow.
|
||||
uint32_t resultId = context()->TakeNextId();
|
||||
if (resultId == 0) {
|
||||
return 0;
|
||||
}
|
||||
std::unique_ptr<Instruction> type_inst(
|
||||
new Instruction(context(), spv::Op::OpTypePointer, 0, resultId,
|
||||
{{spv_operand_type_t::SPV_OPERAND_TYPE_STORAGE_CLASS,
|
||||
|
3
3rdparty/spirv-tools/source/text.cpp
vendored
3
3rdparty/spirv-tools/source/text.cpp
vendored
@ -227,8 +227,7 @@ spv_result_t spvTextEncodeOperand(const spvtools::AssemblyGrammar& grammar,
|
||||
|
||||
// Set the extended instruction type.
|
||||
// The import set id is the 3rd operand of OpExtInst.
|
||||
if (spv::Op(pInst->opcode) == spv::Op::OpExtInst &&
|
||||
pInst->words.size() == 4) {
|
||||
if (spvIsExtendedInstruction(pInst->opcode) && pInst->words.size() == 4) {
|
||||
auto ext_inst_type = context->getExtInstTypeForId(pInst->words[3]);
|
||||
if (ext_inst_type == SPV_EXT_INST_TYPE_NONE) {
|
||||
return context->diagnostic()
|
||||
|
11
3rdparty/spirv-tools/source/val/decoration.h
vendored
11
3rdparty/spirv-tools/source/val/decoration.h
vendored
@ -15,6 +15,7 @@
|
||||
#ifndef SOURCE_VAL_DECORATION_H_
|
||||
#define SOURCE_VAL_DECORATION_H_
|
||||
|
||||
#include <cassert>
|
||||
#include <cstdint>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
@ -55,6 +56,12 @@ namespace val {
|
||||
// params_ = vector { 2 }
|
||||
// struct_member_index_ = 2
|
||||
//
|
||||
// Example 4: Decoration for a Builtin:
|
||||
// OpDecorate %var BuiltIn FragDepth
|
||||
// dec_type_ = spv::Decoration::BuiltIn
|
||||
// params_ = vector { FragDepth }
|
||||
// struct_member_index_ = kInvalidMember
|
||||
//
|
||||
class Decoration {
|
||||
public:
|
||||
enum { kInvalidMember = -1 };
|
||||
@ -68,6 +75,10 @@ class Decoration {
|
||||
spv::Decoration dec_type() const { return dec_type_; }
|
||||
std::vector<uint32_t>& params() { return params_; }
|
||||
const std::vector<uint32_t>& params() const { return params_; }
|
||||
spv::BuiltIn builtin() const {
|
||||
assert(dec_type_ == spv::Decoration::BuiltIn);
|
||||
return spv::BuiltIn(params_[0]);
|
||||
}
|
||||
|
||||
inline bool operator<(const Decoration& rhs) const {
|
||||
// Note: Sort by struct_member_index_ first, then type, so look up can be
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "source/ext_inst.h"
|
||||
#include "source/opcode.h"
|
||||
#include "source/table.h"
|
||||
#include "spirv-tools/libspirv.h"
|
||||
|
||||
@ -87,13 +88,13 @@ class Instruction {
|
||||
}
|
||||
|
||||
bool IsNonSemantic() const {
|
||||
return opcode() == spv::Op::OpExtInst &&
|
||||
return spvIsExtendedInstruction(opcode()) &&
|
||||
spvExtInstIsNonSemantic(inst_.ext_inst_type);
|
||||
}
|
||||
|
||||
/// True if this is an OpExtInst for debug info extension.
|
||||
bool IsDebugInfo() const {
|
||||
return opcode() == spv::Op::OpExtInst &&
|
||||
return spvIsExtendedInstruction(opcode()) &&
|
||||
spvExtInstIsDebugInfo(inst_.ext_inst_type);
|
||||
}
|
||||
|
||||
|
@ -52,6 +52,7 @@ spv_result_t ValidateAdjacency(ValidationState_t& _) {
|
||||
adjacency_status == IN_NEW_FUNCTION ? IN_ENTRY_BLOCK : PHI_VALID;
|
||||
break;
|
||||
case spv::Op::OpExtInst:
|
||||
case spv::Op::OpExtInstWithForwardRefsKHR:
|
||||
// If it is a debug info instruction, we do not change the status to
|
||||
// allow debug info instructions before OpVariable in a function.
|
||||
// TODO(https://gitlab.khronos.org/spirv/SPIR-V/issues/533): We need
|
||||
|
@ -741,7 +741,7 @@ std::string BuiltInsValidator::GetReferenceDesc(
|
||||
|
||||
ss << " which is decorated with BuiltIn ";
|
||||
ss << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN,
|
||||
decoration.params()[0]);
|
||||
(uint32_t)decoration.builtin());
|
||||
if (function_id_) {
|
||||
ss << " in function <" << function_id_ << ">";
|
||||
if (execution_model != spv::ExecutionModel::Max) {
|
||||
@ -1170,7 +1170,7 @@ spv_result_t BuiltInsValidator::ValidateNotCalledWithExecutionModel(
|
||||
const char* execution_model_str = _.grammar().lookupOperandName(
|
||||
SPV_OPERAND_TYPE_EXECUTION_MODEL, uint32_t(execution_model));
|
||||
const char* built_in_str = _.grammar().lookupOperandName(
|
||||
SPV_OPERAND_TYPE_BUILT_IN, decoration.params()[0]);
|
||||
SPV_OPERAND_TYPE_BUILT_IN, (uint32_t)decoration.builtin());
|
||||
return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst)
|
||||
<< (vuid < 0 ? std::string("") : _.VkErrorID(vuid)) << comment
|
||||
<< " " << GetIdDesc(referenced_inst) << " depends on "
|
||||
@ -1201,13 +1201,14 @@ spv_result_t BuiltInsValidator::ValidateClipOrCullDistanceAtReference(
|
||||
const Decoration& decoration, const Instruction& built_in_inst,
|
||||
const Instruction& referenced_inst,
|
||||
const Instruction& referenced_from_inst) {
|
||||
uint32_t operand = decoration.params()[0];
|
||||
uint32_t operand = (uint32_t)decoration.builtin();
|
||||
if (spvIsVulkanEnv(_.context()->target_env)) {
|
||||
const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst);
|
||||
if (storage_class != spv::StorageClass::Max &&
|
||||
storage_class != spv::StorageClass::Input &&
|
||||
storage_class != spv::StorageClass::Output) {
|
||||
uint32_t vuid = (spv::BuiltIn(decoration.params()[0]) == spv::BuiltIn::ClipDistance) ? 4190 : 4199;
|
||||
uint32_t vuid =
|
||||
(decoration.builtin() == spv::BuiltIn::ClipDistance) ? 4190 : 4199;
|
||||
return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst)
|
||||
<< _.VkErrorID(vuid) << "Vulkan spec allows BuiltIn "
|
||||
<< _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN,
|
||||
@ -1221,7 +1222,8 @@ spv_result_t BuiltInsValidator::ValidateClipOrCullDistanceAtReference(
|
||||
|
||||
if (storage_class == spv::StorageClass::Input) {
|
||||
assert(function_id_ == 0);
|
||||
uint32_t vuid = (spv::BuiltIn(decoration.params()[0]) == spv::BuiltIn::ClipDistance) ? 4188 : 4197;
|
||||
uint32_t vuid =
|
||||
(decoration.builtin() == spv::BuiltIn::ClipDistance) ? 4188 : 4197;
|
||||
id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind(
|
||||
&BuiltInsValidator::ValidateNotCalledWithExecutionModel, this, vuid,
|
||||
"Vulkan spec doesn't allow BuiltIn ClipDistance/CullDistance to be "
|
||||
@ -1247,7 +1249,8 @@ spv_result_t BuiltInsValidator::ValidateClipOrCullDistanceAtReference(
|
||||
|
||||
if (storage_class == spv::StorageClass::Output) {
|
||||
assert(function_id_ == 0);
|
||||
uint32_t vuid = (spv::BuiltIn(decoration.params()[0]) == spv::BuiltIn::ClipDistance) ? 4189 : 4198;
|
||||
uint32_t vuid =
|
||||
(decoration.builtin() == spv::BuiltIn::ClipDistance) ? 4189 : 4198;
|
||||
id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind(
|
||||
&BuiltInsValidator::ValidateNotCalledWithExecutionModel, this, vuid,
|
||||
"Vulkan spec doesn't allow BuiltIn ClipDistance/CullDistance to be "
|
||||
@ -1266,7 +1269,7 @@ spv_result_t BuiltInsValidator::ValidateClipOrCullDistanceAtReference(
|
||||
[this, &decoration, &referenced_from_inst](
|
||||
const std::string& message) -> spv_result_t {
|
||||
uint32_t vuid =
|
||||
(spv::BuiltIn(decoration.params()[0]) == spv::BuiltIn::ClipDistance)
|
||||
(decoration.builtin() == spv::BuiltIn::ClipDistance)
|
||||
? 4191
|
||||
: 4200;
|
||||
return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst)
|
||||
@ -1274,7 +1277,7 @@ spv_result_t BuiltInsValidator::ValidateClipOrCullDistanceAtReference(
|
||||
<< "According to the Vulkan spec BuiltIn "
|
||||
<< _.grammar().lookupOperandName(
|
||||
SPV_OPERAND_TYPE_BUILT_IN,
|
||||
decoration.params()[0])
|
||||
(uint32_t)decoration.builtin())
|
||||
<< " variable needs to be a 32-bit float array. "
|
||||
<< message;
|
||||
})) {
|
||||
@ -1294,7 +1297,7 @@ spv_result_t BuiltInsValidator::ValidateClipOrCullDistanceAtReference(
|
||||
[this, &decoration, &referenced_from_inst](
|
||||
const std::string& message) -> spv_result_t {
|
||||
uint32_t vuid =
|
||||
(spv::BuiltIn(decoration.params()[0]) == spv::BuiltIn::ClipDistance)
|
||||
(decoration.builtin() == spv::BuiltIn::ClipDistance)
|
||||
? 4191
|
||||
: 4200;
|
||||
return _.diag(SPV_ERROR_INVALID_DATA,
|
||||
@ -1303,7 +1306,7 @@ spv_result_t BuiltInsValidator::ValidateClipOrCullDistanceAtReference(
|
||||
<< "According to the Vulkan spec BuiltIn "
|
||||
<< _.grammar().lookupOperandName(
|
||||
SPV_OPERAND_TYPE_BUILT_IN,
|
||||
decoration.params()[0])
|
||||
(uint32_t)decoration.builtin())
|
||||
<< " variable needs to be a 32-bit float array. "
|
||||
<< message;
|
||||
})) {
|
||||
@ -1315,7 +1318,7 @@ spv_result_t BuiltInsValidator::ValidateClipOrCullDistanceAtReference(
|
||||
[this, &decoration, &referenced_from_inst](
|
||||
const std::string& message) -> spv_result_t {
|
||||
uint32_t vuid =
|
||||
(spv::BuiltIn(decoration.params()[0]) == spv::BuiltIn::ClipDistance)
|
||||
(decoration.builtin() == spv::BuiltIn::ClipDistance)
|
||||
? 4191
|
||||
: 4200;
|
||||
return _.diag(SPV_ERROR_INVALID_DATA,
|
||||
@ -1324,7 +1327,7 @@ spv_result_t BuiltInsValidator::ValidateClipOrCullDistanceAtReference(
|
||||
<< "According to the Vulkan spec BuiltIn "
|
||||
<< _.grammar().lookupOperandName(
|
||||
SPV_OPERAND_TYPE_BUILT_IN,
|
||||
decoration.params()[0])
|
||||
(uint32_t)decoration.builtin())
|
||||
<< " variable needs to be a 32-bit float array. "
|
||||
<< message;
|
||||
})) {
|
||||
@ -1335,8 +1338,9 @@ spv_result_t BuiltInsValidator::ValidateClipOrCullDistanceAtReference(
|
||||
}
|
||||
|
||||
default: {
|
||||
uint32_t vuid =
|
||||
(spv::BuiltIn(decoration.params()[0]) == spv::BuiltIn::ClipDistance) ? 4187 : 4196;
|
||||
uint32_t vuid = (decoration.builtin() == spv::BuiltIn::ClipDistance)
|
||||
? 4187
|
||||
: 4196;
|
||||
return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst)
|
||||
<< _.VkErrorID(vuid) << "Vulkan spec allows BuiltIn "
|
||||
<< _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN,
|
||||
@ -2542,7 +2546,7 @@ spv_result_t BuiltInsValidator::ValidateTessLevelAtReference(
|
||||
const Decoration& decoration, const Instruction& built_in_inst,
|
||||
const Instruction& referenced_inst,
|
||||
const Instruction& referenced_from_inst) {
|
||||
uint32_t operand = decoration.params()[0];
|
||||
uint32_t operand = (uint32_t)decoration.builtin();
|
||||
if (spvIsVulkanEnv(_.context()->target_env)) {
|
||||
const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst);
|
||||
if (storage_class != spv::StorageClass::Max &&
|
||||
@ -2561,7 +2565,8 @@ spv_result_t BuiltInsValidator::ValidateTessLevelAtReference(
|
||||
|
||||
if (storage_class == spv::StorageClass::Input) {
|
||||
assert(function_id_ == 0);
|
||||
uint32_t vuid = (spv::BuiltIn(decoration.params()[0]) == spv::BuiltIn::TessLevelOuter) ? 4391 : 4395;
|
||||
uint32_t vuid =
|
||||
(decoration.builtin() == spv::BuiltIn::TessLevelOuter) ? 4391 : 4395;
|
||||
id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind(
|
||||
&BuiltInsValidator::ValidateNotCalledWithExecutionModel, this, vuid,
|
||||
"Vulkan spec doesn't allow TessLevelOuter/TessLevelInner to be "
|
||||
@ -2574,7 +2579,8 @@ spv_result_t BuiltInsValidator::ValidateTessLevelAtReference(
|
||||
|
||||
if (storage_class == spv::StorageClass::Output) {
|
||||
assert(function_id_ == 0);
|
||||
uint32_t vuid = (spv::BuiltIn(decoration.params()[0]) == spv::BuiltIn::TessLevelOuter) ? 4392 : 4396;
|
||||
uint32_t vuid =
|
||||
(decoration.builtin() == spv::BuiltIn::TessLevelOuter) ? 4392 : 4396;
|
||||
id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind(
|
||||
&BuiltInsValidator::ValidateNotCalledWithExecutionModel, this, vuid,
|
||||
"Vulkan spec doesn't allow TessLevelOuter/TessLevelInner to be "
|
||||
@ -2724,12 +2730,13 @@ spv_result_t BuiltInsValidator::ValidateLayerOrViewportIndexAtDefinition(
|
||||
[this, &decoration,
|
||||
&inst](const std::string& message) -> spv_result_t {
|
||||
uint32_t vuid =
|
||||
(spv::BuiltIn(decoration.params()[0]) == spv::BuiltIn::Layer) ? 4276 : 4408;
|
||||
(decoration.builtin() == spv::BuiltIn::Layer) ? 4276 : 4408;
|
||||
return _.diag(SPV_ERROR_INVALID_DATA, &inst)
|
||||
<< _.VkErrorID(vuid)
|
||||
<< "According to the Vulkan spec BuiltIn "
|
||||
<< _.grammar().lookupOperandName(
|
||||
SPV_OPERAND_TYPE_BUILT_IN, decoration.params()[0])
|
||||
SPV_OPERAND_TYPE_BUILT_IN,
|
||||
(uint32_t)decoration.builtin())
|
||||
<< "variable needs to be a 32-bit int scalar. "
|
||||
<< message;
|
||||
})) {
|
||||
@ -2741,12 +2748,13 @@ spv_result_t BuiltInsValidator::ValidateLayerOrViewportIndexAtDefinition(
|
||||
[this, &decoration,
|
||||
&inst](const std::string& message) -> spv_result_t {
|
||||
uint32_t vuid =
|
||||
(spv::BuiltIn(decoration.params()[0]) == spv::BuiltIn::Layer) ? 4276 : 4408;
|
||||
(decoration.builtin() == spv::BuiltIn::Layer) ? 4276 : 4408;
|
||||
return _.diag(SPV_ERROR_INVALID_DATA, &inst)
|
||||
<< _.VkErrorID(vuid)
|
||||
<< "According to the Vulkan spec BuiltIn "
|
||||
<< _.grammar().lookupOperandName(
|
||||
SPV_OPERAND_TYPE_BUILT_IN, decoration.params()[0])
|
||||
SPV_OPERAND_TYPE_BUILT_IN,
|
||||
(uint32_t)decoration.builtin())
|
||||
<< "variable needs to be a 32-bit int scalar. "
|
||||
<< message;
|
||||
})) {
|
||||
@ -2763,7 +2771,7 @@ spv_result_t BuiltInsValidator::ValidateLayerOrViewportIndexAtReference(
|
||||
const Decoration& decoration, const Instruction& built_in_inst,
|
||||
const Instruction& referenced_inst,
|
||||
const Instruction& referenced_from_inst) {
|
||||
uint32_t operand = decoration.params()[0];
|
||||
uint32_t operand = (uint32_t)decoration.builtin();
|
||||
if (spvIsVulkanEnv(_.context()->target_env)) {
|
||||
const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst);
|
||||
if (storage_class != spv::StorageClass::Max &&
|
||||
@ -2877,7 +2885,7 @@ spv_result_t BuiltInsValidator::ValidateLayerOrViewportIndexAtReference(
|
||||
spv_result_t BuiltInsValidator::ValidateFragmentShaderF32Vec3InputAtDefinition(
|
||||
const Decoration& decoration, const Instruction& inst) {
|
||||
if (spvIsVulkanEnv(_.context()->target_env)) {
|
||||
const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]);
|
||||
const spv::BuiltIn builtin = decoration.builtin();
|
||||
if (spv_result_t error = ValidateF32Vec(
|
||||
decoration, inst, 3,
|
||||
[this, &inst, builtin](const std::string& message) -> spv_result_t {
|
||||
@ -2907,7 +2915,7 @@ spv_result_t BuiltInsValidator::ValidateFragmentShaderF32Vec3InputAtReference(
|
||||
const Instruction& referenced_from_inst) {
|
||||
|
||||
if (spvIsVulkanEnv(_.context()->target_env)) {
|
||||
const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]);
|
||||
const spv::BuiltIn builtin = decoration.builtin();
|
||||
const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst);
|
||||
if (storage_class != spv::StorageClass::Max &&
|
||||
storage_class != spv::StorageClass::Input) {
|
||||
@ -2951,7 +2959,7 @@ spv_result_t BuiltInsValidator::ValidateFragmentShaderF32Vec3InputAtReference(
|
||||
spv_result_t BuiltInsValidator::ValidateComputeShaderI32Vec3InputAtDefinition(
|
||||
const Decoration& decoration, const Instruction& inst) {
|
||||
if (spvIsVulkanEnv(_.context()->target_env)) {
|
||||
const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]);
|
||||
const spv::BuiltIn builtin = decoration.builtin();
|
||||
if (spv_result_t error = ValidateI32Vec(
|
||||
decoration, inst, 3,
|
||||
[this, &inst, builtin](const std::string& message) -> spv_result_t {
|
||||
@ -2980,7 +2988,7 @@ spv_result_t BuiltInsValidator::ValidateComputeShaderI32Vec3InputAtReference(
|
||||
const Instruction& referenced_inst,
|
||||
const Instruction& referenced_from_inst) {
|
||||
if (spvIsVulkanEnv(_.context()->target_env)) {
|
||||
const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]);
|
||||
const spv::BuiltIn builtin = decoration.builtin();
|
||||
const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst);
|
||||
if (storage_class != spv::StorageClass::Max &&
|
||||
storage_class != spv::StorageClass::Input) {
|
||||
@ -3031,7 +3039,7 @@ spv_result_t BuiltInsValidator::ValidateComputeShaderI32Vec3InputAtReference(
|
||||
spv_result_t BuiltInsValidator::ValidateComputeI32InputAtDefinition(
|
||||
const Decoration& decoration, const Instruction& inst) {
|
||||
if (spvIsVulkanEnv(_.context()->target_env)) {
|
||||
const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]);
|
||||
const spv::BuiltIn builtin = decoration.builtin();
|
||||
if (decoration.struct_member_index() != Decoration::kInvalidMember) {
|
||||
return _.diag(SPV_ERROR_INVALID_DATA, &inst)
|
||||
<< "BuiltIn "
|
||||
@ -3065,7 +3073,7 @@ spv_result_t BuiltInsValidator::ValidateComputeI32InputAtReference(
|
||||
const Instruction& referenced_inst,
|
||||
const Instruction& referenced_from_inst) {
|
||||
if (spvIsVulkanEnv(_.context()->target_env)) {
|
||||
const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]);
|
||||
const spv::BuiltIn builtin = decoration.builtin();
|
||||
const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst);
|
||||
if (storage_class != spv::StorageClass::Max &&
|
||||
storage_class != spv::StorageClass::Input) {
|
||||
@ -3116,7 +3124,7 @@ spv_result_t BuiltInsValidator::ValidateComputeI32InputAtReference(
|
||||
spv_result_t BuiltInsValidator::ValidateI32InputAtDefinition(
|
||||
const Decoration& decoration, const Instruction& inst) {
|
||||
if (spvIsVulkanEnv(_.context()->target_env)) {
|
||||
const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]);
|
||||
const spv::BuiltIn builtin = decoration.builtin();
|
||||
if (decoration.struct_member_index() != Decoration::kInvalidMember) {
|
||||
return _.diag(SPV_ERROR_INVALID_DATA, &inst)
|
||||
<< "BuiltIn "
|
||||
@ -3159,7 +3167,7 @@ spv_result_t BuiltInsValidator::ValidateI32InputAtDefinition(
|
||||
spv_result_t BuiltInsValidator::ValidateI32Vec4InputAtDefinition(
|
||||
const Decoration& decoration, const Instruction& inst) {
|
||||
if (spvIsVulkanEnv(_.context()->target_env)) {
|
||||
const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]);
|
||||
const spv::BuiltIn builtin = decoration.builtin();
|
||||
if (decoration.struct_member_index() != Decoration::kInvalidMember) {
|
||||
return _.diag(SPV_ERROR_INVALID_DATA, &inst)
|
||||
<< "BuiltIn "
|
||||
@ -3247,7 +3255,7 @@ spv_result_t BuiltInsValidator::ValidateWorkgroupSizeAtReference(
|
||||
<< spvLogStringForEnv(_.context()->target_env)
|
||||
<< " spec allows BuiltIn "
|
||||
<< _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN,
|
||||
decoration.params()[0])
|
||||
(uint32_t)decoration.builtin())
|
||||
<< " to be used only with GLCompute, MeshNV, TaskNV, MeshEXT or "
|
||||
<< "TaskEXT execution model. "
|
||||
<< GetReferenceDesc(decoration, built_in_inst, referenced_inst,
|
||||
@ -3273,14 +3281,15 @@ spv_result_t BuiltInsValidator::ValidateBaseInstanceOrVertexAtDefinition(
|
||||
decoration, inst,
|
||||
[this, &inst,
|
||||
&decoration](const std::string& message) -> spv_result_t {
|
||||
uint32_t vuid = (spv::BuiltIn(decoration.params()[0]) == spv::BuiltIn::BaseInstance)
|
||||
? 4183
|
||||
: 4186;
|
||||
uint32_t vuid =
|
||||
(decoration.builtin() == spv::BuiltIn::BaseInstance) ? 4183
|
||||
: 4186;
|
||||
return _.diag(SPV_ERROR_INVALID_DATA, &inst)
|
||||
<< _.VkErrorID(vuid)
|
||||
<< "According to the Vulkan spec BuiltIn "
|
||||
<< _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN,
|
||||
decoration.params()[0])
|
||||
<< _.grammar().lookupOperandName(
|
||||
SPV_OPERAND_TYPE_BUILT_IN,
|
||||
(uint32_t)decoration.builtin())
|
||||
<< " variable needs to be a 32-bit int scalar. "
|
||||
<< message;
|
||||
})) {
|
||||
@ -3295,7 +3304,7 @@ spv_result_t BuiltInsValidator::ValidateBaseInstanceOrVertexAtReference(
|
||||
const Decoration& decoration, const Instruction& built_in_inst,
|
||||
const Instruction& referenced_inst,
|
||||
const Instruction& referenced_from_inst) {
|
||||
uint32_t operand = decoration.params()[0];
|
||||
uint32_t operand = (uint32_t)decoration.builtin();
|
||||
if (spvIsVulkanEnv(_.context()->target_env)) {
|
||||
const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst);
|
||||
if (storage_class != spv::StorageClass::Max &&
|
||||
@ -3346,8 +3355,9 @@ spv_result_t BuiltInsValidator::ValidateDrawIndexAtDefinition(
|
||||
return _.diag(SPV_ERROR_INVALID_DATA, &inst)
|
||||
<< _.VkErrorID(4209)
|
||||
<< "According to the Vulkan spec BuiltIn "
|
||||
<< _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN,
|
||||
decoration.params()[0])
|
||||
<< _.grammar().lookupOperandName(
|
||||
SPV_OPERAND_TYPE_BUILT_IN,
|
||||
(uint32_t)decoration.builtin())
|
||||
<< " variable needs to be a 32-bit int scalar. "
|
||||
<< message;
|
||||
})) {
|
||||
@ -3362,7 +3372,7 @@ spv_result_t BuiltInsValidator::ValidateDrawIndexAtReference(
|
||||
const Decoration& decoration, const Instruction& built_in_inst,
|
||||
const Instruction& referenced_inst,
|
||||
const Instruction& referenced_from_inst) {
|
||||
uint32_t operand = decoration.params()[0];
|
||||
uint32_t operand = (uint32_t)decoration.builtin();
|
||||
if (spvIsVulkanEnv(_.context()->target_env)) {
|
||||
const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst);
|
||||
if (storage_class != spv::StorageClass::Max &&
|
||||
@ -3416,8 +3426,9 @@ spv_result_t BuiltInsValidator::ValidateViewIndexAtDefinition(
|
||||
return _.diag(SPV_ERROR_INVALID_DATA, &inst)
|
||||
<< _.VkErrorID(4403)
|
||||
<< "According to the Vulkan spec BuiltIn "
|
||||
<< _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN,
|
||||
decoration.params()[0])
|
||||
<< _.grammar().lookupOperandName(
|
||||
SPV_OPERAND_TYPE_BUILT_IN,
|
||||
(uint32_t)decoration.builtin())
|
||||
<< " variable needs to be a 32-bit int scalar. "
|
||||
<< message;
|
||||
})) {
|
||||
@ -3432,7 +3443,7 @@ spv_result_t BuiltInsValidator::ValidateViewIndexAtReference(
|
||||
const Decoration& decoration, const Instruction& built_in_inst,
|
||||
const Instruction& referenced_inst,
|
||||
const Instruction& referenced_from_inst) {
|
||||
uint32_t operand = decoration.params()[0];
|
||||
uint32_t operand = (uint32_t)decoration.builtin();
|
||||
if (spvIsVulkanEnv(_.context()->target_env)) {
|
||||
const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst);
|
||||
if (storage_class != spv::StorageClass::Max &&
|
||||
@ -3480,8 +3491,9 @@ spv_result_t BuiltInsValidator::ValidateDeviceIndexAtDefinition(
|
||||
return _.diag(SPV_ERROR_INVALID_DATA, &inst)
|
||||
<< _.VkErrorID(4206)
|
||||
<< "According to the Vulkan spec BuiltIn "
|
||||
<< _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN,
|
||||
decoration.params()[0])
|
||||
<< _.grammar().lookupOperandName(
|
||||
SPV_OPERAND_TYPE_BUILT_IN,
|
||||
(uint32_t)decoration.builtin())
|
||||
<< " variable needs to be a 32-bit int scalar. "
|
||||
<< message;
|
||||
})) {
|
||||
@ -3496,7 +3508,7 @@ spv_result_t BuiltInsValidator::ValidateDeviceIndexAtReference(
|
||||
const Decoration& decoration, const Instruction& built_in_inst,
|
||||
const Instruction& referenced_inst,
|
||||
const Instruction& referenced_from_inst) {
|
||||
uint32_t operand = decoration.params()[0];
|
||||
uint32_t operand = (uint32_t)decoration.builtin();
|
||||
if (spvIsVulkanEnv(_.context()->target_env)) {
|
||||
const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst);
|
||||
if (storage_class != spv::StorageClass::Max &&
|
||||
@ -3526,7 +3538,7 @@ spv_result_t BuiltInsValidator::ValidateFragInvocationCountAtDefinition(const De
|
||||
const Instruction& inst) {
|
||||
|
||||
if (spvIsVulkanEnv(_.context()->target_env)) {
|
||||
const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]);
|
||||
const spv::BuiltIn builtin = decoration.builtin();
|
||||
if (spv_result_t error = ValidateI32(
|
||||
decoration, inst,
|
||||
[this, &inst, &builtin](const std::string& message) -> spv_result_t {
|
||||
@ -3553,7 +3565,7 @@ spv_result_t BuiltInsValidator::ValidateFragInvocationCountAtReference(
|
||||
const Instruction& referenced_from_inst) {
|
||||
|
||||
if (spvIsVulkanEnv(_.context()->target_env)) {
|
||||
const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]);
|
||||
const spv::BuiltIn builtin = decoration.builtin();
|
||||
const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst);
|
||||
if (storage_class != spv::StorageClass::Max &&
|
||||
storage_class != spv::StorageClass::Input) {
|
||||
@ -3596,7 +3608,7 @@ spv_result_t BuiltInsValidator::ValidateFragInvocationCountAtReference(
|
||||
spv_result_t BuiltInsValidator::ValidateFragSizeAtDefinition(const Decoration& decoration,
|
||||
const Instruction& inst) {
|
||||
if (spvIsVulkanEnv(_.context()->target_env)) {
|
||||
const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]);
|
||||
const spv::BuiltIn builtin = decoration.builtin();
|
||||
if (spv_result_t error = ValidateI32Vec(
|
||||
decoration, inst, 2,
|
||||
[this, &inst, &builtin](const std::string& message) -> spv_result_t {
|
||||
@ -3623,7 +3635,7 @@ spv_result_t BuiltInsValidator::ValidateFragSizeAtReference(
|
||||
const Instruction& referenced_from_inst) {
|
||||
|
||||
if (spvIsVulkanEnv(_.context()->target_env)) {
|
||||
const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]);
|
||||
const spv::BuiltIn builtin = decoration.builtin();
|
||||
const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst);
|
||||
if (storage_class != spv::StorageClass::Max &&
|
||||
storage_class != spv::StorageClass::Input) {
|
||||
@ -3666,7 +3678,7 @@ spv_result_t BuiltInsValidator::ValidateFragSizeAtReference(
|
||||
spv_result_t BuiltInsValidator::ValidateFragStencilRefAtDefinition(const Decoration& decoration,
|
||||
const Instruction& inst) {
|
||||
if (spvIsVulkanEnv(_.context()->target_env)) {
|
||||
const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]);
|
||||
const spv::BuiltIn builtin = decoration.builtin();
|
||||
if (spv_result_t error = ValidateI(
|
||||
decoration, inst,
|
||||
[this, &inst, &builtin](const std::string& message) -> spv_result_t {
|
||||
@ -3693,7 +3705,7 @@ spv_result_t BuiltInsValidator::ValidateFragStencilRefAtReference(
|
||||
const Instruction& referenced_from_inst) {
|
||||
|
||||
if (spvIsVulkanEnv(_.context()->target_env)) {
|
||||
const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]);
|
||||
const spv::BuiltIn builtin = decoration.builtin();
|
||||
const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst);
|
||||
if (storage_class != spv::StorageClass::Max &&
|
||||
storage_class != spv::StorageClass::Output) {
|
||||
@ -3736,7 +3748,7 @@ spv_result_t BuiltInsValidator::ValidateFragStencilRefAtReference(
|
||||
spv_result_t BuiltInsValidator::ValidateFullyCoveredAtDefinition(const Decoration& decoration,
|
||||
const Instruction& inst) {
|
||||
if (spvIsVulkanEnv(_.context()->target_env)) {
|
||||
const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]);
|
||||
const spv::BuiltIn builtin = decoration.builtin();
|
||||
if (spv_result_t error = ValidateBool(
|
||||
decoration, inst,
|
||||
[this, &inst, &builtin](const std::string& message) -> spv_result_t {
|
||||
@ -3763,7 +3775,7 @@ spv_result_t BuiltInsValidator::ValidateFullyCoveredAtReference(
|
||||
const Instruction& referenced_from_inst) {
|
||||
|
||||
if (spvIsVulkanEnv(_.context()->target_env)) {
|
||||
const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]);
|
||||
const spv::BuiltIn builtin = decoration.builtin();
|
||||
const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst);
|
||||
if (storage_class != spv::StorageClass::Max &&
|
||||
storage_class != spv::StorageClass::Input) {
|
||||
@ -3814,8 +3826,9 @@ spv_result_t BuiltInsValidator::ValidateNVSMOrARMCoreBuiltinsAtDefinition(
|
||||
<< "According to the "
|
||||
<< spvLogStringForEnv(_.context()->target_env)
|
||||
<< " spec BuiltIn "
|
||||
<< _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN,
|
||||
decoration.params()[0])
|
||||
<< _.grammar().lookupOperandName(
|
||||
SPV_OPERAND_TYPE_BUILT_IN,
|
||||
(uint32_t)decoration.builtin())
|
||||
<< " variable needs to be a 32-bit int scalar. "
|
||||
<< message;
|
||||
})) {
|
||||
@ -3839,7 +3852,7 @@ spv_result_t BuiltInsValidator::ValidateNVSMOrARMCoreBuiltinsAtReference(
|
||||
<< spvLogStringForEnv(_.context()->target_env)
|
||||
<< " spec allows BuiltIn "
|
||||
<< _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN,
|
||||
decoration.params()[0])
|
||||
(uint32_t)decoration.builtin())
|
||||
<< " to be only used for "
|
||||
"variables with Input storage class. "
|
||||
<< GetReferenceDesc(decoration, built_in_inst, referenced_inst,
|
||||
@ -3868,8 +3881,9 @@ spv_result_t BuiltInsValidator::ValidatePrimitiveShadingRateAtDefinition(
|
||||
return _.diag(SPV_ERROR_INVALID_DATA, &inst)
|
||||
<< _.VkErrorID(4486)
|
||||
<< "According to the Vulkan spec BuiltIn "
|
||||
<< _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN,
|
||||
decoration.params()[0])
|
||||
<< _.grammar().lookupOperandName(
|
||||
SPV_OPERAND_TYPE_BUILT_IN,
|
||||
(uint32_t)decoration.builtin())
|
||||
<< " variable needs to be a 32-bit int scalar. "
|
||||
<< message;
|
||||
})) {
|
||||
@ -3892,7 +3906,7 @@ spv_result_t BuiltInsValidator::ValidatePrimitiveShadingRateAtReference(
|
||||
return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst)
|
||||
<< _.VkErrorID(4485) << "Vulkan spec allows BuiltIn "
|
||||
<< _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN,
|
||||
decoration.params()[0])
|
||||
(uint32_t)decoration.builtin())
|
||||
<< " to be only used for variables with Output storage class. "
|
||||
<< GetReferenceDesc(decoration, built_in_inst, referenced_inst,
|
||||
referenced_from_inst)
|
||||
@ -3909,8 +3923,9 @@ spv_result_t BuiltInsValidator::ValidatePrimitiveShadingRateAtReference(
|
||||
default: {
|
||||
return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst)
|
||||
<< _.VkErrorID(4484) << "Vulkan spec allows BuiltIn "
|
||||
<< _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN,
|
||||
decoration.params()[0])
|
||||
<< _.grammar().lookupOperandName(
|
||||
SPV_OPERAND_TYPE_BUILT_IN,
|
||||
(uint32_t)decoration.builtin())
|
||||
<< " to be used only with Vertex, Geometry, or MeshNV "
|
||||
"execution models. "
|
||||
<< GetReferenceDesc(decoration, built_in_inst, referenced_inst,
|
||||
@ -3941,8 +3956,9 @@ spv_result_t BuiltInsValidator::ValidateShadingRateAtDefinition(
|
||||
return _.diag(SPV_ERROR_INVALID_DATA, &inst)
|
||||
<< _.VkErrorID(4492)
|
||||
<< "According to the Vulkan spec BuiltIn "
|
||||
<< _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN,
|
||||
decoration.params()[0])
|
||||
<< _.grammar().lookupOperandName(
|
||||
SPV_OPERAND_TYPE_BUILT_IN,
|
||||
(uint32_t)decoration.builtin())
|
||||
<< " variable needs to be a 32-bit int scalar. "
|
||||
<< message;
|
||||
})) {
|
||||
@ -3965,7 +3981,7 @@ spv_result_t BuiltInsValidator::ValidateShadingRateAtReference(
|
||||
return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst)
|
||||
<< _.VkErrorID(4491) << "Vulkan spec allows BuiltIn "
|
||||
<< _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN,
|
||||
decoration.params()[0])
|
||||
(uint32_t)decoration.builtin())
|
||||
<< " to be only used for variables with Input storage class. "
|
||||
<< GetReferenceDesc(decoration, built_in_inst, referenced_inst,
|
||||
referenced_from_inst)
|
||||
@ -3977,7 +3993,7 @@ spv_result_t BuiltInsValidator::ValidateShadingRateAtReference(
|
||||
return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst)
|
||||
<< _.VkErrorID(4490) << "Vulkan spec allows BuiltIn "
|
||||
<< _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN,
|
||||
decoration.params()[0])
|
||||
(uint32_t)decoration.builtin())
|
||||
<< " to be used only with the Fragment execution model. "
|
||||
<< GetReferenceDesc(decoration, built_in_inst, referenced_inst,
|
||||
referenced_from_inst, execution_model);
|
||||
@ -3998,7 +4014,7 @@ spv_result_t BuiltInsValidator::ValidateShadingRateAtReference(
|
||||
spv_result_t BuiltInsValidator::ValidateRayTracingBuiltinsAtDefinition(
|
||||
const Decoration& decoration, const Instruction& inst) {
|
||||
if (spvIsVulkanEnv(_.context()->target_env)) {
|
||||
const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]);
|
||||
const spv::BuiltIn builtin = decoration.builtin();
|
||||
switch (builtin) {
|
||||
case spv::BuiltIn::HitTNV:
|
||||
case spv::BuiltIn::RayTminKHR:
|
||||
@ -4121,7 +4137,7 @@ spv_result_t BuiltInsValidator::ValidateRayTracingBuiltinsAtReference(
|
||||
const Instruction& referenced_inst,
|
||||
const Instruction& referenced_from_inst) {
|
||||
if (spvIsVulkanEnv(_.context()->target_env)) {
|
||||
const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]);
|
||||
const spv::BuiltIn builtin = decoration.builtin();
|
||||
const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst);
|
||||
if (storage_class != spv::StorageClass::Max &&
|
||||
storage_class != spv::StorageClass::Input) {
|
||||
@ -4129,7 +4145,7 @@ spv_result_t BuiltInsValidator::ValidateRayTracingBuiltinsAtReference(
|
||||
return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst)
|
||||
<< _.VkErrorID(vuid) << "Vulkan spec allows BuiltIn "
|
||||
<< _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN,
|
||||
decoration.params()[0])
|
||||
(uint32_t)decoration.builtin())
|
||||
<< " to be only used for variables with Input storage class. "
|
||||
<< GetReferenceDesc(decoration, built_in_inst, referenced_inst,
|
||||
referenced_from_inst)
|
||||
@ -4142,10 +4158,11 @@ spv_result_t BuiltInsValidator::ValidateRayTracingBuiltinsAtReference(
|
||||
return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst)
|
||||
<< _.VkErrorID(vuid) << "Vulkan spec does not allow BuiltIn "
|
||||
<< _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN,
|
||||
decoration.params()[0])
|
||||
(uint32_t)decoration.builtin())
|
||||
<< " to be used with the execution model "
|
||||
<< _.grammar().lookupOperandName(
|
||||
SPV_OPERAND_TYPE_EXECUTION_MODEL, uint32_t(execution_model))
|
||||
SPV_OPERAND_TYPE_EXECUTION_MODEL,
|
||||
uint32_t(execution_model))
|
||||
<< ".\n"
|
||||
<< GetReferenceDesc(decoration, built_in_inst, referenced_inst,
|
||||
referenced_from_inst, execution_model);
|
||||
@ -4167,7 +4184,7 @@ spv_result_t BuiltInsValidator::ValidateRayTracingBuiltinsAtReference(
|
||||
spv_result_t BuiltInsValidator::ValidateMeshShadingEXTBuiltinsAtDefinition(
|
||||
const Decoration& decoration, const Instruction& inst) {
|
||||
if (spvIsVulkanEnv(_.context()->target_env)) {
|
||||
const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]);
|
||||
const spv::BuiltIn builtin = decoration.builtin();
|
||||
uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorType);
|
||||
if (builtin == spv::BuiltIn::PrimitivePointIndicesEXT) {
|
||||
if (spv_result_t error = ValidateI32Arr(
|
||||
@ -4179,7 +4196,8 @@ spv_result_t BuiltInsValidator::ValidateMeshShadingEXTBuiltinsAtDefinition(
|
||||
<< spvLogStringForEnv(_.context()->target_env)
|
||||
<< " spec BuiltIn "
|
||||
<< _.grammar().lookupOperandName(
|
||||
SPV_OPERAND_TYPE_BUILT_IN, decoration.params()[0])
|
||||
SPV_OPERAND_TYPE_BUILT_IN,
|
||||
(uint32_t)decoration.builtin())
|
||||
<< " variable needs to be a 32-bit int array."
|
||||
<< message;
|
||||
})) {
|
||||
@ -4196,7 +4214,8 @@ spv_result_t BuiltInsValidator::ValidateMeshShadingEXTBuiltinsAtDefinition(
|
||||
<< spvLogStringForEnv(_.context()->target_env)
|
||||
<< " spec BuiltIn "
|
||||
<< _.grammar().lookupOperandName(
|
||||
SPV_OPERAND_TYPE_BUILT_IN, decoration.params()[0])
|
||||
SPV_OPERAND_TYPE_BUILT_IN,
|
||||
(uint32_t)decoration.builtin())
|
||||
<< " variable needs to be a 2-component 32-bit int "
|
||||
"array."
|
||||
<< message;
|
||||
@ -4214,7 +4233,8 @@ spv_result_t BuiltInsValidator::ValidateMeshShadingEXTBuiltinsAtDefinition(
|
||||
<< spvLogStringForEnv(_.context()->target_env)
|
||||
<< " spec BuiltIn "
|
||||
<< _.grammar().lookupOperandName(
|
||||
SPV_OPERAND_TYPE_BUILT_IN, decoration.params()[0])
|
||||
SPV_OPERAND_TYPE_BUILT_IN,
|
||||
(uint32_t)decoration.builtin())
|
||||
<< " variable needs to be a 3-component 32-bit int "
|
||||
"array."
|
||||
<< message;
|
||||
@ -4233,7 +4253,7 @@ spv_result_t BuiltInsValidator::ValidateMeshShadingEXTBuiltinsAtReference(
|
||||
const Instruction& referenced_inst,
|
||||
const Instruction& referenced_from_inst) {
|
||||
if (spvIsVulkanEnv(_.context()->target_env)) {
|
||||
const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]);
|
||||
const spv::BuiltIn builtin = decoration.builtin();
|
||||
const spv::StorageClass storage_class =
|
||||
GetStorageClass(referenced_from_inst);
|
||||
if (storage_class != spv::StorageClass::Max &&
|
||||
@ -4279,7 +4299,7 @@ spv_result_t BuiltInsValidator::ValidateMeshShadingEXTBuiltinsAtReference(
|
||||
|
||||
spv_result_t BuiltInsValidator::ValidateSingleBuiltInAtDefinition(
|
||||
const Decoration& decoration, const Instruction& inst) {
|
||||
const spv::BuiltIn label = spv::BuiltIn(decoration.params()[0]);
|
||||
const spv::BuiltIn label = decoration.builtin();
|
||||
|
||||
if (!spvIsVulkanEnv(_.context()->target_env)) {
|
||||
// Early return. All currently implemented rules are based on Vulkan spec.
|
||||
|
@ -71,26 +71,6 @@ uint32_t GetArrayStride(uint32_t array_id, ValidationState_t& vstate) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Returns true if the given variable has a BuiltIn decoration.
|
||||
bool isBuiltInVar(uint32_t var_id, ValidationState_t& vstate) {
|
||||
const auto& decorations = vstate.id_decorations(var_id);
|
||||
return std::any_of(decorations.begin(), decorations.end(),
|
||||
[](const Decoration& d) {
|
||||
return spv::Decoration::BuiltIn == d.dec_type();
|
||||
});
|
||||
}
|
||||
|
||||
// Returns true if the given structure type has any members with BuiltIn
|
||||
// decoration.
|
||||
bool isBuiltInStruct(uint32_t struct_id, ValidationState_t& vstate) {
|
||||
const auto& decorations = vstate.id_decorations(struct_id);
|
||||
return std::any_of(
|
||||
decorations.begin(), decorations.end(), [](const Decoration& d) {
|
||||
return spv::Decoration::BuiltIn == d.dec_type() &&
|
||||
Decoration::kInvalidMember != d.struct_member_index();
|
||||
});
|
||||
}
|
||||
|
||||
// Returns true if the given structure type has a Block decoration.
|
||||
bool isBlock(uint32_t struct_id, ValidationState_t& vstate) {
|
||||
const auto& decorations = vstate.id_decorations(struct_id);
|
||||
@ -786,6 +766,8 @@ spv_result_t CheckDecorationsOfEntryPoints(ValidationState_t& vstate) {
|
||||
int num_workgroup_variables_with_aliased = 0;
|
||||
for (const auto& desc : descs) {
|
||||
std::unordered_set<Instruction*> seen_vars;
|
||||
std::unordered_set<spv::BuiltIn> input_var_builtin;
|
||||
std::unordered_set<spv::BuiltIn> output_var_builtin;
|
||||
for (auto interface : desc.interfaces) {
|
||||
Instruction* var_instr = vstate.FindDef(interface);
|
||||
if (!var_instr || spv::Op::OpVariable != var_instr->opcode()) {
|
||||
@ -829,33 +811,70 @@ spv_result_t CheckDecorationsOfEntryPoints(ValidationState_t& vstate) {
|
||||
// to.
|
||||
const uint32_t type_id = ptr_instr->word(3);
|
||||
Instruction* type_instr = vstate.FindDef(type_id);
|
||||
if (type_instr && spv::Op::OpTypeStruct == type_instr->opcode() &&
|
||||
isBuiltInStruct(type_id, vstate)) {
|
||||
if (!isBlock(type_id, vstate)) {
|
||||
return vstate.diag(SPV_ERROR_INVALID_DATA, vstate.FindDef(type_id))
|
||||
<< vstate.VkErrorID(4919)
|
||||
<< "Interface struct has no Block decoration but has "
|
||||
"BuiltIn members. "
|
||||
"Location decorations must be used on each member of "
|
||||
"OpVariable with a structure type that is a block not "
|
||||
"decorated with Location.";
|
||||
const bool is_struct =
|
||||
type_instr && spv::Op::OpTypeStruct == type_instr->opcode();
|
||||
|
||||
// Search all Built-in (on the variable or the struct)
|
||||
bool has_built_in = false;
|
||||
for (auto& dec :
|
||||
vstate.id_decorations(is_struct ? type_id : interface)) {
|
||||
if (dec.dec_type() != spv::Decoration::BuiltIn) continue;
|
||||
has_built_in = true;
|
||||
|
||||
if (!spvIsVulkanEnv(vstate.context()->target_env)) continue;
|
||||
|
||||
const spv::BuiltIn builtin = dec.builtin();
|
||||
if (storage_class == spv::StorageClass::Input) {
|
||||
if (!input_var_builtin.insert(builtin).second) {
|
||||
return vstate.diag(SPV_ERROR_INVALID_ID, var_instr)
|
||||
<< vstate.VkErrorID(9658)
|
||||
<< "OpEntryPoint contains duplicate input variables "
|
||||
"with "
|
||||
<< vstate.grammar().lookupOperandName(
|
||||
SPV_OPERAND_TYPE_BUILT_IN, (uint32_t)builtin)
|
||||
<< " builtin";
|
||||
}
|
||||
}
|
||||
if (storage_class == spv::StorageClass::Input)
|
||||
++num_builtin_block_inputs;
|
||||
if (storage_class == spv::StorageClass::Output)
|
||||
++num_builtin_block_outputs;
|
||||
if (num_builtin_block_inputs > 1 || num_builtin_block_outputs > 1)
|
||||
break;
|
||||
if (auto error = CheckBuiltInVariable(interface, vstate))
|
||||
return error;
|
||||
} else if (isBuiltInVar(interface, vstate)) {
|
||||
if (storage_class == spv::StorageClass::Output) {
|
||||
if (!output_var_builtin.insert(builtin).second) {
|
||||
return vstate.diag(SPV_ERROR_INVALID_ID, var_instr)
|
||||
<< vstate.VkErrorID(9659)
|
||||
<< "OpEntryPoint contains duplicate output variables "
|
||||
"with "
|
||||
<< vstate.grammar().lookupOperandName(
|
||||
SPV_OPERAND_TYPE_BUILT_IN, (uint32_t)builtin)
|
||||
<< " builtin";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (has_built_in) {
|
||||
if (auto error = CheckBuiltInVariable(interface, vstate))
|
||||
return error;
|
||||
|
||||
if (is_struct) {
|
||||
if (!isBlock(type_id, vstate)) {
|
||||
return vstate.diag(SPV_ERROR_INVALID_DATA,
|
||||
vstate.FindDef(type_id))
|
||||
<< vstate.VkErrorID(4919)
|
||||
<< "Interface struct has no Block decoration but has "
|
||||
"BuiltIn members. "
|
||||
"Location decorations must be used on each member of "
|
||||
"OpVariable with a structure type that is a block not "
|
||||
"decorated with Location.";
|
||||
}
|
||||
if (storage_class == spv::StorageClass::Input)
|
||||
++num_builtin_block_inputs;
|
||||
if (storage_class == spv::StorageClass::Output)
|
||||
++num_builtin_block_outputs;
|
||||
if (num_builtin_block_inputs > 1 || num_builtin_block_outputs > 1)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (storage_class == spv::StorageClass::Workgroup) {
|
||||
++num_workgroup_variables;
|
||||
if (type_instr && spv::Op::OpTypeStruct == type_instr->opcode()) {
|
||||
if (is_struct) {
|
||||
if (hasDecoration(type_id, spv::Decoration::Block, vstate))
|
||||
++num_workgroup_variables_with_block;
|
||||
if (hasDecoration(var_instr->id(), spv::Decoration::Aliased,
|
||||
@ -1665,6 +1684,7 @@ spv_result_t CheckIntegerWrapDecoration(ValidationState_t& vstate,
|
||||
case spv::Op::OpSNegate:
|
||||
return SPV_SUCCESS;
|
||||
case spv::Op::OpExtInst:
|
||||
case spv::Op::OpExtInstWithForwardRefsKHR:
|
||||
// TODO(dneto): Only certain extended instructions allow these
|
||||
// decorations. For now allow anything.
|
||||
return SPV_SUCCESS;
|
||||
|
@ -147,7 +147,7 @@ bool DoesDebugInfoOperandMatchExpectation(
|
||||
const Instruction* inst, uint32_t word_index) {
|
||||
if (inst->words().size() <= word_index) return false;
|
||||
auto* debug_inst = _.FindDef(inst->word(word_index));
|
||||
if (debug_inst->opcode() != spv::Op::OpExtInst ||
|
||||
if (!spvIsExtendedInstruction(debug_inst->opcode()) ||
|
||||
(debug_inst->ext_inst_type() != SPV_EXT_INST_TYPE_OPENCL_DEBUGINFO_100 &&
|
||||
debug_inst->ext_inst_type() !=
|
||||
SPV_EXT_INST_TYPE_NONSEMANTIC_SHADER_DEBUGINFO_100) ||
|
||||
@ -165,7 +165,7 @@ bool DoesDebugInfoOperandMatchExpectation(
|
||||
const Instruction* inst, uint32_t word_index) {
|
||||
if (inst->words().size() <= word_index) return false;
|
||||
auto* debug_inst = _.FindDef(inst->word(word_index));
|
||||
if (debug_inst->opcode() != spv::Op::OpExtInst ||
|
||||
if (!spvIsExtendedInstruction(debug_inst->opcode()) ||
|
||||
(debug_inst->ext_inst_type() !=
|
||||
SPV_EXT_INST_TYPE_NONSEMANTIC_SHADER_DEBUGINFO_100) ||
|
||||
!expectation(
|
||||
@ -409,7 +409,7 @@ spv_result_t ValidateClspvReflectionArgumentInfo(ValidationState_t& _,
|
||||
spv_result_t ValidateKernelDecl(ValidationState_t& _, const Instruction* inst) {
|
||||
const auto decl_id = inst->GetOperandAs<uint32_t>(4);
|
||||
const auto decl = _.FindDef(decl_id);
|
||||
if (!decl || decl->opcode() != spv::Op::OpExtInst) {
|
||||
if (!decl || !spvIsExtendedInstruction(decl->opcode())) {
|
||||
return _.diag(SPV_ERROR_INVALID_ID, inst)
|
||||
<< "Kernel must be a Kernel extended instruction";
|
||||
}
|
||||
@ -432,7 +432,7 @@ spv_result_t ValidateKernelDecl(ValidationState_t& _, const Instruction* inst) {
|
||||
spv_result_t ValidateArgInfo(ValidationState_t& _, const Instruction* inst,
|
||||
uint32_t info_index) {
|
||||
auto info = _.FindDef(inst->GetOperandAs<uint32_t>(info_index));
|
||||
if (!info || info->opcode() != spv::Op::OpExtInst) {
|
||||
if (!info || !spvIsExtendedInstruction(info->opcode())) {
|
||||
return _.diag(SPV_ERROR_INVALID_ID, inst)
|
||||
<< "ArgInfo must be an ArgumentInfo extended instruction";
|
||||
}
|
||||
@ -3706,7 +3706,7 @@ spv_result_t ExtensionPass(ValidationState_t& _, const Instruction* inst) {
|
||||
const spv::Op opcode = inst->opcode();
|
||||
if (opcode == spv::Op::OpExtension) return ValidateExtension(_, inst);
|
||||
if (opcode == spv::Op::OpExtInstImport) return ValidateExtInstImport(_, inst);
|
||||
if (opcode == spv::Op::OpExtInst) return ValidateExtInst(_, inst);
|
||||
if (spvIsExtendedInstruction(opcode)) return ValidateExtInst(_, inst);
|
||||
|
||||
return SPV_SUCCESS;
|
||||
}
|
||||
|
30
3rdparty/spirv-tools/source/val/validate_id.cpp
vendored
30
3rdparty/spirv-tools/source/val/validate_id.cpp
vendored
@ -120,15 +120,16 @@ spv_result_t CheckIdDefinitionDominateUse(ValidationState_t& _) {
|
||||
// instruction operand's ID can be forward referenced.
|
||||
spv_result_t IdPass(ValidationState_t& _, Instruction* inst) {
|
||||
auto can_have_forward_declared_ids =
|
||||
inst->opcode() == spv::Op::OpExtInst &&
|
||||
spvIsExtendedInstruction(inst->opcode()) &&
|
||||
spvExtInstIsDebugInfo(inst->ext_inst_type())
|
||||
? spvDbgInfoExtOperandCanBeForwardDeclaredFunction(
|
||||
inst->ext_inst_type(), inst->word(4))
|
||||
inst->opcode(), inst->ext_inst_type(), inst->word(4))
|
||||
: spvOperandCanBeForwardDeclaredFunction(inst->opcode());
|
||||
|
||||
// Keep track of a result id defined by this instruction. 0 means it
|
||||
// does not define an id.
|
||||
uint32_t result_id = 0;
|
||||
bool has_forward_declared_ids = false;
|
||||
|
||||
for (unsigned i = 0; i < inst->operands().size(); i++) {
|
||||
const spv_parsed_operand_t& operand = inst->operand(i);
|
||||
@ -177,6 +178,7 @@ spv_result_t IdPass(ValidationState_t& _, Instruction* inst) {
|
||||
!inst->IsNonSemantic() && !spvOpcodeIsDecoration(opcode) &&
|
||||
!spvOpcodeIsBranch(opcode) && opcode != spv::Op::OpPhi &&
|
||||
opcode != spv::Op::OpExtInst &&
|
||||
opcode != spv::Op::OpExtInstWithForwardRefsKHR &&
|
||||
opcode != spv::Op::OpExtInstImport &&
|
||||
opcode != spv::Op::OpSelectionMerge &&
|
||||
opcode != spv::Op::OpLoopMerge &&
|
||||
@ -200,6 +202,7 @@ spv_result_t IdPass(ValidationState_t& _, Instruction* inst) {
|
||||
ret = SPV_SUCCESS;
|
||||
}
|
||||
} else if (can_have_forward_declared_ids(i)) {
|
||||
has_forward_declared_ids = true;
|
||||
if (spvOpcodeGeneratesType(inst->opcode()) &&
|
||||
!_.IsForwardPointer(operand_word)) {
|
||||
ret = _.diag(SPV_ERROR_INVALID_ID, inst)
|
||||
@ -229,12 +232,35 @@ spv_result_t IdPass(ValidationState_t& _, Instruction* inst) {
|
||||
<< " has not been defined";
|
||||
}
|
||||
break;
|
||||
case SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER:
|
||||
// Ideally, this check would live in validate_extensions.cpp. But since
|
||||
// forward references are only allowed on non-semantic instructions, and
|
||||
// ID validation is done first, we would fail with a "ID had not been
|
||||
// defined" error before we could give a more helpful message. For this
|
||||
// reason, this test is done here, so we can be more helpful to the
|
||||
// user.
|
||||
if (inst->opcode() == spv::Op::OpExtInstWithForwardRefsKHR &&
|
||||
!inst->IsNonSemantic())
|
||||
return _.diag(SPV_ERROR_INVALID_DATA, inst)
|
||||
<< "OpExtInstWithForwardRefsKHR is only allowed with "
|
||||
"non-semantic instructions.";
|
||||
ret = SPV_SUCCESS;
|
||||
break;
|
||||
default:
|
||||
ret = SPV_SUCCESS;
|
||||
break;
|
||||
}
|
||||
if (SPV_SUCCESS != ret) return ret;
|
||||
}
|
||||
const bool must_have_forward_declared_ids =
|
||||
inst->opcode() == spv::Op::OpExtInstWithForwardRefsKHR;
|
||||
if (must_have_forward_declared_ids && !has_forward_declared_ids) {
|
||||
return _.diag(SPV_ERROR_INVALID_ID, inst)
|
||||
<< "Opcode OpExtInstWithForwardRefsKHR must have at least one "
|
||||
"forward "
|
||||
"declared ID.";
|
||||
}
|
||||
|
||||
if (result_id) _.RemoveIfForwardDeclared(result_id);
|
||||
|
||||
return SPV_SUCCESS;
|
||||
|
@ -1005,7 +1005,8 @@ bool IsAllowedSampledImageOperand(spv::Op opcode, ValidationState_t& _) {
|
||||
|
||||
spv_result_t ValidateSampledImage(ValidationState_t& _,
|
||||
const Instruction* inst) {
|
||||
if (_.GetIdOpcode(inst->type_id()) != spv::Op::OpTypeSampledImage) {
|
||||
auto type_inst = _.FindDef(inst->type_id());
|
||||
if (type_inst->opcode() != spv::Op::OpTypeSampledImage) {
|
||||
return _.diag(SPV_ERROR_INVALID_DATA, inst)
|
||||
<< "Expected Result Type to be OpTypeSampledImage.";
|
||||
}
|
||||
@ -1016,6 +1017,11 @@ spv_result_t ValidateSampledImage(ValidationState_t& _,
|
||||
<< "Expected Image to be of type OpTypeImage.";
|
||||
}
|
||||
|
||||
if (type_inst->GetOperandAs<uint32_t>(1) != image_type) {
|
||||
return _.diag(SPV_ERROR_INVALID_DATA, inst)
|
||||
<< "Expected Image to have the same type as Result Type Image";
|
||||
}
|
||||
|
||||
ImageTypeInfo info;
|
||||
if (!GetImageTypeInfo(_, image_type, &info)) {
|
||||
return _.diag(SPV_ERROR_INVALID_DATA, inst)
|
||||
|
@ -35,6 +35,7 @@ spv_result_t ModuleScopedInstructions(ValidationState_t& _,
|
||||
const Instruction* inst, spv::Op opcode) {
|
||||
switch (opcode) {
|
||||
case spv::Op::OpExtInst:
|
||||
case spv::Op::OpExtInstWithForwardRefsKHR:
|
||||
if (spvExtInstIsDebugInfo(inst->ext_inst_type())) {
|
||||
const uint32_t ext_inst_index = inst->word(4);
|
||||
bool local_debug_info = false;
|
||||
@ -243,6 +244,7 @@ spv_result_t FunctionScopedInstructions(ValidationState_t& _,
|
||||
break;
|
||||
|
||||
case spv::Op::OpExtInst:
|
||||
case spv::Op::OpExtInstWithForwardRefsKHR:
|
||||
if (spvExtInstIsDebugInfo(inst->ext_inst_type())) {
|
||||
const uint32_t ext_inst_index = inst->word(4);
|
||||
bool local_debug_info = false;
|
||||
|
@ -76,6 +76,7 @@ ModuleLayoutSection InstructionLayoutSection(
|
||||
if (current_section == kLayoutTypes) return kLayoutTypes;
|
||||
return kLayoutFunctionDefinitions;
|
||||
case spv::Op::OpExtInst:
|
||||
case spv::Op::OpExtInstWithForwardRefsKHR:
|
||||
// spv::Op::OpExtInst is only allowed in types section for certain
|
||||
// extended instruction sets. This will be checked separately.
|
||||
if (current_section == kLayoutTypes) return kLayoutTypes;
|
||||
@ -2353,6 +2354,10 @@ std::string ValidationState_t::VkErrorID(uint32_t id,
|
||||
return VUID_WRAP(VUID-StandaloneSpirv-Pointer-08973);
|
||||
case 9638:
|
||||
return VUID_WRAP(VUID-StandaloneSpirv-OpTypeImage-09638);
|
||||
case 9658:
|
||||
return VUID_WRAP(VUID-StandaloneSpirv-OpEntryPoint-09658);
|
||||
case 9659:
|
||||
return VUID_WRAP(VUID-StandaloneSpirv-OpEntryPoint-09659);
|
||||
default:
|
||||
return ""; // unknown id
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user