Бранимир Караџић преди 6 години
родител
ревизия
eabaa485af
променени са 45 файла, в които са добавени 918 реда и са изтрити 334 реда
  1. 1 1
      3rdparty/spirv-tools/include/generated/DebugInfo.h
  2. 1 1
      3rdparty/spirv-tools/include/generated/build-version.inc
  3. 4 1
      3rdparty/spirv-tools/include/generated/core.insts-unified1.inc
  4. 1 1
      3rdparty/spirv-tools/include/generated/debuginfo.insts.inc
  5. 2 1
      3rdparty/spirv-tools/include/generated/enum_string_mapping.inc
  6. 2 1
      3rdparty/spirv-tools/include/generated/extension_enum.inc
  7. 1 1
      3rdparty/spirv-tools/include/generated/generators.inc
  8. 1 1
      3rdparty/spirv-tools/include/generated/glsl.std.450.insts.inc
  9. 1 1
      3rdparty/spirv-tools/include/generated/opencl.std.insts.inc
  10. 3 1
      3rdparty/spirv-tools/include/generated/operand.kinds-unified1.inc
  11. 1 1
      3rdparty/spirv-tools/include/generated/spv-amd-gcn-shader.insts.inc
  12. 1 1
      3rdparty/spirv-tools/include/generated/spv-amd-shader-ballot.insts.inc
  13. 1 1
      3rdparty/spirv-tools/include/generated/spv-amd-shader-explicit-vertex-parameter.insts.inc
  14. 1 1
      3rdparty/spirv-tools/include/generated/spv-amd-shader-trinary-minmax.insts.inc
  15. 33 8
      3rdparty/spirv-tools/source/opt/aggressive_dead_code_elim_pass.cpp
  16. 4 15
      3rdparty/spirv-tools/source/opt/inst_bindless_check_pass.cpp
  17. 0 3
      3rdparty/spirv-tools/source/opt/inst_bindless_check_pass.h
  18. 12 10
      3rdparty/spirv-tools/source/opt/merge_return_pass.cpp
  19. 13 13
      3rdparty/spirv-tools/source/opt/merge_return_pass.h
  20. 7 0
      3rdparty/spirv-tools/source/opt/ssa_rewrite_pass.cpp
  21. 3 0
      3rdparty/spirv-tools/source/opt/ssa_rewrite_pass.h
  22. 9 6
      3rdparty/spirv-tools/source/val/function.cpp
  23. 3 4
      3rdparty/spirv-tools/source/val/validate_annotation.cpp
  24. 56 24
      3rdparty/spirv-tools/source/val/validate_atomics.cpp
  25. 39 26
      3rdparty/spirv-tools/source/val/validate_cfg.cpp
  26. 38 30
      3rdparty/spirv-tools/source/val/validate_derivatives.cpp
  27. 71 5
      3rdparty/spirv-tools/source/val/validate_image.cpp
  28. 56 0
      3rdparty/spirv-tools/test/opt/aggressive_dead_code_elim_test.cpp
  29. 30 28
      3rdparty/spirv-tools/test/opt/inst_bindless_check_test.cpp
  30. 57 0
      3rdparty/spirv-tools/test/opt/local_ssa_elim_test.cpp
  31. 51 0
      3rdparty/spirv-tools/test/opt/pass_merge_return_test.cpp
  32. 0 2
      3rdparty/spirv-tools/test/scripts/test_compact_ids.py
  33. 0 2
      3rdparty/spirv-tools/test/tools/spirv_test_framework.py
  34. 27 21
      3rdparty/spirv-tools/test/val/val_atomics_test.cpp
  35. 174 0
      3rdparty/spirv-tools/test/val/val_cfg_test.cpp
  36. 3 4
      3rdparty/spirv-tools/test/val/val_derivatives_test.cpp
  37. 1 1
      3rdparty/spirv-tools/test/val/val_id_test.cpp
  38. 141 44
      3rdparty/spirv-tools/test/val/val_image_test.cpp
  39. 0 1
      3rdparty/spirv-tools/utils/check_copyright.py
  40. 0 2
      3rdparty/spirv-tools/utils/check_symbol_exports.py
  41. 65 61
      3rdparty/spirv-tools/utils/generate_grammar_tables.py
  42. 2 3
      3rdparty/spirv-tools/utils/generate_language_headers.py
  43. 2 3
      3rdparty/spirv-tools/utils/generate_registry_tables.py
  44. 0 2
      3rdparty/spirv-tools/utils/generate_vim_syntax.py
  45. 0 2
      3rdparty/spirv-tools/utils/update_build_version.py

+ 1 - 1
3rdparty/spirv-tools/include/generated/DebugInfo.h

@@ -134,4 +134,4 @@ enum DebugInfoDebugOperation {
 }
 }
 #endif
 #endif
 
 
-#endif // SPIRV_EXTINST_DebugInfo_H_
+#endif // SPIRV_EXTINST_DebugInfo_H_

+ 1 - 1
3rdparty/spirv-tools/include/generated/build-version.inc

@@ -1 +1 @@
-"v2019.4-dev", "SPIRV-Tools v2019.4-dev v2019.3-90-g76b75c40"
+"v2019.4-dev", "SPIRV-Tools v2019.4-dev v2019.3-99-g65f49dfc"

+ 4 - 1
3rdparty/spirv-tools/include/generated/core.insts-unified1.inc

@@ -32,6 +32,7 @@ static const SpvCapability pygen_variable_caps_PipeStorage[] = {SpvCapabilityPip
 static const SpvCapability pygen_variable_caps_Pipes[] = {SpvCapabilityPipes};
 static const SpvCapability pygen_variable_caps_Pipes[] = {SpvCapabilityPipes};
 static const SpvCapability pygen_variable_caps_RayTracingNV[] = {SpvCapabilityRayTracingNV};
 static const SpvCapability pygen_variable_caps_RayTracingNV[] = {SpvCapabilityRayTracingNV};
 static const SpvCapability pygen_variable_caps_Shader[] = {SpvCapabilityShader};
 static const SpvCapability pygen_variable_caps_Shader[] = {SpvCapabilityShader};
+static const SpvCapability pygen_variable_caps_ShaderClockKHR[] = {SpvCapabilityShaderClockKHR};
 static const SpvCapability pygen_variable_caps_SparseResidency[] = {SpvCapabilitySparseResidency};
 static const SpvCapability pygen_variable_caps_SparseResidency[] = {SpvCapabilitySparseResidency};
 static const SpvCapability pygen_variable_caps_SubgroupAvcMotionEstimationINTEL[] = {SpvCapabilitySubgroupAvcMotionEstimationINTEL};
 static const SpvCapability pygen_variable_caps_SubgroupAvcMotionEstimationINTEL[] = {SpvCapabilitySubgroupAvcMotionEstimationINTEL};
 static const SpvCapability pygen_variable_caps_SubgroupAvcMotionEstimationINTELSubgroupAvcMotionEstimationChromaINTEL[] = {SpvCapabilitySubgroupAvcMotionEstimationINTEL, SpvCapabilitySubgroupAvcMotionEstimationChromaINTEL};
 static const SpvCapability pygen_variable_caps_SubgroupAvcMotionEstimationINTELSubgroupAvcMotionEstimationChromaINTEL[] = {SpvCapabilitySubgroupAvcMotionEstimationINTEL, SpvCapabilitySubgroupAvcMotionEstimationChromaINTEL};
@@ -51,6 +52,7 @@ static const spvtools::Extension pygen_variable_exts_SPV_EXT_fragment_shader_int
 static const spvtools::Extension pygen_variable_exts_SPV_GOOGLE_decorate_stringSPV_GOOGLE_hlsl_functionality1[] = {spvtools::Extension::kSPV_GOOGLE_decorate_string, spvtools::Extension::kSPV_GOOGLE_hlsl_functionality1};
 static const spvtools::Extension pygen_variable_exts_SPV_GOOGLE_decorate_stringSPV_GOOGLE_hlsl_functionality1[] = {spvtools::Extension::kSPV_GOOGLE_decorate_string, spvtools::Extension::kSPV_GOOGLE_hlsl_functionality1};
 static const spvtools::Extension pygen_variable_exts_SPV_GOOGLE_hlsl_functionality1[] = {spvtools::Extension::kSPV_GOOGLE_hlsl_functionality1};
 static const spvtools::Extension pygen_variable_exts_SPV_GOOGLE_hlsl_functionality1[] = {spvtools::Extension::kSPV_GOOGLE_hlsl_functionality1};
 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_shader_ballot[] = {spvtools::Extension::kSPV_KHR_shader_ballot};
+static const spvtools::Extension pygen_variable_exts_SPV_KHR_shader_clock[] = {spvtools::Extension::kSPV_KHR_shader_clock};
 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_subgroup_vote[] = {spvtools::Extension::kSPV_KHR_subgroup_vote};
 static const spvtools::Extension pygen_variable_exts_SPV_NV_cooperative_matrix[] = {spvtools::Extension::kSPV_NV_cooperative_matrix};
 static const spvtools::Extension pygen_variable_exts_SPV_NV_cooperative_matrix[] = {spvtools::Extension::kSPV_NV_cooperative_matrix};
 static const spvtools::Extension pygen_variable_exts_SPV_NV_mesh_shader[] = {spvtools::Extension::kSPV_NV_mesh_shader};
 static const spvtools::Extension pygen_variable_exts_SPV_NV_mesh_shader[] = {spvtools::Extension::kSPV_NV_mesh_shader};
@@ -419,6 +421,7 @@ static const spv_opcode_desc_t kOpcodeTableEntries[] = {
   {"GroupSMaxNonUniformAMD", SpvOpGroupSMaxNonUniformAMD, 1, pygen_variable_caps_Groups, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_AMD_shader_ballot, 0xffffffffu, 0xffffffffu},
   {"GroupSMaxNonUniformAMD", SpvOpGroupSMaxNonUniformAMD, 1, pygen_variable_caps_Groups, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_AMD_shader_ballot, 0xffffffffu, 0xffffffffu},
   {"FragmentMaskFetchAMD", SpvOpFragmentMaskFetchAMD, 1, pygen_variable_caps_FragmentMaskAMD, 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_AMD_shader_fragment_mask, 0xffffffffu, 0xffffffffu},
   {"FragmentMaskFetchAMD", SpvOpFragmentMaskFetchAMD, 1, pygen_variable_caps_FragmentMaskAMD, 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_AMD_shader_fragment_mask, 0xffffffffu, 0xffffffffu},
   {"FragmentFetchAMD", SpvOpFragmentFetchAMD, 1, pygen_variable_caps_FragmentMaskAMD, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_AMD_shader_fragment_mask, 0xffffffffu, 0xffffffffu},
   {"FragmentFetchAMD", SpvOpFragmentFetchAMD, 1, pygen_variable_caps_FragmentMaskAMD, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_AMD_shader_fragment_mask, 0xffffffffu, 0xffffffffu},
+  {"ReadClockKHR", SpvOpReadClockKHR, 1, pygen_variable_caps_ShaderClockKHR, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_KHR_shader_clock, 0xffffffffu, 0xffffffffu},
   {"ImageSampleFootprintNV", SpvOpImageSampleFootprintNV, 1, pygen_variable_caps_ImageFootprintNV, 7, {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_ID, SPV_OPERAND_TYPE_OPTIONAL_IMAGE}, 1, 1, 1, pygen_variable_exts_SPV_NV_shader_image_footprint, 0xffffffffu, 0xffffffffu},
   {"ImageSampleFootprintNV", SpvOpImageSampleFootprintNV, 1, pygen_variable_caps_ImageFootprintNV, 7, {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_ID, SPV_OPERAND_TYPE_OPTIONAL_IMAGE}, 1, 1, 1, pygen_variable_exts_SPV_NV_shader_image_footprint, 0xffffffffu, 0xffffffffu},
   {"GroupNonUniformPartitionNV", SpvOpGroupNonUniformPartitionNV, 1, pygen_variable_caps_GroupNonUniformPartitionedNV, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_NV_shader_subgroup_partitioned, 0xffffffffu, 0xffffffffu},
   {"GroupNonUniformPartitionNV", SpvOpGroupNonUniformPartitionNV, 1, pygen_variable_caps_GroupNonUniformPartitionedNV, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_NV_shader_subgroup_partitioned, 0xffffffffu, 0xffffffffu},
   {"WritePackedPrimitiveIndices4x8NV", SpvOpWritePackedPrimitiveIndices4x8NV, 1, pygen_variable_caps_MeshShadingNV, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 1, pygen_variable_exts_SPV_NV_mesh_shader, 0xffffffffu, 0xffffffffu},
   {"WritePackedPrimitiveIndices4x8NV", SpvOpWritePackedPrimitiveIndices4x8NV, 1, pygen_variable_caps_MeshShadingNV, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 1, pygen_variable_exts_SPV_NV_mesh_shader, 0xffffffffu, 0xffffffffu},
@@ -583,4 +586,4 @@ static const spv_opcode_desc_t kOpcodeTableEntries[] = {
   {"SubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL", SpvOpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL, 2, pygen_variable_caps_SubgroupAvcMotionEstimationINTELSubgroupAvcMotionEstimationIntraINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
   {"SubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL", SpvOpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL, 2, pygen_variable_caps_SubgroupAvcMotionEstimationINTELSubgroupAvcMotionEstimationIntraINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
   {"SubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL", SpvOpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL, 2, pygen_variable_caps_SubgroupAvcMotionEstimationINTELSubgroupAvcMotionEstimationIntraINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
   {"SubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL", SpvOpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL, 2, pygen_variable_caps_SubgroupAvcMotionEstimationINTELSubgroupAvcMotionEstimationIntraINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
   {"SubgroupAvcSicGetInterRawSadsINTEL", SpvOpSubgroupAvcSicGetInterRawSadsINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}
   {"SubgroupAvcSicGetInterRawSadsINTEL", SpvOpSubgroupAvcSicGetInterRawSadsINTEL, 1, pygen_variable_caps_SubgroupAvcMotionEstimationINTEL, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}
-};
+};

+ 1 - 1
3rdparty/spirv-tools/include/generated/debuginfo.insts.inc

@@ -35,4 +35,4 @@ static const spv_ext_inst_desc_t debuginfo_entries[] = {
   {"DebugExpression", 31, 0, nullptr, {SPV_OPERAND_TYPE_VARIABLE_ID, SPV_OPERAND_TYPE_NONE}},
   {"DebugExpression", 31, 0, nullptr, {SPV_OPERAND_TYPE_VARIABLE_ID, SPV_OPERAND_TYPE_NONE}},
   {"DebugMacroDef", 32, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}},
   {"DebugMacroDef", 32, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}},
   {"DebugMacroUndef", 33, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}
   {"DebugMacroUndef", 33, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}
-};
+};

Файловите разлики са ограничени, защото са твърде много
+ 2 - 1
3rdparty/spirv-tools/include/generated/enum_string_mapping.inc


+ 2 - 1
3rdparty/spirv-tools/include/generated/extension_enum.inc

@@ -32,6 +32,7 @@ kSPV_KHR_no_integer_wrap_decoration,
 kSPV_KHR_post_depth_coverage,
 kSPV_KHR_post_depth_coverage,
 kSPV_KHR_shader_atomic_counter_ops,
 kSPV_KHR_shader_atomic_counter_ops,
 kSPV_KHR_shader_ballot,
 kSPV_KHR_shader_ballot,
+kSPV_KHR_shader_clock,
 kSPV_KHR_shader_draw_parameters,
 kSPV_KHR_shader_draw_parameters,
 kSPV_KHR_storage_buffer_storage_class,
 kSPV_KHR_storage_buffer_storage_class,
 kSPV_KHR_subgroup_vote,
 kSPV_KHR_subgroup_vote,
@@ -51,4 +52,4 @@ kSPV_NV_shader_subgroup_partitioned,
 kSPV_NV_shading_rate,
 kSPV_NV_shading_rate,
 kSPV_NV_stereo_view_rendering,
 kSPV_NV_stereo_view_rendering,
 kSPV_NV_viewport_array2,
 kSPV_NV_viewport_array2,
-kSPV_VALIDATOR_ignore_type_decl_unique
+kSPV_VALIDATOR_ignore_type_decl_unique

+ 1 - 1
3rdparty/spirv-tools/include/generated/generators.inc

@@ -20,4 +20,4 @@
 {19, "Clay", "Clay Shader Compiler", "Clay Clay Shader Compiler"},
 {19, "Clay", "Clay Shader Compiler", "Clay Clay Shader Compiler"},
 {20, "W3C WebGPU Group", "WHLSL Shader Translator", "W3C WebGPU Group WHLSL Shader Translator"},
 {20, "W3C WebGPU Group", "WHLSL Shader Translator", "W3C WebGPU Group WHLSL Shader Translator"},
 {21, "Google", "Clspv", "Google Clspv"},
 {21, "Google", "Clspv", "Google Clspv"},
-{22, "Google", "MLIR SPIR-V Serializer", "Google MLIR SPIR-V Serializer"},
+{22, "Google", "MLIR SPIR-V Serializer", "Google MLIR SPIR-V Serializer"},

+ 1 - 1
3rdparty/spirv-tools/include/generated/glsl.std.450.insts.inc

@@ -83,4 +83,4 @@ static const spv_ext_inst_desc_t glsl_entries[] = {
   {"NMin", 79, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
   {"NMin", 79, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
   {"NMax", 80, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
   {"NMax", 80, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
   {"NClamp", 81, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}
   {"NClamp", 81, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}
-};
+};

+ 1 - 1
3rdparty/spirv-tools/include/generated/opencl.std.insts.inc

@@ -163,4 +163,4 @@ static const spv_ext_inst_desc_t opencl_entries[] = {
   {"u_abs_diff", 202, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
   {"u_abs_diff", 202, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
   {"u_mul_hi", 203, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
   {"u_mul_hi", 203, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
   {"u_mad_hi", 204, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}
   {"u_mad_hi", 204, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}
-};
+};

+ 3 - 1
3rdparty/spirv-tools/include/generated/operand.kinds-unified1.inc

@@ -114,6 +114,7 @@ static const spvtools::Extension pygen_variable_exts_SPV_KHR_no_integer_wrap_dec
 static const spvtools::Extension pygen_variable_exts_SPV_KHR_post_depth_coverage[] = {spvtools::Extension::kSPV_KHR_post_depth_coverage};
 static const spvtools::Extension pygen_variable_exts_SPV_KHR_post_depth_coverage[] = {spvtools::Extension::kSPV_KHR_post_depth_coverage};
 static const spvtools::Extension pygen_variable_exts_SPV_KHR_shader_atomic_counter_ops[] = {spvtools::Extension::kSPV_KHR_shader_atomic_counter_ops};
 static const spvtools::Extension pygen_variable_exts_SPV_KHR_shader_atomic_counter_ops[] = {spvtools::Extension::kSPV_KHR_shader_atomic_counter_ops};
 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_shader_ballot[] = {spvtools::Extension::kSPV_KHR_shader_ballot};
+static const spvtools::Extension pygen_variable_exts_SPV_KHR_shader_clock[] = {spvtools::Extension::kSPV_KHR_shader_clock};
 static const spvtools::Extension pygen_variable_exts_SPV_KHR_shader_draw_parameters[] = {spvtools::Extension::kSPV_KHR_shader_draw_parameters};
 static const spvtools::Extension pygen_variable_exts_SPV_KHR_shader_draw_parameters[] = {spvtools::Extension::kSPV_KHR_shader_draw_parameters};
 static const spvtools::Extension pygen_variable_exts_SPV_KHR_shader_draw_parametersSPV_NV_mesh_shader[] = {spvtools::Extension::kSPV_KHR_shader_draw_parameters, spvtools::Extension::kSPV_NV_mesh_shader};
 static const spvtools::Extension pygen_variable_exts_SPV_KHR_shader_draw_parametersSPV_NV_mesh_shader[] = {spvtools::Extension::kSPV_KHR_shader_draw_parameters, spvtools::Extension::kSPV_NV_mesh_shader};
 static const spvtools::Extension pygen_variable_exts_SPV_KHR_storage_buffer_storage_classSPV_KHR_variable_pointers[] = {spvtools::Extension::kSPV_KHR_storage_buffer_storage_class, spvtools::Extension::kSPV_KHR_variable_pointers};
 static const spvtools::Extension pygen_variable_exts_SPV_KHR_storage_buffer_storage_classSPV_KHR_variable_pointers[] = {spvtools::Extension::kSPV_KHR_storage_buffer_storage_class, spvtools::Extension::kSPV_KHR_variable_pointers};
@@ -781,6 +782,7 @@ static const spv_operand_desc_t pygen_variable_CapabilityEntries[] = {
   {"FragmentMaskAMD", 5010, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_AMD_shader_fragment_mask, {}, 0xffffffffu, 0xffffffffu},
   {"FragmentMaskAMD", 5010, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_AMD_shader_fragment_mask, {}, 0xffffffffu, 0xffffffffu},
   {"StencilExportEXT", 5013, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_EXT_shader_stencil_export, {}, 0xffffffffu, 0xffffffffu},
   {"StencilExportEXT", 5013, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_EXT_shader_stencil_export, {}, 0xffffffffu, 0xffffffffu},
   {"ImageReadWriteLodAMD", 5015, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_AMD_shader_image_load_store_lod, {}, 0xffffffffu, 0xffffffffu},
   {"ImageReadWriteLodAMD", 5015, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_AMD_shader_image_load_store_lod, {}, 0xffffffffu, 0xffffffffu},
+  {"ShaderClockKHR", 5055, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_KHR_shader_clock, {}, 0xffffffffu, 0xffffffffu},
   {"SampleMaskOverrideCoverageNV", 5249, 1, pygen_variable_caps_SampleRateShading, 1, pygen_variable_exts_SPV_NV_sample_mask_override_coverage, {}, 0xffffffffu, 0xffffffffu},
   {"SampleMaskOverrideCoverageNV", 5249, 1, pygen_variable_caps_SampleRateShading, 1, pygen_variable_exts_SPV_NV_sample_mask_override_coverage, {}, 0xffffffffu, 0xffffffffu},
   {"GeometryShaderPassthroughNV", 5251, 1, pygen_variable_caps_Geometry, 1, pygen_variable_exts_SPV_NV_geometry_shader_passthrough, {}, 0xffffffffu, 0xffffffffu},
   {"GeometryShaderPassthroughNV", 5251, 1, pygen_variable_caps_Geometry, 1, pygen_variable_exts_SPV_NV_geometry_shader_passthrough, {}, 0xffffffffu, 0xffffffffu},
   {"ShaderViewportIndexLayerEXT", 5254, 1, pygen_variable_caps_MultiViewport, 2, pygen_variable_exts_SPV_EXT_shader_viewport_index_layerSPV_NV_viewport_array2, {}, 0xffffffffu, 0xffffffffu},
   {"ShaderViewportIndexLayerEXT", 5254, 1, pygen_variable_caps_MultiViewport, 2, pygen_variable_exts_SPV_EXT_shader_viewport_index_layerSPV_NV_viewport_array2, {}, 0xffffffffu, 0xffffffffu},
@@ -921,4 +923,4 @@ static const spv_operand_desc_group_t pygen_variable_OperandInfoTable[] = {
   {SPV_OPERAND_TYPE_OPTIONAL_IMAGE, ARRAY_SIZE(pygen_variable_ImageOperandsEntries), pygen_variable_ImageOperandsEntries},
   {SPV_OPERAND_TYPE_OPTIONAL_IMAGE, ARRAY_SIZE(pygen_variable_ImageOperandsEntries), pygen_variable_ImageOperandsEntries},
   {SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS, ARRAY_SIZE(pygen_variable_MemoryAccessEntries), pygen_variable_MemoryAccessEntries},
   {SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS, ARRAY_SIZE(pygen_variable_MemoryAccessEntries), pygen_variable_MemoryAccessEntries},
   {SPV_OPERAND_TYPE_OPTIONAL_ACCESS_QUALIFIER, ARRAY_SIZE(pygen_variable_AccessQualifierEntries), pygen_variable_AccessQualifierEntries}
   {SPV_OPERAND_TYPE_OPTIONAL_ACCESS_QUALIFIER, ARRAY_SIZE(pygen_variable_AccessQualifierEntries), pygen_variable_AccessQualifierEntries}
-};
+};

+ 1 - 1
3rdparty/spirv-tools/include/generated/spv-amd-gcn-shader.insts.inc

@@ -4,4 +4,4 @@ static const spv_ext_inst_desc_t spv_amd_gcn_shader_entries[] = {
   {"CubeFaceIndexAMD", 1, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
   {"CubeFaceIndexAMD", 1, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
   {"CubeFaceCoordAMD", 2, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
   {"CubeFaceCoordAMD", 2, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
   {"TimeAMD", 3, 0, nullptr, {SPV_OPERAND_TYPE_NONE}}
   {"TimeAMD", 3, 0, nullptr, {SPV_OPERAND_TYPE_NONE}}
-};
+};

+ 1 - 1
3rdparty/spirv-tools/include/generated/spv-amd-shader-ballot.insts.inc

@@ -5,4 +5,4 @@ static const spv_ext_inst_desc_t spv_amd_shader_ballot_entries[] = {
   {"SwizzleInvocationsMaskedAMD", 2, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
   {"SwizzleInvocationsMaskedAMD", 2, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
   {"WriteInvocationAMD", 3, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
   {"WriteInvocationAMD", 3, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
   {"MbcntAMD", 4, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}
   {"MbcntAMD", 4, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}
-};
+};

+ 1 - 1
3rdparty/spirv-tools/include/generated/spv-amd-shader-explicit-vertex-parameter.insts.inc

@@ -2,4 +2,4 @@
 
 
 static const spv_ext_inst_desc_t spv_amd_shader_explicit_vertex_parameter_entries[] = {
 static const spv_ext_inst_desc_t spv_amd_shader_explicit_vertex_parameter_entries[] = {
   {"InterpolateAtVertexAMD", 1, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}
   {"InterpolateAtVertexAMD", 1, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}
-};
+};

+ 1 - 1
3rdparty/spirv-tools/include/generated/spv-amd-shader-trinary-minmax.insts.inc

@@ -10,4 +10,4 @@ static const spv_ext_inst_desc_t spv_amd_shader_trinary_minmax_entries[] = {
   {"FMid3AMD", 7, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
   {"FMid3AMD", 7, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
   {"UMid3AMD", 8, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
   {"UMid3AMD", 8, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
   {"SMid3AMD", 9, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}
   {"SMid3AMD", 9, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}
-};
+};

+ 33 - 8
3rdparty/spirv-tools/source/opt/aggressive_dead_code_elim_pass.cpp

@@ -490,6 +490,28 @@ bool AggressiveDCEPass::AggressiveDCE(Function* func) {
         ProcessLoad(varId);
         ProcessLoad(varId);
       }
       }
     }
     }
+
+    // Add OpDecorateId instructions that apply to this instruction to the work
+    // list.  We use the decoration manager to look through the group
+    // decorations to get to the OpDecorate* instructions themselves.
+    auto decorations =
+        get_decoration_mgr()->GetDecorationsFor(liveInst->result_id(), false);
+    for (Instruction* dec : decorations) {
+      // We only care about OpDecorateId instructions because the are the only
+      // decorations that will reference an id that will have to be kept live
+      // because of that use.
+      if (dec->opcode() != SpvOpDecorateId) {
+        continue;
+      }
+      if (dec->GetSingleWordInOperand(1) ==
+          SpvDecorationHlslCounterBufferGOOGLE) {
+        // These decorations should not force the use id to be live.  It will be
+        // removed if either the target or the in operand are dead.
+        continue;
+      }
+      AddToWorklist(dec);
+    }
+
     worklist_.pop();
     worklist_.pop();
   }
   }
 
 
@@ -618,14 +640,6 @@ Pass::Status AggressiveDCEPass::ProcessImpl() {
   // return unmodified.
   // return unmodified.
   if (!AllExtensionsSupported()) return Status::SuccessWithoutChange;
   if (!AllExtensionsSupported()) return Status::SuccessWithoutChange;
 
 
-  // If the decoration manager is kept live then the context will try to keep it
-  // up to date.  ADCE deals with group decorations by changing the operands in
-  // |OpGroupDecorate| instruction directly without informing the decoration
-  // manager.  This can put it in an invalid state which will cause an error
-  // when the context tries to update it.  To avoid this problem invalidate
-  // the decoration manager upfront.
-  context()->InvalidateAnalyses(IRContext::Analysis::kAnalysisDecorations);
-
   // Eliminate Dead functions.
   // Eliminate Dead functions.
   bool modified = EliminateDeadFunctions();
   bool modified = EliminateDeadFunctions();
 
 
@@ -635,6 +649,17 @@ Pass::Status AggressiveDCEPass::ProcessImpl() {
   ProcessFunction pfn = [this](Function* fp) { return AggressiveDCE(fp); };
   ProcessFunction pfn = [this](Function* fp) { return AggressiveDCE(fp); };
   modified |= context()->ProcessEntryPointCallTree(pfn);
   modified |= context()->ProcessEntryPointCallTree(pfn);
 
 
+  // If the decoration manager is kept live then the context will try to keep it
+  // up to date.  ADCE deals with group decorations by changing the operands in
+  // |OpGroupDecorate| instruction directly without informing the decoration
+  // manager.  This can put it in an invalid state which will cause an error
+  // when the context tries to update it.  To avoid this problem invalidate
+  // the decoration manager upfront.
+  //
+  // We kill it at now because it is used when processing the entry point
+  // functions.
+  context()->InvalidateAnalyses(IRContext::Analysis::kAnalysisDecorations);
+
   // Process module-level instructions. Now that all live instructions have
   // Process module-level instructions. Now that all live instructions have
   // been marked, it is safe to remove dead global values.
   // been marked, it is safe to remove dead global values.
   modified |= ProcessGlobalValues();
   modified |= ProcessGlobalValues();

+ 4 - 15
3rdparty/spirv-tools/source/opt/inst_bindless_check_pass.cpp

@@ -398,20 +398,9 @@ void InstBindlessCheckPass::GenInitCheckCode(
 void InstBindlessCheckPass::InitializeInstBindlessCheck() {
 void InstBindlessCheckPass::InitializeInstBindlessCheck() {
   // Initialize base class
   // Initialize base class
   InitializeInstrument();
   InitializeInstrument();
-  // Look for related extensions
-  ext_descriptor_indexing_defined_ = false;
-  for (auto& ei : get_module()->extensions()) {
-    const char* ext_name =
-        reinterpret_cast<const char*>(&ei.GetInOperand(0).words[0]);
-    if (strcmp(ext_name, "SPV_EXT_descriptor_indexing") == 0) {
-      ext_descriptor_indexing_defined_ = true;
-      break;
-    }
-  }
-  // If descriptor indexing extension and runtime array length support enabled,
-  // create variable mappings. Length support is always enabled if descriptor
-  // init check is enabled.
-  if (ext_descriptor_indexing_defined_ && input_length_enabled_)
+  // If runtime array length support enabled, create variable mappings. Length
+  // support is always enabled if descriptor init check is enabled.
+  if (input_length_enabled_)
     for (auto& anno : get_module()->annotations())
     for (auto& anno : get_module()->annotations())
       if (anno.opcode() == SpvOpDecorate) {
       if (anno.opcode() == SpvOpDecorate) {
         if (anno.GetSingleWordInOperand(1u) == SpvDecorationDescriptorSet)
         if (anno.GetSingleWordInOperand(1u) == SpvDecorationDescriptorSet)
@@ -433,7 +422,7 @@ Pass::Status InstBindlessCheckPass::ProcessImpl() {
                                   new_blocks);
                                   new_blocks);
       };
       };
   bool modified = InstProcessEntryPointCallTree(pfn);
   bool modified = InstProcessEntryPointCallTree(pfn);
-  if (ext_descriptor_indexing_defined_ && input_init_enabled_) {
+  if (input_init_enabled_) {
     // Perform descriptor initialization check on each entry point function in
     // Perform descriptor initialization check on each entry point function in
     // module
     // module
     pfn = [this](BasicBlock::iterator ref_inst_itr,
     pfn = [this](BasicBlock::iterator ref_inst_itr,

+ 0 - 3
3rdparty/spirv-tools/source/opt/inst_bindless_check_pass.h

@@ -162,9 +162,6 @@ class InstBindlessCheckPass : public InstrumentPass {
   // GenInitCheckCode to every instruction in module.
   // GenInitCheckCode to every instruction in module.
   Pass::Status ProcessImpl();
   Pass::Status ProcessImpl();
 
 
-  // True if VK_EXT_descriptor_indexing is defined
-  bool ext_descriptor_indexing_defined_;
-
   // Enable instrumentation of runtime array length checking
   // Enable instrumentation of runtime array length checking
   bool input_length_enabled_;
   bool input_length_enabled_;
 
 

+ 12 - 10
3rdparty/spirv-tools/source/opt/merge_return_pass.cpp

@@ -81,6 +81,7 @@ bool MergeReturnPass::ProcessStructured(
     return false;
     return false;
   }
   }
 
 
+  RecordImmediateDominators(function);
   AddDummyLoopAroundFunction();
   AddDummyLoopAroundFunction();
 
 
   std::list<BasicBlock*> order;
   std::list<BasicBlock*> order;
@@ -236,10 +237,6 @@ void MergeReturnPass::UpdatePhiNodes(BasicBlock* new_source,
     inst->AddOperand({SPV_OPERAND_TYPE_ID, {new_source->id()}});
     inst->AddOperand({SPV_OPERAND_TYPE_ID, {new_source->id()}});
     context()->UpdateDefUse(inst);
     context()->UpdateDefUse(inst);
   });
   });
-
-  // Store the immediate dominator for this block in case new phi nodes will be
-  // needed later.
-  RecordImmediateDominator(target);
 }
 }
 
 
 void MergeReturnPass::CreatePhiNodesForInst(BasicBlock* merge_block,
 void MergeReturnPass::CreatePhiNodesForInst(BasicBlock* merge_block,
@@ -683,7 +680,7 @@ void MergeReturnPass::AddNewPhiNodes(BasicBlock* bb) {
     return;
     return;
   }
   }
 
 
-  BasicBlock* current_bb = new_merge_nodes_[bb];
+  BasicBlock* current_bb = context()->get_instr_block(original_dominator_[bb]);
   while (current_bb != nullptr && current_bb != dominator) {
   while (current_bb != nullptr && current_bb != dominator) {
     for (Instruction& inst : *current_bb) {
     for (Instruction& inst : *current_bb) {
       CreatePhiNodesForInst(bb, inst);
       CreatePhiNodesForInst(bb, inst);
@@ -692,11 +689,16 @@ void MergeReturnPass::AddNewPhiNodes(BasicBlock* bb) {
   }
   }
 }
 }
 
 
-void MergeReturnPass::RecordImmediateDominator(BasicBlock* block) {
-  DominatorAnalysis* dom_tree =
-      context()->GetDominatorAnalysis(block->GetParent());
-  auto idom = dom_tree->ImmediateDominator(block);
-  new_merge_nodes_[block] = idom;
+void MergeReturnPass::RecordImmediateDominators(Function* function) {
+  DominatorAnalysis* dom_tree = context()->GetDominatorAnalysis(function);
+  for (BasicBlock& bb : *function) {
+    BasicBlock* dominator_bb = dom_tree->ImmediateDominator(&bb);
+    if (dominator_bb && dominator_bb != cfg()->pseudo_entry_block()) {
+      original_dominator_[&bb] = dominator_bb->terminator();
+    } else {
+      original_dominator_[&bb] = nullptr;
+    }
+  }
 }
 }
 
 
 void MergeReturnPass::InsertAfterElement(BasicBlock* element,
 void MergeReturnPass::InsertAfterElement(BasicBlock* element,

+ 13 - 13
3rdparty/spirv-tools/source/opt/merge_return_pass.h

@@ -246,24 +246,23 @@ class MergeReturnPass : public MemPass {
   // instruction.
   // instruction.
   void CreatePhiNodesForInst(BasicBlock* merge_block, Instruction& inst);
   void CreatePhiNodesForInst(BasicBlock* merge_block, Instruction& inst);
 
 
-  // Traverse the nodes in |new_merge_nodes_|, and adds the OpPhi instructions
-  // that are needed to make the code correct.  It is assumed that at this point
-  // there are no unreachable blocks in the control flow graph.
+  // Add new phi nodes for any id that no longer dominate all of it uses.  A phi
+  // node is added to a block |bb| for an id if the id is defined between the
+  // original immediate dominator of |bb| and its new immidiate dominator.  It
+  // is assumed that at this point there are no unreachable blocks in the
+  // control flow graph.
   void AddNewPhiNodes();
   void AddNewPhiNodes();
 
 
   // Creates any new phi nodes that are needed in |bb|.  |AddNewPhiNodes| must
   // Creates any new phi nodes that are needed in |bb|.  |AddNewPhiNodes| must
   // have already been called on the original dominators of |bb|.
   // have already been called on the original dominators of |bb|.
   void AddNewPhiNodes(BasicBlock* bb);
   void AddNewPhiNodes(BasicBlock* bb);
 
 
-  // Saves |block| to a list of basic block that will require OpPhi nodes to be
-  // added by calling |AddNewPhiNodes|.  It is assumed that |block| used to have
-  // a single predecessor, |single_original_pred|, but now has more.
-  void RecordImmediateDominator(BasicBlock* block);
+  // Records the terminator of immediate dominator for every basic block in
+  // |function|.
+  void RecordImmediateDominators(Function* function);
 
 
   // Modifies existing OpPhi instruction in |target| block to account for the
   // Modifies existing OpPhi instruction in |target| block to account for the
-  // new edge from |new_source|.  The value for that edge will be an Undef. If
-  // |target| only had a single predecessor, then it is marked as needing new
-  // phi nodes.  See |RecordImmediateDominator|.
+  // new edge from |new_source|.  The value for that edge will be an Undef.
   //
   //
   // The CFG must not include the edge from |new_source| to |target| yet.
   // The CFG must not include the edge from |new_source| to |target| yet.
   void UpdatePhiNodes(BasicBlock* new_source, BasicBlock* target);
   void UpdatePhiNodes(BasicBlock* new_source, BasicBlock* target);
@@ -317,9 +316,10 @@ class MergeReturnPass : public MemPass {
   // after processing the current function.
   // after processing the current function.
   BasicBlock* final_return_block_;
   BasicBlock* final_return_block_;
 
 
-  // This is a map from a node to its original immediate dominator.  This is
-  // used to determine which values will require a new phi node.
-  std::unordered_map<BasicBlock*, BasicBlock*> new_merge_nodes_;
+  // This is a map from a node to its original immediate dominator identified by
+  // the terminator if that block.  We use the terminator because the block we
+  // want may change if the block is split.
+  std::unordered_map<BasicBlock*, Instruction*> original_dominator_;
 
 
   // A map from a basic block, bb, to the set of basic blocks which represent
   // A map from a basic block, bb, to the set of basic blocks which represent
   // the new edges that reach |bb|.
   // the new edges that reach |bb|.

+ 7 - 0
3rdparty/spirv-tools/source/opt/ssa_rewrite_pass.cpp

@@ -102,6 +102,7 @@ void SSARewriter::ReplacePhiUsersWith(const PhiCandidate& phi_to_remove,
                                       uint32_t repl_id) {
                                       uint32_t repl_id) {
   for (uint32_t user_id : phi_to_remove.users()) {
   for (uint32_t user_id : phi_to_remove.users()) {
     PhiCandidate* user_phi = GetPhiCandidate(user_id);
     PhiCandidate* user_phi = GetPhiCandidate(user_id);
+    BasicBlock* bb = pass_->context()->get_instr_block(user_id);
     if (user_phi) {
     if (user_phi) {
       // If the user is a Phi candidate, replace all arguments that refer to
       // If the user is a Phi candidate, replace all arguments that refer to
       // |phi_to_remove.result_id()| with |repl_id|.
       // |phi_to_remove.result_id()| with |repl_id|.
@@ -110,6 +111,10 @@ void SSARewriter::ReplacePhiUsersWith(const PhiCandidate& phi_to_remove,
           arg = repl_id;
           arg = repl_id;
         }
         }
       }
       }
+    } else if (bb->id() == user_id) {
+      // The phi candidate is the definition of the variable at basic block
+      // |bb|.  We must change this to the replacement.
+      WriteVariable(phi_to_remove.var_id(), bb, repl_id);
     } else {
     } else {
       // For regular loads, traverse the |load_replacement_| table looking for
       // For regular loads, traverse the |load_replacement_| table looking for
       // instances of |phi_to_remove|.
       // instances of |phi_to_remove|.
@@ -259,6 +264,8 @@ uint32_t SSARewriter::GetReachingDef(uint32_t var_id, BasicBlock* bb) {
     // require a Phi instruction.  This will act as |var_id|'s current
     // require a Phi instruction.  This will act as |var_id|'s current
     // definition to break potential cycles.
     // definition to break potential cycles.
     PhiCandidate& phi_candidate = CreatePhiCandidate(var_id, bb);
     PhiCandidate& phi_candidate = CreatePhiCandidate(var_id, bb);
+
+    // Set the value for |bb| to avoid an infinite recursion.
     WriteVariable(var_id, bb, phi_candidate.result_id());
     WriteVariable(var_id, bb, phi_candidate.result_id());
     val_id = AddPhiOperands(&phi_candidate);
     val_id = AddPhiOperands(&phi_candidate);
   }
   }

+ 3 - 0
3rdparty/spirv-tools/source/opt/ssa_rewrite_pass.h

@@ -188,6 +188,9 @@ class SSARewriter {
   // value |val_id|.
   // value |val_id|.
   void WriteVariable(uint32_t var_id, BasicBlock* bb, uint32_t val_id) {
   void WriteVariable(uint32_t var_id, BasicBlock* bb, uint32_t val_id) {
     defs_at_block_[bb][var_id] = val_id;
     defs_at_block_[bb][var_id] = val_id;
+    if (auto* pc = GetPhiCandidate(val_id)) {
+      pc->AddUser(bb->id());
+    }
   }
   }
 
 
   // Processes the store operation |inst| in basic block |bb|. This extracts
   // Processes the store operation |inst| in basic block |bb|. This extracts

+ 9 - 6
3rdparty/spirv-tools/source/val/function.cpp

@@ -317,13 +317,10 @@ int Function::GetBlockDepth(BasicBlock* bb) {
   if (!bb_dom || bb == bb_dom) {
   if (!bb_dom || bb == bb_dom) {
     // This block has no dominator, so it's at depth 0.
     // This block has no dominator, so it's at depth 0.
     block_depth_[bb] = 0;
     block_depth_[bb] = 0;
-  } else if (bb->is_type(kBlockTypeMerge)) {
-    // If this is a merge block, its depth is equal to the block before
-    // branching.
-    BasicBlock* header = merge_block_header_[bb];
-    assert(header);
-    block_depth_[bb] = GetBlockDepth(header);
   } else if (bb->is_type(kBlockTypeContinue)) {
   } else if (bb->is_type(kBlockTypeContinue)) {
+    // This rule must precede the rule for merge blocks in order to set up
+    // depths correctly. If a block is both a merge and continue then the merge
+    // is nested within the continue's loop (or the graph is incorrect).
     // The depth of the continue block entry point is 1 + loop header depth.
     // The depth of the continue block entry point is 1 + loop header depth.
     Construct* continue_construct =
     Construct* continue_construct =
         entry_block_to_construct_[std::make_pair(bb, ConstructType::kContinue)];
         entry_block_to_construct_[std::make_pair(bb, ConstructType::kContinue)];
@@ -341,6 +338,12 @@ int Function::GetBlockDepth(BasicBlock* bb) {
     } else {
     } else {
       block_depth_[bb] = 1 + GetBlockDepth(loop_header);
       block_depth_[bb] = 1 + GetBlockDepth(loop_header);
     }
     }
+  } else if (bb->is_type(kBlockTypeMerge)) {
+    // If this is a merge block, its depth is equal to the block before
+    // branching.
+    BasicBlock* header = merge_block_header_[bb];
+    assert(header);
+    block_depth_[bb] = GetBlockDepth(header);
   } else if (bb_dom->is_type(kBlockTypeHeader) ||
   } else if (bb_dom->is_type(kBlockTypeHeader) ||
              bb_dom->is_type(kBlockTypeLoop)) {
              bb_dom->is_type(kBlockTypeLoop)) {
     // The dominator of the given block is a header block. So, the nesting
     // The dominator of the given block is a header block. So, the nesting

+ 3 - 4
3rdparty/spirv-tools/source/val/validate_annotation.cpp

@@ -12,11 +12,10 @@
 // See the License for the specific language governing permissions and
 // See the License for the specific language governing permissions and
 // limitations under the License.
 // limitations under the License.
 
 
-#include "source/val/validate.h"
-
 #include "source/opcode.h"
 #include "source/opcode.h"
 #include "source/spirv_target_env.h"
 #include "source/spirv_target_env.h"
 #include "source/val/instruction.h"
 #include "source/val/instruction.h"
+#include "source/val/validate.h"
 #include "source/val/validation_state.h"
 #include "source/val/validation_state.h"
 
 
 namespace spvtools {
 namespace spvtools {
@@ -287,11 +286,11 @@ spv_result_t ValidateDecorationGroup(ValidationState_t& _,
     auto use = pair.first;
     auto use = pair.first;
     if (use->opcode() != SpvOpDecorate && use->opcode() != SpvOpGroupDecorate &&
     if (use->opcode() != SpvOpDecorate && use->opcode() != SpvOpGroupDecorate &&
         use->opcode() != SpvOpGroupMemberDecorate &&
         use->opcode() != SpvOpGroupMemberDecorate &&
-        use->opcode() != SpvOpName) {
+        use->opcode() != SpvOpName && use->opcode() != SpvOpDecorateId) {
       return _.diag(SPV_ERROR_INVALID_ID, inst)
       return _.diag(SPV_ERROR_INVALID_ID, inst)
              << "Result id of OpDecorationGroup can only "
              << "Result id of OpDecorationGroup can only "
              << "be targeted by OpName, OpGroupDecorate, "
              << "be targeted by OpName, OpGroupDecorate, "
-             << "OpDecorate, and OpGroupMemberDecorate";
+             << "OpDecorate, OpDecorateId, and OpGroupMemberDecorate";
     }
     }
   }
   }
   return SPV_SUCCESS;
   return SPV_SUCCESS;

+ 56 - 24
3rdparty/spirv-tools/source/val/validate_atomics.cpp

@@ -25,6 +25,28 @@
 #include "source/val/validate_scopes.h"
 #include "source/val/validate_scopes.h"
 #include "source/val/validation_state.h"
 #include "source/val/validation_state.h"
 
 
+namespace {
+
+bool IsStorageClassAllowedByUniversalRules(uint32_t storage_class) {
+  switch (storage_class) {
+    case SpvStorageClassUniform:
+    case SpvStorageClassStorageBuffer:
+    case SpvStorageClassWorkgroup:
+    case SpvStorageClassCrossWorkgroup:
+    case SpvStorageClassGeneric:
+    case SpvStorageClassAtomicCounter:
+    case SpvStorageClassImage:
+    case SpvStorageClassFunction:
+    case SpvStorageClassPhysicalStorageBufferEXT:
+      return true;
+      break;
+    default:
+      return false;
+  }
+}
+
+}  // namespace
+
 namespace spvtools {
 namespace spvtools {
 namespace val {
 namespace val {
 
 
@@ -119,32 +141,42 @@ spv_result_t AtomicsPass(ValidationState_t& _, const Instruction* inst) {
                << ": expected Pointer to be of type OpTypePointer";
                << ": expected Pointer to be of type OpTypePointer";
       }
       }
 
 
-      switch (storage_class) {
-        case SpvStorageClassUniform:
-        case SpvStorageClassWorkgroup:
-        case SpvStorageClassCrossWorkgroup:
-        case SpvStorageClassGeneric:
-        case SpvStorageClassAtomicCounter:
-        case SpvStorageClassImage:
-        case SpvStorageClassStorageBuffer:
-        case SpvStorageClassPhysicalStorageBufferEXT:
-          break;
-        default:
-          if (spvIsOpenCLEnv(_.context()->target_env)) {
-            if (storage_class != SpvStorageClassFunction) {
-              return _.diag(SPV_ERROR_INVALID_DATA, inst)
-                     << spvOpcodeString(opcode)
-                     << ": expected Pointer Storage Class to be Uniform, "
-                        "Workgroup, CrossWorkgroup, Generic, AtomicCounter, "
-                        "Image, StorageBuffer or Function";
-            }
-          } else {
+      // Validate storage class against universal rules
+      if (!IsStorageClassAllowedByUniversalRules(storage_class)) {
+        return _.diag(SPV_ERROR_INVALID_DATA, inst)
+               << spvOpcodeString(opcode)
+               << ": storage class forbidden by universal validation rules.";
+      }
+
+      // Then Shader rules
+      if (_.HasCapability(SpvCapabilityShader)) {
+        if (storage_class == SpvStorageClassFunction) {
+          return _.diag(SPV_ERROR_INVALID_DATA, inst)
+                 << spvOpcodeString(opcode)
+                 << ": Function storage class forbidden when the Shader "
+                    "capability is declared.";
+        }
+      }
+
+      // And finally OpenCL environment rules
+      if (spvIsOpenCLEnv(_.context()->target_env)) {
+        if ((storage_class != SpvStorageClassFunction) &&
+            (storage_class != SpvStorageClassWorkgroup) &&
+            (storage_class != SpvStorageClassCrossWorkgroup) &&
+            (storage_class != SpvStorageClassGeneric)) {
+          return _.diag(SPV_ERROR_INVALID_DATA, inst)
+                 << spvOpcodeString(opcode)
+                 << ": storage class must be Function, Workgroup, "
+                    "CrossWorkGroup or Generic in the OpenCL environment.";
+        }
+
+        if (_.context()->target_env == SPV_ENV_OPENCL_1_2) {
+          if (storage_class == SpvStorageClassGeneric) {
             return _.diag(SPV_ERROR_INVALID_DATA, inst)
             return _.diag(SPV_ERROR_INVALID_DATA, inst)
-                   << spvOpcodeString(opcode)
-                   << ": expected Pointer Storage Class to be Uniform, "
-                      "Workgroup, CrossWorkgroup, Generic, AtomicCounter, "
-                      "Image or StorageBuffer";
+                   << "Storage class cannot be Generic in OpenCL 1.2 "
+                      "environment";
           }
           }
+        }
       }
       }
 
 
       if (opcode == SpvOpAtomicFlagTestAndSet ||
       if (opcode == SpvOpAtomicFlagTestAndSet ||

+ 39 - 26
3rdparty/spirv-tools/source/val/validate_cfg.cpp

@@ -493,41 +493,54 @@ spv_result_t StructuredSwitchChecks(ValidationState_t& _, Function* function,
   std::map<uint32_t, uint32_t> num_fall_through_targeted;
   std::map<uint32_t, uint32_t> num_fall_through_targeted;
   uint32_t default_case_fall_through = 0u;
   uint32_t default_case_fall_through = 0u;
   uint32_t default_target = switch_inst->GetOperandAs<uint32_t>(1u);
   uint32_t default_target = switch_inst->GetOperandAs<uint32_t>(1u);
-  std::unordered_set<uint32_t> seen;
+  bool default_appears_multiple_times = false;
+  for (uint32_t i = 3; i < switch_inst->operands().size(); i += 2) {
+    if (default_target == switch_inst->GetOperandAs<uint32_t>(i)) {
+      default_appears_multiple_times = true;
+      break;
+    }
+  }
+  std::unordered_map<uint32_t, uint32_t> seen_to_fall_through;
   for (uint32_t i = 1; i < switch_inst->operands().size(); i += 2) {
   for (uint32_t i = 1; i < switch_inst->operands().size(); i += 2) {
     uint32_t target = switch_inst->GetOperandAs<uint32_t>(i);
     uint32_t target = switch_inst->GetOperandAs<uint32_t>(i);
     if (target == merge->id()) continue;
     if (target == merge->id()) continue;
 
 
-    if (!seen.insert(target).second) continue;
-
-    const auto target_block = function->GetBlock(target).first;
-    // OpSwitch must dominate all its case constructs.
-    if (header->reachable() && target_block->reachable() &&
-        !header->dominates(*target_block)) {
-      return _.diag(SPV_ERROR_INVALID_CFG, header->label())
-             << "Selection header " << _.getIdName(header->id())
-             << " does not dominate its case construct " << _.getIdName(target);
-    }
-
     uint32_t case_fall_through = 0u;
     uint32_t case_fall_through = 0u;
-    if (auto error = FindCaseFallThrough(_, target_block, &case_fall_through,
-                                         merge, case_targets, function)) {
-      return error;
-    }
+    auto seen_iter = seen_to_fall_through.find(target);
+    if (seen_iter == seen_to_fall_through.end()) {
+      const auto target_block = function->GetBlock(target).first;
+      // OpSwitch must dominate all its case constructs.
+      if (header->reachable() && target_block->reachable() &&
+          !header->dominates(*target_block)) {
+        return _.diag(SPV_ERROR_INVALID_CFG, header->label())
+               << "Selection header " << _.getIdName(header->id())
+               << " does not dominate its case construct "
+               << _.getIdName(target);
+      }
 
 
-    // Track how many time the fall through case has been targeted.
-    if (case_fall_through != 0u) {
-      auto where = num_fall_through_targeted.lower_bound(case_fall_through);
-      if (where == num_fall_through_targeted.end() ||
-          where->first != case_fall_through) {
-        num_fall_through_targeted.insert(where,
-                                         std::make_pair(case_fall_through, 1));
-      } else {
-        where->second++;
+      if (auto error = FindCaseFallThrough(_, target_block, &case_fall_through,
+                                           merge, case_targets, function)) {
+        return error;
       }
       }
+
+      // Track how many time the fall through case has been targeted.
+      if (case_fall_through != 0u) {
+        auto where = num_fall_through_targeted.lower_bound(case_fall_through);
+        if (where == num_fall_through_targeted.end() ||
+            where->first != case_fall_through) {
+          num_fall_through_targeted.insert(
+              where, std::make_pair(case_fall_through, 1));
+        } else {
+          where->second++;
+        }
+      }
+      seen_to_fall_through.insert(std::make_pair(target, case_fall_through));
+    } else {
+      case_fall_through = seen_iter->second;
     }
     }
 
 
-    if (case_fall_through == default_target) {
+    if (case_fall_through == default_target &&
+        !default_appears_multiple_times) {
       case_fall_through = default_case_fall_through;
       case_fall_through = default_case_fall_through;
     }
     }
     if (case_fall_through != 0u) {
     if (case_fall_through != 0u) {

+ 38 - 30
3rdparty/spirv-tools/source/val/validate_derivatives.cpp

@@ -53,37 +53,45 @@ spv_result_t DerivativesPass(ValidationState_t& _, const Instruction* inst) {
                << "Expected P type and Result Type to be the same: "
                << "Expected P type and Result Type to be the same: "
                << spvOpcodeString(opcode);
                << spvOpcodeString(opcode);
       }
       }
-
-      const spvtools::Extension compute_shader_derivatives_extension =
-          kSPV_NV_compute_shader_derivatives;
-      ExtensionSet exts(1, &compute_shader_derivatives_extension);
-
-      if (_.HasAnyOfExtensions(exts)) {
-        _.function(inst->function()->id())
-            ->RegisterExecutionModelLimitation([opcode](SpvExecutionModel model,
-                                                        std::string* message) {
-              if (model != SpvExecutionModelFragment &&
-                  model != SpvExecutionModelGLCompute) {
-                if (message) {
-                  *message =
-                      std::string(
-                          "Derivative instructions require Fragment execution "
-                          "model: ") +
-                      spvOpcodeString(opcode);
-                }
-                return false;
+      _.function(inst->function()->id())
+          ->RegisterExecutionModelLimitation([opcode](SpvExecutionModel model,
+                                                      std::string* message) {
+            if (model != SpvExecutionModelFragment &&
+                model != SpvExecutionModelGLCompute) {
+              if (message) {
+                *message =
+                    std::string(
+                        "Derivative instructions require Fragment or GLCompute "
+                        "execution model: ") +
+                    spvOpcodeString(opcode);
               }
               }
-              return true;
-            });
-      } else {
-        _.function(inst->function()->id())
-            ->RegisterExecutionModelLimitation(
-                SpvExecutionModelFragment,
-                std::string(
-                    "Derivative instructions require Fragment execution "
-                    "model: ") +
-                    spvOpcodeString(opcode));
-      }
+              return false;
+            }
+            return true;
+          });
+      _.function(inst->function()->id())
+          ->RegisterLimitation([opcode](const ValidationState_t& state,
+                                        const Function* entry_point,
+                                        std::string* message) {
+            const auto* models = state.GetExecutionModels(entry_point->id());
+            const auto* modes = state.GetExecutionModes(entry_point->id());
+            if (models->find(SpvExecutionModelGLCompute) != models->end() &&
+                modes->find(SpvExecutionModeDerivativeGroupLinearNV) ==
+                    modes->end() &&
+                modes->find(SpvExecutionModeDerivativeGroupQuadsNV) ==
+                    modes->end()) {
+              if (message) {
+                *message = std::string(
+                               "Derivative instructions require "
+                               "DerivativeGroupQuadsNV "
+                               "or DerivativeGroupLinearNV execution mode for "
+                               "GLCompute execution model: ") +
+                           spvOpcodeString(opcode);
+              }
+              return false;
+            }
+            return true;
+          });
       break;
       break;
     }
     }
 
 

+ 71 - 5
3rdparty/spirv-tools/source/val/validate_image.cpp

@@ -1710,8 +1710,39 @@ spv_result_t ValidateImageQueryLod(ValidationState_t& _,
                                    const Instruction* inst) {
                                    const Instruction* inst) {
   _.function(inst->function()->id())
   _.function(inst->function()->id())
       ->RegisterExecutionModelLimitation(
       ->RegisterExecutionModelLimitation(
-          SpvExecutionModelFragment,
-          "OpImageQueryLod requires Fragment execution model");
+          [&](SpvExecutionModel model, std::string* message) {
+            if (model != SpvExecutionModelFragment &&
+                model != SpvExecutionModelGLCompute) {
+              if (message) {
+                *message = std::string(
+                    "OpImageQueryLod requires Fragment or GLCompute execution "
+                    "model");
+              }
+              return false;
+            }
+            return true;
+          });
+  _.function(inst->function()->id())
+      ->RegisterLimitation([](const ValidationState_t& state,
+                              const Function* entry_point,
+                              std::string* message) {
+        const auto* models = state.GetExecutionModels(entry_point->id());
+        const auto* modes = state.GetExecutionModes(entry_point->id());
+        if (models->find(SpvExecutionModelGLCompute) != models->end() &&
+            modes->find(SpvExecutionModeDerivativeGroupLinearNV) ==
+                modes->end() &&
+            modes->find(SpvExecutionModeDerivativeGroupQuadsNV) ==
+                modes->end()) {
+          if (message) {
+            *message = std::string(
+                "OpImageQueryLod requires DerivativeGroupQuadsNV "
+                "or DerivativeGroupLinearNV execution mode for GLCompute "
+                "execution model");
+          }
+          return false;
+        }
+        return true;
+      });
 
 
   const uint32_t result_type = inst->type_id();
   const uint32_t result_type = inst->type_id();
   if (!_.IsFloatVectorType(result_type)) {
   if (!_.IsFloatVectorType(result_type)) {
@@ -1835,9 +1866,44 @@ spv_result_t ImagePass(ValidationState_t& _, const Instruction* inst) {
   const SpvOp opcode = inst->opcode();
   const SpvOp opcode = inst->opcode();
   if (IsImplicitLod(opcode)) {
   if (IsImplicitLod(opcode)) {
     _.function(inst->function()->id())
     _.function(inst->function()->id())
-        ->RegisterExecutionModelLimitation(
-            SpvExecutionModelFragment,
-            "ImplicitLod instructions require Fragment execution model");
+        ->RegisterExecutionModelLimitation([opcode](SpvExecutionModel model,
+                                                    std::string* message) {
+          if (model != SpvExecutionModelFragment &&
+              model != SpvExecutionModelGLCompute) {
+            if (message) {
+              *message =
+                  std::string(
+                      "ImplicitLod instructions require Fragment or GLCompute "
+                      "execution model: ") +
+                  spvOpcodeString(opcode);
+            }
+            return false;
+          }
+          return true;
+        });
+    _.function(inst->function()->id())
+        ->RegisterLimitation([opcode](const ValidationState_t& state,
+                                      const Function* entry_point,
+                                      std::string* message) {
+          const auto* models = state.GetExecutionModels(entry_point->id());
+          const auto* modes = state.GetExecutionModes(entry_point->id());
+          if (models->find(SpvExecutionModelGLCompute) != models->end() &&
+              modes->find(SpvExecutionModeDerivativeGroupLinearNV) ==
+                  modes->end() &&
+              modes->find(SpvExecutionModeDerivativeGroupQuadsNV) ==
+                  modes->end()) {
+            if (message) {
+              *message =
+                  std::string(
+                      "ImplicitLod instructions require DerivativeGroupQuadsNV "
+                      "or DerivativeGroupLinearNV execution mode for GLCompute "
+                      "execution model: ") +
+                  spvOpcodeString(opcode);
+            }
+            return false;
+          }
+          return true;
+        });
   }
   }
 
 
   switch (opcode) {
   switch (opcode) {

+ 56 - 0
3rdparty/spirv-tools/test/opt/aggressive_dead_code_elim_test.cpp

@@ -6560,6 +6560,62 @@ OpFunctionEnd
   SinglePassRunAndMatch<AggressiveDCEPass>(spirv, true);
   SinglePassRunAndMatch<AggressiveDCEPass>(spirv, true);
 }
 }
 
 
+TEST_F(AggressiveDCETest, LiveDecorateId) {
+  const std::string spirv = R"(OpCapability Shader
+OpMemoryModel Logical GLSL450
+OpEntryPoint GLCompute %1 "main" %2
+OpExecutionMode %1 LocalSize 8 1 1
+OpDecorate %2 DescriptorSet 0
+OpDecorate %2 Binding 0
+OpDecorateId %3 UniformId %uint_2
+%void = OpTypeVoid
+%uint = OpTypeInt 32 0
+%uint_2 = OpConstant %uint 2
+%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
+%2 = OpVariable %_ptr_StorageBuffer_uint StorageBuffer
+%8 = OpTypeFunction %void
+%1 = OpFunction %void None %8
+%9 = OpLabel
+%3 = OpLoad %uint %2
+OpStore %2 %3
+OpReturn
+OpFunctionEnd
+)";
+
+  SetTargetEnv(SPV_ENV_UNIVERSAL_1_4);
+  OptimizerOptions()->preserve_spec_constants_ = true;
+  SinglePassRunAndCheck<AggressiveDCEPass>(spirv, spirv, true);
+}
+
+TEST_F(AggressiveDCETest, LiveDecorateIdOnGroup) {
+  const std::string spirv = R"(OpCapability Shader
+OpMemoryModel Logical GLSL450
+OpEntryPoint GLCompute %1 "main" %2
+OpExecutionMode %1 LocalSize 8 1 1
+OpDecorate %2 DescriptorSet 0
+OpDecorate %2 Binding 0
+OpDecorateId %3 UniformId %uint_2
+%3 = OpDecorationGroup
+OpGroupDecorate %3 %5
+%void = OpTypeVoid
+%uint = OpTypeInt 32 0
+%uint_2 = OpConstant %uint 2
+%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
+%2 = OpVariable %_ptr_StorageBuffer_uint StorageBuffer
+%9 = OpTypeFunction %void
+%1 = OpFunction %void None %9
+%10 = OpLabel
+%5 = OpLoad %uint %2
+OpStore %2 %5
+OpReturn
+OpFunctionEnd
+)";
+
+  SetTargetEnv(SPV_ENV_UNIVERSAL_1_4);
+  OptimizerOptions()->preserve_spec_constants_ = true;
+  SinglePassRunAndCheck<AggressiveDCEPass>(spirv, spirv, true);
+}
+
 // TODO(greg-lunarg): Add tests to verify handling of these cases:
 // TODO(greg-lunarg): Add tests to verify handling of these cases:
 //
 //
 //    Check that logical addressing required
 //    Check that logical addressing required

+ 30 - 28
3rdparty/spirv-tools/test/opt/inst_bindless_check_test.cpp

@@ -255,7 +255,7 @@ OpFunctionEnd
           func_pt2_before,
           func_pt2_before,
       entry_after + names_annots + new_annots + consts_types_vars +
       entry_after + names_annots + new_annots + consts_types_vars +
           new_consts_types_vars + func_pt1 + func_pt2_after + output_func,
           new_consts_types_vars + func_pt1 + func_pt2_after + output_func,
-      true, true);
+      true, true, 7u, 23u, false, false, 1u);
 }
 }
 
 
 TEST_F(InstBindlessTest, NoInstrumentConstIndexInbounds) {
 TEST_F(InstBindlessTest, NoInstrumentConstIndexInbounds) {
@@ -335,7 +335,8 @@ OpFunctionEnd
 )";
 )";
 
 
   SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
   SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  SinglePassRunAndCheck<InstBindlessCheckPass>(before, before, true, true);
+  SinglePassRunAndCheck<InstBindlessCheckPass>(before, before, true, true, 7u,
+                                               23u, false, false, 1u);
 }
 }
 
 
 TEST_F(InstBindlessTest, InstrumentMultipleInstructions) {
 TEST_F(InstBindlessTest, InstrumentMultipleInstructions) {
@@ -630,7 +631,7 @@ OpFunctionEnd
   SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
   SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
   SinglePassRunAndCheck<InstBindlessCheckPass>(
   SinglePassRunAndCheck<InstBindlessCheckPass>(
       defs_before + func_before, defs_after + func_after + output_func, true,
       defs_before + func_before, defs_after + func_after + output_func, true,
-      true);
+      true, 7u, 23u, false, false, 1u);
 }
 }
 
 
 TEST_F(InstBindlessTest, InstrumentOpImage) {
 TEST_F(InstBindlessTest, InstrumentOpImage) {
@@ -858,7 +859,7 @@ OpFunctionEnd
   // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
   // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
   SinglePassRunAndCheck<InstBindlessCheckPass>(
   SinglePassRunAndCheck<InstBindlessCheckPass>(
       defs_before + func_before, defs_after + func_after + output_func, true,
       defs_before + func_before, defs_after + func_after + output_func, true,
-      true);
+      true, 7u, 23u, false, false, 1u);
 }
 }
 
 
 TEST_F(InstBindlessTest, InstrumentSampledImage) {
 TEST_F(InstBindlessTest, InstrumentSampledImage) {
@@ -1081,7 +1082,7 @@ OpFunctionEnd
   // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
   // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
   SinglePassRunAndCheck<InstBindlessCheckPass>(
   SinglePassRunAndCheck<InstBindlessCheckPass>(
       defs_before + func_before, defs_after + func_after + output_func, true,
       defs_before + func_before, defs_after + func_after + output_func, true,
-      true);
+      true, 7u, 23u, false, false, 1u);
 }
 }
 
 
 TEST_F(InstBindlessTest, InstrumentImageWrite) {
 TEST_F(InstBindlessTest, InstrumentImageWrite) {
@@ -1306,7 +1307,7 @@ OpFunctionEnd
   // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
   // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
   SinglePassRunAndCheck<InstBindlessCheckPass>(
   SinglePassRunAndCheck<InstBindlessCheckPass>(
       defs_before + func_before, defs_after + func_after + output_func, true,
       defs_before + func_before, defs_after + func_after + output_func, true,
-      true);
+      true, 7u, 23u, false, false, 1u);
 }
 }
 
 
 TEST_F(InstBindlessTest, InstrumentVertexSimple) {
 TEST_F(InstBindlessTest, InstrumentVertexSimple) {
@@ -1580,7 +1581,7 @@ OpFunctionEnd
   // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
   // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
   SinglePassRunAndCheck<InstBindlessCheckPass>(
   SinglePassRunAndCheck<InstBindlessCheckPass>(
       defs_before + func_before, defs_after + func_after + output_func, true,
       defs_before + func_before, defs_after + func_after + output_func, true,
-      true);
+      true, 7u, 23u, false, false, 1u);
 }
 }
 
 
 TEST_F(InstBindlessTest, MultipleDebugFunctions) {
 TEST_F(InstBindlessTest, MultipleDebugFunctions) {
@@ -1903,7 +1904,8 @@ OpFunctionEnd
   // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
   // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
   SinglePassRunAndCheck<InstBindlessCheckPass>(
   SinglePassRunAndCheck<InstBindlessCheckPass>(
       defs_before + func1_before + func2_before,
       defs_before + func1_before + func2_before,
-      defs_after + func1_after + func2_after + output_func, true, true);
+      defs_after + func1_after + func2_after + output_func, true, true, 7u, 23u,
+      false, false, 1u);
 }
 }
 
 
 TEST_F(InstBindlessTest, RuntimeArray) {
 TEST_F(InstBindlessTest, RuntimeArray) {
@@ -2276,18 +2278,19 @@ OpFunctionEnd
 
 
   // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
   // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
   SinglePassRunAndCheck<InstBindlessCheckPass>(whole_file, whole_file, true,
   SinglePassRunAndCheck<InstBindlessCheckPass>(whole_file, whole_file, true,
-                                               true);
+                                               true, 7u, 23u, false, false, 1u);
 }
 }
 
 
 TEST_F(InstBindlessTest, InstrumentInitCheckOnScalarDescriptor) {
 TEST_F(InstBindlessTest, InstrumentInitCheckOnScalarDescriptor) {
   // This test verifies that the pass will correctly instrument vanilla
   // This test verifies that the pass will correctly instrument vanilla
   // texture sample on a scalar descriptor with an initialization check if the
   // texture sample on a scalar descriptor with an initialization check if the
-  // SPV_EXT_descriptor_checking extension is enabled. This is the same shader
-  // as NoInstrumentNonBindless, but with the extension hacked on in the SPIR-V.
+  // input_init_enable argument is set to true. This can happen when the
+  // descriptor indexing extension is enabled in the API but the SPIR-V
+  // does not have the extension enabled because it does not contain a
+  // runtime array. This is the same shader as NoInstrumentNonBindless.
 
 
   const std::string defs_before =
   const std::string defs_before =
       R"(OpCapability Shader
       R"(OpCapability Shader
-OpExtension "SPV_EXT_descriptor_indexing"
 %1 = OpExtInstImport "GLSL.std.450"
 %1 = OpExtInstImport "GLSL.std.450"
 OpMemoryModel Logical GLSL450
 OpMemoryModel Logical GLSL450
 OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor
 OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor
@@ -2324,7 +2327,6 @@ OpDecorate %_entryPointOutput_vColor Location 0
 
 
   const std::string defs_after =
   const std::string defs_after =
       R"(OpCapability Shader
       R"(OpCapability Shader
-OpExtension "SPV_EXT_descriptor_indexing"
 OpExtension "SPV_KHR_storage_buffer_storage_class"
 OpExtension "SPV_KHR_storage_buffer_storage_class"
 %1 = OpExtInstImport "GLSL.std.450"
 %1 = OpExtInstImport "GLSL.std.450"
 OpMemoryModel Logical GLSL450
 OpMemoryModel Logical GLSL450
@@ -2395,7 +2397,7 @@ OpDecorate %gl_FragCoord BuiltIn FragCoord
 %uint_6 = OpConstant %uint 6
 %uint_6 = OpConstant %uint 6
 %uint_7 = OpConstant %uint 7
 %uint_7 = OpConstant %uint 7
 %uint_8 = OpConstant %uint 8
 %uint_8 = OpConstant %uint 8
-%uint_40 = OpConstant %uint 40
+%uint_39 = OpConstant %uint 39
 %113 = OpConstantNull %v4float
 %113 = OpConstantNull %v4float
 )";
 )";
 
 
@@ -2429,7 +2431,7 @@ OpBranchConditional %52 %55 %56
 %59 = OpImageSampleImplicitLod %v4float %58 %20
 %59 = OpImageSampleImplicitLod %v4float %58 %20
 OpBranch %54
 OpBranch %54
 %56 = OpLabel
 %56 = OpLabel
-%112 = OpFunctionCall %void %60 %uint_40 %uint_1 %uint_0 %uint_0
+%112 = OpFunctionCall %void %60 %uint_39 %uint_1 %uint_0 %uint_0
 OpBranch %54
 OpBranch %54
 %54 = OpLabel
 %54 = OpLabel
 %114 = OpPhi %v4float %59 %55 %113 %56
 %114 = OpPhi %v4float %59 %55 %113 %56
@@ -4456,7 +4458,7 @@ OpFunctionEnd
           func_pt2_before,
           func_pt2_before,
       entry_after + names_annots + new_annots + consts_types_vars +
       entry_after + names_annots + new_annots + consts_types_vars +
           new_consts_types_vars + func_pt1 + func_pt2_after + output_func,
           new_consts_types_vars + func_pt1 + func_pt2_after + output_func,
-      true, true, 7u, 23u, true, true, 2u);
+      true, true, 7u, 23u, false, false, 2u);
 }
 }
 
 
 TEST_F(InstBindlessTest, InstrumentMultipleInstructionsV2) {
 TEST_F(InstBindlessTest, InstrumentMultipleInstructionsV2) {
@@ -4751,7 +4753,7 @@ OpFunctionEnd
   SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
   SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
   SinglePassRunAndCheck<InstBindlessCheckPass>(
   SinglePassRunAndCheck<InstBindlessCheckPass>(
       defs_before + func_before, defs_after + func_after + output_func, true,
       defs_before + func_before, defs_after + func_after + output_func, true,
-      true, 7u, 23u, true, true, 2u);
+      true, 7u, 23u, false, false, 2u);
 }
 }
 
 
 TEST_F(InstBindlessTest, InstrumentOpImageV2) {
 TEST_F(InstBindlessTest, InstrumentOpImageV2) {
@@ -4979,7 +4981,7 @@ OpFunctionEnd
   // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
   // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
   SinglePassRunAndCheck<InstBindlessCheckPass>(
   SinglePassRunAndCheck<InstBindlessCheckPass>(
       defs_before + func_before, defs_after + func_after + output_func, true,
       defs_before + func_before, defs_after + func_after + output_func, true,
-      true, 7u, 23u, true, true, 2u);
+      true, 7u, 23u, false, false, 2u);
 }
 }
 
 
 TEST_F(InstBindlessTest, InstrumentSampledImageV2) {
 TEST_F(InstBindlessTest, InstrumentSampledImageV2) {
@@ -5202,7 +5204,7 @@ OpFunctionEnd
   // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
   // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
   SinglePassRunAndCheck<InstBindlessCheckPass>(
   SinglePassRunAndCheck<InstBindlessCheckPass>(
       defs_before + func_before, defs_after + func_after + output_func, true,
       defs_before + func_before, defs_after + func_after + output_func, true,
-      true, 7u, 23u, true, true, 2u);
+      true, 7u, 23u, false, false, 2u);
 }
 }
 
 
 TEST_F(InstBindlessTest, InstrumentImageWriteV2) {
 TEST_F(InstBindlessTest, InstrumentImageWriteV2) {
@@ -5427,7 +5429,7 @@ OpFunctionEnd
   // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
   // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
   SinglePassRunAndCheck<InstBindlessCheckPass>(
   SinglePassRunAndCheck<InstBindlessCheckPass>(
       defs_before + func_before, defs_after + func_after + output_func, true,
       defs_before + func_before, defs_after + func_after + output_func, true,
-      true, 7u, 23u, true, true, 2u);
+      true, 7u, 23u, false, false, 2u);
 }
 }
 
 
 TEST_F(InstBindlessTest, InstrumentVertexSimpleV2) {
 TEST_F(InstBindlessTest, InstrumentVertexSimpleV2) {
@@ -5701,7 +5703,7 @@ OpFunctionEnd
   // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
   // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
   SinglePassRunAndCheck<InstBindlessCheckPass>(
   SinglePassRunAndCheck<InstBindlessCheckPass>(
       defs_before + func_before, defs_after + func_after + output_func, true,
       defs_before + func_before, defs_after + func_after + output_func, true,
-      true, 7u, 23u, true, true, 2u);
+      true, 7u, 23u, false, false, 2u);
 }
 }
 
 
 TEST_F(InstBindlessTest, MultipleDebugFunctionsV2) {
 TEST_F(InstBindlessTest, MultipleDebugFunctionsV2) {
@@ -6025,7 +6027,7 @@ OpFunctionEnd
   SinglePassRunAndCheck<InstBindlessCheckPass>(
   SinglePassRunAndCheck<InstBindlessCheckPass>(
       defs_before + func1_before + func2_before,
       defs_before + func1_before + func2_before,
       defs_after + func1_after + func2_after + output_func, true, true, 7u, 23u,
       defs_after + func1_after + func2_after + output_func, true, true, 7u, 23u,
-      true, true, 2u);
+      false, false, 2u);
 }
 }
 
 
 TEST_F(InstBindlessTest, RuntimeArrayV2) {
 TEST_F(InstBindlessTest, RuntimeArrayV2) {
@@ -6327,12 +6329,13 @@ OpFunctionEnd
 TEST_F(InstBindlessTest, InstrumentInitCheckOnScalarDescriptorV2) {
 TEST_F(InstBindlessTest, InstrumentInitCheckOnScalarDescriptorV2) {
   // This test verifies that the pass will correctly instrument vanilla
   // This test verifies that the pass will correctly instrument vanilla
   // texture sample on a scalar descriptor with an initialization check if the
   // texture sample on a scalar descriptor with an initialization check if the
-  // SPV_EXT_descriptor_checking extension is enabled. This is the same shader
-  // as NoInstrumentNonBindless, but with the extension hacked on in the SPIR-V.
+  // input_init_enable argument is set to true. This can happen when the
+  // descriptor indexing extension is enabled in the API but the SPIR-V
+  // does not have the extension enabled because it does not contain a
+  // runtime array. This is the same shader as NoInstrumentNonBindless.
 
 
   const std::string defs_before =
   const std::string defs_before =
       R"(OpCapability Shader
       R"(OpCapability Shader
-OpExtension "SPV_EXT_descriptor_indexing"
 %1 = OpExtInstImport "GLSL.std.450"
 %1 = OpExtInstImport "GLSL.std.450"
 OpMemoryModel Logical GLSL450
 OpMemoryModel Logical GLSL450
 OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor
 OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor
@@ -6369,7 +6372,6 @@ OpDecorate %_entryPointOutput_vColor Location 0
 
 
   const std::string defs_after =
   const std::string defs_after =
       R"(OpCapability Shader
       R"(OpCapability Shader
-OpExtension "SPV_EXT_descriptor_indexing"
 OpExtension "SPV_KHR_storage_buffer_storage_class"
 OpExtension "SPV_KHR_storage_buffer_storage_class"
 %1 = OpExtInstImport "GLSL.std.450"
 %1 = OpExtInstImport "GLSL.std.450"
 OpMemoryModel Logical GLSL450
 OpMemoryModel Logical GLSL450
@@ -6440,7 +6442,7 @@ OpDecorate %gl_FragCoord BuiltIn FragCoord
 %uint_7 = OpConstant %uint 7
 %uint_7 = OpConstant %uint 7
 %uint_8 = OpConstant %uint 8
 %uint_8 = OpConstant %uint 8
 %uint_9 = OpConstant %uint 9
 %uint_9 = OpConstant %uint 9
-%uint_40 = OpConstant %uint 40
+%uint_39 = OpConstant %uint 39
 %113 = OpConstantNull %v4float
 %113 = OpConstantNull %v4float
 )";
 )";
 
 
@@ -6474,7 +6476,7 @@ OpBranchConditional %52 %55 %56
 %59 = OpImageSampleImplicitLod %v4float %58 %20
 %59 = OpImageSampleImplicitLod %v4float %58 %20
 OpBranch %54
 OpBranch %54
 %56 = OpLabel
 %56 = OpLabel
-%112 = OpFunctionCall %void %60 %uint_40 %uint_1 %uint_0 %uint_0
+%112 = OpFunctionCall %void %60 %uint_39 %uint_1 %uint_0 %uint_0
 OpBranch %54
 OpBranch %54
 %54 = OpLabel
 %54 = OpLabel
 %114 = OpPhi %v4float %59 %55 %113 %56
 %114 = OpPhi %v4float %59 %55 %113 %56

+ 57 - 0
3rdparty/spirv-tools/test/opt/local_ssa_elim_test.cpp

@@ -1930,6 +1930,63 @@ TEST_F(LocalSSAElimTest, VariablePointerTest2) {
   SinglePassRunAndMatch<LocalMultiStoreElimPass>(text, false);
   SinglePassRunAndMatch<LocalMultiStoreElimPass>(text, false);
 }
 }
 
 
+TEST_F(LocalSSAElimTest, ChainedTrivialPhis) {
+  // Check that the copy object get the undef value implicitly assigned in the
+  // entry block.
+  const std::string text = R"(
+; CHECK: [[undef:%\w+]] = OpUndef %v4float
+; CHECK: OpCopyObject %v4float [[undef]]
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint GLCompute %2 "main"
+               OpExecutionMode %2 LocalSize 1 18 6
+               OpSource ESSL 310
+       %void = OpTypeVoid
+          %4 = OpTypeFunction %void
+       %bool = OpTypeBool
+      %float = OpTypeFloat 32
+    %v4float = OpTypeVector %float 4
+%_ptr_Function_v4float = OpTypePointer Function %v4float
+          %2 = OpFunction %void None %4
+          %9 = OpLabel
+         %10 = OpVariable %_ptr_Function_v4float Function
+               OpBranch %11
+         %11 = OpLabel
+               OpLoopMerge %12 %13 None
+               OpBranch %14
+         %14 = OpLabel
+         %15 = OpUndef %bool
+               OpBranchConditional %15 %16 %12
+         %16 = OpLabel
+         %17 = OpUndef %bool
+               OpSelectionMerge %18 None
+               OpBranchConditional %17 %19 %18
+         %19 = OpLabel
+         %20 = OpUndef %bool
+               OpLoopMerge %21 %22 None
+               OpBranchConditional %20 %23 %21
+         %23 = OpLabel
+         %24 = OpLoad %v4float %10
+         %25 = OpCopyObject %v4float %24
+         %26 = OpUndef %bool
+               OpBranch %22
+         %22 = OpLabel
+               OpBranch %19
+         %21 = OpLabel
+               OpBranch %12
+         %18 = OpLabel
+               OpBranch %13
+         %13 = OpLabel
+               OpBranch %11
+         %12 = OpLabel
+         %27 = OpLoad %v4float %10
+               OpReturn
+               OpFunctionEnd
+  )";
+  SinglePassRunAndMatch<SSARewritePass>(text, false);
+}
+
 // TODO(greg-lunarg): Add tests to verify handling of these cases:
 // TODO(greg-lunarg): Add tests to verify handling of these cases:
 //
 //
 //    No optimization in the presence of
 //    No optimization in the presence of

+ 51 - 0
3rdparty/spirv-tools/test/opt/pass_merge_return_test.cpp

@@ -1779,6 +1779,57 @@ TEST_F(MergeReturnPassTest, MergeToMergeBranch) {
   SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
   SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
   SinglePassRunAndMatch<MergeReturnPass>(text, true);
   SinglePassRunAndMatch<MergeReturnPass>(text, true);
 }
 }
+TEST_F(MergeReturnPassTest, PhiInSecondMerge) {
+  //  Add and use a phi in the second merge block from the return.
+  const std::string text =
+      R"(
+; CHECK: OpLoopMerge
+; CHECK: OpLoopMerge [[merge_bb:%\w+]] [[continue_bb:%\w+]]
+; CHECK: [[continue_bb]] = OpLabel
+; CHECK-NEXT: [[val:%\w+]] = OpUndef %float
+; CHECK: [[merge_bb]] = OpLabel
+; CHECK-NEXT: [[phi:%\w+]] = OpPhi %float {{%\w+}} {{%\w+}} [[val]] [[continue_bb]]
+; CHECK-NOT: OpLabel
+; CHECK: OpBranchConditional {{%\w+}} {{%\w+}} [[old_merge:%\w+]]
+; CHECK: [[old_merge]] = OpLabel
+; CHECK-NEXT: OpConvertFToS %int [[phi]]
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %2 "main"
+               OpExecutionMode %2 OriginUpperLeft
+               OpSource ESSL 310
+       %void = OpTypeVoid
+          %4 = OpTypeFunction %void
+        %int = OpTypeInt 32 1
+      %float = OpTypeFloat 32
+       %bool = OpTypeBool
+          %8 = OpUndef %bool
+          %2 = OpFunction %void None %4
+          %9 = OpLabel
+               OpBranch %10
+         %10 = OpLabel
+               OpLoopMerge %11 %12 None
+               OpBranch %13
+         %13 = OpLabel
+               OpLoopMerge %12 %14 None
+               OpBranchConditional %8 %15 %12
+         %15 = OpLabel
+               OpReturn
+         %14 = OpLabel
+               OpBranch %13
+         %12 = OpLabel
+         %16 = OpUndef %float
+               OpBranchConditional %8 %10 %11
+         %11 = OpLabel
+         %17 = OpConvertFToS %int %16
+               OpReturn
+               OpFunctionEnd
+)";
+
+  SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
+  SinglePassRunAndMatch<MergeReturnPass>(text, true);
+}
 
 
 }  // namespace
 }  // namespace
 }  // namespace opt
 }  // namespace opt

+ 0 - 2
3rdparty/spirv-tools/test/scripts/test_compact_ids.py

@@ -14,8 +14,6 @@
 # limitations under the License.
 # limitations under the License.
 """Tests correctness of opt pass tools/opt --compact-ids."""
 """Tests correctness of opt pass tools/opt --compact-ids."""
 
 
-from __future__ import print_function
-
 import os.path
 import os.path
 import sys
 import sys
 import tempfile
 import tempfile

+ 0 - 2
3rdparty/spirv-tools/test/tools/spirv_test_framework.py

@@ -44,8 +44,6 @@ If --leave-output was not specified, all temporary files and directories will
 be deleted.
 be deleted.
 """
 """
 
 
-from __future__ import print_function
-
 import argparse
 import argparse
 import fnmatch
 import fnmatch
 import inspect
 import inspect

+ 27 - 21
3rdparty/spirv-tools/test/val/val_atomics_test.cpp

@@ -190,6 +190,9 @@ OpMemoryModel Physical32 OpenCL
 %f32_ptr_uniformconstant = OpTypePointer UniformConstant %f32
 %f32_ptr_uniformconstant = OpTypePointer UniformConstant %f32
 %f32_uc_var = OpVariable %f32_ptr_uniformconstant UniformConstant
 %f32_uc_var = OpVariable %f32_ptr_uniformconstant UniformConstant
 
 
+%f32_ptr_image = OpTypePointer Image %f32
+%f32_im_var = OpVariable %f32_ptr_image Image
+
 %main = OpFunction %void None %func
 %main = OpFunction %void None %func
 %main_entry = OpLabel
 %main_entry = OpLabel
 )";
 )";
@@ -288,11 +291,9 @@ OpAtomicStore %f32_var_function %device %relaxed %f32_1
 
 
   CompileSuccessfully(GenerateShaderCode(body), SPV_ENV_VULKAN_1_0);
   CompileSuccessfully(GenerateShaderCode(body), SPV_ENV_VULKAN_1_0);
   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
-  EXPECT_THAT(
-      getDiagnosticString(),
-      HasSubstr("AtomicStore: expected Pointer Storage Class to be Uniform, "
-                "Workgroup, CrossWorkgroup, Generic, AtomicCounter, Image or "
-                "StorageBuffer"));
+  EXPECT_THAT(getDiagnosticString(),
+              HasSubstr("AtomicStore: Function storage class forbidden when "
+                        "the Shader capability is declared."));
 }
 }
 
 
 // TODO([email protected]): the corresponding check fails Vulkan CTS,
 // TODO([email protected]): the corresponding check fails Vulkan CTS,
@@ -500,8 +501,7 @@ TEST_F(ValidateAtomics, AtomicLoadWrongScopeType) {
   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   EXPECT_THAT(
   EXPECT_THAT(
       getDiagnosticString(),
       getDiagnosticString(),
-      HasSubstr("AtomicLoad: expected Memory Scope to be a 32-bit int\n  %40 = "
-                "OpAtomicLoad %float %28 %float_1 %uint_0_1\n"));
+      HasSubstr("AtomicLoad: expected Memory Scope to be a 32-bit int"));
 }
 }
 
 
 TEST_F(ValidateAtomics, AtomicLoadWrongMemorySemanticsType) {
 TEST_F(ValidateAtomics, AtomicLoadWrongMemorySemanticsType) {
@@ -641,6 +641,19 @@ OpAtomicStore %f32vec4_var %device %relaxed %f32_1
                 "type"));
                 "type"));
 }
 }
 
 
+TEST_F(ValidateAtomics, AtomicStoreWrongPointerStorageTypeForOpenCL) {
+  const std::string body = R"(
+OpAtomicStore %f32_im_var %device %relaxed %f32_1
+)";
+
+  CompileSuccessfully(GenerateKernelCode(body));
+  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_OPENCL_1_2));
+  EXPECT_THAT(
+      getDiagnosticString(),
+      HasSubstr("AtomicStore: storage class must be Function, Workgroup, "
+                "CrossWorkGroup or Generic in the OpenCL environment."));
+}
+
 TEST_F(ValidateAtomics, AtomicStoreWrongPointerStorageType) {
 TEST_F(ValidateAtomics, AtomicStoreWrongPointerStorageType) {
   const std::string body = R"(
   const std::string body = R"(
 OpAtomicStore %f32_uc_var %device %relaxed %f32_1
 OpAtomicStore %f32_uc_var %device %relaxed %f32_1
@@ -648,11 +661,9 @@ OpAtomicStore %f32_uc_var %device %relaxed %f32_1
 
 
   CompileSuccessfully(GenerateKernelCode(body));
   CompileSuccessfully(GenerateKernelCode(body));
   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
-  EXPECT_THAT(
-      getDiagnosticString(),
-      HasSubstr("AtomicStore: expected Pointer Storage Class to be Uniform, "
-                "Workgroup, CrossWorkgroup, Generic, AtomicCounter, Image or "
-                "StorageBuffer"));
+  EXPECT_THAT(getDiagnosticString(),
+              HasSubstr("AtomicStore: storage class forbidden by universal "
+                        "validation rules."));
 }
 }
 
 
 TEST_F(ValidateAtomics, AtomicStoreWrongScopeType) {
 TEST_F(ValidateAtomics, AtomicStoreWrongScopeType) {
@@ -778,9 +789,7 @@ OpAtomicStore %f32_var %device %relaxed %f32_1
   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
   EXPECT_THAT(
   EXPECT_THAT(
       getDiagnosticString(),
       getDiagnosticString(),
-      HasSubstr(
-          "AtomicExchange: expected Memory Scope to be a 32-bit int\n  %40 = "
-          "OpAtomicExchange %float %28 %float_1 %uint_0_1 %float_0\n"));
+      HasSubstr("AtomicExchange: expected Memory Scope to be a 32-bit int"));
 }
 }
 
 
 TEST_F(ValidateAtomics, AtomicExchangeWrongMemorySemanticsType) {
 TEST_F(ValidateAtomics, AtomicExchangeWrongMemorySemanticsType) {
@@ -895,8 +904,7 @@ OpAtomicStore %f32_var %device %relaxed %f32_1
   EXPECT_THAT(
   EXPECT_THAT(
       getDiagnosticString(),
       getDiagnosticString(),
       HasSubstr("AtomicCompareExchange: expected Memory Scope to be a 32-bit "
       HasSubstr("AtomicCompareExchange: expected Memory Scope to be a 32-bit "
-                "int\n  %40 = OpAtomicCompareExchange %float %28 %float_1 "
-                "%uint_0_1 %uint_0_1 %float_0 %float_0\n"));
+                "int"));
 }
 }
 
 
 TEST_F(ValidateAtomics, AtomicCompareExchangeWrongMemorySemanticsType1) {
 TEST_F(ValidateAtomics, AtomicCompareExchangeWrongMemorySemanticsType1) {
@@ -1077,8 +1085,7 @@ TEST_F(ValidateAtomics, AtomicFlagTestAndSetWrongScopeType) {
   EXPECT_THAT(
   EXPECT_THAT(
       getDiagnosticString(),
       getDiagnosticString(),
       HasSubstr(
       HasSubstr(
-          "AtomicFlagTestAndSet: expected Memory Scope to be a 32-bit int\n  "
-          "%40 = OpAtomicFlagTestAndSet %bool %30 %ulong_1 %uint_0_1\n"));
+          "AtomicFlagTestAndSet: expected Memory Scope to be a 32-bit int"));
 }
 }
 
 
 TEST_F(ValidateAtomics, AtomicFlagTestAndSetWrongMemorySemanticsType) {
 TEST_F(ValidateAtomics, AtomicFlagTestAndSetWrongMemorySemanticsType) {
@@ -1179,8 +1186,7 @@ OpAtomicStore %u32_var %device %relaxed %u32_1
   EXPECT_THAT(getDiagnosticString(),
   EXPECT_THAT(getDiagnosticString(),
               HasSubstr("AtomicIIncrement: Memory Semantics can have at most "
               HasSubstr("AtomicIIncrement: Memory Semantics can have at most "
                         "one of the following bits set: Acquire, Release, "
                         "one of the following bits set: Acquire, Release, "
-                        "AcquireRelease or SequentiallyConsistent\n  %40 = "
-                        "OpAtomicIIncrement %uint %30 %uint_1_0 %uint_6\n"));
+                        "AcquireRelease or SequentiallyConsistent"));
 }
 }
 
 
 TEST_F(ValidateAtomics, AtomicUniformMemorySemanticsShader) {
 TEST_F(ValidateAtomics, AtomicUniformMemorySemanticsShader) {

+ 174 - 0
3rdparty/spirv-tools/test/val/val_cfg_test.cpp

@@ -2623,6 +2623,134 @@ OpFunctionEnd
   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
 }
 }
 
 
+TEST_F(ValidateCFG, SwitchCaseOrderingBad1) {
+  const std::string text = R"(
+OpCapability Shader
+OpCapability Linkage
+OpMemoryModel Logical GLSL450
+OpName %default "default"
+OpName %other "other"
+%void = OpTypeVoid
+%int = OpTypeInt 32 0
+%undef = OpUndef %int
+%void_fn = OpTypeFunction %void
+%func = OpFunction %void None %void_fn
+%entry = OpLabel
+OpSelectionMerge %merge None
+OpSwitch %undef %default 0 %other 1 %default
+%default = OpLabel
+OpBranch %other
+%other = OpLabel
+OpBranch %merge
+%merge = OpLabel
+OpReturn
+OpFunctionEnd
+)";
+
+  CompileSuccessfully(text);
+  EXPECT_EQ(SPV_ERROR_INVALID_CFG, ValidateInstructions());
+  EXPECT_THAT(
+      getDiagnosticString(),
+      HasSubstr("Case construct that targets 1[%default] has branches to the "
+                "case construct that targets 2[%other], but does not "
+                "immediately precede it in the OpSwitch's target list"));
+}
+
+TEST_F(ValidateCFG, SwitchCaseOrderingBad2) {
+  const std::string text = R"(
+OpCapability Shader
+OpCapability Linkage
+OpMemoryModel Logical GLSL450
+OpName %default "default"
+OpName %other "other"
+%void = OpTypeVoid
+%int = OpTypeInt 32 0
+%undef = OpUndef %int
+%void_fn = OpTypeFunction %void
+%func = OpFunction %void None %void_fn
+%entry = OpLabel
+OpSelectionMerge %merge None
+OpSwitch %undef %default 0 %default 1 %other
+%other = OpLabel
+OpBranch %default
+%default = OpLabel
+OpBranch %merge
+%merge = OpLabel
+OpReturn
+OpFunctionEnd
+)";
+
+  CompileSuccessfully(text);
+  EXPECT_EQ(SPV_ERROR_INVALID_CFG, ValidateInstructions());
+  EXPECT_THAT(
+      getDiagnosticString(),
+      HasSubstr("Case construct that targets 2[%other] has branches to the "
+                "case construct that targets 1[%default], but does not "
+                "immediately precede it in the OpSwitch's target list"));
+}
+
+TEST_F(ValidateCFG, SwitchMultipleDefaultWithFallThroughGood) {
+  const std::string text = R"(
+OpCapability Shader
+OpCapability Linkage
+OpMemoryModel Logical GLSL450
+OpName %first "first"
+OpName %second "second"
+OpName %third "third"
+%void = OpTypeVoid
+%int = OpTypeInt 32 0
+%undef = OpUndef %int
+%void_fn = OpTypeFunction %void
+%func = OpFunction %void None %void_fn
+%entry = OpLabel
+OpSelectionMerge %merge None
+OpSwitch %undef %second 0 %first 1 %second 2 %third
+%first = OpLabel
+OpBranch %second
+%second = OpLabel
+OpBranch %third
+%third = OpLabel
+OpBranch %merge
+%merge = OpLabel
+OpReturn
+OpFunctionEnd
+)";
+
+  CompileSuccessfully(text);
+  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
+}
+
+TEST_F(ValidateCFG, SwitchMultipleDefaultWithFallThroughBad) {
+  const std::string text = R"(
+OpCapability Shader
+OpCapability Linkage
+OpMemoryModel Logical GLSL450
+OpName %first "first"
+OpName %second "second"
+OpName %third "third"
+%void = OpTypeVoid
+%int = OpTypeInt 32 0
+%undef = OpUndef %int
+%void_fn = OpTypeFunction %void
+%func = OpFunction %void None %void_fn
+%entry = OpLabel
+OpSelectionMerge %merge None
+OpSwitch %undef %second 0 %second 1 %first 2 %third
+%first = OpLabel
+OpBranch %second
+%second = OpLabel
+OpBranch %third
+%third = OpLabel
+OpBranch %merge
+%merge = OpLabel
+OpReturn
+OpFunctionEnd
+)";
+
+  CompileSuccessfully(text);
+  EXPECT_EQ(SPV_ERROR_INVALID_CFG, ValidateInstructions());
+}
+
 TEST_F(ValidateCFG, GoodUnreachableSelection) {
 TEST_F(ValidateCFG, GoodUnreachableSelection) {
   const std::string text = R"(
   const std::string text = R"(
 OpCapability Shader
 OpCapability Shader
@@ -3575,6 +3703,52 @@ OpFunctionEnd
                         "10[%10], but not via a structured exit"));
                         "10[%10], but not via a structured exit"));
 }
 }
 
 
