From ff6dcca5750659306c4c68d9f176d295f5445965 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Alejandro=20Pi=C3=B1eiro?= Date: Thu, 4 Jun 2020 09:39:31 +0200 Subject: [PATCH] spirv: Support initializers on uniforms (#1588) MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit If a uniform has an initializer it will now be given as the optional initializer operand to the OpVariable instruction. Fixes: https://github.com/KhronosGroup/glslang/issues/1259 Signed-off-by: Neil Roberts (the code) Signed-off-by: Alejandro Piñeiro (the tests) Signed-off-by: Arcady Goldmints-Orlov Co-authored-by: Neil Roberts --- SPIRV/GlslangToSpv.cpp | 13 ++- Test/baseResults/spv.uniformInitializer.frag.out | 33 ++++++++ .../spv.uniformInitializerSpecConstant.frag.out | 6 ++ .../spv.uniformInitializerStruct.frag.out | 96 ++++++++++++++++++++++ Test/spv.uniformInitializer.frag | 10 +++ Test/spv.uniformInitializerSpecConstant.frag | 14 ++++ Test/spv.uniformInitializerStruct.frag | 19 +++++ gtests/Spv.FromFile.cpp | 3 + 8 files changed, 193 insertions(+), 1 deletion(-) create mode 100644 Test/baseResults/spv.uniformInitializer.frag.out create mode 100644 Test/baseResults/spv.uniformInitializerSpecConstant.frag.out create mode 100644 Test/baseResults/spv.uniformInitializerStruct.frag.out create mode 100644 Test/spv.uniformInitializer.frag create mode 100644 Test/spv.uniformInitializerSpecConstant.frag create mode 100644 Test/spv.uniformInitializerStruct.frag diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp index 9c4d88e..3e420aa 100644 --- a/SPIRV/GlslangToSpv.cpp +++ b/SPIRV/GlslangToSpv.cpp @@ -3525,7 +3525,18 @@ spv::Id TGlslangToSpvTraverser::createSpvVariable(const glslang::TIntermSymbol* if (glslang::IsAnonymous(name)) name = ""; - return builder.createVariable(storageClass, spvType, name); + spv::Id initializer = spv::NoResult; + + if (node->getType().getQualifier().storage == glslang::EvqUniform && + !node->getConstArray().empty()) { + int nextConst = 0; + initializer = createSpvConstantFromConstUnionArray(node->getType(), + node->getConstArray(), + nextConst, + false /* specConst */); + } + + return builder.createVariable(storageClass, spvType, name, initializer); } // Return type Id of the sampled type. diff --git a/Test/baseResults/spv.uniformInitializer.frag.out b/Test/baseResults/spv.uniformInitializer.frag.out new file mode 100644 index 0000000..ac03a99 --- /dev/null +++ b/Test/baseResults/spv.uniformInitializer.frag.out @@ -0,0 +1,33 @@ +spv.uniformInitializer.frag +// Module Version 10000 +// Generated by (magic number): 80008 +// Id's are bound by 16 + + Capability Shader + 1: ExtInstImport "GLSL.std.450" + MemoryModel Logical GLSL450 + EntryPoint Fragment 4 "main" 9 + ExecutionMode 4 OriginLowerLeft + Source GLSL 450 + Name 4 "main" + Name 9 "color" + Name 14 "in_color" + Decorate 9(color) Location 0 + Decorate 14(in_color) Location 0 + 2: TypeVoid + 3: TypeFunction 2 + 6: TypeFloat 32 + 7: TypeVector 6(float) 4 + 8: TypePointer Output 7(fvec4) + 9(color): 8(ptr) Variable Output + 10: 6(float) Constant 0 + 11: 6(float) Constant 1065353216 + 12: 7(fvec4) ConstantComposite 10 11 10 11 + 13: TypePointer UniformConstant 7(fvec4) + 14(in_color): 13(ptr) Variable UniformConstant 12 + 4(main): 2 Function None 3 + 5: Label + 15: 7(fvec4) Load 14(in_color) + Store 9(color) 15 + Return + FunctionEnd diff --git a/Test/baseResults/spv.uniformInitializerSpecConstant.frag.out b/Test/baseResults/spv.uniformInitializerSpecConstant.frag.out new file mode 100644 index 0000000..1cd053c --- /dev/null +++ b/Test/baseResults/spv.uniformInitializerSpecConstant.frag.out @@ -0,0 +1,6 @@ +spv.uniformInitializerSpecConstant.frag +ERROR: 0:9: '=' : uniform initializers must be constant 'layout( location=4) uniform float' +ERROR: 1 compilation errors. No code generated. + + +SPIR-V is not generated for failed compile or link diff --git a/Test/baseResults/spv.uniformInitializerStruct.frag.out b/Test/baseResults/spv.uniformInitializerStruct.frag.out new file mode 100644 index 0000000..a3e36aa --- /dev/null +++ b/Test/baseResults/spv.uniformInitializerStruct.frag.out @@ -0,0 +1,96 @@ +spv.uniformInitializerStruct.frag +// Module Version 10000 +// Generated by (magic number): 80008 +// Id's are bound by 63 + + Capability Shader + 1: ExtInstImport "GLSL.std.450" + MemoryModel Logical GLSL450 + EntryPoint Fragment 4 "main" 9 + ExecutionMode 4 OriginLowerLeft + Source GLSL 450 + Name 4 "main" + Name 9 "color" + Name 15 "i" + Name 26 "" + MemberName 26 0 "r" + MemberName 26 1 "g" + MemberName 26 2 "b" + Name 34 "parts" + Decorate 9(color) Location 0 + Decorate 34(parts) Location 0 + 2: TypeVoid + 3: TypeFunction 2 + 6: TypeFloat 32 + 7: TypeVector 6(float) 4 + 8: TypePointer Output 7(fvec4) + 9(color): 8(ptr) Variable Output + 10: 6(float) Constant 0 + 11: 6(float) Constant 1065353216 + 12: 7(fvec4) ConstantComposite 10 10 10 11 + 13: TypeInt 32 1 + 14: TypePointer Function 13(int) + 16: 13(int) Constant 0 + 23: 13(int) Constant 2 + 24: TypeBool + 26: TypeStruct 6(float) 6(float) 6(float) + 27: TypeInt 32 0 + 28: 27(int) Constant 2 + 29: TypeArray 26(struct) 28 + 30: 26(struct) ConstantComposite 11 11 11 + 31: 26(struct) ConstantComposite 10 11 10 + 32: 29 ConstantComposite 30 31 + 33: TypePointer UniformConstant 29 + 34(parts): 33(ptr) Variable UniformConstant 32 + 36: TypePointer UniformConstant 6(float) + 39: 27(int) Constant 0 + 40: TypePointer Output 6(float) + 46: 13(int) Constant 1 + 49: 27(int) Constant 1 + 4(main): 2 Function None 3 + 5: Label + 15(i): 14(ptr) Variable Function + Store 9(color) 12 + Store 15(i) 16 + Branch 17 + 17: Label + LoopMerge 19 20 None + Branch 21 + 21: Label + 22: 13(int) Load 15(i) + 25: 24(bool) SLessThan 22 23 + BranchConditional 25 18 19 + 18: Label + 35: 13(int) Load 15(i) + 37: 36(ptr) AccessChain 34(parts) 35 16 + 38: 6(float) Load 37 + 41: 40(ptr) AccessChain 9(color) 39 + 42: 6(float) Load 41 + 43: 6(float) FAdd 42 38 + 44: 40(ptr) AccessChain 9(color) 39 + Store 44 43 + 45: 13(int) Load 15(i) + 47: 36(ptr) AccessChain 34(parts) 45 46 + 48: 6(float) Load 47 + 50: 40(ptr) AccessChain 9(color) 49 + 51: 6(float) Load 50 + 52: 6(float) FAdd 51 48 + 53: 40(ptr) AccessChain 9(color) 49 + Store 53 52 + 54: 13(int) Load 15(i) + 55: 36(ptr) AccessChain 34(parts) 54 23 + 56: 6(float) Load 55 + 57: 40(ptr) AccessChain 9(color) 28 + 58: 6(float) Load 57 + 59: 6(float) FAdd 58 56 + 60: 40(ptr) AccessChain 9(color) 28 + Store 60 59 + Branch 20 + 20: Label + 61: 13(int) Load 15(i) + 62: 13(int) IAdd 61 46 + Store 15(i) 62 + Branch 17 + 19: Label + Return + FunctionEnd diff --git a/Test/spv.uniformInitializer.frag b/Test/spv.uniformInitializer.frag new file mode 100644 index 0000000..cdae1c1 --- /dev/null +++ b/Test/spv.uniformInitializer.frag @@ -0,0 +1,10 @@ +#version 450 + +layout (location = 0) out vec4 color; + +layout (location = 0) uniform vec4 in_color = vec4(0.0, 1.0, 0.0, 1.0); + +void main() +{ + color = in_color; +} diff --git a/Test/spv.uniformInitializerSpecConstant.frag b/Test/spv.uniformInitializerSpecConstant.frag new file mode 100644 index 0000000..289d61a --- /dev/null +++ b/Test/spv.uniformInitializerSpecConstant.frag @@ -0,0 +1,14 @@ +#version 450 + +layout (location = 0) out vec4 color; + +layout (constant_id = 1) const float opacity = 0.5; + +layout (location = 0) uniform vec3 in_color = vec3(1.0, 0.5, 0); + +layout (location = 4) uniform float foo = opacity; + +void main() +{ + color = vec4(in_color, foo); +} diff --git a/Test/spv.uniformInitializerStruct.frag b/Test/spv.uniformInitializerStruct.frag new file mode 100644 index 0000000..b614806 --- /dev/null +++ b/Test/spv.uniformInitializerStruct.frag @@ -0,0 +1,19 @@ +#version 450 + +layout (location = 0) out vec4 color; + +layout (location = 0) uniform struct { + float r; + float g; + float b; +} parts[2] = { { 1.0, 1.0, 1.0}, { 0.0, 1.0, 0.0 } }; + +void main() { + color = vec4(0.0, 0.0, 0.0, 1.0); + + for (int i = 0; i < 2; i++) { + color.r += parts[i].r; + color.g += parts[i].g; + color.b += parts[i].b; + } +} diff --git a/gtests/Spv.FromFile.cpp b/gtests/Spv.FromFile.cpp index 84375a8..5c9fb9b 100644 --- a/gtests/Spv.FromFile.cpp +++ b/gtests/Spv.FromFile.cpp @@ -604,6 +604,9 @@ INSTANTIATE_TEST_CASE_P( "spv.specConst.vert", "spv.specTexture.frag", "spv.OVR_multiview.vert", + "spv.uniformInitializer.frag", + "spv.uniformInitializerSpecConstant.frag", + "spv.uniformInitializerStruct.frag", "spv.xfbOffsetOnBlockMembersAssignment.vert", "spv.xfbOffsetOnStructMembersAssignment.vert", "spv.xfbOverlapOffsetCheckWithBlockAndMember.vert", -- 2.7.4