소스 검색

Updated spirv-tools.

Бранимир Караџић 5 년 전
부모
커밋
6fe24f441e

+ 3 - 2
3rdparty/spirv-tools/CHANGES

@@ -1,14 +1,15 @@
 Revision history for SPIRV-Tools
 
-v2020.7-dev 2020-12-03
+v2020.7-dev 2020-12-07
  - Start v2020.7-dev
 
-v2020.6 2020-12-02
+v2020.6 2020-12-07
  - General
     CMake: Add SPIRV_TOOLS_BUILD_STATIC flag (#3910)
  - Disassembler
     Add some context comments to disassembly. (#3847)
  - Optimizer
+   - Take new (raytracing) termination instructions into account. (#4050)
    - Do run DCE if SPV_KHR_ray_query is used. (#4047)
    - Handle 8-bit index in elim dead member (#4043)
    - Add texel buffer out-of-bounds checking instrumentation (#4038)

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

@@ -1 +1 @@
-"v2020.7-dev", "SPIRV-Tools v2020.7-dev c73d8d8cf8076c3848338cc5a5f63d291afa2989"
+"v2020.7-dev", "SPIRV-Tools v2020.7-dev 5a705a115f558ea53abd7ef08456551e6d9bd42f"

+ 19 - 2
3rdparty/spirv-tools/source/opcode.cpp

@@ -444,15 +444,32 @@ bool spvOpcodeIsReturn(SpvOp opcode) {
   }
 }
 
+bool spvOpcodeIsAbort(SpvOp opcode) {
+  switch (opcode) {
+    case SpvOpKill:
+    case SpvOpUnreachable:
+    case SpvOpTerminateInvocation:
+    case SpvOpTerminateRayKHR:
+    case SpvOpIgnoreIntersectionKHR:
+      return true;
+    default:
+      return false;
+  }
+}
+
 bool spvOpcodeIsReturnOrAbort(SpvOp opcode) {
-  return spvOpcodeIsReturn(opcode) || opcode == SpvOpKill ||
-         opcode == SpvOpUnreachable || opcode == SpvOpTerminateInvocation;
+  return spvOpcodeIsReturn(opcode) || spvOpcodeIsAbort(opcode);
 }
 
 bool spvOpcodeIsBlockTerminator(SpvOp opcode) {
   return spvOpcodeIsBranch(opcode) || spvOpcodeIsReturnOrAbort(opcode);
 }
 
+bool spvOpcodeTerminatesExecution(SpvOp opcode) {
+  return opcode == SpvOpKill || opcode == SpvOpTerminateInvocation ||
+         opcode == SpvOpTerminateRayKHR || opcode == SpvOpIgnoreIntersectionKHR;
+}
+
 bool spvOpcodeIsBaseOpaqueType(SpvOp opcode) {
   switch (opcode) {
     case SpvOpTypeImage:

+ 8 - 0
3rdparty/spirv-tools/source/opcode.h

@@ -110,10 +110,18 @@ bool spvOpcodeIsBranch(SpvOp opcode);
 // Returns true if the given opcode is a return instruction.
 bool spvOpcodeIsReturn(SpvOp opcode);
 
+// Returns true if the given opcode aborts execution.
+bool spvOpcodeIsAbort(SpvOp opcode);
+
 // Returns true if the given opcode is a return instruction or it aborts
 // execution.
 bool spvOpcodeIsReturnOrAbort(SpvOp opcode);
 
+// Returns true if the given opcode is a kill instruction or it terminates
+// execution. Note that branches, returns, and unreachables do not terminate
+// execution.
+bool spvOpcodeTerminatesExecution(SpvOp opcode);
+
 // Returns true if the given opcode is a basic block terminator.
 bool spvOpcodeIsBlockTerminator(SpvOp opcode);
 

+ 6 - 1
3rdparty/spirv-tools/source/operand.cpp

@@ -24,6 +24,7 @@
 #include "DebugInfo.h"
 #include "OpenCLDebugInfo100.h"
 #include "source/macro.h"
+#include "source/opcode.h"
 #include "source/spirv_constant.h"
 #include "source/spirv_target_env.h"
 
@@ -491,6 +492,11 @@ bool spvIsInIdType(spv_operand_type_t type) {
 std::function<bool(unsigned)> spvOperandCanBeForwardDeclaredFunction(
     SpvOp opcode) {
   std::function<bool(unsigned index)> out;
+  if (spvOpcodeGeneratesType(opcode)) {
+    // All types can use forward pointers.
+    out = [](unsigned) { return true; };
+    return out;
+  }
   switch (opcode) {
     case SpvOpExecutionMode:
     case SpvOpExecutionModeId:
@@ -503,7 +509,6 @@ std::function<bool(unsigned)> spvOperandCanBeForwardDeclaredFunction(
     case SpvOpDecorateId:
     case SpvOpDecorateStringGOOGLE:
     case SpvOpMemberDecorateStringGOOGLE:
-    case SpvOpTypeStruct:
     case SpvOpBranch:
     case SpvOpLoopMerge:
       out = [](unsigned) { return true; };

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

@@ -995,6 +995,7 @@ void AggressiveDCEPass::InitExtensions() {
       "SPV_EXT_fragment_invocation_density",
       "SPV_EXT_physical_storage_buffer",
       "SPV_KHR_terminate_invocation",
+      "SPV_KHR_shader_clock",
   });
 }
 

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

@@ -230,7 +230,7 @@ std::string BasicBlock::PrettyPrint(uint32_t options) const {
   std::ostringstream str;
   ForEachInst([&str, options](const Instruction* inst) {
     str << inst->PrettyPrint(options);
-    if (!IsTerminatorInst(inst->opcode())) {
+    if (!spvOpcodeIsBlockTerminator(inst->opcode())) {
       str << std::endl;
     }
   });

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

@@ -383,9 +383,7 @@ std::unique_ptr<BasicBlock> InlinePass::InlineReturn(
   uint32_t returnLabelId = 0;
   for (auto callee_block_itr = calleeFn->begin();
        callee_block_itr != calleeFn->end(); ++callee_block_itr) {
-    if (callee_block_itr->tail()->opcode() == SpvOpUnreachable ||
-        callee_block_itr->tail()->opcode() == SpvOpKill ||
-        callee_block_itr->tail()->opcode() == SpvOpTerminateInvocation) {
+    if (spvOpcodeIsAbort(callee_block_itr->tail()->opcode())) {
       returnLabelId = context()->TakeNextId();
       break;
     }
@@ -759,8 +757,7 @@ bool InlinePass::IsInlinableFunction(Function* func) {
 
 bool InlinePass::ContainsKillOrTerminateInvocation(Function* func) const {
   return !func->WhileEachInst([](Instruction* inst) {
-    const auto opcode = inst->opcode();
-    return (opcode != SpvOpKill) && (opcode != SpvOpTerminateInvocation);
+    return !spvOpcodeTerminatesExecution(inst->opcode());
   });
 }
 

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

@@ -137,7 +137,7 @@ bool IrLoader::AddInstruction(const spv_parsed_instruction_t* inst) {
       return false;
     }
     block_ = MakeUnique<BasicBlock>(std::move(spv_inst));
-  } else if (IsTerminatorInst(opcode)) {
+  } else if (spvOpcodeIsBlockTerminator(opcode)) {
     if (function_ == nullptr) {
       Error(consumer_, src, loc, "terminator instruction outside function");
       return false;

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

@@ -188,7 +188,7 @@ void Module::ToBinary(std::vector<uint32_t>* binary, bool skip_nop) const {
       i->ToBinaryWithoutAttachedDebugInsts(binary);
     }
     // Update the last line instruction.
-    if (IsTerminatorInst(opcode) || opcode == SpvOpNoLine) {
+    if (spvOpcodeIsBlockTerminator(opcode) || opcode == SpvOpNoLine) {
       last_line_inst = nullptr;
     } else if (opcode == SpvOpLoopMerge || opcode == SpvOpSelectionMerge) {
       between_merge_and_branch = true;

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

@@ -59,10 +59,6 @@ inline bool IsCompileTimeConstantInst(SpvOp opcode) {
 inline bool IsSpecConstantInst(SpvOp opcode) {
   return opcode >= SpvOpSpecConstantTrue && opcode <= SpvOpSpecConstantOp;
 }
-inline bool IsTerminatorInst(SpvOp opcode) {
-  return (opcode >= SpvOpBranch && opcode <= SpvOpUnreachable) ||
-         (opcode == SpvOpTerminateInvocation);
-}
 
 }  // namespace opt
 }  // namespace spvtools

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

@@ -1098,8 +1098,9 @@ spv_result_t BuiltInsValidator::ValidateClipOrCullDistanceAtReference(
     if (storage_class != SpvStorageClassMax &&
         storage_class != SpvStorageClassInput &&
         storage_class != SpvStorageClassOutput) {
+      uint32_t vuid = (decoration.params()[0] == SpvBuiltInClipDistance) ? 4190 : 4199;
       return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst)
-             << "Vulkan spec allows BuiltIn "
+             << _.VkErrorID(vuid) << "Vulkan spec allows BuiltIn "
              << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN,
                                               operand)
              << " to be only used for variables with Input or Output storage "
@@ -1111,19 +1112,28 @@ spv_result_t BuiltInsValidator::ValidateClipOrCullDistanceAtReference(
 
     if (storage_class == SpvStorageClassInput) {
       assert(function_id_ == 0);
+      uint32_t vuid = (decoration.params()[0] == SpvBuiltInClipDistance) ? 4188 : 4197;
       id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind(
-          &BuiltInsValidator::ValidateNotCalledWithExecutionModel, this, -1,
+          &BuiltInsValidator::ValidateNotCalledWithExecutionModel, this, vuid,
           "Vulkan spec doesn't allow BuiltIn ClipDistance/CullDistance to be "
           "used for variables with Input storage class if execution model is "
           "Vertex.",
           SpvExecutionModelVertex, decoration, built_in_inst,
           referenced_from_inst, std::placeholders::_1));
+      id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind(
+          &BuiltInsValidator::ValidateNotCalledWithExecutionModel, this, vuid,
+          "Vulkan spec doesn't allow BuiltIn ClipDistance/CullDistance to be "
+          "used for variables with Input storage class if execution model is "
+          "Vertex.",
+          SpvExecutionModelMeshNV, decoration, built_in_inst,
+          referenced_from_inst, std::placeholders::_1));
     }
 
     if (storage_class == SpvStorageClassOutput) {
       assert(function_id_ == 0);
+      uint32_t vuid = (decoration.params()[0] == SpvBuiltInClipDistance) ? 4189 : 4198;
       id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind(
-          &BuiltInsValidator::ValidateNotCalledWithExecutionModel, this, -1,
+          &BuiltInsValidator::ValidateNotCalledWithExecutionModel, this, vuid,
           "Vulkan spec doesn't allow BuiltIn ClipDistance/CullDistance to be "
           "used for variables with Output storage class if execution model is "
           "Fragment.",
@@ -1869,7 +1879,7 @@ spv_result_t BuiltInsValidator::ValidatePositionAtReference(
         storage_class != SpvStorageClassInput &&
         storage_class != SpvStorageClassOutput) {
       return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst)
-             << "Vulkan spec allows BuiltIn Position to be only used for "
+             << _.VkErrorID(4320) << "Vulkan spec allows BuiltIn Position to be only used for "
                 "variables with Input or Output storage class. "
              << GetReferenceDesc(decoration, built_in_inst, referenced_inst,
                                  referenced_from_inst)
@@ -1879,12 +1889,19 @@ spv_result_t BuiltInsValidator::ValidatePositionAtReference(
     if (storage_class == SpvStorageClassInput) {
       assert(function_id_ == 0);
       id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind(
-          &BuiltInsValidator::ValidateNotCalledWithExecutionModel, this, 4320,
+          &BuiltInsValidator::ValidateNotCalledWithExecutionModel, this, 4319,
           "Vulkan spec doesn't allow BuiltIn Position to be used "
           "for variables "
           "with Input storage class if execution model is Vertex.",
           SpvExecutionModelVertex, decoration, built_in_inst,
           referenced_from_inst, std::placeholders::_1));
+      id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind(
+          &BuiltInsValidator::ValidateNotCalledWithExecutionModel, this, 4319,
+          "Vulkan spec doesn't allow BuiltIn Position to be used "
+          "for variables "
+          "with Input storage class if execution model is MeshNV.",
+          SpvExecutionModelMeshNV, decoration, built_in_inst,
+          referenced_from_inst, std::placeholders::_1));
     }
 
     for (const SpvExecutionModel execution_model : execution_models_) {
@@ -2458,8 +2475,9 @@ spv_result_t BuiltInsValidator::ValidateTessLevelAtReference(
 
     if (storage_class == SpvStorageClassInput) {
       assert(function_id_ == 0);
+      uint32_t vuid = (decoration.params()[0] == SpvBuiltInTessLevelOuter) ? 4391 : 4395;
       id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind(
-          &BuiltInsValidator::ValidateNotCalledWithExecutionModel, this, -1,
+          &BuiltInsValidator::ValidateNotCalledWithExecutionModel, this, vuid,
           "Vulkan spec doesn't allow TessLevelOuter/TessLevelInner to be "
           "used "
           "for variables with Input storage class if execution model is "
@@ -2470,8 +2488,9 @@ spv_result_t BuiltInsValidator::ValidateTessLevelAtReference(
 
     if (storage_class == SpvStorageClassOutput) {
       assert(function_id_ == 0);
+      uint32_t vuid = (decoration.params()[0] == SpvBuiltInTessLevelOuter) ? 4392 : 4396;
       id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind(
-          &BuiltInsValidator::ValidateNotCalledWithExecutionModel, this, -1,
+          &BuiltInsValidator::ValidateNotCalledWithExecutionModel, this, vuid,
           "Vulkan spec doesn't allow TessLevelOuter/TessLevelInner to be "
           "used "
           "for variables with Output storage class if execution model is "
@@ -2768,8 +2787,9 @@ spv_result_t BuiltInsValidator::ValidateLayerOrViewportIndexAtReference(
             if (operand == SpvBuiltInLayer)
               capability = "ShaderViewportIndexLayerEXT or ShaderLayer";
 
+            uint32_t vuid = (operand == SpvBuiltInLayer) ? 4273 : 4405;
             return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst)
-                   << "Using BuiltIn "
+                   << _.VkErrorID(vuid) << "Using BuiltIn "
                    << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN,
                                                     operand)
                    << " in Vertex or Tessellation execution model requires the "

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

@@ -201,7 +201,7 @@ spv_result_t IdPass(ValidationState_t& _, Instruction* inst) {
             ret = SPV_SUCCESS;
           }
         } else if (can_have_forward_declared_ids(i)) {
-          if (inst->opcode() == SpvOpTypeStruct &&
+          if (spvOpcodeGeneratesType(inst->opcode()) &&
               !_.IsForwardPointer(operand_word)) {
             ret = _.diag(SPV_ERROR_INVALID_ID, inst)
                   << "Operand " << _.getIdName(operand_word)

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

@@ -736,7 +736,8 @@ spv_result_t ValidateTypeImage(ValidationState_t& _, const Instruction* inst) {
            << "Corrupt image type definition";
   }
 
-  if (spvIsVulkanEnv(_.context()->target_env)) {
+  const auto target_env = _.context()->target_env;
+  if (spvIsVulkanEnv(target_env)) {
     if ((!_.IsFloatScalarType(info.sampled_type) &&
          !_.IsIntScalarType(info.sampled_type)) ||
         (32 != _.GetBitWidth(info.sampled_type) &&
@@ -746,7 +747,7 @@ spv_result_t ValidateTypeImage(ValidationState_t& _, const Instruction* inst) {
              << "Expected Sampled Type to be a 32-bit int or float "
                 "scalar type for Vulkan environment";
     }
-  } else if (spvIsOpenCLEnv(_.context()->target_env)) {
+  } else if (spvIsOpenCLEnv(target_env)) {
     if (!_.IsVoidType(info.sampled_type)) {
       return _.diag(SPV_ERROR_INVALID_DATA, inst)
              << "Sampled Type must be OpTypeVoid in the OpenCL environment.";
@@ -774,7 +775,7 @@ spv_result_t ValidateTypeImage(ValidationState_t& _, const Instruction* inst) {
            << "Invalid Arrayed " << info.arrayed << " (must be 0 or 1)";
   }
 
-  if (spvIsOpenCLEnv(_.context()->target_env)) {
+  if (spvIsOpenCLEnv(target_env)) {
     if ((info.arrayed == 1) && (info.dim != SpvDim1D) &&
         (info.dim != SpvDim2D)) {
       return _.diag(SPV_ERROR_INVALID_DATA, inst)
@@ -788,10 +789,10 @@ spv_result_t ValidateTypeImage(ValidationState_t& _, const Instruction* inst) {
            << "Invalid MS " << info.multisampled << " (must be 0 or 1)";
   }
 
-  if (spvIsOpenCLEnv(_.context()->target_env)) {
+  if (spvIsOpenCLEnv(target_env)) {
     if (info.multisampled != 0) {
       return _.diag(SPV_ERROR_INVALID_DATA, inst)
-             << "MS must be 0 in the OpenCL environement.";
+             << "MS must be 0 in the OpenCL environment.";
     }
   }
 
@@ -800,6 +801,15 @@ spv_result_t ValidateTypeImage(ValidationState_t& _, const Instruction* inst) {
            << "Invalid Sampled " << info.sampled << " (must be 0, 1 or 2)";
   }
 
+  if (spvIsVulkanEnv(target_env) || spvIsWebGPUEnv(target_env)) {
+    if (info.sampled == 0) {
+      return _.diag(SPV_ERROR_INVALID_DATA, inst)
+             << "Sampled must be 1 or 2 in the "
+             << (spvIsVulkanEnv(target_env) ? "Vulkan" : "WebGPU")
+             << " environment.";
+    }
+  }
+
   if (spvIsOpenCLEnv(_.context()->target_env)) {
     if (info.sampled != 0) {
       return _.diag(SPV_ERROR_INVALID_DATA, inst)
@@ -829,6 +839,15 @@ spv_result_t ValidateTypeImage(ValidationState_t& _, const Instruction* inst) {
     }
   }
 
+  if (info.multisampled && (info.sampled == 2) &&
+      (info.dim != SpvDimSubpassData)) {
+    if (!_.HasCapability(SpvCapabilityStorageImageMultisample)) {
+      return _.diag(SPV_ERROR_INVALID_DATA, inst)
+             << "Capability StorageImageMultisample is required when using "
+                "multisampled storage image";
+    }
+  }
+
   return SPV_SUCCESS;
 }
 

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

@@ -1315,10 +1315,22 @@ std::string ValidationState_t::VkErrorID(uint32_t id,
       return VUID_WRAP(VUID-BaseVertex-BaseVertex-04186);
     case 4187:
       return VUID_WRAP(VUID-ClipDistance-ClipDistance-04187);
+    case 4188:
+      return VUID_WRAP(VUID-ClipDistance-ClipDistance-04188);
+    case 4189:
+      return VUID_WRAP(VUID-ClipDistance-ClipDistance-04189);
+    case 4190:
+      return VUID_WRAP(VUID-ClipDistance-ClipDistance-04190);
     case 4191:
       return VUID_WRAP(VUID-ClipDistance-ClipDistance-04191);
     case 4196:
       return VUID_WRAP(VUID-CullDistance-CullDistance-04196);
+    case 4197:
+      return VUID_WRAP(VUID-CullDistance-CullDistance-04197);
+    case 4198:
+      return VUID_WRAP(VUID-CullDistance-CullDistance-04198);
+    case 4199:
+      return VUID_WRAP(VUID-CullDistance-CullDistance-04199);
     case 4200:
       return VUID_WRAP(VUID-CullDistance-CullDistance-04200);
     case 4205:
@@ -1419,6 +1431,8 @@ std::string ValidationState_t::VkErrorID(uint32_t id,
       return VUID_WRAP(VUID-LaunchSizeKHR-LaunchSizeKHR-04271);
     case 4272:
       return VUID_WRAP(VUID-Layer-Layer-04272);
+    case 4273:
+      return VUID_WRAP(VUID-Layer-Layer-04273);
     case 4274:
       return VUID_WRAP(VUID-Layer-Layer-04274);
     case 4275:
@@ -1477,6 +1491,8 @@ std::string ValidationState_t::VkErrorID(uint32_t id,
       return VUID_WRAP(VUID-PointSize-PointSize-04317);
     case 4318:
       return VUID_WRAP(VUID-Position-Position-04318);
+    case 4319:
+      return VUID_WRAP(VUID-Position-Position-04319);
     case 4320:
       return VUID_WRAP(VUID-Position-Position-04320);
     case 4321:
@@ -1531,10 +1547,18 @@ std::string ValidationState_t::VkErrorID(uint32_t id,
       return VUID_WRAP(VUID-TessCoord-TessCoord-04389);
     case 4390:
       return VUID_WRAP(VUID-TessLevelOuter-TessLevelOuter-04390);
+    case 4391:
+      return VUID_WRAP(VUID-TessLevelOuter-TessLevelOuter-04391);
+    case 4392:
+      return VUID_WRAP(VUID-TessLevelOuter-TessLevelOuter-04392);
     case 4393:
       return VUID_WRAP(VUID-TessLevelOuter-TessLevelOuter-04393);
     case 4394:
       return VUID_WRAP(VUID-TessLevelInner-TessLevelInner-04394);
+    case 4395:
+      return VUID_WRAP(VUID-TessLevelInner-TessLevelInner-04395);
+    case 4396:
+      return VUID_WRAP(VUID-TessLevelInner-TessLevelInner-04396);
     case 4397:
       return VUID_WRAP(VUID-TessLevelInner-TessLevelInner-04397);
     case 4398:
@@ -1551,6 +1575,8 @@ std::string ValidationState_t::VkErrorID(uint32_t id,
       return VUID_WRAP(VUID-ViewIndex-ViewIndex-04403);
     case 4404:
       return VUID_WRAP(VUID-ViewportIndex-ViewportIndex-04404);
+    case 4405:
+      return VUID_WRAP(VUID-ViewportIndex-ViewportIndex-04405);
     case 4406:
       return VUID_WRAP(VUID-ViewportIndex-ViewportIndex-04406);
     case 4407:

+ 1 - 1
3rdparty/spirv-tools/utils/git-sync-deps

@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 # Copyright 2014 Google Inc.
 #
 # Redistribution and use in source and binary forms, with or without