From 8a74f7422bedb419f3527bb1ccd60e1e9220502c Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 18 Oct 2010 09:45:58 +1000 Subject: [PATCH] r600g: retrieve tiling info from kernel for shared buffers. we need to know if the back is tiled so we can blit from it properly. --- src/gallium/drivers/r600/r600.h | 2 +- src/gallium/drivers/r600/r600_buffer.c | 2 +- src/gallium/drivers/r600/r600_texture.c | 7 +++++-- src/gallium/winsys/r600/drm/r600_bo.c | 18 +++++++++++++++++- src/gallium/winsys/r600/drm/r600_priv.h | 7 ++++++- src/gallium/winsys/r600/drm/radeon_bo.c | 19 +++++++++++++++++++ 6 files changed, 49 insertions(+), 6 deletions(-) diff --git a/src/gallium/drivers/r600/r600.h b/src/gallium/drivers/r600/r600.h index 15ee001..62d9832 100644 --- a/src/gallium/drivers/r600/r600.h +++ b/src/gallium/drivers/r600/r600.h @@ -114,7 +114,7 @@ struct r600_bo; struct r600_bo *r600_bo(struct radeon *radeon, unsigned size, unsigned alignment, unsigned usage); struct r600_bo *r600_bo_handle(struct radeon *radeon, - unsigned handle); + unsigned handle, unsigned *array_mode); void *r600_bo_map(struct radeon *radeon, struct r600_bo *bo, unsigned usage, void *ctx); void r600_bo_unmap(struct radeon *radeon, struct r600_bo *bo); void r600_bo_reference(struct radeon *radeon, struct r600_bo **dst, diff --git a/src/gallium/drivers/r600/r600_buffer.c b/src/gallium/drivers/r600/r600_buffer.c index 2bfa4e2..455aa2e 100644 --- a/src/gallium/drivers/r600/r600_buffer.c +++ b/src/gallium/drivers/r600/r600_buffer.c @@ -227,7 +227,7 @@ struct pipe_resource *r600_buffer_from_handle(struct pipe_screen *screen, struct r600_resource *rbuffer; struct r600_bo *bo = NULL; - bo = r600_bo_handle(rw, whandle->handle); + bo = r600_bo_handle(rw, whandle->handle, NULL); if (bo == NULL) { return NULL; } diff --git a/src/gallium/drivers/r600/r600_texture.c b/src/gallium/drivers/r600/r600_texture.c index edaebf8..95906a7 100644 --- a/src/gallium/drivers/r600/r600_texture.c +++ b/src/gallium/drivers/r600/r600_texture.c @@ -192,6 +192,8 @@ r600_texture_create_object(struct pipe_screen *screen, rtex->pitch_override = pitch_in_bytes_override; rtex->array_mode = array_mode; + if (array_mode) + rtex->tiled = 1; r600_setup_miptree(screen, rtex); resource->size = rtex->size; @@ -271,18 +273,19 @@ struct pipe_resource *r600_texture_from_handle(struct pipe_screen *screen, { struct radeon *rw = (struct radeon*)screen->winsys; struct r600_bo *bo = NULL; + unsigned array_mode = 0; /* Support only 2D textures without mipmaps */ if ((templ->target != PIPE_TEXTURE_2D && templ->target != PIPE_TEXTURE_RECT) || templ->depth0 != 1 || templ->last_level != 0) return NULL; - bo = r600_bo_handle(rw, whandle->handle); + bo = r600_bo_handle(rw, whandle->handle, &array_mode); if (bo == NULL) { return NULL; } - return (struct pipe_resource *)r600_texture_create_object(screen, templ, 0, + return (struct pipe_resource *)r600_texture_create_object(screen, templ, array_mode, whandle->stride, 0, bo); diff --git a/src/gallium/winsys/r600/drm/r600_bo.c b/src/gallium/winsys/r600/drm/r600_bo.c index 9498f3a..7d54ff1 100644 --- a/src/gallium/winsys/r600/drm/r600_bo.c +++ b/src/gallium/winsys/r600/drm/r600_bo.c @@ -26,7 +26,9 @@ #include #include #include +#include "radeon_drm.h" #include "r600_priv.h" +#include "r600d.h" struct r600_bo *r600_bo(struct radeon *radeon, unsigned size, unsigned alignment, unsigned usage) @@ -55,7 +57,7 @@ struct r600_bo *r600_bo(struct radeon *radeon, } struct r600_bo *r600_bo_handle(struct radeon *radeon, - unsigned handle) + unsigned handle, unsigned *array_mode) { struct r600_bo *ws_bo = calloc(1, sizeof(struct r600_bo)); struct radeon_bo *bo; @@ -68,6 +70,20 @@ struct r600_bo *r600_bo_handle(struct radeon *radeon, bo = radeon_bo_pb_get_bo(ws_bo->pb); ws_bo->size = bo->size; pipe_reference_init(&ws_bo->reference, 1); + + radeon_bo_get_tiling_flags(radeon, bo, &ws_bo->tiling_flags, + &ws_bo->kernel_pitch); + if (array_mode) { + if (ws_bo->tiling_flags) { + if (ws_bo->tiling_flags & RADEON_TILING_MICRO) + *array_mode = V_0280A0_ARRAY_1D_TILED_THIN1; + if ((ws_bo->tiling_flags & (RADEON_TILING_MICRO | RADEON_TILING_MACRO)) == + (RADEON_TILING_MICRO | RADEON_TILING_MACRO)) + *array_mode = V_0280A0_ARRAY_2D_TILED_THIN1; + } else { + *array_mode = 0; + } + } return ws_bo; } diff --git a/src/gallium/winsys/r600/drm/r600_priv.h b/src/gallium/winsys/r600/drm/r600_priv.h index 08e243b..b5bd7bd 100644 --- a/src/gallium/winsys/r600/drm/r600_priv.h +++ b/src/gallium/winsys/r600/drm/r600_priv.h @@ -77,6 +77,8 @@ struct r600_bo { struct pipe_reference reference; struct pb_buffer *pb; unsigned size; + unsigned tiling_flags; + unsigned kernel_pitch; }; @@ -95,7 +97,10 @@ int radeon_bo_wait(struct radeon *radeon, struct radeon_bo *bo); int radeon_bo_busy(struct radeon *radeon, struct radeon_bo *bo, uint32_t *domain); void radeon_bo_pbmgr_flush_maps(struct pb_manager *_mgr); int radeon_bo_fencelist(struct radeon *radeon, struct radeon_bo **bolist, uint32_t num_bo); - +int radeon_bo_get_tiling_flags(struct radeon *radeon, + struct radeon_bo *bo, + uint32_t *tiling_flags, + uint32_t *pitch); /* radeon_bo_pb.c */ struct radeon_bo *radeon_bo_pb_get_bo(struct pb_buffer *_buf); diff --git a/src/gallium/winsys/r600/drm/radeon_bo.c b/src/gallium/winsys/r600/drm/radeon_bo.c index 14a0016..9d664b7 100644 --- a/src/gallium/winsys/r600/drm/radeon_bo.c +++ b/src/gallium/winsys/r600/drm/radeon_bo.c @@ -200,3 +200,22 @@ int radeon_bo_busy(struct radeon *radeon, struct radeon_bo *bo, uint32_t *domain *domain = args.domain; return ret; } + +int radeon_bo_get_tiling_flags(struct radeon *radeon, + struct radeon_bo *bo, + uint32_t *tiling_flags, + uint32_t *pitch) +{ + struct drm_radeon_gem_get_tiling args; + int ret; + + args.handle = bo->handle; + ret = drmCommandWriteRead(radeon->fd, DRM_RADEON_GEM_GET_TILING, + &args, sizeof(args)); + if (ret) + return ret; + + *tiling_flags = args.tiling_flags; + *pitch = args.pitch; + return ret; +} -- 2.7.4