diff --git a/Test/baseResults/hlsl.structbuffer.append.fn.frag.out b/Test/baseResults/hlsl.structbuffer.append.fn.frag.out new file mode 100644 index 000000000..487247824 --- /dev/null +++ b/Test/baseResults/hlsl.structbuffer.append.fn.frag.out @@ -0,0 +1,275 @@ +hlsl.structbuffer.append.fn.frag +Shader version: 500 +gl_FragCoord origin is upper left +0:? Sequence +0:8 Function Definition: Fn2(block--vf4[0]1;block--vf4[0]1; ( temp 4-component vector of float) +0:8 Function Parameters: +0:8 'arg_a' (layout( row_major std430) buffer block{layout( row_major std430) buffer implicitly-sized array of 4-component vector of float @data}) +0:8 'arg_a@count' ( buffer block{layout( row_major std430) buffer int @count}) +0:8 'arg_c' (layout( row_major std430) buffer block{layout( row_major std430) buffer implicitly-sized array of 4-component vector of float @data}) +0:8 'arg_c@count' ( buffer block{layout( row_major std430) buffer int @count}) +0:? Sequence +0:9 move second child to first child ( temp 4-component vector of float) +0:9 indirect index ( buffer 4-component vector of float) +0:9 @data: direct index for structure ( buffer implicitly-sized array of 4-component vector of float) +0:9 'arg_a' (layout( row_major std430) buffer block{layout( row_major std430) buffer implicitly-sized array of 4-component vector of float @data}) +0:9 Constant: +0:9 0 (const uint) +0:9 AtomicAdd ( temp uint) +0:9 @count: direct index for structure ( temp int) +0:9 'arg_a@count' ( buffer block{layout( row_major std430) buffer int @count}) +0:9 Constant: +0:9 0 (const int) +0:9 Constant: +0:9 1 (const int) +0:? Constant: +0:? 1.000000 +0:? 2.000000 +0:? 3.000000 +0:? 4.000000 +0:10 Branch: Return with expression +0:10 indirect index ( buffer 4-component vector of float) +0:10 @data: direct index for structure ( buffer implicitly-sized array of 4-component vector of float) +0:10 'arg_c' (layout( row_major std430) buffer block{layout( row_major std430) buffer implicitly-sized array of 4-component vector of float @data}) +0:10 Constant: +0:10 0 (const uint) +0:10 add ( temp uint) +0:10 AtomicAdd ( temp uint) +0:10 @count: direct index for structure ( temp int) +0:10 'arg_c@count' ( buffer block{layout( row_major std430) buffer int @count}) +0:10 Constant: +0:10 0 (const int) +0:10 Constant: +0:10 -1 (const int) +0:10 Constant: +0:10 -1 (const int) +0:19 Function Definition: @main(u1; ( temp 4-component vector of float) +0:19 Function Parameters: +0:19 'pos' ( in uint) +0:? Sequence +0:22 Branch: Return with expression +0:22 Function Call: Fn2(block--vf4[0]1;block--vf4[0]1; ( temp 4-component vector of float) +0:22 'sbuf_a' (layout( row_major std430) buffer block{layout( row_major std430) buffer implicitly-sized array of 4-component vector of float @data}) +0:22 'sbuf_a@count' ( buffer block{layout( row_major std430) buffer int @count}) +0:22 'sbuf_c' (layout( row_major std430) buffer block{layout( row_major std430) buffer implicitly-sized array of 4-component vector of float @data}) +0:22 'sbuf_c@count' ( buffer block{layout( row_major std430) buffer int @count}) +0:19 Function Definition: main( ( temp void) +0:19 Function Parameters: +0:? Sequence +0:19 move second child to first child ( temp uint) +0:? 'pos' ( temp uint) +0:? 'pos' (layout( location=0) in uint) +0:19 move second child to first child ( temp 4-component vector of float) +0:? '@entryPointOutput' (layout( location=0) out 4-component vector of float) +0:19 Function Call: @main(u1; ( temp 4-component vector of float) +0:? 'pos' ( temp uint) +0:? Linker Objects +0:? 'sbuf_a' (layout( row_major std430) buffer block{layout( row_major std430) buffer implicitly-sized array of 4-component vector of float @data}) +0:? 'sbuf_a@count' (layout( row_major std430) buffer block{layout( row_major std430) buffer int @count}) +0:? 'sbuf_c' (layout( row_major std430) buffer block{layout( row_major std430) buffer implicitly-sized array of 4-component vector of float @data}) +0:? 'sbuf_c@count' (layout( row_major std430) buffer block{layout( row_major std430) buffer int @count}) +0:? 'sbuf_unused' (layout( row_major std430) buffer block{layout( row_major std430) buffer implicitly-sized array of 4-component vector of float @data}) +0:? '@entryPointOutput' (layout( location=0) out 4-component vector of float) +0:? 'pos' (layout( location=0) in uint) + + +Linked fragment stage: + + +Shader version: 500 +gl_FragCoord origin is upper left +0:? Sequence +0:8 Function Definition: Fn2(block--vf4[0]1;block--vf4[0]1; ( temp 4-component vector of float) +0:8 Function Parameters: +0:8 'arg_a' (layout( row_major std430) buffer block{layout( row_major std430) buffer implicitly-sized array of 4-component vector of float @data}) +0:8 'arg_a@count' ( buffer block{layout( row_major std430) buffer int @count}) +0:8 'arg_c' (layout( row_major std430) buffer block{layout( row_major std430) buffer implicitly-sized array of 4-component vector of float @data}) +0:8 'arg_c@count' ( buffer block{layout( row_major std430) buffer int @count}) +0:? Sequence +0:9 move second child to first child ( temp 4-component vector of float) +0:9 indirect index ( buffer 4-component vector of float) +0:9 @data: direct index for structure ( buffer implicitly-sized array of 4-component vector of float) +0:9 'arg_a' (layout( row_major std430) buffer block{layout( row_major std430) buffer implicitly-sized array of 4-component vector of float @data}) +0:9 Constant: +0:9 0 (const uint) +0:9 AtomicAdd ( temp uint) +0:9 @count: direct index for structure ( temp int) +0:9 'arg_a@count' ( buffer block{layout( row_major std430) buffer int @count}) +0:9 Constant: +0:9 0 (const int) +0:9 Constant: +0:9 1 (const int) +0:? Constant: +0:? 1.000000 +0:? 2.000000 +0:? 3.000000 +0:? 4.000000 +0:10 Branch: Return with expression +0:10 indirect index ( buffer 4-component vector of float) +0:10 @data: direct index for structure ( buffer implicitly-sized array of 4-component vector of float) +0:10 'arg_c' (layout( row_major std430) buffer block{layout( row_major std430) buffer implicitly-sized array of 4-component vector of float @data}) +0:10 Constant: +0:10 0 (const uint) +0:10 add ( temp uint) +0:10 AtomicAdd ( temp uint) +0:10 @count: direct index for structure ( temp int) +0:10 'arg_c@count' ( buffer block{layout( row_major std430) buffer int @count}) +0:10 Constant: +0:10 0 (const int) +0:10 Constant: +0:10 -1 (const int) +0:10 Constant: +0:10 -1 (const int) +0:19 Function Definition: @main(u1; ( temp 4-component vector of float) +0:19 Function Parameters: +0:19 'pos' ( in uint) +0:? Sequence +0:22 Branch: Return with expression +0:22 Function Call: Fn2(block--vf4[0]1;block--vf4[0]1; ( temp 4-component vector of float) +0:22 'sbuf_a' (layout( row_major std430) buffer block{layout( row_major std430) buffer implicitly-sized array of 4-component vector of float @data}) +0:22 'sbuf_a@count' ( buffer block{layout( row_major std430) buffer int @count}) +0:22 'sbuf_c' (layout( row_major std430) buffer block{layout( row_major std430) buffer implicitly-sized array of 4-component vector of float @data}) +0:22 'sbuf_c@count' ( buffer block{layout( row_major std430) buffer int @count}) +0:19 Function Definition: main( ( temp void) +0:19 Function Parameters: +0:? Sequence +0:19 move second child to first child ( temp uint) +0:? 'pos' ( temp uint) +0:? 'pos' (layout( location=0) in uint) +0:19 move second child to first child ( temp 4-component vector of float) +0:? '@entryPointOutput' (layout( location=0) out 4-component vector of float) +0:19 Function Call: @main(u1; ( temp 4-component vector of float) +0:? 'pos' ( temp uint) +0:? Linker Objects +0:? 'sbuf_a' (layout( row_major std430) buffer block{layout( row_major std430) buffer implicitly-sized array of 4-component vector of float @data}) +0:? 'sbuf_a@count' (layout( row_major std430) buffer block{layout( row_major std430) buffer int @count}) +0:? 'sbuf_c' (layout( row_major std430) buffer block{layout( row_major std430) buffer implicitly-sized array of 4-component vector of float @data}) +0:? 'sbuf_c@count' (layout( row_major std430) buffer block{layout( row_major std430) buffer int @count}) +0:? 'sbuf_unused' (layout( row_major std430) buffer block{layout( row_major std430) buffer implicitly-sized array of 4-component vector of float @data}) +0:? '@entryPointOutput' (layout( location=0) out 4-component vector of float) +0:? 'pos' (layout( location=0) in uint) + +// Module Version 10000 +// Generated by (magic number): 80001 +// Id's are bound by 70 + + Capability Shader + 1: ExtInstImport "GLSL.std.450" + MemoryModel Logical GLSL450 + EntryPoint Fragment 4 "main" 58 61 + ExecutionMode 4 OriginUpperLeft + Source HLSL 500 + Name 4 "main" + Name 9 "" + MemberName 9 0 "@data" + Name 12 "" + MemberName 12 0 "@count" + Name 19 "Fn2(block--vf4[0]1;block--vf4[0]1;" + Name 15 "arg_a" + Name 16 "arg_a@count" + Name 17 "arg_c" + Name 18 "arg_c@count" + Name 25 "@main(u1;" + Name 24 "pos" + Name 49 "sbuf_a" + Name 50 "sbuf_a@count" + Name 51 "sbuf_c" + Name 52 "sbuf_c@count" + Name 56 "pos" + Name 58 "pos" + Name 61 "@entryPointOutput" + Name 62 "param" + Name 65 "sbuf_a@count" + MemberName 65(sbuf_a@count) 0 "@count" + Name 67 "sbuf_a@count" + Name 68 "sbuf_c@count" + Name 69 "sbuf_unused" + Decorate 8 ArrayStride 16 + MemberDecorate 9 0 Offset 0 + Decorate 9 BufferBlock + Decorate 12 BufferBlock + Decorate 49(sbuf_a) DescriptorSet 0 + Decorate 50(sbuf_a@count) DescriptorSet 0 + Decorate 51(sbuf_c) DescriptorSet 0 + Decorate 52(sbuf_c@count) DescriptorSet 0 + Decorate 58(pos) Location 0 + Decorate 61(@entryPointOutput) Location 0 + MemberDecorate 65(sbuf_a@count) 0 Offset 0 + Decorate 65(sbuf_a@count) BufferBlock + Decorate 67(sbuf_a@count) DescriptorSet 0 + Decorate 68(sbuf_c@count) DescriptorSet 0 + Decorate 69(sbuf_unused) DescriptorSet 0 + 2: TypeVoid + 3: TypeFunction 2 + 6: TypeFloat 32 + 7: TypeVector 6(float) 4 + 8: TypeRuntimeArray 7(fvec4) + 9: TypeStruct 8 + 10: TypePointer Uniform 9(struct) + 11: TypeInt 32 1 + 12: TypeStruct 11(int) + 13: TypePointer Uniform 12(struct) + 14: TypeFunction 7(fvec4) 10(ptr) 13(ptr) 10(ptr) 13(ptr) + 21: TypeInt 32 0 + 22: TypePointer Function 21(int) + 23: TypeFunction 7(fvec4) 22(ptr) + 27: 11(int) Constant 0 + 28: TypePointer Uniform 11(int) + 30: 11(int) Constant 1 + 31: 21(int) Constant 1 + 32: 21(int) Constant 0 + 34: 6(float) Constant 1065353216 + 35: 6(float) Constant 1073741824 + 36: 6(float) Constant 1077936128 + 37: 6(float) Constant 1082130432 + 38: 7(fvec4) ConstantComposite 34 35 36 37 + 39: TypePointer Uniform 7(fvec4) + 42: 11(int) Constant 4294967295 + 49(sbuf_a): 10(ptr) Variable Uniform +50(sbuf_a@count): 13(ptr) Variable Uniform + 51(sbuf_c): 10(ptr) Variable Uniform +52(sbuf_c@count): 13(ptr) Variable Uniform + 57: TypePointer Input 21(int) + 58(pos): 57(ptr) Variable Input + 60: TypePointer Output 7(fvec4) +61(@entryPointOutput): 60(ptr) Variable Output +65(sbuf_a@count): TypeStruct 11(int) + 66: TypePointer Uniform 65(sbuf_a@count) +67(sbuf_a@count): 66(ptr) Variable Uniform +68(sbuf_c@count): 66(ptr) Variable Uniform + 69(sbuf_unused): 10(ptr) Variable Uniform + 4(main): 2 Function None 3 + 5: Label + 56(pos): 22(ptr) Variable Function + 62(param): 22(ptr) Variable Function + 59: 21(int) Load 58(pos) + Store 56(pos) 59 + 63: 21(int) Load 56(pos) + Store 62(param) 63 + 64: 7(fvec4) FunctionCall 25(@main(u1;) 62(param) + Store 61(@entryPointOutput) 64 + Return + FunctionEnd +19(Fn2(block--vf4[0]1;block--vf4[0]1;): 7(fvec4) Function None 14 + 15(arg_a): 10(ptr) FunctionParameter + 16(arg_a@count): 13(ptr) FunctionParameter + 17(arg_c): 10(ptr) FunctionParameter + 18(arg_c@count): 13(ptr) FunctionParameter + 20: Label + 29: 28(ptr) AccessChain 16(arg_a@count) 27 + 33: 21(int) AtomicIAdd 29 31 32 30 + 40: 39(ptr) AccessChain 15(arg_a) 27 33 + Store 40 38 + 41: 28(ptr) AccessChain 18(arg_c@count) 27 + 43: 21(int) AtomicIAdd 41 31 32 42 + 44: 21(int) IAdd 43 42 + 45: 39(ptr) AccessChain 17(arg_c) 27 44 + 46: 7(fvec4) Load 45 + ReturnValue 46 + FunctionEnd + 25(@main(u1;): 7(fvec4) Function None 23 + 24(pos): 22(ptr) FunctionParameter + 26: Label + 53: 7(fvec4) FunctionCall 19(Fn2(block--vf4[0]1;block--vf4[0]1;) 49(sbuf_a) 50(sbuf_a@count) 51(sbuf_c) 52(sbuf_c@count) + ReturnValue 53 + FunctionEnd diff --git a/Test/baseResults/hlsl.structbuffer.fn.frag.out b/Test/baseResults/hlsl.structbuffer.fn.frag.out index 762ea807e..0fcdab32e 100644 --- a/Test/baseResults/hlsl.structbuffer.fn.frag.out +++ b/Test/baseResults/hlsl.structbuffer.fn.frag.out @@ -17,6 +17,7 @@ gl_FragCoord origin is upper left 0:10 Function Definition: set(block--vu4[0]1;u1;vu4; ( temp void) 0:10 Function Parameters: 0:10 'sb' (layout( row_major std430) buffer block{layout( row_major std430) buffer implicitly-sized array of 4-component vector of uint @data}) +0:10 'sb@count' ( buffer block{layout( row_major std430) buffer int @count}) 0:10 'bufferOffset' ( in uint) 0:10 'data' ( in 4-component vector of uint) 0:? Sequence @@ -34,6 +35,7 @@ gl_FragCoord origin is upper left 0:? Sequence 0:21 Function Call: set(block--vu4[0]1;u1;vu4; ( temp void) 0:21 'sbuf2' (layout( row_major std430) buffer block{layout( row_major std430) buffer implicitly-sized array of 4-component vector of uint @data}) +0:21 'sbuf2@count' ( buffer block{layout( row_major std430) buffer int @count}) 0:21 Constant: 0:21 2 (const uint) 0:21 Function Call: get(block--vu4[0]1;u1; ( temp 4-component vector of uint) @@ -59,6 +61,7 @@ gl_FragCoord origin is upper left 0:? Linker Objects 0:? 'sbuf' (layout( binding=10 row_major std430) readonly buffer block{layout( row_major std430) buffer implicitly-sized array of 4-component vector of uint @data}) 0:? 'sbuf2' (layout( row_major std430) buffer block{layout( row_major std430) buffer implicitly-sized array of 4-component vector of uint @data}) +0:? 'sbuf2@count' (layout( row_major std430) buffer block{layout( row_major std430) buffer int @count}) 0:? 'sbuf3' (layout( binding=12 row_major std430) readonly buffer block{layout( row_major std430) buffer implicitly-sized array of 3-component vector of uint @data}) 0:? '@entryPointOutput' (layout( location=0) out 4-component vector of float) 0:? 'pos' (layout( location=0) in uint) @@ -85,6 +88,7 @@ gl_FragCoord origin is upper left 0:10 Function Definition: set(block--vu4[0]1;u1;vu4; ( temp void) 0:10 Function Parameters: 0:10 'sb' (layout( row_major std430) buffer block{layout( row_major std430) buffer implicitly-sized array of 4-component vector of uint @data}) +0:10 'sb@count' ( buffer block{layout( row_major std430) buffer int @count}) 0:10 'bufferOffset' ( in uint) 0:10 'data' ( in 4-component vector of uint) 0:? Sequence @@ -102,6 +106,7 @@ gl_FragCoord origin is upper left 0:? Sequence 0:21 Function Call: set(block--vu4[0]1;u1;vu4; ( temp void) 0:21 'sbuf2' (layout( row_major std430) buffer block{layout( row_major std430) buffer implicitly-sized array of 4-component vector of uint @data}) +0:21 'sbuf2@count' ( buffer block{layout( row_major std430) buffer int @count}) 0:21 Constant: 0:21 2 (const uint) 0:21 Function Call: get(block--vu4[0]1;u1; ( temp 4-component vector of uint) @@ -127,18 +132,19 @@ gl_FragCoord origin is upper left 0:? Linker Objects 0:? 'sbuf' (layout( binding=10 row_major std430) readonly buffer block{layout( row_major std430) buffer implicitly-sized array of 4-component vector of uint @data}) 0:? 'sbuf2' (layout( row_major std430) buffer block{layout( row_major std430) buffer implicitly-sized array of 4-component vector of uint @data}) +0:? 'sbuf2@count' (layout( row_major std430) buffer block{layout( row_major std430) buffer int @count}) 0:? 'sbuf3' (layout( binding=12 row_major std430) readonly buffer block{layout( row_major std430) buffer implicitly-sized array of 3-component vector of uint @data}) 0:? '@entryPointOutput' (layout( location=0) out 4-component vector of float) 0:? 'pos' (layout( location=0) in uint) // Module Version 10000 // Generated by (magic number): 80001 -// Id's are bound by 71 +// Id's are bound by 78 Capability Shader 1: ExtInstImport "GLSL.std.450" MemoryModel Logical GLSL450 - EntryPoint Fragment 4 "main" 59 62 + EntryPoint Fragment 4 "main" 63 66 ExecutionMode 4 OriginUpperLeft Source HLSL 500 Name 4 "main" @@ -149,24 +155,31 @@ gl_FragCoord origin is upper left Name 14 "bufferOffset" Name 18 "" MemberName 18 0 "@data" - Name 25 "set(block--vu4[0]1;u1;vu4;" - Name 22 "sb" - Name 23 "bufferOffset" - Name 24 "data" - Name 31 "@main(u1;" - Name 30 "pos" - Name 44 "sbuf2" - Name 46 "sbuf" - Name 48 "param" - Name 50 "param" - Name 51 "param" - Name 57 "pos" - Name 59 "pos" - Name 62 "@entryPointOutput" - Name 63 "param" - Name 68 "sbuf3" - MemberName 68(sbuf3) 0 "@data" - Name 70 "sbuf3" + Name 21 "" + MemberName 21 0 "@count" + Name 29 "set(block--vu4[0]1;u1;vu4;" + Name 25 "sb" + Name 26 "sb@count" + Name 27 "bufferOffset" + Name 28 "data" + Name 35 "@main(u1;" + Name 34 "pos" + Name 47 "sbuf2" + Name 48 "sbuf2@count" + Name 50 "sbuf" + Name 52 "param" + Name 54 "param" + Name 55 "param" + Name 61 "pos" + Name 63 "pos" + Name 66 "@entryPointOutput" + Name 67 "param" + Name 70 "sbuf2@count" + MemberName 70(sbuf2@count) 0 "@count" + Name 72 "sbuf2@count" + Name 75 "sbuf3" + MemberName 75(sbuf3) 0 "@data" + Name 77 "sbuf3" Decorate 8 ArrayStride 16 MemberDecorate 9 0 NonWritable MemberDecorate 9 0 Offset 0 @@ -174,17 +187,22 @@ gl_FragCoord origin is upper left Decorate 17 ArrayStride 16 MemberDecorate 18 0 Offset 0 Decorate 18 BufferBlock - Decorate 44(sbuf2) DescriptorSet 0 - Decorate 46(sbuf) DescriptorSet 0 - Decorate 46(sbuf) Binding 10 - Decorate 59(pos) Location 0 - Decorate 62(@entryPointOutput) Location 0 - Decorate 67 ArrayStride 16 - MemberDecorate 68(sbuf3) 0 NonWritable - MemberDecorate 68(sbuf3) 0 Offset 0 - Decorate 68(sbuf3) BufferBlock - Decorate 70(sbuf3) DescriptorSet 0 - Decorate 70(sbuf3) Binding 12 + Decorate 21 BufferBlock + Decorate 47(sbuf2) DescriptorSet 0 + Decorate 48(sbuf2@count) DescriptorSet 0 + Decorate 50(sbuf) DescriptorSet 0 + Decorate 50(sbuf) Binding 10 + Decorate 63(pos) Location 0 + Decorate 66(@entryPointOutput) Location 0 + MemberDecorate 70(sbuf2@count) 0 Offset 0 + Decorate 70(sbuf2@count) BufferBlock + Decorate 72(sbuf2@count) DescriptorSet 0 + Decorate 74 ArrayStride 16 + MemberDecorate 75(sbuf3) 0 NonWritable + MemberDecorate 75(sbuf3) 0 Offset 0 + Decorate 75(sbuf3) BufferBlock + Decorate 77(sbuf3) DescriptorSet 0 + Decorate 77(sbuf3) Binding 12 2: TypeVoid 3: TypeFunction 2 6: TypeInt 32 0 @@ -197,71 +215,78 @@ gl_FragCoord origin is upper left 17: TypeRuntimeArray 7(ivec4) 18: TypeStruct 17 19: TypePointer Uniform 18(struct) - 20: TypePointer Function 7(ivec4) - 21: TypeFunction 2 19(ptr) 11(ptr) 20(ptr) - 27: TypeFloat 32 - 28: TypeVector 27(float) 4 - 29: TypeFunction 28(fvec4) 11(ptr) - 33: TypeInt 32 1 - 34: 33(int) Constant 0 - 36: TypePointer Uniform 7(ivec4) - 44(sbuf2): 19(ptr) Variable Uniform - 45: 6(int) Constant 2 - 46(sbuf): 10(ptr) Variable Uniform - 47: 6(int) Constant 3 - 53: 27(float) Constant 0 - 54: 28(fvec4) ConstantComposite 53 53 53 53 - 58: TypePointer Input 6(int) - 59(pos): 58(ptr) Variable Input - 61: TypePointer Output 28(fvec4) -62(@entryPointOutput): 61(ptr) Variable Output - 66: TypeVector 6(int) 3 - 67: TypeRuntimeArray 66(ivec3) - 68(sbuf3): TypeStruct 67 - 69: TypePointer Uniform 68(sbuf3) - 70(sbuf3): 69(ptr) Variable Uniform + 20: TypeInt 32 1 + 21: TypeStruct 20(int) + 22: TypePointer Uniform 21(struct) + 23: TypePointer Function 7(ivec4) + 24: TypeFunction 2 19(ptr) 22(ptr) 11(ptr) 23(ptr) + 31: TypeFloat 32 + 32: TypeVector 31(float) 4 + 33: TypeFunction 32(fvec4) 11(ptr) + 37: 20(int) Constant 0 + 39: TypePointer Uniform 7(ivec4) + 47(sbuf2): 19(ptr) Variable Uniform + 48(sbuf2@count): 22(ptr) Variable Uniform + 49: 6(int) Constant 2 + 50(sbuf): 10(ptr) Variable Uniform + 51: 6(int) Constant 3 + 57: 31(float) Constant 0 + 58: 32(fvec4) ConstantComposite 57 57 57 57 + 62: TypePointer Input 6(int) + 63(pos): 62(ptr) Variable Input + 65: TypePointer Output 32(fvec4) +66(@entryPointOutput): 65(ptr) Variable Output + 70(sbuf2@count): TypeStruct 20(int) + 71: TypePointer Uniform 70(sbuf2@count) + 72(sbuf2@count): 71(ptr) Variable Uniform + 73: TypeVector 6(int) 3 + 74: TypeRuntimeArray 73(ivec3) + 75(sbuf3): TypeStruct 74 + 76: TypePointer Uniform 75(sbuf3) + 77(sbuf3): 76(ptr) Variable Uniform 4(main): 2 Function None 3 5: Label - 57(pos): 11(ptr) Variable Function - 63(param): 11(ptr) Variable Function - 60: 6(int) Load 59(pos) - Store 57(pos) 60 - 64: 6(int) Load 57(pos) - Store 63(param) 64 - 65: 28(fvec4) FunctionCall 31(@main(u1;) 63(param) - Store 62(@entryPointOutput) 65 + 61(pos): 11(ptr) Variable Function + 67(param): 11(ptr) Variable Function + 64: 6(int) Load 63(pos) + Store 61(pos) 64 + 68: 6(int) Load 61(pos) + Store 67(param) 68 + 69: 32(fvec4) FunctionCall 35(@main(u1;) 67(param) + Store 66(@entryPointOutput) 69 Return FunctionEnd 15(get(block--vu4[0]1;u1;): 7(ivec4) Function None 12 13(sb): 10(ptr) FunctionParameter 14(bufferOffset): 11(ptr) FunctionParameter 16: Label - 35: 6(int) Load 14(bufferOffset) - 37: 36(ptr) AccessChain 13(sb) 34 35 - 38: 7(ivec4) Load 37 - ReturnValue 38 + 38: 6(int) Load 14(bufferOffset) + 40: 39(ptr) AccessChain 13(sb) 37 38 + 41: 7(ivec4) Load 40 + ReturnValue 41 FunctionEnd -25(set(block--vu4[0]1;u1;vu4;): 2 Function None 21 - 22(sb): 19(ptr) FunctionParameter -23(bufferOffset): 11(ptr) FunctionParameter - 24(data): 20(ptr) FunctionParameter - 26: Label - 41: 6(int) Load 23(bufferOffset) - 42: 7(ivec4) Load 24(data) - 43: 36(ptr) AccessChain 22(sb) 34 41 - Store 43 42 +29(set(block--vu4[0]1;u1;vu4;): 2 Function None 24 + 25(sb): 19(ptr) FunctionParameter + 26(sb@count): 22(ptr) FunctionParameter +27(bufferOffset): 11(ptr) FunctionParameter + 28(data): 23(ptr) FunctionParameter + 30: Label + 44: 6(int) Load 27(bufferOffset) + 45: 7(ivec4) Load 28(data) + 46: 39(ptr) AccessChain 25(sb) 37 44 + Store 46 45 Return FunctionEnd - 31(@main(u1;): 28(fvec4) Function None 29 - 30(pos): 11(ptr) FunctionParameter - 32: Label - 48(param): 11(ptr) Variable Function - 50(param): 11(ptr) Variable Function - 51(param): 20(ptr) Variable Function - Store 48(param) 47 - 49: 7(ivec4) FunctionCall 15(get(block--vu4[0]1;u1;) 46(sbuf) 48(param) - Store 50(param) 45 - Store 51(param) 49 - 52: 2 FunctionCall 25(set(block--vu4[0]1;u1;vu4;) 44(sbuf2) 50(param) 51(param) - ReturnValue 54 + 35(@main(u1;): 32(fvec4) Function None 33 + 34(pos): 11(ptr) FunctionParameter + 36: Label + 52(param): 11(ptr) Variable Function + 54(param): 11(ptr) Variable Function + 55(param): 23(ptr) Variable Function + Store 52(param) 51 + 53: 7(ivec4) FunctionCall 15(get(block--vu4[0]1;u1;) 50(sbuf) 52(param) + Store 54(param) 49 + Store 55(param) 53 + 56: 2 FunctionCall 29(set(block--vu4[0]1;u1;vu4;) 47(sbuf2) 48(sbuf2@count) 54(param) 55(param) + ReturnValue 58 FunctionEnd diff --git a/Test/hlsl.structbuffer.append.fn.frag b/Test/hlsl.structbuffer.append.fn.frag new file mode 100644 index 000000000..668bc1e8e --- /dev/null +++ b/Test/hlsl.structbuffer.append.fn.frag @@ -0,0 +1,23 @@ + +// float4 Fn1(ConsumeStructuredBuffer arg_c) +// { +// return arg_c.Consume(); +// } + +float4 Fn2(AppendStructuredBuffer arg_a, ConsumeStructuredBuffer arg_c) +{ + arg_a.Append(float4(1,2,3,4)); + return arg_c.Consume(); +} + +AppendStructuredBuffer sbuf_a; +ConsumeStructuredBuffer sbuf_c; + +AppendStructuredBuffer sbuf_unused; + +float4 main(uint pos : FOO) : SV_Target0 +{ + // Fn1(sbuf_c); + + return Fn2(sbuf_a, sbuf_c); +} diff --git a/gtests/Hlsl.FromFile.cpp b/gtests/Hlsl.FromFile.cpp index 9612a4cfb..f95df0802 100644 --- a/gtests/Hlsl.FromFile.cpp +++ b/gtests/Hlsl.FromFile.cpp @@ -255,6 +255,7 @@ INSTANTIATE_TEST_CASE_P( {"hlsl.structarray.flatten.geom", "main"}, {"hlsl.structbuffer.frag", "main"}, {"hlsl.structbuffer.append.frag", "main"}, + {"hlsl.structbuffer.append.fn.frag", "main"}, {"hlsl.structbuffer.atomics.frag", "main"}, {"hlsl.structbuffer.byte.frag", "main"}, {"hlsl.structbuffer.coherent.frag", "main"}, diff --git a/hlsl/hlslParseHelper.cpp b/hlsl/hlslParseHelper.cpp index 85d973dd2..a2abcfa87 100755 --- a/hlsl/hlslParseHelper.cpp +++ b/hlsl/hlslParseHelper.cpp @@ -1580,6 +1580,28 @@ void HlslParseContext::addInterstageIoToLinkage() } } +// For struct buffers with counters, we must pass the counter buffer as hidden parameter. +// This adds the hidden parameter to the parameter list in 'paramNodes' if needed. +// Otherwise, it's a no-op +void HlslParseContext::addStructBufferHiddenCounterParam(const TSourceLoc& loc, TParameter& param, TIntermAggregate*& paramNodes) +{ + if (! hasStructBuffCounter(*param.type)) + return; + + const TString counterBlockName(getStructBuffCounterName(*param.name)); + + TType counterType; + counterBufferType(loc, counterType); + TVariable *variable = makeInternalVariable(counterBlockName, counterType); + + if (! symbolTable.insert(*variable)) + error(loc, "redefinition", variable->getName().c_str(), ""); + + paramNodes = intermediate.growAggregate(paramNodes, + intermediate.addSymbol(*variable, loc), + loc); +} + // // Handle seeing the function prototype in front of a function definition in the grammar. // The body is handled after this function returns. @@ -1649,7 +1671,8 @@ TIntermAggregate* HlslParseContext::handleFunctionDefinition(const TSourceLoc& l intermediate.addSymbol(*variable, loc), loc); - // TODO: for struct buffers with counters, pass counter buffer as hidden parameter + // Add hidden parameter for struct buffer counters, if needed. + addStructBufferHiddenCounterParam(loc, param, paramNodes); } else paramNodes = intermediate.growAggregate(paramNodes, intermediate.addSymbol(*param.type, loc), loc); } @@ -2492,6 +2515,29 @@ bool HlslParseContext::hasStructBuffCounter(const TType& type) const } } +void HlslParseContext::counterBufferType(const TSourceLoc& loc, TType& type) +{ + // Counter type + TType* counterType = new TType(EbtInt, EvqBuffer); + counterType->setFieldName("@count"); + + TTypeList* blockStruct = new TTypeList; + TTypeLoc member = { counterType, loc }; + blockStruct->push_back(member); + + TType blockType(blockStruct, "", counterType->getQualifier()); + blockType.getQualifier().storage = EvqBuffer; + + type.shallowCopy(blockType); + shareStructBufferType(type); +} + +// knowledge of how to construct block name, in one place instead of N places. +TString HlslParseContext::getStructBuffCounterName(const TString& blockName) const +{ + return blockName + "@count"; +} + // declare counter for a structured buffer type void HlslParseContext::declareStructBufferCounter(const TSourceLoc& loc, const TType& bufferType, const TString& name) { @@ -2502,22 +2548,14 @@ void HlslParseContext::declareStructBufferCounter(const TSourceLoc& loc, const T if (! hasStructBuffCounter(bufferType)) return; - // Counter type - TType* counterType = new TType(EbtInt, EvqBuffer); - counterType->setFieldName("@count"); + TType blockType; + counterBufferType(loc, blockType); - TTypeList* blockStruct = new TTypeList; - TTypeLoc member = { counterType, loc }; - blockStruct->push_back(member); - - TString* blockName = new TString(name); - *blockName += "@count"; + TString* blockName = new TString(getStructBuffCounterName(name)); + // Counter buffer does not have its own counter buffer. TODO: there should be a better way to track this. structBufferCounter[*blockName] = false; - TType blockType(blockStruct, "", counterType->getQualifier()); - blockType.getQualifier().storage = EvqBuffer; - shareStructBufferType(blockType); declareBlock(loc, blockType, blockName); } @@ -2529,13 +2567,12 @@ TIntermTyped* HlslParseContext::getStructBufferCounter(const TSourceLoc& loc, TI if (buffer == nullptr || ! isStructBufferType(buffer->getType())) return nullptr; - TString blockName(buffer->getAsSymbolNode()->getName()); - blockName += "@count"; + const TString counterBlockName(getStructBuffCounterName(buffer->getAsSymbolNode()->getName())); // Mark the counter as being used - structBufferCounter[blockName] = true; + structBufferCounter[counterBlockName] = true; - TIntermTyped* counterVar = handleVariable(loc, &blockName); // find the block structure + TIntermTyped* counterVar = handleVariable(loc, &counterBlockName); // find the block structure TIntermTyped* index = intermediate.addConstantUnion(0, loc); // index to counter inside block struct TIntermTyped* counterMember = intermediate.addIndex(EOpIndexDirectStruct, counterVar, index, loc); @@ -4320,6 +4357,8 @@ TIntermTyped* HlslParseContext::handleFunctionCall(const TSourceLoc& loc, TFunct const TFunction* fnCandidate = nullptr; bool builtIn = false; + TIntermAggregate* aggregate = arguments ? arguments->getAsAggregate() : nullptr; + // TODO: this needs improvement: there's no way at present to look up a signature in // the symbol table for an arbitrary type. This is a temporary hack until that ability exists. // It will have false positives, since it doesn't check arg counts or types. @@ -4329,14 +4368,12 @@ TIntermTyped* HlslParseContext::handleFunctionCall(const TSourceLoc& loc, TFunct TIntermTyped* arg0 = nullptr; - if (arguments->getAsAggregate() && arguments->getAsAggregate()->getSequence().size() > 0) - arg0 = arguments->getAsAggregate()->getSequence()[0]->getAsTyped(); + if (aggregate && aggregate->getSequence().size() > 0) + arg0 = aggregate->getSequence()[0]->getAsTyped(); else if (arguments->getAsSymbolNode()) arg0 = arguments->getAsSymbolNode(); if (arg0 != nullptr && isStructBufferType(arg0->getType())) { - // TODO: for struct buffers with counters, pass counter buffer as hidden parameter - static const int methodPrefixSize = sizeof(BUILTIN_PREFIX)-1; if (function->getName().length() > methodPrefixSize && @@ -4367,6 +4404,11 @@ TIntermTyped* HlslParseContext::handleFunctionCall(const TSourceLoc& loc, TFunct if (arguments) addInputArgumentConversions(*fnCandidate, arguments); + // If any argument is a pass-by-reference struct buffer with an associated counter + // buffer, we have to add another hidden parameter for that counter. + if (aggregate && !builtIn) + addStructBuffArguments(loc, aggregate); + op = fnCandidate->getBuiltInOp(); if (builtIn && op != EOpNull) { // A function call mapped to a built-in operation. @@ -4413,7 +4455,12 @@ TIntermTyped* HlslParseContext::handleFunctionCall(const TSourceLoc& loc, TFunct for (int i = 0; i < fnCandidate->getParamCount(); ++i) { TStorageQualifier qual = (*fnCandidate)[i].type->getQualifier().storage; qualifierList.push_back(qual); + + // add counter buffer argument qualifier + if (hasStructBuffCounter(*(*fnCandidate)[i].type)) + qualifierList.push_back(qual); } + result = addOutputArgumentConversions(*fnCandidate, *result->getAsOperator()); } } @@ -4582,6 +4629,55 @@ TIntermTyped* HlslParseContext::addOutputArgumentConversions(const TFunction& fu return conversionTree; } +// +// Add any needed "hidden" counter buffer arguments for function calls. +// +// Modifies the 'aggregate' argument if needed. Otherwise, is no-op. +// +void HlslParseContext::addStructBuffArguments(const TSourceLoc& loc, TIntermAggregate*& aggregate) +{ + // See if there are any SB types with counters. + const bool hasStructBuffArg = + std::any_of(aggregate->getSequence().begin(), + aggregate->getSequence().end(), + [this](const TIntermNode* node) { + return (node->getAsTyped() != nullptr) && hasStructBuffCounter(node->getAsTyped()->getType()); + }); + + // Nothing to do, if we didn't find one. + if (! hasStructBuffArg) + return; + + TIntermSequence argsWithCounterBuffers; + + for (int param=0; paramgetSequence().size()); ++param) { + argsWithCounterBuffers.push_back(aggregate->getSequence()[param]); + + if (hasStructBuffCounter(aggregate->getSequence()[param]->getAsTyped()->getType())) { + const TIntermSymbol* blockSym = aggregate->getSequence()[param]->getAsSymbolNode(); + if (blockSym != nullptr) { + TType counterType; + counterBufferType(loc, counterType); + + const TString counterBlockName(getStructBuffCounterName(blockSym->getName())); + + TVariable* variable = makeInternalVariable(counterBlockName, counterType); + + // Mark this buffer as requiring a counter block. TODO: there should be a better + // way to track it. + structBufferCounter[counterBlockName] = true; + + TIntermSymbol* sym = intermediate.addSymbol(*variable, loc); + argsWithCounterBuffers.push_back(sym); + } + } + } + + // Swap with the temp list we've built up. + aggregate->getSequence().swap(argsWithCounterBuffers); +} + + // // Do additional checking of built-in function calls that is not caught // by normal semantic checks on argument type, extension tagging, etc. @@ -5740,6 +5836,7 @@ void HlslParseContext::paramFix(TType& type) bufferQualifier.storage = type.getQualifier().storage; bufferQualifier.readonly = type.getQualifier().readonly; bufferQualifier.coherent = type.getQualifier().coherent; + bufferQualifier.declaredBuiltIn = type.getQualifier().declaredBuiltIn; type.getQualifier() = bufferQualifier; break; } diff --git a/hlsl/hlslParseHelper.h b/hlsl/hlslParseHelper.h index 592cd8293..729da78f6 100755 --- a/hlsl/hlslParseHelper.h +++ b/hlsl/hlslParseHelper.h @@ -275,6 +275,7 @@ protected: // Test method names bool isStructBufferMethod(const TString& name) const; + void counterBufferType(const TSourceLoc& loc, TType& type); // Return standard sample position array TIntermConstantUnion* getSamplePosArray(int count); @@ -283,6 +284,9 @@ protected: bool isStructBufferType(const TType& type) const { return getStructBufferContentType(type) != nullptr; } TIntermTyped* indexStructBufferContent(const TSourceLoc& loc, TIntermTyped* buffer) const; TIntermTyped* getStructBufferCounter(const TSourceLoc& loc, TIntermTyped* buffer); + TString getStructBuffCounterName(const TString&) const; + void addStructBuffArguments(const TSourceLoc& loc, TIntermAggregate*&); + void addStructBufferHiddenCounterParam(const TSourceLoc& loc, TParameter&, TIntermAggregate*&); // Return true if this type is a reference. This is not currently a type method in case that's // a language specific answer.