| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166 |
- 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);
- GalTextureTarget TextureTarget = (GalTextureTarget)((Tic[4] >> 23) & 0xF);
- 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);
- int MaxMipmapLevel = (Tic[3] >> 28) & 0xF + 1;
- GalMemoryLayout Layout;
- if (Swizzle == TextureSwizzle.BlockLinear ||
- Swizzle == TextureSwizzle.BlockLinearColorKey)
- {
- Layout = GalMemoryLayout.BlockLinear;
- }
- else
- {
- Layout = GalMemoryLayout.Pitch;
- }
- int GobBlockHeightLog2 = (Tic[3] >> 3) & 7;
- int GobBlockDepthLog2 = (Tic[3] >> 6) & 7;
- int TileWidthLog2 = (Tic[3] >> 10) & 7;
- int GobBlockHeight = 1 << GobBlockHeightLog2;
- int GobBlockDepth = 1 << GobBlockDepthLog2;
- int TileWidth = 1 << TileWidthLog2;
- int Width = ((Tic[4] >> 0) & 0xffff) + 1;
- int Height = ((Tic[5] >> 0) & 0xffff) + 1;
- int Depth = ((Tic[5] >> 16) & 0x3fff) + 1;
- int LayoutCount = 1;
- // TODO: check this
- if (ImageUtils.IsArray(TextureTarget))
- {
- LayoutCount = Depth;
- Depth = 1;
- }
- if (TextureTarget == GalTextureTarget.OneD)
- {
- Height = 1;
- }
- if (TextureTarget == GalTextureTarget.TwoD || TextureTarget == GalTextureTarget.OneD)
- {
- Depth = 1;
- }
- else if (TextureTarget == GalTextureTarget.CubeMap)
- {
- // FIXME: This is a bit hacky but I guess it's fine for now
- LayoutCount = 6;
- Depth = 1;
- }
- else if (TextureTarget == GalTextureTarget.CubeArray)
- {
- // FIXME: This is a really really hacky but I guess it's fine for now
- LayoutCount *= 6;
- Depth = 1;
- }
- GalImage Image = new GalImage(
- Width,
- Height,
- Depth,
- LayoutCount,
- TileWidth,
- GobBlockHeight,
- GobBlockDepth,
- Layout,
- Format,
- TextureTarget,
- MaxMipmapLevel,
- 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);
- 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);
- 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,
- DepthCompare,
- DepthCompareFunc);
- }
- 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;
- }
- }
- }
|