From 6b13c5b439a54d0bb0139a2e33a2f76707db5fe7 Mon Sep 17 00:00:00 2001 From: gdkchan Date: Sat, 7 Dec 2019 18:31:17 -0300 Subject: [PATCH] Support bindless texture gather shader instruction --- .../Decoders/IOpCodeTexture.cs | 23 +++++++++++++++++++ .../Decoders/IOpCodeTld4.cs | 11 +++++++++ .../Decoders/OpCodeTable.cs | 1 + .../Decoders/OpCodeTexture.cs | 2 +- .../Decoders/OpCodeTld4.cs | 4 +++- .../Decoders/OpCodeTld4B.cs | 22 ++++++++++++++++++ .../Instructions/InstEmitTexture.cs | 9 +++++++- 7 files changed, 69 insertions(+), 3 deletions(-) create mode 100644 Ryujinx.Graphics.Shader/Decoders/IOpCodeTexture.cs create mode 100644 Ryujinx.Graphics.Shader/Decoders/IOpCodeTld4.cs create mode 100644 Ryujinx.Graphics.Shader/Decoders/OpCodeTld4B.cs diff --git a/Ryujinx.Graphics.Shader/Decoders/IOpCodeTexture.cs b/Ryujinx.Graphics.Shader/Decoders/IOpCodeTexture.cs new file mode 100644 index 000000000..55d1225ae --- /dev/null +++ b/Ryujinx.Graphics.Shader/Decoders/IOpCodeTexture.cs @@ -0,0 +1,23 @@ +namespace Ryujinx.Graphics.Shader.Decoders +{ + interface IOpCodeTexture : IOpCode + { + Register Rd { get; } + Register Ra { get; } + Register Rb { get; } + + bool IsArray { get; } + + TextureDimensions Dimensions { get; } + + int ComponentMask { get; } + + int Immediate { get; } + + TextureLodMode LodMode { get; } + + bool HasOffset { get; } + bool HasDepthCompare { get; } + bool IsMultisample { get; } + } +} \ No newline at end of file diff --git a/Ryujinx.Graphics.Shader/Decoders/IOpCodeTld4.cs b/Ryujinx.Graphics.Shader/Decoders/IOpCodeTld4.cs new file mode 100644 index 000000000..219d00cbf --- /dev/null +++ b/Ryujinx.Graphics.Shader/Decoders/IOpCodeTld4.cs @@ -0,0 +1,11 @@ +namespace Ryujinx.Graphics.Shader.Decoders +{ + interface IOpCodeTld4 : IOpCodeTexture + { + TextureGatherOffset Offset { get; } + + int GatherCompIndex { get; } + + bool Bindless { get; } + } +} \ No newline at end of file diff --git a/Ryujinx.Graphics.Shader/Decoders/OpCodeTable.cs b/Ryujinx.Graphics.Shader/Decoders/OpCodeTable.cs index 0837e1858..bdc7ed80c 100644 --- a/Ryujinx.Graphics.Shader/Decoders/OpCodeTable.cs +++ b/Ryujinx.Graphics.Shader/Decoders/OpCodeTable.cs @@ -184,6 +184,7 @@ namespace Ryujinx.Graphics.Shader.Decoders Set("11011100xx111x", InstEmit.Tld, typeof(OpCodeTld)); Set("11011101xx111x", InstEmit.TldB, typeof(OpCodeTld)); Set("110010xxxx111x", InstEmit.Tld4, typeof(OpCodeTld4)); + Set("1101111011111x", InstEmit.Tld4, typeof(OpCodeTld4B)); Set("110111100x1110", InstEmit.Txd, typeof(OpCodeTxd)); Set("1101111101001x", InstEmit.Txq, typeof(OpCodeTex)); Set("1101111101010x", InstEmit.TxqB, typeof(OpCodeTex)); diff --git a/Ryujinx.Graphics.Shader/Decoders/OpCodeTexture.cs b/Ryujinx.Graphics.Shader/Decoders/OpCodeTexture.cs index 7a7e8f46e..76e95118f 100644 --- a/Ryujinx.Graphics.Shader/Decoders/OpCodeTexture.cs +++ b/Ryujinx.Graphics.Shader/Decoders/OpCodeTexture.cs @@ -2,7 +2,7 @@ using Ryujinx.Graphics.Shader.Instructions; namespace Ryujinx.Graphics.Shader.Decoders { - class OpCodeTexture : OpCode + class OpCodeTexture : OpCode, IOpCodeTexture { public Register Rd { get; } public Register Ra { get; } diff --git a/Ryujinx.Graphics.Shader/Decoders/OpCodeTld4.cs b/Ryujinx.Graphics.Shader/Decoders/OpCodeTld4.cs index 485edf936..0ffafbe1a 100644 --- a/Ryujinx.Graphics.Shader/Decoders/OpCodeTld4.cs +++ b/Ryujinx.Graphics.Shader/Decoders/OpCodeTld4.cs @@ -2,12 +2,14 @@ using Ryujinx.Graphics.Shader.Instructions; namespace Ryujinx.Graphics.Shader.Decoders { - class OpCodeTld4 : OpCodeTexture + class OpCodeTld4 : OpCodeTexture, IOpCodeTld4 { public TextureGatherOffset Offset { get; } public int GatherCompIndex { get; } + public bool Bindless => false; + public OpCodeTld4(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) { HasDepthCompare = opCode.Extract(50); diff --git a/Ryujinx.Graphics.Shader/Decoders/OpCodeTld4B.cs b/Ryujinx.Graphics.Shader/Decoders/OpCodeTld4B.cs new file mode 100644 index 000000000..dc274d141 --- /dev/null +++ b/Ryujinx.Graphics.Shader/Decoders/OpCodeTld4B.cs @@ -0,0 +1,22 @@ +using Ryujinx.Graphics.Shader.Instructions; + +namespace Ryujinx.Graphics.Shader.Decoders +{ + class OpCodeTld4B : OpCodeTexture, IOpCodeTld4 + { + public TextureGatherOffset Offset { get; } + + public int GatherCompIndex { get; } + + public bool Bindless => true; + + public OpCodeTld4B(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) + { + HasDepthCompare = opCode.Extract(50); + + Offset = (TextureGatherOffset)opCode.Extract(36, 2); + + GatherCompIndex = opCode.Extract(38, 2); + } + } +} \ No newline at end of file diff --git a/Ryujinx.Graphics.Shader/Instructions/InstEmitTexture.cs b/Ryujinx.Graphics.Shader/Instructions/InstEmitTexture.cs index 41ba740e7..59096869e 100644 --- a/Ryujinx.Graphics.Shader/Instructions/InstEmitTexture.cs +++ b/Ryujinx.Graphics.Shader/Instructions/InstEmitTexture.cs @@ -417,7 +417,7 @@ namespace Ryujinx.Graphics.Shader.Instructions public static void Tld4(EmitterContext context) { - OpCodeTld4 op = (OpCodeTld4)context.CurrOp; + IOpCodeTld4 op = (IOpCodeTld4)context.CurrOp; if (op.Rd.IsRZ) { @@ -455,6 +455,13 @@ namespace Ryujinx.Graphics.Shader.Instructions TextureFlags flags = TextureFlags.Gather; + if (op.Bindless) + { + sourcesList.Add(Rb()); + + flags |= TextureFlags.Bindless; + } + int coordsCount = type.GetDimensions(); for (int index = 0; index < coordsCount; index++)