From: Christian König <christian.koe...@amd.com> Signed-off-by: Christian König <christian.koe...@amd.com> --- src/gallium/drivers/radeon/r600_pipe_common.c | 9 ++++++ src/gallium/drivers/radeon/r600_pipe_common.h | 11 +++++++ src/gallium/drivers/radeon/r600_texture.c | 41 +++++++++++++++++++++++++-- 3 files changed, 59 insertions(+), 2 deletions(-)
diff --git a/src/gallium/drivers/radeon/r600_pipe_common.c b/src/gallium/drivers/radeon/r600_pipe_common.c index 69d344e..f745311 100644 --- a/src/gallium/drivers/radeon/r600_pipe_common.c +++ b/src/gallium/drivers/radeon/r600_pipe_common.c @@ -770,11 +770,20 @@ bool r600_common_screen_init(struct r600_common_screen *rscreen, } } + pipe_mutex_init(rscreen->userptr_lock); + return true; } void r600_destroy_common_screen(struct r600_common_screen *rscreen) { + unsigned i; + + for (i = 0; i < R600_USERPTR_CACHE; ++i) + pipe_resource_reference((struct pipe_resource **)&rscreen->userptr[i].tex, NULL); + + pipe_mutex_destroy(rscreen->userptr_lock); + pipe_mutex_destroy(rscreen->aux_context_lock); rscreen->aux_context->destroy(rscreen->aux_context); diff --git a/src/gallium/drivers/radeon/r600_pipe_common.h b/src/gallium/drivers/radeon/r600_pipe_common.h index dcec2bb..88dbaf8 100644 --- a/src/gallium/drivers/radeon/r600_pipe_common.h +++ b/src/gallium/drivers/radeon/r600_pipe_common.h @@ -97,6 +97,8 @@ #define R600_MAP_BUFFER_ALIGNMENT 64 +#define R600_USERPTR_CACHE 32 + struct r600_common_context; struct radeon_shader_binary { @@ -258,6 +260,15 @@ struct r600_common_screen { struct r600_resource *trace_bo; uint32_t *trace_ptr; unsigned cs_count; + + struct { + struct r600_texture *tex; + void *pointer; + unsigned offset; + unsigned size; + } userptr[R600_USERPTR_CACHE]; + unsigned userptr_idx; + pipe_mutex userptr_lock; }; /* This encapsulates a state or an operation which can emitted into the GPU diff --git a/src/gallium/drivers/radeon/r600_texture.c b/src/gallium/drivers/radeon/r600_texture.c index 89b3b55..c3ff96c 100644 --- a/src/gallium/drivers/radeon/r600_texture.c +++ b/src/gallium/drivers/radeon/r600_texture.c @@ -855,10 +855,11 @@ static struct r600_texture *r600_texture_from_ptr(struct pipe_screen *screen, { struct r600_common_screen *rscreen = (struct r600_common_screen*)screen; struct radeon_surface surface = {}; + struct pipe_resource *res = NULL; struct r600_texture *tex; unsigned offset, size; struct pb_buffer *buf; - int r; + int r, i; /* Support only 2D textures without mipmaps */ if ((templ->target != PIPE_TEXTURE_2D && templ->target != PIPE_TEXTURE_RECT) || @@ -877,16 +878,52 @@ static struct r600_texture *r600_texture_from_ptr(struct pipe_screen *screen, if (size < 64*1024) return NULL; + pipe_mutex_lock(rscreen->userptr_lock); + for (i = 0; i < R600_USERPTR_CACHE; ++i) { + + if (rscreen->userptr[i].pointer != pointer || + rscreen->userptr[i].offset != offset || + rscreen->userptr[i].size != size || + !rscreen->userptr[i].tex) + continue; + + tex = rscreen->userptr[i].tex; + if (tex->resource.b.b.width0 != templ->width0 && + tex->resource.b.b.height0 != templ->height0 && + tex->resource.b.b.target != templ->target && + tex->resource.b.b.format != templ->format) + continue; + + pipe_resource_reference(&res, (struct pipe_resource *)tex); + pipe_mutex_unlock(rscreen->userptr_lock); + return (struct r600_texture *)res; + } + pipe_mutex_unlock(rscreen->userptr_lock); + 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); + r = r600_init_surface(rscreen, &surface, templ, RADEON_SURF_MODE_LINEAR, false); if (r) return NULL; tex = r600_texture_create_object(screen, templ, stride, buf, &surface); tex->surface.level[0].offset += offset; + + pipe_mutex_lock(rscreen->userptr_lock); + ++rscreen->userptr_idx; + rscreen->userptr_idx %= R600_USERPTR_CACHE; + + i = rscreen->userptr_idx; + pipe_resource_reference((struct pipe_resource **)&rscreen->userptr[i].tex, + (struct pipe_resource *)tex); + rscreen->userptr[i].pointer = pointer; + rscreen->userptr[i].offset = offset; + rscreen->userptr[i].size = size; + + pipe_mutex_unlock(rscreen->userptr_lock); + return tex; } -- 1.9.1 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev