Merge "HWC2: Change version detection scheme" into nyc-dev
diff --git a/cmds/dumpstate/utils.cpp b/cmds/dumpstate/utils.cpp
index da4b5ad..f1a1ed6 100644
--- a/cmds/dumpstate/utils.cpp
+++ b/cmds/dumpstate/utils.cpp
@@ -51,10 +51,14 @@
 static const int64_t NANOS_PER_SEC = 1000000000;
 
 /* list of native processes to include in the native dumps */
+// This matches the /proc/pid/exe link instead of /proc/pid/cmdline.
 static const char* native_processes_to_dump[] = {
         "/system/bin/audioserver",
         "/system/bin/cameraserver",
         "/system/bin/drmserver",
+        "/system/bin/mediacodec",     // media.codec
+        "/system/bin/mediadrmserver",
+        "/system/bin/mediaextractor", // media.extractor
         "/system/bin/mediaserver",
         "/system/bin/sdcard",
         "/system/bin/surfaceflinger",
diff --git a/opengl/include/EGL/eglext.h b/opengl/include/EGL/eglext.h
index b1f51f7..bef5f02 100644
--- a/opengl/include/EGL/eglext.h
+++ b/opengl/include/EGL/eglext.h
@@ -616,6 +616,10 @@
 #define EGL_FRONT_BUFFER_AUTO_REFRESH_ANDROID 0x314C
 #endif
 
+#ifndef EGL_KHR_mutable_render_buffer
+#define EGL_KHR_mutable_render_buffer 1
+#define EGL_MUTABLE_RENDER_BUFFER_BIT_KHR 0x1000
+#endif
 
 #ifdef __cplusplus
 }
diff --git a/opengl/libs/EGL/eglApi.cpp b/opengl/libs/EGL/eglApi.cpp
index b997574..613b63b 100644
--- a/opengl/libs/EGL/eglApi.cpp
+++ b/opengl/libs/EGL/eglApi.cpp
@@ -115,6 +115,7 @@
         "EGL_KHR_partial_update "               // strongly recommended
         "EGL_EXT_buffer_age "                   // strongly recommended with partial_update
         "EGL_KHR_create_context_no_error "
+        "EGL_KHR_mutable_render_buffer "
         ;
 
 // extensions not exposed to applications but used by the ANDROID system
diff --git a/services/surfaceflinger/DisplayHardware/HWC2.cpp b/services/surfaceflinger/DisplayHardware/HWC2.cpp
index 5c78c68..f7678e4 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWC2.cpp
@@ -30,6 +30,7 @@
 
 #include <android/configuration.h>
 
+#include <algorithm>
 #include <inttypes.h>
 
 extern "C" {
@@ -303,6 +304,12 @@
     mHwcDevice->getCapabilities(mHwcDevice, &numCapabilities, asInt);
 }
 
+bool Device::hasCapability(HWC2::Capability capability) const
+{
+    return std::find(mCapabilities.cbegin(), mCapabilities.cend(),
+            capability) != mCapabilities.cend();
+}
+
 void Device::loadFunctionPointers()
 {
     // For all of these early returns, we log an error message inside
@@ -378,8 +385,10 @@
             mSetLayerDisplayFrame)) return;
     if (!loadFunctionPointer(FunctionDescriptor::SetLayerPlaneAlpha,
             mSetLayerPlaneAlpha)) return;
