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 // Licensed under the Apache License, Version 2.0 (the "License");
9 // you may not use this file except in compliance with the License.
10 // You may obtain a copy of the License at
11 //
12 // http://www.apache.org/licenses/LICENSE-2.0
13 //
14 // Unless required by applicable law or agreed to in writing, software
15 // distributed under the License is distributed on an "AS IS" BASIS,
16 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 // See the License for the specific language governing permissions and
18 // limitations under the License.
19 ///////////////////////////////////////////////////////////////////////////////
20
21 #define VK_PROTOTYPES
22 #include "vkjson.h"
23
24 #include <utility>
25
26 namespace {
EnumerateExtensions(const char * layer_name,std::vector<VkExtensionProperties> * extensions)27 bool EnumerateExtensions(const char* layer_name,
28 std::vector<VkExtensionProperties>* extensions) {
29 VkResult result;
30 uint32_t count = 0;
31 result = vkEnumerateInstanceExtensionProperties(layer_name, &count, nullptr);
32 if (result != VK_SUCCESS)
33 return false;
34 extensions->resize(count);
35 result = vkEnumerateInstanceExtensionProperties(layer_name, &count,
36 extensions->data());
37 if (result != VK_SUCCESS)
38 return false;
39 return true;
40 }
41
42 } // anonymous namespace
43
VkJsonGetDevice(VkPhysicalDevice physical_device)44 VkJsonDevice VkJsonGetDevice(VkPhysicalDevice physical_device) {
45 VkJsonDevice device;
46 vkGetPhysicalDeviceProperties(physical_device, &device.properties);
47 vkGetPhysicalDeviceFeatures(physical_device, &device.features);
48 vkGetPhysicalDeviceMemoryProperties(physical_device, &device.memory);
49
50 uint32_t queue_family_count = 0;
51 vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &queue_family_count,
52 nullptr);
53 if (queue_family_count > 0) {
54 device.queues.resize(queue_family_count);
55 vkGetPhysicalDeviceQueueFamilyProperties(
56 physical_device, &queue_family_count, device.queues.data());
57 }
58
59 // Only device extensions.
60 // TODO(piman): do we want to show layer extensions?
61 uint32_t extension_count = 0;
62 vkEnumerateDeviceExtensionProperties(physical_device, nullptr,
63 &extension_count, nullptr);
64 if (extension_count > 0) {
65 device.extensions.resize(extension_count);
66 vkEnumerateDeviceExtensionProperties(
67 physical_device, nullptr, &extension_count, device.extensions.data());
68 }
69
70 uint32_t layer_count = 0;
71 vkEnumerateDeviceLayerProperties(physical_device, &layer_count, nullptr);
72 if (layer_count > 0) {
73 device.layers.resize(layer_count);
74 vkEnumerateDeviceLayerProperties(physical_device, &layer_count,
75 device.layers.data());
76 }
77
78 VkFormatProperties format_properties = {};
79 for (VkFormat format = VK_FORMAT_R4G4_UNORM_PACK8;
80 format <= VK_FORMAT_END_RANGE;
81 format = static_cast<VkFormat>(format + 1)) {
82 vkGetPhysicalDeviceFormatProperties(physical_device, format,
83 &format_properties);
84 if (format_properties.linearTilingFeatures ||
85 format_properties.optimalTilingFeatures ||
86 format_properties.bufferFeatures) {
87 device.formats.insert(std::make_pair(format, format_properties));
88 }
89 }
90 return device;
91 }
92
VkJsonGetInstance()93 VkJsonInstance VkJsonGetInstance() {
94 VkJsonInstance instance;
95 VkResult result;
96 uint32_t count;
97
98 count = 0;
99 result = vkEnumerateInstanceLayerProperties(&count, nullptr);
100 if (result != VK_SUCCESS)
101 return VkJsonInstance();
102 if (count > 0) {
103 std::vector<VkLayerProperties> layers(count);
104 result = vkEnumerateInstanceLayerProperties(&count, layers.data());
105 if (result != VK_SUCCESS)
106 return VkJsonInstance();
107 instance.layers.reserve(count);
108 for (auto& layer : layers) {
109 instance.layers.push_back(VkJsonLayer{layer, std::vector<VkExtensionProperties>()});
110 if (!EnumerateExtensions(layer.layerName,
111 &instance.layers.back().extensions))
112 return VkJsonInstance();
113 }
114 }
115
116 if (!EnumerateExtensions(nullptr, &instance.extensions))
117 return VkJsonInstance();
118
119 const VkApplicationInfo app_info = {VK_STRUCTURE_TYPE_APPLICATION_INFO,
120 nullptr,
121 "vkjson_info",
122 1,
123 "",
124 0,
125 VK_API_VERSION_1_0};
126 VkInstanceCreateInfo instance_info = {
127 VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
128 nullptr,
129 0,
130 &app_info,
131 0,
132 nullptr,
133 0,
134 nullptr};
135 VkInstance vkinstance;
136 result = vkCreateInstance(&instance_info, nullptr, &vkinstance);
137 if (result != VK_SUCCESS)
138 return VkJsonInstance();
139
140 count = 0;
141 result = vkEnumeratePhysicalDevices(vkinstance, &count, nullptr);
142 if (result != VK_SUCCESS) {
143 vkDestroyInstance(vkinstance, nullptr);
144 return VkJsonInstance();
145 }
146 std::vector<VkPhysicalDevice> devices(count, VK_NULL_HANDLE);
147 result = vkEnumeratePhysicalDevices(vkinstance, &count, devices.data());
148 if (result != VK_SUCCESS) {
149 vkDestroyInstance(vkinstance, nullptr);
150 return VkJsonInstance();
151 }
152
153 instance.devices.reserve(devices.size());
154 for (auto device : devices)
155 instance.devices.emplace_back(VkJsonGetDevice(device));
156
157 vkDestroyInstance(vkinstance, nullptr);
158 return instance;
159 }
160