[Mesa-dev] [PATCH 4/4] radeon: Enable DRI Image 7 support
Christian König
deathsimple at vodafone.de
Mon Apr 22 04:33:32 PDT 2013
Am 22.04.2013 13:21, schrieb Marek Olšák:
> On Mon, Apr 22, 2013 at 8:38 AM,
> <christopher.halse.rogers at canonical.com> wrote:
>> From: Christopher James Halse Rogers <raof at ubuntu.com>
>>
>> ---
>> src/gallium/drivers/r300/r300_screen.c | 8 ++-
>> src/gallium/drivers/r300/r300_texture.c | 2 +-
>> src/gallium/drivers/r600/r600_pipe.c | 7 ++-
>> src/gallium/drivers/r600/r600_texture.c | 2 +-
>> src/gallium/drivers/radeonsi/r600_texture.c | 2 +-
>> src/gallium/drivers/radeonsi/radeonsi_pipe.c | 6 +-
>> src/gallium/winsys/radeon/drm/radeon_drm_bo.c | 70 ++++++++++++++++++-----
>> src/gallium/winsys/radeon/drm/radeon_drm_winsys.c | 4 ++
>> src/gallium/winsys/radeon/drm/radeon_winsys.h | 3 +
>> 9 files changed, 84 insertions(+), 20 deletions(-)
>>
>> diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c
>> index 000c71d..b7a7a2d 100644
>> --- a/src/gallium/drivers/r300/r300_screen.c
>> +++ b/src/gallium/drivers/r300/r300_screen.c
>> @@ -28,6 +28,8 @@
>> #include "vl/vl_decoder.h"
>> #include "vl/vl_video_buffer.h"
>>
>> +#include <drm.h>
>> +
>> #include "r300_context.h"
>> #include "r300_texture.h"
>> #include "r300_screen_buffer.h"
>> @@ -163,7 +165,6 @@ static int r300_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
>> case PIPE_CAP_TEXTURE_BUFFER_OBJECTS:
>> case PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT:
>> case PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK:
>> - case PIPE_CAP_PRIME:
>> return 0;
>>
>> /* SWTCL-only features. */
>> @@ -191,6 +192,11 @@ static int r300_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
>> /* Render targets. */
>> case PIPE_CAP_MAX_RENDER_TARGETS:
>> return 4;
>> +
>> + /* PRIME import/export support */
>> + case PIPE_CAP_PRIME:
>> + return r300screen->info.prime_caps &
>> + (DRM_PRIME_CAP_IMPORT | DRM_PRIME_CAP_EXPORT);
>> }
>> return 0;
>> }
>> diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c
>> index 13e9bc3..442b575 100644
>> --- a/src/gallium/drivers/r300/r300_texture.c
>> +++ b/src/gallium/drivers/r300/r300_texture.c
>> @@ -1111,7 +1111,7 @@ struct pipe_resource *r300_texture_from_handle(struct pipe_screen *screen,
>> return NULL;
>> }
>>
>> - buffer = rws->buffer_from_handle(rws, whandle, &stride);
>> + buffer = rws->buffer_from_handle(rws, whandle, base->height0, &stride);
>> if (!buffer)
>> return NULL;
>>
>> diff --git a/src/gallium/drivers/r600/r600_pipe.c b/src/gallium/drivers/r600/r600_pipe.c
>> index b056041..03e67f9 100644
>> --- a/src/gallium/drivers/r600/r600_pipe.c
>> +++ b/src/gallium/drivers/r600/r600_pipe.c
>> @@ -26,6 +26,8 @@
>> #include "evergreen_compute.h"
>> #include "r600d.h"
>>
>> +#include <drm.h>
>> +
>> #include <errno.h>
>> #include "pipe/p_shader_tokens.h"
>> #include "util/u_blitter.h"
>> @@ -612,7 +614,6 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
>> case PIPE_CAP_FRAGMENT_COLOR_CLAMPED:
>> case PIPE_CAP_VERTEX_COLOR_CLAMPED:
>> case PIPE_CAP_USER_VERTEX_BUFFERS:
>> - case PIPE_CAP_PRIME:
>> return 0;
>>
>> /* Stream output. */
>> @@ -655,9 +656,11 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
>>
>> case PIPE_CAP_MAX_TEXEL_OFFSET:
>> return 7;
>> -
>> case PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK:
>> return PIPE_QUIRK_TEXTURE_BORDER_COLOR_SWIZZLE_R600;
>> + case PIPE_CAP_PRIME:
>> + return rscreen->info.prime_caps &
>> + (DRM_PRIME_CAP_IMPORT | DRM_PRIME_CAP_EXPORT);
>> }
>> return 0;
>> }
>> diff --git a/src/gallium/drivers/r600/r600_texture.c b/src/gallium/drivers/r600/r600_texture.c
>> index 98cb118..8fa821b 100644
>> --- a/src/gallium/drivers/r600/r600_texture.c
>> +++ b/src/gallium/drivers/r600/r600_texture.c
>> @@ -670,7 +670,7 @@ struct pipe_resource *r600_texture_from_handle(struct pipe_screen *screen,
>> templ->depth0 != 1 || templ->last_level != 0)
>> return NULL;
>>
>> - buf = rscreen->ws->buffer_from_handle(rscreen->ws, whandle, &stride);
>> + buf = rscreen->ws->buffer_from_handle(rscreen->ws, whandle, templ->height0, &stride);
>> if (!buf)
>> return NULL;
>>
>> diff --git a/src/gallium/drivers/radeonsi/r600_texture.c b/src/gallium/drivers/radeonsi/r600_texture.c
>> index 8992f9a..5ef526c 100644
>> --- a/src/gallium/drivers/radeonsi/r600_texture.c
>> +++ b/src/gallium/drivers/radeonsi/r600_texture.c
>> @@ -602,7 +602,7 @@ struct pipe_resource *si_texture_from_handle(struct pipe_screen *screen,
>> templ->depth0 != 1 || templ->last_level != 0)
>> return NULL;
>>
>> - buf = rscreen->ws->buffer_from_handle(rscreen->ws, whandle, &stride);
>> + buf = rscreen->ws->buffer_from_handle(rscreen->ws, whandle, templ->height0, &stride);
>> if (!buf)
>> return NULL;
>>
>> diff --git a/src/gallium/drivers/radeonsi/radeonsi_pipe.c b/src/gallium/drivers/radeonsi/radeonsi_pipe.c
>> index 1705e3e..60c40f5 100644
>> --- a/src/gallium/drivers/radeonsi/radeonsi_pipe.c
>> +++ b/src/gallium/drivers/radeonsi/radeonsi_pipe.c
>> @@ -20,6 +20,7 @@
>> * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
>> * USE OR OTHER DEALINGS IN THE SOFTWARE.
>> */
>> +#include <drm.h>
>> #include <stdio.h>
>> #include <errno.h>
>> #include "pipe/p_defines.h"
>> @@ -381,7 +382,6 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
>> case PIPE_CAP_TEXTURE_BUFFER_OBJECTS:
>> case PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT:
>> case PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK:
>> - case PIPE_CAP_PRIME:
>> return 0;
>>
>> /* Stream output. */
>> @@ -424,6 +424,10 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
>>
>> case PIPE_CAP_MAX_TEXEL_OFFSET:
>> return 7;
>> +
>> + case PIPE_CAP_PRIME:
>> + return rscreen->info.prime_caps &
>> + (DRM_PRIME_CAP_IMPORT | DRM_PRIME_CAP_EXPORT);
>> }
>> return 0;
>> }
>> diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_bo.c b/src/gallium/winsys/radeon/drm/radeon_drm_bo.c
>> index c0ea4c0..53d9e9c 100644
>> --- a/src/gallium/winsys/radeon/drm/radeon_drm_bo.c
>> +++ b/src/gallium/winsys/radeon/drm/radeon_drm_bo.c
>> @@ -40,6 +40,7 @@
>> #include <sys/ioctl.h>
>> #include <xf86drm.h>
>> #include <errno.h>
>> +#include <fcntl.h>
>>
>> /*
>> * this are copy from radeon_drm, once an updated libdrm is released
>> @@ -116,6 +117,8 @@ struct radeon_bomgr {
>>
>> /* List of buffer GEM names. Protected by bo_handles_mutex. */
>> struct util_hash_table *bo_names;
>> + /* List of buffer handles. Protectded by bo_handles_mutex. */
>> + struct util_hash_table *bo_handles;
>> pipe_mutex bo_handles_mutex;
>> pipe_mutex bo_va_mutex;
>>
>> @@ -370,12 +373,13 @@ static void radeon_bo_destroy(struct pb_buffer *_buf)
>>
>> memset(&args, 0, sizeof(args));
>>
>> + pipe_mutex_lock(bo->mgr->bo_handles_mutex);
>> + util_hash_table_remove(bo->mgr->bo_handles, (void*)(uintptr_t)bo->handle);
>> if (bo->name) {
>> - pipe_mutex_lock(bo->mgr->bo_handles_mutex);
>> util_hash_table_remove(bo->mgr->bo_names,
>> (void*)(uintptr_t)bo->name);
>> - pipe_mutex_unlock(bo->mgr->bo_handles_mutex);
>> }
>> + pipe_mutex_unlock(bo->mgr->bo_handles_mutex);
>>
>> if (bo->ptr)
>> os_munmap(bo->ptr, bo->base.size);
>> @@ -659,6 +663,7 @@ static void radeon_bomgr_destroy(struct pb_manager *_mgr)
>> {
>> struct radeon_bomgr *mgr = radeon_bomgr(_mgr);
>> util_hash_table_destroy(mgr->bo_names);
>> + util_hash_table_destroy(mgr->bo_handles);;
>> pipe_mutex_destroy(mgr->bo_handles_mutex);
>> pipe_mutex_destroy(mgr->bo_va_mutex);
>> FREE(mgr);
>> @@ -691,6 +696,7 @@ struct pb_manager *radeon_bomgr_create(struct radeon_drm_winsys *rws)
>>
>> mgr->rws = rws;
>> mgr->bo_names = util_hash_table_create(handle_hash, handle_compare);
>> + mgr->bo_handles = util_hash_table_create(handle_hash, handle_compare);
>> pipe_mutex_init(mgr->bo_handles_mutex);
>> pipe_mutex_init(mgr->bo_va_mutex);
>>
>> @@ -839,6 +845,7 @@ radeon_winsys_bo_create(struct radeon_winsys *rws,
>> enum radeon_bo_domain domain)
>> {
>> struct radeon_drm_winsys *ws = radeon_drm_winsys(rws);
>> + struct radeon_bomgr *mgr = radeon_bomgr(ws->kman);
>> struct radeon_bo_desc desc;
>> struct pb_manager *provider;
>> struct pb_buffer *buffer;
>> @@ -860,11 +867,16 @@ radeon_winsys_bo_create(struct radeon_winsys *rws,
>> if (!buffer)
>> return NULL;
>>
>> + pipe_mutex_lock(mgr->bo_handles_mutex);
>> + util_hash_table_set(mgr->bo_handles, (void*)(uintptr_t)get_radeon_bo(buffer)->handle, buffer);
>> + pipe_mutex_unlock(mgr->bo_handles_mutex);
>> +
> This piece of code should be moved to radeon_bomgr_create_bo.
> radeon_winsys_bo_create is only a wrapper.
>
>> return (struct pb_buffer*)buffer;
>> }
>>
>> static struct pb_buffer *radeon_winsys_bo_from_handle(struct radeon_winsys *rws,
>> struct winsys_handle *whandle,
>> + unsigned height,
>> unsigned *stride)
>> {
>> struct radeon_drm_winsys *ws = radeon_drm_winsys(rws);
>> @@ -872,6 +884,7 @@ static struct pb_buffer *radeon_winsys_bo_from_handle(struct radeon_winsys *rws,
>> struct radeon_bomgr *mgr = radeon_bomgr(ws->kman);
>> struct drm_gem_open open_arg = {};
>> int r;
>> + unsigned handle, size;
>>
>> memset(&open_arg, 0, sizeof(open_arg));
>>
>> @@ -883,8 +896,20 @@ static struct pb_buffer *radeon_winsys_bo_from_handle(struct radeon_winsys *rws,
>> * The list of pairs is guarded by a mutex, of course. */
>> pipe_mutex_lock(mgr->bo_handles_mutex);
>>
>> - /* First check if there already is an existing bo for the handle. */
>> - bo = util_hash_table_get(mgr->bo_names, (void*)(uintptr_t)whandle->handle);
>> + if (whandle->type == DRM_API_HANDLE_TYPE_SHARED) {
>> + /* First check if there already is an existing bo for the handle. */
>> + bo = util_hash_table_get(mgr->bo_names, (void*)(uintptr_t)whandle->handle);
>> + } else if (whandle->type == DRM_API_HANDLE_TYPE_FD) {
>> + /* We must first get the GEM handle, as fds are unreliable keys */
>> + r = drmPrimeFDToHandle(ws->fd, whandle->handle, &handle);
>> + if (r)
>> + goto fail;
>> + bo = util_hash_table_get(mgr->bo_handles, (void*)(uintptr_t)handle);
>> + } else {
>> + /* Unknown handle type */
>> + goto fail;
>> + }
>> +
>> if (bo) {
>> /* Increase the refcount. */
>> struct pb_buffer *b = NULL;
>> @@ -898,27 +923,40 @@ static struct pb_buffer *radeon_winsys_bo_from_handle(struct radeon_winsys *rws,
>> goto fail;
>> }
>>
>> - /* Open the BO. */
>> - open_arg.name = whandle->handle;
>> - if (drmIoctl(ws->fd, DRM_IOCTL_GEM_OPEN, &open_arg)) {
>> - FREE(bo);
>> - goto fail;
>> + if (whandle->type == DRM_API_HANDLE_TYPE_SHARED) {
>> + /* Open the BO. */
>> + open_arg.name = whandle->handle;
>> + if (drmIoctl(ws->fd, DRM_IOCTL_GEM_OPEN, &open_arg)) {
>> + FREE(bo);
>> + goto fail;
>> + }
>> + handle = open_arg.handle;
>> + size = open_arg.size;
>> + bo->name = whandle->handle;
>> + } else if (whandle->type == DRM_API_HANDLE_TYPE_FD) {
>> + /* You know, it'd be really nice if we could get size out of the
>> + * dma-buf fd.
>> + */
>> + size = height * whandle->stride;
> Can you by any chance obtain the size from the kernel? The kernel
> should know it and some drivers (r300 for sure, not sure about r600)
> refuse to initialize the texture if the size is too small.
Indeed this will probably fail if the FD is containing some sort of
tiled buffer.
>
>> }
>> - bo->handle = open_arg.handle;
>> - bo->name = whandle->handle;
>> +
>> + bo->handle = handle;
>>
>> /* Initialize it. */
>> pipe_reference_init(&bo->base.reference, 1);
>> bo->base.alignment = 0;
>> bo->base.usage = PB_USAGE_GPU_WRITE | PB_USAGE_GPU_READ;
>> - bo->base.size = open_arg.size;
>> + bo->base.size = size;
>> bo->base.vtbl = &radeon_bo_vtbl;
>> bo->mgr = mgr;
>> bo->rws = mgr->rws;
>> bo->va = 0;
>> pipe_mutex_init(bo->map_mutex);
>>
>> - util_hash_table_set(mgr->bo_names, (void*)(uintptr_t)whandle->handle, bo);
>> + if (bo->name)
>> + util_hash_table_set(mgr->bo_names, (void*)(uintptr_t)bo->name, bo);
>> +
>> + util_hash_table_set(mgr->bo_handles, (void*)(uintptr_t)bo->handle, bo);
>>
>> done:
>> pipe_mutex_unlock(mgr->bo_handles_mutex);
>> @@ -956,6 +994,9 @@ done:
>> ws->allocated_vram += align(open_arg.size, 4096);
>> bo->initial_domain = RADEON_DOMAIN_VRAM;
>>
>> + if (whandle->type == DRM_API_HANDLE_TYPE_FD)
>> + bo->initial_domain = RADEON_DOMAIN_GTT;
>> +
> ws->allocated_vram shouldn't be incremented if the initial domain is
> GTT. ws->allocated_gtt should be incremented instead.
Why do we need to force this buffer to GTT anyway if it's shared using
an FD instead of an handle?
Christian.
> Marek
> _______________________________________________
> 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