Include array index in reflected uniform names more consistently
* This comes from the resolution of issues 4, 5 & 6 in ARB_program_interface_query, stating that uniform buffers should have their members expanded out as normal and arrays should have elements added. * If a buffer block has a large array e.g. [10000] we don't want to iterate over every array element. Instead we should only expand out the first [0] element, then expand as normal from there. * The array name should still be appended with [0] to indicate that it's an array.
This commit is contained in:
parent
6d47785825
commit
15c37f79a9
@ -524,6 +524,8 @@ void ProcessArguments(std::vector<std::unique_ptr<glslang::TWorkItem>>& workItem
|
|||||||
Options |= EOptionNoStorageFormat;
|
Options |= EOptionNoStorageFormat;
|
||||||
} else if (lowerword == "relaxed-errors") {
|
} else if (lowerword == "relaxed-errors") {
|
||||||
Options |= EOptionRelaxedErrors;
|
Options |= EOptionRelaxedErrors;
|
||||||
|
} else if (lowerword == "reflect-strict-array-suffix") {
|
||||||
|
ReflectOptions |= EShReflectionStrictArraySuffix;
|
||||||
} else if (lowerword == "resource-set-bindings" || // synonyms
|
} else if (lowerword == "resource-set-bindings" || // synonyms
|
||||||
lowerword == "resource-set-binding" ||
|
lowerword == "resource-set-binding" ||
|
||||||
lowerword == "rsb") {
|
lowerword == "rsb") {
|
||||||
@ -1519,6 +1521,7 @@ void usage()
|
|||||||
" --invert-y | --iy invert position.Y output in vertex shader\n"
|
" --invert-y | --iy invert position.Y output in vertex shader\n"
|
||||||
" --keep-uncalled | --ku don't eliminate uncalled functions\n"
|
" --keep-uncalled | --ku don't eliminate uncalled functions\n"
|
||||||
" --no-storage-format | --nsf use Unknown image format\n"
|
" --no-storage-format | --nsf use Unknown image format\n"
|
||||||
|
" --reflect-strict-array-suffix use strict array suffix rules when reflecting\n"
|
||||||
" --resource-set-binding [stage] name set binding\n"
|
" --resource-set-binding [stage] name set binding\n"
|
||||||
" set descriptor set and binding for\n"
|
" set descriptor set and binding for\n"
|
||||||
" individual resources\n"
|
" individual resources\n"
|
||||||
|
15
Test/baseResults/reflection.options.vert.out
Normal file
15
Test/baseResults/reflection.options.vert.out
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
reflection.options.vert
|
||||||
|
Uniform reflection:
|
||||||
|
t[0].v[0].position: offset 0, type 1406, size 3, index 0, binding -1, stages 1
|
||||||
|
t[0].v[1].position: offset 24, type 1406, size 3, index 0, binding -1, stages 1
|
||||||
|
t[0].v[2].position: offset 48, type 1406, size 3, index 0, binding -1, stages 1
|
||||||
|
t[0].v[0].normal: offset 12, type 1406, size 3, index 0, binding -1, stages 1
|
||||||
|
t[0].v[1].normal: offset 36, type 1406, size 3, index 0, binding -1, stages 1
|
||||||
|
t[0].v[2].normal: offset 60, type 1406, size 3, index 0, binding -1, stages 1
|
||||||
|
|
||||||
|
Uniform block reflection:
|
||||||
|
VertexCollection: offset -1, type ffffffff, size 360, index -1, binding -1, stages 0
|
||||||
|
|
||||||
|
Vertex attribute reflection:
|
||||||
|
gl_InstanceID: offset 0, type 1404, size 0, index 0, binding -1, stages 0
|
||||||
|
|
@ -84,6 +84,43 @@ nested2.b[2].a: offset 80, type 1406, size 1, index 16, binding -1, stages 1
|
|||||||
nested2.b[3].a: offset 96, type 1406, size 1, index 16, binding -1, stages 1
|
nested2.b[3].a: offset 96, type 1406, size 1, index 16, binding -1, stages 1
|
||||||
nested2.c.a: offset 112, type 1406, size 1, index 16, binding -1, stages 1
|
nested2.c.a: offset 112, type 1406, size 1, index 16, binding -1, stages 1
|
||||||
nested2.d.a: offset 144, type 1406, size 1, index 16, binding -1, stages 1
|
nested2.d.a: offset 144, type 1406, size 1, index 16, binding -1, stages 1
|
||||||
|
t.v.position: offset 0, type 1406, size 1, index 17, binding -1, stages 1
|
||||||
|
t.v[0].position: offset 0, type 1406, size 3, index 17, binding -1, stages 1
|
||||||
|
t.v[1].position: offset 24, type 1406, size 3, index 17, binding -1, stages 1
|
||||||
|
t.v[2].position: offset 48, type 1406, size 3, index 17, binding -1, stages 1
|
||||||
|
t.v[0].normal: offset 12, type 1406, size 3, index 17, binding -1, stages 1
|
||||||
|
t.v[1].normal: offset 36, type 1406, size 3, index 17, binding -1, stages 1
|
||||||
|
t.v[2].normal: offset 60, type 1406, size 3, index 17, binding -1, stages 1
|
||||||
|
t[0].v[0].position: offset 0, type 1406, size 3, index 17, binding -1, stages 1
|
||||||
|
t[0].v[0].normal: offset 12, type 1406, size 3, index 17, binding -1, stages 1
|
||||||
|
t[0].v[1].position: offset 24, type 1406, size 3, index 17, binding -1, stages 1
|
||||||
|
t[0].v[1].normal: offset 36, type 1406, size 3, index 17, binding -1, stages 1
|
||||||
|
t[0].v[2].position: offset 48, type 1406, size 3, index 17, binding -1, stages 1
|
||||||
|
t[0].v[2].normal: offset 60, type 1406, size 3, index 17, binding -1, stages 1
|
||||||
|
t[1].v[0].position: offset 72, type 1406, size 3, index 17, binding -1, stages 1
|
||||||
|
t[1].v[0].normal: offset 84, type 1406, size 3, index 17, binding -1, stages 1
|
||||||
|
t[1].v[1].position: offset 96, type 1406, size 3, index 17, binding -1, stages 1
|
||||||
|
t[1].v[1].normal: offset 108, type 1406, size 3, index 17, binding -1, stages 1
|
||||||
|
t[1].v[2].position: offset 120, type 1406, size 3, index 17, binding -1, stages 1
|
||||||
|
t[1].v[2].normal: offset 132, type 1406, size 3, index 17, binding -1, stages 1
|
||||||
|
t[2].v[0].position: offset 144, type 1406, size 3, index 17, binding -1, stages 1
|
||||||
|
t[2].v[0].normal: offset 156, type 1406, size 3, index 17, binding -1, stages 1
|
||||||
|
t[2].v[1].position: offset 168, type 1406, size 3, index 17, binding -1, stages 1
|
||||||
|
t[2].v[1].normal: offset 180, type 1406, size 3, index 17, binding -1, stages 1
|
||||||
|
t[2].v[2].position: offset 192, type 1406, size 3, index 17, binding -1, stages 1
|
||||||
|
t[2].v[2].normal: offset 204, type 1406, size 3, index 17, binding -1, stages 1
|
||||||
|
t[3].v[0].position: offset 216, type 1406, size 3, index 17, binding -1, stages 1
|
||||||
|
t[3].v[0].normal: offset 228, type 1406, size 3, index 17, binding -1, stages 1
|
||||||
|
t[3].v[1].position: offset 240, type 1406, size 3, index 17, binding -1, stages 1
|
||||||
|
t[3].v[1].normal: offset 252, type 1406, size 3, index 17, binding -1, stages 1
|
||||||
|
t[3].v[2].position: offset 264, type 1406, size 3, index 17, binding -1, stages 1
|
||||||
|
t[3].v[2].normal: offset 276, type 1406, size 3, index 17, binding -1, stages 1
|
||||||
|
t[4].v[0].position: offset 288, type 1406, size 3, index 17, binding -1, stages 1
|
||||||
|
t[4].v[0].normal: offset 300, type 1406, size 3, index 17, binding -1, stages 1
|
||||||
|
t[4].v[1].position: offset 312, type 1406, size 3, index 17, binding -1, stages 1
|
||||||
|
t[4].v[1].normal: offset 324, type 1406, size 3, index 17, binding -1, stages 1
|
||||||
|
t[4].v[2].position: offset 336, type 1406, size 3, index 17, binding -1, stages 1
|
||||||
|
t[4].v[2].normal: offset 348, type 1406, size 3, index 17, binding -1, stages 1
|
||||||
anonMember1: offset 0, type 8b51, size 1, index 0, binding -1, stages 1
|
anonMember1: offset 0, type 8b51, size 1, index 0, binding -1, stages 1
|
||||||
uf1: offset -1, type 1406, size 1, index -1, binding -1, stages 1
|
uf1: offset -1, type 1406, size 1, index -1, binding -1, stages 1
|
||||||
uf2: offset -1, type 1406, size 1, index -1, binding -1, stages 1
|
uf2: offset -1, type 1406, size 1, index -1, binding -1, stages 1
|
||||||
@ -107,6 +144,7 @@ buf2: offset -1, type ffffffff, size 4, index -1, binding -1, stages 0
|
|||||||
buf3: offset -1, type ffffffff, size 4, index -1, binding -1, stages 0
|
buf3: offset -1, type ffffffff, size 4, index -1, binding -1, stages 0
|
||||||
buf4: offset -1, type ffffffff, size 4, index -1, binding -1, stages 0
|
buf4: offset -1, type ffffffff, size 4, index -1, binding -1, stages 0
|
||||||
nested2: offset -1, type ffffffff, size 208, index -1, binding -1, stages 0
|
nested2: offset -1, type ffffffff, size 208, index -1, binding -1, stages 0
|
||||||
|
VertexCollection: offset -1, type ffffffff, size 360, index -1, binding -1, stages 0
|
||||||
|
|
||||||
Vertex attribute reflection:
|
Vertex attribute reflection:
|
||||||
attributeFloat: offset 0, type 1406, size 0, index 0, binding -1, stages 0
|
attributeFloat: offset 0, type 1406, size 0, index 0, binding -1, stages 0
|
||||||
|
23
Test/reflection.options.vert
Normal file
23
Test/reflection.options.vert
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
#version 440 core
|
||||||
|
|
||||||
|
struct VertexInfo {
|
||||||
|
float position[3];
|
||||||
|
float normal[3];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct TriangleInfo {
|
||||||
|
VertexInfo v[3];
|
||||||
|
};
|
||||||
|
|
||||||
|
buffer VertexCollection {
|
||||||
|
TriangleInfo t[5];
|
||||||
|
};
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
float f;
|
||||||
|
f += t[0].v[0].position[0];
|
||||||
|
f += t[gl_InstanceID].v[gl_InstanceID].position[gl_InstanceID];
|
||||||
|
f += t[gl_InstanceID].v[gl_InstanceID].normal[gl_InstanceID];
|
||||||
|
TriangleInfo tlocal[5] = t;
|
||||||
|
}
|
@ -161,6 +161,19 @@ buffer buf4 {
|
|||||||
N2 runtimeArray[];
|
N2 runtimeArray[];
|
||||||
} buf4i;
|
} buf4i;
|
||||||
|
|
||||||
|
struct VertexInfo {
|
||||||
|
float position[3];
|
||||||
|
float normal[3];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct TriangleInfo {
|
||||||
|
VertexInfo v[3];
|
||||||
|
};
|
||||||
|
|
||||||
|
buffer VertexCollection {
|
||||||
|
TriangleInfo t[5];
|
||||||
|
};
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
liveFunction1(image_ui2D, sampler_2D, sampler_2DMSArray);
|
liveFunction1(image_ui2D, sampler_2D, sampler_2DMSArray);
|
||||||
@ -216,4 +229,9 @@ void main()
|
|||||||
N1 b[4] = nest2.b;
|
N1 b[4] = nest2.b;
|
||||||
f += nest2.c[1].a;
|
f += nest2.c[1].a;
|
||||||
f += nest2.d[gl_InstanceID].a;
|
f += nest2.d[gl_InstanceID].a;
|
||||||
|
|
||||||
|
f += t[0].v[0].position[0];
|
||||||
|
f += t[gl_InstanceID].v[gl_InstanceID].position[gl_InstanceID];
|
||||||
|
f += t[gl_InstanceID].v[gl_InstanceID].normal[gl_InstanceID];
|
||||||
|
TriangleInfo tlocal[5] = t;
|
||||||
}
|
}
|
||||||
|
@ -32,6 +32,8 @@ diff -b $BASEDIR/badMacroArgs.frag.out $TARGETDIR/badMacroArgs.frag.out || HASER
|
|||||||
echo Running reflection...
|
echo Running reflection...
|
||||||
$EXE -l -q -C reflection.vert > $TARGETDIR/reflection.vert.out
|
$EXE -l -q -C reflection.vert > $TARGETDIR/reflection.vert.out
|
||||||
diff -b $BASEDIR/reflection.vert.out $TARGETDIR/reflection.vert.out || HASERROR=1
|
diff -b $BASEDIR/reflection.vert.out $TARGETDIR/reflection.vert.out || HASERROR=1
|
||||||
|
$EXE -l -q -C --reflect-strict-array-suffix reflection.options.vert > $TARGETDIR/reflection.options.vert.out
|
||||||
|
diff -b $BASEDIR/reflection.options.vert.out $TARGETDIR/reflection.options.vert.out || HASERROR=1
|
||||||
$EXE -D -Od -e flizv -l -q -C -V -Od hlsl.reflection.vert > $TARGETDIR/hlsl.reflection.vert.out
|
$EXE -D -Od -e flizv -l -q -C -V -Od hlsl.reflection.vert > $TARGETDIR/hlsl.reflection.vert.out
|
||||||
diff -b $BASEDIR/hlsl.reflection.vert.out $TARGETDIR/hlsl.reflection.vert.out || HASERROR=1
|
diff -b $BASEDIR/hlsl.reflection.vert.out $TARGETDIR/hlsl.reflection.vert.out || HASERROR=1
|
||||||
$EXE -D -Od -e main -l -q -C -V -Od hlsl.reflection.binding.frag > $TARGETDIR/hlsl.reflection.binding.frag.out
|
$EXE -D -Od -e main -l -q -C -V -Od hlsl.reflection.binding.frag > $TARGETDIR/hlsl.reflection.binding.frag.out
|
||||||
|
@ -223,6 +223,16 @@ public:
|
|||||||
void blowUpActiveAggregate(const TType& baseType, const TString& baseName, const TList<TIntermBinary*>& derefs,
|
void blowUpActiveAggregate(const TType& baseType, const TString& baseName, const TList<TIntermBinary*>& derefs,
|
||||||
TList<TIntermBinary*>::const_iterator deref, int offset, int blockIndex, int arraySize)
|
TList<TIntermBinary*>::const_iterator deref, int offset, int blockIndex, int arraySize)
|
||||||
{
|
{
|
||||||
|
// when strictArraySuffix is enabled, we closely follow the rules from ARB_program_interface_query.
|
||||||
|
// Broadly:
|
||||||
|
// * arrays-of-structs always have a [x] suffix.
|
||||||
|
// * with array-of-struct variables in the root of a buffer block, only ever return [0].
|
||||||
|
// * otherwise, array suffixes are added whenever we iterate, even if that means expanding out an array.
|
||||||
|
const bool strictArraySuffix = (reflection.options & EShReflectionStrictArraySuffix);
|
||||||
|
|
||||||
|
// is this variable inside a buffer block. This flag is set back to false after we iterate inside the first array element.
|
||||||
|
bool blockParent = (baseType.getBasicType() == EbtBlock && baseType.getQualifier().storage == EvqBuffer);
|
||||||
|
|
||||||
// process the part of the dereference chain that was explicit in the shader
|
// process the part of the dereference chain that was explicit in the shader
|
||||||
TString name = baseName;
|
TString name = baseName;
|
||||||
const TType* terminalType = &baseType;
|
const TType* terminalType = &baseType;
|
||||||
@ -237,7 +247,9 @@ public:
|
|||||||
// Visit all the indices of this array, and for each one add on the remaining dereferencing
|
// Visit all the indices of this array, and for each one add on the remaining dereferencing
|
||||||
for (int i = 0; i < std::max(visitNode->getLeft()->getType().getOuterArraySize(), 1); ++i) {
|
for (int i = 0; i < std::max(visitNode->getLeft()->getType().getOuterArraySize(), 1); ++i) {
|
||||||
TString newBaseName = name;
|
TString newBaseName = name;
|
||||||
if (baseType.getBasicType() != EbtBlock)
|
if (strictArraySuffix && blockParent)
|
||||||
|
newBaseName.append(TString("[0]"));
|
||||||
|
else if (strictArraySuffix || baseType.getBasicType() != EbtBlock)
|
||||||
newBaseName.append(TString("[") + String(i) + "]");
|
newBaseName.append(TString("[") + String(i) + "]");
|
||||||
TList<TIntermBinary*>::const_iterator nextDeref = deref;
|
TList<TIntermBinary*>::const_iterator nextDeref = deref;
|
||||||
++nextDeref;
|
++nextDeref;
|
||||||
@ -253,12 +265,15 @@ public:
|
|||||||
}
|
}
|
||||||
case EOpIndexDirect:
|
case EOpIndexDirect:
|
||||||
index = visitNode->getRight()->getAsConstantUnion()->getConstArray()[0].getIConst();
|
index = visitNode->getRight()->getAsConstantUnion()->getConstArray()[0].getIConst();
|
||||||
if (baseType.getBasicType() != EbtBlock) {
|
if (strictArraySuffix && blockParent) {
|
||||||
|
name.append(TString("[0]"));
|
||||||
|
} else if (strictArraySuffix || baseType.getBasicType() != EbtBlock) {
|
||||||
name.append(TString("[") + String(index) + "]");
|
name.append(TString("[") + String(index) + "]");
|
||||||
|
|
||||||
if (offset >= 0)
|
if (offset >= 0)
|
||||||
offset += getArrayStride(baseType, visitNode->getLeft()->getType()) * index;
|
offset += getArrayStride(baseType, visitNode->getLeft()->getType()) * index;
|
||||||
}
|
}
|
||||||
|
blockParent = false;
|
||||||
break;
|
break;
|
||||||
case EOpIndexDirectStruct:
|
case EOpIndexDirectStruct:
|
||||||
index = visitNode->getRight()->getAsConstantUnion()->getConstArray()[0].getIConst();
|
index = visitNode->getRight()->getAsConstantUnion()->getConstArray()[0].getIConst();
|
||||||
@ -286,7 +301,13 @@ public:
|
|||||||
if (offset >= 0)
|
if (offset >= 0)
|
||||||
stride = getArrayStride(baseType, *terminalType);
|
stride = getArrayStride(baseType, *terminalType);
|
||||||
|
|
||||||
for (int i = 0; i < std::max(terminalType->getOuterArraySize(), 1); ++i) {
|
int arrayIterateSize = std::max(terminalType->getOuterArraySize(), 1);
|
||||||
|
|
||||||
|
// for top-level arrays in blocks, only expand [0] to avoid explosion of items
|
||||||
|
if (strictArraySuffix && blockParent)
|
||||||
|
arrayIterateSize = 1;
|
||||||
|
|
||||||
|
for (int i = 0; i < arrayIterateSize; ++i) {
|
||||||
TString newBaseName = name;
|
TString newBaseName = name;
|
||||||
newBaseName.append(TString("[") + String(i) + "]");
|
newBaseName.append(TString("[") + String(i) + "]");
|
||||||
TType derefType(*terminalType, 0);
|
TType derefType(*terminalType, 0);
|
||||||
|
@ -244,6 +244,7 @@ enum EShMessages {
|
|||||||
//
|
//
|
||||||
typedef enum {
|
typedef enum {
|
||||||
EShReflectionDefault = 0, // default is original behaviour before options were added
|
EShReflectionDefault = 0, // default is original behaviour before options were added
|
||||||
|
EShReflectionStrictArraySuffix = (1 << 0), // reflection will follow stricter rules for array-of-structs suffixes
|
||||||
} EShReflectionOptions;
|
} EShReflectionOptions;
|
||||||
|
|
||||||
//
|
//
|
||||||
|
Loading…
x
Reference in New Issue
Block a user