aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics.Shader/Translation
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2020-04-02 21:20:47 -0300
committerGitHub <noreply@github.com>2020-04-03 11:20:47 +1100
commite93ca84b14cc325364f1ccc45a6e8622978e959d (patch)
tree8e32b23e94e529ccf91b8e7d7613ce003d16e841 /Ryujinx.Graphics.Shader/Translation
parent2365ddfc363e76ac1ac9d2e32ef9b36b85463431 (diff)
Better IPA shader instruction implementation (#1082)
* Fix varying interpolation on fragment shader * Some nits * Alignment
Diffstat (limited to 'Ryujinx.Graphics.Shader/Translation')
-rw-r--r--Ryujinx.Graphics.Shader/Translation/EmitterContext.cs2
-rw-r--r--Ryujinx.Graphics.Shader/Translation/ShaderConfig.cs10
-rw-r--r--Ryujinx.Graphics.Shader/Translation/ShaderHeader.cs64
3 files changed, 65 insertions, 11 deletions
diff --git a/Ryujinx.Graphics.Shader/Translation/EmitterContext.cs b/Ryujinx.Graphics.Shader/Translation/EmitterContext.cs
index 7111196b..8044f074 100644
--- a/Ryujinx.Graphics.Shader/Translation/EmitterContext.cs
+++ b/Ryujinx.Graphics.Shader/Translation/EmitterContext.cs
@@ -76,7 +76,7 @@ namespace Ryujinx.Graphics.Shader.Translation
for (int attachment = 0; attachment < 8; attachment++)
{
- OutputMapTarget target = _config.OmapTargets[attachment];
+ OmapTarget target = _config.OmapTargets[attachment];
for (int component = 0; component < 4; component++)
{
diff --git a/Ryujinx.Graphics.Shader/Translation/ShaderConfig.cs b/Ryujinx.Graphics.Shader/Translation/ShaderConfig.cs
index e3708b41..60660847 100644
--- a/Ryujinx.Graphics.Shader/Translation/ShaderConfig.cs
+++ b/Ryujinx.Graphics.Shader/Translation/ShaderConfig.cs
@@ -12,9 +12,11 @@ namespace Ryujinx.Graphics.Shader.Translation
public int LocalMemorySize { get; }
- public OutputMapTarget[] OmapTargets { get; }
- public bool OmapSampleMask { get; }
- public bool OmapDepth { get; }
+ public ImapPixelType[] ImapTypes { get; }
+
+ public OmapTarget[] OmapTargets { get; }
+ public bool OmapSampleMask { get; }
+ public bool OmapDepth { get; }
public TranslationFlags Flags { get; }
@@ -26,6 +28,7 @@ namespace Ryujinx.Graphics.Shader.Translation
OutputTopology = OutputTopology.PointList;
MaxOutputVertices = 0;
LocalMemorySize = 0;
+ ImapTypes = null;
OmapTargets = null;
OmapSampleMask = false;
OmapDepth = false;
@@ -39,6 +42,7 @@ namespace Ryujinx.Graphics.Shader.Translation
OutputTopology = header.OutputTopology;
MaxOutputVertices = header.MaxOutputVertexCount;
LocalMemorySize = header.ShaderLocalMemoryLowSize + header.ShaderLocalMemoryHighSize;
+ ImapTypes = header.ImapTypes;
OmapTargets = header.OmapTargets;
OmapSampleMask = header.OmapSampleMask;
OmapDepth = header.OmapDepth;
diff --git a/Ryujinx.Graphics.Shader/Translation/ShaderHeader.cs b/Ryujinx.Graphics.Shader/Translation/ShaderHeader.cs
index 42701fbd..a3b861c9 100644
--- a/Ryujinx.Graphics.Shader/Translation/ShaderHeader.cs
+++ b/Ryujinx.Graphics.Shader/Translation/ShaderHeader.cs
@@ -4,7 +4,39 @@ using System.Runtime.InteropServices;
namespace Ryujinx.Graphics.Shader.Translation
{
- struct OutputMapTarget
+ enum PixelImap
+ {
+ Unused = 0,
+ Constant = 1,
+ Perspective = 2,
+ ScreenLinear = 3
+ }
+
+ struct ImapPixelType
+ {
+ public PixelImap X { get; }
+ public PixelImap Y { get; }
+ public PixelImap Z { get; }
+ public PixelImap W { get; }
+
+ public ImapPixelType(PixelImap x, PixelImap y, PixelImap z, PixelImap w)
+ {
+ X = x;
+ Y = y;
+ Z = z;
+ W = w;
+ }
+
+ public PixelImap GetFirstUsedType()
+ {
+ if (X != PixelImap.Unused) return X;
+ if (Y != PixelImap.Unused) return Y;
+ if (Z != PixelImap.Unused) return Z;
+ return W;
+ }
+ }
+
+ struct OmapTarget
{
public bool Red { get; }
public bool Green { get; }
@@ -13,7 +45,7 @@ namespace Ryujinx.Graphics.Shader.Translation
public bool Enabled => Red || Green || Blue || Alpha;
- public OutputMapTarget(bool red, bool green, bool blue, bool alpha)
+ public OmapTarget(bool red, bool green, bool blue, bool alpha)
{
Red = red;
Green = green;
@@ -72,9 +104,11 @@ namespace Ryujinx.Graphics.Shader.Translation
public int StoreReqStart { get; }
public int StoreReqEnd { get; }
- public OutputMapTarget[] OmapTargets { get; }
- public bool OmapSampleMask { get; }
- public bool OmapDepth { get; }
+ public ImapPixelType[] ImapTypes { get; }
+
+ public OmapTarget[] OmapTargets { get; }
+ public bool OmapSampleMask { get; }
+ public bool OmapDepth { get; }
public ShaderHeader(ReadOnlySpan<byte> code)
{
@@ -127,14 +161,30 @@ namespace Ryujinx.Graphics.Shader.Translation
StoreReqStart = commonWord4.Extract(12, 8);
StoreReqEnd = commonWord4.Extract(24, 8);
+ ImapTypes = new ImapPixelType[32];
+
+ for (int i = 0; i < 8; i++)
+ {
+ for (int j = 0; j < 4; j++)
+ {
+ byte imap = (byte)(header[6 + i] >> (j * 8));
+
+ ImapTypes[i * 4 + j] = new ImapPixelType(
+ (PixelImap)((imap >> 0) & 3),
+ (PixelImap)((imap >> 2) & 3),
+ (PixelImap)((imap >> 4) & 3),
+ (PixelImap)((imap >> 6) & 3));
+ }
+ }
+
int type2OmapTarget = header[18];
int type2Omap = header[19];
- OmapTargets = new OutputMapTarget[8];
+ OmapTargets = new OmapTarget[8];
for (int offset = 0; offset < OmapTargets.Length * 4; offset += 4)
{
- OmapTargets[offset >> 2] = new OutputMapTarget(
+ OmapTargets[offset >> 2] = new OmapTarget(
type2OmapTarget.Extract(offset + 0),
type2OmapTarget.Extract(offset + 1),
type2OmapTarget.Extract(offset + 2),