aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics.Shader/Translation/Translator.cs
diff options
context:
space:
mode:
authorgdk <gab.dark.100@gmail.com>2019-11-14 14:20:30 -0300
committerThog <thog@protonmail.com>2020-01-09 02:13:00 +0100
commitf0a59f345c633b757ebd2a22fca23d7dab0f9f99 (patch)
tree444aa5ac024119594bc9f5b51e3710483537e6e6 /Ryujinx.Graphics.Shader/Translation/Translator.cs
parentd274328c3192fd85b9eec661b00f1599d673776c (diff)
Add partial support for the BRX shader instruction
Diffstat (limited to 'Ryujinx.Graphics.Shader/Translation/Translator.cs')
-rw-r--r--Ryujinx.Graphics.Shader/Translation/Translator.cs47
1 files changed, 30 insertions, 17 deletions
diff --git a/Ryujinx.Graphics.Shader/Translation/Translator.cs b/Ryujinx.Graphics.Shader/Translation/Translator.cs
index b7a5bffa..55617b24 100644
--- a/Ryujinx.Graphics.Shader/Translation/Translator.cs
+++ b/Ryujinx.Graphics.Shader/Translation/Translator.cs
@@ -46,7 +46,12 @@ namespace Ryujinx.Graphics.Shader.Translation
bool compute = (translationConfig.Flags & TranslationFlags.Compute) != 0;
bool debugMode = (translationConfig.Flags & TranslationFlags.DebugMode) != 0;
- Operation[] ops = DecodeShader(code, compute, debugMode, out ShaderHeader header);
+ Operation[] ops = DecodeShader(
+ code,
+ compute,
+ debugMode,
+ out ShaderHeader header,
+ out int size);
ShaderStage stage;
@@ -76,15 +81,15 @@ namespace Ryujinx.Graphics.Shader.Translation
maxOutputVertexCount,
outputTopology);
- return Translate(ops, config);
+ return Translate(ops, config, size);
}
public static ShaderProgram Translate(Span<byte> vpACode, Span<byte> vpBCode, TranslationConfig translationConfig)
{
bool debugMode = (translationConfig.Flags & TranslationFlags.DebugMode) != 0;
- Operation[] vpAOps = DecodeShader(vpACode, compute: false, debugMode, out _);
- Operation[] vpBOps = DecodeShader(vpBCode, compute: false, debugMode, out ShaderHeader header);
+ Operation[] vpAOps = DecodeShader(vpACode, compute: false, debugMode, out _, out _);
+ Operation[] vpBOps = DecodeShader(vpBCode, compute: false, debugMode, out ShaderHeader header, out int sizeB);
ShaderConfig config = new ShaderConfig(
header.Stage,
@@ -93,10 +98,10 @@ namespace Ryujinx.Graphics.Shader.Translation
header.MaxOutputVertexCount,
header.OutputTopology);
- return Translate(Combine(vpAOps, vpBOps), config);
+ return Translate(Combine(vpAOps, vpBOps), config, sizeB);
}
- private static ShaderProgram Translate(Operation[] ops, ShaderConfig config)
+ private static ShaderProgram Translate(Operation[] ops, ShaderConfig config, int size)
{
BasicBlock[] irBlocks = ControlFlowGraph.MakeCfg(ops);
@@ -122,17 +127,20 @@ namespace Ryujinx.Graphics.Shader.Translation
string glslCode = program.Code;
- return new ShaderProgram(spInfo, config.Stage, glslCode);
+ return new ShaderProgram(spInfo, config.Stage, glslCode, size);
}
- private static Operation[] DecodeShader(Span<byte> code, bool compute, bool debugMode, out ShaderHeader header)
+ private static Operation[] DecodeShader(
+ Span<byte> code,
+ bool compute,
+ bool debugMode,
+ out ShaderHeader header,
+ out int size)
{
Block[] cfg;
EmitterContext context;
- ulong headerSize;
-
if (compute)
{
header = null;
@@ -140,8 +148,6 @@ namespace Ryujinx.Graphics.Shader.Translation
cfg = Decoder.Decode(code, 0);
context = new EmitterContext(ShaderStage.Compute, header);
-
- headerSize = 0;
}
else
{
@@ -150,14 +156,19 @@ namespace Ryujinx.Graphics.Shader.Translation
cfg = Decoder.Decode(code, HeaderSize);
context = new EmitterContext(header.Stage, header);
-
- headerSize = HeaderSize;
}
+ ulong maxEndAddress = 0;
+
for (int blkIndex = 0; blkIndex < cfg.Length; blkIndex++)
{
Block block = cfg[blkIndex];
+ if (maxEndAddress < block.EndAddress)
+ {
+ maxEndAddress = block.EndAddress;
+ }
+
context.CurrBlock = block;
context.MarkLabel(context.GetLabel(block.Address));
@@ -179,7 +190,7 @@ namespace Ryujinx.Graphics.Shader.Translation
instName = "???";
}
- string dbgComment = $"0x{(op.Address - headerSize):X6}: 0x{op.RawOpCode:X16} {instName}";
+ string dbgComment = $"0x{op.Address:X6}: 0x{op.RawOpCode:X16} {instName}";
context.Add(new CommentNode(dbgComment));
}
@@ -193,13 +204,13 @@ namespace Ryujinx.Graphics.Shader.Translation
bool skipPredicateCheck = op.Emitter == InstEmit.Bra;
- if (op is OpCodeSync opSync)
+ if (op is OpCodeBranchPop opBranchPop)
{
// If the instruction is a SYNC instruction with only one
// possible target address, then the instruction is basically
// just a simple branch, we can generate code similar to branch
// instructions, with the condition check on the branch itself.
- skipPredicateCheck |= opSync.Targets.Count < 2;
+ skipPredicateCheck |= opBranchPop.Targets.Count < 2;
}
if (!(op.Predicate.IsPT || skipPredicateCheck))
@@ -243,6 +254,8 @@ namespace Ryujinx.Graphics.Shader.Translation
}
}
+ size = (int)maxEndAddress + (compute ? 0 : HeaderSize);
+
return context.GetOperations();
}