xref: /aosp_15_r20/external/mesa3d/src/asahi/vulkan/hk_image.h (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /*
2  * Copyright 2024 Valve Corporation
3  * Copyright 2024 Alyssa Rosenzweig
4  * Copyright 2022-2023 Collabora Ltd. and Red Hat Inc.
5  * SPDX-License-Identifier: MIT
6  */
7 
8 #pragma once
9 
10 #include "asahi/layout/layout.h"
11 #include "vulkan/vulkan_core.h"
12 
13 #include "hk_private.h"
14 
15 #include "vk_image.h"
16 
17 /* Because small images can end up with an array_stride_B that is less than
18  * the sparse block size (in bytes), we have to set SINGLE_MIPTAIL_BIT when
19  * advertising sparse properties to the client.  This means that we get one
20  * single memory range for the miptail of the image.  For large images with
21  * mipTailStartLod > 0, we have to deal with the array stride ourselves.
22  *
23  * We do this by returning HK_MIP_TAIL_START_OFFSET as the image's
24  * imageMipTailOffset.  We can then detect anything with that address as
25  * being part of the miptail and re-map it accordingly.  The Vulkan spec
26  * explicitly allows for this.
27  *
28  * From the Vulkan 1.3.279 spec:
29  *
30  *    "When VK_SPARSE_MEMORY_BIND_METADATA_BIT is present, the resourceOffset
31  *    must have been derived explicitly from the imageMipTailOffset in the
32  *    sparse resource properties returned for the metadata aspect. By
33  *    manipulating the value returned for imageMipTailOffset, the
34  *    resourceOffset does not have to correlate directly to a device virtual
35  *    address offset, and may instead be whatever value makes it easiest for
36  *    the implementation to derive the correct device virtual address."
37  */
38 #define HK_MIP_TAIL_START_OFFSET 0x6d74000000000000UL
39 
40 struct hk_device_memory;
41 struct hk_physical_device;
42 
43 static VkFormatFeatureFlags2
44 hk_get_image_plane_format_features(struct hk_physical_device *pdev,
45                                    VkFormat vk_format, VkImageTiling tiling);
46 
47 VkFormatFeatureFlags2
48 hk_get_image_format_features(struct hk_physical_device *pdevice,
49                              VkFormat format, VkImageTiling tiling);
50 
51 struct hk_image_plane {
52    struct ail_layout layout;
53    uint64_t addr;
54 
55    /** Size of the reserved VMA range for sparse images, zero otherwise. */
56    uint64_t vma_size_B;
57 
58    /* For host image copy */
59    void *map;
60    uint32_t rem;
61 };
62 
63 struct hk_image {
64    struct vk_image vk;
65 
66    /** True if the planes are bound separately
67     *
68     * This is set based on VK_IMAGE_CREATE_DISJOINT_BIT
69     */
70    bool disjoint;
71 
72    uint8_t plane_count;
73    struct hk_image_plane planes[3];
74 };
75 
76 VK_DEFINE_NONDISP_HANDLE_CASTS(hk_image, vk.base, VkImage, VK_OBJECT_TYPE_IMAGE)
77 
78 static inline uint64_t
hk_image_plane_base_address(const struct hk_image_plane * plane)79 hk_image_plane_base_address(const struct hk_image_plane *plane)
80 {
81    return plane->addr;
82 }
83 
84 static inline uint64_t
hk_image_base_address(const struct hk_image * image,uint8_t plane)85 hk_image_base_address(const struct hk_image *image, uint8_t plane)
86 {
87    return hk_image_plane_base_address(&image->planes[plane]);
88 }
89 
90 static inline uint8_t
hk_image_aspects_to_plane(const struct hk_image * image,VkImageAspectFlags aspectMask)91 hk_image_aspects_to_plane(const struct hk_image *image,
92                           VkImageAspectFlags aspectMask)
93 {
94    /* Must only be one aspect unless it's depth/stencil */
95    assert(aspectMask ==
96              (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT) ||
97           util_bitcount(aspectMask) == 1);
98 
99    switch (aspectMask) {
100    default:
101       assert(aspectMask != VK_IMAGE_ASPECT_MEMORY_PLANE_3_BIT_EXT);
102       return 0;
103 
104    case VK_IMAGE_ASPECT_STENCIL_BIT:
105       return image->vk.format == VK_FORMAT_D32_SFLOAT_S8_UINT;
106 
107    case VK_IMAGE_ASPECT_PLANE_1_BIT:
108    case VK_IMAGE_ASPECT_MEMORY_PLANE_1_BIT_EXT:
109       return 1;
110 
111    case VK_IMAGE_ASPECT_PLANE_2_BIT:
112    case VK_IMAGE_ASPECT_MEMORY_PLANE_2_BIT_EXT:
113       return 2;
114    }
115 }
116