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 DEALINGS
26 #include "tu_private.h"
28 #include "vk_format.h"
32 #include "util/format_r11g11b10f.h"
33 #include "util/format_srgb.h"
34 #include "util/u_half.h"
37 tu_physical_device_get_format_properties(
38 struct tu_physical_device
*physical_device
,
40 VkFormatProperties
*out_properties
)
42 VkFormatFeatureFlags linear
= 0, tiled
= 0, buffer
= 0;
43 const struct vk_format_description
*desc
= vk_format_description(format
);
45 out_properties
->linearTilingFeatures
= linear
;
46 out_properties
->optimalTilingFeatures
= tiled
;
47 out_properties
->bufferFeatures
= buffer
;
51 out_properties
->linearTilingFeatures
= linear
;
52 out_properties
->optimalTilingFeatures
= tiled
;
53 out_properties
->bufferFeatures
= buffer
;
57 tu_GetPhysicalDeviceFormatProperties(VkPhysicalDevice physicalDevice
,
59 VkFormatProperties
*pFormatProperties
)
61 TU_FROM_HANDLE(tu_physical_device
, physical_device
, physicalDevice
);
63 tu_physical_device_get_format_properties(
64 physical_device
, format
, pFormatProperties
);
68 tu_GetPhysicalDeviceFormatProperties2(
69 VkPhysicalDevice physicalDevice
,
71 VkFormatProperties2KHR
*pFormatProperties
)
73 TU_FROM_HANDLE(tu_physical_device
, physical_device
, physicalDevice
);
75 tu_physical_device_get_format_properties(
76 physical_device
, format
, &pFormatProperties
->formatProperties
);
80 tu_get_image_format_properties(struct tu_physical_device
*physical_device
,
81 const VkPhysicalDeviceImageFormatInfo2KHR
*info
,
82 VkImageFormatProperties
*pImageFormatProperties
)
85 VkFormatProperties format_props
;
86 VkFormatFeatureFlags format_feature_flags
;
88 uint32_t maxMipLevels
;
89 uint32_t maxArraySize
;
90 VkSampleCountFlags sampleCounts
= VK_SAMPLE_COUNT_1_BIT
;
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
;
99 unreachable("bad VkImageTiling");
102 if (format_feature_flags
== 0)
105 if (info
->type
!= VK_IMAGE_TYPE_2D
&&
106 vk_format_is_depth_or_stencil(info
->format
))
109 switch (info
->type
) {
111 unreachable("bad vkimage type\n");
112 case VK_IMAGE_TYPE_1D
:
113 maxExtent
.width
= 16384;
114 maxExtent
.height
= 1;
116 maxMipLevels
= 15; /* log2(maxWidth) + 1 */
119 case VK_IMAGE_TYPE_2D
:
120 maxExtent
.width
= 16384;
121 maxExtent
.height
= 16384;
123 maxMipLevels
= 15; /* log2(maxWidth) + 1 */
126 case VK_IMAGE_TYPE_3D
:
127 maxExtent
.width
= 2048;
128 maxExtent
.height
= 2048;
129 maxExtent
.depth
= 2048;
130 maxMipLevels
= 12; /* log2(maxWidth) + 1 */
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
)) {
143 VK_SAMPLE_COUNT_2_BIT
| VK_SAMPLE_COUNT_4_BIT
| VK_SAMPLE_COUNT_8_BIT
;
146 if (info
->usage
& VK_IMAGE_USAGE_SAMPLED_BIT
) {
147 if (!(format_feature_flags
& VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT
)) {
152 if (info
->usage
& VK_IMAGE_USAGE_STORAGE_BIT
) {
153 if (!(format_feature_flags
& VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT
)) {
158 if (info
->usage
& VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT
) {
159 if (!(format_feature_flags
& VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT
)) {
164 if (info
->usage
& VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT
) {
165 if (!(format_feature_flags
&
166 VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT
)) {
171 *pImageFormatProperties
= (VkImageFormatProperties
){
172 .maxExtent
= maxExtent
,
173 .maxMipLevels
= maxMipLevels
,
174 .maxArrayLayers
= maxArraySize
,
175 .sampleCounts
= sampleCounts
,
177 /* FINISHME: Accurately calculate
178 * VkImageFormatProperties::maxResourceSize.
180 .maxResourceSize
= UINT32_MAX
,
185 *pImageFormatProperties
= (VkImageFormatProperties
){
186 .maxExtent
= { 0, 0, 0 },
190 .maxResourceSize
= 0,
193 return VK_ERROR_FORMAT_NOT_SUPPORTED
;
197 tu_GetPhysicalDeviceImageFormatProperties(
198 VkPhysicalDevice physicalDevice
,
201 VkImageTiling tiling
,
202 VkImageUsageFlags usage
,
203 VkImageCreateFlags createFlags
,
204 VkImageFormatProperties
*pImageFormatProperties
)
206 TU_FROM_HANDLE(tu_physical_device
, physical_device
, physicalDevice
);
208 const VkPhysicalDeviceImageFormatInfo2KHR info
= {
209 .sType
= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2_KHR
,
215 .flags
= createFlags
,
218 return tu_get_image_format_properties(
219 physical_device
, &info
, pImageFormatProperties
);
223 get_external_image_format_properties(
224 const VkPhysicalDeviceImageFormatInfo2KHR
*pImageFormatInfo
,
225 VkExternalMemoryHandleTypeFlagBitsKHR handleType
,
226 VkExternalMemoryPropertiesKHR
*external_properties
)
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
;
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
;
255 *external_properties
= (VkExternalMemoryPropertiesKHR
){
256 .externalMemoryFeatures
= flags
,
257 .exportFromImportedHandleTypes
= export_flags
,
258 .compatibleHandleTypes
= compat_flags
,
263 tu_GetPhysicalDeviceImageFormatProperties2(
264 VkPhysicalDevice physicalDevice
,
265 const VkPhysicalDeviceImageFormatInfo2KHR
*base_info
,
266 VkImageFormatProperties2KHR
*base_props
)
268 TU_FROM_HANDLE(tu_physical_device
, physical_device
, physicalDevice
);
269 const VkPhysicalDeviceExternalImageFormatInfoKHR
*external_info
= NULL
;
270 VkExternalImageFormatPropertiesKHR
*external_props
= NULL
;
273 result
= tu_get_image_format_properties(
274 physical_device
, base_info
, &base_props
->imageFormatProperties
);
275 if (result
!= VK_SUCCESS
)
278 /* Extract input structs */
279 vk_foreach_struct_const(s
, base_info
->pNext
)
282 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO_KHR
:
283 external_info
= (const void *)s
;
290 /* Extract output structs */
291 vk_foreach_struct(s
, base_props
->pNext
)
294 case VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES_KHR
:
295 external_props
= (void *)s
;
302 /* From the Vulkan 1.0.42 spec:
304 * If handleType is 0, vkGetPhysicalDeviceImageFormatProperties2KHR will
305 * behave as if VkPhysicalDeviceExternalImageFormatInfoKHR was not
306 * present and VkExternalImageFormatPropertiesKHR will be ignored.
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(
315 external_info
->handleType
,
316 &external_props
->externalMemoryProperties
);
319 /* From the Vulkan 1.0.42 spec:
321 * If handleType is not compatible with the [parameters]
323 * in VkPhysicalDeviceImageFormatInfo2KHR, then
324 * vkGetPhysicalDeviceImageFormatProperties2KHR returns
325 * VK_ERROR_FORMAT_NOT_SUPPORTED.
328 vk_errorf(physical_device
->instance
,
329 VK_ERROR_FORMAT_NOT_SUPPORTED
,
330 "unsupported VkExternalMemoryTypeFlagBitsKHR 0x%x",
331 external_info
->handleType
);
339 if (result
== VK_ERROR_FORMAT_NOT_SUPPORTED
) {
340 /* From the Vulkan 1.0.42 spec:
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.
347 base_props
->imageFormatProperties
= (VkImageFormatProperties
){ 0 };
354 tu_GetPhysicalDeviceSparseImageFormatProperties(
355 VkPhysicalDevice physicalDevice
,
359 VkImageUsageFlags usage
,
360 VkImageTiling tiling
,
361 uint32_t *pNumProperties
,
362 VkSparseImageFormatProperties
*pProperties
)
364 /* Sparse images are not yet supported. */
369 tu_GetPhysicalDeviceSparseImageFormatProperties2(
370 VkPhysicalDevice physicalDevice
,
371 const VkPhysicalDeviceSparseImageFormatInfo2KHR
*pFormatInfo
,
372 uint32_t *pPropertyCount
,
373 VkSparseImageFormatProperties2KHR
*pProperties
)
375 /* Sparse images are not yet supported. */
380 tu_GetPhysicalDeviceExternalBufferProperties(
381 VkPhysicalDevice physicalDevice
,
382 const VkPhysicalDeviceExternalBufferInfoKHR
*pExternalBufferInfo
,
383 VkExternalBufferPropertiesKHR
*pExternalBufferProperties
)
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
;
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
;
404 pExternalBufferProperties
->externalMemoryProperties
=
405 (VkExternalMemoryPropertiesKHR
){
406 .externalMemoryFeatures
= flags
,
407 .exportFromImportedHandleTypes
= export_flags
,
408 .compatibleHandleTypes
= compat_flags
,