Merge pull request #1404 from KhronosGroup/fix-1402

HLSL: Workaround FXC bugs with degenerate switch blocks.
This commit is contained in:
Hans-Kristian Arntzen 2020-06-23 18:32:35 +02:00 committed by GitHub
commit 2e7a562583
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 163 additions and 165 deletions

View File

@ -11,64 +11,61 @@ struct main0_out
fragment main0_out main0()
{
main0_out out = {};
switch (0u)
do
{
default:
out.FragColor = 16;
for (int _143 = 0; _143 < 25; )
{
out.FragColor = 16;
for (int _143 = 0; _143 < 25; )
out.FragColor += 10;
_143++;
continue;
}
for (int _144 = 1; _144 < 30; )
{
out.FragColor += 11;
_144++;
continue;
}
int _145;
_145 = 0;
for (; _145 < 20; )
{
out.FragColor += 12;
_145++;
continue;
}
int _62 = _145 + 3;
out.FragColor += _62;
if (_62 == 40)
{
for (int _149 = 0; _149 < 40; )
{
out.FragColor += 10;
_143++;
out.FragColor += 13;
_149++;
continue;
}
for (int _144 = 1; _144 < 30; )
{
out.FragColor += 11;
_144++;
continue;
}
int _145;
_145 = 0;
for (; _145 < 20; )
{
out.FragColor += 12;
_145++;
continue;
}
int _62 = _145 + 3;
out.FragColor += _62;
if (_62 == 40)
{
for (int _149 = 0; _149 < 40; )
{
out.FragColor += 13;
_149++;
continue;
}
break;
}
out.FragColor += _62;
int2 _146;
_146 = int2(0);
for (; _146.x < 10; )
{
out.FragColor += _146.y;
int2 _142 = _146;
_142.x = _146.x + 4;
_146 = _142;
continue;
}
for (int _148 = _62; _148 < 40; )
{
out.FragColor += _148;
_148++;
continue;
}
out.FragColor += _62;
break;
}
}
out.FragColor += _62;
int2 _146;
_146 = int2(0);
for (; _146.x < 10; )
{
out.FragColor += _146.y;
int2 _142 = _146;
_142.x = _146.x + 4;
_146 = _142;
continue;
}
for (int _148 = _62; _148 < 40; )
{
out.FragColor += _148;
_148++;
continue;
}
out.FragColor += _62;
break;
} while(false);
return out;
}

View File

@ -15,55 +15,49 @@ int _231;
void main()
{
int _228;
switch (0u)
do
{
default:
bool _225;
int _229;
uint _222 = 0u;
for (;;)
{
bool _225;
int _229;
uint _222 = 0u;
for (;;)
if (_222 < _11.shadowCascadesNum)
{
if (_222 < _11.shadowCascadesNum)
mat4 _223;
do
{
mat4 _223;
switch (0u)
if (_11.test == 0)
{
default:
{
if (_11.test == 0)
{
_223 = mat4(vec4(0.5, 0.0, 0.0, 0.0), vec4(0.0, 0.5, 0.0, 0.0), vec4(0.0, 0.0, 0.5, 0.0), vec4(0.0, 0.0, 0.0, 1.0));
break;
}
_223 = mat4(vec4(1.0, 0.0, 0.0, 0.0), vec4(0.0, 1.0, 0.0, 0.0), vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0));
break;
}
}
vec4 _170 = (_223 * _11.lightVP[_222]) * vec4(fragWorld, 1.0);
float _172 = _170.z;
float _179 = _170.x;
float _181 = _170.y;
if ((((_172 >= 0.0) && (_172 <= 1.0)) && (max(_179, _181) <= 1.0)) && (min(_179, _181) >= 0.0))
{
_229 = int(_222);
_225 = true;
_223 = mat4(vec4(0.5, 0.0, 0.0, 0.0), vec4(0.0, 0.5, 0.0, 0.0), vec4(0.0, 0.0, 0.5, 0.0), vec4(0.0, 0.0, 0.0, 1.0));
break;
}
_222++;
continue;
}
else
_223 = mat4(vec4(1.0, 0.0, 0.0, 0.0), vec4(0.0, 1.0, 0.0, 0.0), vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0));
break;
} while(false);
vec4 _170 = (_223 * _11.lightVP[_222]) * vec4(fragWorld, 1.0);
float _172 = _170.z;
float _179 = _170.x;
float _181 = _170.y;
if ((((_172 >= 0.0) && (_172 <= 1.0)) && (max(_179, _181) <= 1.0)) && (min(_179, _181) >= 0.0))
{
_229 = _231;
_225 = false;
_229 = int(_222);
_225 = true;
break;
}
_222++;
continue;
}
else
{
_229 = _231;
_225 = false;
break;
}
_228 = -1;
break;
}
}
_228 = -1;
break;
} while(false);
_entryPointOutput = _228;
}

