mirror of
https://git.naxdy.org/Mirror/Ryujinx.git
synced 2025-02-22 17:10:19 +00:00
SPIR-V: Implement LoopContinue IR instruction
This commit is contained in:
parent
aa0913838d
commit
3c949309e5
3 changed files with 21 additions and 0 deletions
|
@ -57,6 +57,8 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
||||||
|
|
||||||
private readonly Dictionary<AstBlock, BlockState> _labels = new Dictionary<AstBlock, BlockState>();
|
private readonly Dictionary<AstBlock, BlockState> _labels = new Dictionary<AstBlock, BlockState>();
|
||||||
|
|
||||||
|
public Dictionary<AstBlock, (Instruction, Instruction)> LoopTargets { get; set; }
|
||||||
|
|
||||||
public AstBlock CurrentBlock { get; private set; }
|
public AstBlock CurrentBlock { get; private set; }
|
||||||
|
|
||||||
public CodeGenContext(ShaderConfig config) : base(0x00010300)
|
public CodeGenContext(ShaderConfig config) : base(0x00010300)
|
||||||
|
|
|
@ -95,6 +95,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
||||||
Add(Instruction.LogicalNot, GenerateLogicalNot);
|
Add(Instruction.LogicalNot, GenerateLogicalNot);
|
||||||
Add(Instruction.LogicalOr, GenerateLogicalOr);
|
Add(Instruction.LogicalOr, GenerateLogicalOr);
|
||||||
Add(Instruction.LoopBreak, GenerateLoopBreak);
|
Add(Instruction.LoopBreak, GenerateLoopBreak);
|
||||||
|
Add(Instruction.LoopContinue, GenerateLoopContinue);
|
||||||
Add(Instruction.Maximum, GenerateMaximum);
|
Add(Instruction.Maximum, GenerateMaximum);
|
||||||
Add(Instruction.MaximumU32, GenerateMaximumU32);
|
Add(Instruction.MaximumU32, GenerateMaximumU32);
|
||||||
Add(Instruction.MemoryBarrier, GenerateMemoryBarrier);
|
Add(Instruction.MemoryBarrier, GenerateMemoryBarrier);
|
||||||
|
@ -963,6 +964,21 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
||||||
return OperationResult.Invalid;
|
return OperationResult.Invalid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static OperationResult GenerateLoopContinue(CodeGenContext context, AstOperation operation)
|
||||||
|
{
|
||||||
|
AstBlock loopBlock = context.CurrentBlock;
|
||||||
|
while (loopBlock.Type != AstBlockType.DoWhile)
|
||||||
|
{
|
||||||
|
loopBlock = loopBlock.Parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
(var loopTarget, var continueTarget) = context.LoopTargets[loopBlock];
|
||||||
|
|
||||||
|
context.Branch(continueTarget);
|
||||||
|
|
||||||
|
return OperationResult.Invalid;
|
||||||
|
}
|
||||||
|
|
||||||
private static OperationResult GenerateMaximum(CodeGenContext context, AstOperation operation)
|
private static OperationResult GenerateMaximum(CodeGenContext context, AstOperation operation)
|
||||||
{
|
{
|
||||||
return GenerateBinary(context, operation, context.GlslFMax, context.GlslSMax);
|
return GenerateBinary(context, operation, context.GlslFMax, context.GlslSMax);
|
||||||
|
|
|
@ -130,6 +130,8 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
||||||
|
|
||||||
var loopTargets = new Dictionary<AstBlock, (SpvInstruction, SpvInstruction)>();
|
var loopTargets = new Dictionary<AstBlock, (SpvInstruction, SpvInstruction)>();
|
||||||
|
|
||||||
|
context.LoopTargets = loopTargets;
|
||||||
|
|
||||||
visitor.BlockEntered += (sender, e) =>
|
visitor.BlockEntered += (sender, e) =>
|
||||||
{
|
{
|
||||||
AstBlock mergeBlock = e.Block.Parent;
|
AstBlock mergeBlock = e.Block.Parent;
|
||||||
|
@ -192,6 +194,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
||||||
bool lastIsCf = e.Block.Last is AstOperation lastOp &&
|
bool lastIsCf = e.Block.Last is AstOperation lastOp &&
|
||||||
(lastOp.Inst == Instruction.Discard ||
|
(lastOp.Inst == Instruction.Discard ||
|
||||||
lastOp.Inst == Instruction.LoopBreak ||
|
lastOp.Inst == Instruction.LoopBreak ||
|
||||||
|
lastOp.Inst == Instruction.LoopContinue ||
|
||||||
lastOp.Inst == Instruction.Return);
|
lastOp.Inst == Instruction.Return);
|
||||||
|
|
||||||
if (!lastIsCf)
|
if (!lastIsCf)
|
||||||
|
|
Loading…
Reference in a new issue