diff options
author | Eric Anholt <[email protected]> | 2019-11-26 12:02:34 -0800 |
---|---|---|
committer | Eric Anholt <[email protected]> | 2019-12-11 04:24:18 +0000 |
commit | d9cf3e76bd45e83721f8ab7b9322302741d99668 (patch) | |
tree | 9efbba823e31f28bc483110154e1b6b09f6f45cf /src/gallium/drivers/freedreno | |
parent | 67258a44d2c7d77509e0983e5925940bcee277cf (diff) |
freedreno: Move a6xx's setup_slices() to a shareable helper function.
We pass in all the parameters for setting up the layout, though freedreno
still sets a few of them up early (since it uses layout helpers in making
some decisions about the layout setup parameters that will be cleaned up
once krh's blitter work lands).
Diffstat (limited to 'src/gallium/drivers/freedreno')
-rw-r--r-- | src/gallium/drivers/freedreno/a6xx/fd6_resource.c | 155 | ||||
-rw-r--r-- | src/gallium/drivers/freedreno/freedreno_resource.c | 8 | ||||
-rw-r--r-- | src/gallium/drivers/freedreno/meson.build | 2 |
3 files changed, 19 insertions, 146 deletions
diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_resource.c b/src/gallium/drivers/freedreno/a6xx/fd6_resource.c index 4a35dd6db2f..8801982a7a7 100644 --- a/src/gallium/drivers/freedreno/a6xx/fd6_resource.c +++ b/src/gallium/drivers/freedreno/a6xx/fd6_resource.c @@ -30,139 +30,6 @@ #include "a6xx.xml.h" -/* indexed by cpp, including msaa 2x and 4x: */ -static const struct { - unsigned pitchalign; - unsigned heightalign; -} tile_alignment[] = { - [1] = { 128, 32 }, - [2] = { 64, 32 }, - [3] = { 64, 32 }, - [4] = { 64, 16 }, - [6] = { 64, 16 }, - [8] = { 64, 16 }, - [12] = { 64, 16 }, - [16] = { 64, 16 }, - [24] = { 64, 16 }, - [32] = { 64, 16 }, - [48] = { 64, 16 }, - [64] = { 64, 16 }, - - /* special cases for r16: */ - [0] = { 128, 16 }, -}; - -/* NOTE: good way to test this is: (for example) - * piglit/bin/texelFetch fs sampler3D 100x100x8 - */ -static uint32_t -setup_slices(struct fd_resource *rsc, uint32_t alignment, enum pipe_format format) -{ - struct pipe_resource *prsc = &rsc->base; - struct fd_screen *screen = fd_screen(prsc->screen); - enum util_format_layout layout = util_format_description(format)->layout; - uint32_t pitchalign = screen->gmem_alignw; - uint32_t level, size = 0; - uint32_t depth = prsc->depth0; - /* linear dimensions: */ - uint32_t lwidth = prsc->width0; - uint32_t lheight = prsc->height0; - /* tile_mode dimensions: */ - uint32_t twidth = util_next_power_of_two(lwidth); - uint32_t theight = util_next_power_of_two(lheight); - /* in layer_first layout, the level (slice) contains just one - * layer (since in fact the layer contains the slices) - */ - uint32_t layers_in_level = rsc->layout.layer_first ? 1 : prsc->array_size; - int ta = rsc->layout.cpp; - - /* The z16/r16 formats seem to not play by the normal tiling rules: */ - if ((rsc->layout.cpp == 2) && (util_format_get_nr_components(format) == 1)) - ta = 0; - - debug_assert(ta < ARRAY_SIZE(tile_alignment)); - debug_assert(tile_alignment[ta].pitchalign); - - for (level = 0; level <= prsc->last_level; level++) { - struct fdl_slice *slice = fd_resource_slice(rsc, level); - uint32_t tile_mode = fd_resource_tile_mode(prsc, level); - uint32_t width, height; - - /* tiled levels of 3D textures are rounded up to PoT dimensions: */ - if ((prsc->target == PIPE_TEXTURE_3D) && tile_mode) { - width = twidth; - height = theight; - } else { - width = lwidth; - height = lheight; - } - uint32_t aligned_height = height; - uint32_t blocks; - - if (tile_mode) { - pitchalign = tile_alignment[ta].pitchalign; - aligned_height = align(aligned_height, - tile_alignment[ta].heightalign); - } else { - pitchalign = 64; - } - - /* The blits used for mem<->gmem work at a granularity of - * 32x32, which can cause faults due to over-fetch on the - * last level. The simple solution is to over-allocate a - * bit the last level to ensure any over-fetch is harmless. - * The pitch is already sufficiently aligned, but height - * may not be: - */ - if ((level == prsc->last_level) && (prsc->target != PIPE_BUFFER)) - aligned_height = align(aligned_height, 32); - - if (layout == UTIL_FORMAT_LAYOUT_ASTC) - slice->pitch = - util_align_npot(width, pitchalign * util_format_get_blockwidth(format)); - else - slice->pitch = align(width, pitchalign); - - slice->offset = size; - blocks = util_format_get_nblocks(format, slice->pitch, aligned_height); - - /* 1d array and 2d array textures must all have the same layer size - * for each miplevel on a6xx. 3d textures can have different layer - * sizes for high levels, but the hw auto-sizer is buggy (or at least - * different than what this code does), so as soon as the layer size - * range gets into range, we stop reducing it. - */ - if (prsc->target == PIPE_TEXTURE_3D) { - if (level < 1 || fd_resource_slice(rsc, level - 1)->size0 > 0xf000) { - slice->size0 = align(blocks * rsc->layout.cpp, alignment); - } else { - slice->size0 = fd_resource_slice(rsc, level - 1)->size0; - } - } else { - slice->size0 = align(blocks * rsc->layout.cpp, alignment); - } - - size += slice->size0 * depth * layers_in_level; - -#if 0 - fprintf(stderr, "%s: %ux%ux%u@%u:\t%2u: stride=%4u, size=%6u,%7u, aligned_height=%3u, blocks=%u, offset=0x%x tiling=%d\n", - util_format_name(prsc->format), - width, height, depth, rsc->layout.cpp, - level, slice->pitch * rsc->layout.cpp, - slice->size0, size, aligned_height, blocks, - slice->offset, fd_resource_tile_mode(prsc, level)); -#endif - - depth = u_minify(depth, 1); - lwidth = u_minify(lwidth, 1); - lheight = u_minify(lheight, 1); - twidth = u_minify(twidth, 1); - theight = u_minify(theight, 1); - } - - return size; -} - /* A subset of the valid tiled formats can be compressed. We do * already require tiled in order to be compressed, but just because * it can be tiled doesn't mean it can be compressed. @@ -325,21 +192,19 @@ setup_lrz(struct fd_resource *rsc) uint32_t fd6_setup_slices(struct fd_resource *rsc) { - uint32_t alignment; + struct pipe_resource *prsc = &rsc->base; if (!(fd_mesa_debug & FD_DBG_NOLRZ) && has_depth(rsc->base.format)) setup_lrz(rsc); - switch (rsc->base.target) { - case PIPE_TEXTURE_3D: - rsc->layout.layer_first = false; - alignment = 4096; - break; - default: - rsc->layout.layer_first = true; - alignment = 1; - break; - } + fdl6_layout(&rsc->layout, prsc->format, fd_resource_nr_samples(prsc), + prsc->width0, prsc->height0, prsc->depth0, + prsc->last_level + 1, prsc->array_size, + prsc->target == PIPE_TEXTURE_3D); - return setup_slices(rsc, alignment, rsc->base.format); + /* The caller does this bit of layout setup again. */ + if (rsc->layout.layer_first) + return rsc->layout.size / prsc->array_size; + else + return rsc->layout.size; } diff --git a/src/gallium/drivers/freedreno/freedreno_resource.c b/src/gallium/drivers/freedreno/freedreno_resource.c index 5826e16c154..10e9196886f 100644 --- a/src/gallium/drivers/freedreno/freedreno_resource.c +++ b/src/gallium/drivers/freedreno/freedreno_resource.c @@ -991,7 +991,13 @@ fd_resource_create_with_modifiers(struct pipe_screen *pscreen, rsc->internal_format = format; - size = screen->setup_slices(rsc); + if (prsc->target == PIPE_BUFFER) { + assert(prsc->format == PIPE_FORMAT_R8_UNORM); + size = prsc->width0; + fdl_layout_buffer(&rsc->layout, size); + } else { + size = screen->setup_slices(rsc); + } if (allow_ubwc && screen->fill_ubwc_buffer_sizes && rsc->layout.tile_mode) size += screen->fill_ubwc_buffer_sizes(rsc); diff --git a/src/gallium/drivers/freedreno/meson.build b/src/gallium/drivers/freedreno/meson.build index 09cf125c61d..7125ecd274f 100644 --- a/src/gallium/drivers/freedreno/meson.build +++ b/src/gallium/drivers/freedreno/meson.build @@ -243,6 +243,7 @@ driver_freedreno = declare_dependency( libfreedreno, libfreedreno_drm, libfreedreno_ir3, + libfreedreno_layout, libfreedreno_perfcntrs ], dependencies : idep_nir, @@ -260,6 +261,7 @@ ir3_compiler = executable( libfreedreno, libfreedreno_drm, libfreedreno_ir3, + libfreedreno_layout, libgallium, libglsl_standalone, ], |