From aa2186db0e8c8cc5ed9a9ab6995948e36067f8ba Mon Sep 17 00:00:00 2001 From: Jonathan Marek Date: Tue, 21 Jan 2020 16:51:17 -0500 Subject: [PATCH] freedreno: move a4xx specific layout code to a4xx code Every other gen has its own setup_slices Signed-off-by: Jonathan Marek Part-of: --- .../drivers/freedreno/Makefile.sources | 2 + .../drivers/freedreno/a4xx/fd4_resource.c | 125 ++++++++++++++++++ .../drivers/freedreno/a4xx/fd4_resource.h | 35 +++++ .../drivers/freedreno/a4xx/fd4_screen.c | 2 + .../drivers/freedreno/freedreno_resource.c | 100 -------------- src/gallium/drivers/freedreno/meson.build | 2 + 6 files changed, 166 insertions(+), 100 deletions(-) create mode 100644 src/gallium/drivers/freedreno/a4xx/fd4_resource.c create mode 100644 src/gallium/drivers/freedreno/a4xx/fd4_resource.h diff --git a/src/gallium/drivers/freedreno/Makefile.sources b/src/gallium/drivers/freedreno/Makefile.sources index f6cb2bd3fac..f7586017c23 100644 --- a/src/gallium/drivers/freedreno/Makefile.sources +++ b/src/gallium/drivers/freedreno/Makefile.sources @@ -123,6 +123,8 @@ a4xx_SOURCES := \ a4xx/fd4_query.h \ a4xx/fd4_rasterizer.c \ a4xx/fd4_rasterizer.h \ + a4xx/fd4_resource.c \ + a4xx/fd4_resource.h \ a4xx/fd4_screen.c \ a4xx/fd4_screen.h \ a4xx/fd4_texture.c \ diff --git a/src/gallium/drivers/freedreno/a4xx/fd4_resource.c b/src/gallium/drivers/freedreno/a4xx/fd4_resource.c new file mode 100644 index 00000000000..f0c4de9b316 --- /dev/null +++ b/src/gallium/drivers/freedreno/a4xx/fd4_resource.c @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2012 Rob Clark + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Authors: + * Rob Clark + */ + +#include "fd4_resource.h" + +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 width = prsc->width0; + uint32_t height = prsc->height0; + uint32_t depth = prsc->depth0; + /* 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; + + for (level = 0; level <= prsc->last_level; level++) { + struct fdl_slice *slice = fd_resource_slice(rsc, level); + uint32_t blocks; + + if (layout == UTIL_FORMAT_LAYOUT_ASTC) + slice->pitch = width = + util_align_npot(width, pitchalign * util_format_get_blockwidth(format)); + else + slice->pitch = width = align(width, pitchalign); + slice->offset = size; + blocks = util_format_get_nblocks(format, width, height); + /* 1d array and 2d array textures must all have the same layer size + * for each miplevel on a3xx. 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 && ( + level == 1 || + (level > 1 && fd_resource_slice(rsc, level - 1)->size0 > 0xf000))) + slice->size0 = align(blocks * rsc->layout.cpp, alignment); + else if (level == 0 || rsc->layout.layer_first || alignment == 1) + slice->size0 = align(blocks * rsc->layout.cpp, alignment); + else + slice->size0 = fd_resource_slice(rsc, level - 1)->size0; + + size += slice->size0 * depth * layers_in_level; + + width = u_minify(width, 1); + height = u_minify(height, 1); + depth = u_minify(depth, 1); + } + + return size; +} + +static uint32_t +slice_alignment(enum pipe_texture_target target) +{ + /* on a3xx, 2d array and 3d textures seem to want their + * layers aligned to page boundaries: + */ + switch (target) { + case PIPE_TEXTURE_3D: + case PIPE_TEXTURE_1D_ARRAY: + case PIPE_TEXTURE_2D_ARRAY: + return 4096; + default: + return 1; + } +} + +/* cross generation texture layout to plug in to screen->setup_slices().. + * replace with generation specific one as-needed. + * + * TODO for a4xx probably can extract out the a4xx specific logic int + * a small fd4_setup_slices() wrapper that sets up layer_first, and then + * calls this. + */ +uint32_t +fd4_setup_slices(struct fd_resource *rsc) +{ + uint32_t alignment; + + alignment = slice_alignment(rsc->base.target); + + struct fd_screen *screen = fd_screen(rsc->base.screen); + if (is_a4xx(screen)) { + switch (rsc->base.target) { + case PIPE_TEXTURE_3D: + rsc->layout.layer_first = false; + break; + default: + rsc->layout.layer_first = true; + alignment = 1; + break; + } + } + + return setup_slices(rsc, alignment, rsc->base.format); +} diff --git a/src/gallium/drivers/freedreno/a4xx/fd4_resource.h b/src/gallium/drivers/freedreno/a4xx/fd4_resource.h new file mode 100644 index 00000000000..9c7c35809f7 --- /dev/null +++ b/src/gallium/drivers/freedreno/a4xx/fd4_resource.h @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2018 Rob Clark + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Authors: + * Rob Clark + */ + +#ifndef FD4_RESOURCE_H_ +#define FD4_RESOURCE_H_ + +#include "freedreno_resource.h" + +uint32_t fd4_setup_slices(struct fd_resource *rsc); +unsigned fd4_tile_mode(const struct pipe_resource *tmpl); + +#endif /* FD4_RESOURCE_H_ */ diff --git a/src/gallium/drivers/freedreno/a4xx/fd4_screen.c b/src/gallium/drivers/freedreno/a4xx/fd4_screen.c index db639c72c12..7f7c36da9b7 100644 --- a/src/gallium/drivers/freedreno/a4xx/fd4_screen.c +++ b/src/gallium/drivers/freedreno/a4xx/fd4_screen.c @@ -31,6 +31,7 @@ #include "fd4_context.h" #include "fd4_emit.h" #include "fd4_format.h" +#include "fd4_resource.h" #include "ir3/ir3_compiler.h" @@ -109,6 +110,7 @@ fd4_screen_init(struct pipe_screen *pscreen) struct fd_screen *screen = fd_screen(pscreen); screen->max_rts = A4XX_MAX_RENDER_TARGETS; screen->compiler = ir3_compiler_create(screen->dev, screen->gpu_id); + screen->setup_slices = fd4_setup_slices; pscreen->context_create = fd4_context_create; pscreen->is_format_supported = fd4_screen_is_format_supported; fd4_emit_init_screen(pscreen); diff --git a/src/gallium/drivers/freedreno/freedreno_resource.c b/src/gallium/drivers/freedreno/freedreno_resource.c index cf81a0c3b90..5d8a5c76f19 100644 --- a/src/gallium/drivers/freedreno/freedreno_resource.c +++ b/src/gallium/drivers/freedreno/freedreno_resource.c @@ -801,104 +801,6 @@ fd_resource_get_handle(struct pipe_screen *pscreen, fd_resource_slice(rsc, 0)->pitch, handle); } -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 width = prsc->width0; - uint32_t height = prsc->height0; - uint32_t depth = prsc->depth0; - /* 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; - - for (level = 0; level <= prsc->last_level; level++) { - struct fdl_slice *slice = fd_resource_slice(rsc, level); - uint32_t blocks; - - if (layout == UTIL_FORMAT_LAYOUT_ASTC) - width = util_align_npot(width, pitchalign * util_format_get_blockwidth(format)); - else - width = align(width, pitchalign); - slice->pitch = util_format_get_nblocksx(format, width) * rsc->layout.cpp; - slice->offset = size; - blocks = util_format_get_nblocks(format, width, height); - /* 1d array and 2d array textures must all have the same layer size - * for each miplevel on a3xx. 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 && ( - level == 1 || - (level > 1 && fd_resource_slice(rsc, level - 1)->size0 > 0xf000))) - slice->size0 = align(blocks * rsc->layout.cpp, alignment); - else if (level == 0 || rsc->layout.layer_first || alignment == 1) - slice->size0 = align(blocks * rsc->layout.cpp, alignment); - else - slice->size0 = fd_resource_slice(rsc, level - 1)->size0; - - size += slice->size0 * depth * layers_in_level; - - width = u_minify(width, 1); - height = u_minify(height, 1); - depth = u_minify(depth, 1); - } - - return size; -} - -static uint32_t -slice_alignment(enum pipe_texture_target target) -{ - /* on a3xx, 2d array and 3d textures seem to want their - * layers aligned to page boundaries: - */ - switch (target) { - case PIPE_TEXTURE_3D: - case PIPE_TEXTURE_1D_ARRAY: - case PIPE_TEXTURE_2D_ARRAY: - return 4096; - default: - return 1; - } -} - -/* cross generation texture layout to plug in to screen->setup_slices().. - * replace with generation specific one as-needed. - * - * TODO for a4xx probably can extract out the a4xx specific logic int - * a small fd4_setup_slices() wrapper that sets up layer_first, and then - * calls this. - */ -uint32_t -fd_setup_slices(struct fd_resource *rsc) -{ - uint32_t alignment; - - alignment = slice_alignment(rsc->base.target); - - struct fd_screen *screen = fd_screen(rsc->base.screen); - if (is_a4xx(screen)) { - switch (rsc->base.target) { - case PIPE_TEXTURE_3D: - rsc->layout.layer_first = false; - break; - default: - rsc->layout.layer_first = true; - alignment = 1; - break; - } - } - - return setup_slices(rsc, alignment, rsc->base.format); -} - /* special case to resize query buf after allocated.. */ void fd_resource_resize(struct pipe_resource *prsc, uint32_t sz) @@ -1268,8 +1170,6 @@ fd_resource_screen_init(struct pipe_screen *pscreen) pscreen->transfer_helper = u_transfer_helper_create(&transfer_vtbl, true, false, fake_rgtc, true); - if (!screen->setup_slices) - screen->setup_slices = fd_setup_slices; if (!screen->layout_resource_for_modifier) screen->layout_resource_for_modifier = fd_layout_resource_for_modifier; if (!screen->supported_modifiers) { diff --git a/src/gallium/drivers/freedreno/meson.build b/src/gallium/drivers/freedreno/meson.build index 0e1d7a877e2..8284f5e1a6d 100644 --- a/src/gallium/drivers/freedreno/meson.build +++ b/src/gallium/drivers/freedreno/meson.build @@ -137,6 +137,8 @@ files_libfreedreno = files( 'a4xx/fd4_query.h', 'a4xx/fd4_rasterizer.c', 'a4xx/fd4_rasterizer.h', + 'a4xx/fd4_resource.c', + 'a4xx/fd4_resource.h', 'a4xx/fd4_screen.c', 'a4xx/fd4_screen.h', 'a4xx/fd4_texture.c', -- 2.30.2