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