HLSL: Handle "fake" entry points, by undoing their built-in variable declarations.
authorJohn Kessenich <cepheus@frii.com>
Sat, 3 Sep 2016 02:23:27 +0000 (20:23 -0600)
committerJohn Kessenich <cepheus@frii.com>
Sat, 3 Sep 2016 02:24:07 +0000 (20:24 -0600)
Test/baseResults/hlsl.multiEntry.vert.out [new file with mode: 0755]
Test/hlsl.multiEntry.vert [new file with mode: 0755]
glslang/Include/revision.h
gtests/Hlsl.FromFile.cpp
hlsl/hlslParseHelper.cpp
hlsl/hlslParseHelper.h

diff --git a/Test/baseResults/hlsl.multiEntry.vert.out b/Test/baseResults/hlsl.multiEntry.vert.out
new file mode 100755 (executable)
index 0000000..8aa302c
--- /dev/null
@@ -0,0 +1,107 @@
+hlsl.multiEntry.vert
+Shader version: 450
+0:? Sequence
+0:4  Function Definition: FakeEntrypoint(u1; (global 4-component vector of float)
+0:4    Function Parameters: 
+0:4      'Index' (in uint)
+0:?     Sequence
+0:5      Branch: Return with expression
+0:5        textureFetch (global 4-component vector of float)
+0:5          'Position' (uniform samplerBuffer)
+0:5          Convert uint to int (temp int)
+0:5            'Index' (in uint)
+0:9  Function Definition: RealEntrypoint(u1; (global 4-component vector of float Position)
+0:9    Function Parameters: 
+0:9      'Index' (in uint VertexIndex)
+0:?     Sequence
+0:10      Sequence
+0:10        move second child to first child (temp 4-component vector of float)
+0:?           '@entryPointOutput' (out 4-component vector of float Position)
+0:10          Function Call: FakeEntrypoint(u1; (global 4-component vector of float)
+0:10            'Index' (in uint VertexIndex)
+0:10        Branch: Return
+0:?   Linker Objects
+0:?     'Position' (uniform samplerBuffer)
+
+
+Linked vertex stage:
+
+
+Shader version: 450
+0:? Sequence
+0:4  Function Definition: FakeEntrypoint(u1; (global 4-component vector of float)
+0:4    Function Parameters: 
+0:4      'Index' (in uint)
+0:?     Sequence
+0:5      Branch: Return with expression
+0:5        textureFetch (global 4-component vector of float)
+0:5          'Position' (uniform samplerBuffer)
+0:5          Convert uint to int (temp int)
+0:5            'Index' (in uint)
+0:9  Function Definition: RealEntrypoint(u1; (global 4-component vector of float Position)
+0:9    Function Parameters: 
+0:9      'Index' (in uint VertexIndex)
+0:?     Sequence
+0:10      Sequence
+0:10        move second child to first child (temp 4-component vector of float)
+0:?           '@entryPointOutput' (out 4-component vector of float Position)
+0:10          Function Call: FakeEntrypoint(u1; (global 4-component vector of float)
+0:10            'Index' (in uint VertexIndex)
+0:10        Branch: Return
+0:?   Linker Objects
+0:?     'Position' (uniform samplerBuffer)
+
+// Module Version 10000
+// Generated by (magic number): 80001
+// Id's are bound by 34
+
+                              Capability Shader
+                              Capability SampledBuffer
+               1:             ExtInstImport  "GLSL.std.450"
+                              MemoryModel Logical GLSL450
+                              EntryPoint Vertex 4  "RealEntrypoint" 27 29
+                              Name 4  "RealEntrypoint"
+                              Name 12  "FakeEntrypoint(u1;"
+                              Name 11  "Index"
+                              Name 17  "Position"
+                              Name 27  "@entryPointOutput"
+                              Name 29  "Index"
+                              Name 30  "param"
+                              Decorate 17(Position) DescriptorSet 0
+                              Decorate 27(@entryPointOutput) BuiltIn Position
+                              Decorate 29(Index) BuiltIn VertexIndex
+               2:             TypeVoid
+               3:             TypeFunction 2
+               6:             TypeInt 32 0
+               7:             TypePointer Function 6(int)
+               8:             TypeFloat 32
+               9:             TypeVector 8(float) 4
+              10:             TypeFunction 9(fvec4) 7(ptr)
+              14:             TypeImage 8(float) Buffer sampled format:Unknown
+              15:             TypeSampledImage 14
+              16:             TypePointer UniformConstant 15
+    17(Position):     16(ptr) Variable UniformConstant
+              20:             TypeInt 32 1
+              26:             TypePointer Output 9(fvec4)
+27(@entryPointOutput):     26(ptr) Variable Output
+              28:             TypePointer Input 6(int)
+       29(Index):     28(ptr) Variable Input
+4(RealEntrypoint):           2 Function None 3
+               5:             Label
+       30(param):      7(ptr) Variable Function
+              31:      6(int) Load 29(Index)
+                              Store 30(param) 31
+              32:    9(fvec4) FunctionCall 12(FakeEntrypoint(u1;) 30(param)
+                              Store 27(@entryPointOutput) 32
+                              Return
+                              FunctionEnd
+12(FakeEntrypoint(u1;):    9(fvec4) Function None 10
+       11(Index):      7(ptr) FunctionParameter
+              13:             Label
+              18:          15 Load 17(Position)
+              19:      6(int) Load 11(Index)
+              21:     20(int) Bitcast 19
+              22:          14 Image 18
+              23:    9(fvec4) ImageFetch 22 21
+                              ReturnValue 23
+                              FunctionEnd
diff --git a/Test/hlsl.multiEntry.vert b/Test/hlsl.multiEntry.vert
new file mode 100755 (executable)
index 0000000..d155c26
--- /dev/null
@@ -0,0 +1,11 @@
+Buffer<float4> Position;\r
+\r
+float4 FakeEntrypoint(uint Index : SV_VERTEXID) : SV_POSITION\r
+{ \r
+    return Position.Load(Index);\r
+}\r
+\r
+float4 RealEntrypoint(uint Index : SV_VERTEXID) : SV_POSITION\r
+{ \r
+    return FakeEntrypoint(Index);\r
+}
\ No newline at end of file
index be71662..86b4ab8 100644 (file)
@@ -2,5 +2,5 @@
 // For the version, it uses the latest git tag followed by the number of commits.
 // For the date, it uses the current date (when then script is run).
 
-#define GLSLANG_REVISION "Overload400-PrecQual.1463"
+#define GLSLANG_REVISION "Overload400-PrecQual.1464"
 #define GLSLANG_DATE "02-Sep-2016"
index 9fb3840..0ebc17e 100644 (file)
@@ -123,6 +123,7 @@ INSTANTIATE_TEST_CASE_P(
         {"hlsl.load.buffer.dx10.frag", "main"},
         {"hlsl.load.offset.dx10.frag", "main"},
         {"hlsl.load.offsetarray.dx10.frag", "main"},
+        {"hlsl.multiEntry.vert", "RealEntrypoint"},
         {"hlsl.numericsuffixes.frag", "main"},
         {"hlsl.overload.frag", "PixelShaderFunction"},
         {"hlsl.pp.line.frag", "main"},
index 5f4d8c5..f74591c 100755 (executable)
@@ -755,6 +755,8 @@ TIntermAggregate* HlslParseContext::handleFunctionDefinition(const TSourceLoc& l
     inEntrypoint = (function.getName() == intermediate.getEntryPoint().c_str());
     if (inEntrypoint)
         remapEntrypointIO(function);
+    else
+        remapNonEntrypointIO(function);
 
     //
     // New symbol table scope for body of function plus its arguments
@@ -864,6 +866,21 @@ void HlslParseContext::remapEntrypointIO(TFunction& function)
     }
 }
 
+// An HLSL function that looks like an entry point, but is not,
+// declares entry point IO built-ins, but these have to be undone.
+void HlslParseContext::remapNonEntrypointIO(TFunction& function)
+{
+    const auto remapBuiltInType = [&](TType& type) { type.getQualifier().builtIn = EbvNone; };
+
+    // return value
+    if (function.getType().getBasicType() != EbtVoid)
+        remapBuiltInType(function.getWritableType());
+
+    // parameters
+    for (int i = 0; i < function.getParamCount(); i++)
+        remapBuiltInType(*function[i].type);
+}
+
 // Handle function returns, including type conversions to the function return type
 // if necessary.
 TIntermNode* HlslParseContext::handleReturnValue(const TSourceLoc& loc, TIntermTyped* value)
index 77d8157..8e1a683 100755 (executable)
@@ -87,6 +87,7 @@ public:
     TIntermAggregate* handleFunctionDefinition(const TSourceLoc&, TFunction&);
     void handleFunctionBody(const TSourceLoc&, TFunction&, TIntermNode* functionBody, TIntermNode*& node);
     void remapEntrypointIO(TFunction& function);
+    void remapNonEntrypointIO(TFunction& function);
     TIntermNode* handleReturnValue(const TSourceLoc&, TIntermTyped*);
     void handleFunctionArgument(TFunction*, TIntermTyped*& arguments, TIntermTyped* newArg);
     TIntermTyped* handleFunctionCall(const TSourceLoc&, TFunction*, TIntermNode*);