Better IPA shader instruction implementation (#1082)

* Fix varying interpolation on fragment shader

* Some nits

* Alignment
This commit is contained in:
gdkchan 2020-04-02 21:20:47 -03:00 committed by GitHub
parent 2365ddfc36
commit e93ca84b14
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 97 additions and 89 deletions

View file

@ -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++)
{

View file

@ -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;

View file

@ -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),