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