xref: /aosp_15_r20/external/mesa3d/src/nouveau/vulkan/nvk_image.h (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker  * Copyright © 2022 Collabora Ltd. and Red Hat Inc.
3*61046927SAndroid Build Coastguard Worker  * SPDX-License-Identifier: MIT
4*61046927SAndroid Build Coastguard Worker  */
5*61046927SAndroid Build Coastguard Worker #ifndef NVK_IMAGE_H
6*61046927SAndroid Build Coastguard Worker #define NVK_IMAGE_H 1
7*61046927SAndroid Build Coastguard Worker 
8*61046927SAndroid Build Coastguard Worker #include "nvk_private.h"
9*61046927SAndroid Build Coastguard Worker #include "nvk_device_memory.h"
10*61046927SAndroid Build Coastguard Worker 
11*61046927SAndroid Build Coastguard Worker #include "vk_image.h"
12*61046927SAndroid Build Coastguard Worker 
13*61046927SAndroid Build Coastguard Worker #include "nil.h"
14*61046927SAndroid Build Coastguard Worker 
15*61046927SAndroid Build Coastguard Worker /* Because small images can end up with an array_stride_B that is less than
16*61046927SAndroid Build Coastguard Worker  * the sparse block size (in bytes), we have to set SINGLE_MIPTAIL_BIT when
17*61046927SAndroid Build Coastguard Worker  * advertising sparse properties to the client.  This means that we get one
18*61046927SAndroid Build Coastguard Worker  * single memory range for the miptail of the image.  For large images with
19*61046927SAndroid Build Coastguard Worker  * mipTailStartLod > 0, we have to deal with the array stride ourselves.
20*61046927SAndroid Build Coastguard Worker  *
21*61046927SAndroid Build Coastguard Worker  * We do this by returning NVK_MIP_TAIL_START_OFFSET as the image's
22*61046927SAndroid Build Coastguard Worker  * imageMipTailOffset.  We can then detect anything with that address as
23*61046927SAndroid Build Coastguard Worker  * being part of the miptail and re-map it accordingly.  The Vulkan spec
24*61046927SAndroid Build Coastguard Worker  * explicitly allows for this.
25*61046927SAndroid Build Coastguard Worker  *
26*61046927SAndroid Build Coastguard Worker  * From the Vulkan 1.3.279 spec:
27*61046927SAndroid Build Coastguard Worker  *
28*61046927SAndroid Build Coastguard Worker  *    "When VK_SPARSE_MEMORY_BIND_METADATA_BIT is present, the resourceOffset
29*61046927SAndroid Build Coastguard Worker  *    must have been derived explicitly from the imageMipTailOffset in the
30*61046927SAndroid Build Coastguard Worker  *    sparse resource properties returned for the metadata aspect. By
31*61046927SAndroid Build Coastguard Worker  *    manipulating the value returned for imageMipTailOffset, the
32*61046927SAndroid Build Coastguard Worker  *    resourceOffset does not have to correlate directly to a device virtual
33*61046927SAndroid Build Coastguard Worker  *    address offset, and may instead be whatever value makes it easiest for
34*61046927SAndroid Build Coastguard Worker  *    the implementation to derive the correct device virtual address."
35*61046927SAndroid Build Coastguard Worker  */
36*61046927SAndroid Build Coastguard Worker #define NVK_MIP_TAIL_START_OFFSET 0x6d74000000000000UL
37*61046927SAndroid Build Coastguard Worker 
38*61046927SAndroid Build Coastguard Worker struct nvk_device_memory;
39*61046927SAndroid Build Coastguard Worker struct nvk_physical_device;
40*61046927SAndroid Build Coastguard Worker struct nvk_queue;
41*61046927SAndroid Build Coastguard Worker struct nvkmd_mem;
42*61046927SAndroid Build Coastguard Worker struct nvkmd_va;
43*61046927SAndroid Build Coastguard Worker 
44*61046927SAndroid Build Coastguard Worker VkFormatFeatureFlags2
45*61046927SAndroid Build Coastguard Worker nvk_get_image_format_features(struct nvk_physical_device *pdevice,
46*61046927SAndroid Build Coastguard Worker                               VkFormat format, VkImageTiling tiling,
47*61046927SAndroid Build Coastguard Worker                               uint64_t drm_format_mod);
48*61046927SAndroid Build Coastguard Worker 
49*61046927SAndroid Build Coastguard Worker void
50*61046927SAndroid Build Coastguard Worker nvk_get_drm_format_modifier_properties_list(struct nvk_physical_device *pdev,
51*61046927SAndroid Build Coastguard Worker                                             VkFormat vk_format,
52*61046927SAndroid Build Coastguard Worker                                             VkBaseOutStructure *ext);
53*61046927SAndroid Build Coastguard Worker 
54*61046927SAndroid Build Coastguard Worker uint32_t
55*61046927SAndroid Build Coastguard Worker nvk_image_max_dimension(const struct nv_device_info *info,
56*61046927SAndroid Build Coastguard Worker                         VkImageType image_type);
57*61046927SAndroid Build Coastguard Worker 
58*61046927SAndroid Build Coastguard Worker struct nvk_image_plane {
59*61046927SAndroid Build Coastguard Worker    struct nil_image nil;
60*61046927SAndroid Build Coastguard Worker    uint64_t addr;
61*61046927SAndroid Build Coastguard Worker 
62*61046927SAndroid Build Coastguard Worker    /** Reserved VA for sparse images, NULL otherwise. */
63*61046927SAndroid Build Coastguard Worker    struct nvkmd_va *va;
64*61046927SAndroid Build Coastguard Worker };
65*61046927SAndroid Build Coastguard Worker 
66*61046927SAndroid Build Coastguard Worker struct nvk_image {
67*61046927SAndroid Build Coastguard Worker    struct vk_image vk;
68*61046927SAndroid Build Coastguard Worker 
69*61046927SAndroid Build Coastguard Worker    /** True if the planes are bound separately
70*61046927SAndroid Build Coastguard Worker     *
71*61046927SAndroid Build Coastguard Worker     * This is set based on VK_IMAGE_CREATE_DISJOINT_BIT
72*61046927SAndroid Build Coastguard Worker     */
73*61046927SAndroid Build Coastguard Worker    bool disjoint;
74*61046927SAndroid Build Coastguard Worker 
75*61046927SAndroid Build Coastguard Worker    uint8_t plane_count;
76*61046927SAndroid Build Coastguard Worker    struct nvk_image_plane planes[3];
77*61046927SAndroid Build Coastguard Worker 
78*61046927SAndroid Build Coastguard Worker    /* In order to support D32_SFLOAT_S8_UINT, a temp area is
79*61046927SAndroid Build Coastguard Worker     * needed. The stencil plane can't be a copied using the DMA
80*61046927SAndroid Build Coastguard Worker     * engine in a single pass since it would need 8 components support.
81*61046927SAndroid Build Coastguard Worker     * Instead we allocate a 16-bit temp, that gets copied into, then
82*61046927SAndroid Build Coastguard Worker     * copied again down to the 8-bit result.
83*61046927SAndroid Build Coastguard Worker     */
84*61046927SAndroid Build Coastguard Worker    struct nvk_image_plane stencil_copy_temp;
85*61046927SAndroid Build Coastguard Worker 
86*61046927SAndroid Build Coastguard Worker    /* The hardware doesn't support rendering to linear images except
87*61046927SAndroid Build Coastguard Worker     * under certain conditions, so to support DRM_FORMAT_MOD_LINEAR
88*61046927SAndroid Build Coastguard Worker     * rendering in the general case, we need to keep a tiled copy, which would
89*61046927SAndroid Build Coastguard Worker     * be used to fake support if the conditions aren't satisfied.
90*61046927SAndroid Build Coastguard Worker     */
91*61046927SAndroid Build Coastguard Worker    struct nvk_image_plane linear_tiled_shadow;
92*61046927SAndroid Build Coastguard Worker    struct nvkmd_mem *linear_tiled_shadow_mem;
93*61046927SAndroid Build Coastguard Worker };
94*61046927SAndroid Build Coastguard Worker 
95*61046927SAndroid Build Coastguard Worker VK_DEFINE_NONDISP_HANDLE_CASTS(nvk_image, vk.base, VkImage, VK_OBJECT_TYPE_IMAGE)
96*61046927SAndroid Build Coastguard Worker 
97*61046927SAndroid Build Coastguard Worker static inline uint64_t
nvk_image_plane_base_address(const struct nvk_image_plane * plane)98*61046927SAndroid Build Coastguard Worker nvk_image_plane_base_address(const struct nvk_image_plane *plane)
99*61046927SAndroid Build Coastguard Worker {
100*61046927SAndroid Build Coastguard Worker    return plane->addr;
101*61046927SAndroid Build Coastguard Worker }
102*61046927SAndroid Build Coastguard Worker 
103*61046927SAndroid Build Coastguard Worker static inline uint64_t
nvk_image_base_address(const struct nvk_image * image,uint8_t plane)104*61046927SAndroid Build Coastguard Worker nvk_image_base_address(const struct nvk_image *image, uint8_t plane)
105*61046927SAndroid Build Coastguard Worker {
106*61046927SAndroid Build Coastguard Worker    return nvk_image_plane_base_address(&image->planes[plane]);
107*61046927SAndroid Build Coastguard Worker }
108*61046927SAndroid Build Coastguard Worker 
109*61046927SAndroid Build Coastguard Worker static inline uint8_t
nvk_image_aspects_to_plane(ASSERTED const struct nvk_image * image,VkImageAspectFlags aspectMask)110*61046927SAndroid Build Coastguard Worker nvk_image_aspects_to_plane(ASSERTED const struct nvk_image *image,
111*61046927SAndroid Build Coastguard Worker                            VkImageAspectFlags aspectMask)
112*61046927SAndroid Build Coastguard Worker {
113*61046927SAndroid Build Coastguard Worker    /* Memory planes are only allowed for memory operations */
114*61046927SAndroid Build Coastguard Worker    assert(!(aspectMask & (VK_IMAGE_ASPECT_MEMORY_PLANE_0_BIT_EXT |
115*61046927SAndroid Build Coastguard Worker                           VK_IMAGE_ASPECT_MEMORY_PLANE_1_BIT_EXT |
116*61046927SAndroid Build Coastguard Worker                           VK_IMAGE_ASPECT_MEMORY_PLANE_2_BIT_EXT |
117*61046927SAndroid Build Coastguard Worker                           VK_IMAGE_ASPECT_MEMORY_PLANE_3_BIT_EXT)));
118*61046927SAndroid Build Coastguard Worker 
119*61046927SAndroid Build Coastguard Worker    /* Verify that the aspects are actually in the image */
120*61046927SAndroid Build Coastguard Worker    assert(!(aspectMask & ~image->vk.aspects));
121*61046927SAndroid Build Coastguard Worker 
122*61046927SAndroid Build Coastguard Worker    /* Must only be one aspect unless it's depth/stencil */
123*61046927SAndroid Build Coastguard Worker    assert(aspectMask == (VK_IMAGE_ASPECT_DEPTH_BIT |
124*61046927SAndroid Build Coastguard Worker                          VK_IMAGE_ASPECT_STENCIL_BIT) ||
125*61046927SAndroid Build Coastguard Worker           util_bitcount(aspectMask) == 1);
126*61046927SAndroid Build Coastguard Worker 
127*61046927SAndroid Build Coastguard Worker    switch(aspectMask) {
128*61046927SAndroid Build Coastguard Worker    case VK_IMAGE_ASPECT_PLANE_1_BIT: return 1;
129*61046927SAndroid Build Coastguard Worker    case VK_IMAGE_ASPECT_PLANE_2_BIT: return 2;
130*61046927SAndroid Build Coastguard Worker    default: return 0;
131*61046927SAndroid Build Coastguard Worker    }
132*61046927SAndroid Build Coastguard Worker }
133*61046927SAndroid Build Coastguard Worker 
134*61046927SAndroid Build Coastguard Worker static inline uint8_t
nvk_image_memory_aspects_to_plane(ASSERTED const struct nvk_image * image,VkImageAspectFlags aspectMask)135*61046927SAndroid Build Coastguard Worker nvk_image_memory_aspects_to_plane(ASSERTED const struct nvk_image *image,
136*61046927SAndroid Build Coastguard Worker                                   VkImageAspectFlags aspectMask)
137*61046927SAndroid Build Coastguard Worker {
138*61046927SAndroid Build Coastguard Worker    if (aspectMask & (VK_IMAGE_ASPECT_MEMORY_PLANE_0_BIT_EXT |
139*61046927SAndroid Build Coastguard Worker                      VK_IMAGE_ASPECT_MEMORY_PLANE_1_BIT_EXT |
140*61046927SAndroid Build Coastguard Worker                      VK_IMAGE_ASPECT_MEMORY_PLANE_2_BIT_EXT |
141*61046927SAndroid Build Coastguard Worker                      VK_IMAGE_ASPECT_MEMORY_PLANE_3_BIT_EXT)) {
142*61046927SAndroid Build Coastguard Worker       /* We don't support DRM format modifiers on anything but single-plane
143*61046927SAndroid Build Coastguard Worker        * color at the moment.
144*61046927SAndroid Build Coastguard Worker        */
145*61046927SAndroid Build Coastguard Worker       assert(aspectMask == VK_IMAGE_ASPECT_MEMORY_PLANE_0_BIT_EXT);
146*61046927SAndroid Build Coastguard Worker       return 0;
147*61046927SAndroid Build Coastguard Worker    } else {
148*61046927SAndroid Build Coastguard Worker       return nvk_image_aspects_to_plane(image, aspectMask);
149*61046927SAndroid Build Coastguard Worker    }
150*61046927SAndroid Build Coastguard Worker }
151*61046927SAndroid Build Coastguard Worker 
152*61046927SAndroid Build Coastguard Worker VkResult nvk_queue_image_bind(struct nvk_queue *queue,
153*61046927SAndroid Build Coastguard Worker                               const VkSparseImageMemoryBindInfo *bind_info);
154*61046927SAndroid Build Coastguard Worker 
155*61046927SAndroid Build Coastguard Worker VkResult nvk_queue_image_opaque_bind(struct nvk_queue *queue,
156*61046927SAndroid Build Coastguard Worker                                      const VkSparseImageOpaqueMemoryBindInfo *bind_info);
157*61046927SAndroid Build Coastguard Worker 
158*61046927SAndroid Build Coastguard Worker #endif
159