瀏覽代碼

Updated spirv-tools.

Бранимир Караџић 3 年之前
父節點
當前提交
0a26666409
共有 39 個文件被更改,包括 855 次插入398 次删除
  1. 1 1
      3rdparty/spirv-tools/include/generated/build-version.inc
  2. 10 1
      3rdparty/spirv-tools/include/generated/core.insts-unified1.inc
  3. 2 0
      3rdparty/spirv-tools/include/generated/enum_string_mapping.inc
  4. 1 0
      3rdparty/spirv-tools/include/generated/extension_enum.inc
  5. 3 1
      3rdparty/spirv-tools/include/generated/operand.kinds-unified1.inc
  6. 7 0
      3rdparty/spirv-tools/include/spirv-tools/optimizer.hpp
  7. 3 3
      3rdparty/spirv-tools/source/assembly_grammar.cpp
  8. 402 210
      3rdparty/spirv-tools/source/diff/diff.cpp
  9. 9 5
      3rdparty/spirv-tools/source/operand.cpp
  10. 1 0
      3rdparty/spirv-tools/source/opt/aggressive_dead_code_elim_pass.cpp
  11. 1 1
      3rdparty/spirv-tools/source/opt/dead_branch_elim_pass.cpp
  12. 146 0
      3rdparty/spirv-tools/source/opt/eliminate_dead_input_components_pass.cpp
  13. 59 0
      3rdparty/spirv-tools/source/opt/eliminate_dead_input_components_pass.h
  14. 0 7
      3rdparty/spirv-tools/source/opt/inst_bindless_check_pass.cpp
  15. 0 7
      3rdparty/spirv-tools/source/opt/interp_fixup_pass.cpp
  16. 1 0
      3rdparty/spirv-tools/source/opt/local_access_chain_convert_pass.cpp
  17. 1 0
      3rdparty/spirv-tools/source/opt/local_single_block_elim_pass.cpp
  18. 1 0
      3rdparty/spirv-tools/source/opt/local_single_store_elim_pass.cpp
  19. 7 0
      3rdparty/spirv-tools/source/opt/optimizer.cpp
  20. 7 0
      3rdparty/spirv-tools/source/opt/pass.h
  21. 1 0
      3rdparty/spirv-tools/source/opt/passes.h
  22. 1 1
      3rdparty/spirv-tools/source/opt/private_to_local_pass.cpp
  23. 4 0
      3rdparty/spirv-tools/source/opt/spread_volatile_semantics.cpp
  24. 7 0
      3rdparty/spirv-tools/source/opt/spread_volatile_semantics.h
  25. 6 0
      3rdparty/spirv-tools/source/opt/types.cpp
  26. 1 0
      3rdparty/spirv-tools/source/opt/types.h
  27. 11 8
      3rdparty/spirv-tools/source/text.cpp
  28. 1 0
      3rdparty/spirv-tools/source/util/ilist.h
  29. 2 2
      3rdparty/spirv-tools/source/val/validate_annotation.cpp
  30. 1 1
      3rdparty/spirv-tools/source/val/validate_atomics.cpp
  31. 48 35
      3rdparty/spirv-tools/source/val/validate_bitwise.cpp
  32. 3 8
      3rdparty/spirv-tools/source/val/validate_cfg.cpp
  33. 25 25
      3rdparty/spirv-tools/source/val/validate_decorations.cpp
  34. 18 19
      3rdparty/spirv-tools/source/val/validate_function.cpp
  35. 3 2
      3rdparty/spirv-tools/source/val/validate_image.cpp
  36. 1 2
      3rdparty/spirv-tools/source/val/validate_logicals.cpp
  37. 36 48
      3rdparty/spirv-tools/source/val/validate_memory.cpp
  38. 22 7
      3rdparty/spirv-tools/source/val/validation_state.cpp
  39. 2 4
      3rdparty/spirv-tools/source/val/validation_state.h

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

@@ -1 +1 @@
-"v2022.2-dev", "SPIRV-Tools v2022.2-dev 6a1809baa2ff1cb740db73cf23ad9df390a40ea3"
+"v2022.2-dev", "SPIRV-Tools v2022.2-dev 5ae22716672dc8dbefc3b24f142ffa9f50bab74c"

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

@@ -31,6 +31,7 @@ static const SpvCapability pygen_variable_caps_GroupNonUniformQuad[] = {SpvCapab
 static const SpvCapability pygen_variable_caps_GroupNonUniformShuffle[] = {SpvCapabilityGroupNonUniformShuffle};
 static const SpvCapability pygen_variable_caps_GroupNonUniformShuffle[] = {SpvCapabilityGroupNonUniformShuffle};
 static const SpvCapability pygen_variable_caps_GroupNonUniformShuffleRelative[] = {SpvCapabilityGroupNonUniformShuffleRelative};
 static const SpvCapability pygen_variable_caps_GroupNonUniformShuffleRelative[] = {SpvCapabilityGroupNonUniformShuffleRelative};
 static const SpvCapability pygen_variable_caps_GroupNonUniformVote[] = {SpvCapabilityGroupNonUniformVote};
 static const SpvCapability pygen_variable_caps_GroupNonUniformVote[] = {SpvCapabilityGroupNonUniformVote};
+static const SpvCapability pygen_variable_caps_GroupUniformArithmeticKHR[] = {SpvCapabilityGroupUniformArithmeticKHR};
 static const SpvCapability pygen_variable_caps_Groups[] = {SpvCapabilityGroups};
 static const SpvCapability pygen_variable_caps_Groups[] = {SpvCapabilityGroups};
 static const SpvCapability pygen_variable_caps_ImageFootprintNV[] = {SpvCapabilityImageFootprintNV};
 static const SpvCapability pygen_variable_caps_ImageFootprintNV[] = {SpvCapabilityImageFootprintNV};
 static const SpvCapability pygen_variable_caps_ImageQuery[] = {SpvCapabilityImageQuery};
 static const SpvCapability pygen_variable_caps_ImageQuery[] = {SpvCapabilityImageQuery};
@@ -761,5 +762,13 @@ static const spv_opcode_desc_t kOpcodeTableEntries[] = {
   {"ConstantCompositeContinuedINTEL", SpvOpConstantCompositeContinuedINTEL, 1, pygen_variable_caps_LongConstantCompositeINTEL, 1, {SPV_OPERAND_TYPE_VARIABLE_ID}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu},
   {"ConstantCompositeContinuedINTEL", SpvOpConstantCompositeContinuedINTEL, 1, pygen_variable_caps_LongConstantCompositeINTEL, 1, {SPV_OPERAND_TYPE_VARIABLE_ID}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu},
   {"SpecConstantCompositeContinuedINTEL", SpvOpSpecConstantCompositeContinuedINTEL, 1, pygen_variable_caps_LongConstantCompositeINTEL, 1, {SPV_OPERAND_TYPE_VARIABLE_ID}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu},
   {"SpecConstantCompositeContinuedINTEL", SpvOpSpecConstantCompositeContinuedINTEL, 1, pygen_variable_caps_LongConstantCompositeINTEL, 1, {SPV_OPERAND_TYPE_VARIABLE_ID}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu},
   {"ControlBarrierArriveINTEL", SpvOpControlBarrierArriveINTEL, 1, pygen_variable_caps_SplitBarrierINTEL, 3, {SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu},
   {"ControlBarrierArriveINTEL", SpvOpControlBarrierArriveINTEL, 1, pygen_variable_caps_SplitBarrierINTEL, 3, {SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu},
-  {"ControlBarrierWaitINTEL", SpvOpControlBarrierWaitINTEL, 1, pygen_variable_caps_SplitBarrierINTEL, 3, {SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}
+  {"ControlBarrierWaitINTEL", SpvOpControlBarrierWaitINTEL, 1, pygen_variable_caps_SplitBarrierINTEL, 3, {SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu},
+  {"GroupIMulKHR", SpvOpGroupIMulKHR, 1, pygen_variable_caps_GroupUniformArithmeticKHR, 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, 0, nullptr, 0xffffffffu, 0xffffffffu},
+  {"GroupFMulKHR", SpvOpGroupFMulKHR, 1, pygen_variable_caps_GroupUniformArithmeticKHR, 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, 0, nullptr, 0xffffffffu, 0xffffffffu},
+  {"GroupBitwiseAndKHR", SpvOpGroupBitwiseAndKHR, 1, pygen_variable_caps_GroupUniformArithmeticKHR, 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, 0, nullptr, 0xffffffffu, 0xffffffffu},
+  {"GroupBitwiseOrKHR", SpvOpGroupBitwiseOrKHR, 1, pygen_variable_caps_GroupUniformArithmeticKHR, 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, 0, nullptr, 0xffffffffu, 0xffffffffu},
+  {"GroupBitwiseXorKHR", SpvOpGroupBitwiseXorKHR, 1, pygen_variable_caps_GroupUniformArithmeticKHR, 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, 0, nullptr, 0xffffffffu, 0xffffffffu},
+  {"GroupLogicalAndKHR", SpvOpGroupLogicalAndKHR, 1, pygen_variable_caps_GroupUniformArithmeticKHR, 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, 0, nullptr, 0xffffffffu, 0xffffffffu},
+  {"GroupLogicalOrKHR", SpvOpGroupLogicalOrKHR, 1, pygen_variable_caps_GroupUniformArithmeticKHR, 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, 0, nullptr, 0xffffffffu, 0xffffffffu},
+  {"GroupLogicalXorKHR", SpvOpGroupLogicalXorKHR, 1, pygen_variable_caps_GroupUniformArithmeticKHR, 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, 0, nullptr, 0xffffffffu, 0xffffffffu}
 };
 };

文件差異過大導致無法顯示
+ 2 - 0
3rdparty/spirv-tools/include/generated/enum_string_mapping.inc


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

@@ -78,6 +78,7 @@ kSPV_KHR_storage_buffer_storage_class,
 kSPV_KHR_subgroup_uniform_control_flow,
 kSPV_KHR_subgroup_uniform_control_flow,
 kSPV_KHR_subgroup_vote,
 kSPV_KHR_subgroup_vote,
 kSPV_KHR_terminate_invocation,
 kSPV_KHR_terminate_invocation,
+kSPV_KHR_uniform_group_instructions,
 kSPV_KHR_variable_pointers,
 kSPV_KHR_variable_pointers,
 kSPV_KHR_vulkan_memory_model,
 kSPV_KHR_vulkan_memory_model,
 kSPV_KHR_workgroup_memory_explicit_layout,
 kSPV_KHR_workgroup_memory_explicit_layout,

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

@@ -195,6 +195,7 @@ static const spvtools::Extension pygen_variable_exts_SPV_KHR_shader_draw_paramet
 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};
 static const spvtools::Extension pygen_variable_exts_SPV_KHR_subgroup_uniform_control_flow[] = {spvtools::Extension::kSPV_KHR_subgroup_uniform_control_flow};
 static const spvtools::Extension pygen_variable_exts_SPV_KHR_subgroup_uniform_control_flow[] = {spvtools::Extension::kSPV_KHR_subgroup_uniform_control_flow};
 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_KHR_uniform_group_instructions[] = {spvtools::Extension::kSPV_KHR_uniform_group_instructions};
 static const spvtools::Extension pygen_variable_exts_SPV_KHR_variable_pointers[] = {spvtools::Extension::kSPV_KHR_variable_pointers};
 static const spvtools::Extension pygen_variable_exts_SPV_KHR_variable_pointers[] = {spvtools::Extension::kSPV_KHR_variable_pointers};
 static const spvtools::Extension pygen_variable_exts_SPV_KHR_vulkan_memory_model[] = {spvtools::Extension::kSPV_KHR_vulkan_memory_model};
 static const spvtools::Extension pygen_variable_exts_SPV_KHR_vulkan_memory_model[] = {spvtools::Extension::kSPV_KHR_vulkan_memory_model};
 static const spvtools::Extension pygen_variable_exts_SPV_KHR_workgroup_memory_explicit_layout[] = {spvtools::Extension::kSPV_KHR_workgroup_memory_explicit_layout};
 static const spvtools::Extension pygen_variable_exts_SPV_KHR_workgroup_memory_explicit_layout[] = {spvtools::Extension::kSPV_KHR_workgroup_memory_explicit_layout};
@@ -1157,7 +1158,8 @@ static const spv_operand_desc_t pygen_variable_CapabilityEntries[] = {
   {"OptNoneINTEL", 6094, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_optnone, {}, 0xffffffffu, 0xffffffffu},
   {"OptNoneINTEL", 6094, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_optnone, {}, 0xffffffffu, 0xffffffffu},
   {"AtomicFloat16AddEXT", 6095, 0, nullptr, 1, pygen_variable_exts_SPV_EXT_shader_atomic_float16_add, {}, 0xffffffffu, 0xffffffffu},
   {"AtomicFloat16AddEXT", 6095, 0, nullptr, 1, pygen_variable_exts_SPV_EXT_shader_atomic_float16_add, {}, 0xffffffffu, 0xffffffffu},
   {"DebugInfoModuleINTEL", 6114, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_debug_module, {}, 0xffffffffu, 0xffffffffu},
   {"DebugInfoModuleINTEL", 6114, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_debug_module, {}, 0xffffffffu, 0xffffffffu},
-  {"SplitBarrierINTEL", 6141, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_split_barrier, {}, 0xffffffffu, 0xffffffffu}
+  {"SplitBarrierINTEL", 6141, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_split_barrier, {}, 0xffffffffu, 0xffffffffu},
+  {"GroupUniformArithmeticKHR", 6400, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_uniform_group_instructions, {}, 0xffffffffu, 0xffffffffu}
 };
 };
 
 
 static const spv_operand_desc_t pygen_variable_RayQueryIntersectionEntries[] = {
 static const spv_operand_desc_t pygen_variable_RayQueryIntersectionEntries[] = {

+ 7 - 0
3rdparty/spirv-tools/include/spirv-tools/optimizer.hpp

@@ -886,6 +886,13 @@ Optimizer::PassToken CreateAmdExtToKhrPass();
 // propagated into their final positions.
 // propagated into their final positions.
 Optimizer::PassToken CreateInterpolateFixupPass();
 Optimizer::PassToken CreateInterpolateFixupPass();
 
 
+// Removes unused components from composite input variables. Current
+// implementation just removes trailing unused components from input arrays.
+// The pass performs best after maximizing dead code removal. A subsequent dead
+// code elimination pass would be beneficial in removing newly unused component
+// types.
+Optimizer::PassToken CreateEliminateDeadInputComponentsPass();
+
 // Creates a convert-to-sampled-image pass to convert images and/or
 // Creates a convert-to-sampled-image pass to convert images and/or
 // samplers with given pairs of descriptor set and binding to sampled image.
 // samplers with given pairs of descriptor set and binding to sampled image.
 // If a pair of an image and a sampler have the same pair of descriptor set and
 // If a pair of an image and a sampler have the same pair of descriptor set and

+ 3 - 3
3rdparty/spirv-tools/source/assembly_grammar.cpp

@@ -62,9 +62,9 @@ spv_result_t spvTextParseMaskOperand(spv_target_env env,
     end = std::find(begin, text_end, separator);
     end = std::find(begin, text_end, separator);
 
 
     spv_operand_desc entry = nullptr;
     spv_operand_desc entry = nullptr;
-    if (spvOperandTableNameLookup(env, operandTable, type, begin, end - begin,
-                                  &entry)) {
-      return SPV_ERROR_INVALID_TEXT;
+    if (auto error = spvOperandTableNameLookup(env, operandTable, type, begin,
+                                               end - begin, &entry)) {
+      return error;
     }
     }
     value |= entry->value;
     value |= entry->value;
 
 

文件差異過大導致無法顯示
+ 402 - 210
3rdparty/spirv-tools/source/diff/diff.cpp


+ 9 - 5
3rdparty/spirv-tools/source/operand.cpp

@@ -72,12 +72,16 @@ spv_result_t spvOperandTableNameLookup(spv_target_env env,
       // Note that the second rule assumes the extension enabling this operand
       // Note that the second rule assumes the extension enabling this operand
       // is indeed requested in the SPIR-V code; checking that should be
       // is indeed requested in the SPIR-V code; checking that should be
       // validator's work.
       // validator's work.
-      if (((version >= entry.minVersion && version <= entry.lastVersion) ||
-           entry.numExtensions > 0u || entry.numCapabilities > 0u) &&
-          nameLength == strlen(entry.name) &&
+      if (nameLength == strlen(entry.name) &&
           !strncmp(entry.name, name, nameLength)) {
           !strncmp(entry.name, name, nameLength)) {
-        *pEntry = &entry;
-        return SPV_SUCCESS;
+        if ((version >= entry.minVersion && version <= entry.lastVersion) ||
+            entry.numExtensions > 0u || entry.numCapabilities > 0u) {
+          *pEntry = &entry;
+          return SPV_SUCCESS;
+        } else {
+          // if there is no extension/capability then the version is wrong
+          return SPV_ERROR_WRONG_VERSION;
+        }
       }
       }
     }
     }
   }
   }

+ 1 - 0
3rdparty/spirv-tools/source/opt/aggressive_dead_code_elim_pass.cpp

@@ -967,6 +967,7 @@ void AggressiveDCEPass::InitExtensions() {
       "SPV_KHR_integer_dot_product",
       "SPV_KHR_integer_dot_product",
       "SPV_EXT_shader_image_int64",
       "SPV_EXT_shader_image_int64",
       "SPV_KHR_non_semantic_info",
       "SPV_KHR_non_semantic_info",
+      "SPV_KHR_uniform_group_instructions",
   });
   });
 }
 }
 
 