-    if (!loadFunctionPointer(FunctionDescriptor::SetLayerSidebandStream,
-            mSetLayerSidebandStream)) return;
+    if (hasCapability(Capability::SidebandStream)) {
+        if (!loadFunctionPointer(FunctionDescriptor::SetLayerSidebandStream,
+                mSetLayerSidebandStream)) return;
+    }
     if (!loadFunctionPointer(FunctionDescriptor::SetLayerSourceCrop,
             mSetLayerSourceCrop)) return;
     if (!loadFunctionPointer(FunctionDescriptor::SetLayerTransform,
@@ -973,6 +982,11 @@
 
 Error Layer::setSidebandStream(const native_handle_t* stream)
 {
+    if (!mDevice.hasCapability(Capability::SidebandStream)) {
+        ALOGE("Attempted to call setSidebandStream without checking that the "
+                "device supports sideband streams");
+        return Error::Unsupported;
+    }
     int32_t intError = mDevice.mSetLayerSidebandStream(mDevice.mHwcDevice,
             mDisplayId, mId, stream);
     return static_cast<Error>(intError);
diff --git a/services/surfaceflinger/DisplayHardware/HWC2.h b/services/surfaceflinger/DisplayHardware/HWC2.h
index 7d33a0a..967add0 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.h
+++ b/services/surfaceflinger/DisplayHardware/HWC2.h
@@ -89,6 +89,8 @@
     // as connected
     std::shared_ptr<Display> getDisplayById(hwc2_display_t id);
 
+    bool hasCapability(HWC2::Capability capability) const;
+
 private:
     // Initialization methods
 
diff --git a/vulkan/libvulkan/api.cpp b/vulkan/libvulkan/api.cpp
index eeb32d4..e7f10b3 100644
--- a/vulkan/libvulkan/api.cpp
+++ b/vulkan/libvulkan/api.cpp
@@ -465,6 +465,7 @@
 
     VkExtensionProperties* driver_extensions_;
     uint32_t driver_extension_count_;
+    std::bitset<driver::ProcHook::EXTENSION_COUNT> enabled_extensions_;
 };
 
 LayerChain::LayerChain(bool is_instance, const VkAllocationCallbacks& allocator)
@@ -477,7 +478,9 @@
       get_instance_proc_addr_(nullptr),
       get_device_proc_addr_(nullptr),
       driver_extensions_(nullptr),
-      driver_extension_count_(0) {}
+      driver_extension_count_(0) {
+    enabled_extensions_.set(driver::ProcHook::EXTENSION_CORE);
+}
 
 LayerChain::~LayerChain() {
     allocator_.pfnFree(allocator_.pUserData, driver_extensions_);
@@ -694,11 +697,11 @@
 
     // initialize InstanceData
     InstanceData& data = GetData(instance);
-    memset(&data, 0, sizeof(data));
 
     data.instance = instance;
 
-    if (!InitDispatchTable(instance, get_instance_proc_addr_)) {
+    if (!InitDispatchTable(instance, get_instance_proc_addr_,
+                           enabled_extensions_)) {
         if (data.dispatch.DestroyInstance)
             data.dispatch.DestroyInstance(instance, allocator);
 
@@ -774,9 +777,8 @@
 
     // initialize DeviceData
     DeviceData& data = GetData(dev);
-    memset(&data, 0, sizeof(data));
 
-    if (!InitDispatchTable(dev, get_device_proc_addr_)) {
+    if (!InitDispatchTable(dev, get_device_proc_addr_, enabled_extensions_)) {
         if (data.dispatch.DestroyDevice)
             data.dispatch.DestroyDevice(dev, allocator);
 
@@ -816,6 +818,10 @@
             ALOGE("Failed to enable missing instance extension %s", name);
             return VK_ERROR_EXTENSION_NOT_PRESENT;
         }
+
+        auto ext_bit = driver::GetProcHookExtension(name);
+        if (ext_bit != driver::ProcHook::EXTENSION_UNKNOWN)
+            enabled_extensions_.set(ext_bit);
     }
 
     return VK_SUCCESS;
@@ -849,6 +855,10 @@
             ALOGE("Failed to enable missing device extension %s", name);
             return VK_ERROR_EXTENSION_NOT_PRESENT;
         }
+
+        auto ext_bit = driver::GetProcHookExtension(name);
+        if (ext_bit != driver::ProcHook::EXTENSION_UNKNOWN)
+            enabled_extensions_.set(ext_bit);
     }
 
     return VK_SUCCESS;
diff --git a/vulkan/libvulkan/api_gen.cpp b/vulkan/libvulkan/api_gen.cpp
index a8cca59..fe4136f 100644
--- a/vulkan/libvulkan/api_gen.cpp
+++ b/vulkan/libvulkan/api_gen.cpp
@@ -37,14 +37,81 @@
         }                                                              \
     } while (0)
 
-// TODO do we want to point to a stub or nullptr when ext is not enabled?
-#define INIT_PROC_EXT(ext, obj, proc) \
-    do {                              \
-        INIT_PROC(obj, proc);         \
+// Exported extension functions may be invoked even when their extensions
+// are disabled.  Dispatch to stubs when that happens.
+#define INIT_PROC_EXT(ext, obj, proc)            \
+    do {                                         \
+        if (extensions[driver::ProcHook::ext])   \
+            INIT_PROC(obj, proc);                \
+        else                                     \
+            data.dispatch.proc = disabled##proc; \
     } while (0)
 
-bool InitDispatchTable(VkInstance instance,
-                       PFN_vkGetInstanceProcAddr get_proc) {
+namespace {
+
+// clang-format off
+
+VKAPI_ATTR void disabledDestroySurfaceKHR(VkInstance, VkSurfaceKHR, const VkAllocationCallbacks*) {
+    ALOGE("VK_KHR_surface not enabled. vkDestroySurfaceKHR not executed.");
+}
+
+VKAPI_ATTR VkResult disabledGetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevice, uint32_t, VkSurfaceKHR, VkBool32*) {
+    ALOGE("VK_KHR_surface not enabled. vkGetPhysicalDeviceSurfaceSupportKHR not executed.");
+    return VK_SUCCESS;
+}
+
+VKAPI_ATTR VkResult disabledGetPhysicalDeviceSurfaceCapabilitiesKHR(VkPhysicalDevice, VkSurfaceKHR, VkSurfaceCapabilitiesKHR*) {
+    ALOGE("VK_KHR_surface not enabled. vkGetPhysicalDeviceSurfaceCapabilitiesKHR not executed.");
+    return VK_SUCCESS;
+}
+
+VKAPI_ATTR VkResult disabledGetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice, VkSurfaceKHR, uint32_t*, VkSurfaceFormatKHR*) {
+    ALOGE("VK_KHR_surface not enabled. vkGetPhysicalDeviceSurfaceFormatsKHR not executed.");
+    return VK_SUCCESS;
+}
+
+VKAPI_ATTR VkResult disabledGetPhysicalDeviceSurfacePresentModesKHR(VkPhysicalDevice, VkSurfaceKHR, uint32_t*, VkPresentModeKHR*) {
+    ALOGE("VK_KHR_surface not enabled. vkGetPhysicalDeviceSurfacePresentModesKHR not executed.");
+    return VK_SUCCESS;
+}
+
+VKAPI_ATTR VkResult disabledCreateSwapchainKHR(VkDevice, const VkSwapchainCreateInfoKHR*, const VkAllocationCallbacks*, VkSwapchainKHR*) {
+    ALOGE("VK_KHR_swapchain not enabled. vkCreateSwapchainKHR not executed.");
+    return VK_SUCCESS;
+}
+
+VKAPI_ATTR void disabledDestroySwapchainKHR(VkDevice, VkSwapchainKHR, const VkAllocationCallbacks*) {
+    ALOGE("VK_KHR_swapchain not enabled. vkDestroySwapchainKHR not executed.");
+}
+
+VKAPI_ATTR VkResult disabledGetSwapchainImagesKHR(VkDevice, VkSwapchainKHR, uint32_t*, VkImage*) {
+    ALOGE("VK_KHR_swapchain not enabled. vkGetSwapchainImagesKHR not executed.");
+    return VK_SUCCESS;
+}
+
+VKAPI_ATTR VkResult disabledAcquireNextImageKHR(VkDevice, VkSwapchainKHR, uint64_t, VkSemaphore, VkFence, uint32_t*) {
+    ALOGE("VK_KHR_swapchain not enabled. vkAcquireNextImageKHR not executed.");
+    return VK_SUCCESS;
+}
+
+VKAPI_ATTR VkResult disabledQueuePresentKHR(VkQueue, const VkPresentInfoKHR*) {
+    ALOGE("VK_KHR_swapchain not enabled. vkQueuePresentKHR not executed.");
+    return VK_SUCCESS;
+}
+
+VKAPI_ATTR VkResult disabledCreateAndroidSurfaceKHR(VkInstance, const VkAndroidSurfaceCreateInfoKHR*, const VkAllocationCallbacks*, VkSurfaceKHR*) {
+    ALOGE("VK_KHR_android_surface not enabled. vkCreateAndroidSurfaceKHR not executed.");
+    return VK_SUCCESS;
+}
+
+// clang-format on
+
+}  // anonymous
+
+bool InitDispatchTable(
+    VkInstance instance,
+    PFN_vkGetInstanceProcAddr get_proc,
+    const std::bitset<driver::ProcHook::EXTENSION_COUNT>& extensions) {
     auto& data = GetData(instance);
     bool success = true;
 
@@ -73,7 +140,10 @@
     return success;
 }
 
-bool InitDispatchTable(VkDevice dev, PFN_vkGetDeviceProcAddr get_proc) {
+bool InitDispatchTable(
+    VkDevice dev,
+    PFN_vkGetDeviceProcAddr get_proc,
+    const std::bitset<driver::ProcHook::EXTENSION_COUNT>& extensions) {
     auto& data = GetData(dev);
     bool success = true;
 
diff --git a/vulkan/libvulkan/api_gen.h b/vulkan/libvulkan/api_gen.h
index 54be83b..779b654 100644
--- a/vulkan/libvulkan/api_gen.h
+++ b/vulkan/libvulkan/api_gen.h
@@ -19,7 +19,9 @@
 #ifndef LIBVULKAN_API_GEN_H
 #define LIBVULKAN_API_GEN_H
 
+#include <bitset>
 #include <vulkan/vulkan.h>
+#include "driver_gen.h"
 
 namespace vulkan {
 namespace api {
@@ -179,8 +181,14 @@
     // clang-format on
 };
 
-bool InitDispatchTable(VkInstance instance, PFN_vkGetInstanceProcAddr get_proc);
-bool InitDispatchTable(VkDevice dev, PFN_vkGetDeviceProcAddr get_proc);
+bool InitDispatchTable(
+    VkInstance instance,
+    PFN_vkGetInstanceProcAddr get_proc,
+    const std::bitset<driver::ProcHook::EXTENSION_COUNT>& extensions);
+bool InitDispatchTable(
+    VkDevice dev,
+    PFN_vkGetDeviceProcAddr get_proc,
+    const std::bitset<driver::ProcHook::EXTENSION_COUNT>& extensions);
 
 }  // namespace api
 }  // namespace vulkan
diff --git a/vulkan/libvulkan/code-generator.tmpl b/vulkan/libvulkan/code-generator.tmpl
index 7517e91..3968371 100644
--- a/vulkan/libvulkan/code-generator.tmpl
+++ b/vulkan/libvulkan/code-generator.tmpl
@@ -37,7 +37,9 @@
 #ifndef LIBVULKAN_API_GEN_H
 #define LIBVULKAN_API_GEN_H

+#include <bitset>
 #include <vulkan/vulkan.h>
+#include "driver_gen.h"

 namespace vulkan {«
 namespace api {«
@@ -62,8 +64,14 @@
   // clang-format on
 };

-bool InitDispatchTable(VkInstance instance, PFN_vkGetInstanceProcAddr get_proc);
-bool InitDispatchTable(VkDevice dev, PFN_vkGetDeviceProcAddr get_proc);
+bool InitDispatchTable(
+    VkInstance instance,
+    PFN_vkGetInstanceProcAddr get_proc,
+    const std::bitset<driver::ProcHook::EXTENSION_COUNT> &extensions);
+bool InitDispatchTable(
+    VkDevice dev,
+    PFN_vkGetDeviceProcAddr get_proc,
+    const std::bitset<driver::ProcHook::EXTENSION_COUNT> &extensions);

 »} // namespace api
 »} // namespace vulkan
@@ -95,7 +103,21 @@

 {{Macro "api.C++.DefineInitProcExtMacro"}}

-bool InitDispatchTable(VkInstance instance, PFN_vkGetInstanceProcAddr get_proc) {
+namespace {«

+// clang-format off

+{{range $f := AllCommands $}}
+  {{Macro "api.C++.DefineExtensionStub" $f}}
+{{end}}
+// clang-format on

+»} // anonymous

+bool InitDispatchTable(
+    VkInstance instance,
+    PFN_vkGetInstanceProcAddr get_proc,
+    const std::bitset<driver::ProcHook::EXTENSION_COUNT> &extensions) {
     auto& data = GetData(instance);
     bool success = true;

@@ -110,7 +132,10 @@
     return success;
 }

-bool InitDispatchTable(VkDevice dev, PFN_vkGetDeviceProcAddr get_proc) {
+bool InitDispatchTable(
+    VkDevice dev,
+    PFN_vkGetDeviceProcAddr get_proc,
+    const std::bitset<driver::ProcHook::EXTENSION_COUNT> &extensions) {
     auto& data = GetData(dev);
     bool success = true;

@@ -163,6 +188,7 @@
 #ifndef LIBVULKAN_DRIVER_GEN_H
 #define LIBVULKAN_DRIVER_GEN_H

+#include <bitset>
 #include <vulkan/vulkan.h>
 #include <vulkan/vk_android_native_buffer.h>

@@ -194,8 +220,10 @@
 const ProcHook* GetProcHook(const char* name);
 ProcHook::Extension GetProcHookExtension(const char* name);

-bool InitDriverTable(VkInstance instance, PFN_vkGetInstanceProcAddr get_proc);
-bool InitDriverTable(VkDevice dev, PFN_vkGetDeviceProcAddr get_proc);
+bool InitDriverTable(VkInstance instance, PFN_vkGetInstanceProcAddr get_proc,
+                     const std::bitset<ProcHook::EXTENSION_COUNT> &extensions);
+bool InitDriverTable(VkDevice dev, PFN_vkGetDeviceProcAddr get_proc,
+                     const std::bitset<ProcHook::EXTENSION_COUNT> &extensions);

 »} // namespace driver
 »} // namespace vulkan
@@ -228,7 +256,7 @@
 // clang-format off

 {{range $f := AllCommands $}}
-  {{Macro "driver.C++.DefineProcHookStubs" $f}}
+  {{Macro "driver.C++.DefineProcHookStub" $f}}
 {{end}}
 // clang-format on

@@ -273,7 +301,8 @@

 {{Macro "driver.C++.DefineInitProcExtMacro"}}

-bool InitDriverTable(VkInstance instance, PFN_vkGetInstanceProcAddr get_proc)
+bool InitDriverTable(VkInstance instance, PFN_vkGetInstanceProcAddr get_proc,
+                     const std::bitset<ProcHook::EXTENSION_COUNT> &extensions)
 {
     auto& data = GetData(instance);
     bool success = true;
@@ -289,7 +318,8 @@
     return success;
 }

-bool InitDriverTable(VkDevice dev, PFN_vkGetDeviceProcAddr get_proc)
+bool InitDriverTable(VkDevice dev, PFN_vkGetDeviceProcAddr get_proc,
+                     const std::bitset<ProcHook::EXTENSION_COUNT> &extensions)
 {
     auto& data = GetData(dev);
     bool success = true;
@@ -428,14 +458,42 @@
 -------------------------------------------------------------------------------
 */}}
 {{define "api.C++.DefineInitProcExtMacro"}}
-  // TODO do we want to point to a stub or nullptr when ext is not enabled?
+  // Exported extension functions may be invoked even when their extensions
+  // are disabled.  Dispatch to stubs when that happens.
   #define INIT_PROC_EXT(ext, obj, proc) do {                    \
-      INIT_PROC(obj, proc);                                     \
+      if (extensions[driver::ProcHook::ext])                    \
+        INIT_PROC(obj, proc);                                   \
+      else                                                      \
+        data.dispatch.proc = disabled ## proc;                  \
   } while(0)
 {{end}}
 
 
 {{/*
+-------------------------------------------------------------------------------
+  Emits a stub for an exported extension function.
+-------------------------------------------------------------------------------
+*/}}
+{{define "api.C++.DefineExtensionStub"}}
+  {{AssertType $ "Function"}}
+
+  {{$ext := GetAnnotation $ "extension"}}
+  {{if and $ext (Macro "IsFunctionExported" $)}}
+    {{$ext_name := index $ext.Arguments 0}}
+
+    {{$base := (Macro "BaseName" $)}}
+    {{$unnamed_params := (ForEach $.CallParameters "ParameterType" | JoinWith ", ")}}
+
+    VKAPI_ATTR {{Node "Type" $.Return}} disabled{{$base}}({{$unnamed_params}}) {
+      ALOGE("{{$ext_name}} not enabled. {{$.Name}} not executed.");
+      {{if not (IsVoid $.Return.Type)}}return VK_SUCCESS;{{end}}
+    }
+    ¶
+  {{end}}
+{{end}}
+
+
+{{/*
 ------------------------------------------------------------------------------
   Emits code for vkGetInstanceProcAddr for function interception.
 ------------------------------------------------------------------------------
@@ -642,13 +700,13 @@
 
 {{/*
 ------------------------------------------------------------------------------
-  Emits true if a function needs ProcHook stubs.
+  Emits true if a function needs a ProcHook stub.
 ------------------------------------------------------------------------------
 */}}