+TEST_F(ValidateCFG, ContinueFromNestedSelection) {
+  const std::string text = R"(
+OpCapability Shader
+OpCapability Linkage
+OpMemoryModel Logical GLSL450
+%void = OpTypeVoid
+%void_fn = OpTypeFunction %void
+%bool = OpTypeBool
+%undef = OpUndef %bool
+%4 = OpFunction %void None %void_fn
+%5 = OpLabel
+OpBranch %48
+%48 = OpLabel
+OpLoopMerge %47 %50 None
+OpBranch %10
+%10 = OpLabel
+OpLoopMerge %12 %37 None
+OpBranchConditional %undef %11 %12
+%11 = OpLabel
+OpSelectionMerge %31 None
+OpBranchConditional %undef %30 %31
+%30 = OpLabel
+OpSelectionMerge %37 None
+OpBranchConditional %undef %36 %37
+%36 = OpLabel
+OpBranch %37
+%37 = OpLabel
+OpBranch %10
+%31 = OpLabel
+OpBranch %12
+%12 = OpLabel
+OpSelectionMerge %55 None
+OpBranchConditional %undef %47 %55
+%55 = OpLabel
+OpBranch %47
+%50 = OpLabel
+OpBranch %48
+%47 = OpLabel
+OpReturn
+OpFunctionEnd
+)";
+
+  CompileSuccessfully(text);
+  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
+}
+
 /// TODO(umar): Nested CFG constructs
 /// TODO(umar): Nested CFG constructs
 
 
 }  // namespace
 }  // namespace

