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
parent deb3c58020
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,
Texture,
TextureMirror,
TextureArrayLayer,
ColorBuffer,
ZetaBuffer
}
@ -74,13 +74,13 @@ namespace Ryujinx.Graphics
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];
if (Type != ImageType.Texture && Type != ImageType.TextureMirror)
if (Type != ImageType.Texture && Type != ImageType.TextureArrayLayer)
{
throw new InvalidOperationException();
}
@ -88,14 +88,14 @@ namespace Ryujinx.Graphics
return true;
}
Layer = -1;
LayerIndex = -1;
return false;
}
public void SetTextureMirror(long Position, int Layer)
public void SetTextureArrayLayer(long Position, int LayerIndex)
{
ImageTypes[Position] = ImageType.TextureMirror;
MirroredTextures[Position] = Layer;
ImageTypes[Position] = ImageType.TextureArrayLayer;
MirroredTextures[Position] = LayerIndex;
}
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)
{
// FIXME: CALCULATE THE REAL TEXTURE SIZE (GPU SIZE NOT OGL SIZE)
// TODO: mip map
return ImageUtils.GetSize(Image) * Layer;
return (ImageUtils.GetGpuSize(Image) / Image.Depth) * Layer;
}
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);
}
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);
}
@ -164,7 +163,7 @@ namespace Ryujinx.Graphics.Graphics3d
{
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;
@ -174,7 +173,7 @@ namespace Ryujinx.Graphics.Graphics3d
{
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;

View file

@ -1,5 +1,6 @@
using ChocolArm64.Memory;
using OpenTK.Graphics.OpenGL;
using Ryujinx.Common;
using Ryujinx.Graphics.Gal;
using Ryujinx.Graphics.Memory;
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)
{
ImageDescriptor Desc = GetImageDescriptor(Format);