summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/gallium/state_trackers/xorg/xorg_composite.c7
-rw-r--r--src/gallium/state_trackers/xorg/xorg_exa.c49
-rw-r--r--src/gallium/state_trackers/xorg/xorg_exa.h2
-rw-r--r--src/gallium/state_trackers/xorg/xorg_renderer.c20
-rw-r--r--src/gallium/state_trackers/xorg/xorg_renderer.h4
-rw-r--r--src/gallium/state_trackers/xorg/xorg_xv.c4
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;
@@ -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 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);