Implement GetGpuSize + fix somes issues with 2d engine copies

TODO: mipmap level in it
This commit is contained in:
Thog 2018-12-30 22:41:36 +01:00
commit 3697d65009
No known key found for this signature in database
GPG key ID: 0CD291558FAFDBC6
3 changed files with 99 additions and 14 deletions

View file

@ -12,7 +12,7 @@ namespace Ryujinx.Graphics
{ {
None, None,
Texture, Texture,
TextureMirror, TextureArrayLayer,
ColorBuffer, ColorBuffer,
ZetaBuffer ZetaBuffer
} }
@ -74,13 +74,13 @@ namespace Ryujinx.Graphics
ImageTypes[Position] = ImageType.Texture; ImageTypes[Position] = ImageType.Texture;
} }
public bool TryGetTextureMirorLayer(long Position, out int Layer) public bool TryGetTextureLayer(long Position, out int LayerIndex)
{ {
if (MirroredTextures.TryGetValue(Position, out Layer)) if (MirroredTextures.TryGetValue(Position, out LayerIndex))
{ {
ImageType Type = ImageTypes[Position]; ImageType Type = ImageTypes[Position];
if (Type != ImageType.Texture && Type != ImageType.TextureMirror) if (Type != ImageType.Texture && Type != ImageType.TextureArrayLayer)
{ {
throw new InvalidOperationException(); throw new InvalidOperationException();
} }
@ -88,14 +88,14 @@ namespace Ryujinx.Graphics
return true; return true;
} }
Layer = -1; LayerIndex = -1;
return false; return false;
} }
public void SetTextureMirror(long Position, int Layer) public void SetTextureArrayLayer(long Position, int LayerIndex)
{ {
ImageTypes[Position] = ImageType.TextureMirror; ImageTypes[Position] = ImageType.TextureArrayLayer;
MirroredTextures[Position] = Layer; MirroredTextures[Position] = LayerIndex;
} }
private void PrepareSendTexture(NvGpuVmm Vmm, long Position, GalImage NewImage) private void PrepareSendTexture(NvGpuVmm Vmm, long Position, GalImage NewImage)

View file

@ -138,21 +138,20 @@ namespace Ryujinx.Graphics.Graphics3d
long GetLayerOffset(GalImage Image, int Layer) long GetLayerOffset(GalImage Image, int Layer)
{ {
// FIXME: CALCULATE THE REAL TEXTURE SIZE (GPU SIZE NOT OGL SIZE)
// TODO: mip map // TODO: mip map
return ImageUtils.GetSize(Image) * Layer; return (ImageUtils.GetGpuSize(Image) / Image.Depth) * Layer;
} }
int SrcLayerIndex = -1; int SrcLayerIndex = -1;
if (IsSrcLayered && Gpu.ResourceManager.TryGetTextureMirorLayer(SrcKey, out SrcLayerIndex)) if (IsSrcLayered && Gpu.ResourceManager.TryGetTextureLayer(SrcKey, out SrcLayerIndex) && SrcLayerIndex != 0)
{ {
SrcKey = SrcKey - GetLayerOffset(SrcTexture, SrcLayerIndex); SrcKey = SrcKey - GetLayerOffset(SrcTexture, SrcLayerIndex);
} }
int DstLayerIndex = -1; int DstLayerIndex = -1;
if (IsDstLayered && Gpu.ResourceManager.TryGetTextureMirorLayer(DstKey, out DstLayerIndex)) if (IsDstLayered && Gpu.ResourceManager.TryGetTextureLayer(DstKey, out DstLayerIndex) && DstLayerIndex != 0)
{ {
DstKey = DstKey - GetLayerOffset(DstTexture, DstLayerIndex); DstKey = DstKey - GetLayerOffset(DstTexture, DstLayerIndex);
} }
@ -164,7 +163,7 @@ namespace Ryujinx.Graphics.Graphics3d
{ {
for (int Layer = 0; Layer < SrcTexture.Depth; Layer++) for (int Layer = 0; Layer < SrcTexture.Depth; Layer++)
{ {
Gpu.ResourceManager.SetTextureMirror(SrcKey + GetLayerOffset(SrcTexture, Layer), Layer); Gpu.ResourceManager.SetTextureArrayLayer(SrcKey + GetLayerOffset(SrcTexture, Layer), Layer);
} }
SrcLayerIndex = 0; SrcLayerIndex = 0;
@ -174,7 +173,7 @@ namespace Ryujinx.Graphics.Graphics3d
{ {
for (int Layer = 0; Layer < DstTexture.Depth; Layer++) for (int Layer = 0; Layer < DstTexture.Depth; Layer++)
{ {
Gpu.ResourceManager.SetTextureMirror(DstKey + GetLayerOffset(DstTexture, Layer), Layer); Gpu.ResourceManager.SetTextureArrayLayer(DstKey + GetLayerOffset(DstTexture, Layer), Layer);
} }
DstLayerIndex = 0; DstLayerIndex = 0;

View file

@ -1,5 +1,6 @@
using ChocolArm64.Memory; using ChocolArm64.Memory;
using OpenTK.Graphics.OpenGL; using OpenTK.Graphics.OpenGL;
using Ryujinx.Common;
using Ryujinx.Graphics.Gal; using Ryujinx.Graphics.Gal;
using Ryujinx.Graphics.Memory; using Ryujinx.Graphics.Memory;
using System; using System;
@ -363,6 +364,91 @@ 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));
}
public static int GetPitch(GalImageFormat Format, int Width) public static int GetPitch(GalImageFormat Format, int Width)
{ {
ImageDescriptor Desc = GetImageDescriptor(Format); ImageDescriptor Desc = GetImageDescriptor(Format);