mirror of
https://github.com/Ryujinx/Ryujinx.git
synced 2024-11-20 03:36:34 +00:00
[GPU] Fix frame buffer being upside down in some cases
This commit is contained in:
parent
47100ec8c1
commit
42ebfdff7f
9 changed files with 96 additions and 5 deletions
|
@ -1,8 +1,4 @@
|
||||||
using System;
|
namespace Ryujinx.Core
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace Ryujinx.Core
|
|
||||||
{
|
{
|
||||||
public enum LogClass
|
public enum LogClass
|
||||||
{
|
{
|
||||||
|
|
7
Ryujinx.Graphics/Gal/GalConsts.cs
Normal file
7
Ryujinx.Graphics/Gal/GalConsts.cs
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
namespace Ryujinx.Graphics.Gal
|
||||||
|
{
|
||||||
|
public static class GalConsts
|
||||||
|
{
|
||||||
|
public const string FlipUniformName = "flip";
|
||||||
|
}
|
||||||
|
}
|
|
@ -42,6 +42,8 @@ namespace Ryujinx.Graphics.Gal
|
||||||
|
|
||||||
void SetFrameBufferTransform(float SX, float SY, float Rotate, float TX, float TY);
|
void SetFrameBufferTransform(float SX, float SY, float Rotate, float TX, float TY);
|
||||||
|
|
||||||
|
void SetViewport(int X, int Y, int Width, int Height);
|
||||||
|
|
||||||
//Rasterizer
|
//Rasterizer
|
||||||
void ClearBuffers(int RtIndex, GalClearBufferFlags Flags);
|
void ClearBuffers(int RtIndex, GalClearBufferFlags Flags);
|
||||||
|
|
||||||
|
@ -62,6 +64,8 @@ namespace Ryujinx.Graphics.Gal
|
||||||
|
|
||||||
void SetUniform1(string UniformName, int Value);
|
void SetUniform1(string UniformName, int Value);
|
||||||
|
|
||||||
|
void SetUniform2F(string UniformName, float X, float Y);
|
||||||
|
|
||||||
void BindShader(long Tag);
|
void BindShader(long Tag);
|
||||||
|
|
||||||
void BindProgram();
|
void BindProgram();
|
||||||
|
|
|
@ -7,6 +7,22 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
||||||
{
|
{
|
||||||
class OGLFrameBuffer
|
class OGLFrameBuffer
|
||||||
{
|
{
|
||||||
|
private struct Rect
|
||||||
|
{
|
||||||
|
public int X { get; private set; }
|
||||||
|
public int Y { get; private set; }
|
||||||
|
public int Width { get; private set; }
|
||||||
|
public int Height { get; private set; }
|
||||||
|
|
||||||
|
public Rect(int X, int Y, int Width, int Height)
|
||||||
|
{
|
||||||
|
this.X = X;
|
||||||
|
this.Y = Y;
|
||||||
|
this.Width = Width;
|
||||||
|
this.Height = Height;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private class FrameBuffer
|
private class FrameBuffer
|
||||||
{
|
{
|
||||||
public int Width { get; set; }
|
public int Width { get; set; }
|
||||||
|
@ -38,6 +54,8 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
||||||
|
|
||||||
private ShaderProgram Shader;
|
private ShaderProgram Shader;
|
||||||
|
|
||||||
|
private Rect Viewport;
|
||||||
|
|
||||||
private bool IsInitialized;
|
private bool IsInitialized;
|
||||||
|
|
||||||
private int RawFbTexWidth;
|
private int RawFbTexWidth;
|
||||||
|
@ -178,6 +196,13 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
||||||
GL.UseProgram(CurrentProgram);
|
GL.UseProgram(CurrentProgram);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SetViewport(int X, int Y, int Width, int Height)
|
||||||
|
{
|
||||||
|
Viewport = new Rect(X, Y, Width, Height);
|
||||||
|
|
||||||
|
//TODO
|
||||||
|
}
|
||||||
|
|
||||||
public void Render()
|
public void Render()
|
||||||
{
|
{
|
||||||
if (CurrTexHandle != 0)
|
if (CurrTexHandle != 0)
|
||||||
|
@ -196,6 +221,8 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
||||||
|
|
||||||
GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0);
|
GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0);
|
||||||
|
|
||||||
|
GL.Viewport(0, 0, 1280, 720);
|
||||||
|
|
||||||
GL.Clear(
|
GL.Clear(
|
||||||
ClearBufferMask.ColorBufferBit |
|
ClearBufferMask.ColorBufferBit |
|
||||||
ClearBufferMask.DepthBufferBit);
|
ClearBufferMask.DepthBufferBit);
|
||||||
|
@ -218,6 +245,15 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void SetViewport()
|
||||||
|
{
|
||||||
|
GL.Viewport(
|
||||||
|
Viewport.X,
|
||||||
|
Viewport.Y,
|
||||||
|
Viewport.Width,
|
||||||
|
Viewport.Height);
|
||||||
|
}
|
||||||
|
|
||||||
private void EnsureInitialized()
|
private void EnsureInitialized()
|
||||||
{
|
{
|
||||||
if (!IsInitialized)
|
if (!IsInitialized)
|
||||||
|
|
|
@ -158,6 +158,15 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
||||||
GL.Uniform1(Location, Value);
|
GL.Uniform1(Location, Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SetUniform2F(string UniformName, float X, float Y)
|
||||||
|
{
|
||||||
|
BindProgram();
|
||||||
|
|
||||||
|
int Location = GL.GetUniformLocation(CurrentProgramHandle, UniformName);
|
||||||
|
|
||||||
|
GL.Uniform2(Location, X, Y);
|
||||||
|
}
|
||||||
|
|
||||||
public void Bind(long Tag)
|
public void Bind(long Tag)
|
||||||
{
|
{
|
||||||
if (Stages.TryGetValue(Tag, out ShaderStage Stage))
|
if (Stages.TryGetValue(Tag, out ShaderStage Stage))
|
||||||
|
|
|
@ -141,6 +141,11 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
||||||
ActionsQueue.Enqueue(() => FrameBuffer.SetTransform(Transform, Offs));
|
ActionsQueue.Enqueue(() => FrameBuffer.SetTransform(Transform, Offs));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SetViewport(int X, int Y, int Width, int Height)
|
||||||
|
{
|
||||||
|
ActionsQueue.Enqueue(() => FrameBuffer.SetViewport(X, Y, Width, Height));
|
||||||
|
}
|
||||||
|
|
||||||
public void ClearBuffers(int RtIndex, GalClearBufferFlags Flags)
|
public void ClearBuffers(int RtIndex, GalClearBufferFlags Flags)
|
||||||
{
|
{
|
||||||
ActionsQueue.Enqueue(() => Rasterizer.ClearBuffers(RtIndex, Flags));
|
ActionsQueue.Enqueue(() => Rasterizer.ClearBuffers(RtIndex, Flags));
|
||||||
|
@ -218,6 +223,16 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
||||||
ActionsQueue.Enqueue(() => Shader.SetUniform1(UniformName, Value));
|
ActionsQueue.Enqueue(() => Shader.SetUniform1(UniformName, Value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SetUniform2F(string UniformName, float X, float Y)
|
||||||
|
{
|
||||||
|
if (UniformName == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(UniformName));
|
||||||
|
}
|
||||||
|
|
||||||
|
ActionsQueue.Enqueue(() => Shader.SetUniform2F(UniformName, X, Y));
|
||||||
|
}
|
||||||
|
|
||||||
public IEnumerable<ShaderDeclInfo> GetTextureUsage(long Tag)
|
public IEnumerable<ShaderDeclInfo> GetTextureUsage(long Tag)
|
||||||
{
|
{
|
||||||
return Shader.GetTextureUsage(Tag);
|
return Shader.GetTextureUsage(Tag);
|
||||||
|
|
|
@ -115,6 +115,11 @@ namespace Ryujinx.Graphics.Gal.Shader
|
||||||
|
|
||||||
private void PrintDeclUniforms()
|
private void PrintDeclUniforms()
|
||||||
{
|
{
|
||||||
|
if (Decl.ShaderType == GalShaderType.Vertex)
|
||||||
|
{
|
||||||
|
SB.AppendLine("uniform vec2 " + GalConsts.FlipUniformName + ";");
|
||||||
|
}
|
||||||
|
|
||||||
foreach (ShaderDeclInfo DeclInfo in Decl.Uniforms.Values.OrderBy(DeclKeySelector))
|
foreach (ShaderDeclInfo DeclInfo in Decl.Uniforms.Values.OrderBy(DeclKeySelector))
|
||||||
{
|
{
|
||||||
SB.AppendLine($"uniform {GetDecl(DeclInfo)};");
|
SB.AppendLine($"uniform {GetDecl(DeclInfo)};");
|
||||||
|
@ -270,6 +275,8 @@ namespace Ryujinx.Graphics.Gal.Shader
|
||||||
//the shader ends here.
|
//the shader ends here.
|
||||||
if (Decl.ShaderType == GalShaderType.Vertex)
|
if (Decl.ShaderType == GalShaderType.Vertex)
|
||||||
{
|
{
|
||||||
|
SB.AppendLine(Identation + "gl_Position.xy *= flip;");
|
||||||
|
|
||||||
SB.AppendLine(Identation + GlslDecl.PositionOutAttrName + " = gl_Position;");
|
SB.AppendLine(Identation + GlslDecl.PositionOutAttrName + " = gl_Position;");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -147,6 +147,17 @@ namespace Ryujinx.Graphics.Gpu
|
||||||
Gpu.Renderer.BindShader(Tag);
|
Gpu.Renderer.BindShader(Tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int RawSX = ReadRegister(NvGpuEngine3dReg.ViewportScaleX);
|
||||||
|
int RawSY = ReadRegister(NvGpuEngine3dReg.ViewportScaleY);
|
||||||
|
|
||||||
|
float SX = BitConverter.Int32BitsToSingle(RawSX);
|
||||||
|
float SY = BitConverter.Int32BitsToSingle(RawSY);
|
||||||
|
|
||||||
|
float SignX = MathF.Sign(SX);
|
||||||
|
float SignY = MathF.Sign(SY);
|
||||||
|
|
||||||
|
Gpu.Renderer.SetUniform2F(GalConsts.FlipUniformName, SignX, SignY);
|
||||||
|
|
||||||
return Tags;
|
return Tags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,12 @@ namespace Ryujinx.Graphics.Gpu
|
||||||
FrameBufferNWidth = 0x202,
|
FrameBufferNWidth = 0x202,
|
||||||
FrameBufferNHeight = 0x203,
|
FrameBufferNHeight = 0x203,
|
||||||
FrameBufferNFormat = 0x204,
|
FrameBufferNFormat = 0x204,
|
||||||
|
ViewportScaleX = 0x280,
|
||||||
|
ViewportScaleY = 0x281,
|
||||||
|
ViewportScaleZ = 0x282,
|
||||||
|
ViewportTranslateX = 0x283,
|
||||||
|
ViewportTranslateY = 0x284,
|
||||||
|
ViewportTranslateZ = 0x285,
|
||||||
VertexAttribNFormat = 0x458,
|
VertexAttribNFormat = 0x458,
|
||||||
IBlendEnable = 0x4b9,
|
IBlendEnable = 0x4b9,
|
||||||
BlendSeparateAlpha = 0x4cf,
|
BlendSeparateAlpha = 0x4cf,
|
||||||
|
|
Loading…
Reference in a new issue