turnip: add .clang-format
[mesa.git] / src / freedreno / vulkan / tu_formats.c
1
2 /*
3 * Copyright © 2016 Red Hat.
4 * Copyright © 2016 Bas Nieuwenhuizen
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice (including the next
14 * paragraph) shall be included in all copies or substantial portions of the
15 * Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23 * DEALINGS IN THE SOFTWARE.
24 */
25
26 #include "tu_private.h"
27
28 #include "util/format_r11g11b10f.h"
29 #include "util/format_srgb.h"
30 #include "util/u_half.h"
31 #include "vk_format.h"
32 #include "vk_util.h"
33
34 static void
35 tu_physical_device_get_format_properties(
36 struct tu_physical_device *physical_device,
37 VkFormat format,
38 VkFormatProperties *out_properties)
39 {
40 VkFormatFeatureFlags linear = 0, tiled = 0, buffer = 0;
41 const struct vk_format_description *desc = vk_format_description(format);
42 if (!desc) {
43 out_properties->linearTilingFeatures = linear;
44 out_properties->optimalTilingFeatures = tiled;
45 out_properties->bufferFeatures = buffer;
46 return;
47 }
48
49 out_properties->linearTilingFeatures = linear;
50 out_properties->optimalTilingFeatures = tiled;
51 out_properties->bufferFeatures = buffer;
52 }
53
54 void
55 tu_GetPhysicalDeviceFormatProperties(VkPhysicalDevice physicalDevice,
56 VkFormat format,
57 VkFormatProperties *pFormatProperties)
58 {
59 TU_FROM_HANDLE(tu_physical_device, physical_device, physicalDevice);
60
61 tu_physical_device_get_format_properties(physical_device, format,
62 pFormatProperties);
63 }
64
65 void
66 tu_GetPhysicalDeviceFormatProperties2(
67 VkPhysicalDevice physicalDevice,
68 VkFormat format,
69 VkFormatProperties2KHR *pFormatProperties)
70 {
71 TU_FROM_HANDLE(tu_physical_device, physical_device, physicalDevice);
72
73 tu_physical_device_get_format_properties(
74 physical_device, format, &pFormatProperties->formatProperties);
75 }
76
77 static VkResult
78 tu_get_image_format_properties(
79 struct tu_physical_device *physical_device,
80 const VkPhysicalDeviceImageFormatInfo2KHR *info,
81 VkImageFormatProperties *pImageFormatProperties)
82
83 {
84 VkFormatProperties format_props;
85 VkFormatFeatureFlags format_feature_flags;
86 VkExtent3D maxExtent;
87 uint32_t maxMipLevels;
88 uint32_t maxArraySize;
89 VkSampleCountFlags sampleCounts = VK_SAMPLE_COUNT_1_BIT;
90
91 tu_physical_device_get_format_properties(physical_device, info->format,
92 &format_props);
93 if (info->tiling == VK_IMAGE_TILING_LINEAR) {
94 format_feature_flags = format_props.linearTilingFeatures;
95 } else if (info->tiling == VK_IMAGE_TILING_OPTIMAL) {
96 format_feature_flags = format_props.optimalTilingFeatures;
97 } else {
98 unreachable("bad VkImageTiling");
99 }
100
101 if (format_feature_flags == 0)
102 goto unsupported;
103
104 if (info->type != VK_IMAGE_TYPE_2D &&
105 vk_format_is_depth_or_stencil(info->format))
106 goto unsupported;
107
108 switch (info->type) {
109 default:
110 unreachable("bad vkimage type\n");
111 case VK_IMAGE_TYPE_1D:
112 maxExtent.width = 16384;
113 maxExtent.height = 1;
114 maxExtent.depth = 1;
115 maxMipLevels = 15; /* log2(maxWidth) + 1 */
116 maxArraySize = 2048;
117 break;
118 case VK_IMAGE_TYPE_2D:
119 maxExtent.width = 16384;
120 maxExtent.height = 16384;
121 maxExtent.depth = 1;
122 maxMipLevels = 15; /* log2(maxWidth) + 1 */
123 maxArraySize = 2048;
124 break;
125 case VK_IMAGE_TYPE_3D:
126 maxExtent.width = 2048;
127 maxExtent.height = 2048;
128 maxExtent.depth = 2048;
129 maxMipLevels = 12; /* log2(maxWidth) + 1 */
130 maxArraySize = 1;
131 break;
132 }
133
134 if (info->tiling == VK_IMAGE_TILING_OPTIMAL &&
135 info->type == VK_IMAGE_TYPE_2D &&
136 (format_feature_flags &
137 (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT |
138 VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)) &&
139 !(info->flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) &&
140 !(info->usage & VK_IMAGE_USAGE_STORAGE_BIT)) {
141 sampleCounts |= VK_SAMPLE_COUNT_2_BIT | VK_SAMPLE_COUNT_4_BIT |
142 VK_SAMPLE_COUNT_8_BIT;
143 }
144
145 if (info->usage & VK_IMAGE_USAGE_SAMPLED_BIT) {
146 if (!(format_feature_flags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)) {
147 goto unsupported;
148 }
149 }
150
151 if (info->usage & VK_IMAGE_USAGE_STORAGE_BIT) {
152 if (!(format_feature_flags & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT)) {
153 goto unsupported;
154 }
155 }
156
157 if (info->usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) {
158 if (!(format_feature_flags & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT)) {
159 goto unsupported;
160 }
161 }
162
163 if (info->usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
164 if (!(format_feature_flags &
165 VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)) {
166 goto unsupported;
167 }
168 }
169
170 *pImageFormatProperties = (VkImageFormatProperties) {
171 .maxExtent = maxExtent,
172 .maxMipLevels = maxMipLevels,
173 .maxArrayLayers = maxArraySize,
174 .sampleCounts = sampleCounts,
175
176 /* FINISHME: Accurately calculate
177 * VkImageFormatProperties::maxResourceSize.
178 */
179 .maxResourceSize = UINT32_MAX,
180 };
181
182 return VK_SUCCESS;
183 unsupported:
184 *pImageFormatProperties = (VkImageFormatProperties) {
185 .maxExtent = { 0, 0, 0 },
186 .maxMipLevels = 0,
187 .maxArrayLayers = 0,
188 .sampleCounts = 0,
189 .maxResourceSize = 0,
190 };
191
192 return VK_ERROR_FORMAT_NOT_SUPPORTED;
193 }
194
195 VkResult
196 tu_GetPhysicalDeviceImageFormatProperties(
197 VkPhysicalDevice physicalDevice,
198 VkFormat format,
199 VkImageType type,
200 VkImageTiling tiling,
201 VkImageUsageFlags usage,
202 VkImageCreateFlags createFlags,
203 VkImageFormatProperties *pImageFormatProperties)
204 {
205 TU_FROM_HANDLE(tu_physical_device, physical_device, physicalDevice);
206
207 const VkPhysicalDeviceImageFormatInfo2KHR info = {
208 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2_KHR,
209 .pNext = NULL,
210 .format = format,
211 .type = type,
212 .tiling = tiling,
213 .usage = usage,
214 .flags = createFlags,
215 };
216
217 return tu_get_image_format_properties(physical_device, &info,
218 pImageFormatProperties);
219 }
220
221 static void
222 get_external_image_format_properties(
223 const VkPhysicalDeviceImageFormatInfo2KHR *pImageFormatInfo,
224 VkExternalMemoryHandleTypeFlagBitsKHR handleType,
225 VkExternalMemoryPropertiesKHR *external_properties)
226 {
227 VkExternalMemoryFeatureFlagBitsKHR flags = 0;
228 VkExternalMemoryHandleTypeFlagsKHR export_flags = 0;
229 VkExternalMemoryHandleTypeFlagsKHR compat_flags = 0;
230 switch (handleType) {
231 case VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR:
232 case VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT:
233 switch (pImageFormatInfo->type) {
234 case VK_IMAGE_TYPE_2D:
235 flags = VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT_KHR |
236 VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT_KHR |
237 VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT_KHR;
238 compat_flags = export_flags =
239 VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR |
240 VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;
241 break;
242 default:
243 break;
244 }
245 break;
246 case VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT:
247 flags = VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT_KHR;
248 compat_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT;
249 break;
250 default:
251 break;
252 }
253
254 *external_properties = (VkExternalMemoryPropertiesKHR) {
255 .externalMemoryFeatures = flags,
256 .exportFromImportedHandleTypes = export_flags,
257 .compatibleHandleTypes = compat_flags,
258 };
259 }
260
261 VkResult
262 tu_GetPhysicalDeviceImageFormatProperties2(
263 VkPhysicalDevice physicalDevice,
264 const VkPhysicalDeviceImageFormatInfo2KHR *base_info,
265 VkImageFormatProperties2KHR *base_props)
266 {
267 TU_FROM_HANDLE(tu_physical_device, physical_device, physicalDevice);
268 const VkPhysicalDeviceExternalImageFormatInfoKHR *external_info = NULL;
269 VkExternalImageFormatPropertiesKHR *external_props = NULL;
270 VkResult result;
271
272 result = tu_get_image_format_properties(
273 physical_device, base_info, &base_props->imageFormatProperties);
274 if (result != VK_SUCCESS)
275 return result;
276
277 /* Extract input structs */
278 vk_foreach_struct_const(s, base_info->pNext)
279 {
280 switch (s->sType) {
281 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO_KHR:
282 external_info = (const void *) s;
283 break;
284 default:
285 break;
286 }
287 }
288
289 /* Extract output structs */
290 vk_foreach_struct(s, base_props->pNext)
291 {
292 switch (s->sType) {
293 case VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES_KHR:
294 external_props = (void *) s;
295 break;
296 default:
297 break;
298 }
299 }
300
301 /* From the Vulkan 1.0.42 spec:
302 *
303 * If handleType is 0, vkGetPhysicalDeviceImageFormatProperties2KHR will
304 * behave as if VkPhysicalDeviceExternalImageFormatInfoKHR was not
305 * present and VkExternalImageFormatPropertiesKHR will be ignored.
306 */
307 if (external_info && external_info->handleType != 0) {
308 switch (external_info->handleType) {
309 case VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR:
310 case VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT:
311 case VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT:
312 get_external_image_format_properties(
313 base_info, external_info->handleType,
314 &external_props->externalMemoryProperties);
315 break;
316 default:
317 /* From the Vulkan 1.0.42 spec:
318 *
319 * If handleType is not compatible with the [parameters]
320 * specified
321 * in VkPhysicalDeviceImageFormatInfo2KHR, then
322 * vkGetPhysicalDeviceImageFormatProperties2KHR returns
323 * VK_ERROR_FORMAT_NOT_SUPPORTED.
324 */
325 result = vk_errorf(
326 physical_device->instance, VK_ERROR_FORMAT_NOT_SUPPORTED,
327 "unsupported VkExternalMemoryTypeFlagBitsKHR 0x%x",
328 external_info->handleType);
329 goto fail;
330 }
331 }
332
333 return VK_SUCCESS;
334
335 fail:
336 if (result == VK_ERROR_FORMAT_NOT_SUPPORTED) {
337 /* From the Vulkan 1.0.42 spec:
338 *
339 * If the combination of parameters to
340 * vkGetPhysicalDeviceImageFormatProperties2KHR is not supported by
341 * the implementation for use in vkCreateImage, then all members of
342 * imageFormatProperties will be filled with zero.
343 */
344 base_props->imageFormatProperties = (VkImageFormatProperties) { 0 };
345 }
346
347 return result;
348 }
349
350 void
351 tu_GetPhysicalDeviceSparseImageFormatProperties(
352 VkPhysicalDevice physicalDevice,
353 VkFormat format,
354 VkImageType type,
355 uint32_t samples,
356 VkImageUsageFlags usage,
357 VkImageTiling tiling,
358 uint32_t *pNumProperties,
359 VkSparseImageFormatProperties *pProperties)
360 {
361 /* Sparse images are not yet supported. */
362 *pNumProperties = 0;
363 }
364
365 void
366 tu_GetPhysicalDeviceSparseImageFormatProperties2(
367 VkPhysicalDevice physicalDevice,
368 const VkPhysicalDeviceSparseImageFormatInfo2KHR *pFormatInfo,
369 uint32_t *pPropertyCount,
370 VkSparseImageFormatProperties2KHR *pProperties)
371 {
372 /* Sparse images are not yet supported. */
373 *pPropertyCount = 0;
374 }
375
376 void
377 tu_GetPhysicalDeviceExternalBufferProperties(
378 VkPhysicalDevice physicalDevice,
379 const VkPhysicalDeviceExternalBufferInfoKHR *pExternalBufferInfo,
380 VkExternalBufferPropertiesKHR *pExternalBufferProperties)
381 {
382 VkExternalMemoryFeatureFlagBitsKHR flags = 0;
383 VkExternalMemoryHandleTypeFlagsKHR export_flags = 0;
384 VkExternalMemoryHandleTypeFlagsKHR compat_flags = 0;
385 switch (pExternalBufferInfo->handleType) {
386 case VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR:
387 case VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT:
388 flags = VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT_KHR |
389 VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT_KHR;
390 compat_flags = export_flags =
391 VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR |
392 VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;
393 break;
394 case VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT:
395 flags = VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT_KHR;
396 compat_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT;
397 break;
398 default:
399 break;
400 }
401 pExternalBufferProperties->externalMemoryProperties =
402 (VkExternalMemoryPropertiesKHR) {
403 .externalMemoryFeatures = flags,
404 .exportFromImportedHandleTypes = export_flags,
405 .compatibleHandleTypes = compat_flags,
406 };
407 }