From f953a021fd01d13c4670a714e661d8fe587b6b7c Mon Sep 17 00:00:00 2001 From: Neil Roberts Date: Wed, 14 Mar 2018 19:06:22 +0100 Subject: [PATCH] spirv: Support initializers on uniforms MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 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) --- SPIRV/GlslangToSpv.cpp | 13 +++++++- SPIRV/SpvBuilder.cpp | 5 ++- SPIRV/SpvBuilder.h | 2 +- .../spv.uniformInitializer.frag.out | 33 +++++++++++++++++++ Test/spv.uniformInitializer.frag | 10 ++++++ gtests/Spv.FromFile.cpp | 1 + 6 files changed, 61 insertions(+), 3 deletions(-) create mode 100644 Test/baseResults/spv.uniformInitializer.frag.out create mode 100644 Test/spv.uniformInitializer.frag diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp index 25ef210555..f8654fea7a 100644 --- a/SPIRV/GlslangToSpv.cpp +++ b/SPIRV/GlslangToSpv.cpp @@ -2996,7 +2996,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/SPIRV/SpvBuilder.cpp b/SPIRV/SpvBuilder.cpp index 138c41c5f6..adcb41b5a2 100644 --- a/SPIRV/SpvBuilder.cpp +++ b/SPIRV/SpvBuilder.cpp @@ -1306,7 +1306,7 @@ void Builder::makeDiscard() } // Comments in header -Id Builder::createVariable(StorageClass storageClass, Id type, const char* name) +Id Builder::createVariable(StorageClass storageClass, Id type, const char* name, Id initializer) { Id pointerType = makePointer(storageClass, type); Instruction* inst = new Instruction(getUniqueId(), pointerType, OpVariable); @@ -1327,6 +1327,9 @@ Id Builder::createVariable(StorageClass storageClass, Id type, const char* name) if (name) addName(inst->getResultId(), name); + if (initializer != NoResult) + inst->addIdOperand(initializer); + return inst->getResultId(); } diff --git a/SPIRV/SpvBuilder.h b/SPIRV/SpvBuilder.h index 52f7fba761..142f3ca66d 100644 --- a/SPIRV/SpvBuilder.h +++ b/SPIRV/SpvBuilder.h @@ -300,7 +300,7 @@ class Builder { void makeDiscard(); // Create a global or function local or IO variable. - Id createVariable(StorageClass, Id type, const char* name = 0); + Id createVariable(StorageClass, Id type, const char* name = 0, Id initializer = NoResult); // Create an intermediate with an undefined value. Id createUndefined(Id type); diff --git a/Test/baseResults/spv.uniformInitializer.frag.out b/Test/baseResults/spv.uniformInitializer.frag.out new file mode 100644 index 0000000000..b1474c6fb6 --- /dev/null +++ b/Test/baseResults/spv.uniformInitializer.frag.out @@ -0,0 +1,33 @@ +spv.uniformInitializer.frag +// Module Version 10000 +// Generated by (magic number): 80007 +// 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/spv.uniformInitializer.frag b/Test/spv.uniformInitializer.frag new file mode 100644 index 0000000000..cdae1c1dac --- /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/gtests/Spv.FromFile.cpp b/gtests/Spv.FromFile.cpp index 4663df63b4..cd387fd6f6 100644 --- a/gtests/Spv.FromFile.cpp +++ b/gtests/Spv.FromFile.cpp @@ -490,6 +490,7 @@ INSTANTIATE_TEST_CASE_P( "spv.rankShift.comp", "spv.specConst.vert", "spv.OVR_multiview.vert", + "spv.uniformInitializer.frag", "spv.xfbOffsetOnBlockMembersAssignment.vert", "spv.xfbOffsetOnStructMembersAssignment.vert", "spv.xfbOverlapOffsetCheckWithBlockAndMember.vert",