GL_ARB_enhanced_layouts, part 6: Numerical side of uniform offset and align semantics. Included
- moving offset calculations for std140/std430 from reflection to linkValidate.cpp - applying the offset/align rules on top of std140/std430 - removing caching the structure's number of components (and correcting that this is components, not size) git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@25174 e7fa87d3-cd2b-0410-9028-fcbf551c1848
This commit is contained in:
parent
04b1c6ed4c
commit
ac1e188f3b
15 changed files with 367 additions and 219 deletions
|
|
@ -79,13 +79,58 @@ uniform ubl11 {
|
||||||
|
|
||||||
layout(std140) uniform block {
|
layout(std140) uniform block {
|
||||||
vec4 a; // a takes offsets 0-15
|
vec4 a; // a takes offsets 0-15
|
||||||
layout(offset = 20) vec3 b; // b takes offsets 32-43
|
layout(offset = 32) vec3 b; // b takes offsets 32-43
|
||||||
layout(offset = 40) vec2 c; // ERROR, lies within previous member
|
layout(offset = 40) vec2 c; // ERROR, lies within previous member
|
||||||
|
layout(align = 6) double g; // ERROR, 6 is not a power of 2
|
||||||
|
layout(offset=68) double h; // ERROR, offset not aligned
|
||||||
|
} specExampleErrors;
|
||||||
|
|
||||||
|
layout(std140) uniform block2 {
|
||||||
|
vec4 a; // a takes offsets 0-15
|
||||||
|
layout(offset = 32) vec3 b; // b takes offsets 32-43
|
||||||
layout(offset = 48) vec2 d; // d takes offsets 48-55
|
layout(offset = 48) vec2 d; // d takes offsets 48-55
|
||||||
layout(align = 16) float e; // e takes offsets 64-67
|
layout(align = 16) float e; // e takes offsets 64-67
|
||||||
layout(align = 2) double f; // f takes offsets 72-79
|
layout(align = 2) double f; // f takes offsets 72-79
|
||||||
layout(align = 6) double g; // ERROR, 6 is not a power of 2
|
|
||||||
layout(offset = 80) float h; // h takes offsets 80-83
|
layout(offset = 80) float h; // h takes offsets 80-83
|
||||||
layout(align = 64) dvec3 i; // i takes offsets 128-151
|
layout(align = 64) dvec3 i; // i takes offsets 128-151
|
||||||
layout(offset = 153, align = 8) float j; // j takes offsets 160-163
|
layout(offset = 164, align = 8) float j; // j takes offsets 168-171
|
||||||
} specExample;
|
} specExample;
|
||||||
|
|
||||||
|
layout(std430) uniform block430 {
|
||||||
|
vec4 a; // a takes offsets 0-15
|
||||||
|
layout(offset = 32) vec3 b; // b takes offsets 32-43
|
||||||
|
layout(offset = 40) vec2 c; // ERROR, lies within previous member
|
||||||
|
layout(align = 6) double g; // ERROR, 6 is not a power of 2
|
||||||
|
layout(offset=68) double h; // ERROR, offset not aligned
|
||||||
|
} specExampleErrors430;
|
||||||
|
|
||||||
|
layout(std430) uniform block2430 {
|
||||||
|
vec4 a; // a takes offsets 0-15
|
||||||
|
layout(offset = 32) vec3 b; // b takes offsets 32-43
|
||||||
|
layout(offset = 48) vec2 d; // d takes offsets 48-55
|
||||||
|
layout(align = 16) float e; // e takes offsets 64-67
|
||||||
|
layout(align = 2) double f; // f takes offsets 72-79
|
||||||
|
layout(offset = 80) float h; // h takes offsets 80-83
|
||||||
|
layout(align = 64) dvec3 i; // i takes offsets 128-151
|
||||||
|
layout(offset = 164, align = 8) float j; // j takes offsets 168-171
|
||||||
|
} specExample430;
|
||||||
|
|
||||||
|
layout(std430, align = 128) uniform block24300 {
|
||||||
|
vec4 a;
|
||||||
|
vec3 b;
|
||||||
|
vec2 d;
|
||||||
|
float e;
|
||||||
|
double f;
|
||||||
|
float h;
|
||||||
|
dvec3 i;
|
||||||
|
} specExample4300;
|
||||||
|
|
||||||
|
layout(std430, align = 128) uniform block24301 {
|
||||||
|
vec4 a;
|
||||||
|
vec3 b;
|
||||||
|
vec2 d;
|
||||||
|
layout(offset=388) float e;
|
||||||
|
layout(align=8) double f;
|
||||||
|
float h;
|
||||||
|
dvec3 i;
|
||||||
|
} specExample4301;
|
||||||
|
|
|
||||||
|
|
@ -32,12 +32,12 @@ ERROR: node is still EOpNull!
|
||||||
0:46 add (highp 4X4 matrix of float)
|
0:46 add (highp 4X4 matrix of float)
|
||||||
0:46 add (highp 4X4 matrix of float)
|
0:46 add (highp 4X4 matrix of float)
|
||||||
0:46 add (highp 4X4 matrix of float)
|
0:46 add (highp 4X4 matrix of float)
|
||||||
0:46 M1: direct index for structure (layout(row_major std140 ) uniform highp 4X4 matrix of float)
|
0:46 M1: direct index for structure (layout(row_major std140 offset=0 ) uniform highp 4X4 matrix of float)
|
||||||
0:46 'tblock' (layout(row_major std140 ) uniform block{layout(row_major std140 ) uniform highp 4X4 matrix of float M1, layout(column_major std140 ) uniform highp 4X4 matrix of float M2, layout(row_major std140 ) uniform highp 3X3 matrix of float N1, layout(row_major std140 ) centroid uniform highp float badf, layout(row_major std140 ) uniform highp float badg, layout(row_major std140 ) uniform highp float bad1, layout(row_major shared ) uniform highp float bad2, layout(row_major packed ) uniform highp float bad3})
|
0:46 'tblock' (layout(row_major std140 ) uniform block{layout(row_major std140 offset=0 ) uniform highp 4X4 matrix of float M1, layout(column_major std140 offset=64 ) uniform highp 4X4 matrix of float M2, layout(row_major std140 offset=128 ) uniform highp 3X3 matrix of float N1, layout(row_major std140 offset=176 ) centroid uniform highp float badf, layout(row_major std140 offset=180 ) uniform highp float badg, layout(row_major std140 offset=184 ) uniform highp float bad1, layout(row_major shared offset=188 ) uniform highp float bad2, layout(row_major packed offset=192 ) uniform highp float bad3})
|
||||||
0:46 Constant:
|
0:46 Constant:
|
||||||
0:46 0 (const int)
|
0:46 0 (const int)
|
||||||
0:46 M2: direct index for structure (layout(column_major std140 ) uniform highp 4X4 matrix of float)
|
0:46 M2: direct index for structure (layout(column_major std140 offset=64 ) uniform highp 4X4 matrix of float)
|
||||||
0:46 'tblock' (layout(row_major std140 ) uniform block{layout(row_major std140 ) uniform highp 4X4 matrix of float M1, layout(column_major std140 ) uniform highp 4X4 matrix of float M2, layout(row_major std140 ) uniform highp 3X3 matrix of float N1, layout(row_major std140 ) centroid uniform highp float badf, layout(row_major std140 ) uniform highp float badg, layout(row_major std140 ) uniform highp float bad1, layout(row_major shared ) uniform highp float bad2, layout(row_major packed ) uniform highp float bad3})
|
0:46 'tblock' (layout(row_major std140 ) uniform block{layout(row_major std140 offset=0 ) uniform highp 4X4 matrix of float M1, layout(column_major std140 offset=64 ) uniform highp 4X4 matrix of float M2, layout(row_major std140 offset=128 ) uniform highp 3X3 matrix of float N1, layout(row_major std140 offset=176 ) centroid uniform highp float badf, layout(row_major std140 offset=180 ) uniform highp float badg, layout(row_major std140 offset=184 ) uniform highp float bad1, layout(row_major shared offset=188 ) uniform highp float bad2, layout(row_major packed offset=192 ) uniform highp float bad3})
|
||||||
0:46 Constant:
|
0:46 Constant:
|
||||||
0:46 1 (const int)
|
0:46 1 (const int)
|
||||||
0:46 M4: direct index for structure (layout(row_major shared ) uniform highp 4X4 matrix of float)
|
0:46 M4: direct index for structure (layout(row_major shared ) uniform highp 4X4 matrix of float)
|
||||||
|
|
@ -56,8 +56,8 @@ ERROR: node is still EOpNull!
|
||||||
0:47 'color' (smooth out highp 3-component vector of float)
|
0:47 'color' (smooth out highp 3-component vector of float)
|
||||||
0:47 vector-times-matrix (highp 3-component vector of float)
|
0:47 vector-times-matrix (highp 3-component vector of float)
|
||||||
0:47 'c' (layout(location=7 ) in highp 3-component vector of float)
|
0:47 'c' (layout(location=7 ) in highp 3-component vector of float)
|
||||||
0:47 N1: direct index for structure (layout(row_major std140 ) uniform highp 3X3 matrix of float)
|
0:47 N1: direct index for structure (layout(row_major std140 offset=128 ) uniform highp 3X3 matrix of float)
|
||||||
0:47 'tblock' (layout(row_major std140 ) uniform block{layout(row_major std140 ) uniform highp 4X4 matrix of float M1, layout(column_major std140 ) uniform highp 4X4 matrix of float M2, layout(row_major std140 ) uniform highp 3X3 matrix of float N1, layout(row_major std140 ) centroid uniform highp float badf, layout(row_major std140 ) uniform highp float badg, layout(row_major std140 ) uniform highp float bad1, layout(row_major shared ) uniform highp float bad2, layout(row_major packed ) uniform highp float bad3})
|
0:47 'tblock' (layout(row_major std140 ) uniform block{layout(row_major std140 offset=0 ) uniform highp 4X4 matrix of float M1, layout(column_major std140 offset=64 ) uniform highp 4X4 matrix of float M2, layout(row_major std140 offset=128 ) uniform highp 3X3 matrix of float N1, layout(row_major std140 offset=176 ) centroid uniform highp float badf, layout(row_major std140 offset=180 ) uniform highp float badg, layout(row_major std140 offset=184 ) uniform highp float bad1, layout(row_major shared offset=188 ) uniform highp float bad2, layout(row_major packed offset=192 ) uniform highp float bad3})
|
||||||
0:47 Constant:
|
0:47 Constant:
|
||||||
0:47 2 (const int)
|
0:47 2 (const int)
|
||||||
0:? Linker Objects
|
0:? Linker Objects
|
||||||
|
|
@ -68,7 +68,7 @@ ERROR: node is still EOpNull!
|
||||||
0:? 'pos' (smooth out highp 4-component vector of float)
|
0:? 'pos' (smooth out highp 4-component vector of float)
|
||||||
0:? 'color' (smooth out highp 3-component vector of float)
|
0:? 'color' (smooth out highp 3-component vector of float)
|
||||||
0:? 'badm4' (layout(column_major shared ) uniform highp 4X4 matrix of float)
|
0:? 'badm4' (layout(column_major shared ) uniform highp 4X4 matrix of float)
|
||||||
0:? 'tblock' (layout(row_major std140 ) uniform block{layout(row_major std140 ) uniform highp 4X4 matrix of float M1, layout(column_major std140 ) uniform highp 4X4 matrix of float M2, layout(row_major std140 ) uniform highp 3X3 matrix of float N1, layout(row_major std140 ) centroid uniform highp float badf, layout(row_major std140 ) uniform highp float badg, layout(row_major std140 ) uniform highp float bad1, layout(row_major shared ) uniform highp float bad2, layout(row_major packed ) uniform highp float bad3})
|
0:? 'tblock' (layout(row_major std140 ) uniform block{layout(row_major std140 offset=0 ) uniform highp 4X4 matrix of float M1, layout(column_major std140 offset=64 ) uniform highp 4X4 matrix of float M2, layout(row_major std140 offset=128 ) uniform highp 3X3 matrix of float N1, layout(row_major std140 offset=176 ) centroid uniform highp float badf, layout(row_major std140 offset=180 ) uniform highp float badg, layout(row_major std140 offset=184 ) uniform highp float bad1, layout(row_major shared offset=188 ) uniform highp float bad2, layout(row_major packed offset=192 ) uniform highp float bad3})
|
||||||
0:? '__anon__0' (layout(row_major shared ) uniform block{layout(row_major shared ) uniform bool b, layout(row_major shared ) uniform highp 4X4 matrix of float t2m})
|
0:? '__anon__0' (layout(row_major shared ) uniform block{layout(row_major shared ) uniform bool b, layout(row_major shared ) uniform highp 4X4 matrix of float t2m})
|
||||||
0:? '__anon__2' (out block{out highp float f})
|
0:? '__anon__2' (out block{out highp float f})
|
||||||
0:? 'badoutA' (layout(location=10 ) smooth out highp 4-component vector of float)
|
0:? 'badoutA' (layout(location=10 ) smooth out highp 4-component vector of float)
|
||||||
|
|
|
||||||
|
|
@ -39,8 +39,13 @@ ERROR: 0:58: 'align' : can only be used with std140 or std430 layout packing
|
||||||
ERROR: 0:63: 'align' : can only be used with std140 or std430 layout packing
|
ERROR: 0:63: 'align' : can only be used with std140 or std430 layout packing
|
||||||
ERROR: 0:62: 'layout' : offset/align can only be used on a uniform or buffer
|
ERROR: 0:62: 'layout' : offset/align can only be used on a uniform or buffer
|
||||||
ERROR: 0:63: 'layout' : offset/align can only be used on a uniform or buffer
|
ERROR: 0:63: 'layout' : offset/align can only be used on a uniform or buffer
|
||||||
ERROR: 0:87: 'align' : must be a power of 2
|
ERROR: 0:84: 'align' : must be a power of 2
|
||||||
ERROR: 40 compilation errors. No code generated.
|
ERROR: 0:83: 'offset' : cannot lie in previous members
|
||||||
|
ERROR: 0:85: 'offset' : must be a multiple of the member's alignment
|
||||||
|
ERROR: 0:103: 'align' : must be a power of 2
|
||||||
|
ERROR: 0:102: 'offset' : cannot lie in previous members
|
||||||
|
ERROR: 0:104: 'offset' : must be a multiple of the member's alignment
|
||||||
|
ERROR: 45 compilation errors. No code generated.
|
||||||
|
|
||||||
|
|
||||||
ERROR: node is still EOpNull!
|
ERROR: node is still EOpNull!
|
||||||
|
|
@ -56,7 +61,7 @@ ERROR: node is still EOpNull!
|
||||||
0:? 'inst1' (layout(column_major shared offset=12 ) uniform block{layout(column_major shared ) uniform int a})
|
0:? 'inst1' (layout(column_major shared offset=12 ) uniform block{layout(column_major shared ) uniform int a})
|
||||||
0:? 'inst2' (layout(offset=12 ) in block{in int a})
|
0:? 'inst2' (layout(offset=12 ) in block{in int a})
|
||||||
0:? 'inst3' (layout(offset=12 ) out block{out int a})
|
0:? 'inst3' (layout(offset=12 ) out block{out int a})
|
||||||
0:? 'inst4' (layout(column_major std140 align=16 ) uniform block{layout(column_major std140 align=16 ) uniform int a})
|
0:? 'inst4' (layout(column_major std140 align=16 ) uniform block{layout(column_major std140 offset=0 align=16 ) uniform int a})
|
||||||
0:? 'inst8' (layout(column_major shared align=16 ) uniform block{layout(column_major shared ) uniform int a})
|
0:? 'inst8' (layout(column_major shared align=16 ) uniform block{layout(column_major shared ) uniform int a})
|
||||||
0:? 'inst5' (layout(align=16 ) in block{in int a})
|
0:? 'inst5' (layout(align=16 ) in block{in int a})
|
||||||
0:? 'inst6' (layout(align=16 ) out block{out int a})
|
0:? 'inst6' (layout(align=16 ) out block{out int a})
|
||||||
|
|
@ -71,7 +76,12 @@ ERROR: node is still EOpNull!
|
||||||
0:? 'inst10' (in block{layout(offset=12 ) in float f, layout(align=4 ) in float g})
|
0:? 'inst10' (in block{layout(offset=12 ) in float f, layout(align=4 ) in float g})
|
||||||
0:? 'inst9' (layout(column_major std430 align=32 ) uniform block{layout(column_major std430 align=32 ) uniform float e, layout(column_major std430 offset=12 align=4 ) uniform float f, layout(column_major std430 offset=20 align=32 ) uniform float g, layout(column_major std430 align=32 ) uniform float h})
|
0:? 'inst9' (layout(column_major std430 align=32 ) uniform block{layout(column_major std430 align=32 ) uniform float e, layout(column_major std430 offset=12 align=4 ) uniform float f, layout(column_major std430 offset=20 align=32 ) uniform float g, layout(column_major std430 align=32 ) uniform float h})
|
||||||
0:? 'inst11' (layout(column_major std430 ) uniform block{layout(column_major std430 offset=12 align=4 ) uniform float f, layout(column_major std430 ) uniform float g})
|
0:? 'inst11' (layout(column_major std430 ) uniform block{layout(column_major std430 offset=12 align=4 ) uniform float f, layout(column_major std430 ) uniform float g})
|
||||||
0:? 'specExample' (layout(column_major std140 ) uniform block{layout(column_major std140 ) uniform 4-component vector of float a, layout(column_major std140 offset=20 ) uniform 3-component vector of float b, layout(column_major std140 offset=40 ) uniform 2-component vector of float c, layout(column_major std140 offset=48 ) uniform 2-component vector of float d, layout(column_major std140 align=16 ) uniform float e, layout(column_major std140 align=2 ) uniform double f, layout(column_major std140 ) uniform double g, layout(column_major std140 offset=80 ) uniform float h, layout(column_major std140 align=64 ) uniform 3-component vector of double i, layout(column_major std140 offset=153 align=8 ) uniform float j})
|
0:? 'specExampleErrors' (layout(column_major std140 ) uniform block{layout(column_major std140 offset=0 ) uniform 4-component vector of float a, layout(column_major std140 offset=32 ) uniform 3-component vector of float b, layout(column_major std140 offset=48 ) uniform 2-component vector of float c, layout(column_major std140 offset=56 ) uniform double g, layout(column_major std140 offset=72 ) uniform double h})
|
||||||
|
0:? 'specExample' (layout(column_major std140 ) uniform block{layout(column_major std140 offset=0 ) uniform 4-component vector of float a, layout(column_major std140 offset=32 ) uniform 3-component vector of float b, layout(column_major std140 offset=48 ) uniform 2-component vector of float d, layout(column_major std140 offset=64 align=16 ) uniform float e, layout(column_major std140 offset=72 align=2 ) uniform double f, layout(column_major std140 offset=80 ) uniform float h, layout(column_major std140 offset=128 align=64 ) uniform 3-component vector of double i, layout(column_major std140 offset=168 align=8 ) uniform float j})
|
||||||
|
0:? 'specExampleErrors430' (layout(column_major std430 ) uniform block{layout(column_major std430 offset=0 ) uniform 4-component vector of float a, layout(column_major std430 offset=32 ) uniform 3-component vector of float b, layout(column_major std430 offset=48 ) uniform 2-component vector of float c, layout(column_major std430 offset=56 ) uniform double g, layout(column_major std430 offset=72 ) uniform double h})
|
||||||
|
0:? 'specExample430' (layout(column_major std430 ) uniform block{layout(column_major std430 offset=0 ) uniform 4-component vector of float a, layout(column_major std430 offset=32 ) uniform 3-component vector of float b, layout(column_major std430 offset=48 ) uniform 2-component vector of float d, layout(column_major std430 offset=64 align=16 ) uniform float e, layout(column_major std430 offset=72 align=2 ) uniform double f, layout(column_major std430 offset=80 ) uniform float h, layout(column_major std430 offset=128 align=64 ) uniform 3-component vector of double i, layout(column_major std430 offset=168 align=8 ) uniform float j})
|
||||||
|
0:? 'specExample4300' (layout(column_major std430 align=128 ) uniform block{layout(column_major std430 offset=0 align=128 ) uniform 4-component vector of float a, layout(column_major std430 offset=128 align=128 ) uniform 3-component vector of float b, layout(column_major std430 offset=256 align=128 ) uniform 2-component vector of float d, layout(column_major std430 offset=384 align=128 ) uniform float e, layout(column_major std430 offset=512 align=128 ) uniform double f, layout(column_major std430 offset=640 align=128 ) uniform float h, layout(column_major std430 offset=768 align=128 ) uniform 3-component vector of double i})
|
||||||
|
0:? 'specExample4301' (layout(column_major std430 align=128 ) uniform block{layout(column_major std430 offset=0 align=128 ) uniform 4-component vector of float a, layout(column_major std430 offset=128 align=128 ) uniform 3-component vector of float b, layout(column_major std430 offset=256 align=128 ) uniform 2-component vector of float d, layout(column_major std430 offset=512 align=128 ) uniform float e, layout(column_major std430 offset=520 align=8 ) uniform double f, layout(column_major std430 offset=640 align=128 ) uniform float h, layout(column_major std430 offset=768 align=128 ) uniform 3-component vector of double i})
|
||||||
|
|
||||||
|
|
||||||
Linked fragment stage:
|
Linked fragment stage:
|
||||||
|
|
|
||||||
|
|
@ -289,7 +289,7 @@ ERROR: node is still EOpNull!
|
||||||
0:? 'var5' (smooth out 4-component vector of float)
|
0:? 'var5' (smooth out 4-component vector of float)
|
||||||
0:? '__anon__2' (out block{out 4-component vector of float var6})
|
0:? '__anon__2' (out block{out 4-component vector of float var6})
|
||||||
0:? 'var7' (smooth out 4-component vector of float)
|
0:? 'var7' (smooth out 4-component vector of float)
|
||||||
0:? '__anon__3' (layout(row_major std140 ) uniform block{layout(row_major std140 ) uniform 4X4 matrix of float M1, layout(column_major std140 ) uniform 4X4 matrix of float M2, layout(row_major std140 ) uniform 3X3 matrix of float N1})
|
0:? '__anon__3' (layout(row_major std140 ) uniform block{layout(row_major std140 offset=0 ) uniform 4X4 matrix of float M1, layout(column_major std140 offset=64 ) uniform 4X4 matrix of float M2, layout(row_major std140 offset=128 ) uniform 3X3 matrix of float N1})
|
||||||
0:? '__anon__4' (layout(column_major shared ) uniform block{layout(column_major shared ) uniform 4X4 matrix of float M13, layout(row_major shared ) uniform 4X4 matrix of float m14, layout(column_major shared ) uniform 3X3 matrix of float N12})
|
0:? '__anon__4' (layout(column_major shared ) uniform block{layout(column_major shared ) uniform 4X4 matrix of float M13, layout(row_major shared ) uniform 4X4 matrix of float m14, layout(column_major shared ) uniform 3X3 matrix of float N12})
|
||||||
0:? 's17' (layout(binding=3 ) uniform sampler2D)
|
0:? 's17' (layout(binding=3 ) uniform sampler2D)
|
||||||
0:? 'a2' (layout(binding=2 offset=4 ) uniform int)
|
0:? 'a2' (layout(binding=2 offset=4 ) uniform int)
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@
|
||||||
|
|
||||||
namespace glslang {
|
namespace glslang {
|
||||||
|
|
||||||
const int GlslangMaxTypeLength = 200;
|
const int GlslangMaxTypeLength = 200; // TODO: need to print block/struct one member per line, so this can stay bounded
|
||||||
|
|
||||||
//
|
//
|
||||||
// Details within a sampler type
|
// Details within a sampler type
|
||||||
|
|
@ -643,7 +643,7 @@ public:
|
||||||
// for "empty" type (no args) or simple scalar/vector/matrix
|
// for "empty" type (no args) or simple scalar/vector/matrix
|
||||||
explicit TType(TBasicType t = EbtVoid, TStorageQualifier q = EvqTemporary, int vs = 1, int mc = 0, int mr = 0) :
|
explicit TType(TBasicType t = EbtVoid, TStorageQualifier q = EvqTemporary, int vs = 1, int mc = 0, int mr = 0) :
|
||||||
basicType(t), vectorSize(vs), matrixCols(mc), matrixRows(mr), arraySizes(0),
|
basicType(t), vectorSize(vs), matrixCols(mc), matrixRows(mr), arraySizes(0),
|
||||||
structure(0), structureSize(0), fieldName(0), typeName(0)
|
structure(0), fieldName(0), typeName(0)
|
||||||
{
|
{
|
||||||
sampler.clear();
|
sampler.clear();
|
||||||
qualifier.clear();
|
qualifier.clear();
|
||||||
|
|
@ -652,7 +652,7 @@ public:
|
||||||
// for explicit precision qualifier
|
// for explicit precision qualifier
|
||||||
TType(TBasicType t, TStorageQualifier q, TPrecisionQualifier p, int vs = 1, int mc = 0, int mr = 0) :
|
TType(TBasicType t, TStorageQualifier q, TPrecisionQualifier p, int vs = 1, int mc = 0, int mr = 0) :
|
||||||
basicType(t), vectorSize(vs), matrixCols(mc), matrixRows(mr), arraySizes(0),
|
basicType(t), vectorSize(vs), matrixCols(mc), matrixRows(mr), arraySizes(0),
|
||||||
structure(0), structureSize(0), fieldName(0), typeName(0)
|
structure(0), fieldName(0), typeName(0)
|
||||||
{
|
{
|
||||||
sampler.clear();
|
sampler.clear();
|
||||||
qualifier.clear();
|
qualifier.clear();
|
||||||
|
|
@ -663,7 +663,7 @@ public:
|
||||||
// for turning a TPublicType into a TType
|
// for turning a TPublicType into a TType
|
||||||
explicit TType(const TPublicType& p) :
|
explicit TType(const TPublicType& p) :
|
||||||
basicType(p.basicType), vectorSize(p.vectorSize), matrixCols(p.matrixCols), matrixRows(p.matrixRows), arraySizes(p.arraySizes),
|
basicType(p.basicType), vectorSize(p.vectorSize), matrixCols(p.matrixCols), matrixRows(p.matrixRows), arraySizes(p.arraySizes),
|
||||||
structure(0), structureSize(0), fieldName(0), typeName(0)
|
structure(0), fieldName(0), typeName(0)
|
||||||
{
|
{
|
||||||
if (basicType == EbtSampler)
|
if (basicType == EbtSampler)
|
||||||
sampler = p.sampler;
|
sampler = p.sampler;
|
||||||
|
|
@ -723,7 +723,6 @@ public:
|
||||||
matrixRows = copyOf.matrixRows;
|
matrixRows = copyOf.matrixRows;
|
||||||
arraySizes = copyOf.arraySizes;
|
arraySizes = copyOf.arraySizes;
|
||||||
structure = copyOf.structure;
|
structure = copyOf.structure;
|
||||||
structureSize = copyOf.structureSize;
|
|
||||||
fieldName = copyOf.fieldName;
|
fieldName = copyOf.fieldName;
|
||||||
typeName = copyOf.typeName;
|
typeName = copyOf.typeName;
|
||||||
}
|
}
|
||||||
|
|
@ -1015,24 +1014,25 @@ public:
|
||||||
TTypeList* getStruct() { return structure; }
|
TTypeList* getStruct() { return structure; }
|
||||||
TTypeList* getStruct() const { return structure; }
|
TTypeList* getStruct() const { return structure; }
|
||||||
|
|
||||||
int getObjectSize() const
|
int computeNumComponents() const
|
||||||
{
|
{
|
||||||
int totalSize;
|
int components = 0;
|
||||||
|
|
||||||
if (getBasicType() == EbtStruct || getBasicType() == EbtBlock)
|
if (getBasicType() == EbtStruct || getBasicType() == EbtBlock) {
|
||||||
totalSize = getStructSize();
|
for (TTypeList::iterator tl = getStruct()->begin(); tl != getStruct()->end(); tl++)
|
||||||
else if (matrixCols)
|
components += ((*tl).type)->computeNumComponents();
|
||||||
totalSize = matrixCols * matrixRows;
|
} else if (matrixCols)
|
||||||
|
components = matrixCols * matrixRows;
|
||||||
else
|
else
|
||||||
totalSize = vectorSize;
|
components = vectorSize;
|
||||||
|
|
||||||
if (isArray()) {
|
if (isArray()) {
|
||||||
// this function can only be used in paths that don't allow unsized arrays
|
// this function can only be used in paths that don't allow unsized arrays
|
||||||
assert(getArraySize() > 0);
|
assert(getArraySize() > 0);
|
||||||
totalSize *= getArraySize();
|
components *= getArraySize();
|
||||||
}
|
}
|
||||||
|
|
||||||
return totalSize;
|
return components;
|
||||||
}
|
}
|
||||||
|
|
||||||
// append this type's mangled name to the passed in 'name'
|
// append this type's mangled name to the passed in 'name'
|
||||||
|
|
@ -1117,7 +1117,6 @@ protected:
|
||||||
TType& operator=(const TType& type);
|
TType& operator=(const TType& type);
|
||||||
|
|
||||||
void buildMangledName(TString&);
|
void buildMangledName(TString&);
|
||||||
int getStructSize() const;
|
|
||||||
|
|
||||||
TBasicType basicType : 8;
|
TBasicType basicType : 8;
|
||||||
int vectorSize : 4;
|
int vectorSize : 4;
|
||||||
|
|
@ -1129,7 +1128,6 @@ protected:
|
||||||
TArraySizes* arraySizes;
|
TArraySizes* arraySizes;
|
||||||
|
|
||||||
TTypeList* structure; // 0 unless this is a struct
|
TTypeList* structure; // 0 unless this is a struct
|
||||||
mutable int structureSize; // a cache, updated on first access
|
|
||||||
TString *fieldName; // for structure field names
|
TString *fieldName; // for structure field names
|
||||||
TString *typeName; // for structure type name
|
TString *typeName; // for structure type name
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -9,5 +9,5 @@
|
||||||
// source have to figure out how to create revision.h just to get a build
|
// source have to figure out how to create revision.h just to get a build
|
||||||
// going. However, if it is not updated, it can be a version behind.
|
// going. However, if it is not updated, it can be a version behind.
|
||||||
|
|
||||||
#define GLSLANG_REVISION "25043"
|
#define GLSLANG_REVISION "25092"
|
||||||
#define GLSLANG_DATE "2014/01/27 13:02:12"
|
#define GLSLANG_DATE "2014/01/28 14:13:59"
|
||||||
|
|
|
||||||
|
|
@ -101,50 +101,52 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TIntermTyped* const
|
||||||
TConstUnionArray rightUnionArray = node->getConstArray();
|
TConstUnionArray rightUnionArray = node->getConstArray();
|
||||||
|
|
||||||
// Figure out the size of the result
|
// Figure out the size of the result
|
||||||
int objectSize;
|
int newComps;
|
||||||
|
int constComps;
|
||||||
switch(op) {
|
switch(op) {
|
||||||
case EOpMatrixTimesMatrix:
|
case EOpMatrixTimesMatrix:
|
||||||
objectSize = getMatrixRows() * node->getMatrixCols();
|
newComps = getMatrixRows() * node->getMatrixCols();
|
||||||
break;
|
break;
|
||||||
case EOpMatrixTimesVector:
|
case EOpMatrixTimesVector:
|
||||||
objectSize = getMatrixRows();
|
newComps = getMatrixRows();
|
||||||
break;
|
break;
|
||||||
case EOpVectorTimesMatrix:
|
case EOpVectorTimesMatrix:
|
||||||
objectSize = node->getMatrixCols();
|
newComps = node->getMatrixCols();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
objectSize = getType().getObjectSize();
|
newComps = getType().computeNumComponents();
|
||||||
if (constantNode->getType().getObjectSize() == 1 && getType().getObjectSize() > 1) {
|
constComps = constantNode->getType().computeNumComponents();
|
||||||
|
if (constComps == 1 && newComps > 1) {
|
||||||
// for a case like vec4 f = vec4(2,3,4,5) + 1.2;
|
// for a case like vec4 f = vec4(2,3,4,5) + 1.2;
|
||||||
TConstUnionArray smearedArray(objectSize, node->getConstArray()[0]);
|
TConstUnionArray smearedArray(newComps, node->getConstArray()[0]);
|
||||||
rightUnionArray = smearedArray;
|
rightUnionArray = smearedArray;
|
||||||
} else if (constantNode->getType().getObjectSize() > 1 && getType().getObjectSize() == 1) {
|
} else if (constComps > 1 && newComps == 1) {
|
||||||
// for a case like vec4 f = 1.2 + vec4(2,3,4,5);
|
// for a case like vec4 f = 1.2 + vec4(2,3,4,5);
|
||||||
objectSize = constantNode->getType().getObjectSize();
|
newComps = constComps;
|
||||||
rightUnionArray = node->getConstArray();
|
rightUnionArray = node->getConstArray();
|
||||||
TConstUnionArray smearedArray(objectSize, getConstArray()[0]);
|
TConstUnionArray smearedArray(newComps, getConstArray()[0]);
|
||||||
unionArray = smearedArray;
|
unionArray = smearedArray;
|
||||||
returnType.shallowCopy(node->getType());
|
returnType.shallowCopy(node->getType());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
TConstUnionArray newConstArray(objectSize);
|
TConstUnionArray newConstArray(newComps);
|
||||||
|
|
||||||
switch(op) {
|
switch(op) {
|
||||||
case EOpAdd:
|
case EOpAdd:
|
||||||
for (int i = 0; i < objectSize; i++)
|
for (int i = 0; i < newComps; i++)
|
||||||
newConstArray[i] = unionArray[i] + rightUnionArray[i];
|
newConstArray[i] = unionArray[i] + rightUnionArray[i];
|
||||||
break;
|
break;
|
||||||
case EOpSub:
|
case EOpSub:
|
||||||
for (int i = 0; i < objectSize; i++)
|
for (int i = 0; i < newComps; i++)
|
||||||
newConstArray[i] = unionArray[i] - rightUnionArray[i];
|
newConstArray[i] = unionArray[i] - rightUnionArray[i];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EOpMul:
|
case EOpMul:
|
||||||
case EOpVectorTimesScalar:
|
case EOpVectorTimesScalar:
|
||||||
case EOpMatrixTimesScalar:
|
case EOpMatrixTimesScalar:
|
||||||
for (int i = 0; i < objectSize; i++)
|
for (int i = 0; i < newComps; i++)
|
||||||
newConstArray[i] = unionArray[i] * rightUnionArray[i];
|
newConstArray[i] = unionArray[i] * rightUnionArray[i];
|
||||||
break;
|
break;
|
||||||
case EOpMatrixTimesMatrix:
|
case EOpMatrixTimesMatrix:
|
||||||
|
|
@ -159,7 +161,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TIntermTyped* const
|
||||||
returnType.shallowCopy(TType(getType().getBasicType(), EvqConst, 0, getMatrixRows(), node->getMatrixCols()));
|
returnType.shallowCopy(TType(getType().getBasicType(), EvqConst, 0, getMatrixRows(), node->getMatrixCols()));
|
||||||
break;
|
break;
|
||||||
case EOpDiv:
|
case EOpDiv:
|
||||||
for (int i = 0; i < objectSize; i++) {
|
for (int i = 0; i < newComps; i++) {
|
||||||
switch (getType().getBasicType()) {
|
switch (getType().getBasicType()) {
|
||||||
case EbtDouble:
|
case EbtDouble:
|
||||||
case EbtFloat:
|
case EbtFloat:
|
||||||
|
|
@ -211,7 +213,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TIntermTyped* const
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EOpMod:
|
case EOpMod:
|
||||||
for (int i = 0; i < objectSize; i++) {
|
for (int i = 0; i < newComps; i++) {
|
||||||
if (rightUnionArray[i] == 0)
|
if (rightUnionArray[i] == 0)
|
||||||
newConstArray[i] = unionArray[i];
|
newConstArray[i] = unionArray[i];
|
||||||
else
|
else
|
||||||
|
|
@ -220,40 +222,40 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TIntermTyped* const
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EOpRightShift:
|
case EOpRightShift:
|
||||||
for (int i = 0; i < objectSize; i++)
|
for (int i = 0; i < newComps; i++)
|
||||||
newConstArray[i] = unionArray[i] >> rightUnionArray[i];
|
newConstArray[i] = unionArray[i] >> rightUnionArray[i];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EOpLeftShift:
|
case EOpLeftShift:
|
||||||
for (int i = 0; i < objectSize; i++)
|
for (int i = 0; i < newComps; i++)
|
||||||
newConstArray[i] = unionArray[i] << rightUnionArray[i];
|
newConstArray[i] = unionArray[i] << rightUnionArray[i];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EOpAnd:
|
case EOpAnd:
|
||||||
for (int i = 0; i < objectSize; i++)
|
for (int i = 0; i < newComps; i++)
|
||||||
newConstArray[i] = unionArray[i] & rightUnionArray[i];
|
newConstArray[i] = unionArray[i] & rightUnionArray[i];
|
||||||
break;
|
break;
|
||||||
case EOpInclusiveOr:
|
case EOpInclusiveOr:
|
||||||
for (int i = 0; i < objectSize; i++)
|
for (int i = 0; i < newComps; i++)
|
||||||
newConstArray[i] = unionArray[i] | rightUnionArray[i];
|
newConstArray[i] = unionArray[i] | rightUnionArray[i];
|
||||||
break;
|
break;
|
||||||
case EOpExclusiveOr:
|
case EOpExclusiveOr:
|
||||||
for (int i = 0; i < objectSize; i++)
|
for (int i = 0; i < newComps; i++)
|
||||||
newConstArray[i] = unionArray[i] ^ rightUnionArray[i];
|
newConstArray[i] = unionArray[i] ^ rightUnionArray[i];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EOpLogicalAnd: // this code is written for possible future use, will not get executed currently
|
case EOpLogicalAnd: // this code is written for possible future use, will not get executed currently
|
||||||
for (int i = 0; i < objectSize; i++)
|
for (int i = 0; i < newComps; i++)
|
||||||
newConstArray[i] = unionArray[i] && rightUnionArray[i];
|
newConstArray[i] = unionArray[i] && rightUnionArray[i];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EOpLogicalOr: // this code is written for possible future use, will not get executed currently
|
case EOpLogicalOr: // this code is written for possible future use, will not get executed currently
|
||||||
for (int i = 0; i < objectSize; i++)
|
for (int i = 0; i < newComps; i++)
|
||||||
newConstArray[i] = unionArray[i] || rightUnionArray[i];
|
newConstArray[i] = unionArray[i] || rightUnionArray[i];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EOpLogicalXor:
|
case EOpLogicalXor:
|
||||||
for (int i = 0; i < objectSize; i++) {
|
for (int i = 0; i < newComps; i++) {
|
||||||
switch (getType().getBasicType()) {
|
switch (getType().getBasicType()) {
|
||||||
case EbtBool: newConstArray[i].setBConst((unionArray[i] == rightUnionArray[i]) ? false : true); break;
|
case EbtBool: newConstArray[i].setBConst((unionArray[i] == rightUnionArray[i]) ? false : true); break;
|
||||||
default: assert(false && "Default missing");
|
default: assert(false && "Default missing");
|
||||||
|
|
@ -309,6 +311,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType)
|
||||||
int resultSize;
|
int resultSize;
|
||||||
bool componentWise = true;
|
bool componentWise = true;
|
||||||
|
|
||||||
|
int objectSize = getType().computeNumComponents();
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case EOpDeterminant:
|
case EOpDeterminant:
|
||||||
case EOpAny:
|
case EOpAny:
|
||||||
|
|
@ -339,18 +342,17 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType)
|
||||||
|
|
||||||
case EOpNormalize:
|
case EOpNormalize:
|
||||||
componentWise = false;
|
componentWise = false;
|
||||||
resultSize = getType().getObjectSize();
|
resultSize = objectSize;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
resultSize = getType().getObjectSize();
|
resultSize = objectSize;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set up for processing
|
// Set up for processing
|
||||||
TConstUnionArray newConstArray(resultSize);
|
TConstUnionArray newConstArray(resultSize);
|
||||||
const TConstUnionArray& unionArray = getConstArray();
|
const TConstUnionArray& unionArray = getConstArray();
|
||||||
int objectSize = getType().getObjectSize();
|
|
||||||
|
|
||||||
// Process non-component-wise operations
|
// Process non-component-wise operations
|
||||||
switch (op) {
|
switch (op) {
|
||||||
|
|
@ -593,13 +595,13 @@ TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode)
|
||||||
case EOpVectorEqual:
|
case EOpVectorEqual:
|
||||||
case EOpVectorNotEqual:
|
case EOpVectorNotEqual:
|
||||||
componentwise = true;
|
componentwise = true;
|
||||||
objectSize = children[0]->getAsConstantUnion()->getType().getObjectSize();
|
objectSize = children[0]->getAsConstantUnion()->getType().computeNumComponents();
|
||||||
break;
|
break;
|
||||||
case EOpCross:
|
case EOpCross:
|
||||||
case EOpReflect:
|
case EOpReflect:
|
||||||
case EOpRefract:
|
case EOpRefract:
|
||||||
case EOpFaceForward:
|
case EOpFaceForward:
|
||||||
objectSize = children[0]->getAsConstantUnion()->getType().getObjectSize();
|
objectSize = children[0]->getAsConstantUnion()->getType().computeNumComponents();
|
||||||
break;
|
break;
|
||||||
case EOpDistance:
|
case EOpDistance:
|
||||||
case EOpDot:
|
case EOpDot:
|
||||||
|
|
@ -726,7 +728,7 @@ TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode)
|
||||||
} else {
|
} else {
|
||||||
// Non-componentwise...
|
// Non-componentwise...
|
||||||
|
|
||||||
int numComps = children[0]->getAsConstantUnion()->getType().getObjectSize();
|
int numComps = children[0]->getAsConstantUnion()->getType().computeNumComponents();
|
||||||
double dot;
|
double dot;
|
||||||
|
|
||||||
switch (aggrNode->getOp()) {
|
switch (aggrNode->getOp()) {
|
||||||
|
|
@ -788,7 +790,7 @@ TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode)
|
||||||
case EOpOuterProduct:
|
case EOpOuterProduct:
|
||||||
{
|
{
|
||||||
int numRows = numComps;
|
int numRows = numComps;
|
||||||
int numCols = children[1]->getAsConstantUnion()->getType().getObjectSize();
|
int numCols = children[1]->getAsConstantUnion()->getType().computeNumComponents();
|
||||||
for (int row = 0; row < numRows; ++row)
|
for (int row = 0; row < numRows; ++row)
|
||||||
for (int col = 0; col < numCols; ++col)
|
for (int col = 0; col < numCols; ++col)
|
||||||
newConstArray[col * numRows + row] = childConstUnions[0][row] * childConstUnions[1][col];
|
newConstArray[col * numRows + row] = childConstUnions[0][row] * childConstUnions[1][col];
|
||||||
|
|
@ -828,7 +830,7 @@ TIntermTyped* TIntermediate::foldConstructor(TIntermAggregate* aggrNode)
|
||||||
{
|
{
|
||||||
bool error = false;
|
bool error = false;
|
||||||
|
|
||||||
TConstUnionArray unionArray(aggrNode->getType().getObjectSize());
|
TConstUnionArray unionArray(aggrNode->getType().computeNumComponents());
|
||||||
if (aggrNode->getSequence().size() == 1)
|
if (aggrNode->getSequence().size() == 1)
|
||||||
error = parseConstTree(aggrNode, unionArray, aggrNode->getOp(), aggrNode->getType(), true);
|
error = parseConstTree(aggrNode, unionArray, aggrNode->getOp(), aggrNode->getType(), true);
|
||||||
else
|
else
|
||||||
|
|
@ -850,13 +852,13 @@ TIntermTyped* TIntermediate::foldDereference(TIntermTyped* node, int index, TSou
|
||||||
TType dereferencedType(node->getType(), index);
|
TType dereferencedType(node->getType(), index);
|
||||||
dereferencedType.getQualifier().storage = EvqConst;
|
dereferencedType.getQualifier().storage = EvqConst;
|
||||||
TIntermTyped* result = 0;
|
TIntermTyped* result = 0;
|
||||||
int size = dereferencedType.getObjectSize();
|
int size = dereferencedType.computeNumComponents();
|
||||||
|
|
||||||
int start;
|
int start;
|
||||||
if (node->isStruct()) {
|
if (node->isStruct()) {
|
||||||
start = 0;
|
start = 0;
|
||||||
for (int i = 0; i < index; ++i)
|
for (int i = 0; i < index; ++i)
|
||||||
start += (*node->getType().getStruct())[i].type->getObjectSize();
|
start += (*node->getType().getStruct())[i].type->computeNumComponents();
|
||||||
} else
|
} else
|
||||||
start = size * index;
|
start = size * index;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1415,7 +1415,7 @@ void TIntermTyped::propagatePrecision(TPrecisionQualifier newPrecision)
|
||||||
TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermConstantUnion* node)
|
TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermConstantUnion* node)
|
||||||
{
|
{
|
||||||
const TConstUnionArray& rightUnionArray = node->getConstArray();
|
const TConstUnionArray& rightUnionArray = node->getConstArray();
|
||||||
int size = node->getType().getObjectSize();
|
int size = node->getType().computeNumComponents();
|
||||||
|
|
||||||
TConstUnionArray leftUnionArray(size);
|
TConstUnionArray leftUnionArray(size);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1602,13 +1602,13 @@ bool TParseContext::constructorError(TSourceLoc loc, TIntermNode* node, TFunctio
|
||||||
bool matrixInMatrix = false;
|
bool matrixInMatrix = false;
|
||||||
bool arrayArg = false;
|
bool arrayArg = false;
|
||||||
for (int i = 0; i < function.getParamCount(); ++i) {
|
for (int i = 0; i < function.getParamCount(); ++i) {
|
||||||
size += function[i].type->getObjectSize();
|
size += function[i].type->computeNumComponents();
|
||||||
|
|
||||||
if (constructingMatrix && function[i].type->isMatrix())
|
if (constructingMatrix && function[i].type->isMatrix())
|
||||||
matrixInMatrix = true;
|
matrixInMatrix = true;
|
||||||
if (full)
|
if (full)
|
||||||
overFull = true;
|
overFull = true;
|
||||||
if (op != EOpConstructStruct && ! type.isArray() && size >= type.getObjectSize())
|
if (op != EOpConstructStruct && ! type.isArray() && size >= type.computeNumComponents())
|
||||||
full = true;
|
full = true;
|
||||||
if (function[i].type->getQualifier().storage != EvqConst)
|
if (function[i].type->getQualifier().storage != EvqConst)
|
||||||
constType = false;
|
constType = false;
|
||||||
|
|
@ -1649,8 +1649,8 @@ bool TParseContext::constructorError(TSourceLoc loc, TIntermNode* node, TFunctio
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((op != EOpConstructStruct && size != 1 && size < type.getObjectSize()) ||
|
if ((op != EOpConstructStruct && size != 1 && size < type.computeNumComponents()) ||
|
||||||
(op == EOpConstructStruct && size < type.getObjectSize())) {
|
(op == EOpConstructStruct && size < type.computeNumComponents())) {
|
||||||
error(loc, "not enough data provided for construction", "constructor", "");
|
error(loc, "not enough data provided for construction", "constructor", "");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -4097,10 +4097,58 @@ void TParseContext::fixBlockXfbOffsets(TSourceLoc loc, TQualifier& qualifier, TT
|
||||||
qualifier.layoutXfbOffset = TQualifier::layoutXfbOffsetEnd;
|
qualifier.layoutXfbOffset = TQualifier::layoutXfbOffsetEnd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Calculate and save the offset of each block member, using the recursively
|
||||||
|
// defined block offset rules and the user-provided offset and align.
|
||||||
|
//
|
||||||
|
// Also, compute and save the total size of the block. For the block's size, arrayness
|
||||||
|
// is not taken into account, as each element is backed by a separate buffer.
|
||||||
|
//
|
||||||
void TParseContext::fixBlockUniformOffsets(TSourceLoc loc, TQualifier& qualifier, TTypeList& typeList)
|
void TParseContext::fixBlockUniformOffsets(TSourceLoc loc, TQualifier& qualifier, TTypeList& typeList)
|
||||||
{
|
{
|
||||||
if (qualifier.storage != EvqUniform || qualifier.storage != EvqBuffer)
|
if (qualifier.storage != EvqUniform && qualifier.storage != EvqBuffer)
|
||||||
return;
|
return;
|
||||||
|
if (qualifier.layoutPacking != ElpStd140 && qualifier.layoutPacking != ElpStd430)
|
||||||
|
return;
|
||||||
|
|
||||||
|
int offset = 0;
|
||||||
|
int memberSize;
|
||||||
|
for (unsigned int member = 0; member < typeList.size(); ++member) {
|
||||||
|
TQualifier& memberQualifier = typeList[member].type->getQualifier();
|
||||||
|
TSourceLoc memberLoc = typeList[member].loc;
|
||||||
|
|
||||||
|
// "When align is applied to an array, it effects only the start of the array, not the array's internal stride."
|
||||||
|
|
||||||
|
int memberAlignment = intermediate.getBaseAlignment(*typeList[member].type, memberSize, qualifier.layoutPacking == ElpStd140);
|
||||||
|
if (memberQualifier.hasOffset()) {
|
||||||
|
// "The specified offset must be a multiple
|
||||||
|
// of the base alignment of the type of the block member it qualifies, or a compile-time error results."
|
||||||
|
if (! IsMultipleOfPow2(memberQualifier.layoutOffset, memberAlignment))
|
||||||
|
error(memberLoc, "must be a multiple of the member's alignment", "offset", "");
|
||||||
|
|
||||||
|
// "It is a compile-time error to specify an offset that is smaller than the offset of the previous
|
||||||
|
// member in the block or that lies within the previous member of the block"
|
||||||
|
if (memberQualifier.layoutOffset < offset)
|
||||||
|
error(memberLoc, "cannot lie in previous members", "offset", "");
|
||||||
|
|
||||||
|
// "The offset qualifier forces the qualified member to start at or after the specified
|
||||||
|
// integral-constant expression, which will be its byte offset from the beginning of the buffer.
|
||||||
|
// "The actual offset of a member is computed as
|
||||||
|
// follows: If offset was declared, start with that offset, otherwise start with the next available offset."
|
||||||
|
offset = std::max(offset, memberQualifier.layoutOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
// "The actual alignment of a member will be the greater of the specified align alignment and the standard
|
||||||
|
// (e.g., std140) base alignment for the member's type."
|
||||||
|
if (memberQualifier.hasAlign())
|
||||||
|
memberAlignment = std::max(memberAlignment, memberQualifier.layoutAlign);
|
||||||
|
|
||||||
|
// "If the resulting offset is not a multiple of the actual alignment,
|
||||||
|
// increase it to the first offset that is a multiple of
|
||||||
|
// the actual alignment."
|
||||||
|
RoundToPow2(offset, memberAlignment);
|
||||||
|
typeList[member].type->getQualifier().layoutOffset = offset;
|
||||||
|
offset += memberSize;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// For an identifier that is already declared, add more qualification to it.
|
// For an identifier that is already declared, add more qualification to it.
|
||||||
|
|
|
||||||
|
|
@ -118,20 +118,6 @@ void TType::buildMangledName(TString& mangledName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int TType::getStructSize() const
|
|
||||||
{
|
|
||||||
if (! isStruct()) {
|
|
||||||
assert(false && "Not a struct");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (structureSize == 0)
|
|
||||||
for (TTypeList::iterator tl = getStruct()->begin(); tl != getStruct()->end(); tl++)
|
|
||||||
structureSize += ((*tl).type)->getObjectSize();
|
|
||||||
|
|
||||||
return structureSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Dump functions.
|
// Dump functions.
|
||||||
//
|
//
|
||||||
|
|
@ -256,7 +242,6 @@ TVariable::TVariable(const TVariable& copyOf) : TSymbol(copyOf)
|
||||||
|
|
||||||
if (! copyOf.unionArray.empty()) {
|
if (! copyOf.unionArray.empty()) {
|
||||||
assert(! copyOf.type.isStruct());
|
assert(! copyOf.type.isStruct());
|
||||||
assert(copyOf.type.getObjectSize() == 1);
|
|
||||||
TConstUnionArray newArray(1);
|
TConstUnionArray newArray(1);
|
||||||
newArray[0] = copyOf.unionArray[0];
|
newArray[0] = copyOf.unionArray[0];
|
||||||
unionArray = newArray;
|
unionArray = newArray;
|
||||||
|
|
|
||||||
|
|
@ -411,7 +411,7 @@ bool TOutputTraverser::visitSelection(TVisit /* visit */, TIntermSelection* node
|
||||||
|
|
||||||
void OutputConstantUnion(TInfoSink& out, const TIntermTyped* node, const TConstUnionArray& constUnion, int depth)
|
void OutputConstantUnion(TInfoSink& out, const TIntermTyped* node, const TConstUnionArray& constUnion, int depth)
|
||||||
{
|
{
|
||||||
int size = node->getType().getObjectSize();
|
int size = node->getType().computeNumComponents();
|
||||||
|
|
||||||
for (int i = 0; i < size; i++) {
|
for (int i = 0; i < size; i++) {
|
||||||
OutputTreeText(out, node, depth);
|
OutputTreeText(out, node, depth);
|
||||||
|
|
|
||||||
|
|
@ -60,6 +60,10 @@ void TIntermediate::error(TInfoSink& infoSink, const char* message)
|
||||||
++numErrors;
|
++numErrors;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: 4.4 offset/align: "Two blocks linked together in the same program with the same block
|
||||||
|
// name must have the exact same set of members qualified with offset and their integral-constant
|
||||||
|
// expression values must be the same, or a link-time error results."
|
||||||
|
|
||||||
//
|
//
|
||||||
// Merge the information from 'unit' into 'this'
|
// Merge the information from 'unit' into 'this'
|
||||||
//
|
//
|
||||||
|
|
@ -266,7 +270,9 @@ void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& sy
|
||||||
}
|
}
|
||||||
|
|
||||||
// Layouts...
|
// Layouts...
|
||||||
// TODO: 4.4 enhanced layouts: generalize to include offset/align
|
// TODO: 4.4 enhanced layouts: Generalize to include offset/align: currrent spec
|
||||||
|
// requires separate user-supplied offset from actual computed offset, but
|
||||||
|
// current implementation only has one offset.
|
||||||
if (symbol.getQualifier().layoutMatrix != unitSymbol.getQualifier().layoutMatrix ||
|
if (symbol.getQualifier().layoutMatrix != unitSymbol.getQualifier().layoutMatrix ||
|
||||||
symbol.getQualifier().layoutPacking != unitSymbol.getQualifier().layoutPacking ||
|
symbol.getQualifier().layoutPacking != unitSymbol.getQualifier().layoutPacking ||
|
||||||
symbol.getQualifier().layoutLocation != unitSymbol.getQualifier().layoutLocation ||
|
symbol.getQualifier().layoutLocation != unitSymbol.getQualifier().layoutLocation ||
|
||||||
|
|
@ -740,4 +746,153 @@ unsigned int TIntermediate::computeTypeXfbSize(const TType& type, bool& contains
|
||||||
return 4 * numComponents;
|
return 4 * numComponents;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const int baseAlignmentVec4Std140 = 16;
|
||||||
|
|
||||||
|
// Return the size and alignment of a scalar.
|
||||||
|
// The size is returned in the 'size' parameter
|
||||||
|
// Return value is the alignment of the type.
|
||||||
|
int TIntermediate::getBaseAlignmentScalar(const TType& type, int& size) const
|
||||||
|
{
|
||||||
|
switch (type.getBasicType()) {
|
||||||
|
case EbtDouble: size = 8; return 8;
|
||||||
|
default: size = 4; return 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Implement base-alignment and size rules from section 7.6.2.2 Standard Uniform Block Layout
|
||||||
|
// Operates recursively.
|
||||||
|
//
|
||||||
|
// If std140 is true, it does the rounding up to vec4 size required by std140,
|
||||||
|
// otherwise it does not, yielding std430 rules.
|
||||||
|
//
|
||||||
|
// The size is returned in the 'size' parameter
|
||||||
|
// Return value is the alignment of the type.
|
||||||
|
int TIntermediate::getBaseAlignment(const TType& type, int& size, bool std140) const
|
||||||
|
{
|
||||||
|
int alignment;
|
||||||
|
|
||||||
|
// When using the std140 storage layout, structures will be laid out in buffer
|
||||||
|
// storage with its members stored in monotonically increasing order based on their
|
||||||
|
// location in the declaration. A structure and each structure member have a base
|
||||||
|
// offset and a base alignment, from which an aligned offset is computed by rounding
|
||||||
|
// the base offset up to a multiple of the base alignment. The base offset of the first
|
||||||
|
// member of a structure is taken from the aligned offset of the structure itself. The
|
||||||
|
// base offset of all other structure members is derived by taking the offset of the
|
||||||
|
// last basic machine unit consumed by the previous member and adding one. Each
|
||||||
|
// structure member is stored in memory at its aligned offset. The members of a top-
|
||||||
|
// level uniform block are laid out in buffer storage by treating the uniform block as
|
||||||
|
// a structure with a base offset of zero.
|
||||||
|
//
|
||||||
|
// 1. If the member is a scalar consuming N basic machine units, the base alignment is N.
|
||||||
|
//
|
||||||
|
// 2. If the member is a two- or four-component vector with components consuming N basic
|
||||||
|
// machine units, the base alignment is 2N or 4N, respectively.
|
||||||
|
//
|
||||||
|
// 3. If the member is a three-component vector with components consuming N
|
||||||
|
// basic machine units, the base alignment is 4N.
|
||||||
|
//
|
||||||
|
// 4. If the member is an array of scalars or vectors, the base alignment and array
|
||||||
|
// stride are set to match the base alignment of a single array element, according
|
||||||
|
// to rules (1), (2), and (3), and rounded up to the base alignment of a vec4. The
|
||||||
|
// array may have padding at the end; the base offset of the member following
|
||||||
|
// the array is rounded up to the next multiple of the base alignment.
|
||||||
|
//
|
||||||
|
// 5. If the member is a column-major matrix with C columns and R rows, the
|
||||||
|
// matrix is stored identically to an array of C column vectors with R
|
||||||
|
// components each, according to rule (4).
|
||||||
|
//
|
||||||
|
// 6. If the member is an array of S column-major matrices with C columns and
|
||||||
|
// R rows, the matrix is stored identically to a row of S C column vectors
|
||||||
|
// with R components each, according to rule (4).
|
||||||
|
//
|
||||||
|
// 7. If the member is a row-major matrix with C columns and R rows, the matrix
|
||||||
|
// is stored identically to an array of R row vectors with C components each,
|
||||||
|
// according to rule (4).
|
||||||
|
//
|
||||||
|
// 8. If the member is an array of S row-major matrices with C columns and R
|
||||||
|
// rows, the matrix is stored identically to a row of S R row vectors with C
|
||||||
|
// components each, according to rule (4).
|
||||||
|
//
|
||||||
|
// 9. If the member is a structure, the base alignment of the structure is N , where
|
||||||
|
// N is the largest base alignment value of any of its members, and rounded
|
||||||
|
// up to the base alignment of a vec4. The individual members of this substructure
|
||||||
|
// are then assigned offsets by applying this set of rules recursively,
|
||||||
|
// where the base offset of the first member of the sub-structure is equal to the
|
||||||
|
// aligned offset of the structure. The structure may have padding at the end;
|
||||||
|
// the base offset of the member following the sub-structure is rounded up to
|
||||||
|
// the next multiple of the base alignment of the structure.
|
||||||
|
//
|
||||||
|
// 10. If the member is an array of S structures, the S elements of the array are laid
|
||||||
|
// out in order, according to rule (9).
|
||||||
|
|
||||||
|
// rules 4, 6, and 8
|
||||||
|
if (type.isArray()) {
|
||||||
|
TType derefType(type, 0);
|
||||||
|
alignment = getBaseAlignment(derefType, size, std140);
|
||||||
|
if (std140)
|
||||||
|
alignment = std::max(baseAlignmentVec4Std140, alignment);
|
||||||
|
RoundToPow2(size, alignment);
|
||||||
|
size *= type.getArraySize();
|
||||||
|
return alignment;
|
||||||
|
}
|
||||||
|
|
||||||
|
// rule 9
|
||||||
|
if (type.getBasicType() == EbtStruct) {
|
||||||
|
const TTypeList& memberList = *type.getStruct();
|
||||||
|
|
||||||
|
size = 0;
|
||||||
|
int maxAlignment = std140 ? baseAlignmentVec4Std140 : 0;
|
||||||
|
for (size_t m = 0; m < memberList.size(); ++m) {
|
||||||
|
int memberSize;
|
||||||
|
int memberAlignment = getBaseAlignment(*memberList[m].type, memberSize, std140);
|
||||||
|
maxAlignment = std::max(maxAlignment, memberAlignment);
|
||||||
|
RoundToPow2(size, memberAlignment);
|
||||||
|
size += memberSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
return maxAlignment;
|
||||||
|
}
|
||||||
|
|
||||||
|
// rule 1
|
||||||
|
if (type.isScalar())
|
||||||
|
return getBaseAlignmentScalar(type, size);
|
||||||
|
|
||||||
|
// rules 2 and 3
|
||||||
|
if (type.isVector()) {
|
||||||
|
int scalarAlign = getBaseAlignmentScalar(type, size);
|
||||||
|
switch (type.getVectorSize()) {
|
||||||
|
case 2:
|
||||||
|
size *= 2;
|
||||||
|
return 2 * scalarAlign;
|
||||||
|
default:
|
||||||
|
size *= type.getVectorSize();
|
||||||
|
return 4 * scalarAlign;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// rules 5 and 7
|
||||||
|
if (type.isMatrix()) {
|
||||||
|
TType derefType(type, 0);
|
||||||
|
|
||||||
|
// rule 5: deref to row, not to column, meaning the size of vector is num columns instead of num rows
|
||||||
|
if (type.getQualifier().layoutMatrix == ElmRowMajor)
|
||||||
|
derefType.setElementType(derefType.getBasicType(), type.getMatrixCols(), 0, 0, 0);
|
||||||
|
|
||||||
|
alignment = getBaseAlignment(derefType, size, std140);
|
||||||
|
if (std140)
|
||||||
|
alignment = std::max(baseAlignmentVec4Std140, alignment);
|
||||||
|
RoundToPow2(size, alignment);
|
||||||
|
if (type.getQualifier().layoutMatrix == ElmRowMajor)
|
||||||
|
size *= type.getMatrixRows();
|
||||||
|
else
|
||||||
|
size *= type.getMatrixCols();
|
||||||
|
|
||||||
|
return alignment;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(0); // all cases should be covered above
|
||||||
|
size = baseAlignmentVec4Std140;
|
||||||
|
return baseAlignmentVec4Std140;
|
||||||
|
}
|
||||||
|
|
||||||
} // end namespace glslang
|
} // end namespace glslang
|
||||||
|
|
|
||||||
|
|
@ -239,6 +239,7 @@ public:
|
||||||
}
|
}
|
||||||
int addXfbBufferOffset(const TType&);
|
int addXfbBufferOffset(const TType&);
|
||||||
unsigned int computeTypeXfbSize(const TType&, bool& containsDouble) const;
|
unsigned int computeTypeXfbSize(const TType&, bool& containsDouble) const;
|
||||||
|
int getBaseAlignment(const TType&, int& size, bool std140) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void error(TInfoSink& infoSink, const char*);
|
void error(TInfoSink& infoSink, const char*);
|
||||||
|
|
@ -249,6 +250,7 @@ protected:
|
||||||
void inOutLocationCheck(TInfoSink&);
|
void inOutLocationCheck(TInfoSink&);
|
||||||
TIntermSequence& findLinkerObjects() const;
|
TIntermSequence& findLinkerObjects() const;
|
||||||
bool userOutputUsed() const;
|
bool userOutputUsed() const;
|
||||||
|
int getBaseAlignmentScalar(const TType&, int& size) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
const EShLanguage language;
|
const EShLanguage language;
|
||||||
|
|
|
||||||
|
|
@ -82,7 +82,7 @@ bool TConstTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node)
|
||||||
if (flag) {
|
if (flag) {
|
||||||
singleConstantParam = true;
|
singleConstantParam = true;
|
||||||
constructorType = node->getOp();
|
constructorType = node->getOp();
|
||||||
size = node->getType().getObjectSize();
|
size = node->getType().computeNumComponents();
|
||||||
|
|
||||||
if (node->getType().isMatrix()) {
|
if (node->getType().isMatrix()) {
|
||||||
isMatrix = true;
|
isMatrix = true;
|
||||||
|
|
@ -115,13 +115,13 @@ bool TConstTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node)
|
||||||
void TConstTraverser::visitConstantUnion(TIntermConstantUnion* node)
|
void TConstTraverser::visitConstantUnion(TIntermConstantUnion* node)
|
||||||
{
|
{
|
||||||
TConstUnionArray leftUnionArray(unionArray);
|
TConstUnionArray leftUnionArray(unionArray);
|
||||||
int instanceSize = type.getObjectSize();
|
int instanceSize = type.computeNumComponents();
|
||||||
|
|
||||||
if (index >= instanceSize)
|
if (index >= instanceSize)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (! singleConstantParam) {
|
if (! singleConstantParam) {
|
||||||
int rightUnionSize = node->getType().getObjectSize();
|
int rightUnionSize = node->getType().computeNumComponents();
|
||||||
|
|
||||||
const TConstUnionArray& rightUnionArray = node->getConstArray();
|
const TConstUnionArray& rightUnionArray = node->getConstArray();
|
||||||
for (int i = 0; i < rightUnionSize; i++) {
|
for (int i = 0; i < rightUnionSize; i++) {
|
||||||
|
|
@ -136,6 +136,7 @@ void TConstTraverser::visitConstantUnion(TIntermConstantUnion* node)
|
||||||
const TConstUnionArray& rightUnionArray = node->getConstArray();
|
const TConstUnionArray& rightUnionArray = node->getConstArray();
|
||||||
if (! isMatrix) {
|
if (! isMatrix) {
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
int nodeComps = node->getType().computeNumComponents();
|
||||||
for (int i = index; i < endIndex; i++) {
|
for (int i = index; i < endIndex; i++) {
|
||||||
if (i >= instanceSize)
|
if (i >= instanceSize)
|
||||||
return;
|
return;
|
||||||
|
|
@ -144,7 +145,7 @@ void TConstTraverser::visitConstantUnion(TIntermConstantUnion* node)
|
||||||
|
|
||||||
(index)++;
|
(index)++;
|
||||||
|
|
||||||
if (node->getType().getObjectSize() > 1)
|
if (nodeComps > 1)
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -169,6 +170,7 @@ void TConstTraverser::visitConstantUnion(TIntermConstantUnion* node)
|
||||||
// matrix from vector
|
// matrix from vector
|
||||||
int count = 0;
|
int count = 0;
|
||||||
const int startIndex = index;
|
const int startIndex = index;
|
||||||
|
int nodeComps = node->getType().computeNumComponents();
|
||||||
for (int i = startIndex; i < endIndex; i++) {
|
for (int i = startIndex; i < endIndex; i++) {
|
||||||
if (i >= instanceSize)
|
if (i >= instanceSize)
|
||||||
return;
|
return;
|
||||||
|
|
@ -179,7 +181,7 @@ void TConstTraverser::visitConstantUnion(TIntermConstantUnion* node)
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
|
|
||||||
if (node->getType().getObjectSize() > 1)
|
if (nodeComps > 1)
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -108,139 +108,42 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static const int baseAlignmentVec4Std140;
|
// Lookup or calculate the offset of a block member, using the recursively
|
||||||
|
// defined block offset rules.
|
||||||
// align a value: if 'value' is not aligned to 'alignment', move it up to a multiple of alignment
|
int getOffset(const TType& type, int index)
|
||||||
void align(int& value, int alignment)
|
|
||||||
{
|
{
|
||||||
int error = value % alignment;
|
|
||||||
if (error)
|
|
||||||
value += alignment - error;
|
|
||||||
}
|
|
||||||
|
|
||||||
// return the size and alignment of a scalar
|
|
||||||
int getBaseAlignmentScalar(const TType& type, int& size)
|
|
||||||
{
|
|
||||||
switch (type.getBasicType()) {
|
|
||||||
case EbtDouble: size = 8; return 8;
|
|
||||||
default: size = 4; return 4;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Implement base-alignment and size rules from section 7.6.2.2 Standard Uniform Block Layout
|
|
||||||
// Operates recursively.
|
|
||||||
// If std140 is true, it does the rounding up to vec4 size required by std140,
|
|
||||||
// otherwise it does not, yielding std430 rules.
|
|
||||||
//
|
|
||||||
// Returns the size of the type.
|
|
||||||
int getBaseAlignment(const TType& type, int& size, bool std140)
|
|
||||||
{
|
|
||||||
int alignment;
|
|
||||||
|
|
||||||
// rules 4, 6, and 8
|
|
||||||
if (type.isArray()) {
|
|
||||||
TType derefType(type, 0);
|
|
||||||
alignment = getBaseAlignment(derefType, size, std140);
|
|
||||||
if (std140)
|
|
||||||
alignment = std::max(baseAlignmentVec4Std140, alignment);
|
|
||||||
align(size, alignment);
|
|
||||||
size *= type.getArraySize();
|
|
||||||
return alignment;
|
|
||||||
}
|
|
||||||
|
|
||||||
// rule 9
|
|
||||||
if (type.getBasicType() == EbtStruct) {
|
|
||||||
const TTypeList& memberList = *type.getStruct();
|
const TTypeList& memberList = *type.getStruct();
|
||||||
|
|
||||||
size = 0;
|
// Don't calculate offset if one is present, it could be user supplied
|
||||||
int maxAlignment = std140 ? baseAlignmentVec4Std140 : 0;
|
// and different than what would be calculated. That is, this is faster,
|
||||||
for (size_t m = 0; m < memberList.size(); ++m) {
|
// but not just an optimization.
|
||||||
|
if (memberList[index].type->getQualifier().hasOffset())
|
||||||
|
return memberList[index].type->getQualifier().layoutOffset;
|
||||||
|
|
||||||
int memberSize;
|
int memberSize;
|
||||||
int memberAlignment = getBaseAlignment(*memberList[m].type, memberSize, std140);
|
|
||||||
maxAlignment = std::max(maxAlignment, memberAlignment);
|
|
||||||
align(size, memberAlignment);
|
|
||||||
size += memberSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
return maxAlignment;
|
|
||||||
}
|
|
||||||
|
|
||||||
// rule 1
|
|
||||||
if (type.isScalar())
|
|
||||||
return getBaseAlignmentScalar(type, size);
|
|
||||||
|
|
||||||
// rules 2 and 3
|
|
||||||
if (type.isVector()) {
|
|
||||||
int scalarAlign = getBaseAlignmentScalar(type, size);
|
|
||||||
switch (type.getVectorSize()) {
|
|
||||||
case 2:
|
|
||||||
size *= 2;
|
|
||||||
return 2 * scalarAlign;
|
|
||||||
default:
|
|
||||||
size *= type.getVectorSize();
|
|
||||||
return 4 * scalarAlign;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// rules 5 and 7
|
|
||||||
if (type.isMatrix()) {
|
|
||||||
TType derefType(type, 0);
|
|
||||||
|
|
||||||
// rule 5: deref to row, not to column, meaning the size of vector is num columns instead of num rows
|
|
||||||
if (type.getQualifier().layoutMatrix == ElmRowMajor)
|
|
||||||
derefType.setElementType(derefType.getBasicType(), type.getMatrixCols(), 0, 0, 0);
|
|
||||||
|
|
||||||
alignment = getBaseAlignment(derefType, size, std140);
|
|
||||||
if (std140)
|
|
||||||
alignment = std::max(baseAlignmentVec4Std140, alignment);
|
|
||||||
align(size, alignment);
|
|
||||||
if (type.getQualifier().layoutMatrix == ElmRowMajor)
|
|
||||||
size *= type.getMatrixRows();
|
|
||||||
else
|
|
||||||
size *= type.getMatrixCols();
|
|
||||||
|
|
||||||
return alignment;
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(0); // all cases should be covered above
|
|
||||||
size = baseAlignmentVec4Std140;
|
|
||||||
return baseAlignmentVec4Std140;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Calculate the offset of a block member, using the recursively defined
|
|
||||||
// block offset rules.
|
|
||||||
int getBlockMemberOffset(const TType& blockType, int index)
|
|
||||||
{
|
|
||||||
// TODO: reflection performance: cache intermediate results instead of recomputing them
|
|
||||||
|
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
const TTypeList& memberList = *blockType.getStruct();
|
for (int m = 0; m <= index; ++m) {
|
||||||
int memberSize;
|
int memberAlignment = intermediate.getBaseAlignment(*memberList[m].type, memberSize, type.getQualifier().layoutPacking == ElpStd140);
|
||||||
for (int m = 0; m < index; ++m) {
|
RoundToPow2(offset, memberAlignment);
|
||||||
int memberAlignment = getBaseAlignment(*memberList[m].type, memberSize, blockType.getQualifier().layoutPacking == ElpStd140);
|
if (m < index)
|
||||||
align(offset, memberAlignment);
|
|
||||||
offset += memberSize;
|
offset += memberSize;
|
||||||
}
|
}
|
||||||
int memberAlignment = getBaseAlignment(*memberList[index].type, memberSize, blockType.getQualifier().layoutPacking == ElpStd140);
|
|
||||||
align(offset, memberAlignment);
|
|
||||||
|
|
||||||
return offset;
|
return offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate the block data size.
|
// Calculate the block data size.
|
||||||
// Arrayness is not taken into account, each element is backed by a separate buffer.
|
// Block arrayness is not taken into account, each element is backed by a separate buffer.
|
||||||
int getBlockSize(const TType& blockType)
|
int getBlockSize(const TType& blockType)
|
||||||
{
|
{
|
||||||
int size = 0;
|
|
||||||
const TTypeList& memberList = *blockType.getStruct();
|
const TTypeList& memberList = *blockType.getStruct();
|
||||||
int memberSize;
|
int lastIndex = memberList.size() - 1;
|
||||||
for (size_t m = 0; m < memberList.size(); ++m) {
|
int lastOffset = getOffset(blockType, lastIndex);
|
||||||
int memberAlignment = getBaseAlignment(*memberList[m].type, memberSize, blockType.getQualifier().layoutPacking == ElpStd140);
|
|
||||||
align(size, memberAlignment);
|
|
||||||
size += memberSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
return size;
|
int lastMemberSize;
|
||||||
|
intermediate.getBaseAlignment(*memberList[lastIndex].type, lastMemberSize, blockType.getQualifier().layoutPacking == ElpStd140);
|
||||||
|
|
||||||
|
return lastOffset + lastMemberSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Traverse the provided deref chain, including the base, and
|
// Traverse the provided deref chain, including the base, and
|
||||||
|
|
@ -283,7 +186,7 @@ public:
|
||||||
case EOpIndexDirectStruct:
|
case EOpIndexDirectStruct:
|
||||||
index = visitNode->getRight()->getAsConstantUnion()->getConstArray()[0].getIConst();
|
index = visitNode->getRight()->getAsConstantUnion()->getConstArray()[0].getIConst();
|
||||||
if (offset >= 0)
|
if (offset >= 0)
|
||||||
offset += getBlockMemberOffset(visitNode->getLeft()->getType(), index);
|
offset += getOffset(visitNode->getLeft()->getType(), index);
|
||||||
if (name.size() > 0)
|
if (name.size() > 0)
|
||||||
name.append(".");
|
name.append(".");
|
||||||
name.append((*visitNode->getLeft()->getType().getStruct())[index].type->getFieldName());
|
name.append((*visitNode->getLeft()->getType().getStruct())[index].type->getFieldName());
|
||||||
|
|
@ -715,8 +618,6 @@ public:
|
||||||
std::set<const TIntermNode*> processedDerefs;
|
std::set<const TIntermNode*> processedDerefs;
|
||||||
};
|
};
|
||||||
|
|
||||||
const int TLiveTraverser::baseAlignmentVec4Std140 = 16;
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Implement the traversal functions of interest.
|
// Implement the traversal functions of interest.
|
||||||
//
|
//
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue