aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics.Shader/Translation
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2019-12-06 19:37:00 -0300
committerThog <thog@protonmail.com>2020-01-09 02:13:00 +0100
commitcb171f6ebfa7e1aa5721503d1c1115719957932d (patch)
tree20de7fca78819fe436fbde629544aa547f446cc8 /Ryujinx.Graphics.Shader/Translation
parente25b7c9848b6ec486eb513297b5c536857665c7f (diff)
Support shared color mask, implement more shader instructions
Support shared color masks (used by Nouveau and maybe the NVIDIA driver). Support draw buffers (also required by OpenGL). Support viewport transform disable (disabled for now as it breaks some games). Fix instanced rendering draw being ignored for multi draw. Fix IADD and IADD3 immediate shader encodings, that was not matching some ops. Implement FFMA32I shader instruction. Implement IMAD shader instruction.
Diffstat (limited to 'Ryujinx.Graphics.Shader/Translation')
-rw-r--r--Ryujinx.Graphics.Shader/Translation/EmitterContext.cs32
-rw-r--r--Ryujinx.Graphics.Shader/Translation/EmitterContextInsts.cs10
-rw-r--r--Ryujinx.Graphics.Shader/Translation/TranslationFlags.cs3
-rw-r--r--Ryujinx.Graphics.Shader/Translation/Translator.cs34
4 files changed, 51 insertions, 28 deletions
diff --git a/Ryujinx.Graphics.Shader/Translation/EmitterContext.cs b/Ryujinx.Graphics.Shader/Translation/EmitterContext.cs
index 3995d430..7ba7b697 100644
--- a/Ryujinx.Graphics.Shader/Translation/EmitterContext.cs
+++ b/Ryujinx.Graphics.Shader/Translation/EmitterContext.cs
@@ -11,18 +11,25 @@ namespace Ryujinx.Graphics.Shader.Translation
public Block CurrBlock { get; set; }
public OpCode CurrOp { get; set; }
- private ShaderStage _stage;
-
- private ShaderHeader _header;
+ private ShaderStage _stage;
+ private ShaderHeader _header;
+ private ShaderCapabilities _capabilities;
+ private TranslationFlags _flags;
private List<Operation> _operations;
private Dictionary<ulong, Operand> _labels;
- public EmitterContext(ShaderStage stage, ShaderHeader header)
+ public EmitterContext(
+ ShaderStage stage,
+ ShaderHeader header,
+ ShaderCapabilities capabilities,
+ TranslationFlags flags)
{
- _stage = stage;
- _header = header;
+ _stage = stage;
+ _header = header;
+ _capabilities = capabilities;
+ _flags = flags;
_operations = new List<Operation>();
@@ -62,7 +69,18 @@ namespace Ryujinx.Graphics.Shader.Translation
public void PrepareForReturn()
{
- if (_stage == ShaderStage.Fragment)
+ if (_stage == ShaderStage.Vertex)
+ {
+ if ((_flags & TranslationFlags.DividePosXY) != 0)
+ {
+ Operand posX = Attribute(AttributeConsts.PositionX);
+ Operand posY = Attribute(AttributeConsts.PositionY);
+
+ this.Copy(posX, this.FPDivide(posX, ConstF(_capabilities.MaximumViewportDimensions / 2)));
+ this.Copy(posY, this.FPDivide(posY, ConstF(_capabilities.MaximumViewportDimensions / 2)));
+ }
+ }
+ else if (_stage == ShaderStage.Fragment)
{
if (_header.OmapDepth)
{
diff --git a/Ryujinx.Graphics.Shader/Translation/EmitterContextInsts.cs b/Ryujinx.Graphics.Shader/Translation/EmitterContextInsts.cs
index d884cfdb..e39d8c64 100644
--- a/Ryujinx.Graphics.Shader/Translation/EmitterContextInsts.cs
+++ b/Ryujinx.Graphics.Shader/Translation/EmitterContextInsts.cs
@@ -476,6 +476,16 @@ namespace Ryujinx.Graphics.Shader.Translation
return context.Add(Instruction.LoadShared, Local(), a);
}
+ public static Operand MultiplyHighS32(this EmitterContext context, Operand a, Operand b)
+ {
+ return context.Add(Instruction.MultiplyHighS32, Local(), a, b);
+ }
+
+ public static Operand MultiplyHighU32(this EmitterContext context, Operand a, Operand b)
+ {
+ return context.Add(Instruction.MultiplyHighU32, Local(), a, b);
+ }
+
public static Operand PackHalf2x16(this EmitterContext context, Operand a, Operand b)
{
return context.Add(Instruction.PackHalf2x16, Local(), a, b);
diff --git a/Ryujinx.Graphics.Shader/Translation/TranslationFlags.cs b/Ryujinx.Graphics.Shader/Translation/TranslationFlags.cs
index 99b6107a..8faa4383 100644
--- a/Ryujinx.Graphics.Shader/Translation/TranslationFlags.cs
+++ b/Ryujinx.Graphics.Shader/Translation/TranslationFlags.cs
@@ -6,6 +6,7 @@ namespace Ryujinx.Graphics.Shader.Translation
Compute = 1 << 0,
DebugMode = 1 << 1,
- Unspecialized = 1 << 2
+ Unspecialized = 1 << 2,
+ DividePosXY = 1 << 3
}
} \ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Translation/Translator.cs b/Ryujinx.Graphics.Shader/Translation/Translator.cs
index b129be93..69e63ae1 100644
--- a/Ryujinx.Graphics.Shader/Translation/Translator.cs
+++ b/Ryujinx.Graphics.Shader/Translation/Translator.cs
@@ -49,15 +49,9 @@ namespace Ryujinx.Graphics.Shader.Translation
public static ShaderProgram Translate(Span<byte> code, ShaderCapabilities capabilities, TranslationFlags flags)
{
- bool compute = (flags & TranslationFlags.Compute) != 0;
- bool debugMode = (flags & TranslationFlags.DebugMode) != 0;
+ bool compute = (flags & TranslationFlags.Compute) != 0;
- Operation[] ops = DecodeShader(
- code,
- compute,
- debugMode,
- out ShaderHeader header,
- out int size);
+ Operation[] ops = DecodeShader(code, capabilities, flags, out ShaderHeader header, out int size);
ShaderStage stage;
@@ -94,8 +88,8 @@ namespace Ryujinx.Graphics.Shader.Translation
{
bool debugMode = (flags & TranslationFlags.DebugMode) != 0;
- Operation[] vpAOps = DecodeShader(vpACode, compute: false, debugMode, out _, out _);
- Operation[] vpBOps = DecodeShader(vpBCode, compute: false, debugMode, out ShaderHeader header, out int sizeB);
+ Operation[] vpAOps = DecodeShader(vpACode, capabilities, flags, out _, out _);
+ Operation[] vpBOps = DecodeShader(vpBCode, capabilities, flags, out ShaderHeader header, out int sizeB);
ShaderConfig config = new ShaderConfig(
header.Stage,
@@ -142,23 +136,23 @@ namespace Ryujinx.Graphics.Shader.Translation
}
private static Operation[] DecodeShader(
- Span<byte> code,
- bool compute,
- bool debugMode,
- out ShaderHeader header,
- out int size)
+ Span<byte> code,
+ ShaderCapabilities capabilities,
+ TranslationFlags flags,
+ out ShaderHeader header,
+ out int size)
{
Block[] cfg;
EmitterContext context;
- if (compute)
+ if ((flags & TranslationFlags.Compute) != 0)
{
header = null;
cfg = Decoder.Decode(code, 0);
- context = new EmitterContext(ShaderStage.Compute, header);
+ context = new EmitterContext(ShaderStage.Compute, header, capabilities, flags);
}
else
{
@@ -166,7 +160,7 @@ namespace Ryujinx.Graphics.Shader.Translation
cfg = Decoder.Decode(code, HeaderSize);
- context = new EmitterContext(header.Stage, header);
+ context = new EmitterContext(header.Stage, header, capabilities, flags);
}
if (cfg == null)
@@ -197,7 +191,7 @@ namespace Ryujinx.Graphics.Shader.Translation
{
OpCode op = block.OpCodes[opIndex];
- if (debugMode)
+ if ((flags & TranslationFlags.DebugMode) != 0)
{
string instName;
@@ -274,7 +268,7 @@ namespace Ryujinx.Graphics.Shader.Translation
}
}
- size = (int)maxEndAddress + (compute ? 0 : HeaderSize);
+ size = (int)maxEndAddress + (((flags & TranslationFlags.Compute) != 0) ? 0 : HeaderSize);
return context.GetOperations();
}