-{{define "driver.NeedProcHookStubs"}}
+{{define "driver.NeedProcHookStub"}}
   {{AssertType $ "Function"}}
 
-  {{if (Macro "driver.IsIntercepted" $)}}
+  {{if and (Macro "driver.IsIntercepted" $) (Macro "IsDeviceDispatched" $)}}
     {{$ext := GetAnnotation $ "extension"}}
     {{if $ext}}
       {{if not (Macro "IsExtensionInternal" $ext)}}true{{end}}
@@ -686,8 +744,7 @@
       Extension extension;

       PFN_vkVoidFunction proc;
-      PFN_vkVoidFunction disabled_proc; // nullptr for global hooks
-      PFN_vkVoidFunction checked_proc;  // nullptr for global/instance hooks
+      PFN_vkVoidFunction checked_proc;  // always nullptr for non-device hooks
   };
 {{end}}
 
@@ -699,7 +756,7 @@
 */}}
 {{define "driver.C++.DefineInitProcExtMacro"}}
   #define INIT_PROC_EXT(ext, obj, proc) do {                    \
-      if (data.hal_extensions[ProcHook::ext])           \
+      if (extensions[ProcHook::ext])                            \
         INIT_PROC(obj, proc);                                   \
   } while(0)
 {{end}}
@@ -707,35 +764,31 @@
 
 {{/*
 -------------------------------------------------------------------------------
-  Emits definitions of stub functions for ProcHook.
+  Emits a stub for ProcHook::checked_proc.
 -------------------------------------------------------------------------------
 */}}
