summaryrefslogtreecommitdiff
path: root/src/gallium/state_trackers/xorg/xorg_exa.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/state_trackers/xorg/xorg_exa.c')
-rw-r--r--src/gallium/state_trackers/xorg/xorg_exa.c533
1 files changed, 374 insertions, 159 deletions
diff --git a/src/gallium/state_trackers/xorg/xorg_exa.c b/src/gallium/state_trackers/xorg/xorg_exa.c
index bd97baae2b..d9432babf1 100644
--- a/src/gallium/state_trackers/xorg/xorg_exa.c
+++ b/src/gallium/state_trackers/xorg/xorg_exa.c
@@ -43,38 +43,104 @@
#include "pipe/p_state.h"
#include "pipe/p_inlines.h"
+#include "util/u_format.h"
#include "util/u_rect.h"
+#include "util/u_math.h"
+#include "util/u_debug.h"
#define DEBUG_PRINT 0
-#define DEBUG_SOLID 0
-#define ACCEL_ENABLED TRUE
+#define ROUND_UP_TEXTURES 1
/*
* Helper functions
*/
+struct render_format_str {
+ int format;
+ const char *name;
+};
+static const struct render_format_str formats_info[] =
+{
+ {PICT_a8r8g8b8, "PICT_a8r8g8b8"},
+ {PICT_x8r8g8b8, "PICT_x8r8g8b8"},
+ {PICT_a8b8g8r8, "PICT_a8b8g8r8"},
+ {PICT_x8b8g8r8, "PICT_x8b8g8r8"},
+#ifdef PICT_TYPE_BGRA
+ {PICT_b8g8r8a8, "PICT_b8g8r8a8"},
+ {PICT_b8g8r8x8, "PICT_b8g8r8x8"},
+ {PICT_a2r10g10b10, "PICT_a2r10g10b10"},
+ {PICT_x2r10g10b10, "PICT_x2r10g10b10"},
+ {PICT_a2b10g10r10, "PICT_a2b10g10r10"},
+ {PICT_x2b10g10r10, "PICT_x2b10g10r10"},
+#endif
+ {PICT_r8g8b8, "PICT_r8g8b8"},
+ {PICT_b8g8r8, "PICT_b8g8r8"},
+ {PICT_r5g6b5, "PICT_r5g6b5"},
+ {PICT_b5g6r5, "PICT_b5g6r5"},
+ {PICT_a1r5g5b5, "PICT_a1r5g5b5"},
+ {PICT_x1r5g5b5, "PICT_x1r5g5b5"},
+ {PICT_a1b5g5r5, "PICT_a1b5g5r5"},
+ {PICT_x1b5g5r5, "PICT_x1b5g5r5"},
+ {PICT_a4r4g4b4, "PICT_a4r4g4b4"},
+ {PICT_x4r4g4b4, "PICT_x4r4g4b4"},
+ {PICT_a4b4g4r4, "PICT_a4b4g4r4"},
+ {PICT_x4b4g4r4, "PICT_x4b4g4r4"},
+ {PICT_a8, "PICT_a8"},
+ {PICT_r3g3b2, "PICT_r3g3b2"},
+ {PICT_b2g3r3, "PICT_b2g3r3"},
+ {PICT_a2r2g2b2, "PICT_a2r2g2b2"},
+ {PICT_a2b2g2r2, "PICT_a2b2g2r2"},
+ {PICT_c8, "PICT_c8"},
+ {PICT_g8, "PICT_g8"},
+ {PICT_x4a4, "PICT_x4a4"},
+ {PICT_x4c4, "PICT_x4c4"},
+ {PICT_x4g4, "PICT_x4g4"},
+ {PICT_a4, "PICT_a4"},
+ {PICT_r1g2b1, "PICT_r1g2b1"},
+ {PICT_b1g2r1, "PICT_b1g2r1"},
+ {PICT_a1r1g1b1, "PICT_a1r1g1b1"},
+ {PICT_a1b1g1r1, "PICT_a1b1g1r1"},
+ {PICT_c4, "PICT_c4"},
+ {PICT_g4, "PICT_g4"},
+ {PICT_a1, "PICT_a1"},
+ {PICT_g1, "PICT_g1"}
+};
+static const char *render_format_name(int format)
+{
+ int i = 0;
+ for (i = 0; i < sizeof(formats_info)/sizeof(formats_info[0]); ++i) {
+ if (formats_info[i].format == format)
+ return formats_info[i].name;
+ }
+ return NULL;
+}
static void
-exa_get_pipe_format(int depth, enum pipe_format *format, int *bbp)
+exa_get_pipe_format(int depth, enum pipe_format *format, int *bbp, int *picture_format)
{
switch (depth) {
case 32:
*format = PIPE_FORMAT_A8R8G8B8_UNORM;
+ *picture_format = PICT_a8r8g8b8;
assert(*bbp == 32);
break;
case 24:
*format = PIPE_FORMAT_X8R8G8B8_UNORM;
+ *picture_format = PICT_x8r8g8b8;
assert(*bbp == 32);
break;
case 16:
*format = PIPE_FORMAT_R5G6B5_UNORM;
+ *picture_format = PICT_r5g6b5;
assert(*bbp == 16);
break;
case 15:
*format = PIPE_FORMAT_A1R5G5B5_UNORM;
+ *picture_format = PICT_x1r5g5b5;
assert(*bbp == 16);
break;
case 8:
*format = PIPE_FORMAT_L8_UNORM;
+ *picture_format = PICT_a8;
assert(*bbp == 8);
break;
case 4:
@@ -87,16 +153,6 @@ exa_get_pipe_format(int depth, enum pipe_format *format, int *bbp)
}
}
-static void
-xorg_exa_common_done(struct exa_context *exa)
-{
- exa->copy.src = NULL;
- exa->copy.dst = NULL;
- exa->transform.has_src = FALSE;
- exa->transform.has_mask = FALSE;
- exa->has_solid_color = FALSE;
- exa->num_bound_samplers = 0;
-}
/*
* Static exported EXA functions
@@ -105,15 +161,7 @@ xorg_exa_common_done(struct exa_context *exa)
static void
ExaWaitMarker(ScreenPtr pScreen, int marker)
{
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- modesettingPtr ms = modesettingPTR(pScrn);
- struct exa_context *exa = ms->exa;
-
-#if 0
- xorg_exa_flush(exa, PIPE_FLUSH_RENDER_CACHE, NULL);
-#else
- xorg_exa_finish(exa);
-#endif
+ /* Nothing to do, handled in the PrepareAccess hook */
}
static int
@@ -122,6 +170,11 @@ ExaMarkSync(ScreenPtr pScreen)
return 1;
}
+
+/***********************************************************************
+ * Screen upload/download
+ */
+
static Bool
ExaDownloadFromScreen(PixmapPtr pPix, int x, int y, int w, int h, char *dst,
int dst_pitch)
@@ -150,7 +203,7 @@ ExaDownloadFromScreen(PixmapPtr pPix, int x, int y, int w, int h, char *dst,
x, y, w, h, dst_pitch);
#endif
- util_copy_rect((unsigned char*)dst, &priv->tex->block, dst_pitch, 0, 0,
+ util_copy_rect((unsigned char*)dst, priv->tex->format, dst_pitch, 0, 0,
w, h, exa->scrn->transfer_map(exa->scrn, transfer),
transfer->stride, 0, 0);
@@ -174,6 +227,11 @@ ExaUploadToScreen(PixmapPtr pPix, int x, int y, int w, int h, char *src,
if (!priv || !priv->tex)
return FALSE;
+ /* make sure that any pending operations are flushed to hardware */
+ if (exa->pipe->is_texture_referenced(exa->pipe, priv->tex, 0, 0) &
+ (PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE))
+ xorg_exa_flush(exa, 0, NULL);
+
transfer = exa->scrn->get_tex_transfer(exa->scrn, priv->tex, 0, 0, 0,
PIPE_TRANSFER_WRITE, x, y, w, h);
if (!transfer)
@@ -185,7 +243,7 @@ ExaUploadToScreen(PixmapPtr pPix, int x, int y, int w, int h, char *src,
#endif
util_copy_rect(exa->scrn->transfer_map(exa->scrn, transfer),
- &priv->tex->block, transfer->stride, 0, 0, w, h,
+ priv->tex->format, transfer->stride, 0, 0, w, h,
(unsigned char*)src, src_pitch, 0, 0);
exa->scrn->transfer_unmap(exa->scrn, transfer);
@@ -217,13 +275,18 @@ ExaPrepareAccess(PixmapPtr pPix, int index)
PIPE_REFERENCED_FOR_WRITE)
exa->pipe->flush(exa->pipe, 0, NULL);
+ assert(pPix->drawable.width <= priv->tex->width0);
+ assert(pPix->drawable.height <= priv->tex->height0);
+
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;
@@ -266,29 +329,9 @@ ExaFinishAccess(PixmapPtr pPix, int index)
}
}
-static void
-ExaDone(PixmapPtr pPixmap)
-{
- ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
- modesettingPtr ms = modesettingPTR(pScrn);
- struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPixmap);
- struct exa_context *exa = ms->exa;
-
- if (!priv)
- return;
-
- xorg_exa_common_done(exa);
-}
-
-static void
-ExaDoneComposite(PixmapPtr pPixmap)
-{
- ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
- modesettingPtr ms = modesettingPTR(pScrn);
- struct exa_context *exa = ms->exa;
-
- xorg_exa_common_done(exa);
-}
+/***********************************************************************
+ * Solid Fills
+ */
static Bool
ExaPrepareSolid(PixmapPtr pPixmap, int alu, Pixel planeMask, Pixel fg)
@@ -301,6 +344,9 @@ ExaPrepareSolid(PixmapPtr pPixmap, int alu, Pixel planeMask, Pixel fg)
#if DEBUG_PRINT
debug_printf("ExaPrepareSolid(0x%x)\n", fg);
#endif
+ if (!exa->accel)
+ return FALSE;
+
if (!exa->pipe)
XORG_FALLBACK("accle not enabled");
@@ -319,11 +365,7 @@ ExaPrepareSolid(PixmapPtr pPixmap, int alu, Pixel planeMask, Pixel fg)
XORG_FALLBACK("format %s", pf_name(priv->tex->format));
}
-#if DEBUG_SOLID
- fg = 0xffff0000;
-#endif
-
- return ACCEL_ENABLED && xorg_solid_bind_state(exa, priv, fg);
+ return xorg_solid_bind_state(exa, priv, fg);
}
static void
@@ -338,48 +380,34 @@ ExaSolid(PixmapPtr pPixmap, int x0, int y0, int x1, int y1)
debug_printf("\tExaSolid(%d, %d, %d, %d)\n", x0, y0, x1, y1);
#endif
-#if 0
if (x0 == 0 && y0 == 0 &&
- x1 == priv->tex->width[0] &&
- y1 == priv->tex->height[0]) {
- exa->ctx->clear(exa->pipe, PIPE_CLEAR_COLOR,
- exa->solid_color, 1., 0);
- } else
-#endif
+ x1 == pPixmap->drawable.width && y1 == pPixmap->drawable.height) {
+ exa->pipe->clear(exa->pipe, PIPE_CLEAR_COLOR, exa->solid_color, 0.0, 0);
+ return;
+ }
-#if DEBUG_SOLID
- exa->solid_color[0] = 0.f;
- exa->solid_color[1] = 1.f;
- exa->solid_color[2] = 0.f;
- exa->solid_color[3] = 1.f;
- xorg_solid(exa, priv, 0, 0, 1024, 768);
- exa->solid_color[0] = 1.f;
- exa->solid_color[1] = 0.f;
- exa->solid_color[2] = 0.f;
- exa->solid_color[3] = 1.f;
- xorg_solid(exa, priv, 0, 0, 300, 300);
- xorg_solid(exa, priv, 300, 300, 350, 350);
- xorg_solid(exa, priv, 350, 350, 500, 500);
-
- xorg_solid(exa, priv,
- priv->tex->width[0] - 10,
- priv->tex->height[0] - 10,
- priv->tex->width[0],
- priv->tex->height[0]);
-
- exa->solid_color[0] = 0.f;
- exa->solid_color[1] = 0.f;
- exa->solid_color[2] = 1.f;
- exa->solid_color[3] = 1.f;
-
- exa->has_solid_color = FALSE;
- ExaPrepareCopy(pPixmap, pPixmap, 0, 0, GXcopy, 0xffffffff);
- ExaCopy(pPixmap, 0, 0, 50, 50, 500, 500);
-#else
xorg_solid(exa, priv, x0, y0, x1, y1) ;
-#endif
}
+
+static void
+ExaDoneSolid(PixmapPtr pPixmap)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
+ modesettingPtr ms = modesettingPTR(pScrn);
+ struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPixmap);
+ struct exa_context *exa = ms->exa;
+
+ if (!priv)
+ return;
+
+ xorg_composite_done(exa);
+}
+
+/***********************************************************************
+ * Copy Blits
+ */
+
static Bool
ExaPrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xdir,
int ydir, int alu, Pixel planeMask)
@@ -393,6 +421,10 @@ ExaPrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xdir,
#if DEBUG_PRINT
debug_printf("ExaPrepareCopy\n");
#endif
+
+ if (!exa->accel)
+ return FALSE;
+
if (!exa->pipe)
XORG_FALLBACK("accle not enabled");
@@ -421,7 +453,52 @@ ExaPrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xdir,
exa->copy.src = src_priv;
exa->copy.dst = priv;
- return ACCEL_ENABLED;
+ /* For same-surface copies, the pipe->surface_copy path is clearly
+ * superior, providing it is implemented. In other cases it's not
+ * clear what the better path would be, and eventually we'd
+ * probably want to gather timings and choose dynamically.
+ */
+ if (exa->pipe->surface_copy &&
+ exa->copy.src == exa->copy.dst) {
+
+ exa->copy.use_surface_copy = TRUE;
+
+ exa->copy.src_surface =
+ exa->scrn->get_tex_surface( exa->scrn,
+ exa->copy.src->tex,
+ 0, 0, 0,
+ PIPE_BUFFER_USAGE_GPU_READ);
+
+ exa->copy.dst_surface =
+ exa->scrn->get_tex_surface( exa->scrn,
+ exa->copy.dst->tex,
+ 0, 0, 0,
+ PIPE_BUFFER_USAGE_GPU_WRITE );
+ }
+ else {
+ exa->copy.use_surface_copy = FALSE;
+
+ if (exa->copy.dst == exa->copy.src)
+ exa->copy.src_texture = renderer_clone_texture( exa->renderer,
+ exa->copy.src->tex );
+ else
+ pipe_texture_reference(&exa->copy.src_texture,
+ exa->copy.src->tex);
+
+ exa->copy.dst_surface =
+ exa->scrn->get_tex_surface(exa->scrn,
+ exa->copy.dst->tex,
+ 0, 0, 0,
+ PIPE_BUFFER_USAGE_GPU_WRITE);
+
+
+ renderer_copy_prepare(exa->renderer,
+ exa->copy.dst_surface,
+ exa->copy.src_texture );
+ }
+
+
+ return TRUE;
}
static void
@@ -439,12 +516,113 @@ ExaCopy(PixmapPtr pDstPixmap, int srcX, int srcY, int dstX, int dstY,
#endif
debug_assert(priv == exa->copy.dst);
+ (void) priv;
+
+ if (exa->copy.use_surface_copy) {
+ /* XXX: consider exposing >1 box in surface_copy interface.
+ */
+ exa->pipe->surface_copy( exa->pipe,
+ exa->copy.dst_surface,
+ dstX, dstY,
+ exa->copy.src_surface,
+ srcX, srcY,
+ width, height );
+ }
+ else {
+ renderer_copy_pixmap(exa->renderer,
+ dstX, dstY,
+ srcX, srcY,
+ width, height,
+ exa->copy.src_texture->width0,
+ exa->copy.src_texture->height0);
+ }
+}
+
+static void
+ExaDoneCopy(PixmapPtr pPixmap)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
+ modesettingPtr ms = modesettingPTR(pScrn);
+ struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPixmap);
+ struct exa_context *exa = ms->exa;
- renderer_copy_pixmap(exa->renderer, exa->copy.dst, dstX, dstY,
- exa->copy.src, srcX, srcY,
- width, height);
+ if (!priv)
+ return;
+
+ renderer_draw_flush(exa->renderer);
+
+ exa->copy.src = NULL;
+ exa->copy.dst = NULL;
+ pipe_surface_reference(&exa->copy.src_surface, NULL);
+ pipe_surface_reference(&exa->copy.dst_surface, NULL);
+ pipe_texture_reference(&exa->copy.src_texture, NULL);
}
+
+
+static Bool
+picture_check_formats(struct exa_pixmap_priv *pSrc, PicturePtr pSrcPicture)
+{
+ if (pSrc->picture_format == pSrcPicture->format)
+ return TRUE;
+
+ if (pSrc->picture_format != PICT_a8r8g8b8)
+ return FALSE;
+
+ /* pSrc->picture_format == PICT_a8r8g8b8 */
+ switch (pSrcPicture->format) {
+ case PICT_a8r8g8b8:
+ case PICT_x8r8g8b8:
+ case PICT_a8b8g8r8:
+ case PICT_x8b8g8r8:
+ /* just treat these two as x8... */
+ case PICT_r8g8b8:
+ case PICT_b8g8r8:
+ return TRUE;
+#ifdef PICT_TYPE_BGRA
+ case PICT_b8g8r8a8:
+ case PICT_b8g8r8x8:
+ return FALSE; /* does not support swizzleing the alpha channel yet */
+ case PICT_a2r10g10b10:
+ case PICT_x2r10g10b10:
+ case PICT_a2b10g10r10:
+ case PICT_x2b10g10r10:
+ return FALSE;
+#endif
+ default:
+ return FALSE;
+ }
+ return FALSE;
+}
+
+/***********************************************************************
+ * Composite entrypoints
+ */
+
+static Bool
+ExaCheckComposite(int op,
+ PicturePtr pSrcPicture, PicturePtr pMaskPicture,
+ PicturePtr pDstPicture)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pDstPicture->pDrawable->pScreen->myNum];
+ modesettingPtr ms = modesettingPTR(pScrn);
+ struct exa_context *exa = ms->exa;
+
+#if DEBUG_PRINT
+ debug_printf("ExaCheckComposite(%d, %p, %p, %p) = %d\n",
+ op, pSrcPicture, pMaskPicture, pDstPicture, accelerated);
+#endif
+
+ if (!exa->accel)
+ return FALSE;
+
+ return xorg_composite_accelerated(op,
+ pSrcPicture,
+ pMaskPicture,
+ pDstPicture);
+}
+
+
static Bool
ExaPrepareComposite(int op, PicturePtr pSrcPicture,
PicturePtr pMaskPicture, PicturePtr pDstPicture,
@@ -455,9 +633,16 @@ ExaPrepareComposite(int op, PicturePtr pSrcPicture,
struct exa_context *exa = ms->exa;
struct exa_pixmap_priv *priv;
+ if (!exa->accel)
+ return FALSE;
+
#if DEBUG_PRINT
debug_printf("ExaPrepareComposite(%d, src=0x%p, mask=0x%p, dst=0x%p)\n",
op, pSrcPicture, pMaskPicture, pDstPicture);
+ debug_printf("\tFormats: src(%s), mask(%s), dst(%s)\n",
+ pSrcPicture ? render_format_name(pSrcPicture->format) : "none",
+ pMaskPicture ? render_format_name(pMaskPicture->format) : "none",
+ pDstPicture ? render_format_name(pDstPicture->format) : "none");
#endif
if (!exa->pipe)
XORG_FALLBACK("accle not enabled");
@@ -471,6 +656,11 @@ ExaPrepareComposite(int op, PicturePtr pSrcPicture,
PIPE_TEXTURE_USAGE_RENDER_TARGET, 0))
XORG_FALLBACK("pDst format: %s", pf_name(priv->tex->format));
+ if (priv->picture_format != pDstPicture->format)
+ XORG_FALLBACK("pDst pic_format: %s != %s",
+ render_format_name(priv->picture_format),
+ render_format_name(pDstPicture->format));
+
if (pSrc) {
priv = exaGetPixmapDriverPrivate(pSrc);
if (!priv || !priv->tex)
@@ -480,6 +670,12 @@ ExaPrepareComposite(int op, PicturePtr pSrcPicture,
priv->tex->target,
PIPE_TEXTURE_USAGE_SAMPLER, 0))
XORG_FALLBACK("pSrc format: %s", pf_name(priv->tex->format));
+
+ if (!picture_check_formats(priv, pSrcPicture))
+ XORG_FALLBACK("pSrc pic_format: %s != %s",
+ render_format_name(priv->picture_format),
+ render_format_name(pSrcPicture->format));
+
}
if (pMask) {
@@ -491,10 +687,14 @@ ExaPrepareComposite(int op, PicturePtr pSrcPicture,
priv->tex->target,
PIPE_TEXTURE_USAGE_SAMPLER, 0))
XORG_FALLBACK("pMask format: %s", pf_name(priv->tex->format));
+
+ if (!picture_check_formats(priv, pMaskPicture))
+ XORG_FALLBACK("pMask pic_format: %s != %s",
+ render_format_name(priv->picture_format),
+ render_format_name(pMaskPicture->format));
}
- return ACCEL_ENABLED &&
- xorg_composite_bind_state(exa, op, pSrcPicture, pMaskPicture,
+ return xorg_composite_bind_state(exa, op, pSrcPicture, pMaskPicture,
pDstPicture,
pSrc ? exaGetPixmapDriverPrivate(pSrc) : NULL,
pMask ? exaGetPixmapDriverPrivate(pMask) : NULL,
@@ -521,22 +721,23 @@ ExaComposite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY,
dstX, dstY, width, height);
}
-static Bool
-ExaCheckComposite(int op,
- PicturePtr pSrcPicture, PicturePtr pMaskPicture,
- PicturePtr pDstPicture)
+
+
+static void
+ExaDoneComposite(PixmapPtr pPixmap)
{
- boolean accelerated = xorg_composite_accelerated(op,
- pSrcPicture,
- pMaskPicture,
- pDstPicture);
-#if DEBUG_PRINT
- debug_printf("ExaCheckComposite(%d, %p, %p, %p) = %d\n",
- op, pSrcPicture, pMaskPicture, pDstPicture, accelerated);
-#endif
- return ACCEL_ENABLED && accelerated;
+ ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
+ modesettingPtr ms = modesettingPTR(pScrn);
+ struct exa_context *exa = ms->exa;
+
+ xorg_composite_done(exa);
}
+
+/***********************************************************************
+ * Pixmaps
+ */
+
static void *
ExaCreatePixmap(ScreenPtr pScreen, int size, int align)
{
@@ -610,33 +811,22 @@ xorg_exa_set_shared_usage(PixmapPtr pPixmap)
return 0;
}
-unsigned
-xorg_exa_get_pixmap_handle(PixmapPtr pPixmap, unsigned *stride_out)
-{
- ScreenPtr pScreen = pPixmap->drawable.pScreen;
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- modesettingPtr ms = modesettingPTR(pScrn);
- struct exa_pixmap_priv *priv;
- unsigned handle;
- unsigned stride;
- if (!ms->exa) {
- FatalError("NO MS->EXA\n");
- return 0;
- }
- priv = exaGetPixmapDriverPrivate(pPixmap);
-
- if (!priv) {
- FatalError("NO PIXMAP PRIVATE\n");
- return 0;
- }
+static Bool
+size_match( int width, int tex_width )
+{
+#if ROUND_UP_TEXTURES
+ if (width > tex_width)
+ return FALSE;
- ms->api->local_handle_from_texture(ms->api, ms->screen, priv->tex, &stride, &handle);
- if (stride_out)
- *stride_out = stride;
+ if (width * 2 < tex_width)
+ return FALSE;
- return handle;
+ return TRUE;
+#else
+ return width == tex_width;
+#endif
}
static Bool
@@ -653,6 +843,17 @@ ExaModifyPixmapHeader(PixmapPtr pPixmap, int width, int height,
if (!priv || pPixData)
return FALSE;
+ if (0) {
+ debug_printf("%s pixmap %p sz %dx%dx%d devKind %d\n",
+ __FUNCTION__, pPixmap, width, height, bitsPerPixel, devKind);
+
+ if (priv->tex)
+ debug_printf(" ==> old texture %dx%d\n",
+ priv->tex->width0,
+ priv->tex->height0);
+ }
+
+
if (depth <= 0)
depth = pPixmap->drawable.depth;
@@ -671,21 +872,31 @@ 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 (!priv->tex ||
- (priv->tex->width[0] != width ||
- priv->tex->height[0] != height ||
+ if ((exa->accel || priv->flags) &&
+ (!priv->tex ||
+ !size_match(width, priv->tex->width0) ||
+ !size_match(height, priv->tex->height0) ||
priv->tex_flags != priv->flags)) {
struct pipe_texture *texture = NULL;
struct pipe_texture template;
memset(&template, 0, sizeof(template));
template.target = PIPE_TEXTURE_2D;
- exa_get_pipe_format(depth, &template.format, &bitsPerPixel);
- pf_get_block(template.format, &template.block);
- template.width[0] = width;
- template.height[0] = height;
- template.depth[0] = 1;
+ exa_get_pipe_format(depth, &template.format, &bitsPerPixel, &priv->picture_format);
+ if (ROUND_UP_TEXTURES && priv->flags == 0) {
+ template.width0 = util_next_power_of_two(width);
+ template.height0 = util_next_power_of_two(height);
+ }
+ else {
+ template.width0 = width;
+ template.height0 = height;
+ }
+
+ template.depth0 = 1;
template.last_level = 0;
template.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET | priv->flags;
priv->tex_flags = priv->flags;
@@ -698,15 +909,15 @@ ExaModifyPixmapHeader(PixmapPtr pPixmap, int width, int height,
dst_surf = exa->scrn->get_tex_surface(
exa->scrn, texture, 0, 0, 0, PIPE_BUFFER_USAGE_GPU_WRITE);
src_surf = xorg_gpu_surface(exa->pipe->screen, priv);
- if (exa->pipe->surface_copy) {
- exa->pipe->surface_copy(exa->pipe, dst_surf, 0, 0, src_surf,
- 0, 0, min(width, texture->width[0]),
- min(height, texture->height[0]));
- } else {
- util_surface_copy(exa->pipe, FALSE, dst_surf, 0, 0, src_surf,
- 0, 0, min(width, texture->width[0]),
- min(height, texture->height[0]));
- }
+ if (exa->pipe->surface_copy) {
+ exa->pipe->surface_copy(exa->pipe, dst_surf, 0, 0, src_surf,
+ 0, 0, min(width, texture->width0),
+ min(height, texture->height0));
+ } else {
+ util_surface_copy(exa->pipe, FALSE, dst_surf, 0, 0, src_surf,
+ 0, 0, min(width, texture->width0),
+ min(height, texture->height0));
+ }
exa->scrn->tex_surface_destroy(dst_surf);
exa->scrn->tex_surface_destroy(src_surf);
}
@@ -738,8 +949,8 @@ xorg_exa_set_texture(PixmapPtr pPixmap, struct pipe_texture *tex)
if (!priv)
return FALSE;
- if (pPixmap->drawable.width != tex->width[0] ||
- pPixmap->drawable.height != tex->height[0])
+ if (pPixmap->drawable.width != tex->width0 ||
+ pPixmap->drawable.height != tex->height0)
return FALSE;
pipe_texture_reference(&priv->tex, tex);
@@ -756,14 +967,14 @@ xorg_exa_create_root_texture(ScrnInfoPtr pScrn,
modesettingPtr ms = modesettingPTR(pScrn);
struct exa_context *exa = ms->exa;
struct pipe_texture template;
+ int dummy;
memset(&template, 0, sizeof(template));
template.target = PIPE_TEXTURE_2D;
- exa_get_pipe_format(depth, &template.format, &bitsPerPixel);
- pf_get_block(template.format, &template.block);
- template.width[0] = width;
- template.height[0] = height;
- template.depth[0] = 1;
+ exa_get_pipe_format(depth, &template.format, &bitsPerPixel, &dummy);
+ template.width0 = width;
+ template.height0 = height;
+ template.depth0 = 1;
template.last_level = 0;
template.tex_usage |= PIPE_TEXTURE_USAGE_RENDER_TARGET;
template.tex_usage |= PIPE_TEXTURE_USAGE_PRIMARY;
@@ -782,6 +993,9 @@ xorg_exa_close(ScrnInfoPtr pScrn)
if (exa->pipe)
exa->pipe->destroy(exa->pipe);
+ exa->pipe = NULL;
+ /* Since this was shared be proper with the pointer */
+ ms->ctx = NULL;
exaDriverFini(pScrn->pScreen);
xfree(exa);
@@ -789,7 +1003,7 @@ xorg_exa_close(ScrnInfoPtr pScrn)
}
void *
-xorg_exa_init(ScrnInfoPtr pScrn)
+xorg_exa_init(ScrnInfoPtr pScrn, Bool accel)
{
modesettingPtr ms = modesettingPTR(pScrn);
struct exa_context *exa;
@@ -827,10 +1041,10 @@ xorg_exa_init(ScrnInfoPtr pScrn)
pExa->MarkSync = ExaMarkSync;
pExa->PrepareSolid = ExaPrepareSolid;
pExa->Solid = ExaSolid;
- pExa->DoneSolid = ExaDone;
+ pExa->DoneSolid = ExaDoneSolid;
pExa->PrepareCopy = ExaPrepareCopy;
pExa->Copy = ExaCopy;
- pExa->DoneCopy = ExaDone;
+ pExa->DoneCopy = ExaDoneCopy;
pExa->CheckComposite = ExaCheckComposite;
pExa->PrepareComposite = ExaPrepareComposite;
pExa->Composite = ExaComposite;
@@ -854,6 +1068,7 @@ xorg_exa_init(ScrnInfoPtr pScrn)
ms->ctx = exa->pipe;
exa->renderer = renderer_create(exa->pipe);
+ exa->accel = accel;
return (void *)exa;