Ryujinx/Ryujinx.Graphics/Graphics3d/Texture/TextureFactory.cs
Alex Barney 1f554c1093 Do naming refactoring on Ryujinx.Graphics (#611)
* Renaming part 1

* Renaming part 2

* Renaming part 3

* Renaming part 4

* Renaming part 5

* Renaming part 6

* Renaming part 7

* Renaming part 8

* Renaming part 9

* Renaming part 10

* General cleanup

* Thought I got all of these

* Apply #595

* Additional renaming

* Tweaks from feedback

* Rename files
2019-03-04 12:45:25 +11:00

166 lines
5.5 KiB
C#

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;
}
}
}