aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gallium/state_trackers/xa/xa_context.c43
-rw-r--r--src/gallium/state_trackers/xa/xa_priv.h11
-rw-r--r--src/gallium/state_trackers/xa/xa_renderer.c12
3 files changed, 53 insertions, 13 deletions
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;