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>();
|
||||
|
||||
public Dictionary<AstBlock, (Instruction, Instruction)> LoopTargets { get; set; }
|
||||
|
||||
public AstBlock CurrentBlock { get; private set; }
|
||||
|
||||
public CodeGenContext(ShaderConfig config) : base(0x00010300)
|
||||
|
|
|
@ -95,6 +95,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||
Add(Instruction.LogicalNot, GenerateLogicalNot);
|
||||
Add(Instruction.LogicalOr, GenerateLogicalOr);
|
||||
Add(Instruction.LoopBreak, GenerateLoopBreak);
|
||||
Add(Instruction.LoopContinue, GenerateLoopContinue);
|
||||
Add(Instruction.Maximum, GenerateMaximum);
|
||||
Add(Instruction.MaximumU32, GenerateMaximumU32);
|
||||
Add(Instruction.MemoryBarrier, GenerateMemoryBarrier);
|
||||
|
@ -963,6 +964,21 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||
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)
|
||||
{
|
||||
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)>();
|
||||
|
||||
context.LoopTargets = loopTargets;
|
||||
|
||||
visitor.BlockEntered += (sender, e) =>
|
||||
{
|
||||
AstBlock mergeBlock = e.Block.Parent;
|
||||
|
@ -192,6 +194,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
|
|||
bool lastIsCf = e.Block.Last is AstOperation lastOp &&
|
||||
(lastOp.Inst == Instruction.Discard ||
|
||||
lastOp.Inst == Instruction.LoopBreak ||
|
||||
lastOp.Inst == Instruction.LoopContinue ||
|
||||
lastOp.Inst == Instruction.Return);
|
||||
|
||||
if (!lastIsCf)
|
||||
|
|
Loading…
Reference in a new issue