Support 2D array copy operation in the 2D engine
This make every copy right in the GPU side. Thie CPU copy probably needs to be updated
This commit is contained in:
parent
17550a21cd
commit
deb3c58020
5 changed files with 128 additions and 23 deletions
|
@ -25,16 +25,20 @@ namespace Ryujinx.Graphics.Gal
|
||||||
void Render();
|
void Render();
|
||||||
|
|
||||||
void Copy(
|
void Copy(
|
||||||
long SrcKey,
|
GalImage SrcImage,
|
||||||
long DstKey,
|
GalImage DstImage,
|
||||||
int SrcX0,
|
long SrcKey,
|
||||||
int SrcY0,
|
long DstKey,
|
||||||
int SrcX1,
|
int SrcLayer,
|
||||||
int SrcY1,
|
int DstLayer,
|
||||||
int DstX0,
|
int SrcX0,
|
||||||
int DstY0,
|
int SrcY0,
|
||||||
int DstX1,
|
int SrcX1,
|
||||||
int DstY1);
|
int SrcY1,
|
||||||
|
int DstX0,
|
||||||
|
int DstY0,
|
||||||
|
int DstX1,
|
||||||
|
int DstY1);
|
||||||
|
|
||||||
void Reinterpret(long Key, GalImage NewImage);
|
void Reinterpret(long Key, GalImage NewImage);
|
||||||
}
|
}
|
||||||
|
|
|
@ -389,16 +389,20 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Copy(
|
public void Copy(
|
||||||
long SrcKey,
|
GalImage SrcImage,
|
||||||
long DstKey,
|
GalImage DstImage,
|
||||||
int SrcX0,
|
long SrcKey,
|
||||||
int SrcY0,
|
long DstKey,
|
||||||
int SrcX1,
|
int SrcLayer,
|
||||||
int SrcY1,
|
int DstLayer,
|
||||||
int DstX0,
|
int SrcX0,
|
||||||
int DstY0,
|
int SrcY0,
|
||||||
int DstX1,
|
int SrcX1,
|
||||||
int DstY1)
|
int SrcY1,
|
||||||
|
int DstX0,
|
||||||
|
int DstY0,
|
||||||
|
int DstX1,
|
||||||
|
int DstY1)
|
||||||
{
|
{
|
||||||
if (Texture.TryGetImageHandler(SrcKey, out ImageHandler SrcTex) &&
|
if (Texture.TryGetImageHandler(SrcKey, out ImageHandler SrcTex) &&
|
||||||
Texture.TryGetImageHandler(DstKey, out ImageHandler DstTex))
|
Texture.TryGetImageHandler(DstKey, out ImageHandler DstTex))
|
||||||
|
@ -425,8 +429,24 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
||||||
|
|
||||||
FramebufferAttachment Attachment = GetAttachment(SrcTex);
|
FramebufferAttachment Attachment = GetAttachment(SrcTex);
|
||||||
|
|
||||||
GL.FramebufferTexture(FramebufferTarget.ReadFramebuffer, Attachment, SrcTex.Handle, 0);
|
if (ImageUtils.IsArray(SrcImage.TextureTarget) && SrcLayer > 0)
|
||||||
GL.FramebufferTexture(FramebufferTarget.DrawFramebuffer, Attachment, DstTex.Handle, 0);
|
{
|
||||||
|
GL.FramebufferTextureLayer(FramebufferTarget.ReadFramebuffer, Attachment, SrcTex.Handle, 0, SrcLayer);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GL.FramebufferTexture(FramebufferTarget.ReadFramebuffer, Attachment, SrcTex.Handle, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ImageUtils.IsArray(DstImage.TextureTarget) && DstLayer > 0)
|
||||||
|
{
|
||||||
|
GL.FramebufferTextureLayer(FramebufferTarget.DrawFramebuffer, Attachment, DstTex.Handle, 0, DstLayer);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GL.FramebufferTexture(FramebufferTarget.DrawFramebuffer, Attachment, DstTex.Handle, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
BlitFramebufferFilter Filter = BlitFramebufferFilter.Nearest;
|
BlitFramebufferFilter Filter = BlitFramebufferFilter.Nearest;
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
using Ryujinx.Graphics.Gal;
|
using Ryujinx.Graphics.Gal;
|
||||||
using Ryujinx.Graphics.Memory;
|
using Ryujinx.Graphics.Memory;
|
||||||
using Ryujinx.Graphics.Texture;
|
using Ryujinx.Graphics.Texture;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace Ryujinx.Graphics
|
namespace Ryujinx.Graphics
|
||||||
|
@ -11,6 +12,7 @@ namespace Ryujinx.Graphics
|
||||||
{
|
{
|
||||||
None,
|
None,
|
||||||
Texture,
|
Texture,
|
||||||
|
TextureMirror,
|
||||||
ColorBuffer,
|
ColorBuffer,
|
||||||
ZetaBuffer
|
ZetaBuffer
|
||||||
}
|
}
|
||||||
|
@ -20,6 +22,7 @@ namespace Ryujinx.Graphics
|
||||||
private HashSet<long>[] UploadedKeys;
|
private HashSet<long>[] UploadedKeys;
|
||||||
|
|
||||||
private Dictionary<long, ImageType> ImageTypes;
|
private Dictionary<long, ImageType> ImageTypes;
|
||||||
|
private Dictionary<long, int> MirroredTextures;
|
||||||
|
|
||||||
public GpuResourceManager(NvGpu Gpu)
|
public GpuResourceManager(NvGpu Gpu)
|
||||||
{
|
{
|
||||||
|
@ -33,6 +36,7 @@ namespace Ryujinx.Graphics
|
||||||
}
|
}
|
||||||
|
|
||||||
ImageTypes = new Dictionary<long, ImageType>();
|
ImageTypes = new Dictionary<long, ImageType>();
|
||||||
|
MirroredTextures = new Dictionary<long, int>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SendColorBuffer(NvGpuVmm Vmm, long Position, int Attachment, GalImage NewImage)
|
public void SendColorBuffer(NvGpuVmm Vmm, long Position, int Attachment, GalImage NewImage)
|
||||||
|
@ -70,6 +74,30 @@ namespace Ryujinx.Graphics
|
||||||
ImageTypes[Position] = ImageType.Texture;
|
ImageTypes[Position] = ImageType.Texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool TryGetTextureMirorLayer(long Position, out int Layer)
|
||||||
|
{
|
||||||
|
if (MirroredTextures.TryGetValue(Position, out Layer))
|
||||||
|
{
|
||||||
|
ImageType Type = ImageTypes[Position];
|
||||||
|
|
||||||
|
if (Type != ImageType.Texture && Type != ImageType.TextureMirror)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Layer = -1;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetTextureMirror(long Position, int Layer)
|
||||||
|
{
|
||||||
|
ImageTypes[Position] = ImageType.TextureMirror;
|
||||||
|
MirroredTextures[Position] = Layer;
|
||||||
|
}
|
||||||
|
|
||||||
private void PrepareSendTexture(NvGpuVmm Vmm, long Position, GalImage NewImage)
|
private void PrepareSendTexture(NvGpuVmm Vmm, long Position, GalImage NewImage)
|
||||||
{
|
{
|
||||||
long Size = ImageUtils.GetSize(NewImage);
|
long Size = ImageUtils.GetSize(NewImage);
|
||||||
|
|
|
@ -86,12 +86,16 @@ namespace Ryujinx.Graphics.Graphics3d
|
||||||
long SrcKey = Vmm.GetPhysicalAddress(SrcAddress);
|
long SrcKey = Vmm.GetPhysicalAddress(SrcAddress);
|
||||||
long DstKey = Vmm.GetPhysicalAddress(DstAddress);
|
long DstKey = Vmm.GetPhysicalAddress(DstAddress);
|
||||||
|
|
||||||
|
bool IsSrcLayered = false;
|
||||||
|
bool IsDstLayered = false;
|
||||||
|
|
||||||
GalTextureTarget SrcTarget = GalTextureTarget.TwoD;
|
GalTextureTarget SrcTarget = GalTextureTarget.TwoD;
|
||||||
|
|
||||||
if (SrcDepth != 0)
|
if (SrcDepth != 0)
|
||||||
{
|
{
|
||||||
SrcTarget = GalTextureTarget.TwoDArray;
|
SrcTarget = GalTextureTarget.TwoDArray;
|
||||||
SrcDepth++;
|
SrcDepth++;
|
||||||
|
IsSrcLayered = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -104,6 +108,7 @@ namespace Ryujinx.Graphics.Graphics3d
|
||||||
{
|
{
|
||||||
DstTarget = GalTextureTarget.TwoDArray;
|
DstTarget = GalTextureTarget.TwoDArray;
|
||||||
DstDepth++;
|
DstDepth++;
|
||||||
|
IsDstLayered = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -131,19 +136,63 @@ namespace Ryujinx.Graphics.Graphics3d
|
||||||
SrcTexture.Pitch = SrcPitch;
|
SrcTexture.Pitch = SrcPitch;
|
||||||
DstTexture.Pitch = DstPitch;
|
DstTexture.Pitch = DstPitch;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
int SrcLayerIndex = -1;
|
||||||
|
|
||||||
|
if (IsSrcLayered && Gpu.ResourceManager.TryGetTextureMirorLayer(SrcKey, out SrcLayerIndex))
|
||||||
|
{
|
||||||
|
SrcKey = SrcKey - GetLayerOffset(SrcTexture, SrcLayerIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
int DstLayerIndex = -1;
|
||||||
|
|
||||||
|
if (IsDstLayered && Gpu.ResourceManager.TryGetTextureMirorLayer(DstKey, out DstLayerIndex))
|
||||||
|
{
|
||||||
|
DstKey = DstKey - GetLayerOffset(DstTexture, DstLayerIndex);
|
||||||
|
}
|
||||||
|
|
||||||
Gpu.ResourceManager.SendTexture(Vmm, SrcKey, SrcTexture);
|
Gpu.ResourceManager.SendTexture(Vmm, SrcKey, SrcTexture);
|
||||||
Gpu.ResourceManager.SendTexture(Vmm, DstKey, DstTexture);
|
Gpu.ResourceManager.SendTexture(Vmm, DstKey, DstTexture);
|
||||||
|
|
||||||
|
if (IsSrcLayered && SrcLayerIndex == -1)
|
||||||
|
{
|
||||||
|
for (int Layer = 0; Layer < SrcTexture.Depth; Layer++)
|
||||||
|
{
|
||||||
|
Gpu.ResourceManager.SetTextureMirror(SrcKey + GetLayerOffset(SrcTexture, Layer), Layer);
|
||||||
|
}
|
||||||
|
|
||||||
|
SrcLayerIndex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsDstLayered && DstLayerIndex == -1)
|
||||||
|
{
|
||||||
|
for (int Layer = 0; Layer < DstTexture.Depth; Layer++)
|
||||||
|
{
|
||||||
|
Gpu.ResourceManager.SetTextureMirror(DstKey + GetLayerOffset(DstTexture, Layer), Layer);
|
||||||
|
}
|
||||||
|
|
||||||
|
DstLayerIndex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
int SrcBlitX1 = (int)(SrcBlitX >> 32);
|
int SrcBlitX1 = (int)(SrcBlitX >> 32);
|
||||||
int SrcBlitY1 = (int)(SrcBlitY >> 32);
|
int SrcBlitY1 = (int)(SrcBlitY >> 32);
|
||||||
|
|
||||||
int SrcBlitX2 = (int)(SrcBlitX + DstBlitW * BlitDuDx >> 32);
|
int SrcBlitX2 = (int)(SrcBlitX + DstBlitW * BlitDuDx >> 32);
|
||||||
int SrcBlitY2 = (int)(SrcBlitY + DstBlitH * BlitDvDy >> 32);
|
int SrcBlitY2 = (int)(SrcBlitY + DstBlitH * BlitDvDy >> 32);
|
||||||
|
|
||||||
// TODO: support 2d array copy
|
|
||||||
Gpu.Renderer.RenderTarget.Copy(
|
Gpu.Renderer.RenderTarget.Copy(
|
||||||
|
SrcTexture,
|
||||||
|
DstTexture,
|
||||||
SrcKey,
|
SrcKey,
|
||||||
DstKey,
|
DstKey,
|
||||||
|
SrcLayerIndex,
|
||||||
|
DstLayerIndex,
|
||||||
SrcBlitX1,
|
SrcBlitX1,
|
||||||
SrcBlitY1,
|
SrcBlitY1,
|
||||||
SrcBlitX2,
|
SrcBlitX2,
|
||||||
|
@ -157,6 +206,8 @@ namespace Ryujinx.Graphics.Graphics3d
|
||||||
//the texture is modified by the guest, however it doesn't
|
//the texture is modified by the guest, however it doesn't
|
||||||
//work when resources that the gpu can write to are copied,
|
//work when resources that the gpu can write to are copied,
|
||||||
//like framebuffers.
|
//like framebuffers.
|
||||||
|
|
||||||
|
// FIXME: SUPPORT MULTILAYER CORRECTLY HERE (this will cause weird stuffs on the first layer)
|
||||||
ImageUtils.CopyTexture(
|
ImageUtils.CopyTexture(
|
||||||
Vmm,
|
Vmm,
|
||||||
SrcTexture,
|
SrcTexture,
|
||||||
|
|
|
@ -11,6 +11,7 @@ namespace Ryujinx.Graphics.Graphics3d
|
||||||
DstWidth = 0x86,
|
DstWidth = 0x86,
|
||||||
DstHeight = 0x87,
|
DstHeight = 0x87,
|
||||||
DstAddress = 0x88,
|
DstAddress = 0x88,
|
||||||
|
DstAddressLow = 0x89,
|
||||||
SrcFormat = 0x8c,
|
SrcFormat = 0x8c,
|
||||||
SrcLinear = 0x8d,
|
SrcLinear = 0x8d,
|
||||||
SrcBlockDimensions = 0x8e,
|
SrcBlockDimensions = 0x8e,
|
||||||
|
@ -20,6 +21,7 @@ namespace Ryujinx.Graphics.Graphics3d
|
||||||
SrcWidth = 0x92,
|
SrcWidth = 0x92,
|
||||||
SrcHeight = 0x93,
|
SrcHeight = 0x93,
|
||||||
SrcAddress = 0x94,
|
SrcAddress = 0x94,
|
||||||
|
SrcAddressLow = 0x95,
|
||||||
ClipEnable = 0xa4,
|
ClipEnable = 0xa4,
|
||||||
CopyOperation = 0xab,
|
CopyOperation = 0xab,
|
||||||
BlitControl = 0x223,
|
BlitControl = 0x223,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue