mirror of
https://github.com/gnif/LookingGlass.git
synced 2024-11-10 11:17:54 +00:00
[client] egl: make the bgr_bgra filter generic for 24-bit formats
This commit is contained in:
parent
3843afa927
commit
c0e09e13a5
12 changed files with 154 additions and 59 deletions
|
@ -56,7 +56,7 @@ build_shaders(
|
|||
shader/damage.vert
|
||||
shader/damage.frag
|
||||
shader/basic.vert
|
||||
shader/convert_bgr_bgra.frag
|
||||
shader/convert_24bit.frag
|
||||
shader/ffx_cas.frag
|
||||
shader/ffx_fsr1_easu.frag
|
||||
shader/ffx_fsr1_rcas.frag
|
||||
|
@ -88,7 +88,7 @@ add_library(renderer_EGL STATIC
|
|||
postprocess.c
|
||||
ffx.c
|
||||
filter.c
|
||||
filter_bgr_bgra.c
|
||||
filter_24bit.c
|
||||
filter_ffx_cas.c
|
||||
filter_ffx_fsr1.c
|
||||
filter_downscale.c
|
||||
|
|
|
@ -100,7 +100,7 @@ static bool cursorTexInit(struct CursorTex * t,
|
|||
}
|
||||
|
||||
if (!egl_shaderCompile(t->shader,
|
||||
vertex_code, vertex_size, fragment_code, fragment_size, false))
|
||||
vertex_code, vertex_size, fragment_code, fragment_size, false, NULL))
|
||||
{
|
||||
DEBUG_ERROR("Failed to compile the cursor shader");
|
||||
return false;
|
||||
|
|
|
@ -77,7 +77,7 @@ bool egl_damageInit(EGL_Damage ** damage)
|
|||
if (!egl_shaderCompile((*damage)->shader,
|
||||
b_shader_damage_vert, b_shader_damage_vert_size,
|
||||
b_shader_damage_frag, b_shader_damage_frag_size,
|
||||
false))
|
||||
false, NULL))
|
||||
{
|
||||
DEBUG_ERROR("Failed to compile the damage shader");
|
||||
return false;
|
||||
|
|
|
@ -114,7 +114,7 @@ static bool egl_initDesktopShader(
|
|||
if (!egl_shaderCompile(shader->shader,
|
||||
vertex_code , vertex_size,
|
||||
fragment_code, fragment_size,
|
||||
useDMA))
|
||||
useDMA, NULL))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -207,7 +207,7 @@ bool egl_desktopInit(EGL * egl, EGL_Desktop ** desktop_, EGLDisplay * display,
|
|||
}
|
||||
|
||||
// this MUST be first
|
||||
egl_postProcessAdd(desktop->pp, &egl_filterBGRtoBGRAOps);
|
||||
egl_postProcessAdd(desktop->pp, &egl_filter24bitOps);
|
||||
|
||||
egl_postProcessAdd(desktop->pp, &egl_filterDownscaleOps);
|
||||
egl_postProcessAdd(desktop->pp, &egl_filterFFXCASOps );
|
||||
|
|
|
@ -29,14 +29,15 @@
|
|||
#include "cimgui.h"
|
||||
|
||||
#include "basic.vert.h"
|
||||
#include "convert_bgr_bgra.frag.h"
|
||||
#include "convert_24bit.frag.h"
|
||||
|
||||
|
||||
typedef struct EGL_FilterBGRtoBGRA
|
||||
typedef struct EGL_Filter24bit
|
||||
{
|
||||
EGL_Filter base;
|
||||
|
||||
bool enable;
|
||||
EGL_PixelFormat format;
|
||||
int useDMA;
|
||||
unsigned int width, height;
|
||||
unsigned int desktopWidth, desktopHeight;
|
||||
|
@ -48,11 +49,11 @@ typedef struct EGL_FilterBGRtoBGRA
|
|||
EGL_Framebuffer * fb;
|
||||
GLuint sampler[2];
|
||||
}
|
||||
EGL_FilterBGRtoBGRA;
|
||||
EGL_Filter24bit;
|
||||
|
||||
static bool egl_filterBGRtoBGRAInit(EGL_Filter ** filter)
|
||||
static bool egl_filter24bitInit(EGL_Filter ** filter)
|
||||
{
|
||||
EGL_FilterBGRtoBGRA * this = calloc(1, sizeof(*this));
|
||||
EGL_Filter24bit * this = calloc(1, sizeof(*this));
|
||||
if (!this)
|
||||
{
|
||||
DEBUG_ERROR("Failed to allocate ram");
|
||||
|
@ -94,9 +95,9 @@ error_this:
|
|||
return false;
|
||||
}
|
||||
|
||||
static void egl_filterBGRtoBGRAFree(EGL_Filter * filter)
|
||||
static void egl_filter24bitFree(EGL_Filter * filter)
|
||||
{
|
||||
EGL_FilterBGRtoBGRA * this = UPCAST(EGL_FilterBGRtoBGRA, filter);
|
||||
EGL_Filter24bit * this = UPCAST(EGL_Filter24bit, filter);
|
||||
|
||||
egl_shaderFree(&this->shader);
|
||||
egl_framebufferFree(&this->fb);
|
||||
|
@ -104,22 +105,28 @@ static void egl_filterBGRtoBGRAFree(EGL_Filter * filter)
|
|||
free(this);
|
||||
}
|
||||
|
||||
static bool egl_filterBGRtoBGRASetup(EGL_Filter * filter,
|
||||
static bool egl_filter24bitSetup(EGL_Filter * filter,
|
||||
enum EGL_PixelFormat pixFmt, unsigned int width, unsigned int height,
|
||||
unsigned int desktopWidth, unsigned int desktopHeight,
|
||||
bool useDMA)
|
||||
{
|
||||
EGL_FilterBGRtoBGRA * this = UPCAST(EGL_FilterBGRtoBGRA, filter);
|
||||
EGL_Filter24bit * this = UPCAST(EGL_Filter24bit, filter);
|
||||
|
||||
if (pixFmt != EGL_PF_BGR_32 && pixFmt != EGL_PF_RGB_24)
|
||||
return false;
|
||||
|
||||
if (this->useDMA != useDMA)
|
||||
if (this->useDMA != useDMA || this->format != pixFmt)
|
||||
{
|
||||
EGL_ShaderDefine defines[] =
|
||||
{
|
||||
{"OUTPUT", pixFmt == EGL_PF_BGR_32 ? "fragColor.bgra" : "fragColor.rgba" },
|
||||
{0}
|
||||
};
|
||||
|
||||
if (!egl_shaderCompile(this->shader,
|
||||
b_shader_basic_vert , b_shader_basic_vert_size,
|
||||
b_shader_convert_bgr_bgra_frag, b_shader_convert_bgr_bgra_frag_size,
|
||||
useDMA)
|
||||
b_shader_basic_vert , b_shader_basic_vert_size,
|
||||
b_shader_convert_24bit_frag, b_shader_convert_24bit_frag_size,
|
||||
useDMA, defines)
|
||||
)
|
||||
{
|
||||
DEBUG_ERROR("Failed to compile the shader");
|
||||
|
@ -144,6 +151,7 @@ static bool egl_filterBGRtoBGRASetup(EGL_Filter * filter,
|
|||
if (!egl_framebufferSetup(this->fb, pixFmt, desktopWidth, desktopHeight))
|
||||
return false;
|
||||
|
||||
this->format = pixFmt;
|
||||
this->width = width;
|
||||
this->height = height;
|
||||
this->desktopWidth = desktopWidth;
|
||||
|
@ -153,17 +161,17 @@ static bool egl_filterBGRtoBGRASetup(EGL_Filter * filter,
|
|||
return true;
|
||||
}
|
||||
|
||||
static void egl_filterBGRtoBGRAGetOutputRes(EGL_Filter * filter,
|
||||
static void egl_filter24bitGetOutputRes(EGL_Filter * filter,
|
||||
unsigned int *width, unsigned int *height)
|
||||
{
|
||||
EGL_FilterBGRtoBGRA * this = UPCAST(EGL_FilterBGRtoBGRA, filter);
|
||||
EGL_Filter24bit * this = UPCAST(EGL_Filter24bit, filter);
|
||||
*width = this->desktopWidth;
|
||||
*height = this->desktopHeight;
|
||||
}
|
||||
|
||||
static bool egl_filterBGRtoBGRAPrepare(EGL_Filter * filter)
|
||||
static bool egl_filter24bitPrepare(EGL_Filter * filter)
|
||||
{
|
||||
EGL_FilterBGRtoBGRA * this = UPCAST(EGL_FilterBGRtoBGRA, filter);
|
||||
EGL_Filter24bit * this = UPCAST(EGL_Filter24bit, filter);
|
||||
|
||||
if (this->prepared)
|
||||
return true;
|
||||
|
@ -176,10 +184,10 @@ static bool egl_filterBGRtoBGRAPrepare(EGL_Filter * filter)
|
|||
return true;
|
||||
}
|
||||
|
||||
static EGL_Texture * egl_filterBGRtoBGRARun(EGL_Filter * filter,
|
||||
static EGL_Texture * egl_filter24bitRun(EGL_Filter * filter,
|
||||
EGL_FilterRects * rects, EGL_Texture * texture)
|
||||
{
|
||||
EGL_FilterBGRtoBGRA * this = UPCAST(EGL_FilterBGRtoBGRA, filter);
|
||||
EGL_Filter24bit * this = UPCAST(EGL_Filter24bit, filter);
|
||||
|
||||
egl_framebufferBind(this->fb);
|
||||
|
||||
|
@ -194,19 +202,19 @@ static EGL_Texture * egl_filterBGRtoBGRARun(EGL_Filter * filter,
|
|||
return egl_framebufferGetTexture(this->fb);
|
||||
}
|
||||
|
||||
EGL_FilterOps egl_filterBGRtoBGRAOps =
|
||||
EGL_FilterOps egl_filter24bitOps =
|
||||
{
|
||||
.id = "bgrtobgra",
|
||||
.name = "BGRtoBGRA",
|
||||
.id = "24bit",
|
||||
.name = "24bit",
|
||||
.type = EGL_FILTER_TYPE_INTERNAL,
|
||||
.earlyInit = NULL,
|
||||
.init = egl_filterBGRtoBGRAInit,
|
||||
.free = egl_filterBGRtoBGRAFree,
|
||||
.init = egl_filter24bitInit,
|
||||
.free = egl_filter24bitFree,
|
||||
.imguiConfig = NULL,
|
||||
.saveState = NULL,
|
||||
.loadState = NULL,
|
||||
.setup = egl_filterBGRtoBGRASetup,
|
||||
.getOutputRes = egl_filterBGRtoBGRAGetOutputRes,
|
||||
.prepare = egl_filterBGRtoBGRAPrepare,
|
||||
.run = egl_filterBGRtoBGRARun
|
||||
.setup = egl_filter24bitSetup,
|
||||
.getOutputRes = egl_filter24bitGetOutputRes,
|
||||
.prepare = egl_filter24bitPrepare,
|
||||
.run = egl_filter24bitRun
|
||||
};
|
|
@ -316,7 +316,7 @@ static bool egl_filterDownscaleSetup(EGL_Filter * filter,
|
|||
b_shader_basic_vert , b_shader_basic_vert_size,
|
||||
b_shader_downscale_frag,
|
||||
b_shader_downscale_frag_size,
|
||||
useDMA)
|
||||
useDMA, NULL)
|
||||
)
|
||||
{
|
||||
DEBUG_ERROR("Failed to compile the shader");
|
||||
|
@ -327,7 +327,7 @@ static bool egl_filterDownscaleSetup(EGL_Filter * filter,
|
|||
b_shader_basic_vert, b_shader_basic_vert_size,
|
||||
b_shader_downscale_linear_frag,
|
||||
b_shader_downscale_linear_frag_size,
|
||||
useDMA)
|
||||
useDMA, NULL)
|
||||
)
|
||||
{
|
||||
DEBUG_ERROR("Failed to compile the shader");
|
||||
|
@ -338,7 +338,7 @@ static bool egl_filterDownscaleSetup(EGL_Filter * filter,
|
|||
b_shader_basic_vert, b_shader_basic_vert_size,
|
||||
b_shader_downscale_lanczos2_frag,
|
||||
b_shader_downscale_lanczos2_frag_size,
|
||||
useDMA)
|
||||
useDMA, NULL)
|
||||
)
|
||||
{
|
||||
DEBUG_ERROR("Failed to compile the shader");
|
||||
|
|
|
@ -222,7 +222,7 @@ static bool egl_filterFFXCASSetup(EGL_Filter * filter,
|
|||
if (!egl_shaderCompile(this->shader,
|
||||
b_shader_basic_vert , b_shader_basic_vert_size,
|
||||
b_shader_ffx_cas_frag, b_shader_ffx_cas_frag_size,
|
||||
useDMA)
|
||||
useDMA, NULL)
|
||||
)
|
||||
{
|
||||
DEBUG_ERROR("Failed to compile the shader");
|
||||
|
|
|
@ -127,7 +127,7 @@ static bool egl_filterFFXFSR1Init(EGL_Filter ** filter)
|
|||
if (!egl_shaderCompile(this->rcas,
|
||||
b_shader_basic_vert , b_shader_basic_vert_size,
|
||||
b_shader_ffx_fsr1_rcas_frag, b_shader_ffx_fsr1_rcas_frag_size,
|
||||
false)
|
||||
false, NULL)
|
||||
)
|
||||
{
|
||||
DEBUG_ERROR("Failed to compile the Rcas shader");
|
||||
|
@ -336,7 +336,7 @@ static bool egl_filterFFXFSR1Setup(EGL_Filter * filter,
|
|||
if (!egl_shaderCompile(this->easu,
|
||||
b_shader_basic_vert , b_shader_basic_vert_size,
|
||||
b_shader_ffx_fsr1_easu_frag, b_shader_ffx_fsr1_easu_frag_size,
|
||||
useDMA)
|
||||
useDMA, NULL)
|
||||
)
|
||||
{
|
||||
DEBUG_ERROR("Failed to compile the Easu shader");
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
extern EGL_FilterOps egl_filterBGRtoBGRAOps;
|
||||
extern EGL_FilterOps egl_filter24bitOps;
|
||||
extern EGL_FilterOps egl_filterDownscaleOps;
|
||||
extern EGL_FilterOps egl_filterFFXCASOps;
|
||||
extern EGL_FilterOps egl_filterFFXFSR1Ops;
|
||||
|
|
|
@ -65,7 +65,8 @@ void egl_shaderFree(EGL_Shader ** shader)
|
|||
}
|
||||
|
||||
bool egl_shaderLoad(EGL_Shader * this,
|
||||
const char * vertex_file, const char * fragment_file, bool useDMA)
|
||||
const char * vertex_file, const char * fragment_file, bool useDMA,
|
||||
const EGL_ShaderDefine * defines)
|
||||
{
|
||||
char * vertex_code, * fragment_code;
|
||||
size_t vertex_size, fragment_size;
|
||||
|
@ -89,7 +90,7 @@ bool egl_shaderLoad(EGL_Shader * this,
|
|||
|
||||
bool ret = egl_shaderCompile(this,
|
||||
vertex_code, vertex_size, fragment_code, fragment_size,
|
||||
useDMA);
|
||||
useDMA, defines);
|
||||
|
||||
free(vertex_code);
|
||||
free(fragment_code);
|
||||
|
@ -210,8 +211,12 @@ static bool shaderCompile(EGL_Shader * this, const char * vertex_code,
|
|||
|
||||
bool egl_shaderCompile(EGL_Shader * this, const char * vertex_code,
|
||||
size_t vertex_size, const char * fragment_code, size_t fragment_size,
|
||||
bool useDMA)
|
||||
bool useDMA, const EGL_ShaderDefine * defines)
|
||||
{
|
||||
bool result = false;
|
||||
char * processed = NULL;
|
||||
char * newCode = NULL;
|
||||
|
||||
if (useDMA)
|
||||
{
|
||||
const char * search = "sampler2D";
|
||||
|
@ -225,12 +230,13 @@ bool egl_shaderCompile(EGL_Shader * this, const char * vertex_code,
|
|||
src += strlen(search);
|
||||
}
|
||||
|
||||
const int diff = (strlen(replace) - strlen(search)) * instances;
|
||||
char * newCode = malloc(fragment_size + diff + 1);
|
||||
const int diff = (strlen(replace) - strlen(search)) * instances;
|
||||
const int newLen = fragment_size + diff;
|
||||
newCode = malloc(newLen + 1);
|
||||
if (!newCode)
|
||||
{
|
||||
DEBUG_ERROR("Out of memory");
|
||||
return false;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
src = fragment_code;
|
||||
|
@ -250,20 +256,94 @@ bool egl_shaderCompile(EGL_Shader * this, const char * vertex_code,
|
|||
|
||||
const int final = fragment_size - (src - fragment_code);
|
||||
memcpy(dst, src, final);
|
||||
dst[final] = 0;
|
||||
dst[final] = '\0';
|
||||
|
||||
bool result = shaderCompile(
|
||||
this,
|
||||
vertex_code, vertex_size,
|
||||
newCode , fragment_size + diff);
|
||||
|
||||
free(newCode);
|
||||
return result;
|
||||
fragment_code = newCode;
|
||||
fragment_size = newLen;
|
||||
}
|
||||
|
||||
return shaderCompile(this,
|
||||
if (defines)
|
||||
{
|
||||
// find the end of any existing lines starting with #
|
||||
bool newLine = true;
|
||||
bool skip = false;
|
||||
int insertPos = 0;
|
||||
for(int i = 0; i < fragment_size; ++i)
|
||||
{
|
||||
if (skip)
|
||||
{
|
||||
if (fragment_code[i] == '\n')
|
||||
skip = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
switch(fragment_code[i])
|
||||
{
|
||||
case '\n':
|
||||
newLine = true;
|
||||
continue;
|
||||
|
||||
case ' ':
|
||||
case '\t':
|
||||
case '\r':
|
||||
continue;
|
||||
|
||||
case '#':
|
||||
if (newLine)
|
||||
{
|
||||
skip = true;
|
||||
continue;
|
||||
}
|
||||
//fallthrough
|
||||
|
||||
default:
|
||||
newLine = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!newLine)
|
||||
{
|
||||
insertPos = i - 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int processedLen = fragment_size;
|
||||
const char * defineFormat = "#define %s %s\n";
|
||||
for(const EGL_ShaderDefine * define = defines; define->name; ++define)
|
||||
processedLen += snprintf(NULL, 0, defineFormat, define->name, define->value);
|
||||
|
||||
processed = malloc(processedLen);
|
||||
if (!processed)
|
||||
{
|
||||
DEBUG_ERROR("Out of memory");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
memcpy(processed, fragment_code, insertPos);
|
||||
|
||||
int offset = insertPos;
|
||||
for(const EGL_ShaderDefine * define = defines; define->name; ++define)
|
||||
offset += sprintf(processed + offset, defineFormat,
|
||||
define->name, define->value);
|
||||
|
||||
memcpy(
|
||||
processed + offset,
|
||||
fragment_code + insertPos,
|
||||
fragment_size - insertPos);
|
||||
|
||||
fragment_code = processed;
|
||||
fragment_size = processedLen;
|
||||
}
|
||||
|
||||
result = shaderCompile(this,
|
||||
vertex_code , vertex_size,
|
||||
fragment_code, fragment_size);
|
||||
|
||||
exit:
|
||||
free(processed);
|
||||
free(newCode);
|
||||
return result;
|
||||
}
|
||||
|
||||
void egl_shaderSetUniforms(EGL_Shader * this, EGL_Uniform * uniforms, int count)
|
||||
|
|
|
@ -93,15 +93,22 @@ typedef struct EGL_Uniform
|
|||
}
|
||||
EGL_Uniform;
|
||||
|
||||
typedef struct EGL_ShaderDefine
|
||||
{
|
||||
const char * name;
|
||||
const char * value;
|
||||
}
|
||||
EGL_ShaderDefine;
|
||||
|
||||
bool egl_shaderInit(EGL_Shader ** shader);
|
||||
void egl_shaderFree(EGL_Shader ** shader);
|
||||
|
||||
bool egl_shaderLoad(EGL_Shader * model, const char * vertex_file,
|
||||
const char * fragment_file, bool useDMA);
|
||||
const char * fragment_file, bool useDMA, const EGL_ShaderDefine * defines);
|
||||
|
||||
bool egl_shaderCompile(EGL_Shader * model, const char * vertex_code,
|
||||
size_t vertex_size, const char * fragment_code, size_t fragment_size,
|
||||
bool useDMA);
|
||||
bool useDMA, const EGL_ShaderDefine * defines);
|
||||
|
||||
void egl_shaderSetUniforms(EGL_Shader * shader, EGL_Uniform * uniforms,
|
||||
int count);
|
||||
|
|
|
@ -23,7 +23,7 @@ void main()
|
|||
uint trd = (outputPos.x * 3u + 2u) / 4u;
|
||||
vec4 color_2 = texelFetch(sampler1, ivec2(trd, outputPos.y), 0);
|
||||
|
||||
fragColor.bgra = vec4(
|
||||
OUTPUT = vec4(
|
||||
color_0.barg[outputPos.x % 4u],
|
||||
color_1.gbar[outputPos.x % 4u],
|
||||
color_2.rgba[outputPos.x % 4u],
|
Loading…
Reference in a new issue