st/xa: Support format-changing copy.
authorThomas Hellstrom <thellstrom@vmware.com>
Mon, 20 Jun 2011 21:46:03 +0000 (23:46 +0200)
committerThomas Hellstrom <thellstrom@vmware.com>
Mon, 20 Jun 2011 21:47:13 +0000 (23:47 +0200)
Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
src/gallium/state_trackers/xa/xa_context.c
src/gallium/state_trackers/xa/xa_priv.h
src/gallium/state_trackers/xa/xa_renderer.c

index 5ac16a2b1954266ea852fa2f9aa51c3b09a2e39d..a6abd8c4107d627c7ddf45c003e74f457e895338 100644 (file)
@@ -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 *
index 57f2e3da54516d12b788c19230628a85d65c5ab1..22a49c138ce3dae9f9263abcd02fdbb0e22eaee9 100644 (file)
@@ -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
index 4e42833db461019bb5acc22c15992bbc426dcb6a..b92df0da7d5ce12c1b4e168ad0728bacefaa56f8 100644 (file)
@@ -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;