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 */