What is this patch good for?
Nothing in particular, I just wanted to test how much overhead creating a new BO each time we do transfer_inline_write actually makes.

BTW: Implementing transfer_inline_write using userptrs was just a prove of concept. It turned out to actually be way slower than just copying with the CPU because we need to block for the copy to complete.

For a real use case we need to support creating textures from application supplied pointers and implement the matching OpenGL extensions, but you probably know that better than I do.

Christian.

Am 06.08.2014 um 13:24 schrieb Marek Olšák:
What is this patch good for?

Marek

On Tue, Aug 5, 2014 at 7:31 PM, Christian König <deathsim...@vodafone.de> wrote:
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

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

Reply via email to