ac: declare an enum for the OOB select field on GFX10
[mesa.git] / src / amd / vulkan / radv_image.c
index baf49c6b65adda8a5aceb64024be1c88d4d357b5..deb34af3733b746c163a344b1994f0cdd5d2a3c1 100644 (file)
 
 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)));
 }