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