aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Ryujinx.Graphics/Gal/OpenGL/OGLLimit.cs12
-rw-r--r--Ryujinx.Graphics/Gal/OpenGL/OGLPipeline.cs22
-rw-r--r--Ryujinx.Graphics/Gal/OpenGL/OGLRenderTarget.cs33
-rw-r--r--Ryujinx.Graphics/Gal/OpenGL/OGLRenderer.cs6
-rw-r--r--Ryujinx.Graphics/Gal/Shader/GlslDecl.cs8
-rw-r--r--Ryujinx.Graphics/NvGpuEngine2d.cs33
6 files changed, 90 insertions, 24 deletions
diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLLimit.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLLimit.cs
new file mode 100644
index 00000000..6c385bc4
--- /dev/null
+++ b/Ryujinx.Graphics/Gal/OpenGL/OGLLimit.cs
@@ -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;
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLPipeline.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLPipeline.cs
index ac12314c..eb7f958b 100644
--- a/Ryujinx.Graphics/Gal/OpenGL/OGLPipeline.cs
+++ b/Ryujinx.Graphics/Gal/OpenGL/OGLPipeline.cs
@@ -77,17 +77,23 @@ namespace Ryujinx.Graphics.Gal.OpenGL
private GalPipelineState Old;
- private OGLConstBuffer Buffer;
- private OGLRasterizer Rasterizer;
- private OGLShader Shader;
+ private OGLConstBuffer Buffer;
+ private OGLRenderTarget RenderTarget;
+ private OGLRasterizer Rasterizer;
+ private OGLShader Shader;
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.Rasterizer = Rasterizer;
- this.Shader = Shader;
+ this.Buffer = Buffer;
+ this.RenderTarget = RenderTarget;
+ this.Rasterizer = Rasterizer;
+ this.Shader = Shader;
//These values match OpenGL's defaults
Old = new GalPipelineState
@@ -144,6 +150,8 @@ namespace Ryujinx.Graphics.Gal.OpenGL
if (New.FramebufferSrgb != Old.FramebufferSrgb)
{
Enable(EnableCap.FramebufferSrgb, New.FramebufferSrgb);
+
+ RenderTarget.FramebufferSrgb = New.FramebufferSrgb;
}
if (New.FlipX != Old.FlipX || New.FlipY != Old.FlipY || New.Instance != Old.Instance)
diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLRenderTarget.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLRenderTarget.cs
index 8d04f1aa..ce5364e1 100644
--- a/Ryujinx.Graphics/Gal/OpenGL/OGLRenderTarget.cs
+++ b/Ryujinx.Graphics/Gal/OpenGL/OGLRenderTarget.cs
@@ -90,6 +90,8 @@ namespace Ryujinx.Graphics.Gal.OpenGL
private int CopyPBO;
+ public bool FramebufferSrgb { get; set; }
+
public OGLRenderTarget(OGLTexture Texture)
{
Attachments = new FrameBufferAttachments();
@@ -363,11 +365,24 @@ namespace Ryujinx.Graphics.Gal.OpenGL
GL.Clear(ClearBufferMask.ColorBufferBit);
+ GL.Disable(EnableCap.FramebufferSrgb);
+
GL.BlitFramebuffer(
- SrcX0, SrcY0, SrcX1, SrcY1,
- DstX0, DstY0, DstX1, DstY1,
+ SrcX0,
+ SrcY0,
+ SrcX1,
+ SrcY1,
+ DstX0,
+ DstY0,
+ DstX1,
+ DstY1,
ClearBufferMask.ColorBufferBit,
BlitFramebufferFilter.Linear);
+
+ if (FramebufferSrgb)
+ {
+ GL.Enable(EnableCap.FramebufferSrgb);
+ }
}
public void Copy(
@@ -432,7 +447,9 @@ namespace Ryujinx.Graphics.Gal.OpenGL
return;
}
- if (NewImage.Format == OldImage.Format)
+ if (NewImage.Format == OldImage.Format &&
+ NewImage.Width == OldImage.Width &&
+ NewImage.Height == OldImage.Height)
{
return;
}
@@ -444,7 +461,11 @@ namespace Ryujinx.Graphics.Gal.OpenGL
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))
{
@@ -460,8 +481,12 @@ namespace Ryujinx.Graphics.Gal.OpenGL
GL.BindBuffer(BufferTarget.PixelPackBuffer, 0);
GL.BindBuffer(BufferTarget.PixelUnpackBuffer, CopyPBO);
+ GL.PixelStore(PixelStoreParameter.UnpackRowLength, OldImage.Width);
+
Texture.Create(Key, ImageUtils.GetSize(NewImage), NewImage);
+ GL.PixelStore(PixelStoreParameter.UnpackRowLength, 0);
+
GL.BindBuffer(BufferTarget.PixelUnpackBuffer, 0);
}
diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLRenderer.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLRenderer.cs
index a23541f3..14fb9018 100644
--- a/Ryujinx.Graphics/Gal/OpenGL/OGLRenderer.cs
+++ b/Ryujinx.Graphics/Gal/OpenGL/OGLRenderer.cs
@@ -31,7 +31,11 @@ namespace Ryujinx.Graphics.Gal.OpenGL
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>();
}
diff --git a/Ryujinx.Graphics/Gal/Shader/GlslDecl.cs b/Ryujinx.Graphics/Gal/Shader/GlslDecl.cs
index c837632e..f1b63a8d 100644
--- a/Ryujinx.Graphics/Gal/Shader/GlslDecl.cs
+++ b/Ryujinx.Graphics/Gal/Shader/GlslDecl.cs
@@ -1,3 +1,4 @@
+using Ryujinx.Graphics.Gal.OpenGL;
using System;
using System.Collections.Generic;
@@ -16,8 +17,6 @@ namespace Ryujinx.Graphics.Gal.Shader
public const int VertexIdAttr = 0x2fc;
public const int FaceAttr = 0x3fc;
- public const int MaxUboSize = 1024;
-
public const int GlPositionVec4Index = 7;
public const int PositionOutAttrLocation = 15;
@@ -51,6 +50,8 @@ namespace Ryujinx.Graphics.Gal.Shader
public const string SsyStackName = "ssy_stack";
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 StagePrefix;
@@ -98,8 +99,7 @@ namespace Ryujinx.Graphics.Gal.Shader
m_Preds = new Dictionary<int, ShaderDeclInfo>();
}
- public GlslDecl(ShaderIrBlock[] Blocks, GalShaderType ShaderType, ShaderHeader Header)
- : this(ShaderType)
+ public GlslDecl(ShaderIrBlock[] Blocks, GalShaderType ShaderType, ShaderHeader Header) : this(ShaderType)
{
StagePrefix = StagePrefixes[(int)ShaderType] + "_";
diff --git a/Ryujinx.Graphics/NvGpuEngine2d.cs b/Ryujinx.Graphics/NvGpuEngine2d.cs
index f20f8d6e..43fbcedf 100644
--- a/Ryujinx.Graphics/NvGpuEngine2d.cs
+++ b/Ryujinx.Graphics/NvGpuEngine2d.cs
@@ -61,8 +61,11 @@ namespace Ryujinx.Graphics
int DstBlitW = ReadRegister(NvGpuEngine2dReg.BlitDstW);
int DstBlitH = ReadRegister(NvGpuEngine2dReg.BlitDstH);
- int SrcBlitX = ReadRegister(NvGpuEngine2dReg.BlitSrcXInt);
- int SrcBlitY = ReadRegister(NvGpuEngine2dReg.BlitSrcYInt);
+ long BlitDuDx = ReadRegisterFixed1_31_32(NvGpuEngine2dReg.BlitDuDxFract);
+ 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 DstImgFormat = ImageUtils.ConvertSurface((GalSurfaceFormat)DstFormat);
@@ -99,13 +102,19 @@ namespace Ryujinx.Graphics
Gpu.ResourceManager.SendTexture(Vmm, SrcKey, SrcTexture);
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(
SrcKey,
DstKey,
- SrcBlitX,
- SrcBlitY,
- SrcBlitX + DstBlitW,
- SrcBlitY + DstBlitH,
+ SrcBlitX1,
+ SrcBlitY1,
+ SrcBlitX2,
+ SrcBlitY2,
DstBlitX,
DstBlitY,
DstBlitX + DstBlitW,
@@ -121,8 +130,8 @@ namespace Ryujinx.Graphics
DstTexture,
SrcAddress,
DstAddress,
- SrcBlitX,
- SrcBlitY,
+ SrcBlitX1,
+ SrcBlitY1,
DstBlitX,
DstBlitY,
DstBlitW,
@@ -150,6 +159,14 @@ namespace Ryujinx.Graphics
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)
{
return Registers[(int)Reg];