3 * Copyright © 2016 Red Hat.
4 * Copyright © 2016 Bas Nieuwenhuizen
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:
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
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.
26 #include "tu_private.h"
28 #include "util/format_r11g11b10f.h"
29 #include "util/format_srgb.h"
30 #include "util/u_half.h"
31 #include "vk_format.h"
35 tu_physical_device_get_format_properties(
36 struct tu_physical_device
*physical_device
,
38 VkFormatProperties
*out_properties
)
40 VkFormatFeatureFlags linear
= 0, tiled
= 0, buffer
= 0;
41 const struct vk_format_description
*desc
= vk_format_description(format
);
43 out_properties
->linearTilingFeatures
= linear
;
44 out_properties
->optimalTilingFeatures
= tiled
;
45 out_properties
->bufferFeatures
= buffer
;
49 out_properties
->linearTilingFeatures
= linear
;
50 out_properties
->optimalTilingFeatures
= tiled
;
51 out_properties
->bufferFeatures
= buffer
;
55 tu_GetPhysicalDeviceFormatProperties(VkPhysicalDevice physicalDevice
,
57 VkFormatProperties
*pFormatProperties
)
59 TU_FROM_HANDLE(tu_physical_device
, physical_device
, physicalDevice
);
61 tu_physical_device_get_format_properties(physical_device
, format
,
66 tu_GetPhysicalDeviceFormatProperties2(
67 VkPhysicalDevice physicalDevice
,
69 VkFormatProperties2KHR
*pFormatProperties
)
71 TU_FROM_HANDLE(tu_physical_device
, physical_device
, physicalDevice
);
73 tu_physical_device_get_format_properties(
74 physical_device
, format
, &pFormatProperties
->formatProperties
);
78 tu_get_image_format_properties(
79 struct tu_physical_device
*physical_device
,
80 const VkPhysicalDeviceImageFormatInfo2KHR
*info
,
81 VkImageFormatProperties
*pImageFormatProperties
)
84 VkFormatProperties format_props
;
85 VkFormatFeatureFlags format_feature_flags
;
87 uint32_t maxMipLevels
;
88 uint32_t maxArraySize
;
89 VkSampleCountFlags sampleCounts
= VK_SAMPLE_COUNT_1_BIT
;
91 tu_physical_device_get_format_properties(physical_device
, info
->format
,
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
;
98 unreachable("bad VkImageTiling");
101 if (format_feature_flags
== 0)
104 if (info
->type
!= VK_IMAGE_TYPE_2D
&&
105 vk_format_is_depth_or_stencil(info
->format
))
108 switch (info
->type
) {
110 unreachable("bad vkimage type\n");
111 case VK_IMAGE_TYPE_1D
:
112 maxExtent
.width
= 16384;
113 maxExtent
.height
= 1;
115 maxMipLevels
= 15; /* log2(maxWidth) + 1 */
118 case VK_IMAGE_TYPE_2D
:
119 maxExtent
.width
= 16384;
120 maxExtent
.height
= 16384;
122 maxMipLevels
= 15; /* log2(maxWidth) + 1 */
125 case VK_IMAGE_TYPE_3D
:
126 maxExtent
.width
= 2048;
127 maxExtent
.height
= 2048;
128 maxExtent
.depth
= 2048;
129 maxMipLevels
= 12; /* log2(maxWidth) + 1 */
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
;
145 if (info
->usage
& VK_IMAGE_USAGE_SAMPLED_BIT
) {
146 if (!(format_feature_flags
& VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT
)) {
151 if (info
->usage
& VK_IMAGE_USAGE_STORAGE_BIT
) {
152 if (!(format_feature_flags
& VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT
)) {
157 if (info
->usage
& VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT
) {
158 if (!(format_feature_flags
& VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT
)) {
163 if (info
->usage
& VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT
) {
164 if (!(format_feature_flags
&
165 VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT
)) {
170 *pImageFormatProperties
= (VkImageFormatProperties
) {
171 .maxExtent
= maxExtent
,
172 .maxMipLevels
= maxMipLevels
,
173 .maxArrayLayers
= maxArraySize
,
174 .sampleCounts
= sampleCounts
,
176 /* FINISHME: Accurately calculate
177 * VkImageFormatProperties::maxResourceSize.
179 .maxResourceSize
= UINT32_MAX
,
184 *pImageFormatProperties
= (VkImageFormatProperties
) {
185 .maxExtent
= { 0, 0, 0 },
189 .maxResourceSize
= 0,
192 return VK_ERROR_FORMAT_NOT_SUPPORTED
;
196 tu_GetPhysicalDeviceImageFormatProperties(
197 VkPhysicalDevice physicalDevice
,
200 VkImageTiling tiling
,
201 VkImageUsageFlags usage
,
202 VkImageCreateFlags createFlags
,
203 VkImageFormatProperties
*pImageFormatProperties
)
205 TU_FROM_HANDLE(tu_physical_device
, physical_device
, physicalDevice
);
207 const VkPhysicalDeviceImageFormatInfo2KHR info
= {
208 .sType
= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2_KHR
,
214 .flags
= createFlags
,
217 return tu_get_image_format_properties(physical_device
, &info
,
218 pImageFormatProperties
);
222 get_external_image_format_properties(
223 const VkPhysicalDeviceImageFormatInfo2KHR
*pImageFormatInfo
,
224 VkExternalMemoryHandleTypeFlagBitsKHR handleType
,
225 VkExternalMemoryPropertiesKHR
*external_properties
)
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
;
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
;
254 *external_properties
= (VkExternalMemoryPropertiesKHR
) {
255 .externalMemoryFeatures
= flags
,
256 .exportFromImportedHandleTypes
= export_flags
,
257 .compatibleHandleTypes
= compat_flags
,
262 tu_GetPhysicalDeviceImageFormatProperties2(
263 VkPhysicalDevice physicalDevice
,
264 const VkPhysicalDeviceImageFormatInfo2KHR
*base_info
,
265 VkImageFormatProperties2KHR
*base_props
)
267 TU_FROM_HANDLE(tu_physical_device
, physical_device
, physicalDevice
);
268 const VkPhysicalDeviceExternalImageFormatInfoKHR
*external_info
= NULL
;
269 VkExternalImageFormatPropertiesKHR
*external_props
= NULL
;
272 result
= tu_get_image_format_properties(
273 physical_device
, base_info
, &base_props
->imageFormatProperties
);
274 if (result
!= VK_SUCCESS
)
277 /* Extract input structs */
278 vk_foreach_struct_const(s
, base_info
->pNext
)
281 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO_KHR
:
282 external_info
= (const void *) s
;
289 /* Extract output structs */
290 vk_foreach_struct(s
, base_props
->pNext
)
293 case VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES_KHR
:
294 external_props
= (void *) s
;
301 /* From the Vulkan 1.0.42 spec:
303 * If handleType is 0, vkGetPhysicalDeviceImageFormatProperties2KHR will
304 * behave as if VkPhysicalDeviceExternalImageFormatInfoKHR was not
305 * present and VkExternalImageFormatPropertiesKHR will be ignored.
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
);
317 /* From the Vulkan 1.0.42 spec:
319 * If handleType is not compatible with the [parameters]
321 * in VkPhysicalDeviceImageFormatInfo2KHR, then
322 * vkGetPhysicalDeviceImageFormatProperties2KHR returns
323 * VK_ERROR_FORMAT_NOT_SUPPORTED.
326 physical_device
->instance
, VK_ERROR_FORMAT_NOT_SUPPORTED
,
327 "unsupported VkExternalMemoryTypeFlagBitsKHR 0x%x",
328 external_info
->handleType
);
336 if (result
== VK_ERROR_FORMAT_NOT_SUPPORTED
) {
337 /* From the Vulkan 1.0.42 spec:
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.
344 base_props
->imageFormatProperties
= (VkImageFormatProperties
) { 0 };
351 tu_GetPhysicalDeviceSparseImageFormatProperties(
352 VkPhysicalDevice physicalDevice
,
356 VkImageUsageFlags usage
,
357 VkImageTiling tiling
,
358 uint32_t *pNumProperties
,
359 VkSparseImageFormatProperties
*pProperties
)
361 /* Sparse images are not yet supported. */
366 tu_GetPhysicalDeviceSparseImageFormatProperties2(
367 VkPhysicalDevice physicalDevice
,
368 const VkPhysicalDeviceSparseImageFormatInfo2KHR
*pFormatInfo
,
369 uint32_t *pPropertyCount
,
370 VkSparseImageFormatProperties2KHR
*pProperties
)
372 /* Sparse images are not yet supported. */
377 tu_GetPhysicalDeviceExternalBufferProperties(
378 VkPhysicalDevice physicalDevice
,
379 const VkPhysicalDeviceExternalBufferInfoKHR
*pExternalBufferInfo
,
380 VkExternalBufferPropertiesKHR
*pExternalBufferProperties
)
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
;
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
;
401 pExternalBufferProperties
->externalMemoryProperties
=
402 (VkExternalMemoryPropertiesKHR
) {
403 .externalMemoryFeatures
= flags
,
404 .exportFromImportedHandleTypes
= export_flags
,
405 .compatibleHandleTypes
= compat_flags
,