Enable hardware frame buffer texture scaling

This commit is contained in:
gdkchan 2018-02-28 23:37:40 -03:00
parent eacd432387
commit 5d8a615c21
5 changed files with 75 additions and 12 deletions

View file

@ -35,12 +35,22 @@ namespace Ryujinx.Core.OsHle.IpcServices.Android
Acquired Acquired
} }
private struct Rect
{
public int Top;
public int Left;
public int Right;
public int Bottom;
}
private struct BufferEntry private struct BufferEntry
{ {
public BufferState State; public BufferState State;
public HalTransform Transform; public HalTransform Transform;
public Rect Crop;
public GbpBuffer Data; public GbpBuffer Data;
} }
@ -168,6 +178,11 @@ namespace Ryujinx.Core.OsHle.IpcServices.Android
BufferQueue[Slot].Transform = (HalTransform)Transform; BufferQueue[Slot].Transform = (HalTransform)Transform;
BufferQueue[Slot].Crop.Top = CropTop;
BufferQueue[Slot].Crop.Left = CropLeft;
BufferQueue[Slot].Crop.Right = CropRight;
BufferQueue[Slot].Crop.Bottom = CropBottom;
BufferQueue[Slot].State = BufferState.Queued; BufferQueue[Slot].State = BufferState.Queued;
SendFrameBuffer(Context, Slot); SendFrameBuffer(Context, Slot);
@ -258,18 +273,42 @@ namespace Ryujinx.Core.OsHle.IpcServices.Android
BufferQueue[Slot].State = BufferState.Acquired; BufferQueue[Slot].State = BufferState.Acquired;
Rect Crop = BufferQueue[Slot].Crop;
int RealWidth = FbWidth;
int RealHeight = FbHeight;
float ScaleX = 1; float ScaleX = 1;
float ScaleY = 1; float ScaleY = 1;
float OffsX = 0;
float OffsY = 0;
if (Crop.Right != 0 &&
Crop.Bottom != 0)
{
RealWidth = Crop.Right - Crop.Left;
RealHeight = Crop.Bottom - Crop.Top;
ScaleX = (float)FbWidth / RealWidth;
ScaleY = (float)FbHeight / RealHeight;
OffsX = -(float)Crop.Left / Crop.Right;
OffsY = -(float)Crop.Top / Crop.Bottom;
OffsX += ScaleX - 1;
OffsY += ScaleY - 1;
}
float Rotate = 0; float Rotate = 0;
if (BufferQueue[Slot].Transform.HasFlag(HalTransform.FlipX)) if (BufferQueue[Slot].Transform.HasFlag(HalTransform.FlipX))
{ {
ScaleX = -1; ScaleX = -ScaleX;
} }
if (BufferQueue[Slot].Transform.HasFlag(HalTransform.FlipY)) if (BufferQueue[Slot].Transform.HasFlag(HalTransform.FlipY))
{ {
ScaleY = -1; ScaleY = -ScaleY;
} }
if (BufferQueue[Slot].Transform.HasFlag(HalTransform.Rotate90)) if (BufferQueue[Slot].Transform.HasFlag(HalTransform.Rotate90))
@ -287,6 +326,8 @@ namespace Ryujinx.Core.OsHle.IpcServices.Android
FbHeight, FbHeight,
ScaleX, ScaleX,
ScaleY, ScaleY,
OffsX,
OffsY,
Rotate); Rotate);
BufferQueue[Slot].State = BufferState.Free; BufferQueue[Slot].State = BufferState.Free;

View file

@ -10,9 +10,20 @@ namespace Ryujinx.Graphics.Gal
void InitializeFrameBuffer(); void InitializeFrameBuffer();
void Render(); void Render();
void SetWindowSize(int Width, int Height); void SetWindowSize(int Width, int Height);
void SetFrameBuffer(byte* Fb, int Width, int Height, float SX, float SY, float R); void SetFrameBuffer(
byte* Fb,
int Width,
int Height,
float ScaleX,
float ScaleY,
float OffsX,
float OffsY,
float Rotate);
void SendVertexBuffer(int Index, byte[] Buffer, int Stride, GalVertexAttrib[] Attribs); void SendVertexBuffer(int Index, byte[] Buffer, int Stride, GalVertexAttrib[] Attribs);
void SendR8G8B8A8Texture(int Index, byte[] Buffer, int Width, int Height); void SendR8G8B8A8Texture(int Index, byte[] Buffer, int Width, int Height);
void BindTexture(int Index); void BindTexture(int Index);
} }
} }

View file

@ -2,8 +2,9 @@
precision highp float; precision highp float;
uniform vec2 window_size;
uniform mat2 transform; uniform mat2 transform;
uniform vec2 window_size;
uniform vec2 offset;
layout(location = 0) in vec2 in_position; layout(location = 0) in vec2 in_position;
layout(location = 1) in vec2 in_tex_coord; layout(location = 1) in vec2 in_tex_coord;
@ -22,5 +23,6 @@ vec2 get_scale_ratio(void) {
void main(void) { void main(void) {
tex_coord = in_tex_coord; tex_coord = in_tex_coord;
gl_Position = vec4((transform * in_position) * get_scale_ratio(), 0, 1); vec2 t_pos = (transform * in_position) + offset;
gl_Position = vec4(t_pos * get_scale_ratio(), 0, 1);
} }

View file

@ -135,7 +135,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL
GL.BindVertexArray(0); GL.BindVertexArray(0);
} }
public unsafe void Set(byte* Fb, int Width, int Height, Matrix2 Transform) public unsafe void Set(byte* Fb, int Width, int Height, Matrix2 Transform, Vector2 Offs)
{ {
if (Fb == null) if (Fb == null)
{ {
@ -172,6 +172,10 @@ namespace Ryujinx.Graphics.Gal.OpenGL
int WindowSizeUniformLocation = GL.GetUniformLocation(PrgShaderHandle, "window_size"); int WindowSizeUniformLocation = GL.GetUniformLocation(PrgShaderHandle, "window_size");
GL.Uniform2(WindowSizeUniformLocation, new Vector2(WindowWidth, WindowHeight)); GL.Uniform2(WindowSizeUniformLocation, new Vector2(WindowWidth, WindowHeight));
int OffsetUniformLocation = GL.GetUniformLocation(PrgShaderHandle, "offset");
GL.Uniform2(OffsetUniformLocation, Offs);
} }
public void Render() public void Render()

View file

@ -1,6 +1,7 @@
using OpenTK; using OpenTK;
using OpenTK.Graphics.OpenGL; using OpenTK.Graphics.OpenGL;
using System; using System;
using System.Collections.Concurrent;
using System.Collections.Generic; using System.Collections.Generic;
namespace Ryujinx.Graphics.Gal.OpenGL namespace Ryujinx.Graphics.Gal.OpenGL
@ -24,7 +25,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL
private Texture[] Textures; private Texture[] Textures;
private Queue<Action> ActionsQueue; private ConcurrentQueue<Action> ActionsQueue;
private FrameBuffer FbRenderer; private FrameBuffer FbRenderer;
@ -34,7 +35,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL
Textures = new Texture[8]; Textures = new Texture[8];
ActionsQueue = new Queue<Action>(); ActionsQueue = new ConcurrentQueue<Action>();
} }
public void InitializeFrameBuffer() public void InitializeFrameBuffer()
@ -51,9 +52,9 @@ namespace Ryujinx.Graphics.Gal.OpenGL
{ {
int Count = ActionsQueue.Count; int Count = ActionsQueue.Count;
while (Count-- > 0) while (Count-- > 0 && ActionsQueue.TryDequeue(out Action RenderAction))
{ {
ActionsQueue.Dequeue()(); RenderAction();
} }
} }
@ -86,6 +87,8 @@ namespace Ryujinx.Graphics.Gal.OpenGL
int Height, int Height,
float ScaleX, float ScaleX,
float ScaleY, float ScaleY,
float OffsX,
float OffsY,
float Rotate) float Rotate)
{ {
Matrix2 Transform; Matrix2 Transform;
@ -93,7 +96,9 @@ namespace Ryujinx.Graphics.Gal.OpenGL
Transform = Matrix2.CreateScale(ScaleX, ScaleY); Transform = Matrix2.CreateScale(ScaleX, ScaleY);
Transform *= Matrix2.CreateRotation(Rotate); Transform *= Matrix2.CreateRotation(Rotate);
FbRenderer.Set(Fb, Width, Height, Transform); Vector2 Offs = new Vector2(OffsX, OffsY);
FbRenderer.Set(Fb, Width, Height, Transform, Offs);
} }
public void SendVertexBuffer(int Index, byte[] Buffer, int Stride, GalVertexAttrib[] Attribs) public void SendVertexBuffer(int Index, byte[] Buffer, int Stride, GalVertexAttrib[] Attribs)