From: Thomas Hellstrom Date: Mon, 20 Jun 2011 21:46:03 +0000 (+0200) Subject: st/xa: Support format-changing copy. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=642951fbcaa56a975422f7caddf6620f20d47721;p=mesa.git st/xa: Support format-changing copy. Signed-off-by: Thomas Hellstrom --- diff --git a/src/gallium/state_trackers/xa/xa_context.c b/src/gallium/state_trackers/xa/xa_context.c index 5ac16a2b195..a6abd8c4107 100644 --- a/src/gallium/state_trackers/xa/xa_context.c +++ b/src/gallium/state_trackers/xa/xa_context.c @@ -31,6 +31,7 @@ #include "cso_cache/cso_context.h" #include "util/u_inlines.h" #include "util/u_rect.h" +#include "util/u_surface.h" #include "pipe/p_context.h" @@ -176,9 +177,28 @@ int xa_copy_prepare(struct xa_context *ctx, struct xa_surface *dst, struct xa_surface *src) { - if (src == dst || src->tex->format != dst->tex->format) + if (src == dst || dst->srf != NULL) return -XA_ERR_INVAL; + if (src->tex->format != dst->tex->format) { + struct pipe_screen *screen = ctx->pipe->screen; + struct pipe_surface srf_templ; + + if (!screen->is_format_supported(screen, dst->tex->format, + PIPE_TEXTURE_2D, 0, + PIPE_BIND_RENDER_TARGET)) + return -XA_ERR_INVAL; + u_surface_default_template(&srf_templ, dst->tex, + PIPE_BIND_RENDER_TARGET); + dst->srf = ctx->pipe->create_surface(ctx->pipe, dst->tex, &srf_templ); + if (!dst->srf) + return -XA_ERR_NORES; + + renderer_copy_prepare(ctx, dst->srf, src->tex); + ctx->simple_copy = 0; + } else + ctx->simple_copy = 1; + ctx->src = src; ctx->dst = dst; @@ -191,17 +211,26 @@ xa_copy(struct xa_context *ctx, { struct pipe_box src_box; - u_box_2d(sx, sy, width, height, &src_box); - ctx->pipe->resource_copy_region(ctx->pipe, - ctx->dst->tex, 0, dx, dy, 0, ctx->src->tex, - 0, &src_box); - + if (ctx->simple_copy) { + u_box_2d(sx, sy, width, height, &src_box); + ctx->pipe->resource_copy_region(ctx->pipe, + ctx->dst->tex, 0, dx, dy, 0, + ctx->src->tex, + 0, &src_box); + } else + renderer_copy(ctx, dx, dy, sx, sy, width, height, + (float) width, (float) height); } void xa_copy_done(struct xa_context *ctx) { - ctx->pipe->flush(ctx->pipe, &ctx->last_fence); + if (!ctx->simple_copy) { + renderer_draw_flush(ctx); + ctx->pipe->flush(ctx->pipe, &ctx->last_fence); + pipe_surface_reference(&ctx->dst->srf, NULL); + } else + ctx->pipe->flush(ctx->pipe, &ctx->last_fence); } struct xa_fence * diff --git a/src/gallium/state_trackers/xa/xa_priv.h b/src/gallium/state_trackers/xa/xa_priv.h index 57f2e3da545..22a49c138ce 100644 --- a/src/gallium/state_trackers/xa/xa_priv.h +++ b/src/gallium/state_trackers/xa/xa_priv.h @@ -95,6 +95,7 @@ struct xa_context { struct pipe_fence_handle *last_fence; struct xa_surface *src; struct xa_surface *dst; + int simple_copy; }; enum xa_vs_traits { @@ -175,5 +176,15 @@ void renderer_bind_destination(struct xa_context *r, int height); void renderer_init_state(struct xa_context *r); +void renderer_copy_prepare(struct xa_context *r, + struct pipe_surface *dst_surface, + struct pipe_resource *src_texture); +void renderer_copy(struct xa_context *r, int dx, + int dy, + int sx, + int sy, + int width, int height, float src_width, float src_height); + +void renderer_draw_flush(struct xa_context *r); #endif diff --git a/src/gallium/state_trackers/xa/xa_renderer.c b/src/gallium/state_trackers/xa/xa_renderer.c index 4e42833db46..b92df0da7d5 100644 --- a/src/gallium/state_trackers/xa/xa_renderer.c +++ b/src/gallium/state_trackers/xa/xa_renderer.c @@ -377,12 +377,12 @@ renderer_copy_prepare(struct xa_context *r, } void -renderer_copy_pixmap(struct xa_context *r, - int dx, - int dy, - int sx, - int sy, - int width, int height, float src_width, float src_height) +renderer_copy(struct xa_context *r, + int dx, + int dy, + int sx, + int sy, + int width, int height, float src_width, float src_height) { float s0, t0, s1, t1; float x0, y0, x1, y1;