1 /*
2 * Copyright © 2019 Red Hat.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 */
23
24 #include "lvp_private.h"
25 #include "pipe/p_config.h"
26 #include "pipe/p_defines.h"
27 #include "util/format/u_format.h"
28 #include "util/u_math.h"
29 #include "vk_util.h"
30
lvp_is_filter_minmax_format_supported(VkFormat format)31 static bool lvp_is_filter_minmax_format_supported(VkFormat format)
32 {
33 /* From the Vulkan spec 1.1.71:
34 *
35 * "The following formats must support the
36 * VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT feature with
37 * VK_IMAGE_TILING_OPTIMAL, if they support
38 * VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT."
39 */
40 /* TODO: enable more formats. */
41 switch (format) {
42 case VK_FORMAT_R8_UNORM:
43 case VK_FORMAT_R8_SNORM:
44 case VK_FORMAT_R16_UNORM:
45 case VK_FORMAT_R16_SNORM:
46 case VK_FORMAT_R16_SFLOAT:
47 case VK_FORMAT_R32_SFLOAT:
48 case VK_FORMAT_D16_UNORM:
49 case VK_FORMAT_X8_D24_UNORM_PACK32:
50 case VK_FORMAT_D32_SFLOAT:
51 case VK_FORMAT_D16_UNORM_S8_UINT:
52 case VK_FORMAT_D24_UNORM_S8_UINT:
53 case VK_FORMAT_D32_SFLOAT_S8_UINT:
54 return true;
55 default:
56 return false;
57 }
58 }
59
60 static void
lvp_physical_device_get_format_properties(struct lvp_physical_device * physical_device,VkFormat format,VkFormatProperties * out_properties)61 lvp_physical_device_get_format_properties(struct lvp_physical_device *physical_device,
62 VkFormat format,
63 VkFormatProperties *out_properties)
64 {
65 enum pipe_format pformat = lvp_vk_format_to_pipe_format(format);
66 unsigned features = 0, buffer_features = 0;
67 if (pformat == PIPE_FORMAT_NONE) {
68 out_properties->linearTilingFeatures = 0;
69 out_properties->optimalTilingFeatures = 0;
70 out_properties->bufferFeatures = 0;
71 return;
72 }
73
74 if (physical_device->pscreen->is_format_supported(physical_device->pscreen, pformat,
75 PIPE_TEXTURE_2D, 0, 0, PIPE_BIND_DEPTH_STENCIL)) {
76 out_properties->linearTilingFeatures = 0;
77 out_properties->optimalTilingFeatures = VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT |
78 VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT |
79 VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT;
80
81 if (lvp_is_filter_minmax_format_supported(format))
82 out_properties->optimalTilingFeatures |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT;
83 out_properties->bufferFeatures = 0;
84 return;
85 }
86
87 if (util_format_is_compressed(pformat)) {
88 if (physical_device->pscreen->is_format_supported(physical_device->pscreen, pformat,
89 PIPE_TEXTURE_2D, 0, 0, PIPE_BIND_SAMPLER_VIEW)) {
90 features |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT;
91 features |= VK_FORMAT_FEATURE_BLIT_SRC_BIT;
92 features |= VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT;
93 features |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT;
94 }
95 out_properties->linearTilingFeatures = features;
96 out_properties->optimalTilingFeatures = features;
97 out_properties->bufferFeatures = buffer_features;
98 return;
99 }
100
101 if (!util_format_is_srgb(pformat) &&
102 physical_device->pscreen->is_format_supported(physical_device->pscreen, pformat,
103 PIPE_BUFFER, 0, 0, PIPE_BIND_VERTEX_BUFFER)) {
104 buffer_features |= VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT;
105 }
106
107 if (physical_device->pscreen->is_format_supported(physical_device->pscreen, pformat,
108 PIPE_BUFFER, 0, 0, PIPE_BIND_CONSTANT_BUFFER)) {
109 buffer_features |= VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT;
110 }
111
112 if (physical_device->pscreen->is_format_supported(physical_device->pscreen, pformat,
113 PIPE_BUFFER, 0, 0, PIPE_BIND_SHADER_IMAGE)) {
114 buffer_features |= VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT;
115 }
116
117 if (physical_device->pscreen->is_format_supported(physical_device->pscreen, pformat,
118 PIPE_TEXTURE_2D, 0, 0, PIPE_BIND_SAMPLER_VIEW)) {
119 features |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT;
120 if (!util_format_is_pure_integer(pformat))
121 features |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT;
122 if (lvp_is_filter_minmax_format_supported(format))
123 features |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT;
124 }
125
126 if (physical_device->pscreen->is_format_supported(physical_device->pscreen, pformat,
127 PIPE_TEXTURE_2D, 0, 0, PIPE_BIND_RENDER_TARGET)) {
128 features |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT;
129 /* SNORM blending on llvmpipe fails CTS - disable for now */
130 if (!util_format_is_snorm(pformat))
131 features |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT;
132 }
133
134 if (physical_device->pscreen->is_format_supported(physical_device->pscreen, pformat,
135 PIPE_TEXTURE_2D, 0, 0, PIPE_BIND_SHADER_IMAGE)) {
136 features |= VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT;
137 }
138
139 if (pformat == PIPE_FORMAT_R32_UINT || pformat == PIPE_FORMAT_R32_SINT) {
140 features |= VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT;
141 buffer_features |= VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT;
142 }
143
144 if (pformat == PIPE_FORMAT_R11G11B10_FLOAT || pformat == PIPE_FORMAT_R9G9B9E5_FLOAT)
145 features |= VK_FORMAT_FEATURE_BLIT_SRC_BIT;
146
147 if (features && buffer_features != VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)
148 features |= VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT;
149 if (pformat == PIPE_FORMAT_B5G6R5_UNORM)
150 features |= VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT;
151 if ((pformat != PIPE_FORMAT_R9G9B9E5_FLOAT) && util_format_get_nr_components(pformat) != 3 &&
152 pformat != PIPE_FORMAT_R10G10B10A2_SNORM && pformat != PIPE_FORMAT_B10G10R10A2_SNORM &&
153 pformat != PIPE_FORMAT_B10G10R10A2_UNORM) {
154 features |= VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT;
155 }
156 out_properties->linearTilingFeatures = features;
157 out_properties->optimalTilingFeatures = features;
158 out_properties->bufferFeatures = buffer_features;
159 return;
160 }
161
lvp_GetPhysicalDeviceFormatProperties2(VkPhysicalDevice physicalDevice,VkFormat format,VkFormatProperties2 * pFormatProperties)162 VKAPI_ATTR void VKAPI_CALL lvp_GetPhysicalDeviceFormatProperties2(
163 VkPhysicalDevice physicalDevice,
164 VkFormat format,
165 VkFormatProperties2* pFormatProperties)
166 {
167 LVP_FROM_HANDLE(lvp_physical_device, physical_device, physicalDevice);
168
169 lvp_physical_device_get_format_properties(physical_device,
170 format,
171 &pFormatProperties->formatProperties);
172 }
lvp_get_image_format_properties(struct lvp_physical_device * physical_device,const VkPhysicalDeviceImageFormatInfo2 * info,VkImageFormatProperties * pImageFormatProperties)173 static VkResult lvp_get_image_format_properties(struct lvp_physical_device *physical_device,
174 const VkPhysicalDeviceImageFormatInfo2 *info,
175 VkImageFormatProperties *pImageFormatProperties)
176 {
177 VkFormatProperties format_props;
178 VkFormatFeatureFlags format_feature_flags;
179 VkExtent3D maxExtent;
180 uint32_t maxMipLevels;
181 uint32_t maxArraySize;
182 VkSampleCountFlags sampleCounts = VK_SAMPLE_COUNT_1_BIT;
183 enum pipe_format pformat = lvp_vk_format_to_pipe_format(info->format);
184 lvp_physical_device_get_format_properties(physical_device, info->format,
185 &format_props);
186 if (info->tiling == VK_IMAGE_TILING_LINEAR) {
187 format_feature_flags = format_props.linearTilingFeatures;
188 } else if (info->tiling == VK_IMAGE_TILING_OPTIMAL) {
189 format_feature_flags = format_props.optimalTilingFeatures;
190 } else {
191 unreachable("bad VkImageTiling");
192 }
193
194 if (format_feature_flags == 0)
195 goto unsupported;
196
197 uint32_t max_2d_ext = physical_device->pscreen->get_param(physical_device->pscreen, PIPE_CAP_MAX_TEXTURE_2D_SIZE);
198 uint32_t max_layers = physical_device->pscreen->get_param(physical_device->pscreen, PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS);
199 switch (info->type) {
200 default:
201 unreachable("bad vkimage type\n");
202 case VK_IMAGE_TYPE_1D:
203 if (util_format_is_compressed(pformat))
204 goto unsupported;
205
206 maxExtent.width = max_2d_ext;
207 maxExtent.height = 1;
208 maxExtent.depth = 1;
209 maxMipLevels = util_logbase2(max_2d_ext) + 1;
210 maxArraySize = max_layers;
211 break;
212 case VK_IMAGE_TYPE_2D:
213 maxExtent.width = max_2d_ext;
214 maxExtent.height = max_2d_ext;
215 maxExtent.depth = 1;
216 maxMipLevels = util_logbase2(max_2d_ext) + 1;
217 maxArraySize = max_layers;
218 if (info->tiling == VK_IMAGE_TILING_OPTIMAL &&
219 !(info->flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) &&
220 !util_format_is_compressed(pformat) &&
221 (format_feature_flags & (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)))
222 sampleCounts |= VK_SAMPLE_COUNT_4_BIT;
223 break;
224 case VK_IMAGE_TYPE_3D:
225 maxExtent.width = max_2d_ext;
226 maxExtent.height = max_2d_ext;
227 maxExtent.depth = (1 << physical_device->pscreen->get_param(physical_device->pscreen, PIPE_CAP_MAX_TEXTURE_3D_LEVELS));
228 maxMipLevels = util_logbase2(max_2d_ext) + 1;
229 maxArraySize = 1;
230 break;
231 }
232
233 if (info->usage & VK_IMAGE_USAGE_SAMPLED_BIT) {
234 if (!(format_feature_flags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)) {
235 goto unsupported;
236 }
237 }
238
239 if (info->usage & VK_IMAGE_USAGE_STORAGE_BIT) {
240 if (!(format_feature_flags & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT)) {
241 goto unsupported;
242 }
243 }
244
245 if (info->usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) {
246 if (!(format_feature_flags & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT)) {
247 goto unsupported;
248 }
249 }
250
251 if (info->usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
252 if (!(format_feature_flags & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)) {
253 goto unsupported;
254 }
255 }
256
257 if (info->usage & VK_IMAGE_USAGE_TRANSFER_SRC_BIT) {
258 if (!(format_feature_flags & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT)) {
259 goto unsupported;
260 }
261 }
262
263 if (info->usage & VK_IMAGE_USAGE_TRANSFER_DST_BIT) {
264 if (!(format_feature_flags & VK_FORMAT_FEATURE_TRANSFER_DST_BIT)) {
265 goto unsupported;
266 }
267 }
268
269 if (info->usage & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT) {
270 if (!(format_feature_flags & (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT |
271 VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT))) {
272 goto unsupported;
273 }
274 }
275
276 *pImageFormatProperties = (VkImageFormatProperties) {
277 .maxExtent = maxExtent,
278 .maxMipLevels = maxMipLevels,
279 .maxArrayLayers = maxArraySize,
280 .sampleCounts = sampleCounts,
281
282 /* FINISHME: Accurately calculate
283 * VkImageFormatProperties::maxResourceSize.
284 */
285 .maxResourceSize = UINT32_MAX,
286 };
287 return VK_SUCCESS;
288 unsupported:
289 *pImageFormatProperties = (VkImageFormatProperties) {
290 .maxExtent = { 0, 0, 0 },
291 .maxMipLevels = 0,
292 .maxArrayLayers = 0,
293 .sampleCounts = 0,
294 .maxResourceSize = 0,
295 };
296
297 return VK_ERROR_FORMAT_NOT_SUPPORTED;
298 }
299
lvp_GetPhysicalDeviceImageFormatProperties2(VkPhysicalDevice physicalDevice,const VkPhysicalDeviceImageFormatInfo2 * base_info,VkImageFormatProperties2 * base_props)300 VKAPI_ATTR VkResult VKAPI_CALL lvp_GetPhysicalDeviceImageFormatProperties2(
301 VkPhysicalDevice physicalDevice,
302 const VkPhysicalDeviceImageFormatInfo2 *base_info,
303 VkImageFormatProperties2 *base_props)
304 {
305 LVP_FROM_HANDLE(lvp_physical_device, physical_device, physicalDevice);
306 const VkPhysicalDeviceExternalImageFormatInfo *external_info = NULL;
307 VkExternalImageFormatProperties *external_props = NULL;
308 VkSamplerYcbcrConversionImageFormatProperties *ycbcr_props = NULL;
309 VkResult result;
310 result = lvp_get_image_format_properties(physical_device, base_info,
311 &base_props->imageFormatProperties);
312 if (result != VK_SUCCESS)
313 return result;
314
315 vk_foreach_struct_const(s, base_info->pNext) {
316 switch (s->sType) {
317 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO:
318 external_info = (const void *) s;
319 break;
320 default:
321 break;
322 }
323 }
324
325 /* Extract output structs */
326 vk_foreach_struct(s, base_props->pNext) {
327 switch (s->sType) {
328 case VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES:
329 external_props = (void *) s;
330 break;
331 case VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_IMAGE_FORMAT_PROPERTIES:
332 ycbcr_props = (void *) s;
333 break;
334 default:
335 break;
336 }
337 }
338
339 if (external_info && external_info->handleType != 0) {
340 VkExternalMemoryFeatureFlagBits flags = 0;
341 VkExternalMemoryHandleTypeFlags export_flags = 0;
342 VkExternalMemoryHandleTypeFlags compat_flags = 0;
343
344 switch (external_info->handleType) {
345 #ifdef PIPE_MEMORY_FD
346 case VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT:
347 flags = VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT | VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT;
348 export_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT;
349 compat_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT;
350 break;
351 #endif
352 case VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT:
353 flags = VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT;
354 compat_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT;
355 break;
356 default:
357 break;
358 }
359 external_props->externalMemoryProperties = (VkExternalMemoryProperties) {
360 .externalMemoryFeatures = flags,
361 .exportFromImportedHandleTypes = export_flags,
362 .compatibleHandleTypes = compat_flags,
363 };
364 }
365 if (ycbcr_props)
366 ycbcr_props->combinedImageSamplerDescriptorCount = 0;
367 return VK_SUCCESS;
368 }
369
lvp_GetPhysicalDeviceSparseImageFormatProperties(VkPhysicalDevice physicalDevice,VkFormat format,VkImageType type,uint32_t samples,VkImageUsageFlags usage,VkImageTiling tiling,uint32_t * pNumProperties,VkSparseImageFormatProperties * pProperties)370 VKAPI_ATTR void VKAPI_CALL lvp_GetPhysicalDeviceSparseImageFormatProperties(
371 VkPhysicalDevice physicalDevice,
372 VkFormat format,
373 VkImageType type,
374 uint32_t samples,
375 VkImageUsageFlags usage,
376 VkImageTiling tiling,
377 uint32_t* pNumProperties,
378 VkSparseImageFormatProperties* pProperties)
379 {
380 /* Sparse images are not yet supported. */
381 *pNumProperties = 0;
382 }
383
lvp_GetPhysicalDeviceSparseImageFormatProperties2(VkPhysicalDevice physicalDevice,const VkPhysicalDeviceSparseImageFormatInfo2 * pFormatInfo,uint32_t * pPropertyCount,VkSparseImageFormatProperties2 * pProperties)384 VKAPI_ATTR void VKAPI_CALL lvp_GetPhysicalDeviceSparseImageFormatProperties2(
385 VkPhysicalDevice physicalDevice,
386 const VkPhysicalDeviceSparseImageFormatInfo2 *pFormatInfo,
387 uint32_t *pPropertyCount,
388 VkSparseImageFormatProperties2 *pProperties)
389 {
390 /* Sparse images are not yet supported. */
391 *pPropertyCount = 0;
392 }
393
lvp_GetPhysicalDeviceExternalBufferProperties(VkPhysicalDevice physicalDevice,const VkPhysicalDeviceExternalBufferInfo * pExternalBufferInfo,VkExternalBufferProperties * pExternalBufferProperties)394 VKAPI_ATTR void VKAPI_CALL lvp_GetPhysicalDeviceExternalBufferProperties(
395 VkPhysicalDevice physicalDevice,
396 const VkPhysicalDeviceExternalBufferInfo *pExternalBufferInfo,
397 VkExternalBufferProperties *pExternalBufferProperties)
398 {
399 VkExternalMemoryFeatureFlagBits flags = 0;
400 VkExternalMemoryHandleTypeFlags export_flags = 0;
401 VkExternalMemoryHandleTypeFlags compat_flags = 0;
402 switch (pExternalBufferInfo->handleType) {
403 #ifdef PIPE_MEMORY_FD
404 case VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT:
405 flags = VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT | VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT;
406 export_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT;
407 compat_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT;
408 break;
409 #endif
410 case VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT:
411 flags = VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT;
412 compat_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT;
413 break;
414 default:
415 break;
416 }
417
418 pExternalBufferProperties->externalMemoryProperties = (VkExternalMemoryProperties) {
419 .externalMemoryFeatures = flags,
420 .exportFromImportedHandleTypes = export_flags,
421 .compatibleHandleTypes = compat_flags,
422 };
423 }
424