Add support for bigger UBOs, fix sRGB regression, small improvement t… (#503)

* Add support for bigger UBOs, fix sRGB regression, small improvement to the 2D copy engine

* Break into multiple lines

* Read fractions for source/step values on the 2d copy engine aswell

* Use fixed point math for more speed

* Fix reinterpret when texture sizes are different
This commit is contained in:
gdkchan 2018-11-28 21:09:44 -02:00 committed by GitHub
parent 00579927e4
commit 59964f667c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 90 additions and 24 deletions

View file

@ -0,0 +1,12 @@
using OpenTK.Graphics.OpenGL;
using System;
namespace Ryujinx.Graphics.Gal.OpenGL
{
static class OGLLimit
{
private static Lazy<int> s_MaxUboSize = new Lazy<int>(() => GL.GetInteger(GetPName.MaxUniformBlockSize));
public static int MaxUboSize => s_MaxUboSize.Value;
}
}

View file

@ -78,14 +78,20 @@ namespace Ryujinx.Graphics.Gal.OpenGL
private GalPipelineState Old; private GalPipelineState Old;
private OGLConstBuffer Buffer; private OGLConstBuffer Buffer;
private OGLRenderTarget RenderTarget;
private OGLRasterizer Rasterizer; private OGLRasterizer Rasterizer;
private OGLShader Shader; private OGLShader Shader;
private int VaoHandle; private int VaoHandle;
public OGLPipeline(OGLConstBuffer Buffer, OGLRasterizer Rasterizer, OGLShader Shader) public OGLPipeline(
OGLConstBuffer Buffer,
OGLRenderTarget RenderTarget,
OGLRasterizer Rasterizer,
OGLShader Shader)
{ {
this.Buffer = Buffer; this.Buffer = Buffer;
this.RenderTarget = RenderTarget;
this.Rasterizer = Rasterizer; this.Rasterizer = Rasterizer;
this.Shader = Shader; this.Shader = Shader;
@ -144,6 +150,8 @@ namespace Ryujinx.Graphics.Gal.OpenGL
if (New.FramebufferSrgb != Old.FramebufferSrgb) if (New.FramebufferSrgb != Old.FramebufferSrgb)
{ {
Enable(EnableCap.FramebufferSrgb, New.FramebufferSrgb); Enable(EnableCap.FramebufferSrgb, New.FramebufferSrgb);
RenderTarget.FramebufferSrgb = New.FramebufferSrgb;
} }
if (New.FlipX != Old.FlipX || New.FlipY != Old.FlipY || New.Instance != Old.Instance) if (New.FlipX != Old.FlipX || New.FlipY != Old.FlipY || New.Instance != Old.Instance)

View file

@ -90,6 +90,8 @@ namespace Ryujinx.Graphics.Gal.OpenGL
private int CopyPBO; private int CopyPBO;
public bool FramebufferSrgb { get; set; }
public OGLRenderTarget(OGLTexture Texture) public OGLRenderTarget(OGLTexture Texture)
{ {
Attachments = new FrameBufferAttachments(); Attachments = new FrameBufferAttachments();
@ -363,11 +365,24 @@ namespace Ryujinx.Graphics.Gal.OpenGL
GL.Clear(ClearBufferMask.ColorBufferBit); GL.Clear(ClearBufferMask.ColorBufferBit);
GL.Disable(EnableCap.FramebufferSrgb);
GL.BlitFramebuffer( GL.BlitFramebuffer(
SrcX0, SrcY0, SrcX1, SrcY1, SrcX0,
DstX0, DstY0, DstX1, DstY1, SrcY0,
SrcX1,
SrcY1,
DstX0,
DstY0,
DstX1,
DstY1,
ClearBufferMask.ColorBufferBit, ClearBufferMask.ColorBufferBit,
BlitFramebufferFilter.Linear); BlitFramebufferFilter.Linear);
if (FramebufferSrgb)
{
GL.Enable(EnableCap.FramebufferSrgb);
}
} }
public void Copy( public void Copy(
@ -432,7 +447,9 @@ namespace Ryujinx.Graphics.Gal.OpenGL
return; return;
} }
if (NewImage.Format == OldImage.Format) if (NewImage.Format == OldImage.Format &&
NewImage.Width == OldImage.Width &&
NewImage.Height == OldImage.Height)
{ {
return; return;
} }
@ -444,7 +461,11 @@ namespace Ryujinx.Graphics.Gal.OpenGL
GL.BindBuffer(BufferTarget.PixelPackBuffer, CopyPBO); GL.BindBuffer(BufferTarget.PixelPackBuffer, CopyPBO);
GL.BufferData(BufferTarget.PixelPackBuffer, Math.Max(ImageUtils.GetSize(OldImage), ImageUtils.GetSize(NewImage)), IntPtr.Zero, BufferUsageHint.StreamCopy); //The buffer should be large enough to hold the largest texture.
int BufferSize = Math.Max(ImageUtils.GetSize(OldImage),
ImageUtils.GetSize(NewImage));
GL.BufferData(BufferTarget.PixelPackBuffer, BufferSize, IntPtr.Zero, BufferUsageHint.StreamCopy);
if (!Texture.TryGetImageHandler(Key, out ImageHandler CachedImage)) if (!Texture.TryGetImageHandler(Key, out ImageHandler CachedImage))
{ {
@ -460,8 +481,12 @@ namespace Ryujinx.Graphics.Gal.OpenGL
GL.BindBuffer(BufferTarget.PixelPackBuffer, 0); GL.BindBuffer(BufferTarget.PixelPackBuffer, 0);
GL.BindBuffer(BufferTarget.PixelUnpackBuffer, CopyPBO); GL.BindBuffer(BufferTarget.PixelUnpackBuffer, CopyPBO);
GL.PixelStore(PixelStoreParameter.UnpackRowLength, OldImage.Width);
Texture.Create(Key, ImageUtils.GetSize(NewImage), NewImage); Texture.Create(Key, ImageUtils.GetSize(NewImage), NewImage);
GL.PixelStore(PixelStoreParameter.UnpackRowLength, 0);
GL.BindBuffer(BufferTarget.PixelUnpackBuffer, 0); GL.BindBuffer(BufferTarget.PixelUnpackBuffer, 0);
} }

View file

@ -31,7 +31,11 @@ namespace Ryujinx.Graphics.Gal.OpenGL
Shader = new OGLShader(Buffer as OGLConstBuffer); Shader = new OGLShader(Buffer as OGLConstBuffer);
Pipeline = new OGLPipeline(Buffer as OGLConstBuffer, Rasterizer as OGLRasterizer, Shader as OGLShader); Pipeline = new OGLPipeline(
Buffer as OGLConstBuffer,
RenderTarget as OGLRenderTarget,
Rasterizer as OGLRasterizer,
Shader as OGLShader);
ActionsQueue = new ConcurrentQueue<Action>(); ActionsQueue = new ConcurrentQueue<Action>();
} }

View file

@ -1,3 +1,4 @@
using Ryujinx.Graphics.Gal.OpenGL;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@ -16,8 +17,6 @@ namespace Ryujinx.Graphics.Gal.Shader
public const int VertexIdAttr = 0x2fc; public const int VertexIdAttr = 0x2fc;
public const int FaceAttr = 0x3fc; public const int FaceAttr = 0x3fc;
public const int MaxUboSize = 1024;
public const int GlPositionVec4Index = 7; public const int GlPositionVec4Index = 7;
public const int PositionOutAttrLocation = 15; public const int PositionOutAttrLocation = 15;
@ -51,6 +50,8 @@ namespace Ryujinx.Graphics.Gal.Shader
public const string SsyStackName = "ssy_stack"; public const string SsyStackName = "ssy_stack";
public const string SsyCursorName = "ssy_cursor"; public const string SsyCursorName = "ssy_cursor";
public static int MaxUboSize => OGLLimit.MaxUboSize / 16;
private string[] StagePrefixes = new string[] { "vp", "tcp", "tep", "gp", "fp" }; private string[] StagePrefixes = new string[] { "vp", "tcp", "tep", "gp", "fp" };
private string StagePrefix; private string StagePrefix;
@ -98,8 +99,7 @@ namespace Ryujinx.Graphics.Gal.Shader
m_Preds = new Dictionary<int, ShaderDeclInfo>(); m_Preds = new Dictionary<int, ShaderDeclInfo>();
} }
public GlslDecl(ShaderIrBlock[] Blocks, GalShaderType ShaderType, ShaderHeader Header) public GlslDecl(ShaderIrBlock[] Blocks, GalShaderType ShaderType, ShaderHeader Header) : this(ShaderType)
: this(ShaderType)
{ {
StagePrefix = StagePrefixes[(int)ShaderType] + "_"; StagePrefix = StagePrefixes[(int)ShaderType] + "_";

View file

@ -61,8 +61,11 @@ namespace Ryujinx.Graphics
int DstBlitW = ReadRegister(NvGpuEngine2dReg.BlitDstW); int DstBlitW = ReadRegister(NvGpuEngine2dReg.BlitDstW);
int DstBlitH = ReadRegister(NvGpuEngine2dReg.BlitDstH); int DstBlitH = ReadRegister(NvGpuEngine2dReg.BlitDstH);
int SrcBlitX = ReadRegister(NvGpuEngine2dReg.BlitSrcXInt); long BlitDuDx = ReadRegisterFixed1_31_32(NvGpuEngine2dReg.BlitDuDxFract);
int SrcBlitY = ReadRegister(NvGpuEngine2dReg.BlitSrcYInt); long BlitDvDy = ReadRegisterFixed1_31_32(NvGpuEngine2dReg.BlitDvDyFract);
long SrcBlitX = ReadRegisterFixed1_31_32(NvGpuEngine2dReg.BlitSrcXFract);
long SrcBlitY = ReadRegisterFixed1_31_32(NvGpuEngine2dReg.BlitSrcYFract);
GalImageFormat SrcImgFormat = ImageUtils.ConvertSurface((GalSurfaceFormat)SrcFormat); GalImageFormat SrcImgFormat = ImageUtils.ConvertSurface((GalSurfaceFormat)SrcFormat);
GalImageFormat DstImgFormat = ImageUtils.ConvertSurface((GalSurfaceFormat)DstFormat); GalImageFormat DstImgFormat = ImageUtils.ConvertSurface((GalSurfaceFormat)DstFormat);
@ -99,13 +102,19 @@ namespace Ryujinx.Graphics
Gpu.ResourceManager.SendTexture(Vmm, SrcKey, SrcTexture); Gpu.ResourceManager.SendTexture(Vmm, SrcKey, SrcTexture);
Gpu.ResourceManager.SendTexture(Vmm, DstKey, DstTexture); Gpu.ResourceManager.SendTexture(Vmm, DstKey, DstTexture);
int SrcBlitX1 = (int)(SrcBlitX >> 32);
int SrcBlitY1 = (int)(SrcBlitY >> 32);
int SrcBlitX2 = (int)(SrcBlitX + DstBlitW * BlitDuDx >> 32);
int SrcBlitY2 = (int)(SrcBlitY + DstBlitH * BlitDvDy >> 32);
Gpu.Renderer.RenderTarget.Copy( Gpu.Renderer.RenderTarget.Copy(
SrcKey, SrcKey,
DstKey, DstKey,
SrcBlitX, SrcBlitX1,
SrcBlitY, SrcBlitY1,
SrcBlitX + DstBlitW, SrcBlitX2,
SrcBlitY + DstBlitH, SrcBlitY2,
DstBlitX, DstBlitX,
DstBlitY, DstBlitY,
DstBlitX + DstBlitW, DstBlitX + DstBlitW,
@ -121,8 +130,8 @@ namespace Ryujinx.Graphics
DstTexture, DstTexture,
SrcAddress, SrcAddress,
DstAddress, DstAddress,
SrcBlitX, SrcBlitX1,
SrcBlitY, SrcBlitY1,
DstBlitX, DstBlitX,
DstBlitY, DstBlitY,
DstBlitW, DstBlitW,
@ -150,6 +159,14 @@ namespace Ryujinx.Graphics
Registers[MethCall.Method] = MethCall.Argument; Registers[MethCall.Method] = MethCall.Argument;
} }
private long ReadRegisterFixed1_31_32(NvGpuEngine2dReg Reg)
{
long Low = (uint)ReadRegister(Reg + 0);
long High = (uint)ReadRegister(Reg + 1);
return Low | (High << 32);
}
private int ReadRegister(NvGpuEngine2dReg Reg) private int ReadRegister(NvGpuEngine2dReg Reg)
{ {
return Registers[(int)Reg]; return Registers[(int)Reg];