+ 3 - 4
3rdparty/spirv-tools/test/val/val_derivatives_test.cpp

@@ -145,10 +145,9 @@ TEST_F(ValidateDerivatives, OpDPdxWrongExecutionModel) {
 
 
   CompileSuccessfully(GenerateShaderCode(body, "", "Vertex").c_str());
   CompileSuccessfully(GenerateShaderCode(body, "", "Vertex").c_str());
   ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
   ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
-  EXPECT_THAT(
-      getDiagnosticString(),
-      HasSubstr(
-          "Derivative instructions require Fragment execution model: DPdx"));
+  EXPECT_THAT(getDiagnosticString(),
+              HasSubstr("Derivative instructions require Fragment or GLCompute "
+                        "execution model: DPdx"));
 }
 }
 
 
 }  // namespace
 }  // namespace

+ 1 - 1
3rdparty/spirv-tools/test/val/val_id_test.cpp

@@ -314,7 +314,7 @@ TEST_F(ValidateIdWithMessage, OpDecorationGroupBad) {
   EXPECT_THAT(getDiagnosticString(),
   EXPECT_THAT(getDiagnosticString(),
               HasSubstr("Result id of OpDecorationGroup can only "
               HasSubstr("Result id of OpDecorationGroup can only "
                         "be targeted by OpName, OpGroupDecorate, "
                         "be targeted by OpName, OpGroupDecorate, "
-                        "OpDecorate, and OpGroupMemberDecorate"));
+                        "OpDecorate, OpDecorateId, and OpGroupMemberDecorate"));
 }
 }
 TEST_F(ValidateIdWithMessage, OpGroupDecorateDecorationGroupBad) {
 TEST_F(ValidateIdWithMessage, OpGroupDecorateDecorationGroupBad) {
   std::string spirv = R"(
   std::string spirv = R"(

+ 141 - 44
3rdparty/spirv-tools/test/val/val_image_test.cpp

@@ -35,6 +35,7 @@ std::string GenerateShaderCode(
     const std::string& body,
     const std::string& body,
     const std::string& capabilities_and_extensions = "",
     const std::string& capabilities_and_extensions = "",
     const std::string& execution_model = "Fragment",
     const std::string& execution_model = "Fragment",
+    const std::string& execution_mode = "",
     const spv_target_env env = SPV_ENV_UNIVERSAL_1_0,
     const spv_target_env env = SPV_ENV_UNIVERSAL_1_0,
     const std::string& memory_model = "GLSL450") {
     const std::string& memory_model = "GLSL450") {
   std::ostringstream ss;
   std::ostringstream ss;
@@ -85,6 +86,7 @@ OpCapability ImageBuffer
   if (execution_model == "Fragment") {
   if (execution_model == "Fragment") {
     ss << "OpExecutionMode %main OriginUpperLeft\n";
     ss << "OpExecutionMode %main OriginUpperLeft\n";
   }
   }
+  ss << execution_mode;
 
 
   if (env == SPV_ENV_VULKAN_1_0) {
   if (env == SPV_ENV_VULKAN_1_0) {
     ss << R"(
     ss << R"(
@@ -606,7 +608,7 @@ TEST_F(ValidateImage, SampledImageVulkanSuccess) {
 )";
 )";
 
 
   const spv_target_env env = SPV_ENV_VULKAN_1_0;
   const spv_target_env env = SPV_ENV_VULKAN_1_0;
-  CompileSuccessfully(GenerateShaderCode(body, "", "Fragment", env), env);
+  CompileSuccessfully(GenerateShaderCode(body, "", "Fragment", "", env), env);
   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(env));
   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(env));
 }
 }
 
 
