01f0978e4c02cd07ce1bd5127832fd3f6ce84a54
[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   guint dummy;
56 };
57
58 static void
59 _init_debug (void)
60 {
61   static volatile gsize init;
62
63   if (g_once_init_enter (&init)) {
64     GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, "vulkandevice", 0,
65         "Vulkan Device");
66     g_once_init_leave (&init, 1);
67   }
68 }
69
70 #define GET_PRIV(device) gst_vulkan_physical_device_get_instance_private (device)
71
72 #define gst_vulkan_physical_device_parent_class parent_class
73 G_DEFINE_TYPE_WITH_CODE (GstVulkanPhysicalDevice, gst_vulkan_physical_device,
74     GST_TYPE_OBJECT, G_ADD_PRIVATE (GstVulkanPhysicalDevice);
75     _init_debug ());
76
77 static gboolean gst_vulkan_physical_device_fill_info (GstVulkanPhysicalDevice *
78     device, GError ** error);
79
80 /**
81  * gst_vulkan_physical_device_new:
82  * @instance: the parent #GstVulkanInstance
83  *
84  * Returns: (transfer full): a new #GstVulkanPhysicalDevice
85  *
86  * Since: 1.18
87  */
88 GstVulkanPhysicalDevice *
89 gst_vulkan_physical_device_new (GstVulkanInstance * instance,
90     guint device_index)
91 {
92   GstVulkanPhysicalDevice *device;
93
94   g_return_val_if_fail (GST_IS_VULKAN_INSTANCE (instance), NULL);
95
96   device = g_object_new (GST_TYPE_VULKAN_PHYSICAL_DEVICE, "instance", instance,
97       "device-index", device_index, NULL);
98   gst_object_ref_sink (device);
99
100   return device;
101 }
102
103 static void
104 gst_vulkan_physical_device_set_property (GObject * object, guint prop_id,
105     const GValue * value, GParamSpec * pspec)
106 {
107   GstVulkanPhysicalDevice *device = GST_VULKAN_PHYSICAL_DEVICE (object);
108
109   switch (prop_id) {
110     case PROP_INSTANCE:
111       device->instance = g_value_dup_object (value);
112       break;
113     case PROP_DEVICE_ID:{
114       guint device_id = g_value_get_uint (value);
115       if (device_id >= device->instance->n_physical_devices) {
116         g_critical ("%s: Cannot set device-index larger than the "
117             "number of physical devices", GST_OBJECT_NAME (device));
118       } else {
119         device->device_index = device_id;
120       }
121       break;
122     }
123     default:
124       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
125       break;
126   }
127 }
128
129 static void
130 gst_vulkan_physical_device_get_property (GObject * object, guint prop_id,
131     GValue * value, GParamSpec * pspec)
132 {
133   GstVulkanPhysicalDevice *device = GST_VULKAN_PHYSICAL_DEVICE (object);
134
135   switch (prop_id) {
136     case PROP_INSTANCE:
137       g_value_set_object (value, device->instance);
138       break;
139     case PROP_DEVICE_ID:
140       g_value_set_uint (value, device->device_index);
141       break;
142     case PROP_NAME:
143       g_value_set_string (value, device->properties.deviceName);
144       break;
145     default:
146       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
147       break;
148   }
149 }
150
151 static void
152 gst_vulkan_physical_device_init (GstVulkanPhysicalDevice * device)
153 {
154 }
155
156 static void
157 gst_vulkan_physical_device_constructed (GObject * object)
158 {
159   GstVulkanPhysicalDevice *device = GST_VULKAN_PHYSICAL_DEVICE (object);
160   GError *error = NULL;
161
162   device->device = device->instance->physical_devices[device->device_index];
163
164   if (!gst_vulkan_physical_device_fill_info (device, &error)) {
165     GST_ERROR_OBJECT (object, "%s", error->message);
166     g_clear_error (&error);
167   }
168 }
169
170 static void
171 gst_vulkan_physical_device_class_init (GstVulkanPhysicalDeviceClass *
172     device_class)
173 {
174   GObjectClass *gobject_class = (GObjectClass *) device_class;
175
176   gobject_class->set_property = gst_vulkan_physical_device_set_property;
177   gobject_class->get_property = gst_vulkan_physical_device_get_property;
178   gobject_class->finalize = gst_vulkan_physical_device_finalize;
179   gobject_class->constructed = gst_vulkan_physical_device_constructed;
180
181   g_object_class_install_property (gobject_class, PROP_INSTANCE,
182       g_param_spec_object ("instance", "Instance",
183           "Associated Vulkan Instance",
184           GST_TYPE_VULKAN_INSTANCE,
185           G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
186
187   g_object_class_install_property (gobject_class, PROP_DEVICE_ID,
188       g_param_spec_uint ("device-index", "Device Index", "Device Index", 0,
189           G_MAXUINT32, 0,
190           G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
191
192   g_object_class_install_property (gobject_class, PROP_NAME,
193       g_param_spec_string ("name", "Name", "Device Name", NULL,
194           G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
195 }
196
197 static void
198 gst_vulkan_physical_device_finalize (GObject * object)
199 {
200   GstVulkanPhysicalDevice *device = GST_VULKAN_PHYSICAL_DEVICE (object);
201
202   g_free (device->device_layers);
203   device->device_layers = NULL;
204
205   g_free (device->device_extensions);
206   device->device_extensions = NULL;
207
208   g_free (device->queue_family_props);
209   device->queue_family_props = NULL;
210
211   if (device->instance)
212     gst_object_unref (device->instance);
213   device->instance = VK_NULL_HANDLE;
214
215   G_OBJECT_CLASS (parent_class)->finalize (object);
216 }
217
218 #define DEBUG_BOOL(prefix, name, value)                             \
219   GST_DEBUG_OBJECT (device, prefix " " G_STRINGIFY(name) ": %s",    \
220     value ? "YES" : "NO")
221
222 static gboolean
223 dump_features (GstVulkanPhysicalDevice * device, GError ** error)
224 {
225 #define DEBUG_BOOL_FEATURE(name) DEBUG_BOOL("support for", name, device->features.name)
226   DEBUG_BOOL_FEATURE (robustBufferAccess);
227   DEBUG_BOOL_FEATURE (fullDrawIndexUint32);
228   DEBUG_BOOL_FEATURE (imageCubeArray);
229   DEBUG_BOOL_FEATURE (independentBlend);
230   DEBUG_BOOL_FEATURE (geometryShader);
231   DEBUG_BOOL_FEATURE (tessellationShader);
232   DEBUG_BOOL_FEATURE (sampleRateShading);
233   DEBUG_BOOL_FEATURE (sampleRateShading);
234   DEBUG_BOOL_FEATURE (dualSrcBlend);
235   DEBUG_BOOL_FEATURE (logicOp);
236   DEBUG_BOOL_FEATURE (multiDrawIndirect);
237   DEBUG_BOOL_FEATURE (drawIndirectFirstInstance);
238   DEBUG_BOOL_FEATURE (depthClamp);
239   DEBUG_BOOL_FEATURE (depthBiasClamp);
240   DEBUG_BOOL_FEATURE (fillModeNonSolid);
241   DEBUG_BOOL_FEATURE (depthBounds);
242   DEBUG_BOOL_FEATURE (wideLines);
243   DEBUG_BOOL_FEATURE (largePoints);
244   DEBUG_BOOL_FEATURE (alphaToOne);
245   DEBUG_BOOL_FEATURE (multiViewport);
246   DEBUG_BOOL_FEATURE (samplerAnisotropy);
247   DEBUG_BOOL_FEATURE (textureCompressionETC2);
248   DEBUG_BOOL_FEATURE (textureCompressionASTC_LDR);
249   DEBUG_BOOL_FEATURE (textureCompressionBC);
250   DEBUG_BOOL_FEATURE (occlusionQueryPrecise);
251   DEBUG_BOOL_FEATURE (pipelineStatisticsQuery);
252   DEBUG_BOOL_FEATURE (vertexPipelineStoresAndAtomics);
253   DEBUG_BOOL_FEATURE (fragmentStoresAndAtomics);
254   DEBUG_BOOL_FEATURE (shaderTessellationAndGeometryPointSize);
255   DEBUG_BOOL_FEATURE (shaderImageGatherExtended);
256   DEBUG_BOOL_FEATURE (shaderStorageImageExtendedFormats);
257   DEBUG_BOOL_FEATURE (shaderStorageImageMultisample);
258   DEBUG_BOOL_FEATURE (shaderStorageImageReadWithoutFormat);
259   DEBUG_BOOL_FEATURE (shaderStorageImageWriteWithoutFormat);
260   DEBUG_BOOL_FEATURE (shaderUniformBufferArrayDynamicIndexing);
261   DEBUG_BOOL_FEATURE (shaderSampledImageArrayDynamicIndexing);
262   DEBUG_BOOL_FEATURE (shaderStorageBufferArrayDynamicIndexing);
263   DEBUG_BOOL_FEATURE (shaderStorageImageArrayDynamicIndexing);
264   DEBUG_BOOL_FEATURE (shaderClipDistance);
265   DEBUG_BOOL_FEATURE (shaderCullDistance);
266   DEBUG_BOOL_FEATURE (shaderFloat64);
267   DEBUG_BOOL_FEATURE (shaderInt64);
268   DEBUG_BOOL_FEATURE (shaderInt16);
269   DEBUG_BOOL_FEATURE (shaderResourceResidency);
270   DEBUG_BOOL_FEATURE (shaderResourceMinLod);
271   DEBUG_BOOL_FEATURE (sparseBinding);
272   DEBUG_BOOL_FEATURE (sparseResidencyBuffer);
273   DEBUG_BOOL_FEATURE (sparseResidencyImage2D);
274   DEBUG_BOOL_FEATURE (sparseResidencyImage3D);
275   DEBUG_BOOL_FEATURE (sparseResidency2Samples);
276   DEBUG_BOOL_FEATURE (sparseResidency4Samples);
277   DEBUG_BOOL_FEATURE (sparseResidency8Samples);
278   DEBUG_BOOL_FEATURE (sparseResidency16Samples);
279   DEBUG_BOOL_FEATURE (sparseResidencyAliased);
280   DEBUG_BOOL_FEATURE (variableMultisampleRate);
281   DEBUG_BOOL_FEATURE (inheritedQueries);
282
283 #undef DEBUG_BOOL_FEATURE
284
285   return TRUE;
286 }
287
288 static gboolean
289 dump_memory_properties (GstVulkanPhysicalDevice * device, GError ** error)
290 {
291   int i;
292
293   GST_DEBUG_OBJECT (device, "found %" G_GUINT32_FORMAT " memory heaps",
294       device->memory_properties.memoryHeapCount);
295   for (i = 0; i < device->memory_properties.memoryHeapCount; i++) {
296     gchar *prop_flags_str =
297         gst_vulkan_memory_heap_flags_to_string (device->
298         memory_properties.memoryHeaps[i].flags);
299     GST_LOG_OBJECT (device,
300         "memory heap at index %i has size %" G_GUINT64_FORMAT
301         " and flags (0x%x) \'%s\'", i,
302         (guint64) device->memory_properties.memoryHeaps[i].size,
303         device->memory_properties.memoryHeaps[i].flags, prop_flags_str);
304     g_free (prop_flags_str);
305   }
306   GST_DEBUG_OBJECT (device, "found %" G_GUINT32_FORMAT " memory types",
307       device->memory_properties.memoryTypeCount);
308   for (i = 0; i < device->memory_properties.memoryTypeCount; i++) {
309     gchar *prop_flags_str =
310         gst_vulkan_memory_property_flags_to_string (device->memory_properties.
311         memoryTypes[i].propertyFlags);
312     GST_LOG_OBJECT (device,
313         "memory type at index %i is allocatable from "
314         "heap %i with flags (0x%x) \'%s\'", i,
315         device->memory_properties.memoryTypes[i].heapIndex,
316         device->memory_properties.memoryTypes[i].propertyFlags, prop_flags_str);
317     g_free (prop_flags_str);
318   }
319
320   return TRUE;
321 }
322
323 static gboolean
324 dump_queue_properties (GstVulkanPhysicalDevice * device, GError ** error)
325 {
326   int i;
327
328   GST_DEBUG_OBJECT (device, "found %" G_GUINT32_FORMAT " queue families",
329       device->n_queue_families);
330   for (i = 0; i < device->n_queue_families; i++) {
331     gchar *queue_flags_str =
332         gst_vulkan_queue_flags_to_string (device->
333         queue_family_props[i].queueFlags);
334     GST_LOG_OBJECT (device,
335         "queue family at index %i supports %i queues "
336         "with flags (0x%x) \'%s\', %" G_GUINT32_FORMAT " timestamp bits and "
337         "a minimum image transfer granuality of %" GST_VULKAN_EXTENT3D_FORMAT,
338         i, device->queue_family_props[i].queueCount,
339         device->queue_family_props[i].queueFlags, queue_flags_str,
340         device->queue_family_props[i].timestampValidBits,
341         GST_VULKAN_EXTENT3D_ARGS (device->
342             queue_family_props[i].minImageTransferGranularity));
343     g_free (queue_flags_str);
344   }
345
346   return TRUE;
347 }
348
349 static gboolean
350 dump_limits (GstVulkanPhysicalDevice * device, GError ** error)
351 {
352 #define DEBUG_LIMIT(limit, format, type)                                \
353   GST_DEBUG_OBJECT (device, "limit " G_STRINGIFY(limit) ": %" format,   \
354     (type) device->properties.limits.limit)
355 #define DEBUG_LIMIT_2(limit, format, type)                                  \
356   GST_DEBUG_OBJECT (device, "limit " G_STRINGIFY(limit)                     \
357     ": %" format ", %" format,                                              \
358     (type) device->properties.limits.limit[0],                                           \
359     (type) device->properties.limits.limit[1])
360 #define DEBUG_LIMIT_3(limit, format, type)                                  \
361   GST_DEBUG_OBJECT (device, "limit " G_STRINGIFY(limit)                     \
362     ": %" format ", %" format ", %" format,                                 \
363     (type) device->properties.limits.limit[0],                                           \
364     (type) device->properties.limits.limit[1],                                           \
365     (type) device->properties.limits.limit[2])
366 #define DEBUG_BOOL_LIMIT(limit) DEBUG_BOOL("limit", limit, device->properties.limits.limit)
367
368 #define DEBUG_UINT32_LIMIT(limit) DEBUG_LIMIT(limit, G_GUINT32_FORMAT, guint32)
369 #define DEBUG_UINT32_2_LIMIT(limit) DEBUG_LIMIT_2(limit, G_GUINT32_FORMAT, guint32)
370 #define DEBUG_UINT32_3_LIMIT(limit) DEBUG_LIMIT_3(limit, G_GUINT32_FORMAT, guint32)
371
372 #define DEBUG_INT32_LIMIT(limit) DEBUG_LIMIT(limit, G_GINT32_FORMAT, gint32)
373
374 #define DEBUG_UINT64_LIMIT(limit) DEBUG_LIMIT(limit, G_GUINT64_FORMAT, guint64)
375
376 #define DEBUG_SIZE_LIMIT(limit) DEBUG_LIMIT(limit, G_GSIZE_FORMAT, gsize)
377
378 #define DEBUG_FLOAT_LIMIT(limit) DEBUG_LIMIT(limit, "f", float)
379 #define DEBUG_FLOAT_2_LIMIT(limit) DEBUG_LIMIT_2(limit, "f", float)
380
381 #define DEBUG_FLAGS_LIMIT(limit, under_name_type)                           \
382   G_STMT_START {                                                            \
383     gchar *str = G_PASTE(G_PASTE(gst_vulkan_,under_name_type),_flags_to_string) (device->properties.limits.limit); \
384     GST_DEBUG_OBJECT (device, "limit " G_STRINGIFY(limit) ": (0x%x) %s",    \
385         device->properties.limits.limit, str);                              \
386     g_free (str);                                                           \
387   } G_STMT_END
388
389   DEBUG_UINT32_LIMIT (maxImageDimension1D);
390   DEBUG_UINT32_LIMIT (maxImageDimension2D);
391   DEBUG_UINT32_LIMIT (maxImageDimension3D);
392   DEBUG_UINT32_LIMIT (maxImageDimensionCube);
393   DEBUG_UINT32_LIMIT (maxImageArrayLayers);
394   DEBUG_UINT32_LIMIT (maxTexelBufferElements);
395   DEBUG_UINT32_LIMIT (maxUniformBufferRange);
396   DEBUG_UINT32_LIMIT (maxStorageBufferRange);
397   DEBUG_UINT32_LIMIT (maxPushConstantsSize);
398   DEBUG_UINT32_LIMIT (maxMemoryAllocationCount);
399   DEBUG_UINT32_LIMIT (maxSamplerAllocationCount);
400   DEBUG_UINT64_LIMIT (bufferImageGranularity);
401   DEBUG_UINT64_LIMIT (sparseAddressSpaceSize);
402   DEBUG_UINT32_LIMIT (maxBoundDescriptorSets);
403   DEBUG_UINT32_LIMIT (maxPerStageDescriptorSamplers);
404   DEBUG_UINT32_LIMIT (maxPerStageDescriptorUniformBuffers);
405   DEBUG_UINT32_LIMIT (maxPerStageDescriptorStorageBuffers);
406   DEBUG_UINT32_LIMIT (maxPerStageDescriptorSampledImages);
407   DEBUG_UINT32_LIMIT (maxPerStageDescriptorStorageImages);
408   DEBUG_UINT32_LIMIT (maxPerStageDescriptorInputAttachments);
409   DEBUG_UINT32_LIMIT (maxPerStageResources);
410   DEBUG_UINT32_LIMIT (maxDescriptorSetSamplers);
411   DEBUG_UINT32_LIMIT (maxDescriptorSetUniformBuffers);
412   DEBUG_UINT32_LIMIT (maxDescriptorSetUniformBuffersDynamic);
413   DEBUG_UINT32_LIMIT (maxDescriptorSetStorageBuffers);
414   DEBUG_UINT32_LIMIT (maxDescriptorSetStorageBuffersDynamic);
415   DEBUG_UINT32_LIMIT (maxDescriptorSetSampledImages);
416   DEBUG_UINT32_LIMIT (maxDescriptorSetStorageImages);
417   DEBUG_UINT32_LIMIT (maxDescriptorSetInputAttachments);
418   DEBUG_UINT32_LIMIT (maxVertexInputAttributes);
419   DEBUG_UINT32_LIMIT (maxVertexInputBindings);
420   DEBUG_UINT32_LIMIT (maxVertexInputBindings);
421   DEBUG_UINT32_LIMIT (maxVertexInputAttributeOffset);
422   DEBUG_UINT32_LIMIT (maxVertexInputBindingStride);
423   DEBUG_UINT32_LIMIT (maxVertexOutputComponents);
424   DEBUG_UINT32_LIMIT (maxTessellationGenerationLevel);
425   DEBUG_UINT32_LIMIT (maxTessellationPatchSize);
426   DEBUG_UINT32_LIMIT (maxTessellationControlPerVertexInputComponents);
427   DEBUG_UINT32_LIMIT (maxTessellationControlPerVertexOutputComponents);
428   DEBUG_UINT32_LIMIT (maxTessellationControlPerPatchOutputComponents);
429   DEBUG_UINT32_LIMIT (maxTessellationControlTotalOutputComponents);
430   DEBUG_UINT32_LIMIT (maxTessellationControlTotalOutputComponents);
431   DEBUG_UINT32_LIMIT (maxTessellationEvaluationInputComponents);
432   DEBUG_UINT32_LIMIT (maxTessellationEvaluationOutputComponents);
433   DEBUG_UINT32_LIMIT (maxGeometryShaderInvocations);
434   DEBUG_UINT32_LIMIT (maxGeometryInputComponents);
435   DEBUG_UINT32_LIMIT (maxGeometryOutputComponents);
436   DEBUG_UINT32_LIMIT (maxGeometryOutputVertices);
437   DEBUG_UINT32_LIMIT (maxGeometryTotalOutputComponents);
438   DEBUG_UINT32_LIMIT (maxFragmentInputComponents);
439   DEBUG_UINT32_LIMIT (maxFragmentOutputAttachments);
440   DEBUG_UINT32_LIMIT (maxFragmentDualSrcAttachments);
441   DEBUG_UINT32_LIMIT (maxFragmentCombinedOutputResources);
442   DEBUG_UINT32_LIMIT (maxComputeSharedMemorySize);
443   DEBUG_UINT32_3_LIMIT (maxComputeWorkGroupCount);
444   DEBUG_UINT32_LIMIT (maxComputeWorkGroupInvocations);
445   DEBUG_UINT32_3_LIMIT (maxComputeWorkGroupSize);
446   DEBUG_UINT32_LIMIT (subPixelPrecisionBits);
447   DEBUG_UINT32_LIMIT (subTexelPrecisionBits);
448   DEBUG_UINT32_LIMIT (mipmapPrecisionBits);
449   DEBUG_UINT32_LIMIT (maxDrawIndexedIndexValue);
450   DEBUG_UINT32_LIMIT (maxDrawIndirectCount);
451   DEBUG_FLOAT_LIMIT (maxSamplerLodBias);
452   DEBUG_FLOAT_LIMIT (maxSamplerAnisotropy);
453   DEBUG_UINT32_LIMIT (maxViewports);
454   DEBUG_UINT32_2_LIMIT (maxViewportDimensions);
455   DEBUG_FLOAT_2_LIMIT (viewportBoundsRange);
456   DEBUG_UINT32_LIMIT (viewportSubPixelBits);
457   DEBUG_SIZE_LIMIT (minMemoryMapAlignment);
458   DEBUG_UINT64_LIMIT (minTexelBufferOffsetAlignment);
459   DEBUG_UINT64_LIMIT (minUniformBufferOffsetAlignment);
460   DEBUG_UINT64_LIMIT (minStorageBufferOffsetAlignment);
461   DEBUG_INT32_LIMIT (minTexelOffset);
462   DEBUG_UINT32_LIMIT (maxTexelOffset);
463   DEBUG_INT32_LIMIT (minTexelGatherOffset);
464   DEBUG_UINT32_LIMIT (maxTexelGatherOffset);
465   DEBUG_FLOAT_LIMIT (minInterpolationOffset);
466   DEBUG_FLOAT_LIMIT (maxInterpolationOffset);
467   DEBUG_UINT32_LIMIT (subPixelInterpolationOffsetBits);
468   DEBUG_UINT32_LIMIT (maxFramebufferWidth);
469   DEBUG_UINT32_LIMIT (maxFramebufferHeight);
470   DEBUG_UINT32_LIMIT (maxFramebufferLayers);
471   DEBUG_FLAGS_LIMIT (framebufferColorSampleCounts, sample_count);
472   DEBUG_FLAGS_LIMIT (framebufferDepthSampleCounts, sample_count);
473   DEBUG_FLAGS_LIMIT (framebufferStencilSampleCounts, sample_count);
474   DEBUG_FLAGS_LIMIT (framebufferNoAttachmentsSampleCounts, sample_count);
475   DEBUG_UINT32_LIMIT (maxColorAttachments);
476   DEBUG_FLAGS_LIMIT (sampledImageColorSampleCounts, sample_count);
477   DEBUG_FLAGS_LIMIT (sampledImageIntegerSampleCounts, sample_count);
478   DEBUG_FLAGS_LIMIT (sampledImageDepthSampleCounts, sample_count);
479   DEBUG_FLAGS_LIMIT (sampledImageStencilSampleCounts, sample_count);
480   DEBUG_FLAGS_LIMIT (storageImageSampleCounts, sample_count);
481   DEBUG_BOOL_LIMIT (timestampComputeAndGraphics);
482   DEBUG_FLOAT_LIMIT (timestampPeriod);
483   DEBUG_UINT32_LIMIT (maxClipDistances);
484   DEBUG_UINT32_LIMIT (maxCullDistances);
485   DEBUG_UINT32_LIMIT (maxCombinedClipAndCullDistances);
486   DEBUG_UINT32_LIMIT (discreteQueuePriorities);
487   DEBUG_FLOAT_2_LIMIT (pointSizeRange);
488   DEBUG_FLOAT_2_LIMIT (lineWidthRange);
489   DEBUG_FLOAT_LIMIT (pointSizeGranularity);
490   DEBUG_FLOAT_LIMIT (lineWidthGranularity);
491   DEBUG_BOOL_LIMIT (strictLines);
492   DEBUG_BOOL_LIMIT (standardSampleLocations);
493   DEBUG_UINT64_LIMIT (optimalBufferCopyOffsetAlignment);
494   DEBUG_UINT64_LIMIT (optimalBufferCopyRowPitchAlignment);
495   DEBUG_UINT64_LIMIT (nonCoherentAtomSize);
496
497 #undef DEBUG_LIMIT
498 #undef DEBUG_LIMIT_2
499 #undef DEBUG_LIMIT_3
500 #undef DEBUG_BOOL_LIMIT
501 #undef DEBUG_UINT32_LIMIT
502 #undef DEBUG_UINT32_2_LIMIT
503 #undef DEBUG_UINT32_3_LIMIT
504 #undef DEBUG_INT32_LIMIT
505 #undef DEBUG_UINT64_LIMIT
506 #undef DEBUG_SIZE_LIMIT
507 #undef DEBUG_FLOAT_LIMIT
508 #undef DEBUG_FLOAT_2_LIMIT
509 #undef DEBUG_FLAGS_LIMIT
510
511   return TRUE;
512 }
513
514 static gboolean
515 dump_sparse_properties (GstVulkanPhysicalDevice * device, GError ** error)
516 {
517 #define DEBUG_BOOL_SPARSE_PROPERTY(name) DEBUG_BOOL("sparse property", name, device->properties.sparseProperties.name)
518   DEBUG_BOOL_SPARSE_PROPERTY (residencyStandard2DBlockShape);
519   DEBUG_BOOL_SPARSE_PROPERTY (residencyStandard2DMultisampleBlockShape);
520   DEBUG_BOOL_SPARSE_PROPERTY (residencyStandard3DBlockShape);
521   DEBUG_BOOL_SPARSE_PROPERTY (residencyAlignedMipSize);
522   DEBUG_BOOL_SPARSE_PROPERTY (residencyNonResidentStrict);
523 #undef DEBUG_BOOL_SPARSE_PROPERTY
524
525   return TRUE;
526 }
527
528 static gboolean
529 physical_device_info (GstVulkanPhysicalDevice * device, GError ** error)
530 {
531   GST_INFO_OBJECT (device, "physical device %i name \'%s\' type \'%s\' "
532       "api version %u.%u.%u, driver version %u.%u.%u vendor ID 0x%x, "
533       "device ID 0x%x", device->device_index, device->properties.deviceName,
534       gst_vulkan_physical_device_type_to_string (device->properties.deviceType),
535       VK_VERSION_MAJOR (device->properties.apiVersion),
536       VK_VERSION_MINOR (device->properties.apiVersion),
537       VK_VERSION_PATCH (device->properties.apiVersion),
538       VK_VERSION_MAJOR (device->properties.driverVersion),
539       VK_VERSION_MINOR (device->properties.driverVersion),
540       VK_VERSION_PATCH (device->properties.driverVersion),
541       device->properties.vendorID, device->properties.deviceID);
542
543   if (!dump_queue_properties (device, error))
544     return FALSE;
545   if (!dump_memory_properties (device, error))
546     return FALSE;
547   if (!dump_features (device, error))
548     return FALSE;
549   if (!dump_limits (device, error))
550     return FALSE;
551   if (!dump_sparse_properties (device, error))
552     return FALSE;
553
554   return TRUE;
555 }
556
557 static gboolean
558 gst_vulkan_physical_device_fill_info (GstVulkanPhysicalDevice * device,
559     GError ** error)
560 {
561   VkResult err;
562
563   device->device = gst_vulkan_physical_device_get_handle (device);
564   if (!device->device) {
565     g_set_error (error, GST_VULKAN_ERROR, VK_ERROR_INITIALIZATION_FAILED,
566         "Failed to retrieve physical device");
567     goto error;
568   }
569
570   err =
571       vkEnumerateDeviceLayerProperties (device->device,
572       &device->n_device_layers, NULL);
573   if (gst_vulkan_error_to_g_error (err, error,
574           "vkEnumerateDeviceLayerProperties") < 0)
575     goto error;
576
577   device->device_layers = g_new0 (VkLayerProperties, device->n_device_layers);
578   err =
579       vkEnumerateDeviceLayerProperties (device->device,
580       &device->n_device_layers, device->device_layers);
581   if (gst_vulkan_error_to_g_error (err, error,
582           "vkEnumerateDeviceLayerProperties") < 0) {
583     goto error;
584   }
585
586   err =
587       vkEnumerateDeviceExtensionProperties (device->device, NULL,
588       &device->n_device_extensions, NULL);
589   if (gst_vulkan_error_to_g_error (err, error,
590           "vkEnumerateDeviceExtensionProperties") < 0) {
591     goto error;
592   }
593   GST_DEBUG_OBJECT (device, "Found %u extensions", device->n_device_extensions);
594
595   device->device_extensions =
596       g_new0 (VkExtensionProperties, device->n_device_extensions);
597   err =
598       vkEnumerateDeviceExtensionProperties (device->device, NULL,
599       &device->n_device_extensions, device->device_extensions);
600   if (gst_vulkan_error_to_g_error (err, error,
601           "vkEnumerateDeviceExtensionProperties") < 0) {
602     goto error;
603   }
604
605   vkGetPhysicalDeviceProperties (device->device, &device->properties);
606   vkGetPhysicalDeviceMemoryProperties (device->device,
607       &device->memory_properties);
608   vkGetPhysicalDeviceFeatures (device->device, &device->features);
609   vkGetPhysicalDeviceQueueFamilyProperties (device->device,
610       &device->n_queue_families, NULL);
611   if (device->n_queue_families > 0) {
612     device->queue_family_props =
613         g_new0 (VkQueueFamilyProperties, device->n_queue_families);
614     vkGetPhysicalDeviceQueueFamilyProperties (device->device,
615         &device->n_queue_families, device->queue_family_props);
616   }
617
618   if (!physical_device_info (device, error))
619     goto error;
620
621   return TRUE;
622
623 error:
624   return FALSE;
625 }
626
627 /**
628  * gst_vulkan_physical_device_get_physical_device: (skip)
629  * @device: a #GstVulkanPhysicalDevice
630  *
631  * Returns: The associated `VkPhysicalDevice` handle
632  *
633  * Since: 1.18
634  */
635 VkPhysicalDevice
636 gst_vulkan_physical_device_get_handle (GstVulkanPhysicalDevice * device)
637 {
638   g_return_val_if_fail (GST_IS_VULKAN_PHYSICAL_DEVICE (device), NULL);
639
640   return device->device;
641 }