Implement depth compare
This commit is contained in:
parent
df99afeded
commit
47f6f5776f
9 changed files with 152 additions and 35 deletions
14
Ryujinx.Graphics/DepthCompareFunc.cs
Normal file
14
Ryujinx.Graphics/DepthCompareFunc.cs
Normal file
|
@ -0,0 +1,14 @@
|
|||
namespace Ryujinx.Graphics
|
||||
{
|
||||
public enum DepthCompareFunc
|
||||
{
|
||||
Never = 0,
|
||||
Less = 1,
|
||||
Equal = 2,
|
||||
LEqual = 3,
|
||||
Greater = 4,
|
||||
NotEqual = 5,
|
||||
GEqual = 6,
|
||||
Always = 7
|
||||
}
|
||||
}
|
|
@ -12,6 +12,9 @@ namespace Ryujinx.Graphics.Gal
|
|||
|
||||
public GalColorF BorderColor { get; private set; }
|
||||
|
||||
public bool DepthCompare { get; private set; }
|
||||
public DepthCompareFunc DepthCompareFunc { get; private set; }
|
||||
|
||||
public GalTextureSampler(
|
||||
GalTextureWrap AddressU,
|
||||
GalTextureWrap AddressV,
|
||||
|
@ -19,7 +22,9 @@ namespace Ryujinx.Graphics.Gal
|
|||
GalTextureFilter MinFilter,
|
||||
GalTextureFilter MagFilter,
|
||||
GalTextureMipFilter MipFilter,
|
||||
GalColorF BorderColor)
|
||||
GalColorF BorderColor,
|
||||
bool DepthCompare,
|
||||
DepthCompareFunc DepthCompareFunc)
|
||||
{
|
||||
this.AddressU = AddressU;
|
||||
this.AddressV = AddressV;
|
||||
|
@ -28,6 +33,9 @@ namespace Ryujinx.Graphics.Gal
|
|||
this.MagFilter = MagFilter;
|
||||
this.MipFilter = MipFilter;
|
||||
this.BorderColor = BorderColor;
|
||||
|
||||
this.DepthCompare = DepthCompare;
|
||||
this.DepthCompareFunc = DepthCompareFunc;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -189,6 +189,31 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
|||
throw new NotImplementedException($"{Format & GalImageFormat.FormatMask} {Format & GalImageFormat.TypeMask}");
|
||||
}
|
||||
|
||||
public static All GetDepthCompareFunc(DepthCompareFunc DepthCompareFunc)
|
||||
{
|
||||
switch (DepthCompareFunc)
|
||||
{
|
||||
case DepthCompareFunc.LEqual:
|
||||
return All.Lequal;
|
||||
case DepthCompareFunc.GEqual:
|
||||
return All.Gequal;
|
||||
case DepthCompareFunc.Less:
|
||||
return All.Less;
|
||||
case DepthCompareFunc.Greater:
|
||||
return All.Greater;
|
||||
case DepthCompareFunc.Equal:
|
||||
return All.Equal;
|
||||
case DepthCompareFunc.NotEqual:
|
||||
return All.Notequal;
|
||||
case DepthCompareFunc.Always:
|
||||
return All.Always;
|
||||
case DepthCompareFunc.Never:
|
||||
return All.Never;
|
||||
default:
|
||||
throw new ArgumentException(nameof(DepthCompareFunc) + " \"" + DepthCompareFunc + "\" is not valid!");
|
||||
}
|
||||
}
|
||||
|
||||
public static InternalFormat GetCompressedImageFormat(GalImageFormat Format)
|
||||
{
|
||||
switch (Format)
|
||||
|
|
|
@ -370,6 +370,17 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
|||
};
|
||||
|
||||
GL.TexParameter(Target, TextureParameterName.TextureBorderColor, Color);
|
||||
|
||||
if (Sampler.DepthCompare)
|
||||
{
|
||||
GL.TexParameter(Target, TextureParameterName.TextureCompareMode, (int)All.CompareRToTexture);
|
||||
GL.TexParameter(Target, TextureParameterName.TextureCompareFunc, (int)OGLEnumConverter.GetDepthCompareFunc(Sampler.DepthCompareFunc));
|
||||
}
|
||||
else
|
||||
{
|
||||
GL.TexParameter(Target, TextureParameterName.TextureCompareMode, (int)All.None);
|
||||
GL.TexParameter(Target, TextureParameterName.TextureCompareFunc, (int)All.Never);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -235,18 +235,24 @@ namespace Ryujinx.Graphics.Gal.Shader
|
|||
string Name = StagePrefix + TextureName + Index;
|
||||
|
||||
TextureType TextureType;
|
||||
|
||||
TextureInstructionSuffix TextureInstructionSuffix;
|
||||
|
||||
// TODO: non 2d texture type for TEXQ?
|
||||
if (Op.Inst == ShaderIrInst.Texq)
|
||||
{
|
||||
TextureType = TextureType.TwoD;
|
||||
TextureInstructionSuffix = TextureInstructionSuffix.None;
|
||||
}
|
||||
else
|
||||
{
|
||||
TextureType = ((ShaderIrMetaTex)Op.MetaData).TextureType;
|
||||
ShaderIrMetaTex Meta = ((ShaderIrMetaTex)Op.MetaData);
|
||||
|
||||
TextureType = Meta.TextureType;
|
||||
TextureInstructionSuffix = Meta.TextureInstructionSuffix;
|
||||
}
|
||||
|
||||
m_Textures.TryAdd(Handle, new ShaderDeclInfo(Name, Handle, false, 0, 1, TextureType));
|
||||
m_Textures.TryAdd(Handle, new ShaderDeclInfo(Name, Handle, false, 0, 1, TextureType, TextureInstructionSuffix));
|
||||
}
|
||||
else if (Op.Inst == ShaderIrInst.Texb)
|
||||
{
|
||||
|
@ -271,9 +277,10 @@ namespace Ryujinx.Graphics.Gal.Shader
|
|||
|
||||
if (HandleSrc != null && HandleSrc is ShaderIrOperCbuf Cbuf)
|
||||
{
|
||||
ShaderIrMetaTex Meta = ((ShaderIrMetaTex)Op.MetaData);
|
||||
string Name = StagePrefix + TextureName + "_cb" + Cbuf.Index + "_" + Cbuf.Pos;
|
||||
|
||||
m_CbTextures.Add(Op, new ShaderDeclInfo(Name, Cbuf.Pos, true, Cbuf.Index, 1, ((ShaderIrMetaTex)Op.MetaData).TextureType));
|
||||
m_CbTextures.Add(Op, new ShaderDeclInfo(Name, Cbuf.Pos, true, Cbuf.Index, 1, Meta.TextureType, Meta.TextureInstructionSuffix));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -221,35 +221,54 @@ namespace Ryujinx.Graphics.Gal.Shader
|
|||
}
|
||||
}
|
||||
|
||||
private string GetSamplerType(TextureTarget TextureTarget)
|
||||
private string GetSamplerType(TextureTarget TextureTarget, bool HasShadow)
|
||||
{
|
||||
string Result;
|
||||
|
||||
switch (TextureTarget)
|
||||
{
|
||||
case TextureTarget.Texture1D:
|
||||
return "sampler1D";
|
||||
Result = "sampler1D";
|
||||
break;
|
||||
case TextureTarget.Texture2D:
|
||||
return "sampler2D";
|
||||
Result = "sampler2D";
|
||||
break;
|
||||
case TextureTarget.Texture3D:
|
||||
return "sampler3D";
|
||||
Result = "sampler3D";
|
||||
break;
|
||||
case TextureTarget.TextureCubeMap:
|
||||
return "samplerCube";
|
||||
Result = "samplerCube";
|
||||
break;
|
||||
case TextureTarget.TextureRectangle:
|
||||
return "sampler2DRect";
|
||||
Result = "sampler2DRect";
|
||||
break;
|
||||
case TextureTarget.Texture1DArray:
|
||||
return "sampler1DArray";
|
||||
Result = "sampler1DArray";
|
||||
break;
|
||||
case TextureTarget.Texture2DArray:
|
||||
return "sampler2DArray";
|
||||
Result = "sampler2DArray";
|
||||
break;
|
||||
case TextureTarget.TextureCubeMapArray:
|
||||
return "samplerCubeArray";
|
||||
Result = "samplerCubeArray";
|
||||
break;
|
||||
case TextureTarget.TextureBuffer:
|
||||
return "samplerBuffer";
|
||||
Result = "samplerBuffer";
|
||||
break;
|
||||
case TextureTarget.Texture2DMultisample:
|
||||
return "sampler2DMS";
|
||||
Result = "sampler2DMS";
|
||||
break;
|
||||
case TextureTarget.Texture2DMultisampleArray:
|
||||
return "sampler2DMSArray";
|
||||
Result = "sampler2DMSArray";
|
||||
break;
|
||||
default:
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
if (HasShadow)
|
||||
Result += "Shadow";
|
||||
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
private void PrintDeclTextures()
|
||||
|
@ -257,15 +276,15 @@ namespace Ryujinx.Graphics.Gal.Shader
|
|||
foreach (ShaderDeclInfo DeclInfo in IterateCbTextures())
|
||||
{
|
||||
TextureTarget Target = ImageUtils.GetTextureTarget(DeclInfo.TextureType);
|
||||
|
||||
SB.AppendLine("uniform " + GetSamplerType(Target) + " " + DeclInfo.Name + ";");
|
||||
SB.AppendLine($"// {DeclInfo.TextureSuffix}");
|
||||
SB.AppendLine("uniform " + GetSamplerType(Target, (DeclInfo.TextureSuffix & TextureInstructionSuffix.DC) != 0) + " " + DeclInfo.Name + ";");
|
||||
}
|
||||
|
||||
foreach (ShaderDeclInfo DeclInfo in Decl.Textures.Values.OrderBy(DeclKeySelector))
|
||||
{
|
||||
TextureTarget Target = ImageUtils.GetTextureTarget(DeclInfo.TextureType);
|
||||
|
||||
SB.AppendLine("uniform " + GetSamplerType(Target) + " " + DeclInfo.Name + ";");
|
||||
SB.AppendLine($"// {DeclInfo.TextureSuffix}");
|
||||
SB.AppendLine("uniform " + GetSamplerType(Target, (DeclInfo.TextureSuffix & TextureInstructionSuffix.DC) != 0) + " " + DeclInfo.Name + ";");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1303,10 +1322,13 @@ namespace Ryujinx.Graphics.Gal.Shader
|
|||
{
|
||||
ShaderIrMetaTex Meta = (ShaderIrMetaTex)Op.MetaData;
|
||||
|
||||
bool HasDepth = (Meta.TextureInstructionSuffix & TextureInstructionSuffix.DC) != 0;
|
||||
|
||||
int Coords = ImageUtils.GetCoordsCountTextureType(Meta.TextureType);
|
||||
|
||||
bool IsArray = ImageUtils.IsArray(Meta.TextureType);
|
||||
|
||||
|
||||
string GetLastArgument(ShaderIrNode Node)
|
||||
{
|
||||
string Result = GetOperExpr(Op, Node);
|
||||
|
@ -1321,23 +1343,35 @@ namespace Ryujinx.Graphics.Gal.Shader
|
|||
}
|
||||
|
||||
string LastArgument;
|
||||
string DepthArgument = "";
|
||||
|
||||
int VecSize = Coords;
|
||||
if (HasDepth)
|
||||
{
|
||||
VecSize++;
|
||||
DepthArgument = $", {GetOperExpr(Op, Meta.DepthCompare)}";
|
||||
}
|
||||
|
||||
switch (Coords)
|
||||
{
|
||||
case 1:
|
||||
if (HasDepth)
|
||||
{
|
||||
return $"vec2({GetOperExpr(Op, Meta.Coordinates[0])}{DepthArgument})";
|
||||
}
|
||||
return GetOperExpr(Op, Meta.Coordinates[0]);
|
||||
case 2:
|
||||
LastArgument = GetLastArgument(Meta.Coordinates[1]);
|
||||
|
||||
return "vec2(" + GetOperExpr(Op, Meta.Coordinates[0]) + ", " + LastArgument + ")";
|
||||
return $"vec{VecSize}({GetOperExpr(Op, Meta.Coordinates[0])}, {LastArgument}{DepthArgument})";
|
||||
case 3:
|
||||
LastArgument = GetLastArgument(Meta.Coordinates[2]);
|
||||
|
||||
return "vec3(" + GetOperExpr(Op, Meta.Coordinates[0]) + ", " + GetOperExpr(Op, Meta.Coordinates[1]) + ", " + LastArgument + ")";
|
||||
return $"vec{VecSize}({GetOperExpr(Op, Meta.Coordinates[0])}, {GetOperExpr(Op, Meta.Coordinates[1])}, {LastArgument}{DepthArgument})";
|
||||
case 4:
|
||||
LastArgument = GetLastArgument(Meta.Coordinates[3]);
|
||||
|
||||
return "vec4(" + GetOperExpr(Op, Meta.Coordinates[0]) + ", " + GetOperExpr(Op, Meta.Coordinates[1]) + ", " + GetOperExpr(Op, Meta.Coordinates[2]) + ", " + LastArgument + ")";
|
||||
return $"vec4({GetOperExpr(Op, Meta.Coordinates[0])}, {GetOperExpr(Op, Meta.Coordinates[1])}, {GetOperExpr(Op, Meta.Coordinates[2])}, {LastArgument}){DepthArgument}";
|
||||
default:
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
|
@ -1378,6 +1412,13 @@ namespace Ryujinx.Graphics.Gal.Shader
|
|||
|
||||
TextureInstructionSuffix Suffix = Meta.TextureInstructionSuffix;
|
||||
|
||||
string ChString = "." + Ch;
|
||||
|
||||
if ((Suffix & TextureInstructionSuffix.DC) != 0)
|
||||
{
|
||||
ChString = "";
|
||||
}
|
||||
|
||||
// TODO: support LBA and LLA and DC
|
||||
if ((Suffix & TextureInstructionSuffix.LZ) != 0)
|
||||
{
|
||||
|
@ -1385,10 +1426,10 @@ namespace Ryujinx.Graphics.Gal.Shader
|
|||
{
|
||||
string Offset = GetTextureOffset(Meta, "floatBitsToInt((" + GetOperExpr(Op, Meta.Offset) + "))");
|
||||
|
||||
return "textureLodOffset(" + Sampler + ", " + Coords + ", 0.0, " + Offset + ")." + Ch;
|
||||
return "textureLodOffset(" + Sampler + ", " + Coords + ", 0.0, " + Offset + ")" + ChString;
|
||||
}
|
||||
|
||||
return "textureLod(" + Sampler + ", " + Coords + ", 0.0)." + Ch;
|
||||
return "textureLod(" + Sampler + ", " + Coords + ", 0.0)" + ChString;
|
||||
}
|
||||
else if ((Suffix & TextureInstructionSuffix.LB) != 0)
|
||||
{
|
||||
|
@ -1396,10 +1437,10 @@ namespace Ryujinx.Graphics.Gal.Shader
|
|||
{
|
||||
string Offset = GetTextureOffset(Meta, "floatBitsToInt((" + GetOperExpr(Op, Meta.Offset) + "))");
|
||||
|
||||
return "textureOffset(" + Sampler + ", " + Coords + ", " + Offset + ", " + GetOperExpr(Op, Meta.LevelOfDetail) + ")." + Ch;
|
||||
return "textureOffset(" + Sampler + ", " + Coords + ", " + Offset + ", " + GetOperExpr(Op, Meta.LevelOfDetail) + ")" + ChString;
|
||||
}
|
||||
|
||||
return "texture(" + Sampler + ", " + Coords + ", " + GetOperExpr(Op, Meta.LevelOfDetail) + ")." + Ch;
|
||||
return "texture(" + Sampler + ", " + Coords + ", " + GetOperExpr(Op, Meta.LevelOfDetail) + ")" + ChString;
|
||||
}
|
||||
else if ((Suffix & TextureInstructionSuffix.LL) != 0)
|
||||
{
|
||||
|
@ -1407,22 +1448,22 @@ namespace Ryujinx.Graphics.Gal.Shader
|
|||
{
|
||||
string Offset = GetTextureOffset(Meta, "floatBitsToInt((" + GetOperExpr(Op, Meta.Offset) + "))");
|
||||
|
||||
return "textureLodOffset(" + Sampler + ", " + Coords + ", " + GetOperExpr(Op, Meta.LevelOfDetail) + ", " + Offset + ")." + Ch;
|
||||
return "textureLodOffset(" + Sampler + ", " + Coords + ", " + GetOperExpr(Op, Meta.LevelOfDetail) + ", " + Offset + ")" + ChString;
|
||||
}
|
||||
|
||||
return "textureLod(" + Sampler + ", " + Coords + ", " + GetOperExpr(Op, Meta.LevelOfDetail) + ")." + Ch;
|
||||
return "textureLod(" + Sampler + ", " + Coords + ", " + GetOperExpr(Op, Meta.LevelOfDetail) + ")" + ChString;
|
||||
}
|
||||
else if (Suffix == TextureInstructionSuffix.AOFFI)
|
||||
{
|
||||
string Offset = GetTextureOffset(Meta, "floatBitsToInt((" + GetOperExpr(Op, Meta.Offset) + "))");
|
||||
|
||||
return "textureOffset(" + Sampler + ", " + Coords + ", " + Offset + ")." + Ch;
|
||||
return "textureOffset(" + Sampler + ", " + Coords + ", " + Offset + ")" + ChString;
|
||||
}
|
||||
else if (Suffix == TextureInstructionSuffix.None || Suffix == TextureInstructionSuffix.DC)
|
||||
else
|
||||
{
|
||||
// FIXME: implement DC
|
||||
// Load Standard
|
||||
return "texture(" + Sampler + ", " + Coords + ")." + Ch;
|
||||
return "texture(" + Sampler + ", " + Coords + ")" + ChString;
|
||||
}
|
||||
throw new NotImplementedException($"Texture Suffix {Meta.TextureInstructionSuffix} is not implemented");
|
||||
|
||||
|
|
|
@ -13,13 +13,16 @@ namespace Ryujinx.Graphics.Gal
|
|||
|
||||
public TextureType TextureType { get; private set; }
|
||||
|
||||
public TextureInstructionSuffix TextureSuffix { get; private set; }
|
||||
|
||||
public ShaderDeclInfo(
|
||||
string Name,
|
||||
int Index,
|
||||
bool IsCb = false,
|
||||
int Cbuf = 0,
|
||||
int Size = 1,
|
||||
TextureType TextureType = TextureType.TwoD)
|
||||
TextureType TextureType = TextureType.TwoD,
|
||||
TextureInstructionSuffix TextureSuffix = TextureInstructionSuffix.None)
|
||||
{
|
||||
this.Name = Name;
|
||||
this.Index = Index;
|
||||
|
@ -27,6 +30,8 @@ namespace Ryujinx.Graphics.Gal
|
|||
this.Cbuf = Cbuf;
|
||||
this.Size = Size;
|
||||
this.TextureType = TextureType;
|
||||
|
||||
this.TextureSuffix = TextureSuffix;
|
||||
}
|
||||
|
||||
internal void Enlarge(int NewSize)
|
||||
|
|
|
@ -94,6 +94,10 @@ namespace Ryujinx.Graphics.Texture
|
|||
GalTextureWrap AddressV = (GalTextureWrap)((Tsc[0] >> 3) & 7);
|
||||
GalTextureWrap AddressP = (GalTextureWrap)((Tsc[0] >> 6) & 7);
|
||||
|
||||
bool DepthCompare = ((Tsc[0] >> 9) & 1) == 1;
|
||||
|
||||
DepthCompareFunc DepthCompareFunc = (DepthCompareFunc)((Tsc[0] >> 10) & 7);
|
||||
|
||||
GalTextureFilter MagFilter = (GalTextureFilter) ((Tsc[1] >> 0) & 3);
|
||||
GalTextureFilter MinFilter = (GalTextureFilter) ((Tsc[1] >> 4) & 3);
|
||||
GalTextureMipFilter MipFilter = (GalTextureMipFilter)((Tsc[1] >> 6) & 3);
|
||||
|
@ -111,7 +115,9 @@ namespace Ryujinx.Graphics.Texture
|
|||
MinFilter,
|
||||
MagFilter,
|
||||
MipFilter,
|
||||
BorderColor);
|
||||
BorderColor,
|
||||
DepthCompare,
|
||||
DepthCompareFunc);
|
||||
}
|
||||
|
||||
private static GalImageFormat GetImageFormat(int[] Tic)
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
namespace Ryujinx.Graphics.Texture
|
||||
{
|
||||
[Flags]
|
||||
enum TextureInstructionSuffix
|
||||
public enum TextureInstructionSuffix
|
||||
{
|
||||
None = 0x00, // No Modifier
|
||||
LZ = 0x02, // Load LOD Zero
|
||||
|
|
Loading…
Add table
Reference in a new issue