Improve shader global memory to storage pass (#2200)

* Improve shader global memory to storage pass

* Formatting and more comments

* Shader cache version bump
This commit is contained in:
gdkchan 2021-04-18 07:31:39 -03:00 committed by GitHub
parent 7719909397
commit 40e276c9b5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 158 additions and 129 deletions

View file

@ -5,66 +5,6 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
{
class BindlessElimination
{
private static Operation FindBranchSource(BasicBlock block)
{
foreach (BasicBlock sourceBlock in block.Predecessors)
{
if (sourceBlock.Operations.Count > 0)
{
Operation lastOp = sourceBlock.Operations.Last.Value as Operation;
if (lastOp != null &&
((sourceBlock.Next == block && lastOp.Inst == Instruction.BranchIfFalse) ||
(sourceBlock.Branch == block && lastOp.Inst == Instruction.BranchIfTrue)))
{
return lastOp;
}
}
}
return null;
}
private static bool BlockConditionsMatch(BasicBlock currentBlock, BasicBlock queryBlock)
{
// Check if all the conditions for the query block are satisfied by the current block.
// Just checks the top-most conditional for now.
Operation currentBranch = FindBranchSource(currentBlock);
Operation queryBranch = FindBranchSource(queryBlock);
Operand currentCondition = currentBranch?.GetSource(0);
Operand queryCondition = queryBranch?.GetSource(0);
// The condition should be the same operand instance.
return currentBranch != null && queryBranch != null &&
currentBranch.Inst == queryBranch.Inst &&
currentCondition == queryCondition;
}
private static Operand FindLastOperation(Operand source, BasicBlock block)
{
if (source.AsgOp is PhiNode phiNode)
{
// This source can have a different value depending on a previous branch.
// Ensure that conditions met for that branch are also met for the current one.
// Prefer the latest sources for the phi node.
for (int i = phiNode.SourcesCount - 1; i >= 0; i--)
{
BasicBlock phiBlock = phiNode.GetBlock(i);
if (BlockConditionsMatch(block, phiBlock))
{
return phiNode.GetSource(i);
}
}
}
return source;
}
public static void RunPass(BasicBlock block, ShaderConfig config)
{
// We can turn a bindless into regular access by recognizing the pattern
@ -89,7 +29,7 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
texOp.Inst == Instruction.TextureSample ||
texOp.Inst == Instruction.TextureSize)
{
Operand bindlessHandle = FindLastOperation(texOp.GetSource(0), block);
Operand bindlessHandle = Utils.FindLastOperation(texOp.GetSource(0), block);
if (bindlessHandle.Type == OperandType.ConstantBuffer)
{
@ -107,8 +47,8 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
continue;
}
Operand src0 = FindLastOperation(handleCombineOp.GetSource(0), block);
Operand src1 = FindLastOperation(handleCombineOp.GetSource(1), block);
Operand src0 = Utils.FindLastOperation(handleCombineOp.GetSource(0), block);
Operand src1 = Utils.FindLastOperation(handleCombineOp.GetSource(1), block);
if (src0.Type != OperandType.ConstantBuffer ||
src1.Type != OperandType.ConstantBuffer || src0.GetCbufSlot() != src1.GetCbufSlot())
@ -120,7 +60,7 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
}
else if (texOp.Inst == Instruction.ImageLoad || texOp.Inst == Instruction.ImageStore)
{
Operand src0 = FindLastOperation(texOp.GetSource(0), block);
Operand src0 = Utils.FindLastOperation(texOp.GetSource(0), block);
if (src0.Type == OperandType.ConstantBuffer)
{