@@ -658,7 +660,7 @@ TEST_F(ValidateImage, SampledImageVulkanUnknownSampled) {
 )";
 )";
 
 
   const spv_target_env env = SPV_ENV_VULKAN_1_0;
   const spv_target_env env = SPV_ENV_VULKAN_1_0;
-  CompileSuccessfully(GenerateShaderCode(body, "", "Fragment", env), env);
+  CompileSuccessfully(GenerateShaderCode(body, "", "Fragment", "", env), env);
   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(env));
   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(env));
   EXPECT_THAT(getDiagnosticString(),
   EXPECT_THAT(getDiagnosticString(),
               HasSubstr("Expected Image 'Sampled' parameter to "
               HasSubstr("Expected Image 'Sampled' parameter to "
@@ -847,7 +849,7 @@ TEST_F(ValidateImage, SampleImplicitLodSuccess) {
 OpCapability VulkanMemoryModelKHR
 OpCapability VulkanMemoryModelKHR
 OpExtension "SPV_KHR_vulkan_memory_model"
 OpExtension "SPV_KHR_vulkan_memory_model"
 )";
 )";
-  CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment",
+  CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
                                          SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
                                          SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
                           .c_str());
                           .c_str());
   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
@@ -967,7 +969,7 @@ TEST_F(ValidateImage, SampleExplicitLodSuccessShader) {
 OpCapability VulkanMemoryModelKHR
 OpCapability VulkanMemoryModelKHR
 OpExtension "SPV_KHR_vulkan_memory_model"
 OpExtension "SPV_KHR_vulkan_memory_model"
 )";
 )";
