gst: don't use volatile to mean atomic
[platform/upstream/gstreamer.git] / gst-libs / gst / vulkan / gstvkphysicaldevice.c
1 /*
2  * GStreamer
3  * Copyright (C) 2015 Matthew Waters <matthew@centricular.com>
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public
16  * License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
18  * Boston, MA 02110-1301, USA.
19  */
20
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24
25 #include "gstvkphysicaldevice.h"
26
27 #include "gstvkdebug.h"
28
29 #include <string.h>
30
31 /**
32  * SECTION:vkphysicaldevice
33  * @title: GstVulkanPhysicalDevice
34  * @short_description: Vulkan physical device
35  * @see_also: #GstVulkanInstance, #GstVulkanDevice
36  *
37  * A #GstVulkanPhysicalDevice encapsulates a VkPhysicalDevice
38  */
39
40 #define GST_CAT_DEFAULT gst_vulkan_physical_device_debug
41 GST_DEBUG_CATEGORY (GST_CAT_DEFAULT);
42
43 enum
44 {
45   PROP_0,
46   PROP_INSTANCE,
47   PROP_DEVICE_ID,
48   PROP_NAME,
49 };
50
51 static void gst_vulkan_physical_device_finalize (GObject * object);
52
53 struct _GstVulkanPhysicalDevicePrivate
54 {
55   guint32 n_available_layers;
56   VkLayerProperties *available_layers;
57
58   guint32 n_available_extensions;
59   VkExtensionProperties *available_extensions;
60
61 #if defined (VK_API_VERSION_1_2)
62   VkPhysicalDeviceFeatures2 features10;
63   VkPhysicalDeviceProperties2 properties10;
64   VkPhysicalDeviceVulkan11Features features11;
65   VkPhysicalDeviceVulkan11Properties properties11;
66   VkPhysicalDeviceVulkan12Features features12;
67   VkPhysicalDeviceVulkan12Properties properties12;
68 #endif
69 };
70
71 static void
72 _init_debug (void)
73 {
74   static gsize init;
75
76   if (g_once_init_enter (&init)) {
77     GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, "vulkandevice", 0,
78         "Vulkan Device");
79     g_once_init_leave (&init, 1);
80   }
81 }
82
83 #define GET_PRIV(device) gst_vulkan_physical_device_get_instance_private (device)
84
85 #define gst_vulkan_physical_device_parent_class parent_class
86 G_DEFINE_TYPE_WITH_CODE (GstVulkanPhysicalDevice, gst_vulkan_physical_device,
87     GST_TYPE_OBJECT, G_ADD_PRIVATE (GstVulkanPhysicalDevice);
88     _init_debug ());
89
90 static gboolean gst_vulkan_physical_device_fill_info (GstVulkanPhysicalDevice *
91     device, GError ** error);
92
93 /**
94  * gst_vulkan_physical_device_new:
95  * @instance: the parent #GstVulkanInstance
96  *
97  * Returns: (transfer full): a new #GstVulkanPhysicalDevice
98  *
99  * Since: 1.18
100  */
101 GstVulkanPhysicalDevice *
102 gst_vulkan_physical_device_new (GstVulkanInstance * instance,
103     guint device_index)
104 {
105   GstVulkanPhysicalDevice *device;
106
107   g_return_val_if_fail (GST_IS_VULKAN_INSTANCE (instance), NULL);
108
109   device = g_object_new (GST_TYPE_VULKAN_PHYSICAL_DEVICE, "instance", instance,
110       "device-index", device_index, NULL);
111   gst_object_ref_sink (device);
112
113   return device;
114 }
115
116 static void
117 gst_vulkan_physical_device_set_property (GObject * object, guint prop_id,
118     const GValue * value, GParamSpec * pspec)
119 {
120   GstVulkanPhysicalDevice *device = GST_VULKAN_PHYSICAL_DEVICE (object);
121
122   switch (prop_id) {
123     case PROP_INSTANCE:
124       device->instance = g_value_dup_object (value);
125       break;
126     case PROP_DEVICE_ID:{
127       guint device_id = g_value_get_uint (value);
128       if (device->instance == VK_NULL_HANDLE
129           || device_id >= device->instance->n_physical_devices) {
130         g_critical ("%s: Cannot set device-index larger than the "
131             "number of physical devices", GST_OBJECT_NAME (device));
132       } else {
133         device->device_index = device_id;
134       }
135       break;
136     }
137     default:
138       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
139       break;
140   }
141 }
142
143 static void
144 gst_vulkan_physical_device_get_property (GObject * object, guint prop_id,
145     GValue * value, GParamSpec * pspec)
146 {
147   GstVulkanPhysicalDevice *device = GST_VULKAN_PHYSICAL_DEVICE (object);
148
149   switch (prop_id) {
150     case PROP_INSTANCE:
151       g_value_set_object (value, device->instance);
152       break;
153     case PROP_DEVICE_ID:
154       g_value_set_uint (value, device->device_index);
155       break;
156     case PROP_NAME:
157       g_value_set_string (value, device->properties.deviceName);
158       break;
159     default:
160       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
161       break;
162   }
163 }
164
165 static void
166 gst_vulkan_physical_device_init (GstVulkanPhysicalDevice * device)
167 {
168   GstVulkanPhysicalDevicePrivate *priv = GET_PRIV (device);
169
170   priv->n_available_layers = 0;
171   priv->n_available_extensions = 0;
172
173 #if defined (VK_API_VERSION_1_2)
174   priv->properties10.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
175   priv->properties11.sType =
176       VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES;
177   priv->properties12.sType =
178       VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_PROPERTIES;
179   priv->properties10.pNext = &priv->properties11;
180   priv->properties11.pNext = &priv->properties12;
181
182   priv->features10.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
183   priv->features11.sType =
184       VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES;
185   priv->features12.sType =
186       VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES;
187   priv->features10.pNext = &priv->features11;
188   priv->features11.pNext = &priv->features12;
189 #endif
190 }
191
192 static void
193 gst_vulkan_physical_device_constructed (GObject * object)
194 {
195   GstVulkanPhysicalDevice *device = GST_VULKAN_PHYSICAL_DEVICE (object);
196   GError *error = NULL;
197
198   if (device->instance == VK_NULL_HANDLE) {
199     GST_ERROR_OBJECT (object, "Constructed without any instance set");
200     return;
201   }
202
203   device->device = device->instance->physical_devices[device->device_index];
204
205   if (!gst_vulkan_physical_device_fill_info (device, &error)) {
206     GST_ERROR_OBJECT (object, "%s", error->message);
207     g_clear_error (&error);
208   }
209 }
210
211 static void
212 gst_vulkan_physical_device_class_init (GstVulkanPhysicalDeviceClass *
213     device_class)
214 {
215   GObjectClass *gobject_class = (GObjectClass *) device_class;
216
217   gobject_class->set_property = gst_vulkan_physical_device_set_property;
218   gobject_class->get_property = gst_vulkan_physical_device_get_property;
219   gobject_class->finalize = gst_vulkan_physical_device_finalize;
220   gobject_class->constructed = gst_vulkan_physical_device_constructed;
221
222   g_object_class_install_property (gobject_class, PROP_INSTANCE,
223       g_param_spec_object ("instance", "Instance",
224           "Associated Vulkan Instance",
225           GST_TYPE_VULKAN_INSTANCE,
226           G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
227
228   g_object_class_install_property (gobject_class, PROP_DEVICE_ID,
229       g_param_spec_uint ("device-index", "Device Index", "Device Index", 0,
230           G_MAXUINT32, 0,
231           G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
232
233   g_object_class_install_property (gobject_class, PROP_NAME,
234       g_param_spec_string ("name", "Name", "Device Name", NULL,
235           G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
236 }
237
238 static void
239 gst_vulkan_physical_device_finalize (GObject * object)
240 {
241   GstVulkanPhysicalDevice *device = GST_VULKAN_PHYSICAL_DEVICE (object);
242   GstVulkanPhysicalDevicePrivate *priv = GET_PRIV (device);
243
244   g_free (priv->available_layers);
245   priv->available_layers = NULL;
246
247   g_free (priv->available_extensions);
248   priv->available_extensions = NULL;
249
250   g_free (device->queue_family_props);
251   device->queue_family_props = NULL;
252
253   if (device->instance)
254     gst_object_unref (device->instance);
255   device->instance = VK_NULL_HANDLE;
256
257   G_OBJECT_CLASS (parent_class)->finalize (object);
258 }
259
260 #define DEBUG_BOOL(prefix, name, value)                                     \
261   GST_DEBUG_OBJECT (device, prefix " " G_STRINGIFY(name) ": %s",            \
262     value ? "YES" : "NO")
263 #define DEBUG_1(prefix, s, name, format, type)                              \
264   GST_DEBUG_OBJECT (device, prefix " " G_STRINGIFY(name) ": %" format,      \
265     (type) (s)->name)
266 #define DEBUG_2(prefix, s, name, format, type)                              \
267   GST_DEBUG_OBJECT (device, prefix " " G_STRINGIFY(name)                    \
268     ": %" format ", %" format,                                              \
269     (type) (s)->name[0],                                                    \
270     (type) (s)->name[1])
271 #define DEBUG_3(prefix, s, name, format, type)                              \
272   GST_DEBUG_OBJECT (device, prefix " " G_STRINGIFY(limit)                   \
273     ": %" format ", %" format ", %" format,                                 \
274     (type) (s)->name[0],                                                    \
275     (type) (s)->name[1],                                                    \
276     (type) (s)->name[2])
277
278 #define DEBUG_UINT32(prefix, s, var) DEBUG_1(prefix, s, var, G_GUINT32_FORMAT, guint32)
279 #define DEBUG_UINT32_2(prefix, s, var) DEBUG_2(prefix, s, var, G_GUINT32_FORMAT, guint32)
280 #define DEBUG_UINT32_3(prefix, s, var) DEBUG_3(prefix, s, var, G_GUINT32_FORMAT, guint32)
281
282 #define DEBUG_UINT64(prefix, s, var) DEBUG_1(prefix, s, var, G_GUINT64_FORMAT, guint64)
283
284 #define DEBUG_INT32(prefix, s, var) DEBUG_1(prefix, s, var, G_GINT32_FORMAT, gint32)
285
286 #define DEBUG_FLOAT(prefix, s, var) DEBUG_1(prefix, s, var, "f", gfloat)
287 #define DEBUG_FLOAT_2(prefix, s, var) DEBUG_2(prefix, s, var, "f", gfloat)
288
289 #define DEBUG_SIZE(prefix, s, var) DEBUG_1(prefix, s, var, G_GSIZE_FORMAT, gsize)
290 #define DEBUG_FLAGS(prefix, s, limit, under_name_type)                      \
291   G_STMT_START {                                                            \
292     gchar *str = G_PASTE(G_PASTE(gst_vulkan_,under_name_type),_flags_to_string) ((s)->limit); \
293     GST_DEBUG_OBJECT (device, prefix " " G_STRINGIFY(limit) ": (0x%x) %s",  \
294         (s)->limit, str);                                                   \
295     g_free (str);                                                           \
296   } G_STMT_END
297
298 #define DEBUG_BOOL_STRUCT(prefix, s, name) DEBUG_BOOL(prefix, name, (s)->name)
299
300 #define DEBUG_STRING(prefix, s, str) DEBUG_1(prefix, s, str, "s", gchar *);
301
302 static void
303 dump_features10 (GstVulkanPhysicalDevice * device,
304     VkPhysicalDeviceFeatures * features)
305 {
306   /* *INDENT-OFF* */
307   DEBUG_BOOL_STRUCT ("support for", features, robustBufferAccess);
308   DEBUG_BOOL_STRUCT ("support for", features, fullDrawIndexUint32);
309   DEBUG_BOOL_STRUCT ("support for", features, imageCubeArray);
310   DEBUG_BOOL_STRUCT ("support for", features, independentBlend);
311   DEBUG_BOOL_STRUCT ("support for", features, geometryShader);
312   DEBUG_BOOL_STRUCT ("support for", features, tessellationShader);
313   DEBUG_BOOL_STRUCT ("support for", features, sampleRateShading);
314   DEBUG_BOOL_STRUCT ("support for", features, sampleRateShading);
315   DEBUG_BOOL_STRUCT ("support for", features, dualSrcBlend);
316   DEBUG_BOOL_STRUCT ("support for", features, logicOp);
317   DEBUG_BOOL_STRUCT ("support for", features, multiDrawIndirect);
318   DEBUG_BOOL_STRUCT ("support for", features, drawIndirectFirstInstance);
319   DEBUG_BOOL_STRUCT ("support for", features, depthClamp);
320   DEBUG_BOOL_STRUCT ("support for", features, depthBiasClamp);
321   DEBUG_BOOL_STRUCT ("support for", features, fillModeNonSolid);
322   DEBUG_BOOL_STRUCT ("support for", features, depthBounds);
323   DEBUG_BOOL_STRUCT ("support for", features, wideLines);
324   DEBUG_BOOL_STRUCT ("support for", features, largePoints);
325   DEBUG_BOOL_STRUCT ("support for", features, alphaToOne);
326   DEBUG_BOOL_STRUCT ("support for", features, multiViewport);
327   DEBUG_BOOL_STRUCT ("support for", features, samplerAnisotropy);
328   DEBUG_BOOL_STRUCT ("support for", features, textureCompressionETC2);
329   DEBUG_BOOL_STRUCT ("support for", features, textureCompressionASTC_LDR);
330   DEBUG_BOOL_STRUCT ("support for", features, textureCompressionBC);
331   DEBUG_BOOL_STRUCT ("support for", features, occlusionQueryPrecise);
332   DEBUG_BOOL_STRUCT ("support for", features, pipelineStatisticsQuery);
333   DEBUG_BOOL_STRUCT ("support for", features, vertexPipelineStoresAndAtomics);
334   DEBUG_BOOL_STRUCT ("support for", features, fragmentStoresAndAtomics);
335   DEBUG_BOOL_STRUCT ("support for", features, shaderTessellationAndGeometryPointSize);
336   DEBUG_BOOL_STRUCT ("support for", features, shaderImageGatherExtended);
337   DEBUG_BOOL_STRUCT ("support for", features, shaderStorageImageExtendedFormats);
338   DEBUG_BOOL_STRUCT ("support for", features, shaderStorageImageMultisample);
339   DEBUG_BOOL_STRUCT ("support for", features, shaderStorageImageReadWithoutFormat);
340   DEBUG_BOOL_STRUCT ("support for", features, shaderStorageImageWriteWithoutFormat);
341   DEBUG_BOOL_STRUCT ("support for", features, shaderUniformBufferArrayDynamicIndexing);
342   DEBUG_BOOL_STRUCT ("support for", features, shaderSampledImageArrayDynamicIndexing);
343   DEBUG_BOOL_STRUCT ("support for", features, shaderStorageBufferArrayDynamicIndexing);
344   DEBUG_BOOL_STRUCT ("support for", features, shaderStorageImageArrayDynamicIndexing);
345   DEBUG_BOOL_STRUCT ("support for", features, shaderClipDistance);
346   DEBUG_BOOL_STRUCT ("support for", features, shaderCullDistance);
347   DEBUG_BOOL_STRUCT ("support for", features, shaderFloat64);
348   DEBUG_BOOL_STRUCT ("support for", features, shaderInt64);
349   DEBUG_BOOL_STRUCT ("support for", features, shaderInt16);
350   DEBUG_BOOL_STRUCT ("support for", features, shaderResourceResidency);
351   DEBUG_BOOL_STRUCT ("support for", features, shaderResourceMinLod);
352   DEBUG_BOOL_STRUCT ("support for", features, sparseBinding);
353   DEBUG_BOOL_STRUCT ("support for", features, sparseResidencyBuffer);
354   DEBUG_BOOL_STRUCT ("support for", features, sparseResidencyImage2D);
355   DEBUG_BOOL_STRUCT ("support for", features, sparseResidencyImage3D);
356   DEBUG_BOOL_STRUCT ("support for", features, sparseResidency2Samples);
357   DEBUG_BOOL_STRUCT ("support for", features, sparseResidency4Samples);
358   DEBUG_BOOL_STRUCT ("support for", features, sparseResidency8Samples);
359   DEBUG_BOOL_STRUCT ("support for", features, sparseResidency16Samples);
360   DEBUG_BOOL_STRUCT ("support for", features, sparseResidencyAliased);
361   DEBUG_BOOL_STRUCT ("support for", features, variableMultisampleRate);
362   DEBUG_BOOL_STRUCT ("support for", features, inheritedQueries);
363   /* *INDENT-ON* */
364 }
365
366 #if defined (VK_API_VERSION_1_2)
367 static void
368 dump_features11 (GstVulkanPhysicalDevice * device,
369     VkPhysicalDeviceVulkan11Features * features)
370 {
371   /* *INDENT-OFF* */
372   DEBUG_BOOL_STRUCT ("support for (1.1)", features, storageBuffer16BitAccess);
373   DEBUG_BOOL_STRUCT ("support for (1.1)", features, uniformAndStorageBuffer16BitAccess);
374   DEBUG_BOOL_STRUCT ("support for (1.1)", features, storagePushConstant16);
375   DEBUG_BOOL_STRUCT ("support for (1.1)", features, storageInputOutput16);
376   DEBUG_BOOL_STRUCT ("support for (1.1)", features, multiview);
377   DEBUG_BOOL_STRUCT ("support for (1.1)", features, multiviewGeometryShader);
378   DEBUG_BOOL_STRUCT ("support for (1.1)", features, multiviewTessellationShader);
379   DEBUG_BOOL_STRUCT ("support for (1.1)", features, variablePointersStorageBuffer);
380   DEBUG_BOOL_STRUCT ("support for (1.1)", features, variablePointers);
381   DEBUG_BOOL_STRUCT ("support for (1.1)", features, protectedMemory);
382   DEBUG_BOOL_STRUCT ("support for (1.1)", features, samplerYcbcrConversion);
383   DEBUG_BOOL_STRUCT ("support for (1.1)", features, shaderDrawParameters);
384   /* *INDENT-ON* */
385 }
386
387 static void
388 dump_features12 (GstVulkanPhysicalDevice * device,
389     VkPhysicalDeviceVulkan12Features * features)
390 {
391   /* *INDENT-OFF* */
392   DEBUG_BOOL_STRUCT ("support for (1.2)", features, samplerMirrorClampToEdge);
393   DEBUG_BOOL_STRUCT ("support for (1.2)", features, drawIndirectCount);
394   DEBUG_BOOL_STRUCT ("support for (1.2)", features, storageBuffer8BitAccess);
395   DEBUG_BOOL_STRUCT ("support for (1.2)", features, uniformAndStorageBuffer8BitAccess);
396   DEBUG_BOOL_STRUCT ("support for (1.2)", features, shaderBufferInt64Atomics);
397   DEBUG_BOOL_STRUCT ("support for (1.2)", features, shaderSharedInt64Atomics);
398   DEBUG_BOOL_STRUCT ("support for (1.2)", features, shaderFloat16);
399   DEBUG_BOOL_STRUCT ("support for (1.2)", features, shaderInt8);
400   DEBUG_BOOL_STRUCT ("support for (1.2)", features, descriptorIndexing);
401   DEBUG_BOOL_STRUCT ("support for (1.2)", features, shaderInputAttachmentArrayDynamicIndexing);
402   DEBUG_BOOL_STRUCT ("support for (1.2)", features, shaderUniformTexelBufferArrayDynamicIndexing);
403   DEBUG_BOOL_STRUCT ("support for (1.2)", features, shaderStorageTexelBufferArrayDynamicIndexing);
404   DEBUG_BOOL_STRUCT ("support for (1.2)", features, shaderUniformBufferArrayNonUniformIndexing);
405   DEBUG_BOOL_STRUCT ("support for (1.2)", features, shaderSampledImageArrayNonUniformIndexing);
406   DEBUG_BOOL_STRUCT ("support for (1.2)", features, shaderStorageBufferArrayNonUniformIndexing);
407   DEBUG_BOOL_STRUCT ("support for (1.2)", features, shaderStorageImageArrayNonUniformIndexing);
408   DEBUG_BOOL_STRUCT ("support for (1.2)", features, shaderInputAttachmentArrayNonUniformIndexing);
409   DEBUG_BOOL_STRUCT ("support for (1.2)", features, shaderUniformTexelBufferArrayNonUniformIndexing);
410   DEBUG_BOOL_STRUCT ("support for (1.2)", features, descriptorBindingUniformBufferUpdateAfterBind);
411   DEBUG_BOOL_STRUCT ("support for (1.2)", features, descriptorBindingSampledImageUpdateAfterBind);
412   DEBUG_BOOL_STRUCT ("support for (1.2)", features, descriptorBindingStorageImageUpdateAfterBind);
413   DEBUG_BOOL_STRUCT ("support for (1.2)", features, descriptorBindingStorageBufferUpdateAfterBind);
414   DEBUG_BOOL_STRUCT ("support for (1.2)", features, descriptorBindingUniformTexelBufferUpdateAfterBind);
415   DEBUG_BOOL_STRUCT ("support for (1.2)", features, descriptorBindingStorageTexelBufferUpdateAfterBind);
416   DEBUG_BOOL_STRUCT ("support for (1.2)", features, descriptorBindingUpdateUnusedWhilePending);
417   DEBUG_BOOL_STRUCT ("support for (1.2)", features, descriptorBindingPartiallyBound);
418   DEBUG_BOOL_STRUCT ("support for (1.2)", features, descriptorBindingVariableDescriptorCount);
419   DEBUG_BOOL_STRUCT ("support for (1.2)", features, runtimeDescriptorArray);
420   DEBUG_BOOL_STRUCT ("support for (1.2)", features, samplerFilterMinmax);
421   DEBUG_BOOL_STRUCT ("support for (1.2)", features, scalarBlockLayout);
422   DEBUG_BOOL_STRUCT ("support for (1.2)", features, imagelessFramebuffer);
423   DEBUG_BOOL_STRUCT ("support for (1.2)", features, uniformBufferStandardLayout);
424   DEBUG_BOOL_STRUCT ("support for (1.2)", features, shaderSubgroupExtendedTypes);
425   DEBUG_BOOL_STRUCT ("support for (1.2)", features, separateDepthStencilLayouts);
426   DEBUG_BOOL_STRUCT ("support for (1.2)", features, hostQueryReset);
427   DEBUG_BOOL_STRUCT ("support for (1.2)", features, timelineSemaphore);
428   DEBUG_BOOL_STRUCT ("support for (1.2)", features, bufferDeviceAddress);
429   DEBUG_BOOL_STRUCT ("support for (1.2)", features, bufferDeviceAddressCaptureReplay);
430   DEBUG_BOOL_STRUCT ("support for (1.2)", features, bufferDeviceAddressMultiDevice);
431   DEBUG_BOOL_STRUCT ("support for (1.2)", features, vulkanMemoryModel);
432   DEBUG_BOOL_STRUCT ("support for (1.2)", features, vulkanMemoryModelDeviceScope);
433   DEBUG_BOOL_STRUCT ("support for (1.2)", features, vulkanMemoryModelAvailabilityVisibilityChains);
434   DEBUG_BOOL_STRUCT ("support for (1.2)", features, shaderOutputViewportIndex);
435   DEBUG_BOOL_STRUCT ("support for (1.2)", features, shaderOutputLayer);
436   DEBUG_BOOL_STRUCT ("support for (1.2)", features, subgroupBroadcastDynamicId);
437   /* *INDENT-ON* */
438 }
439 #endif
440 static gboolean
441 dump_features (GstVulkanPhysicalDevice * device, GError ** error)
442 {
443 #if defined (VK_API_VERSION_1_2)
444   GstVulkanPhysicalDevicePrivate *priv = GET_PRIV (device);
445   VkBaseOutStructure *iter;
446
447   if (gst_vulkan_instance_check_version (device->instance, 1, 2, 0)) {
448     for (iter = (VkBaseOutStructure *) & priv->features10; iter;
449         iter = iter->pNext) {
450       if (iter->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2)
451         dump_features10 (device,
452             &((VkPhysicalDeviceFeatures2 *) iter)->features);
453       else if (iter->sType ==
454           VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES)
455         dump_features11 (device, (VkPhysicalDeviceVulkan11Features *) iter);
456       else if (iter->sType ==
457           VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES)
458         dump_features12 (device, (VkPhysicalDeviceVulkan12Features *) iter);
459     }
460   } else
461 #endif
462   {
463     dump_features10 (device, &device->features);
464   }
465
466   return TRUE;
467 }
468
469 static gboolean
470 dump_memory_properties (GstVulkanPhysicalDevice * device, GError ** error)
471 {
472   int i;
473
474   GST_DEBUG_OBJECT (device, "found %" G_GUINT32_FORMAT " memory heaps",
475       device->memory_properties.memoryHeapCount);
476   for (i = 0; i < device->memory_properties.memoryHeapCount; i++) {
477     gchar *prop_flags_str =
478         gst_vulkan_memory_heap_flags_to_string (device->
479         memory_properties.memoryHeaps[i].flags);
480     GST_LOG_OBJECT (device,
481         "memory heap at index %i has size %" G_GUINT64_FORMAT
482         " and flags (0x%x) \'%s\'", i,
483         (guint64) device->memory_properties.memoryHeaps[i].size,
484         device->memory_properties.memoryHeaps[i].flags, prop_flags_str);
485     g_free (prop_flags_str);
486   }
487   GST_DEBUG_OBJECT (device, "found %" G_GUINT32_FORMAT " memory types",
488       device->memory_properties.memoryTypeCount);
489   for (i = 0; i < device->memory_properties.memoryTypeCount; i++) {
490     gchar *prop_flags_str =
491         gst_vulkan_memory_property_flags_to_string (device->memory_properties.
492         memoryTypes[i].propertyFlags);
493     GST_LOG_OBJECT (device,
494         "memory type at index %i is allocatable from "
495         "heap %i with flags (0x%x) \'%s\'", i,
496         device->memory_properties.memoryTypes[i].heapIndex,
497         device->memory_properties.memoryTypes[i].propertyFlags, prop_flags_str);
498     g_free (prop_flags_str);
499   }
500
501   return TRUE;
502 }
503
504 static gboolean
505 dump_queue_properties (GstVulkanPhysicalDevice * device, GError ** error)
506 {
507   int i;
508
509   GST_DEBUG_OBJECT (device, "found %" G_GUINT32_FORMAT " queue families",
510       device->n_queue_families);
511   for (i = 0; i < device->n_queue_families; i++) {
512     gchar *queue_flags_str =
513         gst_vulkan_queue_flags_to_string (device->
514         queue_family_props[i].queueFlags);
515     GST_LOG_OBJECT (device,
516         "queue family at index %i supports %i queues "
517         "with flags (0x%x) \'%s\', %" G_GUINT32_FORMAT " timestamp bits and "
518         "a minimum image transfer granuality of %" GST_VULKAN_EXTENT3D_FORMAT,
519         i, device->queue_family_props[i].queueCount,
520         device->queue_family_props[i].queueFlags, queue_flags_str,
521         device->queue_family_props[i].timestampValidBits,
522         GST_VULKAN_EXTENT3D_ARGS (device->
523             queue_family_props[i].minImageTransferGranularity));
524     g_free (queue_flags_str);
525   }
526
527   return TRUE;
528 }
529
530 static gboolean
531 dump_limits (GstVulkanPhysicalDevice * device, GError ** error)
532 {
533   VkPhysicalDeviceLimits *limits = &device->properties.limits;
534
535   /* *INDENT-OFF* */
536   DEBUG_UINT32 ("limit", limits, maxImageDimension1D);
537   DEBUG_UINT32 ("limit", limits, maxImageDimension2D);
538   DEBUG_UINT32 ("limit", limits, maxImageDimension3D);
539   DEBUG_UINT32 ("limit", limits, maxImageDimensionCube);
540   DEBUG_UINT32 ("limit", limits, maxImageArrayLayers);
541   DEBUG_UINT32 ("limit", limits, maxTexelBufferElements);
542   DEBUG_UINT32 ("limit", limits, maxUniformBufferRange);
543   DEBUG_UINT32 ("limit", limits, maxStorageBufferRange);
544   DEBUG_UINT32 ("limit", limits, maxPushConstantsSize);
545   DEBUG_UINT32 ("limit", limits, maxMemoryAllocationCount);
546   DEBUG_UINT32 ("limit", limits, maxSamplerAllocationCount);
547   DEBUG_UINT64 ("limit", limits, bufferImageGranularity);
548   DEBUG_UINT64 ("limit", limits, sparseAddressSpaceSize);
549   DEBUG_UINT32 ("limit", limits, maxBoundDescriptorSets);
550   DEBUG_UINT32 ("limit", limits, maxPerStageDescriptorSamplers);
551   DEBUG_UINT32 ("limit", limits, maxPerStageDescriptorUniformBuffers);
552   DEBUG_UINT32 ("limit", limits, maxPerStageDescriptorStorageBuffers);
553   DEBUG_UINT32 ("limit", limits, maxPerStageDescriptorSampledImages);
554   DEBUG_UINT32 ("limit", limits, maxPerStageDescriptorStorageImages);
555   DEBUG_UINT32 ("limit", limits, maxPerStageDescriptorInputAttachments);
556   DEBUG_UINT32 ("limit", limits, maxPerStageResources);
557   DEBUG_UINT32 ("limit", limits, maxDescriptorSetSamplers);
558   DEBUG_UINT32 ("limit", limits, maxDescriptorSetUniformBuffers);
559   DEBUG_UINT32 ("limit", limits, maxDescriptorSetUniformBuffersDynamic);
560   DEBUG_UINT32 ("limit", limits, maxDescriptorSetStorageBuffers);
561   DEBUG_UINT32 ("limit", limits, maxDescriptorSetStorageBuffersDynamic);
562   DEBUG_UINT32 ("limit", limits, maxDescriptorSetSampledImages);
563   DEBUG_UINT32 ("limit", limits, maxDescriptorSetStorageImages);
564   DEBUG_UINT32 ("limit", limits, maxDescriptorSetInputAttachments);
565   DEBUG_UINT32 ("limit", limits, maxVertexInputAttributes);
566   DEBUG_UINT32 ("limit", limits, maxVertexInputBindings);
567   DEBUG_UINT32 ("limit", limits, maxVertexInputBindings);
568   DEBUG_UINT32 ("limit", limits, maxVertexInputAttributeOffset);
569   DEBUG_UINT32 ("limit", limits, maxVertexInputBindingStride);
570   DEBUG_UINT32 ("limit", limits, maxVertexOutputComponents);
571   DEBUG_UINT32 ("limit", limits, maxTessellationGenerationLevel);
572   DEBUG_UINT32 ("limit", limits, maxTessellationPatchSize);
573   DEBUG_UINT32 ("limit", limits, maxTessellationControlPerVertexInputComponents);
574   DEBUG_UINT32 ("limit", limits, maxTessellationControlPerVertexOutputComponents);
575   DEBUG_UINT32 ("limit", limits, maxTessellationControlPerPatchOutputComponents);
576   DEBUG_UINT32 ("limit", limits, maxTessellationControlTotalOutputComponents);
577   DEBUG_UINT32 ("limit", limits, maxTessellationControlTotalOutputComponents);
578   DEBUG_UINT32 ("limit", limits, maxTessellationEvaluationInputComponents);
579   DEBUG_UINT32 ("limit", limits, maxTessellationEvaluationOutputComponents);
580   DEBUG_UINT32 ("limit", limits, maxGeometryShaderInvocations);
581   DEBUG_UINT32 ("limit", limits, maxGeometryInputComponents);
582   DEBUG_UINT32 ("limit", limits, maxGeometryOutputComponents);
583   DEBUG_UINT32 ("limit", limits, maxGeometryOutputVertices);
584   DEBUG_UINT32 ("limit", limits, maxGeometryTotalOutputComponents);
585   DEBUG_UINT32 ("limit", limits, maxFragmentInputComponents);
586   DEBUG_UINT32 ("limit", limits, maxFragmentOutputAttachments);
587   DEBUG_UINT32 ("limit", limits, maxFragmentDualSrcAttachments);
588   DEBUG_UINT32 ("limit", limits, maxFragmentCombinedOutputResources);
589   DEBUG_UINT32 ("limit", limits, maxComputeSharedMemorySize);
590   DEBUG_UINT32_3 ("limit", limits, maxComputeWorkGroupCount);
591   DEBUG_UINT32 ("limit", limits, maxComputeWorkGroupInvocations);
592   DEBUG_UINT32_3 ("limit", limits, maxComputeWorkGroupSize);
593   DEBUG_UINT32 ("limit", limits, subPixelPrecisionBits);
594   DEBUG_UINT32 ("limit", limits, subTexelPrecisionBits);
595   DEBUG_UINT32 ("limit", limits, mipmapPrecisionBits);
596   DEBUG_UINT32 ("limit", limits, maxDrawIndexedIndexValue);
597   DEBUG_UINT32 ("limit", limits, maxDrawIndirectCount);
598   DEBUG_FLOAT ("limit", limits, maxSamplerLodBias);
599   DEBUG_FLOAT ("limit", limits, maxSamplerAnisotropy);
600   DEBUG_UINT32 ("limit", limits, maxViewports);
601   DEBUG_UINT32_2 ("limit", limits, maxViewportDimensions);
602   DEBUG_FLOAT_2 ("limit", limits, viewportBoundsRange);
603   DEBUG_UINT32 ("limit", limits, viewportSubPixelBits);
604   DEBUG_SIZE ("limit", limits, minMemoryMapAlignment);
605   DEBUG_UINT64 ("limit", limits, minTexelBufferOffsetAlignment);
606   DEBUG_UINT64 ("limit", limits, minUniformBufferOffsetAlignment);
607   DEBUG_UINT64 ("limit", limits, minStorageBufferOffsetAlignment);
608   DEBUG_INT32 ("limit", limits, minTexelOffset);
609   DEBUG_UINT32 ("limit", limits, maxTexelOffset);
610   DEBUG_INT32 ("limit", limits, minTexelGatherOffset);
611   DEBUG_UINT32 ("limit", limits, maxTexelGatherOffset);
612   DEBUG_FLOAT ("limit", limits, minInterpolationOffset);
613   DEBUG_FLOAT ("limit", limits, maxInterpolationOffset);
614   DEBUG_UINT32 ("limit", limits, subPixelInterpolationOffsetBits);
615   DEBUG_UINT32 ("limit", limits, maxFramebufferWidth);
616   DEBUG_UINT32 ("limit", limits, maxFramebufferHeight);
617   DEBUG_UINT32 ("limit", limits, maxFramebufferLayers);
618   DEBUG_FLAGS ("limit", limits, framebufferColorSampleCounts, sample_count);
619   DEBUG_FLAGS ("limit", limits, framebufferDepthSampleCounts, sample_count);
620   DEBUG_FLAGS ("limit", limits, framebufferStencilSampleCounts, sample_count);
621   DEBUG_FLAGS ("limit", limits, framebufferNoAttachmentsSampleCounts, sample_count);
622   DEBUG_UINT32 ("limit", limits, maxColorAttachments);
623   DEBUG_FLAGS ("limit", limits, sampledImageColorSampleCounts, sample_count);
624   DEBUG_FLAGS ("limit", limits, sampledImageIntegerSampleCounts, sample_count);
625   DEBUG_FLAGS ("limit", limits, sampledImageDepthSampleCounts, sample_count);
626   DEBUG_FLAGS ("limit", limits, sampledImageStencilSampleCounts, sample_count);
627   DEBUG_FLAGS ("limit", limits, storageImageSampleCounts, sample_count);
628   DEBUG_BOOL_STRUCT ("limit", limits, timestampComputeAndGraphics);
629   DEBUG_FLOAT ("limit", limits, timestampPeriod);
630   DEBUG_UINT32 ("limit", limits, maxClipDistances);
631   DEBUG_UINT32 ("limit", limits, maxCullDistances);
632   DEBUG_UINT32 ("limit", limits, maxCombinedClipAndCullDistances);
633   DEBUG_UINT32 ("limit", limits, discreteQueuePriorities);
634   DEBUG_FLOAT_2 ("limit", limits, pointSizeRange);
635   DEBUG_FLOAT_2 ("limit", limits, lineWidthRange);
636   DEBUG_FLOAT ("limit", limits, pointSizeGranularity);
637   DEBUG_FLOAT ("limit", limits, lineWidthGranularity);
638   DEBUG_BOOL_STRUCT ("limit", limits, strictLines);
639   DEBUG_BOOL_STRUCT ("limit", limits, standardSampleLocations);
640   DEBUG_UINT64 ("limit", limits, optimalBufferCopyOffsetAlignment);
641   DEBUG_UINT64 ("limit", limits, optimalBufferCopyRowPitchAlignment);
642   DEBUG_UINT64 ("limit", limits, nonCoherentAtomSize);
643   /* *INDENT-ON* */
644
645   return TRUE;
646 }
647
648 static gboolean
649 dump_sparse_properties (GstVulkanPhysicalDevice * device, GError ** error)
650 {
651   VkPhysicalDeviceSparseProperties *props =
652       &device->properties.sparseProperties;
653
654   /* *INDENT-OFF* */
655   DEBUG_BOOL_STRUCT ("sparse property", props, residencyStandard2DBlockShape);
656   DEBUG_BOOL_STRUCT ("sparse property", props, residencyStandard2DMultisampleBlockShape);
657   DEBUG_BOOL_STRUCT ("sparse property", props, residencyStandard3DBlockShape);
658   DEBUG_BOOL_STRUCT ("sparse property", props, residencyAlignedMipSize);
659   DEBUG_BOOL_STRUCT ("sparse property", props, residencyNonResidentStrict);
660   /* *INDENT-ON* */
661
662   return TRUE;
663 }
664
665 #if defined (VK_API_VERSION_1_2)
666 static void
667 dump_properties11 (GstVulkanPhysicalDevice * device,
668     VkPhysicalDeviceVulkan11Properties * properties)
669 {
670   /* *INDENT-OFF* */
671 /*    uint8_t                    deviceUUID[VK_UUID_SIZE];
672     uint8_t                    driverUUID[VK_UUID_SIZE];
673     uint8_t                    deviceLUID[VK_LUID_SIZE];*/
674   DEBUG_UINT32 ("properties (1.1)", properties, deviceNodeMask);
675 /*    VkBool32                   deviceLUIDValid;*/
676   DEBUG_UINT32 ("properties (1.1)", properties, subgroupSize);
677 /*    VkShaderStageFlags         subgroupSupportedStages;
678     VkSubgroupFeatureFlags     subgroupSupportedOperations;*/
679   DEBUG_BOOL_STRUCT ("properties (1.1)", properties, subgroupQuadOperationsInAllStages);
680 /*    VkPointClippingBehavior    pointClippingBehavior;*/
681   DEBUG_UINT32 ("properties (1.1)", properties, maxMultiviewViewCount);
682   DEBUG_UINT32 ("properties (1.1)", properties, maxMultiviewInstanceIndex);
683   DEBUG_BOOL_STRUCT ("properties (1.1)", properties, protectedNoFault);
684   DEBUG_UINT32 ("properties (1.1)", properties, maxPerSetDescriptors);
685   DEBUG_SIZE ("properties (1.1)", properties, maxMemoryAllocationSize);
686   /* *INDENT-ON* */
687 }
688
689 static void
690 dump_properties12 (GstVulkanPhysicalDevice * device,
691     VkPhysicalDeviceVulkan12Properties * properties)
692 {
693   /* *INDENT-OFF* */
694 /*    VkDriverId                           driverID;*/
695   DEBUG_STRING ("properties (1.2)", properties, driverName);
696   DEBUG_STRING ("properties (1.2)", properties, driverInfo);
697 /*    VkConformanceVersion                 conformanceVersion;
698     VkShaderFloatControlsIndependence    denormBehaviorIndependence;
699     VkShaderFloatControlsIndependence    roundingModeIndependence;*/
700   DEBUG_BOOL_STRUCT ("properties (1.2)", properties, shaderSignedZeroInfNanPreserveFloat16);
701   DEBUG_BOOL_STRUCT ("properties (1.2)", properties, shaderSignedZeroInfNanPreserveFloat32);
702   DEBUG_BOOL_STRUCT ("properties (1.2)", properties, shaderSignedZeroInfNanPreserveFloat64);
703   DEBUG_BOOL_STRUCT ("properties (1.2)", properties, shaderDenormPreserveFloat16);
704   DEBUG_BOOL_STRUCT ("properties (1.2)", properties, shaderDenormPreserveFloat32);
705   DEBUG_BOOL_STRUCT ("properties (1.2)", properties, shaderDenormPreserveFloat64);
706   DEBUG_BOOL_STRUCT ("properties (1.2)", properties, shaderDenormFlushToZeroFloat16);
707   DEBUG_BOOL_STRUCT ("properties (1.2)", properties, shaderDenormFlushToZeroFloat16);
708   DEBUG_BOOL_STRUCT ("properties (1.2)", properties, shaderDenormFlushToZeroFloat32);
709   DEBUG_BOOL_STRUCT ("properties (1.2)", properties, shaderRoundingModeRTEFloat16);
710   DEBUG_BOOL_STRUCT ("properties (1.2)", properties, shaderRoundingModeRTEFloat32);
711   DEBUG_BOOL_STRUCT ("properties (1.2)", properties, shaderRoundingModeRTEFloat64);
712   DEBUG_BOOL_STRUCT ("properties (1.2)", properties, shaderRoundingModeRTZFloat16);
713   DEBUG_BOOL_STRUCT ("properties (1.2)", properties, shaderRoundingModeRTZFloat32);
714   DEBUG_BOOL_STRUCT ("properties (1.2)", properties, shaderRoundingModeRTZFloat64);
715   DEBUG_UINT32 ("properties (1.2)", properties, maxUpdateAfterBindDescriptorsInAllPools);
716   DEBUG_BOOL_STRUCT ("properties (1.2)", properties, shaderUniformBufferArrayNonUniformIndexingNative);
717   DEBUG_BOOL_STRUCT ("properties (1.2)", properties, shaderSampledImageArrayNonUniformIndexingNative);
718   DEBUG_BOOL_STRUCT ("properties (1.2)", properties, shaderSampledImageArrayNonUniformIndexingNative);
719   DEBUG_BOOL_STRUCT ("properties (1.2)", properties, shaderStorageBufferArrayNonUniformIndexingNative);
720   DEBUG_BOOL_STRUCT ("properties (1.2)", properties, shaderStorageImageArrayNonUniformIndexingNative);
721   DEBUG_BOOL_STRUCT ("properties (1.2)", properties, shaderInputAttachmentArrayNonUniformIndexingNative);
722   DEBUG_BOOL_STRUCT ("properties (1.2)", properties, robustBufferAccessUpdateAfterBind);
723   DEBUG_BOOL_STRUCT ("properties (1.2)", properties, quadDivergentImplicitLod);
724   DEBUG_UINT32 ("properties (1.2)", properties, maxPerStageDescriptorUpdateAfterBindSamplers);
725   DEBUG_UINT32 ("properties (1.2)", properties, maxPerStageDescriptorUpdateAfterBindUniformBuffers);
726   DEBUG_UINT32 ("properties (1.2)", properties, maxPerStageDescriptorUpdateAfterBindStorageBuffers);
727   DEBUG_UINT32 ("properties (1.2)", properties, maxPerStageDescriptorUpdateAfterBindSampledImages);
728   DEBUG_UINT32 ("properties (1.2)", properties, maxPerStageDescriptorUpdateAfterBindStorageImages);
729   DEBUG_UINT32 ("properties (1.2)", properties, maxPerStageDescriptorUpdateAfterBindInputAttachments);
730   DEBUG_UINT32 ("properties (1.2)", properties, maxPerStageUpdateAfterBindResources);
731   DEBUG_UINT32 ("properties (1.2)", properties, maxDescriptorSetUpdateAfterBindSamplers);
732   DEBUG_UINT32 ("properties (1.2)", properties, maxDescriptorSetUpdateAfterBindUniformBuffers);
733   DEBUG_UINT32 ("properties (1.2)", properties, maxDescriptorSetUpdateAfterBindUniformBuffersDynamic);
734   DEBUG_UINT32 ("properties (1.2)", properties, maxDescriptorSetUpdateAfterBindStorageBuffers);
735   DEBUG_UINT32 ("properties (1.2)", properties, maxDescriptorSetUpdateAfterBindStorageBuffersDynamic);
736   DEBUG_UINT32 ("properties (1.2)", properties, maxDescriptorSetUpdateAfterBindSampledImages);
737   DEBUG_UINT32 ("properties (1.2)", properties, maxDescriptorSetUpdateAfterBindStorageImages);
738   DEBUG_UINT32 ("properties (1.2)", properties, maxDescriptorSetUpdateAfterBindInputAttachments);
739 /*    VkResolveModeFlags                   supportedDepthResolveModes;
740     VkResolveModeFlags                   supportedStencilResolveModes;*/
741   DEBUG_BOOL_STRUCT ("properties (1.2)", properties, independentResolveNone);
742   DEBUG_BOOL_STRUCT ("properties (1.2)", properties, independentResolve);
743   DEBUG_BOOL_STRUCT ("properties (1.2)", properties, filterMinmaxSingleComponentFormats);
744   DEBUG_BOOL_STRUCT ("properties (1.2)", properties, filterMinmaxImageComponentMapping);
745   DEBUG_UINT64 ("properties (1.2)", properties, maxTimelineSemaphoreValueDifference);
746   DEBUG_FLAGS ("properties (1.2)", properties, framebufferIntegerColorSampleCounts, sample_count);
747   /* *INDENT-ON* */
748 }
749 #endif
750
751 static gboolean
752 physical_device_info (GstVulkanPhysicalDevice * device, GError ** error)
753 {
754 #if defined (VK_API_VERSION_1_2)
755   GstVulkanPhysicalDevicePrivate *priv = GET_PRIV (device);
756   VkBaseOutStructure *iter;
757 #endif
758
759   GST_INFO_OBJECT (device, "physical device %i name \'%s\' type \'%s\' "
760       "api version %u.%u.%u, driver version %u.%u.%u vendor ID 0x%x, "
761       "device ID 0x%x", device->device_index, device->properties.deviceName,
762       gst_vulkan_physical_device_type_to_string (device->properties.deviceType),
763       VK_VERSION_MAJOR (device->properties.apiVersion),
764       VK_VERSION_MINOR (device->properties.apiVersion),
765       VK_VERSION_PATCH (device->properties.apiVersion),
766       VK_VERSION_MAJOR (device->properties.driverVersion),
767       VK_VERSION_MINOR (device->properties.driverVersion),
768       VK_VERSION_PATCH (device->properties.driverVersion),
769       device->properties.vendorID, device->properties.deviceID);
770
771   if (!dump_queue_properties (device, error))
772     return FALSE;
773   if (!dump_memory_properties (device, error))
774     return FALSE;
775   if (!dump_features (device, error))
776     return FALSE;
777   if (!dump_limits (device, error))
778     return FALSE;
779   if (!dump_sparse_properties (device, error))
780     return FALSE;
781
782 #if defined (VK_API_VERSION_1_2)
783   if (gst_vulkan_instance_check_version (device->instance, 1, 2, 0)) {
784     for (iter = (VkBaseOutStructure *) & priv->properties10; iter;
785         iter = iter->pNext) {
786       if (iter->sType ==
787           VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES)
788         dump_properties11 (device, (VkPhysicalDeviceVulkan11Properties *) iter);
789       else if (iter->sType ==
790           VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_PROPERTIES)
791         dump_properties12 (device, (VkPhysicalDeviceVulkan12Properties *) iter);
792     }
793   }
794 #endif
795
796   return TRUE;
797 }
798
799 static gboolean
800 gst_vulkan_physical_device_fill_info (GstVulkanPhysicalDevice * device,
801     GError ** error)
802 {
803   GstVulkanPhysicalDevicePrivate *priv = GET_PRIV (device);
804   VkResult err;
805   guint i;
806
807   device->device = gst_vulkan_physical_device_get_handle (device);
808   if (!device->device) {
809     g_set_error (error, GST_VULKAN_ERROR, VK_ERROR_INITIALIZATION_FAILED,
810         "Failed to retrieve physical device");
811     goto error;
812   }
813
814   err =
815       vkEnumerateDeviceLayerProperties (device->device,
816       &priv->n_available_layers, NULL);
817   if (gst_vulkan_error_to_g_error (err, error,
818           "vkEnumerateDeviceLayerProperties") < 0)
819     goto error;
820
821   priv->available_layers = g_new0 (VkLayerProperties, priv->n_available_layers);
822   err =
823       vkEnumerateDeviceLayerProperties (device->device,
824       &priv->n_available_layers, priv->available_layers);
825   if (gst_vulkan_error_to_g_error (err, error,
826           "vkEnumerateDeviceLayerProperties") < 0) {
827     goto error;
828   }
829
830   err =
831       vkEnumerateDeviceExtensionProperties (device->device, NULL,
832       &priv->n_available_extensions, NULL);
833   if (gst_vulkan_error_to_g_error (err, error,
834           "vkEnumerateDeviceExtensionProperties") < 0) {
835     goto error;
836   }
837
838   priv->available_extensions =
839       g_new0 (VkExtensionProperties, priv->n_available_extensions);
840   err =
841       vkEnumerateDeviceExtensionProperties (device->device, NULL,
842       &priv->n_available_extensions, priv->available_extensions);
843   if (gst_vulkan_error_to_g_error (err, error,
844           "vkEnumerateDeviceExtensionProperties") < 0) {
845     goto error;
846   }
847
848   GST_INFO_OBJECT (device, "found %u layers and %u extensions",
849       priv->n_available_layers, priv->n_available_extensions);
850
851   for (i = 0; i < priv->n_available_layers; i++)
852     GST_DEBUG_OBJECT (device, "available layer %u: %s", i,
853         priv->available_layers[i].layerName);
854   for (i = 0; i < priv->n_available_extensions; i++)
855     GST_DEBUG_OBJECT (device, "available extension %u: %s", i,
856         priv->available_extensions[i].extensionName);
857
858   vkGetPhysicalDeviceProperties (device->device, &device->properties);
859 #if defined (VK_API_VERSION_1_2)
860   if (gst_vulkan_instance_check_version (device->instance, 1, 2, 0)) {
861     PFN_vkGetPhysicalDeviceProperties2 get_props2;
862     PFN_vkGetPhysicalDeviceMemoryProperties2 get_mem_props2;
863     PFN_vkGetPhysicalDeviceFeatures2 get_features2;
864     PFN_vkGetPhysicalDeviceQueueFamilyProperties2 get_queue_props2;
865     VkPhysicalDeviceMemoryProperties2 mem_properties10;
866
867     /* *INDENT-OFF* */
868     mem_properties10 = (VkPhysicalDeviceMemoryProperties2) {
869       .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2,
870       .pNext = NULL,
871     };
872     /* *INDENT-ON* */
873
874     get_props2 = (PFN_vkGetPhysicalDeviceProperties2)
875         gst_vulkan_instance_get_proc_address (device->instance,
876         "vkGetPhysicalDeviceProperties2");
877     get_props2 (device->device, &priv->properties10);
878
879     get_mem_props2 = (PFN_vkGetPhysicalDeviceMemoryProperties2)
880         gst_vulkan_instance_get_proc_address (device->instance,
881         "vkGetPhysicalDeviceMemoryProperties2");
882     get_mem_props2 (device->device, &mem_properties10);
883     memcpy (&device->memory_properties, &mem_properties10.memoryProperties,
884         sizeof (device->memory_properties));
885
886     get_features2 = (PFN_vkGetPhysicalDeviceFeatures2)
887         gst_vulkan_instance_get_proc_address (device->instance,
888         "vkGetPhysicalDeviceFeatures2");
889     get_features2 (device->device, &priv->features10);
890     memcpy (&device->features, &priv->features10.features,
891         sizeof (device->features));
892
893     get_queue_props2 = (PFN_vkGetPhysicalDeviceQueueFamilyProperties2)
894         gst_vulkan_instance_get_proc_address (device->instance,
895         "vkGetPhysicalDeviceQueueFamilyProperties2");
896     get_queue_props2 (device->device, &device->n_queue_families, NULL);
897     if (device->n_queue_families > 0) {
898       VkQueueFamilyProperties2 *props;
899       int i;
900
901       props = g_new0 (VkQueueFamilyProperties2, device->n_queue_families);
902       for (i = 0; i < device->n_queue_families; i++) {
903         props[i].sType = VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2;
904         props[i].pNext = NULL;
905       }
906
907       get_queue_props2 (device->device, &device->n_queue_families, props);
908
909       device->queue_family_props =
910           g_new0 (VkQueueFamilyProperties, device->n_queue_families);
911       for (i = 0; i < device->n_queue_families; i++) {
912         memcpy (&device->queue_family_props[i], &props[i].queueFamilyProperties,
913             sizeof (device->queue_family_props[i]));
914       }
915       g_free (props);
916     }
917   } else
918 #endif
919   {
920     vkGetPhysicalDeviceMemoryProperties (device->device,
921         &device->memory_properties);
922     vkGetPhysicalDeviceFeatures (device->device, &device->features);
923     vkGetPhysicalDeviceQueueFamilyProperties (device->device,
924         &device->n_queue_families, NULL);
925     if (device->n_queue_families > 0) {
926       device->queue_family_props =
927           g_new0 (VkQueueFamilyProperties, device->n_queue_families);
928       vkGetPhysicalDeviceQueueFamilyProperties (device->device,
929           &device->n_queue_families, device->queue_family_props);
930     }
931   }
932
933   if (!physical_device_info (device, error))
934     goto error;
935
936   return TRUE;
937
938 error:
939   return FALSE;
940 }
941
942 /**
943  * gst_vulkan_physical_device_get_handle: (skip)
944  * @device: a #GstVulkanPhysicalDevice
945  *
946  * Returns: The associated `VkPhysicalDevice` handle
947  *
948  * Since: 1.18
949  */
950 VkPhysicalDevice
951 gst_vulkan_physical_device_get_handle (GstVulkanPhysicalDevice * device)
952 {
953   g_return_val_if_fail (GST_IS_VULKAN_PHYSICAL_DEVICE (device), NULL);
954
955   return device->device;
956 }
957
958 /**
959  * gst_vulkan_physical_device_get_instance:
960  * @device: a #GstVulkanPhysicalDevice
961  *
962  * Returns: (transfer full): The #GstVulkanInstance associated with this physical device
963  *
964  * Since: 1.18
965  */
966 GstVulkanInstance *
967 gst_vulkan_physical_device_get_instance (GstVulkanPhysicalDevice * device)
968 {
969   g_return_val_if_fail (GST_IS_VULKAN_PHYSICAL_DEVICE (device), NULL);
970
971   return device->instance ? gst_object_ref (device->instance) : NULL;
972 }
973
974 static gboolean
975 gst_vulkan_physical_device_get_layer_info_unlocked (GstVulkanPhysicalDevice *
976     device, const gchar * name, gchar ** description, guint32 * spec_version,
977     guint32 * implementation_version)
978 {
979   GstVulkanPhysicalDevicePrivate *priv;
980   int i;
981
982   priv = GET_PRIV (device);
983
984   for (i = 0; i < priv->n_available_layers; i++) {
985     if (g_strcmp0 (name, priv->available_layers[i].layerName) == 0) {
986       if (description)
987         *description = g_strdup (priv->available_layers[i].description);
988       if (spec_version)
989         *spec_version = priv->available_layers[i].specVersion;
990       if (implementation_version)
991         *spec_version = priv->available_layers[i].implementationVersion;
992       return TRUE;
993     }
994   }
995
996   return FALSE;
997 }
998
999 /**
1000  * gst_vulkan_physical_device_get_layer_info:
1001  * @device: a #GstVulkanPhysicalDevice
1002  * @name: the layer name to look for
1003  * @description: (out) (nullable): return value for the layer description or %NULL
1004  * @spec_version: (out) (nullable): return value for the layer specification version
1005  * @implementation_version: (out) (nullable): return value for the layer implementation version
1006  *
1007  * Retrieves information about a layer.
1008  *
1009  * Will not find any layers before gst_vulkan_instance_fill_info() has been
1010  * called.
1011  *
1012  * Returns: whether layer @name is available
1013  *
1014  * Since: 1.18
1015  */
1016 gboolean
1017 gst_vulkan_physical_device_get_layer_info (GstVulkanPhysicalDevice * device,
1018     const gchar * name, gchar ** description, guint32 * spec_version,
1019     guint32 * implementation_version)
1020 {
1021   gboolean ret;
1022
1023   g_return_val_if_fail (GST_IS_VULKAN_PHYSICAL_DEVICE (device), FALSE);
1024   g_return_val_if_fail (name != NULL, FALSE);
1025
1026   GST_OBJECT_LOCK (device);
1027   ret =
1028       gst_vulkan_physical_device_get_layer_info_unlocked (device, name,
1029       description, spec_version, implementation_version);
1030   GST_OBJECT_UNLOCK (device);
1031
1032   return ret;
1033 }
1034
1035 static gboolean
1036 gst_vulkan_physical_device_get_extension_info_unlocked (GstVulkanPhysicalDevice
1037     * device, const gchar * name, guint32 * spec_version)
1038 {
1039   GstVulkanPhysicalDevicePrivate *priv;
1040   int i;
1041
1042   priv = GET_PRIV (device);
1043
1044   for (i = 0; i < priv->n_available_extensions; i++) {
1045     if (g_strcmp0 (name, priv->available_extensions[i].extensionName) == 0) {
1046       if (spec_version)
1047         *spec_version = priv->available_extensions[i].specVersion;
1048       return TRUE;
1049     }
1050   }
1051
1052   return FALSE;
1053 }
1054
1055 /**
1056  * gst_vulkan_physical_device_get_extension_info:
1057  * @device: a #GstVulkanPhysicalDevice
1058  * @name: the extension name to look for
1059  * @spec_version: (out) (nullable): return value for the exteion specification version
1060  *
1061  * Retrieves information about a device extension.
1062  *
1063  * Will not find any extensions before gst_vulkan_instance_fill_info() has been
1064  * called.
1065  *
1066  * Returns: whether extension @name is available
1067  *
1068  * Since: 1.18
1069  */
1070 gboolean
1071 gst_vulkan_physical_device_get_extension_info (GstVulkanPhysicalDevice * device,
1072     const gchar * name, guint32 * spec_version)
1073 {
1074   gboolean ret;
1075
1076   g_return_val_if_fail (GST_IS_VULKAN_PHYSICAL_DEVICE (device), FALSE);
1077   g_return_val_if_fail (name != NULL, FALSE);
1078
1079   GST_OBJECT_LOCK (device);
1080   ret =
1081       gst_vulkan_physical_device_get_extension_info_unlocked (device, name,
1082       spec_version);
1083   GST_OBJECT_UNLOCK (device);
1084
1085   return ret;
1086 }