]> code.ossystems Code Review - meta-freescale.git/commitdiff
xserver-xorg: Backport pixmap fixes for GLES 846/head
authorTom Hochstein <tom.hochstein@nxp.com>
Wed, 18 Aug 2021 21:15:45 +0000 (16:15 -0500)
committerTom Hochstein <tom.hochstein@nxp.com>
Wed, 18 Aug 2021 21:15:45 +0000 (16:15 -0500)
Signed-off-by: Tom Hochstein <tom.hochstein@nxp.com>
recipes-graphics/xorg-xserver/xserver-xorg/0001-xfree86-define-FOURCC_NV12-and-XVIMAGE_NV12.patch [new file with mode: 0644]
recipes-graphics/xorg-xserver/xserver-xorg/0002-glamor-add-support-for-GL_RG.patch [new file with mode: 0644]
recipes-graphics/xorg-xserver/xserver-xorg/0003-glamor-add-support-for-NV12-in-Xv.patch [new file with mode: 0644]
recipes-graphics/xorg-xserver/xserver-xorg/0004-glamor-Remove-unused-format_for_pixmap-helper.patch [new file with mode: 0644]
recipes-graphics/xorg-xserver/xserver-xorg/0005-glamor-Stop-trying-to-store-the-pixmap-s-format-in-g.patch [new file with mode: 0644]
recipes-graphics/xorg-xserver/xserver-xorg/0006-glamor-Plumb-the-pixmap-through-fbo-creation-instead.patch [new file with mode: 0644]
recipes-graphics/xorg-xserver/xserver-xorg/0007-glamor-Switch-the-gl_flavor-to-a-boolean-is_gles.patch [new file with mode: 0644]
recipes-graphics/xorg-xserver/xserver-xorg/0008-glamor-Introduce-a-central-place-for-our-pixmap-form.patch [new file with mode: 0644]
recipes-graphics/xorg-xserver/xserver-xorg_%.bbappend

diff --git a/recipes-graphics/xorg-xserver/xserver-xorg/0001-xfree86-define-FOURCC_NV12-and-XVIMAGE_NV12.patch b/recipes-graphics/xorg-xserver/xserver-xorg/0001-xfree86-define-FOURCC_NV12-and-XVIMAGE_NV12.patch
new file mode 100644 (file)
index 0000000..e095855
--- /dev/null
@@ -0,0 +1,47 @@
+From 3a6fe85a5f123f53319b5be8a69666174cad09cf Mon Sep 17 00:00:00 2001
+From: Julien Isorce <julien.isorce@gmail.com>
+Date: Thu, 6 Sep 2018 15:38:13 -0700
+Subject: [PATCH 1/8] xfree86: define FOURCC_NV12 and XVIMAGE_NV12
+
+Useful for glamor.
+
+Upstream-Status: Backport
+Signed-off-by: Julien Isorce <jisorce@oblong.com>
+Tested-by: Olivier Fourdan <ofourdan@redhat.com>
+Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
+---
+ hw/xfree86/common/fourcc.h | 20 ++++++++++++++++++++
+ 1 file changed, 20 insertions(+)
+
+diff --git a/hw/xfree86/common/fourcc.h b/hw/xfree86/common/fourcc.h
+index e6126b7fe..a19e6869e 100644
+--- a/hw/xfree86/common/fourcc.h
++++ b/hw/xfree86/common/fourcc.h
+@@ -156,4 +156,24 @@
+         XvTopToBottom \
+    }
++#define FOURCC_NV12 0x3231564e
++#define XVIMAGE_NV12 \
++   { \
++        FOURCC_NV12, \
++        XvYUV, \
++        LSBFirst, \
++        {'N','V','1','2', \
++          0x00,0x00,0x00,0x10,0x80,0x00,0x00,0xAA,0x00,0x38,0x9B,0x71}, \
++        12, \
++        XvPlanar, \
++        2, \
++        0, 0, 0, 0, \
++        8, 8, 8, \
++        1, 2, 2, \
++        1, 2, 2, \
++        {'Y','U','V', \
++          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}, \
++        XvTopToBottom \
++   }
++
+ #endif                          /* _XF86_FOURCC_H_ */
+-- 
+2.17.1
+
diff --git a/recipes-graphics/xorg-xserver/xserver-xorg/0002-glamor-add-support-for-GL_RG.patch b/recipes-graphics/xorg-xserver/xserver-xorg/0002-glamor-add-support-for-GL_RG.patch
new file mode 100644 (file)
index 0000000..7898837
--- /dev/null
@@ -0,0 +1,116 @@
+From 7f46b31e3d80ca769f68a4ffb201d0fc4801ea93 Mon Sep 17 00:00:00 2001
+From: Julien Isorce <julien.isorce@gmail.com>
+Date: Thu, 6 Sep 2018 15:38:14 -0700
+Subject: [PATCH 2/8] glamor: add support for GL_RG
+
+Allow to upload the CbCr plane of an NV12 image into a GL texture.
+
+Upstream-Status: Backport
+Signed-off-by: Julien Isorce <jisorce@oblong.com>
+Tested-by: Olivier Fourdan <ofourdan@redhat.com>
+Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
+---
+ glamor/glamor.c          |  2 ++
+ glamor/glamor.h          |  1 +
+ glamor/glamor_priv.h     |  4 +++-
+ glamor/glamor_transfer.c | 10 ++++++++--
+ glamor/glamor_utils.h    |  4 ++++
+ 5 files changed, 18 insertions(+), 3 deletions(-)
+
+diff --git a/glamor/glamor.c b/glamor/glamor.c
+index abefef614..3e9cf284c 100644
+--- a/glamor/glamor.c
++++ b/glamor/glamor.c
+@@ -222,6 +222,8 @@ 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);
++
+     format = gl_iformat_for_pixmap(pixmap);
+     pitch = (((w * pixmap->drawable.bitsPerPixel + 7) / 8) + 3) & ~3;
+diff --git a/glamor/glamor.h b/glamor/glamor.h
+index be04bf858..e5992aa56 100644
+--- a/glamor/glamor.h
++++ b/glamor/glamor.h
+@@ -129,6 +129,7 @@ extern _X_EXPORT Bool glamor_destroy_pixmap(PixmapPtr pixmap);
+ #define GLAMOR_CREATE_FBO_NO_FBO        0x103
+ #define GLAMOR_CREATE_NO_LARGE          0x105
+ #define GLAMOR_CREATE_PIXMAP_NO_TEXTURE 0x106
++#define GLAMOR_CREATE_FORMAT_CBCR       0x107
+ /* @glamor_egl_exchange_buffers: Exchange the underlying buffers(KHR image,fbo).
+  *
+diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
+index 4353a99f1..a14aaf624 100644
+--- a/glamor/glamor_priv.h
++++ b/glamor/glamor_priv.h
+@@ -380,6 +380,8 @@ typedef struct glamor_pixmap_private {
+      * names.
+      */
+     glamor_pixmap_fbo **fbo_array;
++
++    Bool is_cbcr;
+ } glamor_pixmap_private;
+ extern DevPrivateKeyRec glamor_pixmap_private_key;
+@@ -902,7 +904,7 @@ int glamor_xv_put_image(glamor_port_private *port_priv,
+                         Bool sync,
+                         RegionPtr clipBoxes);
+ void glamor_xv_core_init(ScreenPtr screen);
+-void glamor_xv_render(glamor_port_private *port_priv);
++void glamor_xv_render(glamor_port_private *port_priv, int id);
+ #include "glamor_utils.h"
+diff --git a/glamor/glamor_transfer.c b/glamor/glamor_transfer.c
+index ebb5101d1..421ed3a5f 100644
+--- a/glamor/glamor_transfer.c
++++ b/glamor/glamor_transfer.c
+@@ -27,6 +27,7 @@
+ void
+ glamor_format_for_pixmap(PixmapPtr pixmap, GLenum *format, GLenum *type)
+ {
++    glamor_pixmap_private       *priv = glamor_get_pixmap_private(pixmap);
+     switch (pixmap->drawable.depth) {
+     case 24:
+     case 32:
+@@ -38,8 +39,13 @@ glamor_format_for_pixmap(PixmapPtr pixmap, GLenum *format, GLenum *type)
+         *type = GL_UNSIGNED_INT_2_10_10_10_REV;
+         break;
+     case 16:
+-        *format = GL_RGB;
+-        *type = GL_UNSIGNED_SHORT_5_6_5;
++        if (priv->is_cbcr) {
++          *format = priv->fbo->format;
++          *type = GL_UNSIGNED_BYTE;
++        } else {
++          *format = GL_RGB;
++          *type = GL_UNSIGNED_SHORT_5_6_5;
++        }
+         break;
+     case 15:
+         *format = GL_BGRA;
+diff --git a/glamor/glamor_utils.h b/glamor/glamor_utils.h
+index 0d5674d63..1890c1fe5 100644
+--- a/glamor/glamor_utils.h
++++ b/glamor/glamor_utils.h
+@@ -613,10 +613,14 @@ gl_iformat_for_pixmap(PixmapPtr pixmap)
+ {
+     glamor_screen_private *glamor_priv =
+         glamor_get_screen_private((pixmap)->drawable.pScreen);
++    glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
+     if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP &&
+         ((pixmap)->drawable.depth == 1 || (pixmap)->drawable.depth == 8)) {
+         return glamor_priv->one_channel_format;
++    } else if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP &&
++               (pixmap)->drawable.depth == 16 && pixmap_priv->is_cbcr) {
++        return GL_RG;
+     } else if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP &&
+                (pixmap)->drawable.depth == 30) {
+         return GL_RGB10_A2;
+-- 
+2.17.1
+
diff --git a/recipes-graphics/xorg-xserver/xserver-xorg/0003-glamor-add-support-for-NV12-in-Xv.patch b/recipes-graphics/xorg-xserver/xserver-xorg/0003-glamor-add-support-for-NV12-in-Xv.patch
new file mode 100644 (file)
index 0000000..855d193
--- /dev/null
@@ -0,0 +1,322 @@
+From 17a3528162304f1586329aabd606d3498bfe48a5 Mon Sep 17 00:00:00 2001
+From: Julien Isorce <julien.isorce@gmail.com>
+Date: Tue, 11 Sep 2018 10:28:33 -0700
+Subject: [PATCH 3/8] glamor: add support for NV12 in Xv
+
+Useful when video decoders only output NV12. Currently
+glamor Xv only supports I420 and YV12.
+
+Note that Intel's sna supports I420, YV12, YUY2, UYVY, NV12.
+
+Test: xvinfo | grep NV12
+Test: gst-launch-1.0 videotestsrc ! video/x-raw, format=NV12 ! xvimagesink
+
+v2: Combine the two texture2Ds on u_sampler.
+
+Upstream-Status: Backport
+Signed-off-by: Julien Isorce <jisorce@oblong.com>
+Tested-by: Olivier Fourdan <ofourdan@redhat.com>
+Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
+---
+ glamor/glamor_xv.c | 180 ++++++++++++++++++++++++++++++++++++++-------
+ 1 file changed, 155 insertions(+), 25 deletions(-)
+
+diff --git a/glamor/glamor_xv.c b/glamor/glamor_xv.c
+index 62fc4fff5..6fef6ed0d 100644
+--- a/glamor/glamor_xv.c
++++ b/glamor/glamor_xv.c
+@@ -59,8 +59,40 @@ typedef struct tagREF_TRANSFORM {
+ #define RTFContrast(a)   (1.0 + ((a)*1.0)/1000.0)
+ #define RTFHue(a)   (((a)*3.1416)/1000.0)
+-static const glamor_facet glamor_facet_xv_planar = {
+-    .name = "xv_planar",
++static const glamor_facet glamor_facet_xv_planar_2 = {
++    .name = "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_exec = (GLAMOR_POS(gl_Position, position)
++                "        tcs = v_texcoord0;\n"),
++
++    .fs_vars = ("uniform sampler2D y_sampler;\n"
++                "uniform sampler2D u_sampler;\n"
++                "uniform vec4 offsetyco;\n"
++                "uniform vec4 ucogamma;\n"
++                "uniform vec4 vco;\n"
++                "varying vec2 tcs;\n"),
++    .fs_exec = (
++                "        float sample;\n"
++                "        vec2 sample_uv;\n"
++                "        vec4 temp1;\n"
++                "        sample = texture2D(y_sampler, tcs).w;\n"
++                "        temp1.xyz = offsetyco.www * vec3(sample) + offsetyco.xyz;\n"
++                "        sample_uv = texture2D(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"
++                ),
++};
++
++static const glamor_facet glamor_facet_xv_planar_3 = {
++    .name = "xv_planar_3",
+     .version = 120,
+@@ -110,26 +142,50 @@ Atom glamorBrightness, glamorContrast, glamorSaturation, glamorHue,
+ XvImageRec glamor_xv_images[] = {
+     XVIMAGE_YV12,
+     XVIMAGE_I420,
++    XVIMAGE_NV12
+ };
+ int glamor_xv_num_images = ARRAY_SIZE(glamor_xv_images);
+ static void
+-glamor_init_xv_shader(ScreenPtr screen)
++glamor_init_xv_shader(ScreenPtr screen, int id)
+ {
+     glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+     GLint sampler_loc;
++    const glamor_facet *glamor_facet_xv_planar = NULL;
++
++    switch (id) {
++    case FOURCC_YV12:
++    case FOURCC_I420:
++        glamor_facet_xv_planar = &glamor_facet_xv_planar_3;
++        break;
++    case FOURCC_NV12:
++        glamor_facet_xv_planar = &glamor_facet_xv_planar_2;
++        break;
++    default:
++        break;
++    }
+     glamor_build_program(screen,
+                          &glamor_priv->xv_prog,
+-                         &glamor_facet_xv_planar, NULL, NULL, NULL);
++                         glamor_facet_xv_planar, NULL, NULL, NULL);
+     glUseProgram(glamor_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);
+-    sampler_loc = glGetUniformLocation(glamor_priv->xv_prog.prog, "v_sampler");
+-    glUniform1i(sampler_loc, 2);
++
++    switch (id) {
++    case FOURCC_YV12:
++    case FOURCC_I420:
++        sampler_loc = glGetUniformLocation(glamor_priv->xv_prog.prog, "v_sampler");
++        glUniform1i(sampler_loc, 2);
++        break;
++    case FOURCC_NV12:
++        break;
++    default:
++        break;
++    }
+ }
+@@ -227,6 +283,21 @@ glamor_xv_query_image_attributes(int id,
+             offsets[2] = size;
+         size += tmp;
+         break;
++    case FOURCC_NV12:
++        *w = ALIGN(*w, 2);
++        *h = ALIGN(*h, 2);
++        size = ALIGN(*w, 4);
++        if (pitches)
++            pitches[0] = size;
++        size *= *h;
++        if (offsets)
++            offsets[1] = offsets[2] = size;
++        tmp = ALIGN(*w, 4);
++        if (pitches)
++            pitches[1] = pitches[2] = tmp;
++        tmp *= (*h >> 1);
++        size += tmp;
++        break;
+     }
+     return size;
+ }
+@@ -240,7 +311,7 @@ static REF_TRANSFORM trans[2] = {
+ };
+ void
+-glamor_xv_render(glamor_port_private *port_priv)
++glamor_xv_render(glamor_port_private *port_priv, int id)
+ {
+     ScreenPtr screen = port_priv->pPixmap->drawable.pScreen;
+     glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+@@ -264,7 +335,7 @@ glamor_xv_render(glamor_port_private *port_priv)
+     int dst_box_index;
+     if (!glamor_priv->xv_prog.prog)
+-        glamor_init_xv_shader(screen);
++        glamor_init_xv_shader(screen, id);
+     cont = RTFContrast(port_priv->contrast);
+     bright = RTFBrightness(port_priv->brightness);
+@@ -293,6 +364,8 @@ glamor_xv_render(glamor_port_private *port_priv)
+                 glamor_get_pixmap_private(port_priv->src_pix[i]);
+             pixmap_priv_get_scale(src_pixmap_priv[i], &src_xscale[i],
+                                   &src_yscale[i]);
++        } else {
++           src_pixmap_priv[i] = NULL;
+         }
+     }
+     glamor_make_current(glamor_priv);
+@@ -319,12 +392,21 @@ glamor_xv_render(glamor_port_private *port_priv)
+     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);
+-    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_TEXTURE2);
++        glBindTexture(GL_TEXTURE_2D, src_pixmap_priv[2]->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;
++    case FOURCC_NV12:
++        break;
++    default:
++        break;
++    }
+     glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
+     glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+@@ -336,7 +418,7 @@ glamor_xv_render(glamor_port_private *port_priv)
+     /* Set up a single primitive covering the area being drawn.  We'll
+      * clip it to port_priv->clip using GL scissors instead of just
+      * emitting a GL_QUAD per box, because this way we hopefully avoid
+-     * diagonal tearing between the two trangles used to rasterize a
++     * diagonal tearing between the two triangles used to rasterize a
+      * GL_QUAD.
+      */
+     i = 0;
+@@ -417,6 +499,7 @@ 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;
+@@ -425,9 +508,16 @@ 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)) {
++        (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)) {
+         int i;
++        if (glamor_priv->xv_prog.prog) {
++            glDeleteProgram(glamor_priv->xv_prog.prog);
++            glamor_priv->xv_prog.prog = 0;
++        }
++
+         for (i = 0; i < 3; i++)
+             if (port_priv->src_pix[i])
+                 glamor_destroy_pixmap(port_priv->src_pix[i]);
+@@ -435,17 +525,34 @@ glamor_xv_put_image(glamor_port_private *port_priv,
+         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);
++
++        switch (id) {
++        case FOURCC_YV12:
++        case FOURCC_I420:
++            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])
++                return BadAlloc;
++            break;
++        case FOURCC_NV12:
++            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;
++            break;
++        default:
++            return BadMatch;
++        }
++
+         port_priv->src_pix_w = width;
+         port_priv->src_pix_h = height;
+-        if (!port_priv->src_pix[0] || !port_priv->src_pix[1] ||
+-            !port_priv->src_pix[2])
++        if (!port_priv->src_pix[0] || !port_priv->src_pix[1])
+             return BadAlloc;
+     }
+@@ -489,6 +596,29 @@ glamor_xv_put_image(glamor_port_private *port_priv,
+                             0, 0, 0, 0,
+                             buf + s3offset, srcPitch2);
+         break;
++    case FOURCC_NV12:
++        srcPitch = ALIGN(width, 4);
++        s2offset = srcPitch * height;
++        s2offset += ((top >> 1) * srcPitch);
++
++        full_box.x1 = 0;
++        full_box.y1 = 0;
++        full_box.x2 = width;
++        full_box.y2 = nlines;
++
++        half_box.x1 = 0;
++        half_box.y1 = 0;
++        half_box.x2 = width;
++        half_box.y2 = (nlines + 1) >> 1;
++
++        glamor_upload_boxes(port_priv->src_pix[0], &full_box, 1,
++                            0, 0, 0, 0,
++                            buf + (top * srcPitch), srcPitch);
++
++        glamor_upload_boxes(port_priv->src_pix[1], &half_box, 1,
++                            0, 0, 0, 0,
++                            buf + s2offset, srcPitch);
++        break;
+     default:
+         return BadMatch;
+     }
+@@ -511,7 +641,7 @@ glamor_xv_put_image(glamor_port_private *port_priv,
+     port_priv->w = width;
+     port_priv->h = height;
+     port_priv->pDraw = pDrawable;
+-    glamor_xv_render(port_priv);
++    glamor_xv_render(port_priv, id);
+     return Success;
+ }
+-- 
+2.17.1
+
diff --git a/recipes-graphics/xorg-xserver/xserver-xorg/0004-glamor-Remove-unused-format_for_pixmap-helper.patch b/recipes-graphics/xorg-xserver/xserver-xorg/0004-glamor-Remove-unused-format_for_pixmap-helper.patch
new file mode 100644 (file)
index 0000000..c116576
--- /dev/null
@@ -0,0 +1,31 @@
+From 69892ca6a623057ed4e3be0c22cb7fd812425024 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Michel=20D=C3=A4nzer?= <michel.daenzer@amd.com>
+Date: Wed, 19 Dec 2018 10:11:22 +0100
+Subject: [PATCH 4/8] glamor: Remove unused format_for_pixmap helper
+
+Upstream-Status: Backport
+Reviewed-by: Eric Anholt <eric@anholt.net>
+---
+ glamor/glamor_utils.h | 6 ------
+ 1 file changed, 6 deletions(-)
+
+diff --git a/glamor/glamor_utils.h b/glamor/glamor_utils.h
+index 1890c1fe5..8a147ca7e 100644
+--- a/glamor/glamor_utils.h
++++ b/glamor/glamor_utils.h
+@@ -629,12 +629,6 @@ gl_iformat_for_pixmap(PixmapPtr pixmap)
+     }
+ }
+-static inline CARD32
+-format_for_pixmap(PixmapPtr pixmap)
+-{
+-    return format_for_depth((pixmap)->drawable.depth);
+-}
+-
+ #define REVERT_NONE                   0
+ #define REVERT_NORMAL                 1
+ #define REVERT_UPLOADING_A1           3
+-- 
+2.17.1
+
diff --git a/recipes-graphics/xorg-xserver/xserver-xorg/0005-glamor-Stop-trying-to-store-the-pixmap-s-format-in-g.patch b/recipes-graphics/xorg-xserver/xserver-xorg/0005-glamor-Stop-trying-to-store-the-pixmap-s-format-in-g.patch
new file mode 100644 (file)
index 0000000..9a0aa7a
--- /dev/null
@@ -0,0 +1,132 @@
+From 2498f6712c3b551c4d8104628aff78246b5cd6c8 Mon Sep 17 00:00:00 2001
+From: Eric Anholt <eric@anholt.net>
+Date: Tue, 26 Mar 2019 15:58:59 -0700
+Subject: [PATCH 5/8] glamor: Stop trying to store the pixmap's "format" in
+ glamor_pixmap_fbo.
+
+"format" is a bit of a confused term (internalformat vs GL format),
+and all we really needed was "is this GL_RED?"
+
+Upstream-Status: Backport
+Signed-off-by: Eric Anholt <eric@anholt.net>
+---
+ glamor/glamor.c          |  3 +--
+ glamor/glamor_fbo.c      |  7 ++++---
+ glamor/glamor_priv.h     | 13 ++-----------
+ glamor/glamor_render.c   |  2 +-
+ glamor/glamor_transfer.c |  2 +-
+ 5 files changed, 9 insertions(+), 18 deletions(-)
+
+diff --git a/glamor/glamor.c b/glamor/glamor.c
+index 3e9cf284c..c36b6ea74 100644
+--- a/glamor/glamor.c
++++ b/glamor/glamor.c
+@@ -184,8 +184,7 @@ glamor_bind_texture(glamor_screen_private *glamor_priv, GLenum texture,
+     /* Is the operand a GL_RED fbo?
+      */
+-    if (glamor_fbo_red_is_alpha(glamor_priv, fbo)) {
+-
++    if (fbo->is_red) {
+         /* If destination is also GL_RED, then preserve the bits in
+          * the R channel */
+diff --git a/glamor/glamor_fbo.c b/glamor/glamor_fbo.c
+index f939a6c2f..58eb97bf4 100644
+--- a/glamor/glamor_fbo.c
++++ b/glamor/glamor_fbo.c
+@@ -95,7 +95,7 @@ glamor_pixmap_ensure_fb(glamor_screen_private *glamor_priv,
+ glamor_pixmap_fbo *
+ glamor_create_fbo_from_tex(glamor_screen_private *glamor_priv,
+-                           int w, int h, GLenum format, GLint tex, int flag)
++                           int w, int h, Bool is_red, GLint tex, int flag)
+ {
+     glamor_pixmap_fbo *fbo;
+@@ -106,7 +106,7 @@ glamor_create_fbo_from_tex(glamor_screen_private *glamor_priv,
+     fbo->tex = tex;
+     fbo->width = w;
+     fbo->height = h;
+-    fbo->format = format;
++    fbo->is_red = is_red;
+     if (flag != GLAMOR_CREATE_FBO_NO_FBO) {
+         if (glamor_pixmap_ensure_fb(glamor_priv, fbo) != 0) {
+@@ -163,7 +163,8 @@ glamor_create_fbo(glamor_screen_private *glamor_priv,
+     if (!tex) /* Texture creation failed due to GL_OUT_OF_MEMORY */
+         return NULL;
+-    return glamor_create_fbo_from_tex(glamor_priv, w, h, format, tex, flag);
++    return glamor_create_fbo_from_tex(glamor_priv, w, h, format == GL_RED,
++                                      tex, flag);
+ }
+ /**
+diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
+index a14aaf624..e70d349da 100644
+--- a/glamor/glamor_priv.h
++++ b/glamor/glamor_priv.h
+@@ -317,8 +317,7 @@ typedef struct glamor_pixmap_fbo {
+     GLuint fb; /**< GL FBO name */
+     int width; /**< width in pixels */
+     int height; /**< height in pixels */
+-    GLenum format; /**< GL format used to create the texture. */
+-    GLenum type; /**< GL type used to create the texture. */
++    Bool is_red;
+ } glamor_pixmap_fbo;
+ typedef struct glamor_pixmap_clipped_regions {
+@@ -533,7 +532,7 @@ glamor_pixmap_fbo *glamor_pixmap_detach_fbo(glamor_pixmap_private *
+ void glamor_pixmap_attach_fbo(PixmapPtr pixmap, glamor_pixmap_fbo *fbo);
+ glamor_pixmap_fbo *glamor_create_fbo_from_tex(glamor_screen_private *
+                                               glamor_priv, int w, int h,
+-                                              GLenum format, GLint tex,
++                                              Bool is_red, GLint tex,
+                                               int flag);
+ glamor_pixmap_fbo *glamor_create_fbo(glamor_screen_private *glamor_priv, int w,
+                                      int h, GLenum format, int flag);
+@@ -549,14 +548,6 @@ static inline Bool glamor_picture_is_alpha(PicturePtr picture)
+     return picture->format == PICT_a1 || picture->format == PICT_a8;
+ }
+-/* Return whether 'fbo' is storing alpha bits in the red channel */
+-static inline Bool
+-glamor_fbo_red_is_alpha(glamor_screen_private *glamor_priv, glamor_pixmap_fbo *fbo)
+-{
+-    /* True when the format is GL_RED (that can only happen when our one channel format is GL_RED */
+-    return fbo->format == GL_RED;
+-}
+-
+ /* Return whether 'picture' is storing alpha bits in the red channel */
+ static inline Bool
+ glamor_picture_red_is_alpha(PicturePtr picture)
+diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
+index d5737018f..6db6bfbc3 100644
+--- a/glamor/glamor_render.c
++++ b/glamor/glamor_render.c
+@@ -529,7 +529,7 @@ glamor_set_composite_texture(glamor_screen_private *glamor_priv, int unit,
+      * sometimes get zero bits in the R channel, which is harmless.
+      */
+     glamor_bind_texture(glamor_priv, GL_TEXTURE0 + unit, fbo,
+-                        glamor_fbo_red_is_alpha(glamor_priv, dest_priv->fbo));
++                        dest_priv->fbo->is_red);
+     repeat_type = picture->repeatType;
+     switch (picture->repeatType) {
+     case RepeatNone:
+diff --git a/glamor/glamor_transfer.c b/glamor/glamor_transfer.c
+index 421ed3a5f..215752d7b 100644
+--- a/glamor/glamor_transfer.c
++++ b/glamor/glamor_transfer.c
+@@ -40,7 +40,7 @@ glamor_format_for_pixmap(PixmapPtr pixmap, GLenum *format, GLenum *type)
+         break;
+     case 16:
+         if (priv->is_cbcr) {
+-          *format = priv->fbo->format;
++          *format = GL_RG;
+           *type = GL_UNSIGNED_BYTE;
+         } else {
+           *format = GL_RGB;
+-- 
+2.17.1
+
diff --git a/recipes-graphics/xorg-xserver/xserver-xorg/0006-glamor-Plumb-the-pixmap-through-fbo-creation-instead.patch b/recipes-graphics/xorg-xserver/xserver-xorg/0006-glamor-Plumb-the-pixmap-through-fbo-creation-instead.patch
new file mode 100644 (file)
index 0000000..66d2877
--- /dev/null
@@ -0,0 +1,265 @@
+From 3c14a16e1b4277aa00a2b23d5758d99dc20ca819 Mon Sep 17 00:00:00 2001
+From: Eric Anholt <eric@anholt.net>
+Date: Tue, 26 Mar 2019 16:57:24 -0700
+Subject: [PATCH 6/8] glamor: Plumb the pixmap through fbo creation instead of
+ a "format"
+
+For GLES, we're going to need a lot more logic for picking the
+iformat/format/type of texture setup, so we'll want the pixmap's depth
+and is_cbcr flag.
+
+Upstream-Status: Backport
+Signed-off-by: Eric Anholt <eric@anholt.net>
+---
+ glamor/glamor.c         | 20 +++++++-------------
+ glamor/glamor_fbo.c     | 33 +++++++++++++++++++--------------
+ glamor/glamor_picture.c |  2 +-
+ glamor/glamor_priv.h    | 12 ++++++------
+ 4 files changed, 33 insertions(+), 34 deletions(-)
+
+diff --git a/glamor/glamor.c b/glamor/glamor.c
+index c36b6ea74..f618c2128 100644
+--- a/glamor/glamor.c
++++ b/glamor/glamor.c
+@@ -106,7 +106,6 @@ glamor_set_pixmap_texture(PixmapPtr pixmap, unsigned int tex)
+     glamor_pixmap_private *pixmap_priv;
+     glamor_screen_private *glamor_priv;
+     glamor_pixmap_fbo *fbo;
+-    GLenum format;
+     glamor_priv = glamor_get_screen_private(screen);
+     pixmap_priv = glamor_get_pixmap_private(pixmap);
+@@ -116,9 +115,9 @@ glamor_set_pixmap_texture(PixmapPtr pixmap, unsigned int tex)
+         glamor_destroy_fbo(glamor_priv, fbo);
+     }
+-    format = gl_iformat_for_pixmap(pixmap);
+-    fbo = glamor_create_fbo_from_tex(glamor_priv, pixmap->drawable.width,
+-                                     pixmap->drawable.height, format, tex, 0);
++    fbo = glamor_create_fbo_from_tex(glamor_priv, pixmap,
++                                     pixmap->drawable.width,
++                                     pixmap->drawable.height, tex, 0);
+     if (fbo == NULL) {
+         ErrorF("XXX fail to create fbo.\n");
+@@ -204,7 +203,6 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
+     glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+     glamor_pixmap_fbo *fbo = NULL;
+     int pitch;
+-    GLenum format;
+     if (w > 32767 || h > 32767)
+         return NullPixmap;
+@@ -223,8 +221,6 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
+     pixmap_priv->is_cbcr = (usage == GLAMOR_CREATE_FORMAT_CBCR);
+-    format = gl_iformat_for_pixmap(pixmap);
+-
+     pitch = (((w * pixmap->drawable.bitsPerPixel + 7) / 8) + 3) & ~3;
+     screen->ModifyPixmapHeader(pixmap, w, h, 0, 0, pitch, NULL);
+@@ -238,12 +234,12 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
+         glamor_check_fbo_size(glamor_priv, w, h))
+     {
+         glamor_init_pixmap_private_small(pixmap, pixmap_priv);
+-        fbo = glamor_create_fbo(glamor_priv, w, h, format, usage);
++        fbo = glamor_create_fbo(glamor_priv, pixmap, w, h, usage);
+     } else {
+         int tile_size = glamor_priv->max_fbo_size;
+         DEBUGF("Create LARGE pixmap %p width %d height %d, tile size %d\n",
+                pixmap, w, h, tile_size);
+-        fbo = glamor_create_fbo_array(glamor_priv, w, h, format, usage,
++        fbo = glamor_create_fbo_array(glamor_priv, pixmap, usage,
+                                       tile_size, tile_size, pixmap_priv);
+     }
+@@ -860,8 +856,7 @@ _glamor_fds_from_pixmap(ScreenPtr screen, PixmapPtr pixmap, int *fds,
+     switch (pixmap_priv->type) {
+     case GLAMOR_TEXTURE_DRM:
+     case GLAMOR_TEXTURE_ONLY:
+-        if (!glamor_pixmap_ensure_fbo(pixmap, pixmap->drawable.depth == 30 ?
+-                                      GL_RGB10_A2 : GL_RGBA, 0))
++        if (!glamor_pixmap_ensure_fbo(pixmap, 0))
+             return 0;
+         if (modifier) {
+@@ -937,8 +932,7 @@ glamor_name_from_pixmap(PixmapPtr pixmap, CARD16 *stride, CARD32 *size)
+     switch (pixmap_priv->type) {
+     case GLAMOR_TEXTURE_DRM:
+     case GLAMOR_TEXTURE_ONLY:
+-        if (!glamor_pixmap_ensure_fbo(pixmap, pixmap->drawable.depth == 30 ?
+-                                      GL_RGB10_A2 : GL_RGBA, 0))
++        if (!glamor_pixmap_ensure_fbo(pixmap, 0))
+             return -1;
+         return glamor_egl_fd_name_from_pixmap(pixmap->drawable.pScreen,
+                                               pixmap, stride, size);
+diff --git a/glamor/glamor_fbo.c b/glamor/glamor_fbo.c
+index 58eb97bf4..75f7e2baa 100644
+--- a/glamor/glamor_fbo.c
++++ b/glamor/glamor_fbo.c
+@@ -95,8 +95,9 @@ glamor_pixmap_ensure_fb(glamor_screen_private *glamor_priv,
+ glamor_pixmap_fbo *
+ glamor_create_fbo_from_tex(glamor_screen_private *glamor_priv,
+-                           int w, int h, Bool is_red, GLint tex, int flag)
++                           PixmapPtr pixmap, int w, int h, GLint tex, int flag)
+ {
++    GLenum format = gl_iformat_for_pixmap(pixmap);
+     glamor_pixmap_fbo *fbo;
+     fbo = calloc(1, sizeof(*fbo));
+@@ -106,7 +107,7 @@ glamor_create_fbo_from_tex(glamor_screen_private *glamor_priv,
+     fbo->tex = tex;
+     fbo->width = w;
+     fbo->height = h;
+-    fbo->is_red = is_red;
++    fbo->is_red = format == GL_RED;
+     if (flag != GLAMOR_CREATE_FBO_NO_FBO) {
+         if (glamor_pixmap_ensure_fb(glamor_priv, fbo) != 0) {
+@@ -120,13 +121,15 @@ glamor_create_fbo_from_tex(glamor_screen_private *glamor_priv,
+ static int
+ _glamor_create_tex(glamor_screen_private *glamor_priv,
+-                   int w, int h, GLenum format)
++                   PixmapPtr pixmap, int w, int h)
+ {
++    GLenum iformat = gl_iformat_for_pixmap(pixmap);
++    GLenum format = iformat;
+     unsigned int tex;
+-    GLenum iformat = format;
+     if (format == GL_RGB10_A2)
+         format = GL_RGBA;
++
+     glamor_make_current(glamor_priv);
+     glGenTextures(1, &tex);
+     glBindTexture(GL_TEXTURE_2D, tex);
+@@ -156,14 +159,14 @@ _glamor_create_tex(glamor_screen_private *glamor_priv,
+ glamor_pixmap_fbo *
+ glamor_create_fbo(glamor_screen_private *glamor_priv,
+-                  int w, int h, GLenum format, int flag)
++                  PixmapPtr pixmap, int w, int h, int flag)
+ {
+-    GLint tex = _glamor_create_tex(glamor_priv, w, h, format);
++    GLint tex = _glamor_create_tex(glamor_priv, pixmap, w, h);
+     if (!tex) /* Texture creation failed due to GL_OUT_OF_MEMORY */
+         return NULL;
+-    return glamor_create_fbo_from_tex(glamor_priv, w, h, format == GL_RED,
++    return glamor_create_fbo_from_tex(glamor_priv, pixmap, w, h,
+                                       tex, flag);
+ }
+@@ -173,10 +176,12 @@ glamor_create_fbo(glamor_screen_private *glamor_priv,
+  */
+ glamor_pixmap_fbo *
+ glamor_create_fbo_array(glamor_screen_private *glamor_priv,
+-                         int w, int h, GLenum format, int flag,
++                        PixmapPtr pixmap, int flag,
+                          int block_w, int block_h,
+                          glamor_pixmap_private *priv)
+ {
++    int w = pixmap->drawable.width;
++    int h = pixmap->drawable.height;
+     int block_wcnt;
+     int block_hcnt;
+     glamor_pixmap_fbo **fbo_array;
+@@ -216,8 +221,8 @@ glamor_create_fbo_array(glamor_screen_private *glamor_priv,
+                 box_array[i * block_wcnt + j].x2 - box_array[i * block_wcnt +
+                                                              j].x1;
+             fbo_array[i * block_wcnt + j] = glamor_create_fbo(glamor_priv,
++                                                              pixmap,
+                                                               fbo_w, fbo_h,
+-                                                              format,
+                                                               GLAMOR_CREATE_PIXMAP_FIXUP);
+             if (fbo_array[i * block_wcnt + j] == NULL)
+                 goto cleanup;
+@@ -315,7 +320,7 @@ glamor_pixmap_destroy_fbo(PixmapPtr pixmap)
+ }
+ Bool
+-glamor_pixmap_ensure_fbo(PixmapPtr pixmap, GLenum format, int flag)
++glamor_pixmap_ensure_fbo(PixmapPtr pixmap, int flag)
+ {
+     glamor_screen_private *glamor_priv;
+     glamor_pixmap_private *pixmap_priv;
+@@ -325,8 +330,8 @@ glamor_pixmap_ensure_fbo(PixmapPtr pixmap, GLenum format, int flag)
+     pixmap_priv = glamor_get_pixmap_private(pixmap);
+     if (pixmap_priv->fbo == NULL) {
+-        fbo = glamor_create_fbo(glamor_priv, pixmap->drawable.width,
+-                                pixmap->drawable.height, format, flag);
++        fbo = glamor_create_fbo(glamor_priv, pixmap, pixmap->drawable.width,
++                                pixmap->drawable.height, flag);
+         if (fbo == NULL)
+             return FALSE;
+@@ -336,8 +341,8 @@ glamor_pixmap_ensure_fbo(PixmapPtr pixmap, GLenum format, int flag)
+         /* We do have a fbo, but it may lack of fb or tex. */
+         if (!pixmap_priv->fbo->tex)
+             pixmap_priv->fbo->tex =
+-                _glamor_create_tex(glamor_priv, pixmap->drawable.width,
+-                                   pixmap->drawable.height, format);
++                _glamor_create_tex(glamor_priv, pixmap, pixmap->drawable.width,
++                                   pixmap->drawable.height);
+         if (flag != GLAMOR_CREATE_FBO_NO_FBO && pixmap_priv->fbo->fb == 0)
+             if (glamor_pixmap_ensure_fb(glamor_priv, pixmap_priv->fbo) != 0)
+diff --git a/glamor/glamor_picture.c b/glamor/glamor_picture.c
+index 685d8d618..e6d387d42 100644
+--- a/glamor/glamor_picture.c
++++ b/glamor/glamor_picture.c
+@@ -340,7 +340,7 @@ glamor_upload_picture_to_texture(PicturePtr picture)
+     else
+         iformat = format;
+-    if (!glamor_pixmap_ensure_fbo(pixmap, iformat, GLAMOR_CREATE_FBO_NO_FBO)) {
++    if (!glamor_pixmap_ensure_fbo(pixmap, GLAMOR_CREATE_FBO_NO_FBO)) {
+         ret = FALSE;
+         goto fail;
+     }
+diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
+index e70d349da..a87caec9b 100644
+--- a/glamor/glamor_priv.h
++++ b/glamor/glamor_priv.h
+@@ -531,11 +531,11 @@ glamor_pixmap_fbo *glamor_pixmap_detach_fbo(glamor_pixmap_private *
+                                             pixmap_priv);
+ void glamor_pixmap_attach_fbo(PixmapPtr pixmap, glamor_pixmap_fbo *fbo);
+ glamor_pixmap_fbo *glamor_create_fbo_from_tex(glamor_screen_private *
+-                                              glamor_priv, int w, int h,
+-                                              Bool is_red, GLint tex,
++                                              glamor_priv, PixmapPtr pixmap,
++                                              int w, int h, GLint tex,
+                                               int flag);
+-glamor_pixmap_fbo *glamor_create_fbo(glamor_screen_private *glamor_priv, int w,
+-                                     int h, GLenum format, int flag);
++glamor_pixmap_fbo *glamor_create_fbo(glamor_screen_private *glamor_priv,
++                                     PixmapPtr pixmap, int w, int h, int flag);
+ void glamor_destroy_fbo(glamor_screen_private *glamor_priv,
+                         glamor_pixmap_fbo *fbo);
+ void glamor_pixmap_destroy_fbo(PixmapPtr pixmap);
+@@ -563,7 +563,7 @@ void glamor_bind_texture(glamor_screen_private *glamor_priv,
+                          Bool destination_red);
+ glamor_pixmap_fbo *glamor_create_fbo_array(glamor_screen_private *glamor_priv,
+-                                           int w, int h, GLenum format,
++                                           PixmapPtr pixmap,
+                                            int flag, int block_w, int block_h,
+                                            glamor_pixmap_private *);
+@@ -673,7 +673,7 @@ glamor_put_vbo_space(ScreenPtr screen);
+  * the fbo has valid texture and attach to a valid fb.
+  * If the fbo already has a valid glfbo then do nothing.
+  */
+-Bool glamor_pixmap_ensure_fbo(PixmapPtr pixmap, GLenum format, int flag);
++Bool glamor_pixmap_ensure_fbo(PixmapPtr pixmap, int flag);
+ glamor_pixmap_clipped_regions *
+ glamor_compute_clipped_regions(PixmapPtr pixmap,
+-- 
+2.17.1
+
diff --git a/recipes-graphics/xorg-xserver/xserver-xorg/0007-glamor-Switch-the-gl_flavor-to-a-boolean-is_gles.patch b/recipes-graphics/xorg-xserver/xserver-xorg/0007-glamor-Switch-the-gl_flavor-to-a-boolean-is_gles.patch
new file mode 100644 (file)
index 0000000..f2947f3
--- /dev/null
@@ -0,0 +1,287 @@
+From 3a03576d672d24f19fdb930b08afde9a3a3f55da Mon Sep 17 00:00:00 2001
+From: Eric Anholt <eric@anholt.net>
+Date: Tue, 26 Mar 2019 15:02:38 -0700
+Subject: [PATCH 7/8] glamor: Switch the gl_flavor to a boolean is_gles.
+
+There are only 2 flavors we are distinguishing -- GL versions are
+handled separately.
+
+Upstream-Status: Backport
+Signed-off-by: Eric Anholt <eric@anholt.net>
+---
+ glamor/glamor.c         | 20 +++++++++-----------
+ glamor/glamor_picture.c | 22 +++++++++++-----------
+ glamor/glamor_pixmap.c  |  2 +-
+ glamor/glamor_priv.h    |  7 +------
+ glamor/glamor_program.c |  2 +-
+ glamor/glamor_render.c  |  2 +-
+ glamor/glamor_utils.h   |  6 +++---
+ 7 files changed, 27 insertions(+), 34 deletions(-)
+
+diff --git a/glamor/glamor.c b/glamor/glamor.c
+index f618c2128..019edbbb1 100644
+--- a/glamor/glamor.c
++++ b/glamor/glamor.c
+@@ -505,10 +505,8 @@ glamor_init(ScreenPtr screen, unsigned int flags)
+     glamor_make_current(glamor_priv);
+-    if (epoxy_is_desktop_gl())
+-        glamor_priv->gl_flavor = GLAMOR_GL_DESKTOP;
+-    else
+-        glamor_priv->gl_flavor = GLAMOR_GL_ES2;
++    if (!epoxy_is_desktop_gl())
++        glamor_priv->is_gles = TRUE;
+     gl_version = epoxy_gl_version();
+@@ -540,7 +538,7 @@ glamor_init(ScreenPtr screen, unsigned int flags)
+     }
+     glamor_priv->glsl_version = glsl_major * 100 + glsl_minor;
+-    if (glamor_priv->gl_flavor == GLAMOR_GL_ES2) {
++    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
+@@ -564,7 +562,7 @@ glamor_init(ScreenPtr screen, unsigned int flags)
+      * have support for it, with most of the ones lacking it being on
+      * Windows with Intel 4-series (G45) graphics or older.
+      */
+-    if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
++    if (!glamor_priv->is_gles) {
+         if (gl_version < 21) {
+             ErrorF("Require OpenGL version 2.1 or later.\n");
+             goto fail;
+@@ -610,7 +608,7 @@ glamor_init(ScreenPtr screen, unsigned int flags)
+     }
+     glamor_priv->has_rw_pbo = FALSE;
+-    if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP)
++    if (!glamor_priv->is_gles)
+         glamor_priv->has_rw_pbo = TRUE;
+     glamor_priv->has_khr_debug = epoxy_has_gl_extension("GL_KHR_debug");
+@@ -628,11 +626,11 @@ glamor_init(ScreenPtr screen, unsigned int flags)
+     glamor_priv->has_nv_texture_barrier =
+         epoxy_has_gl_extension("GL_NV_texture_barrier");
+     glamor_priv->has_unpack_subimage =
+-        glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP ||
++        !glamor_priv->is_gles ||
+         epoxy_gl_version() >= 30 ||
+         epoxy_has_gl_extension("GL_EXT_unpack_subimage");
+     glamor_priv->has_pack_subimage =
+-        glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP ||
++        !glamor_priv->is_gles ||
+         epoxy_gl_version() >= 30 ||
+         epoxy_has_gl_extension("GL_NV_pack_subimage");
+     glamor_priv->has_dual_blend =
+@@ -643,7 +641,7 @@ glamor_init(ScreenPtr screen, unsigned int flags)
+     glamor_setup_debug_output(screen);
+-    glamor_priv->use_quads = (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) &&
++    glamor_priv->use_quads = !glamor_priv->is_gles &&
+                              !glamor_priv->is_core_profile;
+     /* Driver-specific hack: Avoid using GL_QUADS on VC4, where
+@@ -665,7 +663,7 @@ glamor_init(ScreenPtr screen, unsigned int flags)
+     glamor_priv->has_texture_swizzle =
+         (epoxy_has_gl_extension("GL_ARB_texture_swizzle") ||
+-         (glamor_priv->gl_flavor != GLAMOR_GL_DESKTOP && gl_version >= 30));
++         (glamor_priv->is_gles && gl_version >= 30));
+     glamor_priv->one_channel_format = GL_ALPHA;
+     if (epoxy_has_gl_extension("GL_ARB_texture_rg") &&
+diff --git a/glamor/glamor_picture.c b/glamor/glamor_picture.c
+index e6d387d42..ed2decc83 100644
+--- a/glamor/glamor_picture.c
++++ b/glamor/glamor_picture.c
+@@ -90,7 +90,7 @@ glamor_get_tex_format_type_from_pictformat(ScreenPtr pScreen,
+     case PICT_b8g8r8x8:
+     case PICT_b8g8r8a8:
+-        if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
++        if (!glamor_priv->is_gles) {
+             *tex_format = GL_BGRA;
+             *tex_type = GL_UNSIGNED_INT_8_8_8_8;
+         } else {
+@@ -109,7 +109,7 @@ glamor_get_tex_format_type_from_pictformat(ScreenPtr pScreen,
+     case PICT_x8r8g8b8:
+     case PICT_a8r8g8b8:
+-        if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
++        if (!glamor_priv->is_gles) {
+             *tex_format = GL_BGRA;
+             *tex_type = GL_UNSIGNED_INT_8_8_8_8_REV;
+         } else {
+@@ -128,7 +128,7 @@ glamor_get_tex_format_type_from_pictformat(ScreenPtr pScreen,
+     case PICT_x8b8g8r8:
+     case PICT_a8b8g8r8:
+         *tex_format = GL_RGBA;
+-        if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
++        if (!glamor_priv->is_gles) {
+             *tex_type = GL_UNSIGNED_INT_8_8_8_8_REV;
+         } else {
+             *tex_format = GL_RGBA;
+@@ -141,7 +141,7 @@ glamor_get_tex_format_type_from_pictformat(ScreenPtr pScreen,
+     case PICT_x2r10g10b10:
+     case PICT_a2r10g10b10:
+-        if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
++        if (!glamor_priv->is_gles) {
+             *tex_format = GL_BGRA;
+             *tex_type = GL_UNSIGNED_INT_2_10_10_10_REV;
+         } else {
+@@ -151,7 +151,7 @@ glamor_get_tex_format_type_from_pictformat(ScreenPtr pScreen,
+     case PICT_x2b10g10r10:
+     case PICT_a2b10g10r10:
+-        if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
++        if (!glamor_priv->is_gles) {
+             *tex_format = GL_RGBA;
+             *tex_type = GL_UNSIGNED_INT_2_10_10_10_REV;
+         } else {
+@@ -165,7 +165,7 @@ glamor_get_tex_format_type_from_pictformat(ScreenPtr pScreen,
+         break;
+     case PICT_b5g6r5:
+         *tex_format = GL_RGB;
+-        if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
++        if (!glamor_priv->is_gles) {
+             *tex_type = GL_UNSIGNED_SHORT_5_6_5_REV;
+         } else {
+             *tex_type = GL_UNSIGNED_SHORT_5_6_5;
+@@ -177,7 +177,7 @@ glamor_get_tex_format_type_from_pictformat(ScreenPtr pScreen,
+     case PICT_x1b5g5r5:
+     case PICT_a1b5g5r5:
+         *tex_format = GL_RGBA;
+-        if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
++        if (!glamor_priv->is_gles) {
+             *tex_type = GL_UNSIGNED_SHORT_1_5_5_5_REV;
+         } else {
+             return FALSE;
+@@ -186,7 +186,7 @@ glamor_get_tex_format_type_from_pictformat(ScreenPtr pScreen,
+     case PICT_x1r5g5b5:
+     case PICT_a1r5g5b5:
+-        if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
++        if (!glamor_priv->is_gles) {
+             *tex_format = GL_BGRA;
+             *tex_type = GL_UNSIGNED_SHORT_1_5_5_5_REV;
+         } else {
+@@ -201,7 +201,7 @@ glamor_get_tex_format_type_from_pictformat(ScreenPtr pScreen,
+     case PICT_x4r4g4b4:
+     case PICT_a4r4g4b4:
+-        if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
++        if (!glamor_priv->is_gles) {
+             *tex_format = GL_BGRA;
+             *tex_type = GL_UNSIGNED_SHORT_4_4_4_4_REV;
+         } else {
+@@ -213,7 +213,7 @@ glamor_get_tex_format_type_from_pictformat(ScreenPtr pScreen,
+     case PICT_x4b4g4r4:
+     case PICT_a4b4g4r4:
+-        if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
++        if (!glamor_priv->is_gles) {
+             *tex_format = GL_RGBA;
+             *tex_type = GL_UNSIGNED_SHORT_4_4_4_4_REV;
+         } else {
+@@ -335,7 +335,7 @@ glamor_upload_picture_to_texture(PicturePtr picture)
+         stride = pixman_image_get_stride(converted_image);
+     }
+-    if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP)
++    if (!glamor_priv->is_gles)
+         iformat = gl_iformat_for_pixmap(pixmap);
+     else
+         iformat = format;
+diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c
+index 166bde509..9aa169cdc 100644
+--- a/glamor/glamor_pixmap.c
++++ b/glamor/glamor_pixmap.c
+@@ -124,7 +124,7 @@ glamor_set_alu(ScreenPtr screen, unsigned char alu)
+ {
+     glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+-    if (glamor_priv->gl_flavor == GLAMOR_GL_ES2) {
++    if (glamor_priv->is_gles) {
+         if (alu != GXcopy)
+             return FALSE;
+         else
+diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
+index a87caec9b..8e8433ff3 100644
+--- a/glamor/glamor_priv.h
++++ b/glamor/glamor_priv.h
+@@ -155,11 +155,6 @@ enum gradient_shader {
+ struct glamor_screen_private;
+ struct glamor_pixmap_private;
+-enum glamor_gl_flavor {
+-    GLAMOR_GL_DESKTOP,          // OPENGL API
+-    GLAMOR_GL_ES2               // OPENGL ES2.0 API
+-};
+-
+ #define GLAMOR_COMPOSITE_VBO_VERT_CNT (64*1024)
+ struct glamor_saved_procs {
+@@ -185,7 +180,7 @@ struct glamor_saved_procs {
+ };
+ typedef struct glamor_screen_private {
+-    enum glamor_gl_flavor gl_flavor;
++    Bool is_gles;
+     int glsl_version;
+     Bool has_pack_invert;
+     Bool has_fbo_blit;
+diff --git a/glamor/glamor_program.c b/glamor/glamor_program.c
+index 830deb38b..b0a9d07a4 100644
+--- a/glamor/glamor_program.c
++++ b/glamor/glamor_program.c
+@@ -459,7 +459,7 @@ glamor_set_blend(CARD8 op, glamor_program_alpha alpha, PicturePtr dst)
+         break;
+     }
+-    if (glamor_priv->gl_flavor != GLAMOR_GL_ES2)
++    if (!glamor_priv->is_gles)
+         glDisable(GL_COLOR_LOGIC_OP);
+     if (op == PictOpSrc)
+diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
+index 6db6bfbc3..d3859e4d1 100644
+--- a/glamor/glamor_render.c
++++ b/glamor/glamor_render.c
+@@ -1091,7 +1091,7 @@ glamor_composite_set_shader_blend(glamor_screen_private *glamor_priv,
+         }
+     }
+-    if (glamor_priv->gl_flavor != GLAMOR_GL_ES2)
++    if (!glamor_priv->is_gles)
+         glDisable(GL_COLOR_LOGIC_OP);
+     if (op_info->source_blend == GL_ONE && op_info->dest_blend == GL_ZERO) {
+diff --git a/glamor/glamor_utils.h b/glamor/glamor_utils.h
+index 8a147ca7e..cbb808294 100644
+--- a/glamor/glamor_utils.h
++++ b/glamor/glamor_utils.h
+@@ -615,13 +615,13 @@ gl_iformat_for_pixmap(PixmapPtr pixmap)
+         glamor_get_screen_private((pixmap)->drawable.pScreen);
+     glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
+-    if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP &&
++    if (!glamor_priv->is_gles &&
+         ((pixmap)->drawable.depth == 1 || (pixmap)->drawable.depth == 8)) {
+         return glamor_priv->one_channel_format;
+-    } else if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP &&
++    } else if (!glamor_priv->is_gles &&
+                (pixmap)->drawable.depth == 16 && pixmap_priv->is_cbcr) {
+         return GL_RG;
+-    } else if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP &&
++    } else if (!glamor_priv->is_gles &&
+                (pixmap)->drawable.depth == 30) {
+         return GL_RGB10_A2;
+     } else {
+-- 
+2.17.1
+
diff --git a/recipes-graphics/xorg-xserver/xserver-xorg/0008-glamor-Introduce-a-central-place-for-our-pixmap-form.patch b/recipes-graphics/xorg-xserver/xserver-xorg/0008-glamor-Introduce-a-central-place-for-our-pixmap-form.patch
new file mode 100644 (file)
index 0000000..dd82340
--- /dev/null
@@ -0,0 +1,669 @@
+From b75296bee6ab3578f3a13cfb6de5d77ec02b9047 Mon Sep 17 00:00:00 2001
+From: Eric Anholt <eric@anholt.net>
+Date: Tue, 26 Mar 2019 15:10:49 -0700
+Subject: [PATCH 8/8] glamor: Introduce a central place for our pixmap
+ format/type handling.
+
+We had various helper functions trying to come up with the
+internalformat/format/type/render formats for pixmaps, and it's much
+nicer to just detect what those should be once at startup.  This gives
+us a chance to do the right thing for GLES.
+
+It also, notably, fixes our format/type for depth 15 and 16 setup for
+desktop GL, so that we actually allocate 16bpp (GL_RGB/565) on most
+drivers instead of 32bpp (GL_RGB/UBYTE).
+
+GLES still has regressions over desktop (2 regressions in llvmpipe
+XTS, many in rendercheck), but I think this is a good baseline.
+
+Upstream-Status: Backport
+Signed-off-by: Eric Anholt <eric@anholt.net>
+---
+ glamor/glamor.c           | 167 ++++++++++++++++++++++++++++++++++++--
+ glamor/glamor_fbo.c       |  16 ++--
+ glamor/glamor_picture.c   |   7 +-
+ glamor/glamor_priv.h      |  22 ++++-
+ glamor/glamor_render.c    |   7 +-
+ glamor/glamor_spans.c     |  14 ++--
+ glamor/glamor_transfer.c  |  56 ++-----------
+ glamor/glamor_transfer.h  |   3 -
+ glamor/glamor_transform.c |   5 +-
+ glamor/glamor_utils.h     |  57 -------------
+ 10 files changed, 209 insertions(+), 145 deletions(-)
+
+diff --git a/glamor/glamor.c b/glamor/glamor.c
+index 019edbbb1..3450113e0 100644
+--- a/glamor/glamor.c
++++ b/glamor/glamor.c
+@@ -212,7 +212,7 @@ 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_check_pixmap_fbo_depth(depth)))
++         || !glamor_priv->formats[depth].format))
+         return fbCreatePixmap(screen, w, h, depth, usage);
+     else
+         pixmap = fbCreatePixmap(screen, 0, 0, depth, usage);
+@@ -440,6 +440,165 @@ glamor_setup_debug_output(ScreenPtr screen)
+         glEnable(GL_DEBUG_OUTPUT);
+ }
++const struct glamor_format *
++glamor_format_for_pixmap(PixmapPtr pixmap)
++{
++    ScreenPtr pScreen = pixmap->drawable.pScreen;
++    glamor_screen_private *glamor_priv = glamor_get_screen_private(pScreen);
++    glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
++
++    if (pixmap_priv->is_cbcr)
++        return &glamor_priv->cbcr_format;
++    else
++        return &glamor_priv->formats[pixmap->drawable.depth];
++}
++
++static void
++glamor_add_format(ScreenPtr screen, int depth, CARD32 render_format,
++                  GLenum internalformat, GLenum format, GLenum type)
++{
++    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
++    struct glamor_format *f = &glamor_priv->formats[depth];
++
++    /* 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
++     * them matching to get data back out.  To avoid this limitation, we
++     * would need to have a more general glReadPixels() path in
++     * glamor_transfer that re-encoded the bits to the pixel format that
++     * we intended after.
++     *
++     * Note that we can't just create a pixmap because we're in
++     * screeninit.
++     */
++    if (glamor_priv->is_gles) {
++        unsigned fbo, tex;
++        int read_format, read_type;
++        GLenum status;
++
++        glGenTextures(1, &tex);
++        glBindTexture(GL_TEXTURE_2D, tex);
++        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
++        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
++        glTexImage2D(GL_TEXTURE_2D, 0, internalformat, 1, 1, 0,
++                     format, type, NULL);
++
++        glGenFramebuffers(1, &fbo);
++        glBindFramebuffer(GL_FRAMEBUFFER, fbo);
++        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
++                               GL_TEXTURE_2D, tex, 0);
++        status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
++        if (status != GL_FRAMEBUFFER_COMPLETE) {
++            ErrorF("glamor: Test fbo for depth %d incomplete.  "
++                   "Falling back to software.\n", depth);
++            glDeleteTextures(1, &tex);
++            glDeleteFramebuffers(1, &fbo);
++            return;
++        }
++
++        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) {
++            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;
++        }
++    }
++
++    f->depth = depth;
++    f->render_format = render_format;
++    f->internalformat = internalformat;
++    f->format = format;
++    f->type = type;
++}
++
++/* Set up the GL format/types that glamor will use for the various depths
++ *
++ * X11's pixel data doesn't have channels, but to store our data in GL
++ * we have to pick some sort of format to move X11 pixel data in and
++ * out with in glamor_transfer.c.  For X11 core operations, other than
++ * GL logic ops (non-GXcopy GC ops) what the driver chooses internally
++ * doesn't matter as long as it doesn't drop any bits (we expect them
++ * to generally expand, if anything).  For Render, we can expect
++ * clients to tend to render with PictFormats matching our channel
++ * layouts here since ultimately X11 pixels tend to end up on the
++ * screen.  The render implementation will fall back to fb if the
++ * channels don't match.
++ *
++ * Note that these formats don't affect what glamor_egl.c or
++ * Xwayland's EGL layer choose for surfaces exposed through DRI or
++ * scanout.  For now, those layers need to match what we're choosing
++ * here, or channels will end up swizzled around.  Similarly, the
++ * driver's visual masks also need to match what we're doing here.
++ */
++static void
++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.
++     */
++    if (glamor_priv->is_gles || epoxy_has_gl_extension("GL_ARB_texture_rg")) {
++        glamor_add_format(screen, 8, PICT_a8,
++                          GL_R8, GL_RED, GL_UNSIGNED_BYTE);
++    } else {
++        glamor_add_format(screen, 8, PICT_a8,
++                          GL_ALPHA, GL_ALPHA, GL_UNSIGNED_BYTE);
++    }
++
++    if (glamor_priv->is_gles) {
++        /* For 15bpp, GLES supports format/type RGBA/5551, rather than
++         * bgra/1555_rev.  GL_EXT_bgra lets the impl say the color
++         * read format/type is bgra/1555 even if we had to create it
++         * with rgba/5551, with Mesa does.  That means we can't use
++         * the same format/type for TexSubImage and readpixels.
++         *
++         * Instead, just store 16 bits using the trusted 565 path, and
++         * disable render accel for now.
++         */
++        glamor_add_format(screen, 15, PICT_x1r5g5b5,
++                          GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1);
++    } else {
++        glamor_add_format(screen, 15, PICT_x1r5g5b5,
++                          GL_RGBA, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV);
++    }
++
++    glamor_add_format(screen, 16, PICT_r5g6b5,
++                      GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5);
++
++    if (glamor_priv->is_gles) {
++        assert(X_BYTE_ORDER == X_LITTLE_ENDIAN);
++        glamor_add_format(screen, 24, PICT_x8b8g8r8,
++                          GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE);
++        glamor_add_format(screen, 32, PICT_a8b8g8r8,
++                          GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE);
++    } else {
++        glamor_add_format(screen, 24, PICT_x8r8g8b8,
++                          GL_RGBA, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV);
++        glamor_add_format(screen, 32, PICT_a8r8g8b8,
++                          GL_RGBA, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV);
++    }
++
++    if (glamor_priv->is_gles) {
++        glamor_add_format(screen, 30, PICT_x2b10g10r10,
++                          GL_RGB10_A2, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV);
++    } else {
++        glamor_add_format(screen, 30, PICT_x2r10g10b10,
++                          GL_RGB10_A2, GL_BGRA, GL_UNSIGNED_INT_2_10_10_10_REV);
++    }
++
++    glamor_priv->cbcr_format.depth = 16;
++    glamor_priv->cbcr_format.internalformat = GL_RG8;
++    glamor_priv->cbcr_format.format = GL_RG;
++    glamor_priv->cbcr_format.type = GL_UNSIGNED_BYTE;
++}
++
+ /** Set up glamor for an already-configured GL context. */
+ Bool
+ glamor_init(ScreenPtr screen, unsigned int flags)
+@@ -665,11 +824,7 @@ glamor_init(ScreenPtr screen, unsigned int flags)
+         (epoxy_has_gl_extension("GL_ARB_texture_swizzle") ||
+          (glamor_priv->is_gles && gl_version >= 30));
+-    glamor_priv->one_channel_format = GL_ALPHA;
+-    if (epoxy_has_gl_extension("GL_ARB_texture_rg") &&
+-        glamor_priv->has_texture_swizzle) {
+-        glamor_priv->one_channel_format = GL_RED;
+-    }
++    glamor_setup_formats(screen);
+     glamor_set_debug_level(&glamor_debug_level);
+diff --git a/glamor/glamor_fbo.c b/glamor/glamor_fbo.c
+index 75f7e2baa..dfb3f754d 100644
+--- a/glamor/glamor_fbo.c
++++ b/glamor/glamor_fbo.c
+@@ -97,7 +97,7 @@ glamor_pixmap_fbo *
+ glamor_create_fbo_from_tex(glamor_screen_private *glamor_priv,
+                            PixmapPtr pixmap, int w, int h, GLint tex, int flag)
+ {
+-    GLenum format = gl_iformat_for_pixmap(pixmap);
++    const struct glamor_format *f = glamor_format_for_pixmap(pixmap);
+     glamor_pixmap_fbo *fbo;
+     fbo = calloc(1, sizeof(*fbo));
+@@ -107,7 +107,7 @@ glamor_create_fbo_from_tex(glamor_screen_private *glamor_priv,
+     fbo->tex = tex;
+     fbo->width = w;
+     fbo->height = h;
+-    fbo->is_red = format == GL_RED;
++    fbo->is_red = f->format == GL_RED;
+     if (flag != GLAMOR_CREATE_FBO_NO_FBO) {
+         if (glamor_pixmap_ensure_fb(glamor_priv, fbo) != 0) {
+@@ -123,23 +123,19 @@ static int
+ _glamor_create_tex(glamor_screen_private *glamor_priv,
+                    PixmapPtr pixmap, int w, int h)
+ {
+-    GLenum iformat = gl_iformat_for_pixmap(pixmap);
+-    GLenum format = iformat;
++    const struct glamor_format *f = glamor_format_for_pixmap(pixmap);
+     unsigned int tex;
+-    if (format == GL_RGB10_A2)
+-        format = GL_RGBA;
+-
+     glamor_make_current(glamor_priv);
+     glGenTextures(1, &tex);
+     glBindTexture(GL_TEXTURE_2D, tex);
+     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+-    if (format == glamor_priv->one_channel_format && format == GL_RED)
++    if (f->format == GL_RED)
+         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_RED);
+     glamor_priv->suppress_gl_out_of_memory_logging = true;
+-    glTexImage2D(GL_TEXTURE_2D, 0, iformat, w, h, 0,
+-                 format, GL_UNSIGNED_BYTE, NULL);
++    glTexImage2D(GL_TEXTURE_2D, 0, f->internalformat, w, h, 0,
++                 f->format, f->type, NULL);
+     glamor_priv->suppress_gl_out_of_memory_logging = false;
+     if (glGetError() == GL_OUT_OF_MEMORY) {
+diff --git a/glamor/glamor_picture.c b/glamor/glamor_picture.c
+index ed2decc83..33b3bebd9 100644
+--- a/glamor/glamor_picture.c
++++ b/glamor/glamor_picture.c
+@@ -83,7 +83,7 @@ glamor_get_tex_format_type_from_pictformat(ScreenPtr pScreen,
+     switch (format) {
+     case PICT_a1:
+-        *tex_format = glamor_priv->one_channel_format;
++        *tex_format = glamor_priv->formats[1].format;
+         *tex_type = GL_UNSIGNED_BYTE;
+         *temp_format = PICT_a8;
+         break;
+@@ -195,7 +195,7 @@ glamor_get_tex_format_type_from_pictformat(ScreenPtr pScreen,
+         break;
+     case PICT_a8:
+-        *tex_format = glamor_priv->one_channel_format;
++        *tex_format = glamor_priv->formats[8].format;
+         *tex_type = GL_UNSIGNED_BYTE;
+         break;
+@@ -286,6 +286,7 @@ glamor_upload_picture_to_texture(PicturePtr picture)
+     Bool ret = TRUE;
+     Bool needs_swizzle;
+     pixman_image_t *converted_image = NULL;
++    const struct glamor_format *f = glamor_format_for_pixmap(pixmap);
+     assert(glamor_pixmap_is_memory(pixmap));
+     assert(!pixmap_priv->fbo);
+@@ -336,7 +337,7 @@ glamor_upload_picture_to_texture(PicturePtr picture)
+     }
+     if (!glamor_priv->is_gles)
+-        iformat = gl_iformat_for_pixmap(pixmap);
++        iformat = f->internalformat;
+     else
+         iformat = format;
+diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
+index 8e8433ff3..b8e2b932e 100644
+--- a/glamor/glamor_priv.h
++++ b/glamor/glamor_priv.h
+@@ -157,6 +157,21 @@ struct glamor_pixmap_private;
+ #define GLAMOR_COMPOSITE_VBO_VERT_CNT (64*1024)
++struct glamor_format {
++    /** X Server's "depth" value */
++    int depth;
++    /** GL internalformat for creating textures of this type */
++    GLenum internalformat;
++    /** GL format transferring pixels in/out of textures of this type. */
++    GLenum format;
++    /** GL type transferring pixels in/out of textures of this type. */
++    GLenum type;
++    /* Render PICT_* matching GL's channel layout for pixels
++     * transferred using format/type.
++     */
++    CARD32 render_format;
++};
++
+ struct glamor_saved_procs {
+     CloseScreenProcPtr close_screen;
+     CreateGCProcPtr create_gc;
+@@ -199,7 +214,8 @@ typedef struct glamor_screen_private {
+     Bool can_copyplane;
+     int max_fbo_size;
+-    GLuint one_channel_format;
++    struct glamor_format formats[33];
++    struct glamor_format cbcr_format;
+     /* glamor point shader */
+     glamor_program point_prog;
+@@ -537,6 +553,8 @@ void glamor_pixmap_destroy_fbo(PixmapPtr pixmap);
+ Bool glamor_pixmap_fbo_fixup(ScreenPtr screen, PixmapPtr pixmap);
+ void glamor_pixmap_clear_fbo(glamor_screen_private *glamor_priv, glamor_pixmap_fbo *fbo);
++const struct glamor_format *glamor_format_for_pixmap(PixmapPtr pixmap);
++
+ /* Return whether 'picture' is alpha-only */
+ static inline Bool glamor_picture_is_alpha(PicturePtr picture)
+ {
+@@ -549,7 +567,7 @@ glamor_picture_red_is_alpha(PicturePtr picture)
+ {
+     /* True when the picture is alpha only and the screen is using GL_RED for alpha pictures */
+     return glamor_picture_is_alpha(picture) &&
+-        glamor_get_screen_private(picture->pDrawable->pScreen)->one_channel_format == GL_RED;
++        glamor_get_screen_private(picture->pDrawable->pScreen)->formats[8].format == GL_RED;
+ }
+ void glamor_bind_texture(glamor_screen_private *glamor_priv,
+diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
+index d3859e4d1..a8dc3924b 100644
+--- a/glamor/glamor_render.c
++++ b/glamor/glamor_render.c
+@@ -772,12 +772,15 @@ static Bool
+ glamor_render_format_is_supported(PicturePtr picture)
+ {
+     PictFormatShort storage_format;
++    glamor_screen_private *glamor_priv;
+     /* Source-only pictures should always work */
+     if (!picture->pDrawable)
+         return TRUE;
+-    storage_format = format_for_depth(picture->pDrawable->depth);
++    glamor_priv = glamor_get_screen_private(picture->pDrawable->pScreen);
++    storage_format =
++        glamor_priv->formats[picture->pDrawable->depth].render_format;
+     switch (picture->format) {
+     case PICT_x2r10g10b10:
+@@ -898,7 +901,7 @@ glamor_composite_choose_shader(CARD8 op,
+     }
+     if (dest_pixmap->drawable.bitsPerPixel <= 8 &&
+-        glamor_priv->one_channel_format == GL_RED) {
++        glamor_priv->formats[8].format == GL_RED) {
+         key.dest_swizzle = SHADER_DEST_SWIZZLE_ALPHA_TO_RED;
+     } else {
+         key.dest_swizzle = SHADER_DEST_SWIZZLE_DEFAULT;
+diff --git a/glamor/glamor_spans.c b/glamor/glamor_spans.c
+index b3c028d67..b5f297d2f 100644
+--- a/glamor/glamor_spans.c
++++ b/glamor/glamor_spans.c
+@@ -187,9 +187,8 @@ glamor_get_spans_gl(DrawablePtr drawable, int wmax,
+     int box_index;
+     int n;
+     char *d;
+-    GLenum type;
+-    GLenum format;
+     int off_x, off_y;
++    const struct glamor_format *f = glamor_format_for_pixmap(pixmap);
+     pixmap_priv = glamor_get_pixmap_private(pixmap);
+     if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
+@@ -197,8 +196,6 @@ glamor_get_spans_gl(DrawablePtr drawable, int wmax,
+     glamor_get_drawable_deltas(drawable, pixmap, &off_x, &off_y);
+-    glamor_format_for_pixmap(pixmap, &format, &type);
+-
+     glamor_make_current(glamor_priv);
+     glamor_pixmap_loop(pixmap_priv, box_index) {
+@@ -234,7 +231,8 @@ glamor_get_spans_gl(DrawablePtr drawable, int wmax,
+             if (y >= box->y2)
+                 continue;
+-            glReadPixels(x1 - box->x1, y - box->y1, x2 - x1, 1, format, type, l);
++            glReadPixels(x1 - box->x1, y - box->y1, x2 - x1, 1,
++                         f->format, f->type, l);
+         }
+     }
+@@ -269,11 +267,10 @@ glamor_set_spans_gl(DrawablePtr drawable, GCPtr gc, char *src,
+     glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+     PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
+     glamor_pixmap_private *pixmap_priv;
++    const struct glamor_format *f = glamor_format_for_pixmap(pixmap);
+     int box_index;
+     int n;
+     char *s;
+-    GLenum type;
+-    GLenum format;
+     int off_x, off_y;
+     pixmap_priv = glamor_get_pixmap_private(pixmap);
+@@ -287,7 +284,6 @@ glamor_set_spans_gl(DrawablePtr drawable, GCPtr gc, char *src,
+         goto bail;
+     glamor_get_drawable_deltas(drawable, pixmap, &off_x, &off_y);
+-    glamor_format_for_pixmap(pixmap, &format, &type);
+     glamor_make_current(glamor_priv);
+@@ -348,7 +344,7 @@ glamor_set_spans_gl(DrawablePtr drawable, GCPtr gc, char *src,
+                 glTexSubImage2D(GL_TEXTURE_2D, 0,
+                                 x1 - box->x1, y1 - box->y1, x2 - x1, 1,
+-                                format, type,
++                                f->format, f->type,
+                                 l);
+             }
+             s += PixmapBytePad(w, drawable->depth);
+diff --git a/glamor/glamor_transfer.c b/glamor/glamor_transfer.c
+index 215752d7b..e706e0fb4 100644
+--- a/glamor/glamor_transfer.c
++++ b/glamor/glamor_transfer.c
+@@ -23,44 +23,6 @@
+ #include "glamor_priv.h"
+ #include "glamor_transfer.h"
+-/* XXX a kludge for now */
+-void
+-glamor_format_for_pixmap(PixmapPtr pixmap, GLenum *format, GLenum *type)
+-{
+-    glamor_pixmap_private       *priv = glamor_get_pixmap_private(pixmap);
+-    switch (pixmap->drawable.depth) {
+-    case 24:
+-    case 32:
+-        *format = GL_BGRA;
+-        *type = GL_UNSIGNED_INT_8_8_8_8_REV;
+-        break;
+-    case 30:
+-        *format = GL_BGRA;
+-        *type = GL_UNSIGNED_INT_2_10_10_10_REV;
+-        break;
+-    case 16:
+-        if (priv->is_cbcr) {
+-          *format = GL_RG;
+-          *type = GL_UNSIGNED_BYTE;
+-        } else {
+-          *format = GL_RGB;
+-          *type = GL_UNSIGNED_SHORT_5_6_5;
+-        }
+-        break;
+-    case 15:
+-        *format = GL_BGRA;
+-        *type = GL_UNSIGNED_SHORT_1_5_5_5_REV;
+-        break;
+-    case 8:
+-        *format = glamor_get_screen_private(pixmap->drawable.pScreen)->one_channel_format;
+-        *type = GL_UNSIGNED_BYTE;
+-        break;
+-    default:
+-        FatalError("Invalid pixmap depth %d\n", pixmap->drawable.depth);
+-        break;
+-    }
+-}
+-
+ /*
+  * Write a region of bits into a pixmap
+  */
+@@ -75,10 +37,7 @@ glamor_upload_boxes(PixmapPtr pixmap, BoxPtr in_boxes, int in_nbox,
+     glamor_pixmap_private       *priv = glamor_get_pixmap_private(pixmap);
+     int                         box_index;
+     int                         bytes_per_pixel = pixmap->drawable.bitsPerPixel >> 3;
+-    GLenum                      type;
+-    GLenum                      format;
+-
+-    glamor_format_for_pixmap(pixmap, &format, &type);
++    const struct glamor_format *f = glamor_format_for_pixmap(pixmap);
+     glamor_make_current(glamor_priv);
+@@ -116,14 +75,14 @@ glamor_upload_boxes(PixmapPtr pixmap, BoxPtr in_boxes, int in_nbox,
+                 glTexSubImage2D(GL_TEXTURE_2D, 0,
+                                 x1 - box->x1, y1 - box->y1,
+                                 x2 - x1, y2 - y1,
+-                                format, type,
++                                f->format, f->type,
+                                 bits + ofs);
+             } else {
+                 for (; y1 < y2; y1++, ofs += byte_stride)
+                     glTexSubImage2D(GL_TEXTURE_2D, 0,
+                                     x1 - box->x1, y1 - box->y1,
+                                     x2 - x1, 1,
+-                                    format, type,
++                                    f->format, f->type,
+                                     bits + ofs);
+             }
+         }
+@@ -178,10 +137,7 @@ glamor_download_boxes(PixmapPtr pixmap, BoxPtr in_boxes, int in_nbox,
+     glamor_pixmap_private *priv = glamor_get_pixmap_private(pixmap);
+     int box_index;
+     int bytes_per_pixel = pixmap->drawable.bitsPerPixel >> 3;
+-    GLenum type;
+-    GLenum format;
+-
+-    glamor_format_for_pixmap(pixmap, &format, &type);
++    const struct glamor_format *f = glamor_format_for_pixmap(pixmap);
+     glamor_make_current(glamor_priv);
+@@ -216,10 +172,10 @@ glamor_download_boxes(PixmapPtr pixmap, BoxPtr in_boxes, int in_nbox,
+             if (glamor_priv->has_pack_subimage ||
+                 x2 - x1 == byte_stride / bytes_per_pixel) {
+-                glReadPixels(x1 - box->x1, y1 - box->y1, x2 - x1, y2 - y1, format, type, bits + ofs);
++                glReadPixels(x1 - box->x1, y1 - box->y1, x2 - x1, y2 - y1, f->format, f->type, bits + ofs);
+             } else {
+                 for (; y1 < y2; y1++, ofs += byte_stride)
+-                    glReadPixels(x1 - box->x1, y1 - box->y1, x2 - x1, 1, format, type, bits + ofs);
++                    glReadPixels(x1 - box->x1, y1 - box->y1, x2 - x1, 1, f->format, f->type, bits + ofs);
+             }
+         }
+     }
+diff --git a/glamor/glamor_transfer.h b/glamor/glamor_transfer.h
+index de8186a70..a6137b3ff 100644
+--- a/glamor/glamor_transfer.h
++++ b/glamor/glamor_transfer.h
+@@ -23,9 +23,6 @@
+ #ifndef _GLAMOR_TRANSFER_H_
+ #define _GLAMOR_TRANSFER_H_
+-void
+-glamor_format_for_pixmap(PixmapPtr pixmap, GLenum *format, GLenum *type);
+-
+ void
+ glamor_upload_boxes(PixmapPtr pixmap, BoxPtr in_boxes, int in_nbox,
+                     int dx_src, int dy_src,
+diff --git a/glamor/glamor_transform.c b/glamor/glamor_transform.c
+index 2d5a634a8..348d00be1 100644
+--- a/glamor/glamor_transform.c
++++ b/glamor/glamor_transform.c
+@@ -121,10 +121,9 @@ glamor_set_color_depth(ScreenPtr      pScreen,
+     glamor_get_rgba_from_pixel(pixel,
+                                &color[0], &color[1], &color[2], &color[3],
+-                               format_for_depth(depth));
++                               glamor_priv->formats[depth].render_format);
+-    if ((depth == 1 || depth == 8) &&
+-        glamor_priv->one_channel_format == GL_RED)
++    if ((depth <= 8) && glamor_priv->formats[8].format == GL_RED)
+       color[0] = color[3];
+     glUniform4fv(uniform, 1, color);
+diff --git a/glamor/glamor_utils.h b/glamor/glamor_utils.h
+index cbb808294..651faf2fe 100644
+--- a/glamor/glamor_utils.h
++++ b/glamor/glamor_utils.h
+@@ -570,65 +570,8 @@
+                                                     && (_w_) <= _glamor_->max_fbo_size  \
+                                                     && (_h_) <= _glamor_->max_fbo_size)
+-/* For 1bpp pixmap, we don't store it as texture. */
+-#define glamor_check_pixmap_fbo_depth(_depth_) (                      \
+-                                              _depth_ == 8            \
+-                                              || _depth_ == 15        \
+-                                              || _depth_ == 16        \
+-                                              || _depth_ == 24        \
+-                                              || _depth_ == 30        \
+-                                              || _depth_ == 32)
+-
+ #define GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)    (pixmap_priv->gl_fbo == GLAMOR_FBO_NORMAL)
+-/**
+- * Borrow from uxa.
+- */
+-static inline CARD32
+-format_for_depth(int depth)
+-{
+-    switch (depth) {
+-    case 1:
+-        return PICT_a1;
+-    case 4:
+-        return PICT_a4;
+-    case 8:
+-        return PICT_a8;
+-    case 15:
+-        return PICT_x1r5g5b5;
+-    case 16:
+-        return PICT_r5g6b5;
+-    default:
+-    case 24:
+-        return PICT_x8r8g8b8;
+-    case 30:
+-        return PICT_x2r10g10b10;
+-    case 32:
+-        return PICT_a8r8g8b8;
+-    }
+-}
+-
+-static inline GLenum
+-gl_iformat_for_pixmap(PixmapPtr pixmap)
+-{
+-    glamor_screen_private *glamor_priv =
+-        glamor_get_screen_private((pixmap)->drawable.pScreen);
+-    glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
+-
+-    if (!glamor_priv->is_gles &&
+-        ((pixmap)->drawable.depth == 1 || (pixmap)->drawable.depth == 8)) {
+-        return glamor_priv->one_channel_format;
+-    } else if (!glamor_priv->is_gles &&
+-               (pixmap)->drawable.depth == 16 && pixmap_priv->is_cbcr) {
+-        return GL_RG;
+-    } else if (!glamor_priv->is_gles &&
+-               (pixmap)->drawable.depth == 30) {
+-        return GL_RGB10_A2;
+-    } else {
+-        return GL_RGBA;
+-    }
+-}
+-
+ #define REVERT_NONE                   0
+ #define REVERT_NORMAL                 1
+ #define REVERT_UPLOADING_A1           3
+-- 
+2.17.1
+
index 34e2ed82377bfe130feebdec76ae0da4bab593e5..be3c3817a0ae54f0a5ac8e869ff51f92952de89f 100644 (file)
@@ -7,6 +7,14 @@ SRC_URI:append:imxgpu = " \
     file://0001-glamor-glamor_egl.c-EGL_NATIVE_PIXMAP_KHR-do-not-req.patch \
     file://0001-prefer-to-use-GLES2-for-glamor-EGL-config.patch \
     file://0001-hw-xwayland-Makefile.am-fix-build-without-glx.patch \
+    file://0001-xfree86-define-FOURCC_NV12-and-XVIMAGE_NV12.patch \
+    file://0002-glamor-add-support-for-GL_RG.patch \
+    file://0003-glamor-add-support-for-NV12-in-Xv.patch \
+    file://0004-glamor-Remove-unused-format_for_pixmap-helper.patch \
+    file://0005-glamor-Stop-trying-to-store-the-pixmap-s-format-in-g.patch \
+    file://0006-glamor-Plumb-the-pixmap-through-fbo-creation-instead.patch \
+    file://0007-glamor-Switch-the-gl_flavor-to-a-boolean-is_gles.patch \
+    file://0008-glamor-Introduce-a-central-place-for-our-pixmap-form.patch \
 "
 
 IMX_OPENGL_PKGCONFIGS_REMOVE        = ""