-{{define "driver.C++.DefineProcHookStubs"}}
+{{define "driver.C++.DefineProcHookStub"}}
   {{AssertType $ "Function"}}
 
-  {{if (Macro "driver.NeedProcHookStubs" $)}}
+  {{if (Macro "driver.NeedProcHookStub" $)}}
     {{$ext := GetAnnotation $ "extension"}}
     {{$ext_name := index $ext.Arguments 0}}
 
     {{$base := (Macro "BaseName" $)}}
     {{$unnamed_params := (ForEach $.CallParameters "ParameterType" | JoinWith ", ")}}
 
-    VKAPI_ATTR {{Node "Type" $.Return}} disabled{{$base}}({{$unnamed_params}}) {
-      ALOGE("{{$ext_name}} not enabled. {{$.Name}} not executed.");
-      {{if not (IsVoid $.Return.Type)}}return VK_SUCCESS;{{end}}
-    }
-    {{if (Macro "IsDeviceDispatched" $)}}
-      ¶
-      VKAPI_ATTR {{Node "Type" $.Return}} checked{{$base}}({{Macro "Parameters" $}}) {
-        {{if not (IsVoid $.Return.Type)}}return §{{end}}
+    VKAPI_ATTR {{Node "Type" $.Return}} checked{{$base}}({{Macro "Parameters" $}}) {
+      {{$p0 := index $.CallParameters 0}}
+      {{$ext_hook := Strings ("ProcHook::") (Macro "BaseName" $ext)}}
 
-        {{$p0 := index $.CallParameters 0}}
-        {{$ext_hook := Strings ("ProcHook::") (Macro "BaseName" $ext)}}
-        (GetData({{$p0.Name}}).hook_extensions[{{$ext_hook}}]) ? §
-          {{$base}}({{Macro "Arguments" $}}) : §
-          disabled{{$base}}({{Macro "Arguments" $}});
+      if (GetData({{$p0.Name}}).hook_extensions[{{$ext_hook}}]) {
+        {{if not (IsVoid $.Return.Type)}}return §{{end}}
+        {{$base}}({{Macro "Arguments" $}});
+      } else {
+        ALOGE("{{$ext_name}} not enabled. {{$.Name}} not executed.");
+        {{if not (IsVoid $.Return.Type)}}return VK_SUCCESS;{{end}}
       }
-    {{end}}
+    }

   {{end}}
 {{end}}
@@ -762,7 +815,6 @@
     ProcHook::EXTENSION_CORE,
     reinterpret_cast<PFN_vkVoidFunction>({{$base}}),
     nullptr,
-    nullptr,
   },
 {{end}}
 
@@ -788,17 +840,14 @@
       {{if (Macro "IsExtensionInternal" $ext)}}
         nullptr,
         nullptr,
-        nullptr,
       {{else}}
         reinterpret_cast<PFN_vkVoidFunction>({{$base}}),
-        reinterpret_cast<PFN_vkVoidFunction>(disabled{{$base}}),
         nullptr,
       {{end}}
     {{else}}
       ProcHook::EXTENSION_CORE,
       reinterpret_cast<PFN_vkVoidFunction>({{$base}}),
       nullptr,
-      nullptr,
     {{end}}
   },
 {{end}}
@@ -825,17 +874,14 @@
       {{if (Macro "IsExtensionInternal" $ext)}}
         nullptr,
         nullptr,
-        nullptr,
       {{else}}
         reinterpret_cast<PFN_vkVoidFunction>({{$base}}),
-        reinterpret_cast<PFN_vkVoidFunction>(disabled{{$base}}),
         reinterpret_cast<PFN_vkVoidFunction>(checked{{$base}}),
       {{end}}
     {{else}}
       ProcHook::EXTENSION_CORE,
       reinterpret_cast<PFN_vkVoidFunction>({{$base}}),
       nullptr,
-      nullptr,
     {{end}}
   },
 {{end}}
diff --git a/vulkan/libvulkan/driver.cpp b/vulkan/libvulkan/driver.cpp
index c5ea20b..17ccc72 100644
--- a/vulkan/libvulkan/driver.cpp
+++ b/vulkan/libvulkan/driver.cpp
@@ -499,7 +499,7 @@
         case ProcHook::INSTANCE:
             proc = (GetData(instance).hook_extensions[hook->extension])
                        ? hook->proc
-                       : hook->disabled_proc;
+                       : nullptr;
             break;
         case ProcHook::DEVICE:
             proc = (hook->extension == ProcHook::EXTENSION_CORE)
@@ -528,9 +528,8 @@
         return nullptr;
     }
 
