mirror of
https://github.com/gnif/LookingGlass.git
synced 2024-12-22 05:23:39 +00:00
[client] egl: switch to using GL_TEXTURE_EXTERNAL_OES for DMABUF
According to Erik @ NVidia the open source NVidia driver will not create a EGLImage from a DMABUF if the target is not GL_TEXTURE_EXTERNAL_OES. This change set converts the dmabuf texture from GL_TEXTURE_2D to GL_TEXTURE_EXTERNAL_OES and at runtime performs a global search & replace on fragment shaders as needed to remain compatible, replacing `sampler2D` with `samplerExternalOES`. Ref: https://github.com/NVIDIA/open-gpu-kernel-modules/discussions/243#discussioncomment-3283415
This commit is contained in:
parent
bbc9204bfe
commit
b4b4a37b2b
@ -100,7 +100,7 @@ static bool cursorTexInit(struct CursorTex * t,
|
||||
}
|
||||
|
||||
if (!egl_shaderCompile(t->shader,
|
||||
vertex_code, vertex_size, fragment_code, fragment_size))
|
||||
vertex_code, vertex_size, fragment_code, fragment_size, false))
|
||||
{
|
||||
DEBUG_ERROR("Failed to compile the cursor shader");
|
||||
return false;
|
||||
|
@ -76,7 +76,8 @@ 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))
|
||||
b_shader_damage_frag, b_shader_damage_frag_size,
|
||||
false))
|
||||
{
|
||||
DEBUG_ERROR("Failed to compile the damage shader");
|
||||
return false;
|
||||
|
@ -46,6 +46,7 @@ struct DesktopShader
|
||||
EGL_Shader * shader;
|
||||
GLint uTransform;
|
||||
GLint uDesktopSize;
|
||||
GLint uSamplerType;
|
||||
GLint uScaleAlgo;
|
||||
GLint uNVGain;
|
||||
GLint uCBMode;
|
||||
@ -57,7 +58,7 @@ struct EGL_Desktop
|
||||
EGLDisplay * display;
|
||||
|
||||
EGL_Texture * texture;
|
||||
struct DesktopShader shader;
|
||||
struct DesktopShader dmaShader, shader;
|
||||
EGL_DesktopRects * mesh;
|
||||
CountedBuffer * matrix;
|
||||
|
||||
@ -92,7 +93,8 @@ void toggleNV(int key, void * opaque);
|
||||
static bool egl_initDesktopShader(
|
||||
struct DesktopShader * shader,
|
||||
const char * vertex_code , size_t vertex_size,
|
||||
const char * fragment_code, size_t fragment_size
|
||||
const char * fragment_code, size_t fragment_size,
|
||||
bool useDMA
|
||||
)
|
||||
{
|
||||
if (!egl_shaderInit(&shader->shader))
|
||||
@ -100,7 +102,8 @@ static bool egl_initDesktopShader(
|
||||
|
||||
if (!egl_shaderCompile(shader->shader,
|
||||
vertex_code , vertex_size,
|
||||
fragment_code, fragment_size))
|
||||
fragment_code, fragment_size,
|
||||
useDMA))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@ -135,15 +138,6 @@ bool egl_desktopInit(EGL * egl, EGL_Desktop ** desktop_, EGLDisplay * display,
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!egl_initDesktopShader(
|
||||
&desktop->shader,
|
||||
b_shader_desktop_vert , b_shader_desktop_vert_size,
|
||||
b_shader_desktop_rgb_frag, b_shader_desktop_rgb_frag_size))
|
||||
{
|
||||
DEBUG_ERROR("Failed to initialize the generic desktop shader");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!egl_desktopRectsInit(&desktop->mesh, maxRects))
|
||||
{
|
||||
DEBUG_ERROR("Failed to initialize the desktop mesh");
|
||||
@ -157,6 +151,27 @@ bool egl_desktopInit(EGL * egl, EGL_Desktop ** desktop_, EGLDisplay * display,
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!egl_initDesktopShader(
|
||||
&desktop->shader,
|
||||
b_shader_desktop_vert , b_shader_desktop_vert_size,
|
||||
b_shader_desktop_rgb_frag, b_shader_desktop_rgb_frag_size,
|
||||
false))
|
||||
{
|
||||
DEBUG_ERROR("Failed to initialize the desktop shader");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (useDMA)
|
||||
if (!egl_initDesktopShader(
|
||||
&desktop->dmaShader,
|
||||
b_shader_desktop_vert , b_shader_desktop_vert_size,
|
||||
b_shader_desktop_rgb_frag, b_shader_desktop_rgb_frag_size,
|
||||
true))
|
||||
{
|
||||
DEBUG_ERROR("Failed to initialize the desktop DMA shader");
|
||||
return false;
|
||||
}
|
||||
|
||||
app_registerKeybind(0, 'N', toggleNV, desktop,
|
||||
"Toggle night vision mode");
|
||||
|
||||
@ -205,11 +220,12 @@ void egl_desktopFree(EGL_Desktop ** desktop)
|
||||
if (!*desktop)
|
||||
return;
|
||||
|
||||
egl_textureFree (&(*desktop)->texture );
|
||||
egl_textureFree (&(*desktop)->spiceTexture );
|
||||
egl_shaderFree (&(*desktop)->shader.shader);
|
||||
egl_desktopRectsFree(&(*desktop)->mesh );
|
||||
countedBufferRelease(&(*desktop)->matrix );
|
||||
egl_textureFree (&(*desktop)->texture );
|
||||
egl_textureFree (&(*desktop)->spiceTexture );
|
||||
egl_shaderFree (&(*desktop)->shader .shader);
|
||||
egl_shaderFree (&(*desktop)->dmaShader.shader);
|
||||
egl_desktopRectsFree(&(*desktop)->mesh );
|
||||
countedBufferRelease(&(*desktop)->matrix );
|
||||
|
||||
egl_postProcessFree(&(*desktop)->pp);
|
||||
|
||||
@ -399,18 +415,17 @@ bool egl_desktopRender(EGL_Desktop * desktop, unsigned int outputWidth,
|
||||
if (atomic_exchange(&desktop->processFrame, false) ||
|
||||
egl_postProcessConfigModified(desktop->pp))
|
||||
egl_postProcessRun(desktop->pp, tex, desktop->mesh,
|
||||
width, height, outputWidth, outputHeight);
|
||||
width, height, outputWidth, outputHeight, desktop->useDMA);
|
||||
|
||||
unsigned int finalSizeX, finalSizeY;
|
||||
GLuint texture = egl_postProcessGetOutput(desktop->pp,
|
||||
EGL_Texture * texture = egl_postProcessGetOutput(desktop->pp,
|
||||
&finalSizeX, &finalSizeY);
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
egl_resetViewport(desktop->egl);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, texture);
|
||||
glBindSampler(0, tex->sampler);
|
||||
egl_textureBind(texture);
|
||||
|
||||
if (finalSizeX > width || finalSizeY > height)
|
||||
scaleType = EGL_DESKTOP_DOWNSCALE;
|
||||
@ -435,7 +450,10 @@ bool egl_desktopRender(EGL_Desktop * desktop, unsigned int outputWidth,
|
||||
scaleAlgo = desktop->scaleAlgo;
|
||||
}
|
||||
|
||||
const struct DesktopShader * shader = &desktop->shader;
|
||||
const struct DesktopShader * shader =
|
||||
desktop->useDMA && texture == desktop->texture ?
|
||||
&desktop->dmaShader : &desktop->shader;
|
||||
|
||||
EGL_Uniform uniforms[] =
|
||||
{
|
||||
{
|
||||
|
@ -68,9 +68,11 @@ typedef struct EGL_FilterOps
|
||||
/* reads filter state from options */
|
||||
void (*loadState)(EGL_Filter * filter);
|
||||
|
||||
/* set the input format of the filter */
|
||||
/* set the input format of the filter
|
||||
* useDMA will be true if the texture provided needs to use samplerExternalOES
|
||||
*/
|
||||
bool (*setup)(EGL_Filter * filter, enum EGL_PixelFormat pixFmt,
|
||||
unsigned int width, unsigned int height);
|
||||
unsigned int width, unsigned int height, bool useDMA);
|
||||
|
||||
/* set the output resolution hint for the filter
|
||||
* this is optional and only a hint */
|
||||
@ -87,8 +89,8 @@ typedef struct EGL_FilterOps
|
||||
|
||||
/* runs the filter on the provided texture
|
||||
* returns the processed texture as the output */
|
||||
GLuint (*run)(EGL_Filter * filter, EGL_FilterRects * rects,
|
||||
GLuint texture);
|
||||
EGL_Texture * (*run)(EGL_Filter * filter, EGL_FilterRects * rects,
|
||||
EGL_Texture * texture);
|
||||
|
||||
/* called when the filter output is no loger needed so it can release memory
|
||||
* this is optional */
|
||||
@ -133,9 +135,10 @@ static inline void egl_filterLoadState(EGL_Filter * filter)
|
||||
}
|
||||
|
||||
static inline bool egl_filterSetup(EGL_Filter * filter,
|
||||
enum EGL_PixelFormat pixFmt, unsigned int width, unsigned int height)
|
||||
enum EGL_PixelFormat pixFmt, unsigned int width, unsigned int height,
|
||||
bool useDMA)
|
||||
{
|
||||
return filter->ops.setup(filter, pixFmt, width, height);
|
||||
return filter->ops.setup(filter, pixFmt, width, height, useDMA);
|
||||
}
|
||||
|
||||
static inline void egl_filterSetOutputResHint(EGL_Filter * filter,
|
||||
@ -156,8 +159,8 @@ static inline bool egl_filterPrepare(EGL_Filter * filter)
|
||||
return filter->ops.prepare(filter);
|
||||
}
|
||||
|
||||
static inline GLuint egl_filterRun(EGL_Filter * filter,
|
||||
EGL_FilterRects * rects, GLuint texture)
|
||||
static inline EGL_Texture * egl_filterRun(EGL_Filter * filter,
|
||||
EGL_FilterRects * rects, EGL_Texture * texture)
|
||||
{
|
||||
return filter->ops.run(filter, rects, texture);
|
||||
}
|
||||
|
@ -60,6 +60,7 @@ typedef struct EGL_FilterDownscale
|
||||
EGL_Shader * lanczos2;
|
||||
|
||||
DownscaleFilter filter;
|
||||
int useDMA;
|
||||
enum EGL_PixelFormat pixFmt;
|
||||
unsigned int width, height;
|
||||
float pixelSize;
|
||||
@ -157,55 +158,26 @@ static bool egl_filterDownscaleInit(EGL_Filter ** filter)
|
||||
return false;
|
||||
}
|
||||
|
||||
this->useDMA = -1;
|
||||
|
||||
if (!egl_shaderInit(&this->nearest))
|
||||
{
|
||||
DEBUG_ERROR("Failed to initialize the shader");
|
||||
goto error_this;
|
||||
}
|
||||
|
||||
if (!egl_shaderCompile(this->nearest,
|
||||
b_shader_basic_vert , b_shader_basic_vert_size,
|
||||
b_shader_downscale_frag, b_shader_downscale_frag_size)
|
||||
)
|
||||
{
|
||||
DEBUG_ERROR("Failed to compile the shader");
|
||||
goto error_shader;
|
||||
}
|
||||
|
||||
if (!egl_shaderInit(&this->linear))
|
||||
{
|
||||
DEBUG_ERROR("Failed to initialize the shader");
|
||||
goto error_this;
|
||||
}
|
||||
|
||||
if (!egl_shaderCompile(this->linear,
|
||||
b_shader_basic_vert, b_shader_basic_vert_size,
|
||||
b_shader_downscale_linear_frag, b_shader_downscale_linear_frag_size)
|
||||
)
|
||||
{
|
||||
DEBUG_ERROR("Failed to compile the shader");
|
||||
goto error_shader;
|
||||
}
|
||||
|
||||
if (!egl_shaderInit(&this->lanczos2))
|
||||
{
|
||||
DEBUG_ERROR("Failed to initialize the shader");
|
||||
goto error_this;
|
||||
}
|
||||
|
||||
if (!egl_shaderCompile(this->lanczos2,
|
||||
b_shader_basic_vert, b_shader_basic_vert_size,
|
||||
b_shader_downscale_lanczos2_frag, b_shader_downscale_lanczos2_frag_size)
|
||||
)
|
||||
{
|
||||
DEBUG_ERROR("Failed to compile the shader");
|
||||
goto error_shader;
|
||||
}
|
||||
|
||||
this->uNearest.type = EGL_UNIFORM_TYPE_3F;
|
||||
this->uNearest.location =
|
||||
egl_shaderGetUniform(this->nearest, "uConfig");
|
||||
|
||||
if (!egl_framebufferInit(&this->fb))
|
||||
{
|
||||
DEBUG_ERROR("Failed to initialize the framebuffer");
|
||||
@ -326,7 +298,8 @@ static bool egl_filterDownscaleImguiConfig(EGL_Filter * filter)
|
||||
}
|
||||
|
||||
static bool egl_filterDownscaleSetup(EGL_Filter * filter,
|
||||
enum EGL_PixelFormat pixFmt, unsigned int width, unsigned int height)
|
||||
enum EGL_PixelFormat pixFmt, unsigned int width, unsigned int height,
|
||||
bool useDMA)
|
||||
{
|
||||
EGL_FilterDownscale * this = UPCAST(EGL_FilterDownscale, filter);
|
||||
|
||||
@ -336,6 +309,48 @@ static bool egl_filterDownscaleSetup(EGL_Filter * filter,
|
||||
if (!this->enable)
|
||||
return false;
|
||||
|
||||
if (this->useDMA != useDMA)
|
||||
{
|
||||
if (!egl_shaderCompile(this->nearest,
|
||||
b_shader_basic_vert , b_shader_basic_vert_size,
|
||||
b_shader_downscale_frag,
|
||||
b_shader_downscale_frag_size,
|
||||
useDMA)
|
||||
)
|
||||
{
|
||||
DEBUG_ERROR("Failed to compile the shader");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!egl_shaderCompile(this->linear,
|
||||
b_shader_basic_vert, b_shader_basic_vert_size,
|
||||
b_shader_downscale_linear_frag,
|
||||
b_shader_downscale_linear_frag_size,
|
||||
useDMA)
|
||||
)
|
||||
{
|
||||
DEBUG_ERROR("Failed to compile the shader");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!egl_shaderCompile(this->lanczos2,
|
||||
b_shader_basic_vert, b_shader_basic_vert_size,
|
||||
b_shader_downscale_lanczos2_frag,
|
||||
b_shader_downscale_lanczos2_frag_size,
|
||||
useDMA)
|
||||
)
|
||||
{
|
||||
DEBUG_ERROR("Failed to compile the shader");
|
||||
return false;
|
||||
}
|
||||
|
||||
this->uNearest.type = EGL_UNIFORM_TYPE_3F;
|
||||
this->uNearest.location =
|
||||
egl_shaderGetUniform(this->nearest, "uConfig");
|
||||
|
||||
this->useDMA = useDMA;
|
||||
}
|
||||
|
||||
if (this->prepared &&
|
||||
pixFmt == this->pixFmt &&
|
||||
this->width == width &&
|
||||
@ -385,15 +400,15 @@ static bool egl_filterDownscalePrepare(EGL_Filter * filter)
|
||||
return true;
|
||||
}
|
||||
|
||||
static GLuint egl_filterDownscaleRun(EGL_Filter * filter,
|
||||
EGL_FilterRects * rects, GLuint texture)
|
||||
static EGL_Texture * egl_filterDownscaleRun(EGL_Filter * filter,
|
||||
EGL_FilterRects * rects, EGL_Texture * texture)
|
||||
{
|
||||
EGL_FilterDownscale * this = UPCAST(EGL_FilterDownscale, filter);
|
||||
|
||||
egl_framebufferBind(this->fb);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, texture);
|
||||
egl_textureBind(texture);
|
||||
|
||||
EGL_Shader * shader;
|
||||
|
||||
|
@ -37,6 +37,7 @@ typedef struct EGL_FilterFFXCAS
|
||||
EGL_Shader * shader;
|
||||
bool enable;
|
||||
|
||||
int useDMA;
|
||||
enum EGL_PixelFormat pixFmt;
|
||||
unsigned int width, height;
|
||||
float sharpness;
|
||||
@ -106,21 +107,14 @@ static bool egl_filterFFXCASInit(EGL_Filter ** filter)
|
||||
return false;
|
||||
}
|
||||
|
||||
this->useDMA = -1;
|
||||
|
||||
if (!egl_shaderInit(&this->shader))
|
||||
{
|
||||
DEBUG_ERROR("Failed to initialize the shader");
|
||||
goto error_this;
|
||||
}
|
||||
|
||||
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)
|
||||
)
|
||||
{
|
||||
DEBUG_ERROR("Failed to compile the shader");
|
||||
goto error_shader;
|
||||
}
|
||||
|
||||
this->consts = countedBufferNew(8 * sizeof(GLuint));
|
||||
if (!this->consts)
|
||||
{
|
||||
@ -128,12 +122,6 @@ static bool egl_filterFFXCASInit(EGL_Filter ** filter)
|
||||
goto error_shader;
|
||||
}
|
||||
|
||||
egl_shaderSetUniforms(this->shader, &(EGL_Uniform) {
|
||||
.type = EGL_UNIFORM_TYPE_4UIV,
|
||||
.location = egl_shaderGetUniform(this->shader, "uConsts"),
|
||||
.v = this->consts,
|
||||
}, 1);
|
||||
|
||||
egl_filterFFXCASLoadState(&this->base);
|
||||
|
||||
if (!egl_framebufferInit(&this->fb))
|
||||
@ -220,13 +208,35 @@ static bool egl_filterFFXCASImguiConfig(EGL_Filter * filter)
|
||||
}
|
||||
|
||||
static bool egl_filterFFXCASSetup(EGL_Filter * filter,
|
||||
enum EGL_PixelFormat pixFmt, unsigned int width, unsigned int height)
|
||||
enum EGL_PixelFormat pixFmt, unsigned int width, unsigned int height,
|
||||
bool useDMA)
|
||||
{
|
||||
EGL_FilterFFXCAS * this = UPCAST(EGL_FilterFFXCAS, filter);
|
||||
|
||||
if (!this->enable)
|
||||
return false;
|
||||
|
||||
if (this->useDMA != useDMA)
|
||||
{
|
||||
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)
|
||||
)
|
||||
{
|
||||
DEBUG_ERROR("Failed to compile the shader");
|
||||
return false;
|
||||
}
|
||||
|
||||
egl_shaderSetUniforms(this->shader, &(EGL_Uniform) {
|
||||
.type = EGL_UNIFORM_TYPE_4UIV,
|
||||
.location = egl_shaderGetUniform(this->shader, "uConsts"),
|
||||
.v = this->consts,
|
||||
}, 1);
|
||||
|
||||
this->useDMA = useDMA;
|
||||
}
|
||||
|
||||
if (pixFmt == this->pixFmt && this->width == width && this->height == height)
|
||||
return true;
|
||||
|
||||
@ -262,15 +272,15 @@ static bool egl_filterFFXCASPrepare(EGL_Filter * filter)
|
||||
return true;
|
||||
}
|
||||
|
||||
static GLuint egl_filterFFXCASRun(EGL_Filter * filter,
|
||||
EGL_FilterRects * rects, GLuint texture)
|
||||
static EGL_Texture * egl_filterFFXCASRun(EGL_Filter * filter,
|
||||
EGL_FilterRects * rects, EGL_Texture * texture)
|
||||
{
|
||||
EGL_FilterFFXCAS * this = UPCAST(EGL_FilterFFXCAS, filter);
|
||||
|
||||
egl_framebufferBind(this->fb);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, texture);
|
||||
egl_textureBind(texture);
|
||||
glBindSampler(0, this->sampler);
|
||||
|
||||
egl_shaderUse(this->shader);
|
||||
|
@ -42,6 +42,7 @@ typedef struct EGL_FilterFFXFSR1
|
||||
CountedBuffer * consts;
|
||||
EGL_Uniform easuUniform[2], rcasUniform;
|
||||
|
||||
int useDMA;
|
||||
enum EGL_PixelFormat pixFmt;
|
||||
unsigned int width, height;
|
||||
unsigned int inWidth, inHeight;
|
||||
@ -109,6 +110,8 @@ static bool egl_filterFFXFSR1Init(EGL_Filter ** filter)
|
||||
return false;
|
||||
}
|
||||
|
||||
this->useDMA = -1;
|
||||
|
||||
if (!egl_shaderInit(&this->easu))
|
||||
{
|
||||
DEBUG_ERROR("Failed to initialize the Easu shader");
|
||||
@ -121,18 +124,10 @@ static bool egl_filterFFXFSR1Init(EGL_Filter ** filter)
|
||||
goto error_esau;
|
||||
}
|
||||
|
||||
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)
|
||||
)
|
||||
{
|
||||
DEBUG_ERROR("Failed to compile the Easu shader");
|
||||
goto error_rcas;
|
||||
}
|
||||
|
||||
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)
|
||||
b_shader_ffx_fsr1_rcas_frag, b_shader_ffx_fsr1_rcas_frag_size,
|
||||
false)
|
||||
)
|
||||
{
|
||||
DEBUG_ERROR("Failed to compile the Rcas shader");
|
||||
@ -148,14 +143,6 @@ static bool egl_filterFFXFSR1Init(EGL_Filter ** filter)
|
||||
|
||||
egl_filterFFXFSR1LoadState(&this->base);
|
||||
|
||||
this->easuUniform[0].type = EGL_UNIFORM_TYPE_4UIV;
|
||||
this->easuUniform[0].location =
|
||||
egl_shaderGetUniform(this->easu, "uConsts");
|
||||
this->easuUniform[0].v = this->consts;
|
||||
this->easuUniform[1].type = EGL_UNIFORM_TYPE_2F;
|
||||
this->easuUniform[1].location =
|
||||
egl_shaderGetUniform(this->easu, "uOutRes");
|
||||
|
||||
this->rcasUniform.type = EGL_UNIFORM_TYPE_4UI;
|
||||
this->rcasUniform.location = egl_shaderGetUniform(this->rcas, "uConsts");
|
||||
rcasUpdateUniform(this);
|
||||
@ -335,13 +322,37 @@ static void egl_filterFFXFSR1SetOutputResHint(EGL_Filter * filter,
|
||||
}
|
||||
|
||||
static bool egl_filterFFXFSR1Setup(EGL_Filter * filter,
|
||||
enum EGL_PixelFormat pixFmt, unsigned int width, unsigned int height)
|
||||
enum EGL_PixelFormat pixFmt, unsigned int width, unsigned int height,
|
||||
bool useDMA)
|
||||
{
|
||||
EGL_FilterFFXFSR1 * this = UPCAST(EGL_FilterFFXFSR1, filter);
|
||||
|
||||
if (!this->enable)
|
||||
return false;
|
||||
|
||||
if (this->useDMA != useDMA)
|
||||
{
|
||||
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)
|
||||
)
|
||||
{
|
||||
DEBUG_ERROR("Failed to compile the Easu shader");
|
||||
return false;
|
||||
}
|
||||
|
||||
this->easuUniform[0].type = EGL_UNIFORM_TYPE_4UIV;
|
||||
this->easuUniform[0].location =
|
||||
egl_shaderGetUniform(this->easu, "uConsts");
|
||||
this->easuUniform[0].v = this->consts;
|
||||
this->easuUniform[1].type = EGL_UNIFORM_TYPE_2F;
|
||||
this->easuUniform[1].location =
|
||||
egl_shaderGetUniform(this->easu, "uOutRes");
|
||||
|
||||
this->useDMA = useDMA;
|
||||
}
|
||||
|
||||
this->active = this->width > width && this->height > height;
|
||||
if (!this->active)
|
||||
return false;
|
||||
@ -395,15 +406,15 @@ static bool egl_filterFFXFSR1Prepare(EGL_Filter * filter)
|
||||
return true;
|
||||
}
|
||||
|
||||
static GLuint egl_filterFFXFSR1Run(EGL_Filter * filter,
|
||||
EGL_FilterRects * rects, GLuint texture)
|
||||
static EGL_Texture * egl_filterFFXFSR1Run(EGL_Filter * filter,
|
||||
EGL_FilterRects * rects, EGL_Texture * texture)
|
||||
{
|
||||
EGL_FilterFFXFSR1 * this = UPCAST(EGL_FilterFFXFSR1, filter);
|
||||
|
||||
// pass 1, Easu
|
||||
egl_framebufferBind(this->easuFb);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, texture);
|
||||
egl_textureBind(texture);
|
||||
glBindSampler(0, this->sampler);
|
||||
egl_shaderUse(this->easu);
|
||||
egl_filterRectsRender(this->easu, rects);
|
||||
@ -412,7 +423,7 @@ static GLuint egl_filterFFXFSR1Run(EGL_Filter * filter,
|
||||
// pass 2, Rcas
|
||||
egl_framebufferBind(this->rcasFb);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, texture);
|
||||
egl_textureBind(texture);
|
||||
glBindSampler(0, this->sampler);
|
||||
egl_shaderUse(this->rcas);
|
||||
egl_filterRectsRender(this->rcas, rects);
|
||||
|
@ -100,9 +100,7 @@ void egl_framebufferBind(EGL_Framebuffer * this)
|
||||
glViewport(0, 0, this->tex->format.width, this->tex->format.height);
|
||||
}
|
||||
|
||||
GLuint egl_framebufferGetTexture(EGL_Framebuffer * this)
|
||||
EGL_Texture * egl_framebufferGetTexture(EGL_Framebuffer * this)
|
||||
{
|
||||
GLuint output;
|
||||
egl_textureGet(this->tex, &output, NULL, NULL);
|
||||
return output;
|
||||
return this->tex;
|
||||
}
|
||||
|
@ -32,4 +32,4 @@ bool egl_framebufferSetup(EGL_Framebuffer * this, enum EGL_PixelFormat pixFmt,
|
||||
|
||||
void egl_framebufferBind(EGL_Framebuffer * this);
|
||||
|
||||
GLuint egl_framebufferGetTexture(EGL_Framebuffer * this);
|
||||
EGL_Texture * egl_framebufferGetTexture(EGL_Framebuffer * this);
|
||||
|
@ -49,7 +49,7 @@ static const EGL_FilterOps * EGL_Filters[] =
|
||||
struct EGL_PostProcess
|
||||
{
|
||||
Vector filters;
|
||||
GLuint output;
|
||||
EGL_Texture * output;
|
||||
unsigned int outputX, outputY;
|
||||
_Atomic(bool) modified;
|
||||
|
||||
@ -606,7 +606,7 @@ bool egl_postProcessConfigModified(EGL_PostProcess * this)
|
||||
|
||||
bool egl_postProcessRun(EGL_PostProcess * this, EGL_Texture * tex,
|
||||
EGL_DesktopRects * rects, int desktopWidth, int desktopHeight,
|
||||
unsigned int targetX, unsigned int targetY)
|
||||
unsigned int targetX, unsigned int targetY, bool useDMA)
|
||||
{
|
||||
if (targetX == 0 && targetY == 0)
|
||||
DEBUG_FATAL("targetX || targetY == 0");
|
||||
@ -614,8 +614,9 @@ bool egl_postProcessRun(EGL_PostProcess * this, EGL_Texture * tex,
|
||||
EGL_Filter * lastFilter = NULL;
|
||||
unsigned int sizeX, sizeY;
|
||||
|
||||
GLuint texture;
|
||||
if (egl_textureGet(tex, &texture, &sizeX, &sizeY) != EGL_TEX_STATUS_OK)
|
||||
//TODO: clean this up
|
||||
GLuint _unused;
|
||||
if (egl_textureGet(tex, &_unused, &sizeX, &sizeY) != EGL_TEX_STATUS_OK)
|
||||
return false;
|
||||
|
||||
if (atomic_exchange(&this->modified, false))
|
||||
@ -636,11 +637,12 @@ bool egl_postProcessRun(EGL_PostProcess * this, EGL_Texture * tex,
|
||||
};
|
||||
|
||||
EGL_Filter * filter;
|
||||
EGL_Texture * texture = tex;
|
||||
vector_forEach(filter, &this->filters)
|
||||
{
|
||||
egl_filterSetOutputResHint(filter, targetX, targetY);
|
||||
|
||||
if (!egl_filterSetup(filter, tex->format.pixFmt, sizeX, sizeY) ||
|
||||
if (!egl_filterSetup(filter, tex->format.pixFmt, sizeX, sizeY, useDMA) ||
|
||||
!egl_filterPrepare(filter))
|
||||
continue;
|
||||
|
||||
@ -651,6 +653,9 @@ bool egl_postProcessRun(EGL_PostProcess * this, EGL_Texture * tex,
|
||||
egl_filterRelease(lastFilter);
|
||||
|
||||
lastFilter = filter;
|
||||
|
||||
// the first filter to run will convert to a normal texture
|
||||
useDMA = false;
|
||||
}
|
||||
|
||||
this->output = texture;
|
||||
@ -659,7 +664,7 @@ bool egl_postProcessRun(EGL_PostProcess * this, EGL_Texture * tex,
|
||||
return true;
|
||||
}
|
||||
|
||||
GLuint egl_postProcessGetOutput(EGL_PostProcess * this,
|
||||
EGL_Texture * egl_postProcessGetOutput(EGL_PostProcess * this,
|
||||
unsigned int * outputX, unsigned int * outputY)
|
||||
{
|
||||
*outputX = this->outputX;
|
||||
|
@ -41,7 +41,7 @@ bool egl_postProcessConfigModified(EGL_PostProcess * this);
|
||||
* targetX/Y is the final target output dimension hint if scalers are present */
|
||||
bool egl_postProcessRun(EGL_PostProcess * this, EGL_Texture * tex,
|
||||
EGL_DesktopRects * rects, int desktopWidth, int desktopHeight,
|
||||
unsigned int targetX, unsigned int targetY);
|
||||
unsigned int targetX, unsigned int targetY, bool useDMA);
|
||||
|
||||
GLuint egl_postProcessGetOutput(EGL_PostProcess * this,
|
||||
EGL_Texture * egl_postProcessGetOutput(EGL_PostProcess * this,
|
||||
unsigned int * outputX, unsigned int * outputY);
|
||||
|
@ -64,7 +64,8 @@ void egl_shaderFree(EGL_Shader ** shader)
|
||||
*shader = NULL;
|
||||
}
|
||||
|
||||
bool egl_shaderLoad(EGL_Shader * this, const char * vertex_file, const char * fragment_file)
|
||||
bool egl_shaderLoad(EGL_Shader * this,
|
||||
const char * vertex_file, const char * fragment_file, bool useDMA)
|
||||
{
|
||||
char * vertex_code, * fragment_code;
|
||||
size_t vertex_size, fragment_size;
|
||||
@ -86,13 +87,16 @@ bool egl_shaderLoad(EGL_Shader * this, const char * vertex_file, const char * fr
|
||||
|
||||
DEBUG_INFO("Loaded fragment shader: %s", fragment_file);
|
||||
|
||||
bool ret = egl_shaderCompile(this, vertex_code, vertex_size, fragment_code, fragment_size);
|
||||
bool ret = egl_shaderCompile(this,
|
||||
vertex_code, vertex_size, fragment_code, fragment_size,
|
||||
useDMA);
|
||||
|
||||
free(vertex_code);
|
||||
free(fragment_code);
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool egl_shaderCompile(EGL_Shader * this, const char * vertex_code,
|
||||
static bool shaderCompile(EGL_Shader * this, const char * vertex_code,
|
||||
size_t vertex_size, const char * fragment_code, size_t fragment_size)
|
||||
{
|
||||
if (this->hasShader)
|
||||
@ -204,6 +208,64 @@ bool egl_shaderCompile(EGL_Shader * this, const char * vertex_code,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool egl_shaderCompile(EGL_Shader * this, const char * vertex_code,
|
||||
size_t vertex_size, const char * fragment_code, size_t fragment_size,
|
||||
bool useDMA)
|
||||
{
|
||||
if (useDMA)
|
||||
{
|
||||
const char * search = "sampler2D";
|
||||
const char * replace = "samplerExternalOES";
|
||||
|
||||
const char * src = fragment_code;
|
||||
int instances = 0;
|
||||
while((src = strstr(src, search)))
|
||||
{
|
||||
++instances;
|
||||
src += strlen(search);
|
||||
}
|
||||
|
||||
const int diff = (strlen(replace) - strlen(search)) * instances;
|
||||
char * newCode = malloc(fragment_size + diff);
|
||||
if (!newCode)
|
||||
{
|
||||
DEBUG_ERROR("Out of memory");
|
||||
return false;
|
||||
}
|
||||
|
||||
src = fragment_code;
|
||||
char * dst = newCode;
|
||||
for(int i = 0; i < instances; ++i)
|
||||
{
|
||||
const char * pos = strstr(src, search);
|
||||
const int offset = pos - src;
|
||||
|
||||
memcpy(dst, src, offset);
|
||||
dst += offset;
|
||||
src = pos + strlen(search);
|
||||
|
||||
memcpy(dst, replace, strlen(replace));
|
||||
dst += strlen(replace);
|
||||
}
|
||||
|
||||
const int final = fragment_size - (src - fragment_code);
|
||||
memcpy(dst, src, final);
|
||||
dst[final] = 0;
|
||||
|
||||
bool result = shaderCompile(
|
||||
this,
|
||||
vertex_code, vertex_size,
|
||||
newCode , fragment_size + diff);
|
||||
|
||||
free(newCode);
|
||||
return result;
|
||||
}
|
||||
|
||||
return shaderCompile(this,
|
||||
vertex_code , vertex_size,
|
||||
fragment_code, fragment_size);
|
||||
}
|
||||
|
||||
void egl_shaderSetUniforms(EGL_Shader * this, EGL_Uniform * uniforms, int count)
|
||||
{
|
||||
egl_shaderFreeUniforms(this);
|
||||
|
@ -97,10 +97,11 @@ 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);
|
||||
const char * fragment_file, bool useDMA);
|
||||
|
||||
bool egl_shaderCompile(EGL_Shader * model, const char * vertex_code,
|
||||
size_t vertex_size, const char * fragment_code, size_t fragment_size);
|
||||
size_t vertex_size, const char * fragment_code, size_t fragment_size,
|
||||
bool useDMA);
|
||||
|
||||
void egl_shaderSetUniforms(EGL_Shader * shader, EGL_Uniform * uniforms,
|
||||
int count);
|
||||
|
@ -1,16 +1,21 @@
|
||||
#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));
|
||||
vec2 res = vec2(textureSize(tex, 0));
|
||||
ivec2 p = ivec2((uv * res) - 0.5f);
|
||||
|
||||
// NOTE: we can't use texelFecthOffset because sampler2D may actually be samplerExternalOES
|
||||
vec4 c0 = texelFetch(tex, p+ivec2(0,1), 0);
|
||||
vec4 c1 = texelFetch(tex, p+ivec2(1,1), 0);
|
||||
vec4 c2 = texelFetch(tex, p+ivec2(1,0), 0);
|
||||
vec4 c3 = texelFetch(tex, p+ivec2(0,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);
|
||||
vec4 c3 = texture(tex, uv);
|
||||
return vec4(c3[comp], c3[comp], c3[comp],c3[comp]);
|
||||
}
|
||||
#endif
|
||||
|
@ -1,4 +1,6 @@
|
||||
#version 300 es
|
||||
#extension GL_OES_EGL_image_external_essl3 : enable
|
||||
|
||||
precision highp float;
|
||||
|
||||
#define EGL_SCALE_AUTO 0
|
||||
@ -23,13 +25,17 @@ void main()
|
||||
switch (scaleAlgo)
|
||||
{
|
||||
case EGL_SCALE_NEAREST:
|
||||
{
|
||||
vec2 ts = vec2(textureSize(sampler1, 0));
|
||||
color = texelFetch(sampler1, ivec2(uv * ts), 0);
|
||||
break;
|
||||
}
|
||||
|
||||
case EGL_SCALE_LINEAR:
|
||||
{
|
||||
color = texture(sampler1, uv);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (cbMode > 0)
|
||||
|
@ -1,10 +1,12 @@
|
||||
#version 300 es
|
||||
#extension GL_OES_EGL_image_external_essl3 : enable
|
||||
|
||||
precision highp float;
|
||||
|
||||
in vec2 fragCoord;
|
||||
out vec4 fragColor;
|
||||
|
||||
uniform sampler2D texture;
|
||||
uniform sampler2D sampler1;
|
||||
uniform vec3 uConfig;
|
||||
|
||||
void main()
|
||||
@ -13,7 +15,7 @@ void main()
|
||||
float vOffset = uConfig.y;
|
||||
float hOffset = uConfig.z;
|
||||
|
||||
vec2 inRes = vec2(textureSize(texture, 0));
|
||||
vec2 inRes = vec2(textureSize(sampler1, 0));
|
||||
ivec2 point = ivec2(
|
||||
(floor((fragCoord * inRes) / pixelSize) * pixelSize) +
|
||||
pixelSize / 2.0f
|
||||
@ -22,5 +24,5 @@ void main()
|
||||
point.x += int(pixelSize * hOffset);
|
||||
point.y += int(pixelSize * vOffset);
|
||||
|
||||
fragColor = texelFetch(texture, point, 0);
|
||||
fragColor = texelFetch(sampler1, point, 0);
|
||||
}
|
||||
|
@ -1,4 +1,6 @@
|
||||
#version 300 es
|
||||
#extension GL_OES_EGL_image_external_essl3 : enable
|
||||
|
||||
precision highp float;
|
||||
|
||||
#define PI 3.141592653589793
|
||||
@ -6,7 +8,7 @@ precision highp float;
|
||||
in vec2 fragCoord;
|
||||
out vec4 fragColor;
|
||||
|
||||
uniform sampler2D texture;
|
||||
uniform sampler2D sampler1;
|
||||
float sinc(float x)
|
||||
{
|
||||
return x == 0.0 ? 1.0 : sin(x * PI) / (x * PI);
|
||||
@ -24,7 +26,7 @@ float lanczos(vec2 v)
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 size = vec2(textureSize(texture, 0));
|
||||
vec2 size = vec2(textureSize(sampler1, 0));
|
||||
vec2 pos = fragCoord * size;
|
||||
vec2 invSize = 1.0 / size;
|
||||
vec2 uvc = floor(pos) + vec2(0.5, 0.5);
|
||||
@ -54,7 +56,7 @@ void main()
|
||||
|
||||
vec3 color = vec3(0.0);
|
||||
for (int i = 0; i < 9; ++i)
|
||||
color += texture2D(texture, uvs[i] * invSize).rgb * factors[i];
|
||||
color += texture(sampler1, uvs[i] * invSize).rgb * factors[i];
|
||||
|
||||
fragColor = vec4(color, 1.0);
|
||||
}
|
||||
|
@ -1,12 +1,14 @@
|
||||
#version 300 es
|
||||
#extension GL_OES_EGL_image_external_essl3 : enable
|
||||
|
||||
precision highp float;
|
||||
|
||||
in vec2 fragCoord;
|
||||
out vec4 fragColor;
|
||||
|
||||
uniform sampler2D texture;
|
||||
uniform sampler2D sampler1;
|
||||
|
||||
void main()
|
||||
{
|
||||
fragColor = texture2D(texture, fragCoord);
|
||||
fragColor = texture(sampler1, fragCoord);
|
||||
}
|
||||
|
@ -1,4 +1,6 @@
|
||||
#version 300 es
|
||||
#extension GL_OES_EGL_image_external_essl3 : enable
|
||||
|
||||
precision highp float;
|
||||
|
||||
#include "compat.h"
|
||||
@ -6,7 +8,7 @@ precision highp float;
|
||||
in vec2 fragCoord;
|
||||
out vec4 fragColor;
|
||||
|
||||
uniform sampler2D texture;
|
||||
uniform sampler2D sampler1;
|
||||
uniform uvec4 uConsts[2];
|
||||
|
||||
#define A_GPU 1
|
||||
@ -16,7 +18,7 @@ uniform uvec4 uConsts[2];
|
||||
|
||||
vec3 imageLoad(ivec2 point)
|
||||
{
|
||||
return texelFetch(texture, point, 0).rgb;
|
||||
return texelFetch(sampler1, point, 0).rgb;
|
||||
}
|
||||
|
||||
AF3 CasLoad(ASU2 p)
|
||||
@ -30,7 +32,7 @@ void CasInput(inout AF1 r,inout AF1 g,inout AF1 b) {}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 res = vec2(textureSize(texture, 0));
|
||||
vec2 res = vec2(textureSize(sampler1, 0));
|
||||
uvec2 point = uvec2(fragCoord * res);
|
||||
|
||||
CasFilter(
|
||||
|
@ -1,4 +1,6 @@
|
||||
#version 300 es
|
||||
#extension GL_OES_EGL_image_external_essl3 : enable
|
||||
|
||||
precision highp float;
|
||||
|
||||
#include "compat.h"
|
||||
@ -6,7 +8,7 @@ precision highp float;
|
||||
in vec2 fragCoord;
|
||||
out vec4 fragColor;
|
||||
|
||||
uniform sampler2D texture;
|
||||
uniform sampler2D sampler1;
|
||||
uniform vec2 uOutRes;
|
||||
uniform uvec4 uConsts[4];
|
||||
|
||||
@ -18,20 +20,9 @@ uniform uvec4 uConsts[4];
|
||||
|
||||
#define FSR_EASU_F 1
|
||||
|
||||
vec4 _textureGather(sampler2D tex, vec2 uv, int comp)
|
||||
{
|
||||
vec2 res = vec2(textureSize(tex, 0));
|
||||
ivec2 p = ivec2((uv * res) - 0.5f);
|
||||
vec4 c0 = texelFetchOffset(tex, p, 0, ivec2(0,1));
|
||||
vec4 c1 = texelFetchOffset(tex, p, 0, ivec2(1,1));
|
||||
vec4 c2 = texelFetchOffset(tex, p, 0, ivec2(1,0));
|
||||
vec4 c3 = texelFetchOffset(tex, p, 0, ivec2(0,0));
|
||||
return vec4(c0[comp], c1[comp], c2[comp],c3[comp]);
|
||||
}
|
||||
|
||||
AF4 FsrEasuRF(AF2 p){return AF4(_textureGather(texture, p, 0));}
|
||||
AF4 FsrEasuGF(AF2 p){return AF4(_textureGather(texture, p, 1));}
|
||||
AF4 FsrEasuBF(AF2 p){return AF4(_textureGather(texture, p, 2));}
|
||||
AF4 FsrEasuRF(AF2 p){return AF4(textureGather(sampler1, p, 0));}
|
||||
AF4 FsrEasuGF(AF2 p){return AF4(textureGather(sampler1, p, 1));}
|
||||
AF4 FsrEasuBF(AF2 p){return AF4(textureGather(sampler1, p, 2));}
|
||||
|
||||
#include "ffx_fsr1.h"
|
||||
|
||||
|
@ -6,7 +6,7 @@ precision highp float;
|
||||
in vec2 fragCoord;
|
||||
out vec4 fragColor;
|
||||
|
||||
uniform sampler2D texture;
|
||||
uniform sampler2D sampler1;
|
||||
uniform uvec4 uConsts;
|
||||
|
||||
#define A_GPU 1
|
||||
@ -15,7 +15,7 @@ uniform uvec4 uConsts;
|
||||
|
||||
#include "ffx_a.h"
|
||||
|
||||
AF4 FsrRcasLoadF(ASU2 p) { return texelFetch(texture, ASU2(p), 0); }
|
||||
AF4 FsrRcasLoadF(ASU2 p) { return texelFetch(sampler1, ASU2(p), 0); }
|
||||
void FsrRcasInputF(inout AF1 r, inout AF1 g, inout AF1 b) {}
|
||||
|
||||
#define FSR_RCAS_F 1
|
||||
@ -24,7 +24,7 @@ void FsrRcasInputF(inout AF1 r, inout AF1 g, inout AF1 b) {}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 inRes = vec2(textureSize(texture, 0));
|
||||
vec2 inRes = vec2(textureSize(sampler1, 0));
|
||||
uvec2 point = uvec2(fragCoord * (inRes + 0.5f));
|
||||
|
||||
FsrRcasF(fragColor.r, fragColor.g, fragColor.b, point, uConsts);
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "shader.h"
|
||||
#include "common/framebuffer.h"
|
||||
#include "common/debug.h"
|
||||
#include "common/array.h"
|
||||
|
||||
#include <EGL/egl.h>
|
||||
#include <EGL/eglext.h>
|
||||
@ -76,6 +77,7 @@ bool egl_textureInit(EGL_Texture ** texture_, EGLDisplay * display,
|
||||
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);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -203,14 +205,7 @@ enum EGL_TexStatus egl_textureProcess(EGL_Texture * this)
|
||||
|
||||
enum EGL_TexStatus egl_textureBind(EGL_Texture * this)
|
||||
{
|
||||
GLuint tex;
|
||||
EGL_TexStatus status;
|
||||
|
||||
if ((status = this->ops.get(this, &tex)) != EGL_TEX_STATUS_OK)
|
||||
return status;
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, tex);
|
||||
glBindSampler(0, this->sampler);
|
||||
return EGL_TEX_STATUS_OK;
|
||||
return this->ops.bind(this);
|
||||
}
|
||||
|
@ -93,6 +93,9 @@ typedef struct EGL_TextureOps
|
||||
|
||||
/* get the texture for use */
|
||||
enum EGL_TexStatus (*get)(EGL_Texture * texture, GLuint * tex);
|
||||
|
||||
/* bind the texture for use */
|
||||
enum EGL_TexStatus (*bind)(EGL_Texture * texture);
|
||||
}
|
||||
EGL_TextureOps;
|
||||
|
||||
|
@ -292,6 +292,19 @@ EGL_TexStatus egl_texBufferStreamGet(EGL_Texture * texture, GLuint * tex)
|
||||
return EGL_TEX_STATUS_OK;
|
||||
}
|
||||
|
||||
EGL_TexStatus egl_texBufferBind(EGL_Texture * texture)
|
||||
{
|
||||
GLuint tex;
|
||||
EGL_TexStatus status;
|
||||
|
||||
if ((status = texture->ops.get(texture, &tex)) != EGL_TEX_STATUS_OK)
|
||||
return status;
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, tex);
|
||||
return EGL_TEX_STATUS_OK;
|
||||
}
|
||||
|
||||
|
||||
const EGL_TextureOps EGL_TextureBuffer =
|
||||
{
|
||||
.init = egl_texBufferInit,
|
||||
@ -299,7 +312,8 @@ const EGL_TextureOps EGL_TextureBuffer =
|
||||
.setup = egl_texBufferSetup,
|
||||
.update = egl_texBufferUpdate,
|
||||
.process = egl_texBufferProcess,
|
||||
.get = egl_texBufferGet
|
||||
.get = egl_texBufferGet,
|
||||
.bind = egl_texBufferBind
|
||||
};
|
||||
|
||||
const EGL_TextureOps EGL_TextureBufferStream =
|
||||
@ -309,5 +323,6 @@ const EGL_TextureOps EGL_TextureBufferStream =
|
||||
.setup = egl_texBufferStreamSetup,
|
||||
.update = egl_texBufferStreamUpdate,
|
||||
.process = egl_texBufferStreamProcess,
|
||||
.get = egl_texBufferStreamGet
|
||||
.get = egl_texBufferStreamGet,
|
||||
.bind = egl_texBufferBind
|
||||
};
|
||||
|
@ -48,6 +48,7 @@ void egl_texBufferFree(EGL_Texture * texture_);
|
||||
bool egl_texBufferSetup(EGL_Texture * texture_, const EGL_TexSetup * setup);
|
||||
EGL_TexStatus egl_texBufferProcess(EGL_Texture * texture_);
|
||||
EGL_TexStatus egl_texBufferGet(EGL_Texture * texture_, GLuint * tex);
|
||||
EGL_TexStatus egl_texBufferBind(EGL_Texture * texture_);
|
||||
|
||||
bool egl_texBufferStreamInit(EGL_Texture ** texture_, EGL_TexType type,
|
||||
EGLDisplay * display);
|
||||
|
@ -46,12 +46,26 @@ EGL_TextureOps EGL_TextureDMABUF;
|
||||
|
||||
// internal functions
|
||||
|
||||
static void egl_texDMABUFCleanup(TexDMABUF * this)
|
||||
static void egl_texDMABUFCleanup(EGL_Texture * texture)
|
||||
{
|
||||
TextureBuffer * parent = UPCAST(TextureBuffer, texture);
|
||||
TexDMABUF * this = UPCAST(TexDMABUF , parent);
|
||||
|
||||
struct FdImage * image;
|
||||
vector_forEachRef(image, &this->images)
|
||||
g_egl_dynProcs.eglDestroyImage(this->display, image->image);
|
||||
vector_clear(&this->images);
|
||||
|
||||
egl_texUtilFreeBuffers(parent->buf, parent->texCount);
|
||||
|
||||
if (parent->tex[0])
|
||||
glDeleteTextures(parent->texCount, parent->tex);
|
||||
|
||||
if (parent->sync)
|
||||
{
|
||||
glDeleteSync(parent->sync);
|
||||
parent->sync = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// dmabuf functions
|
||||
@ -92,7 +106,7 @@ static void egl_texDMABUFFree(EGL_Texture * texture)
|
||||
TextureBuffer * parent = UPCAST(TextureBuffer, texture);
|
||||
TexDMABUF * this = UPCAST(TexDMABUF , parent);
|
||||
|
||||
egl_texDMABUFCleanup(this);
|
||||
egl_texDMABUFCleanup(texture);
|
||||
vector_destroy(&this->images);
|
||||
|
||||
egl_texBufferFree(&parent->base);
|
||||
@ -102,11 +116,27 @@ static void egl_texDMABUFFree(EGL_Texture * texture)
|
||||
static bool egl_texDMABUFSetup(EGL_Texture * texture, const EGL_TexSetup * setup)
|
||||
{
|
||||
TextureBuffer * parent = UPCAST(TextureBuffer, texture);
|
||||
TexDMABUF * this = UPCAST(TexDMABUF , parent);
|
||||
|
||||
egl_texDMABUFCleanup(this);
|
||||
egl_texDMABUFCleanup(texture);
|
||||
|
||||
return egl_texBufferSetup(&parent->base, setup);
|
||||
glGenTextures(parent->texCount, parent->tex);
|
||||
for(int i = 0; i < parent->texCount; ++i)
|
||||
{
|
||||
glBindTexture(GL_TEXTURE_EXTERNAL_OES, parent->tex[i]);
|
||||
glTexImage2D(GL_TEXTURE_EXTERNAL_OES,
|
||||
0,
|
||||
texture->format.intFormat,
|
||||
texture->format.width,
|
||||
texture->format.height,
|
||||
0,
|
||||
texture->format.format,
|
||||
texture->format.dataType,
|
||||
NULL);
|
||||
}
|
||||
|
||||
glBindTexture(GL_TEXTURE_EXTERNAL_OES, 0);
|
||||
parent->rIndex = -1;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool egl_texDMABUFUpdate(EGL_Texture * texture,
|
||||
@ -173,8 +203,8 @@ static bool egl_texDMABUFUpdate(EGL_Texture * texture,
|
||||
|
||||
INTERLOCKED_SECTION(parent->copyLock,
|
||||
{
|
||||
glBindTexture(GL_TEXTURE_2D, parent->tex[parent->bufIndex]);
|
||||
g_egl_dynProcs.glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image);
|
||||
glBindTexture(GL_TEXTURE_EXTERNAL_OES, parent->tex[parent->bufIndex]);
|
||||
g_egl_dynProcs.glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, image);
|
||||
|
||||
if (parent->sync)
|
||||
glDeleteSync(parent->sync);
|
||||
@ -238,6 +268,18 @@ static EGL_TexStatus egl_texDMABUFGet(EGL_Texture * texture, GLuint * tex)
|
||||
return EGL_TEX_STATUS_OK;
|
||||
}
|
||||
|
||||
static EGL_TexStatus egl_texDMABUFBind(EGL_Texture * texture)
|
||||
{
|
||||
GLuint tex;
|
||||
EGL_TexStatus status;
|
||||
|
||||
if ((status = egl_texDMABUFGet(texture, &tex)) != EGL_TEX_STATUS_OK)
|
||||
return status;
|
||||
|
||||
glBindTexture(GL_TEXTURE_EXTERNAL_OES, tex);
|
||||
return EGL_TEX_STATUS_OK;
|
||||
}
|
||||
|
||||
EGL_TextureOps EGL_TextureDMABUF =
|
||||
{
|
||||
.init = egl_texDMABUFInit,
|
||||
@ -245,5 +287,6 @@ EGL_TextureOps EGL_TextureDMABUF =
|
||||
.setup = egl_texDMABUFSetup,
|
||||
.update = egl_texDMABUFUpdate,
|
||||
.process = egl_texDMABUFProcess,
|
||||
.get = egl_texDMABUFGet
|
||||
.get = egl_texDMABUFGet,
|
||||
.bind = egl_texDMABUFBind
|
||||
};
|
||||
|
@ -147,5 +147,6 @@ EGL_TextureOps EGL_TextureFrameBuffer =
|
||||
.setup = egl_texFBSetup,
|
||||
.update = egl_texFBUpdate,
|
||||
.process = egl_texBufferStreamProcess,
|
||||
.get = egl_texBufferStreamGet
|
||||
.get = egl_texBufferStreamGet,
|
||||
.bind = egl_texBufferBind
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user