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 Width;
|
||||||
public int Height;
|
public int Height;
|
||||||
|
|
||||||
|
// FIXME: separate layer and depth
|
||||||
public int Depth;
|
public int Depth;
|
||||||
|
public int LayerCount;
|
||||||
public int TileWidth;
|
public int TileWidth;
|
||||||
public int GobBlockHeight;
|
public int GobBlockHeight;
|
||||||
public int GobBlockDepth;
|
public int GobBlockDepth;
|
||||||
|
@ -25,6 +28,7 @@ namespace Ryujinx.Graphics.Gal
|
||||||
int Width,
|
int Width,
|
||||||
int Height,
|
int Height,
|
||||||
int Depth,
|
int Depth,
|
||||||
|
int LayerCount,
|
||||||
int TileWidth,
|
int TileWidth,
|
||||||
int GobBlockHeight,
|
int GobBlockHeight,
|
||||||
int GobBlockDepth,
|
int GobBlockDepth,
|
||||||
|
@ -39,6 +43,7 @@ namespace Ryujinx.Graphics.Gal
|
||||||
{
|
{
|
||||||
this.Width = Width;
|
this.Width = Width;
|
||||||
this.Height = Height;
|
this.Height = Height;
|
||||||
|
this.LayerCount = LayerCount;
|
||||||
this.Depth = Depth;
|
this.Depth = Depth;
|
||||||
this.TileWidth = TileWidth;
|
this.TileWidth = TileWidth;
|
||||||
this.GobBlockHeight = GobBlockHeight;
|
this.GobBlockHeight = GobBlockHeight;
|
||||||
|
|
|
@ -82,7 +82,6 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
||||||
Type,
|
Type,
|
||||||
IntPtr.Zero);
|
IntPtr.Zero);
|
||||||
break;
|
break;
|
||||||
case TextureTarget.Texture2DArray:
|
|
||||||
case TextureTarget.Texture3D:
|
case TextureTarget.Texture3D:
|
||||||
GL.TexImage3D(
|
GL.TexImage3D(
|
||||||
Target,
|
Target,
|
||||||
|
@ -96,6 +95,19 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
||||||
Type,
|
Type,
|
||||||
IntPtr.Zero);
|
IntPtr.Zero);
|
||||||
break;
|
break;
|
||||||
|
case TextureTarget.Texture2DArray:
|
||||||
|
GL.TexImage3D(
|
||||||
|
Target,
|
||||||
|
Level,
|
||||||
|
InternalFmt,
|
||||||
|
Image.Width,
|
||||||
|
Image.Height,
|
||||||
|
Image.LayerCount,
|
||||||
|
Border,
|
||||||
|
Format,
|
||||||
|
Type,
|
||||||
|
IntPtr.Zero);
|
||||||
|
break;
|
||||||
case TextureTarget.TextureCubeMap:
|
case TextureTarget.TextureCubeMap:
|
||||||
|
|
||||||
int FaceSize = ImageUtils.GetSize(Image) / Image.Depth;
|
int FaceSize = ImageUtils.GetSize(Image) / Image.Depth;
|
||||||
|
@ -175,6 +187,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
||||||
case TextureTarget.TextureCubeMap:
|
case TextureTarget.TextureCubeMap:
|
||||||
Span<byte> Array = new Span<byte>(Data);
|
Span<byte> Array = new Span<byte>(Data);
|
||||||
|
|
||||||
|
// FIXME: wrong
|
||||||
int FaceSize = ImageUtils.GetSize(Image) / Image.Depth;
|
int FaceSize = ImageUtils.GetSize(Image) / Image.Depth;
|
||||||
|
|
||||||
for (int Face = 0; Face < 6; Face++)
|
for (int Face = 0; Face < 6; Face++)
|
||||||
|
@ -197,7 +210,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
||||||
InternalFmt,
|
InternalFmt,
|
||||||
Image.Width,
|
Image.Width,
|
||||||
Image.Height,
|
Image.Height,
|
||||||
Image.Depth * 6,
|
Image.LayerCount * 6,
|
||||||
Border,
|
Border,
|
||||||
Data.Length,
|
Data.Length,
|
||||||
Data);
|
Data);
|
||||||
|
@ -257,7 +270,6 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
||||||
Type,
|
Type,
|
||||||
Data);
|
Data);
|
||||||
break;
|
break;
|
||||||
case TextureTarget.Texture2DArray:
|
|
||||||
case TextureTarget.Texture3D:
|
case TextureTarget.Texture3D:
|
||||||
GL.TexImage3D(
|
GL.TexImage3D(
|
||||||
Target,
|
Target,
|
||||||
|
@ -271,9 +283,23 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
||||||
Type,
|
Type,
|
||||||
Data);
|
Data);
|
||||||
break;
|
break;
|
||||||
|
case TextureTarget.Texture2DArray:
|
||||||
|
GL.TexImage3D(
|
||||||
|
Target,
|
||||||
|
Level,
|
||||||
|
InternalFmt,
|
||||||
|
Image.Width,
|
||||||
|
Image.Height,
|
||||||
|
Image.LayerCount,
|
||||||
|
Border,
|
||||||
|
Format,
|
||||||
|
Type,
|
||||||
|
Data);
|
||||||
|
break;
|
||||||
case TextureTarget.TextureCubeMap:
|
case TextureTarget.TextureCubeMap:
|
||||||
Span<byte> Array = new Span<byte>(Data);
|
Span<byte> Array = new Span<byte>(Data);
|
||||||
|
|
||||||
|
// FIXME: wrong
|
||||||
int FaceSize = ImageUtils.GetSize(Image) / Image.Depth;
|
int FaceSize = ImageUtils.GetSize(Image) / Image.Depth;
|
||||||
|
|
||||||
for (int Face = 0; Face < 6; Face++)
|
for (int Face = 0; Face < 6; Face++)
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
using Ryujinx.Common.Logging;
|
||||||
using Ryujinx.Graphics.Gal;
|
using Ryujinx.Graphics.Gal;
|
||||||
using Ryujinx.Graphics.Memory;
|
using Ryujinx.Graphics.Memory;
|
||||||
using Ryujinx.Graphics.Texture;
|
using Ryujinx.Graphics.Texture;
|
||||||
|
@ -118,7 +119,7 @@ namespace Ryujinx.Graphics.Graphics3d
|
||||||
GalImage SrcTexture = new GalImage(
|
GalImage SrcTexture = new GalImage(
|
||||||
SrcWidth,
|
SrcWidth,
|
||||||
SrcHeight,
|
SrcHeight,
|
||||||
SrcDepth, 1,
|
1, SrcDepth, 1,
|
||||||
SrcBlockHeight, 1,
|
SrcBlockHeight, 1,
|
||||||
SrcLayout,
|
SrcLayout,
|
||||||
SrcImgFormat,
|
SrcImgFormat,
|
||||||
|
@ -127,7 +128,7 @@ namespace Ryujinx.Graphics.Graphics3d
|
||||||
GalImage DstTexture = new GalImage(
|
GalImage DstTexture = new GalImage(
|
||||||
DstWidth,
|
DstWidth,
|
||||||
DstHeight,
|
DstHeight,
|
||||||
DstDepth, 1,
|
1, DstDepth, 1,
|
||||||
DstBlockHeight, 1,
|
DstBlockHeight, 1,
|
||||||
DstLayout,
|
DstLayout,
|
||||||
DstImgFormat,
|
DstImgFormat,
|
||||||
|
@ -138,8 +139,7 @@ namespace Ryujinx.Graphics.Graphics3d
|
||||||
|
|
||||||
long GetLayerOffset(GalImage Image, int Layer)
|
long GetLayerOffset(GalImage Image, int Layer)
|
||||||
{
|
{
|
||||||
// TODO: mip map
|
return (ImageUtils.GetGpuSize(Image) / Image.LayerCount) * Layer;
|
||||||
return (ImageUtils.GetGpuSize(Image) / Image.Depth) * Layer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int SrcLayerIndex = -1;
|
int SrcLayerIndex = -1;
|
||||||
|
@ -161,7 +161,7 @@ namespace Ryujinx.Graphics.Graphics3d
|
||||||
|
|
||||||
if (IsSrcLayered && SrcLayerIndex == -1)
|
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);
|
Gpu.ResourceManager.SetTextureArrayLayer(SrcKey + GetLayerOffset(SrcTexture, Layer), Layer);
|
||||||
}
|
}
|
||||||
|
@ -171,7 +171,7 @@ namespace Ryujinx.Graphics.Graphics3d
|
||||||
|
|
||||||
if (IsDstLayered && DstLayerIndex == -1)
|
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);
|
Gpu.ResourceManager.SetTextureArrayLayer(DstKey + GetLayerOffset(DstTexture, Layer), Layer);
|
||||||
}
|
}
|
||||||
|
|
|
@ -208,7 +208,7 @@ namespace Ryujinx.Graphics.Graphics3d
|
||||||
|
|
||||||
GalImageFormat Format = ImageUtils.ConvertSurface((GalSurfaceFormat)SurfFormat);
|
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);
|
Gpu.ResourceManager.SendColorBuffer(Vmm, Key, FbIndex, Image);
|
||||||
|
|
||||||
|
@ -263,7 +263,7 @@ namespace Ryujinx.Graphics.Graphics3d
|
||||||
GalImageFormat Format = ImageUtils.ConvertZeta((GalZetaFormat)ZetaFormat);
|
GalImageFormat Format = ImageUtils.ConvertZeta((GalZetaFormat)ZetaFormat);
|
||||||
|
|
||||||
// TODO: Support non 2D?
|
// 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);
|
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.
|
//FIXME: Some games like puyo puyo will use handles with the value 0.
|
||||||
//This is a bug, most likely caused by sync issues.
|
//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);
|
bool LinkedTsc = ReadRegisterBool(NvGpuEngine3dReg.LinkedTsc);
|
||||||
|
|
|
@ -3,5 +3,11 @@ namespace Ryujinx.Graphics.Texture
|
||||||
interface ISwizzle
|
interface ISwizzle
|
||||||
{
|
{
|
||||||
int GetSwizzleOffset(int X, int Y, int Z);
|
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)
|
public static int GetGpuSize(GalImage Image, bool forcePitch = false)
|
||||||
{
|
{
|
||||||
ImageDescriptor Desc = GetImageDescriptor(Image.Format);
|
return TextureHelper.GetSwizzle(Image).GetImageSize(Image.MaxMipmapLevel) * Image.LayerCount;
|
||||||
|
|
||||||
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));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int GetPitch(GalImageFormat Format, int Width)
|
public static int GetPitch(GalImageFormat Format, int Width)
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Texture
|
namespace Ryujinx.Graphics.Texture
|
||||||
{
|
{
|
||||||
class LinearSwizzle : ISwizzle
|
class LinearSwizzle : ISwizzle
|
||||||
|
@ -14,6 +16,23 @@ namespace Ryujinx.Graphics.Texture
|
||||||
SliceSize = Width * Height * Bpp;
|
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)
|
public int GetSwizzleOffset(int X, int Y, int Z)
|
||||||
{
|
{
|
||||||
return Z * SliceSize + X * Bpp + Y * Pitch;
|
return Z * SliceSize + X * Bpp + Y * Pitch;
|
||||||
|
|
|
@ -47,6 +47,15 @@ namespace Ryujinx.Graphics.Texture
|
||||||
int Height = ((Tic[5] >> 0) & 0xffff) + 1;
|
int Height = ((Tic[5] >> 0) & 0xffff) + 1;
|
||||||
int Depth = ((Tic[5] >> 16) & 0x3fff) + 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)
|
if (TextureTarget == GalTextureTarget.OneD)
|
||||||
{
|
{
|
||||||
Height = 1;
|
Height = 1;
|
||||||
|
@ -58,6 +67,7 @@ namespace Ryujinx.Graphics.Texture
|
||||||
}
|
}
|
||||||
else if (TextureTarget == GalTextureTarget.CubeMap)
|
else if (TextureTarget == GalTextureTarget.CubeMap)
|
||||||
{
|
{
|
||||||
|
// TODO: WRONG
|
||||||
Depth = 6;
|
Depth = 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,6 +75,7 @@ namespace Ryujinx.Graphics.Texture
|
||||||
Width,
|
Width,
|
||||||
Height,
|
Height,
|
||||||
Depth,
|
Depth,
|
||||||
|
LayoutCount,
|
||||||
TileWidth,
|
TileWidth,
|
||||||
GobBlockHeight,
|
GobBlockHeight,
|
||||||
GobBlockDepth,
|
GobBlockDepth,
|
||||||
|
|
|
@ -216,7 +216,7 @@ namespace Ryujinx.Graphics.VDec
|
||||||
|
|
||||||
GalImage Image = new GalImage(
|
GalImage Image = new GalImage(
|
||||||
OutputConfig.SurfaceWidth,
|
OutputConfig.SurfaceWidth,
|
||||||
OutputConfig.SurfaceHeight, 1, 1,
|
OutputConfig.SurfaceHeight, 1, 1, 1,
|
||||||
OutputConfig.GobBlockHeight, 1,
|
OutputConfig.GobBlockHeight, 1,
|
||||||
GalMemoryLayout.BlockLinear,
|
GalMemoryLayout.BlockLinear,
|
||||||
GalImageFormat.RGBA8 | GalImageFormat.Unorm,
|
GalImageFormat.RGBA8 | GalImageFormat.Unorm,
|
||||||
|
|
|
@ -416,7 +416,7 @@ namespace Ryujinx.HLE.HOS.Services.Android
|
||||||
{
|
{
|
||||||
image = new GalImage(
|
image = new GalImage(
|
||||||
fbWidth,
|
fbWidth,
|
||||||
fbHeight, 1, 1, BlockHeight, 1,
|
fbHeight, 1, 1, 1, BlockHeight, 1,
|
||||||
GalMemoryLayout.BlockLinear,
|
GalMemoryLayout.BlockLinear,
|
||||||
imageFormat,
|
imageFormat,
|
||||||
GalTextureTarget.TwoD);
|
GalTextureTarget.TwoD);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue