[PATCH xserver 2/3] squash: glamor: Fix rendering to a8 textures in core profile.
Eric Anholt
eric at anholt.net
Thu Jan 21 18:36:22 PST 2016
Signed-off-by: Eric Anholt <eric at anholt.net>
---
glamor/glamor_priv.h | 10 +++++++++-
glamor/glamor_render.c | 50 +++++++++++++++++++++++++++++++++++++++++++-------
2 files changed, 52 insertions(+), 8 deletions(-)
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 558ed63..f1eed5b 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -116,10 +116,17 @@ enum shader_in {
SHADER_IN_COUNT,
};
+enum shader_dest_swizzle {
+ SHADER_DEST_SWIZZLE_DEFAULT,
+ SHADER_DEST_SWIZZLE_ALPHA_TO_RED,
+ SHADER_DEST_SWIZZLE_COUNT,
+};
+
struct shader_key {
enum shader_source source;
enum shader_mask mask;
enum shader_in in;
+ enum shader_dest_swizzle dest_swizzle;
};
struct blendinfo {
@@ -285,7 +292,8 @@ typedef struct glamor_screen_private {
int render_nr_quads;
glamor_composite_shader composite_shader[SHADER_SOURCE_COUNT]
[SHADER_MASK_COUNT]
- [SHADER_IN_COUNT];
+ [SHADER_IN_COUNT]
+ [SHADER_DEST_SWIZZLE_COUNT];
/* shaders to restore a texture to another texture. */
GLint finish_access_prog[2];
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index 7a50fe9..c36b345 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -177,25 +177,38 @@ glamor_create_composite_fs(struct shader_key *key)
" return rel_sampler(mask_sampler, mask_texture,\n"
" mask_wh, mask_repeat_mode, 1);\n"
"}\n";
+
+ const char *dest_swizzle_default =
+ "vec4 dest_swizzle(vec4 color)\n"
+ "{"
+ " return color;"
+ "}";
+ const char *dest_swizzle_alpha_to_red =
+ "vec4 dest_swizzle(vec4 color)\n"
+ "{"
+ " float undef;\n"
+ " return vec4(color.a, undef, undef, undef);"
+ "}";
+
const char *in_source_only =
"void main()\n"
"{\n"
- " gl_FragColor = get_source();\n"
+ " gl_FragColor = dest_swizzle(get_source());\n"
"}\n";
const char *in_normal =
"void main()\n"
"{\n"
- " gl_FragColor = get_source() * get_mask().a;\n"
+ " gl_FragColor = dest_swizzle(get_source() * get_mask().a);\n"
"}\n";
const char *in_ca_source =
"void main()\n"
"{\n"
- " gl_FragColor = get_source() * get_mask();\n"
+ " gl_FragColor = dest_swizzle(get_source() * get_mask());\n"
"}\n";
const char *in_ca_alpha =
"void main()\n"
"{\n"
- " gl_FragColor = get_source().a * get_mask();\n"
+ " gl_FragColor = dest_swizzle(get_source().a * get_mask());\n"
"}\n";
const char *in_ca_dual_blend =
"out vec4 color0;\n"
@@ -214,6 +227,7 @@ glamor_create_composite_fs(struct shader_key *key)
const char *in;
const char *header;
const char *header_norm = "";
+ const char *dest_swizzle;
GLuint prog;
switch (key->source) {
@@ -246,6 +260,21 @@ glamor_create_composite_fs(struct shader_key *key)
FatalError("Bad composite shader mask");
}
+ /* If we're storing to an a8 texture but our texture format is
+ * GL_RED because of a core context, then we need to make sure to
+ * put the alpha into the red channel.
+ */
+ switch (key->dest_swizzle) {
+ case SHADER_DEST_SWIZZLE_DEFAULT:
+ dest_swizzle = dest_swizzle_default;
+ break;
+ case SHADER_DEST_SWIZZLE_ALPHA_TO_RED:
+ dest_swizzle = dest_swizzle_alpha_to_red;
+ break;
+ default:
+ FatalError("Bad composite shader dest swizzle");
+ }
+
header = header_norm;
switch (key->in) {
case SHADER_IN_SOURCE_ONLY:
@@ -271,8 +300,8 @@ glamor_create_composite_fs(struct shader_key *key)
XNFasprintf(&source,
"%s"
GLAMOR_DEFAULT_PRECISION
- "%s%s%s%s%s%s", header, repeat_define, relocate_texture,
- rel_sampler, source_fetch, mask_fetch, in);
+ "%s%s%s%s%s%s%s", header, repeat_define, relocate_texture,
+ rel_sampler, source_fetch, mask_fetch, dest_swizzle, in);
prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, source);
free(source);
@@ -386,7 +415,7 @@ glamor_lookup_composite_shader(ScreenPtr screen, struct
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
glamor_composite_shader *shader;
- shader = &glamor_priv->composite_shader[key->source][key->mask][key->in];
+ shader = &glamor_priv->composite_shader[key->source][key->mask][key->in][key->dest_swizzle];
if (shader->prog == 0)
glamor_create_composite_shader(screen, key, shader);
@@ -841,6 +870,13 @@ glamor_composite_choose_shader(CARD8 op,
key.in = SHADER_IN_SOURCE_ONLY;
}
+ if (dest_pixmap->drawable.bitsPerPixel <= 8 &&
+ glamor_priv->one_channel_format == GL_RED) {
+ key.dest_swizzle = SHADER_DEST_SWIZZLE_ALPHA_TO_RED;
+ } else {
+ key.dest_swizzle = SHADER_DEST_SWIZZLE_DEFAULT;
+ }
+
if (source && source->alphaMap) {
glamor_fallback("source alphaMap\n");
goto fail;
--
2.6.4
More information about the xorg-devel
mailing list