X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Famd%2Fvulkan%2Fradv_image.c;h=43ccec304bb74ba4c61ec0a9a0d5e39105a6549c;hb=f18fc34c4d56d6e7d511002b39a257e18d8b3af3;hp=8c65eb6bc37474c4e6d3ad504300f7051898f86d;hpb=3c28438094b8345bc0797e02af728ca41049d4bb;p=mesa.git diff --git a/src/amd/vulkan/radv_image.c b/src/amd/vulkan/radv_image.c index 8c65eb6bc37..43ccec304bb 100644 --- a/src/amd/vulkan/radv_image.c +++ b/src/amd/vulkan/radv_image.c @@ -150,8 +150,12 @@ radv_surface_has_scanout(struct radv_device *device, const struct radv_image_cre } static bool -radv_image_use_fast_clear_for_image(const struct radv_image *image) +radv_image_use_fast_clear_for_image(const struct radv_device *device, + const struct radv_image *image) { + if (device->instance->debug_flags & RADV_DEBUG_FORCE_COMPRESS) + return true; + if (image->info.samples <= 1 && image->info.width * image->info.height <= 512 * 512) { /* Do not enable CMASK or DCC for small surfaces where the cost @@ -196,7 +200,7 @@ radv_use_dcc_for_image(struct radv_device *device, vk_format_get_plane_count(format) > 1) return false; - if (!radv_image_use_fast_clear_for_image(image)) + if (!radv_image_use_fast_clear_for_image(device, image)) return false; /* TODO: Enable DCC for mipmaps on GFX9+. */ @@ -251,17 +255,21 @@ radv_use_dcc_for_image(struct radv_device *device, } static inline bool -radv_use_fmask_for_image(const struct radv_image *image) +radv_use_fmask_for_image(const struct radv_device *device, + const struct radv_image *image) { return image->info.samples > 1 && - image->usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; + ((image->usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) || + (device->instance->debug_flags & RADV_DEBUG_FORCE_COMPRESS)); } static inline bool -radv_use_htile_for_image(const struct radv_image *image) +radv_use_htile_for_image(const struct radv_device *device, + const struct radv_image *image) { return image->info.levels == 1 && - image->info.width * image->info.height >= 8 * 8; + ((image->info.width * image->info.height >= 8 * 8) || + (device->instance->debug_flags & RADV_DEBUG_FORCE_COMPRESS)); } static bool @@ -361,7 +369,7 @@ radv_patch_image_dimensions(struct radv_device *device, if (device->physical_device->rad_info.chip_class >= GFX10) { width = G_00A004_WIDTH_LO(md->metadata[3]) + (G_00A008_WIDTH_HI(md->metadata[4]) << 2) + 1; - height = S_00A008_HEIGHT(md->metadata[4]) + 1; + height = G_00A008_HEIGHT(md->metadata[4]) + 1; } else { width = G_008F18_WIDTH(md->metadata[4]) + 1; height = G_008F18_HEIGHT(md->metadata[4]) + 1; @@ -427,14 +435,14 @@ radv_patch_image_from_extra_info(struct radv_device *device, return VK_SUCCESS; } -static int -radv_init_surface(struct radv_device *device, - const struct radv_image *image, - struct radeon_surf *surface, - unsigned plane_id, - const VkImageCreateInfo *pCreateInfo, - VkFormat image_format) +static uint32_t +radv_get_surface_flags(struct radv_device *device, + const struct radv_image *image, + unsigned plane_id, + const VkImageCreateInfo *pCreateInfo, + VkFormat image_format) { + uint32_t flags; unsigned array_mode = radv_choose_tiling(device, pCreateInfo, image_format); VkFormat format = vk_format_get_plane_format(image_format, plane_id); const struct vk_format_description *desc = vk_format_description(format); @@ -443,65 +451,57 @@ radv_init_surface(struct radv_device *device, is_depth = vk_format_has_depth(desc); is_stencil = vk_format_has_stencil(desc); - surface->blk_w = vk_format_get_blockwidth(format); - surface->blk_h = vk_format_get_blockheight(format); - - surface->bpe = vk_format_get_blocksize(vk_format_depth_only(format)); - /* align byte per element on dword */ - if (surface->bpe == 3) { - surface->bpe = 4; - } - surface->flags = RADEON_SURF_SET(array_mode, MODE); + flags = RADEON_SURF_SET(array_mode, MODE); switch (pCreateInfo->imageType){ case VK_IMAGE_TYPE_1D: if (pCreateInfo->arrayLayers > 1) - surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_1D_ARRAY, TYPE); + flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_1D_ARRAY, TYPE); else - surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_1D, TYPE); + flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_1D, TYPE); break; case VK_IMAGE_TYPE_2D: if (pCreateInfo->arrayLayers > 1) - surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_2D_ARRAY, TYPE); + flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_2D_ARRAY, TYPE); else - surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_2D, TYPE); + flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_2D, TYPE); break; case VK_IMAGE_TYPE_3D: - surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_3D, TYPE); + flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_3D, TYPE); break; default: unreachable("unhandled image type"); } /* Required for clearing/initializing a specific layer on GFX8. */ - surface->flags |= RADEON_SURF_CONTIGUOUS_DCC_LAYERS; + flags |= RADEON_SURF_CONTIGUOUS_DCC_LAYERS; if (is_depth) { - surface->flags |= RADEON_SURF_ZBUFFER; - if (!radv_use_htile_for_image(image) || + flags |= RADEON_SURF_ZBUFFER; + if (!radv_use_htile_for_image(device, image) || (device->instance->debug_flags & RADV_DEBUG_NO_HIZ)) - surface->flags |= RADEON_SURF_NO_HTILE; + flags |= RADEON_SURF_NO_HTILE; if (radv_use_tc_compat_htile_for_image(device, pCreateInfo, image_format)) - surface->flags |= RADEON_SURF_TC_COMPATIBLE_HTILE; + flags |= RADEON_SURF_TC_COMPATIBLE_HTILE; } if (is_stencil) - surface->flags |= RADEON_SURF_SBUFFER; + flags |= RADEON_SURF_SBUFFER; if (device->physical_device->rad_info.chip_class >= GFX9 && pCreateInfo->imageType == VK_IMAGE_TYPE_3D && vk_format_get_blocksizebits(image_format) == 128 && vk_format_is_compressed(image_format)) - surface->flags |= RADEON_SURF_NO_RENDER_TARGET; + flags |= RADEON_SURF_NO_RENDER_TARGET; if (!radv_use_dcc_for_image(device, image, pCreateInfo, image_format)) - surface->flags |= RADEON_SURF_DISABLE_DCC; + flags |= RADEON_SURF_DISABLE_DCC; - if (!radv_use_fmask_for_image(image)) - surface->flags |= RADEON_SURF_NO_FMASK; + if (!radv_use_fmask_for_image(device, image)) + flags |= RADEON_SURF_NO_FMASK; - return 0; + return flags; } static inline unsigned @@ -842,7 +842,9 @@ gfx10_make_texture_descriptor(struct radv_device *device, S_00A014_MAX_MIP(image->info.samples > 1 ? util_logbase2(image->info.samples) : image->info.levels - 1) | - S_00A014_PERF_MOD(4); + S_00A014_PERF_MOD(4) | + S_00A014_BIG_PAGE(device->physical_device->rad_info.chip_class >= GFX10_3 && + image->alignment % (64 * 1024) == 0); state[6] = 0; state[7] = 0; @@ -1030,13 +1032,13 @@ si_make_texture_descriptor(struct radv_device *device, fmask_format = V_008F14_IMG_DATA_FORMAT_FMASK; switch (image->info.samples) { case 2: - num_format = V_008F14_IMG_FMASK_8_2_2; + num_format = V_008F14_IMG_NUM_FORMAT_FMASK_8_2_2; break; case 4: - num_format = V_008F14_IMG_FMASK_8_4_4; + num_format = V_008F14_IMG_NUM_FORMAT_FMASK_8_4_4; break; case 8: - num_format = V_008F14_IMG_FMASK_32_8_8; + num_format = V_008F14_IMG_NUM_FORMAT_FMASK_32_8_8; break; default: unreachable("invalid nr_samples"); @@ -1230,14 +1232,18 @@ radv_image_override_offset_stride(struct radv_device *device, } static void -radv_image_alloc_single_sample_cmask(const struct radv_image *image, +radv_image_alloc_single_sample_cmask(const struct radv_device *device, + const struct radv_image *image, struct radeon_surf *surf) { if (!surf->cmask_size || surf->cmask_offset || surf->bpe > 8 || image->info.levels > 1 || image->info.depth > 1 || - !radv_image_use_fast_clear_for_image(image)) + radv_image_has_dcc(image) || + !radv_image_use_fast_clear_for_image(device, image)) return; + assert(image->info.storage_samples == 1); + surf->cmask_offset = align64(surf->total_size, surf->cmask_alignment); surf->total_size = surf->cmask_offset + surf->cmask_size; surf->alignment = MAX2(surf->alignment, surf->cmask_alignment); @@ -1271,14 +1277,40 @@ radv_image_alloc_values(const struct radv_device *device, struct radv_image *ima } } + +static void +radv_image_reset_layout(struct radv_image *image) +{ + image->size = 0; + image->alignment = 1; + + image->tc_compatible_cmask = image->tc_compatible_htile = 0; + image->fce_pred_offset = image->dcc_pred_offset = 0; + image->clear_value_offset = image->tc_compat_zrange_offset = 0; + + for (unsigned i = 0; i < image->plane_count; ++i) { + VkFormat format = vk_format_get_plane_format(image->vk_format, i); + + uint32_t flags = image->planes[i].surface.flags; + memset(image->planes + i, 0, sizeof(image->planes[i])); + + image->planes[i].surface.flags = flags; + image->planes[i].surface.blk_w = vk_format_get_blockwidth(format); + image->planes[i].surface.blk_h = vk_format_get_blockheight(format); + image->planes[i].surface.bpe = vk_format_get_blocksize(vk_format_depth_only(format)); + + /* align byte per element on dword */ + if (image->planes[i].surface.bpe == 3) { + image->planes[i].surface.bpe = 4; + } + } +} + VkResult radv_image_create_layout(struct radv_device *device, struct radv_image_create_info create_info, struct radv_image *image) { - /* Check that we did not initialize things earlier */ - assert(!image->planes[0].surface.surf_size); - /* Clear the pCreateInfo pointer so we catch issues in the delayed case when we test in the * common internal case. */ create_info.vk_info = NULL; @@ -1288,8 +1320,8 @@ radv_image_create_layout(struct radv_device *device, if (result != VK_SUCCESS) return result; - image->size = 0; - image->alignment = 1; + radv_image_reset_layout(image); + for (unsigned plane = 0; plane < image->plane_count; ++plane) { struct ac_surf_info info = image_info; @@ -1311,7 +1343,7 @@ radv_image_create_layout(struct radv_device *device, device->ws->surface_init(device->ws, &info, &image->planes[plane].surface); if (!create_info.no_metadata_planes && image->plane_count == 1) - radv_image_alloc_single_sample_cmask(image, &image->planes[plane].surface); + radv_image_alloc_single_sample_cmask(device, image, &image->planes[plane].surface); image->planes[plane].offset = align(image->size, image->planes[plane].surface.alignment); image->size = image->planes[plane].offset + image->planes[plane].surface.total_size; @@ -1332,6 +1364,23 @@ radv_image_create_layout(struct radv_device *device, return VK_SUCCESS; } +static void +radv_destroy_image(struct radv_device *device, + const VkAllocationCallbacks *pAllocator, + struct radv_image *image) +{ + if ((image->flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT) && image->bo) + device->ws->buffer_destroy(image->bo); + + if (image->owned_memory != VK_NULL_HANDLE) { + RADV_FROM_HANDLE(radv_device_memory, mem, image->owned_memory); + radv_free_memory(device, pAllocator, mem); + } + + vk_object_base_finish(&image->base); + vk_free2(&device->vk.alloc, pAllocator, image); +} + VkResult radv_image_create(VkDevice _device, const struct radv_image_create_info *create_info, @@ -1398,7 +1447,8 @@ radv_image_create(VkDevice _device, } for (unsigned plane = 0; plane < image->plane_count; ++plane) { - radv_init_surface(device, image, &image->planes[plane].surface, plane, pCreateInfo, format); + image->planes[plane].surface.flags = + radv_get_surface_flags(device, image, plane, pCreateInfo, format); } bool delay_layout = external_info && @@ -1421,7 +1471,7 @@ radv_image_create(VkDevice _device, image->bo = device->ws->buffer_create(device->ws, image->size, image->alignment, 0, RADEON_FLAG_VIRTUAL, RADV_BO_PRIORITY_VIRTUAL); if (!image->bo) { - vk_free2(&device->vk.alloc, alloc, image); + radv_destroy_image(device, alloc, image); return vk_error(device->instance, VK_ERROR_OUT_OF_DEVICE_MEMORY); } } @@ -1683,7 +1733,8 @@ bool radv_layout_can_fast_clear(const struct radv_image *image, bool in_render_loop, unsigned queue_mask) { - return layout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + return layout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL && + queue_mask == (1u << RADV_QUEUE_GENERAL); } bool radv_layout_dcc_compressed(const struct radv_device *device, @@ -1751,14 +1802,7 @@ radv_DestroyImage(VkDevice _device, VkImage _image, if (!image) return; - if (image->flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT) - device->ws->buffer_destroy(image->bo); - - if (image->owned_memory != VK_NULL_HANDLE) - radv_FreeMemory(_device, image->owned_memory, pAllocator); - - vk_object_base_finish(&image->base); - vk_free2(&device->vk.alloc, pAllocator, image); + radv_destroy_image(device, pAllocator, image); } void radv_GetImageSubresourceLayout(