Merge pull request #518 from steve-lunarg/flatten-fix

Fix defects in uniform array flattening
This commit is contained in:
John Kessenich 2016-09-22 21:52:44 -06:00 committed by GitHub
commit e53274dfc1
8 changed files with 109 additions and 19 deletions

View File

@ -8,8 +8,8 @@ gl_FragCoord origin is upper left
0:18 Branch: Return with expression 0:18 Branch: Return with expression
0:18 texture (global 4-component vector of float) 0:18 texture (global 4-component vector of float)
0:18 Construct combined texture-sampler (temp sampler1D) 0:18 Construct combined texture-sampler (temp sampler1D)
0:? 'g_tex[1]' (temp texture1D) 0:? 'g_tex[1]' (uniform texture1D)
0:? 'g_samp[1]' (temp sampler) 0:? 'g_samp[1]' (uniform sampler)
0:18 Constant: 0:18 Constant:
0:18 0.200000 0:18 0.200000
0:22 Function Definition: TestFn2(t11[3];p1[3]; (global 4-component vector of float) 0:22 Function Definition: TestFn2(t11[3];p1[3]; (global 4-component vector of float)
@ -197,8 +197,8 @@ gl_FragCoord origin is upper left
0:18 Branch: Return with expression 0:18 Branch: Return with expression
0:18 texture (global 4-component vector of float) 0:18 texture (global 4-component vector of float)
0:18 Construct combined texture-sampler (temp sampler1D) 0:18 Construct combined texture-sampler (temp sampler1D)
0:? 'g_tex[1]' (temp texture1D) 0:? 'g_tex[1]' (uniform texture1D)
0:? 'g_samp[1]' (temp sampler) 0:? 'g_samp[1]' (uniform sampler)
0:18 Constant: 0:18 Constant:
0:18 0.200000 0:18 0.200000
0:22 Function Definition: TestFn2(t11[3];p1[3]; (global 4-component vector of float) 0:22 Function Definition: TestFn2(t11[3];p1[3]; (global 4-component vector of float)
@ -419,6 +419,8 @@ gl_FragCoord origin is upper left
Name 125 "g_mats_explicit[1]" Name 125 "g_mats_explicit[1]"
Name 126 "g_mats_explicit[2]" Name 126 "g_mats_explicit[2]"
Name 127 "g_mats_explicit[3]" Name 127 "g_mats_explicit[3]"
Decorate 36(g_tex[1]) DescriptorSet 0
Decorate 39(g_samp[1]) DescriptorSet 0
Decorate 57(g_samp[0]) DescriptorSet 0 Decorate 57(g_samp[0]) DescriptorSet 0
Decorate 62(g_samp[2]) DescriptorSet 0 Decorate 62(g_samp[2]) DescriptorSet 0
Decorate 66(g_tex[0]) DescriptorSet 0 Decorate 66(g_tex[0]) DescriptorSet 0

View File

@ -0,0 +1,57 @@
spv.register.autoassign-2.frag
Linked fragment stage:
// Module Version 10000
// Generated by (magic number): 80001
// Id's are bound by 30
Capability Shader
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
EntryPoint Fragment 4 "main" 9
ExecutionMode 4 OriginUpperLeft
Name 4 "main"
Name 9 "Color"
Name 12 "g_tScene[0]"
Name 16 "g_tSamp"
Name 24 "g_tScene[1]"
Decorate 9(Color) Location 0
Decorate 12(g_tScene[0]) DescriptorSet 0
Decorate 12(g_tScene[0]) Binding 10
Decorate 16(g_tSamp) DescriptorSet 0
Decorate 16(g_tSamp) Binding 5
Decorate 24(g_tScene[1]) DescriptorSet 0
Decorate 24(g_tScene[1]) Binding 11
2: TypeVoid
3: TypeFunction 2
6: TypeFloat 32
7: TypeVector 6(float) 4
8: TypePointer Output 7(fvec4)
9(Color): 8(ptr) Variable Output
10: TypeImage 6(float) 2D sampled format:Unknown
11: TypePointer UniformConstant 10
12(g_tScene[0]): 11(ptr) Variable UniformConstant
14: TypeSampler
15: TypePointer UniformConstant 14
16(g_tSamp): 15(ptr) Variable UniformConstant
18: TypeSampledImage 10
20: TypeVector 6(float) 2
21: 6(float) Constant 1050253722
22: 20(fvec2) ConstantComposite 21 21
24(g_tScene[1]): 11(ptr) Variable UniformConstant
4(main): 2 Function None 3
5: Label
13: 10 Load 12(g_tScene[0])
17: 14 Load 16(g_tSamp)
19: 18 SampledImage 13 17
23: 7(fvec4) ImageSampleImplicitLod 19 22
25: 10 Load 24(g_tScene[1])
26: 14 Load 16(g_tSamp)
27: 18 SampledImage 25 26
28: 7(fvec4) ImageSampleImplicitLod 27 22
29: 7(fvec4) FAdd 23 28
Store 9(Color) 29
Return
FunctionEnd

View File

@ -0,0 +1,15 @@
SamplerState g_tSamp : register(s0);
Texture2D g_tScene[2] : register(t0);
struct PS_OUTPUT
{
float4 Color : SV_Target0;
};
void main(out PS_OUTPUT psout)
{
psout.Color = g_tScene[0].Sample(g_tSamp, 0.3) +
g_tScene[1].Sample(g_tSamp, 0.3);
}

View File

@ -56,7 +56,9 @@ namespace glslang {
class TLiveTraverser : public TIntermTraverser { class TLiveTraverser : public TIntermTraverser {
public: public:
TLiveTraverser(const TIntermediate& i, bool traverseAll = false) : TLiveTraverser(const TIntermediate& i, bool traverseAll = false,
bool preVisit = true, bool inVisit = false, bool postVisit = false) :
TIntermTraverser(preVisit, inVisit, postVisit),
intermediate(i), traverseAll(traverseAll) intermediate(i), traverseAll(traverseAll)
{ } { }

View File

@ -74,7 +74,7 @@ class TBindingTraverser : public TLiveTraverser {
public: public:
TBindingTraverser(const TIntermediate& i, TBindingMap& bindingMap, TUsedBindings& usedBindings, TBindingTraverser(const TIntermediate& i, TBindingMap& bindingMap, TUsedBindings& usedBindings,
bool traverseDeadCode = false) : bool traverseDeadCode = false) :
TLiveTraverser(i, traverseDeadCode), TLiveTraverser(i, traverseDeadCode, true, true, false),
bindingMap(bindingMap), bindingMap(bindingMap),
usedBindings(usedBindings) usedBindings(usedBindings)
{ } { }

View File

@ -48,6 +48,7 @@ struct IoMapData {
int baseTextureBinding; int baseTextureBinding;
int baseUboBinding; int baseUboBinding;
bool autoMapBindings; bool autoMapBindings;
bool flattenUniforms;
}; };
std::string FileNameAsCustomTestSuffixIoMap( std::string FileNameAsCustomTestSuffixIoMap(
@ -119,7 +120,8 @@ TEST_P(HlslSemantics, FromFile)
GetParam().baseSamplerBinding, GetParam().baseSamplerBinding,
GetParam().baseTextureBinding, GetParam().baseTextureBinding,
GetParam().baseUboBinding, GetParam().baseUboBinding,
GetParam().autoMapBindings); GetParam().autoMapBindings,
GetParam().flattenUniforms);
} }
// clang-format off // clang-format off
@ -251,8 +253,9 @@ INSTANTIATE_TEST_CASE_P(
INSTANTIATE_TEST_CASE_P( INSTANTIATE_TEST_CASE_P(
Hlsl, HlslSemantics, Hlsl, HlslSemantics,
::testing::ValuesIn(std::vector<IoMapData>{ ::testing::ValuesIn(std::vector<IoMapData>{
{ "spv.register.autoassign.frag", "main_ep", 5, 10, 15, true }, { "spv.register.autoassign.frag", "main_ep", 5, 10, 15, true, false },
{ "spv.register.noautoassign.frag", "main_ep", 5, 10, 15, false }, { "spv.register.noautoassign.frag", "main_ep", 5, 10, 15, false, false },
{ "spv.register.autoassign-2.frag", "main", 5, 10, 15, true, true },
}), }),
FileNameAsCustomTestSuffixIoMap FileNameAsCustomTestSuffixIoMap
); );

View File

@ -248,7 +248,8 @@ public:
int baseSamplerBinding, int baseSamplerBinding,
int baseTextureBinding, int baseTextureBinding,
int baseUboBinding, int baseUboBinding,
bool autoMapBindings) bool autoMapBindings,
bool flattenUniformArrays)
{ {
const EShLanguage kind = GetShaderStage(GetSuffix(shaderName)); const EShLanguage kind = GetShaderStage(GetSuffix(shaderName));
@ -257,6 +258,7 @@ public:
shader.setShiftTextureBinding(baseTextureBinding); shader.setShiftTextureBinding(baseTextureBinding);
shader.setShiftUboBinding(baseUboBinding); shader.setShiftUboBinding(baseUboBinding);
shader.setAutoMapBindings(autoMapBindings); shader.setAutoMapBindings(autoMapBindings);
shader.setFlattenUniformArrays(flattenUniformArrays);
bool success = compile(&shader, code, entryPointName, controls); bool success = compile(&shader, code, entryPointName, controls);
@ -433,7 +435,8 @@ public:
int baseSamplerBinding, int baseSamplerBinding,
int baseTextureBinding, int baseTextureBinding,
int baseUboBinding, int baseUboBinding,
bool autoMapBindings) bool autoMapBindings,
bool flattenUniformArrays)
{ {
const std::string inputFname = testDir + "/" + testName; const std::string inputFname = testDir + "/" + testName;
const std::string expectedOutputFname = const std::string expectedOutputFname =
@ -446,7 +449,8 @@ public:
const EShMessages controls = DeriveOptions(source, semantics, target); const EShMessages controls = DeriveOptions(source, semantics, target);
GlslangResult result = compileLinkIoMap(testName, input, entryPointName, controls, GlslangResult result = compileLinkIoMap(testName, input, entryPointName, controls,
baseSamplerBinding, baseTextureBinding, baseUboBinding, baseSamplerBinding, baseTextureBinding, baseUboBinding,
autoMapBindings); autoMapBindings,
flattenUniformArrays);
// Generate the hybrid output in the way of glslangValidator. // Generate the hybrid output in the way of glslangValidator.
std::ostringstream stream; std::ostringstream stream;

View File

@ -383,6 +383,7 @@ TIntermTyped* HlslParseContext::handleBracketDereference(const TSourceLoc& loc,
{ {
TIntermTyped* result = nullptr; TIntermTyped* result = nullptr;
bool flattened = false;
int indexValue = 0; int indexValue = 0;
if (index->getQualifier().storage == EvqConst) { if (index->getQualifier().storage == EvqConst) {
indexValue = index->getAsConstantUnion()->getConstArray()[0].getIConst(); indexValue = index->getAsConstantUnion()->getConstArray()[0].getIConst();
@ -408,6 +409,7 @@ TIntermTyped* HlslParseContext::handleBracketDereference(const TSourceLoc& loc,
error(loc, "Invalid variable index to flattened uniform array", base->getAsSymbolNode()->getName().c_str(), ""); error(loc, "Invalid variable index to flattened uniform array", base->getAsSymbolNode()->getName().c_str(), "");
result = flattenAccess(base, indexValue); result = flattenAccess(base, indexValue);
flattened = (result != base);
} else { } else {
if (index->getQualifier().storage == EvqConst) { if (index->getQualifier().storage == EvqConst) {
if (base->getType().isImplicitlySizedArray()) if (base->getType().isImplicitlySizedArray())
@ -423,6 +425,10 @@ TIntermTyped* HlslParseContext::handleBracketDereference(const TSourceLoc& loc,
// Insert dummy error-recovery result // Insert dummy error-recovery result
result = intermediate.addConstantUnion(0.0, EbtFloat, loc); result = intermediate.addConstantUnion(0.0, EbtFloat, loc);
} else { } else {
// If the array reference was flattened, it has the correct type. E.g, if it was
// a uniform array, it was flattened INTO a set of scalar uniforms, not scalar temps.
// In that case, we preserve the qualifiers.
if (!flattened) {
// Insert valid dereferenced result // Insert valid dereferenced result
TType newType(base->getType(), 0); // dereferenced type TType newType(base->getType(), 0); // dereferenced type
if (base->getType().getQualifier().storage == EvqConst && index->getQualifier().storage == EvqConst) if (base->getType().getQualifier().storage == EvqConst && index->getQualifier().storage == EvqConst)
@ -431,6 +437,7 @@ TIntermTyped* HlslParseContext::handleBracketDereference(const TSourceLoc& loc,
newType.getQualifier().storage = EvqTemporary; newType.getQualifier().storage = EvqTemporary;
result->setType(newType); result->setType(newType);
} }
}
return result; return result;
} }