diff options
Diffstat (limited to 'src/gallium/state_trackers/xorg/xorg_exa.c')
-rw-r--r-- | src/gallium/state_trackers/xorg/xorg_exa.c | 384 |
1 files changed, 271 insertions, 113 deletions
diff --git a/src/gallium/state_trackers/xorg/xorg_exa.c b/src/gallium/state_trackers/xorg/xorg_exa.c index a17a71f23a..f7949bafaa 100644 --- a/src/gallium/state_trackers/xorg/xorg_exa.c +++ b/src/gallium/state_trackers/xorg/xorg_exa.c @@ -47,6 +47,10 @@ #include "util/u_rect.h" +#define DEBUG_PRINT 0 +#define DEBUG_SOLID 0 +#define DISABLE_ACCEL 0 + /* * Helper functions */ @@ -72,6 +76,9 @@ exa_get_pipe_format(int depth, enum pipe_format *format, int *bbp) assert(*bbp == 16); break; case 8: + *format = PIPE_FORMAT_I8_UNORM; + assert(*bbp == 8); + break; case 4: case 1: *format = PIPE_FORMAT_A8R8G8B8_UNORM; /* bad bad bad */ @@ -82,6 +89,25 @@ exa_get_pipe_format(int depth, enum pipe_format *format, int *bbp) } } +static void +xorg_exa_init_state(struct exa_context *exa) +{ + struct pipe_depth_stencil_alpha_state dsa; + + /* set common initial clip state */ + memset(&dsa, 0, sizeof(struct pipe_depth_stencil_alpha_state)); + cso_set_depth_stencil_alpha(exa->cso, &dsa); +} + +static void +xorg_exa_common_done(struct exa_context *exa) +{ + exa->copy.src = NULL; + exa->copy.dst = NULL; + exa->has_solid_color = FALSE; + exa->num_bound_samplers = 0; +} + /* * Static exported EXA functions */ @@ -111,9 +137,9 @@ ExaDownloadFromScreen(PixmapPtr pPix, int x, int y, int w, int h, char *dst, if (!priv || !priv->tex) return FALSE; - if (exa->ctx->is_texture_referenced(exa->ctx, priv->tex, 0, 0) & + if (exa->pipe->is_texture_referenced(exa->pipe, priv->tex, 0, 0) & PIPE_REFERENCED_FOR_WRITE) - exa->ctx->flush(exa->ctx, 0, NULL); + 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); @@ -176,22 +202,29 @@ ExaPrepareAccess(PixmapPtr pPix, int index) if (!priv->tex) return FALSE; - if (priv->map_count++ == 0) + if (priv->map_count == 0) { - if (exa->ctx->is_texture_referenced(exa->ctx, priv->tex, 0, 0) & + if (exa->pipe->is_texture_referenced(exa->pipe, priv->tex, 0, 0) & PIPE_REFERENCED_FOR_WRITE) - exa->ctx->flush(exa->ctx, 0, NULL); + exa->pipe->flush(exa->pipe, 0, NULL); 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]); + if (!priv->map_transfer) + return FALSE; pPix->devPrivate.ptr = exa->scrn->transfer_map(exa->scrn, priv->map_transfer); pPix->devKind = priv->map_transfer->stride; } + priv->map_count++; + return TRUE; } @@ -231,15 +264,22 @@ ExaDone(PixmapPtr pPixmap) if (!priv) return; - if (priv->src_surf) - exa->scrn->tex_surface_destroy(priv->src_surf); - priv->src_surf = NULL; +#if 1 + xorg_exa_flush(exa, PIPE_FLUSH_RENDER_CACHE, NULL); +#else + xorg_exa_finish(exa); +#endif + 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); } static Bool @@ -250,24 +290,36 @@ ExaPrepareSolid(PixmapPtr pPixmap, int alu, Pixel planeMask, Pixel fg) struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPixmap); struct exa_context *exa = ms->exa; - if (pPixmap->drawable.depth < 15) - return FALSE; - - if (!EXA_PM_IS_SOLID(&pPixmap->drawable, planeMask)) - return FALSE; +#if DEBUG_PRINT + debug_printf("ExaPrepareSolid(0x%x)\n", fg); +#endif + if (!exa->pipe) + XORG_FALLBACK("solid accle not enabled"); if (!priv || !priv->tex) - return FALSE; + XORG_FALLBACK("solid !priv || !priv->tex"); + + if (!EXA_PM_IS_SOLID(&pPixmap->drawable, planeMask)) + XORG_FALLBACK("solid planeMask is not solid"); if (alu != GXcopy) - return FALSE; + XORG_FALLBACK("solid not GXcopy"); - if (!exa->ctx || !exa->ctx->surface_fill) - return FALSE; + if (!exa->scrn->is_format_supported(exa->scrn, priv->tex->format, + priv->tex->target, + PIPE_TEXTURE_USAGE_RENDER_TARGET, 0)) { + XORG_FALLBACK("solid bad format %s", pf_name(priv->tex->format)); + } - priv->color = fg; +#if DEBUG_SOLID + fg = 0xffff0000; +#endif - return TRUE; +#if DISABLE_ACCEL + return FALSE; +#else + return xorg_solid_bind_state(exa, priv, fg); +#endif } static void @@ -277,12 +329,51 @@ ExaSolid(PixmapPtr pPixmap, int x0, int y0, int x1, int y1) modesettingPtr ms = modesettingPTR(pScrn); struct exa_context *exa = ms->exa; struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPixmap); - struct pipe_surface *surf = exa_gpu_surface(exa, priv); - exa->ctx->surface_fill(exa->ctx, surf, x0, y0, x1 - x0, y1 - y0, - priv->color); +#if DEBUG_PRINT + 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 - exa->scrn->tex_surface_destroy(surf); +#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 Bool @@ -295,42 +386,63 @@ ExaPrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xdir, struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pDstPixmap); struct exa_pixmap_priv *src_priv = exaGetPixmapDriverPrivate(pSrcPixmap); - if (alu != GXcopy) - return FALSE; +#if DEBUG_PRINT + debug_printf("ExaPrepareCopy\n"); +#endif + if (!exa->pipe) + XORG_FALLBACK("copy accle not enabled"); - if (pSrcPixmap->drawable.depth < 15 || pDstPixmap->drawable.depth < 15) - return FALSE; + if (!priv || !src_priv) + XORG_FALLBACK("copy !priv || !src_priv"); + + if (!priv->tex || !src_priv->tex) + XORG_FALLBACK("copy !priv->tex || !src_priv->tex"); if (!EXA_PM_IS_SOLID(&pSrcPixmap->drawable, planeMask)) - return FALSE; + XORG_FALLBACK("copy planeMask is not solid"); - if (!priv || !src_priv) - return FALSE; + if (alu != GXcopy) + XORG_FALLBACK("copy alu not GXcopy"); - if (!priv->tex || !src_priv->tex) - return FALSE; + if (!exa->scrn->is_format_supported(exa->scrn, priv->tex->format, + priv->tex->target, + PIPE_TEXTURE_USAGE_RENDER_TARGET, 0)) + XORG_FALLBACK("copy pDst format %s", pf_name(priv->tex->format)); - if (!exa->ctx || !exa->ctx->surface_copy) - return FALSE; + if (!exa->scrn->is_format_supported(exa->scrn, src_priv->tex->format, + src_priv->tex->target, + PIPE_TEXTURE_USAGE_SAMPLER, 0)) + XORG_FALLBACK("copy pSrc format %s", pf_name(src_priv->tex->format)); - priv->src_surf = exa_gpu_surface(exa, src_priv); + exa->copy.src = src_priv; + exa->copy.dst = priv; +#if DISABLE_ACCEL + return FALSE; +#else return TRUE; +#endif } static void ExaCopy(PixmapPtr pDstPixmap, int srcX, int srcY, int dstX, int dstY, int width, int height) { - ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum]; - modesettingPtr ms = modesettingPTR(pScrn); - struct exa_context *exa = ms->exa; - struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pDstPixmap); - struct pipe_surface *surf = exa_gpu_surface(exa, priv); + ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum]; + modesettingPtr ms = modesettingPTR(pScrn); + struct exa_context *exa = ms->exa; + struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pDstPixmap); + +#if DEBUG_PRINT + debug_printf("\tExaCopy(srcx=%d, srcy=%d, dstX=%d, dstY=%d, w=%d, h=%d)\n", + srcX, srcY, dstX, dstY, width, height); +#endif + + debug_assert(priv == exa->copy.dst); - exa->ctx->surface_copy(exa->ctx, surf, dstX, dstY, priv->src_surf, - srcX, srcY, width, height); - exa->scrn->tex_surface_destroy(surf); + xorg_copy_pixmap(exa, exa->copy.dst, dstX, dstY, + exa->copy.src, srcX, srcY, + width, height); } static Bool @@ -341,12 +453,55 @@ ExaPrepareComposite(int op, PicturePtr pSrcPicture, ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum]; modesettingPtr ms = modesettingPTR(pScrn); struct exa_context *exa = ms->exa; + struct exa_pixmap_priv *priv; + +#if DEBUG_PRINT + debug_printf("ExaPrepareComposite\n"); +#endif + if (!exa->pipe) + XORG_FALLBACK("comp accle not enabled"); + + priv = exaGetPixmapDriverPrivate(pDst); + if (!priv || !priv->tex) + XORG_FALLBACK("comp 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("copy pDst format: %s", pf_name(priv->tex->format)); + + if (pSrc) { + priv = exaGetPixmapDriverPrivate(pSrc); + if (!priv || !priv->tex) + XORG_FALLBACK("comp 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("copy pSrc format: %s", pf_name(priv->tex->format)); + } + + if (pMask) { + priv = exaGetPixmapDriverPrivate(pMask); + if (!priv || !priv->tex) + XORG_FALLBACK("comp 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("copy pMask format: %s", pf_name(priv->tex->format)); + } +#if DISABLE_ACCEL + (void) exa; + return FALSE; +#else return xorg_composite_bind_state(exa, op, pSrcPicture, pMaskPicture, pDstPicture, - exaGetPixmapDriverPrivate(pSrc), - exaGetPixmapDriverPrivate(pMask), + pSrc ? exaGetPixmapDriverPrivate(pSrc) : NULL, + pMask ? exaGetPixmapDriverPrivate(pMask) : NULL, exaGetPixmapDriverPrivate(pDst)); +#endif } static void @@ -358,6 +513,10 @@ ExaComposite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY, struct exa_context *exa = ms->exa; struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pDst); +#if DEBUG_PRINT + debug_printf("\tExaComposite\n"); +#endif + xorg_composite(exa, priv, srcX, srcY, maskX, maskY, dstX, dstY, width, height); } @@ -367,10 +526,15 @@ ExaCheckComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture, PicturePtr pDstPicture) { - return xorg_composite_accelerated(op, - pSrcPicture, - pMaskPicture, - pDstPicture); + 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 accelerated; } static void * @@ -389,14 +553,11 @@ static void ExaDestroyPixmap(ScreenPtr pScreen, void *dPriv) { struct exa_pixmap_priv *priv = (struct exa_pixmap_priv *)dPriv; - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - modesettingPtr ms = modesettingPTR(pScrn); if (!priv) return; - if (priv->tex) - ms->screen->texture_destroy(priv->tex); + pipe_texture_reference(&priv->tex, NULL); xfree(priv); } @@ -516,64 +677,37 @@ ExaModifyPixmapHeader(PixmapPtr pPixmap, int width, int height, priv->tex->height[0] != height || priv->tex_flags != priv->flags)) { struct pipe_texture *texture = NULL; - -#ifdef DRM_MODE_FEATURE_DIRTYFB - if (priv->flags) -#endif - { - 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; - template.last_level = 0; - template.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET | priv->flags; - priv->tex_flags = priv->flags; - texture = exa->scrn->texture_create(exa->scrn, &template); - - if (priv->tex) { - struct pipe_surface *dst_surf; - - dst_surf = exa->scrn->get_tex_surface(exa->scrn, texture, 0, 0, 0, - PIPE_BUFFER_USAGE_GPU_WRITE); - priv->src_surf = exa_gpu_surface(exa, priv); - exa->ctx->surface_copy(exa->ctx, dst_surf, 0, 0, priv->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(priv->src_surf); - priv->src_surf = NULL; - } else if (pPixmap->devPrivate.ptr) { - struct pipe_transfer *transfer; - - if (priv->map_count != 0) - FatalError("doing ExaModifyPixmapHeader on mapped buffer\n"); - - transfer = - exa->scrn->get_tex_transfer(exa->scrn, texture, 0, 0, 0, - PIPE_TRANSFER_WRITE, - 0, 0, width, height); - util_copy_rect(exa->scrn->transfer_map(exa->scrn, transfer), - &texture->block, transfer->stride, 0, 0, - width, height, pPixmap->devPrivate.ptr, - pPixmap->devKind, 0, 0); - exa->scrn->transfer_unmap(exa->scrn, transfer); - exa->scrn->tex_transfer_destroy(transfer); - } + 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; + template.last_level = 0; + template.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET | priv->flags; + priv->tex_flags = priv->flags; + texture = exa->scrn->texture_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 = exa_gpu_surface(exa, priv); + exa->pipe->surface_copy(exa->pipe, 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); } -#ifdef DRM_MODE_FEATURE_DIRTYFB - else { - xfree(pPixmap->devPrivate.ptr); - pPixmap->devPrivate.ptr = xalloc(pPixmap->drawable.height * - pPixmap->devKind); - } -#endif pipe_texture_reference(&priv->tex, texture); + /* the texture we create has one reference */ + pipe_texture_reference(&texture, NULL); } return TRUE; @@ -611,8 +745,8 @@ xorg_exa_close(ScrnInfoPtr pScrn) cso_destroy_context(exa->cso); } - if (exa->ctx) - exa->ctx->destroy(exa->ctx); + if (exa->pipe) + exa->pipe->destroy(exa->pipe); exaDriverFini(pScrn->pScreen); xfree(exa); @@ -645,6 +779,12 @@ xorg_exa_init(ScrnInfoPtr pScrn) pExa->pixmapOffsetAlign = 0; pExa->pixmapPitchAlign = 1; pExa->flags = EXA_OFFSCREEN_PIXMAPS | EXA_HANDLES_PIXMAPS; +#ifdef EXA_SUPPORTS_PREPARE_AUX + pExa->flags |= EXA_SUPPORTS_PREPARE_AUX; +#endif +#ifdef EXA_MIXED_PIXMAPS + pExa->flags |= EXA_MIXED_PIXMAPS; +#endif pExa->maxX = 8191; /* FIXME */ pExa->maxY = 8191; /* FIXME */ @@ -674,13 +814,15 @@ xorg_exa_init(ScrnInfoPtr pScrn) } exa->scrn = ms->screen; - exa->ctx = ms->api->create_context(ms->api, exa->scrn); + exa->pipe = ms->api->create_context(ms->api, exa->scrn); /* Share context with DRI */ - ms->ctx = exa->ctx; + ms->ctx = exa->pipe; - exa->cso = cso_create_context(exa->ctx); + exa->cso = cso_create_context(exa->pipe); exa->shaders = xorg_shaders_create(exa); + xorg_exa_init_state(exa); + return (void *)exa; out_err: @@ -698,3 +840,19 @@ exa_gpu_surface(struct exa_context *exa, struct exa_pixmap_priv *priv) } +void xorg_exa_flush(struct exa_context *exa, uint pipeFlushFlags, + struct pipe_fence_handle **fence) +{ + exa->pipe->flush(exa->pipe, pipeFlushFlags, fence); +} + +void xorg_exa_finish(struct exa_context *exa) +{ + struct pipe_fence_handle *fence = NULL; + + xorg_exa_flush(exa, PIPE_FLUSH_RENDER_CACHE, &fence); + + exa->pipe->screen->fence_finish(exa->pipe->screen, fence, 0); + exa->pipe->screen->fence_reference(exa->pipe->screen, &fence, NULL); +} + |