mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-06-03 21:58:26 +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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static VkResult
|
VkResult
|
||||||
tu_image_init(struct tu_device *device, struct tu_image *image,
|
tu_image_update_layout(struct tu_device *device, struct tu_image *image,
|
||||||
const VkImageCreateInfo *pCreateInfo, uint64_t modifier,
|
uint64_t modifier, const VkSubresourceLayout *plane_layouts)
|
||||||
const VkSubresourceLayout *plane_layouts)
|
|
||||||
{
|
{
|
||||||
|
enum a6xx_tile_mode tile_mode = TILE6_3;
|
||||||
image->vk.drm_format_mod = modifier;
|
image->vk.drm_format_mod = modifier;
|
||||||
|
|
||||||
enum a6xx_tile_mode tile_mode = TILE6_3;
|
if (modifier == DRM_FORMAT_MOD_LINEAR) {
|
||||||
bool ubwc_enabled = true;
|
image->force_linear_tile = 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Force linear tiling for formats with "fake" optimalTilingFeatures */
|
if (image->force_linear_tile) {
|
||||||
if (!tiling_possible(image->vk.format)) {
|
|
||||||
tile_mode = TILE6_LINEAR;
|
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. */
|
/* 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 &&
|
/* With AHB, we could be asked to create an image with VK_IMAGE_TILING_LINEAR
|
||||||
!ubwc_possible(device, image->vk.format, pCreateInfo->imageType,
|
* but gralloc doesn't know this. So if we are explicitly told that it is
|
||||||
pCreateInfo->usage, image->vk.stencil_usage,
|
* UBWC, then override how the image was created.
|
||||||
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
|
|
||||||
*/
|
*/
|
||||||
if ((pCreateInfo->flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT) &&
|
if (modifier == DRM_FORMAT_MOD_QCOM_COMPRESSED) {
|
||||||
!vk_format_is_depth_or_stencil(image->vk.format)) {
|
assert(!image->force_linear_tile);
|
||||||
const VkImageFormatListCreateInfo *fmt_list =
|
image->ubwc_enabled = true;
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 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
|
/* 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.
|
* 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
|
* However it was observed in the wild leading to an unrecoverable hang
|
||||||
* on a650/a660.
|
* 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;
|
tile_mode = TILE6_LINEAR;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint32_t i = 0; i < tu6_plane_count(image->vk.format); i++) {
|
for (uint32_t i = 0; i < tu6_plane_count(image->vk.format); i++) {
|
||||||
struct fdl_layout *layout = &image->layout[i];
|
struct fdl_layout *layout = &image->layout[i];
|
||||||
enum pipe_format format = tu6_plane_format(image->vk.format, i);
|
enum pipe_format format = tu6_plane_format(image->vk.format, i);
|
||||||
uint32_t width0 = pCreateInfo->extent.width;
|
uint32_t width0 = image->vk.extent.width;
|
||||||
uint32_t height0 = pCreateInfo->extent.height;
|
uint32_t height0 = image->vk.extent.height;
|
||||||
|
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
switch (image->vk.format) {
|
switch (image->vk.format) {
|
||||||
|
|
@ -555,7 +482,7 @@ tu_image_init(struct tu_device *device, struct tu_image *image,
|
||||||
break;
|
break;
|
||||||
case VK_FORMAT_D32_SFLOAT_S8_UINT:
|
case VK_FORMAT_D32_SFLOAT_S8_UINT:
|
||||||
/* no UBWC for separate stencil */
|
/* no UBWC for separate stencil */
|
||||||
ubwc_enabled = false;
|
image->ubwc_enabled = false;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|
@ -566,9 +493,9 @@ tu_image_init(struct tu_device *device, struct tu_image *image,
|
||||||
|
|
||||||
if (plane_layouts) {
|
if (plane_layouts) {
|
||||||
/* only expect simple 2D images for now */
|
/* only expect simple 2D images for now */
|
||||||
if (pCreateInfo->mipLevels != 1 ||
|
if (image->vk.mip_levels != 1 ||
|
||||||
pCreateInfo->arrayLayers != 1 ||
|
image->vk.array_layers != 1 ||
|
||||||
pCreateInfo->extent.depth != 1)
|
image->vk.extent.depth != 1)
|
||||||
return vk_error(device, VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT);
|
return vk_error(device, VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT);
|
||||||
|
|
||||||
plane_layout.offset = plane_layouts[i].offset;
|
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->tile_mode = tile_mode;
|
||||||
layout->ubwc = ubwc_enabled;
|
layout->ubwc = image->ubwc_enabled;
|
||||||
|
|
||||||
if (!fdl6_layout(layout, format,
|
if (!fdl6_layout(layout, format,
|
||||||
pCreateInfo->samples,
|
image->vk.samples,
|
||||||
width0, height0,
|
width0, height0,
|
||||||
pCreateInfo->extent.depth,
|
image->vk.extent.depth,
|
||||||
pCreateInfo->mipLevels,
|
image->vk.mip_levels,
|
||||||
pCreateInfo->arrayLayers,
|
image->vk.array_layers,
|
||||||
pCreateInfo->imageType == VK_IMAGE_TYPE_3D,
|
image->vk.image_type == VK_IMAGE_TYPE_3D,
|
||||||
plane_layouts ? &plane_layout : NULL)) {
|
plane_layouts ? &plane_layout : NULL)) {
|
||||||
assert(plane_layouts); /* can only fail with explicit layout */
|
assert(plane_layouts); /* can only fail with explicit layout */
|
||||||
return vk_error(device, VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT);
|
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) {
|
if (!plane_layouts && i > 0) {
|
||||||
uint32_t offset = ALIGN_POT(image->total_size, 4096);
|
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->slices[i].offset += offset;
|
||||||
layout->ubwc_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;
|
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
|
VKAPI_ATTR VkResult VKAPI_CALL
|
||||||
tu_CreateImage(VkDevice _device,
|
tu_CreateImage(VkDevice _device,
|
||||||
const VkImageCreateInfo *pCreateInfo,
|
const VkImageCreateInfo *pCreateInfo,
|
||||||
|
|
@ -745,7 +761,11 @@ tu_CreateImage(VkDevice _device,
|
||||||
modifier = eci.drmFormatModifier;
|
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);
|
plane_layouts);
|
||||||
if (result != VK_SUCCESS)
|
if (result != VK_SUCCESS)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
@ -908,8 +928,8 @@ tu_GetDeviceImageMemoryRequirements(
|
||||||
struct tu_image image = {0};
|
struct tu_image image = {0};
|
||||||
|
|
||||||
vk_image_init(&device->vk, &image.vk, pInfo->pCreateInfo);
|
vk_image_init(&device->vk, &image.vk, pInfo->pCreateInfo);
|
||||||
tu_image_init(device, &image, pInfo->pCreateInfo, DRM_FORMAT_MOD_INVALID,
|
tu_image_init(device, &image, pInfo->pCreateInfo);
|
||||||
NULL);
|
tu_image_update_layout(device, &image, DRM_FORMAT_MOD_INVALID, NULL);
|
||||||
|
|
||||||
tu_get_image_memory_requirements(device, &image, pMemoryRequirements);
|
tu_get_image_memory_requirements(device, &image, pMemoryRequirements);
|
||||||
}
|
}
|
||||||
|
|
@ -974,8 +994,8 @@ tu_GetDeviceImageSubresourceLayoutKHR(VkDevice _device,
|
||||||
struct tu_image image = {0};
|
struct tu_image image = {0};
|
||||||
|
|
||||||
vk_image_init(&device->vk, &image.vk, pInfo->pCreateInfo);
|
vk_image_init(&device->vk, &image.vk, pInfo->pCreateInfo);
|
||||||
tu_image_init(device, &image, pInfo->pCreateInfo, DRM_FORMAT_MOD_INVALID,
|
tu_image_init(device, &image, pInfo->pCreateInfo);
|
||||||
NULL);
|
tu_image_update_layout(device, &image, DRM_FORMAT_MOD_INVALID, NULL);
|
||||||
|
|
||||||
tu_get_image_subresource_layout(&image, pInfo->pSubresource, pLayout);
|
tu_get_image_subresource_layout(&image, pInfo->pSubresource, pLayout);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,9 @@ struct tu_image
|
||||||
uint32_t lrz_offset;
|
uint32_t lrz_offset;
|
||||||
uint32_t lrz_fc_offset;
|
uint32_t lrz_fc_offset;
|
||||||
uint32_t lrz_fc_size;
|
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)
|
VK_DEFINE_NONDISP_HANDLE_CASTS(tu_image, vk.base, VkImage, VK_OBJECT_TYPE_IMAGE)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue