[client] egl: rework post process filters and add AMD FXR

This commit is contained in:
Geoffrey McRae 2021-08-10 13:08:54 +10:00
parent 3b751a2017
commit dc0b3a8d45
14 changed files with 2441 additions and 235 deletions

View File

@ -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(

View File

@ -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,

View File

@ -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);

View File

@ -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,

View 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

View File

@ -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;
}

View File

@ -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

View File

@ -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

File diff suppressed because it is too large Load Diff

View 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);
}

View 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;
}

View File

@ -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;
}

View File

@ -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);