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 { 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 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 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