mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-04-15 02:10:36 +02:00
freedreno/layout: Introduce fdl_image_params
fdl6_layout() (and to a lesser degree) fdl5_layout() is growing an unwieldly argument list, and it isn't obvious at first glance what fdl_layout fields should be initialized before calling it. So split out a fdl_image_params struct to clean this up. Signed-off-by: Rob Clark <rob.clark@oss.qualcomm.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/36075>
This commit is contained in:
parent
52f79561e3
commit
15bccc29bd
4 changed files with 157 additions and 64 deletions
|
|
@ -17,24 +17,49 @@ fdl5_layout(struct fdl_layout *layout, enum pipe_format format,
|
|||
uint32_t depth0, uint32_t mip_levels, uint32_t array_size,
|
||||
bool is_3d)
|
||||
{
|
||||
assert(nr_samples > 0);
|
||||
layout->width0 = width0;
|
||||
layout->height0 = height0;
|
||||
layout->depth0 = depth0;
|
||||
struct fdl_image_params params = {
|
||||
.format = format,
|
||||
.nr_samples = nr_samples,
|
||||
.width0 = width0,
|
||||
.height0 = height0,
|
||||
.depth0 = depth0,
|
||||
.mip_levels = mip_levels,
|
||||
.array_size = array_size,
|
||||
.tile_mode = layout->tile_mode,
|
||||
.ubwc = layout->ubwc,
|
||||
.is_3d = is_3d,
|
||||
};
|
||||
|
||||
layout->cpp = util_format_get_blocksize(format);
|
||||
layout->cpp *= nr_samples;
|
||||
return fdl5_layout_image(layout, ¶ms);
|
||||
}
|
||||
|
||||
void
|
||||
fdl5_layout_image(struct fdl_layout *layout, const struct fdl_image_params *params)
|
||||
{
|
||||
memset(layout, 0, sizeof(*layout));
|
||||
|
||||
assert(params->nr_samples > 0);
|
||||
assert(!params->ubwc && !params->force_ubwc);
|
||||
|
||||
layout->width0 = params->width0;
|
||||
layout->height0 = params->height0;
|
||||
layout->depth0 = params->depth0;
|
||||
|
||||
layout->cpp = util_format_get_blocksize(params->format);
|
||||
layout->cpp *= params->nr_samples;
|
||||
layout->cpp_shift = ffs(layout->cpp) - 1;
|
||||
|
||||
layout->format = format;
|
||||
layout->nr_samples = nr_samples;
|
||||
layout->layer_first = !is_3d;
|
||||
layout->format = params->format;
|
||||
layout->nr_samples = params->nr_samples;
|
||||
layout->layer_first = !params->is_3d;
|
||||
|
||||
layout->tile_mode = params->tile_mode;
|
||||
|
||||
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;
|
||||
uint32_t layers_in_level = layout->layer_first ? 1 : params->array_size;
|
||||
|
||||
/* use 128 pixel alignment for cpp=1 and cpp=2 */
|
||||
if (layout->cpp < 4 && layout->tile_mode)
|
||||
|
|
@ -42,13 +67,13 @@ fdl5_layout(struct fdl_layout *layout, enum pipe_format format,
|
|||
else
|
||||
fdl_set_pitchalign(layout, fdl_cpp_shift(layout) + 6);
|
||||
|
||||
for (uint32_t level = 0; level < mip_levels; level++) {
|
||||
uint32_t depth = u_minify(depth0, level);
|
||||
for (uint32_t level = 0; level < params->mip_levels; level++) {
|
||||
uint32_t depth = u_minify(params->depth0, level);
|
||||
struct fdl_slice *slice = &layout->slices[level];
|
||||
uint32_t tile_mode = fdl_tile_mode(layout, level);
|
||||
uint32_t pitch = fdl_pitch(layout, level);
|
||||
uint32_t nblocksy =
|
||||
util_format_get_nblocksy(format, u_minify(height0, level));
|
||||
util_format_get_nblocksy(params->format, u_minify(params->height0, level));
|
||||
|
||||
if (tile_mode) {
|
||||
nblocksy = align(nblocksy, heightalign);
|
||||
|
|
@ -60,7 +85,7 @@ fdl5_layout(struct fdl_layout *layout, enum pipe_format format,
|
|||
* The pitch is already sufficiently aligned, but height
|
||||
* may not be:
|
||||
*/
|
||||
if (level == mip_levels - 1)
|
||||
if (level == params->mip_levels - 1)
|
||||
nblocksy = align(nblocksy, 32);
|
||||
}
|
||||
|
||||
|
|
@ -72,7 +97,7 @@ fdl5_layout(struct fdl_layout *layout, enum pipe_format format,
|
|||
* different than what this code does), so as soon as the layer size
|
||||
* range gets into range, we stop reducing it.
|
||||
*/
|
||||
if (is_3d) {
|
||||
if (params->is_3d) {
|
||||
if (level <= 1 || layout->slices[level - 1].size0 > 0xf000) {
|
||||
slice->size0 = align(nblocksy * pitch, 4096);
|
||||
} else {
|
||||
|
|
@ -87,6 +112,6 @@ fdl5_layout(struct fdl_layout *layout, enum pipe_format format,
|
|||
|
||||
if (layout->layer_first) {
|
||||
layout->layer_size = align64(layout->size, 4096);
|
||||
layout->size = layout->layer_size * array_size;
|
||||
layout->size = layout->layer_size * params->array_size;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -118,24 +118,53 @@ fdl6_layout(struct fdl_layout *layout, const struct fd_dev_info *info,
|
|||
uint32_t array_size, bool is_3d, bool is_mutable,
|
||||
bool force_ubwc,
|
||||
struct fdl_explicit_layout *explicit_layout)
|
||||
{
|
||||
struct fdl_image_params params = {
|
||||
.format = format,
|
||||
.nr_samples = nr_samples,
|
||||
.width0 = width0,
|
||||
.height0 = height0,
|
||||
.depth0 = depth0,
|
||||
.mip_levels = mip_levels,
|
||||
.array_size = array_size,
|
||||
.tile_mode = layout->tile_mode,
|
||||
.ubwc = layout->ubwc,
|
||||
.force_ubwc = force_ubwc,
|
||||
.is_3d = is_3d,
|
||||
.is_mutable = is_mutable,
|
||||
};
|
||||
|
||||
return fdl6_layout_image(layout, info, ¶ms, explicit_layout);
|
||||
}
|
||||
|
||||
bool
|
||||
fdl6_layout_image(struct fdl_layout *layout, const struct fd_dev_info *info,
|
||||
const struct fdl_image_params *params,
|
||||
const struct fdl_explicit_layout *explicit_layout)
|
||||
{
|
||||
uint32_t offset = 0, heightalign;
|
||||
uint32_t ubwc_blockwidth, ubwc_blockheight;
|
||||
|
||||
assert(nr_samples > 0);
|
||||
layout->width0 = width0;
|
||||
layout->height0 = height0;
|
||||
layout->depth0 = depth0;
|
||||
layout->mip_levels = mip_levels;
|
||||
memset(layout, 0, sizeof(*layout));
|
||||
|
||||
layout->cpp = util_format_get_blocksize(format);
|
||||
layout->cpp *= nr_samples;
|
||||
assert(params->nr_samples > 0);
|
||||
|
||||
layout->width0 = params->width0;
|
||||
layout->height0 = params->height0;
|
||||
layout->depth0 = params->depth0;
|
||||
layout->mip_levels = params->mip_levels;
|
||||
|
||||
layout->cpp = util_format_get_blocksize(params->format);
|
||||
layout->cpp *= params->nr_samples;
|
||||
layout->cpp_shift = ffs(layout->cpp) - 1;
|
||||
|
||||
layout->format = format;
|
||||
layout->nr_samples = nr_samples;
|
||||
layout->layer_first = !is_3d;
|
||||
layout->is_mutable = is_mutable;
|
||||
layout->format = params->format;
|
||||
layout->nr_samples = params->nr_samples;
|
||||
layout->layer_first = !params->is_3d;
|
||||
layout->is_mutable = params->is_mutable;
|
||||
|
||||
layout->ubwc = params->ubwc;
|
||||
layout->tile_mode = params->tile_mode;
|
||||
|
||||
if (!util_is_power_of_two_or_zero(layout->cpp)) {
|
||||
/* R8G8B8 and other 3 component formats don't get UBWC: */
|
||||
|
|
@ -147,24 +176,24 @@ fdl6_layout(struct fdl_layout *layout, const struct fd_dev_info *info,
|
|||
/* For simplicity support UBWC only for 3D images without mipmaps,
|
||||
* most d3d11 games don't use mipmaps for 3D images.
|
||||
*/
|
||||
if (depth0 > 1 && mip_levels > 1)
|
||||
if (params->depth0 > 1 && params->mip_levels > 1)
|
||||
layout->ubwc = false;
|
||||
|
||||
if (ubwc_blockwidth == 0)
|
||||
layout->ubwc = false;
|
||||
}
|
||||
|
||||
assert(!force_ubwc || layout->ubwc);
|
||||
assert(!params->force_ubwc || layout->ubwc);
|
||||
|
||||
if (!force_ubwc && width0 < FDL_MIN_UBWC_WIDTH) {
|
||||
if (!params->force_ubwc && params->width0 < FDL_MIN_UBWC_WIDTH) {
|
||||
layout->ubwc = false;
|
||||
/* Linear D/S is not supported by HW. */
|
||||
if (!util_format_is_depth_or_stencil(format))
|
||||
if (!util_format_is_depth_or_stencil(params->format))
|
||||
layout->tile_mode = TILE6_LINEAR;
|
||||
}
|
||||
|
||||
/* Linear D/S is not supported by HW. */
|
||||
if (util_format_is_depth_or_stencil(format))
|
||||
if (util_format_is_depth_or_stencil(params->format))
|
||||
layout->tile_all = true;
|
||||
|
||||
if (layout->ubwc && !info->a6xx.has_ubwc_linear_mipmap_fallback)
|
||||
|
|
@ -173,7 +202,7 @@ fdl6_layout(struct fdl_layout *layout, const struct fd_dev_info *info,
|
|||
/* 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;
|
||||
uint32_t layers_in_level = layout->layer_first ? 1 : params->array_size;
|
||||
|
||||
/* note: for tiled+noubwc layouts, we can use a lower pitchalign
|
||||
* which will affect the linear levels only, (the hardware will still
|
||||
|
|
@ -220,17 +249,17 @@ fdl6_layout(struct fdl_layout *layout, const struct fd_dev_info *info,
|
|||
return false;
|
||||
}
|
||||
|
||||
uint32_t ubwc_width0 = width0;
|
||||
uint32_t ubwc_height0 = height0;
|
||||
uint32_t ubwc_width0 = params->width0;
|
||||
uint32_t ubwc_height0 = params->height0;
|
||||
uint32_t ubwc_tile_height_alignment = RGB_TILE_HEIGHT_ALIGNMENT;
|
||||
if (mip_levels > 1) {
|
||||
if (params->mip_levels > 1) {
|
||||
/* With mipmapping enabled, UBWC layout is power-of-two sized,
|
||||
* specified in log2 width/height in the descriptors. The height
|
||||
* alignment is 64 for mipmapping, but for buffer sharing (always
|
||||
* single level) other participants expect 16.
|
||||
*/
|
||||
ubwc_width0 = util_next_power_of_two(width0);
|
||||
ubwc_height0 = util_next_power_of_two(height0);
|
||||
ubwc_width0 = util_next_power_of_two(params->width0);
|
||||
ubwc_height0 = util_next_power_of_two(params->height0);
|
||||
ubwc_tile_height_alignment = 64;
|
||||
}
|
||||
layout->ubwc_width0 = align(DIV_ROUND_UP(ubwc_width0, ubwc_blockwidth),
|
||||
|
|
@ -240,15 +269,15 @@ fdl6_layout(struct fdl_layout *layout, const struct fd_dev_info *info,
|
|||
|
||||
uint32_t min_3d_layer_size = 0;
|
||||
|
||||
for (uint32_t level = 0; level < mip_levels; level++) {
|
||||
uint32_t depth = u_minify(depth0, level);
|
||||
for (uint32_t level = 0; level < params->mip_levels; level++) {
|
||||
uint32_t depth = u_minify(params->depth0, level);
|
||||
struct fdl_slice *slice = &layout->slices[level];
|
||||
struct fdl_slice *ubwc_slice = &layout->ubwc_slices[level];
|
||||
enum a6xx_tile_mode tile_mode = fdl_tile_mode(layout, level);
|
||||
uint32_t pitch = fdl_pitch(layout, level);
|
||||
uint32_t height = u_minify(height0, level);
|
||||
uint32_t height = u_minify(params->height0, level);
|
||||
|
||||
uint32_t nblocksy = util_format_get_nblocksy(format, height);
|
||||
uint32_t nblocksy = util_format_get_nblocksy(params->format, height);
|
||||
if (tile_mode)
|
||||
nblocksy = align(nblocksy, heightalign);
|
||||
|
||||
|
|
@ -259,7 +288,7 @@ fdl6_layout(struct fdl_layout *layout, const struct fd_dev_info *info,
|
|||
* The pitch is already sufficiently aligned, but height
|
||||
* may not be. note this only matters if last level is linear
|
||||
*/
|
||||
if (level == mip_levels - 1)
|
||||
if (level == params->mip_levels - 1)
|
||||
nblocksy = align(nblocksy, 4);
|
||||
|
||||
slice->offset = offset + layout->size;
|
||||
|
|
@ -269,7 +298,7 @@ fdl6_layout(struct fdl_layout *layout, const struct fd_dev_info *info,
|
|||
* until the value we specify in TEX_CONST_3_MIN_LAYERSZ, which is used to
|
||||
* make sure that we follow alignment requirements after minification.
|
||||
*/
|
||||
if (is_3d) {
|
||||
if (params->is_3d) {
|
||||
if (level == 0) {
|
||||
slice->size0 = align(nblocksy * pitch, 4096);
|
||||
} else if (min_3d_layer_size) {
|
||||
|
|
@ -316,7 +345,7 @@ fdl6_layout(struct fdl_layout *layout, const struct fd_dev_info *info,
|
|||
|
||||
if (layout->layer_first) {
|
||||
layout->layer_size = align64(layout->size, 4096);
|
||||
layout->size = layout->layer_size * array_size;
|
||||
layout->size = layout->layer_size * params->array_size;
|
||||
}
|
||||
|
||||
/* Place the UBWC slices before the uncompressed slices, because the
|
||||
|
|
@ -325,10 +354,12 @@ fdl6_layout(struct fdl_layout *layout, const struct fd_dev_info *info,
|
|||
* independently.
|
||||
*/
|
||||
if (layout->ubwc) {
|
||||
assert(!(depth0 > 1 && mip_levels > 1));
|
||||
for (uint32_t level = 0; level < mip_levels; level++)
|
||||
layout->slices[level].offset += layout->ubwc_layer_size * array_size * depth0;
|
||||
layout->size += layout->ubwc_layer_size * array_size * depth0;
|
||||
assert(!(params->depth0 > 1 && params->mip_levels > 1));
|
||||
for (uint32_t level = 0; level < params->mip_levels; level++) {
|
||||
layout->slices[level].offset +=
|
||||
layout->ubwc_layer_size * params->array_size * params->depth0;
|
||||
}
|
||||
layout->size += layout->ubwc_layer_size * params->array_size * params->depth0;
|
||||
}
|
||||
|
||||
/* include explicit offset in size */
|
||||
|
|
|
|||
|
|
@ -12,11 +12,7 @@
|
|||
bool
|
||||
fdl_test_layout(const struct testcase *testcase, const struct fd_dev_id *dev_id)
|
||||
{
|
||||
struct fdl_layout layout = {
|
||||
.ubwc = testcase->layout.ubwc,
|
||||
.tile_mode = testcase->layout.tile_mode,
|
||||
.tile_all = testcase->layout.tile_all,
|
||||
};
|
||||
struct fdl_layout layout;
|
||||
bool ok = true;
|
||||
|
||||
int max_size = MAX2(testcase->layout.width0, testcase->layout.height0);
|
||||
|
|
@ -26,20 +22,25 @@ fdl_test_layout(const struct testcase *testcase, const struct fd_dev_id *dev_id)
|
|||
max_size = u_minify(max_size, 1);
|
||||
}
|
||||
|
||||
struct fdl_image_params params = {
|
||||
.format = testcase->format,
|
||||
.nr_samples = MAX2(testcase->layout.nr_samples, 1),
|
||||
.width0 = testcase->layout.width0,
|
||||
.height0 = MAX2(testcase->layout.height0, 1),
|
||||
.depth0 = MAX2(testcase->layout.depth0, 1),
|
||||
.mip_levels = mip_levels,
|
||||
.array_size = MAX2(testcase->array_size, 1),
|
||||
.is_3d = testcase->is_3d,
|
||||
.ubwc = testcase->layout.ubwc,
|
||||
.tile_mode = testcase->layout.tile_mode,
|
||||
};
|
||||
|
||||
if (fd_dev_gen(dev_id) >= 6) {
|
||||
const struct fd_dev_info *dev_info = fd_dev_info_raw(dev_id);
|
||||
fdl6_layout(&layout, dev_info, testcase->format,
|
||||
MAX2(testcase->layout.nr_samples, 1), testcase->layout.width0,
|
||||
MAX2(testcase->layout.height0, 1),
|
||||
MAX2(testcase->layout.depth0, 1), mip_levels,
|
||||
MAX2(testcase->array_size, 1), testcase->is_3d, false, false, NULL);
|
||||
fdl6_layout_image(&layout, dev_info, ¶ms, NULL);
|
||||
} else {
|
||||
assert(fd_dev_gen(dev_id) >= 5);
|
||||
fdl5_layout(&layout, testcase->format,
|
||||
MAX2(testcase->layout.nr_samples, 1), testcase->layout.width0,
|
||||
MAX2(testcase->layout.height0, 1),
|
||||
MAX2(testcase->layout.depth0, 1), mip_levels,
|
||||
MAX2(testcase->array_size, 1), testcase->is_3d);
|
||||
fdl5_layout_image(&layout, ¶ms);
|
||||
}
|
||||
|
||||
/* fdl lays out UBWC data before the color data, while all we have
|
||||
|
|
|
|||
|
|
@ -75,6 +75,37 @@ struct fdl_explicit_layout {
|
|||
uint32_t pitch;
|
||||
};
|
||||
|
||||
/**
|
||||
* General layout params for images.
|
||||
*/
|
||||
struct fdl_image_params {
|
||||
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;
|
||||
|
||||
/**
|
||||
* Preferred tile mode, may be overriden by layout constraints.
|
||||
*/
|
||||
uint32_t tile_mode;
|
||||
|
||||
/**
|
||||
* UBWC preferred, may be overriden
|
||||
*/
|
||||
bool ubwc;
|
||||
|
||||
/**
|
||||
* Force UBWC, even when below the minimum width.
|
||||
*/
|
||||
bool force_ubwc;
|
||||
|
||||
bool is_3d;
|
||||
bool is_mutable;
|
||||
};
|
||||
|
||||
/**
|
||||
* Metadata shared between vk and gallium driver for interop.
|
||||
*
|
||||
|
|
@ -232,6 +263,11 @@ const char *fdl_tile_mode_desc(const struct fdl_layout *layout, int level);
|
|||
|
||||
void fdl_layout_buffer(struct fdl_layout *layout, uint32_t size);
|
||||
|
||||
void fdl5_layout_image(struct fdl_layout *layout, const struct fdl_image_params *params);
|
||||
bool fdl6_layout_image(struct fdl_layout *layout, const struct fd_dev_info *info,
|
||||
const struct fdl_image_params *params,
|
||||
const struct fdl_explicit_layout *explicit_layout);
|
||||
|
||||
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,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue