From 4236493899b9ccfcc8df3dcf81697776621fa1f8 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 27 Nov 2009 15:28:46 +0000 Subject: 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 bdc1d9f5da..a5975aad51 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 a22f15f64a..32485add94 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; @@ -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; diff --git a/src/gallium/state_trackers/xorg/xorg_exa.h b/src/gallium/state_trackers/xorg/xorg_exa.h index 0c29187486..f2cefe23b9 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 9cb65b0aac..cbb84a8c0d 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 ba844bf06e..5272cde2b3 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 0b2556b98e..b3315dccad 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); -- cgit v1.2.3