Add the concept of layer count for array instead of using depth

Also cleanup GetGpuSize as Swizzle can compute the size with mipmap
This commit is contained in:
Thog 2019-02-17 15:23:40 +01:00
parent 3d38798f27
commit 5eda7ae7a8
No known key found for this signature in database
GPG key ID: 0CD291558FAFDBC6
10 changed files with 82 additions and 95 deletions

View file

@ -6,7 +6,10 @@ namespace Ryujinx.Graphics.Gal
{
public int Width;
public int Height;
// FIXME: separate layer and depth
public int Depth;
public int LayerCount;
public int TileWidth;
public int GobBlockHeight;
public int GobBlockDepth;
@ -25,6 +28,7 @@ namespace Ryujinx.Graphics.Gal
int Width,
int Height,
int Depth,
int LayerCount,
int TileWidth,
int GobBlockHeight,
int GobBlockDepth,
@ -39,6 +43,7 @@ namespace Ryujinx.Graphics.Gal
{
this.Width = Width;
this.Height = Height;
this.LayerCount = LayerCount;
this.Depth = Depth;
this.TileWidth = TileWidth;
this.GobBlockHeight = GobBlockHeight;

View file

@ -82,7 +82,6 @@ namespace Ryujinx.Graphics.Gal.OpenGL
Type,
IntPtr.Zero);
break;
case TextureTarget.Texture2DArray:
case TextureTarget.Texture3D:
GL.TexImage3D(
Target,
@ -96,6 +95,19 @@ namespace Ryujinx.Graphics.Gal.OpenGL
Type,
IntPtr.Zero);
break;
case TextureTarget.Texture2DArray:
GL.TexImage3D(
Target,
Level,
InternalFmt,
Image.Width,
Image.Height,
Image.LayerCount,
Border,
Format,
Type,
IntPtr.Zero);
break;
case TextureTarget.TextureCubeMap:
int FaceSize = ImageUtils.GetSize(Image) / Image.Depth;
@ -175,6 +187,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL
case TextureTarget.TextureCubeMap:
Span<byte> Array = new Span<byte>(Data);
// FIXME: wrong
int FaceSize = ImageUtils.GetSize(Image) / Image.Depth;
for (int Face = 0; Face < 6; Face++)
@ -197,7 +210,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL
InternalFmt,
Image.Width,
Image.Height,
Image.Depth * 6,
Image.LayerCount * 6,
Border,
Data.Length,
Data);
@ -257,7 +270,6 @@ namespace Ryujinx.Graphics.Gal.OpenGL
Type,
Data);
break;
case TextureTarget.Texture2DArray:
case TextureTarget.Texture3D:
GL.TexImage3D(
Target,
@ -271,9 +283,23 @@ namespace Ryujinx.Graphics.Gal.OpenGL
Type,
Data);
break;
case TextureTarget.Texture2DArray:
GL.TexImage3D(
Target,
Level,
InternalFmt,
Image.Width,
Image.Height,
Image.LayerCount,
Border,
Format,
Type,
Data);
break;
case TextureTarget.TextureCubeMap:
Span<byte> Array = new Span<byte>(Data);
// FIXME: wrong
int FaceSize = ImageUtils.GetSize(Image) / Image.Depth;
for (int Face = 0; Face < 6; Face++)

View file

@ -1,3 +1,4 @@
using Ryujinx.Common.Logging;
using Ryujinx.Graphics.Gal;
using Ryujinx.Graphics.Memory;
using Ryujinx.Graphics.Texture;
@ -118,7 +119,7 @@ namespace Ryujinx.Graphics.Graphics3d
GalImage SrcTexture = new GalImage(
SrcWidth,
SrcHeight,
SrcDepth, 1,
1, SrcDepth, 1,
SrcBlockHeight, 1,
SrcLayout,
SrcImgFormat,
@ -127,7 +128,7 @@ namespace Ryujinx.Graphics.Graphics3d
GalImage DstTexture = new GalImage(
DstWidth,
DstHeight,
DstDepth, 1,
1, DstDepth, 1,
DstBlockHeight, 1,
DstLayout,
DstImgFormat,
@ -138,8 +139,7 @@ namespace Ryujinx.Graphics.Graphics3d
long GetLayerOffset(GalImage Image, int Layer)
{
// TODO: mip map
return (ImageUtils.GetGpuSize(Image) / Image.Depth) * Layer;
return (ImageUtils.GetGpuSize(Image) / Image.LayerCount) * Layer;
}
int SrcLayerIndex = -1;
@ -161,7 +161,7 @@ namespace Ryujinx.Graphics.Graphics3d
if (IsSrcLayered && SrcLayerIndex == -1)
{
for (int Layer = 0; Layer < SrcTexture.Depth; Layer++)
for (int Layer = 0; Layer < SrcTexture.LayerCount; Layer++)
{
Gpu.ResourceManager.SetTextureArrayLayer(SrcKey + GetLayerOffset(SrcTexture, Layer), Layer);
}
@ -171,7 +171,7 @@ namespace Ryujinx.Graphics.Graphics3d
if (IsDstLayered && DstLayerIndex == -1)
{
for (int Layer = 0; Layer < DstTexture.Depth; Layer++)
for (int Layer = 0; Layer < DstTexture.LayerCount; Layer++)
{
Gpu.ResourceManager.SetTextureArrayLayer(DstKey + GetLayerOffset(DstTexture, Layer), Layer);
}

View file

@ -208,7 +208,7 @@ namespace Ryujinx.Graphics.Graphics3d
GalImageFormat Format = ImageUtils.ConvertSurface((GalSurfaceFormat)SurfFormat);
GalImage Image = new GalImage(Width, Height, 1, 1, GobBlockHeight, 1, Layout, Format, GalTextureTarget.TwoD);
GalImage Image = new GalImage(Width, Height, 1, 1, 1, GobBlockHeight, 1, Layout, Format, GalTextureTarget.TwoD);
Gpu.ResourceManager.SendColorBuffer(Vmm, Key, FbIndex, Image);
@ -263,7 +263,7 @@ namespace Ryujinx.Graphics.Graphics3d
GalImageFormat Format = ImageUtils.ConvertZeta((GalZetaFormat)ZetaFormat);
// TODO: Support non 2D?
GalImage Image = new GalImage(Width, Height, 1, 1, GobBlockHeight, 1, Layout, Format, GalTextureTarget.TwoD);
GalImage Image = new GalImage(Width, Height, 1, 1, 1, GobBlockHeight, 1, Layout, Format, GalTextureTarget.TwoD);
Gpu.ResourceManager.SendZetaBuffer(Vmm, Key, Image);
}
@ -609,7 +609,7 @@ namespace Ryujinx.Graphics.Graphics3d
{
//FIXME: Some games like puyo puyo will use handles with the value 0.
//This is a bug, most likely caused by sync issues.
return (0, default(GalImage), default(GalTextureSampler));
//return (0, default(GalImage), default(GalTextureSampler));
}
bool LinkedTsc = ReadRegisterBool(NvGpuEngine3dReg.LinkedTsc);

View file

@ -3,5 +3,11 @@ namespace Ryujinx.Graphics.Texture
interface ISwizzle
{
int GetSwizzleOffset(int X, int Y, int Z);
void SetMipLevel(int Level);
int GetMipOffset(int Level);
int GetImageSize(int MipsCount);
}
}

View file

@ -364,89 +364,9 @@ namespace Ryujinx.Graphics.Texture
}
}
// from envytools
private static readonly int GobSizeX = 64;
private static readonly int GobSizeY = 8;
private static readonly int GobSizeZ = 1;
// https://github.com/mesa3d/mesa/blob/master/src/gallium/drivers/nouveau/nvc0/nvc0_miptree.c
// FIXME: the width is never set to anything, maybe there is other variants?
// TODO: miplevels
private static (int TileWidth, int TileHeight, int TileDepth) GetTileDimensions(GalImage Image)
{
(int Width, int Height, int Depth) = GetImageSizeInBlocks(Image);
int TileWidth = 0;
int TileHeight = 0;
int TileDepth = 0;
if (Height > 64)
{
TileHeight = 4;
}
else if (Height > 32)
{
TileHeight = 3;
}
else if (Height > 16)
{
TileHeight = 2;
}
else if (Height > 8)
{
TileHeight = 1;
}
if (Image.TextureTarget == GalTextureTarget.ThreeD)
{
if (TileHeight > 2)
{
TileHeight = 2;
}
if (Depth > 16 && TileDepth < 2)
{
TileDepth = 5;
}
else if (Depth > 8)
{
TileDepth = 4;
}
else if (Depth > 4)
{
TileDepth = 3;
}
else if (Depth > 2)
{
TileDepth = 2;
}
else if (Depth > 1)
{
TileDepth = 1;
}
}
return (GobSizeX << TileWidth, GobSizeY << TileHeight, GobSizeZ << TileDepth);
}
public static int GetGpuSize(GalImage Image, bool forcePitch = false)
{
ImageDescriptor Desc = GetImageDescriptor(Image.Format);
if (Image.Layout == GalMemoryLayout.Pitch || forcePitch)
{
// TODO: check this
return Image.Width * Image.Height * Image.Depth * Desc.BytesPerPixel;
}
(int TileWidth, int TileHeight, int TileDepth) = GetTileDimensions(Image);
(int BlockX, int BlockY, int _) = GetImageSizeInBlocks(Image);
int Pitch = BitUtils.AlignUp(BlockX * Desc.BytesPerPixel, TileWidth);
int Height = BitUtils.AlignUp(BlockY, TileHeight);
int Depth = BitUtils.AlignUp(Image.Depth, TileDepth);
return BitUtils.AlignUp(Pitch * Height * Depth, (GobSizeX * GobSizeY) << (TileWidth + TileHeight + TileDepth));
return TextureHelper.GetSwizzle(Image).GetImageSize(Image.MaxMipmapLevel) * Image.LayerCount;
}
public static int GetPitch(GalImageFormat Format, int Width)

