diff --git a/Test/baseResults/constFold.frag.out b/Test/baseResults/constFold.frag.out index c03d865d..f5c3e9c5 100644 --- a/Test/baseResults/constFold.frag.out +++ b/Test/baseResults/constFold.frag.out @@ -270,6 +270,14 @@ ERROR: node is still EOpNull! 0:128 76.000000 0:128 59.000000 0:128 88.000000 +0:138 Function Definition: foo4( (global void) +0:138 Function Parameters: +0:140 Sequence +0:140 Sequence +0:140 move second child to first child (temp int) +0:140 'a' (temp int) +0:140 Constant: +0:140 9 (const int) 0:? Linker Objects 0:? 'a' (const int) 0:? 1 (const int) @@ -356,6 +364,16 @@ ERROR: node is still EOpNull! 0:? 13.000000 0:? 14.000000 0:? 15.000000 +0:? 'a0' (const 3-element array of structure{global int i, global float f, global bool b}) +0:? 3 (const int) +0:? 2.000000 +0:? true (const bool) +0:? 1 (const int) +0:? 5.000000 +0:? true (const bool) +0:? 1 (const int) +0:? 9.000000 +0:? false (const bool) Linked fragment stage: @@ -622,6 +640,14 @@ ERROR: node is still EOpNull! 0:128 76.000000 0:128 59.000000 0:128 88.000000 +0:138 Function Definition: foo4( (global void) +0:138 Function Parameters: +0:140 Sequence +0:140 Sequence +0:140 move second child to first child (temp int) +0:140 'a' (temp int) +0:140 Constant: +0:140 9 (const int) 0:? Linker Objects 0:? 'a' (const int) 0:? 1 (const int) @@ -708,4 +734,14 @@ ERROR: node is still EOpNull! 0:? 13.000000 0:? 14.000000 0:? 15.000000 +0:? 'a0' (const 3-element array of structure{global int i, global float f, global bool b}) +0:? 3 (const int) +0:? 2.000000 +0:? true (const bool) +0:? 1 (const int) +0:? 5.000000 +0:? true (const bool) +0:? 1 (const int) +0:? 9.000000 +0:? false (const bool) diff --git a/Test/constFold.frag b/Test/constFold.frag index 81c718c9..97c3b2b6 100644 --- a/Test/constFold.frag +++ b/Test/constFold.frag @@ -127,3 +127,15 @@ void foo3() { mat3x2 r32 = mm2 * mm32; } + +struct cag { + int i; + float f; + bool b; +}; +const cag a0[3] = cag[3](cag(3, 2.0, true), cag(1, 5.0, true), cag(1, 9.0, false)); + +void foo4() +{ + int a = int(a0[2].f); +} \ No newline at end of file diff --git a/glslang/MachineIndependent/Constant.cpp b/glslang/MachineIndependent/Constant.cpp index a0bb8ded..b4d0695c 100644 --- a/glslang/MachineIndependent/Constant.cpp +++ b/glslang/MachineIndependent/Constant.cpp @@ -852,7 +852,7 @@ TIntermTyped* TIntermediate::foldConstructor(TIntermAggregate* aggrNode) // // Constant folding of a bracket (array-style) dereference or struct-like dot -// dereference. Can handle any thing except a multi-character swizzle, though +// dereference. Can handle anything except a multi-character swizzle, though // all swizzles may go to foldSwizzle(). // TIntermTyped* TIntermediate::foldDereference(TIntermTyped* node, int index, const TSourceLoc& loc) @@ -861,14 +861,19 @@ TIntermTyped* TIntermediate::foldDereference(TIntermTyped* node, int index, cons dereferencedType.getQualifier().storage = EvqConst; TIntermTyped* result = 0; int size = dereferencedType.computeNumComponents(); - + + // arrays, vectors, matrices, all use simple multiplicative math + // while structures need to add up heterogeneous members int start; - if (node->isStruct()) { + if (node->isArray() || ! node->isStruct()) + start = size * index; + else { + // it is a structure + assert(node->isStruct()); start = 0; for (int i = 0; i < index; ++i) start += (*node->getType().getStruct())[i].type->computeNumComponents(); - } else - start = size * index; + } result = addConstantUnion(TConstUnionArray(node->getAsConstantUnion()->getConstArray(), start, size), node->getType(), loc);