-    return (GetData(device).hook_extensions[hook->extension])
-               ? hook->proc
-               : hook->disabled_proc;
+    return (GetData(device).hook_extensions[hook->extension]) ? hook->proc
+                                                              : nullptr;
 }
 
 VkResult EnumerateInstanceExtensionProperties(
@@ -616,7 +615,6 @@
         return VK_ERROR_OUT_OF_HOST_MEMORY;
 
     data->hook_extensions |= wrapper.GetHookExtensions();
-    data->hal_extensions |= wrapper.GetHalExtensions();
 
     // call into the driver
     VkInstance instance;
@@ -630,7 +628,8 @@
 
     // initialize InstanceDriverTable
     if (!SetData(instance, *data) ||
-        !InitDriverTable(instance, g_hwdevice->GetInstanceProcAddr)) {
+        !InitDriverTable(instance, g_hwdevice->GetInstanceProcAddr,
+                         wrapper.GetHalExtensions())) {
         data->driver.DestroyInstance = reinterpret_cast<PFN_vkDestroyInstance>(
             g_hwdevice->GetInstanceProcAddr(instance, "vkDestroyInstance"));
         if (data->driver.DestroyInstance)
@@ -687,7 +686,6 @@
         return VK_ERROR_OUT_OF_HOST_MEMORY;
 
     data->hook_extensions |= wrapper.GetHookExtensions();
-    data->hal_extensions |= wrapper.GetHalExtensions();
 
     // call into the driver
     VkDevice dev;
@@ -701,7 +699,8 @@
 
     // initialize DeviceDriverTable
     if (!SetData(dev, *data) ||
-        !InitDriverTable(dev, instance_data.get_device_proc_addr)) {
+        !InitDriverTable(dev, instance_data.get_device_proc_addr,
+                         wrapper.GetHalExtensions())) {
         data->driver.DestroyDevice = reinterpret_cast<PFN_vkDestroyDevice>(
             instance_data.get_device_proc_addr(dev, "vkDestroyDevice"));
         if (data->driver.DestroyDevice)
diff --git a/vulkan/libvulkan/driver.h b/vulkan/libvulkan/driver.h
index 5543792..85b36b6 100644
--- a/vulkan/libvulkan/driver.h
+++ b/vulkan/libvulkan/driver.h
@@ -74,7 +74,6 @@
           driver(),
           get_device_proc_addr(nullptr) {
         hook_extensions.set(ProcHook::EXTENSION_CORE);
-        hal_extensions.set(ProcHook::EXTENSION_CORE);
     }
 
     api::InstanceData opaque_api_data;
@@ -82,7 +81,6 @@
     const VkAllocationCallbacks allocator;
 
     std::bitset<ProcHook::EXTENSION_COUNT> hook_extensions;
-    std::bitset<ProcHook::EXTENSION_COUNT> hal_extensions;
 
     InstanceDriverTable driver;
     PFN_vkGetDeviceProcAddr get_device_proc_addr;
@@ -94,7 +92,6 @@
     DeviceData(const VkAllocationCallbacks& alloc)
         : opaque_api_data(), allocator(alloc), driver() {
         hook_extensions.set(ProcHook::EXTENSION_CORE);
-        hal_extensions.set(ProcHook::EXTENSION_CORE);
     }
 
     api::DeviceData opaque_api_data;
@@ -102,7 +99,6 @@
     const VkAllocationCallbacks allocator;
 
     std::bitset<ProcHook::EXTENSION_COUNT> hook_extensions;
-    std::bitset<ProcHook::EXTENSION_COUNT> hal_extensions;
 
     DeviceDriverTable driver;
 };
diff --git a/vulkan/libvulkan/driver_gen.cpp b/vulkan/libvulkan/driver_gen.cpp
index 8b816ba..5bd2159 100644
--- a/vulkan/libvulkan/driver_gen.cpp
+++ b/vulkan/libvulkan/driver_gen.cpp
@@ -29,90 +29,48 @@
 
 // clang-format off
 
-VKAPI_ATTR void disabledDestroySurfaceKHR(VkInstance, VkSurfaceKHR, const VkAllocationCallbacks*) {
-    ALOGE("VK_KHR_surface not enabled. vkDestroySurfaceKHR not executed.");
-}
-
-VKAPI_ATTR VkResult disabledGetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevice, uint32_t, VkSurfaceKHR, VkBool32*) {
-    ALOGE("VK_KHR_surface not enabled. vkGetPhysicalDeviceSurfaceSupportKHR not executed.");
-    return VK_SUCCESS;
-}
-
-VKAPI_ATTR VkResult disabledGetPhysicalDeviceSurfaceCapabilitiesKHR(VkPhysicalDevice, VkSurfaceKHR, VkSurfaceCapabilitiesKHR*) {
-    ALOGE("VK_KHR_surface not enabled. vkGetPhysicalDeviceSurfaceCapabilitiesKHR not executed.");
-    return VK_SUCCESS;
-}
-
-VKAPI_ATTR VkResult disabledGetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice, VkSurfaceKHR, uint32_t*, VkSurfaceFormatKHR*) {
-    ALOGE("VK_KHR_surface not enabled. vkGetPhysicalDeviceSurfaceFormatsKHR not executed.");
-    return VK_SUCCESS;
-}
-
-VKAPI_ATTR VkResult disabledGetPhysicalDeviceSurfacePresentModesKHR(VkPhysicalDevice, VkSurfaceKHR, uint32_t*, VkPresentModeKHR*) {
-    ALOGE("VK_KHR_surface not enabled. vkGetPhysicalDeviceSurfacePresentModesKHR not executed.");
-    return VK_SUCCESS;
-}
-
-VKAPI_ATTR VkResult disabledCreateSwapchainKHR(VkDevice, const VkSwapchainCreateInfoKHR*, const VkAllocationCallbacks*, VkSwapchainKHR*) {
-    ALOGE("VK_KHR_swapchain not enabled. vkCreateSwapchainKHR not executed.");
-    return VK_SUCCESS;
-}
-
 VKAPI_ATTR VkResult checkedCreateSwapchainKHR(VkDevice device, const VkSwapchainCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSwapchainKHR* pSwapchain) {
-    return (GetData(device).hook_extensions[ProcHook::KHR_swapchain]) ? CreateSwapchainKHR(device, pCreateInfo, pAllocator, pSwapchain) : disabledCreateSwapchainKHR(device, pCreateInfo, pAllocator, pSwapchain);
-}
-
-VKAPI_ATTR void disabledDestroySwapchainKHR(VkDevice, VkSwapchainKHR, const VkAllocationCallbacks*) {
-    ALOGE("VK_KHR_swapchain not enabled. vkDestroySwapchainKHR not executed.");
+    if (GetData(device).hook_extensions[ProcHook::KHR_swapchain]) {
+        return CreateSwapchainKHR(device, pCreateInfo, pAllocator, pSwapchain);
+    } else {
+        ALOGE("VK_KHR_swapchain not enabled. vkCreateSwapchainKHR not executed.");
+        return VK_SUCCESS;
+    }
 }
 
 VKAPI_ATTR void checkedDestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain, const VkAllocationCallbacks* pAllocator) {
-    (GetData(device).hook_extensions[ProcHook::KHR_swapchain]) ? DestroySwapchainKHR(device, swapchain, pAllocator) : disabledDestroySwapchainKHR(device, swapchain, pAllocator);
-}
-
-VKAPI_ATTR VkResult disabledGetSwapchainImagesKHR(VkDevice, VkSwapchainKHR, uint32_t*, VkImage*) {
-    ALOGE("VK_KHR_swapchain not enabled. vkGetSwapchainImagesKHR not executed.");
-    return VK_SUCCESS;
+    if (GetData(device).hook_extensions[ProcHook::KHR_swapchain]) {
+        DestroySwapchainKHR(device, swapchain, pAllocator);
+    } else {
+        ALOGE("VK_KHR_swapchain not enabled. vkDestroySwapchainKHR not executed.");
+    }
 }
 
 VKAPI_ATTR VkResult checkedGetSwapchainImagesKHR(VkDevice device, VkSwapchainKHR swapchain, uint32_t* pSwapchainImageCount, VkImage* pSwapchainImages) {
-    return (GetData(device).hook_extensions[ProcHook::KHR_swapchain]) ? GetSwapchainImagesKHR(device, swapchain, pSwapchainImageCount, pSwapchainImages) : disabledGetSwapchainImagesKHR(device, swapchain, pSwapchainImageCount, pSwapchainImages);
-}
-
-VKAPI_ATTR VkResult disabledAcquireNextImageKHR(VkDevice, VkSwapchainKHR, uint64_t, VkSemaphore, VkFence, uint32_t*) {
-    ALOGE("VK_KHR_swapchain not enabled. vkAcquireNextImageKHR not executed.");
-    return VK_SUCCESS;
+    if (GetData(device).hook_extensions[ProcHook::KHR_swapchain]) {
+        return GetSwapchainImagesKHR(device, swapchain, pSwapchainImageCount, pSwapchainImages);
+    } else {
+        ALOGE("VK_KHR_swapchain not enabled. vkGetSwapchainImagesKHR not executed.");
+        return VK_SUCCESS;
+    }
 }
 
 VKAPI_ATTR VkResult checkedAcquireNextImageKHR(VkDevice device, VkSwapchainKHR swapchain, uint64_t timeout, VkSemaphore semaphore, VkFence fence, uint32_t* pImageIndex) {
-    return (GetData(device).hook_extensions[ProcHook::KHR_swapchain]) ? AcquireNextImageKHR(device, swapchain, timeout, semaphore, fence, pImageIndex) : disabledAcquireNextImageKHR(device, swapchain, timeout, semaphore, fence, pImageIndex);
-}
-
-VKAPI_ATTR VkResult disabledQueuePresentKHR(VkQueue, const VkPresentInfoKHR*) {
-    ALOGE("VK_KHR_swapchain not enabled. vkQueuePresentKHR not executed.");
-    return VK_SUCCESS;
+    if (GetData(device).hook_extensions[ProcHook::KHR_swapchain]) {
+        return AcquireNextImageKHR(device, swapchain, timeout, semaphore, fence, pImageIndex);
+    } else {
+        ALOGE("VK_KHR_swapchain not enabled. vkAcquireNextImageKHR not executed.");
+        return VK_SUCCESS;
+    }
 }
 
 VKAPI_ATTR VkResult checkedQueuePresentKHR(VkQueue queue, const VkPresentInfoKHR* pPresentInfo) {
-    return (GetData(queue).hook_extensions[ProcHook::KHR_swapchain]) ? QueuePresentKHR(queue, pPresentInfo) : disabledQueuePresentKHR(queue, pPresentInfo);
-}
-
-VKAPI_ATTR VkResult disabledCreateAndroidSurfaceKHR(VkInstance, const VkAndroidSurfaceCreateInfoKHR*, const VkAllocationCallbacks*, VkSurfaceKHR*) {
-    ALOGE("VK_KHR_android_surface not enabled. vkCreateAndroidSurfaceKHR not executed.");
-    return VK_SUCCESS;
-}
-
-VKAPI_ATTR VkResult disabledCreateDebugReportCallbackEXT(VkInstance, const VkDebugReportCallbackCreateInfoEXT*, const VkAllocationCallbacks*, VkDebugReportCallbackEXT*) {
-    ALOGE("VK_EXT_debug_report not enabled. vkCreateDebugReportCallbackEXT not executed.");
-    return VK_SUCCESS;
-}
-
-VKAPI_ATTR void disabledDestroyDebugReportCallbackEXT(VkInstance, VkDebugReportCallbackEXT, const VkAllocationCallbacks*) {
-    ALOGE("VK_EXT_debug_report not enabled. vkDestroyDebugReportCallbackEXT not executed.");
-}
-
-VKAPI_ATTR void disabledDebugReportMessageEXT(VkInstance, VkDebugReportFlagsEXT, VkDebugReportObjectTypeEXT, uint64_t, size_t, int32_t, const char*, const char*) {
-    ALOGE("VK_EXT_debug_report not enabled. vkDebugReportMessageEXT not executed.");
+    if (GetData(queue).hook_extensions[ProcHook::KHR_swapchain]) {
+        return QueuePresentKHR(queue, pPresentInfo);
+    } else {
+        ALOGE("VK_KHR_swapchain not enabled. vkQueuePresentKHR not executed.");
+        return VK_SUCCESS;
+    }
 }
 
 // clang-format on