-  CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment",
+  CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
                                          SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
                                          SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
                           .c_str());
                           .c_str());
   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
@@ -1552,7 +1554,7 @@ TEST_F(ValidateImage, SampleProjExplicitLodSuccess2D) {
 OpCapability VulkanMemoryModelKHR
 OpCapability VulkanMemoryModelKHR
 OpExtension "SPV_KHR_vulkan_memory_model"
 OpExtension "SPV_KHR_vulkan_memory_model"
 )";
 )";
-  CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment",
+  CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
                                          SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
                                          SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
                           .c_str());
                           .c_str());
   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
@@ -1686,7 +1688,7 @@ TEST_F(ValidateImage, SampleProjImplicitLodSuccess) {
 OpCapability VulkanMemoryModelKHR
 OpCapability VulkanMemoryModelKHR
 OpExtension "SPV_KHR_vulkan_memory_model"
 OpExtension "SPV_KHR_vulkan_memory_model"
 )";
 )";
-  CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment",
+  CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
                                          SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
                                          SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
                           .c_str());
                           .c_str());
   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
@@ -1807,7 +1809,7 @@ TEST_F(ValidateImage, SampleDrefImplicitLodSuccess) {
 OpCapability VulkanMemoryModelKHR
 OpCapability VulkanMemoryModelKHR
 OpExtension "SPV_KHR_vulkan_memory_model"
 OpExtension "SPV_KHR_vulkan_memory_model"
 )";
 )";
-  CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment",
+  CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
                                          SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
                                          SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
                           .c_str());
                           .c_str());
   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
@@ -1930,7 +1932,7 @@ TEST_F(ValidateImage, SampleDrefExplicitLodSuccess) {
 OpCapability VulkanMemoryModelKHR
 OpCapability VulkanMemoryModelKHR
 OpExtension "SPV_KHR_vulkan_memory_model"
 OpExtension "SPV_KHR_vulkan_memory_model"
 )";
 )";
-  CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment",
+  CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
                                          SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
                                          SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
                           .c_str());
                           .c_str());
   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
@@ -2054,7 +2056,7 @@ TEST_F(ValidateImage, SampleProjDrefImplicitLodSuccess) {
 OpCapability VulkanMemoryModelKHR
 OpCapability VulkanMemoryModelKHR
 OpExtension "SPV_KHR_vulkan_memory_model"
 OpExtension "SPV_KHR_vulkan_memory_model"
 )";
 )";
-  CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment",
+  CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
                                          SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
                                          SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
                           .c_str());
                           .c_str());
   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
@@ -2177,7 +2179,7 @@ TEST_F(ValidateImage, SampleProjDrefExplicitLodSuccess) {
 OpCapability VulkanMemoryModelKHR
 OpCapability VulkanMemoryModelKHR
 OpExtension "SPV_KHR_vulkan_memory_model"
 OpExtension "SPV_KHR_vulkan_memory_model"
 )";
 )";
-  CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment",
+  CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
                                          SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
                                          SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
                           .c_str());
                           .c_str());
   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
@@ -2280,7 +2282,7 @@ TEST_F(ValidateImage, FetchSuccess) {
 OpCapability VulkanMemoryModelKHR
 OpCapability VulkanMemoryModelKHR
 OpExtension "SPV_KHR_vulkan_memory_model"
 OpExtension "SPV_KHR_vulkan_memory_model"
 )";
 )";
-  CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment",
+  CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
                                          SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
                                          SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
                           .c_str());
                           .c_str());
   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
@@ -2439,7 +2441,7 @@ TEST_F(ValidateImage, GatherSuccess) {
 OpCapability VulkanMemoryModelKHR
 OpCapability VulkanMemoryModelKHR
 OpExtension "SPV_KHR_vulkan_memory_model"
 OpExtension "SPV_KHR_vulkan_memory_model"
 )";
 )";
-  CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment",
+  CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
                                          SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
                                          SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
                           .c_str());
                           .c_str());
   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
@@ -2695,7 +2697,7 @@ TEST_F(ValidateImage, DrefGatherSuccess) {
 OpCapability VulkanMemoryModelKHR
 OpCapability VulkanMemoryModelKHR
 OpExtension "SPV_KHR_vulkan_memory_model"
 OpExtension "SPV_KHR_vulkan_memory_model"
 )";
 )";
-  CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment",
+  CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
                                          SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
                                          SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
                           .c_str());
                           .c_str());
   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
@@ -2790,7 +2792,7 @@ TEST_F(ValidateImage, ReadNeedCapabilityStorageImageReadWithoutFormatVulkan) {
 )";
 )";
 
 
   spv_target_env env = SPV_ENV_VULKAN_1_0;
   spv_target_env env = SPV_ENV_VULKAN_1_0;
