From: Jonathan Marek Date: Tue, 7 Jul 2020 22:27:32 +0000 (-0400) Subject: freedreno/layout: layout simplifications and pitch from level 0 pitch X-Git-Url: https://git.libre-soc.org/?p=mesa.git;a=commitdiff_plain;h=979e7e3680792dc23d434295edd10b161af8aee3 freedreno/layout: layout simplifications and pitch from level 0 pitch This updates a3xx/a4xx/a5xx to fix the fetchsize to "PITCHALIGN" (called "MINLINEOFFSET" by the a3xx docs), and some simplifications to make things more like a6xx. Also similar simplifications for a2xx layout code. The pitch can always be determined using a simple calculation from the base level pitch, so don't pre-calculate a pitch for each mipmap level. Signed-off-by: Jonathan Marek Part-of: --- diff --git a/src/freedreno/fdl/fd5_layout.c b/src/freedreno/fdl/fd5_layout.c index da74b18fe59..159773fff61 100644 --- a/src/freedreno/fdl/fd5_layout.c +++ b/src/freedreno/fdl/fd5_layout.c @@ -29,29 +29,12 @@ #include "freedreno_layout.h" -/* indexed by cpp: */ -static const struct { - unsigned pitchalign; - unsigned heightalign; -} tile_alignment[] = { - [1] = { 128, 32 }, - [2] = { 128, 16 }, - [3] = { 128, 16 }, - [4] = { 64, 16 }, - [8] = { 64, 16 }, - [12] = { 64, 16 }, - [16] = { 64, 16 }, -}; - void fdl5_layout(struct fdl_layout *layout, enum pipe_format format, uint32_t nr_samples, uint32_t width0, uint32_t height0, uint32_t depth0, uint32_t mip_levels, uint32_t array_size, bool is_3d) { - const struct util_format_description *format_desc = - util_format_description(format); - assert(nr_samples > 0); layout->width0 = width0; layout->height0 = height0; @@ -65,30 +48,27 @@ fdl5_layout(struct fdl_layout *layout, layout->nr_samples = nr_samples; layout->layer_first = !is_3d; - uint32_t pitchalign; - uint32_t heightalign; - uint32_t width = width0; - uint32_t height = height0; - uint32_t depth = depth0; + uint32_t heightalign = layout->cpp == 1 ? 32 : 16; /* in layer_first layout, the level (slice) contains just one * layer (since in fact the layer contains the slices) */ uint32_t layers_in_level = layout->layer_first ? 1 : array_size; - heightalign = tile_alignment[layout->cpp].heightalign; + /* use 128 pixel alignment for cpp=1 and cpp=2 */ + if (layout->cpp < 4 && layout->tile_mode) + fdl_set_pitchalign(layout, fdl_cpp_shift(layout) + 7); + else + fdl_set_pitchalign(layout, fdl_cpp_shift(layout) + 6); for (uint32_t level = 0; level < mip_levels; level++) { struct fdl_slice *slice = &layout->slices[level]; uint32_t tile_mode = fdl_tile_mode(layout, level); - uint32_t aligned_height = height; - uint32_t blocks; + uint32_t pitch = fdl_pitch(layout, level); + uint32_t nblocksy = util_format_get_nblocksy(format, u_minify(height0, level)); if (tile_mode) { - pitchalign = tile_alignment[layout->cpp].pitchalign; - aligned_height = align(aligned_height, heightalign); + nblocksy = align(nblocksy, 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 @@ -97,20 +77,10 @@ fdl5_layout(struct fdl_layout *layout, * may not be: */ if (level == mip_levels - 1) - aligned_height = align(aligned_height, 32); + nblocksy = align(nblocksy, 32); } - unsigned pitch_pixels; - if (format_desc->layout == UTIL_FORMAT_LAYOUT_ASTC) - pitch_pixels = - util_align_npot(width, pitchalign * util_format_get_blockwidth(format)); - else - pitch_pixels = align(width, pitchalign); - slice->offset = layout->size; - blocks = util_format_get_nblocks(format, pitch_pixels, aligned_height); - slice->pitch = util_format_get_nblocksx(format, pitch_pixels) * - layout->cpp; const int alignment = is_3d ? 4096 : 1; @@ -123,17 +93,13 @@ fdl5_layout(struct fdl_layout *layout, if (is_3d && ( level == 1 || (level > 1 && layout->slices[level - 1].size0 > 0xf000))) - slice->size0 = align(blocks * layout->cpp, alignment); + slice->size0 = align(nblocksy * pitch, alignment); else if (level == 0 || layout->layer_first || alignment == 1) - slice->size0 = align(blocks * layout->cpp, alignment); + slice->size0 = align(nblocksy * pitch, alignment); else slice->size0 = layout->slices[level - 1].size0; - layout->size += slice->size0 * depth * layers_in_level; - - width = u_minify(width, 1); - height = u_minify(height, 1); - depth = u_minify(depth, 1); + layout->size += slice->size0 * u_minify(depth0, level) * layers_in_level; } } diff --git a/src/freedreno/fdl/fd6_layout.c b/src/freedreno/fdl/fd6_layout.c index 47a6c852da7..096af1672a2 100644 --- a/src/freedreno/fdl/fd6_layout.c +++ b/src/freedreno/fdl/fd6_layout.c @@ -29,10 +29,6 @@ #include "freedreno_layout.h" -#define RGB_TILE_WIDTH_ALIGNMENT 64 -#define RGB_TILE_HEIGHT_ALIGNMENT 16 -#define UBWC_PLANE_SIZE_ALIGNMENT 4096 - static bool is_r8g8(struct fdl_layout *layout) { @@ -103,10 +99,9 @@ fdl6_layout(struct fdl_layout *layout, enum pipe_format format, uint32_t nr_samples, uint32_t width0, uint32_t height0, uint32_t depth0, uint32_t mip_levels, uint32_t array_size, bool is_3d, - struct fdl_slice *plane_layout) + struct fdl_explicit_layout *explicit_layout) { - uint32_t offset, pitch0; - uint32_t pitchalign, heightalign; + uint32_t offset = 0, heightalign; uint32_t ubwc_blockwidth, ubwc_blockheight; assert(nr_samples > 0); @@ -152,24 +147,20 @@ fdl6_layout(struct fdl_layout *layout, /* when possible, use a bit more alignment than necessary * presumably this is better for performance? */ - if (!plane_layout) + if (!explicit_layout) layout->pitchalign = fdl_cpp_shift(layout); /* not used, avoid "may be used uninitialized" warning */ heightalign = 1; } - pitchalign = 64 << layout->pitchalign; + fdl_set_pitchalign(layout, layout->pitchalign + 6); - if (plane_layout) { - offset = plane_layout->offset; - pitch0 = plane_layout->pitch; - if (align(pitch0, pitchalign) != pitch0) + if (explicit_layout) { + offset = explicit_layout->offset; + layout->pitch0 = explicit_layout->pitch; + if (align(layout->pitch0, 1 << layout->pitchalign) != layout->pitch0) return false; - } else { - uint32_t nblocksx = util_format_get_nblocksx(format, width0); - offset = 0; - pitch0 = util_align_npot(nblocksx * layout->cpp, pitchalign); } uint32_t ubwc_width0 = width0; @@ -185,8 +176,8 @@ fdl6_layout(struct fdl_layout *layout, ubwc_height0 = util_next_power_of_two(height0); ubwc_tile_height_alignment = 64; } - ubwc_width0 = align(DIV_ROUND_UP(ubwc_width0, ubwc_blockwidth), - RGB_TILE_WIDTH_ALIGNMENT); + layout->ubwc_width0 = align(DIV_ROUND_UP(ubwc_width0, ubwc_blockwidth), + RGB_TILE_WIDTH_ALIGNMENT); ubwc_height0 = align(DIV_ROUND_UP(ubwc_height0, ubwc_blockheight), ubwc_tile_height_alignment); @@ -195,6 +186,7 @@ fdl6_layout(struct fdl_layout *layout, struct fdl_slice *slice = &layout->slices[level]; struct fdl_slice *ubwc_slice = &layout->ubwc_slices[level]; uint32_t tile_mode = fdl_tile_mode(layout, level); + uint32_t pitch = fdl_pitch(layout, level); uint32_t height; /* tiled levels of 3D textures are rounded up to PoT dimensions: */ @@ -219,7 +211,6 @@ fdl6_layout(struct fdl_layout *layout, height = align(nblocksy, 4); slice->offset = offset + layout->size; - slice->pitch = align(u_minify(pitch0, level), pitchalign); /* 1d array and 2d array textures must all have the same layer size * for each miplevel on a6xx. 3d textures can have different layer @@ -229,12 +220,12 @@ fdl6_layout(struct fdl_layout *layout, */ if (is_3d) { if (level < 1 || layout->slices[level - 1].size0 > 0xf000) { - slice->size0 = align(nblocksy * slice->pitch, 4096); + slice->size0 = align(nblocksy * pitch, 4096); } else { slice->size0 = layout->slices[level - 1].size0; } } else { - slice->size0 = nblocksy * slice->pitch; + slice->size0 = nblocksy * pitch; } layout->size += slice->size0 * depth * layers_in_level; @@ -243,13 +234,11 @@ fdl6_layout(struct fdl_layout *layout, /* with UBWC every level is aligned to 4K */ layout->size = align(layout->size, 4096); - uint32_t meta_pitch = align(u_minify(ubwc_width0, level), - RGB_TILE_WIDTH_ALIGNMENT); + uint32_t meta_pitch = fdl_ubwc_pitch(layout, level); uint32_t meta_height = align(u_minify(ubwc_height0, level), ubwc_tile_height_alignment); ubwc_slice->size0 = align(meta_pitch * meta_height, UBWC_PLANE_SIZE_ALIGNMENT); - ubwc_slice->pitch = meta_pitch; ubwc_slice->offset = offset + layout->ubwc_layer_size; layout->ubwc_layer_size += ubwc_slice->size0; } diff --git a/src/freedreno/fdl/fd_layout_test.c b/src/freedreno/fdl/fd_layout_test.c index 99d17e52cc6..08e8c1b2509 100644 --- a/src/freedreno/fdl/fd_layout_test.c +++ b/src/freedreno/fdl/fd_layout_test.c @@ -89,12 +89,12 @@ bool fdl_test_layout(const struct testcase *testcase, int gpu_id) testcase->layout.slices[l].offset); ok = false; } - if (layout.slices[l].pitch != testcase->layout.slices[l].pitch) { + if (fdl_pitch(&layout, l) != testcase->layout.slices[l].pitch) { fprintf(stderr, "%s %dx%dx%d@%dx lvl%d: pitch %d != %d\n", util_format_short_name(testcase->format), layout.width0, layout.height0, layout.depth0, layout.nr_samples, l, - layout.slices[l].pitch, + fdl_pitch(&layout, l), testcase->layout.slices[l].pitch); ok = false; } @@ -108,12 +108,12 @@ bool fdl_test_layout(const struct testcase *testcase, int gpu_id) testcase->layout.ubwc_slices[l].offset); ok = false; } - if (layout.ubwc_slices[l].pitch != testcase->layout.ubwc_slices[l].pitch) { + if (fdl_ubwc_pitch(&layout, l) != testcase->layout.ubwc_slices[l].pitch) { fprintf(stderr, "%s %dx%dx%d@%dx lvl%d: UBWC pitch %d != %d\n", util_format_short_name(testcase->format), layout.width0, layout.height0, layout.depth0, layout.nr_samples, l, - layout.ubwc_slices[l].pitch, + fdl_ubwc_pitch(&layout, l), testcase->layout.ubwc_slices[l].pitch); ok = false; } diff --git a/src/freedreno/fdl/fd_layout_test.h b/src/freedreno/fdl/fd_layout_test.h index 0be7a4030a4..edf56cec511 100644 --- a/src/freedreno/fdl/fd_layout_test.h +++ b/src/freedreno/fdl/fd_layout_test.h @@ -28,7 +28,20 @@ struct testcase { bool is_3d; /* Partially filled layout of input parameters and expected results. */ - struct fdl_layout layout; + struct { + uint32_t tile_mode : 2; + bool ubwc : 1; + uint32_t width0, height0, depth0; + uint32_t nr_samples; + struct { + uint32_t offset; + uint32_t pitch; + } slices[FDL_MAX_MIP_LEVELS]; + struct { + uint32_t offset; + uint32_t pitch; + } ubwc_slices[FDL_MAX_MIP_LEVELS]; + } layout; }; bool fdl_test_layout(const struct testcase *testcase, int gpu_id); diff --git a/src/freedreno/fdl/freedreno_layout.c b/src/freedreno/fdl/freedreno_layout.c index 226382f271a..c6dc5ecf769 100644 --- a/src/freedreno/fdl/freedreno_layout.c +++ b/src/freedreno/fdl/freedreno_layout.c @@ -56,9 +56,9 @@ fdl_dump_layout(struct fdl_layout *layout) u_minify(layout->depth0, level), layout->cpp, layout->nr_samples, level, - slice->pitch, + fdl_pitch(layout, level), slice->size0, ubwc_slice->size0, - slice->size0 / slice->pitch, + slice->size0 / fdl_pitch(layout, level), slice->offset, ubwc_slice->offset, layout->layer_size, layout->ubwc_layer_size, fdl_tile_mode(layout, level)); diff --git a/src/freedreno/fdl/freedreno_layout.h b/src/freedreno/fdl/freedreno_layout.h index 3b2cb67c493..bae4be585b0 100644 --- a/src/freedreno/fdl/freedreno_layout.h +++ b/src/freedreno/fdl/freedreno_layout.h @@ -79,10 +79,15 @@ struct fdl_slice { uint32_t offset; /* offset of first layer in slice */ - uint32_t pitch; /* pitch in bytes between rows. */ uint32_t size0; /* size of first layer in slice */ }; +/* parameters for explicit (imported) layout */ +struct fdl_explicit_layout { + uint32_t offset; + uint32_t pitch; +}; + /** * Encapsulates the layout of a resource, including position of given 2d * surface (layer, level) within. Or rather all the information needed @@ -91,6 +96,8 @@ struct fdl_slice { struct fdl_layout { struct fdl_slice slices[FDL_MAX_MIP_LEVELS]; struct fdl_slice ubwc_slices[FDL_MAX_MIP_LEVELS]; + uint32_t pitch0; + uint32_t ubwc_width0; uint32_t layer_size; uint32_t ubwc_layer_size; /* in bytes */ bool ubwc : 1; @@ -121,7 +128,7 @@ struct fdl_layout { uint32_t size; /* Size of the whole image, in bytes. */ uint32_t base_align; /* Alignment of the base address, in bytes. */ - uint8_t pitchalign; /* log2(pitchalign / 64) */ + uint8_t pitchalign; /* log2(pitchalign) */ }; static inline uint32_t @@ -131,6 +138,24 @@ fdl_cpp_shift(const struct fdl_layout *layout) return layout->cpp_shift; } +static inline uint32_t +fdl_pitch(const struct fdl_layout *layout, unsigned level) +{ + return align(u_minify(layout->pitch0, level), 1 << layout->pitchalign); +} + +#define RGB_TILE_WIDTH_ALIGNMENT 64 +#define RGB_TILE_HEIGHT_ALIGNMENT 16 +#define UBWC_PLANE_SIZE_ALIGNMENT 4096 + +static inline uint32_t +fdl_ubwc_pitch(const struct fdl_layout *layout, unsigned level) +{ + if (!layout->ubwc) + return 0; + return align(u_minify(layout->ubwc_width0, level), RGB_TILE_WIDTH_ALIGNMENT); +} + static inline uint32_t fdl_layer_stride(const struct fdl_layout *layout, unsigned level) { @@ -140,6 +165,22 @@ fdl_layer_stride(const struct fdl_layout *layout, unsigned level) return layout->slices[level].size0; } +/* a2xx is special and needs PoT alignment for mipmaps: */ +static inline uint32_t +fdl2_pitch(const struct fdl_layout *layout, unsigned level) +{ + uint32_t pitch = fdl_pitch(layout, level); + if (level) + pitch = util_next_power_of_two(pitch); + return pitch; +} + +static inline uint32_t +fdl2_pitch_pixels(const struct fdl_layout *layout, unsigned level) +{ + return fdl2_pitch(layout, level) >> fdl_cpp_shift(layout); +} + static inline uint32_t fdl_surface_offset(const struct fdl_layout *layout, unsigned level, unsigned layer) { @@ -196,7 +237,15 @@ fdl6_layout(struct fdl_layout *layout, enum pipe_format format, uint32_t nr_samples, uint32_t width0, uint32_t height0, uint32_t depth0, uint32_t mip_levels, uint32_t array_size, bool is_3d, - struct fdl_slice *plane_layout); + struct fdl_explicit_layout *plane_layout); + +static inline void +fdl_set_pitchalign(struct fdl_layout *layout, unsigned pitchalign) +{ + uint32_t nblocksx = util_format_get_nblocksx(layout->format, layout->width0); + layout->pitchalign = pitchalign; + layout->pitch0 = align(nblocksx * layout->cpp, 1 << pitchalign); +} void fdl_dump_layout(struct fdl_layout *layout); diff --git a/src/freedreno/registers/a3xx.xml b/src/freedreno/registers/a3xx.xml index c8849693f8c..0efe4fe581e 100644 --- a/src/freedreno/registers/a3xx.xml +++ b/src/freedreno/registers/a3xx.xml @@ -216,19 +216,6 @@ xsi:schemaLocation="http://nouveau.freedesktop.org/ rules-ng.xsd"> - - - Size pixel to fetch, in bytes. Doesn't seem to be required, setting - it to 0x0 seems to work ok, but may be less optimal. - - - - - - - - - @@ -1736,7 +1723,8 @@ xsi:schemaLocation="http://nouveau.freedesktop.org/ rules-ng.xsd"> - + + INDX is index of texture address(es) in MIPMAP state block diff --git a/src/freedreno/registers/a4xx.xml b/src/freedreno/registers/a4xx.xml index 596f722e94f..634e808d3d1 100644 --- a/src/freedreno/registers/a4xx.xml +++ b/src/freedreno/registers/a4xx.xml @@ -268,18 +268,6 @@ xsi:schemaLocation="http://nouveau.freedesktop.org/ rules-ng.xsd"> - - - Size pixel to fetch, in bytes. Doesn't seem to be required, setting - it to 0x0 seems to work ok, but may be less optimal. - - - - - - - - @@ -2346,7 +2334,8 @@ perhaps they should be taken with a grain of salt - + + Pitch in bytes (so actually stride) diff --git a/src/freedreno/registers/a5xx.xml b/src/freedreno/registers/a5xx.xml index 0f3795a51f5..44d72536009 100644 --- a/src/freedreno/registers/a5xx.xml +++ b/src/freedreno/registers/a5xx.xml @@ -232,18 +232,6 @@ xsi:schemaLocation="http://nouveau.freedesktop.org/ rules-ng.xsd"> - - - Size pixel to fetch, in bytes. Doesn't seem to be required, setting - it to 0x0 seems to work ok, but may be less optimal. - - - - - - - - @@ -2914,7 +2902,8 @@ different border-color states per texture.. Looks something like: - + + Pitch in bytes (so actually stride) diff --git a/src/freedreno/vulkan/tu_image.c b/src/freedreno/vulkan/tu_image.c index 4641c8ea34b..88b302e7e21 100644 --- a/src/freedreno/vulkan/tu_image.c +++ b/src/freedreno/vulkan/tu_image.c @@ -210,7 +210,7 @@ tu_image_create(VkDevice _device, } } - struct fdl_slice plane_layout; + struct fdl_explicit_layout plane_layout; if (plane_layouts) { /* only expect simple 2D images for now */ @@ -412,8 +412,8 @@ tu_image_view_init(struct tu_image_view *iview, uint64_t ubwc_addr = image->bo->iova + image->bo_offset + fdl_ubwc_offset(layout, range->baseMipLevel, range->baseArrayLayer); - uint32_t pitch = layout->slices[range->baseMipLevel].pitch; - uint32_t ubwc_pitch = layout->ubwc_slices[range->baseMipLevel].pitch; + uint32_t pitch = fdl_pitch(layout, range->baseMipLevel); + uint32_t ubwc_pitch = fdl_ubwc_pitch(layout, range->baseMipLevel); uint32_t layer_size = fdl_layer_stride(layout, range->baseMipLevel); struct tu_native_format fmt = tu6_format_texture(format, layout->tile_mode); @@ -443,7 +443,7 @@ tu_image_view_init(struct tu_image_view *iview, A6XX_TEX_CONST_0_MIPLVLS(tu_get_levelCount(image, range) - 1); iview->descriptor[1] = A6XX_TEX_CONST_1_WIDTH(width) | A6XX_TEX_CONST_1_HEIGHT(height); iview->descriptor[2] = - A6XX_TEX_CONST_2_PITCHALIGN(layout->pitchalign) | + A6XX_TEX_CONST_2_PITCHALIGN(layout->pitchalign - 6) | A6XX_TEX_CONST_2_PITCH(pitch) | A6XX_TEX_CONST_2_TYPE(tu6_tex_type(pCreateInfo->viewType, false)); iview->descriptor[3] = A6XX_TEX_CONST_3_ARRAY_PITCH(layer_size); @@ -481,7 +481,7 @@ tu_image_view_init(struct tu_image_view *iview, iview->descriptor[4] = base_addr[0]; iview->descriptor[5] |= base_addr[0] >> 32; iview->descriptor[6] = - A6XX_TEX_CONST_6_PLANE_PITCH(image->layout[1].slices[range->baseMipLevel].pitch); + A6XX_TEX_CONST_6_PLANE_PITCH(fdl_pitch(&image->layout[1], range->baseMipLevel)); iview->descriptor[7] = base_addr[1]; iview->descriptor[8] = base_addr[1] >> 32; iview->descriptor[9] = base_addr[2]; @@ -685,7 +685,7 @@ tu_GetImageSubresourceLayout(VkDevice _device, pLayout->offset = fdl_surface_offset(layout, pSubresource->mipLevel, pSubresource->arrayLayer); pLayout->size = slice->size0; - pLayout->rowPitch = slice->pitch; + pLayout->rowPitch = fdl_pitch(layout, pSubresource->mipLevel); pLayout->arrayPitch = fdl_layer_stride(layout, pSubresource->mipLevel); pLayout->depthPitch = slice->size0; diff --git a/src/gallium/drivers/freedreno/a2xx/fd2_gmem.c b/src/gallium/drivers/freedreno/a2xx/fd2_gmem.c index 48ba75cc46e..b9b68971320 100644 --- a/src/gallium/drivers/freedreno/a2xx/fd2_gmem.c +++ b/src/gallium/drivers/freedreno/a2xx/fd2_gmem.c @@ -89,11 +89,10 @@ emit_gmem2mem_surf(struct fd_batch *batch, uint32_t base, { struct fd_ringbuffer *ring = batch->tile_fini; struct fd_resource *rsc = fd_resource(psurf->texture); - struct fdl_slice *slice = fd_resource_slice(rsc, psurf->u.tex.level); uint32_t offset = fd_resource_offset(rsc, psurf->u.tex.level, psurf->u.tex.first_layer); enum pipe_format format = fd_gmem_restore_format(psurf->format); - uint32_t pitch = slice->pitch >> fdl_cpp_shift(&rsc->layout); + uint32_t pitch = fdl2_pitch_pixels(&rsc->layout, psurf->u.tex.level); assert((pitch & 31) == 0); assert((offset & 0xfff) == 0); @@ -230,11 +229,11 @@ emit_mem2gmem_surf(struct fd_batch *batch, uint32_t base, { struct fd_ringbuffer *ring = batch->gmem; struct fd_resource *rsc = fd_resource(psurf->texture); - struct fdl_slice *slice = fd_resource_slice(rsc, psurf->u.tex.level); uint32_t offset = fd_resource_offset(rsc, psurf->u.tex.level, psurf->u.tex.first_layer); enum pipe_format format = fd_gmem_restore_format(psurf->format); + OUT_PKT3(ring, CP_SET_CONSTANT, 2); OUT_RING(ring, CP_REG(REG_A2XX_RB_COLOR_INFO)); OUT_RING(ring, A2XX_RB_COLOR_INFO_BASE(base) | @@ -246,7 +245,7 @@ emit_mem2gmem_surf(struct fd_batch *batch, uint32_t base, OUT_RING(ring, A2XX_SQ_TEX_0_CLAMP_X(SQ_TEX_WRAP) | A2XX_SQ_TEX_0_CLAMP_Y(SQ_TEX_WRAP) | A2XX_SQ_TEX_0_CLAMP_Z(SQ_TEX_WRAP) | - A2XX_SQ_TEX_0_PITCH(slice->pitch >> fdl_cpp_shift(&rsc->layout))); + A2XX_SQ_TEX_0_PITCH(fdl2_pitch_pixels(&rsc->layout, psurf->u.tex.level))); OUT_RELOC(ring, rsc->bo, offset, A2XX_SQ_TEX_1_FORMAT(fd2_pipe2surface(format).format) | A2XX_SQ_TEX_1_CLAMP_POLICY(SQ_TEX_CLAMP_POLICY_OGL), 0); @@ -436,10 +435,9 @@ fd2_emit_sysmem_prep(struct fd_batch *batch) return; struct fd_resource *rsc = fd_resource(psurf->texture); - struct fdl_slice *slice = fd_resource_slice(rsc, psurf->u.tex.level); uint32_t offset = fd_resource_offset(rsc, psurf->u.tex.level, psurf->u.tex.first_layer); - uint32_t pitch = slice->pitch >> fdl_cpp_shift(&rsc->layout); + uint32_t pitch = fdl2_pitch_pixels(&rsc->layout, psurf->u.tex.level); assert((pitch & 31) == 0); assert((offset & 0xfff) == 0); diff --git a/src/gallium/drivers/freedreno/a2xx/fd2_resource.c b/src/gallium/drivers/freedreno/a2xx/fd2_resource.c index 1cd3e9da884..ad5a72a6764 100644 --- a/src/gallium/drivers/freedreno/a2xx/fd2_resource.c +++ b/src/gallium/drivers/freedreno/a2xx/fd2_resource.c @@ -31,50 +31,27 @@ fd2_setup_slices(struct fd_resource *rsc) { struct pipe_resource *prsc = &rsc->base; enum pipe_format format = rsc->base.format; + uint32_t height0 = util_format_get_nblocksy(format, prsc->height0); uint32_t level, size = 0; - uint32_t width = prsc->width0; - uint32_t height = prsc->height0; - uint32_t depth = prsc->depth0; + + /* 32 pixel alignment */ + fdl_set_pitchalign(&rsc->layout, fdl_cpp_shift(&rsc->layout) + 5); for (level = 0; level <= prsc->last_level; level++) { struct fdl_slice *slice = fd_resource_slice(rsc, level); - uint32_t blocks; - - /* 32 * 32 block alignment */ - switch (prsc->target) { - default: assert(0); - case PIPE_TEXTURE_2D: - case PIPE_TEXTURE_2D_ARRAY: - case PIPE_TEXTURE_RECT: - case PIPE_TEXTURE_CUBE: - height = align(height, 32 * util_format_get_blockheight(format)); - case PIPE_TEXTURE_1D: - case PIPE_TEXTURE_1D_ARRAY: - width = align(width, 32 * util_format_get_blockwidth(format)); - case PIPE_BUFFER: - break; - } + uint32_t pitch = fdl2_pitch(&rsc->layout, level); + uint32_t nblocksy = align(u_minify(height0, level), 32); /* mipmaps have power of two sizes in memory */ - if (level) { - width = util_next_power_of_two(width); - height = util_next_power_of_two(height); - } + if (level) + nblocksy = util_next_power_of_two(nblocksy); - slice->pitch = util_format_get_nblocksx(format, width) * rsc->layout.cpp; slice->offset = size; + slice->size0 = align(pitch * nblocksy, 4096); - blocks = util_format_get_nblocks(format, width, height); - - /* 4k aligned size */ - slice->size0 = align(blocks * rsc->layout.cpp, 4096); - - size += slice->size0 * depth * prsc->array_size; - - width = u_minify(width, 1); - height = u_minify(height, 1); - depth = u_minify(depth, 1); + size += slice->size0 * u_minify(prsc->depth0, level) * prsc->array_size; } + return size; } diff --git a/src/gallium/drivers/freedreno/a2xx/fd2_texture.c b/src/gallium/drivers/freedreno/a2xx/fd2_texture.c index 5545c416191..57cab74082c 100644 --- a/src/gallium/drivers/freedreno/a2xx/fd2_texture.c +++ b/src/gallium/drivers/freedreno/a2xx/fd2_texture.c @@ -181,13 +181,12 @@ fd2_sampler_view_create(struct pipe_context *pctx, struct pipe_resource *prsc, so->base.reference.count = 1; so->base.context = pctx; - struct fdl_slice *slice0 = fd_resource_slice(rsc, 0); so->tex0 = A2XX_SQ_TEX_0_SIGN_X(fmt.sign) | A2XX_SQ_TEX_0_SIGN_Y(fmt.sign) | A2XX_SQ_TEX_0_SIGN_Z(fmt.sign) | A2XX_SQ_TEX_0_SIGN_W(fmt.sign) | - A2XX_SQ_TEX_0_PITCH((slice0->pitch >> fdl_cpp_shift(&rsc->layout)) * + A2XX_SQ_TEX_0_PITCH(fdl2_pitch_pixels(&rsc->layout, 0) * util_format_get_blockwidth(prsc->format)) | COND(rsc->layout.tile_mode, A2XX_SQ_TEX_0_TILED); so->tex1 = diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_emit.c b/src/gallium/drivers/freedreno/a3xx/fd3_emit.c index e31acc01655..5d82dc306b6 100644 --- a/src/gallium/drivers/freedreno/a3xx/fd3_emit.c +++ b/src/gallium/drivers/freedreno/a3xx/fd3_emit.c @@ -344,9 +344,8 @@ fd3_emit_gmem_restore_tex(struct fd_ringbuffer *ring, A3XX_TEX_CONST_0_TYPE(A3XX_TEX_2D) | fd3_tex_swiz(format, PIPE_SWIZZLE_X, PIPE_SWIZZLE_Y, PIPE_SWIZZLE_Z, PIPE_SWIZZLE_W)); - OUT_RING(ring, A3XX_TEX_CONST_1_FETCHSIZE(TFETCH_DISABLE) | - A3XX_TEX_CONST_1_WIDTH(psurf[i]->width) | - A3XX_TEX_CONST_1_HEIGHT(psurf[i]->height)); + OUT_RING(ring, A3XX_TEX_CONST_1_WIDTH(psurf[i]->width) | + A3XX_TEX_CONST_1_HEIGHT(psurf[i]->height)); OUT_RING(ring, A3XX_TEX_CONST_2_PITCH(fd_resource_pitch(rsc, lvl)) | A3XX_TEX_CONST_2_INDX(BASETABLE_SZ * i)); OUT_RING(ring, 0x00000000); diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_format.c b/src/gallium/drivers/freedreno/a3xx/fd3_format.c index 58df9714f0a..10195c1eb7b 100644 --- a/src/gallium/drivers/freedreno/a3xx/fd3_format.c +++ b/src/gallium/drivers/freedreno/a3xx/fd3_format.c @@ -321,27 +321,6 @@ fd3_pipe2swap(enum pipe_format format) return formats[format].swap; } -enum a3xx_tex_fetchsize -fd3_pipe2fetchsize(enum pipe_format format) -{ - if (format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT) - format = PIPE_FORMAT_Z32_FLOAT; - else if (util_format_description(format)->layout == UTIL_FORMAT_LAYOUT_RGTC) - format = PIPE_FORMAT_R8G8B8A8_UNORM; - switch (util_format_get_blocksizebits(format) / util_format_get_blockwidth(format)) { - case 8: return TFETCH_1_BYTE; - case 16: return TFETCH_2_BYTE; - case 32: return TFETCH_4_BYTE; - case 64: return TFETCH_8_BYTE; - case 128: return TFETCH_16_BYTE; - default: - debug_printf("Unknown block size for format %s: %d\n", - util_format_name(format), - util_format_get_blocksizebits(format)); - return TFETCH_DISABLE; - } -} - enum a3xx_color_fmt fd3_fs_output_format(enum pipe_format format) { diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_format.h b/src/gallium/drivers/freedreno/a3xx/fd3_format.h index 1e4597242eb..229ed5621ed 100644 --- a/src/gallium/drivers/freedreno/a3xx/fd3_format.h +++ b/src/gallium/drivers/freedreno/a3xx/fd3_format.h @@ -32,7 +32,6 @@ enum a3xx_vtx_fmt fd3_pipe2vtx(enum pipe_format format); enum a3xx_tex_fmt fd3_pipe2tex(enum pipe_format format); -enum a3xx_tex_fetchsize fd3_pipe2fetchsize(enum pipe_format format); enum a3xx_color_fmt fd3_pipe2color(enum pipe_format format); enum a3xx_color_fmt fd3_fs_output_format(enum pipe_format format); enum a3xx_color_swap fd3_pipe2swap(enum pipe_format format); diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_resource.c b/src/gallium/drivers/freedreno/a3xx/fd3_resource.c index 49a7e0babec..500b4150c62 100644 --- a/src/gallium/drivers/freedreno/a3xx/fd3_resource.c +++ b/src/gallium/drivers/freedreno/a3xx/fd3_resource.c @@ -29,42 +29,26 @@ 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); - 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; + uint32_t width0 = prsc->width0; + + if (rsc->layout.tile_mode && prsc->target != PIPE_TEXTURE_CUBE) + width0 = util_next_power_of_two(width0); + + /* 32 pixel alignment */ + fdl_set_pitchalign(&rsc->layout, fdl_cpp_shift(&rsc->layout) + 5); for (level = 0; level <= prsc->last_level; level++) { struct fdl_slice *slice = fd_resource_slice(rsc, level); - uint32_t blocks; - + uint32_t pitch = fdl_pitch(&rsc->layout, level); + uint32_t height = u_minify(prsc->height0, level); if (rsc->layout.tile_mode) { - if (prsc->target != PIPE_TEXTURE_CUBE) { - if (level == 0) { - width = util_next_power_of_two(width); - height = util_next_power_of_two(height); - } - width = MAX2(width, 8); - height = MAX2(height, 4); - // Multiplying by 4 is the result of the 4x4 tiling pattern. - slice->pitch = width * 4; - blocks = util_format_get_nblocks(format, width, height); - } else { - uint32_t twidth, theight; - twidth = align(width, 8); - theight = align(height, 4); - // Multiplying by 4 is the result of the 4x4 tiling pattern. - slice->pitch = twidth * 4; - blocks = util_format_get_nblocks(format, twidth, theight); - } - } else { - slice->pitch = width = align(width, pitchalign); - blocks = util_format_get_nblocks(format, slice->pitch, height); + height = align(height, 4); + if (prsc->target != PIPE_TEXTURE_CUBE) + height = util_next_power_of_two(height); } - slice->pitch = util_format_get_nblocksx(format, slice->pitch) * - rsc->layout.cpp; + + uint32_t nblocksy = util_format_get_nblocksy(format, height); slice->offset = size; /* 1d array and 2d array textures must all have the same layer size @@ -76,17 +60,13 @@ setup_slices(struct fd_resource *rsc, uint32_t alignment, enum pipe_format forma 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); + slice->size0 = align(nblocksy * pitch, alignment); else if (level == 0 || alignment == 1) - slice->size0 = align(blocks * rsc->layout.cpp, alignment); + slice->size0 = align(nblocksy * pitch, alignment); else slice->size0 = fd_resource_slice(rsc, level - 1)->size0; - size += slice->size0 * depth * prsc->array_size; - - width = u_minify(width, 1); - height = u_minify(height, 1); - depth = u_minify(depth, 1); + size += slice->size0 * u_minify(prsc->depth0, level) * prsc->array_size; } return size; diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_texture.c b/src/gallium/drivers/freedreno/a3xx/fd3_texture.c index de1ab392bf5..bea94bf0008 100644 --- a/src/gallium/drivers/freedreno/a3xx/fd3_texture.c +++ b/src/gallium/drivers/freedreno/a3xx/fd3_texture.c @@ -247,7 +247,6 @@ fd3_sampler_view_create(struct pipe_context *pctx, struct pipe_resource *prsc, if (prsc->target == PIPE_BUFFER) { lvl = 0; so->texconst1 = - A3XX_TEX_CONST_1_FETCHSIZE(fd3_pipe2fetchsize(cso->format)) | A3XX_TEX_CONST_1_WIDTH(cso->u.buf.size / util_format_get_blocksize(cso->format)) | A3XX_TEX_CONST_1_HEIGHT(1); } else { @@ -258,7 +257,7 @@ fd3_sampler_view_create(struct pipe_context *pctx, struct pipe_resource *prsc, so->texconst0 |= A3XX_TEX_CONST_0_MIPLVLS(miplevels); so->texconst1 = - A3XX_TEX_CONST_1_FETCHSIZE(fd3_pipe2fetchsize(cso->format)) | + A3XX_TEX_CONST_1_PITCHALIGN(rsc->layout.pitchalign - 4) | A3XX_TEX_CONST_1_WIDTH(u_minify(prsc->width0, lvl)) | A3XX_TEX_CONST_1_HEIGHT(u_minify(prsc->height0, lvl)); } diff --git a/src/gallium/drivers/freedreno/a4xx/fd4_emit.c b/src/gallium/drivers/freedreno/a4xx/fd4_emit.c index 9fe94395328..5e1513f79d3 100644 --- a/src/gallium/drivers/freedreno/a4xx/fd4_emit.c +++ b/src/gallium/drivers/freedreno/a4xx/fd4_emit.c @@ -348,8 +348,7 @@ fd4_emit_gmem_restore_tex(struct fd_ringbuffer *ring, unsigned nr_bufs, PIPE_SWIZZLE_Z, PIPE_SWIZZLE_W)); OUT_RING(ring, A4XX_TEX_CONST_1_WIDTH(bufs[i]->width) | A4XX_TEX_CONST_1_HEIGHT(bufs[i]->height)); - OUT_RING(ring, A4XX_TEX_CONST_2_PITCH(fd_resource_pitch(rsc, lvl)) | - A4XX_TEX_CONST_2_FETCHSIZE(fd4_pipe2fetchsize(format))); + OUT_RING(ring, A4XX_TEX_CONST_2_PITCH(fd_resource_pitch(rsc, lvl))); OUT_RING(ring, 0x00000000); OUT_RELOC(ring, rsc->bo, offset, 0, 0); OUT_RING(ring, 0x00000000); diff --git a/src/gallium/drivers/freedreno/a4xx/fd4_format.c b/src/gallium/drivers/freedreno/a4xx/fd4_format.c index 3e7fff51743..1a6157ff462 100644 --- a/src/gallium/drivers/freedreno/a4xx/fd4_format.c +++ b/src/gallium/drivers/freedreno/a4xx/fd4_format.c @@ -369,30 +369,6 @@ fd4_pipe2swap(enum pipe_format format) return formats[format].swap; } -enum a4xx_tex_fetchsize -fd4_pipe2fetchsize(enum pipe_format format) -{ - if (format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT) - format = PIPE_FORMAT_Z32_FLOAT; - - if (util_format_description(format)->layout == UTIL_FORMAT_LAYOUT_ASTC) - return TFETCH4_16_BYTE; - - switch (util_format_get_blocksizebits(format) / util_format_get_blockwidth(format)) { - case 8: return TFETCH4_1_BYTE; - case 16: return TFETCH4_2_BYTE; - case 32: return TFETCH4_4_BYTE; - case 64: return TFETCH4_8_BYTE; - case 96: return TFETCH4_1_BYTE; /* Does this matter? */ - case 128: return TFETCH4_16_BYTE; - default: - debug_printf("Unknown block size for format %s: %d\n", - util_format_name(format), - util_format_get_blocksizebits(format)); - return TFETCH4_1_BYTE; - } -} - enum a4xx_depth_format fd4_pipe2depth(enum pipe_format format) { diff --git a/src/gallium/drivers/freedreno/a4xx/fd4_format.h b/src/gallium/drivers/freedreno/a4xx/fd4_format.h index 4000bf620d0..7184af3eac8 100644 --- a/src/gallium/drivers/freedreno/a4xx/fd4_format.h +++ b/src/gallium/drivers/freedreno/a4xx/fd4_format.h @@ -35,7 +35,6 @@ enum a4xx_vtx_fmt fd4_pipe2vtx(enum pipe_format format); enum a4xx_tex_fmt fd4_pipe2tex(enum pipe_format format); enum a4xx_color_fmt fd4_pipe2color(enum pipe_format format); enum a3xx_color_swap fd4_pipe2swap(enum pipe_format format); -enum a4xx_tex_fetchsize fd4_pipe2fetchsize(enum pipe_format format); enum a4xx_depth_format fd4_pipe2depth(enum pipe_format format); uint32_t fd4_tex_swiz(enum pipe_format format, unsigned swizzle_r, diff --git a/src/gallium/drivers/freedreno/a4xx/fd4_resource.c b/src/gallium/drivers/freedreno/a4xx/fd4_resource.c index 1640a1acb95..57cd0d5cefb 100644 --- a/src/gallium/drivers/freedreno/a4xx/fd4_resource.c +++ b/src/gallium/drivers/freedreno/a4xx/fd4_resource.c @@ -32,7 +32,6 @@ fd4_setup_slices(struct fd_resource *rsc) { struct pipe_resource *prsc = &rsc->base; enum pipe_format format = prsc->format; - enum util_format_layout layout = util_format_description(format)->layout; uint32_t level, size = 0; uint32_t width = prsc->width0; uint32_t height = prsc->height0; @@ -52,17 +51,16 @@ fd4_setup_slices(struct fd_resource *rsc) alignment = 1; } + /* 32 pixel alignment */ + fdl_set_pitchalign(&rsc->layout, fdl_cpp_shift(&rsc->layout) + 5); + for (level = 0; level <= prsc->last_level; level++) { struct fdl_slice *slice = fd_resource_slice(rsc, level); - uint32_t blocks; + uint32_t pitch = fdl_pitch(&rsc->layout, level); + uint32_t nblocksy = util_format_get_nblocksy(format, height); - if (layout == UTIL_FORMAT_LAYOUT_ASTC) - width = util_align_npot(width, 32 * util_format_get_blockwidth(format)); - else - width = align(width, 32); - slice->pitch = util_format_get_nblocksx(format, width) * rsc->layout.cpp; slice->offset = size; - blocks = util_format_get_nblocks(format, width, height); + /* 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 @@ -72,7 +70,7 @@ fd4_setup_slices(struct fd_resource *rsc) (level > 1 && fd_resource_slice(rsc, level - 1)->size0 <= 0xf000)) slice->size0 = fd_resource_slice(rsc, level - 1)->size0; else - slice->size0 = align(blocks * rsc->layout.cpp, alignment); + slice->size0 = align(nblocksy * pitch, alignment); size += slice->size0 * depth * layers_in_level; diff --git a/src/gallium/drivers/freedreno/a4xx/fd4_texture.c b/src/gallium/drivers/freedreno/a4xx/fd4_texture.c index 45444e995d1..e1f9f24be43 100644 --- a/src/gallium/drivers/freedreno/a4xx/fd4_texture.c +++ b/src/gallium/drivers/freedreno/a4xx/fd4_texture.c @@ -259,7 +259,6 @@ fd4_sampler_view_create(struct pipe_context *pctx, struct pipe_resource *prsc, A4XX_TEX_CONST_1_WIDTH(elements) | A4XX_TEX_CONST_1_HEIGHT(1); so->texconst2 = - A4XX_TEX_CONST_2_FETCHSIZE(fd4_pipe2fetchsize(format)) | A4XX_TEX_CONST_2_PITCH(elements * rsc->layout.cpp); so->offset = cso->u.buf.offset; } else { @@ -274,7 +273,7 @@ fd4_sampler_view_create(struct pipe_context *pctx, struct pipe_resource *prsc, A4XX_TEX_CONST_1_WIDTH(u_minify(prsc->width0, lvl)) | A4XX_TEX_CONST_1_HEIGHT(u_minify(prsc->height0, lvl)); so->texconst2 = - A4XX_TEX_CONST_2_FETCHSIZE(fd4_pipe2fetchsize(format)) | + A4XX_TEX_CONST_2_PITCHALIGN(rsc->layout.pitchalign - 5) | A4XX_TEX_CONST_2_PITCH(fd_resource_pitch(rsc, lvl)); so->offset = fd_resource_offset(rsc, lvl, cso->u.tex.first_layer); } diff --git a/src/gallium/drivers/freedreno/a5xx/fd5_format.c b/src/gallium/drivers/freedreno/a5xx/fd5_format.c index a201b64402f..f5a17cebb8b 100644 --- a/src/gallium/drivers/freedreno/a5xx/fd5_format.c +++ b/src/gallium/drivers/freedreno/a5xx/fd5_format.c @@ -372,31 +372,6 @@ fd5_pipe2swap(enum pipe_format format) return formats[format].swap; } -// XXX possibly same as a4xx.. -enum a5xx_tex_fetchsize -fd5_pipe2fetchsize(enum pipe_format format) -{ - if (format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT) - format = PIPE_FORMAT_Z32_FLOAT; - - if (util_format_description(format)->layout == UTIL_FORMAT_LAYOUT_ASTC) - return TFETCH5_16_BYTE; - - switch (util_format_get_blocksizebits(format) / util_format_get_blockwidth(format)) { - case 8: return TFETCH5_1_BYTE; - case 16: return TFETCH5_2_BYTE; - case 32: return TFETCH5_4_BYTE; - case 64: return TFETCH5_8_BYTE; - case 96: return TFETCH5_1_BYTE; /* Does this matter? */ - case 128: return TFETCH5_16_BYTE; - default: - debug_printf("Unknown block size for format %s: %d\n", - util_format_name(format), - util_format_get_blocksizebits(format)); - return TFETCH5_1_BYTE; - } -} - enum a5xx_depth_format fd5_pipe2depth(enum pipe_format format) { diff --git a/src/gallium/drivers/freedreno/a5xx/fd5_format.h b/src/gallium/drivers/freedreno/a5xx/fd5_format.h index b052aa52960..f662455ef65 100644 --- a/src/gallium/drivers/freedreno/a5xx/fd5_format.h +++ b/src/gallium/drivers/freedreno/a5xx/fd5_format.h @@ -35,7 +35,6 @@ enum a5xx_vtx_fmt fd5_pipe2vtx(enum pipe_format format); enum a5xx_tex_fmt fd5_pipe2tex(enum pipe_format format); enum a5xx_color_fmt fd5_pipe2color(enum pipe_format format); enum a3xx_color_swap fd5_pipe2swap(enum pipe_format format); -enum a5xx_tex_fetchsize fd5_pipe2fetchsize(enum pipe_format format); enum a5xx_depth_format fd5_pipe2depth(enum pipe_format format); uint32_t fd5_tex_swiz(enum pipe_format format, unsigned swizzle_r, diff --git a/src/gallium/drivers/freedreno/a5xx/fd5_image.c b/src/gallium/drivers/freedreno/a5xx/fd5_image.c index d49215ee55e..8badf74f928 100644 --- a/src/gallium/drivers/freedreno/a5xx/fd5_image.c +++ b/src/gallium/drivers/freedreno/a5xx/fd5_image.c @@ -44,7 +44,6 @@ static enum a4xx_state_block imgsb[] = { struct fd5_image { enum pipe_format pfmt; enum a5xx_tex_fmt fmt; - enum a5xx_tex_fetchsize fetchsize; enum a5xx_tex_type type; bool srgb; uint32_t cpp; @@ -71,7 +70,6 @@ static void translate_image(struct fd5_image *img, struct pipe_image_view *pimg) img->pfmt = format; img->fmt = fd5_pipe2tex(format); - img->fetchsize = fd5_pipe2fetchsize(format); img->type = fd5_tex_type(prsc->target); img->srgb = util_format_is_srgb(format); img->cpp = rsc->layout.cpp; @@ -138,8 +136,7 @@ static void emit_image_tex(struct fd_ringbuffer *ring, unsigned slot, COND(img->srgb, A5XX_TEX_CONST_0_SRGB)); OUT_RING(ring, A5XX_TEX_CONST_1_WIDTH(img->width) | A5XX_TEX_CONST_1_HEIGHT(img->height)); - OUT_RING(ring, A5XX_TEX_CONST_2_FETCHSIZE(img->fetchsize) | - A5XX_TEX_CONST_2_TYPE(img->type) | + OUT_RING(ring, A5XX_TEX_CONST_2_TYPE(img->type) | A5XX_TEX_CONST_2_PITCH(img->pitch)); OUT_RING(ring, A5XX_TEX_CONST_3_ARRAY_PITCH(img->array_pitch)); if (img->bo) { diff --git a/src/gallium/drivers/freedreno/a5xx/fd5_texture.c b/src/gallium/drivers/freedreno/a5xx/fd5_texture.c index f411cffc1c7..84e66d504ab 100644 --- a/src/gallium/drivers/freedreno/a5xx/fd5_texture.c +++ b/src/gallium/drivers/freedreno/a5xx/fd5_texture.c @@ -257,7 +257,6 @@ fd5_sampler_view_create(struct pipe_context *pctx, struct pipe_resource *prsc, A5XX_TEX_CONST_1_WIDTH(elements) | A5XX_TEX_CONST_1_HEIGHT(1); so->texconst2 = - A5XX_TEX_CONST_2_FETCHSIZE(fd5_pipe2fetchsize(format)) | A5XX_TEX_CONST_2_PITCH(elements * rsc->layout.cpp); so->offset = cso->u.buf.offset; } else { @@ -272,7 +271,7 @@ fd5_sampler_view_create(struct pipe_context *pctx, struct pipe_resource *prsc, A5XX_TEX_CONST_1_WIDTH(u_minify(prsc->width0, lvl)) | A5XX_TEX_CONST_1_HEIGHT(u_minify(prsc->height0, lvl)); so->texconst2 = - A5XX_TEX_CONST_2_FETCHSIZE(fd5_pipe2fetchsize(format)) | + A5XX_TEX_CONST_2_PITCHALIGN(rsc->layout.pitchalign - 6) | A5XX_TEX_CONST_2_PITCH(fd_resource_pitch(rsc, lvl)); so->offset = fd_resource_offset(rsc, lvl, cso->u.tex.first_layer); } diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_gmem.c b/src/gallium/drivers/freedreno/a6xx/fd6_gmem.c index 4e9b81a98ed..4707eee18d9 100644 --- a/src/gallium/drivers/freedreno/a6xx/fd6_gmem.c +++ b/src/gallium/drivers/freedreno/a6xx/fd6_gmem.c @@ -60,7 +60,7 @@ fd6_emit_flag_reference(struct fd_ringbuffer *ring, struct fd_resource *rsc, if (fd_resource_ubwc_enabled(rsc, level)) { OUT_RELOC(ring, rsc->bo, fd_resource_ubwc_offset(rsc, level, layer), 0, 0); OUT_RING(ring, - A6XX_RB_MRT_FLAG_BUFFER_PITCH_PITCH(rsc->layout.ubwc_slices[level].pitch) | + A6XX_RB_MRT_FLAG_BUFFER_PITCH_PITCH(fdl_ubwc_pitch(&rsc->layout, level)) | A6XX_RB_MRT_FLAG_BUFFER_PITCH_ARRAY_PITCH(rsc->layout.ubwc_layer_size >> 2)); } else { OUT_RING(ring, 0x00000000); /* RB_MRT_FLAG_BUFFER[i].ADDR_LO */ diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_image.c b/src/gallium/drivers/freedreno/a6xx/fd6_image.c index 13b0923a90f..bb65a97f31f 100644 --- a/src/gallium/drivers/freedreno/a6xx/fd6_image.c +++ b/src/gallium/drivers/freedreno/a6xx/fd6_image.c @@ -192,15 +192,13 @@ static void emit_image_tex(struct fd_ringbuffer *ring, struct fd6_image *img) OUT_RING(ring, 0x00000000); /* texconst6 */ if (ubwc_enabled) { - struct fdl_slice *ubwc_slice = &rsc->layout.ubwc_slices[img->level]; - uint32_t block_width, block_height; fdl6_get_ubwc_blockwidth(&rsc->layout, &block_width, &block_height); OUT_RELOC(ring, rsc->bo, img->ubwc_offset, 0, 0); OUT_RING(ring, A6XX_TEX_CONST_9_FLAG_BUFFER_ARRAY_PITCH(rsc->layout.ubwc_layer_size >> 2)); OUT_RING(ring, - A6XX_TEX_CONST_10_FLAG_BUFFER_PITCH(ubwc_slice->pitch) | + A6XX_TEX_CONST_10_FLAG_BUFFER_PITCH(fdl_ubwc_pitch(&rsc->layout, img->level)) | A6XX_TEX_CONST_10_FLAG_BUFFER_LOGW(util_logbase2_ceil(DIV_ROUND_UP(img->width, block_width))) | A6XX_TEX_CONST_10_FLAG_BUFFER_LOGH(util_logbase2_ceil(DIV_ROUND_UP(img->height, block_height)))); } else { @@ -267,10 +265,9 @@ static void emit_image_ssbo(struct fd_ringbuffer *ring, struct fd6_image *img) OUT_RING(ring, 0x00000000); if (ubwc_enabled) { - struct fdl_slice *ubwc_slice = &rsc->layout.ubwc_slices[img->level]; OUT_RELOC(ring, rsc->bo, img->ubwc_offset, 0, 0); OUT_RING(ring, A6XX_IBO_9_FLAG_BUFFER_ARRAY_PITCH(rsc->layout.ubwc_layer_size >> 2)); - OUT_RING(ring, A6XX_IBO_10_FLAG_BUFFER_PITCH(ubwc_slice->pitch)); + OUT_RING(ring, A6XX_IBO_10_FLAG_BUFFER_PITCH(fdl_ubwc_pitch(&rsc->layout, img->level))); } else { OUT_RING(ring, 0x00000000); OUT_RING(ring, 0x00000000); diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_resource.c b/src/gallium/drivers/freedreno/a6xx/fd6_resource.c index c3e34939579..7adc92d3968 100644 --- a/src/gallium/drivers/freedreno/a6xx/fd6_resource.c +++ b/src/gallium/drivers/freedreno/a6xx/fd6_resource.c @@ -163,7 +163,10 @@ static int fill_ubwc_buffer_sizes(struct fd_resource *rsc) { struct pipe_resource *prsc = &rsc->base; - struct fdl_slice slice = *fd_resource_slice(rsc, 0); + struct fdl_explicit_layout explicit = { + .offset = rsc->layout.slices[0].offset, + .pitch = rsc->layout.pitch0, + }; /* limit things to simple single level 2d for now: */ if ((prsc->depth0 != 1) || (prsc->array_size != 1) || (prsc->last_level != 0)) @@ -178,7 +181,7 @@ fill_ubwc_buffer_sizes(struct fd_resource *rsc) if (!fdl6_layout(&rsc->layout, prsc->format, fd_resource_nr_samples(prsc), prsc->width0, prsc->height0, prsc->depth0, - prsc->last_level + 1, prsc->array_size, false, &slice)) + prsc->last_level + 1, prsc->array_size, false, &explicit)) return -1; if (rsc->layout.size > fd_bo_size(rsc->bo)) diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_texture.c b/src/gallium/drivers/freedreno/a6xx/fd6_texture.c index 19b3716a3d6..5e6b9010453 100644 --- a/src/gallium/drivers/freedreno/a6xx/fd6_texture.c +++ b/src/gallium/drivers/freedreno/a6xx/fd6_texture.c @@ -263,7 +263,7 @@ fd6_sampler_view_create(struct pipe_context *pctx, struct pipe_resource *prsc, A6XX_TEX_CONST_1_WIDTH(u_minify(prsc->width0, lvl)) | A6XX_TEX_CONST_1_HEIGHT(u_minify(prsc->height0, lvl)); so->texconst2 = - A6XX_TEX_CONST_2_PITCHALIGN(rsc->layout.pitchalign) | + A6XX_TEX_CONST_2_PITCHALIGN(rsc->layout.pitchalign - 6) | A6XX_TEX_CONST_2_PITCH(fd_resource_pitch(rsc, lvl)); so->offset = fd_resource_offset(rsc, lvl, cso->u.tex.first_layer); so->ubwc_offset = fd_resource_ubwc_offset(rsc, lvl, cso->u.tex.first_layer); @@ -312,15 +312,13 @@ fd6_sampler_view_create(struct pipe_context *pctx, struct pipe_resource *prsc, } if (so->ubwc_enabled) { - struct fdl_slice *ubwc_base_slice = &rsc->layout.ubwc_slices[lvl]; - uint32_t block_width, block_height; fdl6_get_ubwc_blockwidth(&rsc->layout, &block_width, &block_height); so->texconst3 |= A6XX_TEX_CONST_3_FLAG | A6XX_TEX_CONST_3_TILE_ALL; so->texconst9 |= A6XX_TEX_CONST_9_FLAG_BUFFER_ARRAY_PITCH(rsc->layout.ubwc_layer_size >> 2); so->texconst10 |= - A6XX_TEX_CONST_10_FLAG_BUFFER_PITCH(ubwc_base_slice->pitch) | + A6XX_TEX_CONST_10_FLAG_BUFFER_PITCH(fdl_ubwc_pitch(&rsc->layout, lvl)) | A6XX_TEX_CONST_10_FLAG_BUFFER_LOGW(util_logbase2_ceil(DIV_ROUND_UP(u_minify(prsc->width0, lvl), block_width))) | A6XX_TEX_CONST_10_FLAG_BUFFER_LOGH(util_logbase2_ceil(DIV_ROUND_UP(u_minify(prsc->height0, lvl), block_height))); } diff --git a/src/gallium/drivers/freedreno/freedreno_resource.c b/src/gallium/drivers/freedreno/freedreno_resource.c index f5a72887582..fb5bb532e57 100644 --- a/src/gallium/drivers/freedreno/freedreno_resource.c +++ b/src/gallium/drivers/freedreno/freedreno_resource.c @@ -821,6 +821,8 @@ fd_resource_layout_init(struct pipe_resource *prsc) struct fd_resource *rsc = fd_resource(prsc); struct fdl_layout *layout = &rsc->layout; + layout->format = prsc->format; + layout->width0 = prsc->width0; layout->height0 = prsc->height0; layout->depth0 = prsc->depth0; @@ -1021,7 +1023,7 @@ fd_resource_from_handle(struct pipe_screen *pscreen, goto fail; rsc->internal_format = tmpl->format; - slice->pitch = handle->stride; + rsc->layout.pitch0 = handle->stride; slice->offset = handle->offset; slice->size0 = handle->stride * prsc->height0; @@ -1033,8 +1035,8 @@ fd_resource_from_handle(struct pipe_screen *pscreen, if (is_a6xx(screen)) pitchalign = 64; - if ((slice->pitch < align(prsc->width0 * rsc->layout.cpp, pitchalign)) || - (slice->pitch & (pitchalign - 1))) + if ((rsc->layout.pitch0 < align(prsc->width0 * rsc->layout.cpp, pitchalign)) || + (rsc->layout.pitch0 & (pitchalign - 1))) goto fail; assert(rsc->layout.cpp); diff --git a/src/gallium/drivers/freedreno/freedreno_resource.h b/src/gallium/drivers/freedreno/freedreno_resource.h index 0e8502a493d..9419097dcdf 100644 --- a/src/gallium/drivers/freedreno/freedreno_resource.h +++ b/src/gallium/drivers/freedreno/freedreno_resource.h @@ -201,7 +201,10 @@ fd_resource_layer_stride(struct fd_resource *rsc, unsigned level) static inline uint32_t fd_resource_pitch(struct fd_resource *rsc, unsigned level) { - return fd_resource_slice(rsc, level)->pitch; + if (is_a2xx(fd_screen(rsc->base.screen))) + return fdl2_pitch(&rsc->layout, level); + + return fdl_pitch(&rsc->layout, level); } /* get offset for specified mipmap level and texture/array layer */