HLSL: iomapper: Fix #914. Tolerate user aliasing of bindings.
authorJohn Kessenich <cepheus@frii.com>
Fri, 2 Jun 2017 00:16:33 +0000 (18:16 -0600)
committerJohn Kessenich <cepheus@frii.com>
Fri, 2 Jun 2017 00:16:33 +0000 (18:16 -0600)
Because it is valid in HLSL to alias bindings:
A) remove validation that aliasing is not done
B) make the algorithms tolerate aliasing

Test/baseResults/spv.ssboAlias.frag.out [new file with mode: 0755]
Test/spv.ssboAlias.frag [new file with mode: 0644]
glslang/MachineIndependent/iomapper.cpp
gtests/Spv.FromFile.cpp

diff --git a/Test/baseResults/spv.ssboAlias.frag.out b/Test/baseResults/spv.ssboAlias.frag.out
new file mode 100755 (executable)
index 0000000..22915d7
--- /dev/null
@@ -0,0 +1,88 @@
+spv.ssboAlias.frag
+// Module Version 10000
+// Generated by (magic number): 80001
+// Id's are bound by 46
+
+                              Capability Shader
+               1:             ExtInstImport  "GLSL.std.450"
+                              MemoryModel Logical GLSL450
+                              EntryPoint Fragment 4  "main" 43
+                              ExecutionMode 4 OriginUpperLeft
+                              Source HLSL 500
+                              Name 4  "main"
+                              Name 9  "@main("
+                              Name 13  "Buf1"
+                              MemberName 13(Buf1) 0  "@data"
+                              Name 15  "Buf1"
+                              Name 18  "Buf1@count"
+                              MemberName 18(Buf1@count) 0  "@count"
+                              Name 20  "Buf1@count"
+                              Name 30  "Buf2"
+                              Name 31  "Buf2@count"
+                              Name 43  "@entryPointOutput"
+                              Name 45  "Buf3"
+                              Decorate 12 ArrayStride 4
+                              MemberDecorate 13(Buf1) 0 Offset 0
+                              Decorate 13(Buf1) BufferBlock
+                              Decorate 15(Buf1) DescriptorSet 0
+                              Decorate 15(Buf1) Binding 84
+                              MemberDecorate 18(Buf1@count) 0 Offset 0
+                              Decorate 18(Buf1@count) BufferBlock
+                              Decorate 20(Buf1@count) DescriptorSet 0
+                              Decorate 20(Buf1@count) Binding 83
+                              Decorate 30(Buf2) DescriptorSet 0
+                              Decorate 30(Buf2) Binding 85
+                              Decorate 31(Buf2@count) DescriptorSet 0
+                              Decorate 31(Buf2@count) Binding 86
+                              Decorate 43(@entryPointOutput) Location 0
+                              Decorate 45(Buf3) DescriptorSet 0
+                              Decorate 45(Buf3) Binding 84
+               2:             TypeVoid
+               3:             TypeFunction 2
+               6:             TypeFloat 32
+               7:             TypeVector 6(float) 4
+               8:             TypeFunction 7(fvec4)
+              11:             TypeInt 32 0
+              12:             TypeRuntimeArray 11(int)
+        13(Buf1):             TypeStruct 12
+              14:             TypePointer Uniform 13(Buf1)
+        15(Buf1):     14(ptr) Variable Uniform
+              16:             TypeInt 32 1
+              17:     16(int) Constant 0
+  18(Buf1@count):             TypeStruct 16(int)
+              19:             TypePointer Uniform 18(Buf1@count)
+  20(Buf1@count):     19(ptr) Variable Uniform
+              21:             TypePointer Uniform 16(int)
+              23:     16(int) Constant 1
+              24:     11(int) Constant 1
+              25:     11(int) Constant 0
+              27:     11(int) Constant 10
+              28:             TypePointer Uniform 11(int)
+        30(Buf2):     14(ptr) Variable Uniform
+  31(Buf2@count):     19(ptr) Variable Uniform
+              34:     11(int) Constant 20
+              36:    6(float) Constant 1065353216
+              37:    6(float) Constant 1077936128
+              38:    6(float) Constant 1084227584
+              39:    7(fvec4) ConstantComposite 36 37 38 36
+              42:             TypePointer Output 7(fvec4)
+43(@entryPointOutput):     42(ptr) Variable Output
+        45(Buf3):     14(ptr) Variable Uniform
+         4(main):           2 Function None 3
+               5:             Label
+              44:    7(fvec4) FunctionCall 9(@main()
+                              Store 43(@entryPointOutput) 44
+                              Return
+                              FunctionEnd
+       9(@main():    7(fvec4) Function None 8
+              10:             Label
+              22:     21(ptr) AccessChain 20(Buf1@count) 17
+              26:     11(int) AtomicIAdd 22 24 25 23
+              29:     28(ptr) AccessChain 15(Buf1) 17 26
+                              Store 29 27
+              32:     21(ptr) AccessChain 31(Buf2@count) 17
+              33:     11(int) AtomicIAdd 32 24 25 23
+              35:     28(ptr) AccessChain 30(Buf2) 17 33
+                              Store 35 34
+                              ReturnValue 39
+                              FunctionEnd
diff --git a/Test/spv.ssboAlias.frag b/Test/spv.ssboAlias.frag
new file mode 100644 (file)
index 0000000..ed3d3e7
--- /dev/null
@@ -0,0 +1,10 @@
+AppendStructuredBuffer<uint> Buf1 : register(u1);
+AppendStructuredBuffer<uint> Buf2 : register(u2);
+AppendStructuredBuffer<uint> Buf3 : register(u1);
+
+float4 main() : SV_Target
+{
+       Buf1.Append(10u);
+       Buf2.Append(20u);
+       return float4(1.0, 3.0, 5.0, 1.0);
+}
\ No newline at end of file
index 26772dd..e5991ff 100644 (file)
@@ -374,7 +374,12 @@ struct TDefaultIoResolverBase : public glslang::TIoMapResolver
     int reserveSlot(int set, int slot)
     {
         TSlotSet::iterator at = findSlot(set, slot);
-        slots[set].insert(at, slot);
+
+        // tolerate aliasing, by not double-recording aliases
+        // (policy about appropriateness of the alias is higher up)
+        if (at == slots[set].end() || *at != slot)
+            slots[set].insert(at, slot);
+
         return slot;
     }
 
@@ -468,24 +473,6 @@ struct TDefaultIoResolver : public TDefaultIoResolverBase
 {
     bool validateBinding(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& type, bool /*is_live*/) override
     {
-        if (type.getQualifier().hasBinding()) {
-            const int set = getLayoutSet(type);
-
-            if (isImageType(type))
-                return checkEmpty(set, baseImageBinding + type.getQualifier().layoutBinding);
-
-            if (isTextureType(type))
-                return checkEmpty(set, baseTextureBinding + type.getQualifier().layoutBinding);
-
-            if (isSsboType(type))
-                return checkEmpty(set, baseSsboBinding + type.getQualifier().layoutBinding);
-
-            if (isSamplerType(type))
-                return checkEmpty(set, baseSamplerBinding + type.getQualifier().layoutBinding);
-
-            if (isUboType(type))
-                return checkEmpty(set, baseUboBinding + type.getQualifier().layoutBinding);
-        }
         return true;
     }
 
@@ -496,7 +483,7 @@ struct TDefaultIoResolver : public TDefaultIoResolverBase
         if (type.getQualifier().hasBinding()) {
             if (isImageType(type))
                 return reserveSlot(set, baseImageBinding + type.getQualifier().layoutBinding);
-                
+
             if (isTextureType(type))
                 return reserveSlot(set, baseTextureBinding + type.getQualifier().layoutBinding);
 
@@ -588,21 +575,6 @@ struct TDefaultHlslIoResolver : public TDefaultIoResolverBase
 {
     bool validateBinding(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& type, bool /*is_live*/) override
     {
-        if (type.getQualifier().hasBinding()) {
-            const int set = getLayoutSet(type);
-
-            if (isUavType(type))
-                return checkEmpty(set, baseUavBinding + type.getQualifier().layoutBinding);
-
-            if (isSrvType(type))
-                return checkEmpty(set, baseTextureBinding + type.getQualifier().layoutBinding);
-
-            if (isSamplerType(type))
-                return checkEmpty(set, baseSamplerBinding + type.getQualifier().layoutBinding);
-
-            if (isUboType(type))
-                return checkEmpty(set, baseUboBinding + type.getQualifier().layoutBinding);
-        }
         return true;
     }
 
index b551d64..1552b95 100644 (file)
@@ -330,6 +330,7 @@ INSTANTIATE_TEST_CASE_P(
         { "spv.register.autoassign-2.frag", "main", 5, 10, 0, 15, 30, true, true },
         { "spv.buffer.autoassign.frag", "main", 5, 10, 0, 15, 30, true, true },
         { "spv.ssbo.autoassign.frag", "main", 5, 10, 0, 15, 30, true, true },
+        { "spv.ssboAlias.frag", "main", 0, 0, 0, 0, 83, true, false },
         { "spv.rw.autoassign.frag", "main", 5, 10, 20, 15, 30, true, true },
         { "spv.register.autoassign.rangetest.frag", "main", 
                 glslang::TQualifier::layoutBindingEnd-2,