• 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  * 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 #include "vulkan/vulkan_core.h"
12 
13 #include "hk_buffer_view.h"
14 #include "hk_entrypoints.h"
15 #include "hk_image.h"
16 #include "hk_physical_device.h"
17 
18 #include "vk_enum_defines.h"
19 #include "vk_format.h"
20 
21 uint64_t agx_best_modifiers[] = {
22    DRM_FORMAT_MOD_APPLE_TWIDDLED_COMPRESSED,
23    DRM_FORMAT_MOD_APPLE_TWIDDLED,
24    DRM_FORMAT_MOD_LINEAR,
25 };
26 
27 static VkFormatFeatureFlags2
hk_modifier_features(const struct agx_device * dev,uint64_t mod,VkFormat vk_format,const VkFormatProperties * props)28 hk_modifier_features(const struct agx_device *dev, uint64_t mod,
29                      VkFormat vk_format, const VkFormatProperties *props)
30 {
31    /* There's no corresponding fourcc, so don't advertise modifiers */
32    if (vk_format == VK_FORMAT_B10G11R11_UFLOAT_PACK32 ||
33        vk_format == VK_FORMAT_E5B9G9R9_UFLOAT_PACK32) {
34       return 0;
35    }
36 
37    /* Don't advertise compression for the uncompressable */
38    if (mod == DRM_FORMAT_MOD_APPLE_TWIDDLED_COMPRESSED &&
39        !hk_can_compress_format(dev, vk_format))
40       return 0;
41 
42    if (mod == DRM_FORMAT_MOD_LINEAR)
43       return props->linearTilingFeatures;
44    else
45       return props->optimalTilingFeatures;
46 }
47 
48 static void
get_drm_format_modifier_properties_list(const struct hk_physical_device * physical_device,VkFormat vk_format,VkDrmFormatModifierPropertiesListEXT * list,const VkFormatProperties * props)49 get_drm_format_modifier_properties_list(
50    const struct hk_physical_device *physical_device, VkFormat vk_format,
51    VkDrmFormatModifierPropertiesListEXT *list, const VkFormatProperties *props)
52 {
53    VK_OUTARRAY_MAKE_TYPED(VkDrmFormatModifierPropertiesEXT, out,
54                           list->pDrmFormatModifierProperties,
55                           &list->drmFormatModifierCount);
56 
57    for (unsigned i = 0; i < ARRAY_SIZE(agx_best_modifiers); ++i) {
58       uint64_t mod = agx_best_modifiers[i];
59       VkFormatFeatureFlags2 flags =
60          hk_modifier_features(&physical_device->dev, mod, vk_format, props);
61 
62       if (!flags)
63          continue;
64 
65       vk_outarray_append_typed(VkDrmFormatModifierPropertiesEXT, &out,
66                                out_props)
67       {
68          *out_props = (VkDrmFormatModifierPropertiesEXT){
69             .drmFormatModifier = mod,
70             .drmFormatModifierPlaneCount = 1 /* no planar mods */,
71             .drmFormatModifierTilingFeatures = flags,
72          };
73       };
74    }
75 }
76 
77 static void
get_drm_format_modifier_properties_list_2(const struct hk_physical_device * physical_device,VkFormat vk_format,VkDrmFormatModifierPropertiesList2EXT * list,const VkFormatProperties * props)78 get_drm_format_modifier_properties_list_2(
79    const struct hk_physical_device *physical_device, VkFormat vk_format,
80    VkDrmFormatModifierPropertiesList2EXT *list, const VkFormatProperties *props)
81 {
82    VK_OUTARRAY_MAKE_TYPED(VkDrmFormatModifierProperties2EXT, out,
83                           list->pDrmFormatModifierProperties,
84                           &list->drmFormatModifierCount);
85 
86    for (unsigned i = 0; i < ARRAY_SIZE(agx_best_modifiers); ++i) {
87       uint64_t mod = agx_best_modifiers[i];
88       VkFormatFeatureFlags2 flags =
89          hk_modifier_features(&physical_device->dev, mod, vk_format, props);
90 
91       if (!flags)
92          continue;
93 
94       vk_outarray_append_typed(VkDrmFormatModifierProperties2EXT, &out,
95                                out_props)
96       {
97          *out_props = (VkDrmFormatModifierProperties2EXT){
98             .drmFormatModifier = mod,
99             .drmFormatModifierPlaneCount = 1, /* no planar mods */
100             .drmFormatModifierTilingFeatures = flags,
101          };
102       };
103    }
104 }
105 
106 VKAPI_ATTR void VKAPI_CALL
hk_GetPhysicalDeviceFormatProperties2(VkPhysicalDevice physicalDevice,VkFormat format,VkFormatProperties2 * pFormatProperties)107 hk_GetPhysicalDeviceFormatProperties2(VkPhysicalDevice physicalDevice,
108                                       VkFormat format,
109                                       VkFormatProperties2 *pFormatProperties)
110 {
111    VK_FROM_HANDLE(hk_physical_device, pdevice, physicalDevice);
112 
113    VkFormatFeatureFlags2 linear2, optimal2, buffer2;
114    linear2 =
115       hk_get_image_format_features(pdevice, format, VK_IMAGE_TILING_LINEAR);
116    optimal2 =
117       hk_get_image_format_features(pdevice, format, VK_IMAGE_TILING_OPTIMAL);
118    buffer2 = hk_get_buffer_format_features(pdevice, format);
119 
120    pFormatProperties->formatProperties = (VkFormatProperties){
121       .linearTilingFeatures = vk_format_features2_to_features(linear2),
122       .optimalTilingFeatures = vk_format_features2_to_features(optimal2),
123       .bufferFeatures = vk_format_features2_to_features(buffer2),
124    };
125 
126    vk_foreach_struct(ext, pFormatProperties->pNext) {
127       switch (ext->sType) {
128       case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3: {
129          VkFormatProperties3 *p = (void *)ext;
130          p->linearTilingFeatures = linear2;
131          p->optimalTilingFeatures = optimal2;
132          p->bufferFeatures = buffer2;
133          break;
134       }
135 
136       case VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_EXT:
137          get_drm_format_modifier_properties_list(
138             pdevice, format, (void *)ext, &pFormatProperties->formatProperties);
139          break;
140 
141       case VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_2_EXT:
142          get_drm_format_modifier_properties_list_2(
143             pdevice, format, (void *)ext, &pFormatProperties->formatProperties);
144          break;
145 
146       default:
147          vk_debug_ignored_stype(ext->sType);
148          break;
149       }
150    }
151 }
152