View file

@ -1,3 +1,5 @@
using System;
namespace Ryujinx.Graphics.Texture
{
class LinearSwizzle : ISwizzle
@ -14,6 +16,23 @@ namespace Ryujinx.Graphics.Texture
SliceSize = Width * Height * Bpp;
}
public void SetMipLevel(int Level)
{
throw new NotImplementedException();
}
public int GetMipOffset(int Level)
{
throw new NotImplementedException();
}
public int GetImageSize(int MipsCount)
{
if (MipsCount == 1)
return SliceSize;
throw new NotImplementedException();
}
public int GetSwizzleOffset(int X, int Y, int Z)
{
return Z * SliceSize + X * Bpp + Y * Pitch;

View file

@ -47,6 +47,15 @@ namespace Ryujinx.Graphics.Texture
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;
@ -58,6 +67,7 @@ namespace Ryujinx.Graphics.Texture
}
else if (TextureTarget == GalTextureTarget.CubeMap)
{
// TODO: WRONG
Depth = 6;
}
@ -65,6 +75,7 @@ namespace Ryujinx.Graphics.Texture
Width,
Height,
Depth,
LayoutCount,
TileWidth,
GobBlockHeight,
GobBlockDepth,

View file

@ -216,7 +216,7 @@ namespace Ryujinx.Graphics.VDec
GalImage Image = new GalImage(
OutputConfig.SurfaceWidth,
OutputConfig.SurfaceHeight, 1, 1,
OutputConfig.SurfaceHeight, 1, 1, 1,
OutputConfig.GobBlockHeight, 1,
GalMemoryLayout.BlockLinear,
GalImageFormat.RGBA8 | GalImageFormat.Unorm,

View file

@ -416,7 +416,7 @@ namespace Ryujinx.HLE.HOS.Services.Android
{
image = new GalImage(
fbWidth,
fbHeight, 1, 1, BlockHeight, 1,
fbHeight, 1, 1, 1, BlockHeight, 1,
GalMemoryLayout.BlockLinear,
imageFormat,
GalTextureTarget.TwoD);