+ 1 - 1
3rdparty/spirv-tools/source/opt/dead_branch_elim_pass.cpp

@@ -207,7 +207,7 @@ bool DeadBranchElimPass::SimplifyBranch(BasicBlock* block,
       Instruction::OperandList new_operands;
       Instruction::OperandList new_operands;
       new_operands.push_back(terminator->GetInOperand(0));
       new_operands.push_back(terminator->GetInOperand(0));
       new_operands.push_back({SPV_OPERAND_TYPE_ID, {live_lab_id}});
       new_operands.push_back({SPV_OPERAND_TYPE_ID, {live_lab_id}});
-      terminator->SetInOperands(move(new_operands));
+      terminator->SetInOperands(std::move(new_operands));
       context()->UpdateDefUse(terminator);
       context()->UpdateDefUse(terminator);
     } else {
     } else {
       // Check if the merge instruction is still needed because of a
       // Check if the merge instruction is still needed because of a

+ 146 - 0
3rdparty/spirv-tools/source/opt/eliminate_dead_input_components_pass.cpp

@@ -0,0 +1,146 @@
+// Copyright (c) 2022 The Khronos Group Inc.
+// Copyright (c) 2022 LunarG Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "source/opt/eliminate_dead_input_components_pass.h"
+
+#include <set>
+#include <vector>
+
+#include "source/opt/instruction.h"
+#include "source/opt/ir_builder.h"
+#include "source/opt/ir_context.h"
+#include "source/util/bit_vector.h"
+
+namespace {
+
+const uint32_t kAccessChainBaseInIdx = 0;
+const uint32_t kAccessChainIndex0InIdx = 1;
+const uint32_t kConstantValueInIdx = 0;
+const uint32_t kVariableStorageClassInIdx = 0;
+
+}  // namespace
+
+namespace spvtools {
+namespace opt {
+
+Pass::Status EliminateDeadInputComponentsPass::Process() {
+  // Current functionality assumes shader capability
+  if (!context()->get_feature_mgr()->HasCapability(SpvCapabilityShader))
+    return Status::SuccessWithoutChange;
+  analysis::DefUseManager* def_use_mgr = context()->get_def_use_mgr();
+  analysis::TypeManager* type_mgr = context()->get_type_mgr();
+  bool modified = false;
+  std::vector<std::pair<Instruction*, unsigned>> arrays_to_change;
+  for (auto& var : context()->types_values()) {
+    if (var.opcode() != SpvOpVariable) {
+      continue;
+    }
+    analysis::Type* var_type = type_mgr->GetType(var.type_id());
+    analysis::Pointer* ptr_type = var_type->AsPointer();
+    if (ptr_type == nullptr) {
+      continue;
+    }
+    if (ptr_type->storage_class() != SpvStorageClassInput) {
+      continue;
+    }
+    const analysis::Array* arr_type = ptr_type->pointee_type()->AsArray();
+    if (arr_type == nullptr) {
+      continue;
+    }
+    unsigned arr_len_id = arr_type->LengthId();
+    Instruction* arr_len_inst = def_use_mgr->GetDef(arr_len_id);
+    if (arr_len_inst->opcode() != SpvOpConstant) {
+      continue;
+    }
+    // SPIR-V requires array size is >= 1, so this works for signed or
+    // unsigned size
+    unsigned original_max =
+        arr_len_inst->GetSingleWordInOperand(kConstantValueInIdx) - 1;
+    unsigned max_idx = FindMaxIndex(var, original_max);
+    if (max_idx != original_max) {
+      ChangeArrayLength(var, max_idx + 1);
+      modified = true;
+    }
+  }
+
+  return modified ? Status::SuccessWithChange : Status::SuccessWithoutChange;
+}
+
+unsigned EliminateDeadInputComponentsPass::FindMaxIndex(Instruction& var,
+                                                        unsigned original_max) {
+  unsigned max = 0;
+  bool seen_non_const_ac = false;
+  assert(var.opcode() == SpvOpVariable && "must be variable");
+  context()->get_def_use_mgr()->WhileEachUser(
+      var.result_id(), [&max, &seen_non_const_ac, var, this](Instruction* use) {
+        auto use_opcode = use->opcode();
+        if (use_opcode == SpvOpLoad || use_opcode == SpvOpCopyMemory ||
+            use_opcode == SpvOpCopyMemorySized ||
+            use_opcode == SpvOpCopyObject) {
+          seen_non_const_ac = true;
+          return false;
+        }
+        if (use->opcode() != SpvOpAccessChain &&
+            use->opcode() != SpvOpInBoundsAccessChain) {
+          return true;
+        }
+        // OpAccessChain with no indices currently not optimized
+        if (use->NumInOperands() == 1) {
+          seen_non_const_ac = true;
+          return false;
+        }
+        unsigned base_id = use->GetSingleWordInOperand(kAccessChainBaseInIdx);
+        USE_ASSERT(base_id == var.result_id() && "unexpected base");
+        unsigned idx_id = use->GetSingleWordInOperand(kAccessChainIndex0InIdx);
+        Instruction* idx_inst = context()->get_def_use_mgr()->GetDef(idx_id);
+        if (idx_inst->opcode() != SpvOpConstant) {
+          seen_non_const_ac = true;
+          return false;
+        }
+        unsigned value = idx_inst->GetSingleWordInOperand(kConstantValueInIdx);
+        if (value > max) max = value;
+        return true;
+      });
+  return seen_non_const_ac ? original_max : max;
+}
+
+void EliminateDeadInputComponentsPass::ChangeArrayLength(Instruction& arr,
+                                                         unsigned length) {
+  analysis::TypeManager* type_mgr = context()->get_type_mgr();
+  analysis::ConstantManager* const_mgr = context()->get_constant_mgr();
+  analysis::DefUseManager* def_use_mgr = context()->get_def_use_mgr();
+  analysis::Pointer* ptr_type = type_mgr->GetType(arr.type_id())->AsPointer();
+  const analysis::Array* arr_ty = ptr_type->pointee_type()->AsArray();
+  assert(arr_ty && "expecting array type");
+  uint32_t length_id = const_mgr->GetUIntConst(length);
+  analysis::Array new_arr_ty(arr_ty->element_type(),
+                             arr_ty->GetConstantLengthInfo(length_id, length));
+  analysis::Type* reg_new_arr_ty = type_mgr->GetRegisteredType(&new_arr_ty);
+  analysis::Pointer new_ptr_ty(reg_new_arr_ty, SpvStorageClassInput);
+  analysis::Type* reg_new_ptr_ty = type_mgr->GetRegisteredType(&new_ptr_ty);
+  uint32_t new_ptr_ty_id = type_mgr->GetTypeInstruction(reg_new_ptr_ty);
+  arr.SetResultType(new_ptr_ty_id);
+  def_use_mgr->AnalyzeInstUse(&arr);
+  // Move array OpVariable instruction after its new type to preserve order
+  USE_ASSERT(arr.GetSingleWordInOperand(kVariableStorageClassInIdx) !=
+                 SpvStorageClassFunction &&
+             "cannot move Function variable");
+  Instruction* new_ptr_ty_inst = def_use_mgr->GetDef(new_ptr_ty_id);
+  arr.RemoveFromList();
+  arr.InsertAfter(new_ptr_ty_inst);
+}
+
+}  // namespace opt
+}  // namespace spvtools

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

@@ -0,0 +1,59 @@
+// Copyright (c) 2022 The Khronos Group Inc.
+// Copyright (c) 2022 LunarG Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef SOURCE_OPT_ELIMINATE_DEAD_INPUT_COMPONENTS_H_
+#define SOURCE_OPT_ELIMINATE_DEAD_INPUT_COMPONENTS_H_
+
+#include <unordered_map>
+
+#include "source/opt/ir_context.h"
+#include "source/opt/module.h"
+#include "source/opt/pass.h"
+
+namespace spvtools {
+namespace opt {
+
+// See optimizer.hpp for documentation.
+class EliminateDeadInputComponentsPass : public Pass {
+ public:
+  explicit EliminateDeadInputComponentsPass() {}
+
+  const char* name() const override { return "reduce-load-size"; }
+  Status Process() override;
+
+  // Return the mask of preserved Analyses.
+  IRContext::Analysis GetPreservedAnalyses() override {
+    return IRContext::kAnalysisDefUse |
+           IRContext::kAnalysisInstrToBlockMapping |
+           IRContext::kAnalysisCombinators | IRContext::kAnalysisCFG |
+           IRContext::kAnalysisDominatorAnalysis |
+           IRContext::kAnalysisLoopAnalysis | IRContext::kAnalysisNameMap |
+           IRContext::kAnalysisConstants | IRContext::kAnalysisTypes;
+  }
+
+ private:
+  // Find the max constant used to index the variable declared by |var|
+  // through OpAccessChain or OpInBoundsAccessChain. If any non-constant
+  // indices or non-Op*AccessChain use of |var|, return |original_max|.
+  unsigned FindMaxIndex(Instruction& var, unsigned original_max);
+
+  // Change the length of the array |inst| to |length|
+  void ChangeArrayLength(Instruction& inst, unsigned length);
+};
+
+}  // namespace opt
+}  // namespace spvtools
+
+#endif  // SOURCE_OPT_ELIMINATE_DEAD_INPUT_COMPONENTS_H_

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

@@ -39,13 +39,6 @@ static const int kSpvTypeImageMS = 4;
 static const int kSpvTypeImageSampled = 5;
 static const int kSpvTypeImageSampled = 5;
 }  // anonymous namespace
 }  // anonymous namespace
 
 
