From e5530b92ce1af8cbe8977024dd8a6ab5a2eb3fb7 Mon Sep 17 00:00:00 2001 From: LoopDawg Date: Wed, 8 Nov 2017 19:48:11 -0700 Subject: [PATCH] HLSL: implement TextureBuffer Almost equivalent to tbuffer, except members not at global scope. So, reference is "TextureBuffer_var.member", not simply "member". --- Test/baseResults/hlsl.texturebuffer.frag.out | 153 +++++++++++++++++++ Test/hlsl.texturebuffer.frag | 17 +++ gtests/Hlsl.FromFile.cpp | 1 + hlsl/hlslGrammar.cpp | 41 +++++ hlsl/hlslGrammar.h | 1 + hlsl/hlslScanContext.cpp | 2 + hlsl/hlslTokens.h | 1 + 7 files changed, 216 insertions(+) create mode 100644 Test/baseResults/hlsl.texturebuffer.frag.out create mode 100644 Test/hlsl.texturebuffer.frag diff --git a/Test/baseResults/hlsl.texturebuffer.frag.out b/Test/baseResults/hlsl.texturebuffer.frag.out new file mode 100644 index 000000000..e1e36b00f --- /dev/null +++ b/Test/baseResults/hlsl.texturebuffer.frag.out @@ -0,0 +1,153 @@ +hlsl.texturebuffer.frag +Shader version: 500 +gl_FragCoord origin is upper left +0:? Sequence +0:15 Function Definition: @main(vf4; ( temp 4-component vector of float) +0:15 Function Parameters: +0:15 'pos' ( in 4-component vector of float) +0:? Sequence +0:16 Branch: Return with expression +0:16 add ( temp 4-component vector of float) +0:16 f: direct index for structure (layout( row_major std430) buffer 4-component vector of float) +0:16 'TextureBuffer_var' (layout( binding=0 row_major std430) readonly buffer block{layout( row_major std430) buffer 4-component vector of float f, layout( row_major std430) buffer 4-component vector of int i}) +0:16 Constant: +0:16 0 (const int) +0:16 f2: direct index for structure (layout( row_major std430) buffer 4-component vector of float) +0:16 'anon@0' (layout( row_major std430) readonly buffer block{layout( row_major std430) buffer 4-component vector of float f2, layout( row_major std430) buffer 4-component vector of int i2}) +0:16 Constant: +0:16 0 (const uint) +0:15 Function Definition: main( ( temp void) +0:15 Function Parameters: +0:? Sequence +0:15 move second child to first child ( temp 4-component vector of float) +0:? 'pos' ( temp 4-component vector of float) +0:? 'pos' ( in 4-component vector of float FragCoord) +0:15 move second child to first child ( temp 4-component vector of float) +0:? '@entryPointOutput' (layout( location=0) out 4-component vector of float) +0:15 Function Call: @main(vf4; ( temp 4-component vector of float) +0:? 'pos' ( temp 4-component vector of float) +0:? Linker Objects +0:? 'TextureBuffer_var' (layout( binding=0 row_major std430) readonly buffer block{layout( row_major std430) buffer 4-component vector of float f, layout( row_major std430) buffer 4-component vector of int i}) +0:? 'anon@0' (layout( row_major std430) readonly buffer block{layout( row_major std430) buffer 4-component vector of float f2, layout( row_major std430) buffer 4-component vector of int i2}) +0:? '@entryPointOutput' (layout( location=0) out 4-component vector of float) +0:? 'pos' ( in 4-component vector of float FragCoord) + + +Linked fragment stage: + + +Shader version: 500 +gl_FragCoord origin is upper left +0:? Sequence +0:15 Function Definition: @main(vf4; ( temp 4-component vector of float) +0:15 Function Parameters: +0:15 'pos' ( in 4-component vector of float) +0:? Sequence +0:16 Branch: Return with expression +0:16 add ( temp 4-component vector of float) +0:16 f: direct index for structure (layout( row_major std430) buffer 4-component vector of float) +0:16 'TextureBuffer_var' (layout( binding=0 row_major std430) readonly buffer block{layout( row_major std430) buffer 4-component vector of float f, layout( row_major std430) buffer 4-component vector of int i}) +0:16 Constant: +0:16 0 (const int) +0:16 f2: direct index for structure (layout( row_major std430) buffer 4-component vector of float) +0:16 'anon@0' (layout( row_major std430) readonly buffer block{layout( row_major std430) buffer 4-component vector of float f2, layout( row_major std430) buffer 4-component vector of int i2}) +0:16 Constant: +0:16 0 (const uint) +0:15 Function Definition: main( ( temp void) +0:15 Function Parameters: +0:? Sequence +0:15 move second child to first child ( temp 4-component vector of float) +0:? 'pos' ( temp 4-component vector of float) +0:? 'pos' ( in 4-component vector of float FragCoord) +0:15 move second child to first child ( temp 4-component vector of float) +0:? '@entryPointOutput' (layout( location=0) out 4-component vector of float) +0:15 Function Call: @main(vf4; ( temp 4-component vector of float) +0:? 'pos' ( temp 4-component vector of float) +0:? Linker Objects +0:? 'TextureBuffer_var' (layout( binding=0 row_major std430) readonly buffer block{layout( row_major std430) buffer 4-component vector of float f, layout( row_major std430) buffer 4-component vector of int i}) +0:? 'anon@0' (layout( row_major std430) readonly buffer block{layout( row_major std430) buffer 4-component vector of float f2, layout( row_major std430) buffer 4-component vector of int i2}) +0:? '@entryPointOutput' (layout( location=0) out 4-component vector of float) +0:? 'pos' ( in 4-component vector of float FragCoord) + +// Module Version 10000 +// Generated by (magic number): 80002 +// Id's are bound by 39 + + Capability Shader + 1: ExtInstImport "GLSL.std.450" + MemoryModel Logical GLSL450 + EntryPoint Fragment 4 "main" 32 35 + ExecutionMode 4 OriginUpperLeft + Source HLSL 500 + Name 4 "main" + Name 11 "@main(vf4;" + Name 10 "pos" + Name 15 "TextureBuffer_var" + MemberName 15(TextureBuffer_var) 0 "f" + MemberName 15(TextureBuffer_var) 1 "i" + Name 17 "TextureBuffer_var" + Name 22 "tbuf2" + MemberName 22(tbuf2) 0 "f2" + MemberName 22(tbuf2) 1 "i2" + Name 24 "" + Name 30 "pos" + Name 32 "pos" + Name 35 "@entryPointOutput" + Name 36 "param" + MemberDecorate 15(TextureBuffer_var) 0 NonWritable + MemberDecorate 15(TextureBuffer_var) 0 Offset 0 + MemberDecorate 15(TextureBuffer_var) 1 NonWritable + MemberDecorate 15(TextureBuffer_var) 1 Offset 16 + Decorate 15(TextureBuffer_var) BufferBlock + Decorate 17(TextureBuffer_var) DescriptorSet 0 + Decorate 17(TextureBuffer_var) Binding 0 + MemberDecorate 22(tbuf2) 0 NonWritable + MemberDecorate 22(tbuf2) 0 Offset 0 + MemberDecorate 22(tbuf2) 1 NonWritable + MemberDecorate 22(tbuf2) 1 Offset 16 + Decorate 22(tbuf2) BufferBlock + Decorate 24 DescriptorSet 0 + Decorate 32(pos) BuiltIn FragCoord + Decorate 35(@entryPointOutput) Location 0 + 2: TypeVoid + 3: TypeFunction 2 + 6: TypeFloat 32 + 7: TypeVector 6(float) 4 + 8: TypePointer Function 7(fvec4) + 9: TypeFunction 7(fvec4) 8(ptr) + 13: TypeInt 32 1 + 14: TypeVector 13(int) 4 +15(TextureBuffer_var): TypeStruct 7(fvec4) 14(ivec4) + 16: TypePointer Uniform 15(TextureBuffer_var) +17(TextureBuffer_var): 16(ptr) Variable Uniform + 18: 13(int) Constant 0 + 19: TypePointer Uniform 7(fvec4) + 22(tbuf2): TypeStruct 7(fvec4) 14(ivec4) + 23: TypePointer Uniform 22(tbuf2) + 24: 23(ptr) Variable Uniform + 31: TypePointer Input 7(fvec4) + 32(pos): 31(ptr) Variable Input + 34: TypePointer Output 7(fvec4) +35(@entryPointOutput): 34(ptr) Variable Output + 4(main): 2 Function None 3 + 5: Label + 30(pos): 8(ptr) Variable Function + 36(param): 8(ptr) Variable Function + 33: 7(fvec4) Load 32(pos) + Store 30(pos) 33 + 37: 7(fvec4) Load 30(pos) + Store 36(param) 37 + 38: 7(fvec4) FunctionCall 11(@main(vf4;) 36(param) + Store 35(@entryPointOutput) 38 + Return + FunctionEnd + 11(@main(vf4;): 7(fvec4) Function None 9 + 10(pos): 8(ptr) FunctionParameter + 12: Label + 20: 19(ptr) AccessChain 17(TextureBuffer_var) 18 + 21: 7(fvec4) Load 20 + 25: 19(ptr) AccessChain 24 18 + 26: 7(fvec4) Load 25 + 27: 7(fvec4) FAdd 21 26 + ReturnValue 27 + FunctionEnd diff --git a/Test/hlsl.texturebuffer.frag b/Test/hlsl.texturebuffer.frag new file mode 100644 index 000000000..d06974656 --- /dev/null +++ b/Test/hlsl.texturebuffer.frag @@ -0,0 +1,17 @@ + +struct Data { + float4 f; + int4 i; +}; + +TextureBuffer TextureBuffer_var : register(t0); + +tbuffer tbuf2 { + float4 f2; + int4 i2; +}; + +float4 main(float4 pos : SV_POSITION) : SV_TARGET +{ + return TextureBuffer_var.f + f2; +} diff --git a/gtests/Hlsl.FromFile.cpp b/gtests/Hlsl.FromFile.cpp index 9d97fdf09..5d8ab47a7 100644 --- a/gtests/Hlsl.FromFile.cpp +++ b/gtests/Hlsl.FromFile.cpp @@ -326,6 +326,7 @@ INSTANTIATE_TEST_CASE_P( {"hlsl.structStructName.frag", "main"}, {"hlsl.subpass.frag", "main"}, {"hlsl.synthesizeInput.frag", "main"}, + {"hlsl.texturebuffer.frag", "main"}, {"hlsl.texture.struct.frag", "main"}, {"hlsl.texture.subvec4.frag", "main"}, {"hlsl.this.frag", "main"}, diff --git a/hlsl/hlslGrammar.cpp b/hlsl/hlslGrammar.cpp index 515922e03..3fe7a0dab 100755 --- a/hlsl/hlslGrammar.cpp +++ b/hlsl/hlslGrammar.cpp @@ -1453,6 +1453,10 @@ bool HlslGrammar::acceptType(TType& type, TIntermNode*& nodeList) return acceptStructBufferType(type); break; + case EHTokTextureBuffer: + return acceptTextureBufferType(type); + break; + case EHTokConstantBuffer: return acceptConstantBufferType(type); @@ -2127,6 +2131,43 @@ bool HlslGrammar::acceptConstantBufferType(TType& type) } } +// texture_buffer +// : TEXTUREBUFFER LEFT_ANGLE type RIGHT_ANGLE +bool HlslGrammar::acceptTextureBufferType(TType& type) +{ + if (! acceptTokenClass(EHTokTextureBuffer)) + return false; + + if (! acceptTokenClass(EHTokLeftAngle)) { + expected("left angle bracket"); + return false; + } + + TType templateType; + if (! acceptType(templateType)) { + expected("type"); + return false; + } + + if (! acceptTokenClass(EHTokRightAngle)) { + expected("right angle bracket"); + return false; + } + + templateType.getQualifier().storage = EvqBuffer; + templateType.getQualifier().readonly = true; + + TType blockType(templateType.getWritableStruct(), "", templateType.getQualifier()); + + blockType.getQualifier().storage = EvqBuffer; + blockType.getQualifier().readonly = true; + + type.shallowCopy(blockType); + + return true; +} + + // struct_buffer // : APPENDSTRUCTUREDBUFFER // | BYTEADDRESSBUFFER diff --git a/hlsl/hlslGrammar.h b/hlsl/hlslGrammar.h index f0adfa0b7..9d5380c10 100755 --- a/hlsl/hlslGrammar.h +++ b/hlsl/hlslGrammar.h @@ -89,6 +89,7 @@ namespace glslang { bool acceptTextureType(TType&); bool acceptSubpassInputType(TType&); bool acceptStructBufferType(TType&); + bool acceptTextureBufferType(TType&); bool acceptConstantBufferType(TType&); bool acceptStruct(TType&, TIntermNode*& nodeList); bool acceptStructDeclarationList(TTypeList*&, TIntermNode*& nodeList, TVector&); diff --git a/hlsl/hlslScanContext.cpp b/hlsl/hlslScanContext.cpp index c16fdfaff..d1e0be6e1 100755 --- a/hlsl/hlslScanContext.cpp +++ b/hlsl/hlslScanContext.cpp @@ -345,6 +345,7 @@ void HlslScanContext::fillInKeywordMap() (*KeywordMap)["RWByteAddressBuffer"] = EHTokRWByteAddressBuffer; (*KeywordMap)["RWStructuredBuffer"] = EHTokRWStructuredBuffer; (*KeywordMap)["StructuredBuffer"] = EHTokStructuredBuffer; + (*KeywordMap)["TextureBuffer"] = EHTokTextureBuffer; (*KeywordMap)["class"] = EHTokClass; (*KeywordMap)["struct"] = EHTokStruct; @@ -829,6 +830,7 @@ EHlslTokenClass HlslScanContext::tokenizeIdentifier() case EHTokRWByteAddressBuffer: case EHTokRWStructuredBuffer: case EHTokStructuredBuffer: + case EHTokTextureBuffer: case EHTokSubpassInput: case EHTokSubpassInputMS: return keyword; diff --git a/hlsl/hlslTokens.h b/hlsl/hlslTokens.h index 1c827bf8c..98450c9a0 100755 --- a/hlsl/hlslTokens.h +++ b/hlsl/hlslTokens.h @@ -283,6 +283,7 @@ enum EHlslTokenClass { EHTokRWByteAddressBuffer, EHTokRWStructuredBuffer, EHTokStructuredBuffer, + EHTokTextureBuffer, // variable, user type, ... EHTokIdentifier,