mirror of
https://github.com/gnif/LookingGlass.git
synced 2024-12-22 22:01:46 +00:00
[client] egl: add ffx_cas post process filter
This commit is contained in:
parent
9b1d03fcfe
commit
92de467edc
9 changed files with 3499 additions and 12 deletions
|
@ -52,6 +52,8 @@ build_shaders(
|
|||
shader/splash_bg.frag
|
||||
shader/splash_logo.vert
|
||||
shader/splash_logo.frag
|
||||
shader/basic.vert
|
||||
shader/ffx_cas.frag
|
||||
)
|
||||
|
||||
make_defines(
|
||||
|
|
|
@ -38,6 +38,9 @@
|
|||
#include "desktop_rgb.frag.h"
|
||||
#include "desktop_rgb.def.h"
|
||||
|
||||
#include "basic.vert.h"
|
||||
#include "ffx_cas.frag.h"
|
||||
|
||||
struct DesktopShader
|
||||
{
|
||||
EGL_Shader * shader;
|
||||
|
@ -75,6 +78,10 @@ struct EGL_Desktop
|
|||
|
||||
bool useDMA;
|
||||
LG_RendererFormat format;
|
||||
|
||||
EGL_Shader * ffxCAS;
|
||||
bool enableCAS;
|
||||
PostProcessHandle ffxCASHandle;
|
||||
};
|
||||
|
||||
// forwards
|
||||
|
@ -106,6 +113,12 @@ static bool egl_initDesktopShader(
|
|||
return true;
|
||||
}
|
||||
|
||||
static void setupFilters(EGL_Desktop * desktop)
|
||||
{
|
||||
desktop->ffxCASHandle =
|
||||
egl_textureAddFilter(desktop->texture, desktop->ffxCAS, 1.0f, false);
|
||||
}
|
||||
|
||||
bool egl_desktopInit(EGL * egl, EGL_Desktop ** desktop, EGLDisplay * display,
|
||||
bool useDMA, int maxRects)
|
||||
{
|
||||
|
@ -156,6 +169,13 @@ bool egl_desktopInit(EGL * egl, EGL_Desktop ** desktop, EGLDisplay * display,
|
|||
(*desktop)->scaleAlgo = option_get_int("egl", "scale" );
|
||||
(*desktop)->useDMA = useDMA;
|
||||
|
||||
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);
|
||||
|
||||
setupFilters(*desktop);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -190,6 +210,7 @@ void egl_desktopFree(EGL_Desktop ** desktop)
|
|||
egl_shaderFree (&(*desktop)->shader.shader);
|
||||
egl_desktopRectsFree(&(*desktop)->mesh );
|
||||
countedBufferRelease(&(*desktop)->matrix );
|
||||
egl_shaderFree(&(*desktop)->ffxCAS);
|
||||
|
||||
free(*desktop);
|
||||
*desktop = NULL;
|
||||
|
@ -232,6 +253,14 @@ void egl_desktopConfigUI(EGL_Desktop * desktop)
|
|||
}
|
||||
igSliderInt("##nvgain", &desktop->nvGain, 0, desktop->nvMax, format, 0);
|
||||
igPopItemWidth();
|
||||
|
||||
bool cas = desktop->enableCAS;
|
||||
igCheckbox("AMD FidelityFX CAS", &cas);
|
||||
if (cas != desktop->enableCAS)
|
||||
{
|
||||
desktop->enableCAS = cas;
|
||||
egl_textureEnableFilter(desktop->ffxCASHandle, cas);
|
||||
}
|
||||
}
|
||||
|
||||
bool egl_desktopSetup(EGL_Desktop * desktop, const LG_RendererFormat format)
|
||||
|
@ -299,6 +328,8 @@ bool egl_desktop_update(EGL_Desktop * desktop, const FrameBuffer * frame, int dm
|
|||
return false;
|
||||
}
|
||||
|
||||
setupFilters(desktop);
|
||||
|
||||
if (!egl_desktopSetup(desktop, desktop->format))
|
||||
return false;
|
||||
}
|
||||
|
|
1907
client/renderers/EGL/shader/ffx_a.h
Normal file
1907
client/renderers/EGL/shader/ffx_a.h
Normal file
File diff suppressed because it is too large
Load diff
68
client/renderers/EGL/shader/ffx_cas.frag
Normal file
68
client/renderers/EGL/shader/ffx_cas.frag
Normal file
|
@ -0,0 +1,68 @@
|
|||
#version 300 es
|
||||
|
||||
precision mediump float;
|
||||
|
||||
in vec2 iFragCoord;
|
||||
out vec4 fragColor;
|
||||
|
||||
uniform sampler2D iChannel0;
|
||||
uniform uvec2 uInRes[8];
|
||||
uniform uvec2 uOutRes;
|
||||
|
||||
// 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
|
||||
|
||||
#include "ffx_a.h"
|
||||
|
||||
vec3 imageLoad(ivec2 point)
|
||||
{
|
||||
return texelFetch(iChannel0, point, 0).rgb;
|
||||
}
|
||||
|
||||
AF3 CasLoad(ASU2 p)
|
||||
{
|
||||
return imageLoad(p).rgb;
|
||||
}
|
||||
|
||||
void CasInput(inout AF1 r,inout AF1 g,inout AF1 b) {}
|
||||
|
||||
#include "ffx_cas.h"
|
||||
|
||||
void main()
|
||||
{
|
||||
uvec2 point = uvec2(iFragCoord * vec2(uInRes[0].xy));
|
||||
|
||||
vec4 color;
|
||||
vec2 inputResolution = vec2(uInRes[0]);
|
||||
vec2 outputResolution = vec2(uOutRes);
|
||||
float sharpnessTuning = 1.0f;
|
||||
|
||||
uvec4 const0;
|
||||
uvec4 const1;
|
||||
|
||||
CasSetup(const0, const1, sharpnessTuning,
|
||||
inputResolution.x, inputResolution.y,
|
||||
outputResolution.x, outputResolution.y);
|
||||
|
||||
CasFilter(
|
||||
fragColor.r, fragColor.g, fragColor.b,
|
||||
point,
|
||||
const0, const1,
|
||||
true);
|
||||
}
|
1445
client/renderers/EGL/shader/ffx_cas.h
Normal file
1445
client/renderers/EGL/shader/ffx_cas.h
Normal file
File diff suppressed because it is too large
Load diff
|
@ -39,6 +39,7 @@ extern const EGL_TextureOps EGL_TextureDMABUF;
|
|||
|
||||
typedef struct RenderStep
|
||||
{
|
||||
bool enabled;
|
||||
GLuint fb;
|
||||
GLuint tex;
|
||||
EGL_Shader * shader;
|
||||
|
@ -300,11 +301,12 @@ enum EGL_TexStatus egl_textureBind(EGL_Texture * this)
|
|||
|
||||
BindData * bd = (BindData *)this->bindData;
|
||||
RenderStep * step;
|
||||
ringbuffer_reset(this->textures);
|
||||
|
||||
/* if the postProcessing has not yet been done */
|
||||
if (!this->postProcessed)
|
||||
{
|
||||
ringbuffer_reset(this->textures);
|
||||
|
||||
if ((status = this->ops.get(this, &tex)) != EGL_TEX_STATUS_OK)
|
||||
return status;
|
||||
|
||||
|
@ -316,8 +318,14 @@ enum EGL_TexStatus egl_textureBind(EGL_Texture * this)
|
|||
|
||||
ringbuffer_forEach(this->textures, rbBindTexture, bd, true);
|
||||
|
||||
bool cleanup = false;
|
||||
for(ll_reset(this->render); ll_walk(this->render, (void **)&step); )
|
||||
{
|
||||
if (!step->enabled)
|
||||
continue;
|
||||
|
||||
cleanup = true;
|
||||
|
||||
/* create the framebuffer here as it must be in the same gl context as
|
||||
* it's usage */
|
||||
if (!step->fb)
|
||||
|
@ -361,26 +369,29 @@ enum EGL_TexStatus egl_textureBind(EGL_Texture * this)
|
|||
}
|
||||
|
||||
/* restore the state and the viewport */
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
glUseProgram(0);
|
||||
egl_resetViewport(this->egl);
|
||||
if (cleanup)
|
||||
{
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
glUseProgram(0);
|
||||
egl_resetViewport(this->egl);
|
||||
}
|
||||
|
||||
this->postProcessed = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* bind the last texture */
|
||||
ll_peek_tail(this->render, (void **)&step);
|
||||
BindInfo * bi = (BindInfo *)ringBuffer_getLastValue(this->textures);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, step->tex);
|
||||
glBindTexture(GL_TEXTURE_2D, bi->tex);
|
||||
glBindSampler(0, this->sampler);
|
||||
}
|
||||
|
||||
return EGL_TEX_STATUS_OK;
|
||||
}
|
||||
|
||||
enum EGL_TexStatus egl_textureAddShader(EGL_Texture * this, EGL_Shader * shader,
|
||||
float outputScale)
|
||||
PostProcessHandle egl_textureAddFilter(EGL_Texture * this, EGL_Shader * shader,
|
||||
float outputScale, bool enabled)
|
||||
{
|
||||
if (!this->render)
|
||||
{
|
||||
|
@ -396,6 +407,7 @@ enum EGL_TexStatus egl_textureAddShader(EGL_Texture * this, EGL_Shader * shader,
|
|||
step->scale = outputScale;
|
||||
step->uInRes = egl_shaderGetUniform(shader, "uInRes" );
|
||||
step->uOutRes = egl_shaderGetUniform(shader, "uOutRes");
|
||||
step->enabled = enabled;
|
||||
|
||||
this->scale = outputScale;
|
||||
|
||||
|
@ -404,11 +416,17 @@ enum EGL_TexStatus egl_textureAddShader(EGL_Texture * this, EGL_Shader * shader,
|
|||
{
|
||||
glDeleteTextures(1, &step->tex);
|
||||
free(step);
|
||||
return EGL_TEX_STATUS_ERROR;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ll_push(this->render, step);
|
||||
return EGL_TEX_STATUS_OK;
|
||||
return (PostProcessHandle)step;
|
||||
}
|
||||
|
||||
void egl_textureEnableFilter(PostProcessHandle * handle, bool enable)
|
||||
{
|
||||
RenderStep * step = (RenderStep *)handle;
|
||||
step->enabled = enable;
|
||||
}
|
||||
|
||||
float egl_textureGetScale(EGL_Texture * this)
|
||||
|
|
|
@ -170,7 +170,10 @@ enum EGL_TexStatus egl_textureProcess(EGL_Texture * texture);
|
|||
|
||||
enum EGL_TexStatus egl_textureBind(EGL_Texture * texture);
|
||||
|
||||
enum EGL_TexStatus egl_textureAddShader(EGL_Texture * texture,
|
||||
EGL_Shader * shader, float outputScale);
|
||||
typedef void * PostProcessHandle;
|
||||
PostProcessHandle egl_textureAddFilter(EGL_Texture * texture,
|
||||
EGL_Shader * shader, float outputScale, bool enabled);
|
||||
|
||||
void egl_textureEnableFilter(PostProcessHandle * handle, bool enable);
|
||||
|
||||
float egl_textureGetScale(EGL_Texture * texture);
|
||||
|
|
|
@ -33,6 +33,7 @@ int ringbuffer_getLength(const RingBuffer rb);
|
|||
int ringbuffer_getStart (const RingBuffer rb);
|
||||
int ringbuffer_getCount (const RingBuffer rb);
|
||||
void * ringbuffer_getValues(const RingBuffer rb);
|
||||
void * ringBuffer_getLastValue(const RingBuffer rb);
|
||||
|
||||
typedef void (*RingBufferValueFn)(void * value, void * udata);
|
||||
|
||||
|
|
|
@ -99,6 +99,18 @@ void * ringbuffer_getValues(const RingBuffer rb)
|
|||
return rb->values;
|
||||
}
|
||||
|
||||
void * ringBuffer_getLastValue(const RingBuffer rb)
|
||||
{
|
||||
if (rb->count == 0)
|
||||
return NULL;
|
||||
|
||||
int index = rb->start + rb->count - 1;
|
||||
if (index >= rb->length)
|
||||
index -= rb->length;
|
||||
|
||||
return rb->values + index * rb->valueSize;
|
||||
}
|
||||
|
||||
void ringbuffer_setPreOverwriteFn(const RingBuffer rb, RingBufferValueFn fn,
|
||||
void * udata)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue