xref: /aosp_15_r20/external/mesa3d/src/asahi/vulkan/hk_format.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /*
2  * Copyright 2024 Valve Corporation
3  * Copyright 2024 Alyssa Rosenzweig
4  * Copyright 2022-2023 Collabora Ltd. and Red Hat Inc.
5  * Copyright 2024 Valve Corporation
6  * Copyright 2024 Alyssa Rosenzweig
7  * Copyright 2022-2023 Collabora Ltd. and Red Hat Inc.
8  * SPDX-License-Identifier: MIT
9  */
10 #include "drm-uapi/drm_fourcc.h"
11 
12 #include "hk_buffer_view.h"
13 #include "hk_entrypoints.h"
14 #include "hk_image.h"
15 #include "hk_physical_device.h"
16 
17 #include "vk_enum_defines.h"
18 #include "vk_format.h"
19 
20 uint64_t agx_best_modifiers[] = {
21    // DRM_FORMAT_MOD_APPLE_TWIDDLED_COMPRESSED,
22    DRM_FORMAT_MOD_APPLE_TWIDDLED,
23    DRM_FORMAT_MOD_LINEAR,
24 };
25 
26 static VkFormatFeatureFlags2
hk_modifier_features(uint64_t mod,VkFormat vk_format,const VkFormatProperties * props)27 hk_modifier_features(uint64_t mod, VkFormat vk_format,
28                      const VkFormatProperties *props)
29 {
30    if (mod == DRM_FORMAT_MOD_LINEAR)
31       return props->linearTilingFeatures;
32 
33    if (mod == DRM_FORMAT_MOD_APPLE_TWIDDLED_COMPRESSED /* TODO */)
34       return 0;
35 
36    return props->optimalTilingFeatures;
37 }
38 
39 static void
get_drm_format_modifier_properties_list(const struct hk_physical_device * physical_device,VkFormat vk_format,VkDrmFormatModifierPropertiesListEXT * list,const VkFormatProperties * props)40 get_drm_format_modifier_properties_list(
41    const struct hk_physical_device *physical_device, VkFormat vk_format,
42    VkDrmFormatModifierPropertiesListEXT *list, const VkFormatProperties *props)
43 {
44    VK_OUTARRAY_MAKE_TYPED(VkDrmFormatModifierPropertiesEXT, out,
45                           list->pDrmFormatModifierProperties,
46                           &list->drmFormatModifierCount);
47 
48    for (unsigned i = 0; i < ARRAY_SIZE(agx_best_modifiers); ++i) {
49       uint64_t mod = agx_best_modifiers[i];
50       VkFormatFeatureFlags2 flags = hk_modifier_features(mod, vk_format, props);
51 
52       if (!flags)
53          continue;
54 
55       vk_outarray_append_typed(VkDrmFormatModifierPropertiesEXT, &out,
56                                out_props)
57       {
58          *out_props = (VkDrmFormatModifierPropertiesEXT){
59             .drmFormatModifier = mod,
60             .drmFormatModifierPlaneCount = 1 /* no planar mods */,
61             .drmFormatModifierTilingFeatures = flags,
62          };
63       };
64    }
65 }
66 
67 static void
get_drm_format_modifier_properties_list_2(const struct hk_physical_device * physical_device,VkFormat vk_format,VkDrmFormatModifierPropertiesList2EXT * list,const VkFormatProperties * props)68 get_drm_format_modifier_properties_list_2(
69    const struct hk_physical_device *physical_device, VkFormat vk_format,
70    VkDrmFormatModifierPropertiesList2EXT *list, const VkFormatProperties *props)
71 {
72    VK_OUTARRAY_MAKE_TYPED(VkDrmFormatModifierProperties2EXT, out,
73                           list->pDrmFormatModifierProperties,
74                           &list->drmFormatModifierCount);
75 
76    for (unsigned i = 0; i < ARRAY_SIZE(agx_best_modifiers); ++i) {
77       uint64_t mod = agx_best_modifiers[i];
78       VkFormatFeatureFlags2 flags = hk_modifier_features(mod, vk_format, props);
79 
80       if (!flags)
81          continue;
82 
83       vk_outarray_append_typed(VkDrmFormatModifierProperties2EXT, &out,
84                                out_props)
85       {
86          *out_props = (VkDrmFormatModifierProperties2EXT){
87             .drmFormatModifier = mod,
88             .drmFormatModifierPlaneCount = 1, /* no planar mods */
89             .drmFormatModifierTilingFeatures = flags,
90          };
91       };
92    }
93 }
94 
95 VKAPI_ATTR void VKAPI_CALL
hk_GetPhysicalDeviceFormatProperties2(VkPhysicalDevice physicalDevice,VkFormat format,VkFormatProperties2 * pFormatProperties)96 hk_GetPhysicalDeviceFormatProperties2(VkPhysicalDevice physicalDevice,
97                                       VkFormat format,
98                                       VkFormatProperties2 *pFormatProperties)
99 {
100    VK_FROM_HANDLE(hk_physical_device, pdevice, physicalDevice);
101 
102    VkFormatFeatureFlags2 linear2, optimal2, buffer2;
103    linear2 =
104       hk_get_image_format_features(pdevice, format, VK_IMAGE_TILING_LINEAR);
105    optimal2 =
106       hk_get_image_format_features(pdevice, format, VK_IMAGE_TILING_OPTIMAL);
107    buffer2 = hk_get_buffer_format_features(pdevice, format);
108 
109    pFormatProperties->formatProperties = (VkFormatProperties){
110       .linearTilingFeatures = vk_format_features2_to_features(linear2),
111       .optimalTilingFeatures = vk_format_features2_to_features(optimal2),
112       .bufferFeatures = vk_format_features2_to_features(buffer2),
113    };
114 
115    vk_foreach_struct(ext, pFormatProperties->pNext) {
116       switch (ext->sType) {
117       case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3: {
118          VkFormatProperties3 *p = (void *)ext;
119          p->linearTilingFeatures = linear2;
120          p->optimalTilingFeatures = optimal2;
121          p->bufferFeatures = buffer2;
122          break;
123       }
124 
125       case VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_EXT:
126          get_drm_format_modifier_properties_list(
127             pdevice, format, (void *)ext, &pFormatProperties->formatProperties);
128          break;
129 
130       case VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_2_EXT:
131          get_drm_format_modifier_properties_list_2(
132             pdevice, format, (void *)ext, &pFormatProperties->formatProperties);
133          break;
134 
135       default:
136          vk_debug_ignored_stype(ext->sType);
137          break;
138       }
139    }
140 }
141