mirror of
https://github.com/gnif/LookingGlass.git
synced 2024-12-23 05:53:40 +00:00
[client] egl: rework post process filters and add AMD FXR
This commit is contained in:
parent
3b751a2017
commit
dc0b3a8d45
@ -61,6 +61,8 @@ build_shaders(
|
||||
shader/splash_logo.frag
|
||||
shader/basic.vert
|
||||
shader/ffx_cas.frag
|
||||
shader/ffx_fsr1_easu.frag
|
||||
shader/ffx_fsr1_rcas.frag
|
||||
)
|
||||
|
||||
make_defines(
|
||||
|
@ -40,13 +40,15 @@
|
||||
|
||||
#include "basic.vert.h"
|
||||
#include "ffx_cas.frag.h"
|
||||
#include "ffx_fsr1_easu.frag.h"
|
||||
#include "ffx_fsr1_rcas.frag.h"
|
||||
|
||||
struct DesktopShader
|
||||
{
|
||||
EGL_Shader * shader;
|
||||
GLint uTransform;
|
||||
GLint uDesktopSize;
|
||||
GLint uTextureScale;
|
||||
GLint uTextureSize;
|
||||
GLint uScaleAlgo;
|
||||
GLint uNVGain;
|
||||
GLint uCBMode;
|
||||
@ -65,6 +67,7 @@ struct EGL_Desktop
|
||||
// internals
|
||||
int width, height;
|
||||
LG_RendererRotate rotate;
|
||||
bool upscale;
|
||||
|
||||
// scale algorithm
|
||||
int scaleAlgo;
|
||||
@ -79,10 +82,15 @@ struct EGL_Desktop
|
||||
bool useDMA;
|
||||
LG_RendererFormat format;
|
||||
|
||||
EGL_Shader * ffxFSR1[2];
|
||||
bool ffxFSR1Enable;
|
||||
PostProcessHandle ffxFSR1Handle[2];
|
||||
EGL_Uniform ffxFSR1Uniform;
|
||||
|
||||
EGL_Shader * ffxCAS;
|
||||
bool ffxCASEnable;
|
||||
PostProcessHandle ffxCASHandle;
|
||||
EGL_Uniform ffxUniform;
|
||||
EGL_Uniform ffxCASUniform;
|
||||
};
|
||||
|
||||
// forwards
|
||||
@ -104,20 +112,27 @@ static bool egl_initDesktopShader(
|
||||
return false;
|
||||
}
|
||||
|
||||
shader->uTransform = egl_shaderGetUniform(shader->shader, "transform" );
|
||||
shader->uDesktopSize = egl_shaderGetUniform(shader->shader, "size" );
|
||||
shader->uTextureScale = egl_shaderGetUniform(shader->shader, "textureScale");
|
||||
shader->uScaleAlgo = egl_shaderGetUniform(shader->shader, "scaleAlgo" );
|
||||
shader->uNVGain = egl_shaderGetUniform(shader->shader, "nvGain" );
|
||||
shader->uCBMode = egl_shaderGetUniform(shader->shader, "cbMode" );
|
||||
shader->uTransform = egl_shaderGetUniform(shader->shader, "transform" );
|
||||
shader->uDesktopSize = egl_shaderGetUniform(shader->shader, "desktopSize");
|
||||
shader->uTextureSize = egl_shaderGetUniform(shader->shader, "textureSize");
|
||||
shader->uScaleAlgo = egl_shaderGetUniform(shader->shader, "scaleAlgo" );
|
||||
shader->uNVGain = egl_shaderGetUniform(shader->shader, "nvGain" );
|
||||
shader->uCBMode = egl_shaderGetUniform(shader->shader, "cbMode" );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void setupFilters(EGL_Desktop * desktop)
|
||||
{
|
||||
desktop->ffxFSR1Handle[0] =
|
||||
egl_textureAddFilter(desktop->texture, desktop->ffxFSR1[0],
|
||||
desktop->ffxFSR1Enable);
|
||||
desktop->ffxFSR1Handle[1] =
|
||||
egl_textureAddFilter(desktop->texture, desktop->ffxFSR1[1],
|
||||
desktop->ffxFSR1Enable);
|
||||
|
||||
desktop->ffxCASHandle =
|
||||
egl_textureAddFilter(desktop->texture, desktop->ffxCAS, 1.0f,
|
||||
egl_textureAddFilter(desktop->texture, desktop->ffxCAS,
|
||||
desktop->ffxCASEnable);
|
||||
}
|
||||
|
||||
@ -173,18 +188,38 @@ bool egl_desktopInit(EGL * egl, EGL_Desktop ** desktop_, EGLDisplay * display,
|
||||
desktop->scaleAlgo = option_get_int("egl", "scale" );
|
||||
desktop->useDMA = useDMA;
|
||||
|
||||
// AMD FidelidyFX FSR
|
||||
egl_shaderInit(&desktop->ffxFSR1[0]);
|
||||
egl_shaderCompile(desktop->ffxFSR1[0],
|
||||
b_shader_basic_vert , b_shader_basic_vert_size,
|
||||
b_shader_ffx_fsr1_easu_frag, b_shader_ffx_fsr1_easu_frag_size);
|
||||
|
||||
egl_shaderInit(&desktop->ffxFSR1[1]);
|
||||
egl_shaderCompile(desktop->ffxFSR1[1],
|
||||
b_shader_basic_vert , b_shader_basic_vert_size,
|
||||
b_shader_ffx_fsr1_rcas_frag, b_shader_ffx_fsr1_rcas_frag_size);
|
||||
|
||||
desktop->ffxFSR1Enable = option_get_bool("eglFilter", "ffxFSR");
|
||||
desktop->ffxFSR1Uniform.type = EGL_UNIFORM_TYPE_1F;
|
||||
desktop->ffxFSR1Uniform.location =
|
||||
egl_shaderGetUniform(desktop->ffxFSR1[1], "uSharpness");
|
||||
desktop->ffxFSR1Uniform.f[0] =
|
||||
option_get_float("eglFilter", "ffxFSRSharpness");
|
||||
egl_shaderSetUniforms(desktop->ffxFSR1[1], &desktop->ffxFSR1Uniform, 1);
|
||||
|
||||
// AMD FidelidyFX CAS
|
||||
egl_shaderInit(&desktop->ffxCAS);
|
||||
egl_shaderCompile(desktop->ffxCAS,
|
||||
b_shader_basic_vert , b_shader_basic_vert_size,
|
||||
b_shader_ffx_cas_frag, b_shader_ffx_cas_frag_size);
|
||||
|
||||
desktop->ffxCASEnable = option_get_bool("eglFilter", "ffxCAS");
|
||||
desktop->ffxUniform.type = EGL_UNIFORM_TYPE_1F;
|
||||
desktop->ffxUniform.location =
|
||||
desktop->ffxCASUniform.type = EGL_UNIFORM_TYPE_1F;
|
||||
desktop->ffxCASUniform.location =
|
||||
egl_shaderGetUniform(desktop->ffxCAS, "uSharpness");
|
||||
desktop->ffxUniform.f[0] =
|
||||
desktop->ffxCASUniform.f[0] =
|
||||
option_get_float("eglFilter", "ffxCASSharpness");
|
||||
egl_shaderSetUniforms(desktop->ffxCAS, &desktop->ffxUniform, 1);
|
||||
egl_shaderSetUniforms(desktop->ffxCAS, &desktop->ffxCASUniform, 1);
|
||||
|
||||
setupFilters(desktop);
|
||||
|
||||
@ -222,6 +257,9 @@ void egl_desktopFree(EGL_Desktop ** desktop)
|
||||
egl_shaderFree (&(*desktop)->shader.shader);
|
||||
egl_desktopRectsFree(&(*desktop)->mesh );
|
||||
countedBufferRelease(&(*desktop)->matrix );
|
||||
|
||||
egl_shaderFree(&(*desktop)->ffxFSR1[0]);
|
||||
egl_shaderFree(&(*desktop)->ffxFSR1[1]);
|
||||
egl_shaderFree(&(*desktop)->ffxCAS);
|
||||
|
||||
free(*desktop);
|
||||
@ -266,25 +304,64 @@ void egl_desktopConfigUI(EGL_Desktop * desktop)
|
||||
igSliderInt("##nvgain", &desktop->nvGain, 0, desktop->nvMax, format, 0);
|
||||
igPopItemWidth();
|
||||
|
||||
bool invalidateCAS = false;
|
||||
bool invalidateTex = false;
|
||||
// AMD FidelityFX FSR
|
||||
bool fsr1 = desktop->ffxFSR1Enable;
|
||||
igCheckbox("AMD FidelityFX FSR", &fsr1);
|
||||
if (fsr1 != desktop->ffxFSR1Enable)
|
||||
{
|
||||
desktop->ffxFSR1Enable = fsr1;
|
||||
egl_textureEnableFilter(desktop->ffxFSR1Handle[0],
|
||||
fsr1 && desktop->upscale);
|
||||
egl_textureEnableFilter(desktop->ffxFSR1Handle[1],
|
||||
fsr1 && desktop->upscale);
|
||||
invalidateTex = true;
|
||||
}
|
||||
|
||||
float fsr1Sharpness = desktop->ffxFSR1Uniform.f[0];
|
||||
igText("Sharpness:");
|
||||
igSameLine(0.0f, -1.0f);
|
||||
igPushItemWidth(igGetWindowWidth() - igGetCursorPosX() -
|
||||
igGetStyle()->WindowPadding.x);
|
||||
igSliderFloat("##fsr1Sharpness", &fsr1Sharpness, 0.0f, 1.0f, NULL, 0);
|
||||
igPopItemWidth();
|
||||
|
||||
if (fsr1Sharpness != desktop->ffxFSR1Uniform.f[0])
|
||||
{
|
||||
// enable FSR1 if the sharpness was changed
|
||||
if (!fsr1)
|
||||
{
|
||||
fsr1 = true;
|
||||
desktop->ffxFSR1Enable = fsr1;
|
||||
egl_textureEnableFilter(desktop->ffxFSR1Handle[0],
|
||||
fsr1 && desktop->upscale);
|
||||
egl_textureEnableFilter(desktop->ffxFSR1Handle[1],
|
||||
fsr1 && desktop->upscale);
|
||||
}
|
||||
desktop->ffxFSR1Uniform.f[0] = fsr1Sharpness;
|
||||
egl_shaderSetUniforms(desktop->ffxFSR1[1], &desktop->ffxFSR1Uniform, 1);
|
||||
invalidateTex = true;
|
||||
}
|
||||
|
||||
// AMD FiedlityFX CAS
|
||||
bool cas = desktop->ffxCASEnable;
|
||||
igCheckbox("AMD FidelityFX CAS", &cas);
|
||||
if (cas != desktop->ffxCASEnable)
|
||||
{
|
||||
desktop->ffxCASEnable = cas;
|
||||
egl_textureEnableFilter(desktop->ffxCASHandle, cas);
|
||||
invalidateCAS = true;
|
||||
invalidateTex = true;
|
||||
}
|
||||
|
||||
float sharpness = desktop->ffxUniform.f[0];
|
||||
float casSharpness = desktop->ffxCASUniform.f[0];
|
||||
igText("Sharpness:");
|
||||
igSameLine(0.0f, -1.0f);
|
||||
igPushItemWidth(igGetWindowWidth() - igGetCursorPosX() -
|
||||
igGetStyle()->WindowPadding.x);
|
||||
igSliderFloat("##casSharpness", &sharpness, 0.0f, 1.0f, NULL, 0);
|
||||
igSliderFloat("##casSharpness", &casSharpness, 0.0f, 1.0f, NULL, 0);
|
||||
igPopItemWidth();
|
||||
|
||||
if (sharpness != desktop->ffxUniform.f[0])
|
||||
if (casSharpness != desktop->ffxCASUniform.f[0])
|
||||
{
|
||||
// enable CAS if the sharpness was changed
|
||||
if (!cas)
|
||||
@ -293,12 +370,12 @@ void egl_desktopConfigUI(EGL_Desktop * desktop)
|
||||
desktop->ffxCASEnable = cas;
|
||||
egl_textureEnableFilter(desktop->ffxCASHandle, cas);
|
||||
}
|
||||
desktop->ffxUniform.f[0] = sharpness;
|
||||
egl_shaderSetUniforms(desktop->ffxCAS, &desktop->ffxUniform, 1);
|
||||
invalidateCAS = true;
|
||||
desktop->ffxCASUniform.f[0] = casSharpness;
|
||||
egl_shaderSetUniforms(desktop->ffxCAS, &desktop->ffxCASUniform, 1);
|
||||
invalidateTex = true;
|
||||
}
|
||||
|
||||
if (invalidateCAS)
|
||||
if (invalidateTex)
|
||||
{
|
||||
egl_textureInvalidate(desktop->texture);
|
||||
app_invalidateWindow(true);
|
||||
@ -379,6 +456,29 @@ bool egl_desktop_update(EGL_Desktop * desktop, const FrameBuffer * frame, int dm
|
||||
return egl_textureUpdateFromFrame(desktop->texture, frame, damageRects, damageRectsCount);
|
||||
}
|
||||
|
||||
void egl_desktopResize(EGL_Desktop * desktop, int width, int height)
|
||||
{
|
||||
if (width > desktop->width && height > desktop->height)
|
||||
{
|
||||
desktop->upscale = true;
|
||||
if (desktop->ffxFSR1Enable)
|
||||
{
|
||||
egl_textureEnableFilter(desktop->ffxFSR1Handle[0], true);
|
||||
egl_textureEnableFilter(desktop->ffxFSR1Handle[1], true);
|
||||
}
|
||||
egl_textureSetFilterRes(desktop->ffxFSR1Handle[0], width, height);
|
||||
egl_textureSetFilterRes(desktop->ffxFSR1Handle[1], width, height);
|
||||
egl_textureSetFilterRes(desktop->ffxCASHandle , width, height);
|
||||
}
|
||||
else
|
||||
{
|
||||
desktop->upscale = false;
|
||||
egl_textureEnableFilter(desktop->ffxFSR1Handle[0], false);
|
||||
egl_textureEnableFilter(desktop->ffxFSR1Handle[1], false);
|
||||
egl_textureSetFilterRes(desktop->ffxCASHandle, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
bool egl_desktopRender(EGL_Desktop * desktop, const float x, const float y,
|
||||
const float scaleX, const float scaleY, enum EGL_DesktopScaleType scaleType,
|
||||
LG_RendererRotate rotate, const struct DamageRects * rects)
|
||||
@ -412,12 +512,14 @@ bool egl_desktopRender(EGL_Desktop * desktop, const float x, const float y,
|
||||
scaleAlgo = desktop->scaleAlgo;
|
||||
}
|
||||
|
||||
struct Rect finalSize;
|
||||
egl_textureBind(desktop->texture);
|
||||
egl_textureGetFinalSize(desktop->texture, &finalSize);
|
||||
|
||||
egl_desktopRectsMatrix((float *)desktop->matrix->data,
|
||||
desktop->width, desktop->height, x, y, scaleX, scaleY, rotate);
|
||||
egl_desktopRectsUpdate(desktop->mesh, rects, desktop->width, desktop->height);
|
||||
|
||||
egl_textureBind(desktop->texture);
|
||||
|
||||
const struct DesktopShader * shader = &desktop->shader;
|
||||
EGL_Uniform uniforms[] =
|
||||
{
|
||||
@ -432,9 +534,9 @@ bool egl_desktopRender(EGL_Desktop * desktop, const float x, const float y,
|
||||
.f = { desktop->width, desktop->height },
|
||||
},
|
||||
{
|
||||
.type = EGL_UNIFORM_TYPE_1F,
|
||||
.location = shader->uTextureScale,
|
||||
.f = { egl_textureGetScale(desktop->texture) },
|
||||
.type = EGL_UNIFORM_TYPE_2I,
|
||||
.location = shader->uTextureSize,
|
||||
.i = { finalSize.x, finalSize.y },
|
||||
},
|
||||
{
|
||||
.type = EGL_UNIFORM_TYPE_M3x2FV,
|
||||
|
@ -45,6 +45,7 @@ void egl_desktopConfigUI(EGL_Desktop * desktop);
|
||||
bool egl_desktopSetup (EGL_Desktop * desktop, const LG_RendererFormat format);
|
||||
bool egl_desktop_update(EGL_Desktop * desktop, const FrameBuffer * frame, int dmaFd,
|
||||
const FrameDamageRect * damageRects, int damageRectsCount);
|
||||
void egl_desktopResize(EGL_Desktop * desktop, int width, int height);
|
||||
bool egl_desktopRender(EGL_Desktop * desktop, const float x, const float y,
|
||||
const float scaleX, const float scaleY, enum EGL_DesktopScaleType scaleType,
|
||||
LG_RendererRotate rotate, const struct DamageRects * rects);
|
||||
|
@ -183,11 +183,25 @@ static struct Option egl_options[] =
|
||||
},
|
||||
|
||||
{
|
||||
.module = "eglFilter",
|
||||
.name = "ffxCAS",
|
||||
.description = "AMD FidelityFX CAS",
|
||||
.type = OPTION_TYPE_BOOL,
|
||||
.value.x_bool = false
|
||||
.module = "eglFilter",
|
||||
.name = "ffxFSR",
|
||||
.description = "AMD FidelityFX FSR",
|
||||
.type = OPTION_TYPE_BOOL,
|
||||
.value.x_bool = false
|
||||
},
|
||||
{
|
||||
.module = "eglFilter",
|
||||
.name = "ffxFSRSharpness",
|
||||
.description = "AMD FidelityFX FSR Sharpness",
|
||||
.type = OPTION_TYPE_FLOAT,
|
||||
.value.x_float = 1.0f
|
||||
},
|
||||
{
|
||||
.module = "eglFilter",
|
||||
.name = "ffxCAS",
|
||||
.description = "AMD FidelityFX CAS",
|
||||
.type = OPTION_TYPE_BOOL,
|
||||
.value.x_bool = false
|
||||
},
|
||||
{
|
||||
.module = "eglFilter",
|
||||
@ -466,6 +480,7 @@ static void egl_onResize(LG_Renderer * renderer, const int width, const int heig
|
||||
ImGui_ImplOpenGL3_NewFrame();
|
||||
|
||||
egl_damageResize(this->damage, this->translateX, this->translateY, this->scaleX, this->scaleY);
|
||||
egl_desktopResize(this->desktop, this->width, this->height);
|
||||
}
|
||||
|
||||
static bool egl_onMouseShape(LG_Renderer * renderer, const LG_RendererCursor cursor,
|
||||
|
32
client/renderers/EGL/shader/compat.h
Normal file
32
client/renderers/EGL/shader/compat.h
Normal file
@ -0,0 +1,32 @@
|
||||
#if __VERSION__ == 300
|
||||
vec4 textureGather(sampler2D tex, vec2 uv, int comp)
|
||||
{
|
||||
vec4 c0 = textureOffset(tex, uv, ivec2(0,1));
|
||||
vec4 c1 = textureOffset(tex, uv, ivec2(1,1));
|
||||
vec4 c2 = textureOffset(tex, uv, ivec2(1,0));
|
||||
vec4 c3 = textureOffset(tex, uv, ivec2(0,0));
|
||||
return vec4(c0[comp], c1[comp], c2[comp],c3[comp]);
|
||||
}
|
||||
#elif __VERSION__ < 300
|
||||
vec4 textureGather(sampler2D tex, vec2 uv, int comp)
|
||||
{
|
||||
vec4 c3 = texture2D(tex, uv);
|
||||
return vec4(c3[comp], c3[comp], c3[comp],c3[comp]);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if __VERSION__ < 310
|
||||
uint bitfieldExtract(uint val, int off, int size)
|
||||
{
|
||||
uint mask = uint((1 << size) - 1);
|
||||
return uint(val >> off) & mask;
|
||||
}
|
||||
|
||||
uint bitfieldInsert(uint a, uint b, int c, int d)
|
||||
{
|
||||
uint mask = ~(0xffffffffu << d) << c;
|
||||
mask = ~mask;
|
||||
a &= mask;
|
||||
return a | (b << c);
|
||||
}
|
||||
#endif
|
@ -3,11 +3,11 @@
|
||||
layout(location = 0) in vec2 vertex;
|
||||
out highp vec2 uv;
|
||||
|
||||
uniform highp vec2 size;
|
||||
uniform highp vec2 desktopSize;
|
||||
uniform mat3x2 transform;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = vec4(transform * vec3(vertex, 1.0), 0.0, 1.0);
|
||||
uv = vertex / size;
|
||||
uv = vertex / desktopSize;
|
||||
}
|
||||
|
@ -13,8 +13,7 @@ out highp vec4 color;
|
||||
uniform sampler2D sampler1;
|
||||
|
||||
uniform int scaleAlgo;
|
||||
uniform highp vec2 size;
|
||||
uniform highp float textureScale;
|
||||
uniform highp ivec2 textureSize;
|
||||
|
||||
uniform highp float nvGain;
|
||||
uniform int cbMode;
|
||||
@ -24,7 +23,7 @@ void main()
|
||||
switch (scaleAlgo)
|
||||
{
|
||||
case EGL_SCALE_NEAREST:
|
||||
color = texelFetch(sampler1, ivec2(uv * size * textureScale), 0);
|
||||
color = texelFetch(sampler1, ivec2(uv * vec2(textureSize)), 0);
|
||||
break;
|
||||
|
||||
case EGL_SCALE_LINEAR:
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,7 +1,8 @@
|
||||
#version 300 es
|
||||
|
||||
precision mediump float;
|
||||
|
||||
#include "compat.h"
|
||||
|
||||
in vec2 iFragCoord;
|
||||
out vec4 fragColor;
|
||||
|
||||
@ -10,22 +11,6 @@ uniform uvec2 uInRes[8];
|
||||
uniform uvec2 uOutRes;
|
||||
uniform float uSharpness;
|
||||
|
||||
// the following are not available until verion 400 or later
|
||||
// so we implement our own versions of them
|
||||
uint bitfieldExtract(uint val, int off, int size)
|
||||
{
|
||||
uint mask = uint((1 << size) - 1);
|
||||
return uint(val >> off) & mask;
|
||||
}
|
||||
|
||||
uint bitfieldInsert(uint a, uint b, int c, int d)
|
||||
{
|
||||
uint mask = ~(0xffffffffu << d) << c;
|
||||
mask = ~mask;
|
||||
a &= mask;
|
||||
return a | (b << c);
|
||||
}
|
||||
|
||||
#define A_GPU 1
|
||||
#define A_GLSL 1
|
||||
|
||||
|
1199
client/renderers/EGL/shader/ffx_fsr1.h
Normal file
1199
client/renderers/EGL/shader/ffx_fsr1.h
Normal file
File diff suppressed because it is too large
Load Diff
48
client/renderers/EGL/shader/ffx_fsr1_easu.frag
Normal file
48
client/renderers/EGL/shader/ffx_fsr1_easu.frag
Normal file
@ -0,0 +1,48 @@
|
||||
#version 300 es
|
||||
precision mediump float;
|
||||
|
||||
#include "compat.h"
|
||||
|
||||
in vec2 iFragCoord;
|
||||
out vec4 fragColor;
|
||||
|
||||
uniform sampler2D iChannel0;
|
||||
uniform uvec2 uInRes[8];
|
||||
uniform uvec2 uOutRes;
|
||||
|
||||
#define A_GPU 1
|
||||
#define A_GLSL 1
|
||||
#define A_FULL 1
|
||||
|
||||
#include "ffx_a.h"
|
||||
|
||||
#define FSR_EASU_F 1
|
||||
#define FSR_RCAS_F 1
|
||||
|
||||
AF4 FsrEasuRF(AF2 p){return AF4(textureGather(iChannel0, p, 0));}
|
||||
AF4 FsrEasuGF(AF2 p){return AF4(textureGather(iChannel0, p, 1));}
|
||||
AF4 FsrEasuBF(AF2 p){return AF4(textureGather(iChannel0, p, 2));}
|
||||
|
||||
#include "ffx_fsr1.h"
|
||||
|
||||
void main()
|
||||
{
|
||||
AU4 con0, con1, con2, con3;
|
||||
vec2 inRes = vec2(uInRes[0]);
|
||||
vec2 outRes = vec2(uOutRes);
|
||||
|
||||
FsrEasuCon(
|
||||
con0,
|
||||
con1,
|
||||
con2,
|
||||
con3,
|
||||
inRes.x , inRes.y,
|
||||
inRes.x , inRes.y,
|
||||
outRes.x, outRes.y
|
||||
);
|
||||
|
||||
vec3 color;
|
||||
uvec2 point = uvec2(iFragCoord * outRes);
|
||||
FsrEasuF(color, point, con0, con1, con2, con3);
|
||||
fragColor = vec4(color.xyz, 1);
|
||||
}
|
36
client/renderers/EGL/shader/ffx_fsr1_rcas.frag
Normal file
36
client/renderers/EGL/shader/ffx_fsr1_rcas.frag
Normal file
@ -0,0 +1,36 @@
|
||||
#version 300 es
|
||||
precision mediump float;
|
||||
|
||||
#include "compat.h"
|
||||
|
||||
in vec2 iFragCoord;
|
||||
out vec4 fragColor;
|
||||
|
||||
uniform sampler2D iChannel0;
|
||||
uniform uvec2 uInRes[8];
|
||||
uniform float uSharpness;
|
||||
|
||||
#define A_GPU 1
|
||||
#define A_GLSL 1
|
||||
#define A_FULL 1
|
||||
|
||||
#include "ffx_a.h"
|
||||
|
||||
AF4 FsrRcasLoadF(ASU2 p) { return texelFetch(iChannel0, ASU2(p), 0); }
|
||||
void FsrRcasInputF(inout AF1 r, inout AF1 g, inout AF1 b) {}
|
||||
|
||||
#define FSR_RCAS_F 1
|
||||
#define FSR_RCAS_DENOISE 1
|
||||
#include "ffx_fsr1.h"
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 inRes = vec2(uInRes[0]);
|
||||
uvec2 point = uvec2(iFragCoord * inRes);
|
||||
|
||||
uvec4 const0;
|
||||
FsrRcasCon(const0, 1.0f - uSharpness);
|
||||
|
||||
FsrRcasF(fragColor.r, fragColor.g, fragColor.b, point, const0);
|
||||
fragColor.a = 1.0f;
|
||||
}
|
@ -42,10 +42,10 @@ typedef struct RenderStep
|
||||
EGL_Texture *owner;
|
||||
|
||||
bool enabled;
|
||||
bool ready;
|
||||
GLuint fb;
|
||||
GLuint tex;
|
||||
EGL_Shader * shader;
|
||||
float scale;
|
||||
|
||||
unsigned int width, height;
|
||||
|
||||
@ -92,8 +92,6 @@ bool egl_textureInit(EGL * egl, EGL_Texture ** texture_,
|
||||
glSamplerParameteri(this->sampler, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glSamplerParameteri(this->sampler, GL_TEXTURE_WRAP_S , GL_CLAMP_TO_EDGE);
|
||||
glSamplerParameteri(this->sampler, GL_TEXTURE_WRAP_T , GL_CLAMP_TO_EDGE);
|
||||
|
||||
this->scale = 1.0f;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -126,15 +124,15 @@ void egl_textureFree(EGL_Texture ** tex)
|
||||
|
||||
bool setupRenderStep(EGL_Texture * this, RenderStep * step)
|
||||
{
|
||||
step->width = this->format.width * step->scale;
|
||||
step->height = this->format.height * step->scale;
|
||||
if (step->ready && (step->width > 0 || step->height > 0))
|
||||
return true;
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, step->tex);
|
||||
glTexImage2D(GL_TEXTURE_2D,
|
||||
0,
|
||||
this->format.intFormat,
|
||||
step->width,
|
||||
step->height,
|
||||
step->width > 0 ? step->width : this->format.width,
|
||||
step->height > 0 ? step->height : this->format.height,
|
||||
0,
|
||||
this->format.format,
|
||||
this->format.dataType,
|
||||
@ -143,6 +141,7 @@ bool setupRenderStep(EGL_Texture * this, RenderStep * step)
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
step->ready = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -168,8 +167,7 @@ bool egl_textureSetup(EGL_Texture * this, enum EGL_PixelFormat pixFmt,
|
||||
{
|
||||
RenderStep * step;
|
||||
for(ll_reset(this->render); ll_walk(this->render, (void **)&step); )
|
||||
if (!setupRenderStep(this, step))
|
||||
return false;
|
||||
step->ready = false;
|
||||
}
|
||||
|
||||
return this->ops.setup(this, &setup);
|
||||
@ -309,9 +307,25 @@ enum EGL_TexStatus egl_textureBind(EGL_Texture * this)
|
||||
{
|
||||
ringbuffer_reset(this->textures);
|
||||
|
||||
/* configure all the filters */
|
||||
for(ll_reset(this->render); ll_walk(this->render, (void **)&step); )
|
||||
{
|
||||
if (!step->enabled)
|
||||
continue;
|
||||
|
||||
if (!step->ready)
|
||||
setupRenderStep(this, step);
|
||||
}
|
||||
|
||||
if ((status = this->ops.get(this, &tex)) != EGL_TEX_STATUS_OK)
|
||||
return status;
|
||||
|
||||
struct Rect finalSz =
|
||||
{
|
||||
.x = this->format.width,
|
||||
.y = this->format.height
|
||||
};
|
||||
|
||||
ringbuffer_push(this->textures, &(BindInfo) {
|
||||
.tex = tex,
|
||||
.width = this->format.width,
|
||||
@ -346,7 +360,13 @@ enum EGL_TexStatus egl_textureBind(EGL_Texture * this)
|
||||
else
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, step->fb);
|
||||
|
||||
glViewport(0, 0, step->width, step->height);
|
||||
const struct Rect sz =
|
||||
{
|
||||
.x = step->width > 0 ? step->width : this->format.width,
|
||||
.y = step->height > 0 ? step->height : this->format.height
|
||||
};
|
||||
|
||||
glViewport(0, 0, sz.x, sz.y);
|
||||
|
||||
/* use the shader (also configures it's set uniforms) */
|
||||
egl_shaderUse(step->shader);
|
||||
@ -354,16 +374,18 @@ enum EGL_TexStatus egl_textureBind(EGL_Texture * this)
|
||||
/* set the size uniforms */
|
||||
glUniform2uiv(step->uInRes,
|
||||
ringbuffer_getCount(this->textures), bd->dimensions);
|
||||
glUniform2ui(step->uOutRes, step->width, step->height);
|
||||
glUniform2ui(step->uOutRes, sz.x, sz.y);
|
||||
|
||||
/* render the scene */
|
||||
egl_modelRender(this->model);
|
||||
finalSz.x = sz.x;
|
||||
finalSz.y = sz.y;
|
||||
|
||||
/* push the details into the ringbuffer for the next pass */
|
||||
ringbuffer_push(this->textures, &(BindInfo) {
|
||||
.tex = step->tex,
|
||||
.width = step->width,
|
||||
.height = step->height
|
||||
.width = sz.x,
|
||||
.height = sz.y
|
||||
});
|
||||
|
||||
/* bind the textures for the next pass */
|
||||
@ -378,6 +400,8 @@ enum EGL_TexStatus egl_textureBind(EGL_Texture * this)
|
||||
egl_resetViewport(this->egl);
|
||||
}
|
||||
|
||||
this->finalWidth = finalSz.x;
|
||||
this->finalHeight = finalSz.y;
|
||||
this->postProcessed = true;
|
||||
}
|
||||
else
|
||||
@ -393,7 +417,7 @@ enum EGL_TexStatus egl_textureBind(EGL_Texture * this)
|
||||
}
|
||||
|
||||
PostProcessHandle egl_textureAddFilter(EGL_Texture * this, EGL_Shader * shader,
|
||||
float outputScale, bool enabled)
|
||||
bool enabled)
|
||||
{
|
||||
if (!this->render)
|
||||
{
|
||||
@ -407,21 +431,10 @@ PostProcessHandle egl_textureAddFilter(EGL_Texture * this, EGL_Shader * shader,
|
||||
glGenTextures(1, &step->tex);
|
||||
step->owner = this;
|
||||
step->shader = shader;
|
||||
step->scale = outputScale;
|
||||
step->uInRes = egl_shaderGetUniform(shader, "uInRes" );
|
||||
step->uOutRes = egl_shaderGetUniform(shader, "uOutRes");
|
||||
step->enabled = enabled;
|
||||
|
||||
this->scale = outputScale;
|
||||
|
||||
if (this->formatValid)
|
||||
if (!setupRenderStep(this, step))
|
||||
{
|
||||
glDeleteTextures(1, &step->tex);
|
||||
free(step);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ll_push(this->render, step);
|
||||
return (PostProcessHandle)step;
|
||||
}
|
||||
@ -436,12 +449,33 @@ void egl_textureEnableFilter(PostProcessHandle * handle, bool enable)
|
||||
egl_textureInvalidate(step->owner);
|
||||
}
|
||||
|
||||
void egl_textureSetFilterRes(PostProcessHandle * handle,
|
||||
unsigned int x, unsigned int y)
|
||||
{
|
||||
RenderStep * step = (RenderStep *)handle;
|
||||
if (step->width == x && step->height == y)
|
||||
return;
|
||||
|
||||
step->width = x;
|
||||
step->height = y;
|
||||
step->ready = false;
|
||||
egl_textureInvalidate(step->owner);
|
||||
}
|
||||
|
||||
void egl_textureInvalidate(EGL_Texture * texture)
|
||||
{
|
||||
texture->postProcessed = false;
|
||||
}
|
||||
|
||||
float egl_textureGetScale(EGL_Texture * this)
|
||||
void egl_textureGetFinalSize(EGL_Texture * this, struct Rect * rect)
|
||||
{
|
||||
return this->scale;
|
||||
if (!this->render)
|
||||
{
|
||||
rect->x = this->format.width;
|
||||
rect->y = this->format.height;
|
||||
return;
|
||||
}
|
||||
|
||||
rect->x = this->finalWidth;
|
||||
rect->y = this->finalHeight;
|
||||
}
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "model.h"
|
||||
#include "common/framebuffer.h"
|
||||
#include "common/ringbuffer.h"
|
||||
#include "common/types.h"
|
||||
|
||||
#include "util.h"
|
||||
#include "ll.h"
|
||||
@ -144,7 +145,7 @@ struct EGL_Texture
|
||||
_Atomic(bool) updated;
|
||||
bool postProcessed;
|
||||
EGL_Model * model;
|
||||
float scale;
|
||||
unsigned int finalWidth, finalHeight;
|
||||
|
||||
void * bindData;
|
||||
int bindDataSize;
|
||||
@ -172,10 +173,13 @@ enum EGL_TexStatus egl_textureBind(EGL_Texture * texture);
|
||||
|
||||
typedef void * PostProcessHandle;
|
||||
PostProcessHandle egl_textureAddFilter(EGL_Texture * texture,
|
||||
EGL_Shader * shader, float outputScale, bool enabled);
|
||||
EGL_Shader * shader, bool enabled);
|
||||
|
||||
void egl_textureEnableFilter(PostProcessHandle * handle, bool enable);
|
||||
|
||||
void egl_textureSetFilterRes(PostProcessHandle * handle,
|
||||
unsigned int x, unsigned int y);
|
||||
|
||||
void egl_textureInvalidate(EGL_Texture * texture);
|
||||
|
||||
float egl_textureGetScale(EGL_Texture * texture);
|
||||
void egl_textureGetFinalSize(EGL_Texture * texture, struct Rect * rect);
|
||||
|
Loading…
Reference in New Issue
Block a user