From: Christian König <christian.koe...@amd.com>

Not completely implemented, cause we need DMA copy support for every hw 
generation.

Signed-off-by: Christian König <christian.koe...@amd.com>
---
 src/gallium/drivers/radeon/r600_buffer_common.c |   2 +-
 src/gallium/drivers/radeon/r600_pipe_common.c   |   2 +-
 src/gallium/drivers/radeon/r600_texture.c       | 104 ++++++++++++++++++++++--
 3 files changed, 100 insertions(+), 8 deletions(-)

diff --git a/src/gallium/drivers/radeon/r600_buffer_common.c 
b/src/gallium/drivers/radeon/r600_buffer_common.c
index d747cbc..28ab30c 100644
--- a/src/gallium/drivers/radeon/r600_buffer_common.c
+++ b/src/gallium/drivers/radeon/r600_buffer_common.c
@@ -372,7 +372,7 @@ static const struct u_resource_vtbl r600_buffer_vtbl =
        r600_buffer_transfer_map,       /* transfer_map */
        NULL,                           /* transfer_flush_region */
        r600_buffer_transfer_unmap,     /* transfer_unmap */
-       NULL                            /* transfer_inline_write */
+       u_default_transfer_inline_write /* transfer_inline_write */
 };
 
 struct pipe_resource *r600_buffer_create(struct pipe_screen *screen,
diff --git a/src/gallium/drivers/radeon/r600_pipe_common.c 
b/src/gallium/drivers/radeon/r600_pipe_common.c
index 3476021..69d344e 100644
--- a/src/gallium/drivers/radeon/r600_pipe_common.c
+++ b/src/gallium/drivers/radeon/r600_pipe_common.c
@@ -153,7 +153,7 @@ bool r600_common_context_init(struct r600_common_context 
*rctx,
        rctx->b.transfer_map = u_transfer_map_vtbl;
        rctx->b.transfer_flush_region = u_default_transfer_flush_region;
        rctx->b.transfer_unmap = u_transfer_unmap_vtbl;
-       rctx->b.transfer_inline_write = u_default_transfer_inline_write;
+       rctx->b.transfer_inline_write = u_transfer_inline_write_vtbl;
         rctx->b.memory_barrier = r600_memory_barrier;
        rctx->b.flush = r600_flush_from_st;
 
diff --git a/src/gallium/drivers/radeon/r600_texture.c 
b/src/gallium/drivers/radeon/r600_texture.c
index 482bbff..89b3b55 100644
--- a/src/gallium/drivers/radeon/r600_texture.c
+++ b/src/gallium/drivers/radeon/r600_texture.c
@@ -849,6 +849,47 @@ static struct pipe_resource 
*r600_texture_from_handle(struct pipe_screen *screen
                                                                  stride, buf, 
&surface);
 }
 
+static struct r600_texture *r600_texture_from_ptr(struct pipe_screen *screen,
+                                                 const struct pipe_resource 
*templ,
+                                                 void *pointer, unsigned 
stride)
+{
+       struct r600_common_screen *rscreen = (struct r600_common_screen*)screen;
+       struct radeon_surface surface = {};
+       struct r600_texture *tex;
+       unsigned offset, size;
+       struct pb_buffer *buf;
+       int r;
+
+       /* Support only 2D textures without mipmaps */
+       if ((templ->target != PIPE_TEXTURE_2D && templ->target != 
PIPE_TEXTURE_RECT) ||
+             templ->depth0 != 1 || templ->last_level != 0)
+               return NULL;
+
+       /* stride needs to be at least dw aligned */
+       if (stride % 4)
+               return NULL;
+
+       offset = ((uintptr_t)pointer) & 0xfff;
+       pointer = (void *)(((uintptr_t)pointer) - offset);
+       size = align(stride * templ->height0 + offset, 0x1000);
+
+       /* avoid the overhead for small copies */
+       if (size < 64*1024)
+               return NULL;
+
+       buf = rscreen->ws->buffer_from_ptr(rscreen->ws, pointer, size);
+       if (!buf)
+               return NULL;
+
+       r = r600_init_surface(rscreen, &surface, templ, 
RADEON_SURF_MODE_LINEAR_ALIGNED, false);
+       if (r)
+               return NULL;
+
+       tex = r600_texture_create_object(screen, templ, stride, buf, &surface);
+       tex->surface.level[0].offset += offset;
+       return tex;
+}
+
 bool r600_init_flushed_depth_texture(struct pipe_context *ctx,
                                     struct pipe_resource *texture,
                                     struct r600_texture **staging)
@@ -1112,14 +1153,65 @@ static void r600_texture_transfer_unmap(struct 
pipe_context *ctx,
        FREE(transfer);
 }
 
+static void r600_texture_transfer_inline_write(struct pipe_context *ctx,
+                                              struct pipe_resource *dst,
+                                              unsigned level, unsigned usage,
+                                              const struct pipe_box *box,
+                                              const void *data,
+                                              unsigned stride,
+                                              unsigned layer_stride)
+{
+       struct r600_common_context *rctx = (struct r600_common_context*)ctx;
+       struct r600_texture *rsrc;
+       struct pipe_resource *src, templ = {};
+       struct pipe_box src_box = {};
+
+       templ.target = PIPE_TEXTURE_2D;
+       templ.format = dst->format;
+
+       templ.width0 = box->width;
+       templ.height0 = box->height;
+       templ.depth0 = 1;
+       templ.array_size = 1;
+
+       templ.usage = PIPE_USAGE_STAGING;
+       templ.bind = PIPE_BIND_TRANSFER_READ;
+
+       rsrc = r600_texture_from_ptr(ctx->screen, &templ, (void *)data, stride);
+       src = (struct pipe_resource *)rsrc;
+       if (!src) {
+               u_default_transfer_inline_write(ctx, dst, level, usage, box,
+                                               data, stride, layer_stride);
+               return;
+       }
+
+       src_box.width = box->width;
+       src_box.height = box->height;
+       src_box.depth = box->depth;
+       rctx->dma_copy(ctx, dst, level, box->x, box->y, box->z, src, 0, 
&src_box);
+
+       if (rctx->ws->cs_is_buffer_referenced(rctx->rings.gfx.cs, 
rsrc->resource.cs_buf,
+                                             RADEON_USAGE_READ))
+               rctx->rings.gfx.flush(ctx, 0, NULL);
+
+       if (rctx->rings.dma.cs &&
+           rctx->ws->cs_is_buffer_referenced(rctx->rings.dma.cs, 
rsrc->resource.cs_buf,
+                                            RADEON_USAGE_READ))
+               rctx->rings.dma.flush(ctx, 0, NULL);
+
+       rctx->ws->buffer_wait(rsrc->resource.buf, RADEON_USAGE_READWRITE);
+
+       pipe_resource_reference(&src, NULL);
+}
+
 static const struct u_resource_vtbl r600_texture_vtbl =
 {
-       NULL,                           /* get_handle */
-       r600_texture_destroy,           /* resource_destroy */
-       r600_texture_transfer_map,      /* transfer_map */
-       NULL,                           /* transfer_flush_region */
-       r600_texture_transfer_unmap,    /* transfer_unmap */
-       NULL                            /* transfer_inline_write */
+       NULL,                                   /* get_handle */
+       r600_texture_destroy,                   /* resource_destroy */
+       r600_texture_transfer_map,              /* transfer_map */
+       NULL,                                   /* transfer_flush_region */
+       r600_texture_transfer_unmap,            /* transfer_unmap */
+       r600_texture_transfer_inline_write      /* transfer_inline_write */
 };
 
 struct pipe_surface *r600_create_surface_custom(struct pipe_context *pipe,
-- 
1.9.1

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to