xserver: Branch 'master' - 3 commits

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Tue Sep 11 20:01:19 UTC 2018


 glamor/glamor.c            |    2 
 glamor/glamor.h            |    1 
 glamor/glamor_priv.h       |    4 -
 glamor/glamor_transfer.c   |   10 ++
 glamor/glamor_utils.h      |    4 +
 glamor/glamor_xv.c         |  180 ++++++++++++++++++++++++++++++++++++++-------
 hw/xfree86/common/fourcc.h |   20 +++++
 7 files changed, 193 insertions(+), 28 deletions(-)

New commits:
commit f4115bcc8c5f9d30ccfca5d5a7fc27acded02864
Author: Julien Isorce <julien.isorce at gmail.com>
Date:   Tue Sep 11 10:28:33 2018 -0700

    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.
    
    Signed-off-by: Julien Isorce <jisorce at oblong.com>
    Tested-by: Olivier Fourdan <ofourdan at redhat.com>
    Reviewed-by: Alex Deucher <alexander.deucher at amd.com>

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;
 }
 
commit 44f5885686a30776160891e09cd4453afb9d5ade
Author: Julien Isorce <julien.isorce at gmail.com>
Date:   Thu Sep 6 15:38:14 2018 -0700

    glamor: add support for GL_RG
    
    Allow to upload the CbCr plane of an NV12 image into a GL texture.
    
    Signed-off-by: Julien Isorce <jisorce at oblong.com>
    Tested-by: Olivier Fourdan <ofourdan at redhat.com>
    Reviewed-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/glamor/glamor.c b/glamor/glamor.c
index 9bf1707de..f24cc9fd1 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -204,6 +204,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 09e9c895c..8d79597e2 100644
--- a/glamor/glamor.h
+++ b/glamor/glamor.h
@@ -126,6 +126,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 7d9a7d4fb..68cb24865 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -378,6 +378,8 @@ typedef struct glamor_pixmap_private {
      * names.
      */
     glamor_pixmap_fbo **fbo_array;
+
+    Bool is_cbcr;
 } glamor_pixmap_private;
 
 extern DevPrivateKeyRec glamor_pixmap_private_key;
@@ -899,7 +901,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,11 +613,15 @@ 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;
     } else {
commit f98ff253c722da3f5ad747e6813752f9e74c54b5
Author: Julien Isorce <julien.isorce at gmail.com>
Date:   Thu Sep 6 15:38:13 2018 -0700

    xfree86: define FOURCC_NV12 and XVIMAGE_NV12
    
    Useful for glamor.
    
    Signed-off-by: Julien Isorce <jisorce at oblong.com>
    Tested-by: Olivier Fourdan <ofourdan at redhat.com>
    Reviewed-by: Alex Deucher <alexander.deucher at amd.com>

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_ */


More information about the xorg-commit mailing list