HLSL: fix handling of uniform qualifier in entry point parameters (#2254)
authorrdb <rdb@users.noreply.github.com>
Tue, 2 Jun 2020 06:30:07 +0000 (08:30 +0200)
committerGitHub <noreply@github.com>
Tue, 2 Jun 2020 06:30:07 +0000 (00:30 -0600)
* HLSL: Fix handling of uniforms in entry point parameters

* HLSL: fix handling of "uniform in"

* Tests: Update baseResults of hlsl.function.frag.out for #2254

* HLSL: fix uniforms in function parameters for opaque types

SPIRV/GlslangToSpv.cpp
Test/baseResults/hlsl.function.frag.out
hlsl/hlslGrammar.cpp
hlsl/hlslParseHelper.cpp

index 92cce81..e374020 100644 (file)
@@ -4389,8 +4389,10 @@ bool TGlslangToSpvTraverser::writableParam(glslang::TStorageQualifier qualifier)
     assert(qualifier == glslang::EvqIn ||
            qualifier == glslang::EvqOut ||
            qualifier == glslang::EvqInOut ||
+           qualifier == glslang::EvqUniform ||
            qualifier == glslang::EvqConstReadOnly);
-    return qualifier != glslang::EvqConstReadOnly;
+    return qualifier != glslang::EvqConstReadOnly &&
+           qualifier != glslang::EvqUniform;
 }
 
 // Is parameter pass-by-original?
index 00b882d..faa3147 100644 (file)
@@ -26,14 +26,14 @@ ERROR: node is still EOpNull!
 0:12  Function Definition: fun4(u1;u1; ( temp 4-component vector of float)
 0:12    Function Parameters: 
 0:12      'id1' ( in uint)
-0:12      'id2' ( in uint)
+0:12      'id2' ( uniform uint)
 0:?     Sequence
 0:13      Branch: Return with expression
 0:13        Construct vec4 ( temp 4-component vector of float)
 0:13          Convert uint to float ( temp float)
 0:13            component-wise multiply ( temp uint)
 0:13              'id1' ( in uint)
-0:13              'id2' ( in uint)
+0:13              'id2' ( uniform uint)
 0:17  Function Definition: fun1(i1; ( temp 4-component vector of float)
 0:17    Function Parameters: 
 0:17      'index' ( in int)
@@ -84,14 +84,14 @@ ERROR: node is still EOpNull!
 0:12  Function Definition: fun4(u1;u1; ( temp 4-component vector of float)
 0:12    Function Parameters: 
 0:12      'id1' ( in uint)
-0:12      'id2' ( in uint)
+0:12      'id2' ( uniform uint)
 0:?     Sequence
 0:13      Branch: Return with expression
 0:13        Construct vec4 ( temp 4-component vector of float)
 0:13          Convert uint to float ( temp float)
 0:13            component-wise multiply ( temp uint)
 0:13              'id1' ( in uint)
-0:13              'id2' ( in uint)
+0:13              'id2' ( uniform uint)
 0:17  Function Definition: fun1(i1; ( temp 4-component vector of float)
 0:17    Function Parameters: 
 0:17      'index' ( in int)
index 47ced29..e633767 100644 (file)
@@ -697,7 +697,9 @@ bool HlslGrammar::acceptQualifier(TQualifier& qualifier)
             qualifier.noContraction = true;
             break;
         case EHTokIn:
-            qualifier.storage = (qualifier.storage == EvqOut) ? EvqInOut : EvqIn;
+            if (qualifier.storage != EvqUniform) {
+                qualifier.storage = (qualifier.storage == EvqOut) ? EvqInOut : EvqIn;
+            }
             break;
         case EHTokOut:
             qualifier.storage = (qualifier.storage == EvqIn) ? EvqInOut : EvqOut;
index 87ca4c8..58c8b23 100755 (executable)
@@ -2111,6 +2111,23 @@ TIntermNode* HlslParseContext::transformEntryPoint(const TSourceLoc& loc, TFunct
                 makeVariableInOut(*(*it));
     }
 
+    // Add uniform parameters to the $Global uniform block.
+    TVector<TVariable*> opaque_uniforms;
+    for (int i = 0; i < userFunction.getParamCount(); i++) {
+        TType& paramType = *userFunction[i].type;
+        TString& paramName = *userFunction[i].name;
+        if (paramType.getQualifier().storage == EvqUniform) {
+            if (!paramType.containsOpaque()) {
+                // Add it to the global uniform block.
+                growGlobalUniformBlock(loc, paramType, paramName);
+            } else {
+                // Declare it as a separate variable.
+                TVariable *var = makeInternalVariable(paramName.c_str(), paramType);
+                opaque_uniforms.push_back(var);
+            }
+        }
+    }
+
     // Synthesize the call
 
     pushScope(); // matches the one in handleFunctionBody()
@@ -2131,6 +2148,7 @@ TIntermNode* HlslParseContext::transformEntryPoint(const TSourceLoc& loc, TFunct
     TVector<TVariable*> argVars;
     TIntermAggregate* synthBody = new TIntermAggregate();
     auto inputIt = inputs.begin();
+    auto opaqueUniformIt = opaque_uniforms.begin();
     TIntermTyped* callingArgs = nullptr;
 
     for (int i = 0; i < userFunction.getParamCount(); i++) {
@@ -2149,6 +2167,17 @@ TIntermNode* HlslParseContext::transformEntryPoint(const TSourceLoc& loc, TFunct
                                                                intermediate.addSymbol(**inputIt)));
             inputIt++;
         }
+        if (param.type->getQualifier().storage == EvqUniform) {
+            if (!param.type->containsOpaque()) {
+                // Look it up in the $Global uniform block.
+                intermediate.growAggregate(synthBody, handleAssign(loc, EOpAssign, arg,
+                                                                   handleVariable(loc, param.name)));
+            } else {
+                intermediate.growAggregate(synthBody, handleAssign(loc, EOpAssign, arg,
+                                                                   intermediate.addSymbol(**opaqueUniformIt)));
+                ++opaqueUniformIt;
+            }
+        }
     }
 
     // Call
@@ -6914,7 +6943,6 @@ void HlslParseContext::paramFix(TType& type)
         type.getQualifier().storage = EvqConstReadOnly;
         break;
     case EvqGlobal:
-    case EvqUniform:
     case EvqTemporary:
         type.getQualifier().storage = EvqIn;
         break;