Mesa (mesa_7_7_branch): st/xorg: proper fix for compositing after rounding up

Keith Whitwell keithw at kemper.freedesktop.org
Fri Nov 27 15:32:05 UTC 2009


Module: Mesa
Branch: mesa_7_7_branch
Commit: 4236493899b9ccfcc8df3dcf81697776621fa1f8
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=4236493899b9ccfcc8df3dcf81697776621fa1f8

Author: Keith Whitwell <keithw at vmware.com>
Date:   Fri Nov 27 15:28:46 2009 +0000

st/xorg: proper fix for compositing after rounding up

Basically don't round up shared textures.  This fixes compiz,
but I'm afraid that rounding up texture sizes here in the driver
is doomed, as it will inevitably break texture wrap modes.

---

 src/gallium/state_trackers/xorg/xorg_composite.c |    7 ++-
 src/gallium/state_trackers/xorg/xorg_exa.c       |   49 +++++++++++++++++-----
 src/gallium/state_trackers/xorg/xorg_exa.h       |    2 +
 src/gallium/state_trackers/xorg/xorg_renderer.c  |   20 ++++++---
 src/gallium/state_trackers/xorg/xorg_renderer.h  |    4 +-
 src/gallium/state_trackers/xorg/xorg_xv.c        |    4 +-
 6 files changed, 65 insertions(+), 21 deletions(-)

