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:
parent
7719909397
commit
40e276c9b5
5 changed files with 158 additions and 129 deletions
|
@ -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)
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue