[Mesa-dev] [PATCH 4/4] radeon: cache the last used userptr
Marek Olšák
maraeo at gmail.com
Wed Aug 6 04:52:05 PDT 2014
I only know about AMD_pinned_memory, which is for buffers only. I
don't know about an API for creating textures from user pointers. Yes,
there are pixel buffer objects, but they are a lot more difficult to
implement and they are defined such that a zero-copy approach to get a
texture is not possible.
Marek
On Wed, Aug 6, 2014 at 1:39 PM, Christian König <deathsimple at vodafone.de> wrote:
>> 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 <deathsimple at vodafone.de>
>> wrote:
>>>
>>> From: Christian König <christian.koenig at amd.com>
>>>
>>> Signed-off-by: Christian König <christian.koenig at 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 at lists.freedesktop.org
>>> http://lists.freedesktop.org/mailman/listinfo/mesa-dev
>
>
More information about the mesa-dev
mailing list