Home | History | Annotate | Download | only in vkjson
      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