[GPU] Fix frame buffer being upside down in some cases

This commit is contained in:
gdkchan 2018-04-14 00:39:24 -03:00
parent 47100ec8c1
commit 42ebfdff7f
9 changed files with 96 additions and 5 deletions

View file

@ -1,8 +1,4 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Ryujinx.Core
namespace Ryujinx.Core
{
public enum LogClass
{

View file

@ -0,0 +1,7 @@
namespace Ryujinx.Graphics.Gal
{
public static class GalConsts
{
public const string FlipUniformName = "flip";
}
}

View file

@ -42,6 +42,8 @@ namespace Ryujinx.Graphics.Gal
void SetFrameBufferTransform(float SX, float SY, float Rotate, float TX, float TY);
void SetViewport(int X, int Y, int Width, int Height);
//Rasterizer
void ClearBuffers(int RtIndex, GalClearBufferFlags Flags);
@ -62,6 +64,8 @@ namespace Ryujinx.Graphics.Gal
void SetUniform1(string UniformName, int Value);
void SetUniform2F(string UniformName, float X, float Y);
void BindShader(long Tag);
void BindProgram();

View file

@ -7,6 +7,22 @@ namespace Ryujinx.Graphics.Gal.OpenGL
{
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
{
public int Width { get; set; }
@ -38,6 +54,8 @@ namespace Ryujinx.Graphics.Gal.OpenGL
private ShaderProgram Shader;
private Rect Viewport;
private bool IsInitialized;
private int RawFbTexWidth;
@ -178,6 +196,13 @@ namespace Ryujinx.Graphics.Gal.OpenGL
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()
{
if (CurrTexHandle != 0)
@ -196,6 +221,8 @@ namespace Ryujinx.Graphics.Gal.OpenGL
GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0);
GL.Viewport(0, 0, 1280, 720);
GL.Clear(
ClearBufferMask.ColorBufferBit |
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()
{
if (!IsInitialized)

View file

@ -158,6 +158,15 @@ namespace Ryujinx.Graphics.Gal.OpenGL
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)
{
if (Stages.TryGetValue(Tag, out ShaderStage Stage))

View file

@ -141,6 +141,11 @@ namespace Ryujinx.Graphics.Gal.OpenGL
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)
{
ActionsQueue.Enqueue(() => Rasterizer.ClearBuffers(RtIndex, Flags));
@ -218,6 +223,16 @@ namespace Ryujinx.Graphics.Gal.OpenGL
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)
{
return Shader.GetTextureUsage(Tag);

View file

@ -115,6 +115,11 @@ namespace Ryujinx.Graphics.Gal.Shader
private void PrintDeclUniforms()
{
if (Decl.ShaderType == GalShaderType.Vertex)
{
SB.AppendLine("uniform vec2 " + GalConsts.FlipUniformName + ";");
}
foreach (ShaderDeclInfo DeclInfo in Decl.Uniforms.Values.OrderBy(DeclKeySelector))
{
SB.AppendLine($"uniform {GetDecl(DeclInfo)};");
@ -270,6 +275,8 @@ namespace Ryujinx.Graphics.Gal.Shader
//the shader ends here.
if (Decl.ShaderType == GalShaderType.Vertex)
{
SB.AppendLine(Identation + "gl_Position.xy *= flip;");
SB.AppendLine(Identation + GlslDecl.PositionOutAttrName + " = gl_Position;");
}
}

View file

@ -147,6 +147,17 @@ namespace Ryujinx.Graphics.Gpu
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;
}

View file

@ -6,6 +6,12 @@ namespace Ryujinx.Graphics.Gpu
FrameBufferNWidth = 0x202,
FrameBufferNHeight = 0x203,
FrameBufferNFormat = 0x204,
ViewportScaleX = 0x280,
ViewportScaleY = 0x281,
ViewportScaleZ = 0x282,
ViewportTranslateX = 0x283,
ViewportTranslateY = 0x284,
ViewportTranslateZ = 0x285,
VertexAttribNFormat = 0x458,
IBlendEnable = 0x4b9,
BlendSeparateAlpha = 0x4cf,