-// Avoid unused variable warning/error on Linux
-#ifndef NDEBUG
-#define USE_ASSERT(x) assert(x)
-#else
-#define USE_ASSERT(x) ((void)(x))
-#endif
-
 namespace spvtools {
 namespace spvtools {
 namespace opt {
 namespace opt {
 
 

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

@@ -31,13 +31,6 @@ namespace {
 // Input Operand Indices
 // Input Operand Indices
 static const int kSpvVariableStorageClassInIdx = 0;
 static const int kSpvVariableStorageClassInIdx = 0;
 
 
-// Avoid unused variable warning/error on Linux
-#ifndef NDEBUG
-#define USE_ASSERT(x) assert(x)
-#else
-#define USE_ASSERT(x) ((void)(x))
-#endif
-
 // Folding rule function which attempts to replace |op(OpLoad(a),...)|
 // Folding rule function which attempts to replace |op(OpLoad(a),...)|
 // by |op(a,...)|, where |op| is one of the GLSLstd450 InterpolateAt*
 // by |op(a,...)|, where |op| is one of the GLSLstd450 InterpolateAt*
 // instructions. Returns true if replaced, false otherwise.
 // instructions. Returns true if replaced, false otherwise.

+ 1 - 0
3rdparty/spirv-tools/source/opt/local_access_chain_convert_pass.cpp

@@ -434,6 +434,7 @@ void LocalAccessChainConvertPass::InitExtensions() {
       "SPV_KHR_integer_dot_product",
       "SPV_KHR_integer_dot_product",
       "SPV_EXT_shader_image_int64",
       "SPV_EXT_shader_image_int64",
       "SPV_KHR_non_semantic_info",
       "SPV_KHR_non_semantic_info",
+      "SPV_KHR_uniform_group_instructions",
   });
   });
 }
 }
 
 

+ 1 - 0
3rdparty/spirv-tools/source/opt/local_single_block_elim_pass.cpp

@@ -286,6 +286,7 @@ void LocalSingleBlockLoadStoreElimPass::InitExtensions() {
       "SPV_KHR_integer_dot_product",
       "SPV_KHR_integer_dot_product",
       "SPV_EXT_shader_image_int64",
       "SPV_EXT_shader_image_int64",
       "SPV_KHR_non_semantic_info",
       "SPV_KHR_non_semantic_info",
+      "SPV_KHR_uniform_group_instructions",
   });
   });
 }
 }
 
 

+ 1 - 0
3rdparty/spirv-tools/source/opt/local_single_store_elim_pass.cpp

