Browse Source

restore compatibility with dxil.dll 1.0 validator for typed uav loads (#363)

Add an optional extended description…
Marcelo Lopez Ruiz 8 years ago
parent
commit
667e9fecbb
2 changed files with 52 additions and 1 deletions
  1. 48 1
      lib/HLSL/DxilModule.cpp
  2. 4 0
      tools/clang/unittests/HLSL/CompilerTest.cpp

+ 48 - 1
lib/HLSL/DxilModule.cpp

@@ -337,7 +337,17 @@ void DxilModule::CollectShaderFlags(ShaderFlags &Flags) {
   bool hasMSAD = false;
   bool hasMSAD = false;
   bool hasInnerCoverage = false;
   bool hasInnerCoverage = false;
   bool hasViewID = false;
   bool hasViewID = false;
-  bool hasMulticomponentUAVLoads = ModuleHasMulticomponentUAVLoads();
+  bool hasMulticomponentUAVLoads = false;
+  bool hasMulticomponentUAVLoadsBackCompat = false;
+
+  // Try to maintain compatibility with a v1.0 validator if that's what we have.
+  {
+    unsigned valMajor, valMinor;
+    GetValidatorVersion(valMajor, valMinor);
+    hasMulticomponentUAVLoadsBackCompat = valMajor <= 1 && valMinor == 0;
+  }
+  if (!hasMulticomponentUAVLoadsBackCompat)
+    hasMulticomponentUAVLoads = ModuleHasMulticomponentUAVLoads();
 
 
   Type *int16Ty = Type::getInt16Ty(GetCtx());
   Type *int16Ty = Type::getInt16Ty(GetCtx());
   Type *int64Ty = Type::getInt64Ty(GetCtx());
   Type *int64Ty = Type::getInt64Ty(GetCtx());
@@ -402,6 +412,43 @@ void DxilModule::CollectShaderFlags(ShaderFlags &Flags) {
           case DXIL::OpCode::Msad:
           case DXIL::OpCode::Msad:
             hasMSAD = true;
             hasMSAD = true;
             break;
             break;
+          case DXIL::OpCode::BufferLoad:
+          case DXIL::OpCode::TextureLoad: {
+            if (hasMulticomponentUAVLoads) continue;
+            if (!hasMulticomponentUAVLoadsBackCompat) continue;
+            // This is the old-style computation (overestimating requirements).
+            Value *resHandle = CI->getArgOperand(DXIL::OperandIndex::kBufferStoreHandleOpIdx);
+            CallInst *handleCall = cast<CallInst>(resHandle);
+
+            if (ConstantInt *resClassArg =
+              dyn_cast<ConstantInt>(handleCall->getArgOperand(
+                DXIL::OperandIndex::kCreateHandleResClassOpIdx))) {
+              DXIL::ResourceClass resClass = static_cast<DXIL::ResourceClass>(
+                resClassArg->getLimitedValue());
+              if (resClass == DXIL::ResourceClass::UAV) {
+                // For DXIL, all uav load is multi component load.
+                hasMulticomponentUAVLoads = true;
+              }
+            }
+            else if (PHINode *resClassPhi = dyn_cast<
+              PHINode>(handleCall->getArgOperand(
+                DXIL::OperandIndex::kCreateHandleResClassOpIdx))) {
+              unsigned numOperands = resClassPhi->getNumOperands();
+              for (unsigned i = 0; i < numOperands; i++) {
+                if (ConstantInt *resClassArg = dyn_cast<ConstantInt>(
+                  resClassPhi->getIncomingValue(i))) {
+                  DXIL::ResourceClass resClass =
+                    static_cast<DXIL::ResourceClass>(
+                      resClassArg->getLimitedValue());
+                  if (resClass == DXIL::ResourceClass::UAV) {
+                    // For DXIL, all uav load is multi component load.
+                    hasMulticomponentUAVLoads = true;
+                    break;
+                  }
+                }
+              }
+            }
+          } break;
           case DXIL::OpCode::Fma:
           case DXIL::OpCode::Fma:
             hasDoubleExtension |= isDouble;
             hasDoubleExtension |= isDouble;
             break;
             break;

+ 4 - 0
tools/clang/unittests/HLSL/CompilerTest.cpp

@@ -2955,6 +2955,7 @@ TEST_F(CompilerTest, CodeGenMultiUAVLoad1) {
 }
 }
 
 
 TEST_F(CompilerTest, CodeGenMultiUAVLoad2) {
 TEST_F(CompilerTest, CodeGenMultiUAVLoad2) {
+  if (m_ver.SkipDxil_1_1_Test()) return;
   CodeGenTestCheck(L"..\\CodeGenHLSL\\multiUAVLoad2.hlsl");
   CodeGenTestCheck(L"..\\CodeGenHLSL\\multiUAVLoad2.hlsl");
 }
 }
 
 
@@ -2963,6 +2964,7 @@ TEST_F(CompilerTest, CodeGenMultiUAVLoad3) {
 }
 }
 
 
 TEST_F(CompilerTest, CodeGenMultiUAVLoad4) {
 TEST_F(CompilerTest, CodeGenMultiUAVLoad4) {
+  if (m_ver.SkipDxil_1_1_Test()) return;
   CodeGenTestCheck(L"..\\CodeGenHLSL\\multiUAVLoad4.hlsl");
   CodeGenTestCheck(L"..\\CodeGenHLSL\\multiUAVLoad4.hlsl");
 }
 }
 
 
@@ -2971,6 +2973,7 @@ TEST_F(CompilerTest, CodeGenMultiUAVLoad5) {
 }
 }
 
 
 TEST_F(CompilerTest, CodeGenMultiUAVLoad6) {
 TEST_F(CompilerTest, CodeGenMultiUAVLoad6) {
+  if (m_ver.SkipDxil_1_1_Test()) return;
   CodeGenTestCheck(L"..\\CodeGenHLSL\\multiUAVLoad6.hlsl");
   CodeGenTestCheck(L"..\\CodeGenHLSL\\multiUAVLoad6.hlsl");
 }
 }
 
 
@@ -3473,6 +3476,7 @@ TEST_F(CompilerTest, CodeGenUint64_1) {
 }
 }
 
 
 TEST_F(CompilerTest, CodeGenUint64_2) {
 TEST_F(CompilerTest, CodeGenUint64_2) {
+  if (m_ver.SkipDxil_1_1_Test()) return;
   CodeGenTestCheck(L"..\\CodeGenHLSL\\uint64_2.hlsl");
   CodeGenTestCheck(L"..\\CodeGenHLSL\\uint64_2.hlsl");
 }
 }