@@ -125,14 +83,12 @@
         ProcHook::ANDROID_native_buffer,
         nullptr,
         nullptr,
-        nullptr,
     },
     {
         "vkAcquireNextImageKHR",
         ProcHook::DEVICE,
         ProcHook::KHR_swapchain,
         reinterpret_cast<PFN_vkVoidFunction>(AcquireNextImageKHR),
-        reinterpret_cast<PFN_vkVoidFunction>(disabledAcquireNextImageKHR),
         reinterpret_cast<PFN_vkVoidFunction>(checkedAcquireNextImageKHR),
     },
     {
@@ -141,14 +97,12 @@
         ProcHook::EXTENSION_CORE,
         reinterpret_cast<PFN_vkVoidFunction>(AllocateCommandBuffers),
         nullptr,
-        nullptr,
     },
     {
         "vkCreateAndroidSurfaceKHR",
         ProcHook::INSTANCE,
         ProcHook::KHR_android_surface,
         reinterpret_cast<PFN_vkVoidFunction>(CreateAndroidSurfaceKHR),
-        reinterpret_cast<PFN_vkVoidFunction>(disabledCreateAndroidSurfaceKHR),
         nullptr,
     },
     {
@@ -156,7 +110,6 @@
         ProcHook::INSTANCE,
         ProcHook::EXT_debug_report,
         reinterpret_cast<PFN_vkVoidFunction>(CreateDebugReportCallbackEXT),
-        reinterpret_cast<PFN_vkVoidFunction>(disabledCreateDebugReportCallbackEXT),
         nullptr,
     },
     {
@@ -165,7 +118,6 @@
         ProcHook::EXTENSION_CORE,
         reinterpret_cast<PFN_vkVoidFunction>(CreateDevice),
         nullptr,
-        nullptr,
     },
     {
         "vkCreateInstance",
@@ -173,14 +125,12 @@
         ProcHook::EXTENSION_CORE,
         reinterpret_cast<PFN_vkVoidFunction>(CreateInstance),
         nullptr,
-        nullptr,
     },
     {
         "vkCreateSwapchainKHR",
         ProcHook::DEVICE,
         ProcHook::KHR_swapchain,
         reinterpret_cast<PFN_vkVoidFunction>(CreateSwapchainKHR),
-        reinterpret_cast<PFN_vkVoidFunction>(disabledCreateSwapchainKHR),
         reinterpret_cast<PFN_vkVoidFunction>(checkedCreateSwapchainKHR),
     },
     {
@@ -188,7 +138,6 @@
         ProcHook::INSTANCE,
         ProcHook::EXT_debug_report,
         reinterpret_cast<PFN_vkVoidFunction>(DebugReportMessageEXT),
-        reinterpret_cast<PFN_vkVoidFunction>(disabledDebugReportMessageEXT),
         nullptr,
     },
     {
@@ -196,7 +145,6 @@
         ProcHook::INSTANCE,
         ProcHook::EXT_debug_report,
         reinterpret_cast<PFN_vkVoidFunction>(DestroyDebugReportCallbackEXT),
-        reinterpret_cast<PFN_vkVoidFunction>(disabledDestroyDebugReportCallbackEXT),
         nullptr,
     },
     {
@@ -205,7 +153,6 @@
         ProcHook::EXTENSION_CORE,
         reinterpret_cast<PFN_vkVoidFunction>(DestroyDevice),
         nullptr,
-        nullptr,
     },
     {
         "vkDestroyInstance",
@@ -213,14 +160,12 @@
         ProcHook::EXTENSION_CORE,
         reinterpret_cast<PFN_vkVoidFunction>(DestroyInstance),
         nullptr,
-        nullptr,
     },
     {
         "vkDestroySurfaceKHR",
         ProcHook::INSTANCE,
         ProcHook::KHR_surface,
         reinterpret_cast<PFN_vkVoidFunction>(DestroySurfaceKHR),
-        reinterpret_cast<PFN_vkVoidFunction>(disabledDestroySurfaceKHR),
         nullptr,
     },
     {
@@ -228,7 +173,6 @@
         ProcHook::DEVICE,
         ProcHook::KHR_swapchain,
         reinterpret_cast<PFN_vkVoidFunction>(DestroySwapchainKHR),
-        reinterpret_cast<PFN_vkVoidFunction>(disabledDestroySwapchainKHR),
         reinterpret_cast<PFN_vkVoidFunction>(checkedDestroySwapchainKHR),
     },
     {
@@ -237,7 +181,6 @@
         ProcHook::EXTENSION_CORE,
         reinterpret_cast<PFN_vkVoidFunction>(EnumerateDeviceExtensionProperties),
         nullptr,
-        nullptr,
     },
     {
         "vkEnumerateInstanceExtensionProperties",
@@ -245,7 +188,6 @@
         ProcHook::EXTENSION_CORE,
         reinterpret_cast<PFN_vkVoidFunction>(EnumerateInstanceExtensionProperties),
         nullptr,
-        nullptr,
     },
     {
         "vkEnumeratePhysicalDevices",
@@ -253,7 +195,6 @@
         ProcHook::EXTENSION_CORE,
         reinterpret_cast<PFN_vkVoidFunction>(EnumeratePhysicalDevices),
         nullptr,
-        nullptr,
     },
     {
         "vkGetDeviceProcAddr",
@@ -261,7 +202,6 @@
         ProcHook::EXTENSION_CORE,
         reinterpret_cast<PFN_vkVoidFunction>(GetDeviceProcAddr),
         nullptr,
-        nullptr,
     },
     {
         "vkGetDeviceQueue",
@@ -269,7 +209,6 @@
         ProcHook::EXTENSION_CORE,
         reinterpret_cast<PFN_vkVoidFunction>(GetDeviceQueue),
         nullptr,
-        nullptr,
     },
     {
         "vkGetInstanceProcAddr",
@@ -277,14 +216,12 @@
         ProcHook::EXTENSION_CORE,
         reinterpret_cast<PFN_vkVoidFunction>(GetInstanceProcAddr),
         nullptr,
-        nullptr,
     },
     {
         "vkGetPhysicalDeviceSurfaceCapabilitiesKHR",
         ProcHook::INSTANCE,
         ProcHook::KHR_surface,
         reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceSurfaceCapabilitiesKHR),
-        reinterpret_cast<PFN_vkVoidFunction>(disabledGetPhysicalDeviceSurfaceCapabilitiesKHR),
         nullptr,
     },
     {
@@ -292,7 +229,6 @@
         ProcHook::INSTANCE,
         ProcHook::KHR_surface,
         reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceSurfaceFormatsKHR),
-        reinterpret_cast<PFN_vkVoidFunction>(disabledGetPhysicalDeviceSurfaceFormatsKHR),
         nullptr,
     },
     {
@@ -300,7 +236,6 @@
         ProcHook::INSTANCE,
         ProcHook::KHR_surface,
         reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceSurfacePresentModesKHR),
-        reinterpret_cast<PFN_vkVoidFunction>(disabledGetPhysicalDeviceSurfacePresentModesKHR),
         nullptr,
     },
     {
@@ -308,7 +243,6 @@
         ProcHook::INSTANCE,
         ProcHook::KHR_surface,
         reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceSurfaceSupportKHR),
-        reinterpret_cast<PFN_vkVoidFunction>(disabledGetPhysicalDeviceSurfaceSupportKHR),
         nullptr,
     },
     {
@@ -317,14 +251,12 @@
         ProcHook::ANDROID_native_buffer,
         nullptr,
         nullptr,
-        nullptr,
     },
     {
         "vkGetSwapchainImagesKHR",
         ProcHook::DEVICE,
         ProcHook::KHR_swapchain,
         reinterpret_cast<PFN_vkVoidFunction>(GetSwapchainImagesKHR),
-        reinterpret_cast<PFN_vkVoidFunction>(disabledGetSwapchainImagesKHR),
         reinterpret_cast<PFN_vkVoidFunction>(checkedGetSwapchainImagesKHR),
     },
     {
@@ -332,7 +264,6 @@
         ProcHook::DEVICE,
         ProcHook::KHR_swapchain,
         reinterpret_cast<PFN_vkVoidFunction>(QueuePresentKHR),
-        reinterpret_cast<PFN_vkVoidFunction>(disabledQueuePresentKHR),
         reinterpret_cast<PFN_vkVoidFunction>(checkedQueuePresentKHR),
     },
     {
@@ -341,7 +272,6 @@
         ProcHook::ANDROID_native_buffer,
         nullptr,
         nullptr,
-        nullptr,
     },
     // clang-format on
 };
@@ -381,13 +311,15 @@
         }                                                              \
     } while (0)
 
-#define INIT_PROC_EXT(ext, obj, proc)           \
-    do {                                        \
-        if (data.hal_extensions[ProcHook::ext]) \
-            INIT_PROC(obj, proc);               \
+#define INIT_PROC_EXT(ext, obj, proc)  \
+    do {                               \
+        if (extensions[ProcHook::ext]) \
+            INIT_PROC(obj, proc);      \
     } while (0)
 
-bool InitDriverTable(VkInstance instance, PFN_vkGetInstanceProcAddr get_proc) {
+bool InitDriverTable(VkInstance instance,
+                     PFN_vkGetInstanceProcAddr get_proc,
+                     const std::bitset<ProcHook::EXTENSION_COUNT>& extensions) {
     auto& data = GetData(instance);
     bool success = true;
 
@@ -406,7 +338,9 @@
     return success;
 }
 
-bool InitDriverTable(VkDevice dev, PFN_vkGetDeviceProcAddr get_proc) {
+bool InitDriverTable(VkDevice dev,
+                     PFN_vkGetDeviceProcAddr get_proc,
+                     const std::bitset<ProcHook::EXTENSION_COUNT>& extensions) {
     auto& data = GetData(dev);
     bool success = true;
 
diff --git a/vulkan/libvulkan/driver_gen.h b/vulkan/libvulkan/driver_gen.h
index 1eb7d79..ca17d57 100644
--- a/vulkan/libvulkan/driver_gen.h
+++ b/vulkan/libvulkan/driver_gen.h
@@ -19,6 +19,7 @@
 #ifndef LIBVULKAN_DRIVER_GEN_H
 #define LIBVULKAN_DRIVER_GEN_H
 
+#include <bitset>
 #include <vulkan/vulkan.h>
 #include <vulkan/vk_android_native_buffer.h>
 
@@ -48,8 +49,7 @@
     Extension extension;
 
     PFN_vkVoidFunction proc;
-    PFN_vkVoidFunction disabled_proc;  // nullptr for global hooks
-    PFN_vkVoidFunction checked_proc;   // nullptr for global/instance hooks
+    PFN_vkVoidFunction checked_proc;  // always nullptr for non-device hooks
 };
 
 struct InstanceDriverTable {
@@ -83,8 +83,12 @@
 const ProcHook* GetProcHook(const char* name);
 ProcHook::Extension GetProcHookExtension(const char* name);
 
-bool InitDriverTable(VkInstance instance, PFN_vkGetInstanceProcAddr get_proc);
-bool InitDriverTable(VkDevice dev, PFN_vkGetDeviceProcAddr get_proc);
+bool InitDriverTable(VkInstance instance,
+                     PFN_vkGetInstanceProcAddr get_proc,
+                     const std::bitset<ProcHook::EXTENSION_COUNT>& extensions);
+bool InitDriverTable(VkDevice dev,
+                     PFN_vkGetDeviceProcAddr get_proc,
+                     const std::bitset<ProcHook::EXTENSION_COUNT>& extensions);
 
 }  // namespace driver
 }  // namespace vulkan