mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 09:38:07 +02:00
turnip: Split tu_image_init to use layout setting logic separately
Signed-off-by: tarsin <yuanqingxiang233@163.com> [rob: improve comments about modifier taking precedence over image create flags, and fix bogus assert] Signed-off-by: Rob Clark <robdclark@chromium.org> Reviewed-by: Roman Stratiienko <r.stratiienko@gmail.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/29090>
This commit is contained in:
parent
ecd9ece9c1
commit
4b024a15f2
2 changed files with 130 additions and 107 deletions
|
|
@ -429,121 +429,48 @@ format_list_has_swaps(const VkImageFormatListCreateInfo *fmt_list)
|
|||
return false;
|
||||
}
|
||||
|
||||
static VkResult
|
||||
tu_image_init(struct tu_device *device, struct tu_image *image,
|
||||
const VkImageCreateInfo *pCreateInfo, uint64_t modifier,
|
||||
const VkSubresourceLayout *plane_layouts)
|
||||
VkResult
|
||||
tu_image_update_layout(struct tu_device *device, struct tu_image *image,
|
||||
uint64_t modifier, const VkSubresourceLayout *plane_layouts)
|
||||
{
|
||||
enum a6xx_tile_mode tile_mode = TILE6_3;
|
||||
image->vk.drm_format_mod = modifier;
|
||||
|
||||
enum a6xx_tile_mode tile_mode = TILE6_3;
|
||||
bool ubwc_enabled = true;
|
||||
|
||||
/* use linear tiling if requested */
|
||||
if (pCreateInfo->tiling == VK_IMAGE_TILING_LINEAR || modifier == DRM_FORMAT_MOD_LINEAR) {
|
||||
tile_mode = TILE6_LINEAR;
|
||||
ubwc_enabled = false;
|
||||
if (modifier == DRM_FORMAT_MOD_LINEAR) {
|
||||
image->force_linear_tile = true;
|
||||
}
|
||||
|
||||
/* Force linear tiling for formats with "fake" optimalTilingFeatures */
|
||||
if (!tiling_possible(image->vk.format)) {
|
||||
if (image->force_linear_tile) {
|
||||
tile_mode = TILE6_LINEAR;
|
||||
ubwc_enabled = false;
|
||||
image->ubwc_enabled = false;
|
||||
}
|
||||
|
||||
/* No sense in tiling a 1D image, you'd just waste space and cache locality. */
|
||||
if (pCreateInfo->imageType == VK_IMAGE_TYPE_1D) {
|
||||
tile_mode = TILE6_LINEAR;
|
||||
ubwc_enabled = false;
|
||||
}
|
||||
|
||||
/* Fragment density maps are sampled on the CPU and we don't support
|
||||
* sampling tiled images on the CPU or UBWC at the moment.
|
||||
*/
|
||||
if (pCreateInfo->usage & VK_IMAGE_USAGE_FRAGMENT_DENSITY_MAP_BIT_EXT) {
|
||||
tile_mode = TILE6_LINEAR;
|
||||
ubwc_enabled = false;
|
||||
}
|
||||
|
||||
enum pipe_format format =
|
||||
tu_vk_format_to_pipe_format(image->vk.format);
|
||||
/* Whether a view of the image with an R8G8 format could be made. */
|
||||
bool has_r8g8 = tu_is_r8g8(format);
|
||||
bool has_r8g8 = tu_is_r8g8(tu_vk_format_to_pipe_format(image->vk.format));
|
||||
|
||||
if (ubwc_enabled &&
|
||||
!ubwc_possible(device, image->vk.format, pCreateInfo->imageType,
|
||||
pCreateInfo->usage, image->vk.stencil_usage,
|
||||
device->physical_device->info, pCreateInfo->samples,
|
||||
device->use_z24uint_s8uint))
|
||||
ubwc_enabled = false;
|
||||
|
||||
/* Mutable images can be reinterpreted as any other compatible format.
|
||||
* This is a problem with UBWC (compression for different formats is different),
|
||||
* but also tiling ("swap" affects how tiled formats are stored in memory)
|
||||
* Depth and stencil formats cannot be reintepreted as another format, and
|
||||
* cannot be linear with sysmem rendering, so don't fall back for those.
|
||||
*
|
||||
* TODO:
|
||||
* - if the fmt_list contains only formats which are swapped, but compatible
|
||||
* with each other (B8G8R8A8_UNORM and B8G8R8A8_UINT for example), then
|
||||
* tiling is still possible
|
||||
* - figure out which UBWC compressions are compatible to keep it enabled
|
||||
/* With AHB, we could be asked to create an image with VK_IMAGE_TILING_LINEAR
|
||||
* but gralloc doesn't know this. So if we are explicitly told that it is
|
||||
* UBWC, then override how the image was created.
|
||||
*/
|
||||
if ((pCreateInfo->flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT) &&
|
||||
!vk_format_is_depth_or_stencil(image->vk.format)) {
|
||||
const VkImageFormatListCreateInfo *fmt_list =
|
||||
vk_find_struct_const(pCreateInfo->pNext, IMAGE_FORMAT_LIST_CREATE_INFO);
|
||||
if (!tu6_mutable_format_list_ubwc_compatible(device->physical_device->info,
|
||||
fmt_list)) {
|
||||
if (ubwc_enabled) {
|
||||
if (fmt_list && fmt_list->viewFormatCount == 2) {
|
||||
perf_debug(
|
||||
device,
|
||||
"Disabling UBWC on %dx%d %s resource due to mutable formats "
|
||||
"(fmt list %s, %s)",
|
||||
image->vk.extent.width, image->vk.extent.height,
|
||||
util_format_name(vk_format_to_pipe_format(image->vk.format)),
|
||||
util_format_name(vk_format_to_pipe_format(fmt_list->pViewFormats[0])),
|
||||
util_format_name(vk_format_to_pipe_format(fmt_list->pViewFormats[1])));
|
||||
} else {
|
||||
perf_debug(
|
||||
device,
|
||||
"Disabling UBWC on %dx%d %s resource due to mutable formats "
|
||||
"(fmt list %s)",
|
||||
image->vk.extent.width, image->vk.extent.height,
|
||||
util_format_name(vk_format_to_pipe_format(image->vk.format)),
|
||||
fmt_list ? "present" : "missing");
|
||||
}
|
||||
ubwc_enabled = false;
|
||||
}
|
||||
|
||||
if (format_list_reinterprets_r8g8_r16(format, fmt_list) ||
|
||||
format_list_has_swaps(fmt_list)) {
|
||||
tile_mode = TILE6_LINEAR;
|
||||
}
|
||||
}
|
||||
if (modifier == DRM_FORMAT_MOD_QCOM_COMPRESSED) {
|
||||
assert(!image->force_linear_tile);
|
||||
image->ubwc_enabled = true;
|
||||
}
|
||||
|
||||
/* expect UBWC enabled if we asked for it */
|
||||
if (modifier == DRM_FORMAT_MOD_QCOM_COMPRESSED)
|
||||
assert(ubwc_enabled);
|
||||
else if (TU_DEBUG(NOUBWC))
|
||||
ubwc_enabled = false;
|
||||
|
||||
/* Non-UBWC tiled R8G8 is probably buggy since media formats are always
|
||||
* either linear or UBWC. There is no simple test to reproduce the bug.
|
||||
* However it was observed in the wild leading to an unrecoverable hang
|
||||
* on a650/a660.
|
||||
*/
|
||||
if (has_r8g8 && tile_mode == TILE6_3 && !ubwc_enabled) {
|
||||
if (has_r8g8 && tile_mode == TILE6_3 && !image->ubwc_enabled) {
|
||||
tile_mode = TILE6_LINEAR;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < tu6_plane_count(image->vk.format); i++) {
|
||||
struct fdl_layout *layout = &image->layout[i];
|
||||
enum pipe_format format = tu6_plane_format(image->vk.format, i);
|
||||
uint32_t width0 = pCreateInfo->extent.width;
|
||||
uint32_t height0 = pCreateInfo->extent.height;
|
||||
uint32_t width0 = image->vk.extent.width;
|
||||
uint32_t height0 = image->vk.extent.height;
|
||||
|
||||
if (i > 0) {
|
||||
switch (image->vk.format) {
|
||||
|
|
@ -555,7 +482,7 @@ tu_image_init(struct tu_device *device, struct tu_image *image,
|
|||
break;
|
||||
case VK_FORMAT_D32_SFLOAT_S8_UINT:
|
||||
/* no UBWC for separate stencil */
|
||||
ubwc_enabled = false;
|
||||
image->ubwc_enabled = false;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
@ -566,9 +493,9 @@ tu_image_init(struct tu_device *device, struct tu_image *image,
|
|||
|
||||
if (plane_layouts) {
|
||||
/* only expect simple 2D images for now */
|
||||
if (pCreateInfo->mipLevels != 1 ||
|
||||
pCreateInfo->arrayLayers != 1 ||
|
||||
pCreateInfo->extent.depth != 1)
|
||||
if (image->vk.mip_levels != 1 ||
|
||||
image->vk.array_layers != 1 ||
|
||||
image->vk.extent.depth != 1)
|
||||
return vk_error(device, VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT);
|
||||
|
||||
plane_layout.offset = plane_layouts[i].offset;
|
||||
|
|
@ -577,15 +504,15 @@ tu_image_init(struct tu_device *device, struct tu_image *image,
|
|||
}
|
||||
|
||||
layout->tile_mode = tile_mode;
|
||||
layout->ubwc = ubwc_enabled;
|
||||
layout->ubwc = image->ubwc_enabled;
|
||||
|
||||
if (!fdl6_layout(layout, format,
|
||||
pCreateInfo->samples,
|
||||
image->vk.samples,
|
||||
width0, height0,
|
||||
pCreateInfo->extent.depth,
|
||||
pCreateInfo->mipLevels,
|
||||
pCreateInfo->arrayLayers,
|
||||
pCreateInfo->imageType == VK_IMAGE_TYPE_3D,
|
||||
image->vk.extent.depth,
|
||||
image->vk.mip_levels,
|
||||
image->vk.array_layers,
|
||||
image->vk.image_type == VK_IMAGE_TYPE_3D,
|
||||
plane_layouts ? &plane_layout : NULL)) {
|
||||
assert(plane_layouts); /* can only fail with explicit layout */
|
||||
return vk_error(device, VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT);
|
||||
|
|
@ -599,7 +526,7 @@ tu_image_init(struct tu_device *device, struct tu_image *image,
|
|||
*/
|
||||
if (!plane_layouts && i > 0) {
|
||||
uint32_t offset = ALIGN_POT(image->total_size, 4096);
|
||||
for (int i = 0; i < pCreateInfo->mipLevels; i++) {
|
||||
for (int i = 0; i < image->vk.mip_levels; i++) {
|
||||
layout->slices[i].offset += offset;
|
||||
layout->ubwc_slices[i].offset += offset;
|
||||
}
|
||||
|
|
@ -670,6 +597,95 @@ tu_image_init(struct tu_device *device, struct tu_image *image,
|
|||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
static VkResult
|
||||
tu_image_init(struct tu_device *device, struct tu_image *image,
|
||||
const VkImageCreateInfo *pCreateInfo)
|
||||
{
|
||||
image->ubwc_enabled = true;
|
||||
|
||||
/* use linear tiling if requested */
|
||||
if (pCreateInfo->tiling == VK_IMAGE_TILING_LINEAR) {
|
||||
image->force_linear_tile = true;
|
||||
}
|
||||
|
||||
/* Force linear tiling for formats with "fake" optimalTilingFeatures */
|
||||
if (!tiling_possible(image->vk.format)) {
|
||||
image->force_linear_tile = true;
|
||||
}
|
||||
|
||||
/* No sense in tiling a 1D image, you'd just waste space and cache locality. */
|
||||
if (pCreateInfo->imageType == VK_IMAGE_TYPE_1D) {
|
||||
image->force_linear_tile = true;
|
||||
}
|
||||
|
||||
/* Fragment density maps are sampled on the CPU and we don't support
|
||||
* sampling tiled images on the CPU or UBWC at the moment.
|
||||
*/
|
||||
if (pCreateInfo->usage & VK_IMAGE_USAGE_FRAGMENT_DENSITY_MAP_BIT_EXT) {
|
||||
image->force_linear_tile = true;
|
||||
}
|
||||
|
||||
if (image->force_linear_tile ||
|
||||
!ubwc_possible(device, image->vk.format, pCreateInfo->imageType,
|
||||
pCreateInfo->usage, image->vk.stencil_usage,
|
||||
device->physical_device->info, pCreateInfo->samples,
|
||||
device->use_z24uint_s8uint))
|
||||
image->ubwc_enabled = false;
|
||||
|
||||
/* Mutable images can be reinterpreted as any other compatible format.
|
||||
* This is a problem with UBWC (compression for different formats is different),
|
||||
* but also tiling ("swap" affects how tiled formats are stored in memory)
|
||||
* Depth and stencil formats cannot be reintepreted as another format, and
|
||||
* cannot be linear with sysmem rendering, so don't fall back for those.
|
||||
*
|
||||
* TODO:
|
||||
* - if the fmt_list contains only formats which are swapped, but compatible
|
||||
* with each other (B8G8R8A8_UNORM and B8G8R8A8_UINT for example), then
|
||||
* tiling is still possible
|
||||
* - figure out which UBWC compressions are compatible to keep it enabled
|
||||
*/
|
||||
if ((pCreateInfo->flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT) &&
|
||||
!vk_format_is_depth_or_stencil(image->vk.format)) {
|
||||
const VkImageFormatListCreateInfo *fmt_list =
|
||||
vk_find_struct_const(pCreateInfo->pNext, IMAGE_FORMAT_LIST_CREATE_INFO);
|
||||
if (!tu6_mutable_format_list_ubwc_compatible(device->physical_device->info,
|
||||
fmt_list)) {
|
||||
if (image->ubwc_enabled) {
|
||||
if (fmt_list && fmt_list->viewFormatCount == 2) {
|
||||
perf_debug(
|
||||
device,
|
||||
"Disabling UBWC on %dx%d %s resource due to mutable formats "
|
||||
"(fmt list %s, %s)",
|
||||
image->vk.extent.width, image->vk.extent.height,
|
||||
util_format_name(vk_format_to_pipe_format(image->vk.format)),
|
||||
util_format_name(vk_format_to_pipe_format(fmt_list->pViewFormats[0])),
|
||||
util_format_name(vk_format_to_pipe_format(fmt_list->pViewFormats[1])));
|
||||
} else {
|
||||
perf_debug(
|
||||
device,
|
||||
"Disabling UBWC on %dx%d %s resource due to mutable formats "
|
||||
"(fmt list %s)",
|
||||
image->vk.extent.width, image->vk.extent.height,
|
||||
util_format_name(vk_format_to_pipe_format(image->vk.format)),
|
||||
fmt_list ? "present" : "missing");
|
||||
}
|
||||
image->ubwc_enabled = false;
|
||||
}
|
||||
|
||||
if (format_list_reinterprets_r8g8_r16(tu_vk_format_to_pipe_format(image->vk.format), fmt_list) ||
|
||||
format_list_has_swaps(fmt_list)) {
|
||||
image->force_linear_tile = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (TU_DEBUG(NOUBWC)) {
|
||||
image->ubwc_enabled = false;
|
||||
}
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
VKAPI_ATTR VkResult VKAPI_CALL
|
||||
tu_CreateImage(VkDevice _device,
|
||||
const VkImageCreateInfo *pCreateInfo,
|
||||
|
|
@ -745,7 +761,11 @@ tu_CreateImage(VkDevice _device,
|
|||
modifier = eci.drmFormatModifier;
|
||||
}
|
||||
|
||||
result = tu_image_init(device, image, pCreateInfo, modifier,
|
||||
result = tu_image_init(device, image, pCreateInfo);
|
||||
if (result != VK_SUCCESS)
|
||||
goto fail;
|
||||
|
||||
result = tu_image_update_layout(device, image, modifier,
|
||||
plane_layouts);
|
||||
if (result != VK_SUCCESS)
|
||||
goto fail;
|
||||
|
|
@ -908,8 +928,8 @@ tu_GetDeviceImageMemoryRequirements(
|
|||
struct tu_image image = {0};
|
||||
|
||||
vk_image_init(&device->vk, &image.vk, pInfo->pCreateInfo);
|
||||
tu_image_init(device, &image, pInfo->pCreateInfo, DRM_FORMAT_MOD_INVALID,
|
||||
NULL);
|
||||
tu_image_init(device, &image, pInfo->pCreateInfo);
|
||||
tu_image_update_layout(device, &image, DRM_FORMAT_MOD_INVALID, NULL);
|
||||
|
||||
tu_get_image_memory_requirements(device, &image, pMemoryRequirements);
|
||||
}
|
||||
|
|
@ -974,8 +994,8 @@ tu_GetDeviceImageSubresourceLayoutKHR(VkDevice _device,
|
|||
struct tu_image image = {0};
|
||||
|
||||
vk_image_init(&device->vk, &image.vk, pInfo->pCreateInfo);
|
||||
tu_image_init(device, &image, pInfo->pCreateInfo, DRM_FORMAT_MOD_INVALID,
|
||||
NULL);
|
||||
tu_image_init(device, &image, pInfo->pCreateInfo);
|
||||
tu_image_update_layout(device, &image, DRM_FORMAT_MOD_INVALID, NULL);
|
||||
|
||||
tu_get_image_subresource_layout(&image, pInfo->pSubresource, pLayout);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,6 +39,9 @@ struct tu_image
|
|||
uint32_t lrz_offset;
|
||||
uint32_t lrz_fc_offset;
|
||||
uint32_t lrz_fc_size;
|
||||
|
||||
bool ubwc_enabled;
|
||||
bool force_linear_tile;
|
||||
};
|
||||
VK_DEFINE_NONDISP_HANDLE_CASTS(tu_image, vk.base, VkImage, VK_OBJECT_TYPE_IMAGE)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue