Просмотр исходного кода

Add shader support for the round mode on the F2F instruction, support mipmaps on ASTC compressed textures

gdk 6 лет назад
Родитель
Сommit
3bcc395253

+ 4 - 6
Ryujinx.Graphics.Gpu/Image/Texture.cs

@@ -250,17 +250,15 @@ namespace Ryujinx.Graphics.Gpu.Image
 
             if (!_context.Capabilities.SupportsAstcCompression && _info.FormatInfo.Format.IsAstc())
             {
-                int blockWidth  = _info.FormatInfo.BlockWidth;
-                int blockHeight = _info.FormatInfo.BlockHeight;
-
                 data = AstcDecoder.DecodeToRgba8(
                     data,
-                    blockWidth,
-                    blockHeight,
+                    _info.FormatInfo.BlockWidth,
+                    _info.FormatInfo.BlockHeight,
                     1,
                     _info.Width,
                     _info.Height,
-                    _depth);
+                    _depth,
+                    _info.Levels);
             }
 
             HostTexture.SetData(data);

+ 1 - 0
Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGenHelper.cs

@@ -74,6 +74,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
             Add(Instruction.Negate,                   InstType.OpUnary,        "-",               0);
             Add(Instruction.ReciprocalSquareRoot,     InstType.CallUnary,      "inversesqrt");
             Add(Instruction.Return,                   InstType.OpNullary,      "return");
+            Add(Instruction.Round,                    InstType.CallUnary,      "roundEven");
             Add(Instruction.Sine,                     InstType.CallUnary,      "sin");
             Add(Instruction.SquareRoot,               InstType.CallUnary,      "sqrt");
             Add(Instruction.StoreLocal,               InstType.Special);

+ 4 - 0
Ryujinx.Graphics.Shader/Instructions/InstEmitConversion.cs

@@ -29,6 +29,10 @@ namespace Ryujinx.Graphics.Shader.Instructions
             {
                 switch (op.RoundingMode)
                 {
+                    case RoundingMode.ToNearest:
+                        srcB = context.FPRound(srcB);
+                        break;
+
                     case RoundingMode.TowardsNegativeInfinity:
                         srcB = context.FPFloor(srcB);
                         break;

+ 1 - 0
Ryujinx.Graphics.Shader/IntermediateRepresentation/Instruction.cs

@@ -71,6 +71,7 @@ namespace Ryujinx.Graphics.Shader.IntermediateRepresentation
         PackHalf2x16,
         ReciprocalSquareRoot,
         Return,
+        Round,
         ShiftLeft,
         ShiftRightS32,
         ShiftRightU32,

+ 1 - 0
Ryujinx.Graphics.Shader/StructuredIr/InstructionInfo.cs

@@ -83,6 +83,7 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
             Add(Instruction.Negate,                   VariableType.Scalar, VariableType.Scalar);
             Add(Instruction.PackHalf2x16,             VariableType.U32,    VariableType.F32,    VariableType.F32);
             Add(Instruction.ReciprocalSquareRoot,     VariableType.Scalar, VariableType.Scalar);
+            Add(Instruction.Round,                    VariableType.F32,    VariableType.F32);
             Add(Instruction.Sine,                     VariableType.Scalar, VariableType.Scalar);
             Add(Instruction.SquareRoot,               VariableType.Scalar, VariableType.Scalar);
             Add(Instruction.StoreGlobal,              VariableType.None,   VariableType.S32,    VariableType.S32,    VariableType.F32);

+ 10 - 5
Ryujinx.Graphics.Shader/Translation/EmitterContextInsts.cs

@@ -171,6 +171,11 @@ namespace Ryujinx.Graphics.Shader.Translation
             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)
         {
             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);
         }
 
-        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)
         {
             if (neg)
@@ -221,6 +221,11 @@ namespace Ryujinx.Graphics.Shader.Translation
             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)
         {
             if (sat)

+ 17 - 6
Ryujinx.Graphics.Texture/Astc/AstcDecoder.cs

@@ -54,7 +54,8 @@ namespace Ryujinx.Graphics.Texture.Astc
             int        blockDepth,
             int        width,
             int        height,
-            int        depth)
+            int        depth,
+            int        levels)
         {
             using (MemoryStream inputStream = new MemoryStream(data.ToArray()))
             {
@@ -75,23 +76,28 @@ namespace Ryujinx.Graphics.Texture.Astc
                 {
                     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];
 
                             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 baseOffsets = (j * width + i) * 4;
+
+                            int baseOffset = mipOffset + (j * width + i) * 4;
 
                             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)];
+
                                 Buffer.BlockCopy(decompressedData, 0, outputBuffer, 0, outputBuffer.Length);
 
                                 outputStream.Write(outputBuffer, jj * blockWidth * 4, decompressedWidth * 4);
@@ -99,6 +105,11 @@ namespace Ryujinx.Graphics.Texture.Astc
 
                             blockIndex++;
                         }
+
+                        mipOffset += width * height * 4;
+
+                        width  = Math.Max(1, width  >> 1);
+                        height = Math.Max(1, height >> 1);
                     }
 
                     return outputStream.ToArray();

+ 1 - 1
Ryujinx.ShaderTools/Program.cs

@@ -10,7 +10,7 @@ namespace Ryujinx.ShaderTools
         {
             if (args.Length == 1 || args.Length == 2)
             {
-                TranslationFlags flags = TranslationFlags.None;
+                TranslationFlags flags = TranslationFlags.DebugMode;
 
                 if (args.Length == 2 && args[0] == "--compute")
                 {