-  CompileSuccessfully(GenerateShaderCode(body, "", "Fragment", env).c_str(),
+  CompileSuccessfully(GenerateShaderCode(body, "", "Fragment", "", env).c_str(),
                       env);
                       env);
   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(env));
   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(env));
   EXPECT_THAT(getDiagnosticString(),
   EXPECT_THAT(getDiagnosticString(),
@@ -3008,7 +3010,7 @@ TEST_F(ValidateImage, WriteNeedCapabilityStorageImageWriteWithoutFormatVulkan) {
 )";
 )";
 
 
   spv_target_env env = SPV_ENV_VULKAN_1_0;
   spv_target_env env = SPV_ENV_VULKAN_1_0;
-  CompileSuccessfully(GenerateShaderCode(body, "", "Fragment", env).c_str(),
+  CompileSuccessfully(GenerateShaderCode(body, "", "Fragment", "", env).c_str(),
                       env);
                       env);
   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(env));
   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(env));
   EXPECT_THAT(
   EXPECT_THAT(
@@ -3710,8 +3712,10 @@ TEST_F(ValidateImage, QueryLodWrongExecutionModel) {
 
 
   CompileSuccessfully(GenerateShaderCode(body, "", "Vertex").c_str());
   CompileSuccessfully(GenerateShaderCode(body, "", "Vertex").c_str());
   ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
   ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
-  EXPECT_THAT(getDiagnosticString(),
-              HasSubstr("OpImageQueryLod requires Fragment execution model"));
+  EXPECT_THAT(
+      getDiagnosticString(),
+      HasSubstr(
+          "OpImageQueryLod requires Fragment or GLCompute execution model"));
 }
 }
 
 
 TEST_F(ValidateImage, QueryLodWrongExecutionModelWithFunc) {
 TEST_F(ValidateImage, QueryLodWrongExecutionModelWithFunc) {
@@ -3729,8 +3733,55 @@ OpFunctionEnd
 
 
   CompileSuccessfully(GenerateShaderCode(body, "", "Vertex").c_str());
   CompileSuccessfully(GenerateShaderCode(body, "", "Vertex").c_str());
   ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
   ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
+  EXPECT_THAT(
+      getDiagnosticString(),
+      HasSubstr(
+          "OpImageQueryLod requires Fragment or GLCompute execution model"));
+}
+
+TEST_F(ValidateImage, QueryLodComputeShaderDerivatives) {
+  const std::string body = R"(
+%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
+%sampler = OpLoad %type_sampler %uniform_sampler
+%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
+%res1 = OpImageQueryLod %f32vec2 %simg %f32vec2_hh
+)";
+
+  const std::string extra = R"(
+OpCapability ComputeDerivativeGroupLinearNV
+OpExtension "SPV_NV_compute_shader_derivatives"
+)";
+  const std::string mode = R"(
+OpExecutionMode %main LocalSize 8 8 1
+OpExecutionMode %main DerivativeGroupLinearNV
+)";
+  CompileSuccessfully(
+      GenerateShaderCode(body, extra, "GLCompute", mode).c_str());
+  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
+}
+
+TEST_F(ValidateImage, QueryLodComputeShaderDerivativesMissingMode) {
+  const std::string body = R"(
+%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
+%sampler = OpLoad %type_sampler %uniform_sampler
+%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
+%res1 = OpImageQueryLod %f32vec2 %simg %f32vec2_hh
+)";
+
+  const std::string extra = R"(
+OpCapability ComputeDerivativeGroupLinearNV
+OpExtension "SPV_NV_compute_shader_derivatives"
+)";
+  const std::string mode = R"(
+OpExecutionMode %main LocalSize 8 8 1
+)";
+  CompileSuccessfully(
+      GenerateShaderCode(body, extra, "GLCompute", mode).c_str());
+  ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
   EXPECT_THAT(getDiagnosticString(),
   EXPECT_THAT(getDiagnosticString(),
-              HasSubstr("OpImageQueryLod requires Fragment execution model"));
+              HasSubstr("OpImageQueryLod requires DerivativeGroupQuadsNV or "
+                        "DerivativeGroupLinearNV execution mode for GLCompute "
+                        "execution model"));
 }
 }
 
 
 TEST_F(ValidateImage, ImplicitLodWrongExecutionModel) {
 TEST_F(ValidateImage, ImplicitLodWrongExecutionModel) {
@@ -3743,9 +3794,55 @@ TEST_F(ValidateImage, ImplicitLodWrongExecutionModel) {
 
 
   CompileSuccessfully(GenerateShaderCode(body, "", "Vertex").c_str());
   CompileSuccessfully(GenerateShaderCode(body, "", "Vertex").c_str());
   ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
   ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
+  EXPECT_THAT(getDiagnosticString(),
+              HasSubstr("ImplicitLod instructions require Fragment or "
+                        "GLCompute execution model"));
+}
+
+TEST_F(ValidateImage, ImplicitLodComputeShaderDerivatives) {
+  const std::string body = R"(
+%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
+%sampler = OpLoad %type_sampler %uniform_sampler
+%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
+%res1 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh
+)";
+
+  const std::string extra = R"(
+OpCapability ComputeDerivativeGroupLinearNV
+OpExtension "SPV_NV_compute_shader_derivatives"
+)";
+  const std::string mode = R"(
+OpExecutionMode %main LocalSize 8 8 1
+OpExecutionMode %main DerivativeGroupLinearNV
+)";
+  CompileSuccessfully(
+      GenerateShaderCode(body, extra, "GLCompute", mode).c_str());
+  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
+}
+
+TEST_F(ValidateImage, ImplicitLodComputeShaderDerivativesMissingMode) {
+  const std::string body = R"(
+%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
+%sampler = OpLoad %type_sampler %uniform_sampler
+%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
+%res1 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec2_hh
+)";
+
+  const std::string extra = R"(
+OpCapability ComputeDerivativeGroupLinearNV
+OpExtension "SPV_NV_compute_shader_derivatives"
+)";
+  const std::string mode = R"(
+OpExecutionMode %main LocalSize 8 8 1
+)";
+  CompileSuccessfully(
+      GenerateShaderCode(body, extra, "GLCompute", mode).c_str());
+  ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
   EXPECT_THAT(
   EXPECT_THAT(
       getDiagnosticString(),
       getDiagnosticString(),
-      HasSubstr("ImplicitLod instructions require Fragment execution model"));
+      HasSubstr("ImplicitLod instructions require DerivativeGroupQuadsNV or "
+                "DerivativeGroupLinearNV execution mode for GLCompute "
+                "execution model"));
 }
 }
 
 
 TEST_F(ValidateImage, ReadSubpassDataWrongExecutionModel) {
 TEST_F(ValidateImage, ReadSubpassDataWrongExecutionModel) {
@@ -3779,7 +3876,7 @@ TEST_F(ValidateImage, SparseSampleImplicitLodSuccess) {
 OpCapability VulkanMemoryModelKHR
 OpCapability VulkanMemoryModelKHR
 OpExtension "SPV_KHR_vulkan_memory_model"
 OpExtension "SPV_KHR_vulkan_memory_model"
 )";
 )";
-  CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment",
+  CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
                                          SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
                                          SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
                           .c_str());
                           .c_str());
   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
@@ -3907,7 +4004,7 @@ TEST_F(ValidateImage, SparseSampleDrefImplicitLodSuccess) {
 OpCapability VulkanMemoryModelKHR
 OpCapability VulkanMemoryModelKHR
 OpExtension "SPV_KHR_vulkan_memory_model"
 OpExtension "SPV_KHR_vulkan_memory_model"
 )";
 )";
-  CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment",
+  CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
                                          SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
                                          SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
                           .c_str());
                           .c_str());
   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
@@ -4001,7 +4098,7 @@ TEST_F(ValidateImage, SparseFetchSuccess) {
 OpCapability VulkanMemoryModelKHR
 OpCapability VulkanMemoryModelKHR
 OpExtension "SPV_KHR_vulkan_memory_model"
 OpExtension "SPV_KHR_vulkan_memory_model"
 )";
 )";
-  CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment",
+  CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
                                          SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
                                          SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
                           .c_str());
                           .c_str());
   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
@@ -4218,7 +4315,7 @@ TEST_F(ValidateImage, SparseGatherSuccess) {
 OpCapability VulkanMemoryModelKHR
 OpCapability VulkanMemoryModelKHR
 OpExtension "SPV_KHR_vulkan_memory_model"
 OpExtension "SPV_KHR_vulkan_memory_model"
 )";
 )";
-  CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment",
+  CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
                                          SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
                                          SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
                           .c_str());
                           .c_str());
   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
@@ -4359,7 +4456,7 @@ OpCapability StorageImageReadWithoutFormat
 OpCapability VulkanMemoryModelKHR
 OpCapability VulkanMemoryModelKHR
 OpExtension "SPV_KHR_vulkan_memory_model"
 OpExtension "SPV_KHR_vulkan_memory_model"
 )";
 )";
-  CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment",
+  CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
                                          SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
                                          SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
                           .c_str());
                           .c_str());
   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
@@ -4376,7 +4473,7 @@ OpCapability StorageImageReadWithoutFormat
 OpCapability VulkanMemoryModelKHR
 OpCapability VulkanMemoryModelKHR
 OpExtension "SPV_KHR_vulkan_memory_model"
 OpExtension "SPV_KHR_vulkan_memory_model"
 )";
 )";
-  CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment",
+  CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
                                          SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
                                          SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
                           .c_str());
                           .c_str());
   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
@@ -4395,7 +4492,7 @@ OpCapability StorageImageReadWithoutFormat
 OpCapability VulkanMemoryModelKHR
 OpCapability VulkanMemoryModelKHR
 OpExtension "SPV_KHR_vulkan_memory_model"
 OpExtension "SPV_KHR_vulkan_memory_model"
 )";
 )";
-  CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment",
+  CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
                                          SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
                                          SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
                           .c_str());
                           .c_str());
   ASSERT_EQ(SPV_ERROR_INVALID_DATA,
   ASSERT_EQ(SPV_ERROR_INVALID_DATA,
@@ -4417,7 +4514,7 @@ OpCapability StorageImageReadWithoutFormat
 OpCapability VulkanMemoryModelKHR
 OpCapability VulkanMemoryModelKHR
 OpExtension "SPV_KHR_vulkan_memory_model"
 OpExtension "SPV_KHR_vulkan_memory_model"
 )";
 )";
-  CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment",
+  CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
                                          SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
                                          SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
                           .c_str());
                           .c_str());
   ASSERT_EQ(SPV_ERROR_INVALID_DATA,
   ASSERT_EQ(SPV_ERROR_INVALID_DATA,
@@ -4438,7 +4535,7 @@ OpCapability StorageImageWriteWithoutFormat
 OpCapability VulkanMemoryModelKHR
 OpCapability VulkanMemoryModelKHR
 OpExtension "SPV_KHR_vulkan_memory_model"
 OpExtension "SPV_KHR_vulkan_memory_model"
 )";
 )";
-  CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment",
+  CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
                                          SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
                                          SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
                           .c_str());
                           .c_str());
   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
@@ -4457,7 +4554,7 @@ OpCapability StorageImageReadWithoutFormat
 OpCapability VulkanMemoryModelKHR
 OpCapability VulkanMemoryModelKHR
 OpExtension "SPV_KHR_vulkan_memory_model"
 OpExtension "SPV_KHR_vulkan_memory_model"
 )";
 )";
-  CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment",
+  CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
                                          SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
                                          SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
                           .c_str());
                           .c_str());
   ASSERT_EQ(SPV_ERROR_INVALID_DATA,
   ASSERT_EQ(SPV_ERROR_INVALID_DATA,
@@ -4478,7 +4575,7 @@ OpCapability StorageImageWriteWithoutFormat
 OpCapability VulkanMemoryModelKHR
 OpCapability VulkanMemoryModelKHR
 OpExtension "SPV_KHR_vulkan_memory_model"
 OpExtension "SPV_KHR_vulkan_memory_model"
 )";
 )";
-  CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment",
+  CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
                                          SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
                                          SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
                           .c_str());
                           .c_str());
   ASSERT_EQ(SPV_ERROR_INVALID_DATA,
   ASSERT_EQ(SPV_ERROR_INVALID_DATA,
@@ -4499,7 +4596,7 @@ OpCapability StorageImageWriteWithoutFormat
 OpCapability VulkanMemoryModelKHR
 OpCapability VulkanMemoryModelKHR
 OpExtension "SPV_KHR_vulkan_memory_model"
 OpExtension "SPV_KHR_vulkan_memory_model"
 )";
 )";
-  CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment",
+  CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
                                          SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
                                          SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
                           .c_str());
                           .c_str());
   ASSERT_EQ(SPV_ERROR_INVALID_DATA,
   ASSERT_EQ(SPV_ERROR_INVALID_DATA,
@@ -4522,7 +4619,7 @@ OpCapability VulkanMemoryModelKHR
 OpCapability VulkanMemoryModelDeviceScopeKHR
 OpCapability VulkanMemoryModelDeviceScopeKHR
 OpExtension "SPV_KHR_vulkan_memory_model"
 OpExtension "SPV_KHR_vulkan_memory_model"
 )";
 )";
-  CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment",
+  CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
                                          SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
                                          SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
                           .c_str());
                           .c_str());
   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
@@ -4539,7 +4636,7 @@ OpCapability StorageImageReadWithoutFormat
 OpCapability VulkanMemoryModelKHR
 OpCapability VulkanMemoryModelKHR
 OpExtension "SPV_KHR_vulkan_memory_model"
 OpExtension "SPV_KHR_vulkan_memory_model"
 )";
 )";
-  CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment",
+  CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
                                          SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
                                          SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
                           .c_str());
                           .c_str());
   ASSERT_EQ(SPV_ERROR_INVALID_DATA,
   ASSERT_EQ(SPV_ERROR_INVALID_DATA,
@@ -4562,7 +4659,7 @@ OpCapability VulkanMemoryModelKHR
 OpCapability VulkanMemoryModelDeviceScopeKHR
 OpCapability VulkanMemoryModelDeviceScopeKHR
 OpExtension "SPV_KHR_vulkan_memory_model"
 OpExtension "SPV_KHR_vulkan_memory_model"
 )";
 )";
-  CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment",
+  CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "",
                                          SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
                                          SPV_ENV_UNIVERSAL_1_3, "VulkanKHR")
                           .c_str());
                           .c_str());
   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
@@ -4609,7 +4706,7 @@ TEST_F(ValidateImage, SignExtendV13Bad) {
 %res1 = OpImageRead %u32vec4 %img %u32vec2_01 SignExtend
 %res1 = OpImageRead %u32vec4 %img %u32vec2_01 SignExtend
 )";
 )";
 
 
-  EXPECT_THAT(CompileFailure(GenerateShaderCode(body, "", "Fragment",
+  EXPECT_THAT(CompileFailure(GenerateShaderCode(body, "", "Fragment", "",
                                                 SPV_ENV_UNIVERSAL_1_3)),
                                                 SPV_ENV_UNIVERSAL_1_3)),
               HasSubstr("Invalid image operand 'SignExtend'"));
               HasSubstr("Invalid image operand 'SignExtend'"));
 }
 }
@@ -4620,7 +4717,7 @@ TEST_F(ValidateImage, ZeroExtendV13Bad) {
 %res1 = OpImageRead %u32vec4 %img %u32vec2_01 ZeroExtend
 %res1 = OpImageRead %u32vec4 %img %u32vec2_01 ZeroExtend
 )";
 )";
 
 
-  EXPECT_THAT(CompileFailure(GenerateShaderCode(body, "", "Fragment",
+  EXPECT_THAT(CompileFailure(GenerateShaderCode(body, "", "Fragment", "",
                                                 SPV_ENV_UNIVERSAL_1_3)),
                                                 SPV_ENV_UNIVERSAL_1_3)),
               HasSubstr("Invalid image operand 'ZeroExtend'"));
               HasSubstr("Invalid image operand 'ZeroExtend'"));
 }
 }
@@ -4634,7 +4731,7 @@ TEST_F(ValidateImage, SignExtendScalarUIntTexelV14Good) {
   const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
   const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
 
 
   CompileSuccessfully(
   CompileSuccessfully(
-      GenerateShaderCode(body, extra, "Fragment", SPV_ENV_UNIVERSAL_1_4),
+      GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_4),
       SPV_ENV_UNIVERSAL_1_4);
       SPV_ENV_UNIVERSAL_1_4);
   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
   EXPECT_THAT(getDiagnosticString(), Eq(""));
   EXPECT_THAT(getDiagnosticString(), Eq(""));
@@ -4649,7 +4746,7 @@ TEST_F(ValidateImage, SignExtendScalarSIntTexelV14Good) {
   const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
   const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
 
 
   CompileSuccessfully(
   CompileSuccessfully(
-      GenerateShaderCode(body, extra, "Fragment", SPV_ENV_UNIVERSAL_1_4),
+      GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_4),
       SPV_ENV_UNIVERSAL_1_4);
       SPV_ENV_UNIVERSAL_1_4);
   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
   EXPECT_THAT(getDiagnosticString(), Eq(""));
   EXPECT_THAT(getDiagnosticString(), Eq(""));
@@ -4663,7 +4760,7 @@ TEST_F(ValidateImage, SignExtendScalarVectorUIntTexelV14Good) {
   const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
   const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
 
 
   CompileSuccessfully(
   CompileSuccessfully(
-      GenerateShaderCode(body, extra, "Fragment", SPV_ENV_UNIVERSAL_1_4),
+      GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_4),
       SPV_ENV_UNIVERSAL_1_4);
       SPV_ENV_UNIVERSAL_1_4);
   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
   EXPECT_THAT(getDiagnosticString(), Eq(""));
   EXPECT_THAT(getDiagnosticString(), Eq(""));
@@ -4677,7 +4774,7 @@ TEST_F(ValidateImage, SignExtendVectorSIntTexelV14Good) {
   const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
   const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
 
 
   CompileSuccessfully(
   CompileSuccessfully(
-      GenerateShaderCode(body, extra, "Fragment", SPV_ENV_UNIVERSAL_1_4),
+      GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_4),
       SPV_ENV_UNIVERSAL_1_4);
       SPV_ENV_UNIVERSAL_1_4);
   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
   EXPECT_THAT(getDiagnosticString(), Eq(""));
   EXPECT_THAT(getDiagnosticString(), Eq(""));
@@ -4695,7 +4792,7 @@ TEST_F(ValidateImage, ZeroExtendScalarUIntTexelV14Good) {
   const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
   const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
 
 
   CompileSuccessfully(
   CompileSuccessfully(
-      GenerateShaderCode(body, extra, "Fragment", SPV_ENV_UNIVERSAL_1_4),
+      GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_4),
       SPV_ENV_UNIVERSAL_1_4);
       SPV_ENV_UNIVERSAL_1_4);
   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
   EXPECT_THAT(getDiagnosticString(), Eq(""));
   EXPECT_THAT(getDiagnosticString(), Eq(""));
@@ -4710,7 +4807,7 @@ TEST_F(ValidateImage, ZeroExtendScalarSIntTexelV14Good) {
   const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
   const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
 
 
   CompileSuccessfully(
   CompileSuccessfully(
-      GenerateShaderCode(body, extra, "Fragment", SPV_ENV_UNIVERSAL_1_4),
+      GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_4),
       SPV_ENV_UNIVERSAL_1_4);
       SPV_ENV_UNIVERSAL_1_4);
   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
   EXPECT_THAT(getDiagnosticString(), Eq(""));
   EXPECT_THAT(getDiagnosticString(), Eq(""));
@@ -4724,7 +4821,7 @@ TEST_F(ValidateImage, ZeroExtendScalarVectorUIntTexelV14Good) {
   const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
   const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
 
 
   CompileSuccessfully(
   CompileSuccessfully(
-      GenerateShaderCode(body, extra, "Fragment", SPV_ENV_UNIVERSAL_1_4),
+      GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_4),
       SPV_ENV_UNIVERSAL_1_4);
       SPV_ENV_UNIVERSAL_1_4);
   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
   EXPECT_THAT(getDiagnosticString(), Eq(""));
   EXPECT_THAT(getDiagnosticString(), Eq(""));
