release-request-fd631211-effa-4885-9314-559fcbd0a094-for-git_oc-mr1-release-4308825 snap-temp-L52700000098265170

Change-Id: Ie3c556ead353c19853791004a45a909127ac5163
diff --git a/Android.bp b/Android.bp
index 7c2da79..e95bc5d 100644
--- a/Android.bp
+++ b/Android.bp
@@ -1,26 +1,3 @@
-cc_library_headers {
-    name: "vk_headers",
-    clang: true,
-    local_include_dirs: [
-        "include",
-    ],
-    export_include_dirs: [
-        "include",
-    ],
-}
-
-cc_library_headers {
-    name: "vk_headers_ndk",
-    clang: true,
-    local_include_dirs: [
-        "include",
-    ],
-    export_include_dirs: [
-        "include",
-    ],
-    sdk_version: "24",
-}
-
 subdirs = [
     "libs/cjson",
     "libs/vkjson",
diff --git a/libs/vkjson/Android.bp b/libs/vkjson/Android.bp
index 63de5c1..d50c149 100644
--- a/libs/vkjson/Android.bp
+++ b/libs/vkjson/Android.bp
@@ -1,6 +1,5 @@
 cc_library_static {
     name: "libvkjson",
-    clang: true,
     srcs: [
         "vkjson.cc",
         "vkjson_instance.cc",
@@ -16,7 +15,7 @@
         "cjson",
     ],
     header_libs: [
-        "vk_headers",
+        "vulkan_headers",
     ],
 }
 
@@ -38,7 +37,7 @@
         "cjson_ndk",
     ],
     header_libs: [
-        "vk_headers_ndk",
+        "vulkan_headers_ndk",
     ],
     sdk_version: "24",
     stl: "libc++_static",
diff --git a/libs/vkjson/vkjson.cc b/libs/vkjson/vkjson.cc
index aa3719d..a1068f1 100644
--- a/libs/vkjson/vkjson.cc
+++ b/libs/vkjson/vkjson.cc
@@ -33,7 +33,6 @@
 #include <utility>
 
 #include <cJSON.h>
-#include <vulkan/vk_sdk_platform.h>
 
 namespace {
 
@@ -271,6 +270,14 @@
 }
 
 template <typename Visitor>
+inline bool Iterate(Visitor* visitor,
+                    VkPhysicalDeviceVariablePointerFeaturesKHR* features) {
+  return visitor->Visit("variablePointersStorageBuffer",
+                        &features->variablePointersStorageBuffer) &&
+         visitor->Visit("variablePointers", &features->variablePointers);
+}
+
+template <typename Visitor>
 inline bool Iterate(Visitor* visitor, VkMemoryType* type) {
   return
     visitor->Visit("propertyFlags", &type->propertyFlags) &&
@@ -336,6 +343,8 @@
 inline bool Iterate(Visitor* visitor, VkJsonDevice* device) {
   return visitor->Visit("properties", &device->properties) &&
          visitor->Visit("features", &device->features) &&
+         visitor->Visit("variablePointersFeaturesKHR",
+                        &device->variable_pointer_features) &&
          visitor->Visit("memory", &device->memory) &&
          visitor->Visit("queues", &device->queues) &&
          visitor->Visit("extensions", &device->extensions) &&
diff --git a/libs/vkjson/vkjson.h b/libs/vkjson/vkjson.h
index b703750..af3b37f 100644
--- a/libs/vkjson/vkjson.h
+++ b/libs/vkjson/vkjson.h
@@ -42,10 +42,13 @@
   VkJsonDevice() {
           memset(&properties, 0, sizeof(VkPhysicalDeviceProperties));
           memset(&features, 0, sizeof(VkPhysicalDeviceFeatures));
+          memset(&variable_pointer_features, 0,
+                 sizeof(VkPhysicalDeviceVariablePointerFeaturesKHR));
           memset(&memory, 0, sizeof(VkPhysicalDeviceMemoryProperties));
   }
   VkPhysicalDeviceProperties properties;
   VkPhysicalDeviceFeatures features;
+  VkPhysicalDeviceVariablePointerFeaturesKHR variable_pointer_features;
   VkPhysicalDeviceMemoryProperties memory;
   std::vector<VkQueueFamilyProperties> queues;
   std::vector<VkExtensionProperties> extensions;
@@ -65,7 +68,10 @@
                             VkJsonInstance* instance,
                             std::string* errors);
 
-VkJsonDevice VkJsonGetDevice(VkPhysicalDevice device);
+VkJsonDevice VkJsonGetDevice(VkInstance instance,
+                             VkPhysicalDevice device,
+                             uint32_t instanceExtensionCount,
+                             const char* const* instanceExtensions);
 std::string VkJsonDeviceToJson(const VkJsonDevice& device);
 bool VkJsonDeviceFromJson(const std::string& json,
                           VkJsonDevice* device,
@@ -81,7 +87,7 @@
 typedef VkJsonDevice VkJsonAllProperties;
 inline VkJsonAllProperties VkJsonGetAllProperties(
     VkPhysicalDevice physicalDevice) {
-  return VkJsonGetDevice(physicalDevice);
+  return VkJsonGetDevice(VK_NULL_HANDLE, physicalDevice, 0, nullptr);
 }
 inline std::string VkJsonAllPropertiesToJson(
     const VkJsonAllProperties& properties) {
diff --git a/libs/vkjson/vkjson_instance.cc b/libs/vkjson/vkjson_instance.cc
index 7784d53..c3b9e47 100644
--- a/libs/vkjson/vkjson_instance.cc
+++ b/libs/vkjson/vkjson_instance.cc
@@ -24,6 +24,9 @@
 #include <utility>
 
 namespace {
+const char* kSupportedInstanceExtensions[] = {
+    "VK_KHR_get_physical_device_properties2"};
+
 bool EnumerateExtensions(const char* layer_name,
                          std::vector<VkExtensionProperties>* extensions) {
   VkResult result;
@@ -39,21 +42,39 @@
   return true;
 }
 
+bool HasExtension(const char* extension_name,
+                  uint32_t count,
+                  const char* const* extensions) {
+  return std::find_if(extensions, extensions + count,
+                      [extension_name](const char* extension) {
+                        return strcmp(extension, extension_name) == 0;
+                      }) != extensions + count;
+}
+
+bool HasExtension(const char* extension_name,
+                  const std::vector<VkExtensionProperties>& extensions) {
+  return std::find_if(extensions.cbegin(), extensions.cend(),
+                      [extension_name](const VkExtensionProperties& extension) {
+                        return strcmp(extension.extensionName,
+                                      extension_name) == 0;
+                      }) != extensions.cend();
+}
 }  // anonymous namespace
 
-VkJsonDevice VkJsonGetDevice(VkPhysicalDevice physical_device) {
+VkJsonDevice VkJsonGetDevice(VkInstance instance,
+                             VkPhysicalDevice physical_device,
+                             uint32_t instance_extension_count,
+                             const char* const* instance_extensions) {
   VkJsonDevice device;
-  vkGetPhysicalDeviceProperties(physical_device, &device.properties);
-  vkGetPhysicalDeviceFeatures(physical_device, &device.features);
-  vkGetPhysicalDeviceMemoryProperties(physical_device, &device.memory);
 
-  uint32_t queue_family_count = 0;
-  vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &queue_family_count,
-                                           nullptr);
-  if (queue_family_count > 0) {
-    device.queues.resize(queue_family_count);
-    vkGetPhysicalDeviceQueueFamilyProperties(
-        physical_device, &queue_family_count, device.queues.data());
+  PFN_vkGetPhysicalDeviceFeatures2KHR vkpGetPhysicalDeviceFeatures2KHR =
+      nullptr;
+  if (instance != VK_NULL_HANDLE &&
+      HasExtension("VK_KHR_get_physical_device_properties2",
+                   instance_extension_count, instance_extensions)) {
+    vkpGetPhysicalDeviceFeatures2KHR =
+        reinterpret_cast<PFN_vkGetPhysicalDeviceFeatures2KHR>(
+            vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceFeatures2KHR"));
   }
 
   // Only device extensions.
@@ -75,6 +96,36 @@
                                      device.layers.data());
   }
 
+  vkGetPhysicalDeviceProperties(physical_device, &device.properties);
+  if (HasExtension("VK_KHR_get_physical_device_properties2",
+                   instance_extension_count, instance_extensions)) {
+    VkPhysicalDeviceFeatures2KHR features = {
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR,
+        nullptr,
+        {}  // features
+    };
+    if (HasExtension("VK_KHR_variable_pointers", device.extensions)) {
+      device.variable_pointer_features.sType =
+          VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES_KHR;
+      device.variable_pointer_features.pNext = features.pNext;
+      features.pNext = &device.variable_pointer_features;
+    }
+    vkpGetPhysicalDeviceFeatures2KHR(physical_device, &features);
+    device.features = features.features;
+  } else {
+    vkGetPhysicalDeviceFeatures(physical_device, &device.features);
+  }
+  vkGetPhysicalDeviceMemoryProperties(physical_device, &device.memory);
+
+  uint32_t queue_family_count = 0;
+  vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &queue_family_count,
+                                           nullptr);
+  if (queue_family_count > 0) {
+    device.queues.resize(queue_family_count);
+    vkGetPhysicalDeviceQueueFamilyProperties(
+        physical_device, &queue_family_count, device.queues.data());
+  }
+
   VkFormatProperties format_properties = {};
   for (VkFormat format = VK_FORMAT_R4G4_UNORM_PACK8;
        format <= VK_FORMAT_END_RANGE;
@@ -116,6 +167,12 @@
   if (!EnumerateExtensions(nullptr, &instance.extensions))
     return VkJsonInstance();
 
+  std::vector<const char*> instance_extensions;
+  for (const auto extension : kSupportedInstanceExtensions) {
+    if (HasExtension(extension, instance.extensions))
+      instance_extensions.push_back(extension);
+  }
+
   const VkApplicationInfo app_info = {VK_STRUCTURE_TYPE_APPLICATION_INFO,
                                       nullptr,
                                       "vkjson_info",
@@ -130,8 +187,8 @@
       &app_info,
       0,
       nullptr,
-      0,
-      nullptr};
+      static_cast<uint32_t>(instance_extensions.size()),
+      instance_extensions.data()};
   VkInstance vkinstance;
   result = vkCreateInstance(&instance_info, nullptr, &vkinstance);
   if (result != VK_SUCCESS)
@@ -152,7 +209,9 @@
 
   instance.devices.reserve(devices.size());
   for (auto device : devices)
-    instance.devices.emplace_back(VkJsonGetDevice(device));
+    instance.devices.emplace_back(VkJsonGetDevice(vkinstance, device,
+                                                  instance_extensions.size(),
+                                                  instance_extensions.data()));
 
   vkDestroyInstance(vkinstance, nullptr);
   return instance;