2018-08-23 07:07:23 +02:00
|
|
|
|
using System;
|
|
|
|
|
|
|
|
|
|
namespace Ryujinx.Graphics.Gal.Shader
|
2018-07-19 07:33:27 +02:00
|
|
|
|
{
|
2018-08-23 07:07:23 +02:00
|
|
|
|
struct OmapTarget
|
|
|
|
|
{
|
|
|
|
|
public bool Red;
|
|
|
|
|
public bool Green;
|
|
|
|
|
public bool Blue;
|
|
|
|
|
public bool Alpha;
|
|
|
|
|
|
|
|
|
|
public bool Enabled => Red || Green || Blue || Alpha;
|
|
|
|
|
|
2019-03-04 02:45:25 +01:00
|
|
|
|
public bool ComponentEnabled(int component)
|
2018-08-23 07:07:23 +02:00
|
|
|
|
{
|
2019-03-04 02:45:25 +01:00
|
|
|
|
switch (component)
|
2018-08-23 07:07:23 +02:00
|
|
|
|
{
|
|
|
|
|
case 0: return Red;
|
|
|
|
|
case 1: return Green;
|
|
|
|
|
case 2: return Blue;
|
|
|
|
|
case 3: return Alpha;
|
|
|
|
|
}
|
|
|
|
|
|
2019-03-04 02:45:25 +01:00
|
|
|
|
throw new ArgumentException(nameof(component));
|
2018-08-23 07:07:23 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-07-19 07:33:27 +02:00
|
|
|
|
class ShaderHeader
|
|
|
|
|
{
|
|
|
|
|
public const int PointList = 1;
|
|
|
|
|
public const int LineStrip = 6;
|
|
|
|
|
public const int TriangleStrip = 7;
|
|
|
|
|
|
|
|
|
|
public int SphType { get; private set; }
|
|
|
|
|
public int Version { get; private set; }
|
|
|
|
|
public int ShaderType { get; private set; }
|
|
|
|
|
public bool MrtEnable { get; private set; }
|
|
|
|
|
public bool KillsPixels { get; private set; }
|
|
|
|
|
public bool DoesGlobalStore { get; private set; }
|
|
|
|
|
public int SassVersion { get; private set; }
|
|
|
|
|
public bool DoesLoadOrStore { get; private set; }
|
|
|
|
|
public bool DoesFp64 { get; private set; }
|
|
|
|
|
public int StreamOutMask { get; private set; }
|
|
|
|
|
|
|
|
|
|
public int ShaderLocalMemoryLowSize { get; private set; }
|
|
|
|
|
public int PerPatchAttributeCount { get; private set; }
|
|
|
|
|
|
|
|
|
|
public int ShaderLocalMemoryHighSize { get; private set; }
|
|
|
|
|
public int ThreadsPerInputPrimitive { get; private set; }
|
|
|
|
|
|
|
|
|
|
public int ShaderLocalMemoryCrsSize { get; private set; }
|
|
|
|
|
public int OutputTopology { get; private set; }
|
|
|
|
|
|
|
|
|
|
public int MaxOutputVertexCount { get; private set; }
|
|
|
|
|
public int StoreReqStart { get; private set; }
|
|
|
|
|
public int StoreReqEnd { get; private set; }
|
|
|
|
|
|
2018-08-23 07:07:23 +02:00
|
|
|
|
public OmapTarget[] OmapTargets { get; private set; }
|
|
|
|
|
public bool OmapSampleMask { get; private set; }
|
|
|
|
|
public bool OmapDepth { get; private set; }
|
|
|
|
|
|
2019-03-04 02:45:25 +01:00
|
|
|
|
public ShaderHeader(IGalMemory memory, long position)
|
2018-07-19 07:33:27 +02:00
|
|
|
|
{
|
2019-03-04 02:45:25 +01:00
|
|
|
|
uint commonWord0 = (uint)memory.ReadInt32(position + 0);
|
|
|
|
|
uint commonWord1 = (uint)memory.ReadInt32(position + 4);
|
|
|
|
|
uint commonWord2 = (uint)memory.ReadInt32(position + 8);
|
|
|
|
|
uint commonWord3 = (uint)memory.ReadInt32(position + 12);
|
|
|
|
|
uint commonWord4 = (uint)memory.ReadInt32(position + 16);
|
|
|
|
|
|
|
|
|
|
SphType = ReadBits(commonWord0, 0, 5);
|
|
|
|
|
Version = ReadBits(commonWord0, 5, 5);
|
|
|
|
|
ShaderType = ReadBits(commonWord0, 10, 4);
|
|
|
|
|
MrtEnable = ReadBits(commonWord0, 14, 1) != 0;
|
|
|
|
|
KillsPixels = ReadBits(commonWord0, 15, 1) != 0;
|
|
|
|
|
DoesGlobalStore = ReadBits(commonWord0, 16, 1) != 0;
|
|
|
|
|
SassVersion = ReadBits(commonWord0, 17, 4);
|
|
|
|
|
DoesLoadOrStore = ReadBits(commonWord0, 26, 1) != 0;
|
|
|
|
|
DoesFp64 = ReadBits(commonWord0, 27, 1) != 0;
|
|
|
|
|
StreamOutMask = ReadBits(commonWord0, 28, 4);
|
|
|
|
|
|
|
|
|
|
ShaderLocalMemoryLowSize = ReadBits(commonWord1, 0, 24);
|
|
|
|
|
PerPatchAttributeCount = ReadBits(commonWord1, 24, 8);
|
|
|
|
|
|
|
|
|
|
ShaderLocalMemoryHighSize = ReadBits(commonWord2, 0, 24);
|
|
|
|
|
ThreadsPerInputPrimitive = ReadBits(commonWord2, 24, 8);
|
|
|
|
|
|
|
|
|
|
ShaderLocalMemoryCrsSize = ReadBits(commonWord3, 0, 24);
|
|
|
|
|
OutputTopology = ReadBits(commonWord3, 24, 4);
|
|
|
|
|
|
|
|
|
|
MaxOutputVertexCount = ReadBits(commonWord4, 0, 12);
|
|
|
|
|
StoreReqStart = ReadBits(commonWord4, 12, 8);
|
|
|
|
|
StoreReqEnd = ReadBits(commonWord4, 24, 8);
|
2018-08-23 07:07:23 +02:00
|
|
|
|
|
|
|
|
|
//Type 2 (fragment?) reading
|
2019-03-04 02:45:25 +01:00
|
|
|
|
uint type2OmapTarget = (uint)memory.ReadInt32(position + 72);
|
|
|
|
|
uint type2Omap = (uint)memory.ReadInt32(position + 76);
|
2018-08-23 07:07:23 +02:00
|
|
|
|
|
|
|
|
|
OmapTargets = new OmapTarget[8];
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < OmapTargets.Length; i++)
|
|
|
|
|
{
|
2019-03-04 02:45:25 +01:00
|
|
|
|
int offset = i * 4;
|
2018-08-23 07:07:23 +02:00
|
|
|
|
|
|
|
|
|
OmapTargets[i] = new OmapTarget
|
|
|
|
|
{
|
2019-03-04 02:45:25 +01:00
|
|
|
|
Red = ReadBits(type2OmapTarget, offset + 0, 1) != 0,
|
|
|
|
|
Green = ReadBits(type2OmapTarget, offset + 1, 1) != 0,
|
|
|
|
|
Blue = ReadBits(type2OmapTarget, offset + 2, 1) != 0,
|
|
|
|
|
Alpha = ReadBits(type2OmapTarget, offset + 3, 1) != 0
|
2018-08-23 07:07:23 +02:00
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
2019-03-04 02:45:25 +01:00
|
|
|
|
OmapSampleMask = ReadBits(type2Omap, 0, 1) != 0;
|
|
|
|
|
OmapDepth = ReadBits(type2Omap, 1, 1) != 0;
|
2018-08-23 07:07:23 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public int DepthRegister
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
2019-03-04 02:45:25 +01:00
|
|
|
|
int count = 0;
|
2018-08-23 07:07:23 +02:00
|
|
|
|
|
2019-03-04 02:45:25 +01:00
|
|
|
|
for (int index = 0; index < OmapTargets.Length; index++)
|
2018-08-23 07:07:23 +02:00
|
|
|
|
{
|
2019-03-04 02:45:25 +01:00
|
|
|
|
for (int component = 0; component < 4; component++)
|
2018-08-23 07:07:23 +02:00
|
|
|
|
{
|
2019-03-04 02:45:25 +01:00
|
|
|
|
if (OmapTargets[index].ComponentEnabled(component))
|
2018-08-23 07:07:23 +02:00
|
|
|
|
{
|
2019-03-04 02:45:25 +01:00
|
|
|
|
count++;
|
2018-08-23 07:07:23 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Depth register is always two registers after the last color output
|
2019-03-04 02:45:25 +01:00
|
|
|
|
return count + 1;
|
2018-08-23 07:07:23 +02:00
|
|
|
|
}
|
2018-07-19 07:33:27 +02:00
|
|
|
|
}
|
|
|
|
|
|
2019-03-04 02:45:25 +01:00
|
|
|
|
private static int ReadBits(uint word, int offset, int bitWidth)
|
2018-07-19 07:33:27 +02:00
|
|
|
|
{
|
2019-03-04 02:45:25 +01:00
|
|
|
|
uint mask = (1u << bitWidth) - 1u;
|
2018-07-19 07:33:27 +02:00
|
|
|
|
|
2019-03-04 02:45:25 +01:00
|
|
|
|
return (int)((word >> offset) & mask);
|
2018-07-19 07:33:27 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|