@@ -4738,7 +4835,7 @@ TEST_F(ValidateImage, ZeroExtendVectorSIntTexelV14Good) {
   const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
   const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
 
 
   CompileSuccessfully(
   CompileSuccessfully(
-      GenerateShaderCode(body, extra, "Fragment", SPV_ENV_UNIVERSAL_1_4),
+      GenerateShaderCode(body, extra, "Fragment", "", SPV_ENV_UNIVERSAL_1_4),
       SPV_ENV_UNIVERSAL_1_4);
       SPV_ENV_UNIVERSAL_1_4);
   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
   EXPECT_THAT(getDiagnosticString(), Eq(""));
   EXPECT_THAT(getDiagnosticString(), Eq(""));

+ 0 - 1
3rdparty/spirv-tools/utils/check_copyright.py

@@ -16,7 +16,6 @@
 current directory.  Optionally insert them.  When inserting, replaces
 current directory.  Optionally insert them.  When inserting, replaces
 an MIT or Khronos free use license with Apache 2.
 an MIT or Khronos free use license with Apache 2.
 """
 """
-from __future__ import print_function
 
 
 import argparse
 import argparse
 import fileinput
 import fileinput

+ 0 - 2
3rdparty/spirv-tools/utils/check_symbol_exports.py

@@ -14,8 +14,6 @@
 # limitations under the License.
 # limitations under the License.
 """Checks names of global exports from a library."""
 """Checks names of global exports from a library."""
 
 
-from __future__ import print_function
-
 import os.path
 import os.path
 import re
 import re
 import subprocess
 import subprocess

+ 65 - 61
3rdparty/spirv-tools/utils/generate_grammar_tables.py

@@ -14,8 +14,6 @@
 # limitations under the License.
 # limitations under the License.
 """Generates various info tables from SPIR-V JSON grammar."""
 """Generates various info tables from SPIR-V JSON grammar."""
 
 
-from __future__ import print_function
-
 import errno
 import errno
 import json
 import json
 import os.path
 import os.path
@@ -36,8 +34,8 @@ SPV_AMD_shader_trinary_minmax
 
 
 
 
 def make_path_to_file(f):
 def make_path_to_file(f):
-    """Makes all ancestor directories to the given file, if they
-    don't yet exist.
+    """Makes all ancestor directories to the given file, if they don't yet
+    exist.
 
 
     Arguments:
     Arguments:
         f: The file whose ancestor directories are to be created.
         f: The file whose ancestor directories are to be created.
@@ -53,8 +51,8 @@ def make_path_to_file(f):
 
 
 
 
 def convert_min_required_version(version):
 def convert_min_required_version(version):
-    """Converts the minimal required SPIR-V version encoded in the
-    grammar to the symbol in SPIRV-Tools"""
+    """Converts the minimal required SPIR-V version encoded in the grammar to
+    the symbol in SPIRV-Tools."""
     if version is None:
     if version is None:
         return 'SPV_SPIRV_VERSION_WORD(1, 0)'
         return 'SPV_SPIRV_VERSION_WORD(1, 0)'
     if version == 'None':
     if version == 'None':
@@ -63,8 +61,8 @@ def convert_min_required_version(version):
 
 
 
 
 def convert_max_required_version(version):
 def convert_max_required_version(version):
-    """Converts the maximum required SPIR-V version encoded in the
-    grammar to the symbol in SPIRV-Tools"""
+    """Converts the maximum required SPIR-V version encoded in the grammar to
+    the symbol in SPIRV-Tools."""
     if version is None:
     if version is None:
         return '0xffffffffu'
         return '0xffffffffu'
     return 'SPV_SPIRV_VERSION_WORD({})'.format(version.replace('.', ','))
     return 'SPV_SPIRV_VERSION_WORD({})'.format(version.replace('.', ','))
@@ -79,7 +77,7 @@ def compose_capability_list(caps):
     Returns:
     Returns:
       a string containing the braced list of SpvCapability* enums named by caps.
       a string containing the braced list of SpvCapability* enums named by caps.
     """
     """
-    return "{" + ", ".join(['SpvCapability{}'.format(c) for c in caps]) + "}"
+    return '{' + ', '.join(['SpvCapability{}'.format(c) for c in caps]) + '}'
 
 
 
 
 def get_capability_array_name(caps):
 def get_capability_array_name(caps):
@@ -116,8 +114,8 @@ def compose_extension_list(exts):
     Returns:
     Returns:
       a string containing the braced list of extensions named by exts.
       a string containing the braced list of extensions named by exts.
     """
     """
-    return "{" + ", ".join(
-        ['spvtools::Extension::k{}'.format(e) for e in exts]) + "}"
+    return '{' + ', '.join(
+        ['spvtools::Extension::k{}'.format(e) for e in exts]) + '}'
 
 
 
 
 def get_extension_array_name(extensions):
 def get_extension_array_name(extensions):
@@ -148,8 +146,8 @@ def generate_extension_arrays(extensions):
 
 
 
 
 def convert_operand_kind(operand_tuple):
 def convert_operand_kind(operand_tuple):
-    """Returns the corresponding operand type used in spirv-tools for
-    the given operand kind and quantifier used in the JSON grammar.
+    """Returns the corresponding operand type used in spirv-tools for the given
+    operand kind and quantifier used in the JSON grammar.
 
 
     Arguments:
     Arguments:
       - operand_tuple: a tuple of two elements:
       - operand_tuple: a tuple of two elements:
@@ -211,8 +209,8 @@ def convert_operand_kind(operand_tuple):
 
 
 
 
 class InstInitializer(object):
 class InstInitializer(object):
-    """Instances holds a SPIR-V instruction suitable for printing as
-    the initializer for spv_opcode_desc_t."""
+    """Instances holds a SPIR-V instruction suitable for printing as the
+    initializer for spv_opcode_desc_t."""
 
 
     def __init__(self, opname, caps, exts, operands, version, lastVersion):
     def __init__(self, opname, caps, exts, operands, version, lastVersion):
         """Initialization.
         """Initialization.
@@ -244,8 +242,8 @@ class InstInitializer(object):
         self.lastVersion = convert_max_required_version(lastVersion)
         self.lastVersion = convert_max_required_version(lastVersion)
 
 
     def fix_syntax(self):
     def fix_syntax(self):
-        """Fix an instruction's syntax, adjusting for differences between
-        the officially released grammar and how SPIRV-Tools uses the grammar.
+        """Fix an instruction's syntax, adjusting for differences between the
+        officially released grammar and how SPIRV-Tools uses the grammar.
 
 
         Fixes:
         Fixes:
             - ExtInst should not end with SPV_OPERAND_VARIABLE_ID.
             - ExtInst should not end with SPV_OPERAND_VARIABLE_ID.
@@ -337,8 +335,8 @@ def generate_instruction(inst, is_ext_inst):
 
 
 
 
 def generate_instruction_table(inst_table):
 def generate_instruction_table(inst_table):
-    """Returns the info table containing all SPIR-V instructions,
-    sorted by opcode, and prefixed by capability arrays.
+    """Returns the info table containing all SPIR-V instructions, sorted by
+    opcode, and prefixed by capability arrays.
 
 
     Note:
     Note:
       - the built-in sorted() function is guaranteed to be stable.
       - the built-in sorted() function is guaranteed to be stable.
@@ -435,9 +433,9 @@ def generate_enum_operand_kind_entry(entry, extension_map):
     value = entry.get('value')
     value = entry.get('value')
     caps = entry.get('capabilities', [])
     caps = entry.get('capabilities', [])
     if value in extension_map:
     if value in extension_map:
-      exts = extension_map[value]
+        exts = extension_map[value]
     else:
     else:
-      exts = []
+        exts = []
     params = entry.get('parameters', [])
     params = entry.get('parameters', [])
     params = [p.get('kind') for p in params]
     params = [p.get('kind') for p in params]
     params = zip(params, [''] * len(params))
     params = zip(params, [''] * len(params))
@@ -453,8 +451,10 @@ def generate_enum_operand_kind_entry(entry, extension_map):
 
 
 def generate_enum_operand_kind(enum, synthetic_exts_list):
 def generate_enum_operand_kind(enum, synthetic_exts_list):
     """Returns the C definition for the given operand kind.
     """Returns the C definition for the given operand kind.
-    Also appends to |synthetic_exts_list| a list of extension
-    lists used."""
+
+    Also appends to |synthetic_exts_list| a list of extension lists
+    used.
+    """
     kind = enum.get('kind')
     kind = enum.get('kind')
     assert kind is not None
     assert kind is not None
 
 
@@ -462,9 +462,9 @@ def generate_enum_operand_kind(enum, synthetic_exts_list):
     # preserve their order so the first name listed in the grammar
     # preserve their order so the first name listed in the grammar
     # as the preferred name for disassembly.
     # as the preferred name for disassembly.
     if enum.get('category') == 'ValueEnum':
     if enum.get('category') == 'ValueEnum':
-        functor = lambda k: (k['value'])
+        def functor(k): return (k['value'])
     else:
     else:
-        functor = lambda k: (int(k['value'], 16))
+        def functor(k): return (int(k['value'], 16))
     entries = sorted(enum.get('enumerants', []), key=functor)
     entries = sorted(enum.get('enumerants', []), key=functor)
 
 
     # SubgroupEqMask and SubgroupEqMaskKHR are the same number with
     # SubgroupEqMask and SubgroupEqMaskKHR are the same number with
@@ -472,16 +472,16 @@ def generate_enum_operand_kind(enum, synthetic_exts_list):
     # does.  Both should have the extension list.
     # does.  Both should have the extension list.
     # So create a mapping from enum value to the union of the extensions
     # So create a mapping from enum value to the union of the extensions
     # across all those grammar entries.  Preserve order.
     # across all those grammar entries.  Preserve order.
-    extension_map = { }
+    extension_map = {}
     for e in entries:
     for e in entries:
-      value = e.get('value')
-      extension_map[value] = []
+        value = e.get('value')
+        extension_map[value] = []
     for e in entries:
     for e in entries:
-      value = e.get('value')
-      exts = e.get('extensions', [])
-      for ext in exts:
-        if ext not in extension_map[value]:
-          extension_map[value].append(ext)
+        value = e.get('value')
+        exts = e.get('extensions', [])
+        for ext in exts:
+            if ext not in extension_map[value]:
+                extension_map[value].append(ext)
     synthetic_exts_list.extend(extension_map.values())
     synthetic_exts_list.extend(extension_map.values())
 
 
     name = '{}_{}Entries'.format(PYGEN_VARIABLE_PREFIX, kind)
     name = '{}_{}Entries'.format(PYGEN_VARIABLE_PREFIX, kind)
@@ -544,7 +544,8 @@ def get_extension_list(instructions, operand_kinds):
 
 
     things_with_an_extensions_field = [item for item in instructions]
     things_with_an_extensions_field = [item for item in instructions]
 
 
-    enumerants = sum([item.get('enumerants', []) for item in operand_kinds], [])
+    enumerants = sum([item.get('enumerants', [])
+                      for item in operand_kinds], [])
 
 
     things_with_an_extensions_field.extend(enumerants)
     things_with_an_extensions_field.extend(enumerants)
 
 
@@ -553,11 +554,12 @@ def get_extension_list(instructions, operand_kinds):
                       if item.get('extensions')], [])
                       if item.get('extensions')], [])
 
 
     for item in EXTENSIONS_FROM_SPIRV_REGISTRY_AND_NOT_FROM_GRAMMARS.split():
     for item in EXTENSIONS_FROM_SPIRV_REGISTRY_AND_NOT_FROM_GRAMMARS.split():
-        # If it's already listed in a grammar, then don't put it in the
-        # special exceptions list.
-        assert item not in extensions, "Extension %s is already in a grammar file" % item
+            # If it's already listed in a grammar, then don't put it in the
+            # special exceptions list.
+        assert item not in extensions, 'Extension %s is already in a grammar file' % item
 
 
-    extensions.extend(EXTENSIONS_FROM_SPIRV_REGISTRY_AND_NOT_FROM_GRAMMARS.split())
+    extensions.extend(
+        EXTENSIONS_FROM_SPIRV_REGISTRY_AND_NOT_FROM_GRAMMARS.split())
 
 
     # Validator would ignore type declaration unique check. Should only be used
     # Validator would ignore type declaration unique check. Should only be used
     # for legacy autogenerated test files containing multiple instances of the
     # for legacy autogenerated test files containing multiple instances of the
@@ -570,8 +572,7 @@ def get_extension_list(instructions, operand_kinds):
 
 
 def get_capabilities(operand_kinds):
 def get_capabilities(operand_kinds):
     """Returns capabilities as a list of JSON objects, in order of
     """Returns capabilities as a list of JSON objects, in order of
-    appearance.
-    """
+    appearance."""
     enumerants = sum([item.get('enumerants', []) for item in operand_kinds
     enumerants = sum([item.get('enumerants', []) for item in operand_kinds
                       if item.get('kind') in ['Capability']], [])
                       if item.get('kind') in ['Capability']], [])
     return enumerants
     return enumerants
@@ -620,6 +621,7 @@ def generate_string_to_extension_mapping(extensions):
 
 
 def generate_capability_to_string_mapping(operand_kinds):
 def generate_capability_to_string_mapping(operand_kinds):
     """Returns mapping function from capabilities to corresponding strings.
     """Returns mapping function from capabilities to corresponding strings.
+
     We take care to avoid emitting duplicate values.
     We take care to avoid emitting duplicate values.
     """
     """
     function = 'const char* CapabilityToString(SpvCapability capability) {\n'
     function = 'const char* CapabilityToString(SpvCapability capability) {\n'
@@ -649,8 +651,8 @@ def generate_all_string_enum_mappings(extensions, operand_kinds):
 
 
 
 
 def precondition_operand_kinds(operand_kinds):
 def precondition_operand_kinds(operand_kinds):
-    """For operand kinds that have the same number, make sure they all have
-    the same extension list"""
+    """For operand kinds that have the same number, make sure they all have the
+    same extension list."""
     return operand_kinds
     return operand_kinds
 
 
 
 
@@ -751,45 +753,47 @@ def main():
         if args.core_insts_output is not None:
         if args.core_insts_output is not None:
             make_path_to_file(args.core_insts_output)
             make_path_to_file(args.core_insts_output)
             make_path_to_file(args.operand_kinds_output)
             make_path_to_file(args.operand_kinds_output)
-            print(generate_instruction_table(core_grammar['instructions']),
-              file=open(args.core_insts_output, 'w'))
-            print(generate_operand_kind_table(operand_kinds),
-              file=open(args.operand_kinds_output, 'w'))
+            with open(args.core_insts_output, 'w') as f:
+                f.write(generate_instruction_table(
+                    core_grammar['instructions']))
+            with open(args.operand_kinds_output, 'w') as f:
+                f.write(generate_operand_kind_table(operand_kinds))
         if args.extension_enum_output is not None:
         if args.extension_enum_output is not None:
             make_path_to_file(args.extension_enum_output)
             make_path_to_file(args.extension_enum_output)
-            print(generate_extension_enum(extensions),
-              file=open(args.extension_enum_output, 'w'))
+            with open(args.extension_enum_output, 'w') as f:
+                f.write(generate_extension_enum(extensions))
         if args.enum_string_mapping_output is not None:
         if args.enum_string_mapping_output is not None:
             make_path_to_file(args.enum_string_mapping_output)
             make_path_to_file(args.enum_string_mapping_output)
-            print(generate_all_string_enum_mappings(extensions, operand_kinds),
-              file=open(args.enum_string_mapping_output, 'w'))
+            with open(args.enum_string_mapping_output, 'w') as f:
+                f.write(generate_all_string_enum_mappings(
+                    extensions, operand_kinds))
 
 
     if args.extinst_glsl_grammar is not None:
     if args.extinst_glsl_grammar is not None:
         with open(args.extinst_glsl_grammar) as json_file:
         with open(args.extinst_glsl_grammar) as json_file:
             grammar = json.loads(json_file.read())
             grammar = json.loads(json_file.read())
             make_path_to_file(args.glsl_insts_output)
             make_path_to_file(args.glsl_insts_output)
-            print(generate_extended_instruction_table(
-                    grammar['instructions'], "glsl"),
-                  file=open(args.glsl_insts_output, 'w'))
+            with open(args.glsl_insts_output, 'w') as f:
+                f.write(generate_extended_instruction_table(
+                    grammar['instructions'], 'glsl'))
 
 
     if args.extinst_opencl_grammar is not None:
     if args.extinst_opencl_grammar is not None:
         with open(args.extinst_opencl_grammar) as json_file:
         with open(args.extinst_opencl_grammar) as json_file:
             grammar = json.loads(json_file.read())
             grammar = json.loads(json_file.read())
             make_path_to_file(args.opencl_insts_output)
             make_path_to_file(args.opencl_insts_output)
-            print(generate_extended_instruction_table(
-                    grammar['instructions'], "opencl"),
-                  file=open(args.opencl_insts_output, 'w'))
+            with open(args.opencl_insts_output, 'w') as f:
+                f.write(generate_extended_instruction_table(
+                    grammar['instructions'], 'opencl'))
 
 
     if args.extinst_vendor_grammar is not None:
     if args.extinst_vendor_grammar is not None:
         with open(args.extinst_vendor_grammar) as json_file:
         with open(args.extinst_vendor_grammar) as json_file:
             grammar = json.loads(json_file.read())
             grammar = json.loads(json_file.read())
             make_path_to_file(args.vendor_insts_output)
             make_path_to_file(args.vendor_insts_output)
             name = args.extinst_vendor_grammar
             name = args.extinst_vendor_grammar
-            start = name.find("extinst.") + len("extinst.")
-            name = name[start:-len(".grammar.json")].replace("-", "_")
-            print(generate_extended_instruction_table(
-                    grammar['instructions'], name),
-                  file=open(args.vendor_insts_output, 'w'))
+            start = name.find('extinst.') + len('extinst.')
+            name = name[start:-len('.grammar.json')].replace('-', '_')
+            with open(args.vendor_insts_output, 'w') as f:
+                f.write(generate_extended_instruction_table(
+                    grammar['instructions'], name))
 
 
 
 
 if __name__ == '__main__':
 if __name__ == '__main__':

+ 2 - 3
3rdparty/spirv-tools/utils/generate_language_headers.py

@@ -14,8 +14,6 @@
 # limitations under the License.
 # limitations under the License.
 """Generates language headers from a JSON grammar file"""
 """Generates language headers from a JSON grammar file"""
 
 
-from __future__ import print_function
-
 import errno
 import errno
 import json
 import json
 import os.path
 import os.path
@@ -181,7 +179,8 @@ def main():
                                  version = grammar_json['version'],
                                  version = grammar_json['version'],
                                  revision = grammar_json['revision'])
                                  revision = grammar_json['revision'])
         make_path_to_file(args.extinst_output_base)
         make_path_to_file(args.extinst_output_base)
-        print(CGenerator().generate(grammar), file=open(args.extinst_output_base + '.h', 'w'))
+        with open(args.extinst_output_base + '.h', 'w') as f:
+            f.write(CGenerator().generate(grammar))
 
 
 
 
 if __name__ == '__main__':
 if __name__ == '__main__':

+ 2 - 3
3rdparty/spirv-tools/utils/generate_registry_tables.py

@@ -14,8 +14,6 @@
 # limitations under the License.
 # limitations under the License.
 """Generates the vendor tool table from the SPIR-V XML registry."""
 """Generates the vendor tool table from the SPIR-V XML registry."""
 
 
-from __future__ import print_function
-
 import distutils.dir_util
 import distutils.dir_util
 import os.path
 import os.path
 import xml.etree.ElementTree
 import xml.etree.ElementTree
@@ -65,7 +63,8 @@ def main():
        registry = xml.etree.ElementTree.fromstring(xml_in.read())
        registry = xml.etree.ElementTree.fromstring(xml_in.read())
 
 
     distutils.dir_util.mkpath(os.path.dirname(args.generator_output))
     distutils.dir_util.mkpath(os.path.dirname(args.generator_output))
-    print(generate_vendor_table(registry), file=open(args.generator_output, 'w'))
+    with open(args.generator_output, 'w') as f:
+      f.write(generate_vendor_table(registry))
 
 
 
 
 if __name__ == '__main__':
 if __name__ == '__main__':

+ 0 - 2
3rdparty/spirv-tools/utils/generate_vim_syntax.py

@@ -14,8 +14,6 @@
 # limitations under the License.
 # limitations under the License.
 """Generates Vim syntax rules for SPIR-V assembly (.spvasm) files"""
 """Generates Vim syntax rules for SPIR-V assembly (.spvasm) files"""
 
 
-from __future__ import print_function
-
 import json
 import json
 
 
 PREAMBLE="""" Vim syntax file
 PREAMBLE="""" Vim syntax file

+ 0 - 2
3rdparty/spirv-tools/utils/update_build_version.py

@@ -29,8 +29,6 @@
 #    "unknown hash".
 #    "unknown hash".
 # The string contents are escaped as necessary.
 # The string contents are escaped as necessary.
 
 
-from __future__ import print_function
-
 import datetime
 import datetime
 import errno
 import errno
 import os
 import os

Някои файлове не бяха показани, защото твърде много файлове са промени