xserver: Branch 'server-21.1-branch' - 38 commits
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Wed Jul 2 06:40:55 UTC 2025
glamor/Makefile.am | 7
glamor/glamor.c | 136 +++++----
glamor/glamor.h | 6
glamor/glamor_composite_glyphs.c | 52 ++-
glamor/glamor_copy.c | 12
glamor/glamor_core.c | 5
glamor/glamor_dash.c | 14
glamor/glamor_egl.c | 300 +++++++++++++------
glamor/glamor_glx_provider.c | 437 +++++++++++++++++++++++++++++
glamor/glamor_glx_provider.h | 37 ++
glamor/glamor_glyphblt.c | 3
glamor/glamor_gradient.c | 68 +++-
glamor/glamor_lines.c | 2
glamor/glamor_points.c | 5
glamor/glamor_priv.h | 37 ++
glamor/glamor_program.c | 65 ++--
glamor/glamor_program.h | 5
glamor/glamor_rects.c | 4
glamor/glamor_render.c | 126 ++++++--
glamor/glamor_segs.c | 2
glamor/glamor_spans.c | 2
glamor/glamor_text.c | 14
glamor/glamor_transfer.c | 4
glamor/glamor_xv.c | 336 +++++++++++++++++-----
glamor/meson.build | 5
hw/xfree86/glamor_egl/Makefile.am | 1
hw/xfree86/glamor_egl/meson.build | 2
hw/xfree86/man/xorg.conf.man | 8
include/fourcc.h | 39 ++
render/picture.h | 5
test/bugs/bug1354.c | 149 +++++++++
test/bugs/meson.build | 50 +++
test/meson.build | 58 +++
test/scripts/xephyr-glamor-gles2-piglit.sh | 34 ++
34 files changed, 1687 insertions(+), 343 deletions(-)
New commits:
commit b53d9fa4176679cd7b2a031c5e2d25cac5b9aa77
Author: Icenowy Zheng <uwu at icenowy.me>
Date: Sat Dec 14 01:07:31 2024 +0800
glamor: Fix dual blend on GLES3
The EXT_blend_func_extended extension on ESSL always requires explicit
request to allow two FS out variables because of limitations of the ESSL
language, which is mentioned as the No.6 issue of the extension's
specification.
Fix this by adding the extension request.
The original behavior on GLES3 is slightly against the specification of
GL_EXT_blend_func_extended extension, however Mesa and older version of
PowerVR closed drivers will just ignore this issue. Newest PowerVR
closed driver will bail out on this problem, so it deems a fix now.
Fixes: ee107cd4911e ("glamor: support GLES3 shaders")
Signed-off-by: Icenowy Zheng <uwu at icenowy.me>
(cherry picked from commit eba15f1ba75bc041d54693ebc62a8b9957b8b033)
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1636>
diff --git a/glamor/glamor_composite_glyphs.c b/glamor/glamor_composite_glyphs.c
index 102ed4640..231fa0751 100644
--- a/glamor/glamor_composite_glyphs.c
+++ b/glamor/glamor_composite_glyphs.c
@@ -177,6 +177,24 @@ glamor_glyph_add(struct glamor_glyph_atlas *atlas, DrawablePtr glyph_draw)
return TRUE;
}
+static const glamor_facet glamor_facet_composite_glyphs_es300 = {
+ .name = "composite_glyphs",
+ .version = 130,
+ .fs_extensions = ("#extension GL_EXT_blend_func_extended : enable\n"),
+ .vs_vars = ("in vec4 primitive;\n"
+ "in vec2 source;\n"
+ "out vec2 glyph_pos;\n"),
+ .vs_exec = (" vec2 pos = primitive.zw * vec2(gl_VertexID&1, (gl_VertexID&2)>>1);\n"
+ GLAMOR_POS(gl_Position, (primitive.xy + pos))
+ " glyph_pos = (source + pos) * ATLAS_DIM_INV;\n"),
+ .fs_vars = ("in vec2 glyph_pos;\n"
+ "out vec4 color0;\n"
+ "out vec4 color1;\n"),
+ .fs_exec = (" vec4 mask = texture(atlas, glyph_pos);\n"),
+ .source_name = "source",
+ .locations = glamor_program_location_atlas,
+};
+
static const glamor_facet glamor_facet_composite_glyphs_130 = {
.name = "composite_glyphs",
.version = 130,
@@ -453,7 +471,9 @@ glamor_composite_glyphs(CARD8 op,
if (glamor_glsl_has_ints(glamor_priv))
prog = glamor_setup_program_render(op, src, glyph_pict, dst,
glyphs_program,
- &glamor_facet_composite_glyphs_130,
+ glamor_priv->is_gles ?
+ &glamor_facet_composite_glyphs_es300 :
+ &glamor_facet_composite_glyphs_130,
glamor_priv->glyph_defines);
else
prog = glamor_setup_program_render(op, src, glyph_pict, dst,
commit b89a563882f234f6949a874770d3ca075d2d2fdc
Author: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer at amd.com>
Date: Thu Jan 16 10:08:15 2025 +0100
glamor: reject configs using unsupported rgbBits size
The supported color depths is a hardcoded list for now, so we
need to honor the value exposed there otherwise we'll get
inconsistencies between what glXGetFBConfigs and XListDepths
report to applications.
Signed-off-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer at amd.com>
(cherry picked from commit 5397854877c1b17f21c16e43365e1c2e353dc8ba)
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1636>
diff --git a/glamor/glamor_glx_provider.c b/glamor/glamor_glx_provider.c
index 77ccc3c8b..c27141c7c 100644
--- a/glamor/glamor_glx_provider.c
+++ b/glamor/glamor_glx_provider.c
@@ -140,12 +140,14 @@ egl_create_glx_drawable(ClientPtr client, __GLXscreen *screen,
* - drawable type masks is suspicious
*/
static struct egl_config *
-translate_eglconfig(struct egl_screen *screen, EGLConfig hc,
+translate_eglconfig(ScreenPtr pScreen, struct egl_screen *screen, EGLConfig hc,
struct egl_config *chain, Bool direct_color,
Bool double_buffer, Bool duplicate_for_composite,
Bool srgb_only)
{
EGLint value;
+ bool valid_depth;
+ int i;
struct egl_config *c = calloc(1, sizeof *c);
if (!c)
@@ -218,6 +220,19 @@ translate_eglconfig(struct egl_screen *screen, EGLConfig hc,
}
#undef GET
+ /* Only expose this config if rgbBits matches a supported
+ * depth value.
+ */
+ valid_depth = false;
+ for (i = 0; i < pScreen->numDepths && !valid_depth; i++) {
+ if (pScreen->allowedDepths[i].depth == c->base.rgbBits)
+ valid_depth = true;
+ }
+ if (!valid_depth) {
+ free(c);
+ return chain;
+ }
+
/* derived state: config caveats */
eglGetConfigAttrib(screen->display, hc, EGL_CONFIG_CAVEAT, &value);
if (value == EGL_NONE)
@@ -340,13 +355,13 @@ egl_mirror_configs(ScreenPtr pScreen, struct egl_screen *screen)
for (j = 0; j < 3; j++) /* direct_color */
for (k = 0; k < 2; k++) /* double_buffer */ {
if (can_srgb)
- c = translate_eglconfig(screen, host_configs[i], c,
+ c = translate_eglconfig(pScreen, screen, host_configs[i], c,
/* direct_color */ j == 1,
/* double_buffer */ k > 0,
/* duplicate_for_composite */ j == 0,
/* srgb_only */ true);
- c = translate_eglconfig(screen, host_configs[i], c,
+ c = translate_eglconfig(pScreen, screen, host_configs[i], c,
/* direct_color */ j == 1,
/* double_buffer */ k > 0,
/* duplicate_for_composite */ j == 0,
commit 339edca178f45c85924090550350a530a23e17c3
Author: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer at amd.com>
Date: Wed Jan 15 18:34:27 2025 +0100
glamor: use gbm_format_for_depth instead of open-coding it
This way glamor_back_pixmap_from_fd deals with the same depth
values as glamor_pixmap_from_fds.
Signed-off-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer at amd.com>
(cherry picked from commit 83b13387ab8b28cbdfeb44f05e019a656214d722)
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1636>
diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
index da97cb430..d1896340f 100644
--- a/glamor/glamor_egl.c
+++ b/glamor/glamor_egl.c
@@ -561,17 +561,14 @@ glamor_back_pixmap_from_fd(PixmapPtr pixmap,
glamor_egl = glamor_egl_get_screen_private(scrn);
- if (bpp != 32 || !(depth == 24 || depth == 32 || depth == 30) || width == 0 || height == 0)
+ if (!gbm_format_for_depth(depth, &import_data.format) ||
+ width == 0 || height == 0)
return FALSE;
import_data.fd = fd;
import_data.width = width;
import_data.height = height;
import_data.stride = stride;
- if (depth == 30)
- import_data.format = GBM_FORMAT_ARGB2101010;
- else
- import_data.format = GBM_FORMAT_ARGB8888;
bo = gbm_bo_import(glamor_egl->gbm, GBM_BO_IMPORT_FD, &import_data, 0);
if (!bo)
return FALSE;
commit 4f6f1813b6a3f047cd2b8e610747300255aa5687
Author: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer at amd.com>
Date: Wed Jan 15 18:32:46 2025 +0100
glamor: return the result of gbm_format_for_depth
This way the caller knows if the conversion failed.
While at it, check for width/height at the same time.
Signed-off-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer at amd.com>
(cherry picked from commit 87afcc7699f1d143ca91b6ed9bdbfafbbe0d77f7)
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1636>
diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
index 4de7a9902..da97cb430 100644
--- a/glamor/glamor_egl.c
+++ b/glamor/glamor_egl.c
@@ -520,6 +520,31 @@ glamor_egl_fd_name_from_pixmap(ScreenPtr screen,
return fd;
}
+static bool
+gbm_format_for_depth(CARD8 depth, uint32_t *format)
+{
+ switch (depth) {
+ case 15:
+ *format = GBM_FORMAT_ARGB1555;
+ return true;
+ case 16:
+ *format = GBM_FORMAT_RGB565;
+ return true;
+ case 24:
+ *format = GBM_FORMAT_XRGB8888;
+ return true;
+ case 30:
+ *format = GBM_FORMAT_ARGB2101010;
+ return true;
+ case 32:
+ *format = GBM_FORMAT_ARGB8888;
+ return true;
+ default:
+ ErrorF("unexpected depth: %d\n", depth);
+ return false;
+ }
+}
+
_X_EXPORT Bool
glamor_back_pixmap_from_fd(PixmapPtr pixmap,
int fd,
@@ -558,25 +583,6 @@ glamor_back_pixmap_from_fd(PixmapPtr pixmap,
return ret;
}
-static uint32_t
-gbm_format_for_depth(CARD8 depth)
-{
- switch (depth) {
- case 15:
- return GBM_FORMAT_ARGB1555;
- case 16:
- return GBM_FORMAT_RGB565;
- case 24:
- return GBM_FORMAT_XRGB8888;
- case 30:
- return GBM_FORMAT_ARGB2101010;
- default:
- ErrorF("unexpected depth: %d\n", depth);
- case 32:
- return GBM_FORMAT_ARGB8888;
- }
-}
-
_X_EXPORT PixmapPtr
glamor_pixmap_from_fds(ScreenPtr screen,
CARD8 num_fds, const int *fds,
@@ -599,6 +605,10 @@ glamor_pixmap_from_fds(ScreenPtr screen,
struct gbm_import_fd_modifier_data import_data = { 0 };
struct gbm_bo *bo;
+ if (!gbm_format_for_depth(depth, &import_data.format) ||
+ width == 0 || height == 0)
+ goto error;
+
import_data.width = width;
import_data.height = height;
import_data.num_fds = num_fds;
@@ -608,7 +618,6 @@ glamor_pixmap_from_fds(ScreenPtr screen,
import_data.strides[i] = strides[i];
import_data.offsets[i] = offsets[i];
}
- import_data.format = gbm_format_for_depth(depth);
bo = gbm_bo_import(glamor_egl->gbm, GBM_BO_IMPORT_FD_MODIFIER, &import_data, 0);
if (bo) {
screen->ModifyPixmapHeader(pixmap, width, height, 0, 0, strides[0], NULL);
@@ -624,6 +633,7 @@ glamor_pixmap_from_fds(ScreenPtr screen,
}
}
+error:
if (ret == FALSE) {
screen->DestroyPixmap(pixmap);
return NULL;
commit 33a9f47205f6e30538d785ea7f8c82377fe087d5
Author: Michel Dänzer <michel at daenzer.net>
Date: Thu Apr 25 17:16:26 2024 +0200
xwayland/glamor: Handle depth 15 in gbm_format_for_depth
Prevents Xwayland with glamor from logging
unexpected depth: 15
to stderr many times when running
rendercheck -t blend -o clear
(cherry picked from commit 08113b8923a83aa7018463e71b6e2db3661b8604)
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1636>
diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
index 6e24ffdd7..4de7a9902 100644
--- a/glamor/glamor_egl.c
+++ b/glamor/glamor_egl.c
@@ -562,6 +562,8 @@ static uint32_t
gbm_format_for_depth(CARD8 depth)
{
switch (depth) {
+ case 15:
+ return GBM_FORMAT_ARGB1555;
case 16:
return GBM_FORMAT_RGB565;
case 24:
commit d4cf52524ddb72d31f646be62067e77288a91844
Author: Balló György <ballogyor at gmail.com>
Date: Thu Oct 5 14:30:33 2023 +0200
glamor: Fallback to software rendering on GLSL link failure
Instead of thowing fatal error on GLSL link failure, fall back to software
rendering. This allows using Glamor on systems with limited hardware resources
(such as i915).
(cherry picked from commit 007e98b18665ec76c48e0923f10431175755386f)
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1636>
diff --git a/glamor/glamor.c b/glamor/glamor.c
index 8b8590f73..b42345f8e 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -372,35 +372,6 @@ fallback:
}
-static Bool
-glamor_check_instruction_count(int gl_version)
-{
- GLint max_native_alu_instructions;
-
- /* Avoid using glamor if the reported instructions limit is too low,
- * as this would cause glamor to fallback on sw due to large shaders
- * which ends up being unbearably slow.
- */
- if (gl_version < 30) {
- if (!epoxy_has_gl_extension("GL_ARB_fragment_program")) {
- ErrorF("GL_ARB_fragment_program required\n");
- return FALSE;
- }
-
- glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB,
- GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB,
- &max_native_alu_instructions);
- if (max_native_alu_instructions < GLAMOR_MIN_ALU_INSTRUCTIONS) {
- LogMessage(X_WARNING,
- "glamor requires at least %d instructions (%d reported)\n",
- GLAMOR_MIN_ALU_INSTRUCTIONS, max_native_alu_instructions);
- return FALSE;
- }
- }
-
- return TRUE;
-}
-
static void GLAPIENTRY
glamor_debug_output_callback(GLenum source,
GLenum type,
@@ -759,9 +730,6 @@ glamor_init(ScreenPtr screen, unsigned int flags)
goto fail;
}
- if (!glamor_check_instruction_count(gl_version))
- goto fail;
-
/* Glamor rendering assumes that platforms with GLSL 130+
* have instanced arrays, but this is not always the case.
* etnaviv offers GLSL 140 with OpenGL 2.1.
@@ -922,7 +890,16 @@ glamor_init(ScreenPtr screen, unsigned int flags)
ps->Glyphs = glamor_composite_glyphs;
glamor_init_vbo(screen);
- glamor_init_gradient_shader(screen);
+
+ glamor_priv->enable_gradient_shader = TRUE;
+
+ if (!glamor_init_gradient_shader(screen)) {
+ LogMessage(X_WARNING,
+ "glamor%d: Cannot initialize gradient shader, falling back to software rendering for gradients\n",
+ screen->myNum);
+ glamor_priv->enable_gradient_shader = FALSE;
+ }
+
glamor_pixmap_init(screen);
glamor_sync_init(screen);
diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c
index cb315e2d1..9a7510da0 100644
--- a/glamor/glamor_core.c
+++ b/glamor/glamor_core.c
@@ -78,7 +78,7 @@ glamor_compile_glsl_prog(GLenum type, const char *source)
return prog;
}
-void
+Bool
glamor_link_glsl_prog(ScreenPtr screen, GLint prog, const char *format, ...)
{
GLint ok;
@@ -106,8 +106,9 @@ glamor_link_glsl_prog(ScreenPtr screen, GLint prog, const char *format, ...)
glGetProgramInfoLog(prog, size, NULL, info);
ErrorF("Failed to link: %s\n", info);
- FatalError("GLSL link failure\n");
+ return FALSE;
}
+ return TRUE;
}
diff --git a/glamor/glamor_gradient.c b/glamor/glamor_gradient.c
index 4c7ae4d77..ed136d095 100644
--- a/glamor/glamor_gradient.c
+++ b/glamor/glamor_gradient.c
@@ -177,7 +177,7 @@ _glamor_create_getcolor_fs_source(ScreenPtr screen, int stops_count,
}
}
-static void
+static Bool
_glamor_create_radial_gradient_program(ScreenPtr screen, int stops_count,
int dyn_gen)
{
@@ -316,7 +316,7 @@ _glamor_create_radial_gradient_program(ScreenPtr screen, int stops_count,
if ((glamor_priv->radial_max_nstops >= stops_count) && (dyn_gen)) {
/* Very Good, not to generate again. */
- return;
+ return TRUE;
}
glamor_make_current(glamor_priv);
@@ -353,7 +353,10 @@ _glamor_create_radial_gradient_program(ScreenPtr screen, int stops_count,
glBindAttribLocation(gradient_prog, GLAMOR_VERTEX_POS, "v_position");
glBindAttribLocation(gradient_prog, GLAMOR_VERTEX_SOURCE, "v_texcoord");
- glamor_link_glsl_prog(screen, gradient_prog, "radial gradient");
+ if (!glamor_link_glsl_prog(screen, gradient_prog, "radial gradient")) {
+ glDeleteProgram(gradient_prog);
+ return FALSE;
+ }
if (dyn_gen) {
index = 2;
@@ -367,9 +370,11 @@ _glamor_create_radial_gradient_program(ScreenPtr screen, int stops_count,
}
glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][index] = gradient_prog;
+
+ return TRUE;
}
-static void
+static Bool
_glamor_create_linear_gradient_program(ScreenPtr screen, int stops_count,
int dyn_gen)
{
@@ -500,7 +505,7 @@ _glamor_create_linear_gradient_program(ScreenPtr screen, int stops_count,
if ((glamor_priv->linear_max_nstops >= stops_count) && (dyn_gen)) {
/* Very Good, not to generate again. */
- return;
+ return TRUE;
}
glamor_make_current(glamor_priv);
@@ -533,7 +538,10 @@ _glamor_create_linear_gradient_program(ScreenPtr screen, int stops_count,
glBindAttribLocation(gradient_prog, GLAMOR_VERTEX_POS, "v_position");
glBindAttribLocation(gradient_prog, GLAMOR_VERTEX_SOURCE, "v_texcoord");
- glamor_link_glsl_prog(screen, gradient_prog, "linear gradient");
+ if (!glamor_link_glsl_prog(screen, gradient_prog, "linear gradient")) {
+ glDeleteProgram(gradient_prog);
+ return FALSE;
+ }
if (dyn_gen) {
index = 2;
@@ -547,9 +555,11 @@ _glamor_create_linear_gradient_program(ScreenPtr screen, int stops_count,
}
glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][index] = gradient_prog;
+
+ return TRUE;
}
-void
+Bool
glamor_init_gradient_shader(ScreenPtr screen)
{
glamor_screen_private *glamor_priv;
@@ -564,11 +574,15 @@ glamor_init_gradient_shader(ScreenPtr screen)
glamor_priv->linear_max_nstops = 0;
glamor_priv->radial_max_nstops = 0;
- _glamor_create_linear_gradient_program(screen, 0, 0);
- _glamor_create_linear_gradient_program(screen, LINEAR_LARGE_STOPS, 0);
+ if (!_glamor_create_linear_gradient_program(screen, 0, 0) ||
+ !_glamor_create_linear_gradient_program(screen, LINEAR_LARGE_STOPS, 0))
+ return FALSE;
+
+ if (!_glamor_create_radial_gradient_program(screen, 0, 0) ||
+ !_glamor_create_radial_gradient_program(screen, RADIAL_LARGE_STOPS, 0))
+ return FALSE;
- _glamor_create_radial_gradient_program(screen, 0, 0);
- _glamor_create_radial_gradient_program(screen, RADIAL_LARGE_STOPS, 0);
+ return TRUE;
}
static void
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 61df458cc..4c2f4691c 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -246,6 +246,7 @@ typedef struct glamor_screen_private {
Bool can_copyplane;
Bool use_gpu_shader4;
int max_fbo_size;
+ Bool enable_gradient_shader;
/**
* Stores information about supported formats. Note, that this list contains all
@@ -628,7 +629,7 @@ Bool glamor_get_drawable_location(const DrawablePtr drawable);
void glamor_get_drawable_deltas(DrawablePtr drawable, PixmapPtr pixmap,
int *x, int *y);
GLint glamor_compile_glsl_prog(GLenum type, const char *source);
-void glamor_link_glsl_prog(ScreenPtr screen, GLint prog,
+Bool glamor_link_glsl_prog(ScreenPtr screen, GLint prog,
const char *format, ...) _X_ATTRIBUTE_PRINTF(3,4);
void glamor_get_color_4f_from_pixel(PixmapPtr pixmap,
unsigned long fg_pixel, GLfloat *color);
@@ -684,7 +685,7 @@ void glamor_trapezoids(CARD8 op,
int ntrap, xTrapezoid *traps);
/* glamor_gradient.c */
-void glamor_init_gradient_shader(ScreenPtr screen);
+Bool glamor_init_gradient_shader(ScreenPtr screen);
PicturePtr glamor_generate_linear_gradient_picture(ScreenPtr screen,
PicturePtr src_picture,
int x_source, int y_source,
@@ -961,6 +962,4 @@ void glamor_xv_render(glamor_port_private *port_priv, int id);
#include "glamor_font.h"
-#define GLAMOR_MIN_ALU_INSTRUCTIONS 128 /* Minimum required number of native ALU instructions */
-
#endif /* GLAMOR_PRIV_H */
diff --git a/glamor/glamor_program.c b/glamor/glamor_program.c
index 1d9277eee..633cf6529 100644
--- a/glamor/glamor_program.c
+++ b/glamor/glamor_program.c
@@ -376,7 +376,8 @@ glamor_build_program(ScreenPtr screen,
glBindFragDataLocationIndexed(prog->prog, 0, 1, "color1");
}
- glamor_link_glsl_prog(screen, prog->prog, "%s_%s", prim->name, fill->name);
+ if (!glamor_link_glsl_prog(screen, prog->prog, "%s_%s", prim->name, fill->name))
+ goto fail;
prog->matrix_uniform = glamor_get_uniform(prog, glamor_program_location_none, "v_matrix");
prog->fg_uniform = glamor_get_uniform(prog, glamor_program_location_fg, "fg");
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index 43859ebde..a638d46ef 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -61,7 +61,7 @@ static struct blendinfo composite_op_info[] = {
#define RepeatFix 10
static GLuint
-glamor_create_composite_fs(glamor_screen_private *glamor_priv, struct shader_key *key)
+glamor_create_composite_fs(glamor_screen_private *glamor_priv, struct shader_key *key, Bool enable_rel_sampler)
{
const char *repeat_define =
"#define RepeatNone 0\n"
@@ -131,6 +131,15 @@ glamor_create_composite_fs(glamor_screen_private *glamor_priv, struct shader_key
" }\n"
" return vec4(texture(tex_image, tex).rgb, 1.0);\n"
"}\n";
+ const char *stub_rel_sampler =
+ " vec4 rel_sampler_rgba(sampler2D tex_image, vec2 tex, vec4 wh, int repeat)\n"
+ "{\n"
+ " return texture(tex_image, tex);\n"
+ "}\n"
+ " vec4 rel_sampler_rgbx(sampler2D tex_image, vec2 tex, vec4 wh, int repeat)\n"
+ "{\n"
+ " return vec4(texture(tex_image, tex).rgb, 1.0);\n"
+ "}\n";
const char *source_solid_fetch =
"uniform vec4 source;\n"
@@ -319,7 +328,8 @@ glamor_create_composite_fs(glamor_screen_private *glamor_priv, struct shader_key
GLAMOR_DEFAULT_PRECISION
"%s%s%s%s%s%s%s%s", header, GLAMOR_COMPAT_DEFINES_FS,
repeat_define, relocate_texture,
- rel_sampler, source_fetch, mask_fetch, dest_swizzle, in);
+ enable_rel_sampler ? rel_sampler : stub_rel_sampler,
+ source_fetch, mask_fetch, dest_swizzle, in);
prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, source);
free(source);
@@ -383,18 +393,21 @@ glamor_create_composite_shader(ScreenPtr screen, struct shader_key *key,
GLuint vs, fs, prog;
GLint source_sampler_uniform_location, mask_sampler_uniform_location;
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+ Bool enable_rel_sampler = TRUE;
glamor_make_current(glamor_priv);
vs = glamor_create_composite_vs(glamor_priv, key);
if (vs == 0)
return;
- fs = glamor_create_composite_fs(glamor_priv, key);
+ fs = glamor_create_composite_fs(glamor_priv, key, enable_rel_sampler);
if (fs == 0)
return;
prog = glCreateProgram();
glAttachShader(prog, vs);
glAttachShader(prog, fs);
+ glDeleteShader(vs);
+ glDeleteShader(fs);
glBindAttribLocation(prog, GLAMOR_VERTEX_POS, "v_position");
glBindAttribLocation(prog, GLAMOR_VERTEX_SOURCE, "v_texcoord0");
@@ -404,7 +417,22 @@ glamor_create_composite_shader(ScreenPtr screen, struct shader_key *key,
glBindFragDataLocationIndexed(prog, 0, 0, "color0");
glBindFragDataLocationIndexed(prog, 0, 1, "color1");
}
- glamor_link_glsl_prog(screen, prog, "composite");
+
+ if (!glamor_link_glsl_prog(screen, prog, "composite")) {
+ /* Failed to link the shader, try again without rel_sampler. */
+ enable_rel_sampler = FALSE;
+ glDetachShader(prog, fs);
+ fs = glamor_create_composite_fs(glamor_priv, key, enable_rel_sampler);
+ if (fs == 0)
+ return;
+ glAttachShader(prog, fs);
+ glDeleteShader(fs);
+
+ if (!glamor_link_glsl_prog(screen, prog, "composite")) {
+ glDeleteProgram(prog);
+ return;
+ }
+ }
shader->prog = prog;
@@ -1369,6 +1397,7 @@ glamor_convert_gradient_picture(ScreenPtr screen,
int error;
PictFormatPtr pFormat;
PictFormatShort format;
+ glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
if (source->pDrawable) {
pFormat = source->pFormat;
@@ -1378,7 +1407,7 @@ glamor_convert_gradient_picture(ScreenPtr screen,
pFormat = PictureMatchFormat(screen, 32, format);
}
- if (!source->pDrawable) {
+ if (glamor_priv->enable_gradient_shader && !source->pDrawable) {
if (source->pSourcePict->type == SourcePictTypeLinear) {
dst = glamor_generate_linear_gradient_picture(screen,
source, x_source,
commit 3837159a3f6f3f8915c55e282ea545eed3f1dfdc
Author: Konstantin <ria.freelander at gmail.com>
Date: Wed Nov 2 19:13:33 2022 +0300
Fix autotools build for Glamor GLX provider
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1636>
diff --git a/glamor/Makefile.am b/glamor/Makefile.am
index aaf0aab17..847daa2a8 100644
--- a/glamor/Makefile.am
+++ b/glamor/Makefile.am
@@ -49,6 +49,13 @@ libglamor_la_SOURCES = \
glamor_sync.c \
glamor.h
+if GLX
+AM_CFLAGS += -I$(top_srcdir)/glx
+libglamor_la_SOURCES += \
+ glamor_glx_provider.c \
+ glamor_glx_provider.h
+endif
+
if XV
libglamor_la_SOURCES += \
glamor_xv.c
diff --git a/hw/xfree86/glamor_egl/Makefile.am b/hw/xfree86/glamor_egl/Makefile.am
index e697c8296..741eb11d5 100644
--- a/hw/xfree86/glamor_egl/Makefile.am
+++ b/hw/xfree86/glamor_egl/Makefile.am
@@ -33,6 +33,7 @@ libglamoregl_la_LDFLAGS = \
$()
libglamoregl_la_LIBADD = \
+ $(top_builddir)/glx/libglx.la \
$(top_builddir)/glamor/libglamor.la \
$()
commit 0dfcd136682dba0c8777dd4cf865f1f44b9cdf17
Author: Nicolas Dufresne <nicolas.dufresne at collabora.com>
Date: Tue Jul 30 15:53:25 2024 -0400
glamor: xv: Rewrite UYVY shader to match NV12/I420 CSC
This rewrites the shader so that we use the same (more flexible) CSC as
we have for I420 and NV12. This also fixes the reverse of odd/even which
caused chroma shift.
Signed-off-by: Nicolas Dufresne <nicolas.dufresne at collabora.com>
(cherry picked from commit 39c8a6f367154b1110a1e6845566a3388be4f90e)
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1636>
diff --git a/glamor/glamor_xv.c b/glamor/glamor_xv.c
index e51f7d5ba..f81391a1d 100644
--- a/glamor/glamor_xv.c
+++ b/glamor/glamor_xv.c
@@ -141,24 +141,22 @@ static const glamor_facet glamor_facet_xv_uyvy = {
"in vec2 tcs;\n"
),
.fs_exec = (
- " vec3 uyv;\n"
- " vec4 frameOut = texture2D(sampler, tcs.st);\n"
- "\n"
- " vec4 prevPixel = texture2D(sampler, vec2(tcs.s - texelSize.x, tcs.t));\n"
- " vec4 nextPixel = texture2D(sampler, vec2(tcs.s + texelSize.x, tcs.t));\n"
- "\n"
- " float delta = 0.50;\n"
- "\n"
- " int even = int(mod(tcs.x / texelSize.x, 2.0));\n"
- "\n"
- " uyv.rgb = float(even)*vec3(frameOut.rg, nextPixel.r) + (1.0-float(even))*vec3(prevPixel.r, frameOut.gr);\n"
- "\n"
- " frameOut.r = uyv.g + 1.403*(uyv.r - delta);\n"
- " frameOut.g = uyv.g - 0.714*(uyv.r - delta) - 0.344*(uyv.b - delta);\n"
- " frameOut.b = uyv.g + 1.773*(uyv.b - delta);\n"
- " frameOut.a = 1.0;\n"
- " frag_color = frameOut;\n"
- ),
+ " vec4 temp1;\n"
+ " vec2 xy = texture(sampler, tcs.st).xy;\n"
+ " vec2 prev_xy = texture(sampler, vec2(tcs.s - texelSize.x, tcs.t)).xy;\n"
+ " vec2 next_xy = texture(sampler, vec2(tcs.s + texelSize.x, tcs.t)).xy;\n"
+ "\n"
+ " vec3 sample_yuv;\n"
+ " int odd = int(mod(tcs.x / texelSize.x, 2.0));\n"
+ " int even = 1 - odd;\n"
+ " sample_yuv.yxz = float(even)*vec3(xy, next_xy.x) + float(odd)*vec3(prev_xy.x, xy.yx);\n"
+ "\n"
+ " temp1.xyz = offsetyco.www * vec3(sample_yuv.x) + offsetyco.xyz;\n"
+ " temp1.xyz = ucogamma.xyz * vec3(sample_yuv.y) + temp1.xyz;\n"
+ " temp1.xyz = clamp(vco.xyz * vec3(sample_yuv.z) + temp1.xyz, 0.0, 1.0);\n"
+ " temp1.w = 1.0;\n"
+ " frag_color = temp1;\n"
+ ),
};
static const glamor_facet glamor_facet_xv_rgb_raw = {
commit b21b504c4ea25e7a316e2547981f8dbc03097dff
Author: Konstantin <ria.freelander at gmail.com>
Date: Wed Jul 31 11:12:38 2024 +0300
glamor: xv: fix UYVY alignment
UYVY videos should be aligned by 2 to avoid breakups in the shader
Fixes: 832b392f7 - glamor: xv: enable UYVY acceleration
Suggested-by: Nicolas Dufresne <nicolas.dufresne at collabora.com>
Signed-off-by: Konstantin <ria.freelander at gmail.com>
(cherry picked from commit eb26f3236804389f2006388936322dc8115d00e0)
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1636>
diff --git a/glamor/glamor_xv.c b/glamor/glamor_xv.c
index 661cefa6c..e51f7d5ba 100644
--- a/glamor/glamor_xv.c
+++ b/glamor/glamor_xv.c
@@ -379,9 +379,16 @@ glamor_xv_query_image_attributes(int id,
offsets[0] = 0;
size *= *h;
break;
- case FOURCC_RGB565:
case FOURCC_UYVY:
/* UYVU is single-plane really, all tranformation is processed inside a shader */
+ size = ALIGN(*w, 2) * 2;
+ if (pitches)
+ pitches[0] = size;
+ if (offsets)
+ offsets[0] = 0;
+ size *= *h;
+ break;
+ case FOURCC_RGB565:
size = *w * 2;
if (pitches)
pitches[0] = size;
@@ -787,6 +794,15 @@ glamor_xv_put_image(glamor_port_private *port_priv,
buf + s2offset, srcPitch);
break;
case FOURCC_UYVY:
+ srcPitch = ALIGN(width, 2) * 2;
+ full_box.x1 = 0;
+ full_box.y1 = 0;
+ full_box.x2 = width;
+ full_box.y2 = height;
+ glamor_upload_boxes(port_priv->src_pix[0], &full_box, 1,
+ 0, 0, 0, 0,
+ buf, srcPitch);
+ break;
case FOURCC_RGB565:
srcPitch = width * 2;
full_box.x1 = 0;
commit 378f14f9ce1982114b38eb7471626f1540cf8e10
Author: Konstantin <ria.freelander at gmail.com>
Date: Thu Sep 21 16:45:08 2023 +0300
glamor: check BPP by render_format.
Check actual BPP by render_format in upload_boxes, not by drawable BPP.
It is required when we used different BPP formats for storing and
rendering (for example, in the case of UYVY).
The problem of UYVY size lies inside method of glamor downloading boxes.
When we set GLAMOR_CREATE_FORMAT_CBCR, it actually uses 16-bit GL and
Pixman formats, but before this change in glamor_download_boxes, that
function deduces GL and Pixman formats from BPP, which is wrong in this
case (will be deduced to 32).
When GL and Pixman format BPP is identical to drawable BPP, this change
does nothing, but when it is different - it will prioritize Pixman
format, not the format deduced from BPP.
Closes: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1730
Signed-off-by: Konstantin Pugin <ria.freelander at gmail.com>
(cherry picked from commit 75f56b79234bf428455fa0bef741a86fc5919889)
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1636>
diff --git a/glamor/glamor_transfer.c b/glamor/glamor_transfer.c
index e706e0fb4..6facbd8eb 100644
--- a/glamor/glamor_transfer.c
+++ b/glamor/glamor_transfer.c
@@ -36,8 +36,8 @@ glamor_upload_boxes(PixmapPtr pixmap, BoxPtr in_boxes, int in_nbox,
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
glamor_pixmap_private *priv = glamor_get_pixmap_private(pixmap);
int box_index;
- int bytes_per_pixel = pixmap->drawable.bitsPerPixel >> 3;
const struct glamor_format *f = glamor_format_for_pixmap(pixmap);
+ int bytes_per_pixel = PICT_FORMAT_BPP(f->render_format) >> 3;
glamor_make_current(glamor_priv);
@@ -136,8 +136,8 @@ glamor_download_boxes(PixmapPtr pixmap, BoxPtr in_boxes, int in_nbox,
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
glamor_pixmap_private *priv = glamor_get_pixmap_private(pixmap);
int box_index;
- int bytes_per_pixel = pixmap->drawable.bitsPerPixel >> 3;
const struct glamor_format *f = glamor_format_for_pixmap(pixmap);
+ int bytes_per_pixel = PICT_FORMAT_BPP(f->render_format) >> 3;
glamor_make_current(glamor_priv);
commit 48cb710f9f1358f3891680401d1a7f3782cb555b
Author: Yuriy Vasilev <uuvasiliev at yandex.ru>
Date: Fri Sep 10 16:20:06 2021 +0300
glamor: xv: add rgb565
This commit adds RGB565 format to XVideo with reuse of RGBA32 shader
Reviewed-by: Adam Jackson <ajax at redhat.com>
Signed-off-by: Yuriy Vasilev <uuvasiliev at yandex.ru>
(cherry picked from commit c170056111fe0b3c4956a34276b5683e24b8c63c)
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1636>
diff --git a/glamor/glamor_xv.c b/glamor/glamor_xv.c
index 0436b0dc9..661cefa6c 100644
--- a/glamor/glamor_xv.c
+++ b/glamor/glamor_xv.c
@@ -199,6 +199,7 @@ XvImageRec glamor_xv_images[] = {
XVIMAGE_NV12,
XVIMAGE_UYVY,
XVIMAGE_RGB32,
+ XVIMAGE_RGB565,
};
int glamor_xv_num_images = ARRAY_SIZE(glamor_xv_images);
@@ -220,6 +221,7 @@ glamor_init_xv_shader(ScreenPtr screen, glamor_port_private *port_priv, int id)
glamor_facet_xv_planar = &glamor_facet_xv_uyvy;
break;
case FOURCC_RGBA32:
+ case FOURCC_RGB565:
glamor_facet_xv_planar = &glamor_facet_xv_rgb_raw;
break;
default:
@@ -250,6 +252,7 @@ glamor_init_xv_shader(ScreenPtr screen, glamor_port_private *port_priv, int id)
break;
case FOURCC_UYVY:
case FOURCC_RGBA32:
+ case FOURCC_RGB565:
sampler_loc = glGetUniformLocation(port_priv->xv_prog.prog, "sampler");
glUniform1i(sampler_loc, 0);
break;
@@ -376,6 +379,7 @@ glamor_xv_query_image_attributes(int id,
offsets[0] = 0;
size *= *h;
break;
+ case FOURCC_RGB565:
case FOURCC_UYVY:
/* UYVU is single-plane really, all tranformation is processed inside a shader */
size = *w * 2;
@@ -516,6 +520,7 @@ glamor_xv_render(glamor_port_private *port_priv, int id)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
break;
case FOURCC_RGBA32:
+ case FOURCC_RGB565:
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, src_pixmap_priv[0]->fbo->tex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
@@ -692,6 +697,13 @@ glamor_xv_put_image(glamor_port_private *port_priv,
port_priv->src_pix[1] = NULL;
port_priv->src_pix[2] = NULL;
break;
+ case FOURCC_RGB565:
+ port_priv->src_pix[0] =
+ glamor_create_pixmap(pScreen, width, height, 16,
+ GLAMOR_CREATE_FBO_NO_FBO);
+ port_priv->src_pix[1] = NULL;
+ port_priv->src_pix[2] = NULL;
+ break;
case FOURCC_UYVY:
port_priv->src_pix[0] =
glamor_create_pixmap(pScreen, width, height, 32,
@@ -775,6 +787,7 @@ glamor_xv_put_image(glamor_port_private *port_priv,
buf + s2offset, srcPitch);
break;
case FOURCC_UYVY:
+ case FOURCC_RGB565:
srcPitch = width * 2;
full_box.x1 = 0;
full_box.y1 = 0;
diff --git a/include/fourcc.h b/include/fourcc.h
index 582a95afe..83e51a888 100644
--- a/include/fourcc.h
+++ b/include/fourcc.h
@@ -195,4 +195,24 @@
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, \
0 \
}
+
+#define FOURCC_RGB565 0x36314752
+#define XVIMAGE_RGB565 \
+ { \
+ FOURCC_RGB565, \
+ XvRGB, \
+ LSBFirst, \
+ {'R','G','1','6', \
+ 0x00, 0x00, 0x00,0x10,0x80,0x00,0x00,0xAA,0x00,0x38,0x9B,0x71}, \
+ 16, \
+ XvPacked, \
+ 1, \
+ 16, 0xf800, 0x7e0, 0x1f, \
+ 0, 0, 0, \
+ 0, 0, 0, \
+ 0, 0, 0, \
+ {0,0,0,0, \
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, \
+ 0 \
+ }
#endif /* _XF86_FOURCC_H_ */
commit b6d21a444e6d2b6681d28ea7d62089b645f4ec14
Author: Yuriy Vasilev <uuvasiliev at yandex.ru>
Date: Thu Sep 9 18:14:02 2021 +0300
glamor: xv: add rgba32 format
This commit adds RGBA32 format to XVideo along with shader for handling it.
Reviewed-by: Adam Jackson <ajax at redhat.com>
Signed-off-by: Yuriy Vasilev <uuvasiliev at yandex.ru>
(cherry picked from commit 15412e78c83bf3d15bcd343ccc40afda072d3f9e)
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1636>
diff --git a/glamor/glamor_xv.c b/glamor/glamor_xv.c
index 5ae8466b6..0436b0dc9 100644
--- a/glamor/glamor_xv.c
+++ b/glamor/glamor_xv.c
@@ -161,6 +161,23 @@ static const glamor_facet glamor_facet_xv_uyvy = {
),
};
+static const glamor_facet glamor_facet_xv_rgb_raw = {
+ .name = "xv_rgb",
+
+ .source_name = "v_texcoord0",
+ .vs_vars = ("in vec2 position;\n"
+ "in vec2 v_texcoord0;\n"
+ "out vec2 tcs;\n"),
+ .vs_exec = (GLAMOR_POS(gl_Position, position)
+ " tcs = v_texcoord0;\n"),
+
+ .fs_vars = ("uniform sampler2D sampler;\n"
+ "in vec2 tcs;\n"),
+ .fs_exec = (
+ " frag_color = texture2D(sampler, tcs);\n"
+ ),
+};
+
#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE)
XvAttributeRec glamor_xv_attributes[] = {
@@ -181,6 +198,7 @@ XvImageRec glamor_xv_images[] = {
XVIMAGE_I420,
XVIMAGE_NV12,
XVIMAGE_UYVY,
+ XVIMAGE_RGB32,
};
int glamor_xv_num_images = ARRAY_SIZE(glamor_xv_images);
@@ -201,6 +219,9 @@ glamor_init_xv_shader(ScreenPtr screen, glamor_port_private *port_priv, int id)
case FOURCC_UYVY:
glamor_facet_xv_planar = &glamor_facet_xv_uyvy;
break;
+ case FOURCC_RGBA32:
+ glamor_facet_xv_planar = &glamor_facet_xv_rgb_raw;
+ break;
default:
break;
}
@@ -228,6 +249,7 @@ glamor_init_xv_shader(ScreenPtr screen, glamor_port_private *port_priv, int id)
glUniform1i(sampler_loc, 1);
break;
case FOURCC_UYVY:
+ case FOURCC_RGBA32:
sampler_loc = glGetUniformLocation(port_priv->xv_prog.prog, "sampler");
glUniform1i(sampler_loc, 0);
break;
@@ -346,6 +368,14 @@ glamor_xv_query_image_attributes(int id,
tmp *= (*h >> 1);
size += tmp;
break;
+ case FOURCC_RGBA32:
+ size = *w * 4;
+ if(pitches)
+ pitches[0] = size;
+ if(offsets)
+ offsets[0] = 0;
+ size *= *h;
+ break;
case FOURCC_UYVY:
/* UYVU is single-plane really, all tranformation is processed inside a shader */
size = *w * 2;
@@ -485,6 +515,14 @@ glamor_xv_render(glamor_port_private *port_priv, int id)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
break;
+ case FOURCC_RGBA32:
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, src_pixmap_priv[0]->fbo->tex);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ break;
default:
break;
}
@@ -647,6 +685,13 @@ glamor_xv_put_image(glamor_port_private *port_priv,
if (!port_priv->src_pix[1])
return BadAlloc;
break;
+ case FOURCC_RGBA32:
+ port_priv->src_pix[0] =
+ glamor_create_pixmap(pScreen, width, height, 32,
+ GLAMOR_CREATE_FBO_NO_FBO);
+ port_priv->src_pix[1] = NULL;
+ port_priv->src_pix[2] = NULL;
+ break;
case FOURCC_UYVY:
port_priv->src_pix[0] =
glamor_create_pixmap(pScreen, width, height, 32,
@@ -739,6 +784,16 @@ glamor_xv_put_image(glamor_port_private *port_priv,
0, 0, 0, 0,
buf, srcPitch);
break;
+ case FOURCC_RGBA32:
+ srcPitch = width * 4;
+ full_box.x1 = 0;
+ full_box.y1 = 0;
+ full_box.x2 = width;
+ full_box.y2 = height;
+ glamor_upload_boxes(port_priv->src_pix[0], &full_box, 1,
+ 0, 0, 0, 0,
+ buf, srcPitch);
+ break;
default:
return BadMatch;
}
diff --git a/include/fourcc.h b/include/fourcc.h
index a19e6869e..582a95afe 100644
--- a/include/fourcc.h
+++ b/include/fourcc.h
@@ -176,4 +176,23 @@
XvTopToBottom \
}
+#define FOURCC_RGBA32 0x34325241
+#define XVIMAGE_RGB32 \
+ { \
+ FOURCC_RGBA32, \
+ XvRGB, \
+ LSBFirst, \
+ {'R','A','2','4', \
+ 0x00, 0x00, 0x00,0x10,0x80,0x00,0x00,0xAA,0x00,0x38,0x9B,0x71}, \
+ 32, \
+ XvPacked, \
+ 1, \
+ 32, 0xff0000, 0xff00, 0xff, \
+ 0, 0, 0, \
+ 0, 0, 0, \
+ 0, 0, 0, \
+ {0,0,0,0, \
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, \
+ 0 \
+ }
#endif /* _XF86_FOURCC_H_ */
commit e084b6e806217519ccb3d67edc5c5aa1f0591290
Author: Konstantin <ria.freelander at gmail.com>
Date: Tue Oct 19 15:03:35 2021 +0300
glamor: xv: enable UYVY acceleration
This commit adds UYVY format in XVideo for Glamor
along with shader support.
Reviewed-by: Adam Jackson <ajax at redhat.com>
Signed-off-by: Konstantin <ria.freelander at gmail.com>
(cherry picked from commit 832b392f70450f164800d65546ec9adf15d642a2)
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1636>
diff --git a/glamor/glamor_xv.c b/glamor/glamor_xv.c
index 120b731cc..5ae8466b6 100644
--- a/glamor/glamor_xv.c
+++ b/glamor/glamor_xv.c
@@ -120,6 +120,47 @@ static const glamor_facet glamor_facet_xv_planar_3 = {
),
};
+static const glamor_facet glamor_facet_xv_uyvy = {
+ .name = "xv_uyvy",
+
+ .source_name = "v_texcoord0",
+ .vs_vars = ("in vec2 position;\n"
+ "in vec2 v_texcoord0;\n"
+ "out vec2 tcs;\n"),
+ .vs_exec = (GLAMOR_POS(gl_Position, position)
+ " tcs = v_texcoord0;\n"),
+
+ .fs_vars = ("#ifdef GL_ES\n"
+ "precision highp float;\n"
+ "#endif\n"
+ "uniform sampler2D sampler;\n"
+ "uniform vec2 texelSize;\n"
+ "uniform vec4 offsetyco;\n"
+ "uniform vec4 ucogamma;\n"
+ "uniform vec4 vco;\n"
+ "in vec2 tcs;\n"
+ ),
+ .fs_exec = (
+ " vec3 uyv;\n"
+ " vec4 frameOut = texture2D(sampler, tcs.st);\n"
+ "\n"
+ " vec4 prevPixel = texture2D(sampler, vec2(tcs.s - texelSize.x, tcs.t));\n"
+ " vec4 nextPixel = texture2D(sampler, vec2(tcs.s + texelSize.x, tcs.t));\n"
+ "\n"
+ " float delta = 0.50;\n"
+ "\n"
+ " int even = int(mod(tcs.x / texelSize.x, 2.0));\n"
+ "\n"
+ " uyv.rgb = float(even)*vec3(frameOut.rg, nextPixel.r) + (1.0-float(even))*vec3(prevPixel.r, frameOut.gr);\n"
+ "\n"
+ " frameOut.r = uyv.g + 1.403*(uyv.r - delta);\n"
+ " frameOut.g = uyv.g - 0.714*(uyv.r - delta) - 0.344*(uyv.b - delta);\n"
+ " frameOut.b = uyv.g + 1.773*(uyv.b - delta);\n"
+ " frameOut.a = 1.0;\n"
+ " frag_color = frameOut;\n"
+ ),
+};
+
#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE)
XvAttributeRec glamor_xv_attributes[] = {
@@ -138,7 +179,8 @@ Atom glamorBrightness, glamorContrast, glamorSaturation, glamorHue,
XvImageRec glamor_xv_images[] = {
XVIMAGE_YV12,
XVIMAGE_I420,
- XVIMAGE_NV12
+ XVIMAGE_NV12,
+ XVIMAGE_UYVY,
};
int glamor_xv_num_images = ARRAY_SIZE(glamor_xv_images);
@@ -156,6 +198,9 @@ glamor_init_xv_shader(ScreenPtr screen, glamor_port_private *port_priv, int id)
case FOURCC_NV12:
glamor_facet_xv_planar = &glamor_facet_xv_planar_2;
break;
+ case FOURCC_UYVY:
+ glamor_facet_xv_planar = &glamor_facet_xv_uyvy;
+ break;
default:
break;
}
@@ -182,6 +227,10 @@ glamor_init_xv_shader(ScreenPtr screen, glamor_port_private *port_priv, int id)
sampler_loc = glGetUniformLocation(port_priv->xv_prog.prog, "u_sampler");
glUniform1i(sampler_loc, 1);
break;
+ case FOURCC_UYVY:
+ sampler_loc = glGetUniformLocation(port_priv->xv_prog.prog, "sampler");
+ glUniform1i(sampler_loc, 0);
+ break;
default:
break;
}
@@ -297,6 +346,15 @@ glamor_xv_query_image_attributes(int id,
tmp *= (*h >> 1);
size += tmp;
break;
+ case FOURCC_UYVY:
+ /* UYVU is single-plane really, all tranformation is processed inside a shader */
+ size = *w * 2;
+ if (pitches)
+ pitches[0] = size;
+ if (offsets)
+ offsets[0] = 0;
+ size *= *h;
+ break;
}
return size;
}
@@ -377,16 +435,16 @@ glamor_xv_render(glamor_port_private *port_priv, int id)
uloc = glGetUniformLocation(port_priv->xv_prog.prog, "vco");
glUniform4f(uloc, vco[0], vco[1], vco[2], 0);
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, src_pixmap_priv[0]->fbo->tex);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-
switch (id) {
case FOURCC_YV12:
case FOURCC_I420:
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, src_pixmap_priv[0]->fbo->tex);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, src_pixmap_priv[1]->fbo->tex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
@@ -402,6 +460,13 @@ glamor_xv_render(glamor_port_private *port_priv, int id)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
break;
case FOURCC_NV12:
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, src_pixmap_priv[0]->fbo->tex);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, src_pixmap_priv[1]->fbo->tex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
@@ -409,6 +474,17 @@ glamor_xv_render(glamor_port_private *port_priv, int id)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
break;
+ case FOURCC_UYVY:
+ uloc = glGetUniformLocation(port_priv->xv_prog.prog, "texelSize");
+ glUniform2f(uloc, 1.0 / port_priv->w, 1.0 / port_priv->h);
+
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, src_pixmap_priv[0]->fbo->tex);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ break;
default:
break;
}
@@ -571,6 +647,14 @@ glamor_xv_put_image(glamor_port_private *port_priv,
if (!port_priv->src_pix[1])
return BadAlloc;
break;
+ case FOURCC_UYVY:
+ port_priv->src_pix[0] =
+ glamor_create_pixmap(pScreen, width, height, 32,
+ GLAMOR_CREATE_FBO_NO_FBO |
+ GLAMOR_CREATE_FORMAT_CBCR);
+ port_priv->src_pix[1] = NULL;
+ port_priv->src_pix[2] = NULL;
+ break;
default:
return BadMatch;
}
@@ -645,6 +729,16 @@ glamor_xv_put_image(glamor_port_private *port_priv,
0, 0, 0, 0,
buf + s2offset, srcPitch);
break;
+ case FOURCC_UYVY:
+ srcPitch = width * 2;
+ full_box.x1 = 0;
+ full_box.y1 = 0;
+ full_box.x2 = width;
+ full_box.y2 = height;
+ glamor_upload_boxes(port_priv->src_pix[0], &full_box, 1,
+ 0, 0, 0, 0,
+ buf, srcPitch);
+ break;
default:
return BadMatch;
}
commit 966f8aa40ec8b70f56d0d8fc24e1ed0c4a4ab30c
Author: Konstantin <ria.freelander at gmail.com>
Date: Fri Oct 20 22:51:55 2023 +0300
glamor: xv: prepare to one-plane formats
As a preparation to one-plane formats (for example, UYVY), second
texture definition is moved inside a format switch, and all allocations
now also done inside a texture switch.
No functional change.
Reviewed-by: Adam Jackson <ajax at redhat.com>
Signed-off-by: Konstantin <ria.freelander at gmail.com>
(cherry picked from commit ffd7151b109b8c598cd346d34b5233558409a03a)
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1636>
diff --git a/glamor/glamor_xv.c b/glamor/glamor_xv.c
index 4ce06ddb1..120b731cc 100644
--- a/glamor/glamor_xv.c
+++ b/glamor/glamor_xv.c
@@ -165,18 +165,22 @@ glamor_init_xv_shader(ScreenPtr screen, glamor_port_private *port_priv, int id)
glamor_facet_xv_planar, NULL, NULL, NULL);
glUseProgram(port_priv->xv_prog.prog);
- sampler_loc = glGetUniformLocation(glamor_priv->xv_prog.prog, "y_sampler");
- glUniform1i(sampler_loc, 0);
- sampler_loc = glGetUniformLocation(glamor_priv->xv_prog.prog, "u_sampler");
- glUniform1i(sampler_loc, 1);
switch (id) {
case FOURCC_YV12:
case FOURCC_I420:
- sampler_loc = glGetUniformLocation(glamor_priv->xv_prog.prog, "v_sampler");
+ sampler_loc = glGetUniformLocation(port_priv->xv_prog.prog, "y_sampler");
+ glUniform1i(sampler_loc, 0);
+ sampler_loc = glGetUniformLocation(port_priv->xv_prog.prog, "u_sampler");
+ glUniform1i(sampler_loc, 1);
+ sampler_loc = glGetUniformLocation(port_priv->xv_prog.prog, "v_sampler");
glUniform1i(sampler_loc, 2);
break;
case FOURCC_NV12:
+ sampler_loc = glGetUniformLocation(port_priv->xv_prog.prog, "y_sampler");
+ glUniform1i(sampler_loc, 0);
+ sampler_loc = glGetUniformLocation(port_priv->xv_prog.prog, "u_sampler");
+ glUniform1i(sampler_loc, 1);
break;
default:
break;
@@ -380,16 +384,16 @@ glamor_xv_render(glamor_port_private *port_priv, int id)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- glActiveTexture(GL_TEXTURE1);
- glBindTexture(GL_TEXTURE_2D, src_pixmap_priv[1]->fbo->tex);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-
switch (id) {
case FOURCC_YV12:
case FOURCC_I420:
+ glActiveTexture(GL_TEXTURE1);
+ glBindTexture(GL_TEXTURE_2D, src_pixmap_priv[1]->fbo->tex);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, src_pixmap_priv[2]->fbo->tex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
@@ -398,6 +402,12 @@ glamor_xv_render(glamor_port_private *port_priv, int id)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
break;
case FOURCC_NV12:
+ glActiveTexture(GL_TEXTURE1);
+ glBindTexture(GL_TEXTURE_2D, src_pixmap_priv[1]->fbo->tex);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
break;
default:
break;
@@ -532,28 +542,34 @@ glamor_xv_put_image(glamor_port_private *port_priv,
if (port_priv->src_pix[i])
glamor_destroy_pixmap(port_priv->src_pix[i]);
- port_priv->src_pix[0] =
- glamor_create_pixmap(pScreen, width, height, 8,
- GLAMOR_CREATE_FBO_NO_FBO);
-
switch (id) {
case FOURCC_YV12:
case FOURCC_I420:
+ port_priv->src_pix[0] =
+ glamor_create_pixmap(pScreen, width, height, 8,
+ GLAMOR_CREATE_FBO_NO_FBO);
+
port_priv->src_pix[1] =
glamor_create_pixmap(pScreen, width >> 1, height >> 1, 8,
GLAMOR_CREATE_FBO_NO_FBO);
port_priv->src_pix[2] =
glamor_create_pixmap(pScreen, width >> 1, height >> 1, 8,
GLAMOR_CREATE_FBO_NO_FBO);
- if (!port_priv->src_pix[2])
+ if (!port_priv->src_pix[1] || !port_priv->src_pix[2])
return BadAlloc;
break;
case FOURCC_NV12:
+ port_priv->src_pix[0] =
+ glamor_create_pixmap(pScreen, width, height, 8,
+ GLAMOR_CREATE_FBO_NO_FBO);
port_priv->src_pix[1] =
glamor_create_pixmap(pScreen, width >> 1, height >> 1, 16,
GLAMOR_CREATE_FBO_NO_FBO |
GLAMOR_CREATE_FORMAT_CBCR);
port_priv->src_pix[2] = NULL;
+
+ if (!port_priv->src_pix[1])
+ return BadAlloc;
break;
default:
return BadMatch;
@@ -562,7 +578,7 @@ glamor_xv_put_image(glamor_port_private *port_priv,
port_priv->src_pix_w = width;
port_priv->src_pix_h = height;
- if (!port_priv->src_pix[0] || !port_priv->src_pix[1])
+ if (!port_priv->src_pix[0])
return BadAlloc;
}
commit 20f8f90d53ddac0591a8544aab457f65171f0266
Author: Konstantin <ria.freelander at gmail.com>
Date: Fri Oct 20 22:45:11 2023 +0300
glamor: xv: reuse ports and shaders when possible
Xv currently calls glamor_xv_free_port_data at the end of every putImage.
This leads to shader recompilation for every frame, which is a huge performance loss.
This commit changes behaviour of glamor_xv_free_port_data, and its now is called only
if width, height or format is changed for xv port.
Shader management also done in a port now, because if shaders will be
stored in core glamor and try to be reused, this can lead to a bug if we
try to play 2 videos with different formats simultaneously.
Reviewed-by: Adam Jackson <ajax at redhat.com>
Signed-off-by: Konstantin <ria.freelander at gmail.com>
(cherry picked from commit 81ef43dd4ab22185ba63aaa271fdbb36dd39f0c9)
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1636>
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 657b991f5..61df458cc 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -919,6 +919,9 @@ typedef struct {
RegionRec clip;
PixmapPtr src_pix[3]; /* y, u, v for planar */
int src_pix_w, src_pix_h;
+ /* Port optimization */
+ int prev_fmt;
+ glamor_program xv_prog;
} glamor_port_private;
extern XvAttributeRec glamor_xv_attributes[];
diff --git a/glamor/glamor_xv.c b/glamor/glamor_xv.c
index fb72e2a4d..4ce06ddb1 100644
--- a/glamor/glamor_xv.c
+++ b/glamor/glamor_xv.c
@@ -143,9 +143,8 @@ XvImageRec glamor_xv_images[] = {
int glamor_xv_num_images = ARRAY_SIZE(glamor_xv_images);
static void
-glamor_init_xv_shader(ScreenPtr screen, int id)
+glamor_init_xv_shader(ScreenPtr screen, glamor_port_private *port_priv, int id)
{
- glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
GLint sampler_loc;
const glamor_facet *glamor_facet_xv_planar = NULL;
@@ -162,10 +161,10 @@ glamor_init_xv_shader(ScreenPtr screen, int id)
}
glamor_build_program(screen,
- &glamor_priv->xv_prog,
+ &port_priv->xv_prog,
glamor_facet_xv_planar, NULL, NULL, NULL);
- glUseProgram(glamor_priv->xv_prog.prog);
+ glUseProgram(port_priv->xv_prog.prog);
sampler_loc = glGetUniformLocation(glamor_priv->xv_prog.prog, "y_sampler");
glUniform1i(sampler_loc, 0);
sampler_loc = glGetUniformLocation(glamor_priv->xv_prog.prog, "u_sampler");
@@ -330,8 +329,8 @@ glamor_xv_render(glamor_port_private *port_priv, int id)
char *vbo_offset;
int dst_box_index;
- if (!glamor_priv->xv_prog.prog)
- glamor_init_xv_shader(screen, id);
+ if (!port_priv->xv_prog.prog)
+ glamor_init_xv_shader(screen, port_priv, id);
cont = RTFContrast(port_priv->contrast);
bright = RTFBrightness(port_priv->brightness);
@@ -365,13 +364,13 @@ glamor_xv_render(glamor_port_private *port_priv, int id)
}
}
glamor_make_current(glamor_priv);
- glUseProgram(glamor_priv->xv_prog.prog);
+ glUseProgram(port_priv->xv_prog.prog);
- uloc = glGetUniformLocation(glamor_priv->xv_prog.prog, "offsetyco");
+ uloc = glGetUniformLocation(port_priv->xv_prog.prog, "offsetyco");
glUniform4f(uloc, off[0], off[1], off[2], yco);
- uloc = glGetUniformLocation(glamor_priv->xv_prog.prog, "ucogamma");
+ uloc = glGetUniformLocation(port_priv->xv_prog.prog, "ucogamma");
glUniform4f(uloc, uco[0], uco[1], uco[2], gamma);
- uloc = glGetUniformLocation(glamor_priv->xv_prog.prog, "vco");
+ uloc = glGetUniformLocation(port_priv->xv_prog.prog, "vco");
glUniform4f(uloc, vco[0], vco[1], vco[2], 0);
glActiveTexture(GL_TEXTURE0);
@@ -455,7 +454,7 @@ glamor_xv_render(glamor_port_private *port_priv, int id)
glamor_set_destination_drawable(port_priv->pDraw,
dst_box_index,
FALSE, FALSE,
- glamor_priv->xv_prog.matrix_uniform,
+ port_priv->xv_prog.matrix_uniform,
&dst_off_x, &dst_off_y);
for (i = 0; i < nBox; i++) {
@@ -476,8 +475,25 @@ glamor_xv_render(glamor_port_private *port_priv, int id)
glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
DamageDamageRegion(port_priv->pDraw, &port_priv->clip);
+}
+
+static Bool
+glamor_xv_can_reuse_port(glamor_port_private *port_priv, int id, short w, short h)
+{
+ int ret = TRUE;
+
+ if (port_priv->prev_fmt != id)
+ ret = FALSE;
- glamor_xv_free_port_data(port_priv);
+ if (w != port_priv->src_pix_w || h != port_priv->src_pix_h)
+ ret = FALSE;
+
+ if (!port_priv->src_pix[0])
+ ret = FALSE;
+
+ port_priv->prev_fmt = id;
+
+ return ret;
}
int
@@ -495,7 +511,6 @@ glamor_xv_put_image(glamor_port_private *port_priv,
RegionPtr clipBoxes)
{
ScreenPtr pScreen = pDrawable->pScreen;
- glamor_screen_private *glamor_priv = glamor_get_screen_private(pScreen);
int srcPitch, srcPitch2;
int top, nlines;
int s2offset, s3offset, tmp;
@@ -503,15 +518,14 @@ glamor_xv_put_image(glamor_port_private *port_priv,
s2offset = s3offset = srcPitch2 = 0;
- if (!port_priv->src_pix[0] ||
- (width != port_priv->src_pix_w || height != port_priv->src_pix_h) ||
- (port_priv->src_pix[2] && id == FOURCC_NV12) ||
- (!port_priv->src_pix[2] && id != FOURCC_NV12)) {
+ if (!glamor_xv_can_reuse_port(port_priv, id, width, height)) {
int i;
- if (glamor_priv->xv_prog.prog) {
- glDeleteProgram(glamor_priv->xv_prog.prog);
- glamor_priv->xv_prog.prog = 0;
+ glamor_xv_free_port_data(port_priv);
+
+ if (port_priv->xv_prog.prog) {
+ glDeleteProgram(port_priv->xv_prog.prog);
+ port_priv->xv_prog.prog = 0;
}
for (i = 0; i < 3; i++)
commit 111c1d033232c0effb7c5280e54f8e1baf80484e
Author: Konstantin <ria.freelander at gmail.com>
Date: Tue Oct 10 13:07:41 2023 +0300
glamor: xv: do not force a version on XV shaders
There is a no need to force a low version for XV shaders, it will
work on higher version too.
Reviewed-by: Adam Jackson <ajax at redhat.com>
Signed-off-by: Konstantin <ria.freelander at gmail.com>
(cherry picked from commit a8270fc5f0d5e934c266a8b243a35ebd83e2f08f)
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1636>
diff --git a/glamor/glamor_xv.c b/glamor/glamor_xv.c
index a3626d3f8..fb72e2a4d 100644
--- a/glamor/glamor_xv.c
+++ b/glamor/glamor_xv.c
@@ -62,8 +62,6 @@ typedef struct tagREF_TRANSFORM {
static const glamor_facet glamor_facet_xv_planar_2 = {
.name = "xv_planar_2",
- .version = 120,
-
.source_name = "v_texcoord0",
.vs_vars = ("in vec2 position;\n"
"in vec2 v_texcoord0;\n"
@@ -94,8 +92,6 @@ static const glamor_facet glamor_facet_xv_planar_2 = {
static const glamor_facet glamor_facet_xv_planar_3 = {
.name = "xv_planar_3",
- .version = 120,
-
.source_name = "v_texcoord0",
.vs_vars = ("in vec2 position;\n"
"in vec2 v_texcoord0;\n"
commit 062d39977094c89ef34168b78b9c9e9fc85483ff
Author: Konstantin <ria.freelander at gmail.com>
Date: Tue Oct 10 17:36:50 2023 +0300
glamor_egl: add support of GlxVendorLibrary option
Same semantics as in glxdri2.c, and same purpose.
Signed-off-by: Konstantin <ria.freelander at gmail.com>
(cherry picked from commit a449bb4c5dbb569d151e0d714b0ef3eab4074b67)
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1636>
diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
index 119595f09..6e24ffdd7 100644
--- a/glamor/glamor_egl.c
+++ b/glamor/glamor_egl.c
@@ -59,6 +59,7 @@ struct glamor_egl_screen_private {
int fd;
struct gbm_device *gbm;
int dmabuf_capable;
+ Bool force_vendor; /* if GLVND vendor is forced from options */
CloseScreenProcPtr saved_close_screen;
DestroyPixmapProcPtr saved_destroy_pixmap;
@@ -904,10 +905,13 @@ glamor_egl_screen_init(ScreenPtr screen, struct glamor_context *glamor_ctx)
glamor_ctx->make_current = glamor_egl_make_current;
- gbm_backend_name = gbm_device_get_backend_name(glamor_egl->gbm);
- /* Mesa uses "drm" as backend name, in that case, just do nothing */
- if (gbm_backend_name && strcmp(gbm_backend_name, "drm") != 0)
- glamor_set_glvnd_vendor(screen, gbm_backend_name);
+ /* Use dynamic logic only if vendor is not forced via xorg.conf */
+ if (!glamor_egl->force_vendor) {
+ gbm_backend_name = gbm_device_get_backend_name(glamor_egl->gbm);
+ /* Mesa uses "drm" as backend name, in that case, just do nothing */
+ if (gbm_backend_name && strcmp(gbm_backend_name, "drm") != 0)
+ glamor_set_glvnd_vendor(screen, gbm_backend_name);
+ }
#ifdef DRI3
/* Tell the core that we have the interfaces for import/export
* of pixmaps.
@@ -1061,10 +1065,12 @@ glamor_egl_try_gles_api(ScrnInfoPtr scrn)
enum {
GLAMOREGLOPT_RENDERING_API,
+ GLAMOREGLOPT_VENDOR_LIBRARY
};
static const OptionInfoRec GlamorEGLOptions[] = {
{ GLAMOREGLOPT_RENDERING_API, "RenderingAPI", OPTV_STRING, {0}, FALSE },
+ { GLAMOREGLOPT_VENDOR_LIBRARY, "GlxVendorLibrary", OPTV_STRING, {0}, FALSE },
{ -1, NULL, OPTV_NONE, {0}, FALSE },
};
@@ -1077,6 +1083,7 @@ glamor_egl_init(ScrnInfoPtr scrn, int fd)
const char *api = NULL;
Bool es_allowed = TRUE;
Bool force_es = FALSE;
+ const char *glvnd_vendor = NULL;
glamor_egl = calloc(sizeof(*glamor_egl), 1);
if (glamor_egl == NULL)
@@ -1087,6 +1094,11 @@ glamor_egl_init(ScrnInfoPtr scrn, int fd)
options = xnfalloc(sizeof(GlamorEGLOptions));
memcpy(options, GlamorEGLOptions, sizeof(GlamorEGLOptions));
xf86ProcessOptions(scrn->scrnIndex, scrn->options, options);
+ glvnd_vendor = xf86GetOptValString(options, GLAMOREGLOPT_VENDOR_LIBRARY);
+ if (glvnd_vendor) {
+ glamor_set_glvnd_vendor(xf86ScrnToScreen(scrn), glvnd_vendor);
+ glamor_egl->force_vendor = TRUE;
+ }
api = xf86GetOptValString(options, GLAMOREGLOPT_RENDERING_API);
if (api && !strncasecmp(api, "es", 2))
force_es = TRUE;
commit 0a1ee643b26fd53074ec90c95a14c12c8f5166b3
Author: Konstantin Pugin <ria.freelander at gmail.com>
Date: Thu Jul 21 00:49:13 2022 +0300
xorg: initialize glamor provider
This allows Xorg to use Glamor GLX when Glamor is requested,
and eliminates usage of DRI2 in case of Glamor.
Signed-off-by: Konstantin Pugin <ria.freelander at gmail.com>
Reviewed-by: Adam Jackson <ajax at redhat.com>
Acked-by: Emma Anholt <emma at anholt.net>
(cherry picked from commit a987fc7c360fa1c59efa0dde61316d84c171801b)
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1636>
diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
index f8e45c6ae..119595f09 100644
--- a/glamor/glamor_egl.c
+++ b/glamor/glamor_egl.c
@@ -46,6 +46,7 @@
#include "glamor.h"
#include "glamor_priv.h"
+#include "glamor_glx_provider.h"
#include "dri3.h"
struct glamor_egl_screen_private {
@@ -886,6 +887,9 @@ glamor_egl_screen_init(ScreenPtr screen, struct glamor_context *glamor_ctx)
glamor_egl_get_screen_private(scrn);
#ifdef DRI3
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+#endif
+#ifdef GLXEXT
+ static Bool vendor_initialized = FALSE;
#endif
const char *gbm_backend_name;
@@ -927,6 +931,13 @@ glamor_egl_screen_init(ScreenPtr screen, struct glamor_context *glamor_ctx)
}
}
#endif
+#ifdef GLXEXT
+ if (!vendor_initialized) {
+ GlxPushProvider(&glamor_provider);
+ xorgGlxCreateVendor();
+ vendor_initialized = TRUE;
+ }
+#endif
}
static void glamor_egl_cleanup(struct glamor_egl_screen_private *glamor_egl)
diff --git a/hw/xfree86/glamor_egl/meson.build b/hw/xfree86/glamor_egl/meson.build
index 7eae05812..dd1cafcd9 100644
--- a/hw/xfree86/glamor_egl/meson.build
+++ b/hw/xfree86/glamor_egl/meson.build
@@ -15,7 +15,7 @@ shared_module(
dependency('libdrm', version: '>= 2.4.46'),
gbm_dep,
],
- link_with: glamor,
+ link_with: [glamor, libxserver_glx],
install: true,
install_dir: module_dir,
commit ed1ec1350269fb91c2c276680d614653a021ee98
Author: Adam Jackson <ajax at redhat.com>
Date: Wed Aug 26 18:22:22 2020 -0400
glamor: Lift the GLX EGL backend from Xwayland
This code is almost entirely ddx-agnostic already, and I'd like to use
it from the other EGL glamor consumers. Which, right now that's just
Xorg, but soon it'll be Xephyr too.
(cherry picked from commit 58b88ba0b180ec8d05c85c80eef2d224fb0a6daf)
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1636>
diff --git a/glamor/glamor_glx_provider.c b/glamor/glamor_glx_provider.c
new file mode 100644
index 000000000..77ccc3c8b
--- /dev/null
+++ b/glamor/glamor_glx_provider.c
@@ -0,0 +1,422 @@
+/*
+ * Copyright © 2019 Red Hat, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Adam Jackson <ajax at redhat.com>
+ */
+
+/*
+ * Sets up GLX capabilities based on the EGL capabilities of the glamor
+ * renderer for the screen. Without this you will get whatever swrast
+ * can do, which often does not include things like multisample visuals.
+ */
+
+#include <dix-config.h>
+
+#define MESA_EGL_NO_X11_HEADERS
+#define EGL_NO_X11
+#include <epoxy/egl.h>
+#include "glxserver.h"
+#include "glxutil.h"
+#include "compint.h"
+#include <X11/extensions/composite.h>
+#include "glamor_priv.h"
+#include "glamor.h"
+
+/* Can't get these from <GL/glx.h> since it pulls in client headers */
+#define GLX_RGBA_BIT 0x00000001
+#define GLX_WINDOW_BIT 0x00000001
+#define GLX_PIXMAP_BIT 0x00000002
+#define GLX_PBUFFER_BIT 0x00000004
+#define GLX_NONE 0x8000
+#define GLX_SLOW_CONFIG 0x8001
+#define GLX_TRUE_COLOR 0x8002
+#define GLX_DIRECT_COLOR 0x8003
+#define GLX_NON_CONFORMANT_CONFIG 0x800D
+#define GLX_DONT_CARE 0xFFFFFFFF
+#define GLX_RGBA_FLOAT_BIT_ARB 0x00000004
+#define GLX_SWAP_UNDEFINED_OML 0x8063
+
+struct egl_config {
+ __GLXconfig base;
+ EGLConfig config;
+};
+
+struct egl_screen {
+ __GLXscreen base;
+ EGLDisplay display;
+ EGLConfig *configs;
+};
+
+static void
+egl_screen_destroy(__GLXscreen *_screen)
+{
+ struct egl_screen *screen = (struct egl_screen *)_screen;
+
+ /* XXX do we leak the fbconfig list? */
+
+ free(screen->configs);
+ __glXScreenDestroy(_screen);
+ free(_screen);
+}
+
+static void
+egl_drawable_destroy(__GLXdrawable *draw)
+{
+ free(draw);
+}
+
+static GLboolean
+egl_drawable_swap_buffers(ClientPtr client, __GLXdrawable *draw)
+{
+ return GL_FALSE;
+}
+
+static void
+egl_drawable_copy_sub_buffer(__GLXdrawable *draw, int x, int y, int w, int h)
+{
+}
+
+static void
+egl_drawable_wait_x(__GLXdrawable *draw)
+{
+ glamor_block_handler(draw->pDraw->pScreen);
+}
+
+static void
+egl_drawable_wait_gl(__GLXdrawable *draw)
+{
+}
+
+static __GLXdrawable *
+egl_create_glx_drawable(ClientPtr client, __GLXscreen *screen,
+ DrawablePtr draw, XID drawid, int type,
+ XID glxdrawid, __GLXconfig *modes)
+{
+ __GLXdrawable *ret;
+
+ ret = calloc(1, sizeof *ret);
+ if (!ret)
+ return NULL;
+
+ if (!__glXDrawableInit(ret, screen, draw, type, glxdrawid, modes)) {
+ free(ret);
+ return NULL;
+ }
+
+ ret->destroy = egl_drawable_destroy;
+ ret->swapBuffers = egl_drawable_swap_buffers;
+ ret->copySubBuffer = egl_drawable_copy_sub_buffer;
+ ret->waitX = egl_drawable_wait_x;
+ ret->waitGL = egl_drawable_wait_gl;
+
+ return ret;
+}
+
+/*
+ * TODO:
+ *
+ * - bindToTextureTargets is suspicious
+ * - better channel mask setup
+ * - drawable type masks is suspicious
+ */
+static struct egl_config *
+translate_eglconfig(struct egl_screen *screen, EGLConfig hc,
+ struct egl_config *chain, Bool direct_color,
+ Bool double_buffer, Bool duplicate_for_composite,
+ Bool srgb_only)
+{
+ EGLint value;
+ struct egl_config *c = calloc(1, sizeof *c);
+
+ if (!c)
+ return chain;
+
+ /* constants. changing these requires (at least) new EGL extensions */
+ c->base.stereoMode = GL_FALSE;
+ c->base.numAuxBuffers = 0;
+ c->base.level = 0;
+ c->base.transparentAlpha = 0;
+ c->base.transparentIndex = 0;
+ c->base.transparentPixel = GLX_NONE;
+ c->base.visualSelectGroup = 0;
+ c->base.indexBits = 0;
+ c->base.optimalPbufferWidth = 0;
+ c->base.optimalPbufferHeight = 0;
+ c->base.bindToMipmapTexture = 0;
+ c->base.bindToTextureTargets = GLX_DONT_CARE;
+ c->base.swapMethod = GLX_SWAP_UNDEFINED_OML;
+
+ /* this is... suspect */
+ c->base.drawableType = GLX_WINDOW_BIT | GLX_PIXMAP_BIT | GLX_PBUFFER_BIT;
+
+ /* hmm */
+ c->base.bindToTextureRgb = GL_TRUE;
+ c->base.bindToTextureRgba = GL_TRUE;
+
+ /*
+ * glx conformance failure: there's no such thing as accumulation
+ * buffers in EGL. they should be emulable with shaders and fbos,
+ * but i'm pretty sure nobody's using this feature since it's
+ * entirely software. note that glx conformance merely requires
+ * that an accum buffer _exist_, not a minimum bitness.
+ */
+ c->base.accumRedBits = 0;
+ c->base.accumGreenBits = 0;
+ c->base.accumBlueBits = 0;
+ c->base.accumAlphaBits = 0;
+
+ /* parametric state */
+ if (direct_color)
+ c->base.visualType = GLX_DIRECT_COLOR;
+ else
+ c->base.visualType = GLX_TRUE_COLOR;
+
+ if (double_buffer)
+ c->base.doubleBufferMode = GL_TRUE;
+ else
+ c->base.doubleBufferMode = GL_FALSE;
+
+ /* direct-mapped state */
+#define GET(attr, slot) \
+ eglGetConfigAttrib(screen->display, hc, attr, &c->base.slot)
+ GET(EGL_RED_SIZE, redBits);
+ GET(EGL_GREEN_SIZE, greenBits);
+ GET(EGL_BLUE_SIZE, blueBits);
+ GET(EGL_ALPHA_SIZE, alphaBits);
+ GET(EGL_BUFFER_SIZE, rgbBits);
+ GET(EGL_DEPTH_SIZE, depthBits);
+ GET(EGL_STENCIL_SIZE, stencilBits);
+ GET(EGL_TRANSPARENT_RED_VALUE, transparentRed);
+ GET(EGL_TRANSPARENT_GREEN_VALUE, transparentGreen);
+ GET(EGL_TRANSPARENT_BLUE_VALUE, transparentBlue);
+ GET(EGL_SAMPLE_BUFFERS, sampleBuffers);
+ GET(EGL_SAMPLES, samples);
+ if (c->base.renderType & GLX_PBUFFER_BIT) {
+ GET(EGL_MAX_PBUFFER_WIDTH, maxPbufferWidth);
+ GET(EGL_MAX_PBUFFER_HEIGHT, maxPbufferHeight);
+ GET(EGL_MAX_PBUFFER_PIXELS, maxPbufferPixels);
+ }
+#undef GET
+
+ /* derived state: config caveats */
+ eglGetConfigAttrib(screen->display, hc, EGL_CONFIG_CAVEAT, &value);
+ if (value == EGL_NONE)
+ c->base.visualRating = GLX_NONE;
+ else if (value == EGL_SLOW_CONFIG)
+ c->base.visualRating = GLX_SLOW_CONFIG;
+ else if (value == EGL_NON_CONFORMANT_CONFIG)
+ c->base.visualRating = GLX_NON_CONFORMANT_CONFIG;
+ /* else panic */
+
+ /* derived state: float configs */
+ c->base.renderType = GLX_RGBA_BIT;
+ if (eglGetConfigAttrib(screen->display, hc, EGL_COLOR_COMPONENT_TYPE_EXT,
+ &value) == EGL_TRUE) {
+ if (value == EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT) {
+ c->base.renderType = GLX_RGBA_FLOAT_BIT_ARB;
+ }
+ /* else panic */
+ }
+
+ /* derived state: sRGB. EGL doesn't put this in the fbconfig at all,
+ * it's a property of the surface specified at creation time, so we have
+ * to infer it from the GL's extensions. only makes sense at 8bpc though.
+ */
+ if (srgb_only) {
+ if (c->base.redBits == 8) {
+ c->base.sRGBCapable = GL_TRUE;
+ } else {
+ free(c);
+ return chain;
+ }
+ }
+
+ /* map to the backend's config */
+ c->config = hc;
+
+ /*
+ * XXX do something less ugly
+ */
+ if (c->base.renderType == GLX_RGBA_BIT) {
+ if (c->base.redBits == 5 &&
+ (c->base.rgbBits == 15 || c->base.rgbBits == 16)) {
+ c->base.blueMask = 0x0000001f;
+ if (c->base.alphaBits) {
+ c->base.greenMask = 0x000003e0;
+ c->base.redMask = 0x00007c00;
+ c->base.alphaMask = 0x00008000;
+ } else {
+ c->base.greenMask = 0x000007e0;
+ c->base.redMask = 0x0000f800;
+ c->base.alphaMask = 0x00000000;
+ }
+ }
+ else if (c->base.redBits == 8 &&
+ (c->base.rgbBits == 24 || c->base.rgbBits == 32)) {
+ c->base.blueMask = 0x000000ff;
+ c->base.greenMask = 0x0000ff00;
+ c->base.redMask = 0x00ff0000;
+ if (c->base.alphaBits)
+ /* assume all remaining bits are alpha */
+ c->base.alphaMask = 0xff000000;
+ }
+ else if (c->base.redBits == 10 &&
+ (c->base.rgbBits == 30 || c->base.rgbBits == 32)) {
+ c->base.blueMask = 0x000003ff;
+ c->base.greenMask = 0x000ffc00;
+ c->base.redMask = 0x3ff00000;
+ if (c->base.alphaBits)
+ /* assume all remaining bits are alpha */
+ c->base.alphaMask = 0xc000000;
+ }
+ }
+
+ /*
+ * Here we decide which fbconfigs will be duplicated for compositing.
+ * fgbconfigs marked with duplicatedForComp will be reserved for
+ * compositing visuals.
+ * It might look strange to do this decision this late when translation
+ * from an EGLConfig is already done, but using the EGLConfig
+ * accessor functions becomes worse both with respect to code complexity
+ * and CPU usage.
+ */
+ if (duplicate_for_composite &&
+ (c->base.renderType == GLX_RGBA_FLOAT_BIT_ARB ||
+ c->base.rgbBits != 32 ||
+ c->base.redBits != 8 ||
+ c->base.greenBits != 8 ||
+ c->base.blueBits != 8 ||
+ c->base.visualRating != GLX_NONE ||
+ c->base.sampleBuffers != 0)) {
+ free(c);
+ return chain;
+ }
+ c->base.duplicatedForComp = duplicate_for_composite;
+
+ c->base.next = chain ? &chain->base : NULL;
+ return c;
+}
+
+static __GLXconfig *
+egl_mirror_configs(ScreenPtr pScreen, struct egl_screen *screen)
+{
+ int i, j, k, nconfigs;
+ struct egl_config *c = NULL;
+ EGLConfig *host_configs = NULL;
+ bool can_srgb = epoxy_has_gl_extension("GL_ARB_framebuffer_sRGB") ||
+ epoxy_has_gl_extension("GL_EXT_framebuffer_sRGB") ||
+ epoxy_has_gl_extension("GL_EXT_sRGB_write_control");
+
+ eglGetConfigs(screen->display, NULL, 0, &nconfigs);
+ if (!(host_configs = calloc(nconfigs, sizeof *host_configs)))
+ return NULL;
+
+ eglGetConfigs(screen->display, host_configs, nconfigs, &nconfigs);
+
+ /* We walk the EGL configs backwards to make building the
+ * ->next chain easier.
+ */
+ for (i = nconfigs - 1; i >= 0; i--)
+ for (j = 0; j < 3; j++) /* direct_color */
+ for (k = 0; k < 2; k++) /* double_buffer */ {
+ if (can_srgb)
+ c = translate_eglconfig(screen, host_configs[i], c,
+ /* direct_color */ j == 1,
+ /* double_buffer */ k > 0,
+ /* duplicate_for_composite */ j == 0,
+ /* srgb_only */ true);
+
+ c = translate_eglconfig(screen, host_configs[i], c,
+ /* direct_color */ j == 1,
+ /* double_buffer */ k > 0,
+ /* duplicate_for_composite */ j == 0,
+ /* srgb_only */ false);
+ }
+
+ screen->configs = host_configs;
+ return c ? &c->base : NULL;
+}
+
+static __GLXscreen *
+egl_screen_probe(ScreenPtr pScreen)
+{
+ struct egl_screen *screen;
+ glamor_screen_private *glamor_screen;
+ __GLXscreen *base;
+
+ if (enableIndirectGLX)
+ return NULL; /* not implemented */
+
+ glamor_screen = glamor_get_screen_private(pScreen);
+ if (!glamor_screen)
+ return NULL;
+
+ if (!(screen = calloc(1, sizeof *screen)))
+ return NULL;
+
+ base = &screen->base;
+ base->destroy = egl_screen_destroy;
+ base->createDrawable = egl_create_glx_drawable;
+ /* base.swapInterval = NULL; */
+
+ screen->display = glamor_screen->ctx.display;
+
+ __glXInitExtensionEnableBits(screen->base.glx_enable_bits);
+ __glXEnableExtension(base->glx_enable_bits, "GLX_ARB_context_flush_control");
+ __glXEnableExtension(base->glx_enable_bits, "GLX_ARB_create_context");
+ __glXEnableExtension(base->glx_enable_bits, "GLX_ARB_create_context_no_error");
+ __glXEnableExtension(base->glx_enable_bits, "GLX_ARB_create_context_profile");
+ __glXEnableExtension(base->glx_enable_bits, "GLX_ARB_create_context_robustness");
+ __glXEnableExtension(base->glx_enable_bits, "GLX_ARB_fbconfig_float");
+ __glXEnableExtension(base->glx_enable_bits, "GLX_EXT_create_context_es2_profile");
+ __glXEnableExtension(base->glx_enable_bits, "GLX_EXT_create_context_es_profile");
+ __glXEnableExtension(base->glx_enable_bits, "GLX_EXT_fbconfig_packed_float");
+ __glXEnableExtension(base->glx_enable_bits, "GLX_EXT_framebuffer_sRGB");
+ __glXEnableExtension(base->glx_enable_bits, "GLX_EXT_no_config_context");
+ __glXEnableExtension(base->glx_enable_bits, "GLX_EXT_texture_from_pixmap");
+ __glXEnableExtension(base->glx_enable_bits, "GLX_MESA_copy_sub_buffer");
+ // __glXEnableExtension(base->glx_enable_bits, "GLX_SGI_swap_control");
+
+ base->fbconfigs = egl_mirror_configs(pScreen, screen);
+ if (!base->fbconfigs) {
+ free(screen);
+ return NULL;
+ }
+
+ if (!screen->base.glvnd && glamor_screen->glvnd_vendor)
+ screen->base.glvnd = strdup(glamor_screen->glvnd_vendor);
+
+ if (!screen->base.glvnd)
+ screen->base.glvnd = strdup("mesa");
+
+ __glXScreenInit(base, pScreen);
+ __glXsetGetProcAddress(eglGetProcAddress);
+
+ return base;
+}
+
+__GLXprovider glamor_provider = {
+ egl_screen_probe,
+ "glamor",
+ NULL
+};
diff --git a/glamor/glamor_glx_provider.h b/glamor/glamor_glx_provider.h
new file mode 100644
index 000000000..b0db90e47
--- /dev/null
+++ b/glamor/glamor_glx_provider.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright © 2019 Red Hat, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Adam Jackson <ajax at redhat.com>
+ */
+
+#ifndef XWAYLAND_GLX_H
+#define XWAYLAND_GLX_H
+
+#include <dix-config.h>
+
+#ifdef GLXEXT
+#include "glx_extinit.h"
+extern _X_EXPORT __GLXprovider glamor_provider;
+#endif
+
+#endif /* XWAYLAND_GLX_H */
diff --git a/glamor/meson.build b/glamor/meson.build
index 268af593e..1bd2c744f 100644
--- a/glamor/meson.build
+++ b/glamor/meson.build
@@ -34,6 +34,9 @@ srcs_glamor = [
'glamor_sync.c',
]
+if build_glx
+ srcs_glamor += 'glamor_glx_provider.c'
+endif
if build_xv
srcs_glamor += 'glamor_xv.c'
endif
@@ -42,7 +45,7 @@ epoxy_dep = dependency('epoxy')
glamor = static_library('glamor',
srcs_glamor,
- include_directories: inc,
+ include_directories: [inc, glx_inc],
dependencies: [
common_dep,
epoxy_dep,
commit a6145198bc1d4f535c3105f8352e420c7c59382f
Author: Konstantin Pugin <ria.freelander at gmail.com>
Date: Thu Jul 21 00:46:07 2022 +0300
glamor: add glvnd_vendor private
This commit adds an ability to store a glvnd vendor in Glamor
structures, which can be used for initialize some vendor-based values
without hooking into DDX internals. Also this adds setting this value
into Xorg and Xwayland
Signed-off-by: Konstantin Pugin <ria.freelander at gmail.com>
Reviewed-by: Adam Jackson <ajax at redhat.com>
Acked-by: Emma Anholt <emma at anholt.net>
(cherry picked from commit 3caf7aa88d31450f116589d68ff66f78285f0e33)
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1636>
diff --git a/glamor/glamor.c b/glamor/glamor.c
index 8e4485127..8b8590f73 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -964,6 +964,7 @@ glamor_close_screen(ScreenPtr screen)
glamor_priv = glamor_get_screen_private(screen);
glamor_sync_close(screen);
glamor_composite_glyphs_fini(screen);
+ glamor_set_glvnd_vendor(screen, NULL);
screen->CloseScreen = glamor_priv->saved_procs.close_screen;
screen->CreateGC = glamor_priv->saved_procs.create_gc;
@@ -996,6 +997,31 @@ glamor_fini(ScreenPtr screen)
/* Do nothing currently. */
}
+void
+glamor_set_glvnd_vendor(ScreenPtr screen, const char *vendor_name)
+{
+ glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+
+ if (!glamor_priv)
+ return;
+
+ if (glamor_priv->glvnd_vendor)
+ free(glamor_priv->glvnd_vendor);
+
+ glamor_priv->glvnd_vendor = xnfstrdup(vendor_name);
+}
+
+const char *
+glamor_get_glvnd_vendor(ScreenPtr screen)
+{
+ glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+
+ if (!glamor_priv)
+ return NULL;
+
+ return glamor_priv->glvnd_vendor;
+}
+
void
glamor_enable_dri3(ScreenPtr screen)
{
diff --git a/glamor/glamor.h b/glamor/glamor.h
index 31157471d..f5634b7e7 100644
--- a/glamor/glamor.h
+++ b/glamor/glamor.h
@@ -120,6 +120,12 @@ extern _X_EXPORT void glamor_clear_pixmap(PixmapPtr pixmap);
extern _X_EXPORT void glamor_block_handler(ScreenPtr screen);
+/* This function should be called after glamor_init,
+ * but before adding a glamor GLX provider */
+extern _X_EXPORT void glamor_set_glvnd_vendor(ScreenPtr screen,
+ const char *vendor);
+extern _X_EXPORT const char *glamor_get_glvnd_vendor(ScreenPtr screen);
+
extern _X_EXPORT PixmapPtr glamor_create_pixmap(ScreenPtr screen, int w, int h,
int depth, unsigned int usage);
extern _X_EXPORT Bool glamor_destroy_pixmap(PixmapPtr pixmap);
diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
index 845234cec..f8e45c6ae 100644
--- a/glamor/glamor_egl.c
+++ b/glamor/glamor_egl.c
@@ -887,6 +887,7 @@ glamor_egl_screen_init(ScreenPtr screen, struct glamor_context *glamor_ctx)
#ifdef DRI3
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
#endif
+ const char *gbm_backend_name;
glamor_egl->saved_close_screen = screen->CloseScreen;
screen->CloseScreen = glamor_egl_close_screen;
@@ -899,6 +900,10 @@ glamor_egl_screen_init(ScreenPtr screen, struct glamor_context *glamor_ctx)
glamor_ctx->make_current = glamor_egl_make_current;
+ gbm_backend_name = gbm_device_get_backend_name(glamor_egl->gbm);
+ /* Mesa uses "drm" as backend name, in that case, just do nothing */
+ if (gbm_backend_name && strcmp(gbm_backend_name, "drm") != 0)
+ glamor_set_glvnd_vendor(screen, gbm_backend_name);
#ifdef DRI3
/* Tell the core that we have the interfaces for import/export
* of pixmaps.
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index ee7c896eb..657b991f5 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -335,6 +335,7 @@ typedef struct glamor_screen_private {
int flags;
ScreenPtr screen;
int dri3_enabled;
+ char *glvnd_vendor;
Bool suppress_gl_out_of_memory_logging;
Bool logged_any_fbo_allocation_failure;
commit 93abc39fcdcd620dcfc425f4bee55dcbdfd8c5c4
Author: Konstantin <ria.freelander at gmail.com>
Date: Thu Sep 21 17:07:43 2023 +0300
glamor_egl: add info message about context API
It is useful to know on what context we are running, and
we need to show it into xorg.log
Reviewed-by: Adam Jackson <ajax at redhat.com>
Signed-off-by: Konstantin <ria.freelander at gmail.com>
(cherry picked from commit c014f33b43047975cfa4cb0254c36e39669575ad)
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1636>
diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
index f70278e1c..845234cec 100644
--- a/glamor/glamor_egl.c
+++ b/glamor/glamor_egl.c
@@ -1000,6 +1000,10 @@ glamor_egl_try_big_gl_api(ScrnInfoPtr scrn)
eglDestroyContext(glamor_egl->display, glamor_egl->context);
glamor_egl->context = EGL_NO_CONTEXT;
}
+ xf86DrvMsg(scrn->scrnIndex, X_INFO,
+ "glamor: Using OpenGL %d.%d context.\n",
+ epoxy_gl_version() / 10,
+ epoxy_gl_version() % 10);
}
return TRUE;
}
@@ -1031,6 +1035,10 @@ glamor_egl_try_gles_api(ScrnInfoPtr scrn)
"Failed to make GLES context current\n");
return FALSE;
}
+ xf86DrvMsg(scrn->scrnIndex, X_INFO,
+ "glamor: Using OpenGL ES %d.%d context.\n",
+ epoxy_gl_version() / 10,
+ epoxy_gl_version() % 10);
}
return TRUE;
}
commit 98ac366741ec2c88fe517642f5549eb5eecd638e
Author: Konstantin <ria.freelander at gmail.com>
Date: Fri Sep 22 12:29:52 2023 +0300
xorg.conf.man: document new RenderingAPI option
Reviewed-by: Adam Jackson <ajax at redhat.com>
Signed-off-by: Konstantin <ria.freelander at gmail.com>
(cherry picked from commit 4fc1500f747eb53292311098772c32efad7f2fd6)
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1636>
diff --git a/hw/xfree86/man/xorg.conf.man b/hw/xfree86/man/xorg.conf.man
index 10ff3caaa..d0aef7be8 100644
--- a/hw/xfree86/man/xorg.conf.man
+++ b/hw/xfree86/man/xorg.conf.man
@@ -2090,6 +2090,14 @@ use for the screen. This may be used to select an alternate implementation
for development, debugging, or alternate feature sets.
Default: mesa.
.TP 7
+.BI "Option \*RenderingAPI\*q \*q" string \*q
+This option specifies an rendering API for use in conjunction with Glamor
+accel method. You can specify OpenGL with a value "gl" and OpenGL ES with a
+value "es", and the default is both, when Glamor fallbacks to GLES if GL 2.1 is
+not available. This may be useful for embedded and old cards, where GL ES
+feature set works faster than GL feature set.
+Default: gl.
+.TP 7
.BI "Option \*qInitPrimary\*q \*q" boolean \*q
Use the Int10 module to initialize the primary graphics card.
Normally, only secondary cards are soft-booted using the Int10 module, as the
commit 2f659415899296c784874489d85cffd3b3bb2e4b
Author: Konstantin <ria.freelander at gmail.com>
Date: Thu Sep 21 18:06:14 2023 +0300
glamor_egl: add RenderingAPI option
This allows to choose between Glamor on OpenGL and Glamor on OpenGL ES
via an option.
Reviewed-by: Adam Jackson <ajax at redhat.com>
Signed-off-by: Konstantin <ria.freelander at gmail.com>
(cherry picked from commit a44a4b0d4de267eb66f4aa33c84a4e9288fb7c01)
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1636>
diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
index a4a837c47..f70278e1c 100644
--- a/glamor/glamor_egl.c
+++ b/glamor/glamor_egl.c
@@ -1035,13 +1035,24 @@ glamor_egl_try_gles_api(ScrnInfoPtr scrn)
return TRUE;
}
+enum {
+ GLAMOREGLOPT_RENDERING_API,
+};
+
+static const OptionInfoRec GlamorEGLOptions[] = {
+ { GLAMOREGLOPT_RENDERING_API, "RenderingAPI", OPTV_STRING, {0}, FALSE },
+ { -1, NULL, OPTV_NONE, {0}, FALSE },
+};
+
Bool
glamor_egl_init(ScrnInfoPtr scrn, int fd)
{
struct glamor_egl_screen_private *glamor_egl;
const GLubyte *renderer;
- EGLConfig egl_config;
- int n;
+ OptionInfoPtr options;
+ const char *api = NULL;
+ Bool es_allowed = TRUE;
+ Bool force_es = FALSE;
glamor_egl = calloc(sizeof(*glamor_egl), 1);
if (glamor_egl == NULL)
@@ -1049,6 +1060,16 @@ glamor_egl_init(ScrnInfoPtr scrn, int fd)
if (xf86GlamorEGLPrivateIndex == -1)
xf86GlamorEGLPrivateIndex = xf86AllocateScrnInfoPrivateIndex();
+ options = xnfalloc(sizeof(GlamorEGLOptions));
+ memcpy(options, GlamorEGLOptions, sizeof(GlamorEGLOptions));
+ xf86ProcessOptions(scrn->scrnIndex, scrn->options, options);
+ api = xf86GetOptValString(options, GLAMOREGLOPT_RENDERING_API);
+ if (api && !strncasecmp(api, "es", 2))
+ force_es = TRUE;
+ else if (api && !strncasecmp(api, "gl", 2))
+ es_allowed = FALSE;
+ free(options);
+
scrn->privates[xf86GlamorEGLPrivateIndex].ptr = glamor_egl;
glamor_egl->fd = fd;
glamor_egl->gbm = gbm_create_device(glamor_egl->fd);
@@ -1085,10 +1106,12 @@ glamor_egl_init(ScrnInfoPtr scrn, int fd)
GLAMOR_CHECK_EGL_EXTENSION(KHR_surfaceless_context);
- if(!glamor_egl_try_big_gl_api(scrn))
- goto error;
+ if (!force_es) {
+ if(!glamor_egl_try_big_gl_api(scrn))
+ goto error;
+ }
- if (glamor_egl->context == EGL_NO_CONTEXT) {
+ if (glamor_egl->context == EGL_NO_CONTEXT && es_allowed) {
if(!glamor_egl_try_gles_api(scrn))
goto error;
}
commit e4f79ed0addbeb2c8bc4afead319a8c21306323b
Author: Konstantin <ria.freelander at gmail.com>
Date: Tue Oct 31 19:52:07 2023 +0300
glamor_egl: add helper functions for contexts
This is just a split big glamor_egl_init to 3 smaller functions.
No functional change.
Signed-off-by: Konstantin <ria.freelander at gmail.com>
(cherry picked from commit d5c2a4d3f55a873fe6ba0fc77a42f8d1510bcb3d)
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1636>
diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
index b1e81d422..a4a837c47 100644
--- a/glamor/glamor_egl.c
+++ b/glamor/glamor_egl.c
@@ -955,6 +955,86 @@ glamor_egl_free_screen(ScrnInfoPtr scrn)
}
}
+static Bool
+glamor_egl_try_big_gl_api(ScrnInfoPtr scrn)
+{
+ struct glamor_egl_screen_private *glamor_egl =
+ glamor_egl_get_screen_private(scrn);
+
+ if (eglBindAPI(EGL_OPENGL_API)) {
+ static const EGLint config_attribs_core[] = {
+ EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR,
+ EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR,
+ EGL_CONTEXT_MAJOR_VERSION_KHR,
+ GLAMOR_GL_CORE_VER_MAJOR,
+ EGL_CONTEXT_MINOR_VERSION_KHR,
+ GLAMOR_GL_CORE_VER_MINOR,
+ EGL_NONE
+ };
+ static const EGLint config_attribs[] = {
+ EGL_NONE
+ };
+
+ glamor_egl->context = eglCreateContext(glamor_egl->display,
+ EGL_NO_CONFIG_KHR, EGL_NO_CONTEXT,
+ config_attribs_core);
+
+ if (glamor_egl->context == EGL_NO_CONTEXT)
+ glamor_egl->context = eglCreateContext(glamor_egl->display,
+ EGL_NO_CONFIG_KHR,
+ EGL_NO_CONTEXT,
+ config_attribs);
+ }
+
+ if (glamor_egl->context != EGL_NO_CONTEXT) {
+ if (!eglMakeCurrent(glamor_egl->display,
+ EGL_NO_SURFACE, EGL_NO_SURFACE, glamor_egl->context)) {
+ xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+ "Failed to make GL context current\n");
+ return FALSE;
+ }
+
+ if (epoxy_gl_version() < 21) {
+ xf86DrvMsg(scrn->scrnIndex, X_INFO,
+ "glamor: Ignoring GL < 2.1, falling back to GLES.\n");
+ eglDestroyContext(glamor_egl->display, glamor_egl->context);
+ glamor_egl->context = EGL_NO_CONTEXT;
+ }
+ }
+ return TRUE;
+}
+
+static Bool
+glamor_egl_try_gles_api(ScrnInfoPtr scrn)
+{
+ struct glamor_egl_screen_private *glamor_egl =
+ glamor_egl_get_screen_private(scrn);
+
+ static const EGLint config_attribs[] = {
+ EGL_CONTEXT_CLIENT_VERSION, 2,
+ EGL_NONE
+ };
+ if (!eglBindAPI(EGL_OPENGL_ES_API)) {
+ xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+ "glamor: Failed to bind GLES API.\n");
+ return FALSE;
+ }
+
+ glamor_egl->context = eglCreateContext(glamor_egl->display,
+ EGL_NO_CONFIG_KHR, EGL_NO_CONTEXT,
+ config_attribs);
+
+ if (glamor_egl->context != EGL_NO_CONTEXT) {
+ if (!eglMakeCurrent(glamor_egl->display,
+ EGL_NO_SURFACE, EGL_NO_SURFACE, glamor_egl->context)) {
+ xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+ "Failed to make GLES context current\n");
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
Bool
glamor_egl_init(ScrnInfoPtr scrn, int fd)
{
@@ -1005,79 +1085,18 @@ glamor_egl_init(ScrnInfoPtr scrn, int fd)
GLAMOR_CHECK_EGL_EXTENSION(KHR_surfaceless_context);
- if (eglBindAPI(EGL_OPENGL_API)) {
- static const EGLint config_attribs_core[] = {
- EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR,
- EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR,
- EGL_CONTEXT_MAJOR_VERSION_KHR,
- GLAMOR_GL_CORE_VER_MAJOR,
- EGL_CONTEXT_MINOR_VERSION_KHR,
- GLAMOR_GL_CORE_VER_MINOR,
- EGL_NONE
- };
- static const EGLint config_attribs[] = {
- EGL_NONE
- };
-
- glamor_egl->context = eglCreateContext(glamor_egl->display,
- NULL, EGL_NO_CONTEXT,
- config_attribs_core);
-
- if (glamor_egl->context == EGL_NO_CONTEXT)
- glamor_egl->context = eglCreateContext(glamor_egl->display,
- NULL, EGL_NO_CONTEXT,
- config_attribs);
- }
+ if(!glamor_egl_try_big_gl_api(scrn))
+ goto error;
- if (glamor_egl->context != EGL_NO_CONTEXT) {
- if (!eglMakeCurrent(glamor_egl->display,
- EGL_NO_SURFACE, EGL_NO_SURFACE, glamor_egl->context)) {
- xf86DrvMsg(scrn->scrnIndex, X_ERROR,
- "Failed to make GL context current\n");
+ if (glamor_egl->context == EGL_NO_CONTEXT) {
+ if(!glamor_egl_try_gles_api(scrn))
goto error;
- }
-
- if (epoxy_gl_version() < 21) {
- xf86DrvMsg(scrn->scrnIndex, X_INFO,
- "glamor: Ignoring GL < 2.1, falling back to GLES.\n");
- eglDestroyContext(glamor_egl->display, glamor_egl->context);
- glamor_egl->context = EGL_NO_CONTEXT;
- }
}
if (glamor_egl->context == EGL_NO_CONTEXT) {
- static const EGLint config_attribs[] = {
- EGL_CONTEXT_CLIENT_VERSION, 2,
- EGL_NONE
- };
- if (!eglBindAPI(EGL_OPENGL_ES_API)) {
- xf86DrvMsg(scrn->scrnIndex, X_ERROR,
- "glamor: Failed to bind either GL or GLES APIs.\n");
- goto error;
- }
-
- if (!eglChooseConfig(glamor_egl->display, NULL, &egl_config, 1, &n)) {
- xf86DrvMsg(scrn->scrnIndex, X_ERROR,
- "glamor: No acceptable EGL configs found\n");
- goto error;
- }
-
- glamor_egl->context = eglCreateContext(glamor_egl->display,
- egl_config, EGL_NO_CONTEXT,
- config_attribs);
-
- if (glamor_egl->context == EGL_NO_CONTEXT) {
- xf86DrvMsg(scrn->scrnIndex, X_ERROR,
- "glamor: Failed to create GL or GLES2 contexts\n");
- goto error;
- }
-
- if (!eglMakeCurrent(glamor_egl->display,
- EGL_NO_SURFACE, EGL_NO_SURFACE, glamor_egl->context)) {
- xf86DrvMsg(scrn->scrnIndex, X_ERROR,
- "Failed to make GLES2 context current\n");
- goto error;
- }
+ xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+ "glamor: Failed to create GL or GLES2 contexts\n");
+ goto error;
}
renderer = glGetString(GL_RENDERER);
commit 40af9f2d1af27287bdd5f07892aa6fe34f61d9d4
Author: Balló György <ballogyor at gmail.com>
Date: Wed Oct 11 16:01:13 2023 +0200
glamor: Don't require EXT_gpu_shader4 unconditionally
It causes a shader compilation error on systems without EXT_gpu_shader4.
Fixes: ee107cd4
(cherry picked from commit 910847f45265aa1b0177dc4be4d165dc71c01b69)
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1636>
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index c3d325503..43859ebde 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -237,7 +237,11 @@ glamor_create_composite_fs(glamor_screen_private *glamor_priv, struct shader_key
const char *mask_fetch = "";
const char *in;
const char *header;
- const char *header_norm = glamor_priv->glsl_version > 120 ? "#version 130\n" : "#version 120\n#extension GL_EXT_gpu_shader4 : require\n" GLAMOR_COMPAT_DEFINES_FS;
+ const char *header_norm = glamor_priv->glsl_version > 120 ?
+ "#version 130\n" :
+ glamor_priv->use_gpu_shader4 ?
+ "#version 120\n#extension GL_EXT_gpu_shader4 : require\n" GLAMOR_COMPAT_DEFINES_FS :
+ "#version 120\n" GLAMOR_COMPAT_DEFINES_FS;
const char *header_es = glamor_priv->glsl_version > 100 ? "#version 300 es\n" : "#version 100\n" GLAMOR_COMPAT_DEFINES_FS;
const char *dest_swizzle;
GLuint prog;
commit 7fda68174bc5be3332a9dd1922ec51a97350225b
Author: Konstantin Pugin <ria.freelander at gmail.com>
Date: Sun Jul 24 16:03:51 2022 +0300
glamor: support GLES3 shaders
Some hardware (preferably mobile) working on GLES3 way faster than
on desktop GL and supports more features. This commit will allow using
GLES3 if glamor is running over GL ES, and version 3 is supported.
Changes are the following:
1. Add compatibility layer for 120/GLES2 shaders with defines in and out
2. Switch attribute and varying to in and out in almost all shaders
(aside gradient)
3. Add newGL-only frag_color variable, which defines as gl_FragColor on
old pipelines
4. Switch all shaders to use frag_color.
5. Previous commit is reverted, because now we have more than one GL ES
version, previous commit used to set version 100 for all ES shaders, which
is not true for ES 3
Signed-off-by: Konstantin Pugin <ria.freelander at gmail.com>
(cherry picked from commit ee107cd4911e692480ab2ff9c12e3c6958bdec4e)
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1636>
diff --git a/glamor/glamor.c b/glamor/glamor.c
index 0d6e0536e..8e4485127 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -734,17 +734,6 @@ glamor_init(ScreenPtr screen, unsigned int flags)
}
glamor_priv->glsl_version = glsl_major * 100 + glsl_minor;
- if (glamor_priv->is_gles) {
- /* Force us back to the base version of our programs on an ES
- * context, anyway. Basically glamor only uses desktop 1.20
- * or 1.30 currently. 1.30's new features are also present in
- * ES 3.0, but our glamor_program.c constructions use a lot of
- * compatibility features (to reduce the diff between 1.20 and
- * 1.30 programs).
- */
- glamor_priv->glsl_version = 120;
- }
-
/* We'd like to require GL_ARB_map_buffer_range or
* GL_OES_map_buffer_range, since it offers more information to
* the driver than plain old glMapBuffer() or glBufferSubData().
@@ -778,6 +767,7 @@ glamor_init(ScreenPtr screen, unsigned int flags)
* etnaviv offers GLSL 140 with OpenGL 2.1.
*/
if (glamor_glsl_has_ints(glamor_priv) &&
+ !glamor_priv->is_gles &&
!epoxy_has_gl_extension("GL_ARB_instanced_arrays"))
glamor_priv->glsl_version = 120;
} else {
diff --git a/glamor/glamor_composite_glyphs.c b/glamor/glamor_composite_glyphs.c
index c69b940d4..102ed4640 100644
--- a/glamor/glamor_composite_glyphs.c
+++ b/glamor/glamor_composite_glyphs.c
@@ -180,16 +180,16 @@ glamor_glyph_add(struct glamor_glyph_atlas *atlas, DrawablePtr glyph_draw)
static const glamor_facet glamor_facet_composite_glyphs_130 = {
.name = "composite_glyphs",
.version = 130,
- .vs_vars = ("attribute vec4 primitive;\n"
- "attribute vec2 source;\n"
- "varying vec2 glyph_pos;\n"),
+ .vs_vars = ("in vec4 primitive;\n"
+ "in vec2 source;\n"
+ "out vec2 glyph_pos;\n"),
.vs_exec = (" vec2 pos = primitive.zw * vec2(gl_VertexID&1, (gl_VertexID&2)>>1);\n"
GLAMOR_POS(gl_Position, (primitive.xy + pos))
" glyph_pos = (source + pos) * ATLAS_DIM_INV;\n"),
- .fs_vars = ("varying vec2 glyph_pos;\n"
+ .fs_vars = ("in vec2 glyph_pos;\n"
"out vec4 color0;\n"
"out vec4 color1;\n"),
- .fs_exec = (" vec4 mask = texture2D(atlas, glyph_pos);\n"),
+ .fs_exec = (" vec4 mask = texture(atlas, glyph_pos);\n"),
.source_name = "source",
.locations = glamor_program_location_atlas,
};
diff --git a/glamor/glamor_copy.c b/glamor/glamor_copy.c
index 1ab2be6c0..eae70e95f 100644
--- a/glamor/glamor_copy.c
+++ b/glamor/glamor_copy.c
@@ -49,10 +49,10 @@ use_copyarea(PixmapPtr dst, GCPtr gc, glamor_program *prog, void *arg)
static const glamor_facet glamor_facet_copyarea = {
"copy_area",
- .vs_vars = "attribute vec2 primitive;\n",
+ .vs_vars = "in vec2 primitive;\n",
.vs_exec = (GLAMOR_POS(gl_Position, primitive.xy)
" fill_pos = (fill_offset + primitive.xy) * fill_size_inv;\n"),
- .fs_exec = " gl_FragColor = texture2D(sampler, fill_pos);\n",
+ .fs_exec = " frag_color = texture(sampler, fill_pos);\n",
.locations = glamor_program_location_fillsamp | glamor_program_location_fillpos,
.use = use_copyarea,
};
@@ -141,14 +141,14 @@ use_copyplane(PixmapPtr dst, GCPtr gc, glamor_program *prog, void *arg)
static const glamor_facet glamor_facet_copyplane = {
"copy_plane",
.version = 130,
- .vs_vars = "attribute vec2 primitive;\n",
+ .vs_vars = "in vec2 primitive;\n",
.vs_exec = (GLAMOR_POS(gl_Position, (primitive.xy))
" fill_pos = (fill_offset + primitive.xy) * fill_size_inv;\n"),
- .fs_exec = (" uvec4 bits = uvec4(round(texture2D(sampler, fill_pos) * bitmul));\n"
+ .fs_exec = (" uvec4 bits = uvec4(round(texture(sampler, fill_pos) * bitmul));\n"
" if ((bits & bitplane) != uvec4(0,0,0,0))\n"
- " gl_FragColor = fg;\n"
+ " frag_color = fg;\n"
" else\n"
- " gl_FragColor = bg;\n"),
+ " frag_color = bg;\n"),
.locations = glamor_program_location_fillsamp|glamor_program_location_fillpos|glamor_program_location_fg|glamor_program_location_bg|glamor_program_location_bitplane,
.use = use_copyplane,
};
diff --git a/glamor/glamor_dash.c b/glamor/glamor_dash.c
index b53ce5c50..c27367070 100644
--- a/glamor/glamor_dash.c
+++ b/glamor/glamor_dash.c
@@ -27,8 +27,8 @@
#include "glamor_prepare.h"
static const char dash_vs_vars[] =
- "attribute vec3 primitive;\n"
- "varying float dash_offset;\n";
+ "in vec3 primitive;\n"
+ "out float dash_offset;\n";
static const char dash_vs_exec[] =
" dash_offset = primitive.z / dash_length;\n"
@@ -36,20 +36,20 @@ static const char dash_vs_exec[] =
GLAMOR_POS(gl_Position, primitive.xy);
static const char dash_fs_vars[] =
- "varying float dash_offset;\n";
+ "in float dash_offset;\n";
static const char on_off_fs_exec[] =
- " float pattern = texture2D(dash, vec2(dash_offset, 0.5)).w;\n"
+ " float pattern = texture(dash, vec2(dash_offset, 0.5)).w;\n"
" if (pattern == 0.0)\n"
" discard;\n";
/* XXX deal with stippled double dashed lines once we have stippling support */
static const char double_fs_exec[] =
- " float pattern = texture2D(dash, vec2(dash_offset, 0.5)).w;\n"
+ " float pattern = texture(dash, vec2(dash_offset, 0.5)).w;\n"
" if (pattern == 0.0)\n"
- " gl_FragColor = bg;\n"
+ " frag_color = bg;\n"
" else\n"
- " gl_FragColor = fg;\n";
+ " frag_color = fg;\n";
static const glamor_facet glamor_facet_on_off_dash_lines = {
diff --git a/glamor/glamor_glyphblt.c b/glamor/glamor_glyphblt.c
index 2f9f94f93..cada7bae7 100644
--- a/glamor/glamor_glyphblt.c
+++ b/glamor/glamor_glyphblt.c
@@ -32,7 +32,7 @@
static const glamor_facet glamor_facet_poly_glyph_blt = {
.name = "poly_glyph_blt",
- .vs_vars = "attribute vec2 primitive;\n",
+ .vs_vars = "in vec2 primitive;\n",
.vs_exec = (" vec2 pos = vec2(0,0);\n"
GLAMOR_DEFAULT_POINT_SIZE
GLAMOR_POS(gl_Position, primitive)),
diff --git a/glamor/glamor_lines.c b/glamor/glamor_lines.c
index 5d95333fe..5f0758896 100644
--- a/glamor/glamor_lines.c
+++ b/glamor/glamor_lines.c
@@ -27,7 +27,7 @@
static const glamor_facet glamor_facet_poly_lines = {
.name = "poly_lines",
- .vs_vars = "attribute vec2 primitive;\n",
+ .vs_vars = "in vec2 primitive;\n",
.vs_exec = (" vec2 pos = vec2(0.0,0.0);\n"
GLAMOR_POS(gl_Position, primitive.xy)),
};
diff --git a/glamor/glamor_points.c b/glamor/glamor_points.c
index 5f4a8f56a..71228a1c5 100644
--- a/glamor/glamor_points.c
+++ b/glamor/glamor_points.c
@@ -31,7 +31,7 @@
static const glamor_facet glamor_facet_point = {
.name = "poly_point",
- .vs_vars = "attribute vec2 primitive;\n",
+ .vs_vars = "in vec2 primitive;\n",
.vs_exec = (GLAMOR_DEFAULT_POINT_SIZE
GLAMOR_POS(gl_Position, primitive)),
};
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 608e9cbc2..ee7c896eb 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -54,6 +54,19 @@
" gl_PointSize = 1.0;\n" \
"#endif\n"
+#define GLAMOR_COMPAT_DEFINES_VS \
+ "#define in attribute\n" \
+ "#define out varying\n" \
+
+#define GLAMOR_COMPAT_DEFINES_FS \
+ "#if __VERSION__ < 130\n" \
+ "#define in varying\n" \
+ "#define frag_color gl_FragColor\n" \
+ "#define texture texture2D\n" \
+ "#else\n" \
+ "out vec4 frag_color;\n" \
+ "#endif\n"
+
#include "glyphstr.h"
#include "glamor_debug.h"
diff --git a/glamor/glamor_program.c b/glamor/glamor_program.c
index f8bb0efb8..1d9277eee 100644
--- a/glamor/glamor_program.c
+++ b/glamor/glamor_program.c
@@ -32,7 +32,7 @@ use_solid(PixmapPtr pixmap, GCPtr gc, glamor_program *prog, void *arg)
const glamor_facet glamor_fill_solid = {
.name = "solid",
- .fs_exec = " gl_FragColor = fg;\n",
+ .fs_exec = " frag_color = fg;\n",
.locations = glamor_program_location_fg,
.use = use_solid,
};
@@ -46,7 +46,7 @@ use_tile(PixmapPtr pixmap, GCPtr gc, glamor_program *prog, void *arg)
static const glamor_facet glamor_fill_tile = {
.name = "tile",
.vs_exec = " fill_pos = (fill_offset + primitive.xy + pos) * fill_size_inv;\n",
- .fs_exec = " gl_FragColor = texture2D(sampler, fill_pos);\n",
+ .fs_exec = " frag_color = texture(sampler, fill_pos);\n",
.locations = glamor_program_location_fillsamp | glamor_program_location_fillpos,
.use = use_tile,
};
@@ -62,10 +62,10 @@ use_stipple(PixmapPtr pixmap, GCPtr gc, glamor_program *prog, void *arg)
static const glamor_facet glamor_fill_stipple = {
.name = "stipple",
.vs_exec = " fill_pos = (fill_offset + primitive.xy + pos) * fill_size_inv;\n",
- .fs_exec = (" float a = texture2D(sampler, fill_pos).w;\n"
+ .fs_exec = (" float a = texture(sampler, fill_pos).w;\n"
" if (a == 0.0)\n"
" discard;\n"
- " gl_FragColor = fg;\n"),
+ " frag_color = fg;\n"),
.locations = glamor_program_location_fg | glamor_program_location_fillsamp | glamor_program_location_fillpos,
.use = use_stipple,
};
@@ -82,11 +82,11 @@ use_opaque_stipple(PixmapPtr pixmap, GCPtr gc, glamor_program *prog, void *arg)
static const glamor_facet glamor_fill_opaque_stipple = {
.name = "opaque_stipple",
.vs_exec = " fill_pos = (fill_offset + primitive.xy + pos) * fill_size_inv;\n",
- .fs_exec = (" float a = texture2D(sampler, fill_pos).w;\n"
+ .fs_exec = (" float a = texture(sampler, fill_pos).w;\n"
" if (a == 0.0)\n"
- " gl_FragColor = bg;\n"
+ " frag_color = bg;\n"
" else\n"
- " gl_FragColor = fg;\n"),
+ " frag_color = fg;\n"),
.locations = glamor_program_location_fg | glamor_program_location_bg | glamor_program_location_fillsamp | glamor_program_location_fillpos,
.use = use_opaque_stipple
};
@@ -121,12 +121,15 @@ static glamor_location_var location_vars[] = {
.location = glamor_program_location_fillpos,
.vs_vars = ("uniform vec2 fill_offset;\n"
"uniform vec2 fill_size_inv;\n"
- "varying vec2 fill_pos;\n"),
- .fs_vars = ("varying vec2 fill_pos;\n")
+ "out vec2 fill_pos;\n"),
+ .fs_vars = ("in vec2 fill_pos;\n")
},
{
.location = glamor_program_location_font,
- .fs_vars = "uniform usampler2D font;\n",
+ .fs_vars = ("#ifdef GL_ES\n"
+ "precision mediump usampler2D;\n"
+ "#endif\n"
+ "uniform usampler2D font;\n"),
},
{
.location = glamor_program_location_bitplane,
@@ -188,6 +191,7 @@ fs_location_vars(glamor_program_location locations)
static const char vs_template[] =
"%s" /* version */
"%s" /* exts */
+ "%s" /* in/out defines */
"%s" /* defines */
"%s" /* prim vs_vars */
"%s" /* fill vs_vars */
@@ -204,6 +208,7 @@ static const char fs_template[] =
"%s" /* prim fs_extensions */
"%s" /* fill fs_extensions */
GLAMOR_DEFAULT_PRECISION
+ "%s" /* in/out defines */
"%s" /* defines */
"%s" /* prim fs_vars */
"%s" /* fill fs_vars */
@@ -283,11 +288,13 @@ glamor_build_program(ScreenPtr screen,
gpu_shader4 = TRUE;
}
}
- /* For now, fix shader version to GLES as 100. We will fall with 130 shaders
- * in previous check due to forcibly set 120 glsl for GLES. But this patch
- * makes xv shaders to work */
- if(version && glamor_priv->is_gles)
+
+ if (version == 130 && glamor_priv->is_gles && glamor_priv->glsl_version > 110)
+ version = 300;
+ else if (glamor_priv->is_gles)
version = 100;
+ else if (!version)
+ version = 120;
vs_vars = vs_location_vars(locations);
fs_vars = fs_location_vars(locations);
@@ -298,7 +305,8 @@ glamor_build_program(ScreenPtr screen,
goto fail;
if (version) {
- if (asprintf(&version_string, "#version %d\n", version) < 0)
+ if (asprintf(&version_string, "#version %d %s\n", version,
+ glamor_priv->is_gles && version > 100 ? "es" : "") < 0)
version_string = NULL;
if (!version_string)
goto fail;
@@ -308,6 +316,7 @@ glamor_build_program(ScreenPtr screen,
vs_template,
str(version_string),
gpu_shader4 ? "#extension GL_EXT_gpu_shader4 : require\n" : "",
+ version < 130 ? GLAMOR_COMPAT_DEFINES_VS : "",
str(defines),
str(prim->vs_vars),
str(fill->vs_vars),
@@ -322,6 +331,7 @@ glamor_build_program(ScreenPtr screen,
str(prim->fs_extensions),
str(fill->fs_extensions),
gpu_shader4 ? "#extension GL_EXT_gpu_shader4 : require\n#define texelFetch texelFetch2D\n#define uint unsigned int\n" : "",
+ GLAMOR_COMPAT_DEFINES_FS,
str(defines),
str(prim->fs_vars),
str(fill->fs_vars),
@@ -563,7 +573,7 @@ use_source_picture(CARD8 op, PicturePtr src, PicturePtr dst, glamor_program *pro
static const glamor_facet glamor_source_picture = {
.name = "render_picture",
.vs_exec = " fill_pos = (fill_offset + primitive.xy + pos) * fill_size_inv;\n",
- .fs_exec = " vec4 source = texture2D(sampler, fill_pos);\n",
+ .fs_exec = " vec4 source = texture(sampler, fill_pos);\n",
.locations = glamor_program_location_fillsamp | glamor_program_location_fillpos,
.use_render = use_source_picture,
};
@@ -579,7 +589,7 @@ use_source_1x1_picture(CARD8 op, PicturePtr src, PicturePtr dst, glamor_program
static const glamor_facet glamor_source_1x1_picture = {
.name = "render_picture",
- .fs_exec = " vec4 source = texture2D(sampler, vec2(0.5));\n",
+ .fs_exec = " vec4 source = texture(sampler, vec2(0.5));\n",
.locations = glamor_program_location_fillsamp,
.use_render = use_source_1x1_picture,
};
@@ -591,11 +601,11 @@ static const glamor_facet *glamor_facet_source[glamor_program_source_count] = {
};
static const char *glamor_combine[] = {
- [glamor_program_alpha_normal] = " gl_FragColor = source * mask.a;\n",
- [glamor_program_alpha_ca_first] = " gl_FragColor = source.a * mask;\n",
- [glamor_program_alpha_ca_second] = " gl_FragColor = source * mask;\n",
- [glamor_program_alpha_dual_blend] = " color0 = source * mask;\n"
- " color1 = source.a * mask;\n",
+ [glamor_program_alpha_normal] = " frag_color = source * mask.a;\n",
+ [glamor_program_alpha_ca_first] = " frag_color = source.a * mask;\n",
+ [glamor_program_alpha_ca_second] = " frag_color = source * mask;\n",
+ [glamor_program_alpha_dual_blend] = " color0 = source * mask;\n"
+ " color1 = source.a * mask;\n",
[glamor_program_alpha_dual_blend_gles2] = " gl_FragColor = source * mask;\n"
" gl_SecondaryFragColorEXT = source.a * mask;\n"
};
diff --git a/glamor/glamor_rects.c b/glamor/glamor_rects.c
index 8cdad64e4..02a1d5953 100644
--- a/glamor/glamor_rects.c
+++ b/glamor/glamor_rects.c
@@ -28,8 +28,8 @@ static const glamor_facet glamor_facet_polyfillrect_130 = {
.name = "poly_fill_rect",
.version = 130,
.source_name = "size",
- .vs_vars = "attribute vec2 primitive;\n"
- "attribute vec2 size;\n",
+ .vs_vars = "in vec2 primitive;\n"
+ "in vec2 size;\n",
.vs_exec = (" vec2 pos = size * vec2(gl_VertexID&1, (gl_VertexID&2)>>1);\n"
GLAMOR_POS(gl_Position, (primitive.xy + pos))),
};
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index 889fe1b36..c3d325503 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -116,7 +116,7 @@ glamor_create_composite_fs(glamor_screen_private *glamor_priv, struct shader_key
" tex = (fract(tex) / wh.xy);\n"
" }\n"
" }\n"
- " return texture2D(tex_image, tex);\n"
+ " return texture(tex_image, tex);\n"
"}\n"
" vec4 rel_sampler_rgbx(sampler2D tex_image, vec2 tex, vec4 wh, int repeat)\n"
"{\n"
@@ -129,7 +129,7 @@ glamor_create_composite_fs(glamor_screen_private *glamor_priv, struct shader_key
" tex = (fract(tex) / wh.xy);\n"
" }\n"
" }\n"
- " return vec4(texture2D(tex_image, tex).rgb, 1.0);\n"
+ " return vec4(texture(tex_image, tex).rgb, 1.0);\n"
"}\n";
const char *source_solid_fetch =
@@ -139,7 +139,7 @@ glamor_create_composite_fs(glamor_screen_private *glamor_priv, struct shader_key
" return source;\n"
"}\n";
const char *source_alpha_pixmap_fetch =
- "varying vec2 source_texture;\n"
+ "in vec2 source_texture;\n"
"uniform sampler2D source_sampler;\n"
"uniform vec4 source_wh;"
"vec4 get_source()\n"
@@ -148,7 +148,7 @@ glamor_create_composite_fs(glamor_screen_private *glamor_priv, struct shader_key
" source_wh, source_repeat_mode);\n"
"}\n";
const char *source_pixmap_fetch =
- "varying vec2 source_texture;\n"
+ "in vec2 source_texture;\n"
"uniform sampler2D source_sampler;\n"
"uniform vec4 source_wh;\n"
"vec4 get_source()\n"
@@ -168,7 +168,7 @@ glamor_create_composite_fs(glamor_screen_private *glamor_priv, struct shader_key
" return mask;\n"
"}\n";
const char *mask_alpha_pixmap_fetch =
- "varying vec2 mask_texture;\n"
+ "in vec2 mask_texture;\n"
"uniform sampler2D mask_sampler;\n"
"uniform vec4 mask_wh;\n"
"vec4 get_mask()\n"
@@ -177,7 +177,7 @@ glamor_create_composite_fs(glamor_screen_private *glamor_priv, struct shader_key
" mask_wh, mask_repeat_mode);\n"
"}\n";
const char *mask_pixmap_fetch =
- "varying vec2 mask_texture;\n"
+ "in vec2 mask_texture;\n"
"uniform sampler2D mask_sampler;\n"
"uniform vec4 mask_wh;\n"
"vec4 get_mask()\n"
@@ -201,17 +201,17 @@ glamor_create_composite_fs(glamor_screen_private *glamor_priv, struct shader_key
const char *in_normal =
"void main()\n"
"{\n"
- " gl_FragColor = dest_swizzle(get_source() * get_mask().a);\n"
+ " frag_color = dest_swizzle(get_source() * get_mask().a);\n"
"}\n";
const char *in_ca_source =
"void main()\n"
"{\n"
- " gl_FragColor = dest_swizzle(get_source() * get_mask());\n"
+ " frag_color = dest_swizzle(get_source() * get_mask());\n"
"}\n";
const char *in_ca_alpha =
"void main()\n"
"{\n"
- " gl_FragColor = dest_swizzle(get_source().a * get_mask());\n"
+ " frag_color = dest_swizzle(get_source().a * get_mask());\n"
"}\n";
const char *in_ca_dual_blend =
"out vec4 color0;\n"
@@ -221,10 +221,6 @@ glamor_create_composite_fs(glamor_screen_private *glamor_priv, struct shader_key
" color0 = dest_swizzle(get_source() * get_mask());\n"
" color1 = dest_swizzle(get_source().a * get_mask());\n"
"}\n";
- const char *header_ca_dual_blend =
- "#version 130\n";
- const char *header_ca_dual_blend_gpu_shader4 =
- "#version 120\n#extension GL_EXT_gpu_shader4 : require\n";
const char *in_ca_dual_blend_gles2 =
"void main()\n"
"{\n"
@@ -233,14 +229,16 @@ glamor_create_composite_fs(glamor_screen_private *glamor_priv, struct shader_key
"}\n";
const char *header_ca_dual_blend_gles2 =
"#version 100\n"
- "#extension GL_EXT_blend_func_extended : require\n";
+ "#extension GL_EXT_blend_func_extended : require\n"
+ GLAMOR_COMPAT_DEFINES_FS;
char *source;
const char *source_fetch;
const char *mask_fetch = "";
const char *in;
const char *header;
- const char *header_norm = "";
+ const char *header_norm = glamor_priv->glsl_version > 120 ? "#version 130\n" : "#version 120\n#extension GL_EXT_gpu_shader4 : require\n" GLAMOR_COMPAT_DEFINES_FS;
+ const char *header_es = glamor_priv->glsl_version > 100 ? "#version 300 es\n" : "#version 100\n" GLAMOR_COMPAT_DEFINES_FS;
const char *dest_swizzle;
GLuint prog;
@@ -290,7 +288,7 @@ glamor_create_composite_fs(glamor_screen_private *glamor_priv, struct shader_key
FatalError("Bad composite shader dest swizzle");
}
- header = header_norm;
+ header = glamor_priv->is_gles ? header_es : header_norm;
switch (key->in) {
case glamor_program_alpha_normal:
in = in_normal;
@@ -303,10 +301,6 @@ glamor_create_composite_fs(glamor_screen_private *glamor_priv, struct shader_key
break;
case glamor_program_alpha_dual_blend:
in = in_ca_dual_blend;
- if (glamor_priv->glsl_version >= 130)
- header = header_ca_dual_blend;
- else
- header = header_ca_dual_blend_gpu_shader4;
break;
case glamor_program_alpha_dual_blend_gles2:
in = in_ca_dual_blend_gles2;
@@ -319,7 +313,8 @@ glamor_create_composite_fs(glamor_screen_private *glamor_priv, struct shader_key
XNFasprintf(&source,
"%s"
GLAMOR_DEFAULT_PRECISION
- "%s%s%s%s%s%s%s", header, repeat_define, relocate_texture,
+ "%s%s%s%s%s%s%s%s", header, GLAMOR_COMPAT_DEFINES_FS,
+ repeat_define, relocate_texture,
rel_sampler, source_fetch, mask_fetch, dest_swizzle, in);
prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, source);
@@ -329,14 +324,14 @@ glamor_create_composite_fs(glamor_screen_private *glamor_priv, struct shader_key
}
static GLuint
-glamor_create_composite_vs(struct shader_key *key)
+glamor_create_composite_vs(glamor_screen_private* priv, struct shader_key *key)
{
const char *main_opening =
- "attribute vec4 v_position;\n"
- "attribute vec4 v_texcoord0;\n"
- "attribute vec4 v_texcoord1;\n"
- "varying vec2 source_texture;\n"
- "varying vec2 mask_texture;\n"
+ "in vec4 v_position;\n"
+ "in vec4 v_texcoord0;\n"
+ "in vec4 v_texcoord1;\n"
+ "out vec2 source_texture;\n"
+ "out vec2 mask_texture;\n"
"void main()\n"
"{\n"
" gl_Position = v_position;\n";
@@ -346,7 +341,9 @@ glamor_create_composite_vs(struct shader_key *key)
const char *source_coords_setup = "";
const char *mask_coords_setup = "";
const char *version_gles2 = "#version 100\n";
- const char *version = "";
+ const char *version_gles3 = "#version 300 es\n";
+ const char *version = priv->glsl_version > 120 ? "#version 130\n" : "#version 120\n";
+ const char *defines = priv->glsl_version > 120 ? "": GLAMOR_COMPAT_DEFINES_VS;
char *source;
GLuint prog;
@@ -356,14 +353,17 @@ glamor_create_composite_vs(struct shader_key *key)
if (key->mask != SHADER_MASK_NONE && key->mask != SHADER_MASK_SOLID)
mask_coords_setup = mask_coords;
- if (key->in == glamor_program_alpha_dual_blend_gles2)
+ if (priv->is_gles)
version = version_gles2;
+ if (priv->is_gles && priv->glsl_version > 120)
+ version = version_gles3;
+
XNFasprintf(&source,
"%s"
GLAMOR_DEFAULT_PRECISION
- "%s%s%s%s",
- version, main_opening, source_coords_setup,
+ "%s%s%s%s%s",
+ version, defines, main_opening, source_coords_setup,
mask_coords_setup, main_closing);
prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, source);
@@ -381,7 +381,7 @@ glamor_create_composite_shader(ScreenPtr screen, struct shader_key *key,
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
glamor_make_current(glamor_priv);
- vs = glamor_create_composite_vs(key);
+ vs = glamor_create_composite_vs(glamor_priv, key);
if (vs == 0)
return;
fs = glamor_create_composite_fs(glamor_priv, key);
diff --git a/glamor/glamor_segs.c b/glamor/glamor_segs.c
index 4dfa6553b..1fe6aabdd 100644
--- a/glamor/glamor_segs.c
+++ b/glamor/glamor_segs.c
@@ -27,7 +27,7 @@
static const glamor_facet glamor_facet_poly_segment = {
.name = "poly_segment",
- .vs_vars = "attribute vec2 primitive;\n",
+ .vs_vars = "in vec2 primitive;\n",
.vs_exec = (" vec2 pos = vec2(0.0,0.0);\n"
GLAMOR_POS(gl_Position, primitive.xy)),
};
diff --git a/glamor/glamor_spans.c b/glamor/glamor_spans.c
index 00a019c7b..e3d92e50e 100644
--- a/glamor/glamor_spans.c
+++ b/glamor/glamor_spans.c
@@ -29,7 +29,7 @@ glamor_program fill_spans_progs[4];
static const glamor_facet glamor_facet_fillspans_130 = {
.name = "fill_spans",
.version = 130,
- .vs_vars = "attribute vec3 primitive;\n",
+ .vs_vars = "in vec3 primitive;\n",
.vs_exec = (" vec2 pos = vec2(primitive.z,1) * vec2(gl_VertexID&1, (gl_VertexID&2)>>1);\n"
GLAMOR_POS(gl_Position, (primitive.xy + pos))),
};
diff --git a/glamor/glamor_text.c b/glamor/glamor_text.c
index e92f55b3c..39f7f5b83 100644
--- a/glamor/glamor_text.c
+++ b/glamor/glamor_text.c
@@ -221,9 +221,9 @@ glamor_text(DrawablePtr drawable, GCPtr gc,
}
static const char vs_vars_text[] =
- "attribute vec4 primitive;\n"
- "attribute vec2 source;\n"
- "varying vec2 glyph_pos;\n";
+ "in vec4 primitive;\n"
+ "in vec2 source;\n"
+ "out vec2 glyph_pos;\n";
static const char vs_exec_text[] =
" vec2 pos = primitive.zw * vec2(gl_VertexID&1, (gl_VertexID&2)>>1);\n"
@@ -231,7 +231,7 @@ static const char vs_exec_text[] =
" glyph_pos = source + pos;\n";
static const char fs_vars_text[] =
- "varying vec2 glyph_pos;\n";
+ "in vec2 glyph_pos;\n";
static const char fs_exec_text[] =
" ivec2 itile_texture = ivec2(glyph_pos);\n"
@@ -257,9 +257,9 @@ static const char fs_exec_te[] =
" uint texel = texelFetch(font, itile_texture, 0).x;\n"
" uint bit = (texel >> x) & uint(1);\n"
" if (bit == uint(0))\n"
- " gl_FragColor = bg;\n"
+ " frag_color = bg;\n"
" else\n"
- " gl_FragColor = fg;\n";
+ " frag_color = fg;\n";
static const glamor_facet glamor_facet_poly_text = {
.name = "poly_text",
@@ -361,7 +361,7 @@ use_image_solid(PixmapPtr pixmap, GCPtr gc, glamor_program *prog, void *arg)
static const glamor_facet glamor_facet_image_fill = {
.name = "solid",
- .fs_exec = " gl_FragColor = fg;\n",
+ .fs_exec = " frag_color = fg;\n",
.locations = glamor_program_location_fg,
.use = use_image_solid,
};
diff --git a/glamor/glamor_xv.c b/glamor/glamor_xv.c
index 003f12771..a3626d3f8 100644
--- a/glamor/glamor_xv.c
+++ b/glamor/glamor_xv.c
@@ -65,9 +65,9 @@ static const glamor_facet glamor_facet_xv_planar_2 = {
.version = 120,
.source_name = "v_texcoord0",
- .vs_vars = ("attribute vec2 position;\n"
- "attribute vec2 v_texcoord0;\n"
- "varying vec2 tcs;\n"),
+ .vs_vars = ("in vec2 position;\n"
+ "in vec2 v_texcoord0;\n"
+ "out vec2 tcs;\n"),
.vs_exec = (GLAMOR_POS(gl_Position, position)
" tcs = v_texcoord0;\n"),
@@ -76,18 +76,18 @@ static const glamor_facet glamor_facet_xv_planar_2 = {
"uniform vec4 offsetyco;\n"
"uniform vec4 ucogamma;\n"
"uniform vec4 vco;\n"
- "varying vec2 tcs;\n"),
+ "in vec2 tcs;\n"),
.fs_exec = (
" float sample;\n"
" vec2 sample_uv;\n"
" vec4 temp1;\n"
- " sample = texture2D(y_sampler, tcs).w;\n"
+ " sample = texture(y_sampler, tcs).w;\n"
" temp1.xyz = offsetyco.www * vec3(sample) + offsetyco.xyz;\n"
- " sample_uv = texture2D(u_sampler, tcs).xy;\n"
+ " sample_uv = texture(u_sampler, tcs).xy;\n"
" temp1.xyz = ucogamma.xyz * vec3(sample_uv.x) + temp1.xyz;\n"
" temp1.xyz = clamp(vco.xyz * vec3(sample_uv.y) + temp1.xyz, 0.0, 1.0);\n"
" temp1.w = 1.0;\n"
- " gl_FragColor = temp1;\n"
+ " frag_color = temp1;\n"
),
};
@@ -97,9 +97,9 @@ static const glamor_facet glamor_facet_xv_planar_3 = {
.version = 120,
.source_name = "v_texcoord0",
- .vs_vars = ("attribute vec2 position;\n"
- "attribute vec2 v_texcoord0;\n"
- "varying vec2 tcs;\n"),
+ .vs_vars = ("in vec2 position;\n"
+ "in vec2 v_texcoord0;\n"
+ "out vec2 tcs;\n"),
.vs_exec = (GLAMOR_POS(gl_Position, position)
" tcs = v_texcoord0;\n"),
@@ -109,18 +109,18 @@ static const glamor_facet glamor_facet_xv_planar_3 = {
"uniform vec4 offsetyco;\n"
"uniform vec4 ucogamma;\n"
"uniform vec4 vco;\n"
- "varying vec2 tcs;\n"),
+ "in vec2 tcs;\n"),
.fs_exec = (
" float sample;\n"
" vec4 temp1;\n"
- " sample = texture2D(y_sampler, tcs).w;\n"
+ " sample = texture(y_sampler, tcs).w;\n"
" temp1.xyz = offsetyco.www * vec3(sample) + offsetyco.xyz;\n"
- " sample = texture2D(u_sampler, tcs).w;\n"
+ " sample = texture(u_sampler, tcs).w;\n"
" temp1.xyz = ucogamma.xyz * vec3(sample) + temp1.xyz;\n"
- " sample = texture2D(v_sampler, tcs).w;\n"
+ " sample = texture(v_sampler, tcs).w;\n"
" temp1.xyz = clamp(vco.xyz * vec3(sample) + temp1.xyz, 0.0, 1.0);\n"
" temp1.w = 1.0;\n"
- " gl_FragColor = temp1;\n"
+ " frag_color = temp1;\n"
),
};
commit 97d5271487972cd88f2907687ec6e7854ad08109
Author: Konstantin Pugin <ria.freelander at gmail.com>
Date: Sun Jul 10 17:08:44 2022 +0300
glamor: accelerate incomplete textures for GL ES
If texture can be uploaded to GL using glTexImage2D normally, but
cannot be read back using glReadPixels, we still can accelerate it,
but we cannot create pixmap with FBO using this texture type. So,
add a flag to avoid such creations.
This allow us to accelerate 8-bit glyph masks on GL ES 2.0, because those
masks are used only as textures, and in next stages are rendered on RGBA
surfaces normally, so, we do not need to call glReadPixels on them.
This is needed for correctly working fonts on GL ES 2.0, due to inability
to use GL_RED and texture swizzle. We should use GL_ALPHA there, and
with this format we cannot have a complete framebuffer. But completed
framebuffer, according to testing, is not required for fonts anyway.
Also it fixes all 8-bit formats for GLES2.
Fixes #1362
Fixes #1411
Signed-off-by: Konstantin Pugin <ria.freelander at gmail.com>
Reviewed-by: Adam Jackson <ajax at redhat.com>
Acked-by: Michel Dänzer <mdaenzer at redhat.com>
Acked-by: Martin Roukala <martin.roukala at mupuf.org>
(cherry picked from commit e573d4ca03756cd7ea37288a7ca7df003ad5c1f8)
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1636>
diff --git a/glamor/glamor.c b/glamor/glamor.c
index 4046fe66c..0d6e0536e 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -216,7 +216,9 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
w <= glamor_priv->glyph_max_dim &&
h <= glamor_priv->glyph_max_dim)
|| (w == 0 && h == 0)
- || !glamor_priv->formats[depth].rendering_supported))
+ || !glamor_priv->formats[depth].rendering_supported
+ || (glamor_priv->formats[depth].texture_only &&
+ (usage != GLAMOR_CREATE_FBO_NO_FBO))))
return fbCreatePixmap(screen, w, h, depth, usage);
else
pixmap = fbCreatePixmap(screen, 0, 0, depth, usage);
@@ -470,6 +472,7 @@ glamor_add_format(ScreenPtr screen, int depth, CARD32 render_format,
{
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
struct glamor_format *f = &glamor_priv->formats[depth];
+ Bool texture_only = FALSE;
/* If we're trying to run on GLES, make sure that we get the read
* formats that we're expecting, since glamor_transfer relies on
@@ -492,6 +495,13 @@ glamor_add_format(ScreenPtr screen, int depth, CARD32 render_format,
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, internalformat, 1, 1, 0,
format, type, NULL);
+ if (glGetError() != GL_NO_ERROR)
+ {
+ ErrorF("glamor: Cannot upload texture for depth %d. "
+ "Falling back to software.\n", depth);
+ glDeleteTextures(1, &tex);
+ return;
+ }
glGenFramebuffers(1, &fbo);
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
@@ -503,21 +513,23 @@ glamor_add_format(ScreenPtr screen, int depth, CARD32 render_format,
"Falling back to software.\n", depth);
glDeleteTextures(1, &tex);
glDeleteFramebuffers(1, &fbo);
- return;
+ texture_only = TRUE;
}
- glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, &read_format);
- glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE, &read_type);
+ if (!texture_only) {
+ glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, &read_format);
+ glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE, &read_type);
+ }
glDeleteTextures(1, &tex);
glDeleteFramebuffers(1, &fbo);
- if (format != read_format || type != read_type) {
+ if (!texture_only && (format != read_format || type != read_type)) {
ErrorF("glamor: Implementation returned 0x%x/0x%x read format/type "
"for depth %d, expected 0x%x/0x%x. "
"Falling back to software.\n",
read_format, read_type, depth, format, type);
- return;
+ texture_only = TRUE;
}
}
@@ -527,6 +539,7 @@ glamor_add_format(ScreenPtr screen, int depth, CARD32 render_format,
f->format = format;
f->type = type;
f->rendering_supported = rendering_supported;
+ f->texture_only = texture_only;
}
/* Set up the GL format/types that glamor will use for the various depths
@@ -620,6 +633,7 @@ glamor_setup_formats(ScreenPtr screen)
glamor_priv->cbcr_format.render_format = PICT_yuv2;
glamor_priv->cbcr_format.type = GL_UNSIGNED_BYTE;
glamor_priv->cbcr_format.rendering_supported = TRUE;
+ glamor_priv->cbcr_format.texture_only = FALSE;
}
/** Set up glamor for an already-configured GL context. */
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 371761c45..608e9cbc2 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -180,6 +180,13 @@ struct glamor_format {
* just before upload)
*/
Bool rendering_supported;
+ /**
+ * Whether image with this depth is framebuffer-complete in GL.
+ * This flag is set on GL ES when rendering is supported without
+ * conversion, but reading from framebuffer can bring some caveats
+ * like different format combination or incomplete framebuffer.
+ */
+ Bool texture_only;
};
struct glamor_saved_procs {
commit 6086a0210da3530a60e583c121e63563b97e3eb7
Author: Konstantin <ria.freelander at gmail.com>
Date: Tue Jul 19 11:22:30 2022 +0300
glamor: add gl_PointSize for ES shaders
GLES3.2 spec, page 126:
> The variable gl_PointSize is intended for a shader to write
> the size of the point to be rasterized. It is measured in pixels.
> If gl_PointSize is not written to, its value
> is undefined in subsequent pipe stages.
If glamor shader is use points, we should define gl_PointSize for GLES.
On Desktop GL, it "just work" due to default gl_PointSize is 1.
As @anholt requested, define this only for minimal amount of shaders
(point and glyphbit ones), to make sure than performance will not
affected
Reviewed-by: Emma Anholt <emma at anholt.net>
Reviewed-by: Adam Jackson <ajax at redhat.com>
Signed-off-by: Konstantin <ria.freelander at gmail.com>
(cherry picked from commit f273c960c15cf1eaaaccf9c00ed93f5ac75c9397)
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1636>
diff --git a/glamor/glamor_glyphblt.c b/glamor/glamor_glyphblt.c
index 2e01cdd19..2f9f94f93 100644
--- a/glamor/glamor_glyphblt.c
+++ b/glamor/glamor_glyphblt.c
@@ -34,6 +34,7 @@ static const glamor_facet glamor_facet_poly_glyph_blt = {
.name = "poly_glyph_blt",
.vs_vars = "attribute vec2 primitive;\n",
.vs_exec = (" vec2 pos = vec2(0,0);\n"
+ GLAMOR_DEFAULT_POINT_SIZE
GLAMOR_POS(gl_Position, primitive)),
};
diff --git a/glamor/glamor_points.c b/glamor/glamor_points.c
index faf6f433b..5f4a8f56a 100644
--- a/glamor/glamor_points.c
+++ b/glamor/glamor_points.c
@@ -32,7 +32,8 @@
static const glamor_facet glamor_facet_point = {
.name = "poly_point",
.vs_vars = "attribute vec2 primitive;\n",
- .vs_exec = GLAMOR_POS(gl_Position, primitive),
+ .vs_exec = (GLAMOR_DEFAULT_POINT_SIZE
+ GLAMOR_POS(gl_Position, primitive)),
};
static Bool
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index da20bc5aa..371761c45 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -49,6 +49,11 @@
"precision mediump float;\n" \
"#endif\n"
+#define GLAMOR_DEFAULT_POINT_SIZE \
+ "#ifdef GL_ES\n" \
+ " gl_PointSize = 1.0;\n" \
+ "#endif\n"
+
#include "glyphstr.h"
#include "glamor_debug.h"
commit 3078e4925754a3c9aba697008deba2f10aacbdb7
Author: Konstantin <ria.freelander at gmail.com>
Date: Fri Dec 2 16:22:15 2022 +0300
glamor: fixes GL_INVALID_ENUM errors on ES if there is no quads
If there is no quads to draw, then we have a possibility to call
glDrawElements with type as zero, which will generate
GL_INVALID_ENUM error. While this error is harmless, it is annoying.
Signed-off-by: Konstantin <ria.freelander at gmail.com>
Reviewed-by: Adam Jackson <ajax at redhat.com>
(cherry picked from commit baaddf47d593b51d215d836a796b95a3cb14a220)
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1636>
diff --git a/glamor/glamor.c b/glamor/glamor.c
index be8df3893..4046fe66c 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -310,6 +310,10 @@ glamor_gldrawarrays_quads_using_indices(glamor_screen_private *glamor_priv,
{
unsigned i;
+ /* If there is no quads to draw, just exit */
+ if (count == 0)
+ return;
+
/* For a single quad, don't bother with an index buffer. */
if (count == 1)
goto fallback;
commit feb860014df0b8b1a4b1f8921843fb1cd77eeafc
Author: Dave Airlie <airlied at redhat.com>
Date: Thu Feb 9 13:48:30 2023 +1000
glamor: handle EXT_gpu_shader4 in dual source blend paths
Fixes: a9552868697c ("glamor: add EXT_gpu_shader4 support")
Acked-by: Emma Anholt <emma at anholt.net>
(cherry picked from commit 86598739ba285045bc03778d43e25bb0886627f3)
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1636>
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index c9a125ef9..889fe1b36 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -61,7 +61,7 @@ static struct blendinfo composite_op_info[] = {
#define RepeatFix 10
static GLuint
-glamor_create_composite_fs(struct shader_key *key)
+glamor_create_composite_fs(glamor_screen_private *glamor_priv, struct shader_key *key)
{
const char *repeat_define =
"#define RepeatNone 0\n"
@@ -223,6 +223,8 @@ glamor_create_composite_fs(struct shader_key *key)
"}\n";
const char *header_ca_dual_blend =
"#version 130\n";
+ const char *header_ca_dual_blend_gpu_shader4 =
+ "#version 120\n#extension GL_EXT_gpu_shader4 : require\n";
const char *in_ca_dual_blend_gles2 =
"void main()\n"
"{\n"
@@ -301,7 +303,10 @@ glamor_create_composite_fs(struct shader_key *key)
break;
case glamor_program_alpha_dual_blend:
in = in_ca_dual_blend;
- header = header_ca_dual_blend;
+ if (glamor_priv->glsl_version >= 130)
+ header = header_ca_dual_blend;
+ else
+ header = header_ca_dual_blend_gpu_shader4;
break;
case glamor_program_alpha_dual_blend_gles2:
in = in_ca_dual_blend_gles2;
@@ -379,7 +384,7 @@ glamor_create_composite_shader(ScreenPtr screen, struct shader_key *key,
vs = glamor_create_composite_vs(key);
if (vs == 0)
return;
- fs = glamor_create_composite_fs(key);
+ fs = glamor_create_composite_fs(glamor_priv, key);
if (fs == 0)
return;
commit e52e256f1c1d5334827f60ee8538791bce92f943
Author: Konstantin <ria.freelander at gmail.com>
Date: Tue Jun 28 12:28:39 2022 +0300
glamor: fix XVideo run with GLES
For now, it sets .version=120, which prevents shader from compiling on ES.
We just force version of shaders to be always 100 on ES, because we use
only 120 shaders on ES anyway, and all shaders works.
Signed-off-by: Konstantin Pugin <ria.freelander at gmail.com>
Reviewed-by: Adam Jackson <ajax at redhat.com>
Reviewed-by: Emma Anholt <emma at anholt.net>
(cherry picked from commit dcba460af3eedb9d41986bd65f4502998b7a5a6c)
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1636>
diff --git a/glamor/glamor_program.c b/glamor/glamor_program.c
index 00959ea63..f8bb0efb8 100644
--- a/glamor/glamor_program.c
+++ b/glamor/glamor_program.c
@@ -283,6 +283,11 @@ glamor_build_program(ScreenPtr screen,
gpu_shader4 = TRUE;
}
}
+ /* For now, fix shader version to GLES as 100. We will fall with 130 shaders
+ * in previous check due to forcibly set 120 glsl for GLES. But this patch
+ * makes xv shaders to work */
+ if(version && glamor_priv->is_gles)
+ version = 100;
vs_vars = vs_location_vars(locations);
fs_vars = fs_location_vars(locations);
commit fc7012515308e860130e29bb55d070adaae3e87c
Author: Vasily Khoruzhick <anarsoul at gmail.com>
Date: Fri May 27 18:00:56 2022 -0700
glamor: use dual source blend on GL 2.1 with ARB_ES2_compatibility
ARB_blend_func_extended may be exposed even without GLSL 1.30.
In order to use it we need GLES2 shaders that are available if
ARB_ES2_compatibility is exposed.
Signed-off-by: Vasily Khoruzhick <anarsoul at gmail.com>
Reviewed-by: Adam Jackson <ajax at redhat.com>
Reviewed-by: Emma Anholt <emma at anholt.net>
(cherry picked from commit 05b8401eeb263e1395aa5ceeb8b5cdbeb0585db6)
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1636>
diff --git a/glamor/glamor.c b/glamor/glamor.c
index 8a20d6cef..be8df3893 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -816,8 +816,10 @@ glamor_init(ScreenPtr screen, unsigned int flags)
epoxy_gl_version() >= 30 ||
epoxy_has_gl_extension("GL_NV_pack_subimage");
glamor_priv->has_dual_blend =
- glamor_glsl_has_ints(glamor_priv) &&
- epoxy_has_gl_extension("GL_ARB_blend_func_extended");
+ (epoxy_has_gl_extension("GL_ARB_blend_func_extended") &&
+ (glamor_glsl_has_ints(glamor_priv) ||
+ epoxy_has_gl_extension("GL_ARB_ES2_compatibility"))) ||
+ epoxy_has_gl_extension("GL_EXT_blend_func_extended");
glamor_priv->has_clear_texture =
epoxy_gl_version() >= 44 ||
epoxy_has_gl_extension("GL_ARB_clear_texture");
diff --git a/glamor/glamor_composite_glyphs.c b/glamor/glamor_composite_glyphs.c
index 147e3bb31..c69b940d4 100644
--- a/glamor/glamor_composite_glyphs.c
+++ b/glamor/glamor_composite_glyphs.c
@@ -208,6 +208,22 @@ static const glamor_facet glamor_facet_composite_glyphs_120 = {
.locations = glamor_program_location_atlas,
};
+static const glamor_facet glamor_facet_composite_glyphs_gles2 = {
+ .name = "composite_glyphs",
+ .version = 100,
+ .fs_extensions = ("#extension GL_EXT_blend_func_extended : enable\n"),
+ .vs_vars = ("attribute vec2 primitive;\n"
+ "attribute vec2 source;\n"
+ "varying vec2 glyph_pos;\n"),
+ .vs_exec = (" vec2 pos = vec2(0,0);\n"
+ GLAMOR_POS(gl_Position, primitive.xy)
+ " glyph_pos = source.xy * ATLAS_DIM_INV;\n"),
+ .fs_vars = ("varying vec2 glyph_pos;\n"),
+ .fs_exec = (" vec4 mask = texture2D(atlas, glyph_pos);\n"),
+ .source_name = "source",
+ .locations = glamor_program_location_atlas,
+};
+
static Bool
glamor_glyphs_init_facet(ScreenPtr screen)
{
@@ -442,7 +458,9 @@ glamor_composite_glyphs(CARD8 op,
else
prog = glamor_setup_program_render(op, src, glyph_pict, dst,
glyphs_program,
- &glamor_facet_composite_glyphs_120,
+ glamor_priv->has_dual_blend ?
+ &glamor_facet_composite_glyphs_gles2 :
+ &glamor_facet_composite_glyphs_120,
glamor_priv->glyph_defines);
if (!prog)
goto bail_one;
diff --git a/glamor/glamor_program.c b/glamor/glamor_program.c
index cbdb218cb..00959ea63 100644
--- a/glamor/glamor_program.c
+++ b/glamor/glamor_program.c
@@ -201,6 +201,8 @@ static const char vs_template[] =
static const char fs_template[] =
"%s" /* version */
"%s" /* exts */
+ "%s" /* prim fs_extensions */
+ "%s" /* fill fs_extensions */
GLAMOR_DEFAULT_PRECISION
"%s" /* defines */
"%s" /* prim fs_vars */
@@ -312,6 +314,8 @@ glamor_build_program(ScreenPtr screen,
if (asprintf(&fs_prog_string,
fs_template,
str(version_string),
+ str(prim->fs_extensions),
+ str(fill->fs_extensions),
gpu_shader4 ? "#extension GL_EXT_gpu_shader4 : require\n#define texelFetch texelFetch2D\n#define uint unsigned int\n" : "",
str(defines),
str(prim->fs_vars),
@@ -494,7 +498,8 @@ glamor_set_blend(CARD8 op, glamor_program_alpha alpha, PicturePtr dst)
}
/* Set up the source alpha value for blending in component alpha mode. */
- if (alpha == glamor_program_alpha_dual_blend) {
+ if (alpha == glamor_program_alpha_dual_blend ||
+ alpha == glamor_program_alpha_dual_blend_gles2) {
switch (dst_blend) {
case GL_SRC_ALPHA:
dst_blend = GL_SRC1_COLOR;
@@ -581,11 +586,13 @@ static const glamor_facet *glamor_facet_source[glamor_program_source_count] = {
};
static const char *glamor_combine[] = {
- [glamor_program_alpha_normal] = " gl_FragColor = source * mask.a;\n",
- [glamor_program_alpha_ca_first] = " gl_FragColor = source.a * mask;\n",
- [glamor_program_alpha_ca_second] = " gl_FragColor = source * mask;\n",
- [glamor_program_alpha_dual_blend] = " color0 = source * mask;\n"
- " color1 = source.a * mask;\n"
+ [glamor_program_alpha_normal] = " gl_FragColor = source * mask.a;\n",
+ [glamor_program_alpha_ca_first] = " gl_FragColor = source.a * mask;\n",
+ [glamor_program_alpha_ca_second] = " gl_FragColor = source * mask;\n",
+ [glamor_program_alpha_dual_blend] = " color0 = source * mask;\n"
+ " color1 = source.a * mask;\n",
+ [glamor_program_alpha_dual_blend_gles2] = " gl_FragColor = source * mask;\n"
+ " gl_SecondaryFragColorEXT = source.a * mask;\n"
};
static Bool
@@ -633,7 +640,9 @@ glamor_setup_program_render(CARD8 op,
if (glamor_is_component_alpha(mask)) {
if (glamor_priv->has_dual_blend) {
- alpha = glamor_program_alpha_dual_blend;
+ alpha = glamor_glsl_has_ints(glamor_priv) ?
+ glamor_program_alpha_dual_blend :
+ glamor_program_alpha_dual_blend_gles2;
} else {
/* This only works for PictOpOver */
if (op != PictOpOver)
diff --git a/glamor/glamor_program.h b/glamor/glamor_program.h
index ab6e46f7b..0bd918fff 100644
--- a/glamor/glamor_program.h
+++ b/glamor/glamor_program.h
@@ -44,6 +44,7 @@ typedef enum {
glamor_program_alpha_ca_first,
glamor_program_alpha_ca_second,
glamor_program_alpha_dual_blend,
+ glamor_program_alpha_dual_blend_gles2,
glamor_program_alpha_count
} glamor_program_alpha;
@@ -56,8 +57,8 @@ typedef Bool (*glamor_use_render) (CARD8 op, PicturePtr src, PicturePtr dst, gla
typedef struct {
const char *name;
const int version;
- char *vs_defines;
- char *fs_defines;
+ char *vs_extensions;
+ const char *fs_extensions;
const char *vs_vars;
const char *vs_exec;
const char *fs_vars;
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index 2af65bf93..c9a125ef9 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -223,6 +223,15 @@ glamor_create_composite_fs(struct shader_key *key)
"}\n";
const char *header_ca_dual_blend =
"#version 130\n";
+ const char *in_ca_dual_blend_gles2 =
+ "void main()\n"
+ "{\n"
+ " gl_FragColor = dest_swizzle(get_source() * get_mask());\n"
+ " gl_SecondaryFragColorEXT = dest_swizzle(get_source().a * get_mask());\n"
+ "}\n";
+ const char *header_ca_dual_blend_gles2 =
+ "#version 100\n"
+ "#extension GL_EXT_blend_func_extended : require\n";
char *source;
const char *source_fetch;
@@ -294,6 +303,10 @@ glamor_create_composite_fs(struct shader_key *key)
in = in_ca_dual_blend;
header = header_ca_dual_blend;
break;
+ case glamor_program_alpha_dual_blend_gles2:
+ in = in_ca_dual_blend_gles2;
+ header = header_ca_dual_blend_gles2;
+ break;
default:
FatalError("Bad composite IN type");
}
@@ -327,6 +340,8 @@ glamor_create_composite_vs(struct shader_key *key)
const char *main_closing = "}\n";
const char *source_coords_setup = "";
const char *mask_coords_setup = "";
+ const char *version_gles2 = "#version 100\n";
+ const char *version = "";
char *source;
GLuint prog;
@@ -336,10 +351,15 @@ glamor_create_composite_vs(struct shader_key *key)
if (key->mask != SHADER_MASK_NONE && key->mask != SHADER_MASK_SOLID)
mask_coords_setup = mask_coords;
+ if (key->in == glamor_program_alpha_dual_blend_gles2)
+ version = version_gles2;
+
XNFasprintf(&source,
+ "%s"
+ GLAMOR_DEFAULT_PRECISION
"%s%s%s%s",
- main_opening,
- source_coords_setup, mask_coords_setup, main_closing);
+ version, main_opening, source_coords_setup,
+ mask_coords_setup, main_closing);
prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, source);
free(source);
@@ -701,6 +721,7 @@ combine_pict_format(PictFormatShort * des, const PictFormatShort src,
mask_type = PICT_FORMAT_TYPE(mask);
break;
case glamor_program_alpha_dual_blend:
+ case glamor_program_alpha_dual_blend_gles2:
src_type = PICT_FORMAT_TYPE(src);
mask_type = PICT_FORMAT_TYPE(mask);
break;
@@ -886,8 +907,11 @@ glamor_composite_choose_shader(CARD8 op,
else {
if (op == PictOpClear)
key.mask = SHADER_MASK_NONE;
- else if (glamor_priv->has_dual_blend)
- key.in = glamor_program_alpha_dual_blend;
+ else if (glamor_priv->has_dual_blend) {
+ key.in = glamor_glsl_has_ints(glamor_priv) ?
+ glamor_program_alpha_dual_blend :
+ glamor_program_alpha_dual_blend_gles2;
+ }
else if (op == PictOpSrc || op == PictOpAdd
|| op == PictOpIn || op == PictOpOut
|| op == PictOpOverReverse)
commit 4b1d4cc963e7af73abd7c116c12a91cbad9c51f2
Author: Yuriy Vasilev <uuvasiliev at yandex.ru>
Date: Thu Sep 16 14:47:44 2021 +0300
glamor: fix CbCr format handling
In GLES2, we cannot do GL_RED or GL_RG without GL_EXT_texture_rg.
So, add check for GL_EXT_texture_rg to make it working. Also add
a yuv2 pixman format into render.h to make Xv yuv rendering works.
Signed-off-by: Yuriy Vasilev <uuvasiliev at yandex.ru>
Reviewed-by: Adam Jackson <ajax at redhat.com>
Reviewed-by: Emma Anholt <emma at anholt.net>
(cherry picked from commit 65392d27d77fbdb66e874ba3e2d85dbcf46e4583)
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1636>
diff --git a/glamor/glamor.c b/glamor/glamor.c
index bc91de201..8a20d6cef 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -223,7 +223,7 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
pixmap_priv = glamor_get_pixmap_private(pixmap);
- pixmap_priv->is_cbcr = (usage == GLAMOR_CREATE_FORMAT_CBCR);
+ pixmap_priv->is_cbcr = (GLAMOR_CREATE_FORMAT_CBCR & usage) == GLAMOR_CREATE_FORMAT_CBCR;
pitch = (((w * pixmap->drawable.bitsPerPixel + 7) / 8) + 3) & ~3;
screen->ModifyPixmapHeader(pixmap, w, h, 0, 0, pitch, NULL);
@@ -550,9 +550,10 @@ glamor_setup_formats(ScreenPtr screen)
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
/* Prefer r8 textures since they're required by GLES3 and core,
- * only falling back to a8 if we can't do them.
+ * only falling back to a8 if we can't do them. We cannot do them
+ * on GLES2 due to lack of texture swizzle.
*/
- if (glamor_priv->is_gles || epoxy_has_gl_extension("GL_ARB_texture_rg")) {
+ if (glamor_priv->has_rg && glamor_priv->has_texture_swizzle) {
glamor_add_format(screen, 1, PICT_a1,
GL_R8, GL_RED, GL_UNSIGNED_BYTE, FALSE);
glamor_add_format(screen, 8, PICT_a8,
@@ -606,8 +607,13 @@ glamor_setup_formats(ScreenPtr screen)
}
glamor_priv->cbcr_format.depth = 16;
- glamor_priv->cbcr_format.internalformat = GL_RG8;
+ if (glamor_priv->is_gles && glamor_priv->has_rg) {
+ glamor_priv->cbcr_format.internalformat = GL_RG;
+ } else {
+ glamor_priv->cbcr_format.internalformat = GL_RG8;
+ }
glamor_priv->cbcr_format.format = GL_RG;
+ glamor_priv->cbcr_format.render_format = PICT_yuv2;
glamor_priv->cbcr_format.type = GL_UNSIGNED_BYTE;
glamor_priv->cbcr_format.rendering_supported = TRUE;
}
@@ -815,6 +821,11 @@ glamor_init(ScreenPtr screen, unsigned int flags)
glamor_priv->has_clear_texture =
epoxy_gl_version() >= 44 ||
epoxy_has_gl_extension("GL_ARB_clear_texture");
+ /* GL_EXT_texture_rg is part of GLES3 core */
+ glamor_priv->has_rg =
+ (glamor_priv->is_gles && epoxy_gl_version() >= 30) ||
+ epoxy_has_gl_extension("GL_EXT_texture_rg") ||
+ epoxy_has_gl_extension("GL_ARB_texture_rg");
glamor_priv->can_copyplane = (gl_version >= 30);
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 028a6d374..da20bc5aa 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -216,6 +216,7 @@ typedef struct glamor_screen_private {
Bool has_dual_blend;
Bool has_clear_texture;
Bool has_texture_swizzle;
+ Bool has_rg;
Bool is_core_profile;
Bool can_copyplane;
Bool use_gpu_shader4;
diff --git a/render/picture.h b/render/picture.h
index 4499a0021..c3a73d1d8 100644
--- a/render/picture.h
+++ b/render/picture.h
@@ -125,7 +125,10 @@ typedef enum _PictFormatShort {
/* 1bpp formats */
PICT_a1 = PIXMAN_a1,
- PICT_g1 = PIXMAN_g1
+ PICT_g1 = PIXMAN_g1,
+
+/* YCbCr formats */
+ PICT_yuv2 = PIXMAN_yuy2
} PictFormatShort;
/*
commit f94d80b3878897be22d28329a42f65ae13d30caf
Author: Konstantin <ria.freelander at gmail.com>
Date: Sat Jun 25 17:51:15 2022 +0300
glamor: transpose gradients transparently
glUniformMatrix3fv is used with argument transpose set to GL_TRUE.
According to the Khronos OpenGL ES 2.0 pages transpose must be GL_FALSE.
Actually we can just return transformed matrix from
_glamor_gradient_convert_trans_matrix (@anholt suggest),
so @uvas workaround is not required
Signed-off-by: Konstantin Pugin <ria.freelander at gmail.com>
Reviewed-by: Adam Jackson <ajax at redhat.com>
Reviewed-by: Emma Anholt <emma at anholt.net>
(cherry picked from commit a59531533fb8fd137d21e0578909d8e91c28dff6)
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1636>
diff --git a/glamor/glamor_gradient.c b/glamor/glamor_gradient.c
index 7e5d5cca9..4c7ae4d77 100644
--- a/glamor/glamor_gradient.c
+++ b/glamor/glamor_gradient.c
@@ -605,27 +605,35 @@ _glamor_gradient_convert_trans_matrix(PictTransform *from, float to[3][3],
* T_s = | w*t21/h t22 t23/h|
* | w*t31 h*t32 t33 |
* -- --
+ *
+ * Because GLES2 cannot do trasposed mat by spec, we did transposing inside this function
+ * already, and matrix becoming look like this:
+ * -- --
+ * | t11 w*t21/h t31*w|
+ * T_s = | h*t12/w t22 t32*h|
+ * | t13/w t23/h t33 |
+ * -- --
*/
to[0][0] = (float) pixman_fixed_to_double(from->matrix[0][0]);
- to[0][1] = (float) pixman_fixed_to_double(from->matrix[0][1])
+ to[1][0] = (float) pixman_fixed_to_double(from->matrix[0][1])
* (normalize ? (((float) height) / ((float) width)) : 1.0);
- to[0][2] = (float) pixman_fixed_to_double(from->matrix[0][2])
+ to[2][0] = (float) pixman_fixed_to_double(from->matrix[0][2])
/ (normalize ? ((float) width) : 1.0);
- to[1][0] = (float) pixman_fixed_to_double(from->matrix[1][0])
+ to[0][1] = (float) pixman_fixed_to_double(from->matrix[1][0])
* (normalize ? (((float) width) / ((float) height)) : 1.0);
to[1][1] = (float) pixman_fixed_to_double(from->matrix[1][1]);
- to[1][2] = (float) pixman_fixed_to_double(from->matrix[1][2])
+ to[2][1] = (float) pixman_fixed_to_double(from->matrix[1][2])
/ (normalize ? ((float) height) : 1.0);
- to[2][0] = (float) pixman_fixed_to_double(from->matrix[2][0])
+ to[0][2] = (float) pixman_fixed_to_double(from->matrix[2][0])
* (normalize ? ((float) width) : 1.0);
- to[2][1] = (float) pixman_fixed_to_double(from->matrix[2][1])
+ to[1][2] = (float) pixman_fixed_to_double(from->matrix[2][1])
* (normalize ? ((float) height) : 1.0);
to[2][2] = (float) pixman_fixed_to_double(from->matrix[2][2]);
- DEBUGF("the transform matrix is:\n%f\t%f\t%f\n%f\t%f\t%f\n%f\t%f\t%f\n",
+ DEBUGF("the transposed transform matrix is:\n%f\t%f\t%f\n%f\t%f\t%f\n%f\t%f\t%f\n",
to[0][0], to[0][1], to[0][2],
to[1][0], to[1][1], to[1][2], to[2][0], to[2][1], to[2][2]);
}
@@ -950,11 +958,12 @@ glamor_generate_radial_gradient_picture(ScreenPtr screen,
_glamor_gradient_convert_trans_matrix(src_picture->transform,
transform_mat, width, height, 0);
glUniformMatrix3fv(transform_mat_uniform_location,
- 1, 1, &transform_mat[0][0]);
+ 1, GL_FALSE, &transform_mat[0][0]);
}
else {
+ /* identity matrix dont need to be transposed */
glUniformMatrix3fv(transform_mat_uniform_location,
- 1, 1, &identity_mat[0][0]);
+ 1, GL_FALSE, &identity_mat[0][0]);
}
if (!_glamor_gradient_set_pixmap_destination
@@ -1266,11 +1275,12 @@ glamor_generate_linear_gradient_picture(ScreenPtr screen,
_glamor_gradient_convert_trans_matrix(src_picture->transform,
transform_mat, width, height, 1);
glUniformMatrix3fv(transform_mat_uniform_location,
- 1, 1, &transform_mat[0][0]);
+ 1, GL_FALSE, &transform_mat[0][0]);
}
else {
+ /* identity matrix dont need to be transposed */
glUniformMatrix3fv(transform_mat_uniform_location,
- 1, 1, &identity_mat[0][0]);
+ 1, GL_FALSE, &identity_mat[0][0]);
}
if (!_glamor_gradient_set_pixmap_destination
commit 95b8991181b22031f67384403bc166c8749e7a16
Author: Konstantin <ria.freelander at gmail.com>
Date: Sat Jun 25 21:58:08 2022 +0300
meson: add glamor gles2 tests
Signed-off-by: Konstantin Pugin <ria.freelander at gmail.com>
Reviewed-by: Adam Jackson <ajax at redhat.com>
Reviewed-by: Emma Anholt <emma at anholt.net>
(cherry picked from commit ddcd4846d1fa8c408733f4435a52344d3eab850e)
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1636>
diff --git a/test/bugs/bug1354.c b/test/bugs/bug1354.c
new file mode 100644
index 000000000..edc3f228c
--- /dev/null
+++ b/test/bugs/bug1354.c
@@ -0,0 +1,149 @@
+#include <xcb/xcb.h>
+#include <xcb/xcb_aux.h>
+#include <xcb/xcb_image.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <getopt.h>
+#include <ctype.h>
+#include <unistd.h>
+
+/*
+ * This is a test which try to test correct glamor colors when rendered.
+ * It should be run with fullscreen Xephyr (with glamor) with present and with
+ * etalon high-level Xserver (can be any, on CI - Xvfb). For testing this test
+ * creates an image in Xephyr X server, which filled by one of colors defined in
+ * test_pixels. Then it captures central pixel from both Xephyr and Xserver above.
+ * If pixels differ - test failed. Sleep is used to ensure than presentation on both
+ * Xephyr and Xvfb kicks (xcb_aux_sync was not enough) and test results will be actual
+ */
+
+#define WIDTH 300
+#define HEIGHT 300
+
+int get_display_pixel(xcb_connection_t* c, xcb_drawable_t win);
+void draw_display_pixel(xcb_connection_t* c, xcb_drawable_t win, uint32_t pixel_color);
+
+int get_display_pixel(xcb_connection_t* c, xcb_drawable_t win)
+{
+ xcb_image_t *image;
+ uint32_t pixel;
+ int format = XCB_IMAGE_FORMAT_XY_PIXMAP;
+
+ image = xcb_image_get (c, win,
+ 0, 0, WIDTH, HEIGHT,
+ UINT32_MAX,
+ format);
+ if (!image) {
+ printf("xcb_image_get failed: exiting\n");
+ exit(1);
+ }
+
+ pixel = xcb_image_get_pixel(image, WIDTH/2, HEIGHT/2);
+
+ return pixel;
+}
+
+void draw_display_pixel(xcb_connection_t* c, xcb_drawable_t win, uint32_t pixel_color)
+{
+ xcb_gcontext_t foreground;
+ uint32_t mask = 0;
+
+ xcb_rectangle_t rectangles[] = {
+ {0, 0, WIDTH, HEIGHT},
+ };
+
+ foreground = xcb_generate_id (c);
+ mask = XCB_GC_FOREGROUND | XCB_GC_LINE_WIDTH | XCB_GC_SUBWINDOW_MODE;
+
+ uint32_t values[] = {
+ pixel_color,
+ 20,
+ XCB_SUBWINDOW_MODE_INCLUDE_INFERIORS
+ };
+
+ xcb_create_gc (c, foreground, win, mask, values);
+
+ xcb_poly_fill_rectangle (c, win, foreground, 1, rectangles);
+ xcb_aux_sync ( c );
+}
+
+
+int main(int argc, char* argv[])
+{
+ xcb_connection_t *c, *r;
+ xcb_screen_t *screen1, *screen2;
+ xcb_drawable_t win1, win2;
+ char *name_test = NULL, *name_relevant = NULL;
+ uint32_t pixel_server1, pixel_server2;
+ int result = 0;
+ uint32_t test_pixels[3] = {0xff0000, 0x00ff00, 0x0000ff};
+ int gv;
+
+ while ((gv = getopt (argc, argv, "t:r:")) != -1)
+ switch (gv)
+ {
+ case 't':
+ name_test = optarg;
+ break;
+ case 'r':
+ name_relevant = optarg;
+ break;
+ case '?':
+ if (optopt == 't' || optopt == 'r')
+ fprintf (stderr, "Option -%c requires an argument - test screen name.\n", optopt);
+ else if (isprint (optopt))
+ fprintf (stderr, "Unknown option `-%c'.\n", optopt);
+ else
+ fprintf (stderr,
+ "Unknown option character `\\x%x'.\n",
+ optopt);
+ return 1;
+ default:
+ abort ();
+ }
+
+ printf("test=%s, rel=%s\n", name_test, name_relevant);
+
+ c = xcb_connect (name_test, NULL);
+ r = xcb_connect (name_relevant, NULL);
+
+ /* get the first screen */
+ screen1 = xcb_setup_roots_iterator (xcb_get_setup (c)).data;
+
+ win1 = xcb_generate_id (c);
+ xcb_create_window (c, /* Connection */
+ XCB_COPY_FROM_PARENT, /* depth (same as root)*/
+ win1, /* window Id */
+ screen1->root, /* parent window */
+ 0, 0, /* x, y */
+ WIDTH, HEIGHT, /* width, height */
+ 20, /* border_width */
+ XCB_WINDOW_CLASS_INPUT_OUTPUT, /* class */
+ screen1->root_visual, /* visual */
+ 0, NULL ); /* masks, not used yet */
+
+
+ /* Map the window on the screen */
+ xcb_map_window (c, win1);
+ xcb_aux_sync(c);
+
+ /* get the first screen */
+ screen2 = xcb_setup_roots_iterator (xcb_get_setup (r)).data;
+
+ /* root window */
+ win2 = screen2->root;
+
+ for(int i = 0; i < 3; i++)
+ {
+ draw_display_pixel(c, win1, test_pixels[i]);
+ xcb_aux_sync(r);
+ pixel_server1 = get_display_pixel(c, win1);
+ sleep(1);
+ pixel_server2 = get_display_pixel(r, win2);
+ xcb_aux_sync(r);
+ printf("p=0x%x, p2=0x%x\n", pixel_server1, pixel_server2);
+ result+= pixel_server1 == pixel_server2;
+ }
+ return result == 3 ? 0 : 1;
+}
diff --git a/test/bugs/meson.build b/test/bugs/meson.build
new file mode 100644
index 000000000..470706d56
--- /dev/null
+++ b/test/bugs/meson.build
@@ -0,0 +1,50 @@
+xcb_dep = dependency('xcb', required: false)
+xcb_image_dep = dependency('xcb-image', required: false)
+xcb_util_dep = dependency('xcb-util', required: false)
+
+if get_option('xvfb')
+ xvfb_args = [
+ xvfb_server.full_path(),
+ '-screen',
+ 'scrn',
+ '1280x1024x24'
+ ]
+
+ if xcb_dep.found() and xcb_image_dep.found() and xcb_util_dep.found() and get_option('xvfb') and get_option('xephyr') and build_glamor
+ bug1354 = executable('bug1354', 'bug1354.c', dependencies: [xcb_dep, xcb_image_dep, xcb_util_dep])
+ test('bug1354-gl',
+ simple_xinit,
+ args: [simple_xinit.full_path(),
+ bug1354.full_path(),
+ '-t',':201','-r',':200',
+ '----',
+ xephyr_server.full_path(),
+ '-glamor',
+ '-schedMax', '2000',
+ ':201',
+ '--',
+ xvfb_args,
+ ':200'
+ ],
+ suite: 'xephyr-glamor',
+ timeout: 300,
+ )
+ test('bug1354-gles',
+ simple_xinit,
+ args: [simple_xinit.full_path(),
+ bug1354.full_path(),
+ '-t',':199','-r',':198',
+ '----',
+ xephyr_server.full_path(),
+ '-glamor_gles2',
+ '-schedMax', '2000',
+ ':199',
+ '--',
+ xvfb_args,
+ ':198'
+ ],
+ suite: 'xephyr-glamor-gles2',
+ timeout: 300,
+ )
+ endif
+endif
\ No newline at end of file
diff --git a/test/meson.build b/test/meson.build
index 7cd636939..94634c127 100644
--- a/test/meson.build
+++ b/test/meson.build
@@ -9,13 +9,24 @@ piglit_env.set('XSERVER_DIR', meson.source_root())
piglit_env.set('XSERVER_BUILDDIR', meson.build_root())
some_ops = ' -o clear,src,dst,over,xor,disjointover'
-rendercheck_tests = [
+gles2_working_formats = ' -f '+ ','.join(['a8',
+ 'a8r8g8b8',
+ 'x8r8g8b8',
+ 'b8g8r8a8',
+ 'b8g8r8x8',
+ 'r8g8b8',
+ 'r5g5b5',
+ 'b5g5r5',
+ 'r5g6b5',
+ 'b5g6r5',
+ 'b8g8r8',
+ 'x8b8g8r8',
+ 'x2r10g10b10',
+ 'x2b10g10r10'])
+rendercheck_tests_noblend = [
['blend/All/a8r8g8b8', '-t blend -f a8r8g8b8'],
['blend/All/x8r8g8b8', '-t blend -f a8r8g8b8,x8r8g8b8'],
['blend/All/a2r10g10b10', '-t blend -f a8r8g8b8,a2r10g10b10'],
- ['blend/Clear', '-t blend -o clear'],
- ['blend/Src', '-t blend -o src'],
- ['blend/Over', '-t blend -o over'],
['composite/Some/a8r8g8b8', '-t composite -f a8r8g8b8' + some_ops],
['composite/Some/x8r8g8b8', '-t composite -f a8r8g8b8,x8r8g8b8' + some_ops],
['composite/Some/a2r10g10b10', '-t composite -f a8r8g8b8,a2r10g10b10' + some_ops],
@@ -34,7 +45,19 @@ rendercheck_tests = [
['LibreOffice xRGB', '-t libreoffice_xrgb'],
['GTK ARGB vs xBGR', '-t gtk_argb_xbgr'],
]
-
+rendercheck_blend = [
+ ['blend/Clear', '-t blend -o clear'],
+ ['blend/Src', '-t blend -o src'],
+ ['blend/Over', '-t blend -o over'],
+]
+#Exclude 15bpp for now due to GLES limitation (see glamor.c:470)
+rendercheck_blend_gles2 = [
+ ['blend/Clear', '-t blend -o clear' + gles2_working_formats],
+ ['blend/Src', '-t blend -o src' + gles2_working_formats],
+ ['blend/Over', '-t blend -o over' + gles2_working_formats],
+]
+rendercheck_tests = rendercheck_blend + rendercheck_tests_noblend
+rendercheck_tests_gles2 = rendercheck_blend_gles2 + rendercheck_tests_noblend
rendercheck = find_program('rendercheck', required:false)
if get_option('xvfb')
@@ -76,6 +99,12 @@ if get_option('xvfb')
timeout: 1200,
suite: 'xephr-glamor',
)
+ test('XTS',
+ find_program('scripts/xephyr-glamor-gles2-piglit.sh'),
+ env: piglit_env,
+ timeout: 1200,
+ suite: 'xephyr-glamor-gles2',
+ )
if rendercheck.found()
foreach rctest: rendercheck_tests
@@ -96,6 +125,24 @@ if get_option('xvfb')
timeout: 300,
)
endforeach
+ foreach rctest: rendercheck_tests_gles2
+ test(rctest[0],
+ simple_xinit,
+ args: [simple_xinit.full_path(),
+ rendercheck.path(),
+ rctest[1].split(' '),
+ '----',
+ xephyr_server.full_path(),
+ '-glamor_gles2',
+ '-glamor-skip-present',
+ '-schedMax', '2000',
+ '--',
+ xvfb_args,
+ ],
+ suite: 'xephyr-glamor-gles2',
+ timeout: 300,
+ )
+ endforeach
endif
endif
endif
@@ -103,6 +150,7 @@ endif
subdir('bigreq')
subdir('damage')
subdir('sync')
+subdir('bugs')
if build_xorg
# Tests that require at least some DDX functions in order to fully link
diff --git a/test/scripts/xephyr-glamor-gles2-piglit.sh b/test/scripts/xephyr-glamor-gles2-piglit.sh
new file mode 100755
index 000000000..59ca12d26
--- /dev/null
+++ b/test/scripts/xephyr-glamor-gles2-piglit.sh
@@ -0,0 +1,34 @@
+#!/bin/sh
+
+# this times out on Travis, because the tests take too long.
+if test "x$TRAVIS_BUILD_DIR" != "x"; then
+ exit 77
+fi
+
+# Start a Xephyr server using glamor. Since the test environment is
+# headless, we start an Xvfb first to host the Xephyr.
+export PIGLIT_RESULTS_DIR=$XSERVER_BUILDDIR/test/piglit-results/xephyr-glamor-gles2
+
+export SERVER_COMMAND="$XSERVER_BUILDDIR/hw/kdrive/ephyr/Xephyr \
+ -glamor_gles2 \
+ -glamor-skip-present \
+ -noreset \
+ -schedMax 2000 \
+ -screen 1280x1024"
+
+# Tests that currently fail on llvmpipe on CI
+PIGLIT_ARGS="$PIGLIT_ARGS -x xcleararea at 6"
+PIGLIT_ARGS="$PIGLIT_ARGS -x xcleararea at 7"
+PIGLIT_ARGS="$PIGLIT_ARGS -x xclearwindow at 4"
+PIGLIT_ARGS="$PIGLIT_ARGS -x xclearwindow at 5"
+PIGLIT_ARGS="$PIGLIT_ARGS -x xcopyarea at 1"
+PIGLIT_ARGS="$PIGLIT_ARGS -x xsetfontpath at 1"
+PIGLIT_ARGS="$PIGLIT_ARGS -x xsetfontpath at 2"
+
+export PIGLIT_ARGS
+
+$XSERVER_BUILDDIR/test/simple-xinit \
+ $XSERVER_DIR/test/scripts/run-piglit.sh \
+ -- \
+ $XSERVER_BUILDDIR/hw/vfb/Xvfb \
+ -screen scrn 1280x1024x24
commit 8d3b4fa2456efcb4c677e750b9688fc4e005d6aa
Author: Jeffy Chen <jeffy.chen at rock-chips.com>
Date: Fri Nov 8 15:44:41 2019 +0800
glamor: xv: Fix invalid accessing of plane attributes for NV12
NV12 only has 2 planes.
Signed-off-by: Jeffy Chen <jeffy.chen at rock-chips.com>
(cherry picked from commit 0076671e24670f1ddb151946e490497f171589f0)
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1636>
diff --git a/glamor/glamor_xv.c b/glamor/glamor_xv.c
index dbb490599..003f12771 100644
--- a/glamor/glamor_xv.c
+++ b/glamor/glamor_xv.c
@@ -291,10 +291,10 @@ glamor_xv_query_image_attributes(int id,
pitches[0] = size;
size *= *h;
if (offsets)
- offsets[1] = offsets[2] = size;
+ offsets[1] = size;
tmp = ALIGN(*w, 4);
if (pitches)
- pitches[1] = pitches[2] = tmp;
+ pitches[1] = tmp;
tmp *= (*h >> 1);
size += tmp;
break;
commit bec42f6e0b7c4cb2844721f1b566921665bbdc78
Author: Lucas Stach <dev at lynxeye.de>
Date: Sun Jul 10 19:35:43 2022 +0200
glamor_egl: properly get FDs from multiplanar GBM BOs
Multiplanar GBM buffers can point to different objects from each plane.
Use the _for_plane API when possible to retrieve the correct prime FD
for each plane.
Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
Reviewed-by: Simon Ser <contact at emersion.fr>
Tested-by: Guido Günther <agx at sigxcpu.org>
(cherry picked from commit e5b09f7a2cc3bd64a6ea207c7c75d4f05b79cf44)
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1636>
diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
index 2063bab13..b1e81d422 100644
--- a/glamor/glamor_egl.c
+++ b/glamor/glamor_egl.c
@@ -403,6 +403,9 @@ glamor_egl_fds_from_pixmap(ScreenPtr screen, PixmapPtr pixmap, int *fds,
struct gbm_bo *bo;
int num_fds;
#ifdef GBM_BO_WITH_MODIFIERS
+#ifndef GBM_BO_FD_FOR_PLANE
+ int32_t first_handle;
+#endif
int i;
#endif
@@ -416,7 +419,24 @@ glamor_egl_fds_from_pixmap(ScreenPtr screen, PixmapPtr pixmap, int *fds,
#ifdef GBM_BO_WITH_MODIFIERS
num_fds = gbm_bo_get_plane_count(bo);
for (i = 0; i < num_fds; i++) {
- fds[i] = gbm_bo_get_fd(bo);
+#ifdef GBM_BO_FD_FOR_PLANE
+ fds[i] = gbm_bo_get_fd_for_plane(bo, i);
+#else
+ union gbm_bo_handle plane_handle = gbm_bo_get_handle_for_plane(bo, i);
+
+ if (i == 0)
+ first_handle = plane_handle.s32;
+
+ /* If all planes point to the same object as the first plane, i.e. they
+ * all have the same handle, we can fall back to the non-planar
+ * gbm_bo_get_fd without losing information. If they point to different
+ * objects we are out of luck and need to give up.
+ */
+ if (first_handle == plane_handle.s32)
+ fds[i] = gbm_bo_get_fd(bo);
+ else
+ fds[i] = -1;
+#endif
if (fds[i] == -1) {
while (--i >= 0)
close(fds[i]);
commit b621926610129b94d3bfbc3a7e256c6f7799d73f
Author: Lucas Stach <dev at lynxeye.de>
Date: Thu Jul 28 22:52:15 2022 +0200
glamor_egl: handle fd export failure in glamor_egl_fds_from_pixmap
Check the fd for validity before giving a success return code.
Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
Reviewed-by: Simon Ser <contact at emersion.fr>
Tested-by: Guido Günther <agx at sigxcpu.org>
(cherry picked from commit 95944e2b990dacde81892406c8a0e2cc2afa7b3e)
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1636>
diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
index 6e0fc6596..2063bab13 100644
--- a/glamor/glamor_egl.c
+++ b/glamor/glamor_egl.c
@@ -417,6 +417,11 @@ glamor_egl_fds_from_pixmap(ScreenPtr screen, PixmapPtr pixmap, int *fds,
num_fds = gbm_bo_get_plane_count(bo);
for (i = 0; i < num_fds; i++) {
fds[i] = gbm_bo_get_fd(bo);
+ if (fds[i] == -1) {
+ while (--i >= 0)
+ close(fds[i]);
+ return 0;
+ }
strides[i] = gbm_bo_get_stride_for_plane(bo, i);
offsets[i] = gbm_bo_get_offset(bo, i);
}
@@ -424,6 +429,8 @@ glamor_egl_fds_from_pixmap(ScreenPtr screen, PixmapPtr pixmap, int *fds,
#else
num_fds = 1;
fds[0] = gbm_bo_get_fd(bo);
+ if (fds[0] == -1)
+ return 0;
strides[0] = gbm_bo_get_stride(bo);
offsets[0] = 0;
*modifier = DRM_FORMAT_MOD_INVALID;
More information about the xorg-commit
mailing list