Enable hardware frame buffer texture scaling
This commit is contained in:
parent
eacd432387
commit
5d8a615c21
5 changed files with 75 additions and 12 deletions
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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);
|
||||||
}
|
}
|
|
@ -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()
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Reference in a new issue