X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fstate_trackers%2Fxorg%2Fxorg_exa.c;h=3e764f8a7f5ed620c613d71f1ddf0c7c4e4ff6b0;hb=3310acdf4756feb82bf043e7663b6dd8d6e3f7c9;hp=bd97baae2b636aa619fe29252c09580e9a307318;hpb=7d56caabe45e91a67096804c7e341d04d01db7aa;p=mesa.git diff --git a/src/gallium/state_trackers/xorg/xorg_exa.c b/src/gallium/state_trackers/xorg/xorg_exa.c index bd97baae2b6..3e764f8a7f5 100644 --- a/src/gallium/state_trackers/xorg/xorg_exa.c +++ b/src/gallium/state_trackers/xorg/xorg_exa.c @@ -41,45 +41,127 @@ #include "pipe/p_format.h" #include "pipe/p_context.h" #include "pipe/p_state.h" -#include "pipe/p_inlines.h" #include "util/u_rect.h" +#include "util/u_math.h" +#include "util/u_debug.h" +#include "util/u_format.h" +#include "util/u_box.h" +#include "util/u_surface.h" -#define DEBUG_PRINT 0 -#define DEBUG_SOLID 0 -#define ACCEL_ENABLED TRUE +#define ROUND_UP_TEXTURES 1 + +static INLINE void +exa_debug_printf(const char *format, ...) _util_printf_format(1,2); + +static INLINE void +exa_debug_printf(const char *format, ...) +{ +#if 0 + va_list ap; + va_start(ap, format); + _debug_vprintf(format, ap); + va_end(ap); +#else + (void) format; /* silence warning */ +#endif +} /* * 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; + *format = PIPE_FORMAT_B8G8R8A8_UNORM; + *picture_format = PICT_a8r8g8b8; assert(*bbp == 32); break; case 24: - *format = PIPE_FORMAT_X8R8G8B8_UNORM; + *format = PIPE_FORMAT_B8G8R8X8_UNORM; + *picture_format = PICT_x8r8g8b8; assert(*bbp == 32); break; case 16: - *format = PIPE_FORMAT_R5G6B5_UNORM; + *format = PIPE_FORMAT_B5G6R5_UNORM; + *picture_format = PICT_r5g6b5; assert(*bbp == 16); break; case 15: - *format = PIPE_FORMAT_A1R5G5B5_UNORM; + *format = PIPE_FORMAT_B5G5R5A1_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: case 1: - *format = PIPE_FORMAT_A8R8G8B8_UNORM; /* bad bad bad */ + *format = PIPE_FORMAT_B8G8R8A8_UNORM; /* bad bad bad */ break; default: assert(0); @@ -87,16 +169,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 +177,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,40 +186,38 @@ 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) { ScreenPtr pScreen = pPix->drawable.pScreen; - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); modesettingPtr ms = modesettingPTR(pScrn); struct exa_context *exa = ms->exa; struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPix); struct pipe_transfer *transfer; + void *map; if (!priv || !priv->tex) return FALSE; - if (exa->pipe->is_texture_referenced(exa->pipe, priv->tex, 0, 0) & - PIPE_REFERENCED_FOR_WRITE) - exa->pipe->flush(exa->pipe, 0, NULL); - - transfer = exa->scrn->get_tex_transfer(exa->scrn, priv->tex, 0, 0, 0, - PIPE_TRANSFER_READ, x, y, w, h); - if (!transfer) + map = pipe_transfer_map(exa->pipe, priv->tex, 0, 0, + PIPE_TRANSFER_READ, x, y, w, h, &transfer); + if (!map) return FALSE; -#if DEBUG_PRINT - debug_printf("------ ExaDownloadFromScreen(%d, %d, %d, %d, %d)\n", + exa_debug_printf("------ ExaDownloadFromScreen(%d, %d, %d, %d, %d)\n", x, y, w, h, dst_pitch); -#endif - util_copy_rect((unsigned char*)dst, &priv->tex->block, dst_pitch, 0, 0, - w, h, exa->scrn->transfer_map(exa->scrn, transfer), - transfer->stride, 0, 0); + util_copy_rect((unsigned char*)dst, priv->tex->format, dst_pitch, 0, 0, + w, h, map, transfer->stride, 0, 0); - exa->scrn->transfer_unmap(exa->scrn, transfer); - exa->scrn->tex_transfer_destroy(transfer); + exa->pipe->transfer_unmap(exa->pipe, transfer); return TRUE; } @@ -165,31 +227,29 @@ ExaUploadToScreen(PixmapPtr pPix, int x, int y, int w, int h, char *src, int src_pitch) { ScreenPtr pScreen = pPix->drawable.pScreen; - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); modesettingPtr ms = modesettingPTR(pScrn); struct exa_context *exa = ms->exa; struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPix); struct pipe_transfer *transfer; + void *map; if (!priv || !priv->tex) return FALSE; - transfer = exa->scrn->get_tex_transfer(exa->scrn, priv->tex, 0, 0, 0, - PIPE_TRANSFER_WRITE, x, y, w, h); - if (!transfer) + map = pipe_transfer_map(exa->pipe, priv->tex, 0, 0, + PIPE_TRANSFER_WRITE, x, y, w, h, &transfer); + if (!map) return FALSE; -#if DEBUG_PRINT - debug_printf("++++++ ExaUploadToScreen(%d, %d, %d, %d, %d)\n", + exa_debug_printf("++++++ ExaUploadToScreen(%d, %d, %d, %d, %d)\n", x, y, w, h, src_pitch); -#endif - util_copy_rect(exa->scrn->transfer_map(exa->scrn, transfer), - &priv->tex->block, transfer->stride, 0, 0, w, h, + util_copy_rect(map, + priv->tex->format, transfer->stride, 0, 0, w, h, (unsigned char*)src, src_pitch, 0, 0); - exa->scrn->transfer_unmap(exa->scrn, transfer); - exa->scrn->tex_transfer_destroy(transfer); + exa->pipe->transfer_unmap(exa->pipe, transfer); return TRUE; } @@ -198,7 +258,7 @@ static Bool ExaPrepareAccess(PixmapPtr pPix, int index) { ScreenPtr pScreen = pPix->drawable.pScreen; - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); modesettingPtr ms = modesettingPTR(pScrn); struct exa_context *exa = ms->exa; struct exa_pixmap_priv *priv; @@ -211,33 +271,37 @@ ExaPrepareAccess(PixmapPtr pPix, int index) if (!priv->tex) return FALSE; + exa_debug_printf("ExaPrepareAccess %d\n", index); + if (priv->map_count == 0) { - if (exa->pipe->is_texture_referenced(exa->pipe, priv->tex, 0, 0) & - 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, + pPix->devPrivate.ptr = + pipe_transfer_map(exa->pipe, priv->tex, 0, 0, #ifdef EXA_MIXED_PIXMAPS - PIPE_TRANSFER_MAP_DIRECTLY | + PIPE_TRANSFER_MAP_DIRECTLY | #endif - PIPE_TRANSFER_READ_WRITE, - 0, 0, priv->tex->width[0], priv->tex->height[0]); - if (!priv->map_transfer) + PIPE_TRANSFER_READ_WRITE, + 0, 0, + pPix->drawable.width, + pPix->drawable.height, + &priv->map_transfer); + if (!pPix->devPrivate.ptr) #ifdef EXA_MIXED_PIXMAPS return FALSE; #else FatalError("failed to create transfer\n"); #endif - pPix->devPrivate.ptr = - exa->scrn->transfer_map(exa->scrn, priv->map_transfer); pPix->devKind = priv->map_transfer->stride; } priv->map_count++; + exa_debug_printf("ExaPrepareAccess %d prepared\n", index); + return TRUE; } @@ -245,7 +309,7 @@ static void ExaFinishAccess(PixmapPtr pPix, int index) { ScreenPtr pScreen = pPix->drawable.pScreen; - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); modesettingPtr ms = modesettingPTR(pScrn); struct exa_context *exa = ms->exa; struct exa_pixmap_priv *priv; @@ -257,52 +321,37 @@ ExaFinishAccess(PixmapPtr pPix, int index) if (!priv->map_transfer) return; + exa_debug_printf("ExaFinishAccess %d\n", index); + if (--priv->map_count == 0) { assert(priv->map_transfer); - exa->scrn->transfer_unmap(exa->scrn, priv->map_transfer); - exa->scrn->tex_transfer_destroy(priv->map_transfer); + exa->pipe->transfer_unmap(exa->pipe, priv->map_transfer); priv->map_transfer = NULL; pPix->devPrivate.ptr = NULL; } -} - -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); + exa_debug_printf("ExaFinishAccess %d finished\n", index); } -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) { - ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum]; + ScrnInfoPtr pScrn = xf86ScreenToScrn(pPixmap->drawable.pScreen); modesettingPtr ms = modesettingPTR(pScrn); struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPixmap); struct exa_context *exa = ms->exa; -#if DEBUG_PRINT - debug_printf("ExaPrepareSolid(0x%x)\n", fg); -#endif + exa_debug_printf("ExaPrepareSolid(0x%x)\n", fg); + + if (!exa->accel) + return FALSE; + if (!exa->pipe) - XORG_FALLBACK("accle not enabled"); + XORG_FALLBACK("accel not enabled"); if (!priv || !priv->tex) XORG_FALLBACK("%s", !priv ? "!priv" : "!priv->tex"); @@ -314,87 +363,76 @@ ExaPrepareSolid(PixmapPtr pPixmap, int alu, Pixel planeMask, Pixel fg) XORG_FALLBACK("not GXcopy"); if (!exa->scrn->is_format_supported(exa->scrn, priv->tex->format, - priv->tex->target, - PIPE_TEXTURE_USAGE_RENDER_TARGET, 0)) { - XORG_FALLBACK("format %s", pf_name(priv->tex->format)); + priv->tex->target, 0, + PIPE_BIND_RENDER_TARGET)) { + XORG_FALLBACK("format %s", util_format_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 ExaSolid(PixmapPtr pPixmap, int x0, int y0, int x1, int y1) { - ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum]; + ScrnInfoPtr pScrn = xf86ScreenToScrn(pPixmap->drawable.pScreen); modesettingPtr ms = modesettingPTR(pScrn); struct exa_context *exa = ms->exa; struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPixmap); -#if DEBUG_PRINT - debug_printf("\tExaSolid(%d, %d, %d, %d)\n", x0, y0, x1, y1); -#endif + exa_debug_printf("\tExaSolid(%d, %d, %d, %d)\n", x0, y0, x1, y1); -#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) { + union pipe_color_union solid_color; + solid_color.f[0] = exa->solid_color[0]; + solid_color.f[1] = exa->solid_color[1]; + solid_color.f[2] = exa->solid_color[2]; + solid_color.f[3] = exa->solid_color[3]; + exa->pipe->clear(exa->pipe, PIPE_CLEAR_COLOR, &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 = xf86ScreenToScrn(pPixmap->drawable.pScreen); + modesettingPtr ms = modesettingPTR(pScrn); + struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPixmap); + struct exa_context *exa = ms->exa; + + if (!priv) + return; + + exa_debug_printf("ExaDoneSolid\n"); + xorg_composite_done(exa); + exa_debug_printf("ExaDoneSolid done\n"); +} + +/*********************************************************************** + * Copy Blits + */ + static Bool ExaPrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xdir, int ydir, int alu, Pixel planeMask) { - ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum]; + ScrnInfoPtr pScrn = xf86ScreenToScrn(pDstPixmap->drawable.pScreen); modesettingPtr ms = modesettingPTR(pScrn); struct exa_context *exa = ms->exa; struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pDstPixmap); struct exa_pixmap_priv *src_priv = exaGetPixmapDriverPrivate(pSrcPixmap); -#if DEBUG_PRINT - debug_printf("ExaPrepareCopy\n"); -#endif + exa_debug_printf("ExaPrepareCopy\n"); + + if (!exa->accel) + return FALSE; + if (!exa->pipe) - XORG_FALLBACK("accle not enabled"); + XORG_FALLBACK("accel not enabled"); if (!priv || !priv->tex) XORG_FALLBACK("pDst %s", !priv ? "!priv" : "!priv->tex"); @@ -409,67 +447,197 @@ ExaPrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xdir, XORG_FALLBACK("alu not GXcopy"); if (!exa->scrn->is_format_supported(exa->scrn, priv->tex->format, - priv->tex->target, - PIPE_TEXTURE_USAGE_RENDER_TARGET, 0)) - XORG_FALLBACK("pDst format %s", pf_name(priv->tex->format)); + priv->tex->target, 0, + PIPE_BIND_RENDER_TARGET)) + XORG_FALLBACK("pDst format %s", util_format_name(priv->tex->format)); if (!exa->scrn->is_format_supported(exa->scrn, src_priv->tex->format, - src_priv->tex->target, - PIPE_TEXTURE_USAGE_SAMPLER, 0)) - XORG_FALLBACK("pSrc format %s", pf_name(src_priv->tex->format)); + src_priv->tex->target, 0, + PIPE_BIND_SAMPLER_VIEW)) + XORG_FALLBACK("pSrc format %s", util_format_name(src_priv->tex->format)); exa->copy.src = src_priv; exa->copy.dst = priv; - return ACCEL_ENABLED; + return TRUE; } static void ExaCopy(PixmapPtr pDstPixmap, int srcX, int srcY, int dstX, int dstY, int width, int height) { - ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum]; + ScrnInfoPtr pScrn = xf86ScreenToScrn(pDstPixmap->drawable.pScreen); modesettingPtr ms = modesettingPTR(pScrn); struct exa_context *exa = ms->exa; - struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pDstPixmap); + struct pipe_box src_box; -#if DEBUG_PRINT - debug_printf("\tExaCopy(srcx=%d, srcy=%d, dstX=%d, dstY=%d, w=%d, h=%d)\n", + exa_debug_printf("\tExaCopy(srcx=%d, srcy=%d, dstX=%d, dstY=%d, w=%d, h=%d)\n", srcX, srcY, dstX, dstY, width, height); + + debug_assert(exaGetPixmapDriverPrivate(pDstPixmap) == exa->copy.dst); + + u_box_2d(srcX, srcY, width, height, &src_box); + + /* If source and destination overlap, we have to copy to/from a scratch + * pixmap. + */ + if (exa->copy.dst == exa->copy.src && + !((dstX + width) < srcX || dstX > (srcX + width) || + (dstY + height) < srcY || dstY > (srcY + height))) { + struct exa_pixmap_priv *tmp_priv; + + if (!exa->copy.tmp_pix) { + exa->copy.tmp_pix = pScrn->pScreen->CreatePixmap(pScrn->pScreen, + pDstPixmap->drawable.width, + pDstPixmap->drawable.height, + pDstPixmap->drawable.depth, + pDstPixmap->drawable.width); + exaMoveInPixmap(exa->copy.tmp_pix); + } + + tmp_priv = exaGetPixmapDriverPrivate(exa->copy.tmp_pix); + + exa->pipe->resource_copy_region( exa->pipe, + tmp_priv->tex, + 0, + srcX, srcY, 0, + exa->copy.src->tex, + 0, &src_box); + exa->pipe->resource_copy_region( exa->pipe, + exa->copy.dst->tex, + 0, + dstX, dstY, 0, + tmp_priv->tex, + 0, &src_box); + } else + exa->pipe->resource_copy_region( exa->pipe, + exa->copy.dst->tex, + 0, + dstX, dstY, 0, + exa->copy.src->tex, + 0, &src_box); +} + +static void +ExaDoneCopy(PixmapPtr pPixmap) +{ + ScrnInfoPtr pScrn = xf86ScreenToScrn(pPixmap->drawable.pScreen); + modesettingPtr ms = modesettingPTR(pScrn); + struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPixmap); + struct exa_context *exa = ms->exa; + + if (!priv) + return; + + exa_debug_printf("ExaDoneCopy\n"); + + if (exa->copy.tmp_pix) { + pScrn->pScreen->DestroyPixmap(exa->copy.tmp_pix); + exa->copy.tmp_pix = NULL; + } + exa->copy.src = NULL; + exa->copy.dst = NULL; + + exa_debug_printf("ExaDoneCopy done\n"); +} + + + +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; +} - debug_assert(priv == exa->copy.dst); +/*********************************************************************** + * Composite entrypoints + */ - renderer_copy_pixmap(exa->renderer, exa->copy.dst, dstX, dstY, - exa->copy.src, srcX, srcY, - width, height); +static Bool +ExaCheckComposite(int op, + PicturePtr pSrcPicture, PicturePtr pMaskPicture, + PicturePtr pDstPicture) +{ + ScrnInfoPtr pScrn = xf86ScreenToScrn(pDstPicture->pDrawable->pScreen); + modesettingPtr ms = modesettingPTR(pScrn); + struct exa_context *exa = ms->exa; + Bool accelerated = exa->accel && xorg_composite_accelerated(op, + pSrcPicture, + pMaskPicture, + pDstPicture); + + exa_debug_printf("ExaCheckComposite(%d, %p, %p, %p) = %d\n", + op, pSrcPicture, pMaskPicture, pDstPicture, accelerated); + + return accelerated; } + static Bool ExaPrepareComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture, PicturePtr pDstPicture, PixmapPtr pSrc, PixmapPtr pMask, PixmapPtr pDst) { - ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum]; + ScrnInfoPtr pScrn = xf86ScreenToScrn(pDst->drawable.pScreen); modesettingPtr ms = modesettingPTR(pScrn); struct exa_context *exa = ms->exa; struct exa_pixmap_priv *priv; -#if DEBUG_PRINT - debug_printf("ExaPrepareComposite(%d, src=0x%p, mask=0x%p, dst=0x%p)\n", + if (!exa->accel) + return FALSE; + + exa_debug_printf("ExaPrepareComposite(%d, src=0x%p, mask=0x%p, dst=0x%p)\n", op, pSrcPicture, pMaskPicture, pDstPicture); -#endif + exa_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"); + if (!exa->pipe) - XORG_FALLBACK("accle not enabled"); + XORG_FALLBACK("accel not enabled"); priv = exaGetPixmapDriverPrivate(pDst); if (!priv || !priv->tex) XORG_FALLBACK("pDst %s", !priv ? "!priv" : "!priv->tex"); if (!exa->scrn->is_format_supported(exa->scrn, priv->tex->format, - priv->tex->target, - PIPE_TEXTURE_USAGE_RENDER_TARGET, 0)) - XORG_FALLBACK("pDst format: %s", pf_name(priv->tex->format)); + priv->tex->target, 0, + PIPE_BIND_RENDER_TARGET)) + XORG_FALLBACK("pDst format: %s", util_format_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); @@ -477,9 +645,15 @@ ExaPrepareComposite(int op, PicturePtr pSrcPicture, XORG_FALLBACK("pSrc %s", !priv ? "!priv" : "!priv->tex"); if (!exa->scrn->is_format_supported(exa->scrn, priv->tex->format, - priv->tex->target, - PIPE_TEXTURE_USAGE_SAMPLER, 0)) - XORG_FALLBACK("pSrc format: %s", pf_name(priv->tex->format)); + priv->tex->target, 0, + PIPE_BIND_SAMPLER_VIEW)) + XORG_FALLBACK("pSrc format: %s", util_format_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) { @@ -488,13 +662,17 @@ ExaPrepareComposite(int op, PicturePtr pSrcPicture, XORG_FALLBACK("pMask %s", !priv ? "!priv" : "!priv->tex"); if (!exa->scrn->is_format_supported(exa->scrn, priv->tex->format, - priv->tex->target, - PIPE_TEXTURE_USAGE_SAMPLER, 0)) - XORG_FALLBACK("pMask format: %s", pf_name(priv->tex->format)); + priv->tex->target, 0, + PIPE_BIND_SAMPLER_VIEW)) + XORG_FALLBACK("pMask format: %s", util_format_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, @@ -505,44 +683,43 @@ static void ExaComposite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY, int dstX, int dstY, int width, int height) { - ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum]; + ScrnInfoPtr pScrn = xf86ScreenToScrn(pDst->drawable.pScreen); modesettingPtr ms = modesettingPTR(pScrn); struct exa_context *exa = ms->exa; struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pDst); -#if DEBUG_PRINT - debug_printf("\tExaComposite(src[%d,%d], mask=[%d, %d], dst=[%d, %d], dim=[%d, %d])\n", + exa_debug_printf("\tExaComposite(src[%d,%d], mask=[%d, %d], dst=[%d, %d], dim=[%d, %d])\n", srcX, srcY, maskX, maskY, dstX, dstY, width, height); - debug_printf("\t Num bound samplers = %d\n", + exa_debug_printf("\t Num bound samplers = %d\n", exa->num_bound_samplers); -#endif xorg_composite(exa, priv, srcX, srcY, maskX, 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 = xf86ScreenToScrn(pPixmap->drawable.pScreen); + modesettingPtr ms = modesettingPTR(pScrn); + struct exa_context *exa = ms->exa; + + xorg_composite_done(exa); } + +/*********************************************************************** + * Pixmaps + */ + static void * ExaCreatePixmap(ScreenPtr pScreen, int size, int align) { struct exa_pixmap_priv *priv; - priv = xcalloc(1, sizeof(struct exa_pixmap_priv)); + priv = calloc(1, sizeof(struct exa_pixmap_priv)); if (!priv) return NULL; @@ -557,9 +734,9 @@ ExaDestroyPixmap(ScreenPtr pScreen, void *dPriv) if (!priv) return; - pipe_texture_reference(&priv->tex, NULL); + pipe_resource_reference(&priv->tex, NULL); - xfree(priv); + free(priv); } static Bool @@ -589,7 +766,7 @@ xorg_exa_set_displayed_usage(PixmapPtr pPixmap) return 0; } - priv->flags |= PIPE_TEXTURE_USAGE_PRIMARY; + priv->flags |= PIPE_BIND_SCANOUT; return 0; } @@ -605,38 +782,27 @@ xorg_exa_set_shared_usage(PixmapPtr pPixmap) return 0; } - priv->flags |= PIPE_TEXTURE_USAGE_DISPLAY_TARGET; + priv->flags |= PIPE_BIND_SHARED; 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 @@ -645,7 +811,7 @@ ExaModifyPixmapHeader(PixmapPtr pPixmap, int width, int height, pointer pPixData) { ScreenPtr pScreen = pPixmap->drawable.pScreen; - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPixmap); modesettingPtr ms = modesettingPTR(pScrn); struct exa_context *exa = ms->exa; @@ -653,6 +819,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,105 +848,108 @@ 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; + struct pipe_resource *texture = NULL; + struct pipe_resource 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.array_size = 1; template.last_level = 0; - template.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET | priv->flags; + template.bind = PIPE_BIND_RENDER_TARGET | priv->flags; priv->tex_flags = priv->flags; - texture = exa->scrn->texture_create(exa->scrn, &template); + texture = exa->scrn->resource_create(exa->scrn, &template); if (priv->tex) { - struct pipe_surface *dst_surf; - struct pipe_surface *src_surf; - - 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])); - } - exa->scrn->tex_surface_destroy(dst_surf); - exa->scrn->tex_surface_destroy(src_surf); + struct pipe_box src_box; + u_box_origin_2d(min(width, texture->width0), + min(height, texture->height0), + &src_box); + exa->pipe->resource_copy_region(exa->pipe, texture, + 0, 0, 0, 0, + priv->tex, + 0, &src_box); } - pipe_texture_reference(&priv->tex, texture); + pipe_resource_reference(&priv->tex, texture); /* the texture we create has one reference */ - pipe_texture_reference(&texture, NULL); + pipe_resource_reference(&texture, NULL); } return TRUE; } -struct pipe_texture * +struct pipe_resource * xorg_exa_get_texture(PixmapPtr pPixmap) { struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPixmap); - struct pipe_texture *tex = NULL; - pipe_texture_reference(&tex, priv->tex); + struct pipe_resource *tex = NULL; + pipe_resource_reference(&tex, priv->tex); return tex; } Bool -xorg_exa_set_texture(PixmapPtr pPixmap, struct pipe_texture *tex) +xorg_exa_set_texture(PixmapPtr pPixmap, struct pipe_resource *tex) { struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPixmap); - int mask = PIPE_TEXTURE_USAGE_PRIMARY | PIPE_TEXTURE_USAGE_DISPLAY_TARGET; + int mask = PIPE_BIND_SHARED | PIPE_BIND_SCANOUT; 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); - priv->tex_flags = tex->tex_usage & mask; + pipe_resource_reference(&priv->tex, tex); + priv->tex_flags = tex->bind & mask; return TRUE; } -struct pipe_texture * +struct pipe_resource * xorg_exa_create_root_texture(ScrnInfoPtr pScrn, int width, int height, int depth, int bitsPerPixel) { modesettingPtr ms = modesettingPTR(pScrn); struct exa_context *exa = ms->exa; - struct pipe_texture template; + struct pipe_resource 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.array_size = 1; template.last_level = 0; - template.tex_usage |= PIPE_TEXTURE_USAGE_RENDER_TARGET; - template.tex_usage |= PIPE_TEXTURE_USAGE_PRIMARY; - template.tex_usage |= PIPE_TEXTURE_USAGE_DISPLAY_TARGET; + template.bind |= PIPE_BIND_RENDER_TARGET; + template.bind |= PIPE_BIND_SCANOUT; + template.bind |= PIPE_BIND_SHARED; - return exa->scrn->texture_create(exa->scrn, &template); + return exa->scrn->resource_create(exa->scrn, &template); } void @@ -778,34 +958,46 @@ xorg_exa_close(ScrnInfoPtr pScrn) modesettingPtr ms = modesettingPTR(pScrn); struct exa_context *exa = ms->exa; + pipe_sampler_view_reference(&exa->bound_sampler_views[0], NULL); + pipe_sampler_view_reference(&exa->bound_sampler_views[1], NULL); + renderer_destroy(exa->renderer); + xorg_exa_finish(exa); + 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); + free(exa); ms->exa = NULL; } void * -xorg_exa_init(ScrnInfoPtr pScrn) +xorg_exa_init(ScrnInfoPtr pScrn, Bool accel) { modesettingPtr ms = modesettingPTR(pScrn); struct exa_context *exa; ExaDriverPtr pExa; + CustomizerPtr cust = ms->cust; - exa = xcalloc(1, sizeof(struct exa_context)); + exa = calloc(1, sizeof(struct exa_context)); if (!exa) return NULL; + exa->scrn = ms->screen; + exa->pipe = exa->scrn->context_create(exa->scrn, NULL); + if (exa->pipe == NULL) + goto out_err; + pExa = exaDriverAlloc(); if (!pExa) { goto out_err; } - memset(pExa, 0, sizeof(*pExa)); - pExa->exa_major = 2; pExa->exa_minor = 2; pExa->memoryBase = 0; @@ -820,17 +1012,18 @@ xorg_exa_init(ScrnInfoPtr pScrn) #ifdef EXA_MIXED_PIXMAPS pExa->flags |= EXA_MIXED_PIXMAPS; #endif - pExa->maxX = 8191; /* FIXME */ - pExa->maxY = 8191; /* FIXME */ + + pExa->maxX = pExa->maxY = + 1 << (exa->scrn->get_param(exa->scrn, PIPE_CAP_MAX_TEXTURE_2D_LEVELS) - 1); pExa->WaitMarker = ExaWaitMarker; 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; @@ -848,43 +1041,47 @@ xorg_exa_init(ScrnInfoPtr pScrn) goto out_err; } - exa->scrn = ms->screen; - exa->pipe = ms->api->create_context(ms->api, exa->scrn); /* Share context with DRI */ ms->ctx = exa->pipe; + if (cust && cust->winsys_context_throttle) + cust->winsys_context_throttle(cust, ms->ctx, THROTTLE_RENDER); exa->renderer = renderer_create(exa->pipe); + exa->accel = accel; return (void *)exa; out_err: xorg_exa_close(pScrn); + free(exa); return NULL; } struct pipe_surface * -xorg_gpu_surface(struct pipe_screen *scrn, struct exa_pixmap_priv *priv) +xorg_gpu_surface(struct pipe_context *pipe, struct exa_pixmap_priv *priv) { - return scrn->get_tex_surface(scrn, priv->tex, 0, 0, 0, - PIPE_BUFFER_USAGE_GPU_READ | - PIPE_BUFFER_USAGE_GPU_WRITE); + struct pipe_surface surf_tmpl; + u_surface_default_template(&surf_tmpl, priv->tex); + + return pipe->create_surface(pipe, priv->tex, &surf_tmpl); } -void xorg_exa_flush(struct exa_context *exa, uint pipeFlushFlags, +void xorg_exa_flush(struct exa_context *exa, struct pipe_fence_handle **fence) { - exa->pipe->flush(exa->pipe, pipeFlushFlags, fence); + exa->pipe->flush(exa->pipe, fence, 0); } void xorg_exa_finish(struct exa_context *exa) { struct pipe_fence_handle *fence = NULL; - xorg_exa_flush(exa, PIPE_FLUSH_RENDER_CACHE, &fence); + xorg_exa_flush(exa, &fence); - exa->pipe->screen->fence_finish(exa->pipe->screen, fence, 0); + exa->pipe->screen->fence_finish(exa->pipe->screen, fence, + PIPE_TIMEOUT_INFINITE); exa->pipe->screen->fence_reference(exa->pipe->screen, &fence, NULL); }