mirror of
https://gitlab.freedesktop.org/wayland/weston.git
synced 2026-05-02 16:38:22 +02:00
renderer-gl: implement blend shader
This prepares the fragment shader for blending in-shader instead of using the fixed-function blending. This is not yet used, but it will allow avoiding the 16F shadow framebuffer in the future. TEX_UNIT_LAST is actually a count rather than the index of the last unit. Fix the off-by-one in the check. The FB fetch/store curves push our potential texture count beyond 8, so implement a runtime check. Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.com>
This commit is contained in:
parent
27fd323478
commit
a798e75257
4 changed files with 136 additions and 23 deletions
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright 2012 Intel Corporation
|
||||
* Copyright 2015,2019,2021 Collabora, Ltd.
|
||||
* Copyright 2015,2019,2021-2025 Collabora, Ltd.
|
||||
* Copyright 2016 NVIDIA Corporation
|
||||
* Copyright 2021 Advanced Micro Devices, Inc.
|
||||
*
|
||||
|
|
@ -68,6 +68,10 @@
|
|||
#extension GL_OES_texture_3D : require
|
||||
#endif
|
||||
|
||||
#if DEF_SHADER_BLENDING
|
||||
#extension GL_EXT_shader_framebuffer_fetch_non_coherent : require
|
||||
#endif
|
||||
|
||||
#ifdef GL_FRAGMENT_PRECISION_HIGH
|
||||
#define HIGHPRECISION highp
|
||||
#else
|
||||
|
|
@ -84,6 +88,8 @@ compile_const int c_variant = DEF_VARIANT;
|
|||
compile_const int c_color_pre_curve = DEF_COLOR_PRE_CURVE;
|
||||
compile_const int c_color_mapping = DEF_COLOR_MAPPING;
|
||||
compile_const int c_color_post_curve = DEF_COLOR_POST_CURVE;
|
||||
compile_const int c_fb_fetch_curve = DEF_FB_FETCH_CURVE;
|
||||
compile_const int c_fb_store_curve = DEF_FB_STORE_CURVE;
|
||||
compile_const int c_color_effect = DEF_COLOR_EFFECT;
|
||||
|
||||
compile_const bool c_input_is_premult = DEF_INPUT_IS_PREMULT;
|
||||
|
|
@ -160,6 +166,15 @@ uniform HIGHPRECISION vec3 color_mapping_offset;
|
|||
|
||||
uniform HIGHPRECISION mat3 cvd_correction_matrix;
|
||||
|
||||
uniform lut_2d_t fb_fetch_curve_lut;
|
||||
uniform parametric_curve_t fb_fetch_curve_par;
|
||||
|
||||
uniform lut_2d_t fb_store_curve_lut;
|
||||
uniform parametric_curve_t fb_store_curve_par;
|
||||
|
||||
uniform HIGHPRECISION mat3 color_cvd_simulation;
|
||||
uniform HIGHPRECISION mat3 color_cvd_redistribution;
|
||||
|
||||
/*
|
||||
* 2D texture sampler abstracting away the lack of swizzles on OpenGL ES 2. This
|
||||
* should only be used by code relying on swizzling. 'unit' is the texture unit
|
||||
|
|
@ -505,8 +520,8 @@ wireframe()
|
|||
return vec4(clamp(edge1 + edge2 + edge3, 0.0, 1.0));
|
||||
}
|
||||
|
||||
void
|
||||
main()
|
||||
vec4
|
||||
fragment_input_color_premult()
|
||||
{
|
||||
vec4 color;
|
||||
|
||||
|
|
@ -545,5 +560,41 @@ main()
|
|||
color = color * vec4(1.0 - src.a) + src;
|
||||
}
|
||||
|
||||
gl_FragColor = color;
|
||||
return color;
|
||||
}
|
||||
|
||||
#if DEF_SHADER_BLENDING
|
||||
|
||||
layout(noncoherent) mediump vec4 gl_LastFragData[gl_MaxDrawBuffers];
|
||||
|
||||
void
|
||||
main()
|
||||
{
|
||||
vec4 src;
|
||||
vec4 dst;
|
||||
|
||||
src = fragment_input_color_premult();
|
||||
|
||||
/* Framebuffer must have straight alpha. */
|
||||
dst = gl_LastFragData[0];
|
||||
dst.rgb = color_curve(c_fb_fetch_curve, fb_fetch_curve_lut,
|
||||
fb_fetch_curve_par, dst.rgb);
|
||||
|
||||
/* glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); */
|
||||
dst = src + (1.0 - src.a) * dst;
|
||||
|
||||
dst.rgb = color_curve(c_fb_store_curve, fb_store_curve_lut,
|
||||
fb_store_curve_par, dst.rgb);
|
||||
|
||||
gl_FragColor = dst;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void
|
||||
main()
|
||||
{
|
||||
gl_FragColor = fragment_input_color_premult();
|
||||
}
|
||||
|
||||
#endif /* DEF_SHADER_BLENDING */
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright © 2019 Collabora, Ltd.
|
||||
* Copyright © 2019-2025 Collabora, Ltd.
|
||||
* Copyright © 2019 Harish Krupo
|
||||
* Copyright © 2019 Intel Corporation
|
||||
* Copyright 2021 Advanced Micro Devices, Inc.
|
||||
|
|
@ -134,14 +134,15 @@ enum gl_extension_flag {
|
|||
EXTENSION_EXT_EGL_IMAGE_STORAGE = 1ull << 8,
|
||||
EXTENSION_EXT_MAP_BUFFER_RANGE = 1ull << 9,
|
||||
EXTENSION_EXT_READ_FORMAT_BGRA = 1ull << 10,
|
||||
EXTENSION_EXT_TEXTURE_FORMAT_BGRA8888 = 1ull << 11,
|
||||
EXTENSION_EXT_TEXTURE_NORM16 = 1ull << 12,
|
||||
EXTENSION_EXT_TEXTURE_RG = 1ull << 13,
|
||||
EXTENSION_EXT_TEXTURE_SRGB_R8 = 1ull << 14,
|
||||
EXTENSION_EXT_TEXTURE_SRGB_RG8 = 1ull << 15,
|
||||
EXTENSION_EXT_TEXTURE_STORAGE = 1ull << 16,
|
||||
EXTENSION_EXT_TEXTURE_TYPE_2_10_10_10_REV = 1ull << 17,
|
||||
EXTENSION_EXT_UNPACK_SUBIMAGE = 1ull << 18,
|
||||
EXTENSION_EXT_SHADER_FB_FETCH_NC = 1ull << 11,
|
||||
EXTENSION_EXT_TEXTURE_FORMAT_BGRA8888 = 1ull << 12,
|
||||
EXTENSION_EXT_TEXTURE_NORM16 = 1ull << 13,
|
||||
EXTENSION_EXT_TEXTURE_RG = 1ull << 14,
|
||||
EXTENSION_EXT_TEXTURE_SRGB_R8 = 1ull << 15,
|
||||
EXTENSION_EXT_TEXTURE_SRGB_RG8 = 1ull << 16,
|
||||
EXTENSION_EXT_TEXTURE_STORAGE = 1ull << 17,
|
||||
EXTENSION_EXT_TEXTURE_TYPE_2_10_10_10_REV = 1ull << 18,
|
||||
EXTENSION_EXT_UNPACK_SUBIMAGE = 1ull << 19,
|
||||
EXTENSION_NV_PACKED_FLOAT = 1ull << 20,
|
||||
EXTENSION_NV_PIXEL_BUFFER_OBJECT = 1ull << 21,
|
||||
EXTENSION_OES_EGL_IMAGE = 1ull << 22,
|
||||
|
|
@ -203,6 +204,10 @@ enum gl_feature_flag {
|
|||
|
||||
/* GL renderer can create 3D textures. */
|
||||
FEATURE_TEXTURE_3D = 1ull << 9,
|
||||
|
||||
/* GL renderer can do blending explicitly in the fragment shader,
|
||||
* using framebuffer fetch and store curves. */
|
||||
FEATURE_SHADER_BLENDING = 1ull << 10,
|
||||
};
|
||||
|
||||
/* Keep the following in sync with vertex.glsl. */
|
||||
|
|
@ -259,12 +264,16 @@ enum gl_tex_unit {
|
|||
TEX_UNIT_COLOR_MAPPING,
|
||||
TEX_UNIT_COLOR_POST_CURVE,
|
||||
TEX_UNIT_WIREFRAME,
|
||||
TEX_UNIT_LAST,
|
||||
|
||||
TEX_UNIT_COUNT_REQUIRED,
|
||||
/* For all units below, check gr->max_texture_image_units etc. */
|
||||
|
||||
TEX_UNIT_FB_FETCH_CURVE = TEX_UNIT_COUNT_REQUIRED,
|
||||
TEX_UNIT_FB_STORE_CURVE,
|
||||
TEX_UNIT_COUNT_OPTIONAL,
|
||||
};
|
||||
static_assert(TEX_UNIT_LAST < 8, "OpenGL ES 2.0 requires at least 8 texture "
|
||||
"units. Consider replacing this assert with a "
|
||||
"GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS check at display creation "
|
||||
"to require more.");
|
||||
static_assert(TEX_UNIT_COUNT_REQUIRED <= 8, "OpenGL ES 2.0 requires at least 8 texture "
|
||||
"units. Cannot assume having more without a runtime check.");
|
||||
|
||||
enum gl_bgra8_texture_support {
|
||||
BGRA8_TEXTURE_SUPPORT_STORAGE = 0,
|
||||
|
|
@ -303,11 +312,15 @@ struct gl_shader_requirements
|
|||
unsigned color_mapping:2; /* enum gl_shader_color_mapping */
|
||||
unsigned color_post_curve:3; /* enum gl_shader_color_curve */
|
||||
|
||||
bool shader_blending:1;
|
||||
unsigned fb_fetch_curve:3; /* enum gl_shader_color_curve */
|
||||
unsigned fb_store_curve:3; /* enum gl_shader_color_curve */
|
||||
|
||||
/*
|
||||
* The total size of all bitfields plus pad_bits_ must fill up exactly
|
||||
* how many bytes the compiler allocates for them together.
|
||||
*/
|
||||
unsigned pad_bits_:14;
|
||||
unsigned pad_bits_:7;
|
||||
};
|
||||
static_assert(sizeof(struct gl_shader_requirements) ==
|
||||
4 /* total bitfield size in bytes */,
|
||||
|
|
@ -389,6 +402,9 @@ struct gl_shader_config {
|
|||
union gl_shader_config_color_mapping color_mapping;
|
||||
union gl_shader_config_color_curve color_post_curve;
|
||||
|
||||
union gl_shader_config_color_curve fb_fetch_curve;
|
||||
union gl_shader_config_color_curve fb_store_curve;
|
||||
|
||||
enum weston_color_matrix_coef yuv_coefficients;
|
||||
enum weston_color_quant_range yuv_range;
|
||||
};
|
||||
|
|
@ -504,10 +520,15 @@ struct gl_renderer {
|
|||
PFNGLTEXSTORAGE2DEXTPROC tex_storage_2d;
|
||||
PFNGLTEXSTORAGE3DEXTPROC tex_storage_3d;
|
||||
|
||||
/* GL_EXT_shader_framebuffer_fetch_non_coherent */
|
||||
PFNGLFRAMEBUFFERFETCHBARRIEREXTPROC framebuffer_fetch_barrier;
|
||||
|
||||
uint64_t features;
|
||||
|
||||
GLenum pbo_usage;
|
||||
enum gl_bgra8_texture_support bgra8_texture_support;
|
||||
int max_texture_image_units;
|
||||
int max_combined_texture_image_units;
|
||||
|
||||
bool blend_state;
|
||||
|
||||
|
|
|
|||
|
|
@ -331,6 +331,7 @@ static const struct gl_extension_table extension_table[] = {
|
|||
EXT("GL_EXT_EGL_image_storage", EXTENSION_EXT_EGL_IMAGE_STORAGE),
|
||||
EXT("GL_EXT_map_buffer_range", EXTENSION_EXT_MAP_BUFFER_RANGE),
|
||||
EXT("GL_EXT_read_format_bgra", EXTENSION_EXT_READ_FORMAT_BGRA),
|
||||
EXT("GL_EXT_shader_framebuffer_fetch_non_coherent", EXTENSION_EXT_SHADER_FB_FETCH_NC),
|
||||
EXT("GL_EXT_texture_format_BGRA8888", EXTENSION_EXT_TEXTURE_FORMAT_BGRA8888),
|
||||
EXT("GL_EXT_texture_norm16", EXTENSION_EXT_TEXTURE_NORM16),
|
||||
EXT("GL_EXT_texture_rg", EXTENSION_EXT_TEXTURE_RG),
|
||||
|
|
@ -5272,6 +5273,10 @@ gl_renderer_setup(struct weston_compositor *ec)
|
|||
}
|
||||
|
||||
gr->gl_version = get_gl_version();
|
||||
glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS,
|
||||
&gr->max_texture_image_units);
|
||||
glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS,
|
||||
&gr->max_combined_texture_image_units);
|
||||
log_gl_info(gr);
|
||||
|
||||
extensions = (const char *) glGetString(GL_EXTENSIONS);
|
||||
|
|
@ -5414,6 +5419,14 @@ gl_renderer_setup(struct weston_compositor *ec)
|
|||
if (gl_has_sized_bgra8_renderbuffer(gr))
|
||||
gr->features |= FEATURE_SIZED_BGRA8_RENDERBUFFER;
|
||||
|
||||
/* Shader blending feature. */
|
||||
if (gl_extensions_has(gr, EXTENSION_EXT_SHADER_FB_FETCH_NC) &&
|
||||
gr->max_texture_image_units >= TEX_UNIT_COUNT_OPTIONAL &&
|
||||
gr->max_combined_texture_image_units >= TEX_UNIT_COUNT_OPTIONAL) {
|
||||
GET_PROC_ADDRESS(gr->framebuffer_fetch_barrier, "glFramebufferFetchBarrierEXT");
|
||||
gr->features |= FEATURE_SHADER_BLENDING;
|
||||
}
|
||||
|
||||
gr->bgra8_texture_support = gl_get_bgra8_texture_support(gr);
|
||||
|
||||
wl_list_init(&gr->pending_capture_list);
|
||||
|
|
@ -5457,6 +5470,8 @@ gl_renderer_setup(struct weston_compositor *ec)
|
|||
weston_log_continue(STAMP_SPACE "Required precision: %s\n",
|
||||
yesno(gr->gl_version >= gl_version(3, 0) ||
|
||||
gl_extensions_has(gr, EXTENSION_OES_REQUIRED_INTERNALFORMAT)));
|
||||
weston_log_continue(STAMP_SPACE "In-shader blending: %s\n",
|
||||
yesno(gl_features_has(gr, FEATURE_SHADER_BLENDING)));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright 2012 Intel Corporation
|
||||
* Copyright 2015,2019,2021 Collabora, Ltd.
|
||||
* Copyright 2015,2019,2021-2025 Collabora, Ltd.
|
||||
* Copyright 2016 NVIDIA Corporation
|
||||
* Copyright 2019 Harish Krupo
|
||||
* Copyright 2019 Intel Corporation
|
||||
|
|
@ -95,6 +95,8 @@ struct gl_shader {
|
|||
union gl_shader_color_curve_uniforms color_pre_curve;
|
||||
union gl_shader_color_mapping_uniforms color_mapping;
|
||||
union gl_shader_color_curve_uniforms color_post_curve;
|
||||
union gl_shader_color_curve_uniforms fb_fetch_curve;
|
||||
union gl_shader_color_curve_uniforms fb_store_curve;
|
||||
GLint yuv_offsets_uniform;
|
||||
GLint yuv_coefficients_uniform;
|
||||
};
|
||||
|
|
@ -241,7 +243,7 @@ create_shader_description_string(const struct gl_shader_requirements *req)
|
|||
int size;
|
||||
char *str;
|
||||
|
||||
size = asprintf(&str, "%s %s %s %s %s %s %cinput_is_premult %ctint",
|
||||
size = asprintf(&str, "%s %s %s %s %s %s %cinput_is_premult %ctint %cshader_blending (%s, %s)",
|
||||
gl_shader_texcoord_input_to_string(req->texcoord_input),
|
||||
gl_shader_texture_variant_to_string(req->variant),
|
||||
gl_shader_color_effect_to_string(req->color_effect),
|
||||
|
|
@ -249,7 +251,10 @@ create_shader_description_string(const struct gl_shader_requirements *req)
|
|||
gl_shader_color_mapping_to_string(req->color_mapping),
|
||||
gl_shader_color_curve_to_string(req->color_post_curve),
|
||||
req->input_is_premult ? '+' : '-',
|
||||
req->tint ? '+' : '-');
|
||||
req->tint ? '+' : '-',
|
||||
req->shader_blending ? '+' : '-',
|
||||
gl_shader_color_curve_to_string(req->fb_fetch_curve),
|
||||
gl_shader_color_curve_to_string(req->fb_store_curve));
|
||||
if (size < 0)
|
||||
return NULL;
|
||||
return str;
|
||||
|
|
@ -286,6 +291,9 @@ create_fragment_shader_config_string(const struct gl_shader_requirements *req)
|
|||
"#define DEF_COLOR_PRE_CURVE %s\n"
|
||||
"#define DEF_COLOR_MAPPING %s\n"
|
||||
"#define DEF_COLOR_POST_CURVE %s\n"
|
||||
"#define DEF_SHADER_BLENDING %s\n"
|
||||
"#define DEF_FB_FETCH_CURVE %s\n"
|
||||
"#define DEF_FB_STORE_CURVE %s\n"
|
||||
"#define DEF_COLOR_EFFECT %s\n"
|
||||
"#define DEF_VARIANT %s\n",
|
||||
ARRAY_LENGTH(((union weston_color_curve_parametric_chan_data){}).data),
|
||||
|
|
@ -295,6 +303,9 @@ create_fragment_shader_config_string(const struct gl_shader_requirements *req)
|
|||
gl_shader_color_curve_to_string(req->color_pre_curve),
|
||||
gl_shader_color_mapping_to_string(req->color_mapping),
|
||||
gl_shader_color_curve_to_string(req->color_post_curve),
|
||||
req->shader_blending ? "1" : "0",
|
||||
gl_shader_color_curve_to_string(req->fb_fetch_curve),
|
||||
gl_shader_color_curve_to_string(req->fb_store_curve),
|
||||
gl_shader_color_effect_to_string(req->color_effect),
|
||||
gl_shader_texture_variant_to_string(req->variant));
|
||||
if (size < 0)
|
||||
|
|
@ -505,8 +516,14 @@ gl_shader_create(struct gl_renderer *gr,
|
|||
shader->yuv_offsets_uniform = glGetUniformLocation(shader->program,
|
||||
"yuv_offsets");
|
||||
|
||||
free(conf);
|
||||
get_curve_uniform_locations(gr, &shader->fb_fetch_curve,
|
||||
requirements->fb_fetch_curve,
|
||||
shader->program, "fb_fetch_curve");
|
||||
get_curve_uniform_locations(gr, &shader->fb_store_curve,
|
||||
requirements->fb_store_curve,
|
||||
shader->program, "fb_store_curve");
|
||||
|
||||
free(conf);
|
||||
wl_list_insert(&gr->shader_list, &shader->link);
|
||||
|
||||
return shader;
|
||||
|
|
@ -919,6 +936,15 @@ gl_shader_load_config(struct gl_renderer *gr,
|
|||
if (sconf->req.wireframe)
|
||||
glUniform1i(shader->tex_uniform_wireframe, TEX_UNIT_WIREFRAME);
|
||||
|
||||
if (sconf->req.shader_blending) {
|
||||
gl_shader_load_config_curve(gr->compositor, sconf->req.fb_fetch_curve,
|
||||
&sconf->fb_fetch_curve, &shader->fb_fetch_curve,
|
||||
TEX_UNIT_FB_FETCH_CURVE);
|
||||
gl_shader_load_config_curve(gr->compositor, sconf->req.fb_store_curve,
|
||||
&sconf->fb_store_curve, &shader->fb_store_curve,
|
||||
TEX_UNIT_FB_STORE_CURVE);
|
||||
}
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue