Răsfoiți Sursa

[spirv] Add option to ignore emulated feature warnings (#1522)

Some HLSL features does not have direct mapping to SPIR-V, instead
we emulate them using lots of SPIR-V instructions. Because they
can cause performance hit, the compiler warns by default. This
commit add an option, -Wno-vk-emulated-features, to let developers
turn off such warnings.
Lei Zhang 7 ani în urmă
părinte
comite
14bcc3f6a7

+ 2 - 0
include/dxc/Support/HLSLOptions.td

@@ -267,6 +267,8 @@ def fspv_target_env_EQ : Joined<["-"], "fspv-target-env=">, Group<spirv_Group>,
   HelpText<"Specify the target environment: vulkan1.0 (default) or vulkan1.1">;
 def Wno_vk_ignored_features : Joined<["-"], "Wno-vk-ignored-features">, Group<spirv_Group>, Flags<[CoreOption, DriverOption, HelpHidden]>,
   HelpText<"Do not emit warnings for ingored features resulting from no Vulkan support">;
+def Wno_vk_emulated_features : Joined<["-"], "Wno-vk-emulated-features">, Group<spirv_Group>, Flags<[CoreOption, DriverOption, HelpHidden]>,
+  HelpText<"Do not emit warnings for emulated features resulting from no direct mapping">;
 def Oconfig : CommaJoined<["-"], "Oconfig=">, Group<spirv_Group>, Flags<[CoreOption]>,
   HelpText<"Specify a comma-separated list of SPIRV-Tools passes to customize optimization configuration (see http://khr.io/hlsl2spirv#optimization)">;
 // SPIRV Change Ends

+ 1 - 0
include/dxc/Support/SPIRVOptions.h

@@ -46,6 +46,7 @@ struct SpirvCodeGenOptions {
   bool enableReflect;
   bool invertY; // Additive inverse
   bool invertW; // Multiplicative inverse
+  bool noWarnEmulatedFeatures;
   bool noWarnIgnoredFeatures;
   bool useDxLayout;
   bool useGlLayout;

+ 2 - 0
lib/DxcSupport/HLSLOptions.cpp

@@ -563,6 +563,7 @@ int ReadDxcOpts(const OptTable *optionTable, unsigned flagsToInclude,
   opts.SpirvOptions.useDxLayout = Args.hasFlag(OPT_fvk_use_dx_layout, OPT_INVALID, false);
   opts.SpirvOptions.enableReflect = Args.hasFlag(OPT_fspv_reflect, OPT_INVALID, false);
   opts.SpirvOptions.noWarnIgnoredFeatures = Args.hasFlag(OPT_Wno_vk_ignored_features, OPT_INVALID, false);
+  opts.SpirvOptions.noWarnEmulatedFeatures = Args.hasFlag(OPT_Wno_vk_emulated_features, OPT_INVALID, false);
 
   if (!handleVkShiftArgs(Args, OPT_fvk_b_shift, "b", &opts.SpirvOptions.bShift, errors) ||
       !handleVkShiftArgs(Args, OPT_fvk_t_shift, "t", &opts.SpirvOptions.tShift, errors) ||
@@ -637,6 +638,7 @@ int ReadDxcOpts(const OptTable *optionTable, unsigned flagsToInclude,
       Args.hasFlag(OPT_fvk_use_dx_layout, OPT_INVALID, false) ||
       Args.hasFlag(OPT_fspv_reflect, OPT_INVALID, false) ||
       Args.hasFlag(OPT_Wno_vk_ignored_features, OPT_INVALID, false) ||
+      Args.hasFlag(OPT_Wno_vk_emulated_features, OPT_INVALID, false) ||
       !Args.getLastArgValue(OPT_fvk_stage_io_order_EQ).empty() ||
       !Args.getLastArgValue(OPT_fspv_debug_EQ).empty() ||
       !Args.getLastArgValue(OPT_fspv_extension_EQ).empty() ||

+ 22 - 13
tools/clang/lib/SPIRV/SPIRVEmitter.cpp

@@ -1412,8 +1412,10 @@ spv::LoopControlMask SPIRVEmitter::translateLoopAttribute(const Stmt *stmt,
   case attr::HLSLUnroll:
     return spv::LoopControlMask::Unroll;
   case attr::HLSLAllowUAVCondition:
-    emitWarning("unsupported allow_uav_condition attribute ignored",
-                stmt->getLocStart());
+    if (!spirvOptions.noWarnIgnoredFeatures) {
+      emitWarning("unsupported allow_uav_condition attribute ignored",
+                  stmt->getLocStart());
+    }
     break;
   default:
     llvm_unreachable("found unknown loop attribute");
@@ -1807,9 +1809,11 @@ void SPIRVEmitter::doIfStmt(const IfStmt *ifStmt,
       selectionControl = spv::SelectionControlMask::Flatten;
       break;
     default:
-      emitWarning("unknown if statement attribute '%0' ignored",
-                  attribute->getLocation())
-          << attribute->getSpelling();
+      if (!spirvOptions.noWarnIgnoredFeatures) {
+        emitWarning("unknown if statement attribute '%0' ignored",
+                    attribute->getLocation())
+            << attribute->getSpelling();
+      }
       break;
     }
   }
@@ -1958,10 +1962,12 @@ void SPIRVEmitter::doSwitchStmt(const SwitchStmt *switchStmt,
       (attrs.empty() || isAttrForceCase) &&
       allSwitchCasesAreIntegerLiterals(switchStmt->getBody());
 
-  if (isAttrForceCase && !canUseSpirvOpSwitch)
+  if (isAttrForceCase && !canUseSpirvOpSwitch &&
+      !spirvOptions.noWarnIgnoredFeatures) {
     emitWarning("ignored 'forcecase' attribute for the switch statement "
                 "since one or more case values are not integer literals",
                 switchStmt->getLocStart());
+  }
 
   if (canUseSpirvOpSwitch)
     processSwitchStmtUsingSpirvOpSwitch(switchStmt);
@@ -2829,10 +2835,12 @@ uint32_t SPIRVEmitter::processGetSamplePosition(const CXXMemberCallExpr *expr) {
   const auto sampleCount = theBuilder.createUnaryOp(
       spv::Op::OpImageQuerySamples, theBuilder.getUint32Type(),
       loadIfGLValue(object));
-  emitWarning(
-      "GetSamplePosition only supports standard sample settings with 1, 2, 4, "
-      "8, or 16 samples and will return float2(0, 0) for other cases",
-      expr->getCallee()->getExprLoc());
+  if (!spirvOptions.noWarnEmulatedFeatures)
+    emitWarning("GetSamplePosition is emulated using many SPIR-V instructions "
+                "due to lack of direct SPIR-V equivalent, so it only supports "
+                "standard sample settings with 1, 2, 4, 8, or 16 samples and "
+                "will return float2(0, 0) for other cases",
+                expr->getCallee()->getExprLoc());
   return emitGetSamplePosition(sampleCount, doExpr(expr->getArg(0)));
 }
 
@@ -6915,9 +6923,10 @@ SPIRVEmitter::processIntrinsicNonUniformResourceIndex(const CallExpr *expr) {
 }
 
 uint32_t SPIRVEmitter::processIntrinsicMsad4(const CallExpr *callExpr) {
-  emitWarning("msad4 intrinsic function is emulated using many SPIR-V "
-              "instructions due to lack of direct SPIR-V equivalent",
-              callExpr->getExprLoc());
+  if (!spirvOptions.noWarnEmulatedFeatures)
+    emitWarning("msad4 intrinsic function is emulated using many SPIR-V "
+                "instructions due to lack of direct SPIR-V equivalent",
+                callExpr->getExprLoc());
 
   // Compares a 4-byte reference value and an 8-byte source value and
   // accumulates a vector of 4 sums. Each sum corresponds to the masked sum