• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_format.h"
16 #include "vk_image.h"
17 
18 /* Because small images can end up with an array_stride_B that is less than
19  * the sparse block size (in bytes), we have to set SINGLE_MIPTAIL_BIT when
20  * advertising sparse properties to the client.  This means that we get one
21  * single memory range for the miptail of the image.  For large images with
22  * mipTailStartLod > 0, we have to deal with the array stride ourselves.
23  *
24  * We do this by returning HK_MIP_TAIL_START_OFFSET as the image's
25  * imageMipTailOffset.  We can then detect anything with that address as
26  * being part of the miptail and re-map it accordingly.  The Vulkan spec
27  * explicitly allows for this.
28  *
29  * From the Vulkan 1.3.279 spec:
30  *
31  *    "When VK_SPARSE_MEMORY_BIND_METADATA_BIT is present, the resourceOffset
32  *    must have been derived explicitly from the imageMipTailOffset in the
33  *    sparse resource properties returned for the metadata aspect. By
34  *    manipulating the value returned for imageMipTailOffset, the
35  *    resourceOffset does not have to correlate directly to a device virtual
36  *    address offset, and may instead be whatever value makes it easiest for
37  *    the implementation to derive the correct device virtual address."
38  */
39 #define HK_MIP_TAIL_START_OFFSET 0x6d74000000000000UL
40 
41 struct hk_device_memory;
42 struct hk_physical_device;
43 
44 static VkFormatFeatureFlags2
45 hk_get_image_plane_format_features(struct hk_physical_device *pdev,
46                                    VkFormat vk_format, VkImageTiling tiling);
47 
48 VkFormatFeatureFlags2
49 hk_get_image_format_features(struct hk_physical_device *pdevice,
50                              VkFormat format, VkImageTiling tiling);
51 
52 struct hk_image_plane {
53    struct ail_layout layout;
54    uint64_t addr;
55 
56    /** Size of the reserved VMA range for sparse images, zero otherwise. */
57    uint64_t vma_size_B;
58 
59    /* For host image copy */
60    void *map;
61    uint32_t rem;
62 };
63 
64 struct hk_image {
65    struct vk_image vk;
66 
67    /** True if the planes are bound separately
68     *
69     * This is set based on VK_IMAGE_CREATE_DISJOINT_BIT
70     */
71    bool disjoint;
72 
73    uint8_t plane_count;
74    struct hk_image_plane planes[3];
75 };
76 
77 VK_DEFINE_NONDISP_HANDLE_CASTS(hk_image, vk.base, VkImage, VK_OBJECT_TYPE_IMAGE)
78 
79 static inline uint64_t
hk_image_plane_base_address(const struct hk_image_plane * plane)80 hk_image_plane_base_address(const struct hk_image_plane *plane)
81 {
82    return plane->addr;
83 }
84 
85 static inline uint64_t
hk_image_base_address(const struct hk_image * image,uint8_t plane)86 hk_image_base_address(const struct hk_image *image, uint8_t plane)
87 {
88    return hk_image_plane_base_address(&image->planes[plane]);
89 }
90 
91 static inline enum pipe_format
hk_format_to_pipe_format(VkFormat vkformat)92 hk_format_to_pipe_format(VkFormat vkformat)
93 {
94    switch (vkformat) {
95    case VK_FORMAT_R10X6_UNORM_PACK16:
96    case VK_FORMAT_R12X4_UNORM_PACK16:
97       return PIPE_FORMAT_R16_UNORM;
98    case VK_FORMAT_R10X6G10X6_UNORM_2PACK16:
99    case VK_FORMAT_R12X4G12X4_UNORM_2PACK16:
100       return PIPE_FORMAT_R16G16_UNORM;
101    default:
102       return vk_format_to_pipe_format(vkformat);
103    }
104 }
105 
106 static inline uint8_t
hk_image_aspects_to_plane(const struct hk_image * image,VkImageAspectFlags aspectMask)107 hk_image_aspects_to_plane(const struct hk_image *image,
108                           VkImageAspectFlags aspectMask)
109 {
110    /* Must only be one aspect unless it's depth/stencil */
111    assert(aspectMask ==
112              (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT) ||
113           util_bitcount(aspectMask) == 1);
114 
115    switch (aspectMask) {
116    default:
117       assert(aspectMask != VK_IMAGE_ASPECT_MEMORY_PLANE_3_BIT_EXT);
118       return 0;
119 
120    case VK_IMAGE_ASPECT_STENCIL_BIT:
121       return image->vk.format == VK_FORMAT_D32_SFLOAT_S8_UINT;
122 
123    case VK_IMAGE_ASPECT_PLANE_1_BIT:
124    case VK_IMAGE_ASPECT_MEMORY_PLANE_1_BIT_EXT:
125       return 1;
126 
127    case VK_IMAGE_ASPECT_PLANE_2_BIT:
128    case VK_IMAGE_ASPECT_MEMORY_PLANE_2_BIT_EXT:
129       return 2;
130    }
131 }
132 
133 struct agx_device;
134 bool hk_can_compress_format(const struct agx_device *dev, VkFormat format);
135