aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics/Graphics3d/Texture/TextureFactory.cs
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2018-12-03 00:38:47 -0200
committerGitHub <noreply@github.com>2018-12-03 00:38:47 -0200
commitc86aacde76b5f8e503e2b412385c8491ecc86b3b (patch)
tree8e4737422fba15199c1a6ce7c6345996c0e907b5 /Ryujinx.Graphics/Graphics3d/Texture/TextureFactory.cs
parentad00fd02442cf9c0f00c4562635738042b521efa (diff)
NVDEC implementation using FFmpeg (#443)
* Initial nvdec implementation using FFmpeg * Fix swapped channels on the video decoder and the G8R8 texture format * Fix texture samplers not being set properly (regression) * Rebased * Remove unused code introduced on the rebase * Add support for RGBA8 output format on the video image composer * Correct spacing * Some fixes for rebase and other tweaks * Allow size mismatch on frame copy * Get rid of GetHostAddress calls on VDec
Diffstat (limited to 'Ryujinx.Graphics/Graphics3d/Texture/TextureFactory.cs')
-rw-r--r--Ryujinx.Graphics/Graphics3d/Texture/TextureFactory.cs117
1 files changed, 117 insertions, 0 deletions
diff --git a/Ryujinx.Graphics/Graphics3d/Texture/TextureFactory.cs b/Ryujinx.Graphics/Graphics3d/Texture/TextureFactory.cs
new file mode 100644
index 00000000..1f2d625e
--- /dev/null
+++ b/Ryujinx.Graphics/Graphics3d/Texture/TextureFactory.cs
@@ -0,0 +1,117 @@
+using Ryujinx.Graphics.Gal;
+using Ryujinx.Graphics.Memory;
+using System;
+
+namespace Ryujinx.Graphics.Texture
+{
+ static class TextureFactory
+ {
+ public static GalImage MakeTexture(NvGpuVmm Vmm, long TicPosition)
+ {
+ int[] Tic = ReadWords(Vmm, TicPosition, 8);
+
+ GalImageFormat Format = GetImageFormat(Tic);
+
+ GalTextureSource XSource = (GalTextureSource)((Tic[0] >> 19) & 7);
+ GalTextureSource YSource = (GalTextureSource)((Tic[0] >> 22) & 7);
+ GalTextureSource ZSource = (GalTextureSource)((Tic[0] >> 25) & 7);
+ GalTextureSource WSource = (GalTextureSource)((Tic[0] >> 28) & 7);
+
+ TextureSwizzle Swizzle = (TextureSwizzle)((Tic[2] >> 21) & 7);
+
+ GalMemoryLayout Layout;
+
+ if (Swizzle == TextureSwizzle.BlockLinear ||
+ Swizzle == TextureSwizzle.BlockLinearColorKey)
+ {
+ Layout = GalMemoryLayout.BlockLinear;
+ }
+ else
+ {
+ Layout = GalMemoryLayout.Pitch;
+ }
+
+ int BlockHeightLog2 = (Tic[3] >> 3) & 7;
+ int TileWidthLog2 = (Tic[3] >> 10) & 7;
+
+ int BlockHeight = 1 << BlockHeightLog2;
+ int TileWidth = 1 << TileWidthLog2;
+
+ int Width = (Tic[4] & 0xffff) + 1;
+ int Height = (Tic[5] & 0xffff) + 1;
+
+ GalImage Image = new GalImage(
+ Width,
+ Height,
+ TileWidth,
+ BlockHeight,
+ Layout,
+ Format,
+ XSource,
+ YSource,
+ ZSource,
+ WSource);
+
+ if (Layout == GalMemoryLayout.Pitch)
+ {
+ Image.Pitch = (Tic[3] & 0xffff) << 5;
+ }
+
+ return Image;
+ }
+
+ public static GalTextureSampler MakeSampler(NvGpu Gpu, NvGpuVmm Vmm, long TscPosition)
+ {
+ int[] Tsc = ReadWords(Vmm, TscPosition, 8);
+
+ GalTextureWrap AddressU = (GalTextureWrap)((Tsc[0] >> 0) & 7);
+ GalTextureWrap AddressV = (GalTextureWrap)((Tsc[0] >> 3) & 7);
+ GalTextureWrap AddressP = (GalTextureWrap)((Tsc[0] >> 6) & 7);
+
+ GalTextureFilter MagFilter = (GalTextureFilter) ((Tsc[1] >> 0) & 3);
+ GalTextureFilter MinFilter = (GalTextureFilter) ((Tsc[1] >> 4) & 3);
+ GalTextureMipFilter MipFilter = (GalTextureMipFilter)((Tsc[1] >> 6) & 3);
+
+ GalColorF BorderColor = new GalColorF(
+ BitConverter.Int32BitsToSingle(Tsc[4]),
+ BitConverter.Int32BitsToSingle(Tsc[5]),
+ BitConverter.Int32BitsToSingle(Tsc[6]),
+ BitConverter.Int32BitsToSingle(Tsc[7]));
+
+ return new GalTextureSampler(
+ AddressU,
+ AddressV,
+ AddressP,
+ MinFilter,
+ MagFilter,
+ MipFilter,
+ BorderColor);
+ }
+
+ private static GalImageFormat GetImageFormat(int[] Tic)
+ {
+ GalTextureType RType = (GalTextureType)((Tic[0] >> 7) & 7);
+ GalTextureType GType = (GalTextureType)((Tic[0] >> 10) & 7);
+ GalTextureType BType = (GalTextureType)((Tic[0] >> 13) & 7);
+ GalTextureType AType = (GalTextureType)((Tic[0] >> 16) & 7);
+
+ GalTextureFormat Format = (GalTextureFormat)(Tic[0] & 0x7f);
+
+ bool ConvSrgb = ((Tic[4] >> 22) & 1) != 0;
+
+ return ImageUtils.ConvertTexture(Format, RType, GType, BType, AType, ConvSrgb);
+ }
+
+ private static int[] ReadWords(NvGpuVmm Vmm, long Position, int Count)
+ {
+ int[] Words = new int[Count];
+
+ for (int Index = 0; Index < Count; Index++, Position += 4)
+ {
+ Words[Index] = Vmm.ReadInt32(Position);
+ }
+
+ return Words;
+ }
+ }
+} \ No newline at end of file