diff --git a/src/gallium/state_trackers/xorg/xorg_composite.c b/src/gallium/state_trackers/xorg/xorg_composite.c
index bdc1d9f..a5975aa 100644
--- a/src/gallium/state_trackers/xorg/xorg_composite.c
+++ b/src/gallium/state_trackers/xorg/xorg_composite.c
@@ -474,7 +474,9 @@ boolean xorg_composite_bind_state(struct exa_context *exa,
 {
    struct pipe_surface *dst_surf = xorg_gpu_surface(exa->scrn, pDst);
 
-   renderer_bind_destination(exa->renderer, dst_surf);
+   renderer_bind_destination(exa->renderer, dst_surf,
+                             pDst->width,
+                             pDst->height);
 
    bind_blend_state(exa, op, pSrcPicture, pMaskPicture, pDstPicture);
    bind_shaders(exa, op, pSrcPicture, pMaskPicture, pDstPicture, pSrc, pMask);
@@ -545,7 +547,8 @@ boolean xorg_solid_bind_state(struct exa_context *exa,
    vs_traits = VS_SOLID_FILL;
    fs_traits = FS_SOLID_FILL;
 
-   renderer_bind_destination(exa->renderer, dst_surf);
+   renderer_bind_destination(exa->renderer, dst_surf, 
+                             pixmap->width, pixmap->height);
    bind_blend_state(exa, PictOpSrc, NULL, NULL, NULL);
    cso_set_samplers(exa->renderer->cso, 0, NULL);
    cso_set_sampler_textures(exa->renderer->cso, 0, NULL);
diff --git a/src/gallium/state_trackers/xorg/xorg_exa.c b/src/gallium/state_trackers/xorg/xorg_exa.c
index a22f15f..32485ad 100644
--- a/src/gallium/state_trackers/xorg/xorg_exa.c
+++ b/src/gallium/state_trackers/xorg/xorg_exa.c
@@ -48,6 +48,7 @@
 #include "util/u_debug.h"
 
 #define DEBUG_PRINT 0
+#define ROUND_UP_TEXTURES 1
 
 /*
  * Helper functions
@@ -273,13 +274,18 @@ ExaPrepareAccess(PixmapPtr pPix, int index)
 	    PIPE_REFERENCED_FOR_WRITE)
 	    exa->pipe->flush(exa->pipe, 0, NULL);
 
+        assert(pPix->drawable.width <= priv->tex->width[0]);
+        assert(pPix->drawable.height <= priv->tex->height[0]);
+
 	priv->map_transfer =
 	    exa->scrn->get_tex_transfer(exa->scrn, priv->tex, 0, 0, 0,
 #ifdef EXA_MIXED_PIXMAPS
 					PIPE_TRANSFER_MAP_DIRECTLY |
 #endif
 					PIPE_TRANSFER_READ_WRITE,
-					0, 0, priv->tex->width[0], priv->tex->height[0]);
+					0, 0, 
+                                        pPix->drawable.width,
+                                        pPix->drawable.height );
 	if (!priv->map_transfer)
 #ifdef EXA_MIXED_PIXMAPS
 	    return FALSE;
@@ -820,6 +826,22 @@ xorg_exa_get_pixmap_handle(PixmapPtr pPixmap, unsigned *stride_out)
 }
 
 static Bool
+size_match( int width, int tex_width )
+{
+#if ROUND_UP_TEXTURES
+   if (width > tex_width)
+      return FALSE;
+
+   if (width * 2 < tex_width)
+      return FALSE;
+
+   return TRUE;
+#else
+   return width == tex_width;
+#endif
+}
+
+static Bool
 ExaModifyPixmapHeader(PixmapPtr pPixmap, int width, int height,
 		      int depth, int bitsPerPixel, int devKind,
 		      pointer pPixData)
@@ -862,12 +884,15 @@ ExaModifyPixmapHeader(PixmapPtr pPixmap, int width, int height,
     miModifyPixmapHeader(pPixmap, width, height, depth,
 			     bitsPerPixel, devKind, NULL);
 
+    priv->width = width;
+    priv->height = height;
+
     /* Deal with screen resize */
     if ((exa->accel || priv->flags) &&
         (!priv->tex ||
-         (priv->tex->width[0] != width ||
-          priv->tex->height[0] != height ||
-          priv->tex_flags != priv->flags))) {
+         !size_match(width, priv->tex->width[0]) ||
+         !size_match(height, priv->tex->height[0]) ||
+         priv->tex_flags != priv->flags)) {
 	struct pipe_texture *texture = NULL;
 	struct pipe_texture template;
 
@@ -875,13 +900,15 @@ ExaModifyPixmapHeader(PixmapPtr pPixmap, int width, int height,
 	template.target = PIPE_TEXTURE_2D;
 	exa_get_pipe_format(depth, &template.format, &bitsPerPixel, &priv->picture_format);
 	pf_get_block(template.format, &template.block);
-#if 1
-	template.width[0] = util_next_power_of_two(width);
-	template.height[0] = util_next_power_of_two(height);
-#else
-	template.width[0] = width;
-	template.height[0] = height;
-#endif
+        if (ROUND_UP_TEXTURES && priv->flags == 0) {
+           template.width[0] = util_next_power_of_two(width);
+           template.height[0] = util_next_power_of_two(height);
+        }
+        else {
+           template.width[0] = width;
+           template.height[0] = height;
+        }
+
 	template.depth[0] = 1;
 	template.last_level = 0;
 	template.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET | priv->flags;
diff --git a/src/gallium/state_trackers/xorg/xorg_exa.h b/src/gallium/state_trackers/xorg/xorg_exa.h
index 0c29187..f2cefe2 100644
--- a/src/gallium/state_trackers/xorg/xorg_exa.h
+++ b/src/gallium/state_trackers/xorg/xorg_exa.h
@@ -49,6 +49,8 @@ struct exa_context
 
 struct exa_pixmap_priv
 {
+   int width, height;
+
    int flags;
    int tex_flags;
 
diff --git a/src/gallium/state_trackers/xorg/xorg_renderer.c b/src/gallium/state_trackers/xorg/xorg_renderer.c
index 9cb65b0..cbb84a8 100644
--- a/src/gallium/state_trackers/xorg/xorg_renderer.c
+++ b/src/gallium/state_trackers/xorg/xorg_renderer.c
@@ -313,21 +313,25 @@ setup_vertex_data_yuv(struct xorg_renderer *r,
  * these concepts are linked.
  */
 void renderer_bind_destination(struct xorg_renderer *r,
-                               struct pipe_surface *surface )
+                               struct pipe_surface *surface,
+                               int width,
+                               int height )
 {
 
    struct pipe_framebuffer_state fb;
    struct pipe_viewport_state viewport;
-   int width = surface->width;
-   int height = surface->height;
 
+   /* Framebuffer uses actual surface width/height
+    */
    memset(&fb, 0, sizeof fb);
-   fb.width  = width;
-   fb.height = height;
+   fb.width  = surface->width;
+   fb.height = surface->height;
    fb.nr_cbufs = 1;
    fb.cbufs[0] = surface;
    fb.zsbuf = 0;
 
+   /* Viewport just touches the bit we're interested in:
+    */
    viewport.scale[0] =  width / 2.f;
    viewport.scale[1] =  height / 2.f;
    viewport.scale[2] =  1.0;
@@ -337,6 +341,8 @@ void renderer_bind_destination(struct xorg_renderer *r,
    viewport.translate[2] = 0.0;
    viewport.translate[3] = 0.0;
 
+   /* Constant buffer set up to match viewport dimensions:
+    */
    if (r->fb_width != width ||
        r->fb_height != height) 
    {
@@ -460,7 +466,9 @@ void renderer_copy_prepare(struct xorg_renderer *r,
       cso_single_sampler_done(r->cso);
    }
 
-   renderer_bind_destination(r, dst_surface);
+   renderer_bind_destination(r, dst_surface, 
+                             dst_surface->width,
+                             dst_surface->height);
 
    /* texture */
    cso_set_sampler_textures(r->cso, 1, &src_texture);
diff --git a/src/gallium/state_trackers/xorg/xorg_renderer.h b/src/gallium/state_trackers/xorg/xorg_renderer.h
index ba844bf..5272cde 100644
--- a/src/gallium/state_trackers/xorg/xorg_renderer.h
+++ b/src/gallium/state_trackers/xorg/xorg_renderer.h
@@ -38,7 +38,9 @@ struct xorg_renderer *renderer_create(struct pipe_context *pipe);
 void renderer_destroy(struct xorg_renderer *renderer);
 
 void renderer_bind_destination(struct xorg_renderer *r,
-                               struct pipe_surface *surface );
+                               struct pipe_surface *surface,
+                               int width,
+                               int height );
 
 void renderer_bind_framebuffer(struct xorg_renderer *r,
                                struct exa_pixmap_priv *priv);
diff --git a/src/gallium/state_trackers/xorg/xorg_xv.c b/src/gallium/state_trackers/xorg/xorg_xv.c
index 0b2556b..b3315dc 100644
--- a/src/gallium/state_trackers/xorg/xorg_xv.c
+++ b/src/gallium/state_trackers/xorg/xorg_xv.c
@@ -451,7 +451,9 @@ display_video(ScrnInfoPtr pScrn, struct xorg_xv_port_priv *pPriv, int id,
    pbox = REGION_RECTS(dstRegion);
    nbox = REGION_NUM_RECTS(dstRegion);
 
-   renderer_bind_destination(pPriv->r, dst_surf);
+   renderer_bind_destination(pPriv->r, dst_surf, 
+                             dst_surf->width, dst_surf->height);
+
    bind_blend_state(pPriv);
    bind_shaders(pPriv);
    bind_samplers(pPriv);




More information about the mesa-commit mailing list