layers: Move CV::DeviceExtensions into helper
diff --git a/layers/core_validation.cpp b/layers/core_validation.cpp
index 6e36c30..ca2f9e4 100644
--- a/layers/core_validation.cpp
+++ b/layers/core_validation.cpp
@@ -134,7 +134,7 @@
     debug_report_data *report_data = nullptr;
     VkLayerDispatchTable dispatch_table;
 
-    devExts device_extensions = {};
+    DeviceExtensions device_extensions = {};
     unordered_set<VkQueue> queues;  // All queues under given device
     // Global set of all cmdBuffers that are inFlight on this device
     unordered_set<VkCommandBuffer> globalInFlightCmdBuffers;
@@ -2168,11 +2168,11 @@
     struct CapabilityInfo {
         char const *name;
         VkBool32 const VkPhysicalDeviceFeatures::*feature;
-        bool const devExts::*extension;
+        bool const DeviceExtensions::*extension;
     };
 
     using F = VkPhysicalDeviceFeatures;
-    using E = devExts;
+    using E = DeviceExtensions;
 
     // clang-format off
     static const std::unordered_map<uint32_t, CapabilityInfo> capabilities = {
@@ -3503,38 +3503,6 @@
     layer_data_map.erase(key);
 }
 
-static void checkDeviceRegisterExtensions(const VkDeviceCreateInfo *pCreateInfo, devExts *exts) {
-
-    using E = devExts;
-
-    static const std::pair<char const *, bool E::*> known_extensions[] {
-        {VK_KHR_SWAPCHAIN_EXTENSION_NAME, &E::khr_swapchain},
-        {VK_KHR_DISPLAY_SWAPCHAIN_EXTENSION_NAME, &E::khr_display_swapchain},
-        {VK_NV_GLSL_SHADER_EXTENSION_NAME, &E::nv_glsl_shader},
-        {VK_KHR_DESCRIPTOR_UPDATE_TEMPLATE_EXTENSION_NAME, &E::khr_descriptor_update_template},
-        {VK_KHR_SHADER_DRAW_PARAMETERS_EXTENSION_NAME, &E::khr_shader_draw_parameters},
-        {VK_KHR_MAINTENANCE1_EXTENSION_NAME, &E::khr_maintenance1},
-        {VK_NV_GEOMETRY_SHADER_PASSTHROUGH_EXTENSION_NAME, &E::nv_geometry_shader_passthrough},
-        {VK_NV_SAMPLE_MASK_OVERRIDE_COVERAGE_EXTENSION_NAME, &E::nv_sample_mask_override_coverage},
-        {VK_NV_VIEWPORT_ARRAY2_EXTENSION_NAME, &E::nv_viewport_array2},
-        {VK_EXT_SHADER_SUBGROUP_BALLOT_EXTENSION_NAME, &E::khr_subgroup_ballot},
-        {VK_EXT_SHADER_SUBGROUP_VOTE_EXTENSION_NAME, &E::khr_subgroup_vote},
-    };
-
-    for (auto ext : known_extensions) {
-        exts->*(ext.second) = false;
-    }
-
-    for (uint32_t i = 0; i < pCreateInfo->enabledExtensionCount; i++) {
-        for (auto ext : known_extensions) {
-            if (!strcmp(ext.first, pCreateInfo->ppEnabledExtensionNames[i])) {
-                exts->*(ext.second) = true;
-                break;
-            }
-        }
-    }
-}
-
 // Verify that queue family has been properly requested
 static bool ValidateRequestedQueueFamilyProperties(instance_layer_data *instance_data, VkPhysicalDevice gpu,
                                                    const VkDeviceCreateInfo *create_info) {
@@ -3653,7 +3621,7 @@
     device_data->physical_device = gpu;
 
     device_data->report_data = layer_debug_report_create_device(instance_data->report_data, *pDevice);
-    checkDeviceRegisterExtensions(pCreateInfo, &device_data->device_extensions);
+    device_data->device_extensions->InitFromDeviceCreateInfo(pCreateInfo);
     // Get physical device limits for this device
     instance_data->dispatch_table.GetPhysicalDeviceProperties(gpu, &(device_data->phys_dev_properties.properties));
     uint32_t count;
@@ -5874,7 +5842,7 @@
     return &device_data->enabled_features;
 }
 
-const devExts *GetDeviceExtensions(const layer_data *device_data) { return &device_data->device_extensions; }
+const DeviceExtensions *GetDeviceExtensions(const layer_data *device_data) { return &device_data->device_extensions; }
 
 VKAPI_ATTR VkResult VKAPI_CALL CreateImage(VkDevice device, const VkImageCreateInfo *pCreateInfo,
                                            const VkAllocationCallbacks *pAllocator, VkImage *pImage) {
diff --git a/layers/core_validation_types.h b/layers/core_validation_types.h
index b86e663..67631e5 100644
--- a/layers/core_validation_types.h
+++ b/layers/core_validation_types.h
@@ -51,6 +51,7 @@
 #include "vk_validation_error_messages.h"
 #include "vk_layer_logging.h"
 #include "vk_object_types.h"
+#include "device_extensions.h"
 #include <atomic>
 #include <functional>
 #include <map>
@@ -752,21 +753,6 @@
 // Fwd declarations of layer_data and helpers to look-up/validate state from layer_data maps
 namespace core_validation {
 struct layer_data;
-
-struct devExts {
-    bool khr_swapchain;
-    bool khr_display_swapchain;
-    bool nv_glsl_shader;
-    bool khr_descriptor_update_template;
-    bool khr_shader_draw_parameters;
-    bool khr_maintenance1;
-    bool nv_geometry_shader_passthrough;
-    bool nv_sample_mask_override_coverage;
-    bool nv_viewport_array2;
-    bool khr_subgroup_ballot;
-    bool khr_subgroup_vote;
-};
-
 cvdescriptorset::DescriptorSet *GetSetNode(const layer_data *, VkDescriptorSet);
 cvdescriptorset::DescriptorSetLayout const *GetDescriptorSetLayout(layer_data const *, VkDescriptorSetLayout);
 DESCRIPTOR_POOL_STATE *GetDescriptorPoolState(const layer_data *, const VkDescriptorPool);
@@ -832,7 +818,7 @@
 std::unordered_map<VkBuffer, std::unique_ptr<BUFFER_STATE>> *GetBufferMap(layer_data *device_data);
 std::unordered_map<VkBufferView, std::unique_ptr<BUFFER_VIEW_STATE>> *GetBufferViewMap(layer_data *device_data);
 std::unordered_map<VkImageView, std::unique_ptr<IMAGE_VIEW_STATE>> *GetImageViewMap(layer_data *device_data);
-const devExts *GetDeviceExtensions(const layer_data *);
+const DeviceExtensions *GetDeviceExtensions(const layer_data *);
 }
 
 #endif  // CORE_VALIDATION_TYPES_H_
diff --git a/layers/device_extensions.h b/layers/device_extensions.h
new file mode 100644
index 0000000..200aa70
--- /dev/null
+++ b/layers/device_extensions.h
@@ -0,0 +1,68 @@
+/* Copyright (c) 2015-2016 The Khronos Group Inc.
+ * Copyright (c) 2015-2016 Valve Corporation
+ * Copyright (c) 2015-2016 LunarG, Inc.
+ * Copyright (C) 2015-2016 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Chris Forbes <chrisforbes@google.com>
+ */
+#ifndef DEVICE_EXTENSIONS_H_
+#define DEVICE_EXTENSIONS_H_
+
+struct DeviceExtensions {
+    bool khr_swapchain;
+    bool khr_display_swapchain;
+    bool nv_glsl_shader;
+    bool khr_descriptor_update_template;
+    bool khr_shader_draw_parameters;
+    bool khr_maintenance1;
+    bool nv_geometry_shader_passthrough;
+    bool nv_sample_mask_override_coverage;
+    bool nv_viewport_array2;
+    bool khr_subgroup_ballot;
+    bool khr_subgroup_vote;
+
+    void InitFromDeviceCreateInfo(const VkDeviceCreateInfo *pCreateInfo) {
+        using E = DeviceExtensions;
+
+        static const std::pair<char const *, bool E::*> known_extensions[]{
+            {VK_KHR_SWAPCHAIN_EXTENSION_NAME, &E::khr_swapchain},
+            {VK_KHR_DISPLAY_SWAPCHAIN_EXTENSION_NAME, &E::khr_display_swapchain},
+            {VK_NV_GLSL_SHADER_EXTENSION_NAME, &E::nv_glsl_shader},
+            {VK_KHR_DESCRIPTOR_UPDATE_TEMPLATE_EXTENSION_NAME, &E::khr_descriptor_update_template},
+            {VK_KHR_SHADER_DRAW_PARAMETERS_EXTENSION_NAME, &E::khr_shader_draw_parameters},
+            {VK_KHR_MAINTENANCE1_EXTENSION_NAME, &E::khr_maintenance1},
+            {VK_NV_GEOMETRY_SHADER_PASSTHROUGH_EXTENSION_NAME, &E::nv_geometry_shader_passthrough},
+            {VK_NV_SAMPLE_MASK_OVERRIDE_COVERAGE_EXTENSION_NAME, &E::nv_sample_mask_override_coverage},
+            {VK_NV_VIEWPORT_ARRAY2_EXTENSION_NAME, &E::nv_viewport_array2},
+            {VK_EXT_SHADER_SUBGROUP_BALLOT_EXTENSION_NAME, &E::khr_subgroup_ballot},
+            {VK_EXT_SHADER_SUBGROUP_VOTE_EXTENSION_NAME, &E::khr_subgroup_vote},
+        };
+
+        for (auto ext : known_extensions) {
+            this->*(ext.second) = false;
+        }
+
+        for (uint32_t i = 0; i < pCreateInfo->enabledExtensionCount; i++) {
+            for (auto ext : known_extensions) {
+                if (!strcmp(ext.first, pCreateInfo->ppEnabledExtensionNames[i])) {
+                    this->*(ext.second) = true;
+                    break;
+                }
+            }
+        }
+    }
+};
+
+#endif
\ No newline at end of file