From b07baac98d673c4bb8c1dd33bb4a3b09b656e291 Mon Sep 17 00:00:00 2001 From: qining Date: Tue, 22 Mar 2016 14:21:09 -0400 Subject: [PATCH] fix nesting initializer list issue and (fake) type cast in initializer list issue. Note real type casting is still not yet supported as unary operations upon spec constants are not supported yet --- SPIRV/GlslangToSpv.cpp | 12 ++++++++++- .../spv.specConstantComposite.vert.out | 21 ++++++++++++------- Test/spv.specConstantComposite.vert | 12 +++++++++++ glslang/MachineIndependent/ParseHelper.cpp | 9 +++++--- 4 files changed, 42 insertions(+), 12 deletions(-) diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp index b2067e125a..f100881032 100755 --- a/SPIRV/GlslangToSpv.cpp +++ b/SPIRV/GlslangToSpv.cpp @@ -3869,7 +3869,17 @@ spv::Id TGlslangToSpvTraverser::createSpvConstantFromConstSubTree( const_constituents.push_back( createSpvConstantFromConstSubTree((*NI)->getAsTyped())); } - return builder.makeCompositeConstant(typeId, const_constituents, is_spec_const); + // Note that constructors are aggregate nodes, so expressions like: + // float x = float(y) will become an aggregate node. If 'x' is declared + // as a constant, the aggregate node representing 'float(y)' will be + // processed here. + if (builder.isVectorType(typeId) || builder.isMatrixType(typeId) || + builder.isAggregateType(typeId)) { + return builder.makeCompositeConstant(typeId, const_constituents, is_spec_const); + } else { + assert(builder.isScalarType(typeId) && const_constituents.size() == 1); + return const_constituents.front(); + } } else if (const glslang::TIntermBinary* bn = subTree->getAsBinaryNode()) { // Binary operation node, we should generate OpSpecConstantOp diff --git a/Test/baseResults/spv.specConstantComposite.vert.out b/Test/baseResults/spv.specConstantComposite.vert.out index 84b78e40f4..5e2dfa4a76 100644 --- a/Test/baseResults/spv.specConstantComposite.vert.out +++ b/Test/baseResults/spv.specConstantComposite.vert.out @@ -7,13 +7,13 @@ Linked vertex stage: // Module Version 10000 // Generated by (magic number): 80001 -// Id's are bound by 101 +// Id's are bound by 106 Capability Shader Capability Float64 1: ExtInstImport "GLSL.std.450" MemoryModel Logical GLSL450 - EntryPoint Vertex 4 "main" 27 100 + EntryPoint Vertex 4 "main" 27 105 Source GLSL 450 Name 4 "main" Name 6 "refer_primary_spec_const(" @@ -35,7 +35,7 @@ Linked vertex stage: Name 72 "indexable" Name 76 "indexable" Name 83 "len" - Name 100 "global_vec4_array_with_spec_length" + Name 105 "global_vec4_array_with_spec_length" Decorate 21 SpecId 203 Decorate 28 SpecId 200 Decorate 32 SpecId 201 @@ -80,11 +80,16 @@ Linked vertex stage: 88:41(flat_struct) SpecConstantComposite 69 87 43 21 89: 14(int) Constant 10 90:42(nesting_struct) SpecConstantComposite 88 37 89 - 96: 14(int) Constant 3000 - 97:42(nesting_struct) SpecConstantComposite 88 37 96 - 98: TypeArray 25(fvec4) 28 - 99: TypePointer Input 98 -100(global_vec4_array_with_spec_length): 99(ptr) Variable Input + 96: 20(bool) ConstantFalse + 97:41(flat_struct) SpecConstantComposite 28 32 43 96 + 98: 24(float) Constant 1036831949 + 99: 25(fvec4) ConstantComposite 98 98 98 98 + 100:42(nesting_struct) SpecConstantComposite 97 99 28 + 101: 14(int) Constant 3000 + 102:42(nesting_struct) SpecConstantComposite 88 37 101 + 103: TypeArray 25(fvec4) 28 + 104: TypePointer Input 103 +105(global_vec4_array_with_spec_length): 104(ptr) Variable Input 4(main): 2 Function None 3 5: Label Return diff --git a/Test/spv.specConstantComposite.vert b/Test/spv.specConstantComposite.vert index 3d2d94625b..267a01f187 100644 --- a/Test/spv.specConstantComposite.vert +++ b/Test/spv.specConstantComposite.vert @@ -1,11 +1,14 @@ #version 450 +// constant_id specified scalar spec constants layout(constant_id = 200) const int spec_int = 3; layout(constant_id = 201) const float spec_float = 3.14; layout(constant_id = 202) const double spec_double = 3.1415926535897932384626433832795; layout(constant_id = 203) const bool spec_bool = true; +const float cast_spec_float = float(spec_float); + // Flat struct struct flat_struct { int i; @@ -22,16 +25,25 @@ struct nesting_struct { }; // Expect OpSpecConstantComposite +// Flat struct initializer const flat_struct spec_flat_struct_all_spec = {spec_int, spec_float, spec_double, spec_bool}; const flat_struct spec_flat_struct_partial_spec = {30, 30.14, spec_double, spec_bool}; +// Nesting struct initializer +const nesting_struct nesting_struct_ctor = { + {spec_int, spec_float, spec_double, false}, + vec4(0.1, 0.1, 0.1, 0.1), + spec_int}; + +// Vector constructor const vec4 spec_vec4_all_spec = vec4(spec_float, spec_float, spec_float, spec_float); const vec4 spec_vec4_partial_spec = vec4(spec_float, spec_float, 300.14, 300.14); +// Struct nesting constructor const nesting_struct spec_nesting_struct_all_spec = { spec_flat_struct_all_spec, spec_vec4_all_spec, spec_int}; const nesting_struct spec_nesting_struct_partial_spec = { diff --git a/glslang/MachineIndependent/ParseHelper.cpp b/glslang/MachineIndependent/ParseHelper.cpp index d276d88972..5de89e1b32 100644 --- a/glslang/MachineIndependent/ParseHelper.cpp +++ b/glslang/MachineIndependent/ParseHelper.cpp @@ -5120,7 +5120,8 @@ TIntermTyped* TParseContext::addConstructor(const TSourceLoc& loc, TIntermNode* // We don't know "top down" whether type is a specialization constant, // but a const becomes a specialization constant if any of its children are. - bool specConst = false; + bool hasSpecConst = false; + bool isConstConstrutor = true; for (TIntermSequence::iterator p = sequenceVector.begin(); p != sequenceVector.end(); p++, paramCount++) { @@ -5133,14 +5134,16 @@ TIntermTyped* TParseContext::addConstructor(const TSourceLoc& loc, TIntermNode* if (newNode) { *p = newNode; + if (! newNode->getType().getQualifier().isConstant()) + isConstConstrutor = false; if (newNode->getType().getQualifier().isSpecConstant()) - specConst = true; + hasSpecConst = true; } else return nullptr; } TIntermTyped* constructor = intermediate.setAggregateOperator(aggrNode, op, type, loc); - if (constructor->getType().getQualifier().isConstant() && specConst) + if (isConstConstrutor && hasSpecConst) constructor->getWritableType().getQualifier().makeSpecConstant(); return constructor;