mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-31 07:40:11 +01:00
panvk/v9+: Set up limited texture descs for storage use
Storage access to images using LEA_TEX[_IMM] has limitations on some fields in the texture descriptors, making them incompatible with the descriptors required for texture access, specifically in the case non-zero levels. This change sets up two sets of texture descriptors for image views of storage images, then picks the correct one when writing the image view descriptors. Backport-to: 25.0 Backport-to: 25.1 Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com> Tested-by: Heiko Stuebner <heiko@sntech.de> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/34839>
This commit is contained in:
parent
e2aa0b7566
commit
7451bc3bef
5 changed files with 162 additions and 43 deletions
|
|
@ -733,6 +733,55 @@ GENX(panfrost_texture_afbc_reswizzle)(struct pan_image_view *iview)
|
|||
}
|
||||
#endif
|
||||
|
||||
static unsigned
|
||||
panfrost_texture_get_array_size(const struct pan_image_view *iview)
|
||||
{
|
||||
unsigned array_size = iview->last_layer - iview->first_layer + 1;
|
||||
|
||||
/* If this is a cubemap, we expect the number of layers to be a multiple
|
||||
* of 6.
|
||||
*/
|
||||
if (iview->dim == MALI_TEXTURE_DIMENSION_CUBE) {
|
||||
assert(array_size % 6 == 0);
|
||||
array_size /= 6;
|
||||
}
|
||||
|
||||
/* Multiplanar YUV textures require 2 surface descriptors. */
|
||||
if (panfrost_format_is_yuv(iview->format) && PAN_ARCH >= 9 &&
|
||||
pan_image_view_get_plane(iview, 1) != NULL)
|
||||
array_size *= 2;
|
||||
|
||||
return array_size;
|
||||
}
|
||||
|
||||
static struct panfrost_tex_extent
|
||||
panfrost_texture_get_extent(const struct pan_image_view *iview,
|
||||
const struct pan_image_layout *layout)
|
||||
{
|
||||
if (iview->buf.size)
|
||||
return panfrost_texture_buf_get_extent(iview, layout);
|
||||
|
||||
struct panfrost_tex_extent extent;
|
||||
extent.width = u_minify(layout->width, iview->first_level);
|
||||
extent.height = u_minify(layout->height, iview->first_level);
|
||||
extent.depth = u_minify(layout->depth, iview->first_level);
|
||||
if (util_format_is_compressed(layout->format) &&
|
||||
!util_format_is_compressed(iview->format)) {
|
||||
extent.width =
|
||||
DIV_ROUND_UP(extent.width, util_format_get_blockwidth(layout->format));
|
||||
extent.height = DIV_ROUND_UP(extent.height,
|
||||
util_format_get_blockheight(layout->format));
|
||||
extent.depth =
|
||||
DIV_ROUND_UP(extent.depth, util_format_get_blockdepth(layout->format));
|
||||
assert(util_format_get_blockwidth(iview->format) == 1);
|
||||
assert(util_format_get_blockheight(iview->format) == 1);
|
||||
assert(util_format_get_blockheight(iview->format) == 1);
|
||||
assert(iview->last_level == iview->first_level);
|
||||
}
|
||||
|
||||
return extent;
|
||||
}
|
||||
|
||||
/*
|
||||
* Generates a texture descriptor. Ideally, descriptors are immutable after the
|
||||
* texture is created, so we can keep these hanging around in GPU memory in a
|
||||
|
|
@ -751,9 +800,9 @@ GENX(panfrost_new_texture)(const struct pan_image_view *iview,
|
|||
util_format_description(iview->format);
|
||||
const struct pan_image *first_plane = pan_image_view_get_first_plane(iview);
|
||||
const struct pan_image_layout *layout = &first_plane->layout;
|
||||
|
||||
uint32_t mali_format =
|
||||
GENX(panfrost_format_from_pipe_format)(iview->format)->hw;
|
||||
|
||||
if (desc->layout == UTIL_FORMAT_LAYOUT_ASTC && iview->astc.narrow &&
|
||||
desc->colorspace != UTIL_FORMAT_COLORSPACE_SRGB) {
|
||||
mali_format = MALI_PACK_FMT(RGBA8_UNORM, RGBA, L);
|
||||
|
|
@ -761,43 +810,10 @@ GENX(panfrost_new_texture)(const struct pan_image_view *iview,
|
|||
|
||||
panfrost_emit_texture_payload(iview, payload->cpu);
|
||||
|
||||
unsigned array_size = iview->last_layer - iview->first_layer + 1;
|
||||
unsigned array_size = panfrost_texture_get_array_size(iview);
|
||||
|
||||
/* If this is a cubemap, we expect the number of layers to be a multiple
|
||||
* of 6.
|
||||
*/
|
||||
if (iview->dim == MALI_TEXTURE_DIMENSION_CUBE) {
|
||||
assert(array_size % 6 == 0);
|
||||
array_size /= 6;
|
||||
}
|
||||
|
||||
/* Multiplanar YUV textures require 2 surface descriptors. */
|
||||
if (panfrost_format_is_yuv(iview->format) && PAN_ARCH >= 9 &&
|
||||
pan_image_view_get_plane(iview, 1) != NULL)
|
||||
array_size *= 2;
|
||||
|
||||
struct panfrost_tex_extent extent;
|
||||
|
||||
if (iview->buf.size) {
|
||||
extent = panfrost_texture_buf_get_extent(iview, layout);
|
||||
} else {
|
||||
extent.width = u_minify(layout->width, iview->first_level);
|
||||
extent.height = u_minify(layout->height, iview->first_level);
|
||||
extent.depth = u_minify(layout->depth, iview->first_level);
|
||||
if (util_format_is_compressed(layout->format) &&
|
||||
!util_format_is_compressed(iview->format)) {
|
||||
extent.width = DIV_ROUND_UP(
|
||||
extent.width, util_format_get_blockwidth(layout->format));
|
||||
extent.height = DIV_ROUND_UP(
|
||||
extent.height, util_format_get_blockheight(layout->format));
|
||||
extent.depth = DIV_ROUND_UP(
|
||||
extent.depth, util_format_get_blockdepth(layout->format));
|
||||
assert(util_format_get_blockwidth(iview->format) == 1);
|
||||
assert(util_format_get_blockheight(iview->format) == 1);
|
||||
assert(util_format_get_blockheight(iview->format) == 1);
|
||||
assert(iview->last_level == iview->first_level);
|
||||
}
|
||||
}
|
||||
struct panfrost_tex_extent extent =
|
||||
panfrost_texture_get_extent(iview, layout);
|
||||
|
||||
pan_pack(out, TEXTURE, cfg) {
|
||||
cfg.dimension = iview->dim;
|
||||
|
|
@ -830,6 +846,67 @@ GENX(panfrost_new_texture)(const struct pan_image_view *iview,
|
|||
}
|
||||
}
|
||||
|
||||
#if PAN_ARCH >= 9
|
||||
void
|
||||
GENX(panfrost_new_storage_texture)(const struct pan_image_view *iview,
|
||||
struct mali_texture_packed *out,
|
||||
const struct panfrost_ptr *payload)
|
||||
{
|
||||
const struct util_format_description *desc =
|
||||
util_format_description(iview->format);
|
||||
const struct pan_image *first_plane = pan_image_view_get_first_plane(iview);
|
||||
const struct pan_image_layout *layout = &first_plane->layout;
|
||||
|
||||
/* AFBC and AFRC cannot be used in storage operations. */
|
||||
assert(!drm_is_afbc(layout->modifier));
|
||||
assert(!drm_is_afrc(layout->modifier));
|
||||
|
||||
uint32_t mali_format =
|
||||
GENX(panfrost_format_from_pipe_format)(iview->format)->hw;
|
||||
if (desc->layout == UTIL_FORMAT_LAYOUT_ASTC && iview->astc.narrow &&
|
||||
desc->colorspace != UTIL_FORMAT_COLORSPACE_SRGB) {
|
||||
mali_format = MALI_PACK_FMT(RGBA8_UNORM, RGBA, L);
|
||||
}
|
||||
|
||||
panfrost_emit_texture_payload(iview, payload->cpu);
|
||||
|
||||
unsigned array_size = panfrost_texture_get_array_size(iview);
|
||||
|
||||
struct panfrost_tex_extent extent =
|
||||
panfrost_texture_get_extent(iview, layout);
|
||||
|
||||
static const unsigned char rgba_swizzle[4] = {
|
||||
PIPE_SWIZZLE_X,
|
||||
PIPE_SWIZZLE_Y,
|
||||
PIPE_SWIZZLE_Z,
|
||||
PIPE_SWIZZLE_W,
|
||||
};
|
||||
|
||||
pan_pack(out, TEXTURE, cfg) {
|
||||
cfg.dimension = iview->dim;
|
||||
cfg.format = mali_format;
|
||||
cfg.width = extent.width;
|
||||
cfg.height = extent.height;
|
||||
if (iview->dim == MALI_TEXTURE_DIMENSION_3D)
|
||||
cfg.depth = extent.depth;
|
||||
else
|
||||
cfg.sample_count = layout->nr_samples;
|
||||
cfg.texel_interleave = (layout->modifier != DRM_FORMAT_MOD_LINEAR) ||
|
||||
util_format_is_compressed(iview->format);
|
||||
cfg.levels = iview->last_level - iview->first_level + 1;
|
||||
cfg.array_size = array_size;
|
||||
|
||||
cfg.surfaces = payload->gpu;
|
||||
|
||||
/* Requirements for storage image use. */
|
||||
cfg.minimum_lod = 0;
|
||||
cfg.maximum_lod = 0;
|
||||
cfg.minimum_level = 0;
|
||||
cfg.swizzle = panfrost_translate_swizzle_4(rgba_swizzle);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if PAN_ARCH >= 9
|
||||
enum mali_afbc_compression_mode
|
||||
GENX(pan_afbc_compression_mode)(enum pipe_format format)
|
||||
|
|
|
|||
|
|
@ -419,6 +419,12 @@ void GENX(panfrost_texture_afbc_reswizzle)(struct pan_image_view *iview);
|
|||
void GENX(panfrost_new_texture)(const struct pan_image_view *iview,
|
||||
struct mali_texture_packed *out,
|
||||
const struct panfrost_ptr *payload);
|
||||
|
||||
#if PAN_ARCH >= 9
|
||||
void GENX(panfrost_new_storage_texture)(const struct pan_image_view *iview,
|
||||
struct mali_texture_packed *out,
|
||||
const struct panfrost_ptr *payload);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
unsigned panfrost_get_layer_stride(const struct pan_image_layout *layout,
|
||||
|
|
|
|||
|
|
@ -36,9 +36,10 @@ struct panvk_image_view {
|
|||
struct mali_texture_packed other_aspect_tex;
|
||||
} zs;
|
||||
};
|
||||
|
||||
#if PAN_ARCH <= 7
|
||||
/* Valhall passes a texture descriptor to the LEA_TEX instruction. */
|
||||
#if PAN_ARCH >= 9
|
||||
/* Valhall passes a limited texture descriptor to the LEA_TEX instruction */
|
||||
struct mali_texture_packed storage_tex[PANVK_MAX_PLANES];
|
||||
#else
|
||||
struct mali_attribute_buffer_packed img_attrib_buf[2];
|
||||
#endif
|
||||
} descs;
|
||||
|
|
|
|||
|
|
@ -95,14 +95,18 @@ write_image_view_desc(struct panvk_descriptor_set *set,
|
|||
uint8_t plane_count = vk_format_get_plane_count(view->vk.format);
|
||||
for (uint8_t plane = 0; plane < plane_count; plane++) {
|
||||
struct panvk_subdesc_info subdesc = get_tex_subdesc_info(type, plane);
|
||||
#if PAN_ARCH <= 7
|
||||
#if PAN_ARCH >= 9
|
||||
if (type == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
|
||||
write_desc(set, binding, elem, &view->descs.storage_tex[plane],
|
||||
subdesc);
|
||||
else
|
||||
write_desc(set, binding, elem, &view->descs.tex[plane], subdesc);
|
||||
#else
|
||||
if (type == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
|
||||
write_desc(set, binding, elem, &view->descs.img_attrib_buf,
|
||||
NO_SUBDESC);
|
||||
else
|
||||
write_desc(set, binding, elem, &view->descs.tex[plane], subdesc);
|
||||
#else
|
||||
write_desc(set, binding, elem, &view->descs.tex[plane], subdesc);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -131,6 +131,15 @@ prepare_tex_descs(struct panvk_image_view *view)
|
|||
.size = tex_payload_size * (can_preload_other_aspect ? 2 : plane_count),
|
||||
};
|
||||
|
||||
#if PAN_ARCH >= 9
|
||||
uint32_t storage_payload_size = 0;
|
||||
if (view->vk.usage & VK_IMAGE_USAGE_STORAGE_BIT) {
|
||||
/* We'll need a second set of Texture Descriptors for storage use. */
|
||||
storage_payload_size = tex_payload_size * plane_count;
|
||||
alloc_info.size += storage_payload_size;
|
||||
}
|
||||
#endif
|
||||
|
||||
view->mem = panvk_pool_alloc_mem(&dev->mempools.rw, alloc_info);
|
||||
if (!panvk_priv_mem_host_addr(view->mem))
|
||||
return panvk_error(dev, VK_ERROR_OUT_OF_DEVICE_MEMORY);
|
||||
|
|
@ -140,6 +149,15 @@ prepare_tex_descs(struct panvk_image_view *view)
|
|||
.cpu = panvk_priv_mem_host_addr(view->mem),
|
||||
};
|
||||
|
||||
#if PAN_ARCH >= 9
|
||||
struct panfrost_ptr storage_ptr = ptr;
|
||||
if (view->vk.usage & VK_IMAGE_USAGE_STORAGE_BIT) {
|
||||
uint32_t storage_payload_offset = alloc_info.size - storage_payload_size;
|
||||
storage_ptr.gpu += storage_payload_offset;
|
||||
storage_ptr.cpu += storage_payload_offset;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (plane_count > 1) {
|
||||
memset(pview.planes, 0, sizeof(pview.planes));
|
||||
|
||||
|
|
@ -152,12 +170,25 @@ prepare_tex_descs(struct panvk_image_view *view)
|
|||
pview.format = vk_format_to_pipe_format(plane_format);
|
||||
|
||||
GENX(panfrost_new_texture)(&pview, &view->descs.tex[plane], &ptr);
|
||||
#if PAN_ARCH >= 9
|
||||
if (view->vk.usage & VK_IMAGE_USAGE_STORAGE_BIT) {
|
||||
GENX(panfrost_new_storage_texture)(
|
||||
&pview, &view->descs.storage_tex[plane], &storage_ptr);
|
||||
storage_ptr.cpu += tex_payload_size;
|
||||
storage_ptr.gpu += tex_payload_size;
|
||||
}
|
||||
#endif
|
||||
|
||||
ptr.cpu += tex_payload_size;
|
||||
ptr.gpu += tex_payload_size;
|
||||
}
|
||||
} else {
|
||||
GENX(panfrost_new_texture)(&pview, &view->descs.tex[0], &ptr);
|
||||
#if PAN_ARCH >= 9
|
||||
if (view->vk.usage & VK_IMAGE_USAGE_STORAGE_BIT)
|
||||
GENX(panfrost_new_storage_texture)(&pview, &view->descs.storage_tex[0],
|
||||
&storage_ptr);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!can_preload_other_aspect)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue