From 6a862b0de711955902d4d58f1b0c6063e76207a6 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 2 Feb 2018 08:50:51 -0800 Subject: [PATCH] broadcom/vc5: Fix alignment of miplevel 1 with UIF. The alignment here means that we can't get back the padded height from the size/stride any more, so it's now a field in the slice as well. Fixes piglit fbo-generatemipmap-formats RGBA16 NPOT. --- src/gallium/drivers/vc5/vc5_resource.c | 42 +++++++++++++++++--------- src/gallium/drivers/vc5/vc5_resource.h | 1 + src/gallium/drivers/vc5/vc5_screen.h | 3 ++ 3 files changed, 31 insertions(+), 15 deletions(-) diff --git a/src/gallium/drivers/vc5/vc5_resource.c b/src/gallium/drivers/vc5/vc5_resource.c index e2fe2826c2e..40697ce6de2 100644 --- a/src/gallium/drivers/vc5/vc5_resource.c +++ b/src/gallium/drivers/vc5/vc5_resource.c @@ -74,7 +74,7 @@ vc5_debug_resource_layout(struct vc5_resource *rsc, const char *caller) struct vc5_resource_slice *slice = &rsc->slices[i]; int level_width = slice->stride / rsc->cpp; - int level_height = slice->size / slice->stride; + int level_height = slice->padded_height; fprintf(stderr, "rsc %s %p (format %s), %dx%d: " @@ -133,7 +133,7 @@ vc5_resource_transfer_unmap(struct pipe_context *pctx, slice->stride, trans->map, ptrans->stride, slice->tiling, rsc->cpp, - slice->size / slice->stride, + slice->padded_height, &ptrans->box); } free(trans->map); @@ -264,7 +264,7 @@ vc5_resource_transfer_map(struct pipe_context *pctx, ptrans->box.z * rsc->cube_map_stride, slice->stride, slice->tiling, rsc->cpp, - slice->size / slice->stride, + slice->padded_height, &ptrans->box); } return trans->map; @@ -326,6 +326,11 @@ vc5_resource_get_handle(struct pipe_screen *pscreen, return FALSE; } +#define PAGE_UB_ROWS (VC5_UIFCFG_PAGE_SIZE / VC5_UIFBLOCK_ROW_SIZE) +#define PAGE_UB_ROWS_TIMES_1_5 ((PAGE_UB_ROWS * 3) >> 1) +#define PAGE_CACHE_UB_ROWS (VC5_PAGE_CACHE_SIZE / VC5_UIFBLOCK_ROW_SIZE) +#define PAGE_CACHE_MINUS_1_5_UB_ROWS (PAGE_CACHE_UB_ROWS - PAGE_UB_ROWS_TIMES_1_5) + /** * Computes the HW's UIFblock padding for a given height/cpp. * @@ -339,32 +344,27 @@ vc5_get_ub_pad(struct vc5_resource *rsc, uint32_t height) uint32_t utile_h = vc5_utile_height(rsc->cpp); uint32_t uif_block_h = utile_h * 2; uint32_t height_ub = height / uif_block_h; - uint32_t ub_row_size = 256 * 4; - uint32_t page_ub_rows = VC5_UIFCFG_PAGE_SIZE / ub_row_size; - uint32_t pc_ub_rows = VC5_PAGE_CACHE_SIZE / ub_row_size; - uint32_t height_offset_in_pc = height_ub % pc_ub_rows; + uint32_t height_offset_in_pc = height_ub % PAGE_CACHE_UB_ROWS; /* For the perfectly-aligned-for-UIF-XOR case, don't add any pad. */ if (height_offset_in_pc == 0) return 0; - uint32_t half_page_ub_rows = (page_ub_rows * 3) >> 1; - /* Try padding up to where we're offset by at least half a page. */ - if (height_offset_in_pc < half_page_ub_rows) { + if (height_offset_in_pc < PAGE_UB_ROWS_TIMES_1_5) { /* If we fit entirely in the page cache, don't pad. */ - if (height_ub < pc_ub_rows) + if (height_ub < PAGE_CACHE_UB_ROWS) return 0; else - return half_page_ub_rows - height_offset_in_pc; + return PAGE_UB_ROWS_TIMES_1_5 - height_offset_in_pc; } /* If we're close to being aligned to page cache size, then round up * and rely on XOR. */ - if (height_offset_in_pc > (pc_ub_rows - half_page_ub_rows)) - return pc_ub_rows - height_offset_in_pc; + if (height_offset_in_pc > PAGE_CACHE_MINUS_1_5_UB_ROWS) + return PAGE_CACHE_UB_ROWS - height_offset_in_pc; /* Otherwise, we're far enough away (top and bottom) to not need any * padding. @@ -454,8 +454,20 @@ vc5_setup_slices(struct vc5_resource *rsc) slice->offset = offset; slice->stride = level_width * rsc->cpp; + slice->padded_height = level_height; slice->size = level_height * slice->stride; + /* The HW aligns level 1's base to a page if any of level 1 or + * below could be UIF XOR. The lower levels then inherit the + * alignment for as long as necesary, thanks to being power of + * two aligned. + */ + if (i == 1 && + level_width > 4 * uif_block_w && + level_height > PAGE_CACHE_MINUS_1_5_UB_ROWS * uif_block_h) { + slice->size = align(slice->size, VC5_UIFCFG_PAGE_SIZE); + } + offset += slice->size; } @@ -744,7 +756,7 @@ vc5_create_surface(struct pipe_context *pctx, if (surface->tiling == VC5_TILING_UIF_NO_XOR || surface->tiling == VC5_TILING_UIF_XOR) { surface->padded_height_of_output_image_in_uif_blocks = - ((slice->size / slice->stride) / + (slice->padded_height / (2 * vc5_utile_height(rsc->cpp))); } diff --git a/src/gallium/drivers/vc5/vc5_resource.h b/src/gallium/drivers/vc5/vc5_resource.h index 31b2b66cf63..1bba480115b 100644 --- a/src/gallium/drivers/vc5/vc5_resource.h +++ b/src/gallium/drivers/vc5/vc5_resource.h @@ -73,6 +73,7 @@ struct vc5_transfer { struct vc5_resource_slice { uint32_t offset; uint32_t stride; + uint32_t padded_height; uint32_t size; uint8_t ub_pad; enum vc5_tiling_mode tiling; diff --git a/src/gallium/drivers/vc5/vc5_screen.h b/src/gallium/drivers/vc5/vc5_screen.h index 52967e6beca..710396de999 100644 --- a/src/gallium/drivers/vc5/vc5_screen.h +++ b/src/gallium/drivers/vc5/vc5_screen.h @@ -47,6 +47,9 @@ struct vc5_bo; #define VC5_UIFCFG_PAGE_SIZE 4096 #define VC5_UIFCFG_XOR_VALUE (1 << 4) #define VC5_PAGE_CACHE_SIZE (VC5_UIFCFG_PAGE_SIZE * VC5_UIFCFG_BANKS) +#define VC5_UBLOCK_SIZE 64 +#define VC5_UIFBLOCK_SIZE (4 * VC5_UBLOCK_SIZE) +#define VC5_UIFBLOCK_ROW_SIZE (4 * VC5_UIFBLOCK_SIZE) struct vc5_simulator_file;