diff options
author | Eric Anholt <[email protected]> | 2018-01-21 10:25:10 +0800 |
---|---|---|
committer | Eric Anholt <[email protected]> | 2018-02-01 11:02:29 -0800 |
commit | 5329f35ea12fe70e9eff131b60979b810cbc5028 (patch) | |
tree | 36d5c6a330b1e20b0c3a269698ffaeb1818362b2 /src/gallium/drivers/vc5 | |
parent | dea902c93352b875178fef9b8a65fd53e52696b3 (diff) |
broadcom/vc5: Add appropriate height padding for bank conflicts.
I thought I didn't need this because I was doing level-0-always-UIF and
that the pad there would propagate down, but it turns out that for level 1
the padding ends up being chosen by the HW. This brings us closer to
being able to turn on UIF XOR for increased performance, as well.
Diffstat (limited to 'src/gallium/drivers/vc5')
-rw-r--r-- | src/gallium/drivers/vc5/vc5_resource.c | 50 | ||||
-rw-r--r-- | src/gallium/drivers/vc5/vc5_resource.h | 1 | ||||
-rw-r--r-- | src/gallium/drivers/vc5/vc5_screen.h | 8 | ||||
-rw-r--r-- | src/gallium/drivers/vc5/vc5_state.c | 4 |
4 files changed, 63 insertions, 0 deletions
diff --git a/src/gallium/drivers/vc5/vc5_resource.c b/src/gallium/drivers/vc5/vc5_resource.c index 9ecd083b056..f37ffe928fd 100644 --- a/src/gallium/drivers/vc5/vc5_resource.c +++ b/src/gallium/drivers/vc5/vc5_resource.c @@ -327,6 +327,52 @@ vc5_resource_get_handle(struct pipe_screen *pscreen, return FALSE; } +/** + * Computes the HW's UIFblock padding for a given height/cpp. + * + * The goal of the padding is to keep pages of the same color (bank number) at + * least half a page away from each other vertically when crossing between + * between columns of UIF blocks. + */ +static uint32_t +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; + + /* 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 we fit entirely in the page cache, don't pad. */ + if (height_ub < pc_ub_rows) + return 0; + else + return half_page_ub_rows - 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; + + /* Otherwise, we're far enough away (top and bottom) to not need any + * padding. + */ + return 0; +} + static void vc5_setup_slices(struct vc5_resource *rsc) { @@ -400,6 +446,10 @@ vc5_setup_slices(struct vc5_resource *rsc) 4 * uif_block_w); level_height = align(level_height, uif_block_h); + + slice->ub_pad = vc5_get_ub_pad(rsc, + level_height); + level_height += slice->ub_pad * uif_block_h; } } diff --git a/src/gallium/drivers/vc5/vc5_resource.h b/src/gallium/drivers/vc5/vc5_resource.h index 631a7b8fba6..31b2b66cf63 100644 --- a/src/gallium/drivers/vc5/vc5_resource.h +++ b/src/gallium/drivers/vc5/vc5_resource.h @@ -74,6 +74,7 @@ struct vc5_resource_slice { uint32_t offset; uint32_t stride; 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 28925d791c9..52967e6beca 100644 --- a/src/gallium/drivers/vc5/vc5_screen.h +++ b/src/gallium/drivers/vc5/vc5_screen.h @@ -40,6 +40,14 @@ struct vc5_bo; #define VC5_MAX_DRAW_BUFFERS 4 #define VC5_MAX_ATTRIBUTES 16 +/* These are tunable parameters in the HW design, but all the V3D + * implementations agree. + */ +#define VC5_UIFCFG_BANKS 8 +#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) + struct vc5_simulator_file; struct vc5_screen { diff --git a/src/gallium/drivers/vc5/vc5_state.c b/src/gallium/drivers/vc5/vc5_state.c index ea867279a06..a055d252b65 100644 --- a/src/gallium/drivers/vc5/vc5_state.c +++ b/src/gallium/drivers/vc5/vc5_state.c @@ -31,6 +31,7 @@ #include "util/u_helpers.h" #include "vc5_context.h" +#include "vc5_tiling.h" #include "broadcom/common/v3d_macros.h" #include "broadcom/cle/v3dx_pack.h" @@ -787,6 +788,9 @@ vc5_create_sampler_view(struct pipe_context *pctx, struct pipe_resource *prsc, tex.level_0_xor_enable = (rsc->slices[0].tiling == VC5_TILING_UIF_XOR); + if (tex.level_0_is_strictly_uif) + tex.level_0_ub_pad = rsc->slices[0].ub_pad; + #if V3D_VERSION >= 40 if (tex.uif_xor_disable || tex.level_0_is_strictly_uif) { |