forked from Mirror/Ryujinx
Add shader support for the round mode on the F2F instruction, support mipmaps on ASTC compressed textures
This commit is contained in:
parent
d3fcab8511
commit
3bcc395253
8 changed files with 39 additions and 18 deletions
|
@ -250,17 +250,15 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||||
|
|
||||||
if (!_context.Capabilities.SupportsAstcCompression && _info.FormatInfo.Format.IsAstc())
|
if (!_context.Capabilities.SupportsAstcCompression && _info.FormatInfo.Format.IsAstc())
|
||||||
{
|
{
|
||||||
int blockWidth = _info.FormatInfo.BlockWidth;
|
|
||||||
int blockHeight = _info.FormatInfo.BlockHeight;
|
|
||||||
|
|
||||||
data = AstcDecoder.DecodeToRgba8(
|
data = AstcDecoder.DecodeToRgba8(
|
||||||
data,
|
data,
|
||||||
blockWidth,
|
_info.FormatInfo.BlockWidth,
|
||||||
blockHeight,
|
_info.FormatInfo.BlockHeight,
|
||||||
1,
|
1,
|
||||||
_info.Width,
|
_info.Width,
|
||||||
_info.Height,
|
_info.Height,
|
||||||
_depth);
|
_depth,
|
||||||
|
_info.Levels);
|
||||||
}
|
}
|
||||||
|
|
||||||
HostTexture.SetData(data);
|
HostTexture.SetData(data);
|
||||||
|
|
|
@ -74,6 +74,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
|
||||||
Add(Instruction.Negate, InstType.OpUnary, "-", 0);
|
Add(Instruction.Negate, InstType.OpUnary, "-", 0);
|
||||||
Add(Instruction.ReciprocalSquareRoot, InstType.CallUnary, "inversesqrt");
|
Add(Instruction.ReciprocalSquareRoot, InstType.CallUnary, "inversesqrt");
|
||||||
Add(Instruction.Return, InstType.OpNullary, "return");
|
Add(Instruction.Return, InstType.OpNullary, "return");
|
||||||
|
Add(Instruction.Round, InstType.CallUnary, "roundEven");
|
||||||
Add(Instruction.Sine, InstType.CallUnary, "sin");
|
Add(Instruction.Sine, InstType.CallUnary, "sin");
|
||||||
Add(Instruction.SquareRoot, InstType.CallUnary, "sqrt");
|
Add(Instruction.SquareRoot, InstType.CallUnary, "sqrt");
|
||||||
Add(Instruction.StoreLocal, InstType.Special);
|
Add(Instruction.StoreLocal, InstType.Special);
|
||||||
|
|
|
@ -29,6 +29,10 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
||||||
{
|
{
|
||||||
switch (op.RoundingMode)
|
switch (op.RoundingMode)
|
||||||
{
|
{
|
||||||
|
case RoundingMode.ToNearest:
|
||||||
|
srcB = context.FPRound(srcB);
|
||||||
|
break;
|
||||||
|
|
||||||
case RoundingMode.TowardsNegativeInfinity:
|
case RoundingMode.TowardsNegativeInfinity:
|
||||||
srcB = context.FPFloor(srcB);
|
srcB = context.FPFloor(srcB);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -71,6 +71,7 @@ namespace Ryujinx.Graphics.Shader.IntermediateRepresentation
|
||||||
PackHalf2x16,
|
PackHalf2x16,
|
||||||
ReciprocalSquareRoot,
|
ReciprocalSquareRoot,
|
||||||
Return,
|
Return,
|
||||||
|
Round,
|
||||||
ShiftLeft,
|
ShiftLeft,
|
||||||
ShiftRightS32,
|
ShiftRightS32,
|
||||||
ShiftRightU32,
|
ShiftRightU32,
|
||||||
|
|
|
@ -83,6 +83,7 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
|
||||||
Add(Instruction.Negate, VariableType.Scalar, VariableType.Scalar);
|
Add(Instruction.Negate, VariableType.Scalar, VariableType.Scalar);
|
||||||
Add(Instruction.PackHalf2x16, VariableType.U32, VariableType.F32, VariableType.F32);
|
Add(Instruction.PackHalf2x16, VariableType.U32, VariableType.F32, VariableType.F32);
|
||||||
Add(Instruction.ReciprocalSquareRoot, VariableType.Scalar, VariableType.Scalar);
|
Add(Instruction.ReciprocalSquareRoot, VariableType.Scalar, VariableType.Scalar);
|
||||||
|
Add(Instruction.Round, VariableType.F32, VariableType.F32);
|
||||||
Add(Instruction.Sine, VariableType.Scalar, VariableType.Scalar);
|
Add(Instruction.Sine, VariableType.Scalar, VariableType.Scalar);
|
||||||
Add(Instruction.SquareRoot, VariableType.Scalar, VariableType.Scalar);
|
Add(Instruction.SquareRoot, VariableType.Scalar, VariableType.Scalar);
|
||||||
Add(Instruction.StoreGlobal, VariableType.None, VariableType.S32, VariableType.S32, VariableType.F32);
|
Add(Instruction.StoreGlobal, VariableType.None, VariableType.S32, VariableType.S32, VariableType.F32);
|
||||||
|
|
|
@ -171,6 +171,11 @@ namespace Ryujinx.Graphics.Shader.Translation
|
||||||
return context.Add(Instruction.FP | Instruction.Floor, Local(), a);
|
return context.Add(Instruction.FP | Instruction.Floor, Local(), a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Operand FPFusedMultiplyAdd(this EmitterContext context, Operand a, Operand b, Operand c)
|
||||||
|
{
|
||||||
|
return context.Add(Instruction.FusedMultiplyAdd, Local(), a, b, c);
|
||||||
|
}
|
||||||
|
|
||||||
public static Operand FPLogarithmB2(this EmitterContext context, Operand a)
|
public static Operand FPLogarithmB2(this EmitterContext context, Operand a)
|
||||||
{
|
{
|
||||||
return context.Add(Instruction.FP | Instruction.LogarithmB2, Local(), a);
|
return context.Add(Instruction.FP | Instruction.LogarithmB2, Local(), a);
|
||||||
|
@ -191,11 +196,6 @@ namespace Ryujinx.Graphics.Shader.Translation
|
||||||
return context.Add(Instruction.FP | Instruction.Multiply, Local(), a, b);
|
return context.Add(Instruction.FP | Instruction.Multiply, Local(), a, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Operand FPFusedMultiplyAdd(this EmitterContext context, Operand a, Operand b, Operand c)
|
|
||||||
{
|
|
||||||
return context.Add(Instruction.FusedMultiplyAdd, Local(), a, b, c);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Operand FPNegate(this EmitterContext context, Operand a, bool neg)
|
public static Operand FPNegate(this EmitterContext context, Operand a, bool neg)
|
||||||
{
|
{
|
||||||
if (neg)
|
if (neg)
|
||||||
|
@ -221,6 +221,11 @@ namespace Ryujinx.Graphics.Shader.Translation
|
||||||
return context.Add(Instruction.FP | Instruction.ReciprocalSquareRoot, Local(), a);
|
return context.Add(Instruction.FP | Instruction.ReciprocalSquareRoot, Local(), a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Operand FPRound(this EmitterContext context, Operand a)
|
||||||
|
{
|
||||||
|
return context.Add(Instruction.FP | Instruction.Round, Local(), a);
|
||||||
|
}
|
||||||
|
|
||||||
public static Operand FPSaturate(this EmitterContext context, Operand a, bool sat)
|
public static Operand FPSaturate(this EmitterContext context, Operand a, bool sat)
|
||||||
{
|
{
|
||||||
if (sat)
|
if (sat)
|
||||||
|
|
|
@ -54,7 +54,8 @@ namespace Ryujinx.Graphics.Texture.Astc
|
||||||
int blockDepth,
|
int blockDepth,
|
||||||
int width,
|
int width,
|
||||||
int height,
|
int height,
|
||||||
int depth)
|
int depth,
|
||||||
|
int levels)
|
||||||
{
|
{
|
||||||
using (MemoryStream inputStream = new MemoryStream(data.ToArray()))
|
using (MemoryStream inputStream = new MemoryStream(data.ToArray()))
|
||||||
{
|
{
|
||||||
|
@ -75,23 +76,28 @@ namespace Ryujinx.Graphics.Texture.Astc
|
||||||
{
|
{
|
||||||
int blockIndex = 0;
|
int blockIndex = 0;
|
||||||
|
|
||||||
for (int j = 0; j < height; j += blockHeight)
|
int mipOffset = 0;
|
||||||
|
|
||||||
|
for (int l = 0; l < levels; l++)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < width; i += blockWidth)
|
for (int j = 0; j < height; j += blockHeight)
|
||||||
|
for (int i = 0; i < width; i += blockWidth)
|
||||||
{
|
{
|
||||||
int[] decompressedData = new int[144];
|
int[] decompressedData = new int[144];
|
||||||
|
|
||||||
DecompressBlock(binReader.ReadBytes(0x10), decompressedData, blockWidth, blockHeight);
|
DecompressBlock(binReader.ReadBytes(0x10), decompressedData, blockWidth, blockHeight);
|
||||||
|
|
||||||
int decompressedWidth = Math.Min(blockWidth, width - i);
|
int decompressedWidth = Math.Min(blockWidth, width - i);
|
||||||
int decompressedHeight = Math.Min(blockHeight, height - j);
|
int decompressedHeight = Math.Min(blockHeight, height - j);
|
||||||
int baseOffsets = (j * width + i) * 4;
|
|
||||||
|
int baseOffset = mipOffset + (j * width + i) * 4;
|
||||||
|
|
||||||
for (int jj = 0; jj < decompressedHeight; jj++)
|
for (int jj = 0; jj < decompressedHeight; jj++)
|
||||||
{
|
{
|
||||||
outputStream.Seek(baseOffsets + jj * width * 4, SeekOrigin.Begin);
|
outputStream.Seek(baseOffset + jj * width * 4, SeekOrigin.Begin);
|
||||||
|
|
||||||
byte[] outputBuffer = new byte[decompressedData.Length * sizeof(int)];
|
byte[] outputBuffer = new byte[decompressedData.Length * sizeof(int)];
|
||||||
|
|
||||||
Buffer.BlockCopy(decompressedData, 0, outputBuffer, 0, outputBuffer.Length);
|
Buffer.BlockCopy(decompressedData, 0, outputBuffer, 0, outputBuffer.Length);
|
||||||
|
|
||||||
outputStream.Write(outputBuffer, jj * blockWidth * 4, decompressedWidth * 4);
|
outputStream.Write(outputBuffer, jj * blockWidth * 4, decompressedWidth * 4);
|
||||||
|
@ -99,6 +105,11 @@ namespace Ryujinx.Graphics.Texture.Astc
|
||||||
|
|
||||||
blockIndex++;
|
blockIndex++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mipOffset += width * height * 4;
|
||||||
|
|
||||||
|
width = Math.Max(1, width >> 1);
|
||||||
|
height = Math.Max(1, height >> 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return outputStream.ToArray();
|
return outputStream.ToArray();
|
||||||
|
|
|
@ -10,7 +10,7 @@ namespace Ryujinx.ShaderTools
|
||||||
{
|
{
|
||||||
if (args.Length == 1 || args.Length == 2)
|
if (args.Length == 1 || args.Length == 2)
|
||||||
{
|
{
|
||||||
TranslationFlags flags = TranslationFlags.None;
|
TranslationFlags flags = TranslationFlags.DebugMode;
|
||||||
|
|
||||||
if (args.Length == 2 && args[0] == "--compute")
|
if (args.Length == 2 && args[0] == "--compute")
|
||||||
{
|
{
|
||||||
|
|
Reference in a new issue