X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Famd%2Fvulkan%2Fradv_image.c;h=deb34af3733b746c163a344b1994f0cdd5d2a3c1;hb=13b4e9adcfd60eb704528c637a8acb9651bc280c;hp=baf49c6b65adda8a5aceb64024be1c88d4d357b5;hpb=64768111c302014a6ae8db6122dedf0d5e5168cc;p=mesa.git diff --git a/src/amd/vulkan/radv_image.c b/src/amd/vulkan/radv_image.c index baf49c6b65a..deb34af3733 100644 --- a/src/amd/vulkan/radv_image.c +++ b/src/amd/vulkan/radv_image.c @@ -36,15 +36,16 @@ static unsigned radv_choose_tiling(struct radv_device *device, - const VkImageCreateInfo *pCreateInfo) + const VkImageCreateInfo *pCreateInfo, + VkFormat format) { if (pCreateInfo->tiling == VK_IMAGE_TILING_LINEAR) { assert(pCreateInfo->samples <= 1); return RADEON_SURF_MODE_LINEAR_ALIGNED; } - if (!vk_format_is_compressed(pCreateInfo->format) && - !vk_format_is_depth_or_stencil(pCreateInfo->format) + if (!vk_format_is_compressed(format) && + !vk_format_is_depth_or_stencil(format) && device->physical_device->rad_info.chip_class <= GFX8) { /* this causes hangs in some VK CTS tests on GFX9. */ /* Textures with a very small height are recommended to be linear. */ @@ -64,7 +65,8 @@ radv_choose_tiling(struct radv_device *device, static bool radv_use_tc_compat_htile_for_image(struct radv_device *device, - const VkImageCreateInfo *pCreateInfo) + const VkImageCreateInfo *pCreateInfo, + VkFormat format) { /* TC-compat HTILE is only available for GFX8+. */ if (device->physical_device->rad_info.chip_class < GFX8) @@ -84,8 +86,8 @@ radv_use_tc_compat_htile_for_image(struct radv_device *device, * tests - disable for now. On GFX10 D32_SFLOAT is affected as well. */ if (pCreateInfo->samples >= 2 && - (pCreateInfo->format == VK_FORMAT_D32_SFLOAT_S8_UINT || - (pCreateInfo->format == VK_FORMAT_D32_SFLOAT && + (format == VK_FORMAT_D32_SFLOAT_S8_UINT || + (format == VK_FORMAT_D32_SFLOAT && device->physical_device->rad_info.chip_class == GFX10))) return false; @@ -93,9 +95,9 @@ radv_use_tc_compat_htile_for_image(struct radv_device *device, * supports 32-bit. Though, it's possible to enable TC-compat for * 16-bit depth surfaces if no Z planes are compressed. */ - if (pCreateInfo->format != VK_FORMAT_D32_SFLOAT_S8_UINT && - pCreateInfo->format != VK_FORMAT_D32_SFLOAT && - pCreateInfo->format != VK_FORMAT_D16_UNORM) + if (format != VK_FORMAT_D32_SFLOAT_S8_UINT && + format != VK_FORMAT_D32_SFLOAT && + format != VK_FORMAT_D16_UNORM) return false; if (pCreateInfo->flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT) { @@ -113,7 +115,7 @@ radv_use_tc_compat_htile_for_image(struct radv_device *device, if (format_list->pViewFormats[i] == VK_FORMAT_UNDEFINED) continue; - if (pCreateInfo->format != format_list->pViewFormats[i]) + if (format != format_list->pViewFormats[i]) return false; } } else { @@ -143,7 +145,8 @@ radv_surface_has_scanout(struct radv_device *device, const struct radv_image_cre static bool radv_use_dcc_for_image(struct radv_device *device, const struct radv_image *image, - const VkImageCreateInfo *pCreateInfo) + const VkImageCreateInfo *pCreateInfo, + VkFormat format) { bool dcc_compatible_formats; bool blendable; @@ -166,8 +169,8 @@ radv_use_dcc_for_image(struct radv_device *device, if (pCreateInfo->tiling == VK_IMAGE_TILING_LINEAR) return false; - if (vk_format_is_subsampled(pCreateInfo->format) || - vk_format_get_plane_count(pCreateInfo->format) > 1) + if (vk_format_is_subsampled(format) || + vk_format_get_plane_count(format) > 1) return false; /* TODO: Enable DCC for mipmaps on GFX9+. */ @@ -189,7 +192,7 @@ radv_use_dcc_for_image(struct radv_device *device, /* Determine if the formats are DCC compatible. */ dcc_compatible_formats = - radv_is_colorbuffer_format_supported(pCreateInfo->format, + radv_is_colorbuffer_format_supported(format, &blendable); if (pCreateInfo->flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT) { @@ -206,7 +209,7 @@ radv_use_dcc_for_image(struct radv_device *device, if (format_list->pViewFormats[i] == VK_FORMAT_UNDEFINED) continue; - if (!radv_dcc_formats_compatible(pCreateInfo->format, + if (!radv_dcc_formats_compatible(format, format_list->pViewFormats[i])) dcc_compatible_formats = false; } @@ -389,10 +392,11 @@ radv_init_surface(struct radv_device *device, const struct radv_image *image, struct radeon_surf *surface, unsigned plane_id, - const VkImageCreateInfo *pCreateInfo) + const VkImageCreateInfo *pCreateInfo, + VkFormat image_format) { - unsigned array_mode = radv_choose_tiling(device, pCreateInfo); - VkFormat format = vk_format_get_plane_format(pCreateInfo->format, plane_id); + 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); bool is_depth, is_stencil; @@ -432,7 +436,7 @@ radv_init_surface(struct radv_device *device, if (is_depth) { surface->flags |= RADEON_SURF_ZBUFFER; - if (radv_use_tc_compat_htile_for_image(device, pCreateInfo)) + if (radv_use_tc_compat_htile_for_image(device, pCreateInfo, image_format)) surface->flags |= RADEON_SURF_TC_COMPATIBLE_HTILE; } @@ -441,13 +445,13 @@ radv_init_surface(struct radv_device *device, if (device->physical_device->rad_info.chip_class >= GFX9 && pCreateInfo->imageType == VK_IMAGE_TYPE_3D && - vk_format_get_blocksizebits(pCreateInfo->format) == 128 && - vk_format_is_compressed(pCreateInfo->format)) + vk_format_get_blocksizebits(image_format) == 128 && + vk_format_is_compressed(image_format)) surface->flags |= RADEON_SURF_NO_RENDER_TARGET; surface->flags |= RADEON_SURF_OPTIMIZE_FOR_SPACE; - if (!radv_use_dcc_for_image(device, image, pCreateInfo)) + if (!radv_use_dcc_for_image(device, image, pCreateInfo, image_format)) surface->flags |= RADEON_SURF_DISABLE_DCC; return 0; @@ -524,7 +528,7 @@ radv_make_buffer_descriptor(struct radv_device *device, * else: swizzle_address >= NUM_RECORDS */ state[3] |= S_008F0C_FORMAT(fmt->img_format) | - S_008F0C_OOB_SELECT(0) | + S_008F0C_OOB_SELECT(V_008F0C_OOB_SELECT_STRUCTURED_WITH_OFFSET) | S_008F0C_RESOURCE_LEVEL(1); } else { num_format = radv_translate_buffer_numformat(desc, first_non_void); @@ -711,7 +715,7 @@ static unsigned gfx9_border_color_swizzle(const enum vk_swizzle swizzle[4]) return bc_swizzle; } -static bool vi_alpha_is_on_msb(struct radv_device *device, VkFormat format) +bool vi_alpha_is_on_msb(struct radv_device *device, VkFormat format) { const struct vk_format_description *desc = vk_format_description(format); @@ -785,7 +789,7 @@ gfx10_make_texture_descriptor(struct radv_device *device, */ state[4] = S_00A010_DEPTH(type == V_008F1C_SQ_RSRC_IMG_3D ? depth - 1 : last_layer) | S_00A010_BASE_ARRAY(first_layer); - state[5] = S_00A014_ARRAY_PITCH(!!(type == V_008F1C_SQ_RSRC_IMG_3D)) | + state[5] = S_00A014_ARRAY_PITCH(0) | S_00A014_MAX_MIP(image->info.samples > 1 ? util_logbase2(image->info.samples) : image->info.levels - 1) | @@ -1346,16 +1350,20 @@ static void radv_image_disable_htile(struct radv_image *image) image->planes[i].surface.htile_size = 0; } -static VkResult +VkResult radv_image_create_layout(struct radv_device *device, - const struct radv_image_create_info *create_info, + 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; + struct ac_surf_info image_info = image->info; - VkResult result = radv_patch_image_from_extra_info(device, image, create_info, &image_info); + VkResult result = radv_patch_image_from_extra_info(device, image, &create_info, &image_info); if (result != VK_SUCCESS) return result; @@ -1382,7 +1390,7 @@ radv_image_create_layout(struct radv_device *device, image->planes[plane].format = vk_format_get_plane_format(image->vk_format, plane); } - if (!create_info->no_metadata_planes) { + if (!create_info.no_metadata_planes) { /* Try to enable DCC first. */ if (radv_image_can_enable_dcc(device, image)) { radv_image_alloc_dcc(image); @@ -1435,9 +1443,11 @@ radv_image_create(VkDevice _device, RADV_FROM_HANDLE(radv_device, device, _device); const VkImageCreateInfo *pCreateInfo = create_info->vk_info; struct radv_image *image = NULL; + VkFormat format = radv_select_android_external_format(pCreateInfo->pNext, + pCreateInfo->format); assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO); - const unsigned plane_count = vk_format_get_plane_count(pCreateInfo->format); + const unsigned plane_count = vk_format_get_plane_count(format); const size_t image_struct_size = sizeof(*image) + sizeof(struct radv_image_plane) * plane_count; radv_assert(pCreateInfo->mipLevels > 0); @@ -1460,9 +1470,9 @@ radv_image_create(VkDevice _device, image->info.storage_samples = pCreateInfo->samples; image->info.array_size = pCreateInfo->arrayLayers; image->info.levels = pCreateInfo->mipLevels; - image->info.num_channels = vk_format_get_nr_components(pCreateInfo->format); + image->info.num_channels = vk_format_get_nr_components(format); - image->vk_format = pCreateInfo->format; + image->vk_format = format; image->tiling = pCreateInfo->tiling; image->usage = pCreateInfo->usage; image->flags = pCreateInfo->flags; @@ -1478,17 +1488,29 @@ radv_image_create(VkDevice _device, image->queue_family_mask |= 1u << pCreateInfo->pQueueFamilyIndices[i]; } - image->shareable = vk_find_struct_const(pCreateInfo->pNext, - EXTERNAL_MEMORY_IMAGE_CREATE_INFO) != NULL; - if (!vk_format_is_depth_or_stencil(pCreateInfo->format) && !image->shareable) { + const VkExternalMemoryImageCreateInfo *external_info = + vk_find_struct_const(pCreateInfo->pNext, + EXTERNAL_MEMORY_IMAGE_CREATE_INFO) ; + + image->shareable = external_info; + if (!vk_format_is_depth_or_stencil(format) && !image->shareable) { image->info.surf_index = &device->image_mrt_offset_counter; } for (unsigned plane = 0; plane < image->plane_count; ++plane) { - radv_init_surface(device, image, &image->planes[plane].surface, plane, pCreateInfo); + radv_init_surface(device, image, &image->planes[plane].surface, plane, pCreateInfo, format); + } + + bool delay_layout = external_info && + (external_info->handleTypes & VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID); + + if (delay_layout) { + *pImage = radv_image_to_handle(image); + assert (!(image->flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT)); + return VK_SUCCESS; } - ASSERTED VkResult result = radv_image_create_layout(device, create_info, image); + ASSERTED VkResult result = radv_image_create_layout(device, *create_info, image); assert(result == VK_SUCCESS); if (image->flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT) { @@ -1628,8 +1650,14 @@ radv_image_view_init(struct radv_image_view *iview, iview->plane_id = radv_plane_from_aspect(pCreateInfo->subresourceRange.aspectMask); iview->aspect_mask = pCreateInfo->subresourceRange.aspectMask; iview->multiple_planes = vk_format_get_plane_count(image->vk_format) > 1 && iview->aspect_mask == VK_IMAGE_ASPECT_COLOR_BIT; + iview->vk_format = pCreateInfo->format; + /* If the image has an Android external format, pCreateInfo->format will be + * VK_FORMAT_UNDEFINED. */ + if (iview->vk_format == VK_FORMAT_UNDEFINED) + iview->vk_format = image->vk_format; + if (iview->aspect_mask == VK_IMAGE_ASPECT_STENCIL_BIT) { iview->vk_format = vk_format_stencil_only(iview->vk_format); } else if (iview->aspect_mask == VK_IMAGE_ASPECT_DEPTH_BIT) { @@ -1729,6 +1757,8 @@ bool radv_layout_has_htile(const struct radv_image *image, return radv_image_has_htile(image) && (layout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL || + layout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR || + layout == VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL_KHR || (layout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL && queue_mask == (1u << RADV_QUEUE_GENERAL))); } @@ -1743,6 +1773,8 @@ bool radv_layout_is_htile_compressed(const struct radv_image *image, return radv_image_has_htile(image) && (layout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL || + layout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR || + layout == VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL_KHR || (layout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL && queue_mask == (1u << RADV_QUEUE_GENERAL))); }