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