Remove barrier on Intel if control flow is potentially divergent (#5044)

* Remove barrier on Intel if control flow is potentially divergent

* Shader cache version bump
This commit is contained in:
gdkchan 2023-06-08 17:43:16 -03:00 committed by GitHub
parent fe30c03cac
commit 2cdcfe46d8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 64 additions and 8 deletions

View file

@ -28,18 +28,18 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
for (int i = 1; i < info.Functions.Count; i++)
{
PrintFunction(context, info, info.Functions[i]);
PrintFunction(context, info.Functions[i]);
context.AppendLine();
}
}
PrintFunction(context, info, info.Functions[0], MainFunctionName);
PrintFunction(context, info.Functions[0], MainFunctionName);
return context.GetCode();
}
private static void PrintFunction(CodeGenContext context, StructuredProgramInfo info, StructuredFunction function, string funcName = null)
private static void PrintFunction(CodeGenContext context, StructuredFunction function, string funcName = null)
{
context.CurrentFunction = function;
@ -48,7 +48,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
Declarations.DeclareLocals(context, function);
PrintBlock(context, function.MainBlock);
PrintBlock(context, function.MainBlock, funcName == MainFunctionName);
context.LeaveScope();
}
@ -72,7 +72,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
return $"{Declarations.GetVarTypeName(context, function.ReturnType)} {funcName ?? function.Name}({string.Join(", ", args)})";
}
private static void PrintBlock(CodeGenContext context, AstBlock block)
private static void PrintBlock(CodeGenContext context, AstBlock block, bool isMainFunction)
{
AstBlockVisitor visitor = new AstBlockVisitor(block);
@ -112,10 +112,32 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
}
};
bool supportsBarrierDivergence = context.Config.GpuAccessor.QueryHostSupportsShaderBarrierDivergence();
bool mayHaveReturned = false;
foreach (IAstNode node in visitor.Visit())
{
if (node is AstOperation operation)
{
if (!supportsBarrierDivergence)
{
if (operation.Inst == IntermediateRepresentation.Instruction.Barrier)
{
// Barrier on divergent control flow paths may cause the GPU to hang,
// so skip emitting the barrier for those cases.
if (visitor.Block.Type != AstBlockType.Main || mayHaveReturned || !isMainFunction)
{
context.Config.GpuAccessor.Log($"Shader has barrier on potentially divergent block, the barrier will be removed.");
continue;
}
}
else if (operation.Inst == IntermediateRepresentation.Instruction.Return)
{
mayHaveReturned = true;
}
}
string expr = InstGen.GetExpression(context, operation);
if (expr != null)