mirror of
https://gitlab.freedesktop.org/wlroots/wlroots.git
synced 2026-04-18 06:47:31 -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;
|
||||
PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC glEGLImageTargetRenderbufferStorageOES;
|
||||
PFNGLGETGRAPHICSRESETSTATUSKHRPROC glGetGraphicsResetStatusKHR;
|
||||
PFNGLTEXIMAGE3DOESPROC glTexImage3DOES;
|
||||
} procs;
|
||||
|
||||
struct {
|
||||
|
|
@ -121,6 +122,16 @@ enum wlr_gles2_shader_source {
|
|||
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,
|
||||
const struct wlr_gles2_pixel_format *format);
|
||||
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,
|
||||
enum wlr_gles2_shader_source source) {
|
||||
const struct wlr_gles2_shader_params *params) {
|
||||
static char frag_preamble[1024];
|
||||
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);
|
||||
|
||||
|
|
@ -676,8 +678,8 @@ error:
|
|||
|
||||
static bool link_tex_program(struct wlr_gles2_renderer *renderer,
|
||||
struct wlr_gles2_tex_shader *shader,
|
||||
enum wlr_gles2_shader_source source) {
|
||||
shader->program = link_program(renderer, source);
|
||||
const struct wlr_gles2_shader_params *params) {
|
||||
shader->program = link_program(renderer, params);
|
||||
if (!shader->program) {
|
||||
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) {
|
||||
glEnable(GL_DEBUG_OUTPUT_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);
|
||||
|
||||
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;
|
||||
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) {
|
||||
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");
|
||||
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
if (renderer->exts.OES_egl_image_external &&
|
||||
!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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,11 @@
|
|||
#define SOURCE_TEXTURE_RGBX 3
|
||||
#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"
|
||||
#endif
|
||||
|
||||
|
|
@ -12,6 +16,10 @@
|
|||
#extension GL_OES_EGL_image_external : require
|
||||
#endif
|
||||
|
||||
#if COLOR_TRANSFORM == COLOR_TRANSFORM_3DLUT
|
||||
#extension GL_OES_texture_3D : require
|
||||
#endif
|
||||
|
||||
precision mediump float;
|
||||
|
||||
varying vec2 v_texcoord;
|
||||
|
|
@ -30,6 +38,12 @@ uniform float alpha;
|
|||
const float alpha = 1.0;
|
||||
#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() {
|
||||
#if SOURCE == SOURCE_TEXTURE_RGBA || SOURCE == SOURCE_TEXTURE_EXTERNAL
|
||||
return texture2D(tex, v_texcoord);
|
||||
|
|
@ -40,6 +54,30 @@ vec4 sample_texture() {
|
|||
#endif
|
||||
}
|
||||
|
||||
void main() {
|
||||
gl_FragColor = sample_texture() * alpha;
|
||||
vec4 transform_color(vec4 color) {
|
||||
#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