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:
parent
3d38798f27
commit
5eda7ae7a8
10 changed files with 82 additions and 95 deletions
|
@ -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;
|
||||
|
|
|
@ -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++)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Reference in a new issue