mirror of
https://gitlab.freedesktop.org/wlroots/wlroots.git
synced 2026-04-20 06:47:19 -04:00
wip: render/gles2: add support for 3D LUT transforms
This commit is contained in:
parent
451327d6b4
commit
ddd47368f3
3 changed files with 84 additions and 11 deletions
|
|
@ -64,6 +64,7 @@ struct wlr_gles2_renderer {
|
||||||
PFNGLPUSHDEBUGGROUPKHRPROC glPushDebugGroupKHR;
|
PFNGLPUSHDEBUGGROUPKHRPROC glPushDebugGroupKHR;
|
||||||
PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC glEGLImageTargetRenderbufferStorageOES;
|
PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC glEGLImageTargetRenderbufferStorageOES;
|
||||||
PFNGLGETGRAPHICSRESETSTATUSKHRPROC glGetGraphicsResetStatusKHR;
|
PFNGLGETGRAPHICSRESETSTATUSKHRPROC glGetGraphicsResetStatusKHR;
|
||||||
|
PFNGLTEXIMAGE3DOESPROC glTexImage3DOES;
|
||||||
} procs;
|
} procs;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
|
|
@ -121,6 +122,16 @@ enum wlr_gles2_shader_source {
|
||||||
WLR_GLES2_SHADER_SOURCE_TEXTURE_EXTERNAL = 4,
|
WLR_GLES2_SHADER_SOURCE_TEXTURE_EXTERNAL = 4,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum wlr_gles2_shader_color_transform {
|
||||||
|
WLR_GLES2_SHADER_COLOR_TRANSFORM_IDENTITY = 0,
|
||||||
|
WLR_GLES2_SHADER_COLOR_TRANSFORM_LUT_3D = 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct wlr_gles2_shader_params {
|
||||||
|
enum wlr_gles2_shader_source source;
|
||||||
|
enum wlr_gles2_shader_color_transform color_transform;
|
||||||
|
};
|
||||||
|
|
||||||
bool is_gles2_pixel_format_supported(const struct wlr_gles2_renderer *renderer,
|
bool is_gles2_pixel_format_supported(const struct wlr_gles2_renderer *renderer,
|
||||||
const struct wlr_gles2_pixel_format *format);
|
const struct wlr_gles2_pixel_format *format);
|
||||||
const struct wlr_gles2_pixel_format *get_gles2_format_from_drm(uint32_t fmt);
|
const struct wlr_gles2_pixel_format *get_gles2_format_from_drm(uint32_t fmt);
|
||||||
|
|
|
||||||
|
|
@ -627,10 +627,12 @@ static GLuint compile_shader(struct wlr_gles2_renderer *renderer,
|
||||||
}
|
}
|
||||||
|
|
||||||
static GLuint link_program(struct wlr_gles2_renderer *renderer,
|
static GLuint link_program(struct wlr_gles2_renderer *renderer,
|
||||||
enum wlr_gles2_shader_source source) {
|
const struct wlr_gles2_shader_params *params) {
|
||||||
static char frag_preamble[1024];
|
static char frag_preamble[1024];
|
||||||
snprintf(frag_preamble, sizeof(frag_preamble),
|
snprintf(frag_preamble, sizeof(frag_preamble),
|
||||||
"#define SOURCE %d\n", source);
|
"#define SOURCE %d\n"
|
||||||
|
"#define COLOR_TRANSFORM %d\n",
|
||||||
|
params->source, params->color_transform);
|
||||||
|
|
||||||
push_gles2_debug(renderer);
|
push_gles2_debug(renderer);
|
||||||
|
|
||||||
|
|
@ -676,8 +678,8 @@ error:
|
||||||
|
|
||||||
static bool link_tex_program(struct wlr_gles2_renderer *renderer,
|
static bool link_tex_program(struct wlr_gles2_renderer *renderer,
|
||||||
struct wlr_gles2_tex_shader *shader,
|
struct wlr_gles2_tex_shader *shader,
|
||||||
enum wlr_gles2_shader_source source) {
|
const struct wlr_gles2_shader_params *params) {
|
||||||
shader->program = link_program(renderer, source);
|
shader->program = link_program(renderer, params);
|
||||||
if (!shader->program) {
|
if (!shader->program) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -829,6 +831,10 @@ struct wlr_renderer *wlr_gles2_renderer_create(struct wlr_egl *egl) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (check_gl_ext(exts_str, "GL_OES_texture_3D")) {
|
||||||
|
load_gl_proc(&renderer->procs.glTexImage3DOES, "glTexImage3DOES");
|
||||||
|
}
|
||||||
|
|
||||||
if (renderer->exts.KHR_debug) {
|
if (renderer->exts.KHR_debug) {
|
||||||
glEnable(GL_DEBUG_OUTPUT_KHR);
|
glEnable(GL_DEBUG_OUTPUT_KHR);
|
||||||
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_KHR);
|
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_KHR);
|
||||||
|
|
@ -843,9 +849,18 @@ struct wlr_renderer *wlr_gles2_renderer_create(struct wlr_egl *egl) {
|
||||||
|
|
||||||
push_gles2_debug(renderer);
|
push_gles2_debug(renderer);
|
||||||
|
|
||||||
|
enum wlr_gles2_shader_color_transform color_transform =
|
||||||
|
WLR_GLES2_SHADER_COLOR_TRANSFORM_IDENTITY;
|
||||||
|
if (renderer->procs.glTexImage3DOES != NULL) {
|
||||||
|
color_transform = WLR_GLES2_SHADER_COLOR_TRANSFORM_LUT_3D;
|
||||||
|
}
|
||||||
|
|
||||||
GLuint prog;
|
GLuint prog;
|
||||||
renderer->shaders.quad.program = prog =
|
renderer->shaders.quad.program = prog =
|
||||||
link_program(renderer, WLR_GLES2_SHADER_SOURCE_SINGLE_COLOR);
|
link_program(renderer, &(struct wlr_gles2_shader_params){
|
||||||
|
.source = WLR_GLES2_SHADER_SOURCE_SINGLE_COLOR,
|
||||||
|
.color_transform = color_transform,
|
||||||
|
});
|
||||||
if (!renderer->shaders.quad.program) {
|
if (!renderer->shaders.quad.program) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
@ -854,16 +869,25 @@ struct wlr_renderer *wlr_gles2_renderer_create(struct wlr_egl *egl) {
|
||||||
renderer->shaders.quad.pos_attrib = glGetAttribLocation(prog, "pos");
|
renderer->shaders.quad.pos_attrib = glGetAttribLocation(prog, "pos");
|
||||||
|
|
||||||
if (!link_tex_program(renderer, &renderer->shaders.tex_rgba,
|
if (!link_tex_program(renderer, &renderer->shaders.tex_rgba,
|
||||||
WLR_GLES2_SHADER_SOURCE_TEXTURE_RGBA)) {
|
&(struct wlr_gles2_shader_params){
|
||||||
|
.source = WLR_GLES2_SHADER_SOURCE_TEXTURE_RGBA,
|
||||||
|
.color_transform = color_transform,
|
||||||
|
})) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
if (!link_tex_program(renderer, &renderer->shaders.tex_rgbx,
|
if (!link_tex_program(renderer, &renderer->shaders.tex_rgbx,
|
||||||
WLR_GLES2_SHADER_SOURCE_TEXTURE_RGBX)) {
|
&(struct wlr_gles2_shader_params){
|
||||||
|
.source = WLR_GLES2_SHADER_SOURCE_TEXTURE_RGBX,
|
||||||
|
.color_transform = color_transform,
|
||||||
|
})) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
if (renderer->exts.OES_egl_image_external &&
|
if (renderer->exts.OES_egl_image_external &&
|
||||||
!link_tex_program(renderer, &renderer->shaders.tex_ext,
|
!link_tex_program(renderer, &renderer->shaders.tex_ext,
|
||||||
WLR_GLES2_SHADER_SOURCE_TEXTURE_EXTERNAL)) {
|
&(struct wlr_gles2_shader_params){
|
||||||
|
.source = WLR_GLES2_SHADER_SOURCE_TEXTURE_EXTERNAL,
|
||||||
|
.color_transform = color_transform,
|
||||||
|
})) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,11 @@
|
||||||
#define SOURCE_TEXTURE_RGBX 3
|
#define SOURCE_TEXTURE_RGBX 3
|
||||||
#define SOURCE_TEXTURE_EXTERNAL 4
|
#define SOURCE_TEXTURE_EXTERNAL 4
|
||||||
|
|
||||||
#if !defined(SOURCE)
|
/* enum wlr_gles2_color_transform */
|
||||||
|
#define COLOR_TRANSFORM_IDENTITY 0
|
||||||
|
#define COLOR_TRANSFORM_LUT_3D 1
|
||||||
|
|
||||||
|
#if !defined(SOURCE) || !defined(COLOR_TRANSFORM)
|
||||||
#error "Missing shader preamble"
|
#error "Missing shader preamble"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -12,6 +16,10 @@
|
||||||
#extension GL_OES_EGL_image_external : require
|
#extension GL_OES_EGL_image_external : require
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if COLOR_TRANSFORM == COLOR_TRANSFORM_3DLUT
|
||||||
|
#extension GL_OES_texture_3D : require
|
||||||
|
#endif
|
||||||
|
|
||||||
precision mediump float;
|
precision mediump float;
|
||||||
|
|
||||||
varying vec2 v_texcoord;
|
varying vec2 v_texcoord;
|
||||||
|
|
@ -30,6 +38,12 @@ uniform float alpha;
|
||||||
const float alpha = 1.0;
|
const float alpha = 1.0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if COLOR_TRANSFORM == COLOR_TRANSFORM_LUT_3D
|
||||||
|
uniform mediump sampler3D lut_3d;
|
||||||
|
uniform float lut_3d_offset;
|
||||||
|
uniform float lut_3d_scale;
|
||||||
|
#endif
|
||||||
|
|
||||||
vec4 sample_texture() {
|
vec4 sample_texture() {
|
||||||
#if SOURCE == SOURCE_TEXTURE_RGBA || SOURCE == SOURCE_TEXTURE_EXTERNAL
|
#if SOURCE == SOURCE_TEXTURE_RGBA || SOURCE == SOURCE_TEXTURE_EXTERNAL
|
||||||
return texture2D(tex, v_texcoord);
|
return texture2D(tex, v_texcoord);
|
||||||
|
|
@ -40,6 +54,30 @@ vec4 sample_texture() {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void main() {
|
vec4 transform_color(vec4 color) {
|
||||||
gl_FragColor = sample_texture() * alpha;
|
#if COLOR_TRANSFORM == COLOR_TRANSFORM_IDENTITY
|
||||||
|
return color;
|
||||||
|
#elif COLOR_TRANSFORM == COLOR_TRANSFORM_LUT_3D
|
||||||
|
vec3 pos = lut_3d_offset + color * lut_3d_scale;
|
||||||
|
return texture3D(lut_3d, pos).rgb;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec4 color = sample_texture() * alpha;
|
||||||
|
|
||||||
|
#if COLOR_TRANSFORM != COLOR_TRANSFORM_IDENTITY
|
||||||
|
// Convert from pre-multiplied alpha to straight alpha
|
||||||
|
if (color.a == 0.0)
|
||||||
|
color.rgb = vec3(0.0, 0.0, 0.0);
|
||||||
|
else
|
||||||
|
color.rgb /= color.a;
|
||||||
|
|
||||||
|
color = transform_color(color);
|
||||||
|
|
||||||
|
// Convert from straight alpha to pre-multiplied alpha
|
||||||
|
color.rgb *= color.a;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
gl_FragColor = color;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue