diff options
Diffstat (limited to 'src/gallium')
-rw-r--r-- | src/gallium/state_trackers/xorg/xorg_composite.c | 7 | ||||
-rw-r--r-- | src/gallium/state_trackers/xorg/xorg_exa.c | 49 | ||||
-rw-r--r-- | src/gallium/state_trackers/xorg/xorg_exa.h | 2 | ||||
-rw-r--r-- | src/gallium/state_trackers/xorg/xorg_renderer.c | 20 | ||||
-rw-r--r-- | src/gallium/state_trackers/xorg/xorg_renderer.h | 4 | ||||
-rw-r--r-- | 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 bdc1d9f5da3..a5975aad515 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 a22f15f64a7..32485add94e 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 0c29187486b..f2cefe23b99 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 9cb65b0aac9..cbb84a8c0da 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 ba844bf06e4..5272cde2b3f 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 0b2556b98ed..b3315dccad8 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); |