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,8 +25,12 @@ namespace Ryujinx.Graphics.Gal
|
||||||
void Render();
|
void Render();
|
||||||
|
|
||||||
void Copy(
|
void Copy(
|
||||||
|
GalImage SrcImage,
|
||||||
|
GalImage DstImage,
|
||||||
long SrcKey,
|
long SrcKey,
|
||||||
long DstKey,
|
long DstKey,
|
||||||
|
int SrcLayer,
|
||||||
|
int DstLayer,
|
||||||
int SrcX0,
|
int SrcX0,
|
||||||
int SrcY0,
|
int SrcY0,
|
||||||
int SrcX1,
|
int SrcX1,
|
||||||
|
|
|
@ -389,8 +389,12 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Copy(
|
public void Copy(
|
||||||
|
GalImage SrcImage,
|
||||||
|
GalImage DstImage,
|
||||||
long SrcKey,
|
long SrcKey,
|
||||||
long DstKey,
|
long DstKey,
|
||||||
|
int SrcLayer,
|
||||||
|
int DstLayer,
|
||||||
int SrcX0,
|
int SrcX0,
|
||||||
int SrcY0,
|
int SrcY0,
|
||||||
int SrcX1,
|
int SrcX1,
|
||||||
|
@ -425,8 +429,24 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
||||||
|
|
||||||
FramebufferAttachment Attachment = GetAttachment(SrcTex);
|
FramebufferAttachment Attachment = GetAttachment(SrcTex);
|
||||||
|
|
||||||
|
if (ImageUtils.IsArray(SrcImage.TextureTarget) && SrcLayer > 0)
|
||||||
|
{
|
||||||
|
GL.FramebufferTextureLayer(FramebufferTarget.ReadFramebuffer, Attachment, SrcTex.Handle, 0, SrcLayer);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
GL.FramebufferTexture(FramebufferTarget.ReadFramebuffer, Attachment, SrcTex.Handle, 0);
|
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);
|
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