diff options
author | gdk <gab.dark.100@gmail.com> | 2019-11-14 14:20:30 -0300 |
---|---|---|
committer | Thog <thog@protonmail.com> | 2020-01-09 02:13:00 +0100 |
commit | f0a59f345c633b757ebd2a22fca23d7dab0f9f99 (patch) | |
tree | 444aa5ac024119594bc9f5b51e3710483537e6e6 /Ryujinx.Graphics.Shader/Translation/Translator.cs | |
parent | d274328c3192fd85b9eec661b00f1599d673776c (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.cs | 47 |
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(); } |