View File

@ -6,63 +6,60 @@ layout(location = 0) out mediump int FragColor;
void main()
{
switch (0u)
do
{
default:
FragColor = 16;
for (mediump int _143 = 0; _143 < 25; )
{
FragColor = 16;
for (mediump int _143 = 0; _143 < 25; )
FragColor += 10;
_143++;
continue;
}
for (mediump int _144 = 1; _144 < 30; )
{
FragColor += 11;
_144++;
continue;
}
mediump int _145;
_145 = 0;
for (; _145 < 20; )
{
FragColor += 12;
_145++;
continue;
}
mediump int _62 = _145 + 3;
FragColor += _62;
if (_62 == 40)
{
for (mediump int _149 = 0; _149 < 40; )
{
FragColor += 10;
_143++;
FragColor += 13;
_149++;
continue;
}
for (mediump int _144 = 1; _144 < 30; )
{
FragColor += 11;
_144++;
continue;
}
mediump int _145;
_145 = 0;
for (; _145 < 20; )
{
FragColor += 12;
_145++;
continue;
}
mediump int _62 = _145 + 3;
FragColor += _62;
if (_62 == 40)
{
for (mediump int _149 = 0; _149 < 40; )
{
FragColor += 13;
_149++;
continue;
}
break;
}
FragColor += _62;
mediump ivec2 _146;
_146 = ivec2(0);
for (; _146.x < 10; )
{
FragColor += _146.y;
mediump ivec2 _142 = _146;
_142.x = _146.x + 4;
_146 = _142;
continue;
}
for (mediump int _148 = _62; _148 < 40; )
{
FragColor += _148;
_148++;
continue;
}
FragColor += _62;
break;
}
}
FragColor += _62;
mediump ivec2 _146;
_146 = ivec2(0);
for (; _146.x < 10; )
{
FragColor += _146.y;
mediump ivec2 _142 = _146;
_142.x = _146.x + 4;
_146 = _142;
continue;
}
for (mediump int _148 = _62; _148 < 40; )
{
FragColor += _148;
_148++;
continue;
}
FragColor += _62;
break;
} while(false);
}

View File

@ -5,18 +5,15 @@ layout(location = 0) out vec4 FragColor;
void main()
{
switch (0u)
do
{
default:
if (vIndex != 1)
{
if (vIndex != 1)
{
FragColor = vec4(1.0);
break;
}
FragColor = vec4(10.0);
FragColor = vec4(1.0);
break;
}
}
FragColor = vec4(10.0);
break;
} while(false);
}

View File

@ -9,21 +9,18 @@ vec2 _19;
void main()
{
highp vec2 _30;
switch (0)
do
{
default:
if (gl_FragCoord.x != gl_FragCoord.x)
{
if (gl_FragCoord.x != gl_FragCoord.x)
{
_30 = _19;
break;
}
highp vec2 _29 = _19;
_29.y = _19.y;
_30 = _29;
_30 = _19;
break;
}
}
highp vec2 _29 = _19;
_29.y = _19.y;
_30 = _29;
break;
} while(false);
_GLF_color = vec4(_30, 1.0, 1.0);
}

View File

@ -13336,8 +13336,18 @@ void CompilerGLSL::emit_block_chain(SPIRBlock &block)
}
}
emit_block_hints(block);
statement("switch (", to_expression(block.condition), ")");
// If there is only one default block, and no cases, this is a case where SPIRV-opt decided to emulate
// non-structured exits with the help of a switch block.
// This is buggy on FXC, so just emit the logical equivalent of a do { } while(false), which is more idiomatic.
bool degenerate_switch = block.default_block != block.merge_block && block.cases.empty();
if (degenerate_switch)
statement("do");
else
{
emit_block_hints(block);
statement("switch (", to_expression(block.condition), ")");
}
begin_scope();
for (size_t i = 0; i < num_blocks; i++)
@ -13348,7 +13358,8 @@ void CompilerGLSL::emit_block_chain(SPIRBlock &block)
if (literals.empty())
{
// Default case.
statement("default:");
if (!degenerate_switch)
statement("default:");
}
else
{
@ -13372,9 +13383,11 @@ void CompilerGLSL::emit_block_chain(SPIRBlock &block)
else
current_emitting_switch_fallthrough = false;
begin_scope();
if (!degenerate_switch)
begin_scope();
branch(block.self, target_block);
end_scope();
if (!degenerate_switch)
end_scope();
current_emitting_switch_fallthrough = false;
}
@ -13397,7 +13410,10 @@ void CompilerGLSL::emit_block_chain(SPIRBlock &block)
}
}
end_scope();
if (degenerate_switch)
end_scope_decl("while(false)");
else
end_scope();
if (block.need_ladder_break)
{