From c0c979eebc076b95cc8d18a013ce2968fe6311ad Mon Sep 17 00:00:00 2001 From: Jerome Glisse <jglisse@redhat.com> Date: Mon, 30 Jan 2012 17:22:13 -0500 Subject: r600g: add support for common surface allocator for tiling v13 Tiled surface have all kind of alignment constraint that needs to be met. Instead of having all this code duplicated btw ddx and mesa use common code in libdrm_radeon this also ensure that both ddx and mesa compute those alignment in the same way. v2 fix evergreen v3 fix compressed texture and workaround cube texture issue by disabling 2D array mode for cubemap (need to check if r7xx and newer are also affected by the issue) v4 fix texture array v5 fix evergreen and newer, split surface values computation from mipmap tree generation so that we can get them directly from the ddx v6 final fix to evergreen tile split value v7 fix mipmap offset to avoid to use random value, use color view depth view to address different layer as hardware is doing some magic rotation depending on the layer v8 fix COLOR_VIEW on r6xx for linear array mode, use COLOR_VIEW on evergreen, align bytes per pixel to a multiple of a dword v9 fix handling of stencil on evergreen, half fix for compressed texture v10 fix evergreen compressed texture proper support for stencil tile split. Fix stencil issue when array mode was clear by the kernel, always program stencil bo. On evergreen depth buffer bo need to be big enough to hold depth buffer + stencil buffer as even with stencil disabled things get written there. v11 rebase on top of mesa, fix pitch issue with 1d surface on evergreen, old ddx overestimate those. Fix linear case when pitch*height < 64. Fix r300g. v12 Fix linear case when pitch*height < 64 for old path, adapt to libdrm API change v13 add libdrm check Signed-off-by: Jerome Glisse <jglisse@redhat.com> --- src/gallium/winsys/radeon/drm/radeon_drm_bo.c | 29 ++++++++++++++++++++++- src/gallium/winsys/radeon/drm/radeon_drm_winsys.c | 26 ++++++++++++++++++++ src/gallium/winsys/radeon/drm/radeon_drm_winsys.h | 1 + src/gallium/winsys/radeon/drm/radeon_winsys.h | 25 ++++++++++++++++++- 4 files changed, 79 insertions(+), 2 deletions(-) (limited to 'src/gallium/winsys/radeon') diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_bo.c b/src/gallium/winsys/radeon/drm/radeon_drm_bo.c index de2906faef9..adee7b20dbc 100644 --- a/src/gallium/winsys/radeon/drm/radeon_drm_bo.c +++ b/src/gallium/winsys/radeon/drm/radeon_drm_bo.c @@ -620,9 +620,28 @@ static void *radeon_bo_map(struct pb_buffer *buf, return pb_map(buf, get_pb_usage_from_transfer_flags(usage), cs); } +static unsigned eg_tile_split(unsigned tile_split) +{ + switch (tile_split) { + case 0: tile_split = 64; break; + case 1: tile_split = 128; break; + case 2: tile_split = 256; break; + case 3: tile_split = 512; break; + default: + case 4: tile_split = 1024; break; + case 5: tile_split = 2048; break; + case 6: tile_split = 4096; break; + } + return tile_split; +} + static void radeon_bo_get_tiling(struct pb_buffer *_buf, enum radeon_bo_layout *microtiled, - enum radeon_bo_layout *macrotiled) + enum radeon_bo_layout *macrotiled, + unsigned *bankw, unsigned *bankh, + unsigned *tile_split, + unsigned *stencil_tile_split, + unsigned *mtilea) { struct radeon_bo *bo = get_radeon_bo(_buf); struct drm_radeon_gem_set_tiling args; @@ -643,6 +662,14 @@ static void radeon_bo_get_tiling(struct pb_buffer *_buf, if (args.tiling_flags & RADEON_BO_FLAGS_MACRO_TILE) *macrotiled = RADEON_LAYOUT_TILED; + if (bankw && tile_split && stencil_tile_split && mtilea && tile_split) { + *bankw = (args.tiling_flags >> RADEON_TILING_EG_BANKW_SHIFT) & RADEON_TILING_EG_BANKW_MASK; + *bankh = (args.tiling_flags >> RADEON_TILING_EG_BANKH_SHIFT) & RADEON_TILING_EG_BANKH_MASK; + *tile_split = (args.tiling_flags >> RADEON_TILING_EG_TILE_SPLIT_SHIFT) & RADEON_TILING_EG_TILE_SPLIT_MASK; + *stencil_tile_split = (args.tiling_flags >> RADEON_TILING_EG_STENCIL_TILE_SPLIT_SHIFT) & RADEON_TILING_EG_STENCIL_TILE_SPLIT_MASK; + *mtilea = (args.tiling_flags >> RADEON_TILING_EG_MACRO_TILE_ASPECT_SHIFT) & RADEON_TILING_EG_MACRO_TILE_ASPECT_MASK; + *tile_split = eg_tile_split(*tile_split); + } } static void radeon_bo_set_tiling(struct pb_buffer *_buf, diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c b/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c index 051a390ed22..dbec259d7f3 100644 --- a/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c +++ b/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c @@ -302,6 +302,7 @@ static void radeon_winsys_destroy(struct radeon_winsys *rws) ws->cman->destroy(ws->cman); ws->kman->destroy(ws->kman); + radeon_surface_manager_free(ws->surf_man); FREE(rws); } @@ -339,6 +340,22 @@ static boolean radeon_cs_request_feature(struct radeon_winsys_cs *rcs, return FALSE; } +static int radeon_drm_winsys_surface_init(struct radeon_winsys *rws, + struct radeon_surface *surf) +{ + struct radeon_drm_winsys *ws = (struct radeon_drm_winsys*)rws; + + return radeon_surface_init(ws->surf_man, surf); +} + +static int radeon_drm_winsys_surface_best(struct radeon_winsys *rws, + struct radeon_surface *surf) +{ + struct radeon_drm_winsys *ws = (struct radeon_drm_winsys*)rws; + + return radeon_surface_best(ws->surf_man, surf); +} + struct radeon_winsys *radeon_drm_winsys_create(int fd) { struct radeon_drm_winsys *ws = CALLOC_STRUCT(radeon_drm_winsys); @@ -359,10 +376,17 @@ struct radeon_winsys *radeon_drm_winsys_create(int fd) if (!ws->cman) goto fail; + /* FIXME check for libdrm version ?? */ + ws->surf_man = radeon_surface_manager_new(fd); + if (!ws->surf_man) + goto fail; + /* Set functions. */ ws->base.destroy = radeon_winsys_destroy; ws->base.query_info = radeon_query_info; ws->base.cs_request_feature = radeon_cs_request_feature; + ws->base.surface_init = radeon_drm_winsys_surface_init; + ws->base.surface_best = radeon_drm_winsys_surface_best; radeon_bomgr_init_functions(ws); radeon_drm_cs_init_functions(ws); @@ -377,6 +401,8 @@ fail: ws->cman->destroy(ws->cman); if (ws->kman) ws->kman->destroy(ws->kman); + if (ws->surf_man) + radeon_surface_manager_free(ws->surf_man); FREE(ws); return NULL; } diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_winsys.h b/src/gallium/winsys/radeon/drm/radeon_drm_winsys.h index 69216448496..6ac86bcfabb 100644 --- a/src/gallium/winsys/radeon/drm/radeon_drm_winsys.h +++ b/src/gallium/winsys/radeon/drm/radeon_drm_winsys.h @@ -49,6 +49,7 @@ struct radeon_drm_winsys { struct pb_manager *kman; struct pb_manager *cman; + struct radeon_surface_manager *surf_man; uint32_t num_cpus; /* Number of CPUs. */ diff --git a/src/gallium/winsys/radeon/drm/radeon_winsys.h b/src/gallium/winsys/radeon/drm/radeon_winsys.h index 9afd7f8ac82..6fbe765d6b1 100644 --- a/src/gallium/winsys/radeon/drm/radeon_winsys.h +++ b/src/gallium/winsys/radeon/drm/radeon_winsys.h @@ -43,6 +43,7 @@ #include "pipebuffer/pb_bufmgr.h" #include "pipe/p_defines.h" #include "pipe/p_state.h" +#include "libdrm/radeon_surface.h" #define RADEON_MAX_CMDBUF_DWORDS (16 * 1024) @@ -200,7 +201,11 @@ struct radeon_winsys { */ void (*buffer_get_tiling)(struct pb_buffer *buf, enum radeon_bo_layout *microtile, - enum radeon_bo_layout *macrotile); + enum radeon_bo_layout *macrotile, + unsigned *bankw, unsigned *bankh, + unsigned *tile_split, + unsigned *stencil_tile_split, + unsigned *mtilea); /** * Set tiling flags describing a memory layout of a buffer object. @@ -347,6 +352,24 @@ struct radeon_winsys { boolean (*cs_request_feature)(struct radeon_winsys_cs *cs, enum radeon_feature_id fid, boolean enable); + + /** + * Initialize surface + * + * \param ws The winsys this function is called from. + * \param surf Surface structure ptr + */ + int (*surface_init)(struct radeon_winsys *ws, + struct radeon_surface *surf); + + /** + * Find best values for a surface + * + * \param ws The winsys this function is called from. + * \param surf Surface structure ptr + */ + int (*surface_best)(struct radeon_winsys *ws, + struct radeon_surface *surf); }; #endif -- cgit v1.2.3