diff options
author | Keith Whitwell <[email protected]> | 2009-11-27 13:59:00 +0000 |
---|---|---|
committer | Keith Whitwell <[email protected]> | 2009-11-27 13:59:22 +0000 |
commit | 124ae596806f1a77af46f1f0e446d448da6e953a (patch) | |
tree | 1ebb8f691a444b2656e85071e9bc06a7418a1403 /src | |
parent | dc86f4a20b6ffe0340ca178dc303271a8a112bb9 (diff) |
st/xorg: fix composite after texture size changes
Diffstat (limited to 'src')
-rw-r--r-- | src/gallium/state_trackers/xorg/xorg_exa.c | 32 | ||||
-rw-r--r-- | src/gallium/state_trackers/xorg/xorg_renderer.c | 16 |
2 files changed, 38 insertions, 10 deletions
diff --git a/src/gallium/state_trackers/xorg/xorg_exa.c b/src/gallium/state_trackers/xorg/xorg_exa.c index a22f15f64a7..cbada42e0ea 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) @@ -865,9 +887,9 @@ ExaModifyPixmapHeader(PixmapPtr pPixmap, int width, int 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(priv->tex->width[0], width) || + !size_match(priv->tex->height[0], height) || + priv->tex_flags != priv->flags)) { struct pipe_texture *texture = NULL; struct pipe_texture template; @@ -875,7 +897,7 @@ 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 +#if ROUND_UP_TEXTURES template.width[0] = util_next_power_of_two(width); template.height[0] = util_next_power_of_two(height); #else diff --git a/src/gallium/state_trackers/xorg/xorg_renderer.c b/src/gallium/state_trackers/xorg/xorg_renderer.c index 9cb65b0aac9..4f8985a75eb 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 sets us up to just touch 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) { |