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