st/xorg: proper fix for compositing after rounding up
authorKeith Whitwell <keithw@vmware.com>
Fri, 27 Nov 2009 15:28:46 +0000 (15:28 +0000)
committerKeith Whitwell <keithw@vmware.com>
Fri, 27 Nov 2009 15:30:18 +0000 (15:30 +0000)
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
src/gallium/state_trackers/xorg/xorg_exa.c
src/gallium/state_trackers/xorg/xorg_exa.h
src/gallium/state_trackers/xorg/xorg_renderer.c
src/gallium/state_trackers/xorg/xorg_renderer.h
src/gallium/state_trackers/xorg/xorg_xv.c

index bdc1d9f5da34508d48c433ea97c8fcf165358202..a5975aad51501090547808b884a6fa0dcd27eea5 100644 (file)
@@ -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);
index a22f15f64a7b05e4cac0c3e058faa9143590dbc3..32485add94e4e6dd0eaf419a60fa9912e67e3b0a 100644 (file)
@@ -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;
@@ -819,6 +825,22 @@ xorg_exa_get_pixmap_handle(PixmapPtr pPixmap, unsigned *stride_out)
     return handle;
 }
 
+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,
@@ -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;
index 0c29187486b653a8cbfb60f4bd429bf5a2765c45..f2cefe23b99df79aafe6728d124bf6ffc2a0b167 100644 (file)
@@ -49,6 +49,8 @@ struct exa_context
 
 struct exa_pixmap_priv
 {
+   int width, height;
+
    int flags;
    int tex_flags;
 
index 9cb65b0aac9cf2a80ef69ebb7c902384367274b2..cbb84a8c0da6e844d28b861c5152cd63e25590c7 100644 (file)
@@ -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);
index ba844bf06e4a6e397cf89a524fed65fbc37e85d9..5272cde2b3f956d341d415be67fddd8f4a0c0044 100644 (file)
@@ -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);
index 0b2556b98ed7d465470897a5cce7125369ad2dc6..b3315dccad8c43c23708dff85141dae53aaf6914 100644 (file)
@@ -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);