@@ -139,6 +139,7 @@ void LocalSingleStoreElimPass::InitExtensionAllowList() {
       "SPV_KHR_integer_dot_product",
       "SPV_KHR_integer_dot_product",
       "SPV_EXT_shader_image_int64",
       "SPV_EXT_shader_image_int64",
       "SPV_KHR_non_semantic_info",
       "SPV_KHR_non_semantic_info",
+      "SPV_KHR_uniform_group_instructions",
   });
   });
 }
 }
 bool LocalSingleStoreElimPass::ProcessVariable(Instruction* var_inst) {
 bool LocalSingleStoreElimPass::ProcessVariable(Instruction* var_inst) {

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

@@ -523,6 +523,8 @@ bool Optimizer::RegisterPassFromFlag(const std::string& flag) {
     RegisterPass(CreateInterpolateFixupPass());
     RegisterPass(CreateInterpolateFixupPass());
   } else if (pass_name == "remove-dont-inline") {
   } else if (pass_name == "remove-dont-inline") {
     RegisterPass(CreateRemoveDontInlinePass());
     RegisterPass(CreateRemoveDontInlinePass());
+  } else if (pass_name == "eliminate-dead-input-components") {
+    RegisterPass(CreateEliminateDeadInputComponentsPass());
   } else if (pass_name == "convert-to-sampled-image") {
   } else if (pass_name == "convert-to-sampled-image") {
     if (pass_args.size() > 0) {
     if (pass_args.size() > 0) {
       auto descriptor_set_binding_pairs =
       auto descriptor_set_binding_pairs =
@@ -1004,6 +1006,11 @@ Optimizer::PassToken CreateInterpolateFixupPass() {
       MakeUnique<opt::InterpFixupPass>());
       MakeUnique<opt::InterpFixupPass>());
 }
 }
 
 
+Optimizer::PassToken CreateEliminateDeadInputComponentsPass() {
+  return MakeUnique<Optimizer::PassToken::Impl>(
+      MakeUnique<opt::EliminateDeadInputComponentsPass>());
+}
+
 Optimizer::PassToken CreateConvertToSampledImagePass(
 Optimizer::PassToken CreateConvertToSampledImagePass(
     const std::vector<opt::DescriptorSetAndBinding>&
     const std::vector<opt::DescriptorSetAndBinding>&
         descriptor_set_binding_pairs) {
         descriptor_set_binding_pairs) {

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

@@ -28,6 +28,13 @@
 #include "spirv-tools/libspirv.hpp"
 #include "spirv-tools/libspirv.hpp"
 #include "types.h"
 #include "types.h"
 
 
+// Avoid unused variable warning/error on Linux
+#ifndef NDEBUG
+#define USE_ASSERT(x) assert(x)
+#else
+#define USE_ASSERT(x) ((void)(x))
+#endif
+
 namespace spvtools {
 namespace spvtools {
 namespace opt {
 namespace opt {
 
 

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

@@ -34,6 +34,7 @@
 #include "source/opt/desc_sroa.h"
 #include "source/opt/desc_sroa.h"
 #include "source/opt/eliminate_dead_constant_pass.h"
 #include "source/opt/eliminate_dead_constant_pass.h"
 #include "source/opt/eliminate_dead_functions_pass.h"
 #include "source/opt/eliminate_dead_functions_pass.h"
+#include "source/opt/eliminate_dead_input_components_pass.h"
 #include "source/opt/eliminate_dead_members_pass.h"
 #include "source/opt/eliminate_dead_members_pass.h"
 #include "source/opt/empty_pass.h"
 #include "source/opt/empty_pass.h"
 #include "source/opt/fix_storage_class.h"
 #include "source/opt/fix_storage_class.h"

+ 1 - 1
3rdparty/spirv-tools/source/opt/private_to_local_pass.cpp

@@ -135,7 +135,7 @@ bool PrivateToLocalPass::MoveVariable(Instruction* variable,
   // Place the variable at the start of the first basic block.
   // Place the variable at the start of the first basic block.
   context()->AnalyzeUses(variable);
   context()->AnalyzeUses(variable);
   context()->set_instr_block(variable, &*function->begin());
   context()->set_instr_block(variable, &*function->begin());
-  function->begin()->begin()->InsertBefore(move(var));
+  function->begin()->begin()->InsertBefore(std::move(var));
 
 
   // Update uses where the type may have changed.
   // Update uses where the type may have changed.
   return UpdateUses(variable);
   return UpdateUses(variable);

+ 4 - 0
3rdparty/spirv-tools/source/opt/spread_volatile_semantics.cpp

@@ -92,6 +92,10 @@ bool HasOnlyEntryPointsAsFunctions(IRContext* context, Module* module) {
 }  // namespace
 }  // namespace
 
 
 Pass::Status SpreadVolatileSemantics::Process() {
 Pass::Status SpreadVolatileSemantics::Process() {
+  if (HasNoExecutionModel()) {
+    return Status::SuccessWithoutChange;
+  }
+
   if (!HasOnlyEntryPointsAsFunctions(context(), get_module())) {
   if (!HasOnlyEntryPointsAsFunctions(context(), get_module())) {
     return Status::Failure;
     return Status::Failure;
   }
   }

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

@@ -35,6 +35,13 @@ class SpreadVolatileSemantics : public Pass {
   }
   }
 
 
  private:
  private:
+  // Returns true if it does not have an execution model. Linkage shaders do not
+  // have an execution model.
+  bool HasNoExecutionModel() {
+    return get_module()->entry_points().empty() &&
+           context()->get_feature_mgr()->HasCapability(SpvCapabilityLinkage);
+  }
+
   // Iterates interface variables and spreads the Volatile semantics if it has
   // Iterates interface variables and spreads the Volatile semantics if it has
   // load instructions for the Volatile semantics.
   // load instructions for the Volatile semantics.
   Pass::Status SpreadVolatileSemanticsToVariables(
   Pass::Status SpreadVolatileSemanticsToVariables(

+ 6 - 0
3rdparty/spirv-tools/source/opt/types.cpp

@@ -419,6 +419,12 @@ size_t Array::ComputeExtraStateHash(size_t hash, SeenTypes* seen) const {
 
 
 void Array::ReplaceElementType(const Type* type) { element_type_ = type; }
 void Array::ReplaceElementType(const Type* type) { element_type_ = type; }
 
 
+Array::LengthInfo Array::GetConstantLengthInfo(uint32_t const_id,
+                                               uint32_t length) const {
+  std::vector<uint32_t> extra_words{LengthInfo::Case::kConstant, length};
+  return {const_id, extra_words};
+}
+
 RuntimeArray::RuntimeArray(const Type* type)
 RuntimeArray::RuntimeArray(const Type* type)
     : Type(kRuntimeArray), element_type_(type) {
     : Type(kRuntimeArray), element_type_(type) {
   assert(!type->AsVoid());
   assert(!type->AsVoid());

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

@@ -390,6 +390,7 @@ class Array : public Type {
   size_t ComputeExtraStateHash(size_t hash, SeenTypes* seen) const override;
   size_t ComputeExtraStateHash(size_t hash, SeenTypes* seen) const override;
 
 
   void ReplaceElementType(const Type* element_type);
   void ReplaceElementType(const Type* element_type);
+  LengthInfo GetConstantLengthInfo(uint32_t const_id, uint32_t length) const;
 
 
  private:
  private:
   bool IsSameImpl(const Type* that, IsSameCache*) const override;
   bool IsSameImpl(const Type* that, IsSameCache*) const override;

+ 11 - 8
3rdparty/spirv-tools/source/text.cpp

@@ -403,9 +403,10 @@ spv_result_t spvTextEncodeOperand(const spvtools::AssemblyGrammar& grammar,
     case SPV_OPERAND_TYPE_DEBUG_INFO_FLAGS:
     case SPV_OPERAND_TYPE_DEBUG_INFO_FLAGS:
     case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_INFO_FLAGS: {
     case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_INFO_FLAGS: {
       uint32_t value;
       uint32_t value;
-      if (grammar.parseMaskOperand(type, textValue, &value)) {
-        return context->diagnostic() << "Invalid " << spvOperandTypeStr(type)
-                                     << " operand '" << textValue << "'.";
+      if (auto error = grammar.parseMaskOperand(type, textValue, &value)) {
+        return context->diagnostic(error)
+               << "Invalid " << spvOperandTypeStr(type) << " operand '"
+               << textValue << "'.";
       }
       }
       if (auto error = context->binaryEncodeU32(value, pInst)) return error;
       if (auto error = context->binaryEncodeU32(value, pInst)) return error;
       // Prepare to parse the operands for this logical operand.
       // Prepare to parse the operands for this logical operand.
@@ -622,7 +623,8 @@ spv_result_t spvTextEncodeOpcode(const spvtools::AssemblyGrammar& grammar,
           break;
           break;
         } else {
         } else {
           return context->diagnostic()
           return context->diagnostic()
-                 << "Expected operand, found end of stream.";
+                 << "Expected operand for " << opcodeName
+                 << " instruction, but found the end of the stream.";
         }
         }
       }
       }
       assert(error == SPV_SUCCESS && "Somebody added another way to fail");
       assert(error == SPV_SUCCESS && "Somebody added another way to fail");
@@ -632,7 +634,8 @@ spv_result_t spvTextEncodeOpcode(const spvtools::AssemblyGrammar& grammar,
           break;
           break;
         } else {
         } else {
           return context->diagnostic()
           return context->diagnostic()
-                 << "Expected operand, found next instruction instead.";
+                 << "Expected operand for " << opcodeName
+                 << " instruction, but found the next instruction instead.";
         }
         }
       }
       }
 
 
@@ -666,7 +669,7 @@ spv_result_t spvTextEncodeOpcode(const spvtools::AssemblyGrammar& grammar,
 
 
   if (pInst->words.size() > SPV_LIMIT_INSTRUCTION_WORD_COUNT_MAX) {
   if (pInst->words.size() > SPV_LIMIT_INSTRUCTION_WORD_COUNT_MAX) {
     return context->diagnostic()
     return context->diagnostic()
-           << "Instruction too long: " << pInst->words.size()
+           << opcodeName << " Instruction too long: " << pInst->words.size()
            << " words, but the limit is "
            << " words, but the limit is "
            << SPV_LIMIT_INSTRUCTION_WORD_COUNT_MAX;
            << SPV_LIMIT_INSTRUCTION_WORD_COUNT_MAX;
   }
   }
@@ -769,8 +772,8 @@ spv_result_t spvTextToBinaryInternal(const spvtools::AssemblyGrammar& grammar,
     instructions.push_back({});
     instructions.push_back({});
     spv_instruction_t& inst = instructions.back();
     spv_instruction_t& inst = instructions.back();
 
 
-    if (spvTextEncodeOpcode(grammar, &context, &inst)) {
-      return SPV_ERROR_INVALID_TEXT;
+    if (auto error = spvTextEncodeOpcode(grammar, &context, &inst)) {
+      return error;
     }
     }
 
 
     if (context.advance()) break;
     if (context.advance()) break;

+ 1 - 0
3rdparty/spirv-tools/source/util/ilist.h

@@ -348,6 +348,7 @@ void IntrusiveList<NodeType>::Check(NodeType* start) {
     p = p->next_node_;
     p = p->next_node_;
   } while (p != start);
   } while (p != start);
   assert(sentinel_count == 1 && "List should have exactly 1 sentinel node.");
   assert(sentinel_count == 1 && "List should have exactly 1 sentinel node.");
+  (void)sentinel_count;
 
 
   p = start;
   p = start;
   do {
   do {

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

@@ -334,7 +334,7 @@ spv_result_t ValidateDecorationTarget(ValidationState_t& _, SpvDecoration dec,
             sc != SpvStorageClassIncomingCallableDataKHR &&
             sc != SpvStorageClassIncomingCallableDataKHR &&
             sc != SpvStorageClassShaderRecordBufferKHR) {
             sc != SpvStorageClassShaderRecordBufferKHR) {
           return _.diag(SPV_ERROR_INVALID_ID, target)
           return _.diag(SPV_ERROR_INVALID_ID, target)
-                 << LogStringForDecoration(dec)
+                 << _.VkErrorID(6672) << LogStringForDecoration(dec)
                  << " decoration must not be applied to this storage class";
                  << " decoration must not be applied to this storage class";
         }
         }
         break;
         break;
@@ -355,7 +355,7 @@ spv_result_t ValidateDecorationTarget(ValidationState_t& _, SpvDecoration dec,
         break;
         break;
       case SpvDecorationInputAttachmentIndex:
       case SpvDecorationInputAttachmentIndex:
         if (sc != SpvStorageClassUniformConstant) {
         if (sc != SpvStorageClassUniformConstant) {
-          return fail(0) << "must be in the UniformConstant storage class";
+          return fail(6678) << "must be in the UniformConstant storage class";
         }
         }
         break;
         break;
       case SpvDecorationFlat:
       case SpvDecorationFlat:

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

@@ -39,7 +39,7 @@ bool IsStorageClassAllowedByUniversalRules(uint32_t storage_class) {
     case SpvStorageClassAtomicCounter:
     case SpvStorageClassAtomicCounter:
     case SpvStorageClassImage:
     case SpvStorageClassImage:
     case SpvStorageClassFunction:
     case SpvStorageClassFunction:
-    case SpvStorageClassPhysicalStorageBufferEXT:
+    case SpvStorageClassPhysicalStorageBuffer:
       return true;
       return true;
       break;
       break;
     default:
     default:

+ 48 - 35
3rdparty/spirv-tools/source/val/validate_bitwise.cpp

@@ -14,16 +14,48 @@
 
 
 // Validates correctness of bitwise instructions.
 // Validates correctness of bitwise instructions.
 
 
-#include "source/val/validate.h"
-
 #include "source/diagnostic.h"
 #include "source/diagnostic.h"
 #include "source/opcode.h"
 #include "source/opcode.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 {
 namespace val {
 namespace val {
 
 
+// Validates when base and result need to be the same type
+spv_result_t ValidateBaseType(ValidationState_t& _, const Instruction* inst,
+                              const uint32_t base_type) {
+  const SpvOp opcode = inst->opcode();
+
+  if (!_.IsIntScalarType(base_type) && !_.IsIntVectorType(base_type)) {
+    return _.diag(SPV_ERROR_INVALID_DATA, inst)
+           << _.VkErrorID(4781)
+           << "Expected int scalar or vector type for Base operand: "
+           << spvOpcodeString(opcode);
+  }
+
+  // Vulkan has a restriction to 32 bit for base
+  if (spvIsVulkanEnv(_.context()->target_env)) {
+    if (_.GetBitWidth(base_type) != 32) {
+      return _.diag(SPV_ERROR_INVALID_DATA, inst)
+             << _.VkErrorID(4781)
+             << "Expected 32-bit int type for Base operand: "
+             << spvOpcodeString(opcode);
+    }
+  }
+
+  // OpBitCount just needs same number of components
+  if (base_type != inst->type_id() && opcode != SpvOpBitCount) {
+    return _.diag(SPV_ERROR_INVALID_DATA, inst)
+           << "Expected Base Type to be equal to Result Type: "
+           << spvOpcodeString(opcode);
+  }
+
+  return SPV_SUCCESS;
+}
+
 // Validates correctness of bitwise instructions.
 // Validates correctness of bitwise instructions.
 spv_result_t BitwisePass(ValidationState_t& _, const Instruction* inst) {
 spv_result_t BitwisePass(ValidationState_t& _, const Instruction* inst) {
   const SpvOp opcode = inst->opcode();
   const SpvOp opcode = inst->opcode();
@@ -109,20 +141,14 @@ spv_result_t BitwisePass(ValidationState_t& _, const Instruction* inst) {
     }
     }
 
 
     case SpvOpBitFieldInsert: {
     case SpvOpBitFieldInsert: {
-      if (!_.IsIntScalarType(result_type) && !_.IsIntVectorType(result_type))
-        return _.diag(SPV_ERROR_INVALID_DATA, inst)
-               << "Expected int scalar or vector type as Result Type: "
-               << spvOpcodeString(opcode);
-
       const uint32_t base_type = _.GetOperandTypeId(inst, 2);
       const uint32_t base_type = _.GetOperandTypeId(inst, 2);
       const uint32_t insert_type = _.GetOperandTypeId(inst, 3);
       const uint32_t insert_type = _.GetOperandTypeId(inst, 3);
       const uint32_t offset_type = _.GetOperandTypeId(inst, 4);
       const uint32_t offset_type = _.GetOperandTypeId(inst, 4);
       const uint32_t count_type = _.GetOperandTypeId(inst, 5);
       const uint32_t count_type = _.GetOperandTypeId(inst, 5);
 
 
-      if (base_type != result_type)
-        return _.diag(SPV_ERROR_INVALID_DATA, inst)
-               << "Expected Base Type to be equal to Result Type: "
-               << spvOpcodeString(opcode);
+      if (spv_result_t error = ValidateBaseType(_, inst, base_type)) {
+        return error;
+      }
 
 
       if (insert_type != result_type)
       if (insert_type != result_type)
         return _.diag(SPV_ERROR_INVALID_DATA, inst)
         return _.diag(SPV_ERROR_INVALID_DATA, inst)
@@ -143,19 +169,13 @@ spv_result_t BitwisePass(ValidationState_t& _, const Instruction* inst) {
 
 
     case SpvOpBitFieldSExtract:
     case SpvOpBitFieldSExtract:
     case SpvOpBitFieldUExtract: {
     case SpvOpBitFieldUExtract: {
-      if (!_.IsIntScalarType(result_type) && !_.IsIntVectorType(result_type))
-        return _.diag(SPV_ERROR_INVALID_DATA, inst)
-               << "Expected int scalar or vector type as Result Type: "
-               << spvOpcodeString(opcode);
-
       const uint32_t base_type = _.GetOperandTypeId(inst, 2);
       const uint32_t base_type = _.GetOperandTypeId(inst, 2);
       const uint32_t offset_type = _.GetOperandTypeId(inst, 3);
       const uint32_t offset_type = _.GetOperandTypeId(inst, 3);
       const uint32_t count_type = _.GetOperandTypeId(inst, 4);
       const uint32_t count_type = _.GetOperandTypeId(inst, 4);
 
 
-      if (base_type != result_type)
-        return _.diag(SPV_ERROR_INVALID_DATA, inst)
-               << "Expected Base Type to be equal to Result Type: "
-               << spvOpcodeString(opcode);
+      if (spv_result_t error = ValidateBaseType(_, inst, base_type)) {
+        return error;
+      }
 
 
       if (!offset_type || !_.IsIntScalarType(offset_type))
       if (!offset_type || !_.IsIntScalarType(offset_type))
         return _.diag(SPV_ERROR_INVALID_DATA, inst)
         return _.diag(SPV_ERROR_INVALID_DATA, inst)
@@ -170,17 +190,12 @@ spv_result_t BitwisePass(ValidationState_t& _, const Instruction* inst) {
     }
     }
 
 
     case SpvOpBitReverse: {
     case SpvOpBitReverse: {
-      if (!_.IsIntScalarType(result_type) && !_.IsIntVectorType(result_type))
-        return _.diag(SPV_ERROR_INVALID_DATA, inst)
-               << "Expected int scalar or vector type as Result Type: "
-               << spvOpcodeString(opcode);
-
       const uint32_t base_type = _.GetOperandTypeId(inst, 2);
       const uint32_t base_type = _.GetOperandTypeId(inst, 2);
 
 
-      if (base_type != result_type)
-        return _.diag(SPV_ERROR_INVALID_DATA, inst)
-               << "Expected Base Type to be equal to Result Type: "
-               << spvOpcodeString(opcode);
+      if (spv_result_t error = ValidateBaseType(_, inst, base_type)) {
+        return error;
+      }
+
       break;
       break;
     }
     }
 
 
@@ -191,15 +206,13 @@ spv_result_t BitwisePass(ValidationState_t& _, const Instruction* inst) {
                << spvOpcodeString(opcode);
                << spvOpcodeString(opcode);
 
 
       const uint32_t base_type = _.GetOperandTypeId(inst, 2);
       const uint32_t base_type = _.GetOperandTypeId(inst, 2);
-      if (!base_type ||
-          (!_.IsIntScalarType(base_type) && !_.IsIntVectorType(base_type)))
-        return _.diag(SPV_ERROR_INVALID_DATA, inst)
-               << "Expected Base Type to be int scalar or vector: "
-               << spvOpcodeString(opcode);
-
       const uint32_t base_dimension = _.GetDimension(base_type);
       const uint32_t base_dimension = _.GetDimension(base_type);
       const uint32_t result_dimension = _.GetDimension(result_type);
       const uint32_t result_dimension = _.GetDimension(result_type);
 
 
+      if (spv_result_t error = ValidateBaseType(_, inst, base_type)) {
+        return error;
+      }
+
       if (base_dimension != result_dimension)
       if (base_dimension != result_dimension)
         return _.diag(SPV_ERROR_INVALID_DATA, inst)
         return _.diag(SPV_ERROR_INVALID_DATA, inst)
                << "Expected Base dimension to be equal to Result Type "
                << "Expected Base dimension to be equal to Result Type "

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

@@ -55,8 +55,7 @@ spv_result_t ValidatePhi(ValidationState_t& _, const Instruction* inst) {
   }
   }
   if (_.IsPointerType(inst->type_id()) &&
   if (_.IsPointerType(inst->type_id()) &&
       _.addressing_model() == SpvAddressingModelLogical) {
       _.addressing_model() == SpvAddressingModelLogical) {
-    if (!_.features().variable_pointers &&
-        !_.features().variable_pointers_storage_buffer) {
+    if (!_.features().variable_pointers) {
       return _.diag(SPV_ERROR_INVALID_DATA, inst)
       return _.diag(SPV_ERROR_INVALID_DATA, inst)
              << "Using pointers with OpPhi requires capability "
              << "Using pointers with OpPhi requires capability "
              << "VariablePointers or VariablePointersStorageBuffer";
              << "VariablePointers or VariablePointersStorageBuffer";
@@ -249,13 +248,9 @@ spv_result_t ValidateReturnValue(ValidationState_t& _,
            << _.getIdName(value->type_id()) << "' is missing or void.";
            << _.getIdName(value->type_id()) << "' is missing or void.";
   }
   }
 
 
-  const bool uses_variable_pointer =
-      _.features().variable_pointers ||
-      _.features().variable_pointers_storage_buffer;
-
   if (_.addressing_model() == SpvAddressingModelLogical &&
   if (_.addressing_model() == SpvAddressingModelLogical &&
-      SpvOpTypePointer == value_type->opcode() && !uses_variable_pointer &&
-      !_.options()->relax_logical_pointer) {
+      SpvOpTypePointer == value_type->opcode() &&
+      !_.features().variable_pointers && !_.options()->relax_logical_pointer) {
     return _.diag(SPV_ERROR_INVALID_ID, inst)
     return _.diag(SPV_ERROR_INVALID_ID, inst)
            << "OpReturnValue value's type <id> '"
            << "OpReturnValue value's type <id> '"
            << _.getIdName(value->type_id())
            << _.getIdName(value->type_id())

+ 25 - 25
3rdparty/spirv-tools/source/val/validate_decorations.cpp

@@ -956,41 +956,41 @@ spv_result_t CheckDecorationsOfBuffers(ValidationState_t& vstate) {
       const bool storage_buffer = storageClass == SpvStorageClassStorageBuffer;
       const bool storage_buffer = storageClass == SpvStorageClassStorageBuffer;
 
 
       if (spvIsVulkanEnv(vstate.context()->target_env)) {
       if (spvIsVulkanEnv(vstate.context()->target_env)) {
-        // Vulkan 14.5.1: There must be no more than one PushConstant block
-        // per entry point.
+        // Vulkan: There must be no more than one PushConstant block per entry
+        // point.
         if (push_constant) {
         if (push_constant) {
           auto entry_points = vstate.EntryPointReferences(var_id);
           auto entry_points = vstate.EntryPointReferences(var_id);
           for (auto ep_id : entry_points) {
           for (auto ep_id : entry_points) {
             const bool already_used = !uses_push_constant.insert(ep_id).second;
             const bool already_used = !uses_push_constant.insert(ep_id).second;
             if (already_used) {
             if (already_used) {
               return vstate.diag(SPV_ERROR_INVALID_ID, vstate.FindDef(var_id))
               return vstate.diag(SPV_ERROR_INVALID_ID, vstate.FindDef(var_id))
-                     << "Entry point id '" << ep_id
+                     << vstate.VkErrorID(6674) << "Entry point id '" << ep_id
                      << "' uses more than one PushConstant interface.\n"
                      << "' uses more than one PushConstant interface.\n"
-                     << "From Vulkan spec, section 14.5.1:\n"
+                     << "From Vulkan spec:\n"
                      << "There must be no more than one push constant block "
                      << "There must be no more than one push constant block "
                      << "statically used per shader entry point.";
                      << "statically used per shader entry point.";
             }
             }
           }
           }
         }
         }
-        // Vulkan 14.5.2: Check DescriptorSet and Binding decoration for
+        // Vulkan: Check DescriptorSet and Binding decoration for
         // UniformConstant which cannot be a struct.
         // UniformConstant which cannot be a struct.
         if (uniform_constant) {
         if (uniform_constant) {
           auto entry_points = vstate.EntryPointReferences(var_id);
           auto entry_points = vstate.EntryPointReferences(var_id);
           if (!entry_points.empty() &&
           if (!entry_points.empty() &&
               !hasDecoration(var_id, SpvDecorationDescriptorSet, vstate)) {
               !hasDecoration(var_id, SpvDecorationDescriptorSet, vstate)) {
             return vstate.diag(SPV_ERROR_INVALID_ID, vstate.FindDef(var_id))
             return vstate.diag(SPV_ERROR_INVALID_ID, vstate.FindDef(var_id))
-                   << "UniformConstant id '" << var_id
+                   << vstate.VkErrorID(6677) << "UniformConstant id '" << var_id
                    << "' is missing DescriptorSet decoration.\n"
                    << "' is missing DescriptorSet decoration.\n"
-                   << "From Vulkan spec, section 14.5.2:\n"
+                   << "From Vulkan spec:\n"
                    << "These variables must have DescriptorSet and Binding "
                    << "These variables must have DescriptorSet and Binding "
                       "decorations specified";
                       "decorations specified";
           }
           }
           if (!entry_points.empty() &&
           if (!entry_points.empty() &&
               !hasDecoration(var_id, SpvDecorationBinding, vstate)) {
               !hasDecoration(var_id, SpvDecorationBinding, vstate)) {
             return vstate.diag(SPV_ERROR_INVALID_ID, vstate.FindDef(var_id))
             return vstate.diag(SPV_ERROR_INVALID_ID, vstate.FindDef(var_id))
-                   << "UniformConstant id '" << var_id
+                   << vstate.VkErrorID(6677) << "UniformConstant id '" << var_id
                    << "' is missing Binding decoration.\n"
                    << "' is missing Binding decoration.\n"
-                   << "From Vulkan spec, section 14.5.2:\n"
+                   << "From Vulkan spec:\n"
                    << "These variables must have DescriptorSet and Binding "
                    << "These variables must have DescriptorSet and Binding "
                       "decorations specified";
                       "decorations specified";
           }
           }
@@ -1017,7 +1017,7 @@ spv_result_t CheckDecorationsOfBuffers(ValidationState_t& vstate) {
       }
       }
 
 
       const bool phys_storage_buffer =
       const bool phys_storage_buffer =
-          storageClass == SpvStorageClassPhysicalStorageBufferEXT;
+          storageClass == SpvStorageClassPhysicalStorageBuffer;
       const bool workgroup =
       const bool workgroup =
           storageClass == SpvStorageClassWorkgroup &&
           storageClass == SpvStorageClassWorkgroup &&
           vstate.HasCapability(SpvCapabilityWorkgroupMemoryExplicitLayoutKHR);
           vstate.HasCapability(SpvCapabilityWorkgroupMemoryExplicitLayoutKHR);
@@ -1051,55 +1051,55 @@ spv_result_t CheckDecorationsOfBuffers(ValidationState_t& vstate) {
               hasDecoration(id, SpvDecorationBufferBlock, vstate);
               hasDecoration(id, SpvDecorationBufferBlock, vstate);
           if (storage_buffer && buffer_block) {
           if (storage_buffer && buffer_block) {
             return vstate.diag(SPV_ERROR_INVALID_ID, vstate.FindDef(var_id))
             return vstate.diag(SPV_ERROR_INVALID_ID, vstate.FindDef(var_id))
-                   << "Storage buffer id '" << var_id
+                   << vstate.VkErrorID(6675) << "Storage buffer id '" << var_id
                    << " In Vulkan, BufferBlock is disallowed on variables in "
                    << " In Vulkan, BufferBlock is disallowed on variables in "
                       "the StorageBuffer storage class";
                       "the StorageBuffer storage class";
           }
           }
-          // Vulkan 14.5.1/2: Check Block decoration for PushConstant, Uniform
+          // Vulkan: Check Block decoration for PushConstant, Uniform
           // and StorageBuffer variables. Uniform can also use BufferBlock.
           // and StorageBuffer variables. Uniform can also use BufferBlock.
           if (push_constant && !block) {
           if (push_constant && !block) {
             return vstate.diag(SPV_ERROR_INVALID_ID, vstate.FindDef(id))
             return vstate.diag(SPV_ERROR_INVALID_ID, vstate.FindDef(id))
-                   << "PushConstant id '" << id
+                   << vstate.VkErrorID(6675) << "PushConstant id '" << id
                    << "' is missing Block decoration.\n"
                    << "' is missing Block decoration.\n"
-                   << "From Vulkan spec, section 14.5.1:\n"
+                   << "From Vulkan spec:\n"
                    << "Such variables must be identified with a Block "
                    << "Such variables must be identified with a Block "
                       "decoration";
                       "decoration";
           }
           }
           if (storage_buffer && !block) {
           if (storage_buffer && !block) {
             return vstate.diag(SPV_ERROR_INVALID_ID, vstate.FindDef(id))
             return vstate.diag(SPV_ERROR_INVALID_ID, vstate.FindDef(id))
-                   << "StorageBuffer id '" << id
+                   << vstate.VkErrorID(6675) << "StorageBuffer id '" << id
                    << "' is missing Block decoration.\n"
                    << "' is missing Block decoration.\n"
-                   << "From Vulkan spec, section 14.5.2:\n"
+                   << "From Vulkan spec:\n"
                    << "Such variables must be identified with a Block "
                    << "Such variables must be identified with a Block "
                       "decoration";
                       "decoration";
           }
           }
           if (uniform && !block && !buffer_block) {
           if (uniform && !block && !buffer_block) {
             return vstate.diag(SPV_ERROR_INVALID_ID, vstate.FindDef(id))
             return vstate.diag(SPV_ERROR_INVALID_ID, vstate.FindDef(id))
-                   << "Uniform id '" << id
+                   << vstate.VkErrorID(6676) << "Uniform id '" << id
                    << "' is missing Block or BufferBlock decoration.\n"
                    << "' is missing Block or BufferBlock decoration.\n"
-                   << "From Vulkan spec, section 14.5.2:\n"
+                   << "From Vulkan spec:\n"
                    << "Such variables must be identified with a Block or "
                    << "Such variables must be identified with a Block or "
                       "BufferBlock decoration";
                       "BufferBlock decoration";
           }
           }
-          // Vulkan 14.5.2: Check DescriptorSet and Binding decoration for
+          // Vulkan: Check DescriptorSet and Binding decoration for
           // Uniform and StorageBuffer variables.
           // Uniform and StorageBuffer variables.
           if (uniform || storage_buffer) {
           if (uniform || storage_buffer) {
             auto entry_points = vstate.EntryPointReferences(var_id);
             auto entry_points = vstate.EntryPointReferences(var_id);
             if (!entry_points.empty() &&
             if (!entry_points.empty() &&
                 !hasDecoration(var_id, SpvDecorationDescriptorSet, vstate)) {
                 !hasDecoration(var_id, SpvDecorationDescriptorSet, vstate)) {
               return vstate.diag(SPV_ERROR_INVALID_ID, vstate.FindDef(var_id))
               return vstate.diag(SPV_ERROR_INVALID_ID, vstate.FindDef(var_id))
-                     << sc_str << " id '" << var_id
+                     << vstate.VkErrorID(6677) << sc_str << " id '" << var_id
                      << "' is missing DescriptorSet decoration.\n"
                      << "' is missing DescriptorSet decoration.\n"
-                     << "From Vulkan spec, section 14.5.2:\n"
+                     << "From Vulkan spec:\n"
                      << "These variables must have DescriptorSet and Binding "
                      << "These variables must have DescriptorSet and Binding "
                         "decorations specified";
                         "decorations specified";
             }
             }
             if (!entry_points.empty() &&
             if (!entry_points.empty() &&
                 !hasDecoration(var_id, SpvDecorationBinding, vstate)) {
                 !hasDecoration(var_id, SpvDecorationBinding, vstate)) {
               return vstate.diag(SPV_ERROR_INVALID_ID, vstate.FindDef(var_id))
               return vstate.diag(SPV_ERROR_INVALID_ID, vstate.FindDef(var_id))
-                     << sc_str << " id '" << var_id
+                     << vstate.VkErrorID(6677) << sc_str << " id '" << var_id
                      << "' is missing Binding decoration.\n"
                      << "' is missing Binding decoration.\n"
-                     << "From Vulkan spec, section 14.5.2:\n"
+                     << "From Vulkan spec:\n"
                      << "These variables must have DescriptorSet and Binding "
                      << "These variables must have DescriptorSet and Binding "
                         "decorations specified";
                         "decorations specified";
             }
             }
@@ -1407,11 +1407,11 @@ spv_result_t CheckFPRoundingModeForShaders(ValidationState_t& vstate,
         storage != SpvStorageClassUniform &&
         storage != SpvStorageClassUniform &&
         storage != SpvStorageClassPushConstant &&
         storage != SpvStorageClassPushConstant &&
         storage != SpvStorageClassInput && storage != SpvStorageClassOutput &&
         storage != SpvStorageClassInput && storage != SpvStorageClassOutput &&
-        storage != SpvStorageClassPhysicalStorageBufferEXT) {
+        storage != SpvStorageClassPhysicalStorageBuffer) {
       return vstate.diag(SPV_ERROR_INVALID_ID, &inst)
       return vstate.diag(SPV_ERROR_INVALID_ID, &inst)
              << "FPRoundingMode decoration can be applied only to the "
              << "FPRoundingMode decoration can be applied only to the "
                 "Object operand of an OpStore in the StorageBuffer, "
                 "Object operand of an OpStore in the StorageBuffer, "
-                "PhysicalStorageBufferEXT, Uniform, PushConstant, Input, or "
+                "PhysicalStorageBuffer, Uniform, PushConstant, Input, or "
                 "Output Storage Classes.";
                 "Output Storage Classes.";
     }
     }
   }
   }

+ 18 - 19
3rdparty/spirv-tools/source/val/validate_function.cpp

@@ -147,8 +147,8 @@ spv_result_t ValidateFunctionParameter(ValidationState_t& _,
               "type of the same index.";
               "type of the same index.";
   }
   }
 
 
-  // Validate that PhysicalStorageBufferEXT have one of Restrict, Aliased,
-  // RestrictPointerEXT, or AliasedPointerEXT.
+  // Validate that PhysicalStorageBuffer have one of Restrict, Aliased,
+  // RestrictPointer, or AliasedPointer.
   auto param_nonarray_type_id = param_type->id();
   auto param_nonarray_type_id = param_type->id();
   while (_.GetIdOpcode(param_nonarray_type_id) == SpvOpTypeArray) {
   while (_.GetIdOpcode(param_nonarray_type_id) == SpvOpTypeArray) {
     param_nonarray_type_id =
     param_nonarray_type_id =
@@ -157,7 +157,7 @@ spv_result_t ValidateFunctionParameter(ValidationState_t& _,
   if (_.GetIdOpcode(param_nonarray_type_id) == SpvOpTypePointer) {
   if (_.GetIdOpcode(param_nonarray_type_id) == SpvOpTypePointer) {
     auto param_nonarray_type = _.FindDef(param_nonarray_type_id);
     auto param_nonarray_type = _.FindDef(param_nonarray_type_id);
     if (param_nonarray_type->GetOperandAs<uint32_t>(1u) ==
     if (param_nonarray_type->GetOperandAs<uint32_t>(1u) ==
-        SpvStorageClassPhysicalStorageBufferEXT) {
+        SpvStorageClassPhysicalStorageBuffer) {
       // check for Aliased or Restrict
       // check for Aliased or Restrict
       const auto& decorations = _.id_decorations(inst->id());
       const auto& decorations = _.id_decorations(inst->id());
 
 
@@ -174,14 +174,14 @@ spv_result_t ValidateFunctionParameter(ValidationState_t& _,
       if (!foundAliased && !foundRestrict) {
       if (!foundAliased && !foundRestrict) {
         return _.diag(SPV_ERROR_INVALID_ID, inst)
         return _.diag(SPV_ERROR_INVALID_ID, inst)
                << "OpFunctionParameter " << inst->id()
                << "OpFunctionParameter " << inst->id()
-               << ": expected Aliased or Restrict for PhysicalStorageBufferEXT "
+               << ": expected Aliased or Restrict for PhysicalStorageBuffer "
                   "pointer.";
                   "pointer.";
       }
       }
       if (foundAliased && foundRestrict) {
       if (foundAliased && foundRestrict) {
         return _.diag(SPV_ERROR_INVALID_ID, inst)
         return _.diag(SPV_ERROR_INVALID_ID, inst)
                << "OpFunctionParameter " << inst->id()
                << "OpFunctionParameter " << inst->id()
                << ": can't specify both Aliased and Restrict for "
                << ": can't specify both Aliased and Restrict for "
-                  "PhysicalStorageBufferEXT pointer.";
+                  "PhysicalStorageBuffer pointer.";
       }
       }
     } else {
     } else {
       const auto pointee_type_id =
       const auto pointee_type_id =
@@ -189,31 +189,31 @@ spv_result_t ValidateFunctionParameter(ValidationState_t& _,
       const auto pointee_type = _.FindDef(pointee_type_id);
       const auto pointee_type = _.FindDef(pointee_type_id);
       if (SpvOpTypePointer == pointee_type->opcode() &&
       if (SpvOpTypePointer == pointee_type->opcode() &&
           pointee_type->GetOperandAs<uint32_t>(1u) ==
           pointee_type->GetOperandAs<uint32_t>(1u) ==
-              SpvStorageClassPhysicalStorageBufferEXT) {
-        // check for AliasedPointerEXT/RestrictPointerEXT
+              SpvStorageClassPhysicalStorageBuffer) {
+        // check for AliasedPointer/RestrictPointer
         const auto& decorations = _.id_decorations(inst->id());
         const auto& decorations = _.id_decorations(inst->id());
 
 
         bool foundAliased = std::any_of(
         bool foundAliased = std::any_of(
             decorations.begin(), decorations.end(), [](const Decoration& d) {
             decorations.begin(), decorations.end(), [](const Decoration& d) {
-              return SpvDecorationAliasedPointerEXT == d.dec_type();
+              return SpvDecorationAliasedPointer == d.dec_type();
             });
             });
 
 
         bool foundRestrict = std::any_of(
         bool foundRestrict = std::any_of(
             decorations.begin(), decorations.end(), [](const Decoration& d) {
             decorations.begin(), decorations.end(), [](const Decoration& d) {
-              return SpvDecorationRestrictPointerEXT == d.dec_type();
+              return SpvDecorationRestrictPointer == d.dec_type();
             });
             });
 
 
         if (!foundAliased && !foundRestrict) {
         if (!foundAliased && !foundRestrict) {
           return _.diag(SPV_ERROR_INVALID_ID, inst)
           return _.diag(SPV_ERROR_INVALID_ID, inst)
                  << "OpFunctionParameter " << inst->id()
                  << "OpFunctionParameter " << inst->id()
-                 << ": expected AliasedPointerEXT or RestrictPointerEXT for "
-                    "PhysicalStorageBufferEXT pointer.";
+                 << ": expected AliasedPointer or RestrictPointer for "
+                    "PhysicalStorageBuffer pointer.";
         }
         }
         if (foundAliased && foundRestrict) {
         if (foundAliased && foundRestrict) {
           return _.diag(SPV_ERROR_INVALID_ID, inst)
           return _.diag(SPV_ERROR_INVALID_ID, inst)
                  << "OpFunctionParameter " << inst->id()
                  << "OpFunctionParameter " << inst->id()
-                 << ": can't specify both AliasedPointerEXT and "
-                    "RestrictPointerEXT for PhysicalStorageBufferEXT pointer.";
+                 << ": can't specify both AliasedPointer and "
+                    "RestrictPointer for PhysicalStorageBuffer pointer.";
         }
         }
       }
       }
     }
     }
@@ -300,7 +300,7 @@ spv_result_t ValidateFunctionCall(ValidationState_t& _,
             // These are always allowed.
             // These are always allowed.
             break;
             break;
           case SpvStorageClassStorageBuffer:
           case SpvStorageClassStorageBuffer:
-            if (!_.features().variable_pointers_storage_buffer) {
+            if (!_.features().variable_pointers) {
               return _.diag(SPV_ERROR_INVALID_ID, inst)
               return _.diag(SPV_ERROR_INVALID_ID, inst)
                      << "StorageBuffer pointer operand "
                      << "StorageBuffer pointer operand "
                      << _.getIdName(argument_id)
                      << _.getIdName(argument_id)
@@ -316,11 +316,10 @@ spv_result_t ValidateFunctionCall(ValidationState_t& _,
         // Validate memory object declaration requirements.
         // Validate memory object declaration requirements.
         if (argument->opcode() != SpvOpVariable &&
         if (argument->opcode() != SpvOpVariable &&
             argument->opcode() != SpvOpFunctionParameter) {
             argument->opcode() != SpvOpFunctionParameter) {
-          const bool ssbo_vptr =
-              _.features().variable_pointers_storage_buffer &&
-              sc == SpvStorageClassStorageBuffer;
-          const bool wg_vptr =
-              _.features().variable_pointers && sc == SpvStorageClassWorkgroup;
+          const bool ssbo_vptr = _.features().variable_pointers &&
+                                 sc == SpvStorageClassStorageBuffer;
+          const bool wg_vptr = _.HasCapability(SpvCapabilityVariablePointers) &&
+                               sc == SpvStorageClassWorkgroup;
           const bool uc_ptr = sc == SpvStorageClassUniformConstant;
           const bool uc_ptr = sc == SpvStorageClassUniformConstant;
           if (!ssbo_vptr && !wg_vptr && !uc_ptr) {
           if (!ssbo_vptr && !wg_vptr && !uc_ptr) {
             return _.diag(SPV_ERROR_INVALID_ID, inst)
             return _.diag(SPV_ERROR_INVALID_ID, inst)

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

@@ -980,8 +980,9 @@ spv_result_t ValidateSampledImage(ValidationState_t& _,
   if (spvIsVulkanEnv(_.context()->target_env)) {
   if (spvIsVulkanEnv(_.context()->target_env)) {
     if (info.sampled != 1) {
     if (info.sampled != 1) {
       return _.diag(SPV_ERROR_INVALID_DATA, inst)
       return _.diag(SPV_ERROR_INVALID_DATA, inst)
-             << "Expected Image 'Sampled' parameter to be 1 "
-             << "for Vulkan environment.";
+             << _.VkErrorID(6671)
+             << "Expected Image 'Sampled' parameter to be 1 for Vulkan "
+                "environment.";
     }
     }
   } else {
   } else {
     if (info.sampled != 0 && info.sampled != 1) {
     if (info.sampled != 0 && info.sampled != 1) {

+ 1 - 2
3rdparty/spirv-tools/source/val/validate_logicals.cpp

@@ -163,8 +163,7 @@ spv_result_t LogicalsPass(ValidationState_t& _, const Instruction* inst) {
         switch (type_opcode) {
         switch (type_opcode) {
           case SpvOpTypePointer: {
           case SpvOpTypePointer: {
             if (_.addressing_model() == SpvAddressingModelLogical &&
             if (_.addressing_model() == SpvAddressingModelLogical &&
-                !_.features().variable_pointers &&
-                !_.features().variable_pointers_storage_buffer)
+                !_.features().variable_pointers)
               return _.diag(SPV_ERROR_INVALID_DATA, inst)
               return _.diag(SPV_ERROR_INVALID_DATA, inst)
                      << "Using pointers with OpSelect requires capability "
                      << "Using pointers with OpSelect requires capability "
                      << "VariablePointers or VariablePointersStorageBuffer";
                      << "VariablePointers or VariablePointersStorageBuffer";

+ 36 - 48
3rdparty/spirv-tools/source/val/validate_memory.cpp

@@ -315,11 +315,12 @@ spv_result_t CheckMemoryAccess(ValidationState_t& _, const Instruction* inst,
   SpvStorageClass dst_sc, src_sc;
   SpvStorageClass dst_sc, src_sc;
   std::tie(dst_sc, src_sc) = GetStorageClass(_, inst);
   std::tie(dst_sc, src_sc) = GetStorageClass(_, inst);
   if (inst->operands().size() <= index) {
   if (inst->operands().size() <= index) {
-    if (src_sc == SpvStorageClassPhysicalStorageBufferEXT ||
-        dst_sc == SpvStorageClassPhysicalStorageBufferEXT) {
+    // Cases where lack of some operand is invalid
+    if (src_sc == SpvStorageClassPhysicalStorageBuffer ||
+        dst_sc == SpvStorageClassPhysicalStorageBuffer) {
       return _.diag(SPV_ERROR_INVALID_ID, inst)
       return _.diag(SPV_ERROR_INVALID_ID, inst)
-             << "Memory accesses with PhysicalStorageBufferEXT must use "
-                "Aligned.";
+             << _.VkErrorID(4708)
+             << "Memory accesses with PhysicalStorageBuffer must use Aligned.";
     }
     }
     return SPV_SUCCESS;
     return SPV_SUCCESS;
   }
   }
@@ -368,7 +369,7 @@ spv_result_t CheckMemoryAccess(ValidationState_t& _, const Instruction* inst,
         dst_sc != SpvStorageClassCrossWorkgroup &&
         dst_sc != SpvStorageClassCrossWorkgroup &&
         dst_sc != SpvStorageClassGeneric && dst_sc != SpvStorageClassImage &&
         dst_sc != SpvStorageClassGeneric && dst_sc != SpvStorageClassImage &&
         dst_sc != SpvStorageClassStorageBuffer &&
         dst_sc != SpvStorageClassStorageBuffer &&
-        dst_sc != SpvStorageClassPhysicalStorageBufferEXT) {
+        dst_sc != SpvStorageClassPhysicalStorageBuffer) {
       return _.diag(SPV_ERROR_INVALID_ID, inst)
       return _.diag(SPV_ERROR_INVALID_ID, inst)
              << "NonPrivatePointerKHR requires a pointer in Uniform, "
              << "NonPrivatePointerKHR requires a pointer in Uniform, "
              << "Workgroup, CrossWorkgroup, Generic, Image or StorageBuffer "
              << "Workgroup, CrossWorkgroup, Generic, Image or StorageBuffer "
@@ -379,7 +380,7 @@ spv_result_t CheckMemoryAccess(ValidationState_t& _, const Instruction* inst,
         src_sc != SpvStorageClassCrossWorkgroup &&
         src_sc != SpvStorageClassCrossWorkgroup &&
         src_sc != SpvStorageClassGeneric && src_sc != SpvStorageClassImage &&
         src_sc != SpvStorageClassGeneric && src_sc != SpvStorageClassImage &&
         src_sc != SpvStorageClassStorageBuffer &&
         src_sc != SpvStorageClassStorageBuffer &&
-        src_sc != SpvStorageClassPhysicalStorageBufferEXT) {
+        src_sc != SpvStorageClassPhysicalStorageBuffer) {
       return _.diag(SPV_ERROR_INVALID_ID, inst)
       return _.diag(SPV_ERROR_INVALID_ID, inst)
              << "NonPrivatePointerKHR requires a pointer in Uniform, "
              << "NonPrivatePointerKHR requires a pointer in Uniform, "
              << "Workgroup, CrossWorkgroup, Generic, Image or StorageBuffer "
              << "Workgroup, CrossWorkgroup, Generic, Image or StorageBuffer "
@@ -388,11 +389,11 @@ spv_result_t CheckMemoryAccess(ValidationState_t& _, const Instruction* inst,
   }
   }
 
 
   if (!(mask & SpvMemoryAccessAlignedMask)) {
   if (!(mask & SpvMemoryAccessAlignedMask)) {
-    if (src_sc == SpvStorageClassPhysicalStorageBufferEXT ||
-        dst_sc == SpvStorageClassPhysicalStorageBufferEXT) {
+    if (src_sc == SpvStorageClassPhysicalStorageBuffer ||
+        dst_sc == SpvStorageClassPhysicalStorageBuffer) {
       return _.diag(SPV_ERROR_INVALID_ID, inst)
       return _.diag(SPV_ERROR_INVALID_ID, inst)
-             << "Memory accesses with PhysicalStorageBufferEXT must use "
-                "Aligned.";
+             << _.VkErrorID(4708)
+             << "Memory accesses with PhysicalStorageBuffer must use Aligned.";
     }
     }
   }
   }
 
 
@@ -628,9 +629,9 @@ spv_result_t ValidateVariable(ValidationState_t& _, const Instruction* inst) {
     }
     }
   }
   }
 
 
-  if (storage_class == SpvStorageClassPhysicalStorageBufferEXT) {
+  if (storage_class == SpvStorageClassPhysicalStorageBuffer) {
     return _.diag(SPV_ERROR_INVALID_ID, inst)
     return _.diag(SPV_ERROR_INVALID_ID, inst)
-           << "PhysicalStorageBufferEXT must not be used with OpVariable.";
+           << "PhysicalStorageBuffer must not be used with OpVariable.";
   }
   }
 
 
   auto pointee_base = pointee;
   auto pointee_base = pointee;
@@ -639,23 +640,23 @@ spv_result_t ValidateVariable(ValidationState_t& _, const Instruction* inst) {
   }
   }
   if (pointee_base->opcode() == SpvOpTypePointer) {
   if (pointee_base->opcode() == SpvOpTypePointer) {
     if (pointee_base->GetOperandAs<uint32_t>(1u) ==
     if (pointee_base->GetOperandAs<uint32_t>(1u) ==
-        SpvStorageClassPhysicalStorageBufferEXT) {
-      // check for AliasedPointerEXT/RestrictPointerEXT
+        SpvStorageClassPhysicalStorageBuffer) {
+      // check for AliasedPointer/RestrictPointer
       bool foundAliased =
       bool foundAliased =
-          _.HasDecoration(inst->id(), SpvDecorationAliasedPointerEXT);
+          _.HasDecoration(inst->id(), SpvDecorationAliasedPointer);
       bool foundRestrict =
       bool foundRestrict =
-          _.HasDecoration(inst->id(), SpvDecorationRestrictPointerEXT);
+          _.HasDecoration(inst->id(), SpvDecorationRestrictPointer);
       if (!foundAliased && !foundRestrict) {
       if (!foundAliased && !foundRestrict) {
         return _.diag(SPV_ERROR_INVALID_ID, inst)
         return _.diag(SPV_ERROR_INVALID_ID, inst)
                << "OpVariable " << inst->id()
                << "OpVariable " << inst->id()
-               << ": expected AliasedPointerEXT or RestrictPointerEXT for "
-               << "PhysicalStorageBufferEXT pointer.";
+               << ": expected AliasedPointer or RestrictPointer for "
+               << "PhysicalStorageBuffer pointer.";
       }
       }
       if (foundAliased && foundRestrict) {
       if (foundAliased && foundRestrict) {
         return _.diag(SPV_ERROR_INVALID_ID, inst)
         return _.diag(SPV_ERROR_INVALID_ID, inst)
                << "OpVariable " << inst->id()
                << "OpVariable " << inst->id()
-               << ": can't specify both AliasedPointerEXT and "
-               << "RestrictPointerEXT for PhysicalStorageBufferEXT pointer.";
+               << ": can't specify both AliasedPointer and "
+               << "RestrictPointer for PhysicalStorageBuffer pointer.";
       }
       }
     }
     }
   }
   }
@@ -753,7 +754,7 @@ spv_result_t ValidateVariable(ValidationState_t& _, const Instruction* inst) {
           SPV_OPERAND_TYPE_STORAGE_CLASS, storage_class);
           SPV_OPERAND_TYPE_STORAGE_CLASS, storage_class);
       switch (storage_class) {
       switch (storage_class) {
         case SpvStorageClassStorageBuffer:
         case SpvStorageClassStorageBuffer:
-        case SpvStorageClassPhysicalStorageBufferEXT:
+        case SpvStorageClassPhysicalStorageBuffer:
           if (!_.HasCapability(SpvCapabilityStorageBuffer16BitAccess)) {
           if (!_.HasCapability(SpvCapabilityStorageBuffer16BitAccess)) {
             storage_class_ok = false;
             storage_class_ok = false;
           }
           }
@@ -815,7 +816,7 @@ spv_result_t ValidateVariable(ValidationState_t& _, const Instruction* inst) {
           SPV_OPERAND_TYPE_STORAGE_CLASS, storage_class);
           SPV_OPERAND_TYPE_STORAGE_CLASS, storage_class);
       switch (storage_class) {
       switch (storage_class) {
         case SpvStorageClassStorageBuffer:
         case SpvStorageClassStorageBuffer:
-        case SpvStorageClassPhysicalStorageBufferEXT:
+        case SpvStorageClassPhysicalStorageBuffer:
           if (!_.HasCapability(SpvCapabilityStorageBuffer8BitAccess)) {
           if (!_.HasCapability(SpvCapabilityStorageBuffer8BitAccess)) {
             storage_class_ok = false;
             storage_class_ok = false;
           }
           }
@@ -869,17 +870,14 @@ spv_result_t ValidateLoad(ValidationState_t& _, const Instruction* inst) {
            << "' is not defined.";
            << "' is not defined.";
   }
   }
 
 
-  const bool uses_variable_pointers =
-      _.features().variable_pointers ||
-      _.features().variable_pointers_storage_buffer;
   const auto pointer_index = 2;
   const auto pointer_index = 2;
   const auto pointer_id = inst->GetOperandAs<uint32_t>(pointer_index);
   const auto pointer_id = inst->GetOperandAs<uint32_t>(pointer_index);
   const auto pointer = _.FindDef(pointer_id);
   const auto pointer = _.FindDef(pointer_id);
   if (!pointer ||
   if (!pointer ||
       ((_.addressing_model() == SpvAddressingModelLogical) &&
       ((_.addressing_model() == SpvAddressingModelLogical) &&
-       ((!uses_variable_pointers &&
+       ((!_.features().variable_pointers &&
          !spvOpcodeReturnsLogicalPointer(pointer->opcode())) ||
          !spvOpcodeReturnsLogicalPointer(pointer->opcode())) ||
-        (uses_variable_pointers &&
+        (_.features().variable_pointers &&
          !spvOpcodeReturnsLogicalVariablePointer(pointer->opcode()))))) {
          !spvOpcodeReturnsLogicalVariablePointer(pointer->opcode()))))) {
     return _.diag(SPV_ERROR_INVALID_ID, inst)
     return _.diag(SPV_ERROR_INVALID_ID, inst)
            << "OpLoad Pointer <id> '" << _.getIdName(pointer_id)
            << "OpLoad Pointer <id> '" << _.getIdName(pointer_id)
@@ -925,17 +923,14 @@ spv_result_t ValidateLoad(ValidationState_t& _, const Instruction* inst) {
 }
 }
 
 
 spv_result_t ValidateStore(ValidationState_t& _, const Instruction* inst) {
 spv_result_t ValidateStore(ValidationState_t& _, const Instruction* inst) {
-  const bool uses_variable_pointer =
-      _.features().variable_pointers ||
-      _.features().variable_pointers_storage_buffer;
   const auto pointer_index = 0;
   const auto pointer_index = 0;
   const auto pointer_id = inst->GetOperandAs<uint32_t>(pointer_index);
   const auto pointer_id = inst->GetOperandAs<uint32_t>(pointer_index);
   const auto pointer = _.FindDef(pointer_id);
   const auto pointer = _.FindDef(pointer_id);
   if (!pointer ||
   if (!pointer ||
       (_.addressing_model() == SpvAddressingModelLogical &&
       (_.addressing_model() == SpvAddressingModelLogical &&
-       ((!uses_variable_pointer &&
+       ((!_.features().variable_pointers &&
          !spvOpcodeReturnsLogicalPointer(pointer->opcode())) ||
          !spvOpcodeReturnsLogicalPointer(pointer->opcode())) ||
-        (uses_variable_pointer &&
+        (_.features().variable_pointers &&
          !spvOpcodeReturnsLogicalVariablePointer(pointer->opcode()))))) {
          !spvOpcodeReturnsLogicalVariablePointer(pointer->opcode()))))) {
     return _.diag(SPV_ERROR_INVALID_ID, inst)
     return _.diag(SPV_ERROR_INVALID_ID, inst)
            << "OpStore Pointer <id> '" << _.getIdName(pointer_id)
            << "OpStore Pointer <id> '" << _.getIdName(pointer_id)
@@ -1146,8 +1141,6 @@ spv_result_t ValidateCopyMemory(ValidationState_t& _, const Instruction* inst) {
              << "'s type does not match Source <id> '"
              << "'s type does not match Source <id> '"
              << _.getIdName(source_type->id()) << "'s type.";
              << _.getIdName(source_type->id()) << "'s type.";
     }
     }
-
-    if (auto error = CheckMemoryAccess(_, inst, 2)) return error;
   } else {
   } else {
     const auto size_id = inst->GetOperandAs<uint32_t>(2);
     const auto size_id = inst->GetOperandAs<uint32_t>(2);
     const auto size = _.FindDef(size_id);
     const auto size = _.FindDef(size_id);
@@ -1190,8 +1183,6 @@ spv_result_t ValidateCopyMemory(ValidationState_t& _, const Instruction* inst) {
         // Cannot infer any other opcodes.
         // Cannot infer any other opcodes.
         break;
         break;
     }
     }
-
-    if (auto error = CheckMemoryAccess(_, inst, 3)) return error;
   }
   }
   if (auto error = ValidateCopyMemoryMemoryAccess(_, inst)) return error;
   if (auto error = ValidateCopyMemoryMemoryAccess(_, inst)) return error;
 
 
@@ -1365,8 +1356,7 @@ spv_result_t ValidateAccessChain(ValidationState_t& _,
 spv_result_t ValidatePtrAccessChain(ValidationState_t& _,
 spv_result_t ValidatePtrAccessChain(ValidationState_t& _,
                                     const Instruction* inst) {
                                     const Instruction* inst) {
   if (_.addressing_model() == SpvAddressingModelLogical) {
   if (_.addressing_model() == SpvAddressingModelLogical) {
-    if (!_.features().variable_pointers &&
-        !_.features().variable_pointers_storage_buffer) {
+    if (!_.features().variable_pointers) {
       return _.diag(SPV_ERROR_INVALID_DATA, inst)
       return _.diag(SPV_ERROR_INVALID_DATA, inst)
              << "Generating variable pointers requires capability "
              << "Generating variable pointers requires capability "
              << "VariablePointers or VariablePointersStorageBuffer";
              << "VariablePointers or VariablePointersStorageBuffer";
@@ -1484,18 +1474,15 @@ spv_result_t ValidateCooperativeMatrixLoadStoreNV(ValidationState_t& _,
     }
     }
   }
   }
 
 
-  const bool uses_variable_pointers =
-      _.features().variable_pointers ||
-      _.features().variable_pointers_storage_buffer;
   const auto pointer_index =
   const auto pointer_index =
       (inst->opcode() == SpvOpCooperativeMatrixLoadNV) ? 2u : 0u;
       (inst->opcode() == SpvOpCooperativeMatrixLoadNV) ? 2u : 0u;
   const auto pointer_id = inst->GetOperandAs<uint32_t>(pointer_index);
   const auto pointer_id = inst->GetOperandAs<uint32_t>(pointer_index);
   const auto pointer = _.FindDef(pointer_id);
   const auto pointer = _.FindDef(pointer_id);
   if (!pointer ||
   if (!pointer ||
       ((_.addressing_model() == SpvAddressingModelLogical) &&
       ((_.addressing_model() == SpvAddressingModelLogical) &&
-       ((!uses_variable_pointers &&
+       ((!_.features().variable_pointers &&
          !spvOpcodeReturnsLogicalPointer(pointer->opcode())) ||
          !spvOpcodeReturnsLogicalPointer(pointer->opcode())) ||
-        (uses_variable_pointers &&
+        (_.features().variable_pointers &&
          !spvOpcodeReturnsLogicalVariablePointer(pointer->opcode()))))) {
          !spvOpcodeReturnsLogicalVariablePointer(pointer->opcode()))))) {
     return _.diag(SPV_ERROR_INVALID_ID, inst)
     return _.diag(SPV_ERROR_INVALID_ID, inst)
            << opname << " Pointer <id> '" << _.getIdName(pointer_id)
            << opname << " Pointer <id> '" << _.getIdName(pointer_id)
@@ -1516,7 +1503,7 @@ spv_result_t ValidateCooperativeMatrixLoadStoreNV(ValidationState_t& _,
 
 
   if (storage_class != SpvStorageClassWorkgroup &&
   if (storage_class != SpvStorageClassWorkgroup &&
       storage_class != SpvStorageClassStorageBuffer &&
       storage_class != SpvStorageClassStorageBuffer &&
-      storage_class != SpvStorageClassPhysicalStorageBufferEXT) {
+      storage_class != SpvStorageClassPhysicalStorageBuffer) {
     return _.diag(SPV_ERROR_INVALID_ID, inst)
     return _.diag(SPV_ERROR_INVALID_ID, inst)
            << opname << " storage class for pointer type <id> '"
            << opname << " storage class for pointer type <id> '"
            << _.getIdName(pointer_type_id)
            << _.getIdName(pointer_type_id)
@@ -1567,10 +1554,10 @@ spv_result_t ValidateCooperativeMatrixLoadStoreNV(ValidationState_t& _,
 spv_result_t ValidatePtrComparison(ValidationState_t& _,
 spv_result_t ValidatePtrComparison(ValidationState_t& _,
                                    const Instruction* inst) {
                                    const Instruction* inst) {
   if (_.addressing_model() == SpvAddressingModelLogical &&
   if (_.addressing_model() == SpvAddressingModelLogical &&
-      !_.features().variable_pointers_storage_buffer) {
+      !_.features().variable_pointers) {
     return _.diag(SPV_ERROR_INVALID_ID, inst)
     return _.diag(SPV_ERROR_INVALID_ID, inst)
-           << "Instruction cannot be used without a variable pointers "
-              "capability";
+           << "Instruction cannot for logical addressing model be used without "
+              "a variable pointers capability";
   }
   }
 
 
   const auto result_type = _.FindDef(inst->type_id());
   const auto result_type = _.FindDef(inst->type_id());
@@ -1605,7 +1592,8 @@ spv_result_t ValidatePtrComparison(ValidationState_t& _,
              << "Invalid pointer storage class";
              << "Invalid pointer storage class";
     }
     }
 
 
-    if (sc == SpvStorageClassWorkgroup && !_.features().variable_pointers) {
+    if (sc == SpvStorageClassWorkgroup &&
+        !_.HasCapability(SpvCapabilityVariablePointers)) {
       return _.diag(SPV_ERROR_INVALID_ID, inst)
       return _.diag(SPV_ERROR_INVALID_ID, inst)
              << "Workgroup storage class pointer requires VariablePointers "
              << "Workgroup storage class pointer requires VariablePointers "
                 "capability to be specified";
                 "capability to be specified";

+ 22 - 7
3rdparty/spirv-tools/source/val/validation_state.cpp

@@ -392,11 +392,8 @@ void ValidationState_t::RegisterCapability(SpvCapability cap) {
       features_.free_fp_rounding_mode = true;
       features_.free_fp_rounding_mode = true;
       break;
       break;
     case SpvCapabilityVariablePointers:
     case SpvCapabilityVariablePointers:
-      features_.variable_pointers = true;
-      features_.variable_pointers_storage_buffer = true;
-      break;
     case SpvCapabilityVariablePointersStorageBuffer:
     case SpvCapabilityVariablePointersStorageBuffer:
-      features_.variable_pointers_storage_buffer = true;
+      features_.variable_pointers = true;
       break;
       break;
     default:
     default:
       // TODO(dneto): For now don't validate SPV_NV_ray_tracing, which uses
       // TODO(dneto): For now don't validate SPV_NV_ray_tracing, which uses
@@ -460,7 +457,7 @@ void ValidationState_t::set_addressing_model(SpvAddressingModel am) {
     default:
     default:
     // fall through
     // fall through
     case SpvAddressingModelPhysical64:
     case SpvAddressingModelPhysical64:
-    case SpvAddressingModelPhysicalStorageBuffer64EXT:
+    case SpvAddressingModelPhysicalStorageBuffer64:
       pointer_size_and_alignment_ = 8;
       pointer_size_and_alignment_ = 8;
       break;
       break;
   }
   }
@@ -541,7 +538,7 @@ void ValidationState_t::RegisterInstruction(Instruction* inst) {
   if (inst->id()) all_definitions_.insert(std::make_pair(inst->id(), inst));
   if (inst->id()) all_definitions_.insert(std::make_pair(inst->id(), inst));
 
 
   // Some validation checks are easier by getting all the consumers
   // Some validation checks are easier by getting all the consumers
-  for (uint16_t i = 0; i < inst->operands().size(); ++i) {
+  for (size_t i = 0; i < inst->operands().size(); ++i) {
     const spv_parsed_operand_t& operand = inst->operand(i);
     const spv_parsed_operand_t& operand = inst->operand(i);
     if ((SPV_OPERAND_TYPE_ID == operand.type) ||
     if ((SPV_OPERAND_TYPE_ID == operand.type) ||
         (SPV_OPERAND_TYPE_TYPE_ID == operand.type)) {
         (SPV_OPERAND_TYPE_TYPE_ID == operand.type)) {
@@ -1872,6 +1869,8 @@ std::string ValidationState_t::VkErrorID(uint32_t id,
       return VUID_WRAP(VUID-StandaloneSpirv-OpGroupNonUniformBallotBitCount-04685);
       return VUID_WRAP(VUID-StandaloneSpirv-OpGroupNonUniformBallotBitCount-04685);
     case 4686:
     case 4686:
       return VUID_WRAP(VUID-StandaloneSpirv-None-04686);
       return VUID_WRAP(VUID-StandaloneSpirv-None-04686);
+    case 4708:
+      return VUID_WRAP(VUID-StandaloneSpirv-PhysicalStorageBuffer64-04708);
     case 4710:
     case 4710:
       return VUID_WRAP(VUID-StandaloneSpirv-PhysicalStorageBuffer64-04710);
       return VUID_WRAP(VUID-StandaloneSpirv-PhysicalStorageBuffer64-04710);
     case 4711:
     case 4711:
@@ -1890,6 +1889,8 @@ std::string ValidationState_t::VkErrorID(uint32_t id,
       return VUID_WRAP(VUID-StandaloneSpirv-OpImage-04777);
       return VUID_WRAP(VUID-StandaloneSpirv-OpImage-04777);
     case 4780:
     case 4780:
       return VUID_WRAP(VUID-StandaloneSpirv-Result-04780);
       return VUID_WRAP(VUID-StandaloneSpirv-Result-04780);
+    case 4781:
+      return VUID_WRAP(VUID-StandaloneSpirv-Base-04781);
     case 4915:
     case 4915:
       return VUID_WRAP(VUID-StandaloneSpirv-Location-04915);
       return VUID_WRAP(VUID-StandaloneSpirv-Location-04915);
     case 4916:
     case 4916:
@@ -1904,6 +1905,20 @@ std::string ValidationState_t::VkErrorID(uint32_t id,
       return VUID_WRAP(VUID-StandaloneSpirv-OpTypeImage-06214);
       return VUID_WRAP(VUID-StandaloneSpirv-OpTypeImage-06214);
     case 6491:
     case 6491:
       return VUID_WRAP(VUID-StandaloneSpirv-DescriptorSet-06491);
       return VUID_WRAP(VUID-StandaloneSpirv-DescriptorSet-06491);
+    case 6671:
+      return VUID_WRAP(VUID-StandaloneSpirv-OpTypeSampledImage-06671);
+    case 6672:
+      return VUID_WRAP(VUID-StandaloneSpirv-Location-06672);
+    case 6674:
+      return VUID_WRAP(VUID-StandaloneSpirv-OpEntryPoint-06674);
+    case 6675:
+      return VUID_WRAP(VUID-StandaloneSpirv-PushConstant-06675);
+    case 6676:
+      return VUID_WRAP(VUID-StandaloneSpirv-Uniform-06676);
+    case 6677:
+      return VUID_WRAP(VUID-StandaloneSpirv-UniformConstant-06677);
+    case 6678:
+      return VUID_WRAP(VUID-StandaloneSpirv-InputAttachmentIndex-06678);
     default:
     default:
       return "";  // unknown id
       return "";  // unknown id
   }
   }
@@ -1911,4 +1926,4 @@ std::string ValidationState_t::VkErrorID(uint32_t id,
 }
 }
 
 
 }  // namespace val
 }  // namespace val
-}  // namespace spvtools
+}  // namespace spvtools

+ 2 - 4
3rdparty/spirv-tools/source/val/validation_state.h

@@ -70,11 +70,9 @@ class ValidationState_t {
                                          // and its values to be used without
                                          // and its values to be used without
                                          // requiring any capability
                                          // requiring any capability
 
 
-    // Allow functionalities enabled by VariablePointers capability.
+    // Allow functionalities enabled by VariablePointers or
+    // VariablePointersStorageBuffer capability.
     bool variable_pointers = false;
     bool variable_pointers = false;
-    // Allow functionalities enabled by VariablePointersStorageBuffer
-    // capability.
-    bool variable_pointers_storage_buffer = false;
 
 
     // Permit group oerations Reduce, InclusiveScan, ExclusiveScan
     // Permit group oerations Reduce, InclusiveScan, ExclusiveScan
     bool group_ops_reduce_and_scans = false;
     bool group_ops_reduce_and_scans = false;

部分文件因文件數量過多而無法顯示