Przeglądaj źródła

Updated spirv-tools.

Бранимир Караџић 3 lat temu
rodzic
commit
837eecfa16

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

@@ -1 +1 @@
-"v2022.2-dev", "SPIRV-Tools v2022.2-dev da9e2f0400ece7d68b44d7c7126cac808dfcf5c3"
+"v2022.2-dev", "SPIRV-Tools v2022.2-dev 6bc813fb765b20ce28c8e6e8c5e6592e227dbf8c"

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

@@ -896,6 +896,10 @@ Optimizer::PassToken CreateConvertToSampledImagePass(
     const std::vector<opt::DescriptorSetAndBinding>&
         descriptor_set_binding_pairs);
 
+// Creates a remove-dont-inline pass to remove the |DontInline| function control
+// from every function in the module.  This is useful if you want the inliner to
+// inline these functions some reason.
+Optimizer::PassToken CreateRemoveDontInlinePass();
 }  // namespace spvtools
 
 #endif  // INCLUDE_SPIRV_TOOLS_OPTIMIZER_HPP_

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

@@ -172,7 +172,8 @@ SSAPropagator::PropStatus CCPPass::VisitAssignment(Instruction* instr) {
   if (folded_inst != nullptr) {
     // We do not want to change the body of the function by adding new
     // instructions.  When folding we can only generate new constants.
-    assert(folded_inst->IsConstant() &&
+    assert((folded_inst->IsConstant() ||
+            IsSpecConstantInst(folded_inst->opcode())) &&
            "CCP is only interested in constant values.");
     uint32_t new_val = ComputeLatticeMeet(instr, folded_inst->result_id());
     values_[instr->result_id()] = new_val;

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

@@ -86,7 +86,8 @@ Pass::Status CompactIdsPass::Process() {
       },
       true);
 
-  if (modified) {
+  if (context()->module()->id_bound() != result_id_mapping.size() + 1) {
+    modified = true;
     context()->module()->SetIdBound(
         static_cast<uint32_t>(result_id_mapping.size() + 1));
     // There are ids in the feature manager that could now be invalid

+ 2 - 2
3rdparty/spirv-tools/source/opt/folding_rules.cpp

@@ -2368,7 +2368,7 @@ FoldingRule VectorShuffleFeedingShuffle() {
             // fold.
             return false;
           }
-        } else {
+        } else if (component_index != undef_literal) {
           if (new_feeder_id == 0) {
             // First time through, save the id of the operand the element comes
             // from.
@@ -2382,7 +2382,7 @@ FoldingRule VectorShuffleFeedingShuffle() {
           component_index -= feeder_op0_length;
         }
 
-        if (!feeder_is_op0) {
+        if (!feeder_is_op0 && component_index != undef_literal) {
           component_index += op0_length;
         }
       }

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

@@ -521,6 +521,8 @@ bool Optimizer::RegisterPassFromFlag(const std::string& flag) {
     RegisterPass(CreateAmdExtToKhrPass());
   } else if (pass_name == "interpolate-fixup") {
     RegisterPass(CreateInterpolateFixupPass());
+  } else if (pass_name == "remove-dont-inline") {
+    RegisterPass(CreateRemoveDontInlinePass());
   } else if (pass_name == "convert-to-sampled-image") {
     if (pass_args.size() > 0) {
       auto descriptor_set_binding_pairs =
@@ -1009,4 +1011,8 @@ Optimizer::PassToken CreateConvertToSampledImagePass(
       MakeUnique<opt::ConvertToSampledImagePass>(descriptor_set_binding_pairs));
 }
 
+Optimizer::PassToken CreateRemoveDontInlinePass() {
+  return MakeUnique<Optimizer::PassToken::Impl>(
+      MakeUnique<opt::RemoveDontInline>());
+}
 }  // namespace spvtools

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

@@ -64,6 +64,7 @@
 #include "source/opt/reduce_load_size.h"
 #include "source/opt/redundancy_elimination.h"
 #include "source/opt/relax_float_ops_pass.h"
+#include "source/opt/remove_dontinline_pass.h"
 #include "source/opt/remove_duplicates_pass.h"
 #include "source/opt/remove_unused_interface_variables_pass.h"
 #include "source/opt/replace_desc_array_access_using_var_index.h"

+ 49 - 0
3rdparty/spirv-tools/source/opt/remove_dontinline_pass.cpp

@@ -0,0 +1,49 @@
+// Copyright (c) 2022 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "source/opt/remove_dontinline_pass.h"
+
+namespace spvtools {
+namespace opt {
+
+Pass::Status RemoveDontInline::Process() {
+  bool modified = false;
+  modified = ClearDontInlineFunctionControl();
+  return (modified ? Status::SuccessWithChange : Status::SuccessWithoutChange);
+}
+
+bool RemoveDontInline::ClearDontInlineFunctionControl() {
+  bool modified = false;
+  for (auto& func : *get_module()) {
+    ClearDontInlineFunctionControl(&func);
+  }
+  return modified;
+}
+
+bool RemoveDontInline::ClearDontInlineFunctionControl(Function* function) {
+  constexpr uint32_t kFunctionControlInOperandIdx = 0;
+  Instruction* function_inst = &function->DefInst();
+  uint32_t function_control =
+      function_inst->GetSingleWordInOperand(kFunctionControlInOperandIdx);
+
+  if ((function_control & SpvFunctionControlDontInlineMask) == 0) {
+    return false;
+  }
+  function_control &= ~SpvFunctionControlDontInlineMask;
+  function_inst->SetInOperand(kFunctionControlInOperandIdx, {function_control});
+  return true;
+}
+
+}  // namespace opt
+}  // namespace spvtools

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

@@ -0,0 +1,42 @@
+// Copyright (c) 2022 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef SOURCE_OPT_REMOVE_DONTINLINE_PASS_H_
+#define SOURCE_OPT_REMOVE_DONTINLINE_PASS_H_
+
+#include "source/opt/pass.h"
+
+namespace spvtools {
+namespace opt {
+
+// See optimizer.hpp for documentation.
+class RemoveDontInline : public Pass {
+ public:
+  const char* name() const override { return "remove-dont-inline"; }
+  Status Process() override;
+
+ private:
+  // Clears the DontInline function control from every function in the module.
+  // Returns true of a change was made.
+  bool ClearDontInlineFunctionControl();
+
+  // Clears the DontInline function control from |function|.
+  // Returns true of a change was made.
+  bool ClearDontInlineFunctionControl(Function* function);
+};
+
+}  // namespace opt
+}  // namespace spvtools
+
+#endif  // SOURCE_OPT_REMOVE_DONTINLINE_PASS_H_

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

@@ -326,17 +326,20 @@ spv_result_t ValidateDecorationTarget(ValidationState_t& _, SpvDecoration dec,
       case SpvDecorationLocation:
       case SpvDecorationComponent:
         // Location is used for input, output and ray tracing stages.
-        if (sc == SpvStorageClassStorageBuffer ||
-            sc == SpvStorageClassUniform ||
-            sc == SpvStorageClassUniformConstant ||
-            sc == SpvStorageClassWorkgroup || sc == SpvStorageClassPrivate ||
-            sc == SpvStorageClassFunction) {
+        if (sc != SpvStorageClassInput && sc != SpvStorageClassOutput &&
+            sc != SpvStorageClassRayPayloadKHR &&
+            sc != SpvStorageClassIncomingRayPayloadKHR &&
+            sc != SpvStorageClassHitAttributeKHR &&
+            sc != SpvStorageClassCallableDataKHR &&
+            sc != SpvStorageClassIncomingCallableDataKHR &&
+            sc != SpvStorageClassShaderRecordBufferKHR) {
           return _.diag(SPV_ERROR_INVALID_ID, target)
                  << LogStringForDecoration(dec)
                  << " decoration must not be applied to this storage class";
         }
         break;
       case SpvDecorationIndex:
+        // Langauge from SPIR-V definition of Index
         if (sc != SpvStorageClassOutput) {
           return fail(0) << "must be in the Output storage class";
         }
@@ -346,8 +349,8 @@ spv_result_t ValidateDecorationTarget(ValidationState_t& _, SpvDecoration dec,
         if (sc != SpvStorageClassStorageBuffer &&
             sc != SpvStorageClassUniform &&
             sc != SpvStorageClassUniformConstant) {
-          return fail(0) << "must be in the StorageBuffer, Uniform, or "
-                            "UniformConstant storage class";
+          return fail(6491) << "must be in the StorageBuffer, Uniform, or "
+                               "UniformConstant storage class";
         }
         break;
       case SpvDecorationInputAttachmentIndex:

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

@@ -869,13 +869,21 @@ spv_result_t ValidateTypeImage(ValidationState_t& _, const Instruction* inst) {
   if (info.dim == SpvDimSubpassData) {
     if (info.sampled != 2) {
       return _.diag(SPV_ERROR_INVALID_DATA, inst)
-             << "Dim SubpassData requires Sampled to be 2";
+             << _.VkErrorID(6214) << "Dim SubpassData requires Sampled to be 2";
     }
 
     if (info.format != SpvImageFormatUnknown) {
       return _.diag(SPV_ERROR_INVALID_DATA, inst)
              << "Dim SubpassData requires format Unknown";
     }
+
+    if (spvIsVulkanEnv(target_env)) {
+      if (info.arrayed != 0) {
+        return _.diag(SPV_ERROR_INVALID_DATA, inst)
+               << _.VkErrorID(6214)
+               << "Dim SubpassData requires Arrayed to be 0";
+      }
+    }
   }
 
   // Format and Access Qualifier are also checked elsewhere.
@@ -1268,6 +1276,27 @@ spv_result_t ValidateImageLod(ValidationState_t& _, const Instruction* inst) {
   return SPV_SUCCESS;
 }
 
+// Validates anything OpImage*Dref* instruction
+spv_result_t ValidateImageDref(ValidationState_t& _, const Instruction* inst,
+                               const ImageTypeInfo& info) {
+  const uint32_t dref_type = _.GetOperandTypeId(inst, 4);
+  if (!_.IsFloatScalarType(dref_type) || _.GetBitWidth(dref_type) != 32) {
+    return _.diag(SPV_ERROR_INVALID_DATA, inst)
+           << "Expected Dref to be of 32-bit float type";
+  }
+
+  if (spvIsVulkanEnv(_.context()->target_env)) {
+    if (info.dim == SpvDim3D) {
+      return _.diag(SPV_ERROR_INVALID_DATA, inst)
+             << _.VkErrorID(4777)
+             << "In Vulkan, OpImage*Dref* instructions must not use images "
+                "with a 3D Dim";
+    }
+  }
+
+  return SPV_SUCCESS;
+}
+
 spv_result_t ValidateImageDrefLod(ValidationState_t& _,
                                   const Instruction* inst) {
   const SpvOp opcode = inst->opcode();
@@ -1325,11 +1354,7 @@ spv_result_t ValidateImageDrefLod(ValidationState_t& _,
            << " components, but given only " << actual_coord_size;
   }
 
-  const uint32_t dref_type = _.GetOperandTypeId(inst, 4);
-  if (!_.IsFloatScalarType(dref_type) || _.GetBitWidth(dref_type) != 32) {
-    return _.diag(SPV_ERROR_INVALID_DATA, inst)
-           << "Expected Dref to be of 32-bit float type";
-  }
+  if (spv_result_t result = ValidateImageDref(_, inst, info)) return result;
 
   if (spv_result_t result =
           ValidateImageOperands(_, inst, info, /* word_index = */ 7))
@@ -1464,7 +1489,8 @@ spv_result_t ValidateImageGather(ValidationState_t& _,
   if (info.dim != SpvDim2D && info.dim != SpvDimCube &&
       info.dim != SpvDimRect) {
     return _.diag(SPV_ERROR_INVALID_DATA, inst)
-           << "Expected Image 'Dim' cannot be Cube";
+           << _.VkErrorID(4777)
+           << "Expected Image 'Dim' to be 2D, Cube, or Rect";
   }
 
   const uint32_t coord_type = _.GetOperandTypeId(inst, 3);
@@ -1500,11 +1526,7 @@ spv_result_t ValidateImageGather(ValidationState_t& _,
   } else {
     assert(opcode == SpvOpImageDrefGather ||
            opcode == SpvOpImageSparseDrefGather);
-    const uint32_t dref_type = _.GetOperandTypeId(inst, 4);
-    if (!_.IsFloatScalarType(dref_type) || _.GetBitWidth(dref_type) != 32) {
-      return _.diag(SPV_ERROR_INVALID_DATA, inst)
-             << "Expected Dref to be of 32-bit float type";
-    }
+    if (spv_result_t result = ValidateImageDref(_, inst, info)) return result;
   }
 
   if (spv_result_t result =

+ 18 - 10
3rdparty/spirv-tools/source/val/validate_memory.cpp

@@ -519,20 +519,21 @@ spv_result_t ValidateVariable(ValidationState_t& _, const Instruction* inst) {
     }
   }
 
-  // Vulkan 14.5.1: Check type of PushConstant variables.
-  // Vulkan 14.5.2: Check type of UniformConstant and Uniform variables.
   if (spvIsVulkanEnv(_.context()->target_env)) {
+    // Vulkan Push Constant Interface section: Check type of PushConstant
+    // variables.
     if (storage_class == SpvStorageClassPushConstant) {
-      if (!IsAllowedTypeOrArrayOfSame(_, pointee, {SpvOpTypeStruct})) {
+      if (pointee->opcode() != SpvOpTypeStruct) {
         return _.diag(SPV_ERROR_INVALID_ID, inst)
                << "PushConstant OpVariable <id> '" << _.getIdName(inst->id())
                << "' has illegal type.\n"
-               << "From Vulkan spec, section 14.5.1:\n"
-               << "Such variables must be typed as OpTypeStruct, "
-               << "or an array of this type";
+               << "From Vulkan spec, Push Constant Interface section:\n"
+               << "Such variables must be typed as OpTypeStruct";
       }
     }
 
+    // Vulkan Descriptor Set Interface: Check type of UniformConstant and
+    // Uniform variables.
     if (storage_class == SpvStorageClassUniformConstant) {
       if (!IsAllowedTypeOrArrayOfSame(
               _, pointee,
@@ -667,7 +668,8 @@ spv_result_t ValidateVariable(ValidationState_t& _, const Instruction* inst) {
     if (value_type && value_type->opcode() == SpvOpTypeRuntimeArray) {
       if (!_.HasCapability(SpvCapabilityRuntimeDescriptorArrayEXT)) {
         return _.diag(SPV_ERROR_INVALID_ID, inst)
-               << "OpVariable, <id> '" << _.getIdName(inst->id())
+               << _.VkErrorID(4680) << "OpVariable, <id> '"
+               << _.getIdName(inst->id())
                << "', is attempting to create memory for an illegal type, "
                << "OpTypeRuntimeArray.\nFor Vulkan OpTypeRuntimeArray can only "
                << "appear as the final member of an OpTypeStruct, thus cannot "
@@ -679,6 +681,7 @@ spv_result_t ValidateVariable(ValidationState_t& _, const Instruction* inst) {
             storage_class != SpvStorageClassUniform &&
             storage_class != SpvStorageClassUniformConstant) {
           return _.diag(SPV_ERROR_INVALID_ID, inst)
+                 << _.VkErrorID(4680)
                  << "For Vulkan with RuntimeDescriptorArrayEXT, a variable "
                  << "containing OpTypeRuntimeArray must have storage class of "
                  << "StorageBuffer, Uniform, or UniformConstant.";
@@ -692,25 +695,30 @@ spv_result_t ValidateVariable(ValidationState_t& _, const Instruction* inst) {
     // as BufferBlock.
     if (value_type && value_type->opcode() == SpvOpTypeStruct) {
       if (DoesStructContainRTA(_, value_type)) {
-        if (storage_class == SpvStorageClassStorageBuffer) {
+        if (storage_class == SpvStorageClassStorageBuffer ||
+            storage_class == SpvStorageClassPhysicalStorageBuffer) {
           if (!_.HasDecoration(value_id, SpvDecorationBlock)) {
             return _.diag(SPV_ERROR_INVALID_ID, inst)
+                   << _.VkErrorID(4680)
                    << "For Vulkan, an OpTypeStruct variable containing an "
                    << "OpTypeRuntimeArray must be decorated with Block if it "
-                   << "has storage class StorageBuffer.";
+                   << "has storage class StorageBuffer or "
+                      "PhysicalStorageBuffer.";
           }
         } else if (storage_class == SpvStorageClassUniform) {
           if (!_.HasDecoration(value_id, SpvDecorationBufferBlock)) {
             return _.diag(SPV_ERROR_INVALID_ID, inst)
+                   << _.VkErrorID(4680)
                    << "For Vulkan, an OpTypeStruct variable containing an "
                    << "OpTypeRuntimeArray must be decorated with BufferBlock "
                    << "if it has storage class Uniform.";
           }
         } else {
           return _.diag(SPV_ERROR_INVALID_ID, inst)
+                 << _.VkErrorID(4680)
                  << "For Vulkan, OpTypeStruct variables containing "
                  << "OpTypeRuntimeArray must have storage class of "
-                 << "StorageBuffer or Uniform.";
+                 << "StorageBuffer, PhysicalStorageBuffer, or Uniform.";
         }
       }
     }

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

@@ -228,8 +228,8 @@ spv_result_t ValidateTypeArray(ValidationState_t& _, const Instruction* inst) {
   if (spvIsVulkanEnv(_.context()->target_env) &&
       element_type->opcode() == SpvOpTypeRuntimeArray) {
     return _.diag(SPV_ERROR_INVALID_ID, inst)
-           << "OpTypeArray Element Type <id> '" << _.getIdName(element_type_id)
-           << "' is not valid in "
+           << _.VkErrorID(4680) << "OpTypeArray Element Type <id> '"
+           << _.getIdName(element_type_id) << "' is not valid in "
            << spvLogStringForEnv(_.context()->target_env) << " environments.";
   }
 
@@ -298,7 +298,7 @@ spv_result_t ValidateTypeRuntimeArray(ValidationState_t& _,
   if (spvIsVulkanEnv(_.context()->target_env) &&
       element_type->opcode() == SpvOpTypeRuntimeArray) {
     return _.diag(SPV_ERROR_INVALID_ID, inst)
-           << "OpTypeRuntimeArray Element Type <id> '"
+           << _.VkErrorID(4680) << "OpTypeRuntimeArray Element Type <id> '"
            << _.getIdName(element_id) << "' is not valid in "
            << spvLogStringForEnv(_.context()->target_env) << " environments.";
   }
@@ -373,7 +373,8 @@ spv_result_t ValidateTypeStruct(ValidationState_t& _, const Instruction* inst) {
           member_type_index == inst->operands().size() - 1;
       if (!is_last_member) {
         return _.diag(SPV_ERROR_INVALID_ID, inst)
-               << "In " << spvLogStringForEnv(_.context()->target_env)
+               << _.VkErrorID(4680) << "In "
+               << spvLogStringForEnv(_.context()->target_env)
                << ", OpTypeRuntimeArray must only be used for the last member "
                   "of an OpTypeStruct";
       }

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

@@ -1862,6 +1862,8 @@ std::string ValidationState_t::VkErrorID(uint32_t id,
       return VUID_WRAP(VUID-StandaloneSpirv-FPRoundingMode-04675);
     case 4677:
       return VUID_WRAP(VUID-StandaloneSpirv-Invariant-04677);
+    case 4680:
+      return VUID_WRAP( VUID-StandaloneSpirv-OpTypeRuntimeArray-04680);
     case 4682:
       return VUID_WRAP(VUID-StandaloneSpirv-OpControlBarrier-04682);
     case 6426:
@@ -1884,6 +1886,8 @@ std::string ValidationState_t::VkErrorID(uint32_t id,
       return VUID_WRAP(VUID-StandaloneSpirv-OpMemoryBarrier-04733);
     case 4734:
       return VUID_WRAP(VUID-StandaloneSpirv-OpVariable-04734);
+    case 4777:
+      return VUID_WRAP(VUID-StandaloneSpirv-OpImage-04777);
     case 4780:
       return VUID_WRAP(VUID-StandaloneSpirv-Result-04780);
     case 4915:
@@ -1896,6 +1900,10 @@ std::string ValidationState_t::VkErrorID(uint32_t id,
       return VUID_WRAP(VUID-StandaloneSpirv-Location-04918);
     case 4919:
       return VUID_WRAP(VUID-StandaloneSpirv-Location-04919);
+    case 6214:
+      return VUID_WRAP(VUID-StandaloneSpirv-OpTypeImage-06214);
+    case 6491:
+      return VUID_WRAP(VUID-StandaloneSpirv-DescriptorSet-06491);
     default:
       return "";  // unknown id
   }