• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (c) 2015-2016 The Khronos Group Inc.
4 // Copyright (c) 2015-2016 Valve Corporation
5 // Copyright (c) 2015-2016 LunarG, Inc.
6 // Copyright (c) 2015-2016 Google, Inc.
7 //
8 // Permission is hereby granted, free of charge, to any person obtaining a copy
9 // of this software and/or associated documentation files (the "Materials"), to
10 // deal in the Materials without restriction, including without limitation the
11 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
12 // sell copies of the Materials, and to permit persons to whom the Materials are
13 // furnished to do so, subject to the following conditions:
14 //
15 // The above copyright notice(s) and this permission notice shall be included in
16 // all copies or substantial portions of the Materials.
17 //
18 // THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21 //
22 // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
23 // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
24 // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE
25 // USE OR OTHER DEALINGS IN THE MATERIALS.
26 ///////////////////////////////////////////////////////////////////////////////
27 
28 #define VK_PROTOTYPES
29 #include "vkjson.h"
30 
31 #include <utility>
32 
33 namespace {
EnumerateExtensions(const char * layer_name,std::vector<VkExtensionProperties> * extensions)34 bool EnumerateExtensions(const char* layer_name,
35                          std::vector<VkExtensionProperties>* extensions) {
36   VkResult result;
37   uint32_t count = 0;
38   result = vkEnumerateInstanceExtensionProperties(layer_name, &count, nullptr);
39   if (result != VK_SUCCESS)
40     return false;
41   extensions->resize(count);
42   result = vkEnumerateInstanceExtensionProperties(layer_name, &count,
43                                                   extensions->data());
44   if (result != VK_SUCCESS)
45     return false;
46   return true;
47 }
48 
49 }  // anonymous namespace
50 
VkJsonGetDevice(VkPhysicalDevice physical_device)51 VkJsonDevice VkJsonGetDevice(VkPhysicalDevice physical_device) {
52   VkJsonDevice device;
53   vkGetPhysicalDeviceProperties(physical_device, &device.properties);
54   vkGetPhysicalDeviceFeatures(physical_device, &device.features);
55   vkGetPhysicalDeviceMemoryProperties(physical_device, &device.memory);
56 
57   uint32_t queue_family_count = 0;
58   vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &queue_family_count,
59                                            nullptr);
60   if (queue_family_count > 0) {
61     device.queues.resize(queue_family_count);
62     vkGetPhysicalDeviceQueueFamilyProperties(
63         physical_device, &queue_family_count, device.queues.data());
64   }
65 
66   // Only device extensions.
67   // TODO(piman): do we want to show layer extensions?
68   uint32_t extension_count = 0;
69   vkEnumerateDeviceExtensionProperties(physical_device, nullptr,
70                                        &extension_count, nullptr);
71   if (extension_count > 0) {
72     device.extensions.resize(extension_count);
73     vkEnumerateDeviceExtensionProperties(
74         physical_device, nullptr, &extension_count, device.extensions.data());
75   }
76 
77   uint32_t layer_count = 0;
78   vkEnumerateDeviceLayerProperties(physical_device, &layer_count, nullptr);
79   if (layer_count > 0) {
80     device.layers.resize(layer_count);
81     vkEnumerateDeviceLayerProperties(physical_device, &layer_count,
82                                      device.layers.data());
83   }
84 
85   VkFormatProperties format_properties = {};
86   for (VkFormat format = VK_FORMAT_R4G4_UNORM_PACK8;
87        format <= VK_FORMAT_END_RANGE;
88        format = static_cast<VkFormat>(format + 1)) {
89     vkGetPhysicalDeviceFormatProperties(physical_device, format,
90                                         &format_properties);
91     if (format_properties.linearTilingFeatures ||
92         format_properties.optimalTilingFeatures ||
93         format_properties.bufferFeatures) {
94       device.formats.insert(std::make_pair(format, format_properties));
95     }
96   }
97   return device;
98 }
99 
VkJsonGetInstance()100 VkJsonInstance VkJsonGetInstance() {
101   VkJsonInstance instance;
102   VkResult result;
103   uint32_t count;
104 
105   count = 0;
106   result = vkEnumerateInstanceLayerProperties(&count, nullptr);
107   if (result != VK_SUCCESS)
108     return VkJsonInstance();
109   if (count > 0) {
110     std::vector<VkLayerProperties> layers(count);
111     result = vkEnumerateInstanceLayerProperties(&count, layers.data());
112     if (result != VK_SUCCESS)
113       return VkJsonInstance();
114     instance.layers.reserve(count);
115     for (auto& layer : layers) {
116       instance.layers.push_back(VkJsonLayer{layer, std::vector<VkExtensionProperties>()});
117       if (!EnumerateExtensions(layer.layerName,
118                                &instance.layers.back().extensions))
119         return VkJsonInstance();
120     }
121   }
122 
123   if (!EnumerateExtensions(nullptr, &instance.extensions))
124     return VkJsonInstance();
125 
126   std::vector<const char*> layer_names;
127   layer_names.reserve(instance.layers.size());
128   for (auto& layer : instance.layers)
129     layer_names.push_back(layer.properties.layerName);
130 
131   const VkApplicationInfo app_info = {VK_STRUCTURE_TYPE_APPLICATION_INFO,
132                                       nullptr,
133                                       "vkjson_info",
134                                       1,
135                                       "",
136                                       0,
137                                       VK_API_VERSION_1_0};
138   VkInstanceCreateInfo instance_info = {
139       VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
140       nullptr,
141       0,
142       &app_info,
143       static_cast<uint32_t>(layer_names.size()),
144       layer_names.data(),
145       0,
146       nullptr};
147   VkInstance vkinstance;
148   result = vkCreateInstance(&instance_info, nullptr, &vkinstance);
149   if (result != VK_SUCCESS)
150     return VkJsonInstance();
151 
152   count = 0;
153   result = vkEnumeratePhysicalDevices(vkinstance, &count, nullptr);
154   if (result != VK_SUCCESS) {
155     vkDestroyInstance(vkinstance, nullptr);
156     return VkJsonInstance();
157   }
158   std::vector<VkPhysicalDevice> devices(count, VK_NULL_HANDLE);
159   result = vkEnumeratePhysicalDevices(vkinstance, &count, devices.data());
160   if (result != VK_SUCCESS) {
161     vkDestroyInstance(vkinstance, nullptr);
162     return VkJsonInstance();
163   }
164 
165   instance.devices.reserve(devices.size());
166   for (auto device : devices)
167     instance.devices.emplace_back(VkJsonGetDevice(device));
168 
169   vkDestroyInstance(vkinstance, nullptr);
170   return instance;
171 }
172