gfxstream: mega-change to support guest Linux WSI with gfxstream

This is a mega-change to support Linux guest WSI with gfxstream.
We tried to do a branch where every commit was buildable and
runnable, but that quickly proved unworkable. So we squashed
the branch into a mega-change.

Zink provides the GL implementation for Linux guests, so we just
needed to implement the proper Vulkan Wayland/X11 WSI
entrypoints.

The overall strategy to support this is to use Mesa's WSI
functions.  The Vulkan WSI layer was also considered:

https://gitlab.freedesktop.org/mesa/vulkan-wsi-layer

But it was less maintained compared to Mesa.  The way Mesa common
layers communicate with drivers is the through base objects
embedded in driver and a common dispatch layer:

https://gitlab.freedesktop.org/mesa/mesa/-/blob/main/docs/vulkan/dispatch.rst
https://gitlab.freedesktop.org/mesa/mesa/-/blob/main/docs/vulkan/base-objs.rst

Our objects are defined in gfxstream_vk_private.h.  Currently,
Mesa-derived Vulkan objects just serve as shim to gfxstream
Vulkan’s internal handle mapping. Long-term, we can use
Mesa-derived objects inside gfxstream guest Vulkan exclusively.

The flow is typically inside a Vulkan entrypoint is:

- VK_FROM_HANDLE(vk-object) to convert to a gfxstream_vk_obj
  object
- Call ResourceTracker::func(gfxstream_vk_obj->internal) or
  VkEncoder::func(gfxstream_vk_obj>internal)
- Return result

A good follow-up cleanup would be to delete older gfxstream
objects.  For example, we now have struct gfxstream_vk_device
and info_VkDevice in ResourceTracker.

Most of this logic was auto-generated and included in
func_table.cpp. Some vulkan functions were too difficult to
auto-generate or required special logic, and these are included
in gfxstream_vk_device.cpp.  For example, anything that needs to
setup the HostConnection requires special handling.

Android Blueprint support is added to the parts of Mesa needed
to build the Vulkan runtime.  One thing to call out it's
required to build the guest/vulkan_enc and guest/vulkan files
in the same shared library now, when previously have
libvulkan_enc.so and libvulkan_ranchu.so was sufficient
[otherwise, some weak pointer logic wouldn't work].

A side effect of this is libOpenglSystem must also be a static
lib, and so should libandroid_aemu too.  That conceptually makes
sense and the Meson build had been doing this all a long.  We
can probably transition everything besides libGLESv1_emulation.so,
libGLESv2_emulation.so and libvulkan_ranchu.so to be static.

This requires changes in the end2end tests, because since each
HostConnection is separate and internal to it's constituent
library. Lifetimes need to be managed separately: for example
the HostConnection instance created by the end2end tests would
not be visible inside libvulkan_ranchu.so anymore. Probably the
best solution would be improve the testing facade so a
HostConnection represents one virtio-gpu context, while some
other entity represents a virtio-gpu device (client-server
would work).

vk.xml was modified, but change sent to Khronos:

https://gitlab.khronos.org/vulkan/vulkan/-/merge_requests/6325

Fuchsia builds still need to be migrated, but they already have
Fuchsia Mesa with all the build rules so that shouldn't be too
bad. Just need to copy them over the gfxstream/Mesa hybrid.

The new command for building Linux guests is:

meson amd64-build/ -Dvulkan-drivers="gfxstream" -Dgallium-drivers="" -Dvk-no-nir=true -Dopengl=false

Big shout-out to Aaron Ruby, who did most of the gnarly codegen
needed to get the function table logic to work.

BUG=313466265
BUG=298679844
TEST=
     * Run Weston/vkcube on Linux and automotive platform
     * launch_cvd --gpu_mode=gfxstream vkcube
     * launch_cvd --gpu_mod=gfxstream_guest_angle
     * vkcube + 3D Mark Slingshot extreme work with guest ANGLE and
       GL-VK interop
     * GfxstreamEnd2EndTests
     * Some select dEQP tests

Aaron Ruby (46):
  gfxstream: function table: remove entry points that are hand-written.
  gfxstream: function table: more changes
  gfxstream: function table: scope internal_arrays to encoder
  gfxstream: function table: autogenerate compoundType params
  gfxstream: add handwritten EnumeratePhysicalDeviceGroup entrypoint.
  gfxstream: function table: handle nested handle arrays
  gfxstream: function table: adding some handwritten implementations
  gfxstream: revert some unnecessary changes
  gfxstream: use vk_object_zalloc/free instead of vk_zalloc/free.
  gfxstream: revert most gfxstream objects to use vk_object_base
  gfxstream: function table: handwritten commmand-buffers/pools
  gfxstream: codegen functionality to handle special param
  gfxstream: function table: random fixes
  gfxstream: add vk_command_buffer_ops handlers
  gfxstream: func_table.py: Codegen support for nested compound type
  gfxstream: remove handwritten/add autogen entry points
  gfxstream: add gfxstream_vk_device.cpp
  gfxstream: query device and instance extensions early
  gfxstream: func_table: explicit allocation for nested arrays/compound
    types
  gfxstream: goldfish_vulkan: fix commandBuffer allocation.
  gfxstream: meson: Raise api_version in ICD config to 1.1.
  gfxstream: function table: add more handwritten entries
  gfxstream: goldfish_vulkan: update VkDescriptorSetAllocateInfo logic
  gfxstream: function table: NULL check on internal_object dereference
  gfxstream: function table: Remove POSTPROCESSES handling from
    functable
  gfxstream: mesa: Add 'gfxstream' as a -Dvulkan-drivers
  gfxstream: ResourceTracker: add some allowedExtensions
  gfxstream: gfxstream_vk_device: add wsi_common_entrypoints
  gfxstream: Move instance handling into gfxstream_vk_device.cpp
  gfxstream: ResourceTracker: Enable Linux WSI-related extensions
  gfxstream: wsi: add wsi_device initialization
  gfxstream: gfxstream_vk_device: use Mesa common physical device
    management
  gfxstream: ResourceTracker: translate mesa objects in user buffer
  gfxstream: exclude VkSampler and VkDescriptorSet objects from
    translation
  gfxstream: Add guest-side external memory support with colorBuffers.
  gfxstream: function table: Modify semaphoreList inputs to no-op
    semaphores
  gfxstream: function table: Allow VK_NULL_HANDLE for free/destroy APIs.
  gfxstream: cereal: Add VK_EXT_depth_clip_enable as supported feature.
  gfxstream: vulkan_enc: un-namespace vk_util.h and vk_struct_id.h
  gfxstream: gfxstream_vk_device.cpp: Support VK_KHR_surface and
    VK_*_surface
  gfxstream: vulkan_enc: Add support for Mesa-only extensions.
  gfxstream: ResourceTracker: Use DEVICE_TYPE_VIRTUAL_GPU always
  gfxstream: platform: add dma-buf export support with dedicatedBuffer.
  gfxstream: ResourceTracker: add VK_EXT_depth_clip_enable allowed
    extension
  gfxstream: ResourceTracker: external memory via QNX_screen_buffer
    extension
  gfxstream: Add VK_QNX_external_memory_screen_buffer to VulkanDispatch

Gurchetan Singh (18):
  gfxstream: mesa: write Android.bp files
  gfxstream: generate gfxstream_vk_entrypoints.{c, h}
  gfxstream: vulkan_enc: add gfxstream_vk_private.h (objects)
  gfxstream: function table: modify function table to use gfxstream_vk_*
  gfxstream: compiles
  gfxstream: build system improvements
  gfxstream: ResourceTracker: don't crash without
    VkBindImageMemorySwapchainInfoKHR
  gfxstream: vk.xml: make some vkAcquireImageANDROID params optional
  gfxstream_vk_device: filter out swapchain maintenance guest side
  gfxstream: end2end: fixes for End2End tests
  gfxstream: func_table: custom vkEnumerateInstanceLayerProperties
  gfxstream: add VK_EXT_DEBUG_UTILS_EXTENSION_NAME into Mesa list
  gfxstream: clang-format guest code
  gfxstream: libandroid AEMU static
  gfxstream: vkEnumerateInstanceVersion
  gfxstream: vkCreateComputePipeLines
  gfxstream: make end2end tests happy
  gfxstream: delete prior vk.xml, vk_icd_gen.py

Change-Id: Ic4cc50d5098dddd77c9265afa8f432a2fdea8845
diff --git a/guest/vulkan_enc/Android.bp b/guest/vulkan_enc/Android.bp
index 09cd26e..031ebad 100644
--- a/guest/vulkan_enc/Android.bp
+++ b/guest/vulkan_enc/Android.bp
@@ -19,46 +19,69 @@
     default_applicable_licenses: ["hardware_google_gfxstream_license"],
 }
 
+genrule {
+    name: "gfxstream_vk_entrypoints_header",
+    srcs: [":libmesa_vulkan_xml"],
+    out: ["gfxstream_vk_entrypoints.h"],
+    tools: ["vk_entrypoints_gen"],
+    cmd: "python3 $(location vk_entrypoints_gen) --xml " +
+        "$(location :libmesa_vulkan_xml) --proto --weak --out-h " +
+        "$(location gfxstream_vk_entrypoints.h) --out-c " +
+        "$(genDir)/placeholder.c --prefix gfxstream_vk --beta false",
+}
 
-cc_defaults {
-    name: "libgfxstream_guest_vulkan_encoder_defaults",
+genrule {
+    name: "gfxstream_vk_entrypoints_impl",
+    srcs: [":libmesa_vulkan_xml"],
+    out: ["gfxstream_vk_entrypoints.c"],
+    tools: ["vk_entrypoints_gen"],
+    cmd: "python3 $(location vk_entrypoints_gen) --xml " +
+        "$(location :libmesa_vulkan_xml) --proto --weak --out-h " +
+        "$(genDir)/gfxstream_vk_entrypoints.h --out-c " +
+        "$(location gfxstream_vk_entrypoints.c) --prefix gfxstream_vk " +
+        "--beta false",
+}
+
+cc_library_static {
+    name: "libgfxstream_guest_vulkan_entrypoints",
     host_supported: true,
     vendor: true,
     defaults: [
-        "libgfxstream_guest_cc_defaults",
+        "mesa_common_defaults_gfxstream",
     ],
     header_libs: [
-        "gfxstream_vulkan_headers",
-        "libgfxstream_guest_graphics_headers",
-        "libgfxstream_guest_iostream",
-        "libnativewindow_headers",
-    ],
-    shared_libs: [
-        "libandroidemu",
-        "libcutils",
-        "liblog",
-        "libOpenglCodecCommon",
-        "lib_renderControl_enc",
+        "mesa_common_headers_gfxstream",
     ],
     static_libs: [
-        "libarect",
-        "libdrm",
-        "libGoldfishAddressSpace",
-        "libgfxstream_guest_gralloc",
+        "libmesa_vulkan_util_gfxstream",
     ],
-    cflags: [
-        "-DLOG_TAG=\"goldfish_vulkan\"",
-        "-DVIRTIO_GPU",
-        "-DVK_ANDROID_native_buffer",
-        "-DVK_EXT_device_memory_report",
-        "-DVK_GOOGLE_gfxstream",
-        "-DVK_NO_PROTOTYPES",
-        "-DVK_USE_PLATFORM_ANDROID_KHR",
-        "-fstrict-aliasing",
-        "-Werror",
-        "-Wno-missing-field-initializers",
-        "-Wno-unused-parameter",
+    shared_libs: [
+        "libcutils",
     ],
+    generated_headers: [
+        "gfxstream_vk_entrypoints_header",
+    ],
+    generated_sources: [
+        "gfxstream_vk_entrypoints_impl",
+    ],
+    ldflags: [
+        "-Wl,-Bsymbolic",
+        "-Wl,--gc-sections",
+    ],
+    export_generated_headers: [
+        "gfxstream_vk_entrypoints_header",
+    ],
+}
+
+cc_library_headers {
+    name: "vulkan_enc_headers",
+    export_include_dirs: ["."],
+    host_supported: true,
+    vendor_available: true,
+}
+
+filegroup {
+    name: "vulkan_enc_impl",
     srcs: [
         "AndroidHardwareBuffer.cpp",
         "CommandBufferStagingStream.cpp",
@@ -77,10 +100,76 @@
         "VkEncoder.cpp",
         "VulkanHandleMapping.cpp",
         "VulkanStreamGuest.cpp",
+        "gfxstream_vk_private.cpp",
+    ],
+}
+
+cc_defaults {
+    name: "libgfxstream_guest_vulkan_encoder_defaults",
+    host_supported: true,
+    vendor: true,
+    defaults: [
+        "libgfxstream_guest_cc_defaults",
+    ],
+    header_libs: [
+        "gfxstream_vulkan_headers",
+        "libgfxstream_guest_iostream",
+        "libnativewindow_headers",
+        "mesa_common_headers_gfxstream",
+    ],
+    generated_headers: [
+        "vk_cmd_queue_header",
+        "vk_physical_device_features_header",
+        "vk_physical_device_properties_header",
+        "u_format_pack_header",
+    ],
+    shared_libs: [
+        "libcutils",
+        "liblog",
+        "libOpenglCodecCommon",
+    ],
+    static_libs: [
+        "libarect",
+        "libdrm",
+        "libandroidemu_static",
+        "libGoldfishAddressSpace",
+        "libgfxstream_guest_gralloc",
+        "libmesa_vulkan_util_gfxstream",
+        "libmesa_vulkan_runtime_gfxstream",
+        "libgfxstream_guest_vulkan_entrypoints",
+        "libmesa_util_gfxstream",
+        "libmesa_util_format_gfxstream",
+        "libmesa_util_c11_gfxstream",
+    ],
+    cflags: [
+        "-DLOG_TAG=\"goldfish_vulkan\"",
+        "-DVIRTIO_GPU",
+        "-DVK_ANDROID_native_buffer",
+        "-DVK_EXT_device_memory_report",
+        "-DVK_GOOGLE_gfxstream",
+        "-DVK_NO_PROTOTYPES",
+        "-DVK_USE_PLATFORM_ANDROID_KHR",
+        "-fstrict-aliasing",
+        "-Werror",
+        "-Wno-missing-field-initializers",
+        "-Wno-unused-parameter",
+        "-DHAVE_PTHREAD=1",
+        "-DHAVE_TIMESPEC_GET",
+        "-DHAVE_STRUCT_TIMESPEC",
+    ],
+    srcs: [
+        ":vulkan_enc_impl",
     ],
     export_include_dirs: [
         ".",
     ],
+    ldflags: [
+        // Mesa always adds Bsymbolic when available (see 'ld_args_bsymbolic' in Meson build). Duplicate that
+        // behavior here. '--gc-sections' has stronger justification: this lets drivers drop
+        // shared code unused by that specific driver (particularly relevant for Vulkan drivers).
+        "-Wl,-Bsymbolic",
+        "-Wl,--gc-sections",
+    ],
     target: {
         android: {
             shared_libs: [
@@ -89,11 +178,11 @@
             header_libs: [
                 "hwvulkan_headers",
             ],
-        }
-    }
+        },
+    },
 }
 
-cc_library_shared {
+cc_library_static {
     name: "libvulkan_enc",
     defaults: [
         "libgfxstream_guest_vulkan_encoder_defaults",
@@ -103,16 +192,14 @@
     ],
 }
 
-cc_library_shared {
+cc_library_static {
     name: "libgfxstream_guest_vulkan_encoder_with_host",
     defaults: [
         "libgfxstream_guest_vulkan_encoder_defaults",
     ],
     shared_libs: [
-        "libgfxstream_backend",
-    ],
-    static_libs: [
         "libplatform_rutabaga",
+        "libgfxstream_backend",
     ],
     target: {
         host: {
diff --git a/guest/vulkan_enc/AndroidHardwareBuffer.cpp b/guest/vulkan_enc/AndroidHardwareBuffer.cpp
index 3f0c34a..eac0caf 100644
--- a/guest/vulkan_enc/AndroidHardwareBuffer.cpp
+++ b/guest/vulkan_enc/AndroidHardwareBuffer.cpp
@@ -21,11 +21,11 @@
 #endif
 #endif
 
-#include "../OpenglSystemCommon/HostConnection.h"
+#include <assert.h>
 
+#include "../OpenglSystemCommon/HostConnection.h"
 #include "vk_format_info.h"
 #include "vk_util.h"
-#include <assert.h>
 
 namespace gfxstream {
 namespace vk {
@@ -34,36 +34,28 @@
 /* Construct ahw usage mask from image usage bits, see
  * 'AHardwareBuffer Usage Equivalence' in Vulkan spec.
  */
-uint64_t
-getAndroidHardwareBufferUsageFromVkUsage(const VkImageCreateFlags vk_create,
-                                 const VkImageUsageFlags vk_usage)
-{
-   uint64_t ahw_usage = 0;
+uint64_t getAndroidHardwareBufferUsageFromVkUsage(const VkImageCreateFlags vk_create,
+                                                  const VkImageUsageFlags vk_usage) {
+    uint64_t ahw_usage = 0;
 
-   if (vk_usage & VK_IMAGE_USAGE_SAMPLED_BIT)
-      ahw_usage |= AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
+    if (vk_usage & VK_IMAGE_USAGE_SAMPLED_BIT) ahw_usage |= AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
 
-   if (vk_usage & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)
-      ahw_usage |= AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
+    if (vk_usage & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)
+        ahw_usage |= AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
 
-   if (vk_usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)
-      ahw_usage |= AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT;
+    if (vk_usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)
+        ahw_usage |= AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT;
 
-   if (vk_create & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT)
-      ahw_usage |= AHARDWAREBUFFER_USAGE_GPU_CUBE_MAP;
+    if (vk_create & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT)
+        ahw_usage |= AHARDWAREBUFFER_USAGE_GPU_CUBE_MAP;
 
-   if (vk_create & VK_IMAGE_CREATE_PROTECTED_BIT)
-      ahw_usage |= AHARDWAREBUFFER_USAGE_PROTECTED_CONTENT;
+    if (vk_create & VK_IMAGE_CREATE_PROTECTED_BIT)
+        ahw_usage |= AHARDWAREBUFFER_USAGE_PROTECTED_CONTENT;
 
-   /* No usage bits set - set at least one GPU usage. */
-   if (ahw_usage == 0)
-      ahw_usage = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
+    /* No usage bits set - set at least one GPU usage. */
+    if (ahw_usage == 0) ahw_usage = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
 
-   return ahw_usage;
-}
-
-void updateMemoryTypeBits(uint32_t* memoryTypeBits, uint32_t colorBufferMemoryIndex) {
-   *memoryTypeBits = 1u << colorBufferMemoryIndex;
+    return ahw_usage;
 }
 
 VkResult getAndroidHardwareBufferPropertiesANDROID(
@@ -74,45 +66,45 @@
 
     const auto format = grallocHelper->getFormat(buffer);
     if (ahbFormatProps) {
-        switch(format) {
+        switch (format) {
             case AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM:
-                  ahbFormatProps->format = VK_FORMAT_R8G8B8A8_UNORM;
-                  break;
+                ahbFormatProps->format = VK_FORMAT_R8G8B8A8_UNORM;
+                break;
             case AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM:
-                  ahbFormatProps->format = VK_FORMAT_R8G8B8A8_UNORM;
-                  break;
+                ahbFormatProps->format = VK_FORMAT_R8G8B8A8_UNORM;
+                break;
             case AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM:
-                  ahbFormatProps->format = VK_FORMAT_R8G8B8_UNORM;
-                  break;
+                ahbFormatProps->format = VK_FORMAT_R8G8B8_UNORM;
+                break;
             case AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM:
-                  ahbFormatProps->format = VK_FORMAT_R5G6B5_UNORM_PACK16;
-                  break;
+                ahbFormatProps->format = VK_FORMAT_R5G6B5_UNORM_PACK16;
+                break;
             case AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT:
-                  ahbFormatProps->format = VK_FORMAT_R16G16B16A16_SFLOAT;
-                  break;
+                ahbFormatProps->format = VK_FORMAT_R16G16B16A16_SFLOAT;
+                break;
             case AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM:
-                  ahbFormatProps->format = VK_FORMAT_A2B10G10R10_UNORM_PACK32;
-                  break;
+                ahbFormatProps->format = VK_FORMAT_A2B10G10R10_UNORM_PACK32;
+                break;
             case AHARDWAREBUFFER_FORMAT_D16_UNORM:
-                  ahbFormatProps->format = VK_FORMAT_D16_UNORM;
-                  break;
+                ahbFormatProps->format = VK_FORMAT_D16_UNORM;
+                break;
             case AHARDWAREBUFFER_FORMAT_D24_UNORM:
-                  ahbFormatProps->format = VK_FORMAT_X8_D24_UNORM_PACK32;
-                  break;
+                ahbFormatProps->format = VK_FORMAT_X8_D24_UNORM_PACK32;
+                break;
             case AHARDWAREBUFFER_FORMAT_D24_UNORM_S8_UINT:
-                  ahbFormatProps->format = VK_FORMAT_D24_UNORM_S8_UINT;
-                  break;
+                ahbFormatProps->format = VK_FORMAT_D24_UNORM_S8_UINT;
+                break;
             case AHARDWAREBUFFER_FORMAT_D32_FLOAT:
-                  ahbFormatProps->format = VK_FORMAT_D32_SFLOAT;
-                  break;
+                ahbFormatProps->format = VK_FORMAT_D32_SFLOAT;
+                break;
             case AHARDWAREBUFFER_FORMAT_D32_FLOAT_S8_UINT:
-                  ahbFormatProps->format = VK_FORMAT_D32_SFLOAT_S8_UINT;
-                  break;
+                ahbFormatProps->format = VK_FORMAT_D32_SFLOAT_S8_UINT;
+                break;
             case AHARDWAREBUFFER_FORMAT_S8_UINT:
-                  ahbFormatProps->format = VK_FORMAT_S8_UINT;
-                  break;
+                ahbFormatProps->format = VK_FORMAT_S8_UINT;
+                break;
             default:
-                  ahbFormatProps->format = VK_FORMAT_UNDEFINED;
+                ahbFormatProps->format = VK_FORMAT_UNDEFINED;
         }
         ahbFormatProps->externalFormat = format;
 
@@ -128,10 +120,8 @@
         // VK_FORMAT_FEATURE_TRANSFER_DST_BIT
         // VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT
         ahbFormatProps->formatFeatures =
-            VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT |
-            VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT |
-            VK_FORMAT_FEATURE_TRANSFER_SRC_BIT |
-            VK_FORMAT_FEATURE_TRANSFER_DST_BIT |
+            VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT |
+            VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT |
             VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT;
 
         // "Implementations may not always be able to determine the color model,
@@ -166,7 +156,8 @@
                 //  * U (CB) comes from the B-channel (after swizzle)
                 //  * V (CR) comes from the R-channel (after swizzle)
                 //
-                // See https://www.khronos.org/registry/vulkan/specs/1.3-extensions/html/vkspec.html#textures-sampler-YCbCr-conversion
+                // See
+                // https://www.khronos.org/registry/vulkan/specs/1.3-extensions/html/vkspec.html#textures-sampler-YCbCr-conversion
                 //
                 // To match the above, the guest needs to swizzle such that:
                 //
@@ -204,10 +195,9 @@
 #endif
 #endif
 
-        ahbFormatProps->suggestedYcbcrModel =
-            android_format_is_yuv(format) ?
-                VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_601 :
-                VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY;
+        ahbFormatProps->suggestedYcbcrModel = android_format_is_yuv(format)
+                                                  ? VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_601
+                                                  : VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY;
         ahbFormatProps->suggestedYcbcrRange = VK_SAMPLER_YCBCR_RANGE_ITU_FULL;
 
         ahbFormatProps->suggestedXChromaOffset = VK_CHROMA_LOCATION_MIDPOINT;
@@ -281,26 +271,24 @@
 
     /* If caller passed dedicated information. */
     if (hasDedicatedImage) {
-       w = imageExtent.width;
-       h = imageExtent.height;
-       layers = imageLayers;
-       format = android_format_from_vk(imageFormat);
-       usage = getAndroidHardwareBufferUsageFromVkUsage(imageCreateFlags, imageUsage);
+        w = imageExtent.width;
+        h = imageExtent.height;
+        layers = imageLayers;
+        format = android_format_from_vk(imageFormat);
+        usage = getAndroidHardwareBufferUsageFromVkUsage(imageCreateFlags, imageUsage);
     } else if (hasDedicatedBuffer) {
-       w = bufferSize;
-       format = AHARDWAREBUFFER_FORMAT_BLOB;
-       usage = AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN |
-               AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN |
-               AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER;
+        w = bufferSize;
+        format = AHARDWAREBUFFER_FORMAT_BLOB;
+        usage = AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN | AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN |
+                AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER;
     } else {
-       w = allocationInfoAllocSize;
-       format = AHARDWAREBUFFER_FORMAT_BLOB;
-       usage = AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN |
-               AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN |
-               AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER;
+        w = allocationInfoAllocSize;
+        format = AHARDWAREBUFFER_FORMAT_BLOB;
+        usage = AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN | AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN |
+                AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER;
     }
 
-    struct AHardwareBuffer *ahb = NULL;
+    struct AHardwareBuffer* ahb = NULL;
 
     if (gralloc->allocate(w, h, format, usage, &ahb) != 0) {
         return VK_ERROR_OUT_OF_HOST_MEMORY;
diff --git a/guest/vulkan_enc/AndroidHardwareBuffer.h b/guest/vulkan_enc/AndroidHardwareBuffer.h
index b4085b6..0389f09 100644
--- a/guest/vulkan_enc/AndroidHardwareBuffer.h
+++ b/guest/vulkan_enc/AndroidHardwareBuffer.h
@@ -25,10 +25,8 @@
 namespace gfxstream {
 namespace vk {
 
-uint64_t
-getAndroidHardwareBufferUsageFromVkUsage(
-    const VkImageCreateFlags vk_create,
-    const VkImageUsageFlags vk_usage);
+uint64_t getAndroidHardwareBufferUsageFromVkUsage(const VkImageCreateFlags vk_create,
+                                                  const VkImageUsageFlags vk_usage);
 
 void updateMemoryTypeBits(uint32_t* memoryTypeBits, uint32_t colorBufferMemoryIndex);
 
diff --git a/guest/vulkan_enc/CommandBufferStagingStream.cpp b/guest/vulkan_enc/CommandBufferStagingStream.cpp
index 1f57387..63db2fa 100644
--- a/guest/vulkan_enc/CommandBufferStagingStream.cpp
+++ b/guest/vulkan_enc/CommandBufferStagingStream.cpp
@@ -1,18 +1,18 @@
 /*
-* Copyright (C) 2021 The Android Open Source Project
-*
-* 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.
-*/
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * 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.
+ */
 #include "CommandBufferStagingStream.h"
 
 #if PLATFORM_SDK_VERSION < 26
@@ -204,37 +204,33 @@
     return (void*)(getDataPtr() + m_writePos);
 }
 
-int CommandBufferStagingStream::commitBuffer(size_t size)
-{
+int CommandBufferStagingStream::commitBuffer(size_t size) {
     m_writePos += size;
     return 0;
 }
 
-const unsigned char *CommandBufferStagingStream::readFully(void*, size_t) {
+const unsigned char* CommandBufferStagingStream::readFully(void*, size_t) {
     // Not supported
     ALOGE("CommandBufferStagingStream::%s: Fatal: not supported\n", __func__);
     abort();
     return nullptr;
 }
 
-const unsigned char *CommandBufferStagingStream::read(void*, size_t*) {
+const unsigned char* CommandBufferStagingStream::read(void*, size_t*) {
     // Not supported
     ALOGE("CommandBufferStagingStream::%s: Fatal: not supported\n", __func__);
     abort();
     return nullptr;
 }
 
-int CommandBufferStagingStream::writeFully(const void*, size_t)
-{
+int CommandBufferStagingStream::writeFully(const void*, size_t) {
     // Not supported
     ALOGE("CommandBufferStagingStream::%s: Fatal: not supported\n", __func__);
     abort();
     return 0;
 }
 
-const unsigned char *CommandBufferStagingStream::commitBufferAndReadFully(
-    size_t, void *, size_t) {
-
+const unsigned char* CommandBufferStagingStream::commitBufferAndReadFully(size_t, void*, size_t) {
     // Not supported
     ALOGE("CommandBufferStagingStream::%s: Fatal: not supported\n", __func__);
     abort();
diff --git a/guest/vulkan_enc/CommandBufferStagingStream.h b/guest/vulkan_enc/CommandBufferStagingStream.h
index 8e754b7..45af8dc 100644
--- a/guest/vulkan_enc/CommandBufferStagingStream.h
+++ b/guest/vulkan_enc/CommandBufferStagingStream.h
@@ -1,18 +1,18 @@
 /*
-* Copyright (C) 2021 The Android Open Source Project
-*
-* 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.
-*/
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * 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.
+ */
 #ifndef __COMMAND_BUFFER_STAGING_STREAM_H
 #define __COMMAND_BUFFER_STAGING_STREAM_H
 
@@ -26,91 +26,91 @@
 namespace vk {
 
 class CommandBufferStagingStream : public gfxstream::guest::IOStream {
-public:
- // host will write kSyncDataReadComplete to the sync bytes to indicate memory is no longer being
- // used by host. This is only used with custom allocators. The sync bytes are used to ensure that,
- // during reallocations the guest does not free memory being read by the host. The guest ensures
- // that the sync bytes are marked as read complete before releasing the memory.
- static constexpr size_t kSyncDataSize = 8;
- // indicates read is complete
- static constexpr uint32_t kSyncDataReadComplete = 0X0;
- // indicates read is pending
- static constexpr uint32_t kSyncDataReadPending = 0X1;
+   public:
+    // host will write kSyncDataReadComplete to the sync bytes to indicate memory is no longer being
+    // used by host. This is only used with custom allocators. The sync bytes are used to ensure
+    // that, during reallocations the guest does not free memory being read by the host. The guest
+    // ensures that the sync bytes are marked as read complete before releasing the memory.
+    static constexpr size_t kSyncDataSize = 8;
+    // indicates read is complete
+    static constexpr uint32_t kSyncDataReadComplete = 0X0;
+    // indicates read is pending
+    static constexpr uint32_t kSyncDataReadPending = 0X1;
 
- // \struct backing memory structure
- struct Memory {
-     VkDeviceMemory deviceMemory =
-         VK_NULL_HANDLE;                   // device memory associated with allocated memory
-     void* ptr = nullptr;                  // pointer to allocated memory
-     bool operator==(const Memory& rhs) const {
-         return (deviceMemory == rhs.deviceMemory) && (ptr == rhs.ptr);
-     }
- };
+    // \struct backing memory structure
+    struct Memory {
+        VkDeviceMemory deviceMemory =
+            VK_NULL_HANDLE;   // device memory associated with allocated memory
+        void* ptr = nullptr;  // pointer to allocated memory
+        bool operator==(const Memory& rhs) const {
+            return (deviceMemory == rhs.deviceMemory) && (ptr == rhs.ptr);
+        }
+    };
 
- // allocator
- // param size to allocate
- // return allocated memory
- using Alloc = std::function<Memory(size_t)>;
- // free function
- // param memory to free
- using Free = std::function<void(const Memory&)>;
- // constructor
- // \param allocFn is the allocation function provided.
- // \param freeFn is the free function provided
- explicit CommandBufferStagingStream(const Alloc& allocFn, const Free& freeFn);
- // constructor
- explicit CommandBufferStagingStream();
- ~CommandBufferStagingStream();
+    // allocator
+    // param size to allocate
+    // return allocated memory
+    using Alloc = std::function<Memory(size_t)>;
+    // free function
+    // param memory to free
+    using Free = std::function<void(const Memory&)>;
+    // constructor
+    // \param allocFn is the allocation function provided.
+    // \param freeFn is the free function provided
+    explicit CommandBufferStagingStream(const Alloc& allocFn, const Free& freeFn);
+    // constructor
+    explicit CommandBufferStagingStream();
+    ~CommandBufferStagingStream();
 
- virtual size_t idealAllocSize(size_t len);
- virtual void* allocBuffer(size_t minSize);
- virtual int commitBuffer(size_t size);
- virtual const unsigned char* readFully(void* buf, size_t len);
- virtual const unsigned char* read(void* buf, size_t* inout_len);
- virtual int writeFully(const void* buf, size_t len);
- virtual const unsigned char* commitBufferAndReadFully(size_t size, void* buf, size_t len);
+    virtual size_t idealAllocSize(size_t len);
+    virtual void* allocBuffer(size_t minSize);
+    virtual int commitBuffer(size_t size);
+    virtual const unsigned char* readFully(void* buf, size_t len);
+    virtual const unsigned char* read(void* buf, size_t* inout_len);
+    virtual int writeFully(const void* buf, size_t len);
+    virtual const unsigned char* commitBufferAndReadFully(size_t size, void* buf, size_t len);
 
- void getWritten(unsigned char** bufOut, size_t* sizeOut);
- void reset();
+    void getWritten(unsigned char** bufOut, size_t* sizeOut);
+    void reset();
 
- // marks the command buffer stream as flushing. The owner of CommandBufferStagingStream
- // should call markFlushing after finishing writing to the stream.
- // This will mark the sync data to kSyncDataReadPending. This is only applicable when
- // using custom allocators. markFlushing will be a no-op if called
- // when not using custom allocators
- void markFlushing();
+    // marks the command buffer stream as flushing. The owner of CommandBufferStagingStream
+    // should call markFlushing after finishing writing to the stream.
+    // This will mark the sync data to kSyncDataReadPending. This is only applicable when
+    // using custom allocators. markFlushing will be a no-op if called
+    // when not using custom allocators
+    void markFlushing();
 
- // gets the device memory associated with the stream. This is VK_NULL_HANDLE for default allocation
- // \return device memory
- VkDeviceMemory getDeviceMemory();
+    // gets the device memory associated with the stream. This is VK_NULL_HANDLE for default
+    // allocation \return device memory
+    VkDeviceMemory getDeviceMemory();
 
-private:
- // underlying memory for data
- Memory m_mem;
- // size of portion of memory available for data.
- // for custom allocation, this size excludes size of sync data.
- size_t m_size;
- // current write position in data buffer
- uint32_t m_writePos;
+   private:
+    // underlying memory for data
+    Memory m_mem;
+    // size of portion of memory available for data.
+    // for custom allocation, this size excludes size of sync data.
+    size_t m_size;
+    // current write position in data buffer
+    uint32_t m_writePos;
 
- // alloc function
- Alloc m_alloc;
- // free function
- Free m_free;
+    // alloc function
+    Alloc m_alloc;
+    // free function
+    Free m_free;
 
- // realloc function
- // \param size of memory to be allocated
- // \ param reference size to update with actual size allocated. This size can be < requested size
- // for custom allocation to account for sync data
- using Realloc = std::function<Memory(const Memory&, size_t)>;
- Realloc m_realloc;
+    // realloc function
+    // \param size of memory to be allocated
+    // \ param reference size to update with actual size allocated. This size can be < requested
+    // size for custom allocation to account for sync data
+    using Realloc = std::function<Memory(const Memory&, size_t)>;
+    Realloc m_realloc;
 
- // flag tracking use of custom allocation/free
- bool m_usingCustomAlloc = false;
+    // flag tracking use of custom allocation/free
+    bool m_usingCustomAlloc = false;
 
- // adjusted memory location to point to start of data after accounting for metadata
- // \return pointer to data start
- unsigned char* getDataPtr();
+    // adjusted memory location to point to start of data after accounting for metadata
+    // \return pointer to data start
+    unsigned char* getDataPtr();
 };
 
 }  // namespace vk
diff --git a/guest/vulkan_enc/DescriptorSetVirtualization.cpp b/guest/vulkan_enc/DescriptorSetVirtualization.cpp
index fa0cb78..d2389a4 100644
--- a/guest/vulkan_enc/DescriptorSetVirtualization.cpp
+++ b/guest/vulkan_enc/DescriptorSetVirtualization.cpp
@@ -13,6 +13,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 #include "DescriptorSetVirtualization.h"
+
 #include "Resources.h"
 
 namespace gfxstream {
@@ -27,7 +28,8 @@
     set->pendingWriteArrayRanges.clear();
 }
 
-void initDescriptorWriteTable(const std::vector<VkDescriptorSetLayoutBinding>& layoutBindings, DescriptorWriteTable& table) {
+void initDescriptorWriteTable(const std::vector<VkDescriptorSetLayoutBinding>& layoutBindings,
+                              DescriptorWriteTable& table) {
     uint32_t highestBindingNumber = 0;
 
     for (uint32_t i = 0; i < layoutBindings.size(); ++i) {
@@ -39,8 +41,7 @@
     std::vector<uint32_t> countsEachBinding(highestBindingNumber + 1, 0);
 
     for (uint32_t i = 0; i < layoutBindings.size(); ++i) {
-        countsEachBinding[layoutBindings[i].binding] =
-            layoutBindings[i].descriptorCount;
+        countsEachBinding[layoutBindings[i].binding] = layoutBindings[i].descriptorCount;
     }
 
     table.resize(countsEachBinding.size());
@@ -55,8 +56,8 @@
     }
 }
 
-static void initializeReifiedDescriptorSet(VkDescriptorPool pool, VkDescriptorSetLayout setLayout, ReifiedDescriptorSet* set) {
-
+static void initializeReifiedDescriptorSet(VkDescriptorPool pool, VkDescriptorSetLayout setLayout,
+                                           ReifiedDescriptorSet* set) {
     set->pendingWriteArrayRanges.clear();
 
     const auto& layoutInfo = *(as_goldfish_VkDescriptorSetLayout(setLayout)->layoutInfo);
@@ -73,8 +74,7 @@
         set->bindingIsImmutableSampler[bindingIndex] =
             binding.descriptorCount > 0 &&
             (binding.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER ||
-             binding.descriptorType ==
-             VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) &&
+             binding.descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) &&
             binding.pImmutableSamplers;
     }
 
@@ -185,7 +185,8 @@
     }
 }
 
-void doEmulatedDescriptorCopy(const VkCopyDescriptorSet* copy, const ReifiedDescriptorSet* src, ReifiedDescriptorSet* dst) {
+void doEmulatedDescriptorCopy(const VkCopyDescriptorSet* copy, const ReifiedDescriptorSet* src,
+                              ReifiedDescriptorSet* dst) {
     const DescriptorWriteTable& srcTable = src->allWrites;
     DescriptorWriteTable& dstTable = dst->allWrites;
 
@@ -214,14 +215,10 @@
     }
 }
 
-void doEmulatedDescriptorImageInfoWriteFromTemplate(
-    VkDescriptorType descType,
-    uint32_t binding,
-    uint32_t dstArrayElement,
-    uint32_t count,
-    const VkDescriptorImageInfo* imageInfos,
-    ReifiedDescriptorSet* set) {
-
+void doEmulatedDescriptorImageInfoWriteFromTemplate(VkDescriptorType descType, uint32_t binding,
+                                                    uint32_t dstArrayElement, uint32_t count,
+                                                    const VkDescriptorImageInfo* imageInfos,
+                                                    ReifiedDescriptorSet* set) {
     DescriptorWriteTable& table = set->allWrites;
 
     uint32_t currBinding = binding;
@@ -239,14 +236,10 @@
     }
 }
 
-void doEmulatedDescriptorBufferInfoWriteFromTemplate(
-    VkDescriptorType descType,
-    uint32_t binding,
-    uint32_t dstArrayElement,
-    uint32_t count,
-    const VkDescriptorBufferInfo* bufferInfos,
-    ReifiedDescriptorSet* set) {
-
+void doEmulatedDescriptorBufferInfoWriteFromTemplate(VkDescriptorType descType, uint32_t binding,
+                                                     uint32_t dstArrayElement, uint32_t count,
+                                                     const VkDescriptorBufferInfo* bufferInfos,
+                                                     ReifiedDescriptorSet* set) {
     DescriptorWriteTable& table = set->allWrites;
 
     uint32_t currBinding = binding;
@@ -264,14 +257,10 @@
     }
 }
 
-void doEmulatedDescriptorBufferViewWriteFromTemplate(
-    VkDescriptorType descType,
-    uint32_t binding,
-    uint32_t dstArrayElement,
-    uint32_t count,
-    const VkBufferView* bufferViews,
-    ReifiedDescriptorSet* set) {
-
+void doEmulatedDescriptorBufferViewWriteFromTemplate(VkDescriptorType descType, uint32_t binding,
+                                                     uint32_t dstArrayElement, uint32_t count,
+                                                     const VkBufferView* bufferViews,
+                                                     ReifiedDescriptorSet* set) {
     DescriptorWriteTable& table = set->allWrites;
 
     uint32_t currBinding = binding;
@@ -305,22 +294,19 @@
 static bool isBindingFeasibleForAlloc(
     const DescriptorPoolAllocationInfo::DescriptorCountInfo& countInfo,
     const VkDescriptorSetLayoutBinding& binding) {
-
     if (binding.descriptorCount && (countInfo.type != binding.descriptorType)) {
         return false;
     }
 
-    uint32_t availDescriptorCount =
-        countInfo.descriptorCount - countInfo.used;
+    uint32_t availDescriptorCount = countInfo.descriptorCount - countInfo.used;
 
     if (availDescriptorCount < binding.descriptorCount) {
-        ALOGV("%s: Ran out of descriptors of type 0x%x. "
-              "Wanted %u from layout but "
-              "we only have %u free (total in pool: %u)\n", __func__,
-              binding.descriptorType,
-              binding.descriptorCount,
-              countInfo.descriptorCount - countInfo.used,
-              countInfo.descriptorCount);
+        ALOGV(
+            "%s: Ran out of descriptors of type 0x%x. "
+            "Wanted %u from layout but "
+            "we only have %u free (total in pool: %u)\n",
+            __func__, binding.descriptorType, binding.descriptorCount,
+            countInfo.descriptorCount - countInfo.used, countInfo.descriptorCount);
         return false;
     }
 
@@ -330,31 +316,27 @@
 static bool isBindingFeasibleForFree(
     const DescriptorPoolAllocationInfo::DescriptorCountInfo& countInfo,
     const VkDescriptorSetLayoutBinding& binding) {
-
     if (countInfo.type != binding.descriptorType) return false;
     if (countInfo.used < binding.descriptorCount) {
-        ALOGV("%s: Was a descriptor set double freed? "
-              "Ran out of descriptors of type 0x%x. "
-              "Wanted to free %u from layout but "
-              "we only have %u used (total in pool: %u)\n", __func__,
-              binding.descriptorType,
-              binding.descriptorCount,
-              countInfo.used,
-              countInfo.descriptorCount);
+        ALOGV(
+            "%s: Was a descriptor set double freed? "
+            "Ran out of descriptors of type 0x%x. "
+            "Wanted to free %u from layout but "
+            "we only have %u used (total in pool: %u)\n",
+            __func__, binding.descriptorType, binding.descriptorCount, countInfo.used,
+            countInfo.descriptorCount);
         return false;
     }
     return true;
 }
 
-static void allocBindingFeasible(
-    const VkDescriptorSetLayoutBinding& binding,
-    DescriptorPoolAllocationInfo::DescriptorCountInfo& poolState) {
+static void allocBindingFeasible(const VkDescriptorSetLayoutBinding& binding,
+                                 DescriptorPoolAllocationInfo::DescriptorCountInfo& poolState) {
     poolState.used += binding.descriptorCount;
 }
 
-static void freeBindingFeasible(
-    const VkDescriptorSetLayoutBinding& binding,
-    DescriptorPoolAllocationInfo::DescriptorCountInfo& poolState) {
+static void freeBindingFeasible(const VkDescriptorSetLayoutBinding& binding,
+                                DescriptorPoolAllocationInfo::DescriptorCountInfo& poolState) {
     poolState.used -= binding.descriptorCount;
 }
 
@@ -366,11 +348,11 @@
     auto setsAvailable = poolInfo->maxSets - poolInfo->usedSets;
 
     if (setsAvailable < pAllocateInfo->descriptorSetCount) {
-        ALOGV("%s: Error: VkDescriptorSetAllocateInfo wants %u sets "
-              "but we only have %u available. "
-              "Bailing with VK_ERROR_OUT_OF_POOL_MEMORY.\n", __func__,
-              pAllocateInfo->descriptorSetCount,
-              setsAvailable);
+        ALOGV(
+            "%s: Error: VkDescriptorSetAllocateInfo wants %u sets "
+            "but we only have %u available. "
+            "Bailing with VK_ERROR_OUT_OF_POOL_MEMORY.\n",
+            __func__, pAllocateInfo->descriptorSetCount, setsAvailable);
         return VK_ERROR_OUT_OF_POOL_MEMORY;
     }
 
@@ -381,11 +363,13 @@
 
     for (uint32_t i = 0; i < pAllocateInfo->descriptorSetCount; ++i) {
         if (!pAllocateInfo->pSetLayouts[i]) {
-            ALOGV("%s: Error: Tried to allocate a descriptor set with null set layout.\n", __func__);
+            ALOGV("%s: Error: Tried to allocate a descriptor set with null set layout.\n",
+                  __func__);
             return VK_ERROR_INITIALIZATION_FAILED;
         }
 
-        auto setLayoutInfo = as_goldfish_VkDescriptorSetLayout(pAllocateInfo->pSetLayouts[i])->layoutInfo;
+        auto setLayoutInfo =
+            as_goldfish_VkDescriptorSetLayout(pAllocateInfo->pSetLayouts[i])->layoutInfo;
         if (!setLayoutInfo) {
             return VK_ERROR_INITIALIZATION_FAILED;
         }
@@ -423,7 +407,8 @@
     }
 }
 
-void removeDescriptorSetAllocation(VkDescriptorPool pool, const std::vector<VkDescriptorSetLayoutBinding>& bindings) {
+void removeDescriptorSetAllocation(VkDescriptorPool pool,
+                                   const std::vector<VkDescriptorSetLayoutBinding>& bindings) {
     auto allocInfo = as_goldfish_VkDescriptorPool(pool)->allocInfo;
 
     if (0 == allocInfo->usedSets) {
@@ -442,7 +427,8 @@
     }
 }
 
-void fillDescriptorSetInfoForPool(VkDescriptorPool pool, VkDescriptorSetLayout setLayout, VkDescriptorSet set) {
+void fillDescriptorSetInfoForPool(VkDescriptorPool pool, VkDescriptorSetLayout setLayout,
+                                  VkDescriptorSet set) {
     DescriptorPoolAllocationInfo* allocInfo = as_goldfish_VkDescriptorPool(pool)->allocInfo;
 
     ReifiedDescriptorSet* newReified = new ReifiedDescriptorSet;
@@ -457,7 +443,8 @@
     initializeReifiedDescriptorSet(pool, setLayout, newReified);
 }
 
-VkResult validateAndApplyVirtualDescriptorSetAllocation(const VkDescriptorSetAllocateInfo* pAllocateInfo, VkDescriptorSet* pSets) {
+VkResult validateAndApplyVirtualDescriptorSetAllocation(
+    const VkDescriptorSetAllocateInfo* pAllocateInfo, VkDescriptorSet* pSets) {
     VkResult validateRes = validateDescriptorSetAllocation(pAllocateInfo);
 
     if (validateRes != VK_SUCCESS) return validateRes;
@@ -470,15 +457,15 @@
     DescriptorPoolAllocationInfo* allocInfo = as_goldfish_VkDescriptorPool(pool)->allocInfo;
 
     if (allocInfo->freePoolIds.size() < pAllocateInfo->descriptorSetCount) {
-        ALOGE("%s: FATAL: Somehow out of descriptor pool IDs. Wanted %u IDs but only have %u free IDs remaining. The count for maxSets was %u and used was %u\n", __func__,
-                pAllocateInfo->descriptorSetCount,
-                (uint32_t)allocInfo->freePoolIds.size(),
-                allocInfo->maxSets,
-                allocInfo->usedSets);
+        ALOGE(
+            "%s: FATAL: Somehow out of descriptor pool IDs. Wanted %u IDs but only have %u free "
+            "IDs remaining. The count for maxSets was %u and used was %u\n",
+            __func__, pAllocateInfo->descriptorSetCount, (uint32_t)allocInfo->freePoolIds.size(),
+            allocInfo->maxSets, allocInfo->usedSets);
         abort();
     }
 
-    for (uint32_t i = 0 ; i < pAllocateInfo->descriptorSetCount; ++i) {
+    for (uint32_t i = 0; i < pAllocateInfo->descriptorSetCount; ++i) {
         uint64_t id = allocInfo->freePoolIds.back();
         allocInfo->freePoolIds.pop_back();
 
@@ -498,7 +485,8 @@
     DescriptorPoolAllocationInfo* allocInfo = as_goldfish_VkDescriptorPool(pool)->allocInfo;
 
     if (usePoolIds) {
-        // Look for the set's pool Id in the pool. If not found, then this wasn't really allocated, and bail.
+        // Look for the set's pool Id in the pool. If not found, then this wasn't really allocated,
+        // and bail.
         if (allocInfo->allocedPoolIds.find(reified->poolId) == allocInfo->allocedPoolIds.end()) {
             return false;
         }
@@ -522,7 +510,7 @@
         toClear.push_back(set);
     }
 
-    for (auto set: toClear) {
+    for (auto set : toClear) {
         removeDescriptorSetFromPool(set, usePoolIds);
     }
 
diff --git a/guest/vulkan_enc/DescriptorSetVirtualization.h b/guest/vulkan_enc/DescriptorSetVirtualization.h
index c6a6c42..0491102 100644
--- a/guest/vulkan_enc/DescriptorSetVirtualization.h
+++ b/guest/vulkan_enc/DescriptorSetVirtualization.h
@@ -14,13 +14,13 @@
 // limitations under the License.
 #pragma once
 
-#include "aemu/base/containers/EntityManager.h"
-
 #include <vulkan/vulkan.h>
 
 #include <unordered_set>
 #include <vector>
 
+#include "aemu/base/containers/EntityManager.h"
+
 namespace gfxstream {
 namespace vk {
 
@@ -37,7 +37,7 @@
     DescriptorWriteType type;
     VkDescriptorType descriptorType;
 
-    uint32_t dstArrayElement; // Only used for inlineUniformBlock and accelerationStructure.
+    uint32_t dstArrayElement;  // Only used for inlineUniformBlock and accelerationStructure.
 
     union {
         VkDescriptorImageInfo imageInfo;
@@ -105,7 +105,8 @@
 
 void clearReifiedDescriptorSet(ReifiedDescriptorSet* set);
 
-void initDescriptorWriteTable(const std::vector<VkDescriptorSetLayoutBinding>& layoutBindings, DescriptorWriteTable& table);
+void initDescriptorWriteTable(const std::vector<VkDescriptorSetLayoutBinding>& layoutBindings,
+                              DescriptorWriteTable& table);
 
 bool isDescriptorTypeImageInfo(VkDescriptorType descType);
 bool isDescriptorTypeBufferInfo(VkDescriptorType descType);
@@ -114,31 +115,23 @@
 bool isDescriptorTypeAccelerationStructure(VkDescriptorType descType);
 
 void doEmulatedDescriptorWrite(const VkWriteDescriptorSet* write, ReifiedDescriptorSet* toWrite);
-void doEmulatedDescriptorCopy(const VkCopyDescriptorSet* copy, const ReifiedDescriptorSet* src, ReifiedDescriptorSet* dst);
+void doEmulatedDescriptorCopy(const VkCopyDescriptorSet* copy, const ReifiedDescriptorSet* src,
+                              ReifiedDescriptorSet* dst);
 
-void doEmulatedDescriptorImageInfoWriteFromTemplate(
-    VkDescriptorType descType,
-    uint32_t binding,
-    uint32_t dstArrayElement,
-    uint32_t count,
-    const VkDescriptorImageInfo* imageInfos,
-    ReifiedDescriptorSet* set);
+void doEmulatedDescriptorImageInfoWriteFromTemplate(VkDescriptorType descType, uint32_t binding,
+                                                    uint32_t dstArrayElement, uint32_t count,
+                                                    const VkDescriptorImageInfo* imageInfos,
+                                                    ReifiedDescriptorSet* set);
 
-void doEmulatedDescriptorBufferInfoWriteFromTemplate(
-    VkDescriptorType descType,
-    uint32_t binding,
-    uint32_t dstArrayElement,
-    uint32_t count,
-    const VkDescriptorBufferInfo* bufferInfos,
-    ReifiedDescriptorSet* set);
+void doEmulatedDescriptorBufferInfoWriteFromTemplate(VkDescriptorType descType, uint32_t binding,
+                                                     uint32_t dstArrayElement, uint32_t count,
+                                                     const VkDescriptorBufferInfo* bufferInfos,
+                                                     ReifiedDescriptorSet* set);
 
-void doEmulatedDescriptorBufferViewWriteFromTemplate(
-    VkDescriptorType descType,
-    uint32_t binding,
-    uint32_t dstArrayElement,
-    uint32_t count,
-    const VkBufferView* bufferViews,
-    ReifiedDescriptorSet* set);
+void doEmulatedDescriptorBufferViewWriteFromTemplate(VkDescriptorType descType, uint32_t binding,
+                                                     uint32_t dstArrayElement, uint32_t count,
+                                                     const VkBufferView* bufferViews,
+                                                     ReifiedDescriptorSet* set);
 
 void doEmulatedDescriptorInlineUniformBlockFromTemplate(VkDescriptorType descType, uint32_t binding,
                                                         uint32_t dstArrayElement, uint32_t count,
@@ -146,8 +139,10 @@
                                                         ReifiedDescriptorSet* set);
 
 void applyDescriptorSetAllocation(VkDescriptorPool pool, VkDescriptorSetLayout setLayout);
-void fillDescriptorSetInfoForPool(VkDescriptorPool pool, VkDescriptorSetLayout setLayout, VkDescriptorSet set);
-VkResult validateAndApplyVirtualDescriptorSetAllocation(const VkDescriptorSetAllocateInfo* pAllocateInfo, VkDescriptorSet* pSets);
+void fillDescriptorSetInfoForPool(VkDescriptorPool pool, VkDescriptorSetLayout setLayout,
+                                  VkDescriptorSet set);
+VkResult validateAndApplyVirtualDescriptorSetAllocation(
+    const VkDescriptorSetAllocateInfo* pAllocateInfo, VkDescriptorSet* pSets);
 
 // Returns false if set wasn't found in its pool.
 bool removeDescriptorSetFromPool(VkDescriptorSet set, bool usePoolIds);
diff --git a/guest/vulkan_enc/HostVisibleMemoryVirtualization.cpp b/guest/vulkan_enc/HostVisibleMemoryVirtualization.cpp
index 3f2f75c..dcf9f65 100644
--- a/guest/vulkan_enc/HostVisibleMemoryVirtualization.cpp
+++ b/guest/vulkan_enc/HostVisibleMemoryVirtualization.cpp
@@ -45,10 +45,9 @@
                                VkDevice device, VkDeviceMemory memory)
     : mSize(size), mBlock(block), mDevice(device), mMemory(memory) {
     void* address = block->mmap(gpuAddr);
-    mAllocator =
-        std::make_unique<gfxstream::guest::SubAllocator>(address, mSize, kLargestPageSize);
+    mAllocator = std::make_unique<gfxstream::guest::SubAllocator>(address, mSize, kLargestPageSize);
 }
-#endif // defined(__ANDROID__)
+#endif  // defined(__ANDROID__)
 
 CoherentMemory::~CoherentMemory() {
     ResourceTracker::getThreadLocalEncoder()->vkFreeMemorySyncGOOGLE(mDevice, mMemory, nullptr,
diff --git a/guest/vulkan_enc/HostVisibleMemoryVirtualization.h b/guest/vulkan_enc/HostVisibleMemoryVirtualization.h
index 051ea69..92acd5e 100644
--- a/guest/vulkan_enc/HostVisibleMemoryVirtualization.h
+++ b/guest/vulkan_enc/HostVisibleMemoryVirtualization.h
@@ -47,7 +47,7 @@
 #if defined(__ANDROID__)
     CoherentMemory(GoldfishAddressSpaceBlockPtr block, uint64_t gpuAddr, uint64_t size,
                    VkDevice device, VkDeviceMemory memory);
-#endif // defined(__ANDROID__)
+#endif  // defined(__ANDROID__)
 
     ~CoherentMemory();
 
diff --git a/guest/vulkan_enc/ResourceTracker.cpp b/guest/vulkan_enc/ResourceTracker.cpp
index 4e4d0e7..202090a 100644
--- a/guest/vulkan_enc/ResourceTracker.cpp
+++ b/guest/vulkan_enc/ResourceTracker.cpp
@@ -23,6 +23,7 @@
 #include "Resources.h"
 #include "VkEncoder.h"
 #include "aemu/base/AlignedBuf.h"
+#include "gfxstream_vk_private.h"
 #include "goldfish_address_space.h"
 #include "goldfish_vk_private_defs.h"
 #include "util.h"
@@ -200,10 +201,10 @@
     std::unordered_set<VkDescriptorSet> sets;
 };
 
-#define HANDLE_REGISTER_IMPL_IMPL(type)                \
-    void ResourceTracker::register_##type(type obj) {  \
-        AutoLock<RecursiveLock> lock(mLock);           \
-        info_##type[obj] = type##_Info();              \
+#define HANDLE_REGISTER_IMPL_IMPL(type)               \
+    void ResourceTracker::register_##type(type obj) { \
+        AutoLock<RecursiveLock> lock(mLock);          \
+        info_##type[obj] = type##_Info();             \
     }
 
 #define HANDLE_UNREGISTER_IMPL_IMPL(type)               \
@@ -286,7 +287,8 @@
     return as_goldfish_VkDescriptorSet(dstSet)->reified->bindingIsImmutableSampler[dstBinding];
 }
 
-VkDescriptorImageInfo ResourceTracker::filterNonexistentSampler(const VkDescriptorImageInfo& inputInfo) {
+VkDescriptorImageInfo ResourceTracker::filterNonexistentSampler(
+    const VkDescriptorImageInfo& inputInfo) {
     VkSampler sampler = inputInfo.sampler;
 
     VkDescriptorImageInfo res = inputInfo;
@@ -300,9 +302,11 @@
     return res;
 }
 
-void ResourceTracker::emitDeviceMemoryReport(VkDevice_Info info, VkDeviceMemoryReportEventTypeEXT type,
-                            uint64_t memoryObjectId, VkDeviceSize size, VkObjectType objectType,
-                            uint64_t objectHandle, uint32_t heapIndex) {
+void ResourceTracker::emitDeviceMemoryReport(VkDevice_Info info,
+                                             VkDeviceMemoryReportEventTypeEXT type,
+                                             uint64_t memoryObjectId, VkDeviceSize size,
+                                             VkObjectType objectType, uint64_t objectHandle,
+                                             uint32_t heapIndex) {
     if (info.deviceMemoryReportCallbacks.empty()) return;
 
     const VkDeviceMemoryReportCallbackDataEXT callbackData = {
@@ -640,9 +644,10 @@
         createInfoDup.pNext = nullptr;
         enc->vkGetLinearImageLayout2GOOGLE(device, &createInfoDup, &offset, &rowPitchAlignment,
                                            true /* do lock */);
-        ALOGD("vkGetLinearImageLayout2GOOGLE: format %d offset %lu "
-          "rowPitchAlignment = %lu",
-          (int)createInfo->format, offset, rowPitchAlignment);
+        ALOGD(
+            "vkGetLinearImageLayout2GOOGLE: format %d offset %lu "
+            "rowPitchAlignment = %lu",
+            (int)createInfo->format, offset, rowPitchAlignment);
     }
 
     imageConstraints.min_coded_width = createInfo->extent.width;
@@ -721,8 +726,8 @@
     dedicatedReqs->requiresDedicatedAllocation = VK_TRUE;
 }
 
-void ResourceTracker::setMemoryRequirementsForSysmemBackedImage(VkImage image,
-    VkMemoryRequirements* pMemoryRequirements) {
+void ResourceTracker::transformImageMemoryRequirementsForGuestLocked(VkImage image,
+                                                                     VkMemoryRequirements* reqs) {
 #ifdef VK_USE_PLATFORM_FUCHSIA
     auto it = info_VkImage.find(image);
     if (it == info_VkImage.end()) return;
@@ -730,21 +735,25 @@
     if (info.isSysmemBackedMemory) {
         auto width = info.createInfo.extent.width;
         auto height = info.createInfo.extent.height;
-        pMemoryRequirements->size = width * height * 4;
+        reqs->size = width * height * 4;
+    }
+#elif defined(__linux__) && !defined(VK_USE_PLATFORM_ANDROID_KHR)
+    auto it = info_VkImage.find(image);
+    if (it == info_VkImage.end()) return;
+    auto& info = it->second;
+    if (info.isWsiImage) {
+        static const uint32_t kColorBufferBpp = 4;
+        reqs->size = kColorBufferBpp * info.createInfo.extent.width * info.createInfo.extent.height;
     }
 #else
     // Bypass "unused parameter" checks.
     (void)image;
-    (void)pMemoryRequirements;
+    (void)reqs;
 #endif
 }
 
-void ResourceTracker::transformImageMemoryRequirementsForGuestLocked(VkImage image,
-    VkMemoryRequirements* reqs) {
-    setMemoryRequirementsForSysmemBackedImage(image, reqs);
-}
-
-CoherentMemoryPtr ResourceTracker::freeCoherentMemoryLocked(VkDeviceMemory memory, VkDeviceMemory_Info& info) {
+CoherentMemoryPtr ResourceTracker::freeCoherentMemoryLocked(VkDeviceMemory memory,
+                                                            VkDeviceMemory_Info& info) {
     if (info.coherentMemory && info.ptr) {
         if (info.coherentMemory->getDeviceMemory() != memory) {
             delete_goldfish_VkDeviceMemory(memory);
@@ -1341,7 +1350,8 @@
 void ResourceTracker::setDeviceMemoryInfo(VkDevice device, VkDeviceMemory memory,
                                           VkDeviceSize allocationSize, uint8_t* ptr,
                                           uint32_t memoryTypeIndex, AHardwareBuffer* ahw,
-                                          bool imported, zx_handle_t vmoHandle) {
+                                          bool imported, zx_handle_t vmoHandle,
+                                          VirtGpuBlobPtr blobPtr) {
     AutoLock<RecursiveLock> lock(mLock);
     auto& info = info_VkDeviceMemory[memory];
 
@@ -1354,6 +1364,7 @@
 #endif
     info.imported = imported;
     info.vmoHandle = vmoHandle;
+    info.blobPtr = blobPtr;
 }
 
 void ResourceTracker::setImageInfo(VkImage image, VkDevice device,
@@ -1763,6 +1774,7 @@
         "VK_EXT_scalar_block_layout",
         "VK_KHR_descriptor_update_template",
         "VK_KHR_storage_buffer_storage_class",
+        "VK_EXT_depth_clip_enable",
 #if defined(VK_USE_PLATFORM_ANDROID_KHR) || defined(__linux__)
         "VK_KHR_external_semaphore",
         "VK_KHR_external_semaphore_fd",
@@ -1772,7 +1784,7 @@
         "VK_KHR_external_fence_fd",
         "VK_EXT_device_memory_report",
 #endif
-#if !defined(VK_USE_PLATFORM_ANDROID_KHR) && defined(__linux__)
+#if defined(__linux__) && !defined(VK_USE_PLATFORM_ANDROID_KHR)
         "VK_KHR_create_renderpass2",
         "VK_KHR_imageless_framebuffer",
 #endif
@@ -1847,9 +1859,11 @@
     bool win32ExtMemAvailable = getHostDeviceExtensionIndex("VK_KHR_external_memory_win32") != -1;
     bool posixExtMemAvailable = getHostDeviceExtensionIndex("VK_KHR_external_memory_fd") != -1;
     bool moltenVkExtAvailable = getHostDeviceExtensionIndex("VK_MVK_moltenvk") != -1;
+    bool qnxExtMemAvailable =
+        getHostDeviceExtensionIndex("VK_QNX_external_memory_screen_buffer") != -1;
 
     bool hostHasExternalMemorySupport =
-        win32ExtMemAvailable || posixExtMemAvailable || moltenVkExtAvailable;
+        win32ExtMemAvailable || posixExtMemAvailable || moltenVkExtAvailable || qnxExtMemAvailable;
 
     if (hostHasExternalMemorySupport) {
 #ifdef VK_USE_PLATFORM_ANDROID_KHR
@@ -2029,7 +2043,19 @@
 }
 
 void ResourceTracker::on_vkGetPhysicalDeviceProperties(void*, VkPhysicalDevice,
-                                                       VkPhysicalDeviceProperties*) {}
+                                                       VkPhysicalDeviceProperties* pProperties) {
+#if defined(__linux__) && !defined(VK_USE_PLATFORM_ANDROID_KHR)
+    if (pProperties) {
+        if (VK_PHYSICAL_DEVICE_TYPE_CPU == pProperties->deviceType) {
+            /* For Linux guest: Even if host driver reports DEVICE_TYPE_CPU,
+             * override this to VIRTUAL_GPU, otherwise Linux DRM interfaces
+             * will take unexpected code paths to deal with "software" driver
+             */
+            pProperties->deviceType = VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU;
+        }
+    }
+#endif
+}
 
 void ResourceTracker::on_vkGetPhysicalDeviceFeatures2(void*, VkPhysicalDevice,
                                                       VkPhysicalDeviceFeatures2* pFeatures) {
@@ -2048,7 +2074,8 @@
     on_vkGetPhysicalDeviceFeatures2(context, physicalDevice, pFeatures);
 }
 
-void ResourceTracker::on_vkGetPhysicalDeviceProperties2(void*, VkPhysicalDevice,
+void ResourceTracker::on_vkGetPhysicalDeviceProperties2(void* context,
+                                                        VkPhysicalDevice physicalDevice,
                                                         VkPhysicalDeviceProperties2* pProperties) {
     if (pProperties) {
         VkPhysicalDeviceDeviceMemoryReportFeaturesEXT* memoryReportFeaturesEXT =
@@ -2056,6 +2083,7 @@
         if (memoryReportFeaturesEXT) {
             memoryReportFeaturesEXT->deviceMemoryReport = VK_TRUE;
         }
+        on_vkGetPhysicalDeviceProperties(context, physicalDevice, &pProperties->properties);
     }
 }
 
@@ -2142,6 +2170,12 @@
     }
 }
 
+#if defined(VK_USE_PLATFORM_ANDROID_KHR) || defined(__linux__)
+void updateMemoryTypeBits(uint32_t* memoryTypeBits, uint32_t memoryIndex) {
+    *memoryTypeBits = 1u << memoryIndex;
+}
+#endif
+
 #ifdef VK_USE_PLATFORM_ANDROID_KHR
 
 VkResult ResourceTracker::on_vkGetAndroidHardwareBufferPropertiesANDROID(
@@ -2843,6 +2877,33 @@
 }
 #endif
 
+static uint32_t getVirglFormat(VkFormat vkFormat) {
+    uint32_t virglFormat = 0;
+
+    switch (vkFormat) {
+        case VK_FORMAT_R8G8B8A8_SINT:
+        case VK_FORMAT_R8G8B8A8_UNORM:
+        case VK_FORMAT_R8G8B8A8_SRGB:
+        case VK_FORMAT_R8G8B8A8_SNORM:
+        case VK_FORMAT_R8G8B8A8_SSCALED:
+        case VK_FORMAT_R8G8B8A8_USCALED:
+            virglFormat = VIRGL_FORMAT_R8G8B8A8_UNORM;
+            break;
+        case VK_FORMAT_B8G8R8A8_SINT:
+        case VK_FORMAT_B8G8R8A8_UNORM:
+        case VK_FORMAT_B8G8R8A8_SRGB:
+        case VK_FORMAT_B8G8R8A8_SNORM:
+        case VK_FORMAT_B8G8R8A8_SSCALED:
+        case VK_FORMAT_B8G8R8A8_USCALED:
+            virglFormat = VIRGL_FORMAT_B8G8R8A8_UNORM;
+            break;
+        default:
+            break;
+    }
+
+    return virglFormat;
+}
+
 CoherentMemoryPtr ResourceTracker::createCoherentMemory(
     VkDevice device, VkDeviceMemory mem, const VkMemoryAllocateInfo& hostAllocationInfo,
     VkEncoder* enc, VkResult& res) {
@@ -3221,6 +3282,13 @@
     const void* importAhbInfoPtr = nullptr;
 #endif
 
+#if defined(__linux__) && !defined(VK_USE_PLATFORM_ANDROID_KHR)
+    const VkImportMemoryFdInfoKHR* importFdInfoPtr =
+        vk_find_struct<VkImportMemoryFdInfoKHR>(pAllocateInfo);
+#else
+    const VkImportMemoryFdInfoKHR* importFdInfoPtr = nullptr;
+#endif
+
 #ifdef VK_USE_PLATFORM_FUCHSIA
     const VkImportMemoryBufferCollectionFUCHSIA* importBufferCollectionInfoPtr =
         vk_find_struct<VkImportMemoryBufferCollectionFUCHSIA>(pAllocateInfo);
@@ -3268,9 +3336,11 @@
     // State needed for import/export.
     bool exportAhb = false;
     bool exportVmo = false;
+    bool exportDmabuf = false;
     bool importAhb = false;
     bool importBufferCollection = false;
     bool importVmo = false;
+    bool importDmabuf = false;
     (void)exportVmo;
 
     // Even if we export allocate, the underlying operation
@@ -3291,6 +3361,9 @@
         exportVmo = exportAllocateInfoPtr->handleTypes &
                     VK_EXTERNAL_MEMORY_HANDLE_TYPE_ZIRCON_VMO_BIT_FUCHSIA;
 #endif  // VK_USE_PLATFORM_FUCHSIA
+        exportDmabuf =
+            exportAllocateInfoPtr->handleTypes & (VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT |
+                                                  VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT);
     } else if (importAhbInfoPtr) {
         importAhb = true;
     } else if (importBufferCollectionInfoPtr) {
@@ -3298,7 +3371,13 @@
     } else if (importVmoInfoPtr) {
         importVmo = true;
     }
-    bool isImport = importAhb || importBufferCollection || importVmo;
+
+    if (importFdInfoPtr) {
+        importDmabuf =
+            (importFdInfoPtr->handleType & (VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT |
+                                            VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT));
+    }
+    bool isImport = importAhb || importBufferCollection || importVmo || importDmabuf;
 
 #if defined(VK_USE_PLATFORM_ANDROID_KHR)
     if (exportAhb) {
@@ -3671,7 +3750,96 @@
     }
 #endif
 
-    if (ahw || !requestedMemoryIsHostVisible) {
+    VirtGpuBlobPtr colorBufferBlob = nullptr;
+#if defined(__linux__) && !defined(VK_USE_PLATFORM_ANDROID_KHR)
+    if (exportDmabuf) {
+        VirtGpuDevice* instance = VirtGpuDevice::getInstance();
+        // // TODO: any special action for VK_STRUCTURE_TYPE_WSI_MEMORY_ALLOCATE_INFO_MESA? Can mark
+        // special state if needed.
+        // // const wsi_memory_allocate_info* wsiAllocateInfoPtr =
+        // vk_find_struct<wsi_memory_allocate_info>(pAllocateInfo);
+        bool hasDedicatedImage =
+            dedicatedAllocInfoPtr && (dedicatedAllocInfoPtr->image != VK_NULL_HANDLE);
+        bool hasDedicatedBuffer =
+            dedicatedAllocInfoPtr && (dedicatedAllocInfoPtr->buffer != VK_NULL_HANDLE);
+        if (!hasDedicatedImage && !hasDedicatedBuffer) {
+            ALOGE(
+                "%s: dma-buf exportable memory requires dedicated Image or Buffer information.\n");
+            return VK_ERROR_OUT_OF_DEVICE_MEMORY;
+        }
+
+        if (hasDedicatedImage) {
+            VkImageCreateInfo imageCreateInfo;
+            {
+                AutoLock<RecursiveLock> lock(mLock);
+
+                auto it = info_VkImage.find(dedicatedAllocInfoPtr->image);
+                if (it == info_VkImage.end()) return VK_ERROR_INITIALIZATION_FAILED;
+                const auto& imageInfo = it->second;
+
+                imageCreateInfo = imageInfo.createInfo;
+            }
+            uint32_t virglFormat = gfxstream::vk::getVirglFormat(imageCreateInfo.format);
+            if (virglFormat < 0) {
+                ALOGE("%s: Unsupported VK format for colorBuffer, vkFormat: 0x%x", __func__,
+                      imageCreateInfo.format);
+                return VK_ERROR_FORMAT_NOT_SUPPORTED;
+            }
+            colorBufferBlob = instance->createVirglBlob(imageCreateInfo.extent.width,
+                                                        imageCreateInfo.extent.height, virglFormat);
+            if (!colorBufferBlob) {
+                ALOGE("%s: Failed to create colorBuffer resource for Image memory\n", __func__);
+                return VK_ERROR_OUT_OF_DEVICE_MEMORY;
+            }
+            if (0 != colorBufferBlob->wait()) {
+                ALOGE("%s: Failed to wait for colorBuffer resource for Image memory\n", __func__);
+                return VK_ERROR_OUT_OF_DEVICE_MEMORY;
+            }
+        }
+
+        if (hasDedicatedBuffer) {
+            VkBufferCreateInfo bufferCreateInfo;
+            {
+                AutoLock<RecursiveLock> lock(mLock);
+
+                auto it = info_VkBuffer.find(dedicatedAllocInfoPtr->buffer);
+                if (it == info_VkBuffer.end()) return VK_ERROR_INITIALIZATION_FAILED;
+                const auto& bufferInfo = it->second;
+                bufferCreateInfo = bufferInfo.createInfo;
+            }
+            colorBufferBlob = instance->createVirglBlob(bufferCreateInfo.size / 4, 1,
+                                                        VIRGL_FORMAT_R8G8B8A8_UNORM);
+            if (!colorBufferBlob) {
+                ALOGE("%s: Failed to create colorBuffer resource for Buffer memory\n", __func__);
+                return VK_ERROR_OUT_OF_DEVICE_MEMORY;
+            }
+            if (0 != colorBufferBlob->wait()) {
+                ALOGE("%s: Failed to wait for colorBuffer resource for Buffer memory\n", __func__);
+                return VK_ERROR_OUT_OF_DEVICE_MEMORY;
+            }
+        }
+    }
+
+    if (importDmabuf) {
+        VirtGpuExternalHandle importHandle = {};
+        importHandle.osHandle = importFdInfoPtr->fd;
+        importHandle.type = kMemHandleDmabuf;
+
+        auto instance = VirtGpuDevice::getInstance();
+        colorBufferBlob = instance->importBlob(importHandle);
+        if (!colorBufferBlob) {
+            ALOGE("%s: Failed to import colorBuffer resource\n", __func__);
+            return VK_ERROR_OUT_OF_DEVICE_MEMORY;
+        }
+    }
+
+    if (colorBufferBlob) {
+        importCbInfo.colorBuffer = colorBufferBlob->getResourceHandle();
+        vk_append_struct(&structChainIter, &importCbInfo);
+    }
+#endif
+
+    if (ahw || colorBufferBlob || !requestedMemoryIsHostVisible) {
         input_result =
             enc->vkAllocateMemory(device, &finalAllocInfo, pAllocator, pMemory, true /* do lock */);
 
@@ -3679,7 +3847,7 @@
 
         VkDeviceSize allocationSize = finalAllocInfo.allocationSize;
         setDeviceMemoryInfo(device, *pMemory, 0, nullptr, finalAllocInfo.memoryTypeIndex, ahw,
-                            isImport, vmo_handle);
+                            isImport, vmo_handle, colorBufferBlob);
 
         _RETURN_SCUCCESS_WITH_DEVICE_MEMORY_REPORT;
     }
@@ -3714,7 +3882,7 @@
 
         setDeviceMemoryInfo(device, *pMemory, finalAllocInfo.allocationSize,
                             reinterpret_cast<uint8_t*>(addr), finalAllocInfo.memoryTypeIndex,
-                            /*ahw=*/nullptr, isImport, vmo_handle);
+                            /*ahw=*/nullptr, isImport, vmo_handle, /*blobPtr=*/nullptr);
         return VK_SUCCESS;
     }
 #endif
@@ -3857,11 +4025,11 @@
     auto& info = it->second;
 
     if (!info.external || !info.externalCreateInfo.handleTypes) {
-        setMemoryRequirementsForSysmemBackedImage(image, &reqs2->memoryRequirements);
+        transformImageMemoryRequirementsForGuestLocked(image, &reqs2->memoryRequirements);
         return;
     }
 
-    setMemoryRequirementsForSysmemBackedImage(image, &reqs2->memoryRequirements);
+    transformImageMemoryRequirementsForGuestLocked(image, &reqs2->memoryRequirements);
 
     VkMemoryDedicatedRequirements* dedicatedReqs =
         vk_find_struct<VkMemoryDedicatedRequirements>(reqs2);
@@ -3909,11 +4077,29 @@
 
     const VkExternalMemoryImageCreateInfo* extImgCiPtr =
         vk_find_struct<VkExternalMemoryImageCreateInfo>(pCreateInfo);
+
     if (extImgCiPtr) {
         localExtImgCi = vk_make_orphan_copy(*extImgCiPtr);
         vk_append_struct(&structChainIter, &localExtImgCi);
     }
 
+    bool isWsiImage = false;
+
+#if defined(__linux__) && !defined(VK_USE_PLATFORM_ANDROID_KHR)
+    if (extImgCiPtr &&
+        (extImgCiPtr->handleTypes & VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT)) {
+        // Assumes that handleType with DMA_BUF_BIT indicates creation of a
+        // image for WSI use; no other external dma_buf usage is supported
+        isWsiImage = true;
+        // Must be linear. Otherwise querying stride and other properties
+        // can be implementation-dependent.
+        localCreateInfo.tiling = VK_IMAGE_TILING_LINEAR;
+        if (gfxstream::vk::getVirglFormat(localCreateInfo.format) < 0) {
+            localCreateInfo.format = VK_FORMAT_R8G8B8A8_UNORM;
+        }
+    }
+#endif
+
 #ifdef VK_USE_PLATFORM_ANDROID_KHR
     VkNativeBufferANDROID localAnb;
     const VkNativeBufferANDROID* anbInfoPtr = vk_find_struct<VkNativeBufferANDROID>(pCreateInfo);
@@ -4085,13 +4271,16 @@
     }
 #endif
 
+    info.isWsiImage = isWsiImage;
+
 // Delete `protocolVersion` check goldfish drivers are gone.
-#ifdef VK_USE_PLATFORM_ANDROID_KHR
+#if defined(VK_USE_PLATFORM_ANDROID_KHR) || defined(__linux__)
     if (mCaps.vulkanCapset.colorBufferMemoryIndex == 0xFFFFFFFF) {
         mCaps.vulkanCapset.colorBufferMemoryIndex = getColorBufferMemoryIndex(context, device);
     }
-    if (extImgCiPtr && (extImgCiPtr->handleTypes &
-                        VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID)) {
+    if (isWsiImage ||
+        (extImgCiPtr && (extImgCiPtr->handleTypes &
+                         VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID))) {
         updateMemoryTypeBits(&memReqs.memoryTypeBits, mCaps.vulkanCapset.colorBufferMemoryIndex);
     }
 #endif
@@ -4981,7 +5170,6 @@
         vk_append_struct(&structChainIter, &localExtBufCi);
     }
 
-
     VkBufferOpaqueCaptureAddressCreateInfo localCapAddrCi;
     const VkBufferOpaqueCaptureAddressCreateInfo* pCapAddrCi =
         vk_find_struct<VkBufferOpaqueCaptureAddressCreateInfo>(pCreateInfo);
@@ -5057,12 +5245,14 @@
 
     if (res != VK_SUCCESS) return res;
 
-#ifdef VK_USE_PLATFORM_ANDROID_KHR
+#if defined(VK_USE_PLATFORM_ANDROID_KHR) || defined(__linux__)
     if (mCaps.vulkanCapset.colorBufferMemoryIndex == 0xFFFFFFFF) {
         mCaps.vulkanCapset.colorBufferMemoryIndex = getColorBufferMemoryIndex(context, device);
     }
-    if (extBufCiPtr && (extBufCiPtr->handleTypes &
-                        VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID)) {
+    if (extBufCiPtr &&
+        ((extBufCiPtr->handleTypes &
+          VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID) ||
+         (extBufCiPtr->handleTypes & VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT))) {
         updateMemoryTypeBits(&memReqs.memoryTypeBits, mCaps.vulkanCapset.colorBufferMemoryIndex);
     }
 #endif
@@ -5354,6 +5544,53 @@
 #endif
 }
 
+VkResult ResourceTracker::on_vkGetMemoryFdKHR(void* context, VkResult, VkDevice device,
+                                              const VkMemoryGetFdInfoKHR* pGetFdInfo, int* pFd) {
+#if defined(__linux__) && !defined(VK_USE_PLATFORM_ANDROID_KHR)
+    if (!pGetFdInfo) return VK_ERROR_OUT_OF_HOST_MEMORY;
+    if (!pGetFdInfo->memory) return VK_ERROR_OUT_OF_HOST_MEMORY;
+
+    if (!(pGetFdInfo->handleType & (VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT |
+                                    VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT))) {
+        ALOGE("%s: Export operation not defined for handleType: 0x%x\n", __func__,
+              pGetFdInfo->handleType);
+        return VK_ERROR_OUT_OF_HOST_MEMORY;
+    }
+    // Sanity-check device
+    AutoLock<RecursiveLock> lock(mLock);
+    auto deviceIt = info_VkDevice.find(device);
+    if (deviceIt == info_VkDevice.end()) {
+        return VK_ERROR_OUT_OF_HOST_MEMORY;
+    }
+
+    auto deviceMemIt = info_VkDeviceMemory.find(pGetFdInfo->memory);
+    if (deviceMemIt == info_VkDeviceMemory.end()) {
+        return VK_ERROR_OUT_OF_HOST_MEMORY;
+    }
+    auto& info = deviceMemIt->second;
+
+    if (!info.blobPtr) {
+        ALOGE("%s: VkDeviceMemory does not have a resource available for export.\n", __func__);
+        return VK_ERROR_OUT_OF_HOST_MEMORY;
+    }
+
+    VirtGpuExternalHandle handle{};
+    int ret = info.blobPtr->exportBlob(handle);
+    if (ret != 0 || handle.osHandle < 0) {
+        ALOGE("%s: Failed to export host resource to FD.\n", __func__);
+        return VK_ERROR_OUT_OF_HOST_MEMORY;
+    }
+    *pFd = handle.osHandle;
+    return VK_SUCCESS;
+#else
+    (void)context;
+    (void)device;
+    (void)pGetFdInfo;
+    (void)pFd;
+    return VK_ERROR_INCOMPATIBLE_DRIVER;
+#endif
+}
+
 void ResourceTracker::flushCommandBufferPendingCommandsBottomUp(
     void* context, VkQueue queue, const std::vector<VkCommandBuffer>& workingSet) {
     if (workingSet.empty()) return;
@@ -5704,9 +5941,14 @@
     }
 
     auto* gralloc = ResourceTracker::threadingCallbacks.hostConnectionGetFunc()->grallocHelper();
+    const native_handle_t* nativeHandle = (const native_handle_t*)inputNativeInfo->handle;
 
-    *(uint32_t*)(outputNativeInfo->handle) =
-        gralloc->getHostHandle((const native_handle_t*)inputNativeInfo->handle);
+#if defined(END2END_TESTS)
+    // This is valid since the testing backend creates the handle and we know the layout.
+    *(uint32_t*)(outputNativeInfo->handle) = (uint32_t)nativeHandle->data[0];
+#else
+    *(uint32_t*)(outputNativeInfo->handle) = gralloc->getHostHandle(nativeHandle);
+#endif
 }
 
 void ResourceTracker::unwrap_VkBindImageMemorySwapchainInfoKHR(
@@ -6040,6 +6282,14 @@
 
                 memcpy(((uint8_t*)imageInfos) + currImageInfoOffset, user,
                        sizeof(VkDescriptorImageInfo));
+#if defined(__linux__) && !defined(VK_USE_PLATFORM_ANDROID_KHR)
+                // Convert mesa to internal for objects in the user buffer
+                VkDescriptorImageInfo* internalImageInfo =
+                    (VkDescriptorImageInfo*)(((uint8_t*)imageInfos) + currImageInfoOffset);
+                VK_FROM_HANDLE(gfxstream_vk_image_view, gfxstream_image_view,
+                               internalImageInfo->imageView);
+                internalImageInfo->imageView = gfxstream_image_view->internal_object;
+#endif
                 currImageInfoOffset += sizeof(VkDescriptorImageInfo);
             }
 
@@ -6059,6 +6309,13 @@
 
                 memcpy(((uint8_t*)bufferInfos) + currBufferInfoOffset, user,
                        sizeof(VkDescriptorBufferInfo));
+#if defined(__linux__) && !defined(VK_USE_PLATFORM_ANDROID_KHR)
+                // Convert mesa to internal for objects in the user buffer
+                VkDescriptorBufferInfo* internalBufferInfo =
+                    (VkDescriptorBufferInfo*)(((uint8_t*)bufferInfos) + currBufferInfoOffset);
+                VK_FROM_HANDLE(gfxstream_vk_buffer, gfxstream_buffer, internalBufferInfo->buffer);
+                internalBufferInfo->buffer = gfxstream_buffer->internal_object;
+#endif
                 currBufferInfoOffset += sizeof(VkDescriptorBufferInfo);
             }
 
@@ -6077,6 +6334,15 @@
                 const VkBufferView* user = (const VkBufferView*)(userBuffer + offset + j * stride);
 
                 memcpy(((uint8_t*)bufferViews) + currBufferViewOffset, user, sizeof(VkBufferView));
+#if defined(__linux__) && !defined(VK_USE_PLATFORM_ANDROID_KHR)
+                // Convert mesa to internal for objects in the user buffer
+                VkBufferView* internalBufferView =
+                    (VkBufferView*)(((uint8_t*)bufferViews) + currBufferViewOffset);
+                VK_FROM_HANDLE(gfxstream_vk_buffer_view, gfxstream_buffer_view,
+                               *internalBufferView);
+                *internalBufferView = gfxstream_buffer_view->internal_object;
+#endif
+
                 currBufferViewOffset += sizeof(VkBufferView);
             }
 
@@ -6139,7 +6405,6 @@
         VK_FORMAT_R8G8_SSCALED,   VK_FORMAT_R8G8_SRGB,
     };
 
-
     if (ext_img_properties) {
         if (std::find(std::begin(kExternalImageSupportedFormats),
                       std::end(kExternalImageSupportedFormats),
@@ -6154,7 +6419,7 @@
     VkAndroidHardwareBufferUsageANDROID* output_ahw_usage =
         vk_find_struct<VkAndroidHardwareBufferUsageANDROID>(pImageFormatProperties);
     supportedHandleType |= VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT |
-        VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID;
+                           VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID;
 #endif
     const VkPhysicalDeviceExternalImageFormatInfo* ext_img_info =
         vk_find_struct<VkPhysicalDeviceExternalImageFormatInfo>(pImageFormatInfo);
@@ -6201,7 +6466,8 @@
     }
 #endif
     if (ext_img_properties) {
-        transformImpl_VkExternalMemoryProperties_fromhost(&ext_img_properties->externalMemoryProperties, 0);
+        transformImpl_VkExternalMemoryProperties_fromhost(
+            &ext_img_properties->externalMemoryProperties, 0);
     }
     return hostRes;
 }
@@ -6236,11 +6502,12 @@
 #endif
 #ifdef VK_USE_PLATFORM_ANDROID_KHR
     supportedHandleType |= VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT |
-            VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID;
+                           VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID;
 #endif
     if (supportedHandleType) {
         // 0 is a valid handleType so we can't check against 0
-        if (pExternalBufferInfo->handleType != (pExternalBufferInfo->handleType & supportedHandleType)) {
+        if (pExternalBufferInfo->handleType !=
+            (pExternalBufferInfo->handleType & supportedHandleType)) {
             return;
         }
     }
@@ -6252,7 +6519,8 @@
         enc->vkGetPhysicalDeviceExternalBufferProperties(
             physicalDevice, pExternalBufferInfo, pExternalBufferProperties, true /* do lock */);
     }
-    transformImpl_VkExternalMemoryProperties_fromhost(&pExternalBufferProperties->externalMemoryProperties, 0);
+    transformImpl_VkExternalMemoryProperties_fromhost(
+        &pExternalBufferProperties->externalMemoryProperties, 0);
 }
 
 void ResourceTracker::on_vkGetPhysicalDeviceExternalBufferProperties(
@@ -6261,8 +6529,7 @@
     VkExternalBufferProperties* pExternalBufferProperties) {
     return on_vkGetPhysicalDeviceExternalBufferProperties_common(
         false /* not KHR */, context, physicalDevice, pExternalBufferInfo,
-        pExternalBufferProperties
-    );
+        pExternalBufferProperties);
 }
 
 void ResourceTracker::on_vkGetPhysicalDeviceExternalBufferPropertiesKHR(
@@ -6270,9 +6537,7 @@
     const VkPhysicalDeviceExternalBufferInfoKHR* pExternalBufferInfo,
     VkExternalBufferPropertiesKHR* pExternalBufferProperties) {
     return on_vkGetPhysicalDeviceExternalBufferProperties_common(
-        true /* is KHR */, context, physicalDevice, pExternalBufferInfo,
-        pExternalBufferProperties
-    );
+        true /* is KHR */, context, physicalDevice, pExternalBufferInfo, pExternalBufferProperties);
 }
 
 void ResourceTracker::on_vkGetPhysicalDeviceExternalSemaphoreProperties(
@@ -6776,8 +7041,10 @@
             vk_find_struct<VkPipelineRenderingCreateInfo>(&graphicsPipelineCreateInfo);
 
         if (pipelineRenderingInfo) {
-            forceDepthStencilState |= pipelineRenderingInfo->depthAttachmentFormat != VK_FORMAT_UNDEFINED;
-            forceDepthStencilState |= pipelineRenderingInfo->stencilAttachmentFormat != VK_FORMAT_UNDEFINED;
+            forceDepthStencilState |=
+                pipelineRenderingInfo->depthAttachmentFormat != VK_FORMAT_UNDEFINED;
+            forceDepthStencilState |=
+                pipelineRenderingInfo->stencilAttachmentFormat != VK_FORMAT_UNDEFINED;
             forceColorBlendState |= pipelineRenderingInfo->colorAttachmentCount != 0;
         }
 
@@ -6998,7 +7265,8 @@
 }
 
 // static
-ALWAYS_INLINE VkEncoder* ResourceTracker::getCommandBufferEncoder(VkCommandBuffer commandBuffer) {
+ALWAYS_INLINE_GFXSTREAM VkEncoder* ResourceTracker::getCommandBufferEncoder(
+    VkCommandBuffer commandBuffer) {
     if (!(ResourceTracker::streamFeatureBits &
           VULKAN_STREAM_FEATURE_QUEUE_SUBMIT_WITH_COMMANDS_BIT)) {
         auto enc = ResourceTracker::getThreadLocalEncoder();
@@ -7019,7 +7287,7 @@
 }
 
 // static
-ALWAYS_INLINE VkEncoder* ResourceTracker::getQueueEncoder(VkQueue queue) {
+ALWAYS_INLINE_GFXSTREAM VkEncoder* ResourceTracker::getQueueEncoder(VkQueue queue) {
     auto enc = ResourceTracker::getThreadLocalEncoder();
     if (!(ResourceTracker::streamFeatureBits &
           VULKAN_STREAM_FEATURE_QUEUE_SUBMIT_WITH_COMMANDS_BIT)) {
@@ -7029,7 +7297,7 @@
 }
 
 // static
-ALWAYS_INLINE VkEncoder* ResourceTracker::getThreadLocalEncoder() {
+ALWAYS_INLINE_GFXSTREAM VkEncoder* ResourceTracker::getThreadLocalEncoder() {
     auto hostConn = ResourceTracker::threadingCallbacks.hostConnectionGetFunc();
     auto vkEncoder = ResourceTracker::threadingCallbacks.vkEncoderGetFunc(hostConn);
     return vkEncoder;
@@ -7039,13 +7307,13 @@
 void ResourceTracker::setSeqnoPtr(uint32_t* seqnoptr) { sSeqnoPtr = seqnoptr; }
 
 // static
-ALWAYS_INLINE uint32_t ResourceTracker::nextSeqno() {
+ALWAYS_INLINE_GFXSTREAM uint32_t ResourceTracker::nextSeqno() {
     uint32_t res = __atomic_add_fetch(sSeqnoPtr, 1, __ATOMIC_SEQ_CST);
     return res;
 }
 
 // static
-ALWAYS_INLINE uint32_t ResourceTracker::getSeqno() {
+ALWAYS_INLINE_GFXSTREAM uint32_t ResourceTracker::getSeqno() {
     uint32_t res = __atomic_load_n(sSeqnoPtr, __ATOMIC_SEQ_CST);
     return res;
 }
diff --git a/guest/vulkan_enc/ResourceTracker.h b/guest/vulkan_enc/ResourceTracker.h
index af34ab6..07e09cb 100644
--- a/guest/vulkan_enc/ResourceTracker.h
+++ b/guest/vulkan_enc/ResourceTracker.h
@@ -273,6 +273,9 @@
                                               const VkBindImageMemoryInfo* inputBindInfos,
                                               VkBindImageMemoryInfo* outputBindInfos);
 
+    VkResult on_vkGetMemoryFdKHR(void* context, VkResult input_result, VkDevice device,
+                                 const VkMemoryGetFdInfoKHR* pGetFdInfo, int* pFd);
+
 #ifdef VK_USE_PLATFORM_FUCHSIA
     VkResult on_vkGetMemoryZirconHandleFUCHSIA(void* context, VkResult input_result,
                                                VkDevice device,
@@ -541,9 +544,9 @@
     void resetCommandPoolStagingInfo(VkCommandPool commandPool);
 
 #ifdef __GNUC__
-#define ALWAYS_INLINE
+#define ALWAYS_INLINE_GFXSTREAM
 #elif
-#define ALWAYS_INLINE __attribute__((always_inline))
+#define ALWAYS_INLINE_GFXSTREAM __attribute__((always_inline))
 #endif
 
     static VkEncoder* getCommandBufferEncoder(VkCommandBuffer commandBuffer);
@@ -551,8 +554,8 @@
     static VkEncoder* getThreadLocalEncoder();
 
     static void setSeqnoPtr(uint32_t* seqnoptr);
-    static ALWAYS_INLINE uint32_t nextSeqno();
-    static ALWAYS_INLINE uint32_t getSeqno();
+    static ALWAYS_INLINE_GFXSTREAM uint32_t nextSeqno();
+    static ALWAYS_INLINE_GFXSTREAM uint32_t getSeqno();
 
     // Transforms
     void deviceMemoryTransform_tohost(VkDeviceMemory* memory, uint32_t memoryCount,
@@ -614,7 +617,7 @@
 
     void setDeviceMemoryInfo(VkDevice device, VkDeviceMemory memory, VkDeviceSize allocationSize,
                              uint8_t* ptr, uint32_t memoryTypeIndex, AHardwareBuffer* ahw,
-                             bool imported, zx_handle_t vmoHandle);
+                             bool imported, zx_handle_t vmoHandle, VirtGpuBlobPtr blobPtr);
 
     void setImageInfo(VkImage image, VkDevice device, const VkImageCreateInfo* pCreateInfo);
 
@@ -680,11 +683,6 @@
         VkBindImageMemorySwapchainInfoKHR* outputBimsi);
 #endif
 
-    void setMemoryRequirementsForSysmemBackedImage(VkImage image,
-                                               VkMemoryRequirements* pMemoryRequirements);
-
-    void transformImageMemoryRequirementsForGuestLocked(VkImage image, VkMemoryRequirements* reqs);
-
 #if defined(VK_USE_PLATFORM_FUCHSIA)
     VkResult getBufferCollectionImageCreateInfoIndexLocked(
         VkBufferCollectionFUCHSIA collection, fuchsia_sysmem::wire::BufferCollectionInfo2& info,
@@ -722,16 +720,17 @@
         VkPhysicalDeviceMemoryProperties memProps;
         uint32_t apiVersion;
         std::set<std::string> enabledExtensions;
-        std::vector<std::pair<PFN_vkDeviceMemoryReportCallbackEXT, void*>> deviceMemoryReportCallbacks;
+        std::vector<std::pair<PFN_vkDeviceMemoryReportCallbackEXT, void*>>
+            deviceMemoryReportCallbacks;
     };
 
     struct VkDeviceMemory_Info {
         bool dedicated = false;
         bool imported = false;
 
-    #ifdef VK_USE_PLATFORM_ANDROID_KHR
+#ifdef VK_USE_PLATFORM_ANDROID_KHR
         AHardwareBuffer* ahw = nullptr;
-    #endif
+#endif
         zx_handle_t vmoHandle = ZX_HANDLE_INVALID;
         VkDevice device;
 
@@ -743,10 +742,11 @@
         uint64_t coherentMemorySize = 0;
         uint64_t coherentMemoryOffset = 0;
 
-    #if defined(__ANDROID__)
+#if defined(__ANDROID__)
         GoldfishAddressSpaceBlockPtr goldfishBlock = nullptr;
-    #endif  // defined(__ANDROID__)
+#endif  // defined(__ANDROID__)
         CoherentMemoryPtr coherentMemory = nullptr;
+        VirtGpuBlobPtr blobPtr = nullptr;
     };
 
     struct VkCommandBuffer_Info {
@@ -768,14 +768,15 @@
         VkDeviceSize currentBackingSize = 0;
         bool baseRequirementsKnown = false;
         VkMemoryRequirements baseRequirements;
-    #ifdef VK_USE_PLATFORM_ANDROID_KHR
+#ifdef VK_USE_PLATFORM_ANDROID_KHR
         bool hasExternalFormat = false;
         unsigned androidFormat = 0;
         std::vector<int> pendingQsriSyncFds;
-    #endif
-    #ifdef VK_USE_PLATFORM_FUCHSIA
+#endif
+#ifdef VK_USE_PLATFORM_FUCHSIA
         bool isSysmemBackedMemory = false;
-    #endif
+#endif
+        bool isWsiImage = false;
     };
 
     struct VkBuffer_Info {
@@ -788,9 +789,9 @@
         VkDeviceSize currentBackingSize = 0;
         bool baseRequirementsKnown = false;
         VkMemoryRequirements baseRequirements;
-    #ifdef VK_USE_PLATFORM_FUCHSIA
+#ifdef VK_USE_PLATFORM_FUCHSIA
         bool isSysmemBackedMemory = false;
-    #endif
+#endif
     };
 
     struct VkSemaphore_Info {
@@ -822,9 +823,9 @@
         VkDevice device;
         bool external = false;
         VkExportFenceCreateInfo exportFenceCreateInfo;
-    #if defined(VK_USE_PLATFORM_ANDROID_KHR) || defined(__linux__)
+#if defined(VK_USE_PLATFORM_ANDROID_KHR) || defined(__linux__)
         int syncFd = -1;
-    #endif
+#endif
     };
 
     struct VkDescriptorPool_Info {
@@ -848,26 +849,23 @@
     };
 
     struct VkBufferCollectionFUCHSIA_Info {
-    #ifdef VK_USE_PLATFORM_FUCHSIA
+#ifdef VK_USE_PLATFORM_FUCHSIA
         gfxstream::guest::Optional<fuchsia_sysmem::wire::BufferCollectionConstraints> constraints;
         gfxstream::guest::Optional<VkBufferCollectionPropertiesFUCHSIA> properties;
 
         // the index of corresponding createInfo for each image format
         // constraints in |constraints|.
         std::vector<uint32_t> createInfoIndex;
-    #endif  // VK_USE_PLATFORM_FUCHSIA
+#endif  // VK_USE_PLATFORM_FUCHSIA
     };
 
     VkDescriptorImageInfo filterNonexistentSampler(const VkDescriptorImageInfo& inputInfo);
 
-    void emitDeviceMemoryReport(VkDevice_Info info,
-                                VkDeviceMemoryReportEventTypeEXT type,
-                                uint64_t memoryObjectId,
-                                VkDeviceSize size,
-                                VkObjectType objectType,
-                                uint64_t objectHandle,
-                                uint32_t heapIndex = 0);
+    void emitDeviceMemoryReport(VkDevice_Info info, VkDeviceMemoryReportEventTypeEXT type,
+                                uint64_t memoryObjectId, VkDeviceSize size, VkObjectType objectType,
+                                uint64_t objectHandle, uint32_t heapIndex = 0);
 
+    void transformImageMemoryRequirementsForGuestLocked(VkImage image, VkMemoryRequirements* reqs);
     CoherentMemoryPtr freeCoherentMemoryLocked(VkDeviceMemory memory, VkDeviceMemory_Info& info);
 
     mutable RecursiveLock mLock;
@@ -893,10 +891,9 @@
     fidl::WireSyncClient<fuchsia_sysmem::Allocator> mSysmemAllocator;
 #endif
 
-#define HANDLE_REGISTER_DECLARATION(type)              \
-    std::unordered_map<type, type##_Info> info_##type;
+#define HANDLE_REGISTER_DECLARATION(type) std::unordered_map<type, type##_Info> info_##type;
 
-GOLDFISH_VK_LIST_HANDLE_TYPES(HANDLE_REGISTER_DECLARATION)
+    GOLDFISH_VK_LIST_HANDLE_TYPES(HANDLE_REGISTER_DECLARATION)
 
     WorkPool mWorkPool{4};
     std::unordered_map<VkQueue, std::vector<WorkPool::WaitGroupHandle>>
diff --git a/guest/vulkan_enc/Resources.cpp b/guest/vulkan_enc/Resources.cpp
index 00cfd9d..e60e950 100644
--- a/guest/vulkan_enc/Resources.cpp
+++ b/guest/vulkan_enc/Resources.cpp
@@ -19,10 +19,10 @@
 #define GOLDFISH_VK_OBJECT_DEBUG 0
 
 #if GOLDFISH_VK_OBJECT_DEBUG
-#define D(fmt,...) ALOGD("%s: " fmt, __func__, ##__VA_ARGS__);
+#define D(fmt, ...) ALOGD("%s: " fmt, __func__, ##__VA_ARGS__);
 #else
 #ifndef D
-#define D(fmt,...)
+#define D(fmt, ...)
 #endif
 #endif
 
@@ -36,105 +36,103 @@
 #define SET_HWVULKAN_DISPATCH_MAGIC
 #endif
 
-#define GOLDFISH_VK_NEW_DISPATCHABLE_FROM_HOST_IMPL(type) \
-    type new_from_host_##type(type underlying) { \
-        struct goldfish_##type* res = \
+#define GOLDFISH_VK_NEW_DISPATCHABLE_FROM_HOST_IMPL(type)                   \
+    type new_from_host_##type(type underlying) {                            \
+        struct goldfish_##type* res =                                       \
             static_cast<goldfish_##type*>(malloc(sizeof(goldfish_##type))); \
-        if (!res) { \
-            ALOGE("FATAL: Failed to alloc " #type " handle"); \
-            abort(); \
-        } \
-        SET_HWVULKAN_DISPATCH_MAGIC \
-        res->underlying = (uint64_t)underlying; \
-        res->lastUsedEncoder = nullptr; \
-        res->sequenceNumber = 0; \
-        res->privateEncoder = 0; \
-        res->privateStream = 0; \
-        res->flags = 0; \
-        res->poolObjects = 0; \
-        res->subObjects = 0; \
-        res->superObjects = 0; \
-        res->userPtr = 0; \
-        return reinterpret_cast<type>(res); \
-    } \
+        if (!res) {                                                         \
+            ALOGE("FATAL: Failed to alloc " #type " handle");               \
+            abort();                                                        \
+        }                                                                   \
+        SET_HWVULKAN_DISPATCH_MAGIC                                         \
+        res->underlying = (uint64_t)underlying;                             \
+        res->lastUsedEncoder = nullptr;                                     \
+        res->sequenceNumber = 0;                                            \
+        res->privateEncoder = 0;                                            \
+        res->privateStream = 0;                                             \
+        res->flags = 0;                                                     \
+        res->poolObjects = 0;                                               \
+        res->subObjects = 0;                                                \
+        res->superObjects = 0;                                              \
+        res->userPtr = 0;                                                   \
+        return reinterpret_cast<type>(res);                                 \
+    }
 
-#define GOLDFISH_VK_NEW_TRIVIAL_NON_DISPATCHABLE_FROM_HOST_IMPL(type) \
-    type new_from_host_##type(type underlying) { \
-        struct goldfish_##type* res = \
+#define GOLDFISH_VK_NEW_TRIVIAL_NON_DISPATCHABLE_FROM_HOST_IMPL(type)       \
+    type new_from_host_##type(type underlying) {                            \
+        struct goldfish_##type* res =                                       \
             static_cast<goldfish_##type*>(malloc(sizeof(goldfish_##type))); \
-        res->underlying = (uint64_t)underlying; \
-        res->poolObjects = 0; \
-        res->subObjects = 0; \
-        res->superObjects = 0; \
-        res->userPtr = 0; \
-        return reinterpret_cast<type>(res); \
-    } \
+        res->underlying = (uint64_t)underlying;                             \
+        res->poolObjects = 0;                                               \
+        res->subObjects = 0;                                                \
+        res->superObjects = 0;                                              \
+        res->userPtr = 0;                                                   \
+        return reinterpret_cast<type>(res);                                 \
+    }
 
-#define GOLDFISH_VK_AS_GOLDFISH_IMPL(type) \
+#define GOLDFISH_VK_AS_GOLDFISH_IMPL(type)                    \
     struct goldfish_##type* as_goldfish_##type(type toCast) { \
-        return reinterpret_cast<goldfish_##type*>(toCast); \
-    } \
+        return reinterpret_cast<goldfish_##type*>(toCast);    \
+    }
 
-#define GOLDFISH_VK_GET_HOST_IMPL(type) \
-    type get_host_##type(type toUnwrap) { \
-        if (!toUnwrap) return VK_NULL_HANDLE; \
+#define GOLDFISH_VK_GET_HOST_IMPL(type)                  \
+    type get_host_##type(type toUnwrap) {                \
+        if (!toUnwrap) return VK_NULL_HANDLE;            \
         auto as_goldfish = as_goldfish_##type(toUnwrap); \
-        return (type)(as_goldfish->underlying); \
-    } \
+        return (type)(as_goldfish->underlying);          \
+    }
 
-#define GOLDFISH_VK_DELETE_GOLDFISH_IMPL(type) \
+#define GOLDFISH_VK_DELETE_GOLDFISH_IMPL(type)   \
     void delete_goldfish_##type(type toDelete) { \
-        D("guest %p", toDelete); \
-        free(as_goldfish_##type(toDelete)); \
-    } \
+        D("guest %p", toDelete);                 \
+        free(as_goldfish_##type(toDelete));      \
+    }
 
 #define GOLDFISH_VK_IDENTITY_IMPL(type) \
-    type vk_handle_identity_##type(type handle) { \
-        return handle; \
-    } \
+    type vk_handle_identity_##type(type handle) { return handle; }
 
-#define GOLDFISH_VK_NEW_DISPATCHABLE_FROM_HOST_U64_IMPL(type) \
-    type new_from_host_u64_##type(uint64_t underlying) { \
-        struct goldfish_##type* res = \
+#define GOLDFISH_VK_NEW_DISPATCHABLE_FROM_HOST_U64_IMPL(type)               \
+    type new_from_host_u64_##type(uint64_t underlying) {                    \
+        struct goldfish_##type* res =                                       \
             static_cast<goldfish_##type*>(malloc(sizeof(goldfish_##type))); \
-        if (!res) { \
-            ALOGE("FATAL: Failed to alloc " #type " handle"); \
-            abort(); \
-        } \
-        SET_HWVULKAN_DISPATCH_MAGIC \
-        res->underlying = underlying; \
-        res->lastUsedEncoder = nullptr; \
-        res->sequenceNumber = 0; \
-        res->privateEncoder = 0; \
-        res->privateStream = 0; \
-        res->flags = 0; \
-        res->poolObjects = 0; \
-        res->subObjects = 0; \
-        res->superObjects = 0; \
-        res->userPtr = 0; \
-        return reinterpret_cast<type>(res); \
-    } \
+        if (!res) {                                                         \
+            ALOGE("FATAL: Failed to alloc " #type " handle");               \
+            abort();                                                        \
+        }                                                                   \
+        SET_HWVULKAN_DISPATCH_MAGIC                                         \
+        res->underlying = underlying;                                       \
+        res->lastUsedEncoder = nullptr;                                     \
+        res->sequenceNumber = 0;                                            \
+        res->privateEncoder = 0;                                            \
+        res->privateStream = 0;                                             \
+        res->flags = 0;                                                     \
+        res->poolObjects = 0;                                               \
+        res->subObjects = 0;                                                \
+        res->superObjects = 0;                                              \
+        res->userPtr = 0;                                                   \
+        return reinterpret_cast<type>(res);                                 \
+    }
 
-#define GOLDFISH_VK_NEW_TRIVIAL_NON_DISPATCHABLE_FROM_HOST_U64_IMPL(type) \
-    type new_from_host_u64_##type(uint64_t underlying) { \
-        struct goldfish_##type* res = \
-            static_cast<goldfish_##type*>(malloc(sizeof(goldfish_##type))); \
-        res->underlying = underlying; \
+#define GOLDFISH_VK_NEW_TRIVIAL_NON_DISPATCHABLE_FROM_HOST_U64_IMPL(type)          \
+    type new_from_host_u64_##type(uint64_t underlying) {                           \
+        struct goldfish_##type* res =                                              \
+            static_cast<goldfish_##type*>(malloc(sizeof(goldfish_##type)));        \
+        res->underlying = underlying;                                              \
         D("guest %p: host u64: 0x%llx", res, (unsigned long long)res->underlying); \
-        res->poolObjects = 0; \
-        res->subObjects = 0; \
-        res->superObjects = 0; \
-        res->userPtr = 0; \
-        return reinterpret_cast<type>(res); \
-    } \
+        res->poolObjects = 0;                                                      \
+        res->subObjects = 0;                                                       \
+        res->superObjects = 0;                                                     \
+        res->userPtr = 0;                                                          \
+        return reinterpret_cast<type>(res);                                        \
+    }
 
-#define GOLDFISH_VK_GET_HOST_U64_IMPL(type) \
-    uint64_t get_host_u64_##type(type toUnwrap) { \
-        if (!toUnwrap) return 0; \
-        auto as_goldfish = as_goldfish_##type(toUnwrap); \
+#define GOLDFISH_VK_GET_HOST_U64_IMPL(type)                                                     \
+    uint64_t get_host_u64_##type(type toUnwrap) {                                               \
+        if (!toUnwrap) return 0;                                                                \
+        auto as_goldfish = as_goldfish_##type(toUnwrap);                                        \
         D("guest %p: host u64: 0x%llx", toUnwrap, (unsigned long long)as_goldfish->underlying); \
-        return as_goldfish->underlying; \
-    } \
+        return as_goldfish->underlying;                                                         \
+    }
 
 GOLDFISH_VK_LIST_DISPATCHABLE_HANDLE_TYPES(GOLDFISH_VK_NEW_DISPATCHABLE_FROM_HOST_IMPL)
 GOLDFISH_VK_LIST_DISPATCHABLE_HANDLE_TYPES(GOLDFISH_VK_AS_GOLDFISH_IMPL)
@@ -148,8 +146,10 @@
 GOLDFISH_VK_LIST_NON_DISPATCHABLE_HANDLE_TYPES(GOLDFISH_VK_GET_HOST_IMPL)
 GOLDFISH_VK_LIST_NON_DISPATCHABLE_HANDLE_TYPES(GOLDFISH_VK_IDENTITY_IMPL)
 GOLDFISH_VK_LIST_NON_DISPATCHABLE_HANDLE_TYPES(GOLDFISH_VK_GET_HOST_U64_IMPL)
-GOLDFISH_VK_LIST_AUTODEFINED_STRUCT_NON_DISPATCHABLE_HANDLE_TYPES(GOLDFISH_VK_NEW_TRIVIAL_NON_DISPATCHABLE_FROM_HOST_IMPL)
-GOLDFISH_VK_LIST_AUTODEFINED_STRUCT_NON_DISPATCHABLE_HANDLE_TYPES(GOLDFISH_VK_NEW_TRIVIAL_NON_DISPATCHABLE_FROM_HOST_U64_IMPL)
+GOLDFISH_VK_LIST_AUTODEFINED_STRUCT_NON_DISPATCHABLE_HANDLE_TYPES(
+    GOLDFISH_VK_NEW_TRIVIAL_NON_DISPATCHABLE_FROM_HOST_IMPL)
+GOLDFISH_VK_LIST_AUTODEFINED_STRUCT_NON_DISPATCHABLE_HANDLE_TYPES(
+    GOLDFISH_VK_NEW_TRIVIAL_NON_DISPATCHABLE_FROM_HOST_U64_IMPL)
 GOLDFISH_VK_LIST_NON_DISPATCHABLE_HANDLE_TYPES(GOLDFISH_VK_DELETE_GOLDFISH_IMPL)
 
 VkDescriptorPool new_from_host_VkDescriptorPool(VkDescriptorPool underlying) {
@@ -177,8 +177,8 @@
 }
 
 VkDescriptorSetLayout new_from_host_VkDescriptorSetLayout(VkDescriptorSetLayout underlying) {
-    struct goldfish_VkDescriptorSetLayout* res =
-        static_cast<goldfish_VkDescriptorSetLayout*>(malloc(sizeof(goldfish_VkDescriptorSetLayout)));
+    struct goldfish_VkDescriptorSetLayout* res = static_cast<goldfish_VkDescriptorSetLayout*>(
+        malloc(sizeof(goldfish_VkDescriptorSetLayout)));
     res->underlying = (uint64_t)underlying;
     res->layoutInfo = nullptr;
     return reinterpret_cast<VkDescriptorSetLayout>(res);
@@ -188,7 +188,7 @@
     return new_from_host_VkDescriptorSetLayout((VkDescriptorSetLayout)underlying);
 }
 
-} // extern "C"
+}  // extern "C"
 
 namespace gfxstream {
 namespace vk {
@@ -199,7 +199,11 @@
     o->next = nullptr;
     o->obj = val;
     D("new ptr: %p", o);
-    if (!*begin) { D("first"); *begin = o; return; }
+    if (!*begin) {
+        D("first");
+        *begin = o;
+        return;
+    }
 
     struct goldfish_vk_object_list* q = *begin;
     struct goldfish_vk_object_list* p = q;
@@ -214,7 +218,7 @@
 }
 
 void eraseObject(struct goldfish_vk_object_list** begin, void* val) {
-        D("for val %p", val);
+    D("for val %p", val);
     if (!*begin) {
         D("val %p notfound", val);
         return;
@@ -241,7 +245,7 @@
         q = n;
     }
 
-        D("val %p notfound after looping", val);
+    D("val %p notfound after looping", val);
 }
 
 void eraseObjects(struct goldfish_vk_object_list** begin) {
diff --git a/guest/vulkan_enc/Resources.h b/guest/vulkan_enc/Resources.h
index 3e48f5c..1166da4 100644
--- a/guest/vulkan_enc/Resources.h
+++ b/guest/vulkan_enc/Resources.h
@@ -18,14 +18,13 @@
 #elif defined(__linux__)
 #include <vulkan/vk_icd.h>
 #endif
+#include <inttypes.h>
 #include <vulkan/vulkan.h>
 
-#include "VulkanHandles.h"
-
-#include <inttypes.h>
-
 #include <functional>
 
+#include "VulkanHandles.h"
+
 namespace gfxstream {
 namespace guest {
 class IOStream;
@@ -41,7 +40,6 @@
 }  // namespace vk
 }  // namespace gfxstream
 
-
 extern "C" {
 
 struct goldfish_vk_object_list {
@@ -58,51 +56,45 @@
 #endif
 
 #define GOLDFISH_VK_DEFINE_DISPATCHABLE_HANDLE_STRUCT(type) \
-    struct goldfish_##type { \
-        DECLARE_HWVULKAN_DISPATCH \
-        uint64_t underlying; \
-        gfxstream::vk::VkEncoder* lastUsedEncoder; \
-        uint32_t sequenceNumber; \
-        gfxstream::vk::VkEncoder* privateEncoder; \
-        gfxstream::guest::IOStream* privateStream; \
-        uint32_t flags; \
-        struct goldfish_vk_object_list* poolObjects; \
-        struct goldfish_vk_object_list* subObjects; \
-        struct goldfish_vk_object_list* superObjects; \
-        void* userPtr; \
-    }; \
+    struct goldfish_##type {                                \
+        DECLARE_HWVULKAN_DISPATCH                           \
+        uint64_t underlying;                                \
+        gfxstream::vk::VkEncoder* lastUsedEncoder;          \
+        uint32_t sequenceNumber;                            \
+        gfxstream::vk::VkEncoder* privateEncoder;           \
+        gfxstream::guest::IOStream* privateStream;          \
+        uint32_t flags;                                     \
+        struct goldfish_vk_object_list* poolObjects;        \
+        struct goldfish_vk_object_list* subObjects;         \
+        struct goldfish_vk_object_list* superObjects;       \
+        void* userPtr;                                      \
+    };
 
 #define GOLDFISH_VK_DEFINE_TRIVIAL_NON_DISPATCHABLE_HANDLE_STRUCT(type) \
-    struct goldfish_##type { \
-        uint64_t underlying; \
-        struct goldfish_vk_object_list* poolObjects; \
-        struct goldfish_vk_object_list* subObjects; \
-        struct goldfish_vk_object_list* superObjects; \
-        void* userPtr; \
-    }; \
+    struct goldfish_##type {                                            \
+        uint64_t underlying;                                            \
+        struct goldfish_vk_object_list* poolObjects;                    \
+        struct goldfish_vk_object_list* subObjects;                     \
+        struct goldfish_vk_object_list* superObjects;                   \
+        void* userPtr;                                                  \
+    };
 
-#define GOLDFISH_VK_NEW_FROM_HOST_DECL(type) \
-    type new_from_host_##type(type);
+#define GOLDFISH_VK_NEW_FROM_HOST_DECL(type) type new_from_host_##type(type);
 
-#define GOLDFISH_VK_AS_GOLDFISH_DECL(type) \
-    struct goldfish_##type* as_goldfish_##type(type);
+#define GOLDFISH_VK_AS_GOLDFISH_DECL(type) struct goldfish_##type* as_goldfish_##type(type);
 
-#define GOLDFISH_VK_GET_HOST_DECL(type) \
-    type get_host_##type(type);
+#define GOLDFISH_VK_GET_HOST_DECL(type) type get_host_##type(type);
 
-#define GOLDFISH_VK_DELETE_GOLDFISH_DECL(type) \
-    void delete_goldfish_##type(type);
+#define GOLDFISH_VK_DELETE_GOLDFISH_DECL(type) void delete_goldfish_##type(type);
 
-#define GOLDFISH_VK_IDENTITY_DECL(type) \
-    type vk_handle_identity_##type(type);
+#define GOLDFISH_VK_IDENTITY_DECL(type) type vk_handle_identity_##type(type);
 
-#define GOLDFISH_VK_NEW_FROM_HOST_U64_DECL(type) \
-    type new_from_host_u64_##type(uint64_t);
+#define GOLDFISH_VK_NEW_FROM_HOST_U64_DECL(type) type new_from_host_u64_##type(uint64_t);
 
-#define GOLDFISH_VK_GET_HOST_U64_DECL(type) \
-    uint64_t get_host_u64_##type(type);
+#define GOLDFISH_VK_GET_HOST_U64_DECL(type) uint64_t get_host_u64_##type(type);
 
-GOLDFISH_VK_LIST_AUTODEFINED_STRUCT_DISPATCHABLE_HANDLE_TYPES(GOLDFISH_VK_DEFINE_DISPATCHABLE_HANDLE_STRUCT)
+GOLDFISH_VK_LIST_AUTODEFINED_STRUCT_DISPATCHABLE_HANDLE_TYPES(
+    GOLDFISH_VK_DEFINE_DISPATCHABLE_HANDLE_STRUCT)
 GOLDFISH_VK_LIST_DISPATCHABLE_HANDLE_TYPES(GOLDFISH_VK_NEW_FROM_HOST_DECL)
 GOLDFISH_VK_LIST_DISPATCHABLE_HANDLE_TYPES(GOLDFISH_VK_AS_GOLDFISH_DECL)
 GOLDFISH_VK_LIST_DISPATCHABLE_HANDLE_TYPES(GOLDFISH_VK_GET_HOST_DECL)
@@ -118,7 +110,8 @@
 GOLDFISH_VK_LIST_NON_DISPATCHABLE_HANDLE_TYPES(GOLDFISH_VK_IDENTITY_DECL)
 GOLDFISH_VK_LIST_NON_DISPATCHABLE_HANDLE_TYPES(GOLDFISH_VK_NEW_FROM_HOST_U64_DECL)
 GOLDFISH_VK_LIST_NON_DISPATCHABLE_HANDLE_TYPES(GOLDFISH_VK_GET_HOST_U64_DECL)
-GOLDFISH_VK_LIST_AUTODEFINED_STRUCT_NON_DISPATCHABLE_HANDLE_TYPES(GOLDFISH_VK_DEFINE_TRIVIAL_NON_DISPATCHABLE_HANDLE_STRUCT)
+GOLDFISH_VK_LIST_AUTODEFINED_STRUCT_NON_DISPATCHABLE_HANDLE_TYPES(
+    GOLDFISH_VK_DEFINE_TRIVIAL_NON_DISPATCHABLE_HANDLE_STRUCT)
 
 struct goldfish_VkDescriptorPool {
     uint64_t underlying;
@@ -151,7 +144,7 @@
     VkDevice device;
 };
 
-} // extern "C"
+}  // extern "C"
 
 namespace gfxstream {
 namespace vk {
diff --git a/guest/vulkan_enc/Validation.cpp b/guest/vulkan_enc/Validation.cpp
index 3b75786..00652fc 100644
--- a/guest/vulkan_enc/Validation.cpp
+++ b/guest/vulkan_enc/Validation.cpp
@@ -13,19 +13,15 @@
 // limitations under the License.
 #include "Validation.h"
 
-#include "Resources.h"
 #include "ResourceTracker.h"
+#include "Resources.h"
 
 namespace gfxstream {
 namespace vk {
 
-VkResult Validation::on_vkFlushMappedMemoryRanges(
-    void*,
-    VkResult,
-    VkDevice,
-    uint32_t memoryRangeCount,
-    const VkMappedMemoryRange* pMemoryRanges) {
-
+VkResult Validation::on_vkFlushMappedMemoryRanges(void*, VkResult, VkDevice,
+                                                  uint32_t memoryRangeCount,
+                                                  const VkMappedMemoryRange* pMemoryRanges) {
     auto resources = ResourceTracker::get();
 
     for (uint32_t i = 0; i < memoryRangeCount; ++i) {
@@ -37,13 +33,9 @@
     return VK_SUCCESS;
 }
 
-VkResult Validation::on_vkInvalidateMappedMemoryRanges(
-    void*,
-    VkResult,
-    VkDevice,
-    uint32_t memoryRangeCount,
-    const VkMappedMemoryRange* pMemoryRanges) {
-
+VkResult Validation::on_vkInvalidateMappedMemoryRanges(void*, VkResult, VkDevice,
+                                                       uint32_t memoryRangeCount,
+                                                       const VkMappedMemoryRange* pMemoryRanges) {
     auto resources = ResourceTracker::get();
 
     for (uint32_t i = 0; i < memoryRangeCount; ++i) {
diff --git a/guest/vulkan_enc/Validation.h b/guest/vulkan_enc/Validation.h
index 0dfd2d3..e4ebc5f 100644
--- a/guest/vulkan_enc/Validation.h
+++ b/guest/vulkan_enc/Validation.h
@@ -19,19 +19,13 @@
 namespace vk {
 
 class Validation {
-public:
-    VkResult on_vkFlushMappedMemoryRanges(
-        void* context,
-        VkResult input_result,
-        VkDevice device,
-        uint32_t memoryRangeCount,
-        const VkMappedMemoryRange* pMemoryRanges);
-    VkResult on_vkInvalidateMappedMemoryRanges(
-        void* context,
-        VkResult input_result,
-        VkDevice device,
-        uint32_t memoryRangeCount,
-        const VkMappedMemoryRange* pMemoryRanges);
+   public:
+    VkResult on_vkFlushMappedMemoryRanges(void* context, VkResult input_result, VkDevice device,
+                                          uint32_t memoryRangeCount,
+                                          const VkMappedMemoryRange* pMemoryRanges);
+    VkResult on_vkInvalidateMappedMemoryRanges(void* context, VkResult input_result,
+                                               VkDevice device, uint32_t memoryRangeCount,
+                                               const VkMappedMemoryRange* pMemoryRanges);
 };
 
 }  // namespace vk
diff --git a/guest/vulkan_enc/VkEncoder.cpp b/guest/vulkan_enc/VkEncoder.cpp
index a3b2ddd..c9ef5c4 100644
--- a/guest/vulkan_enc/VkEncoder.cpp
+++ b/guest/vulkan_enc/VkEncoder.cpp
@@ -33178,6 +33178,8 @@
 #endif
 #ifdef VK_EXT_texture_compression_astc_hdr
 #endif
+#ifdef VK_EXT_depth_clip_enable
+#endif
 #ifdef VK_EXT_swapchain_colorspace
 #endif
 #ifdef VK_EXT_queue_family_foreign
@@ -39161,6 +39163,8 @@
 #endif
 #ifdef VK_EXT_image_compression_control_swapchain
 #endif
+#ifdef VK_QNX_external_memory_screen_buffer
+#endif
 
 }  // namespace vk
 }  // namespace gfxstream
diff --git a/guest/vulkan_enc/VkEncoder.h b/guest/vulkan_enc/VkEncoder.h
index 794db47..5a40b30 100644
--- a/guest/vulkan_enc/VkEncoder.h
+++ b/guest/vulkan_enc/VkEncoder.h
@@ -919,6 +919,8 @@
 #endif
 #ifdef VK_EXT_texture_compression_astc_hdr
 #endif
+#ifdef VK_EXT_depth_clip_enable
+#endif
 #ifdef VK_EXT_swapchain_colorspace
 #endif
 #ifdef VK_EXT_queue_family_foreign
@@ -1133,6 +1135,8 @@
 #endif
 #ifdef VK_EXT_image_compression_control_swapchain
 #endif
+#ifdef VK_QNX_external_memory_screen_buffer
+#endif
 
    private:
     class Impl;
diff --git a/guest/vulkan_enc/VulkanHandleMapping.cpp b/guest/vulkan_enc/VulkanHandleMapping.cpp
index 068e666..1b5c6a6 100644
--- a/guest/vulkan_enc/VulkanHandleMapping.cpp
+++ b/guest/vulkan_enc/VulkanHandleMapping.cpp
@@ -12,24 +12,29 @@
 // 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.
-#include <vulkan/vulkan.h>
-
 #include "VulkanHandleMapping.h"
 
+#include <vulkan/vulkan.h>
+
 namespace gfxstream {
 namespace vk {
 
-#define DEFAULT_HANDLE_MAP_DEFINE(type) \
-void DefaultHandleMapping::mapHandles_##type(type*, size_t) { return; } \
-void DefaultHandleMapping::mapHandles_##type##_u64(const type* handles, uint64_t* handle_u64s, size_t count) { \
-    for (size_t i = 0; i < count; ++i) { handle_u64s[i] = (uint64_t)(uintptr_t)handles[i]; } \
-} \
-void DefaultHandleMapping::mapHandles_u64_##type(const uint64_t* handle_u64s, type* handles, size_t count) { \
-    for (size_t i = 0; i < count; ++i) { handles[i] = (type)(uintptr_t)handle_u64s[i]; } \
-} \
+#define DEFAULT_HANDLE_MAP_DEFINE(type)                                                            \
+    void DefaultHandleMapping::mapHandles_##type(type*, size_t) { return; }                        \
+    void DefaultHandleMapping::mapHandles_##type##_u64(const type* handles, uint64_t* handle_u64s, \
+                                                       size_t count) {                             \
+        for (size_t i = 0; i < count; ++i) {                                                       \
+            handle_u64s[i] = (uint64_t)(uintptr_t)handles[i];                                      \
+        }                                                                                          \
+    }                                                                                              \
+    void DefaultHandleMapping::mapHandles_u64_##type(const uint64_t* handle_u64s, type* handles,   \
+                                                     size_t count) {                               \
+        for (size_t i = 0; i < count; ++i) {                                                       \
+            handles[i] = (type)(uintptr_t)handle_u64s[i];                                          \
+        }                                                                                          \
+    }
 
 GOLDFISH_VK_LIST_HANDLE_TYPES(DEFAULT_HANDLE_MAP_DEFINE)
 
 }  // namespace vk
 }  // namespace gfxstream
-
diff --git a/guest/vulkan_enc/VulkanHandleMapping.h b/guest/vulkan_enc/VulkanHandleMapping.h
index 7c7fdbc..08c229e 100644
--- a/guest/vulkan_enc/VulkanHandleMapping.h
+++ b/guest/vulkan_enc/VulkanHandleMapping.h
@@ -22,26 +22,29 @@
 namespace vk {
 
 class VulkanHandleMapping {
-public:
+   public:
     VulkanHandleMapping() = default;
-    virtual ~VulkanHandleMapping() { }
+    virtual ~VulkanHandleMapping() {}
 
-#define DECLARE_HANDLE_MAP_PURE_VIRTUAL_METHOD(type) \
-    virtual void mapHandles_##type(type* handles, size_t count = 1) = 0; \
-    virtual void mapHandles_##type##_u64(const type* handles, uint64_t* handle_u64s, size_t count = 1) = 0; \
-    virtual void mapHandles_u64_##type(const uint64_t* handle_u64s, type* handles, size_t count = 1) = 0; \
+#define DECLARE_HANDLE_MAP_PURE_VIRTUAL_METHOD(type)                                 \
+    virtual void mapHandles_##type(type* handles, size_t count = 1) = 0;             \
+    virtual void mapHandles_##type##_u64(const type* handles, uint64_t* handle_u64s, \
+                                         size_t count = 1) = 0;                      \
+    virtual void mapHandles_u64_##type(const uint64_t* handle_u64s, type* handles,   \
+                                       size_t count = 1) = 0;
 
     GOLDFISH_VK_LIST_HANDLE_TYPES(DECLARE_HANDLE_MAP_PURE_VIRTUAL_METHOD)
 };
 
 class DefaultHandleMapping : public VulkanHandleMapping {
-public:
-    virtual ~DefaultHandleMapping() { }
+   public:
+    virtual ~DefaultHandleMapping() {}
 
-#define DECLARE_HANDLE_MAP_OVERRIDE(type) \
-    void mapHandles_##type(type* handles, size_t count) override; \
-    void mapHandles_##type##_u64(const type* handles, uint64_t* handle_u64s, size_t count) override; \
-    void mapHandles_u64_##type(const uint64_t* handle_u64s, type* handles, size_t count) override; \
+#define DECLARE_HANDLE_MAP_OVERRIDE(type)                                                  \
+    void mapHandles_##type(type* handles, size_t count) override;                          \
+    void mapHandles_##type##_u64(const type* handles, uint64_t* handle_u64s, size_t count) \
+        override;                                                                          \
+    void mapHandles_u64_##type(const uint64_t* handle_u64s, type* handles, size_t count) override;
 
     GOLDFISH_VK_LIST_HANDLE_TYPES(DECLARE_HANDLE_MAP_OVERRIDE)
 };
diff --git a/guest/vulkan_enc/VulkanHandles.h b/guest/vulkan_enc/VulkanHandles.h
index cdec839..1be4d70 100644
--- a/guest/vulkan_enc/VulkanHandles.h
+++ b/guest/vulkan_enc/VulkanHandles.h
@@ -19,77 +19,75 @@
 namespace gfxstream {
 namespace vk {
 
-#define GOLDFISH_VK_LIST_TRIVIAL_DISPATCHABLE_HANDLE_TYPES(f) \
-    f(VkPhysicalDevice) \
+#define GOLDFISH_VK_LIST_TRIVIAL_DISPATCHABLE_HANDLE_TYPES(f) f(VkPhysicalDevice)
 
 #define GOLDFISH_VK_LIST_DISPATCHABLE_HANDLE_TYPES(f) \
-    f(VkInstance) \
-    f(VkDevice) \
-    f(VkCommandBuffer) \
-    f(VkQueue) \
+    f(VkInstance)                                     \
+    f(VkDevice)                                       \
+    f(VkCommandBuffer)                                \
+    f(VkQueue)                                        \
     GOLDFISH_VK_LIST_TRIVIAL_DISPATCHABLE_HANDLE_TYPES(f)
 
 #ifdef VK_NVX_binary_import
 
 #define __GOLDFISH_VK_LIST_NON_DISPATCHABLE_HANDLE_TYPES_NVX_BINARY_IMPORT(f) \
-    f(VkCuModuleNVX) \
-    f(VkCuFunctionNVX) \
+    f(VkCuModuleNVX)                                                          \
+    f(VkCuFunctionNVX)
 
 #else
 
 #define __GOLDFISH_VK_LIST_NON_DISPATCHABLE_HANDLE_TYPES_NVX_BINARY_IMPORT(f)
 
-#endif // VK_NVX_binary_import
+#endif  // VK_NVX_binary_import
 
 #ifdef VK_NVX_device_generated_commands
 
 #define __GOLDFISH_VK_LIST_NON_DISPATCHABLE_HANDLE_TYPES_NVX_DEVICE_GENERATED_COMMANDS(f) \
-    f(VkObjectTableNVX) \
-    f(VkIndirectCommandsLayoutNVX) \
+    f(VkObjectTableNVX)                                                                   \
+    f(VkIndirectCommandsLayoutNVX)
 
 #else
 
 #define __GOLDFISH_VK_LIST_NON_DISPATCHABLE_HANDLE_TYPES_NVX_DEVICE_GENERATED_COMMANDS(f)
 
-#endif // VK_NVX_device_generated_commands
+#endif  // VK_NVX_device_generated_commands
 
 #ifdef VK_NV_device_generated_commands
 
 #define __GOLDFISH_VK_LIST_NON_DISPATCHABLE_HANDLE_TYPES_NV_DEVICE_GENERATED_COMMANDS(f) \
-    f(VkIndirectCommandsLayoutNV) \
+    f(VkIndirectCommandsLayoutNV)
 
 #else
 
 #define __GOLDFISH_VK_LIST_NON_DISPATCHABLE_HANDLE_TYPES_NV_DEVICE_GENERATED_COMMANDS(f)
 
-#endif // VK_NV_device_generated_commands
+#endif  // VK_NV_device_generated_commands
 
 #ifdef VK_NV_ray_tracing
 
 #define __GOLDFISH_VK_LIST_NON_DISPATCHABLE_HANDLE_TYPES_NV_RAY_TRACING(f) \
-    f(VkAccelerationStructureNV) \
+    f(VkAccelerationStructureNV)
 
 #else
 
 #define __GOLDFISH_VK_LIST_NON_DISPATCHABLE_HANDLE_TYPES_NV_RAY_TRACING(f)
 
-#endif // VK_NV_ray_tracing
+#endif  // VK_NV_ray_tracing
 
 #ifdef VK_KHR_acceleration_structure
 
 #define __GOLDFISH_VK_LIST_NON_DISPATCHABLE_HANDLE_TYPES_KHR_ACCELERATION_STRUCTURE(f) \
-    f(VkAccelerationStructureKHR) \
+    f(VkAccelerationStructureKHR)
 
 #else
 
 #define __GOLDFISH_VK_LIST_NON_DISPATCHABLE_HANDLE_TYPES_KHR_ACCELERATION_STRUCTURE(f)
 
-#endif // VK_KHR_acceleration_structure
+#endif  // VK_KHR_acceleration_structure
 
 #ifdef VK_USE_PLATFORM_FUCHSIA
 
-#define __GOLDFISH_VK_LIST_NON_DISPATCHABLE_HANDLE_TYPES_FUCHSIA(f) \
-    f(VkBufferCollectionFUCHSIA)
+#define __GOLDFISH_VK_LIST_NON_DISPATCHABLE_HANDLE_TYPES_FUCHSIA(f) f(VkBufferCollectionFUCHSIA)
 
 #else
 
@@ -97,77 +95,77 @@
 
 #endif  // VK_USE_PLATFORM_FUCHSIA
 
-#define GOLDFISH_VK_LIST_TRIVIAL_NON_DISPATCHABLE_HANDLE_TYPES(f) \
-    f(VkBufferView) \
-    f(VkImageView) \
-    f(VkShaderModule) \
-    f(VkPipeline) \
-    f(VkPipelineCache) \
-    f(VkPipelineLayout) \
-    f(VkRenderPass) \
-    f(VkFramebuffer) \
-    f(VkEvent) \
-    f(VkQueryPool) \
-    f(VkSamplerYcbcrConversion) \
-    f(VkSurfaceKHR) \
-    f(VkSwapchainKHR) \
-    f(VkDisplayKHR) \
-    f(VkDisplayModeKHR) \
-    f(VkValidationCacheEXT) \
-    f(VkDebugReportCallbackEXT) \
-    f(VkDebugUtilsMessengerEXT) \
-    f(VkMicromapEXT) \
-    __GOLDFISH_VK_LIST_NON_DISPATCHABLE_HANDLE_TYPES_NVX_BINARY_IMPORT(f) \
+#define GOLDFISH_VK_LIST_TRIVIAL_NON_DISPATCHABLE_HANDLE_TYPES(f)                     \
+    f(VkBufferView)                                                                   \
+    f(VkImageView)                                                                    \
+    f(VkShaderModule)                                                                 \
+    f(VkPipeline)                                                                     \
+    f(VkPipelineCache)                                                                \
+    f(VkPipelineLayout)                                                               \
+    f(VkRenderPass)                                                                   \
+    f(VkFramebuffer)                                                                  \
+    f(VkEvent)                                                                        \
+    f(VkQueryPool)                                                                    \
+    f(VkSamplerYcbcrConversion)                                                       \
+    f(VkSurfaceKHR)                                                                   \
+    f(VkSwapchainKHR)                                                                 \
+    f(VkDisplayKHR)                                                                   \
+    f(VkDisplayModeKHR)                                                               \
+    f(VkValidationCacheEXT)                                                           \
+    f(VkDebugReportCallbackEXT)                                                       \
+    f(VkDebugUtilsMessengerEXT)                                                       \
+    f(VkMicromapEXT)                                                                  \
+    __GOLDFISH_VK_LIST_NON_DISPATCHABLE_HANDLE_TYPES_NVX_BINARY_IMPORT(f)             \
     __GOLDFISH_VK_LIST_NON_DISPATCHABLE_HANDLE_TYPES_NVX_DEVICE_GENERATED_COMMANDS(f) \
-    __GOLDFISH_VK_LIST_NON_DISPATCHABLE_HANDLE_TYPES_NV_DEVICE_GENERATED_COMMANDS(f) \
-    __GOLDFISH_VK_LIST_NON_DISPATCHABLE_HANDLE_TYPES_NV_RAY_TRACING(f) \
-    __GOLDFISH_VK_LIST_NON_DISPATCHABLE_HANDLE_TYPES_KHR_ACCELERATION_STRUCTURE(f) \
+    __GOLDFISH_VK_LIST_NON_DISPATCHABLE_HANDLE_TYPES_NV_DEVICE_GENERATED_COMMANDS(f)  \
+    __GOLDFISH_VK_LIST_NON_DISPATCHABLE_HANDLE_TYPES_NV_RAY_TRACING(f)                \
+    __GOLDFISH_VK_LIST_NON_DISPATCHABLE_HANDLE_TYPES_KHR_ACCELERATION_STRUCTURE(f)
 
-#define GOLDFISH_VK_LIST_NON_DISPATCHABLE_HANDLE_TYPES(f) \
-    f(VkDeviceMemory) \
-    f(VkBuffer) \
-    f(VkImage) \
-    f(VkSemaphore) \
-    f(VkDescriptorUpdateTemplate) \
-    f(VkFence) \
-    f(VkDescriptorPool) \
-    f(VkDescriptorSet) \
-    f(VkDescriptorSetLayout) \
-    f(VkCommandPool) \
-    f(VkSampler) \
+#define GOLDFISH_VK_LIST_NON_DISPATCHABLE_HANDLE_TYPES(f)       \
+    f(VkDeviceMemory)                                           \
+    f(VkBuffer)                                                 \
+    f(VkImage)                                                  \
+    f(VkSemaphore)                                              \
+    f(VkDescriptorUpdateTemplate)                               \
+    f(VkFence)                                                  \
+    f(VkDescriptorPool)                                         \
+    f(VkDescriptorSet)                                          \
+    f(VkDescriptorSetLayout)                                    \
+    f(VkCommandPool)                                            \
+    f(VkSampler)                                                \
     __GOLDFISH_VK_LIST_NON_DISPATCHABLE_HANDLE_TYPES_FUCHSIA(f) \
-    GOLDFISH_VK_LIST_TRIVIAL_NON_DISPATCHABLE_HANDLE_TYPES(f) \
+    GOLDFISH_VK_LIST_TRIVIAL_NON_DISPATCHABLE_HANDLE_TYPES(f)
 
-#define GOLDFISH_VK_LIST_HANDLE_TYPES(f) \
+#define GOLDFISH_VK_LIST_HANDLE_TYPES(f)          \
     GOLDFISH_VK_LIST_DISPATCHABLE_HANDLE_TYPES(f) \
     GOLDFISH_VK_LIST_NON_DISPATCHABLE_HANDLE_TYPES(f)
 
-#define GOLDFISH_VK_LIST_TRIVIAL_HANDLE_TYPES(f) \
+#define GOLDFISH_VK_LIST_TRIVIAL_HANDLE_TYPES(f)          \
     GOLDFISH_VK_LIST_TRIVIAL_DISPATCHABLE_HANDLE_TYPES(f) \
     GOLDFISH_VK_LIST_TRIVIAL_NON_DISPATCHABLE_HANDLE_TYPES(f)
 
 #define GOLDFISH_VK_LIST_AUTODEFINED_STRUCT_DISPATCHABLE_HANDLE_TYPES(f) \
-    f(VkInstance) \
-    f(VkDevice) \
-    f(VkQueue) \
+    f(VkInstance)                                                        \
+    f(VkDevice)                                                          \
+    f(VkQueue)                                                           \
     GOLDFISH_VK_LIST_TRIVIAL_DISPATCHABLE_HANDLE_TYPES(f)
 
 #define GOLDFISH_VK_LIST_AUTODEFINED_STRUCT_NON_DISPATCHABLE_HANDLE_TYPES(f) \
-    f(VkDeviceMemory) \
-    f(VkBuffer) \
-    f(VkImage) \
-    f(VkSemaphore) \
-    f(VkFence) \
-    f(VkDescriptorUpdateTemplate) \
-    f(VkCommandPool) \
-    f(VkSampler) \
-    __GOLDFISH_VK_LIST_NON_DISPATCHABLE_HANDLE_TYPES_FUCHSIA(f) \
-    GOLDFISH_VK_LIST_TRIVIAL_NON_DISPATCHABLE_HANDLE_TYPES(f) \
+    f(VkDeviceMemory)                                                        \
+    f(VkBuffer)                                                              \
+    f(VkImage)                                                               \
+    f(VkSemaphore)                                                           \
+    f(VkFence)                                                               \
+    f(VkDescriptorUpdateTemplate)                                            \
+    f(VkCommandPool)                                                         \
+    f(VkSampler)                                                             \
+    __GOLDFISH_VK_LIST_NON_DISPATCHABLE_HANDLE_TYPES_FUCHSIA(f)              \
+    GOLDFISH_VK_LIST_TRIVIAL_NON_DISPATCHABLE_HANDLE_TYPES(f)
 
 #define GOLDFISH_VK_LIST_MANUAL_STRUCT_NON_DISPATCHABLE_HANDLE_TYPES(f) \
-    f(VkDescriptorPool) \
-    f(VkDescriptorSetLayout) \
-    f(VkDescriptorSet) \
+    f(VkDescriptorPool)                                                 \
+    f(VkDescriptorSetLayout)                                            \
+    f(VkDescriptorSet)
 
 }  // namespace vk
 }  // namespace gfxstream
diff --git a/guest/vulkan_enc/VulkanStreamGuest.cpp b/guest/vulkan_enc/VulkanStreamGuest.cpp
index 459da45..53d4ad5 100644
--- a/guest/vulkan_enc/VulkanStreamGuest.cpp
+++ b/guest/vulkan_enc/VulkanStreamGuest.cpp
@@ -16,16 +16,14 @@
 namespace gfxstream {
 namespace vk {
 
-VulkanStreamGuest::VulkanStreamGuest(gfxstream::guest::IOStream *stream): mStream(stream) {
+VulkanStreamGuest::VulkanStreamGuest(gfxstream::guest::IOStream* stream) : mStream(stream) {
     unsetHandleMapping();
     mFeatureBits = ResourceTracker::get()->getStreamFeatures();
 }
 
 VulkanStreamGuest::~VulkanStreamGuest() = default;
 
-bool VulkanStreamGuest::valid() {
-    return true;
-}
+bool VulkanStreamGuest::valid() { return true; }
 
 void VulkanStreamGuest::alloc(void** ptrAddr, size_t bytes) {
     if (!bytes) {
@@ -56,7 +54,7 @@
 
     alloc((void**)forOutput, count * sizeof(char*));
 
-    char **stringsForOutput = *forOutput;
+    char** stringsForOutput = *forOutput;
 
     for (size_t i = 0; i < count; i++) {
         loadStringInPlace(stringsForOutput + i);
@@ -79,8 +77,9 @@
     }
 }
 
-void VulkanStreamGuest::loadStringArrayInPlaceWithStreamPtr(char*** forOutput, uint8_t** streamPtr) {
- uint32_t count;
+void VulkanStreamGuest::loadStringArrayInPlaceWithStreamPtr(char*** forOutput,
+                                                            uint8_t** streamPtr) {
+    uint32_t count;
     memcpy(&count, *streamPtr, sizeof(uint32_t));
     *streamPtr += sizeof(uint32_t);
     gfxstream::guest::Stream::fromBe32((uint8_t*)&count);
@@ -91,15 +90,14 @@
 
     alloc((void**)forOutput, count * sizeof(char*));
 
-    char **stringsForOutput = *forOutput;
+    char** stringsForOutput = *forOutput;
 
     for (size_t i = 0; i < count; i++) {
         loadStringInPlaceWithStreamPtr(stringsForOutput + i, streamPtr);
     }
 }
 
-
-ssize_t VulkanStreamGuest::read(void *buffer, size_t size) {
+ssize_t VulkanStreamGuest::read(void* buffer, size_t size) {
     if (!mStream->readback(buffer, size)) {
         ALOGE("FATAL: Could not read back %zu bytes", size);
         abort();
@@ -107,7 +105,7 @@
     return size;
 }
 
-ssize_t VulkanStreamGuest::write(const void *buffer, size_t size) {
+ssize_t VulkanStreamGuest::write(const void* buffer, size_t size) {
     uint8_t* streamBuf = (uint8_t*)mStream->alloc(size);
     memcpy(streamBuf, buffer, size);
     return size;
@@ -117,44 +115,30 @@
     mStream->writeFullyAsync(buffer, size);
 }
 
-void VulkanStreamGuest::clearPool() {
-    mPool.freeAll();
-}
+void VulkanStreamGuest::clearPool() { mPool.freeAll(); }
 
 void VulkanStreamGuest::setHandleMapping(VulkanHandleMapping* mapping) {
     mCurrentHandleMapping = mapping;
 }
 
-void VulkanStreamGuest::unsetHandleMapping() {
-    mCurrentHandleMapping = &mDefaultHandleMapping;
-}
+void VulkanStreamGuest::unsetHandleMapping() { mCurrentHandleMapping = &mDefaultHandleMapping; }
 
-VulkanHandleMapping* VulkanStreamGuest::handleMapping() const {
-    return mCurrentHandleMapping;
-}
+VulkanHandleMapping* VulkanStreamGuest::handleMapping() const { return mCurrentHandleMapping; }
 
 void VulkanStreamGuest::flush() {
     AEMU_SCOPED_TRACE("VulkanStreamGuest device write");
     mStream->flush();
 }
 
-uint32_t VulkanStreamGuest::getFeatureBits() const {
-    return mFeatureBits;
-}
+uint32_t VulkanStreamGuest::getFeatureBits() const { return mFeatureBits; }
 
-void VulkanStreamGuest::incStreamRef() {
-    mStream->incRef();
-}
+void VulkanStreamGuest::incStreamRef() { mStream->incRef(); }
 
-bool VulkanStreamGuest::decStreamRef() {
-    return mStream->decRef();
-}
+bool VulkanStreamGuest::decStreamRef() { return mStream->decRef(); }
 
-uint8_t* VulkanStreamGuest::reserve(size_t size) {
-    return (uint8_t*)mStream->alloc(size);
-}
+uint8_t* VulkanStreamGuest::reserve(size_t size) { return (uint8_t*)mStream->alloc(size); }
 
-VulkanCountingStream::VulkanCountingStream() : VulkanStreamGuest(nullptr) { }
+VulkanCountingStream::VulkanCountingStream() : VulkanStreamGuest(nullptr) {}
 VulkanCountingStream::~VulkanCountingStream() = default;
 
 ssize_t VulkanCountingStream::read(void*, size_t size) {
diff --git a/guest/vulkan_enc/VulkanStreamGuest.h b/guest/vulkan_enc/VulkanStreamGuest.h
index ae995e1..92052af 100644
--- a/guest/vulkan_enc/VulkanStreamGuest.h
+++ b/guest/vulkan_enc/VulkanStreamGuest.h
@@ -13,30 +13,26 @@
 // limitations under the License.
 #pragma once
 
-#include "aemu/base/files/Stream.h"
-#include "aemu/base/files/StreamSerializing.h"
+#include <inttypes.h>
+#include <log/log.h>
 
-#include "goldfish_vk_private_defs.h"
-
-#include "VulkanHandleMapping.h"
+#include <memory>
+#include <vector>
 
 #include "gfxstream/guest/IOStream.h"
 #include "ResourceTracker.h"
-
+#include "VulkanHandleMapping.h"
 #include "aemu/base/BumpPool.h"
 #include "aemu/base/Tracing.h"
-
-#include <vector>
-#include <memory>
-
-#include <log/log.h>
-#include <inttypes.h>
+#include "aemu/base/files/Stream.h"
+#include "aemu/base/files/StreamSerializing.h"
+#include "goldfish_vk_private_defs.h"
 
 namespace gfxstream {
 namespace vk {
 
 class VulkanStreamGuest : public gfxstream::guest::Stream {
-public:
+   public:
     VulkanStreamGuest(gfxstream::guest::IOStream* stream);
     ~VulkanStreamGuest();
 
@@ -55,8 +51,8 @@
     void loadStringInPlaceWithStreamPtr(char** forOutput, uint8_t** streamPtr);
     void loadStringArrayInPlaceWithStreamPtr(char*** forOutput, uint8_t** streamPtr);
 
-    ssize_t read(void *buffer, size_t size) override;
-    ssize_t write(const void *buffer, size_t size) override;
+    ssize_t read(void* buffer, size_t size) override;
+    ssize_t write(const void* buffer, size_t size) override;
 
     void writeLarge(const void* buffer, size_t size);
 
@@ -75,7 +71,8 @@
     bool decStreamRef();
 
     uint8_t* reserve(size_t size);
-private:
+
+   private:
     gfxstream::guest::BumpPool mPool;
     std::vector<uint8_t> mWriteBuffer;
     gfxstream::guest::IOStream* mStream = nullptr;
@@ -85,18 +82,19 @@
 };
 
 class VulkanCountingStream : public VulkanStreamGuest {
-public:
+   public:
     VulkanCountingStream();
     ~VulkanCountingStream();
 
-    ssize_t read(void *buffer, size_t size) override;
-    ssize_t write(const void *buffer, size_t size) override;
+    ssize_t read(void* buffer, size_t size) override;
+    ssize_t write(const void* buffer, size_t size) override;
 
     size_t bytesWritten() const { return m_written; }
     size_t bytesRead() const { return m_read; }
 
     void rewind();
-private:
+
+   private:
     size_t m_written = 0;
     size_t m_read = 0;
 };
diff --git a/guest/vulkan_enc/func_table.cpp b/guest/vulkan_enc/func_table.cpp
index e05ac1e..c4408c3 100644
--- a/guest/vulkan_enc/func_table.cpp
+++ b/guest/vulkan_enc/func_table.cpp
@@ -30,8 +30,6 @@
 // $CEREAL_OUTPUT_DIR
 //
 
-#include "func_table.h"
-
 #include <log/log.h>
 
 #include <cstring>
@@ -39,6 +37,8 @@
 #include "../OpenglSystemCommon/HostConnection.h"
 #include "ResourceTracker.h"
 #include "VkEncoder.h"
+#include "gfxstream_vk_entrypoints.h"
+#include "gfxstream_vk_private.h"
 #include "goldfish_vk_private_defs.h"
 
 // Stuff we are not going to use but if included,
@@ -49,2119 +49,3668 @@
 #if defined(LINUX_GUEST_BUILD) || defined(__Fuchsia__)
 #undef VK_ANDROID_native_buffer
 #endif
-
-namespace gfxstream {
-namespace vk {
-
-static void sOnInvalidDynamicallyCheckedCall(const char* apiname, const char* neededFeature) {
-    ALOGE("invalid call to %s: %s not supported", apiname, neededFeature);
-    abort();
-}
 #ifdef VK_VERSION_1_0
-static VkResult entry_vkCreateInstance(const VkInstanceCreateInfo* pCreateInfo,
-                                       const VkAllocationCallbacks* pAllocator,
-                                       VkInstance* pInstance) {
-    AEMU_SCOPED_TRACE("vkCreateInstance");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    VkResult vkCreateInstance_VkResult_return = (VkResult)0;
-    vkCreateInstance_VkResult_return =
-        vkEnc->vkCreateInstance(pCreateInfo, pAllocator, pInstance, true /* do lock */);
-    return vkCreateInstance_VkResult_return;
-}
-static void entry_vkDestroyInstance(VkInstance instance, const VkAllocationCallbacks* pAllocator) {
-    AEMU_SCOPED_TRACE("vkDestroyInstance");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkDestroyInstance(instance, pAllocator, true /* do lock */);
-}
-static VkResult entry_vkEnumeratePhysicalDevices(VkInstance instance,
-                                                 uint32_t* pPhysicalDeviceCount,
-                                                 VkPhysicalDevice* pPhysicalDevices) {
-    AEMU_SCOPED_TRACE("vkEnumeratePhysicalDevices");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    VkResult vkEnumeratePhysicalDevices_VkResult_return = (VkResult)0;
-    auto resources = ResourceTracker::get();
-    vkEnumeratePhysicalDevices_VkResult_return = resources->on_vkEnumeratePhysicalDevices(
-        vkEnc, VK_SUCCESS, instance, pPhysicalDeviceCount, pPhysicalDevices);
-    return vkEnumeratePhysicalDevices_VkResult_return;
-}
-static void entry_vkGetPhysicalDeviceFeatures(VkPhysicalDevice physicalDevice,
-                                              VkPhysicalDeviceFeatures* pFeatures) {
+void gfxstream_vk_GetPhysicalDeviceFeatures(VkPhysicalDevice physicalDevice,
+                                            VkPhysicalDeviceFeatures* pFeatures) {
     AEMU_SCOPED_TRACE("vkGetPhysicalDeviceFeatures");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkGetPhysicalDeviceFeatures(physicalDevice, pFeatures, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_physical_device, gfxstream_physicalDevice, physicalDevice);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkEnc->vkGetPhysicalDeviceFeatures(gfxstream_physicalDevice->internal_object, pFeatures,
+                                           true /* do lock */);
+    }
 }
-static void entry_vkGetPhysicalDeviceFormatProperties(VkPhysicalDevice physicalDevice,
-                                                      VkFormat format,
-                                                      VkFormatProperties* pFormatProperties) {
+void gfxstream_vk_GetPhysicalDeviceFormatProperties(VkPhysicalDevice physicalDevice,
+                                                    VkFormat format,
+                                                    VkFormatProperties* pFormatProperties) {
     AEMU_SCOPED_TRACE("vkGetPhysicalDeviceFormatProperties");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkGetPhysicalDeviceFormatProperties(physicalDevice, format, pFormatProperties,
-                                               true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_physical_device, gfxstream_physicalDevice, physicalDevice);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkEnc->vkGetPhysicalDeviceFormatProperties(gfxstream_physicalDevice->internal_object,
+                                                   format, pFormatProperties, true /* do lock */);
+    }
 }
-static VkResult entry_vkGetPhysicalDeviceImageFormatProperties(
+VkResult gfxstream_vk_GetPhysicalDeviceImageFormatProperties(
     VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, VkImageTiling tiling,
     VkImageUsageFlags usage, VkImageCreateFlags flags,
     VkImageFormatProperties* pImageFormatProperties) {
     AEMU_SCOPED_TRACE("vkGetPhysicalDeviceImageFormatProperties");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
     VkResult vkGetPhysicalDeviceImageFormatProperties_VkResult_return = (VkResult)0;
-    vkGetPhysicalDeviceImageFormatProperties_VkResult_return =
-        vkEnc->vkGetPhysicalDeviceImageFormatProperties(physicalDevice, format, type, tiling, usage,
-                                                        flags, pImageFormatProperties,
-                                                        true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_physical_device, gfxstream_physicalDevice, physicalDevice);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkGetPhysicalDeviceImageFormatProperties_VkResult_return =
+            vkEnc->vkGetPhysicalDeviceImageFormatProperties(
+                gfxstream_physicalDevice->internal_object, format, type, tiling, usage, flags,
+                pImageFormatProperties, true /* do lock */);
+    }
     return vkGetPhysicalDeviceImageFormatProperties_VkResult_return;
 }
-static void entry_vkGetPhysicalDeviceProperties(VkPhysicalDevice physicalDevice,
-                                                VkPhysicalDeviceProperties* pProperties) {
+void gfxstream_vk_GetPhysicalDeviceProperties(VkPhysicalDevice physicalDevice,
+                                              VkPhysicalDeviceProperties* pProperties) {
     AEMU_SCOPED_TRACE("vkGetPhysicalDeviceProperties");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkGetPhysicalDeviceProperties(physicalDevice, pProperties, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_physical_device, gfxstream_physicalDevice, physicalDevice);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkEnc->vkGetPhysicalDeviceProperties(gfxstream_physicalDevice->internal_object, pProperties,
+                                             true /* do lock */);
+    }
 }
-static void entry_vkGetPhysicalDeviceQueueFamilyProperties(
+void gfxstream_vk_GetPhysicalDeviceQueueFamilyProperties(
     VkPhysicalDevice physicalDevice, uint32_t* pQueueFamilyPropertyCount,
     VkQueueFamilyProperties* pQueueFamilyProperties) {
     AEMU_SCOPED_TRACE("vkGetPhysicalDeviceQueueFamilyProperties");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, pQueueFamilyPropertyCount,
-                                                    pQueueFamilyProperties, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_physical_device, gfxstream_physicalDevice, physicalDevice);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkEnc->vkGetPhysicalDeviceQueueFamilyProperties(gfxstream_physicalDevice->internal_object,
+                                                        pQueueFamilyPropertyCount,
+                                                        pQueueFamilyProperties, true /* do lock */);
+    }
 }
-static void entry_vkGetPhysicalDeviceMemoryProperties(
+void gfxstream_vk_GetPhysicalDeviceMemoryProperties(
     VkPhysicalDevice physicalDevice, VkPhysicalDeviceMemoryProperties* pMemoryProperties) {
     AEMU_SCOPED_TRACE("vkGetPhysicalDeviceMemoryProperties");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkGetPhysicalDeviceMemoryProperties(physicalDevice, pMemoryProperties,
-                                               true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_physical_device, gfxstream_physicalDevice, physicalDevice);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkEnc->vkGetPhysicalDeviceMemoryProperties(gfxstream_physicalDevice->internal_object,
+                                                   pMemoryProperties, true /* do lock */);
+    }
 }
-static PFN_vkVoidFunction entry_vkGetInstanceProcAddr(VkInstance instance, const char* pName) {
-    AEMU_SCOPED_TRACE("vkGetInstanceProcAddr");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    PFN_vkVoidFunction vkGetInstanceProcAddr_PFN_vkVoidFunction_return = (PFN_vkVoidFunction)0;
-    vkGetInstanceProcAddr_PFN_vkVoidFunction_return =
-        vkEnc->vkGetInstanceProcAddr(instance, pName, true /* do lock */);
-    return vkGetInstanceProcAddr_PFN_vkVoidFunction_return;
-}
-static PFN_vkVoidFunction entry_vkGetDeviceProcAddr(VkDevice device, const char* pName) {
-    AEMU_SCOPED_TRACE("vkGetDeviceProcAddr");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    PFN_vkVoidFunction vkGetDeviceProcAddr_PFN_vkVoidFunction_return = (PFN_vkVoidFunction)0;
-    vkGetDeviceProcAddr_PFN_vkVoidFunction_return =
-        vkEnc->vkGetDeviceProcAddr(device, pName, true /* do lock */);
-    return vkGetDeviceProcAddr_PFN_vkVoidFunction_return;
-}
-static VkResult entry_vkCreateDevice(VkPhysicalDevice physicalDevice,
-                                     const VkDeviceCreateInfo* pCreateInfo,
-                                     const VkAllocationCallbacks* pAllocator, VkDevice* pDevice) {
-    AEMU_SCOPED_TRACE("vkCreateDevice");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    VkResult vkCreateDevice_VkResult_return = (VkResult)0;
-    vkCreateDevice_VkResult_return =
-        vkEnc->vkCreateDevice(physicalDevice, pCreateInfo, pAllocator, pDevice, true /* do lock */);
-    return vkCreateDevice_VkResult_return;
-}
-static void entry_vkDestroyDevice(VkDevice device, const VkAllocationCallbacks* pAllocator) {
-    AEMU_SCOPED_TRACE("vkDestroyDevice");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkDestroyDevice(device, pAllocator, true /* do lock */);
-}
-static VkResult entry_vkEnumerateInstanceExtensionProperties(const char* pLayerName,
-                                                             uint32_t* pPropertyCount,
-                                                             VkExtensionProperties* pProperties) {
-    AEMU_SCOPED_TRACE("vkEnumerateInstanceExtensionProperties");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    VkResult vkEnumerateInstanceExtensionProperties_VkResult_return = (VkResult)0;
-    auto resources = ResourceTracker::get();
-    vkEnumerateInstanceExtensionProperties_VkResult_return =
-        resources->on_vkEnumerateInstanceExtensionProperties(vkEnc, VK_SUCCESS, pLayerName,
-                                                             pPropertyCount, pProperties);
-    return vkEnumerateInstanceExtensionProperties_VkResult_return;
-}
-static VkResult entry_vkEnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice,
-                                                           const char* pLayerName,
-                                                           uint32_t* pPropertyCount,
-                                                           VkExtensionProperties* pProperties) {
-    AEMU_SCOPED_TRACE("vkEnumerateDeviceExtensionProperties");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    VkResult vkEnumerateDeviceExtensionProperties_VkResult_return = (VkResult)0;
-    auto resources = ResourceTracker::get();
-    vkEnumerateDeviceExtensionProperties_VkResult_return =
-        resources->on_vkEnumerateDeviceExtensionProperties(vkEnc, VK_SUCCESS, physicalDevice,
-                                                           pLayerName, pPropertyCount, pProperties);
-    return vkEnumerateDeviceExtensionProperties_VkResult_return;
-}
-static VkResult entry_vkEnumerateInstanceLayerProperties(uint32_t* pPropertyCount,
-                                                         VkLayerProperties* pProperties) {
-    AEMU_SCOPED_TRACE("vkEnumerateInstanceLayerProperties");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    VkResult vkEnumerateInstanceLayerProperties_VkResult_return = (VkResult)0;
-    vkEnumerateInstanceLayerProperties_VkResult_return =
-        vkEnc->vkEnumerateInstanceLayerProperties(pPropertyCount, pProperties, true /* do lock */);
-    return vkEnumerateInstanceLayerProperties_VkResult_return;
-}
-static VkResult entry_vkEnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice,
-                                                       uint32_t* pPropertyCount,
-                                                       VkLayerProperties* pProperties) {
+VkResult gfxstream_vk_EnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice,
+                                                     uint32_t* pPropertyCount,
+                                                     VkLayerProperties* pProperties) {
     AEMU_SCOPED_TRACE("vkEnumerateDeviceLayerProperties");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
     VkResult vkEnumerateDeviceLayerProperties_VkResult_return = (VkResult)0;
-    vkEnumerateDeviceLayerProperties_VkResult_return = vkEnc->vkEnumerateDeviceLayerProperties(
-        physicalDevice, pPropertyCount, pProperties, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_physical_device, gfxstream_physicalDevice, physicalDevice);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkEnumerateDeviceLayerProperties_VkResult_return = vkEnc->vkEnumerateDeviceLayerProperties(
+            gfxstream_physicalDevice->internal_object, pPropertyCount, pProperties,
+            true /* do lock */);
+    }
     return vkEnumerateDeviceLayerProperties_VkResult_return;
 }
-static void entry_vkGetDeviceQueue(VkDevice device, uint32_t queueFamilyIndex, uint32_t queueIndex,
-                                   VkQueue* pQueue) {
-    AEMU_SCOPED_TRACE("vkGetDeviceQueue");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkGetDeviceQueue(device, queueFamilyIndex, queueIndex, pQueue, true /* do lock */);
-}
-static VkResult entry_vkQueueSubmit(VkQueue queue, uint32_t submitCount,
-                                    const VkSubmitInfo* pSubmits, VkFence fence) {
+VkResult gfxstream_vk_QueueSubmit(VkQueue queue, uint32_t submitCount, const VkSubmitInfo* pSubmits,
+                                  VkFence fence) {
     AEMU_SCOPED_TRACE("vkQueueSubmit");
-    auto vkEnc = ResourceTracker::getQueueEncoder(queue);
     VkResult vkQueueSubmit_VkResult_return = (VkResult)0;
-    auto resources = ResourceTracker::get();
-    vkQueueSubmit_VkResult_return =
-        resources->on_vkQueueSubmit(vkEnc, VK_SUCCESS, queue, submitCount, pSubmits, fence);
+    VK_FROM_HANDLE(gfxstream_vk_queue, gfxstream_queue, queue);
+    VK_FROM_HANDLE(gfxstream_vk_fence, gfxstream_fence, fence);
+    {
+        auto vkEnc =
+            gfxstream::vk::ResourceTracker::getQueueEncoder(gfxstream_queue->internal_object);
+        std::vector<VkSubmitInfo> internal_pSubmits(submitCount);
+        std::vector<std::vector<VkSemaphore>> internal_VkSubmitInfo_pWaitSemaphores;
+        std::vector<std::vector<VkCommandBuffer>> internal_VkSubmitInfo_pCommandBuffers;
+        std::vector<std::vector<VkSemaphore>> internal_VkSubmitInfo_pSignalSemaphores;
+        for (uint32_t i = 0; i < submitCount; ++i) {
+            internal_pSubmits[i] = pSubmits[i];
+            /* VkSubmitInfo::pWaitSemaphores */
+            internal_VkSubmitInfo_pWaitSemaphores.push_back(std::vector<VkSemaphore>());
+            internal_VkSubmitInfo_pWaitSemaphores[i] = transformVkSemaphoreList(
+                internal_pSubmits[i].pWaitSemaphores, internal_pSubmits[i].waitSemaphoreCount);
+            internal_pSubmits[i].pWaitSemaphores = internal_VkSubmitInfo_pWaitSemaphores[i].data();
+            internal_pSubmits[i].waitSemaphoreCount =
+                internal_VkSubmitInfo_pWaitSemaphores[i].size();
+            /* VkSubmitInfo::pCommandBuffers */
+            internal_VkSubmitInfo_pCommandBuffers.push_back(std::vector<VkCommandBuffer>());
+            internal_VkSubmitInfo_pCommandBuffers[i].reserve(
+                internal_pSubmits[i].commandBufferCount);
+            memset(&internal_VkSubmitInfo_pCommandBuffers[i][0], 0,
+                   sizeof(VkCommandBuffer) * internal_pSubmits[i].commandBufferCount);
+            for (uint32_t j = 0; j < internal_pSubmits[i].commandBufferCount; ++j) {
+                VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_pCommandBuffers,
+                               internal_pSubmits[i].pCommandBuffers[j]);
+                internal_VkSubmitInfo_pCommandBuffers[i][j] =
+                    gfxstream_pCommandBuffers->internal_object;
+            }
+            internal_pSubmits[i].pCommandBuffers = internal_VkSubmitInfo_pCommandBuffers[i].data();
+            /* VkSubmitInfo::pSignalSemaphores */
+            internal_VkSubmitInfo_pSignalSemaphores.push_back(std::vector<VkSemaphore>());
+            internal_VkSubmitInfo_pSignalSemaphores[i] = transformVkSemaphoreList(
+                internal_pSubmits[i].pSignalSemaphores, internal_pSubmits[i].signalSemaphoreCount);
+            internal_pSubmits[i].pSignalSemaphores =
+                internal_VkSubmitInfo_pSignalSemaphores[i].data();
+            internal_pSubmits[i].signalSemaphoreCount =
+                internal_VkSubmitInfo_pSignalSemaphores[i].size();
+        }
+        auto resources = gfxstream::vk::ResourceTracker::get();
+        vkQueueSubmit_VkResult_return = resources->on_vkQueueSubmit(
+            vkEnc, VK_SUCCESS, gfxstream_queue->internal_object, submitCount,
+            internal_pSubmits.data(),
+            gfxstream_fence ? gfxstream_fence->internal_object : VK_NULL_HANDLE);
+    }
     return vkQueueSubmit_VkResult_return;
 }
-static VkResult entry_vkQueueWaitIdle(VkQueue queue) {
+VkResult gfxstream_vk_QueueWaitIdle(VkQueue queue) {
     AEMU_SCOPED_TRACE("vkQueueWaitIdle");
-    auto vkEnc = ResourceTracker::getQueueEncoder(queue);
     VkResult vkQueueWaitIdle_VkResult_return = (VkResult)0;
-    auto resources = ResourceTracker::get();
-    vkQueueWaitIdle_VkResult_return = resources->on_vkQueueWaitIdle(vkEnc, VK_SUCCESS, queue);
+    VK_FROM_HANDLE(gfxstream_vk_queue, gfxstream_queue, queue);
+    {
+        auto vkEnc =
+            gfxstream::vk::ResourceTracker::getQueueEncoder(gfxstream_queue->internal_object);
+        auto resources = gfxstream::vk::ResourceTracker::get();
+        vkQueueWaitIdle_VkResult_return =
+            resources->on_vkQueueWaitIdle(vkEnc, VK_SUCCESS, gfxstream_queue->internal_object);
+    }
     return vkQueueWaitIdle_VkResult_return;
 }
-static VkResult entry_vkDeviceWaitIdle(VkDevice device) {
+VkResult gfxstream_vk_DeviceWaitIdle(VkDevice device) {
     AEMU_SCOPED_TRACE("vkDeviceWaitIdle");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
     VkResult vkDeviceWaitIdle_VkResult_return = (VkResult)0;
-    vkDeviceWaitIdle_VkResult_return = vkEnc->vkDeviceWaitIdle(device, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkDeviceWaitIdle_VkResult_return =
+            vkEnc->vkDeviceWaitIdle(gfxstream_device->internal_object, true /* do lock */);
+    }
     return vkDeviceWaitIdle_VkResult_return;
 }
-static VkResult entry_vkAllocateMemory(VkDevice device, const VkMemoryAllocateInfo* pAllocateInfo,
-                                       const VkAllocationCallbacks* pAllocator,
-                                       VkDeviceMemory* pMemory) {
-    AEMU_SCOPED_TRACE("vkAllocateMemory");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    VkResult vkAllocateMemory_VkResult_return = (VkResult)0;
-    auto resources = ResourceTracker::get();
-    vkAllocateMemory_VkResult_return = resources->on_vkAllocateMemory(
-        vkEnc, VK_SUCCESS, device, pAllocateInfo, pAllocator, pMemory);
-    return vkAllocateMemory_VkResult_return;
-}
-static void entry_vkFreeMemory(VkDevice device, VkDeviceMemory memory,
-                               const VkAllocationCallbacks* pAllocator) {
+void gfxstream_vk_FreeMemory(VkDevice device, VkDeviceMemory memory,
+                             const VkAllocationCallbacks* pAllocator) {
     AEMU_SCOPED_TRACE("vkFreeMemory");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    auto resources = ResourceTracker::get();
-    resources->on_vkFreeMemory(vkEnc, device, memory, pAllocator);
+    if (VK_NULL_HANDLE == memory) {
+        return;
+    }
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    VK_FROM_HANDLE(gfxstream_vk_device_memory, gfxstream_memory, memory);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        auto resources = gfxstream::vk::ResourceTracker::get();
+        resources->on_vkFreeMemory(
+            vkEnc, gfxstream_device->internal_object,
+            gfxstream_memory ? gfxstream_memory->internal_object : VK_NULL_HANDLE, pAllocator);
+    }
+    vk_device_memory_destroy(&gfxstream_device->vk, pAllocator, &gfxstream_memory->vk);
 }
-static VkResult entry_vkMapMemory(VkDevice device, VkDeviceMemory memory, VkDeviceSize offset,
-                                  VkDeviceSize size, VkMemoryMapFlags flags, void** ppData) {
+VkResult gfxstream_vk_MapMemory(VkDevice device, VkDeviceMemory memory, VkDeviceSize offset,
+                                VkDeviceSize size, VkMemoryMapFlags flags, void** ppData) {
     AEMU_SCOPED_TRACE("vkMapMemory");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
     VkResult vkMapMemory_VkResult_return = (VkResult)0;
-    vkMapMemory_VkResult_return =
-        vkEnc->vkMapMemory(device, memory, offset, size, flags, ppData, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    VK_FROM_HANDLE(gfxstream_vk_device_memory, gfxstream_memory, memory);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkMapMemory_VkResult_return =
+            vkEnc->vkMapMemory(gfxstream_device->internal_object, gfxstream_memory->internal_object,
+                               offset, size, flags, ppData, true /* do lock */);
+    }
     return vkMapMemory_VkResult_return;
 }
-static void entry_vkUnmapMemory(VkDevice device, VkDeviceMemory memory) {
+void gfxstream_vk_UnmapMemory(VkDevice device, VkDeviceMemory memory) {
     AEMU_SCOPED_TRACE("vkUnmapMemory");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkUnmapMemory(device, memory, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    VK_FROM_HANDLE(gfxstream_vk_device_memory, gfxstream_memory, memory);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkEnc->vkUnmapMemory(gfxstream_device->internal_object, gfxstream_memory->internal_object,
+                             true /* do lock */);
+    }
 }
-static VkResult entry_vkFlushMappedMemoryRanges(VkDevice device, uint32_t memoryRangeCount,
-                                                const VkMappedMemoryRange* pMemoryRanges) {
+VkResult gfxstream_vk_FlushMappedMemoryRanges(VkDevice device, uint32_t memoryRangeCount,
+                                              const VkMappedMemoryRange* pMemoryRanges) {
     AEMU_SCOPED_TRACE("vkFlushMappedMemoryRanges");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
     VkResult vkFlushMappedMemoryRanges_VkResult_return = (VkResult)0;
-    vkFlushMappedMemoryRanges_VkResult_return = vkEnc->vkFlushMappedMemoryRanges(
-        device, memoryRangeCount, pMemoryRanges, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        std::vector<VkMappedMemoryRange> internal_pMemoryRanges(memoryRangeCount);
+        for (uint32_t i = 0; i < memoryRangeCount; ++i) {
+            internal_pMemoryRanges[i] = pMemoryRanges[i];
+            /* VkMappedMemoryRange::memory */
+            VK_FROM_HANDLE(gfxstream_vk_device_memory, gfxstream_memory,
+                           internal_pMemoryRanges[i].memory);
+            internal_pMemoryRanges[i].memory = gfxstream_memory->internal_object;
+        }
+        vkFlushMappedMemoryRanges_VkResult_return =
+            vkEnc->vkFlushMappedMemoryRanges(gfxstream_device->internal_object, memoryRangeCount,
+                                             internal_pMemoryRanges.data(), true /* do lock */);
+    }
     return vkFlushMappedMemoryRanges_VkResult_return;
 }
-static VkResult entry_vkInvalidateMappedMemoryRanges(VkDevice device, uint32_t memoryRangeCount,
-                                                     const VkMappedMemoryRange* pMemoryRanges) {
+VkResult gfxstream_vk_InvalidateMappedMemoryRanges(VkDevice device, uint32_t memoryRangeCount,
+                                                   const VkMappedMemoryRange* pMemoryRanges) {
     AEMU_SCOPED_TRACE("vkInvalidateMappedMemoryRanges");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
     VkResult vkInvalidateMappedMemoryRanges_VkResult_return = (VkResult)0;
-    vkInvalidateMappedMemoryRanges_VkResult_return = vkEnc->vkInvalidateMappedMemoryRanges(
-        device, memoryRangeCount, pMemoryRanges, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        std::vector<VkMappedMemoryRange> internal_pMemoryRanges(memoryRangeCount);
+        for (uint32_t i = 0; i < memoryRangeCount; ++i) {
+            internal_pMemoryRanges[i] = pMemoryRanges[i];
+            /* VkMappedMemoryRange::memory */
+            VK_FROM_HANDLE(gfxstream_vk_device_memory, gfxstream_memory,
+                           internal_pMemoryRanges[i].memory);
+            internal_pMemoryRanges[i].memory = gfxstream_memory->internal_object;
+        }
+        vkInvalidateMappedMemoryRanges_VkResult_return = vkEnc->vkInvalidateMappedMemoryRanges(
+            gfxstream_device->internal_object, memoryRangeCount, internal_pMemoryRanges.data(),
+            true /* do lock */);
+    }
     return vkInvalidateMappedMemoryRanges_VkResult_return;
 }
-static void entry_vkGetDeviceMemoryCommitment(VkDevice device, VkDeviceMemory memory,
-                                              VkDeviceSize* pCommittedMemoryInBytes) {
+void gfxstream_vk_GetDeviceMemoryCommitment(VkDevice device, VkDeviceMemory memory,
+                                            VkDeviceSize* pCommittedMemoryInBytes) {
     AEMU_SCOPED_TRACE("vkGetDeviceMemoryCommitment");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkGetDeviceMemoryCommitment(device, memory, pCommittedMemoryInBytes, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    VK_FROM_HANDLE(gfxstream_vk_device_memory, gfxstream_memory, memory);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkEnc->vkGetDeviceMemoryCommitment(gfxstream_device->internal_object,
+                                           gfxstream_memory->internal_object,
+                                           pCommittedMemoryInBytes, true /* do lock */);
+    }
 }
-static VkResult entry_vkBindBufferMemory(VkDevice device, VkBuffer buffer, VkDeviceMemory memory,
-                                         VkDeviceSize memoryOffset) {
+VkResult gfxstream_vk_BindBufferMemory(VkDevice device, VkBuffer buffer, VkDeviceMemory memory,
+                                       VkDeviceSize memoryOffset) {
     AEMU_SCOPED_TRACE("vkBindBufferMemory");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
     VkResult vkBindBufferMemory_VkResult_return = (VkResult)0;
-    auto resources = ResourceTracker::get();
-    vkBindBufferMemory_VkResult_return =
-        resources->on_vkBindBufferMemory(vkEnc, VK_SUCCESS, device, buffer, memory, memoryOffset);
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    VK_FROM_HANDLE(gfxstream_vk_buffer, gfxstream_buffer, buffer);
+    VK_FROM_HANDLE(gfxstream_vk_device_memory, gfxstream_memory, memory);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        auto resources = gfxstream::vk::ResourceTracker::get();
+        vkBindBufferMemory_VkResult_return = resources->on_vkBindBufferMemory(
+            vkEnc, VK_SUCCESS, gfxstream_device->internal_object, gfxstream_buffer->internal_object,
+            gfxstream_memory->internal_object, memoryOffset);
+    }
     return vkBindBufferMemory_VkResult_return;
 }
-static VkResult entry_vkBindImageMemory(VkDevice device, VkImage image, VkDeviceMemory memory,
-                                        VkDeviceSize memoryOffset) {
+VkResult gfxstream_vk_BindImageMemory(VkDevice device, VkImage image, VkDeviceMemory memory,
+                                      VkDeviceSize memoryOffset) {
     AEMU_SCOPED_TRACE("vkBindImageMemory");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
     VkResult vkBindImageMemory_VkResult_return = (VkResult)0;
-    auto resources = ResourceTracker::get();
-    vkBindImageMemory_VkResult_return =
-        resources->on_vkBindImageMemory(vkEnc, VK_SUCCESS, device, image, memory, memoryOffset);
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    VK_FROM_HANDLE(gfxstream_vk_image, gfxstream_image, image);
+    VK_FROM_HANDLE(gfxstream_vk_device_memory, gfxstream_memory, memory);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        auto resources = gfxstream::vk::ResourceTracker::get();
+        vkBindImageMemory_VkResult_return = resources->on_vkBindImageMemory(
+            vkEnc, VK_SUCCESS, gfxstream_device->internal_object, gfxstream_image->internal_object,
+            gfxstream_memory->internal_object, memoryOffset);
+    }
     return vkBindImageMemory_VkResult_return;
 }
-static void entry_vkGetBufferMemoryRequirements(VkDevice device, VkBuffer buffer,
-                                                VkMemoryRequirements* pMemoryRequirements) {
+void gfxstream_vk_GetBufferMemoryRequirements(VkDevice device, VkBuffer buffer,
+                                              VkMemoryRequirements* pMemoryRequirements) {
     AEMU_SCOPED_TRACE("vkGetBufferMemoryRequirements");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    auto resources = ResourceTracker::get();
-    resources->on_vkGetBufferMemoryRequirements(vkEnc, device, buffer, pMemoryRequirements);
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    VK_FROM_HANDLE(gfxstream_vk_buffer, gfxstream_buffer, buffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        auto resources = gfxstream::vk::ResourceTracker::get();
+        resources->on_vkGetBufferMemoryRequirements(vkEnc, gfxstream_device->internal_object,
+                                                    gfxstream_buffer->internal_object,
+                                                    pMemoryRequirements);
+    }
 }
-static void entry_vkGetImageMemoryRequirements(VkDevice device, VkImage image,
-                                               VkMemoryRequirements* pMemoryRequirements) {
+void gfxstream_vk_GetImageMemoryRequirements(VkDevice device, VkImage image,
+                                             VkMemoryRequirements* pMemoryRequirements) {
     AEMU_SCOPED_TRACE("vkGetImageMemoryRequirements");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    auto resources = ResourceTracker::get();
-    resources->on_vkGetImageMemoryRequirements(vkEnc, device, image, pMemoryRequirements);
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    VK_FROM_HANDLE(gfxstream_vk_image, gfxstream_image, image);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        auto resources = gfxstream::vk::ResourceTracker::get();
+        resources->on_vkGetImageMemoryRequirements(vkEnc, gfxstream_device->internal_object,
+                                                   gfxstream_image->internal_object,
+                                                   pMemoryRequirements);
+    }
 }
-static void entry_vkGetImageSparseMemoryRequirements(
+void gfxstream_vk_GetImageSparseMemoryRequirements(
     VkDevice device, VkImage image, uint32_t* pSparseMemoryRequirementCount,
     VkSparseImageMemoryRequirements* pSparseMemoryRequirements) {
     AEMU_SCOPED_TRACE("vkGetImageSparseMemoryRequirements");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkGetImageSparseMemoryRequirements(device, image, pSparseMemoryRequirementCount,
-                                              pSparseMemoryRequirements, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    VK_FROM_HANDLE(gfxstream_vk_image, gfxstream_image, image);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkEnc->vkGetImageSparseMemoryRequirements(
+            gfxstream_device->internal_object, gfxstream_image->internal_object,
+            pSparseMemoryRequirementCount, pSparseMemoryRequirements, true /* do lock */);
+    }
 }
-static void entry_vkGetPhysicalDeviceSparseImageFormatProperties(
+void gfxstream_vk_GetPhysicalDeviceSparseImageFormatProperties(
     VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type,
     VkSampleCountFlagBits samples, VkImageUsageFlags usage, VkImageTiling tiling,
     uint32_t* pPropertyCount, VkSparseImageFormatProperties* pProperties) {
     AEMU_SCOPED_TRACE("vkGetPhysicalDeviceSparseImageFormatProperties");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkGetPhysicalDeviceSparseImageFormatProperties(physicalDevice, format, type, samples,
-                                                          usage, tiling, pPropertyCount,
-                                                          pProperties, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_physical_device, gfxstream_physicalDevice, physicalDevice);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkEnc->vkGetPhysicalDeviceSparseImageFormatProperties(
+            gfxstream_physicalDevice->internal_object, format, type, samples, usage, tiling,
+            pPropertyCount, pProperties, true /* do lock */);
+    }
 }
-static VkResult entry_vkQueueBindSparse(VkQueue queue, uint32_t bindInfoCount,
-                                        const VkBindSparseInfo* pBindInfo, VkFence fence) {
+VkResult gfxstream_vk_QueueBindSparse(VkQueue queue, uint32_t bindInfoCount,
+                                      const VkBindSparseInfo* pBindInfo, VkFence fence) {
     AEMU_SCOPED_TRACE("vkQueueBindSparse");
-    auto vkEnc = ResourceTracker::getQueueEncoder(queue);
     VkResult vkQueueBindSparse_VkResult_return = (VkResult)0;
-    vkQueueBindSparse_VkResult_return =
-        vkEnc->vkQueueBindSparse(queue, bindInfoCount, pBindInfo, fence, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_queue, gfxstream_queue, queue);
+    VK_FROM_HANDLE(gfxstream_vk_fence, gfxstream_fence, fence);
+    {
+        auto vkEnc =
+            gfxstream::vk::ResourceTracker::getQueueEncoder(gfxstream_queue->internal_object);
+        std::vector<VkBindSparseInfo> internal_pBindInfo(bindInfoCount);
+        std::vector<std::vector<VkSemaphore>> internal_VkBindSparseInfo_pWaitSemaphores;
+        std::vector<std::vector<VkSparseBufferMemoryBindInfo>>
+            internal_VkBindSparseInfo_pBufferBinds;
+        std::vector<std::vector<VkSparseMemoryBind>> internal_VkSparseBufferMemoryBindInfo_pBinds;
+        std::vector<std::vector<VkSparseImageOpaqueMemoryBindInfo>>
+            internal_VkBindSparseInfo_pImageOpaqueBinds;
+        std::vector<std::vector<VkSparseMemoryBind>>
+            internal_VkSparseImageOpaqueMemoryBindInfo_pBinds;
+        std::vector<std::vector<VkSparseImageMemoryBindInfo>> internal_VkBindSparseInfo_pImageBinds;
+        std::vector<std::vector<VkSparseImageMemoryBind>>
+            internal_VkSparseImageMemoryBindInfo_pBinds;
+        std::vector<std::vector<VkSemaphore>> internal_VkBindSparseInfo_pSignalSemaphores;
+        for (uint32_t i = 0; i < bindInfoCount; ++i) {
+            internal_pBindInfo[i] = pBindInfo[i];
+            /* VkBindSparseInfo::pWaitSemaphores */
+            internal_VkBindSparseInfo_pWaitSemaphores.push_back(std::vector<VkSemaphore>());
+            internal_VkBindSparseInfo_pWaitSemaphores[i] = transformVkSemaphoreList(
+                internal_pBindInfo[i].pWaitSemaphores, internal_pBindInfo[i].waitSemaphoreCount);
+            internal_pBindInfo[i].pWaitSemaphores =
+                internal_VkBindSparseInfo_pWaitSemaphores[i].data();
+            internal_pBindInfo[i].waitSemaphoreCount =
+                internal_VkBindSparseInfo_pWaitSemaphores[i].size();
+            /* VkBindSparseInfo::pBufferBinds */
+            internal_VkBindSparseInfo_pBufferBinds.push_back(
+                std::vector<VkSparseBufferMemoryBindInfo>());
+            internal_VkBindSparseInfo_pBufferBinds[i].reserve(
+                internal_pBindInfo[i].bufferBindCount);
+            memset(&internal_VkBindSparseInfo_pBufferBinds[i][0], 0,
+                   sizeof(VkSparseBufferMemoryBindInfo) * internal_pBindInfo[i].bufferBindCount);
+            for (uint32_t j = 0; j < internal_pBindInfo[i].bufferBindCount; ++j) {
+                internal_VkBindSparseInfo_pBufferBinds[i][j] =
+                    internal_pBindInfo[i].pBufferBinds[j];
+                /* VkSparseBufferMemoryBindInfo::buffer */
+                VK_FROM_HANDLE(gfxstream_vk_buffer, gfxstream_buffer,
+                               internal_VkBindSparseInfo_pBufferBinds[i][j].buffer);
+                internal_VkBindSparseInfo_pBufferBinds[i][j].buffer =
+                    gfxstream_buffer->internal_object;
+                /* VkSparseBufferMemoryBindInfo::pBinds */
+                internal_VkSparseBufferMemoryBindInfo_pBinds.push_back(
+                    std::vector<VkSparseMemoryBind>());
+                internal_VkSparseBufferMemoryBindInfo_pBinds[j].reserve(
+                    internal_VkBindSparseInfo_pBufferBinds[i][j].bindCount);
+                memset(&internal_VkSparseBufferMemoryBindInfo_pBinds[j][0], 0,
+                       sizeof(VkSparseMemoryBind) *
+                           internal_VkBindSparseInfo_pBufferBinds[i][j].bindCount);
+                for (uint32_t k = 0; k < internal_VkBindSparseInfo_pBufferBinds[i][j].bindCount;
+                     ++k) {
+                    internal_VkSparseBufferMemoryBindInfo_pBinds[j][k] =
+                        internal_VkBindSparseInfo_pBufferBinds[i][j].pBinds[k];
+                    /* VkSparseMemoryBind::memory */
+                    if (internal_VkSparseBufferMemoryBindInfo_pBinds[j][k].memory) {
+                        VK_FROM_HANDLE(gfxstream_vk_device_memory, gfxstream_memory,
+                                       internal_VkSparseBufferMemoryBindInfo_pBinds[j][k].memory);
+                        internal_VkSparseBufferMemoryBindInfo_pBinds[j][k].memory =
+                            gfxstream_memory->internal_object;
+                    }
+                }
+                internal_VkBindSparseInfo_pBufferBinds[i][j].pBinds =
+                    internal_VkSparseBufferMemoryBindInfo_pBinds[j].data();
+            }
+            internal_pBindInfo[i].pBufferBinds = internal_VkBindSparseInfo_pBufferBinds[i].data();
+            /* VkBindSparseInfo::pImageOpaqueBinds */
+            internal_VkBindSparseInfo_pImageOpaqueBinds.push_back(
+                std::vector<VkSparseImageOpaqueMemoryBindInfo>());
+            internal_VkBindSparseInfo_pImageOpaqueBinds[i].reserve(
+                internal_pBindInfo[i].imageOpaqueBindCount);
+            memset(&internal_VkBindSparseInfo_pImageOpaqueBinds[i][0], 0,
+                   sizeof(VkSparseImageOpaqueMemoryBindInfo) *
+                       internal_pBindInfo[i].imageOpaqueBindCount);
+            for (uint32_t j = 0; j < internal_pBindInfo[i].imageOpaqueBindCount; ++j) {
+                internal_VkBindSparseInfo_pImageOpaqueBinds[i][j] =
+                    internal_pBindInfo[i].pImageOpaqueBinds[j];
+                /* VkSparseImageOpaqueMemoryBindInfo::image */
+                VK_FROM_HANDLE(gfxstream_vk_image, gfxstream_image,
+                               internal_VkBindSparseInfo_pImageOpaqueBinds[i][j].image);
+                internal_VkBindSparseInfo_pImageOpaqueBinds[i][j].image =
+                    gfxstream_image->internal_object;
+                /* VkSparseImageOpaqueMemoryBindInfo::pBinds */
+                internal_VkSparseImageOpaqueMemoryBindInfo_pBinds.push_back(
+                    std::vector<VkSparseMemoryBind>());
+                internal_VkSparseImageOpaqueMemoryBindInfo_pBinds[j].reserve(
+                    internal_VkBindSparseInfo_pImageOpaqueBinds[i][j].bindCount);
+                memset(&internal_VkSparseImageOpaqueMemoryBindInfo_pBinds[j][0], 0,
+                       sizeof(VkSparseMemoryBind) *
+                           internal_VkBindSparseInfo_pImageOpaqueBinds[i][j].bindCount);
+                for (uint32_t l = 0;
+                     l < internal_VkBindSparseInfo_pImageOpaqueBinds[i][j].bindCount; ++l) {
+                    internal_VkSparseImageOpaqueMemoryBindInfo_pBinds[j][l] =
+                        internal_VkBindSparseInfo_pImageOpaqueBinds[i][j].pBinds[l];
+                    /* VkSparseMemoryBind::memory */
+                    if (internal_VkSparseImageOpaqueMemoryBindInfo_pBinds[j][l].memory) {
+                        VK_FROM_HANDLE(
+                            gfxstream_vk_device_memory, gfxstream_memory,
+                            internal_VkSparseImageOpaqueMemoryBindInfo_pBinds[j][l].memory);
+                        internal_VkSparseImageOpaqueMemoryBindInfo_pBinds[j][l].memory =
+                            gfxstream_memory->internal_object;
+                    }
+                }
+                internal_VkBindSparseInfo_pImageOpaqueBinds[i][j].pBinds =
+                    internal_VkSparseImageOpaqueMemoryBindInfo_pBinds[j].data();
+            }
+            internal_pBindInfo[i].pImageOpaqueBinds =
+                internal_VkBindSparseInfo_pImageOpaqueBinds[i].data();
+            /* VkBindSparseInfo::pImageBinds */
+            internal_VkBindSparseInfo_pImageBinds.push_back(
+                std::vector<VkSparseImageMemoryBindInfo>());
+            internal_VkBindSparseInfo_pImageBinds[i].reserve(internal_pBindInfo[i].imageBindCount);
+            memset(&internal_VkBindSparseInfo_pImageBinds[i][0], 0,
+                   sizeof(VkSparseImageMemoryBindInfo) * internal_pBindInfo[i].imageBindCount);
+            for (uint32_t j = 0; j < internal_pBindInfo[i].imageBindCount; ++j) {
+                internal_VkBindSparseInfo_pImageBinds[i][j] = internal_pBindInfo[i].pImageBinds[j];
+                /* VkSparseImageMemoryBindInfo::image */
+                VK_FROM_HANDLE(gfxstream_vk_image, gfxstream_image,
+                               internal_VkBindSparseInfo_pImageBinds[i][j].image);
+                internal_VkBindSparseInfo_pImageBinds[i][j].image =
+                    gfxstream_image->internal_object;
+                /* VkSparseImageMemoryBindInfo::pBinds */
+                internal_VkSparseImageMemoryBindInfo_pBinds.push_back(
+                    std::vector<VkSparseImageMemoryBind>());
+                internal_VkSparseImageMemoryBindInfo_pBinds[j].reserve(
+                    internal_VkBindSparseInfo_pImageBinds[i][j].bindCount);
+                memset(&internal_VkSparseImageMemoryBindInfo_pBinds[j][0], 0,
+                       sizeof(VkSparseImageMemoryBind) *
+                           internal_VkBindSparseInfo_pImageBinds[i][j].bindCount);
+                for (uint32_t m = 0; m < internal_VkBindSparseInfo_pImageBinds[i][j].bindCount;
+                     ++m) {
+                    internal_VkSparseImageMemoryBindInfo_pBinds[j][m] =
+                        internal_VkBindSparseInfo_pImageBinds[i][j].pBinds[m];
+                    /* VkSparseImageMemoryBind::memory */
+                    if (internal_VkSparseImageMemoryBindInfo_pBinds[j][m].memory) {
+                        VK_FROM_HANDLE(gfxstream_vk_device_memory, gfxstream_memory,
+                                       internal_VkSparseImageMemoryBindInfo_pBinds[j][m].memory);
+                        internal_VkSparseImageMemoryBindInfo_pBinds[j][m].memory =
+                            gfxstream_memory->internal_object;
+                    }
+                }
+                internal_VkBindSparseInfo_pImageBinds[i][j].pBinds =
+                    internal_VkSparseImageMemoryBindInfo_pBinds[j].data();
+            }
+            internal_pBindInfo[i].pImageBinds = internal_VkBindSparseInfo_pImageBinds[i].data();
+            /* VkBindSparseInfo::pSignalSemaphores */
+            internal_VkBindSparseInfo_pSignalSemaphores.push_back(std::vector<VkSemaphore>());
+            internal_VkBindSparseInfo_pSignalSemaphores[i] =
+                transformVkSemaphoreList(internal_pBindInfo[i].pSignalSemaphores,
+                                         internal_pBindInfo[i].signalSemaphoreCount);
+            internal_pBindInfo[i].pSignalSemaphores =
+                internal_VkBindSparseInfo_pSignalSemaphores[i].data();
+            internal_pBindInfo[i].signalSemaphoreCount =
+                internal_VkBindSparseInfo_pSignalSemaphores[i].size();
+        }
+        vkQueueBindSparse_VkResult_return = vkEnc->vkQueueBindSparse(
+            gfxstream_queue->internal_object, bindInfoCount, internal_pBindInfo.data(),
+            gfxstream_fence ? gfxstream_fence->internal_object : VK_NULL_HANDLE,
+            true /* do lock */);
+    }
     return vkQueueBindSparse_VkResult_return;
 }
-static VkResult entry_vkCreateFence(VkDevice device, const VkFenceCreateInfo* pCreateInfo,
-                                    const VkAllocationCallbacks* pAllocator, VkFence* pFence) {
+VkResult gfxstream_vk_CreateFence(VkDevice device, const VkFenceCreateInfo* pCreateInfo,
+                                  const VkAllocationCallbacks* pAllocator, VkFence* pFence) {
     AEMU_SCOPED_TRACE("vkCreateFence");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
     VkResult vkCreateFence_VkResult_return = (VkResult)0;
-    auto resources = ResourceTracker::get();
-    vkCreateFence_VkResult_return =
-        resources->on_vkCreateFence(vkEnc, VK_SUCCESS, device, pCreateInfo, pAllocator, pFence);
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    struct gfxstream_vk_fence* gfxstream_pFence = (gfxstream_vk_fence*)vk_object_zalloc(
+        &gfxstream_device->vk, pAllocator, sizeof(gfxstream_vk_fence), VK_OBJECT_TYPE_FENCE);
+    vkCreateFence_VkResult_return = gfxstream_pFence ? VK_SUCCESS : VK_ERROR_OUT_OF_HOST_MEMORY;
+    if (VK_SUCCESS == vkCreateFence_VkResult_return) {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        auto resources = gfxstream::vk::ResourceTracker::get();
+        vkCreateFence_VkResult_return = resources->on_vkCreateFence(
+            vkEnc, VK_SUCCESS, gfxstream_device->internal_object, pCreateInfo, pAllocator,
+            &gfxstream_pFence->internal_object);
+    }
+    *pFence = gfxstream_vk_fence_to_handle(gfxstream_pFence);
     return vkCreateFence_VkResult_return;
 }
-static void entry_vkDestroyFence(VkDevice device, VkFence fence,
-                                 const VkAllocationCallbacks* pAllocator) {
+void gfxstream_vk_DestroyFence(VkDevice device, VkFence fence,
+                               const VkAllocationCallbacks* pAllocator) {
     AEMU_SCOPED_TRACE("vkDestroyFence");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkDestroyFence(device, fence, pAllocator, true /* do lock */);
+    if (VK_NULL_HANDLE == fence) {
+        return;
+    }
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    VK_FROM_HANDLE(gfxstream_vk_fence, gfxstream_fence, fence);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkEnc->vkDestroyFence(gfxstream_device->internal_object,
+                              gfxstream_fence ? gfxstream_fence->internal_object : VK_NULL_HANDLE,
+                              pAllocator, true /* do lock */);
+    }
+    vk_object_free(&gfxstream_device->vk, pAllocator, (void*)gfxstream_fence);
 }
-static VkResult entry_vkResetFences(VkDevice device, uint32_t fenceCount, const VkFence* pFences) {
+VkResult gfxstream_vk_ResetFences(VkDevice device, uint32_t fenceCount, const VkFence* pFences) {
     AEMU_SCOPED_TRACE("vkResetFences");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
     VkResult vkResetFences_VkResult_return = (VkResult)0;
-    auto resources = ResourceTracker::get();
-    vkResetFences_VkResult_return =
-        resources->on_vkResetFences(vkEnc, VK_SUCCESS, device, fenceCount, pFences);
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        std::vector<VkFence> internal_pFences(fenceCount);
+        for (uint32_t i = 0; i < fenceCount; ++i) {
+            VK_FROM_HANDLE(gfxstream_vk_fence, gfxstream_pFences, pFences[i]);
+            internal_pFences[i] = gfxstream_pFences->internal_object;
+        }
+        auto resources = gfxstream::vk::ResourceTracker::get();
+        vkResetFences_VkResult_return =
+            resources->on_vkResetFences(vkEnc, VK_SUCCESS, gfxstream_device->internal_object,
+                                        fenceCount, internal_pFences.data());
+    }
     return vkResetFences_VkResult_return;
 }
-static VkResult entry_vkGetFenceStatus(VkDevice device, VkFence fence) {
+VkResult gfxstream_vk_GetFenceStatus(VkDevice device, VkFence fence) {
     AEMU_SCOPED_TRACE("vkGetFenceStatus");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
     VkResult vkGetFenceStatus_VkResult_return = (VkResult)0;
-    vkGetFenceStatus_VkResult_return = vkEnc->vkGetFenceStatus(device, fence, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    VK_FROM_HANDLE(gfxstream_vk_fence, gfxstream_fence, fence);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkGetFenceStatus_VkResult_return =
+            vkEnc->vkGetFenceStatus(gfxstream_device->internal_object,
+                                    gfxstream_fence->internal_object, true /* do lock */);
+    }
     return vkGetFenceStatus_VkResult_return;
 }
-static VkResult entry_vkWaitForFences(VkDevice device, uint32_t fenceCount, const VkFence* pFences,
-                                      VkBool32 waitAll, uint64_t timeout) {
+VkResult gfxstream_vk_WaitForFences(VkDevice device, uint32_t fenceCount, const VkFence* pFences,
+                                    VkBool32 waitAll, uint64_t timeout) {
     AEMU_SCOPED_TRACE("vkWaitForFences");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
     VkResult vkWaitForFences_VkResult_return = (VkResult)0;
-    auto resources = ResourceTracker::get();
-    vkWaitForFences_VkResult_return = resources->on_vkWaitForFences(
-        vkEnc, VK_SUCCESS, device, fenceCount, pFences, waitAll, timeout);
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        std::vector<VkFence> internal_pFences(fenceCount);
+        for (uint32_t i = 0; i < fenceCount; ++i) {
+            VK_FROM_HANDLE(gfxstream_vk_fence, gfxstream_pFences, pFences[i]);
+            internal_pFences[i] = gfxstream_pFences->internal_object;
+        }
+        auto resources = gfxstream::vk::ResourceTracker::get();
+        vkWaitForFences_VkResult_return =
+            resources->on_vkWaitForFences(vkEnc, VK_SUCCESS, gfxstream_device->internal_object,
+                                          fenceCount, internal_pFences.data(), waitAll, timeout);
+    }
     return vkWaitForFences_VkResult_return;
 }
-static VkResult entry_vkCreateSemaphore(VkDevice device, const VkSemaphoreCreateInfo* pCreateInfo,
-                                        const VkAllocationCallbacks* pAllocator,
-                                        VkSemaphore* pSemaphore) {
+VkResult gfxstream_vk_CreateSemaphore(VkDevice device, const VkSemaphoreCreateInfo* pCreateInfo,
+                                      const VkAllocationCallbacks* pAllocator,
+                                      VkSemaphore* pSemaphore) {
     AEMU_SCOPED_TRACE("vkCreateSemaphore");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
     VkResult vkCreateSemaphore_VkResult_return = (VkResult)0;
-    auto resources = ResourceTracker::get();
-    vkCreateSemaphore_VkResult_return = resources->on_vkCreateSemaphore(
-        vkEnc, VK_SUCCESS, device, pCreateInfo, pAllocator, pSemaphore);
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    struct gfxstream_vk_semaphore* gfxstream_pSemaphore = (gfxstream_vk_semaphore*)vk_object_zalloc(
+        &gfxstream_device->vk, pAllocator, sizeof(gfxstream_vk_semaphore),
+        VK_OBJECT_TYPE_SEMAPHORE);
+    vkCreateSemaphore_VkResult_return =
+        gfxstream_pSemaphore ? VK_SUCCESS : VK_ERROR_OUT_OF_HOST_MEMORY;
+    if (VK_SUCCESS == vkCreateSemaphore_VkResult_return) {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        auto resources = gfxstream::vk::ResourceTracker::get();
+        vkCreateSemaphore_VkResult_return = resources->on_vkCreateSemaphore(
+            vkEnc, VK_SUCCESS, gfxstream_device->internal_object, pCreateInfo, pAllocator,
+            &gfxstream_pSemaphore->internal_object);
+    }
+    *pSemaphore = gfxstream_vk_semaphore_to_handle(gfxstream_pSemaphore);
     return vkCreateSemaphore_VkResult_return;
 }
-static void entry_vkDestroySemaphore(VkDevice device, VkSemaphore semaphore,
-                                     const VkAllocationCallbacks* pAllocator) {
+void gfxstream_vk_DestroySemaphore(VkDevice device, VkSemaphore semaphore,
+                                   const VkAllocationCallbacks* pAllocator) {
     AEMU_SCOPED_TRACE("vkDestroySemaphore");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    auto resources = ResourceTracker::get();
-    resources->on_vkDestroySemaphore(vkEnc, device, semaphore, pAllocator);
+    if (VK_NULL_HANDLE == semaphore) {
+        return;
+    }
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    VK_FROM_HANDLE(gfxstream_vk_semaphore, gfxstream_semaphore, semaphore);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        auto resources = gfxstream::vk::ResourceTracker::get();
+        resources->on_vkDestroySemaphore(
+            vkEnc, gfxstream_device->internal_object,
+            gfxstream_semaphore ? gfxstream_semaphore->internal_object : VK_NULL_HANDLE,
+            pAllocator);
+    }
+    vk_object_free(&gfxstream_device->vk, pAllocator, (void*)gfxstream_semaphore);
 }
-static VkResult entry_vkCreateEvent(VkDevice device, const VkEventCreateInfo* pCreateInfo,
-                                    const VkAllocationCallbacks* pAllocator, VkEvent* pEvent) {
+VkResult gfxstream_vk_CreateEvent(VkDevice device, const VkEventCreateInfo* pCreateInfo,
+                                  const VkAllocationCallbacks* pAllocator, VkEvent* pEvent) {
     AEMU_SCOPED_TRACE("vkCreateEvent");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
     VkResult vkCreateEvent_VkResult_return = (VkResult)0;
-    vkCreateEvent_VkResult_return =
-        vkEnc->vkCreateEvent(device, pCreateInfo, pAllocator, pEvent, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    struct gfxstream_vk_event* gfxstream_pEvent = (gfxstream_vk_event*)vk_object_zalloc(
+        &gfxstream_device->vk, pAllocator, sizeof(gfxstream_vk_event), VK_OBJECT_TYPE_EVENT);
+    vkCreateEvent_VkResult_return = gfxstream_pEvent ? VK_SUCCESS : VK_ERROR_OUT_OF_HOST_MEMORY;
+    if (VK_SUCCESS == vkCreateEvent_VkResult_return) {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkCreateEvent_VkResult_return =
+            vkEnc->vkCreateEvent(gfxstream_device->internal_object, pCreateInfo, pAllocator,
+                                 &gfxstream_pEvent->internal_object, true /* do lock */);
+    }
+    *pEvent = gfxstream_vk_event_to_handle(gfxstream_pEvent);
     return vkCreateEvent_VkResult_return;
 }
-static void entry_vkDestroyEvent(VkDevice device, VkEvent event,
-                                 const VkAllocationCallbacks* pAllocator) {
+void gfxstream_vk_DestroyEvent(VkDevice device, VkEvent event,
+                               const VkAllocationCallbacks* pAllocator) {
     AEMU_SCOPED_TRACE("vkDestroyEvent");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkDestroyEvent(device, event, pAllocator, true /* do lock */);
+    if (VK_NULL_HANDLE == event) {
+        return;
+    }
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    VK_FROM_HANDLE(gfxstream_vk_event, gfxstream_event, event);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkEnc->vkDestroyEvent(gfxstream_device->internal_object,
+                              gfxstream_event ? gfxstream_event->internal_object : VK_NULL_HANDLE,
+                              pAllocator, true /* do lock */);
+    }
+    vk_object_free(&gfxstream_device->vk, pAllocator, (void*)gfxstream_event);
 }
-static VkResult entry_vkGetEventStatus(VkDevice device, VkEvent event) {
+VkResult gfxstream_vk_GetEventStatus(VkDevice device, VkEvent event) {
     AEMU_SCOPED_TRACE("vkGetEventStatus");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
     VkResult vkGetEventStatus_VkResult_return = (VkResult)0;
-    vkGetEventStatus_VkResult_return = vkEnc->vkGetEventStatus(device, event, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    VK_FROM_HANDLE(gfxstream_vk_event, gfxstream_event, event);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkGetEventStatus_VkResult_return =
+            vkEnc->vkGetEventStatus(gfxstream_device->internal_object,
+                                    gfxstream_event->internal_object, true /* do lock */);
+    }
     return vkGetEventStatus_VkResult_return;
 }
-static VkResult entry_vkSetEvent(VkDevice device, VkEvent event) {
+VkResult gfxstream_vk_SetEvent(VkDevice device, VkEvent event) {
     AEMU_SCOPED_TRACE("vkSetEvent");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
     VkResult vkSetEvent_VkResult_return = (VkResult)0;
-    vkSetEvent_VkResult_return = vkEnc->vkSetEvent(device, event, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    VK_FROM_HANDLE(gfxstream_vk_event, gfxstream_event, event);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkSetEvent_VkResult_return =
+            vkEnc->vkSetEvent(gfxstream_device->internal_object, gfxstream_event->internal_object,
+                              true /* do lock */);
+    }
     return vkSetEvent_VkResult_return;
 }
-static VkResult entry_vkResetEvent(VkDevice device, VkEvent event) {
+VkResult gfxstream_vk_ResetEvent(VkDevice device, VkEvent event) {
     AEMU_SCOPED_TRACE("vkResetEvent");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
     VkResult vkResetEvent_VkResult_return = (VkResult)0;
-    vkResetEvent_VkResult_return = vkEnc->vkResetEvent(device, event, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    VK_FROM_HANDLE(gfxstream_vk_event, gfxstream_event, event);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkResetEvent_VkResult_return =
+            vkEnc->vkResetEvent(gfxstream_device->internal_object, gfxstream_event->internal_object,
+                                true /* do lock */);
+    }
     return vkResetEvent_VkResult_return;
 }
-static VkResult entry_vkCreateQueryPool(VkDevice device, const VkQueryPoolCreateInfo* pCreateInfo,
-                                        const VkAllocationCallbacks* pAllocator,
-                                        VkQueryPool* pQueryPool) {
+VkResult gfxstream_vk_CreateQueryPool(VkDevice device, const VkQueryPoolCreateInfo* pCreateInfo,
+                                      const VkAllocationCallbacks* pAllocator,
+                                      VkQueryPool* pQueryPool) {
     AEMU_SCOPED_TRACE("vkCreateQueryPool");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
     VkResult vkCreateQueryPool_VkResult_return = (VkResult)0;
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    struct gfxstream_vk_query_pool* gfxstream_pQueryPool =
+        (struct gfxstream_vk_query_pool*)vk_query_pool_create(
+            (vk_device*)gfxstream_device, pCreateInfo, pAllocator,
+            sizeof(struct gfxstream_vk_query_pool));
     vkCreateQueryPool_VkResult_return =
-        vkEnc->vkCreateQueryPool(device, pCreateInfo, pAllocator, pQueryPool, true /* do lock */);
+        gfxstream_pQueryPool ? VK_SUCCESS : VK_ERROR_OUT_OF_HOST_MEMORY;
+    if (VK_SUCCESS == vkCreateQueryPool_VkResult_return) {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkCreateQueryPool_VkResult_return =
+            vkEnc->vkCreateQueryPool(gfxstream_device->internal_object, pCreateInfo, pAllocator,
+                                     &gfxstream_pQueryPool->internal_object, true /* do lock */);
+    }
+    *pQueryPool = gfxstream_vk_query_pool_to_handle(gfxstream_pQueryPool);
     return vkCreateQueryPool_VkResult_return;
 }
-static void entry_vkDestroyQueryPool(VkDevice device, VkQueryPool queryPool,
-                                     const VkAllocationCallbacks* pAllocator) {
+void gfxstream_vk_DestroyQueryPool(VkDevice device, VkQueryPool queryPool,
+                                   const VkAllocationCallbacks* pAllocator) {
     AEMU_SCOPED_TRACE("vkDestroyQueryPool");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkDestroyQueryPool(device, queryPool, pAllocator, true /* do lock */);
+    if (VK_NULL_HANDLE == queryPool) {
+        return;
+    }
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    VK_FROM_HANDLE(gfxstream_vk_query_pool, gfxstream_queryPool, queryPool);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkEnc->vkDestroyQueryPool(
+            gfxstream_device->internal_object,
+            gfxstream_queryPool ? gfxstream_queryPool->internal_object : VK_NULL_HANDLE, pAllocator,
+            true /* do lock */);
+    }
+    vk_query_pool_destroy(&gfxstream_device->vk, pAllocator, &gfxstream_queryPool->vk);
 }
-static VkResult entry_vkGetQueryPoolResults(VkDevice device, VkQueryPool queryPool,
-                                            uint32_t firstQuery, uint32_t queryCount,
-                                            size_t dataSize, void* pData, VkDeviceSize stride,
-                                            VkQueryResultFlags flags) {
+VkResult gfxstream_vk_GetQueryPoolResults(VkDevice device, VkQueryPool queryPool,
+                                          uint32_t firstQuery, uint32_t queryCount, size_t dataSize,
+                                          void* pData, VkDeviceSize stride,
+                                          VkQueryResultFlags flags) {
     AEMU_SCOPED_TRACE("vkGetQueryPoolResults");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
     VkResult vkGetQueryPoolResults_VkResult_return = (VkResult)0;
-    vkGetQueryPoolResults_VkResult_return =
-        vkEnc->vkGetQueryPoolResults(device, queryPool, firstQuery, queryCount, dataSize, pData,
-                                     stride, flags, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    VK_FROM_HANDLE(gfxstream_vk_query_pool, gfxstream_queryPool, queryPool);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkGetQueryPoolResults_VkResult_return = vkEnc->vkGetQueryPoolResults(
+            gfxstream_device->internal_object, gfxstream_queryPool->internal_object, firstQuery,
+            queryCount, dataSize, pData, stride, flags, true /* do lock */);
+    }
     return vkGetQueryPoolResults_VkResult_return;
 }
-static VkResult entry_vkCreateBuffer(VkDevice device, const VkBufferCreateInfo* pCreateInfo,
-                                     const VkAllocationCallbacks* pAllocator, VkBuffer* pBuffer) {
+VkResult gfxstream_vk_CreateBuffer(VkDevice device, const VkBufferCreateInfo* pCreateInfo,
+                                   const VkAllocationCallbacks* pAllocator, VkBuffer* pBuffer) {
     AEMU_SCOPED_TRACE("vkCreateBuffer");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
     VkResult vkCreateBuffer_VkResult_return = (VkResult)0;
-    auto resources = ResourceTracker::get();
-    vkCreateBuffer_VkResult_return =
-        resources->on_vkCreateBuffer(vkEnc, VK_SUCCESS, device, pCreateInfo, pAllocator, pBuffer);
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    struct gfxstream_vk_buffer* gfxstream_pBuffer = (struct gfxstream_vk_buffer*)vk_buffer_create(
+        (vk_device*)gfxstream_device, pCreateInfo, pAllocator, sizeof(struct gfxstream_vk_buffer));
+    vkCreateBuffer_VkResult_return = gfxstream_pBuffer ? VK_SUCCESS : VK_ERROR_OUT_OF_HOST_MEMORY;
+    if (VK_SUCCESS == vkCreateBuffer_VkResult_return) {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        auto resources = gfxstream::vk::ResourceTracker::get();
+        vkCreateBuffer_VkResult_return = resources->on_vkCreateBuffer(
+            vkEnc, VK_SUCCESS, gfxstream_device->internal_object, pCreateInfo, pAllocator,
+            &gfxstream_pBuffer->internal_object);
+    }
+    *pBuffer = gfxstream_vk_buffer_to_handle(gfxstream_pBuffer);
     return vkCreateBuffer_VkResult_return;
 }
-static void entry_vkDestroyBuffer(VkDevice device, VkBuffer buffer,
-                                  const VkAllocationCallbacks* pAllocator) {
+void gfxstream_vk_DestroyBuffer(VkDevice device, VkBuffer buffer,
+                                const VkAllocationCallbacks* pAllocator) {
     AEMU_SCOPED_TRACE("vkDestroyBuffer");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    auto resources = ResourceTracker::get();
-    resources->on_vkDestroyBuffer(vkEnc, device, buffer, pAllocator);
+    if (VK_NULL_HANDLE == buffer) {
+        return;
+    }
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    VK_FROM_HANDLE(gfxstream_vk_buffer, gfxstream_buffer, buffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        auto resources = gfxstream::vk::ResourceTracker::get();
+        resources->on_vkDestroyBuffer(
+            vkEnc, gfxstream_device->internal_object,
+            gfxstream_buffer ? gfxstream_buffer->internal_object : VK_NULL_HANDLE, pAllocator);
+    }
+    vk_buffer_destroy(&gfxstream_device->vk, pAllocator, &gfxstream_buffer->vk);
 }
-static VkResult entry_vkCreateBufferView(VkDevice device, const VkBufferViewCreateInfo* pCreateInfo,
-                                         const VkAllocationCallbacks* pAllocator,
-                                         VkBufferView* pView) {
+VkResult gfxstream_vk_CreateBufferView(VkDevice device, const VkBufferViewCreateInfo* pCreateInfo,
+                                       const VkAllocationCallbacks* pAllocator,
+                                       VkBufferView* pView) {
     AEMU_SCOPED_TRACE("vkCreateBufferView");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
     VkResult vkCreateBufferView_VkResult_return = (VkResult)0;
-    vkCreateBufferView_VkResult_return =
-        vkEnc->vkCreateBufferView(device, pCreateInfo, pAllocator, pView, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    struct gfxstream_vk_buffer_view* gfxstream_pView =
+        (struct gfxstream_vk_buffer_view*)vk_buffer_view_create(
+            (vk_device*)gfxstream_device, pCreateInfo, pAllocator,
+            sizeof(struct gfxstream_vk_buffer_view));
+    vkCreateBufferView_VkResult_return = gfxstream_pView ? VK_SUCCESS : VK_ERROR_OUT_OF_HOST_MEMORY;
+    if (VK_SUCCESS == vkCreateBufferView_VkResult_return) {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        std::vector<VkBufferViewCreateInfo> internal_pCreateInfo(1);
+        for (uint32_t i = 0; i < 1; ++i) {
+            internal_pCreateInfo[i] = pCreateInfo[i];
+            /* VkBufferViewCreateInfo::buffer */
+            VK_FROM_HANDLE(gfxstream_vk_buffer, gfxstream_buffer, internal_pCreateInfo[i].buffer);
+            internal_pCreateInfo[i].buffer = gfxstream_buffer->internal_object;
+        }
+        vkCreateBufferView_VkResult_return = vkEnc->vkCreateBufferView(
+            gfxstream_device->internal_object, internal_pCreateInfo.data(), pAllocator,
+            &gfxstream_pView->internal_object, true /* do lock */);
+    }
+    *pView = gfxstream_vk_buffer_view_to_handle(gfxstream_pView);
     return vkCreateBufferView_VkResult_return;
 }
-static void entry_vkDestroyBufferView(VkDevice device, VkBufferView bufferView,
-                                      const VkAllocationCallbacks* pAllocator) {
+void gfxstream_vk_DestroyBufferView(VkDevice device, VkBufferView bufferView,
+                                    const VkAllocationCallbacks* pAllocator) {
     AEMU_SCOPED_TRACE("vkDestroyBufferView");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkDestroyBufferView(device, bufferView, pAllocator, true /* do lock */);
+    if (VK_NULL_HANDLE == bufferView) {
+        return;
+    }
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    VK_FROM_HANDLE(gfxstream_vk_buffer_view, gfxstream_bufferView, bufferView);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkEnc->vkDestroyBufferView(
+            gfxstream_device->internal_object,
+            gfxstream_bufferView ? gfxstream_bufferView->internal_object : VK_NULL_HANDLE,
+            pAllocator, true /* do lock */);
+    }
+    vk_buffer_view_destroy(&gfxstream_device->vk, pAllocator, &gfxstream_bufferView->vk);
 }
-static VkResult entry_vkCreateImage(VkDevice device, const VkImageCreateInfo* pCreateInfo,
-                                    const VkAllocationCallbacks* pAllocator, VkImage* pImage) {
+VkResult gfxstream_vk_CreateImage(VkDevice device, const VkImageCreateInfo* pCreateInfo,
+                                  const VkAllocationCallbacks* pAllocator, VkImage* pImage) {
     AEMU_SCOPED_TRACE("vkCreateImage");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
     VkResult vkCreateImage_VkResult_return = (VkResult)0;
-    auto resources = ResourceTracker::get();
-    vkCreateImage_VkResult_return =
-        resources->on_vkCreateImage(vkEnc, VK_SUCCESS, device, pCreateInfo, pAllocator, pImage);
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    struct gfxstream_vk_image* gfxstream_pImage = (struct gfxstream_vk_image*)vk_image_create(
+        (vk_device*)gfxstream_device, pCreateInfo, pAllocator, sizeof(struct gfxstream_vk_image));
+    vkCreateImage_VkResult_return = gfxstream_pImage ? VK_SUCCESS : VK_ERROR_OUT_OF_HOST_MEMORY;
+    if (VK_SUCCESS == vkCreateImage_VkResult_return) {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        auto resources = gfxstream::vk::ResourceTracker::get();
+        vkCreateImage_VkResult_return = resources->on_vkCreateImage(
+            vkEnc, VK_SUCCESS, gfxstream_device->internal_object, pCreateInfo, pAllocator,
+            &gfxstream_pImage->internal_object);
+    }
+    *pImage = gfxstream_vk_image_to_handle(gfxstream_pImage);
     return vkCreateImage_VkResult_return;
 }
-static void entry_vkDestroyImage(VkDevice device, VkImage image,
-                                 const VkAllocationCallbacks* pAllocator) {
+void gfxstream_vk_DestroyImage(VkDevice device, VkImage image,
+                               const VkAllocationCallbacks* pAllocator) {
     AEMU_SCOPED_TRACE("vkDestroyImage");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    auto resources = ResourceTracker::get();
-    resources->on_vkDestroyImage(vkEnc, device, image, pAllocator);
+    if (VK_NULL_HANDLE == image) {
+        return;
+    }
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    VK_FROM_HANDLE(gfxstream_vk_image, gfxstream_image, image);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        auto resources = gfxstream::vk::ResourceTracker::get();
+        resources->on_vkDestroyImage(
+            vkEnc, gfxstream_device->internal_object,
+            gfxstream_image ? gfxstream_image->internal_object : VK_NULL_HANDLE, pAllocator);
+    }
+    vk_image_destroy(&gfxstream_device->vk, pAllocator, &gfxstream_image->vk);
 }
-static void entry_vkGetImageSubresourceLayout(VkDevice device, VkImage image,
-                                              const VkImageSubresource* pSubresource,
-                                              VkSubresourceLayout* pLayout) {
+void gfxstream_vk_GetImageSubresourceLayout(VkDevice device, VkImage image,
+                                            const VkImageSubresource* pSubresource,
+                                            VkSubresourceLayout* pLayout) {
     AEMU_SCOPED_TRACE("vkGetImageSubresourceLayout");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkGetImageSubresourceLayout(device, image, pSubresource, pLayout, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    VK_FROM_HANDLE(gfxstream_vk_image, gfxstream_image, image);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkEnc->vkGetImageSubresourceLayout(gfxstream_device->internal_object,
+                                           gfxstream_image->internal_object, pSubresource, pLayout,
+                                           true /* do lock */);
+    }
 }
-static VkResult entry_vkCreateImageView(VkDevice device, const VkImageViewCreateInfo* pCreateInfo,
-                                        const VkAllocationCallbacks* pAllocator,
-                                        VkImageView* pView) {
+VkResult gfxstream_vk_CreateImageView(VkDevice device, const VkImageViewCreateInfo* pCreateInfo,
+                                      const VkAllocationCallbacks* pAllocator, VkImageView* pView) {
     AEMU_SCOPED_TRACE("vkCreateImageView");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
     VkResult vkCreateImageView_VkResult_return = (VkResult)0;
-    auto resources = ResourceTracker::get();
-    vkCreateImageView_VkResult_return =
-        resources->on_vkCreateImageView(vkEnc, VK_SUCCESS, device, pCreateInfo, pAllocator, pView);
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    struct gfxstream_vk_image_view* gfxstream_pView =
+        (struct gfxstream_vk_image_view*)vk_image_view_create(
+            (vk_device*)gfxstream_device, false /* driver_internal */, pCreateInfo, pAllocator,
+            sizeof(struct gfxstream_vk_image_view));
+    vkCreateImageView_VkResult_return = gfxstream_pView ? VK_SUCCESS : VK_ERROR_OUT_OF_HOST_MEMORY;
+    if (VK_SUCCESS == vkCreateImageView_VkResult_return) {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        std::vector<VkImageViewCreateInfo> internal_pCreateInfo(1);
+        for (uint32_t i = 0; i < 1; ++i) {
+            internal_pCreateInfo[i] = pCreateInfo[i];
+            /* VkImageViewCreateInfo::image */
+            VK_FROM_HANDLE(gfxstream_vk_image, gfxstream_image, internal_pCreateInfo[i].image);
+            internal_pCreateInfo[i].image = gfxstream_image->internal_object;
+        }
+        auto resources = gfxstream::vk::ResourceTracker::get();
+        vkCreateImageView_VkResult_return = resources->on_vkCreateImageView(
+            vkEnc, VK_SUCCESS, gfxstream_device->internal_object, internal_pCreateInfo.data(),
+            pAllocator, &gfxstream_pView->internal_object);
+    }
+    *pView = gfxstream_vk_image_view_to_handle(gfxstream_pView);
     return vkCreateImageView_VkResult_return;
 }
-static void entry_vkDestroyImageView(VkDevice device, VkImageView imageView,
-                                     const VkAllocationCallbacks* pAllocator) {
+void gfxstream_vk_DestroyImageView(VkDevice device, VkImageView imageView,
+                                   const VkAllocationCallbacks* pAllocator) {
     AEMU_SCOPED_TRACE("vkDestroyImageView");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkDestroyImageView(device, imageView, pAllocator, true /* do lock */);
+    if (VK_NULL_HANDLE == imageView) {
+        return;
+    }
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    VK_FROM_HANDLE(gfxstream_vk_image_view, gfxstream_imageView, imageView);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkEnc->vkDestroyImageView(
+            gfxstream_device->internal_object,
+            gfxstream_imageView ? gfxstream_imageView->internal_object : VK_NULL_HANDLE, pAllocator,
+            true /* do lock */);
+    }
+    vk_image_view_destroy(&gfxstream_device->vk, pAllocator, &gfxstream_imageView->vk);
 }
-static VkResult entry_vkCreateShaderModule(VkDevice device,
-                                           const VkShaderModuleCreateInfo* pCreateInfo,
-                                           const VkAllocationCallbacks* pAllocator,
-                                           VkShaderModule* pShaderModule) {
+VkResult gfxstream_vk_CreateShaderModule(VkDevice device,
+                                         const VkShaderModuleCreateInfo* pCreateInfo,
+                                         const VkAllocationCallbacks* pAllocator,
+                                         VkShaderModule* pShaderModule) {
     AEMU_SCOPED_TRACE("vkCreateShaderModule");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
     VkResult vkCreateShaderModule_VkResult_return = (VkResult)0;
-    vkCreateShaderModule_VkResult_return = vkEnc->vkCreateShaderModule(
-        device, pCreateInfo, pAllocator, pShaderModule, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    struct gfxstream_vk_shader_module* gfxstream_pShaderModule =
+        (gfxstream_vk_shader_module*)vk_object_zalloc(&gfxstream_device->vk, pAllocator,
+                                                      sizeof(gfxstream_vk_shader_module),
+                                                      VK_OBJECT_TYPE_SHADER_MODULE);
+    vkCreateShaderModule_VkResult_return =
+        gfxstream_pShaderModule ? VK_SUCCESS : VK_ERROR_OUT_OF_HOST_MEMORY;
+    if (VK_SUCCESS == vkCreateShaderModule_VkResult_return) {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkCreateShaderModule_VkResult_return = vkEnc->vkCreateShaderModule(
+            gfxstream_device->internal_object, pCreateInfo, pAllocator,
+            &gfxstream_pShaderModule->internal_object, true /* do lock */);
+    }
+    *pShaderModule = gfxstream_vk_shader_module_to_handle(gfxstream_pShaderModule);
     return vkCreateShaderModule_VkResult_return;
 }
-static void entry_vkDestroyShaderModule(VkDevice device, VkShaderModule shaderModule,
-                                        const VkAllocationCallbacks* pAllocator) {
+void gfxstream_vk_DestroyShaderModule(VkDevice device, VkShaderModule shaderModule,
+                                      const VkAllocationCallbacks* pAllocator) {
     AEMU_SCOPED_TRACE("vkDestroyShaderModule");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkDestroyShaderModule(device, shaderModule, pAllocator, true /* do lock */);
+    if (VK_NULL_HANDLE == shaderModule) {
+        return;
+    }
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    VK_FROM_HANDLE(gfxstream_vk_shader_module, gfxstream_shaderModule, shaderModule);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkEnc->vkDestroyShaderModule(
+            gfxstream_device->internal_object,
+            gfxstream_shaderModule ? gfxstream_shaderModule->internal_object : VK_NULL_HANDLE,
+            pAllocator, true /* do lock */);
+    }
+    vk_object_free(&gfxstream_device->vk, pAllocator, (void*)gfxstream_shaderModule);
 }
-static VkResult entry_vkCreatePipelineCache(VkDevice device,
-                                            const VkPipelineCacheCreateInfo* pCreateInfo,
-                                            const VkAllocationCallbacks* pAllocator,
-                                            VkPipelineCache* pPipelineCache) {
+VkResult gfxstream_vk_CreatePipelineCache(VkDevice device,
+                                          const VkPipelineCacheCreateInfo* pCreateInfo,
+                                          const VkAllocationCallbacks* pAllocator,
+                                          VkPipelineCache* pPipelineCache) {
     AEMU_SCOPED_TRACE("vkCreatePipelineCache");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
     VkResult vkCreatePipelineCache_VkResult_return = (VkResult)0;
-    vkCreatePipelineCache_VkResult_return = vkEnc->vkCreatePipelineCache(
-        device, pCreateInfo, pAllocator, pPipelineCache, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    struct gfxstream_vk_pipeline_cache* gfxstream_pPipelineCache =
+        (gfxstream_vk_pipeline_cache*)vk_object_zalloc(&gfxstream_device->vk, pAllocator,
+                                                       sizeof(gfxstream_vk_pipeline_cache),
+                                                       VK_OBJECT_TYPE_PIPELINE_CACHE);
+    vkCreatePipelineCache_VkResult_return =
+        gfxstream_pPipelineCache ? VK_SUCCESS : VK_ERROR_OUT_OF_HOST_MEMORY;
+    if (VK_SUCCESS == vkCreatePipelineCache_VkResult_return) {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkCreatePipelineCache_VkResult_return = vkEnc->vkCreatePipelineCache(
+            gfxstream_device->internal_object, pCreateInfo, pAllocator,
+            &gfxstream_pPipelineCache->internal_object, true /* do lock */);
+    }
+    *pPipelineCache = gfxstream_vk_pipeline_cache_to_handle(gfxstream_pPipelineCache);
     return vkCreatePipelineCache_VkResult_return;
 }
-static void entry_vkDestroyPipelineCache(VkDevice device, VkPipelineCache pipelineCache,
-                                         const VkAllocationCallbacks* pAllocator) {
+void gfxstream_vk_DestroyPipelineCache(VkDevice device, VkPipelineCache pipelineCache,
+                                       const VkAllocationCallbacks* pAllocator) {
     AEMU_SCOPED_TRACE("vkDestroyPipelineCache");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkDestroyPipelineCache(device, pipelineCache, pAllocator, true /* do lock */);
+    if (VK_NULL_HANDLE == pipelineCache) {
+        return;
+    }
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    VK_FROM_HANDLE(gfxstream_vk_pipeline_cache, gfxstream_pipelineCache, pipelineCache);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkEnc->vkDestroyPipelineCache(
+            gfxstream_device->internal_object,
+            gfxstream_pipelineCache ? gfxstream_pipelineCache->internal_object : VK_NULL_HANDLE,
+            pAllocator, true /* do lock */);
+    }
+    vk_object_free(&gfxstream_device->vk, pAllocator, (void*)gfxstream_pipelineCache);
 }
-static VkResult entry_vkGetPipelineCacheData(VkDevice device, VkPipelineCache pipelineCache,
-                                             size_t* pDataSize, void* pData) {
+VkResult gfxstream_vk_GetPipelineCacheData(VkDevice device, VkPipelineCache pipelineCache,
+                                           size_t* pDataSize, void* pData) {
     AEMU_SCOPED_TRACE("vkGetPipelineCacheData");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
     VkResult vkGetPipelineCacheData_VkResult_return = (VkResult)0;
-    vkGetPipelineCacheData_VkResult_return =
-        vkEnc->vkGetPipelineCacheData(device, pipelineCache, pDataSize, pData, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    VK_FROM_HANDLE(gfxstream_vk_pipeline_cache, gfxstream_pipelineCache, pipelineCache);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkGetPipelineCacheData_VkResult_return = vkEnc->vkGetPipelineCacheData(
+            gfxstream_device->internal_object, gfxstream_pipelineCache->internal_object, pDataSize,
+            pData, true /* do lock */);
+    }
     return vkGetPipelineCacheData_VkResult_return;
 }
-static VkResult entry_vkMergePipelineCaches(VkDevice device, VkPipelineCache dstCache,
-                                            uint32_t srcCacheCount,
-                                            const VkPipelineCache* pSrcCaches) {
+VkResult gfxstream_vk_MergePipelineCaches(VkDevice device, VkPipelineCache dstCache,
+                                          uint32_t srcCacheCount,
+                                          const VkPipelineCache* pSrcCaches) {
     AEMU_SCOPED_TRACE("vkMergePipelineCaches");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
     VkResult vkMergePipelineCaches_VkResult_return = (VkResult)0;
-    vkMergePipelineCaches_VkResult_return = vkEnc->vkMergePipelineCaches(
-        device, dstCache, srcCacheCount, pSrcCaches, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    VK_FROM_HANDLE(gfxstream_vk_pipeline_cache, gfxstream_dstCache, dstCache);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        std::vector<VkPipelineCache> internal_pSrcCaches(srcCacheCount);
+        for (uint32_t i = 0; i < srcCacheCount; ++i) {
+            VK_FROM_HANDLE(gfxstream_vk_pipeline_cache, gfxstream_pSrcCaches, pSrcCaches[i]);
+            internal_pSrcCaches[i] = gfxstream_pSrcCaches->internal_object;
+        }
+        vkMergePipelineCaches_VkResult_return = vkEnc->vkMergePipelineCaches(
+            gfxstream_device->internal_object, gfxstream_dstCache->internal_object, srcCacheCount,
+            internal_pSrcCaches.data(), true /* do lock */);
+    }
     return vkMergePipelineCaches_VkResult_return;
 }
-static VkResult entry_vkCreateGraphicsPipelines(VkDevice device, VkPipelineCache pipelineCache,
-                                                uint32_t createInfoCount,
-                                                const VkGraphicsPipelineCreateInfo* pCreateInfos,
-                                                const VkAllocationCallbacks* pAllocator,
-                                                VkPipeline* pPipelines) {
+VkResult gfxstream_vk_CreateGraphicsPipelines(VkDevice device, VkPipelineCache pipelineCache,
+                                              uint32_t createInfoCount,
+                                              const VkGraphicsPipelineCreateInfo* pCreateInfos,
+                                              const VkAllocationCallbacks* pAllocator,
+                                              VkPipeline* pPipelines) {
     AEMU_SCOPED_TRACE("vkCreateGraphicsPipelines");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
     VkResult vkCreateGraphicsPipelines_VkResult_return = (VkResult)0;
-    auto resources = ResourceTracker::get();
-    vkCreateGraphicsPipelines_VkResult_return = resources->on_vkCreateGraphicsPipelines(
-        vkEnc, VK_SUCCESS, device, pipelineCache, createInfoCount, pCreateInfos, pAllocator,
-        pPipelines);
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    VK_FROM_HANDLE(gfxstream_vk_pipeline_cache, gfxstream_pipelineCache, pipelineCache);
+    struct gfxstream_vk_pipeline* gfxstream_pPipelines = (gfxstream_vk_pipeline*)vk_object_zalloc(
+        &gfxstream_device->vk, pAllocator, sizeof(gfxstream_vk_pipeline), VK_OBJECT_TYPE_PIPELINE);
+    vkCreateGraphicsPipelines_VkResult_return =
+        gfxstream_pPipelines ? VK_SUCCESS : VK_ERROR_OUT_OF_HOST_MEMORY;
+    if (VK_SUCCESS == vkCreateGraphicsPipelines_VkResult_return) {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        std::vector<VkGraphicsPipelineCreateInfo> internal_pCreateInfos(createInfoCount);
+        std::vector<std::vector<VkPipelineShaderStageCreateInfo>>
+            internal_VkGraphicsPipelineCreateInfo_pStages;
+        for (uint32_t i = 0; i < createInfoCount; ++i) {
+            internal_pCreateInfos[i] = pCreateInfos[i];
+            /* VkGraphicsPipelineCreateInfo::pStages */
+            internal_VkGraphicsPipelineCreateInfo_pStages.push_back(
+                std::vector<VkPipelineShaderStageCreateInfo>());
+            internal_VkGraphicsPipelineCreateInfo_pStages[i].reserve(
+                internal_pCreateInfos[i].stageCount);
+            memset(&internal_VkGraphicsPipelineCreateInfo_pStages[i][0], 0,
+                   sizeof(VkPipelineShaderStageCreateInfo) * internal_pCreateInfos[i].stageCount);
+            for (uint32_t j = 0; j < internal_pCreateInfos[i].stageCount; ++j) {
+                if (internal_pCreateInfos[i].pStages) {
+                    internal_VkGraphicsPipelineCreateInfo_pStages[i][j] =
+                        internal_pCreateInfos[i].pStages[j];
+                    /* VkPipelineShaderStageCreateInfo::module */
+                    if (internal_VkGraphicsPipelineCreateInfo_pStages[i][j].module) {
+                        VK_FROM_HANDLE(gfxstream_vk_shader_module, gfxstream_module,
+                                       internal_VkGraphicsPipelineCreateInfo_pStages[i][j].module);
+                        internal_VkGraphicsPipelineCreateInfo_pStages[i][j].module =
+                            gfxstream_module->internal_object;
+                    }
+                }
+            }
+            internal_pCreateInfos[i].pStages =
+                internal_VkGraphicsPipelineCreateInfo_pStages[i].data();
+            /* VkGraphicsPipelineCreateInfo::layout */
+            if (internal_pCreateInfos[i].layout) {
+                VK_FROM_HANDLE(gfxstream_vk_pipeline_layout, gfxstream_layout,
+                               internal_pCreateInfos[i].layout);
+                internal_pCreateInfos[i].layout = gfxstream_layout->internal_object;
+            }
+            /* VkGraphicsPipelineCreateInfo::renderPass */
+            if (internal_pCreateInfos[i].renderPass) {
+                VK_FROM_HANDLE(gfxstream_vk_render_pass, gfxstream_renderPass,
+                               internal_pCreateInfos[i].renderPass);
+                internal_pCreateInfos[i].renderPass = gfxstream_renderPass->internal_object;
+            }
+            /* VkGraphicsPipelineCreateInfo::basePipelineHandle */
+            if (internal_pCreateInfos[i].basePipelineHandle) {
+                VK_FROM_HANDLE(gfxstream_vk_pipeline, gfxstream_basePipelineHandle,
+                               internal_pCreateInfos[i].basePipelineHandle);
+                internal_pCreateInfos[i].basePipelineHandle =
+                    gfxstream_basePipelineHandle->internal_object;
+            }
+        }
+        auto resources = gfxstream::vk::ResourceTracker::get();
+        vkCreateGraphicsPipelines_VkResult_return = resources->on_vkCreateGraphicsPipelines(
+            vkEnc, VK_SUCCESS, gfxstream_device->internal_object,
+            gfxstream_pipelineCache ? gfxstream_pipelineCache->internal_object : VK_NULL_HANDLE,
+            createInfoCount, internal_pCreateInfos.data(), pAllocator,
+            &gfxstream_pPipelines->internal_object);
+    }
+    *pPipelines = gfxstream_vk_pipeline_to_handle(gfxstream_pPipelines);
     return vkCreateGraphicsPipelines_VkResult_return;
 }
-static VkResult entry_vkCreateComputePipelines(VkDevice device, VkPipelineCache pipelineCache,
-                                               uint32_t createInfoCount,
-                                               const VkComputePipelineCreateInfo* pCreateInfos,
-                                               const VkAllocationCallbacks* pAllocator,
-                                               VkPipeline* pPipelines) {
-    AEMU_SCOPED_TRACE("vkCreateComputePipelines");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    VkResult vkCreateComputePipelines_VkResult_return = (VkResult)0;
-    vkCreateComputePipelines_VkResult_return =
-        vkEnc->vkCreateComputePipelines(device, pipelineCache, createInfoCount, pCreateInfos,
-                                        pAllocator, pPipelines, true /* do lock */);
-    return vkCreateComputePipelines_VkResult_return;
-}
-static void entry_vkDestroyPipeline(VkDevice device, VkPipeline pipeline,
-                                    const VkAllocationCallbacks* pAllocator) {
+void gfxstream_vk_DestroyPipeline(VkDevice device, VkPipeline pipeline,
+                                  const VkAllocationCallbacks* pAllocator) {
     AEMU_SCOPED_TRACE("vkDestroyPipeline");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkDestroyPipeline(device, pipeline, pAllocator, true /* do lock */);
+    if (VK_NULL_HANDLE == pipeline) {
+        return;
+    }
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    VK_FROM_HANDLE(gfxstream_vk_pipeline, gfxstream_pipeline, pipeline);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkEnc->vkDestroyPipeline(
+            gfxstream_device->internal_object,
+            gfxstream_pipeline ? gfxstream_pipeline->internal_object : VK_NULL_HANDLE, pAllocator,
+            true /* do lock */);
+    }
+    vk_object_free(&gfxstream_device->vk, pAllocator, (void*)gfxstream_pipeline);
 }
-static VkResult entry_vkCreatePipelineLayout(VkDevice device,
-                                             const VkPipelineLayoutCreateInfo* pCreateInfo,
-                                             const VkAllocationCallbacks* pAllocator,
-                                             VkPipelineLayout* pPipelineLayout) {
+VkResult gfxstream_vk_CreatePipelineLayout(VkDevice device,
+                                           const VkPipelineLayoutCreateInfo* pCreateInfo,
+                                           const VkAllocationCallbacks* pAllocator,
+                                           VkPipelineLayout* pPipelineLayout) {
     AEMU_SCOPED_TRACE("vkCreatePipelineLayout");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
     VkResult vkCreatePipelineLayout_VkResult_return = (VkResult)0;
-    vkCreatePipelineLayout_VkResult_return = vkEnc->vkCreatePipelineLayout(
-        device, pCreateInfo, pAllocator, pPipelineLayout, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    struct gfxstream_vk_pipeline_layout* gfxstream_pPipelineLayout =
+        (gfxstream_vk_pipeline_layout*)vk_object_zalloc(&gfxstream_device->vk, pAllocator,
+                                                        sizeof(gfxstream_vk_pipeline_layout),
+                                                        VK_OBJECT_TYPE_PIPELINE_LAYOUT);
+    vkCreatePipelineLayout_VkResult_return =
+        gfxstream_pPipelineLayout ? VK_SUCCESS : VK_ERROR_OUT_OF_HOST_MEMORY;
+    if (VK_SUCCESS == vkCreatePipelineLayout_VkResult_return) {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        std::vector<VkPipelineLayoutCreateInfo> internal_pCreateInfo(1);
+        std::vector<std::vector<VkDescriptorSetLayout>>
+            internal_VkPipelineLayoutCreateInfo_pSetLayouts;
+        for (uint32_t i = 0; i < 1; ++i) {
+            internal_pCreateInfo[i] = pCreateInfo[i];
+            /* VkPipelineLayoutCreateInfo::pSetLayouts */
+            internal_VkPipelineLayoutCreateInfo_pSetLayouts.push_back(
+                std::vector<VkDescriptorSetLayout>());
+            internal_VkPipelineLayoutCreateInfo_pSetLayouts[i].reserve(
+                internal_pCreateInfo[i].setLayoutCount);
+            memset(&internal_VkPipelineLayoutCreateInfo_pSetLayouts[i][0], 0,
+                   sizeof(VkDescriptorSetLayout) * internal_pCreateInfo[i].setLayoutCount);
+            for (uint32_t j = 0; j < internal_pCreateInfo[i].setLayoutCount; ++j) {
+                if (internal_pCreateInfo[i].pSetLayouts) {
+                    VK_FROM_HANDLE(gfxstream_vk_descriptor_set_layout, gfxstream_pSetLayouts,
+                                   internal_pCreateInfo[i].pSetLayouts[j]);
+                    internal_VkPipelineLayoutCreateInfo_pSetLayouts[i][j] =
+                        gfxstream_pSetLayouts->internal_object;
+                }
+            }
+            internal_pCreateInfo[i].pSetLayouts =
+                internal_VkPipelineLayoutCreateInfo_pSetLayouts[i].data();
+        }
+        vkCreatePipelineLayout_VkResult_return = vkEnc->vkCreatePipelineLayout(
+            gfxstream_device->internal_object, internal_pCreateInfo.data(), pAllocator,
+            &gfxstream_pPipelineLayout->internal_object, true /* do lock */);
+    }
+    *pPipelineLayout = gfxstream_vk_pipeline_layout_to_handle(gfxstream_pPipelineLayout);
     return vkCreatePipelineLayout_VkResult_return;
 }
-static void entry_vkDestroyPipelineLayout(VkDevice device, VkPipelineLayout pipelineLayout,
-                                          const VkAllocationCallbacks* pAllocator) {
+void gfxstream_vk_DestroyPipelineLayout(VkDevice device, VkPipelineLayout pipelineLayout,
+                                        const VkAllocationCallbacks* pAllocator) {
     AEMU_SCOPED_TRACE("vkDestroyPipelineLayout");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkDestroyPipelineLayout(device, pipelineLayout, pAllocator, true /* do lock */);
+    if (VK_NULL_HANDLE == pipelineLayout) {
+        return;
+    }
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    VK_FROM_HANDLE(gfxstream_vk_pipeline_layout, gfxstream_pipelineLayout, pipelineLayout);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkEnc->vkDestroyPipelineLayout(
+            gfxstream_device->internal_object,
+            gfxstream_pipelineLayout ? gfxstream_pipelineLayout->internal_object : VK_NULL_HANDLE,
+            pAllocator, true /* do lock */);
+    }
+    vk_object_free(&gfxstream_device->vk, pAllocator, (void*)gfxstream_pipelineLayout);
 }
-static VkResult entry_vkCreateSampler(VkDevice device, const VkSamplerCreateInfo* pCreateInfo,
-                                      const VkAllocationCallbacks* pAllocator,
-                                      VkSampler* pSampler) {
+VkResult gfxstream_vk_CreateSampler(VkDevice device, const VkSamplerCreateInfo* pCreateInfo,
+                                    const VkAllocationCallbacks* pAllocator, VkSampler* pSampler) {
     AEMU_SCOPED_TRACE("vkCreateSampler");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
     VkResult vkCreateSampler_VkResult_return = (VkResult)0;
-    auto resources = ResourceTracker::get();
-    vkCreateSampler_VkResult_return =
-        resources->on_vkCreateSampler(vkEnc, VK_SUCCESS, device, pCreateInfo, pAllocator, pSampler);
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        auto resources = gfxstream::vk::ResourceTracker::get();
+        vkCreateSampler_VkResult_return =
+            resources->on_vkCreateSampler(vkEnc, VK_SUCCESS, gfxstream_device->internal_object,
+                                          pCreateInfo, pAllocator, pSampler);
+    }
     return vkCreateSampler_VkResult_return;
 }
-static void entry_vkDestroySampler(VkDevice device, VkSampler sampler,
-                                   const VkAllocationCallbacks* pAllocator) {
+void gfxstream_vk_DestroySampler(VkDevice device, VkSampler sampler,
+                                 const VkAllocationCallbacks* pAllocator) {
     AEMU_SCOPED_TRACE("vkDestroySampler");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkDestroySampler(device, sampler, pAllocator, true /* do lock */);
+    if (VK_NULL_HANDLE == sampler) {
+        return;
+    }
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkEnc->vkDestroySampler(gfxstream_device->internal_object, sampler, pAllocator,
+                                true /* do lock */);
+    }
 }
-static VkResult entry_vkCreateDescriptorSetLayout(
-    VkDevice device, const VkDescriptorSetLayoutCreateInfo* pCreateInfo,
-    const VkAllocationCallbacks* pAllocator, VkDescriptorSetLayout* pSetLayout) {
+VkResult gfxstream_vk_CreateDescriptorSetLayout(VkDevice device,
+                                                const VkDescriptorSetLayoutCreateInfo* pCreateInfo,
+                                                const VkAllocationCallbacks* pAllocator,
+                                                VkDescriptorSetLayout* pSetLayout) {
     AEMU_SCOPED_TRACE("vkCreateDescriptorSetLayout");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
     VkResult vkCreateDescriptorSetLayout_VkResult_return = (VkResult)0;
-    auto resources = ResourceTracker::get();
-    vkCreateDescriptorSetLayout_VkResult_return = resources->on_vkCreateDescriptorSetLayout(
-        vkEnc, VK_SUCCESS, device, pCreateInfo, pAllocator, pSetLayout);
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    struct gfxstream_vk_descriptor_set_layout* gfxstream_pSetLayout =
+        (gfxstream_vk_descriptor_set_layout*)vk_object_zalloc(
+            &gfxstream_device->vk, pAllocator, sizeof(gfxstream_vk_descriptor_set_layout),
+            VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT);
+    vkCreateDescriptorSetLayout_VkResult_return =
+        gfxstream_pSetLayout ? VK_SUCCESS : VK_ERROR_OUT_OF_HOST_MEMORY;
+    if (VK_SUCCESS == vkCreateDescriptorSetLayout_VkResult_return) {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        auto resources = gfxstream::vk::ResourceTracker::get();
+        vkCreateDescriptorSetLayout_VkResult_return = resources->on_vkCreateDescriptorSetLayout(
+            vkEnc, VK_SUCCESS, gfxstream_device->internal_object, pCreateInfo, pAllocator,
+            &gfxstream_pSetLayout->internal_object);
+    }
+    *pSetLayout = gfxstream_vk_descriptor_set_layout_to_handle(gfxstream_pSetLayout);
     return vkCreateDescriptorSetLayout_VkResult_return;
 }
-static void entry_vkDestroyDescriptorSetLayout(VkDevice device,
-                                               VkDescriptorSetLayout descriptorSetLayout,
-                                               const VkAllocationCallbacks* pAllocator) {
+void gfxstream_vk_DestroyDescriptorSetLayout(VkDevice device,
+                                             VkDescriptorSetLayout descriptorSetLayout,
+                                             const VkAllocationCallbacks* pAllocator) {
     AEMU_SCOPED_TRACE("vkDestroyDescriptorSetLayout");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    auto resources = ResourceTracker::get();
-    resources->on_vkDestroyDescriptorSetLayout(vkEnc, device, descriptorSetLayout, pAllocator);
+    if (VK_NULL_HANDLE == descriptorSetLayout) {
+        return;
+    }
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    VK_FROM_HANDLE(gfxstream_vk_descriptor_set_layout, gfxstream_descriptorSetLayout,
+                   descriptorSetLayout);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        auto resources = gfxstream::vk::ResourceTracker::get();
+        resources->on_vkDestroyDescriptorSetLayout(
+            vkEnc, gfxstream_device->internal_object,
+            gfxstream_descriptorSetLayout ? gfxstream_descriptorSetLayout->internal_object
+                                          : VK_NULL_HANDLE,
+            pAllocator);
+    }
+    vk_object_free(&gfxstream_device->vk, pAllocator, (void*)gfxstream_descriptorSetLayout);
 }
-static VkResult entry_vkCreateDescriptorPool(VkDevice device,
-                                             const VkDescriptorPoolCreateInfo* pCreateInfo,
-                                             const VkAllocationCallbacks* pAllocator,
-                                             VkDescriptorPool* pDescriptorPool) {
+VkResult gfxstream_vk_CreateDescriptorPool(VkDevice device,
+                                           const VkDescriptorPoolCreateInfo* pCreateInfo,
+                                           const VkAllocationCallbacks* pAllocator,
+                                           VkDescriptorPool* pDescriptorPool) {
     AEMU_SCOPED_TRACE("vkCreateDescriptorPool");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
     VkResult vkCreateDescriptorPool_VkResult_return = (VkResult)0;
-    auto resources = ResourceTracker::get();
-    vkCreateDescriptorPool_VkResult_return = resources->on_vkCreateDescriptorPool(
-        vkEnc, VK_SUCCESS, device, pCreateInfo, pAllocator, pDescriptorPool);
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    struct gfxstream_vk_descriptor_pool* gfxstream_pDescriptorPool =
+        (gfxstream_vk_descriptor_pool*)vk_object_zalloc(&gfxstream_device->vk, pAllocator,
+                                                        sizeof(gfxstream_vk_descriptor_pool),
+                                                        VK_OBJECT_TYPE_DESCRIPTOR_POOL);
+    vkCreateDescriptorPool_VkResult_return =
+        gfxstream_pDescriptorPool ? VK_SUCCESS : VK_ERROR_OUT_OF_HOST_MEMORY;
+    if (VK_SUCCESS == vkCreateDescriptorPool_VkResult_return) {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        auto resources = gfxstream::vk::ResourceTracker::get();
+        vkCreateDescriptorPool_VkResult_return = resources->on_vkCreateDescriptorPool(
+            vkEnc, VK_SUCCESS, gfxstream_device->internal_object, pCreateInfo, pAllocator,
+            &gfxstream_pDescriptorPool->internal_object);
+    }
+    *pDescriptorPool = gfxstream_vk_descriptor_pool_to_handle(gfxstream_pDescriptorPool);
     return vkCreateDescriptorPool_VkResult_return;
 }
-static void entry_vkDestroyDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool,
-                                          const VkAllocationCallbacks* pAllocator) {
+void gfxstream_vk_DestroyDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool,
+                                        const VkAllocationCallbacks* pAllocator) {
     AEMU_SCOPED_TRACE("vkDestroyDescriptorPool");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    auto resources = ResourceTracker::get();
-    resources->on_vkDestroyDescriptorPool(vkEnc, device, descriptorPool, pAllocator);
+    if (VK_NULL_HANDLE == descriptorPool) {
+        return;
+    }
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    VK_FROM_HANDLE(gfxstream_vk_descriptor_pool, gfxstream_descriptorPool, descriptorPool);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        auto resources = gfxstream::vk::ResourceTracker::get();
+        resources->on_vkDestroyDescriptorPool(
+            vkEnc, gfxstream_device->internal_object,
+            gfxstream_descriptorPool ? gfxstream_descriptorPool->internal_object : VK_NULL_HANDLE,
+            pAllocator);
+    }
+    vk_object_free(&gfxstream_device->vk, pAllocator, (void*)gfxstream_descriptorPool);
 }
-static VkResult entry_vkResetDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool,
-                                            VkDescriptorPoolResetFlags flags) {
+VkResult gfxstream_vk_ResetDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool,
+                                          VkDescriptorPoolResetFlags flags) {
     AEMU_SCOPED_TRACE("vkResetDescriptorPool");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
     VkResult vkResetDescriptorPool_VkResult_return = (VkResult)0;
-    auto resources = ResourceTracker::get();
-    vkResetDescriptorPool_VkResult_return =
-        resources->on_vkResetDescriptorPool(vkEnc, VK_SUCCESS, device, descriptorPool, flags);
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    VK_FROM_HANDLE(gfxstream_vk_descriptor_pool, gfxstream_descriptorPool, descriptorPool);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        auto resources = gfxstream::vk::ResourceTracker::get();
+        vkResetDescriptorPool_VkResult_return = resources->on_vkResetDescriptorPool(
+            vkEnc, VK_SUCCESS, gfxstream_device->internal_object,
+            gfxstream_descriptorPool->internal_object, flags);
+    }
     return vkResetDescriptorPool_VkResult_return;
 }
-static VkResult entry_vkAllocateDescriptorSets(VkDevice device,
-                                               const VkDescriptorSetAllocateInfo* pAllocateInfo,
-                                               VkDescriptorSet* pDescriptorSets) {
+VkResult gfxstream_vk_AllocateDescriptorSets(VkDevice device,
+                                             const VkDescriptorSetAllocateInfo* pAllocateInfo,
+                                             VkDescriptorSet* pDescriptorSets) {
     AEMU_SCOPED_TRACE("vkAllocateDescriptorSets");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
     VkResult vkAllocateDescriptorSets_VkResult_return = (VkResult)0;
-    auto resources = ResourceTracker::get();
-    vkAllocateDescriptorSets_VkResult_return = resources->on_vkAllocateDescriptorSets(
-        vkEnc, VK_SUCCESS, device, pAllocateInfo, pDescriptorSets);
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        std::vector<VkDescriptorSetAllocateInfo> internal_pAllocateInfo(1);
+        std::vector<std::vector<VkDescriptorSetLayout>>
+            internal_VkDescriptorSetAllocateInfo_pSetLayouts;
+        for (uint32_t i = 0; i < 1; ++i) {
+            internal_pAllocateInfo[i] = pAllocateInfo[i];
+            /* VkDescriptorSetAllocateInfo::descriptorPool */
+            VK_FROM_HANDLE(gfxstream_vk_descriptor_pool, gfxstream_descriptorPool,
+                           internal_pAllocateInfo[i].descriptorPool);
+            internal_pAllocateInfo[i].descriptorPool = gfxstream_descriptorPool->internal_object;
+            /* VkDescriptorSetAllocateInfo::pSetLayouts */
+            internal_VkDescriptorSetAllocateInfo_pSetLayouts.push_back(
+                std::vector<VkDescriptorSetLayout>());
+            internal_VkDescriptorSetAllocateInfo_pSetLayouts[i].reserve(
+                internal_pAllocateInfo[i].descriptorSetCount);
+            memset(&internal_VkDescriptorSetAllocateInfo_pSetLayouts[i][0], 0,
+                   sizeof(VkDescriptorSetLayout) * internal_pAllocateInfo[i].descriptorSetCount);
+            for (uint32_t j = 0; j < internal_pAllocateInfo[i].descriptorSetCount; ++j) {
+                VK_FROM_HANDLE(gfxstream_vk_descriptor_set_layout, gfxstream_pSetLayouts,
+                               internal_pAllocateInfo[i].pSetLayouts[j]);
+                internal_VkDescriptorSetAllocateInfo_pSetLayouts[i][j] =
+                    gfxstream_pSetLayouts->internal_object;
+            }
+            internal_pAllocateInfo[i].pSetLayouts =
+                internal_VkDescriptorSetAllocateInfo_pSetLayouts[i].data();
+        }
+        auto resources = gfxstream::vk::ResourceTracker::get();
+        vkAllocateDescriptorSets_VkResult_return = resources->on_vkAllocateDescriptorSets(
+            vkEnc, VK_SUCCESS, gfxstream_device->internal_object, internal_pAllocateInfo.data(),
+            pDescriptorSets);
+    }
     return vkAllocateDescriptorSets_VkResult_return;
 }
-static VkResult entry_vkFreeDescriptorSets(VkDevice device, VkDescriptorPool descriptorPool,
-                                           uint32_t descriptorSetCount,
-                                           const VkDescriptorSet* pDescriptorSets) {
+VkResult gfxstream_vk_FreeDescriptorSets(VkDevice device, VkDescriptorPool descriptorPool,
+                                         uint32_t descriptorSetCount,
+                                         const VkDescriptorSet* pDescriptorSets) {
     AEMU_SCOPED_TRACE("vkFreeDescriptorSets");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
     VkResult vkFreeDescriptorSets_VkResult_return = (VkResult)0;
-    auto resources = ResourceTracker::get();
-    vkFreeDescriptorSets_VkResult_return = resources->on_vkFreeDescriptorSets(
-        vkEnc, VK_SUCCESS, device, descriptorPool, descriptorSetCount, pDescriptorSets);
+    if (VK_NULL_HANDLE == pDescriptorSets) {
+        return vkFreeDescriptorSets_VkResult_return;
+    }
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    VK_FROM_HANDLE(gfxstream_vk_descriptor_pool, gfxstream_descriptorPool, descriptorPool);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        auto resources = gfxstream::vk::ResourceTracker::get();
+        vkFreeDescriptorSets_VkResult_return = resources->on_vkFreeDescriptorSets(
+            vkEnc, VK_SUCCESS, gfxstream_device->internal_object,
+            gfxstream_descriptorPool->internal_object, descriptorSetCount, pDescriptorSets);
+    }
     return vkFreeDescriptorSets_VkResult_return;
 }
-static void entry_vkUpdateDescriptorSets(VkDevice device, uint32_t descriptorWriteCount,
-                                         const VkWriteDescriptorSet* pDescriptorWrites,
-                                         uint32_t descriptorCopyCount,
-                                         const VkCopyDescriptorSet* pDescriptorCopies) {
+void gfxstream_vk_UpdateDescriptorSets(VkDevice device, uint32_t descriptorWriteCount,
+                                       const VkWriteDescriptorSet* pDescriptorWrites,
+                                       uint32_t descriptorCopyCount,
+                                       const VkCopyDescriptorSet* pDescriptorCopies) {
     AEMU_SCOPED_TRACE("vkUpdateDescriptorSets");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    auto resources = ResourceTracker::get();
-    resources->on_vkUpdateDescriptorSets(vkEnc, device, descriptorWriteCount, pDescriptorWrites,
-                                         descriptorCopyCount, pDescriptorCopies);
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        std::vector<VkWriteDescriptorSet> internal_pDescriptorWrites(descriptorWriteCount);
+        std::vector<std::vector<VkDescriptorImageInfo>> internal_VkWriteDescriptorSet_pImageInfo;
+        std::vector<std::vector<VkDescriptorBufferInfo>> internal_VkWriteDescriptorSet_pBufferInfo;
+        std::vector<std::vector<VkBufferView>> internal_VkWriteDescriptorSet_pTexelBufferView;
+        for (uint32_t i = 0; i < descriptorWriteCount; ++i) {
+            internal_pDescriptorWrites[i] = pDescriptorWrites[i];
+            /* VkWriteDescriptorSet::pImageInfo */
+            internal_VkWriteDescriptorSet_pImageInfo.push_back(
+                std::vector<VkDescriptorImageInfo>());
+            internal_VkWriteDescriptorSet_pImageInfo[i].reserve(
+                internal_pDescriptorWrites[i].descriptorCount);
+            memset(&internal_VkWriteDescriptorSet_pImageInfo[i][0], 0,
+                   sizeof(VkDescriptorImageInfo) * internal_pDescriptorWrites[i].descriptorCount);
+            for (uint32_t j = 0; j < internal_pDescriptorWrites[i].descriptorCount; ++j) {
+                if (internal_pDescriptorWrites[i].pImageInfo) {
+                    internal_VkWriteDescriptorSet_pImageInfo[i][j] =
+                        internal_pDescriptorWrites[i].pImageInfo[j];
+                    /* VkDescriptorImageInfo::imageView */
+                    if (internal_VkWriteDescriptorSet_pImageInfo[i][j].imageView) {
+                        VK_FROM_HANDLE(gfxstream_vk_image_view, gfxstream_imageView,
+                                       internal_VkWriteDescriptorSet_pImageInfo[i][j].imageView);
+                        internal_VkWriteDescriptorSet_pImageInfo[i][j].imageView =
+                            gfxstream_imageView->internal_object;
+                    }
+                }
+            }
+            internal_pDescriptorWrites[i].pImageInfo =
+                internal_VkWriteDescriptorSet_pImageInfo[i].data();
+            /* VkWriteDescriptorSet::pBufferInfo */
+            internal_VkWriteDescriptorSet_pBufferInfo.push_back(
+                std::vector<VkDescriptorBufferInfo>());
+            internal_VkWriteDescriptorSet_pBufferInfo[i].reserve(
+                internal_pDescriptorWrites[i].descriptorCount);
+            memset(&internal_VkWriteDescriptorSet_pBufferInfo[i][0], 0,
+                   sizeof(VkDescriptorBufferInfo) * internal_pDescriptorWrites[i].descriptorCount);
+            for (uint32_t j = 0; j < internal_pDescriptorWrites[i].descriptorCount; ++j) {
+                if (internal_pDescriptorWrites[i].pBufferInfo) {
+                    internal_VkWriteDescriptorSet_pBufferInfo[i][j] =
+                        internal_pDescriptorWrites[i].pBufferInfo[j];
+                    /* VkDescriptorBufferInfo::buffer */
+                    if (internal_VkWriteDescriptorSet_pBufferInfo[i][j].buffer) {
+                        VK_FROM_HANDLE(gfxstream_vk_buffer, gfxstream_buffer,
+                                       internal_VkWriteDescriptorSet_pBufferInfo[i][j].buffer);
+                        internal_VkWriteDescriptorSet_pBufferInfo[i][j].buffer =
+                            gfxstream_buffer->internal_object;
+                    }
+                }
+            }
+            internal_pDescriptorWrites[i].pBufferInfo =
+                internal_VkWriteDescriptorSet_pBufferInfo[i].data();
+            /* VkWriteDescriptorSet::pTexelBufferView */
+            internal_VkWriteDescriptorSet_pTexelBufferView.push_back(std::vector<VkBufferView>());
+            internal_VkWriteDescriptorSet_pTexelBufferView[i].reserve(
+                internal_pDescriptorWrites[i].descriptorCount);
+            memset(&internal_VkWriteDescriptorSet_pTexelBufferView[i][0], 0,
+                   sizeof(VkBufferView) * internal_pDescriptorWrites[i].descriptorCount);
+            for (uint32_t j = 0; j < internal_pDescriptorWrites[i].descriptorCount; ++j) {
+                if (internal_pDescriptorWrites[i].pTexelBufferView) {
+                    VK_FROM_HANDLE(gfxstream_vk_buffer_view, gfxstream_pTexelBufferView,
+                                   internal_pDescriptorWrites[i].pTexelBufferView[j]);
+                    internal_VkWriteDescriptorSet_pTexelBufferView[i][j] =
+                        gfxstream_pTexelBufferView->internal_object;
+                }
+            }
+            internal_pDescriptorWrites[i].pTexelBufferView =
+                internal_VkWriteDescriptorSet_pTexelBufferView[i].data();
+        }
+        auto resources = gfxstream::vk::ResourceTracker::get();
+        resources->on_vkUpdateDescriptorSets(
+            vkEnc, gfxstream_device->internal_object, descriptorWriteCount,
+            internal_pDescriptorWrites.data(), descriptorCopyCount, pDescriptorCopies);
+    }
 }
-static VkResult entry_vkCreateFramebuffer(VkDevice device,
-                                          const VkFramebufferCreateInfo* pCreateInfo,
-                                          const VkAllocationCallbacks* pAllocator,
-                                          VkFramebuffer* pFramebuffer) {
+VkResult gfxstream_vk_CreateFramebuffer(VkDevice device, const VkFramebufferCreateInfo* pCreateInfo,
+                                        const VkAllocationCallbacks* pAllocator,
+                                        VkFramebuffer* pFramebuffer) {
     AEMU_SCOPED_TRACE("vkCreateFramebuffer");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
     VkResult vkCreateFramebuffer_VkResult_return = (VkResult)0;
-    vkCreateFramebuffer_VkResult_return = vkEnc->vkCreateFramebuffer(
-        device, pCreateInfo, pAllocator, pFramebuffer, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    struct gfxstream_vk_framebuffer* gfxstream_pFramebuffer =
+        (gfxstream_vk_framebuffer*)vk_object_zalloc(&gfxstream_device->vk, pAllocator,
+                                                    sizeof(gfxstream_vk_framebuffer),
+                                                    VK_OBJECT_TYPE_FRAMEBUFFER);
+    vkCreateFramebuffer_VkResult_return =
+        gfxstream_pFramebuffer ? VK_SUCCESS : VK_ERROR_OUT_OF_HOST_MEMORY;
+    if (VK_SUCCESS == vkCreateFramebuffer_VkResult_return) {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        std::vector<VkFramebufferCreateInfo> internal_pCreateInfo(1);
+        std::vector<std::vector<VkImageView>> internal_VkFramebufferCreateInfo_pAttachments;
+        for (uint32_t i = 0; i < 1; ++i) {
+            internal_pCreateInfo[i] = pCreateInfo[i];
+            /* VkFramebufferCreateInfo::renderPass */
+            VK_FROM_HANDLE(gfxstream_vk_render_pass, gfxstream_renderPass,
+                           internal_pCreateInfo[i].renderPass);
+            internal_pCreateInfo[i].renderPass = gfxstream_renderPass->internal_object;
+            /* VkFramebufferCreateInfo::pAttachments */
+            internal_VkFramebufferCreateInfo_pAttachments.push_back(std::vector<VkImageView>());
+            internal_VkFramebufferCreateInfo_pAttachments[i].reserve(
+                internal_pCreateInfo[i].attachmentCount);
+            memset(&internal_VkFramebufferCreateInfo_pAttachments[i][0], 0,
+                   sizeof(VkImageView) * internal_pCreateInfo[i].attachmentCount);
+            for (uint32_t j = 0; j < internal_pCreateInfo[i].attachmentCount; ++j) {
+                if (internal_pCreateInfo[i].pAttachments) {
+                    VK_FROM_HANDLE(gfxstream_vk_image_view, gfxstream_pAttachments,
+                                   internal_pCreateInfo[i].pAttachments[j]);
+                    internal_VkFramebufferCreateInfo_pAttachments[i][j] =
+                        gfxstream_pAttachments->internal_object;
+                }
+            }
+            internal_pCreateInfo[i].pAttachments =
+                internal_VkFramebufferCreateInfo_pAttachments[i].data();
+        }
+        vkCreateFramebuffer_VkResult_return = vkEnc->vkCreateFramebuffer(
+            gfxstream_device->internal_object, internal_pCreateInfo.data(), pAllocator,
+            &gfxstream_pFramebuffer->internal_object, true /* do lock */);
+    }
+    *pFramebuffer = gfxstream_vk_framebuffer_to_handle(gfxstream_pFramebuffer);
     return vkCreateFramebuffer_VkResult_return;
 }
-static void entry_vkDestroyFramebuffer(VkDevice device, VkFramebuffer framebuffer,
-                                       const VkAllocationCallbacks* pAllocator) {
+void gfxstream_vk_DestroyFramebuffer(VkDevice device, VkFramebuffer framebuffer,
+                                     const VkAllocationCallbacks* pAllocator) {
     AEMU_SCOPED_TRACE("vkDestroyFramebuffer");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkDestroyFramebuffer(device, framebuffer, pAllocator, true /* do lock */);
+    if (VK_NULL_HANDLE == framebuffer) {
+        return;
+    }
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    VK_FROM_HANDLE(gfxstream_vk_framebuffer, gfxstream_framebuffer, framebuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkEnc->vkDestroyFramebuffer(
+            gfxstream_device->internal_object,
+            gfxstream_framebuffer ? gfxstream_framebuffer->internal_object : VK_NULL_HANDLE,
+            pAllocator, true /* do lock */);
+    }
+    vk_object_free(&gfxstream_device->vk, pAllocator, (void*)gfxstream_framebuffer);
 }
-static VkResult entry_vkCreateRenderPass(VkDevice device, const VkRenderPassCreateInfo* pCreateInfo,
-                                         const VkAllocationCallbacks* pAllocator,
-                                         VkRenderPass* pRenderPass) {
+VkResult gfxstream_vk_CreateRenderPass(VkDevice device, const VkRenderPassCreateInfo* pCreateInfo,
+                                       const VkAllocationCallbacks* pAllocator,
+                                       VkRenderPass* pRenderPass) {
     AEMU_SCOPED_TRACE("vkCreateRenderPass");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
     VkResult vkCreateRenderPass_VkResult_return = (VkResult)0;
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    struct gfxstream_vk_render_pass* gfxstream_pRenderPass =
+        (gfxstream_vk_render_pass*)vk_object_zalloc(&gfxstream_device->vk, pAllocator,
+                                                    sizeof(gfxstream_vk_render_pass),
+                                                    VK_OBJECT_TYPE_RENDER_PASS);
     vkCreateRenderPass_VkResult_return =
-        vkEnc->vkCreateRenderPass(device, pCreateInfo, pAllocator, pRenderPass, true /* do lock */);
+        gfxstream_pRenderPass ? VK_SUCCESS : VK_ERROR_OUT_OF_HOST_MEMORY;
+    if (VK_SUCCESS == vkCreateRenderPass_VkResult_return) {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkCreateRenderPass_VkResult_return =
+            vkEnc->vkCreateRenderPass(gfxstream_device->internal_object, pCreateInfo, pAllocator,
+                                      &gfxstream_pRenderPass->internal_object, true /* do lock */);
+    }
+    *pRenderPass = gfxstream_vk_render_pass_to_handle(gfxstream_pRenderPass);
     return vkCreateRenderPass_VkResult_return;
 }
-static void entry_vkDestroyRenderPass(VkDevice device, VkRenderPass renderPass,
-                                      const VkAllocationCallbacks* pAllocator) {
+void gfxstream_vk_DestroyRenderPass(VkDevice device, VkRenderPass renderPass,
+                                    const VkAllocationCallbacks* pAllocator) {
     AEMU_SCOPED_TRACE("vkDestroyRenderPass");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkDestroyRenderPass(device, renderPass, pAllocator, true /* do lock */);
+    if (VK_NULL_HANDLE == renderPass) {
+        return;
+    }
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    VK_FROM_HANDLE(gfxstream_vk_render_pass, gfxstream_renderPass, renderPass);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkEnc->vkDestroyRenderPass(
+            gfxstream_device->internal_object,
+            gfxstream_renderPass ? gfxstream_renderPass->internal_object : VK_NULL_HANDLE,
+            pAllocator, true /* do lock */);
+    }
+    vk_object_free(&gfxstream_device->vk, pAllocator, (void*)gfxstream_renderPass);
 }
-static void entry_vkGetRenderAreaGranularity(VkDevice device, VkRenderPass renderPass,
-                                             VkExtent2D* pGranularity) {
+void gfxstream_vk_GetRenderAreaGranularity(VkDevice device, VkRenderPass renderPass,
+                                           VkExtent2D* pGranularity) {
     AEMU_SCOPED_TRACE("vkGetRenderAreaGranularity");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkGetRenderAreaGranularity(device, renderPass, pGranularity, true /* do lock */);
-}
-static VkResult entry_vkCreateCommandPool(VkDevice device,
-                                          const VkCommandPoolCreateInfo* pCreateInfo,
-                                          const VkAllocationCallbacks* pAllocator,
-                                          VkCommandPool* pCommandPool) {
-    AEMU_SCOPED_TRACE("vkCreateCommandPool");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    VkResult vkCreateCommandPool_VkResult_return = (VkResult)0;
-    vkCreateCommandPool_VkResult_return = vkEnc->vkCreateCommandPool(
-        device, pCreateInfo, pAllocator, pCommandPool, true /* do lock */);
-    return vkCreateCommandPool_VkResult_return;
-}
-static void entry_vkDestroyCommandPool(VkDevice device, VkCommandPool commandPool,
-                                       const VkAllocationCallbacks* pAllocator) {
-    AEMU_SCOPED_TRACE("vkDestroyCommandPool");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkDestroyCommandPool(device, commandPool, pAllocator, true /* do lock */);
-}
-static VkResult entry_vkResetCommandPool(VkDevice device, VkCommandPool commandPool,
-                                         VkCommandPoolResetFlags flags) {
-    AEMU_SCOPED_TRACE("vkResetCommandPool");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    VkResult vkResetCommandPool_VkResult_return = (VkResult)0;
-    vkResetCommandPool_VkResult_return =
-        vkEnc->vkResetCommandPool(device, commandPool, flags, true /* do lock */);
-    if (vkResetCommandPool_VkResult_return == VK_SUCCESS) {
-        ResourceTracker::get()->resetCommandPoolStagingInfo(commandPool);
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    VK_FROM_HANDLE(gfxstream_vk_render_pass, gfxstream_renderPass, renderPass);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkEnc->vkGetRenderAreaGranularity(gfxstream_device->internal_object,
+                                          gfxstream_renderPass->internal_object, pGranularity,
+                                          true /* do lock */);
     }
-    return vkResetCommandPool_VkResult_return;
 }
-static VkResult entry_vkAllocateCommandBuffers(VkDevice device,
-                                               const VkCommandBufferAllocateInfo* pAllocateInfo,
-                                               VkCommandBuffer* pCommandBuffers) {
-    AEMU_SCOPED_TRACE("vkAllocateCommandBuffers");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    VkResult vkAllocateCommandBuffers_VkResult_return = (VkResult)0;
-    auto resources = ResourceTracker::get();
-    vkAllocateCommandBuffers_VkResult_return = resources->on_vkAllocateCommandBuffers(
-        vkEnc, VK_SUCCESS, device, pAllocateInfo, pCommandBuffers);
-    if (vkAllocateCommandBuffers_VkResult_return == VK_SUCCESS) {
-        ResourceTracker::get()->addToCommandPool(
-            pAllocateInfo->commandPool, pAllocateInfo->commandBufferCount, pCommandBuffers);
-    }
-    return vkAllocateCommandBuffers_VkResult_return;
-}
-static void entry_vkFreeCommandBuffers(VkDevice device, VkCommandPool commandPool,
-                                       uint32_t commandBufferCount,
-                                       const VkCommandBuffer* pCommandBuffers) {
-    AEMU_SCOPED_TRACE("vkFreeCommandBuffers");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkFreeCommandBuffers(device, commandPool, commandBufferCount, pCommandBuffers,
-                                true /* do lock */);
-}
-static VkResult entry_vkBeginCommandBuffer(VkCommandBuffer commandBuffer,
-                                           const VkCommandBufferBeginInfo* pBeginInfo) {
+VkResult gfxstream_vk_BeginCommandBuffer(VkCommandBuffer commandBuffer,
+                                         const VkCommandBufferBeginInfo* pBeginInfo) {
     AEMU_SCOPED_TRACE("vkBeginCommandBuffer");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
     VkResult vkBeginCommandBuffer_VkResult_return = (VkResult)0;
-    auto resources = ResourceTracker::get();
-    vkBeginCommandBuffer_VkResult_return =
-        resources->on_vkBeginCommandBuffer(vkEnc, VK_SUCCESS, commandBuffer, pBeginInfo);
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        std::vector<VkCommandBufferBeginInfo> internal_pBeginInfo(1);
+        std::vector<VkCommandBufferInheritanceInfo>
+            internal_VkCommandBufferBeginInfo_pInheritanceInfo;
+        for (uint32_t i = 0; i < 1; ++i) {
+            internal_pBeginInfo[i] = pBeginInfo[i];
+            /* VkCommandBufferBeginInfo::pInheritanceInfo */
+            if (internal_pBeginInfo[i].pInheritanceInfo) {
+                internal_VkCommandBufferBeginInfo_pInheritanceInfo[i] =
+                    internal_pBeginInfo[i].pInheritanceInfo[0];
+                /* VkCommandBufferInheritanceInfo::renderPass */
+                if (internal_VkCommandBufferBeginInfo_pInheritanceInfo[i].renderPass) {
+                    VK_FROM_HANDLE(
+                        gfxstream_vk_render_pass, gfxstream_renderPass,
+                        internal_VkCommandBufferBeginInfo_pInheritanceInfo[i].renderPass);
+                    internal_VkCommandBufferBeginInfo_pInheritanceInfo[i].renderPass =
+                        gfxstream_renderPass->internal_object;
+                }
+                /* VkCommandBufferInheritanceInfo::framebuffer */
+                if (internal_VkCommandBufferBeginInfo_pInheritanceInfo[i].framebuffer) {
+                    VK_FROM_HANDLE(
+                        gfxstream_vk_framebuffer, gfxstream_framebuffer,
+                        internal_VkCommandBufferBeginInfo_pInheritanceInfo[i].framebuffer);
+                    internal_VkCommandBufferBeginInfo_pInheritanceInfo[i].framebuffer =
+                        gfxstream_framebuffer->internal_object;
+                }
+                internal_pBeginInfo[i].pInheritanceInfo =
+                    &internal_VkCommandBufferBeginInfo_pInheritanceInfo[i];
+            }
+        }
+        auto resources = gfxstream::vk::ResourceTracker::get();
+        vkBeginCommandBuffer_VkResult_return = resources->on_vkBeginCommandBuffer(
+            vkEnc, VK_SUCCESS, gfxstream_commandBuffer->internal_object,
+            internal_pBeginInfo.data());
+    }
     return vkBeginCommandBuffer_VkResult_return;
 }
-static VkResult entry_vkEndCommandBuffer(VkCommandBuffer commandBuffer) {
+VkResult gfxstream_vk_EndCommandBuffer(VkCommandBuffer commandBuffer) {
     AEMU_SCOPED_TRACE("vkEndCommandBuffer");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
     VkResult vkEndCommandBuffer_VkResult_return = (VkResult)0;
-    auto resources = ResourceTracker::get();
-    vkEndCommandBuffer_VkResult_return =
-        resources->on_vkEndCommandBuffer(vkEnc, VK_SUCCESS, commandBuffer);
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        auto resources = gfxstream::vk::ResourceTracker::get();
+        vkEndCommandBuffer_VkResult_return = resources->on_vkEndCommandBuffer(
+            vkEnc, VK_SUCCESS, gfxstream_commandBuffer->internal_object);
+    }
     return vkEndCommandBuffer_VkResult_return;
 }
-static VkResult entry_vkResetCommandBuffer(VkCommandBuffer commandBuffer,
-                                           VkCommandBufferResetFlags flags) {
+VkResult gfxstream_vk_ResetCommandBuffer(VkCommandBuffer commandBuffer,
+                                         VkCommandBufferResetFlags flags) {
     AEMU_SCOPED_TRACE("vkResetCommandBuffer");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
     VkResult vkResetCommandBuffer_VkResult_return = (VkResult)0;
-    auto resources = ResourceTracker::get();
-    vkResetCommandBuffer_VkResult_return =
-        resources->on_vkResetCommandBuffer(vkEnc, VK_SUCCESS, commandBuffer, flags);
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        auto resources = gfxstream::vk::ResourceTracker::get();
+        vkResetCommandBuffer_VkResult_return = resources->on_vkResetCommandBuffer(
+            vkEnc, VK_SUCCESS, gfxstream_commandBuffer->internal_object, flags);
+    }
     return vkResetCommandBuffer_VkResult_return;
 }
-static void entry_vkCmdBindPipeline(VkCommandBuffer commandBuffer,
-                                    VkPipelineBindPoint pipelineBindPoint, VkPipeline pipeline) {
+void gfxstream_vk_CmdBindPipeline(VkCommandBuffer commandBuffer,
+                                  VkPipelineBindPoint pipelineBindPoint, VkPipeline pipeline) {
     AEMU_SCOPED_TRACE("vkCmdBindPipeline");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdBindPipeline(commandBuffer, pipelineBindPoint, pipeline, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    VK_FROM_HANDLE(gfxstream_vk_pipeline, gfxstream_pipeline, pipeline);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        vkEnc->vkCmdBindPipeline(gfxstream_commandBuffer->internal_object, pipelineBindPoint,
+                                 gfxstream_pipeline->internal_object, true /* do lock */);
+    }
 }
-static void entry_vkCmdSetViewport(VkCommandBuffer commandBuffer, uint32_t firstViewport,
-                                   uint32_t viewportCount, const VkViewport* pViewports) {
+void gfxstream_vk_CmdSetViewport(VkCommandBuffer commandBuffer, uint32_t firstViewport,
+                                 uint32_t viewportCount, const VkViewport* pViewports) {
     AEMU_SCOPED_TRACE("vkCmdSetViewport");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdSetViewport(commandBuffer, firstViewport, viewportCount, pViewports,
-                            true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        vkEnc->vkCmdSetViewport(gfxstream_commandBuffer->internal_object, firstViewport,
+                                viewportCount, pViewports, true /* do lock */);
+    }
 }
-static void entry_vkCmdSetScissor(VkCommandBuffer commandBuffer, uint32_t firstScissor,
-                                  uint32_t scissorCount, const VkRect2D* pScissors) {
+void gfxstream_vk_CmdSetScissor(VkCommandBuffer commandBuffer, uint32_t firstScissor,
+                                uint32_t scissorCount, const VkRect2D* pScissors) {
     AEMU_SCOPED_TRACE("vkCmdSetScissor");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdSetScissor(commandBuffer, firstScissor, scissorCount, pScissors,
-                           true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        vkEnc->vkCmdSetScissor(gfxstream_commandBuffer->internal_object, firstScissor, scissorCount,
+                               pScissors, true /* do lock */);
+    }
 }
-static void entry_vkCmdSetLineWidth(VkCommandBuffer commandBuffer, float lineWidth) {
+void gfxstream_vk_CmdSetLineWidth(VkCommandBuffer commandBuffer, float lineWidth) {
     AEMU_SCOPED_TRACE("vkCmdSetLineWidth");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdSetLineWidth(commandBuffer, lineWidth, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        vkEnc->vkCmdSetLineWidth(gfxstream_commandBuffer->internal_object, lineWidth,
+                                 true /* do lock */);
+    }
 }
-static void entry_vkCmdSetDepthBias(VkCommandBuffer commandBuffer, float depthBiasConstantFactor,
-                                    float depthBiasClamp, float depthBiasSlopeFactor) {
+void gfxstream_vk_CmdSetDepthBias(VkCommandBuffer commandBuffer, float depthBiasConstantFactor,
+                                  float depthBiasClamp, float depthBiasSlopeFactor) {
     AEMU_SCOPED_TRACE("vkCmdSetDepthBias");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdSetDepthBias(commandBuffer, depthBiasConstantFactor, depthBiasClamp,
-                             depthBiasSlopeFactor, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        vkEnc->vkCmdSetDepthBias(gfxstream_commandBuffer->internal_object, depthBiasConstantFactor,
+                                 depthBiasClamp, depthBiasSlopeFactor, true /* do lock */);
+    }
 }
-static void entry_vkCmdSetBlendConstants(VkCommandBuffer commandBuffer,
-                                         const float blendConstants[4]) {
+void gfxstream_vk_CmdSetBlendConstants(VkCommandBuffer commandBuffer,
+                                       const float blendConstants[4]) {
     AEMU_SCOPED_TRACE("vkCmdSetBlendConstants");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdSetBlendConstants(commandBuffer, blendConstants, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        vkEnc->vkCmdSetBlendConstants(gfxstream_commandBuffer->internal_object, blendConstants,
+                                      true /* do lock */);
+    }
 }
-static void entry_vkCmdSetDepthBounds(VkCommandBuffer commandBuffer, float minDepthBounds,
-                                      float maxDepthBounds) {
+void gfxstream_vk_CmdSetDepthBounds(VkCommandBuffer commandBuffer, float minDepthBounds,
+                                    float maxDepthBounds) {
     AEMU_SCOPED_TRACE("vkCmdSetDepthBounds");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdSetDepthBounds(commandBuffer, minDepthBounds, maxDepthBounds, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        vkEnc->vkCmdSetDepthBounds(gfxstream_commandBuffer->internal_object, minDepthBounds,
+                                   maxDepthBounds, true /* do lock */);
+    }
 }
-static void entry_vkCmdSetStencilCompareMask(VkCommandBuffer commandBuffer,
-                                             VkStencilFaceFlags faceMask, uint32_t compareMask) {
+void gfxstream_vk_CmdSetStencilCompareMask(VkCommandBuffer commandBuffer,
+                                           VkStencilFaceFlags faceMask, uint32_t compareMask) {
     AEMU_SCOPED_TRACE("vkCmdSetStencilCompareMask");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdSetStencilCompareMask(commandBuffer, faceMask, compareMask, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        vkEnc->vkCmdSetStencilCompareMask(gfxstream_commandBuffer->internal_object, faceMask,
+                                          compareMask, true /* do lock */);
+    }
 }
-static void entry_vkCmdSetStencilWriteMask(VkCommandBuffer commandBuffer,
-                                           VkStencilFaceFlags faceMask, uint32_t writeMask) {
+void gfxstream_vk_CmdSetStencilWriteMask(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask,
+                                         uint32_t writeMask) {
     AEMU_SCOPED_TRACE("vkCmdSetStencilWriteMask");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdSetStencilWriteMask(commandBuffer, faceMask, writeMask, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        vkEnc->vkCmdSetStencilWriteMask(gfxstream_commandBuffer->internal_object, faceMask,
+                                        writeMask, true /* do lock */);
+    }
 }
-static void entry_vkCmdSetStencilReference(VkCommandBuffer commandBuffer,
-                                           VkStencilFaceFlags faceMask, uint32_t reference) {
+void gfxstream_vk_CmdSetStencilReference(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask,
+                                         uint32_t reference) {
     AEMU_SCOPED_TRACE("vkCmdSetStencilReference");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdSetStencilReference(commandBuffer, faceMask, reference, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        vkEnc->vkCmdSetStencilReference(gfxstream_commandBuffer->internal_object, faceMask,
+                                        reference, true /* do lock */);
+    }
 }
-static void entry_vkCmdBindDescriptorSets(
+void gfxstream_vk_CmdBindDescriptorSets(
     VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, VkPipelineLayout layout,
     uint32_t firstSet, uint32_t descriptorSetCount, const VkDescriptorSet* pDescriptorSets,
     uint32_t dynamicOffsetCount, const uint32_t* pDynamicOffsets) {
     AEMU_SCOPED_TRACE("vkCmdBindDescriptorSets");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    auto resources = ResourceTracker::get();
-    resources->on_vkCmdBindDescriptorSets(vkEnc, commandBuffer, pipelineBindPoint, layout, firstSet,
-                                          descriptorSetCount, pDescriptorSets, dynamicOffsetCount,
-                                          pDynamicOffsets);
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    VK_FROM_HANDLE(gfxstream_vk_pipeline_layout, gfxstream_layout, layout);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        auto resources = gfxstream::vk::ResourceTracker::get();
+        resources->on_vkCmdBindDescriptorSets(vkEnc, gfxstream_commandBuffer->internal_object,
+                                              pipelineBindPoint, gfxstream_layout->internal_object,
+                                              firstSet, descriptorSetCount, pDescriptorSets,
+                                              dynamicOffsetCount, pDynamicOffsets);
+    }
 }
-static void entry_vkCmdBindIndexBuffer(VkCommandBuffer commandBuffer, VkBuffer buffer,
-                                       VkDeviceSize offset, VkIndexType indexType) {
+void gfxstream_vk_CmdBindIndexBuffer(VkCommandBuffer commandBuffer, VkBuffer buffer,
+                                     VkDeviceSize offset, VkIndexType indexType) {
     AEMU_SCOPED_TRACE("vkCmdBindIndexBuffer");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdBindIndexBuffer(commandBuffer, buffer, offset, indexType, true /* do lock */);
-}
-static void entry_vkCmdBindVertexBuffers(VkCommandBuffer commandBuffer, uint32_t firstBinding,
-                                         uint32_t bindingCount, const VkBuffer* pBuffers,
-                                         const VkDeviceSize* pOffsets) {
-    AEMU_SCOPED_TRACE("vkCmdBindVertexBuffers");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdBindVertexBuffers(commandBuffer, firstBinding, bindingCount, pBuffers, pOffsets,
-                                  true /* do lock */);
-}
-static void entry_vkCmdDraw(VkCommandBuffer commandBuffer, uint32_t vertexCount,
-                            uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance) {
-    AEMU_SCOPED_TRACE("vkCmdDraw");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdDraw(commandBuffer, vertexCount, instanceCount, firstVertex, firstInstance,
-                     true /* do lock */);
-}
-static void entry_vkCmdDrawIndexed(VkCommandBuffer commandBuffer, uint32_t indexCount,
-                                   uint32_t instanceCount, uint32_t firstIndex,
-                                   int32_t vertexOffset, uint32_t firstInstance) {
-    AEMU_SCOPED_TRACE("vkCmdDrawIndexed");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdDrawIndexed(commandBuffer, indexCount, instanceCount, firstIndex, vertexOffset,
-                            firstInstance, true /* do lock */);
-}
-static void entry_vkCmdDrawIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer,
-                                    VkDeviceSize offset, uint32_t drawCount, uint32_t stride) {
-    AEMU_SCOPED_TRACE("vkCmdDrawIndirect");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdDrawIndirect(commandBuffer, buffer, offset, drawCount, stride, true /* do lock */);
-}
-static void entry_vkCmdDrawIndexedIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer,
-                                           VkDeviceSize offset, uint32_t drawCount,
-                                           uint32_t stride) {
-    AEMU_SCOPED_TRACE("vkCmdDrawIndexedIndirect");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdDrawIndexedIndirect(commandBuffer, buffer, offset, drawCount, stride,
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    VK_FROM_HANDLE(gfxstream_vk_buffer, gfxstream_buffer, buffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        vkEnc->vkCmdBindIndexBuffer(gfxstream_commandBuffer->internal_object,
+                                    gfxstream_buffer->internal_object, offset, indexType,
                                     true /* do lock */);
+    }
 }
-static void entry_vkCmdDispatch(VkCommandBuffer commandBuffer, uint32_t groupCountX,
-                                uint32_t groupCountY, uint32_t groupCountZ) {
-    AEMU_SCOPED_TRACE("vkCmdDispatch");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdDispatch(commandBuffer, groupCountX, groupCountY, groupCountZ, true /* do lock */);
+void gfxstream_vk_CmdBindVertexBuffers(VkCommandBuffer commandBuffer, uint32_t firstBinding,
+                                       uint32_t bindingCount, const VkBuffer* pBuffers,
+                                       const VkDeviceSize* pOffsets) {
+    AEMU_SCOPED_TRACE("vkCmdBindVertexBuffers");
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        std::vector<VkBuffer> internal_pBuffers(bindingCount);
+        for (uint32_t i = 0; i < bindingCount; ++i) {
+            if (pBuffers) {
+                VK_FROM_HANDLE(gfxstream_vk_buffer, gfxstream_pBuffers, pBuffers[i]);
+                internal_pBuffers[i] = gfxstream_pBuffers->internal_object;
+            }
+        }
+        vkEnc->vkCmdBindVertexBuffers(gfxstream_commandBuffer->internal_object, firstBinding,
+                                      bindingCount, internal_pBuffers.data(), pOffsets,
+                                      true /* do lock */);
+    }
 }
-static void entry_vkCmdDispatchIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer,
-                                        VkDeviceSize offset) {
-    AEMU_SCOPED_TRACE("vkCmdDispatchIndirect");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdDispatchIndirect(commandBuffer, buffer, offset, true /* do lock */);
+void gfxstream_vk_CmdDraw(VkCommandBuffer commandBuffer, uint32_t vertexCount,
+                          uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance) {
+    AEMU_SCOPED_TRACE("vkCmdDraw");
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        vkEnc->vkCmdDraw(gfxstream_commandBuffer->internal_object, vertexCount, instanceCount,
+                         firstVertex, firstInstance, true /* do lock */);
+    }
 }
-static void entry_vkCmdCopyBuffer(VkCommandBuffer commandBuffer, VkBuffer srcBuffer,
-                                  VkBuffer dstBuffer, uint32_t regionCount,
-                                  const VkBufferCopy* pRegions) {
-    AEMU_SCOPED_TRACE("vkCmdCopyBuffer");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdCopyBuffer(commandBuffer, srcBuffer, dstBuffer, regionCount, pRegions,
-                           true /* do lock */);
+void gfxstream_vk_CmdDrawIndexed(VkCommandBuffer commandBuffer, uint32_t indexCount,
+                                 uint32_t instanceCount, uint32_t firstIndex, int32_t vertexOffset,
+                                 uint32_t firstInstance) {
+    AEMU_SCOPED_TRACE("vkCmdDrawIndexed");
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        vkEnc->vkCmdDrawIndexed(gfxstream_commandBuffer->internal_object, indexCount, instanceCount,
+                                firstIndex, vertexOffset, firstInstance, true /* do lock */);
+    }
 }
-static void entry_vkCmdCopyImage(VkCommandBuffer commandBuffer, VkImage srcImage,
-                                 VkImageLayout srcImageLayout, VkImage dstImage,
-                                 VkImageLayout dstImageLayout, uint32_t regionCount,
-                                 const VkImageCopy* pRegions) {
-    AEMU_SCOPED_TRACE("vkCmdCopyImage");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdCopyImage(commandBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout,
-                          regionCount, pRegions, true /* do lock */);
-}
-static void entry_vkCmdBlitImage(VkCommandBuffer commandBuffer, VkImage srcImage,
-                                 VkImageLayout srcImageLayout, VkImage dstImage,
-                                 VkImageLayout dstImageLayout, uint32_t regionCount,
-                                 const VkImageBlit* pRegions, VkFilter filter) {
-    AEMU_SCOPED_TRACE("vkCmdBlitImage");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdBlitImage(commandBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout,
-                          regionCount, pRegions, filter, true /* do lock */);
-}
-static void entry_vkCmdCopyBufferToImage(VkCommandBuffer commandBuffer, VkBuffer srcBuffer,
-                                         VkImage dstImage, VkImageLayout dstImageLayout,
-                                         uint32_t regionCount, const VkBufferImageCopy* pRegions) {
-    AEMU_SCOPED_TRACE("vkCmdCopyBufferToImage");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdCopyBufferToImage(commandBuffer, srcBuffer, dstImage, dstImageLayout, regionCount,
-                                  pRegions, true /* do lock */);
-}
-static void entry_vkCmdCopyImageToBuffer(VkCommandBuffer commandBuffer, VkImage srcImage,
-                                         VkImageLayout srcImageLayout, VkBuffer dstBuffer,
-                                         uint32_t regionCount, const VkBufferImageCopy* pRegions) {
-    AEMU_SCOPED_TRACE("vkCmdCopyImageToBuffer");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdCopyImageToBuffer(commandBuffer, srcImage, srcImageLayout, dstBuffer, regionCount,
-                                  pRegions, true /* do lock */);
-}
-static void entry_vkCmdUpdateBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer,
-                                    VkDeviceSize dstOffset, VkDeviceSize dataSize,
-                                    const void* pData) {
-    AEMU_SCOPED_TRACE("vkCmdUpdateBuffer");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdUpdateBuffer(commandBuffer, dstBuffer, dstOffset, dataSize, pData,
-                             true /* do lock */);
-}
-static void entry_vkCmdFillBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer,
-                                  VkDeviceSize dstOffset, VkDeviceSize size, uint32_t data) {
-    AEMU_SCOPED_TRACE("vkCmdFillBuffer");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdFillBuffer(commandBuffer, dstBuffer, dstOffset, size, data, true /* do lock */);
-}
-static void entry_vkCmdClearColorImage(VkCommandBuffer commandBuffer, VkImage image,
-                                       VkImageLayout imageLayout, const VkClearColorValue* pColor,
-                                       uint32_t rangeCount,
-                                       const VkImageSubresourceRange* pRanges) {
-    AEMU_SCOPED_TRACE("vkCmdClearColorImage");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdClearColorImage(commandBuffer, image, imageLayout, pColor, rangeCount, pRanges,
-                                true /* do lock */);
-}
-static void entry_vkCmdClearDepthStencilImage(VkCommandBuffer commandBuffer, VkImage image,
-                                              VkImageLayout imageLayout,
-                                              const VkClearDepthStencilValue* pDepthStencil,
-                                              uint32_t rangeCount,
-                                              const VkImageSubresourceRange* pRanges) {
-    AEMU_SCOPED_TRACE("vkCmdClearDepthStencilImage");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdClearDepthStencilImage(commandBuffer, image, imageLayout, pDepthStencil, rangeCount,
-                                       pRanges, true /* do lock */);
-}
-static void entry_vkCmdClearAttachments(VkCommandBuffer commandBuffer, uint32_t attachmentCount,
-                                        const VkClearAttachment* pAttachments, uint32_t rectCount,
-                                        const VkClearRect* pRects) {
-    AEMU_SCOPED_TRACE("vkCmdClearAttachments");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdClearAttachments(commandBuffer, attachmentCount, pAttachments, rectCount, pRects,
+void gfxstream_vk_CmdDrawIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer,
+                                  VkDeviceSize offset, uint32_t drawCount, uint32_t stride) {
+    AEMU_SCOPED_TRACE("vkCmdDrawIndirect");
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    VK_FROM_HANDLE(gfxstream_vk_buffer, gfxstream_buffer, buffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        vkEnc->vkCmdDrawIndirect(gfxstream_commandBuffer->internal_object,
+                                 gfxstream_buffer->internal_object, offset, drawCount, stride,
                                  true /* do lock */);
+    }
 }
-static void entry_vkCmdResolveImage(VkCommandBuffer commandBuffer, VkImage srcImage,
-                                    VkImageLayout srcImageLayout, VkImage dstImage,
-                                    VkImageLayout dstImageLayout, uint32_t regionCount,
-                                    const VkImageResolve* pRegions) {
+void gfxstream_vk_CmdDrawIndexedIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer,
+                                         VkDeviceSize offset, uint32_t drawCount, uint32_t stride) {
+    AEMU_SCOPED_TRACE("vkCmdDrawIndexedIndirect");
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    VK_FROM_HANDLE(gfxstream_vk_buffer, gfxstream_buffer, buffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        vkEnc->vkCmdDrawIndexedIndirect(gfxstream_commandBuffer->internal_object,
+                                        gfxstream_buffer->internal_object, offset, drawCount,
+                                        stride, true /* do lock */);
+    }
+}
+void gfxstream_vk_CmdDispatch(VkCommandBuffer commandBuffer, uint32_t groupCountX,
+                              uint32_t groupCountY, uint32_t groupCountZ) {
+    AEMU_SCOPED_TRACE("vkCmdDispatch");
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        vkEnc->vkCmdDispatch(gfxstream_commandBuffer->internal_object, groupCountX, groupCountY,
+                             groupCountZ, true /* do lock */);
+    }
+}
+void gfxstream_vk_CmdDispatchIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer,
+                                      VkDeviceSize offset) {
+    AEMU_SCOPED_TRACE("vkCmdDispatchIndirect");
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    VK_FROM_HANDLE(gfxstream_vk_buffer, gfxstream_buffer, buffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        vkEnc->vkCmdDispatchIndirect(gfxstream_commandBuffer->internal_object,
+                                     gfxstream_buffer->internal_object, offset, true /* do lock */);
+    }
+}
+void gfxstream_vk_CmdCopyBuffer(VkCommandBuffer commandBuffer, VkBuffer srcBuffer,
+                                VkBuffer dstBuffer, uint32_t regionCount,
+                                const VkBufferCopy* pRegions) {
+    AEMU_SCOPED_TRACE("vkCmdCopyBuffer");
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    VK_FROM_HANDLE(gfxstream_vk_buffer, gfxstream_srcBuffer, srcBuffer);
+    VK_FROM_HANDLE(gfxstream_vk_buffer, gfxstream_dstBuffer, dstBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        vkEnc->vkCmdCopyBuffer(
+            gfxstream_commandBuffer->internal_object, gfxstream_srcBuffer->internal_object,
+            gfxstream_dstBuffer->internal_object, regionCount, pRegions, true /* do lock */);
+    }
+}
+void gfxstream_vk_CmdCopyImage(VkCommandBuffer commandBuffer, VkImage srcImage,
+                               VkImageLayout srcImageLayout, VkImage dstImage,
+                               VkImageLayout dstImageLayout, uint32_t regionCount,
+                               const VkImageCopy* pRegions) {
+    AEMU_SCOPED_TRACE("vkCmdCopyImage");
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    VK_FROM_HANDLE(gfxstream_vk_image, gfxstream_srcImage, srcImage);
+    VK_FROM_HANDLE(gfxstream_vk_image, gfxstream_dstImage, dstImage);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        vkEnc->vkCmdCopyImage(gfxstream_commandBuffer->internal_object,
+                              gfxstream_srcImage->internal_object, srcImageLayout,
+                              gfxstream_dstImage->internal_object, dstImageLayout, regionCount,
+                              pRegions, true /* do lock */);
+    }
+}
+void gfxstream_vk_CmdBlitImage(VkCommandBuffer commandBuffer, VkImage srcImage,
+                               VkImageLayout srcImageLayout, VkImage dstImage,
+                               VkImageLayout dstImageLayout, uint32_t regionCount,
+                               const VkImageBlit* pRegions, VkFilter filter) {
+    AEMU_SCOPED_TRACE("vkCmdBlitImage");
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    VK_FROM_HANDLE(gfxstream_vk_image, gfxstream_srcImage, srcImage);
+    VK_FROM_HANDLE(gfxstream_vk_image, gfxstream_dstImage, dstImage);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        vkEnc->vkCmdBlitImage(gfxstream_commandBuffer->internal_object,
+                              gfxstream_srcImage->internal_object, srcImageLayout,
+                              gfxstream_dstImage->internal_object, dstImageLayout, regionCount,
+                              pRegions, filter, true /* do lock */);
+    }
+}
+void gfxstream_vk_CmdCopyBufferToImage(VkCommandBuffer commandBuffer, VkBuffer srcBuffer,
+                                       VkImage dstImage, VkImageLayout dstImageLayout,
+                                       uint32_t regionCount, const VkBufferImageCopy* pRegions) {
+    AEMU_SCOPED_TRACE("vkCmdCopyBufferToImage");
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    VK_FROM_HANDLE(gfxstream_vk_buffer, gfxstream_srcBuffer, srcBuffer);
+    VK_FROM_HANDLE(gfxstream_vk_image, gfxstream_dstImage, dstImage);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        vkEnc->vkCmdCopyBufferToImage(gfxstream_commandBuffer->internal_object,
+                                      gfxstream_srcBuffer->internal_object,
+                                      gfxstream_dstImage->internal_object, dstImageLayout,
+                                      regionCount, pRegions, true /* do lock */);
+    }
+}
+void gfxstream_vk_CmdCopyImageToBuffer(VkCommandBuffer commandBuffer, VkImage srcImage,
+                                       VkImageLayout srcImageLayout, VkBuffer dstBuffer,
+                                       uint32_t regionCount, const VkBufferImageCopy* pRegions) {
+    AEMU_SCOPED_TRACE("vkCmdCopyImageToBuffer");
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    VK_FROM_HANDLE(gfxstream_vk_image, gfxstream_srcImage, srcImage);
+    VK_FROM_HANDLE(gfxstream_vk_buffer, gfxstream_dstBuffer, dstBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        vkEnc->vkCmdCopyImageToBuffer(gfxstream_commandBuffer->internal_object,
+                                      gfxstream_srcImage->internal_object, srcImageLayout,
+                                      gfxstream_dstBuffer->internal_object, regionCount, pRegions,
+                                      true /* do lock */);
+    }
+}
+void gfxstream_vk_CmdUpdateBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer,
+                                  VkDeviceSize dstOffset, VkDeviceSize dataSize,
+                                  const void* pData) {
+    AEMU_SCOPED_TRACE("vkCmdUpdateBuffer");
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    VK_FROM_HANDLE(gfxstream_vk_buffer, gfxstream_dstBuffer, dstBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        vkEnc->vkCmdUpdateBuffer(gfxstream_commandBuffer->internal_object,
+                                 gfxstream_dstBuffer->internal_object, dstOffset, dataSize, pData,
+                                 true /* do lock */);
+    }
+}
+void gfxstream_vk_CmdFillBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer,
+                                VkDeviceSize dstOffset, VkDeviceSize size, uint32_t data) {
+    AEMU_SCOPED_TRACE("vkCmdFillBuffer");
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    VK_FROM_HANDLE(gfxstream_vk_buffer, gfxstream_dstBuffer, dstBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        vkEnc->vkCmdFillBuffer(gfxstream_commandBuffer->internal_object,
+                               gfxstream_dstBuffer->internal_object, dstOffset, size, data,
+                               true /* do lock */);
+    }
+}
+void gfxstream_vk_CmdClearColorImage(VkCommandBuffer commandBuffer, VkImage image,
+                                     VkImageLayout imageLayout, const VkClearColorValue* pColor,
+                                     uint32_t rangeCount, const VkImageSubresourceRange* pRanges) {
+    AEMU_SCOPED_TRACE("vkCmdClearColorImage");
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    VK_FROM_HANDLE(gfxstream_vk_image, gfxstream_image, image);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        vkEnc->vkCmdClearColorImage(gfxstream_commandBuffer->internal_object,
+                                    gfxstream_image->internal_object, imageLayout, pColor,
+                                    rangeCount, pRanges, true /* do lock */);
+    }
+}
+void gfxstream_vk_CmdClearDepthStencilImage(VkCommandBuffer commandBuffer, VkImage image,
+                                            VkImageLayout imageLayout,
+                                            const VkClearDepthStencilValue* pDepthStencil,
+                                            uint32_t rangeCount,
+                                            const VkImageSubresourceRange* pRanges) {
+    AEMU_SCOPED_TRACE("vkCmdClearDepthStencilImage");
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    VK_FROM_HANDLE(gfxstream_vk_image, gfxstream_image, image);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        vkEnc->vkCmdClearDepthStencilImage(gfxstream_commandBuffer->internal_object,
+                                           gfxstream_image->internal_object, imageLayout,
+                                           pDepthStencil, rangeCount, pRanges, true /* do lock */);
+    }
+}
+void gfxstream_vk_CmdClearAttachments(VkCommandBuffer commandBuffer, uint32_t attachmentCount,
+                                      const VkClearAttachment* pAttachments, uint32_t rectCount,
+                                      const VkClearRect* pRects) {
+    AEMU_SCOPED_TRACE("vkCmdClearAttachments");
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        vkEnc->vkCmdClearAttachments(gfxstream_commandBuffer->internal_object, attachmentCount,
+                                     pAttachments, rectCount, pRects, true /* do lock */);
+    }
+}
+void gfxstream_vk_CmdResolveImage(VkCommandBuffer commandBuffer, VkImage srcImage,
+                                  VkImageLayout srcImageLayout, VkImage dstImage,
+                                  VkImageLayout dstImageLayout, uint32_t regionCount,
+                                  const VkImageResolve* pRegions) {
     AEMU_SCOPED_TRACE("vkCmdResolveImage");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdResolveImage(commandBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout,
-                             regionCount, pRegions, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    VK_FROM_HANDLE(gfxstream_vk_image, gfxstream_srcImage, srcImage);
+    VK_FROM_HANDLE(gfxstream_vk_image, gfxstream_dstImage, dstImage);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        vkEnc->vkCmdResolveImage(gfxstream_commandBuffer->internal_object,
+                                 gfxstream_srcImage->internal_object, srcImageLayout,
+                                 gfxstream_dstImage->internal_object, dstImageLayout, regionCount,
+                                 pRegions, true /* do lock */);
+    }
 }
-static void entry_vkCmdSetEvent(VkCommandBuffer commandBuffer, VkEvent event,
-                                VkPipelineStageFlags stageMask) {
+void gfxstream_vk_CmdSetEvent(VkCommandBuffer commandBuffer, VkEvent event,
+                              VkPipelineStageFlags stageMask) {
     AEMU_SCOPED_TRACE("vkCmdSetEvent");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdSetEvent(commandBuffer, event, stageMask, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    VK_FROM_HANDLE(gfxstream_vk_event, gfxstream_event, event);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        vkEnc->vkCmdSetEvent(gfxstream_commandBuffer->internal_object,
+                             gfxstream_event->internal_object, stageMask, true /* do lock */);
+    }
 }
-static void entry_vkCmdResetEvent(VkCommandBuffer commandBuffer, VkEvent event,
-                                  VkPipelineStageFlags stageMask) {
+void gfxstream_vk_CmdResetEvent(VkCommandBuffer commandBuffer, VkEvent event,
+                                VkPipelineStageFlags stageMask) {
     AEMU_SCOPED_TRACE("vkCmdResetEvent");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdResetEvent(commandBuffer, event, stageMask, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    VK_FROM_HANDLE(gfxstream_vk_event, gfxstream_event, event);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        vkEnc->vkCmdResetEvent(gfxstream_commandBuffer->internal_object,
+                               gfxstream_event->internal_object, stageMask, true /* do lock */);
+    }
 }
-static void entry_vkCmdWaitEvents(VkCommandBuffer commandBuffer, uint32_t eventCount,
-                                  const VkEvent* pEvents, VkPipelineStageFlags srcStageMask,
-                                  VkPipelineStageFlags dstStageMask, uint32_t memoryBarrierCount,
-                                  const VkMemoryBarrier* pMemoryBarriers,
-                                  uint32_t bufferMemoryBarrierCount,
-                                  const VkBufferMemoryBarrier* pBufferMemoryBarriers,
-                                  uint32_t imageMemoryBarrierCount,
-                                  const VkImageMemoryBarrier* pImageMemoryBarriers) {
+void gfxstream_vk_CmdWaitEvents(VkCommandBuffer commandBuffer, uint32_t eventCount,
+                                const VkEvent* pEvents, VkPipelineStageFlags srcStageMask,
+                                VkPipelineStageFlags dstStageMask, uint32_t memoryBarrierCount,
+                                const VkMemoryBarrier* pMemoryBarriers,
+                                uint32_t bufferMemoryBarrierCount,
+                                const VkBufferMemoryBarrier* pBufferMemoryBarriers,
+                                uint32_t imageMemoryBarrierCount,
+                                const VkImageMemoryBarrier* pImageMemoryBarriers) {
     AEMU_SCOPED_TRACE("vkCmdWaitEvents");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdWaitEvents(commandBuffer, eventCount, pEvents, srcStageMask, dstStageMask,
-                           memoryBarrierCount, pMemoryBarriers, bufferMemoryBarrierCount,
-                           pBufferMemoryBarriers, imageMemoryBarrierCount, pImageMemoryBarriers,
-                           true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        std::vector<VkEvent> internal_pEvents(eventCount);
+        for (uint32_t i = 0; i < eventCount; ++i) {
+            VK_FROM_HANDLE(gfxstream_vk_event, gfxstream_pEvents, pEvents[i]);
+            internal_pEvents[i] = gfxstream_pEvents->internal_object;
+        }
+        std::vector<VkBufferMemoryBarrier> internal_pBufferMemoryBarriers(bufferMemoryBarrierCount);
+        for (uint32_t i = 0; i < bufferMemoryBarrierCount; ++i) {
+            internal_pBufferMemoryBarriers[i] = pBufferMemoryBarriers[i];
+            /* VkBufferMemoryBarrier::buffer */
+            VK_FROM_HANDLE(gfxstream_vk_buffer, gfxstream_buffer,
+                           internal_pBufferMemoryBarriers[i].buffer);
+            internal_pBufferMemoryBarriers[i].buffer = gfxstream_buffer->internal_object;
+        }
+        std::vector<VkImageMemoryBarrier> internal_pImageMemoryBarriers(imageMemoryBarrierCount);
+        for (uint32_t i = 0; i < imageMemoryBarrierCount; ++i) {
+            internal_pImageMemoryBarriers[i] = pImageMemoryBarriers[i];
+            /* VkImageMemoryBarrier::image */
+            VK_FROM_HANDLE(gfxstream_vk_image, gfxstream_image,
+                           internal_pImageMemoryBarriers[i].image);
+            internal_pImageMemoryBarriers[i].image = gfxstream_image->internal_object;
+        }
+        vkEnc->vkCmdWaitEvents(gfxstream_commandBuffer->internal_object, eventCount,
+                               internal_pEvents.data(), srcStageMask, dstStageMask,
+                               memoryBarrierCount, pMemoryBarriers, bufferMemoryBarrierCount,
+                               internal_pBufferMemoryBarriers.data(), imageMemoryBarrierCount,
+                               internal_pImageMemoryBarriers.data(), true /* do lock */);
+    }
 }
-static void entry_vkCmdPipelineBarrier(
+void gfxstream_vk_CmdPipelineBarrier(
     VkCommandBuffer commandBuffer, VkPipelineStageFlags srcStageMask,
     VkPipelineStageFlags dstStageMask, VkDependencyFlags dependencyFlags,
     uint32_t memoryBarrierCount, const VkMemoryBarrier* pMemoryBarriers,
     uint32_t bufferMemoryBarrierCount, const VkBufferMemoryBarrier* pBufferMemoryBarriers,
     uint32_t imageMemoryBarrierCount, const VkImageMemoryBarrier* pImageMemoryBarriers) {
     AEMU_SCOPED_TRACE("vkCmdPipelineBarrier");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    auto resources = ResourceTracker::get();
-    resources->on_vkCmdPipelineBarrier(vkEnc, commandBuffer, srcStageMask, dstStageMask,
-                                       dependencyFlags, memoryBarrierCount, pMemoryBarriers,
-                                       bufferMemoryBarrierCount, pBufferMemoryBarriers,
-                                       imageMemoryBarrierCount, pImageMemoryBarriers);
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        std::vector<VkBufferMemoryBarrier> internal_pBufferMemoryBarriers(bufferMemoryBarrierCount);
+        for (uint32_t i = 0; i < bufferMemoryBarrierCount; ++i) {
+            internal_pBufferMemoryBarriers[i] = pBufferMemoryBarriers[i];
+            /* VkBufferMemoryBarrier::buffer */
+            VK_FROM_HANDLE(gfxstream_vk_buffer, gfxstream_buffer,
+                           internal_pBufferMemoryBarriers[i].buffer);
+            internal_pBufferMemoryBarriers[i].buffer = gfxstream_buffer->internal_object;
+        }
+        std::vector<VkImageMemoryBarrier> internal_pImageMemoryBarriers(imageMemoryBarrierCount);
+        for (uint32_t i = 0; i < imageMemoryBarrierCount; ++i) {
+            internal_pImageMemoryBarriers[i] = pImageMemoryBarriers[i];
+            /* VkImageMemoryBarrier::image */
+            VK_FROM_HANDLE(gfxstream_vk_image, gfxstream_image,
+                           internal_pImageMemoryBarriers[i].image);
+            internal_pImageMemoryBarriers[i].image = gfxstream_image->internal_object;
+        }
+        auto resources = gfxstream::vk::ResourceTracker::get();
+        resources->on_vkCmdPipelineBarrier(
+            vkEnc, gfxstream_commandBuffer->internal_object, srcStageMask, dstStageMask,
+            dependencyFlags, memoryBarrierCount, pMemoryBarriers, bufferMemoryBarrierCount,
+            internal_pBufferMemoryBarriers.data(), imageMemoryBarrierCount,
+            internal_pImageMemoryBarriers.data());
+    }
 }
-static void entry_vkCmdBeginQuery(VkCommandBuffer commandBuffer, VkQueryPool queryPool,
-                                  uint32_t query, VkQueryControlFlags flags) {
+void gfxstream_vk_CmdBeginQuery(VkCommandBuffer commandBuffer, VkQueryPool queryPool,
+                                uint32_t query, VkQueryControlFlags flags) {
     AEMU_SCOPED_TRACE("vkCmdBeginQuery");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdBeginQuery(commandBuffer, queryPool, query, flags, true /* do lock */);
-}
-static void entry_vkCmdEndQuery(VkCommandBuffer commandBuffer, VkQueryPool queryPool,
-                                uint32_t query) {
-    AEMU_SCOPED_TRACE("vkCmdEndQuery");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdEndQuery(commandBuffer, queryPool, query, true /* do lock */);
-}
-static void entry_vkCmdResetQueryPool(VkCommandBuffer commandBuffer, VkQueryPool queryPool,
-                                      uint32_t firstQuery, uint32_t queryCount) {
-    AEMU_SCOPED_TRACE("vkCmdResetQueryPool");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdResetQueryPool(commandBuffer, queryPool, firstQuery, queryCount,
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    VK_FROM_HANDLE(gfxstream_vk_query_pool, gfxstream_queryPool, queryPool);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        vkEnc->vkCmdBeginQuery(gfxstream_commandBuffer->internal_object,
+                               gfxstream_queryPool->internal_object, query, flags,
                                true /* do lock */);
+    }
 }
-static void entry_vkCmdWriteTimestamp(VkCommandBuffer commandBuffer,
-                                      VkPipelineStageFlagBits pipelineStage, VkQueryPool queryPool,
-                                      uint32_t query) {
+void gfxstream_vk_CmdEndQuery(VkCommandBuffer commandBuffer, VkQueryPool queryPool,
+                              uint32_t query) {
+    AEMU_SCOPED_TRACE("vkCmdEndQuery");
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    VK_FROM_HANDLE(gfxstream_vk_query_pool, gfxstream_queryPool, queryPool);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        vkEnc->vkCmdEndQuery(gfxstream_commandBuffer->internal_object,
+                             gfxstream_queryPool->internal_object, query, true /* do lock */);
+    }
+}
+void gfxstream_vk_CmdResetQueryPool(VkCommandBuffer commandBuffer, VkQueryPool queryPool,
+                                    uint32_t firstQuery, uint32_t queryCount) {
+    AEMU_SCOPED_TRACE("vkCmdResetQueryPool");
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    VK_FROM_HANDLE(gfxstream_vk_query_pool, gfxstream_queryPool, queryPool);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        vkEnc->vkCmdResetQueryPool(gfxstream_commandBuffer->internal_object,
+                                   gfxstream_queryPool->internal_object, firstQuery, queryCount,
+                                   true /* do lock */);
+    }
+}
+void gfxstream_vk_CmdWriteTimestamp(VkCommandBuffer commandBuffer,
+                                    VkPipelineStageFlagBits pipelineStage, VkQueryPool queryPool,
+                                    uint32_t query) {
     AEMU_SCOPED_TRACE("vkCmdWriteTimestamp");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdWriteTimestamp(commandBuffer, pipelineStage, queryPool, query, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    VK_FROM_HANDLE(gfxstream_vk_query_pool, gfxstream_queryPool, queryPool);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        vkEnc->vkCmdWriteTimestamp(gfxstream_commandBuffer->internal_object, pipelineStage,
+                                   gfxstream_queryPool->internal_object, query, true /* do lock */);
+    }
 }
-static void entry_vkCmdCopyQueryPoolResults(VkCommandBuffer commandBuffer, VkQueryPool queryPool,
-                                            uint32_t firstQuery, uint32_t queryCount,
-                                            VkBuffer dstBuffer, VkDeviceSize dstOffset,
-                                            VkDeviceSize stride, VkQueryResultFlags flags) {
+void gfxstream_vk_CmdCopyQueryPoolResults(VkCommandBuffer commandBuffer, VkQueryPool queryPool,
+                                          uint32_t firstQuery, uint32_t queryCount,
+                                          VkBuffer dstBuffer, VkDeviceSize dstOffset,
+                                          VkDeviceSize stride, VkQueryResultFlags flags) {
     AEMU_SCOPED_TRACE("vkCmdCopyQueryPoolResults");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdCopyQueryPoolResults(commandBuffer, queryPool, firstQuery, queryCount, dstBuffer,
-                                     dstOffset, stride, flags, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    VK_FROM_HANDLE(gfxstream_vk_query_pool, gfxstream_queryPool, queryPool);
+    VK_FROM_HANDLE(gfxstream_vk_buffer, gfxstream_dstBuffer, dstBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        vkEnc->vkCmdCopyQueryPoolResults(gfxstream_commandBuffer->internal_object,
+                                         gfxstream_queryPool->internal_object, firstQuery,
+                                         queryCount, gfxstream_dstBuffer->internal_object,
+                                         dstOffset, stride, flags, true /* do lock */);
+    }
 }
-static void entry_vkCmdPushConstants(VkCommandBuffer commandBuffer, VkPipelineLayout layout,
-                                     VkShaderStageFlags stageFlags, uint32_t offset, uint32_t size,
-                                     const void* pValues) {
+void gfxstream_vk_CmdPushConstants(VkCommandBuffer commandBuffer, VkPipelineLayout layout,
+                                   VkShaderStageFlags stageFlags, uint32_t offset, uint32_t size,
+                                   const void* pValues) {
     AEMU_SCOPED_TRACE("vkCmdPushConstants");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdPushConstants(commandBuffer, layout, stageFlags, offset, size, pValues,
-                              true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    VK_FROM_HANDLE(gfxstream_vk_pipeline_layout, gfxstream_layout, layout);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        vkEnc->vkCmdPushConstants(gfxstream_commandBuffer->internal_object,
+                                  gfxstream_layout->internal_object, stageFlags, offset, size,
+                                  pValues, true /* do lock */);
+    }
 }
-static void entry_vkCmdBeginRenderPass(VkCommandBuffer commandBuffer,
-                                       const VkRenderPassBeginInfo* pRenderPassBegin,
-                                       VkSubpassContents contents) {
-    AEMU_SCOPED_TRACE("vkCmdBeginRenderPass");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdBeginRenderPass(commandBuffer, pRenderPassBegin, contents, true /* do lock */);
-}
-static void entry_vkCmdNextSubpass(VkCommandBuffer commandBuffer, VkSubpassContents contents) {
+void gfxstream_vk_CmdNextSubpass(VkCommandBuffer commandBuffer, VkSubpassContents contents) {
     AEMU_SCOPED_TRACE("vkCmdNextSubpass");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdNextSubpass(commandBuffer, contents, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        vkEnc->vkCmdNextSubpass(gfxstream_commandBuffer->internal_object, contents,
+                                true /* do lock */);
+    }
 }
-static void entry_vkCmdEndRenderPass(VkCommandBuffer commandBuffer) {
+void gfxstream_vk_CmdEndRenderPass(VkCommandBuffer commandBuffer) {
     AEMU_SCOPED_TRACE("vkCmdEndRenderPass");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdEndRenderPass(commandBuffer, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        vkEnc->vkCmdEndRenderPass(gfxstream_commandBuffer->internal_object, true /* do lock */);
+    }
 }
-static void entry_vkCmdExecuteCommands(VkCommandBuffer commandBuffer, uint32_t commandBufferCount,
-                                       const VkCommandBuffer* pCommandBuffers) {
+void gfxstream_vk_CmdExecuteCommands(VkCommandBuffer commandBuffer, uint32_t commandBufferCount,
+                                     const VkCommandBuffer* pCommandBuffers) {
     AEMU_SCOPED_TRACE("vkCmdExecuteCommands");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    auto resources = ResourceTracker::get();
-    resources->on_vkCmdExecuteCommands(vkEnc, commandBuffer, commandBufferCount, pCommandBuffers);
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        std::vector<VkCommandBuffer> internal_pCommandBuffers(commandBufferCount);
+        for (uint32_t i = 0; i < commandBufferCount; ++i) {
+            VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_pCommandBuffers,
+                           pCommandBuffers[i]);
+            internal_pCommandBuffers[i] = gfxstream_pCommandBuffers->internal_object;
+        }
+        auto resources = gfxstream::vk::ResourceTracker::get();
+        resources->on_vkCmdExecuteCommands(vkEnc, gfxstream_commandBuffer->internal_object,
+                                           commandBufferCount, internal_pCommandBuffers.data());
+    }
 }
 #endif
 #ifdef VK_VERSION_1_1
-static VkResult entry_vkEnumerateInstanceVersion(uint32_t* pApiVersion) {
-    AEMU_SCOPED_TRACE("vkEnumerateInstanceVersion");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    VkResult vkEnumerateInstanceVersion_VkResult_return = (VkResult)0;
-    vkEnumerateInstanceVersion_VkResult_return =
-        vkEnc->vkEnumerateInstanceVersion(pApiVersion, true /* do lock */);
-    return vkEnumerateInstanceVersion_VkResult_return;
-}
-static VkResult entry_vkBindBufferMemory2(VkDevice device, uint32_t bindInfoCount,
-                                          const VkBindBufferMemoryInfo* pBindInfos) {
+VkResult gfxstream_vk_BindBufferMemory2(VkDevice device, uint32_t bindInfoCount,
+                                        const VkBindBufferMemoryInfo* pBindInfos) {
     AEMU_SCOPED_TRACE("vkBindBufferMemory2");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
     VkResult vkBindBufferMemory2_VkResult_return = (VkResult)0;
-    auto resources = ResourceTracker::get();
-    vkBindBufferMemory2_VkResult_return =
-        resources->on_vkBindBufferMemory2(vkEnc, VK_SUCCESS, device, bindInfoCount, pBindInfos);
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        std::vector<VkBindBufferMemoryInfo> internal_pBindInfos(bindInfoCount);
+        for (uint32_t i = 0; i < bindInfoCount; ++i) {
+            internal_pBindInfos[i] = pBindInfos[i];
+            /* VkBindBufferMemoryInfo::buffer */
+            VK_FROM_HANDLE(gfxstream_vk_buffer, gfxstream_buffer, internal_pBindInfos[i].buffer);
+            internal_pBindInfos[i].buffer = gfxstream_buffer->internal_object;
+            /* VkBindBufferMemoryInfo::memory */
+            VK_FROM_HANDLE(gfxstream_vk_device_memory, gfxstream_memory,
+                           internal_pBindInfos[i].memory);
+            internal_pBindInfos[i].memory = gfxstream_memory->internal_object;
+        }
+        auto resources = gfxstream::vk::ResourceTracker::get();
+        vkBindBufferMemory2_VkResult_return =
+            resources->on_vkBindBufferMemory2(vkEnc, VK_SUCCESS, gfxstream_device->internal_object,
+                                              bindInfoCount, internal_pBindInfos.data());
+    }
     return vkBindBufferMemory2_VkResult_return;
 }
-static VkResult dynCheck_entry_vkBindBufferMemory2(VkDevice device, uint32_t bindInfoCount,
-                                                   const VkBindBufferMemoryInfo* pBindInfos) {
-    auto resources = ResourceTracker::get();
-    if (resources->getApiVersionFromDevice(device) < VK_API_VERSION_1_1) {
-        sOnInvalidDynamicallyCheckedCall("vkBindBufferMemory2", "VK_VERSION_1_1");
-    }
-    AEMU_SCOPED_TRACE("vkBindBufferMemory2");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    VkResult vkBindBufferMemory2_VkResult_return = (VkResult)0;
-    vkBindBufferMemory2_VkResult_return =
-        resources->on_vkBindBufferMemory2(vkEnc, VK_SUCCESS, device, bindInfoCount, pBindInfos);
-    return vkBindBufferMemory2_VkResult_return;
-}
-static VkResult entry_vkBindImageMemory2(VkDevice device, uint32_t bindInfoCount,
-                                         const VkBindImageMemoryInfo* pBindInfos) {
+VkResult gfxstream_vk_BindImageMemory2(VkDevice device, uint32_t bindInfoCount,
+                                       const VkBindImageMemoryInfo* pBindInfos) {
     AEMU_SCOPED_TRACE("vkBindImageMemory2");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
     VkResult vkBindImageMemory2_VkResult_return = (VkResult)0;
-    auto resources = ResourceTracker::get();
-    vkBindImageMemory2_VkResult_return =
-        resources->on_vkBindImageMemory2(vkEnc, VK_SUCCESS, device, bindInfoCount, pBindInfos);
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        std::vector<VkBindImageMemoryInfo> internal_pBindInfos(bindInfoCount);
+        for (uint32_t i = 0; i < bindInfoCount; ++i) {
+            internal_pBindInfos[i] = pBindInfos[i];
+            /* VkBindImageMemoryInfo::image */
+            VK_FROM_HANDLE(gfxstream_vk_image, gfxstream_image, internal_pBindInfos[i].image);
+            internal_pBindInfos[i].image = gfxstream_image->internal_object;
+            /* VkBindImageMemoryInfo::memory */
+            if (internal_pBindInfos[i].memory) {
+                VK_FROM_HANDLE(gfxstream_vk_device_memory, gfxstream_memory,
+                               internal_pBindInfos[i].memory);
+                internal_pBindInfos[i].memory = gfxstream_memory->internal_object;
+            }
+        }
+        auto resources = gfxstream::vk::ResourceTracker::get();
+        vkBindImageMemory2_VkResult_return =
+            resources->on_vkBindImageMemory2(vkEnc, VK_SUCCESS, gfxstream_device->internal_object,
+                                             bindInfoCount, internal_pBindInfos.data());
+    }
     return vkBindImageMemory2_VkResult_return;
 }
-static VkResult dynCheck_entry_vkBindImageMemory2(VkDevice device, uint32_t bindInfoCount,
-                                                  const VkBindImageMemoryInfo* pBindInfos) {
-    auto resources = ResourceTracker::get();
-    if (resources->getApiVersionFromDevice(device) < VK_API_VERSION_1_1) {
-        sOnInvalidDynamicallyCheckedCall("vkBindImageMemory2", "VK_VERSION_1_1");
-    }
-    AEMU_SCOPED_TRACE("vkBindImageMemory2");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    VkResult vkBindImageMemory2_VkResult_return = (VkResult)0;
-    vkBindImageMemory2_VkResult_return =
-        resources->on_vkBindImageMemory2(vkEnc, VK_SUCCESS, device, bindInfoCount, pBindInfos);
-    return vkBindImageMemory2_VkResult_return;
-}
-static void entry_vkGetDeviceGroupPeerMemoryFeatures(
-    VkDevice device, uint32_t heapIndex, uint32_t localDeviceIndex, uint32_t remoteDeviceIndex,
-    VkPeerMemoryFeatureFlags* pPeerMemoryFeatures) {
+void gfxstream_vk_GetDeviceGroupPeerMemoryFeatures(VkDevice device, uint32_t heapIndex,
+                                                   uint32_t localDeviceIndex,
+                                                   uint32_t remoteDeviceIndex,
+                                                   VkPeerMemoryFeatureFlags* pPeerMemoryFeatures) {
     AEMU_SCOPED_TRACE("vkGetDeviceGroupPeerMemoryFeatures");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkGetDeviceGroupPeerMemoryFeatures(device, heapIndex, localDeviceIndex,
-                                              remoteDeviceIndex, pPeerMemoryFeatures,
-                                              true /* do lock */);
-}
-static void dynCheck_entry_vkGetDeviceGroupPeerMemoryFeatures(
-    VkDevice device, uint32_t heapIndex, uint32_t localDeviceIndex, uint32_t remoteDeviceIndex,
-    VkPeerMemoryFeatureFlags* pPeerMemoryFeatures) {
-    auto resources = ResourceTracker::get();
-    if (resources->getApiVersionFromDevice(device) < VK_API_VERSION_1_1) {
-        sOnInvalidDynamicallyCheckedCall("vkGetDeviceGroupPeerMemoryFeatures", "VK_VERSION_1_1");
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkEnc->vkGetDeviceGroupPeerMemoryFeatures(gfxstream_device->internal_object, heapIndex,
+                                                  localDeviceIndex, remoteDeviceIndex,
+                                                  pPeerMemoryFeatures, true /* do lock */);
     }
-    AEMU_SCOPED_TRACE("vkGetDeviceGroupPeerMemoryFeatures");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkGetDeviceGroupPeerMemoryFeatures(device, heapIndex, localDeviceIndex,
-                                              remoteDeviceIndex, pPeerMemoryFeatures,
-                                              true /* do lock */);
 }
-static void entry_vkCmdSetDeviceMask(VkCommandBuffer commandBuffer, uint32_t deviceMask) {
+void gfxstream_vk_CmdSetDeviceMask(VkCommandBuffer commandBuffer, uint32_t deviceMask) {
     AEMU_SCOPED_TRACE("vkCmdSetDeviceMask");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdSetDeviceMask(commandBuffer, deviceMask, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        vkEnc->vkCmdSetDeviceMask(gfxstream_commandBuffer->internal_object, deviceMask,
+                                  true /* do lock */);
+    }
 }
-static void entry_vkCmdDispatchBase(VkCommandBuffer commandBuffer, uint32_t baseGroupX,
-                                    uint32_t baseGroupY, uint32_t baseGroupZ, uint32_t groupCountX,
-                                    uint32_t groupCountY, uint32_t groupCountZ) {
+void gfxstream_vk_CmdDispatchBase(VkCommandBuffer commandBuffer, uint32_t baseGroupX,
+                                  uint32_t baseGroupY, uint32_t baseGroupZ, uint32_t groupCountX,
+                                  uint32_t groupCountY, uint32_t groupCountZ) {
     AEMU_SCOPED_TRACE("vkCmdDispatchBase");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdDispatchBase(commandBuffer, baseGroupX, baseGroupY, baseGroupZ, groupCountX,
-                             groupCountY, groupCountZ, true /* do lock */);
-}
-static VkResult entry_vkEnumeratePhysicalDeviceGroups(
-    VkInstance instance, uint32_t* pPhysicalDeviceGroupCount,
-    VkPhysicalDeviceGroupProperties* pPhysicalDeviceGroupProperties) {
-    AEMU_SCOPED_TRACE("vkEnumeratePhysicalDeviceGroups");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    VkResult vkEnumeratePhysicalDeviceGroups_VkResult_return = (VkResult)0;
-    vkEnumeratePhysicalDeviceGroups_VkResult_return = vkEnc->vkEnumeratePhysicalDeviceGroups(
-        instance, pPhysicalDeviceGroupCount, pPhysicalDeviceGroupProperties, true /* do lock */);
-    return vkEnumeratePhysicalDeviceGroups_VkResult_return;
-}
-static void entry_vkGetImageMemoryRequirements2(VkDevice device,
-                                                const VkImageMemoryRequirementsInfo2* pInfo,
-                                                VkMemoryRequirements2* pMemoryRequirements) {
-    AEMU_SCOPED_TRACE("vkGetImageMemoryRequirements2");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    auto resources = ResourceTracker::get();
-    resources->on_vkGetImageMemoryRequirements2(vkEnc, device, pInfo, pMemoryRequirements);
-}
-static void dynCheck_entry_vkGetImageMemoryRequirements2(
-    VkDevice device, const VkImageMemoryRequirementsInfo2* pInfo,
-    VkMemoryRequirements2* pMemoryRequirements) {
-    auto resources = ResourceTracker::get();
-    if (resources->getApiVersionFromDevice(device) < VK_API_VERSION_1_1) {
-        sOnInvalidDynamicallyCheckedCall("vkGetImageMemoryRequirements2", "VK_VERSION_1_1");
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        vkEnc->vkCmdDispatchBase(gfxstream_commandBuffer->internal_object, baseGroupX, baseGroupY,
+                                 baseGroupZ, groupCountX, groupCountY, groupCountZ,
+                                 true /* do lock */);
     }
+}
+void gfxstream_vk_GetImageMemoryRequirements2(VkDevice device,
+                                              const VkImageMemoryRequirementsInfo2* pInfo,
+                                              VkMemoryRequirements2* pMemoryRequirements) {
     AEMU_SCOPED_TRACE("vkGetImageMemoryRequirements2");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    resources->on_vkGetImageMemoryRequirements2(vkEnc, device, pInfo, pMemoryRequirements);
-}
-static void entry_vkGetBufferMemoryRequirements2(VkDevice device,
-                                                 const VkBufferMemoryRequirementsInfo2* pInfo,
-                                                 VkMemoryRequirements2* pMemoryRequirements) {
-    AEMU_SCOPED_TRACE("vkGetBufferMemoryRequirements2");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    auto resources = ResourceTracker::get();
-    resources->on_vkGetBufferMemoryRequirements2(vkEnc, device, pInfo, pMemoryRequirements);
-}
-static void dynCheck_entry_vkGetBufferMemoryRequirements2(
-    VkDevice device, const VkBufferMemoryRequirementsInfo2* pInfo,
-    VkMemoryRequirements2* pMemoryRequirements) {
-    auto resources = ResourceTracker::get();
-    if (resources->getApiVersionFromDevice(device) < VK_API_VERSION_1_1) {
-        sOnInvalidDynamicallyCheckedCall("vkGetBufferMemoryRequirements2", "VK_VERSION_1_1");
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        std::vector<VkImageMemoryRequirementsInfo2> internal_pInfo(1);
+        for (uint32_t i = 0; i < 1; ++i) {
+            internal_pInfo[i] = pInfo[i];
+            /* VkImageMemoryRequirementsInfo2::image */
+            VK_FROM_HANDLE(gfxstream_vk_image, gfxstream_image, internal_pInfo[i].image);
+            internal_pInfo[i].image = gfxstream_image->internal_object;
+        }
+        auto resources = gfxstream::vk::ResourceTracker::get();
+        resources->on_vkGetImageMemoryRequirements2(vkEnc, gfxstream_device->internal_object,
+                                                    internal_pInfo.data(), pMemoryRequirements);
     }
-    AEMU_SCOPED_TRACE("vkGetBufferMemoryRequirements2");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    resources->on_vkGetBufferMemoryRequirements2(vkEnc, device, pInfo, pMemoryRequirements);
 }
-static void entry_vkGetImageSparseMemoryRequirements2(
+void gfxstream_vk_GetBufferMemoryRequirements2(VkDevice device,
+                                               const VkBufferMemoryRequirementsInfo2* pInfo,
+                                               VkMemoryRequirements2* pMemoryRequirements) {
+    AEMU_SCOPED_TRACE("vkGetBufferMemoryRequirements2");
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        std::vector<VkBufferMemoryRequirementsInfo2> internal_pInfo(1);
+        for (uint32_t i = 0; i < 1; ++i) {
+            internal_pInfo[i] = pInfo[i];
+            /* VkBufferMemoryRequirementsInfo2::buffer */
+            VK_FROM_HANDLE(gfxstream_vk_buffer, gfxstream_buffer, internal_pInfo[i].buffer);
+            internal_pInfo[i].buffer = gfxstream_buffer->internal_object;
+        }
+        auto resources = gfxstream::vk::ResourceTracker::get();
+        resources->on_vkGetBufferMemoryRequirements2(vkEnc, gfxstream_device->internal_object,
+                                                     internal_pInfo.data(), pMemoryRequirements);
+    }
+}
+void gfxstream_vk_GetImageSparseMemoryRequirements2(
     VkDevice device, const VkImageSparseMemoryRequirementsInfo2* pInfo,
     uint32_t* pSparseMemoryRequirementCount,
     VkSparseImageMemoryRequirements2* pSparseMemoryRequirements) {
     AEMU_SCOPED_TRACE("vkGetImageSparseMemoryRequirements2");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkGetImageSparseMemoryRequirements2(device, pInfo, pSparseMemoryRequirementCount,
-                                               pSparseMemoryRequirements, true /* do lock */);
-}
-static void dynCheck_entry_vkGetImageSparseMemoryRequirements2(
-    VkDevice device, const VkImageSparseMemoryRequirementsInfo2* pInfo,
-    uint32_t* pSparseMemoryRequirementCount,
-    VkSparseImageMemoryRequirements2* pSparseMemoryRequirements) {
-    auto resources = ResourceTracker::get();
-    if (resources->getApiVersionFromDevice(device) < VK_API_VERSION_1_1) {
-        sOnInvalidDynamicallyCheckedCall("vkGetImageSparseMemoryRequirements2", "VK_VERSION_1_1");
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        std::vector<VkImageSparseMemoryRequirementsInfo2> internal_pInfo(1);
+        for (uint32_t i = 0; i < 1; ++i) {
+            internal_pInfo[i] = pInfo[i];
+            /* VkImageSparseMemoryRequirementsInfo2::image */
+            VK_FROM_HANDLE(gfxstream_vk_image, gfxstream_image, internal_pInfo[i].image);
+            internal_pInfo[i].image = gfxstream_image->internal_object;
+        }
+        vkEnc->vkGetImageSparseMemoryRequirements2(
+            gfxstream_device->internal_object, internal_pInfo.data(), pSparseMemoryRequirementCount,
+            pSparseMemoryRequirements, true /* do lock */);
     }
-    AEMU_SCOPED_TRACE("vkGetImageSparseMemoryRequirements2");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkGetImageSparseMemoryRequirements2(device, pInfo, pSparseMemoryRequirementCount,
-                                               pSparseMemoryRequirements, true /* do lock */);
 }
-static void entry_vkGetPhysicalDeviceFeatures2(VkPhysicalDevice physicalDevice,
-                                               VkPhysicalDeviceFeatures2* pFeatures) {
+void gfxstream_vk_GetPhysicalDeviceFeatures2(VkPhysicalDevice physicalDevice,
+                                             VkPhysicalDeviceFeatures2* pFeatures) {
     AEMU_SCOPED_TRACE("vkGetPhysicalDeviceFeatures2");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkGetPhysicalDeviceFeatures2(physicalDevice, pFeatures, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_physical_device, gfxstream_physicalDevice, physicalDevice);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkEnc->vkGetPhysicalDeviceFeatures2(gfxstream_physicalDevice->internal_object, pFeatures,
+                                            true /* do lock */);
+    }
 }
-static void entry_vkGetPhysicalDeviceProperties2(VkPhysicalDevice physicalDevice,
-                                                 VkPhysicalDeviceProperties2* pProperties) {
+void gfxstream_vk_GetPhysicalDeviceProperties2(VkPhysicalDevice physicalDevice,
+                                               VkPhysicalDeviceProperties2* pProperties) {
     AEMU_SCOPED_TRACE("vkGetPhysicalDeviceProperties2");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkGetPhysicalDeviceProperties2(physicalDevice, pProperties, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_physical_device, gfxstream_physicalDevice, physicalDevice);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkEnc->vkGetPhysicalDeviceProperties2(gfxstream_physicalDevice->internal_object,
+                                              pProperties, true /* do lock */);
+    }
 }
-static void entry_vkGetPhysicalDeviceFormatProperties2(VkPhysicalDevice physicalDevice,
-                                                       VkFormat format,
-                                                       VkFormatProperties2* pFormatProperties) {
+void gfxstream_vk_GetPhysicalDeviceFormatProperties2(VkPhysicalDevice physicalDevice,
+                                                     VkFormat format,
+                                                     VkFormatProperties2* pFormatProperties) {
     AEMU_SCOPED_TRACE("vkGetPhysicalDeviceFormatProperties2");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkGetPhysicalDeviceFormatProperties2(physicalDevice, format, pFormatProperties,
-                                                true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_physical_device, gfxstream_physicalDevice, physicalDevice);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkEnc->vkGetPhysicalDeviceFormatProperties2(gfxstream_physicalDevice->internal_object,
+                                                    format, pFormatProperties, true /* do lock */);
+    }
 }
-static VkResult entry_vkGetPhysicalDeviceImageFormatProperties2(
+VkResult gfxstream_vk_GetPhysicalDeviceImageFormatProperties2(
     VkPhysicalDevice physicalDevice, const VkPhysicalDeviceImageFormatInfo2* pImageFormatInfo,
     VkImageFormatProperties2* pImageFormatProperties) {
     AEMU_SCOPED_TRACE("vkGetPhysicalDeviceImageFormatProperties2");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
     VkResult vkGetPhysicalDeviceImageFormatProperties2_VkResult_return = (VkResult)0;
-    auto resources = ResourceTracker::get();
-    vkGetPhysicalDeviceImageFormatProperties2_VkResult_return =
-        resources->on_vkGetPhysicalDeviceImageFormatProperties2(
-            vkEnc, VK_SUCCESS, physicalDevice, pImageFormatInfo, pImageFormatProperties);
+    VK_FROM_HANDLE(gfxstream_vk_physical_device, gfxstream_physicalDevice, physicalDevice);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        auto resources = gfxstream::vk::ResourceTracker::get();
+        vkGetPhysicalDeviceImageFormatProperties2_VkResult_return =
+            resources->on_vkGetPhysicalDeviceImageFormatProperties2(
+                vkEnc, VK_SUCCESS, gfxstream_physicalDevice->internal_object, pImageFormatInfo,
+                pImageFormatProperties);
+    }
     return vkGetPhysicalDeviceImageFormatProperties2_VkResult_return;
 }
-static void entry_vkGetPhysicalDeviceQueueFamilyProperties2(
+void gfxstream_vk_GetPhysicalDeviceQueueFamilyProperties2(
     VkPhysicalDevice physicalDevice, uint32_t* pQueueFamilyPropertyCount,
     VkQueueFamilyProperties2* pQueueFamilyProperties) {
     AEMU_SCOPED_TRACE("vkGetPhysicalDeviceQueueFamilyProperties2");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkGetPhysicalDeviceQueueFamilyProperties2(physicalDevice, pQueueFamilyPropertyCount,
-                                                     pQueueFamilyProperties, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_physical_device, gfxstream_physicalDevice, physicalDevice);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkEnc->vkGetPhysicalDeviceQueueFamilyProperties2(
+            gfxstream_physicalDevice->internal_object, pQueueFamilyPropertyCount,
+            pQueueFamilyProperties, true /* do lock */);
+    }
 }
-static void entry_vkGetPhysicalDeviceMemoryProperties2(
+void gfxstream_vk_GetPhysicalDeviceMemoryProperties2(
     VkPhysicalDevice physicalDevice, VkPhysicalDeviceMemoryProperties2* pMemoryProperties) {
     AEMU_SCOPED_TRACE("vkGetPhysicalDeviceMemoryProperties2");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkGetPhysicalDeviceMemoryProperties2(physicalDevice, pMemoryProperties,
-                                                true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_physical_device, gfxstream_physicalDevice, physicalDevice);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkEnc->vkGetPhysicalDeviceMemoryProperties2(gfxstream_physicalDevice->internal_object,
+                                                    pMemoryProperties, true /* do lock */);
+    }
 }
-static void entry_vkGetPhysicalDeviceSparseImageFormatProperties2(
+void gfxstream_vk_GetPhysicalDeviceSparseImageFormatProperties2(
     VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSparseImageFormatInfo2* pFormatInfo,
     uint32_t* pPropertyCount, VkSparseImageFormatProperties2* pProperties) {
     AEMU_SCOPED_TRACE("vkGetPhysicalDeviceSparseImageFormatProperties2");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkGetPhysicalDeviceSparseImageFormatProperties2(
-        physicalDevice, pFormatInfo, pPropertyCount, pProperties, true /* do lock */);
-}
-static void entry_vkTrimCommandPool(VkDevice device, VkCommandPool commandPool,
-                                    VkCommandPoolTrimFlags flags) {
-    AEMU_SCOPED_TRACE("vkTrimCommandPool");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkTrimCommandPool(device, commandPool, flags, true /* do lock */);
-}
-static void dynCheck_entry_vkTrimCommandPool(VkDevice device, VkCommandPool commandPool,
-                                             VkCommandPoolTrimFlags flags) {
-    auto resources = ResourceTracker::get();
-    if (resources->getApiVersionFromDevice(device) < VK_API_VERSION_1_1) {
-        sOnInvalidDynamicallyCheckedCall("vkTrimCommandPool", "VK_VERSION_1_1");
+    VK_FROM_HANDLE(gfxstream_vk_physical_device, gfxstream_physicalDevice, physicalDevice);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkEnc->vkGetPhysicalDeviceSparseImageFormatProperties2(
+            gfxstream_physicalDevice->internal_object, pFormatInfo, pPropertyCount, pProperties,
+            true /* do lock */);
     }
+}
+void gfxstream_vk_TrimCommandPool(VkDevice device, VkCommandPool commandPool,
+                                  VkCommandPoolTrimFlags flags) {
     AEMU_SCOPED_TRACE("vkTrimCommandPool");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkTrimCommandPool(device, commandPool, flags, true /* do lock */);
-}
-static void entry_vkGetDeviceQueue2(VkDevice device, const VkDeviceQueueInfo2* pQueueInfo,
-                                    VkQueue* pQueue) {
-    AEMU_SCOPED_TRACE("vkGetDeviceQueue2");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkGetDeviceQueue2(device, pQueueInfo, pQueue, true /* do lock */);
-}
-static void dynCheck_entry_vkGetDeviceQueue2(VkDevice device, const VkDeviceQueueInfo2* pQueueInfo,
-                                             VkQueue* pQueue) {
-    auto resources = ResourceTracker::get();
-    if (resources->getApiVersionFromDevice(device) < VK_API_VERSION_1_1) {
-        sOnInvalidDynamicallyCheckedCall("vkGetDeviceQueue2", "VK_VERSION_1_1");
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    VK_FROM_HANDLE(gfxstream_vk_command_pool, gfxstream_commandPool, commandPool);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkEnc->vkTrimCommandPool(gfxstream_device->internal_object,
+                                 gfxstream_commandPool->internal_object, flags, true /* do lock */);
     }
-    AEMU_SCOPED_TRACE("vkGetDeviceQueue2");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkGetDeviceQueue2(device, pQueueInfo, pQueue, true /* do lock */);
 }
-static VkResult entry_vkCreateSamplerYcbcrConversion(
+VkResult gfxstream_vk_CreateSamplerYcbcrConversion(
     VkDevice device, const VkSamplerYcbcrConversionCreateInfo* pCreateInfo,
     const VkAllocationCallbacks* pAllocator, VkSamplerYcbcrConversion* pYcbcrConversion) {
     AEMU_SCOPED_TRACE("vkCreateSamplerYcbcrConversion");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
     VkResult vkCreateSamplerYcbcrConversion_VkResult_return = (VkResult)0;
-    auto resources = ResourceTracker::get();
-    vkCreateSamplerYcbcrConversion_VkResult_return = resources->on_vkCreateSamplerYcbcrConversion(
-        vkEnc, VK_SUCCESS, device, pCreateInfo, pAllocator, pYcbcrConversion);
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        auto resources = gfxstream::vk::ResourceTracker::get();
+        vkCreateSamplerYcbcrConversion_VkResult_return =
+            resources->on_vkCreateSamplerYcbcrConversion(vkEnc, VK_SUCCESS,
+                                                         gfxstream_device->internal_object,
+                                                         pCreateInfo, pAllocator, pYcbcrConversion);
+    }
     return vkCreateSamplerYcbcrConversion_VkResult_return;
 }
-static VkResult dynCheck_entry_vkCreateSamplerYcbcrConversion(
-    VkDevice device, const VkSamplerYcbcrConversionCreateInfo* pCreateInfo,
-    const VkAllocationCallbacks* pAllocator, VkSamplerYcbcrConversion* pYcbcrConversion) {
-    auto resources = ResourceTracker::get();
-    if (resources->getApiVersionFromDevice(device) < VK_API_VERSION_1_1) {
-        sOnInvalidDynamicallyCheckedCall("vkCreateSamplerYcbcrConversion", "VK_VERSION_1_1");
-    }
-    AEMU_SCOPED_TRACE("vkCreateSamplerYcbcrConversion");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    VkResult vkCreateSamplerYcbcrConversion_VkResult_return = (VkResult)0;
-    vkCreateSamplerYcbcrConversion_VkResult_return = resources->on_vkCreateSamplerYcbcrConversion(
-        vkEnc, VK_SUCCESS, device, pCreateInfo, pAllocator, pYcbcrConversion);
-    return vkCreateSamplerYcbcrConversion_VkResult_return;
-}
-static void entry_vkDestroySamplerYcbcrConversion(VkDevice device,
-                                                  VkSamplerYcbcrConversion ycbcrConversion,
-                                                  const VkAllocationCallbacks* pAllocator) {
+void gfxstream_vk_DestroySamplerYcbcrConversion(VkDevice device,
+                                                VkSamplerYcbcrConversion ycbcrConversion,
+                                                const VkAllocationCallbacks* pAllocator) {
     AEMU_SCOPED_TRACE("vkDestroySamplerYcbcrConversion");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    auto resources = ResourceTracker::get();
-    resources->on_vkDestroySamplerYcbcrConversion(vkEnc, device, ycbcrConversion, pAllocator);
-}
-static void dynCheck_entry_vkDestroySamplerYcbcrConversion(
-    VkDevice device, VkSamplerYcbcrConversion ycbcrConversion,
-    const VkAllocationCallbacks* pAllocator) {
-    auto resources = ResourceTracker::get();
-    if (resources->getApiVersionFromDevice(device) < VK_API_VERSION_1_1) {
-        sOnInvalidDynamicallyCheckedCall("vkDestroySamplerYcbcrConversion", "VK_VERSION_1_1");
+    if (VK_NULL_HANDLE == ycbcrConversion) {
+        return;
     }
-    AEMU_SCOPED_TRACE("vkDestroySamplerYcbcrConversion");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    resources->on_vkDestroySamplerYcbcrConversion(vkEnc, device, ycbcrConversion, pAllocator);
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        auto resources = gfxstream::vk::ResourceTracker::get();
+        resources->on_vkDestroySamplerYcbcrConversion(vkEnc, gfxstream_device->internal_object,
+                                                      ycbcrConversion, pAllocator);
+    }
 }
-static VkResult entry_vkCreateDescriptorUpdateTemplate(
+VkResult gfxstream_vk_CreateDescriptorUpdateTemplate(
     VkDevice device, const VkDescriptorUpdateTemplateCreateInfo* pCreateInfo,
     const VkAllocationCallbacks* pAllocator,
     VkDescriptorUpdateTemplate* pDescriptorUpdateTemplate) {
     AEMU_SCOPED_TRACE("vkCreateDescriptorUpdateTemplate");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
     VkResult vkCreateDescriptorUpdateTemplate_VkResult_return = (VkResult)0;
-    vkCreateDescriptorUpdateTemplate_VkResult_return = vkEnc->vkCreateDescriptorUpdateTemplate(
-        device, pCreateInfo, pAllocator, pDescriptorUpdateTemplate, true /* do lock */);
-    return vkCreateDescriptorUpdateTemplate_VkResult_return;
-}
-static VkResult dynCheck_entry_vkCreateDescriptorUpdateTemplate(
-    VkDevice device, const VkDescriptorUpdateTemplateCreateInfo* pCreateInfo,
-    const VkAllocationCallbacks* pAllocator,
-    VkDescriptorUpdateTemplate* pDescriptorUpdateTemplate) {
-    auto resources = ResourceTracker::get();
-    if (resources->getApiVersionFromDevice(device) < VK_API_VERSION_1_1) {
-        sOnInvalidDynamicallyCheckedCall("vkCreateDescriptorUpdateTemplate", "VK_VERSION_1_1");
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    struct gfxstream_vk_descriptor_update_template* gfxstream_pDescriptorUpdateTemplate =
+        (gfxstream_vk_descriptor_update_template*)vk_object_zalloc(
+            &gfxstream_device->vk, pAllocator, sizeof(gfxstream_vk_descriptor_update_template),
+            VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE);
+    vkCreateDescriptorUpdateTemplate_VkResult_return =
+        gfxstream_pDescriptorUpdateTemplate ? VK_SUCCESS : VK_ERROR_OUT_OF_HOST_MEMORY;
+    if (VK_SUCCESS == vkCreateDescriptorUpdateTemplate_VkResult_return) {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        std::vector<VkDescriptorUpdateTemplateCreateInfo> internal_pCreateInfo(1);
+        for (uint32_t i = 0; i < 1; ++i) {
+            internal_pCreateInfo[i] = pCreateInfo[i];
+            /* VkDescriptorUpdateTemplateCreateInfo::descriptorSetLayout */
+            if (internal_pCreateInfo[i].descriptorSetLayout) {
+                VK_FROM_HANDLE(gfxstream_vk_descriptor_set_layout, gfxstream_descriptorSetLayout,
+                               internal_pCreateInfo[i].descriptorSetLayout);
+                internal_pCreateInfo[i].descriptorSetLayout =
+                    gfxstream_descriptorSetLayout->internal_object;
+            }
+            /* VkDescriptorUpdateTemplateCreateInfo::pipelineLayout */
+            if (internal_pCreateInfo[i].pipelineLayout) {
+                VK_FROM_HANDLE(gfxstream_vk_pipeline_layout, gfxstream_pipelineLayout,
+                               internal_pCreateInfo[i].pipelineLayout);
+                internal_pCreateInfo[i].pipelineLayout = gfxstream_pipelineLayout->internal_object;
+            }
+        }
+        vkCreateDescriptorUpdateTemplate_VkResult_return = vkEnc->vkCreateDescriptorUpdateTemplate(
+            gfxstream_device->internal_object, internal_pCreateInfo.data(), pAllocator,
+            &gfxstream_pDescriptorUpdateTemplate->internal_object, true /* do lock */);
     }
-    AEMU_SCOPED_TRACE("vkCreateDescriptorUpdateTemplate");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    VkResult vkCreateDescriptorUpdateTemplate_VkResult_return = (VkResult)0;
-    vkCreateDescriptorUpdateTemplate_VkResult_return = vkEnc->vkCreateDescriptorUpdateTemplate(
-        device, pCreateInfo, pAllocator, pDescriptorUpdateTemplate, true /* do lock */);
+    *pDescriptorUpdateTemplate =
+        gfxstream_vk_descriptor_update_template_to_handle(gfxstream_pDescriptorUpdateTemplate);
     return vkCreateDescriptorUpdateTemplate_VkResult_return;
 }
-static void entry_vkDestroyDescriptorUpdateTemplate(
+void gfxstream_vk_DestroyDescriptorUpdateTemplate(
     VkDevice device, VkDescriptorUpdateTemplate descriptorUpdateTemplate,
     const VkAllocationCallbacks* pAllocator) {
     AEMU_SCOPED_TRACE("vkDestroyDescriptorUpdateTemplate");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkDestroyDescriptorUpdateTemplate(device, descriptorUpdateTemplate, pAllocator,
-                                             true /* do lock */);
-}
-static void dynCheck_entry_vkDestroyDescriptorUpdateTemplate(
-    VkDevice device, VkDescriptorUpdateTemplate descriptorUpdateTemplate,
-    const VkAllocationCallbacks* pAllocator) {
-    auto resources = ResourceTracker::get();
-    if (resources->getApiVersionFromDevice(device) < VK_API_VERSION_1_1) {
-        sOnInvalidDynamicallyCheckedCall("vkDestroyDescriptorUpdateTemplate", "VK_VERSION_1_1");
+    if (VK_NULL_HANDLE == descriptorUpdateTemplate) {
+        return;
     }
-    AEMU_SCOPED_TRACE("vkDestroyDescriptorUpdateTemplate");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkDestroyDescriptorUpdateTemplate(device, descriptorUpdateTemplate, pAllocator,
-                                             true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    VK_FROM_HANDLE(gfxstream_vk_descriptor_update_template, gfxstream_descriptorUpdateTemplate,
+                   descriptorUpdateTemplate);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkEnc->vkDestroyDescriptorUpdateTemplate(
+            gfxstream_device->internal_object,
+            gfxstream_descriptorUpdateTemplate ? gfxstream_descriptorUpdateTemplate->internal_object
+                                               : VK_NULL_HANDLE,
+            pAllocator, true /* do lock */);
+    }
+    vk_object_free(&gfxstream_device->vk, pAllocator, (void*)gfxstream_descriptorUpdateTemplate);
 }
-static void entry_vkUpdateDescriptorSetWithTemplate(
+void gfxstream_vk_UpdateDescriptorSetWithTemplate(
     VkDevice device, VkDescriptorSet descriptorSet,
     VkDescriptorUpdateTemplate descriptorUpdateTemplate, const void* pData) {
     AEMU_SCOPED_TRACE("vkUpdateDescriptorSetWithTemplate");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    auto resources = ResourceTracker::get();
-    resources->on_vkUpdateDescriptorSetWithTemplate(vkEnc, device, descriptorSet,
-                                                    descriptorUpdateTemplate, pData);
-}
-static void dynCheck_entry_vkUpdateDescriptorSetWithTemplate(
-    VkDevice device, VkDescriptorSet descriptorSet,
-    VkDescriptorUpdateTemplate descriptorUpdateTemplate, const void* pData) {
-    auto resources = ResourceTracker::get();
-    if (resources->getApiVersionFromDevice(device) < VK_API_VERSION_1_1) {
-        sOnInvalidDynamicallyCheckedCall("vkUpdateDescriptorSetWithTemplate", "VK_VERSION_1_1");
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    VK_FROM_HANDLE(gfxstream_vk_descriptor_update_template, gfxstream_descriptorUpdateTemplate,
+                   descriptorUpdateTemplate);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        auto resources = gfxstream::vk::ResourceTracker::get();
+        resources->on_vkUpdateDescriptorSetWithTemplate(
+            vkEnc, gfxstream_device->internal_object, descriptorSet,
+            gfxstream_descriptorUpdateTemplate->internal_object, pData);
     }
-    AEMU_SCOPED_TRACE("vkUpdateDescriptorSetWithTemplate");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    resources->on_vkUpdateDescriptorSetWithTemplate(vkEnc, device, descriptorSet,
-                                                    descriptorUpdateTemplate, pData);
 }
-static void entry_vkGetPhysicalDeviceExternalBufferProperties(
+void gfxstream_vk_GetPhysicalDeviceExternalBufferProperties(
     VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalBufferInfo* pExternalBufferInfo,
     VkExternalBufferProperties* pExternalBufferProperties) {
     AEMU_SCOPED_TRACE("vkGetPhysicalDeviceExternalBufferProperties");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    auto resources = ResourceTracker::get();
-    resources->on_vkGetPhysicalDeviceExternalBufferProperties(
-        vkEnc, physicalDevice, pExternalBufferInfo, pExternalBufferProperties);
+    VK_FROM_HANDLE(gfxstream_vk_physical_device, gfxstream_physicalDevice, physicalDevice);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        auto resources = gfxstream::vk::ResourceTracker::get();
+        resources->on_vkGetPhysicalDeviceExternalBufferProperties(
+            vkEnc, gfxstream_physicalDevice->internal_object, pExternalBufferInfo,
+            pExternalBufferProperties);
+    }
 }
-static void entry_vkGetPhysicalDeviceExternalFenceProperties(
+void gfxstream_vk_GetPhysicalDeviceExternalFenceProperties(
     VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalFenceInfo* pExternalFenceInfo,
     VkExternalFenceProperties* pExternalFenceProperties) {
     AEMU_SCOPED_TRACE("vkGetPhysicalDeviceExternalFenceProperties");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    auto resources = ResourceTracker::get();
-    resources->on_vkGetPhysicalDeviceExternalFenceProperties(
-        vkEnc, physicalDevice, pExternalFenceInfo, pExternalFenceProperties);
+    VK_FROM_HANDLE(gfxstream_vk_physical_device, gfxstream_physicalDevice, physicalDevice);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        auto resources = gfxstream::vk::ResourceTracker::get();
+        resources->on_vkGetPhysicalDeviceExternalFenceProperties(
+            vkEnc, gfxstream_physicalDevice->internal_object, pExternalFenceInfo,
+            pExternalFenceProperties);
+    }
 }
-static void entry_vkGetPhysicalDeviceExternalSemaphoreProperties(
+void gfxstream_vk_GetPhysicalDeviceExternalSemaphoreProperties(
     VkPhysicalDevice physicalDevice,
     const VkPhysicalDeviceExternalSemaphoreInfo* pExternalSemaphoreInfo,
     VkExternalSemaphoreProperties* pExternalSemaphoreProperties) {
     AEMU_SCOPED_TRACE("vkGetPhysicalDeviceExternalSemaphoreProperties");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkGetPhysicalDeviceExternalSemaphoreProperties(
-        physicalDevice, pExternalSemaphoreInfo, pExternalSemaphoreProperties, true /* do lock */);
-}
-static void entry_vkGetDescriptorSetLayoutSupport(
-    VkDevice device, const VkDescriptorSetLayoutCreateInfo* pCreateInfo,
-    VkDescriptorSetLayoutSupport* pSupport) {
-    AEMU_SCOPED_TRACE("vkGetDescriptorSetLayoutSupport");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkGetDescriptorSetLayoutSupport(device, pCreateInfo, pSupport, true /* do lock */);
-}
-static void dynCheck_entry_vkGetDescriptorSetLayoutSupport(
-    VkDevice device, const VkDescriptorSetLayoutCreateInfo* pCreateInfo,
-    VkDescriptorSetLayoutSupport* pSupport) {
-    auto resources = ResourceTracker::get();
-    if (resources->getApiVersionFromDevice(device) < VK_API_VERSION_1_1) {
-        sOnInvalidDynamicallyCheckedCall("vkGetDescriptorSetLayoutSupport", "VK_VERSION_1_1");
+    VK_FROM_HANDLE(gfxstream_vk_physical_device, gfxstream_physicalDevice, physicalDevice);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkEnc->vkGetPhysicalDeviceExternalSemaphoreProperties(
+            gfxstream_physicalDevice->internal_object, pExternalSemaphoreInfo,
+            pExternalSemaphoreProperties, true /* do lock */);
     }
+}
+void gfxstream_vk_GetDescriptorSetLayoutSupport(VkDevice device,
+                                                const VkDescriptorSetLayoutCreateInfo* pCreateInfo,
+                                                VkDescriptorSetLayoutSupport* pSupport) {
     AEMU_SCOPED_TRACE("vkGetDescriptorSetLayoutSupport");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkGetDescriptorSetLayoutSupport(device, pCreateInfo, pSupport, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkEnc->vkGetDescriptorSetLayoutSupport(gfxstream_device->internal_object, pCreateInfo,
+                                               pSupport, true /* do lock */);
+    }
 }
 #endif
 #ifdef VK_VERSION_1_2
-static void entry_vkCmdDrawIndirectCount(VkCommandBuffer commandBuffer, VkBuffer buffer,
-                                         VkDeviceSize offset, VkBuffer countBuffer,
-                                         VkDeviceSize countBufferOffset, uint32_t maxDrawCount,
-                                         uint32_t stride) {
+void gfxstream_vk_CmdDrawIndirectCount(VkCommandBuffer commandBuffer, VkBuffer buffer,
+                                       VkDeviceSize offset, VkBuffer countBuffer,
+                                       VkDeviceSize countBufferOffset, uint32_t maxDrawCount,
+                                       uint32_t stride) {
     AEMU_SCOPED_TRACE("vkCmdDrawIndirectCount");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdDrawIndirectCount(commandBuffer, buffer, offset, countBuffer, countBufferOffset,
-                                  maxDrawCount, stride, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    VK_FROM_HANDLE(gfxstream_vk_buffer, gfxstream_buffer, buffer);
+    VK_FROM_HANDLE(gfxstream_vk_buffer, gfxstream_countBuffer, countBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        vkEnc->vkCmdDrawIndirectCount(gfxstream_commandBuffer->internal_object,
+                                      gfxstream_buffer->internal_object, offset,
+                                      gfxstream_countBuffer->internal_object, countBufferOffset,
+                                      maxDrawCount, stride, true /* do lock */);
+    }
 }
-static void entry_vkCmdDrawIndexedIndirectCount(VkCommandBuffer commandBuffer, VkBuffer buffer,
-                                                VkDeviceSize offset, VkBuffer countBuffer,
-                                                VkDeviceSize countBufferOffset,
-                                                uint32_t maxDrawCount, uint32_t stride) {
+void gfxstream_vk_CmdDrawIndexedIndirectCount(VkCommandBuffer commandBuffer, VkBuffer buffer,
+                                              VkDeviceSize offset, VkBuffer countBuffer,
+                                              VkDeviceSize countBufferOffset, uint32_t maxDrawCount,
+                                              uint32_t stride) {
     AEMU_SCOPED_TRACE("vkCmdDrawIndexedIndirectCount");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdDrawIndexedIndirectCount(commandBuffer, buffer, offset, countBuffer,
-                                         countBufferOffset, maxDrawCount, stride,
-                                         true /* do lock */);
-}
-static VkResult entry_vkCreateRenderPass2(VkDevice device,
-                                          const VkRenderPassCreateInfo2* pCreateInfo,
-                                          const VkAllocationCallbacks* pAllocator,
-                                          VkRenderPass* pRenderPass) {
-    AEMU_SCOPED_TRACE("vkCreateRenderPass2");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    VkResult vkCreateRenderPass2_VkResult_return = (VkResult)0;
-    vkCreateRenderPass2_VkResult_return = vkEnc->vkCreateRenderPass2(
-        device, pCreateInfo, pAllocator, pRenderPass, true /* do lock */);
-    return vkCreateRenderPass2_VkResult_return;
-}
-static VkResult dynCheck_entry_vkCreateRenderPass2(VkDevice device,
-                                                   const VkRenderPassCreateInfo2* pCreateInfo,
-                                                   const VkAllocationCallbacks* pAllocator,
-                                                   VkRenderPass* pRenderPass) {
-    auto resources = ResourceTracker::get();
-    if (resources->getApiVersionFromDevice(device) < VK_API_VERSION_1_2) {
-        sOnInvalidDynamicallyCheckedCall("vkCreateRenderPass2", "VK_VERSION_1_2");
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    VK_FROM_HANDLE(gfxstream_vk_buffer, gfxstream_buffer, buffer);
+    VK_FROM_HANDLE(gfxstream_vk_buffer, gfxstream_countBuffer, countBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        vkEnc->vkCmdDrawIndexedIndirectCount(
+            gfxstream_commandBuffer->internal_object, gfxstream_buffer->internal_object, offset,
+            gfxstream_countBuffer->internal_object, countBufferOffset, maxDrawCount, stride,
+            true /* do lock */);
     }
+}
+VkResult gfxstream_vk_CreateRenderPass2(VkDevice device, const VkRenderPassCreateInfo2* pCreateInfo,
+                                        const VkAllocationCallbacks* pAllocator,
+                                        VkRenderPass* pRenderPass) {
     AEMU_SCOPED_TRACE("vkCreateRenderPass2");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
     VkResult vkCreateRenderPass2_VkResult_return = (VkResult)0;
-    vkCreateRenderPass2_VkResult_return = vkEnc->vkCreateRenderPass2(
-        device, pCreateInfo, pAllocator, pRenderPass, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    struct gfxstream_vk_render_pass* gfxstream_pRenderPass =
+        (gfxstream_vk_render_pass*)vk_object_zalloc(&gfxstream_device->vk, pAllocator,
+                                                    sizeof(gfxstream_vk_render_pass),
+                                                    VK_OBJECT_TYPE_RENDER_PASS);
+    vkCreateRenderPass2_VkResult_return =
+        gfxstream_pRenderPass ? VK_SUCCESS : VK_ERROR_OUT_OF_HOST_MEMORY;
+    if (VK_SUCCESS == vkCreateRenderPass2_VkResult_return) {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkCreateRenderPass2_VkResult_return =
+            vkEnc->vkCreateRenderPass2(gfxstream_device->internal_object, pCreateInfo, pAllocator,
+                                       &gfxstream_pRenderPass->internal_object, true /* do lock */);
+    }
+    *pRenderPass = gfxstream_vk_render_pass_to_handle(gfxstream_pRenderPass);
     return vkCreateRenderPass2_VkResult_return;
 }
-static void entry_vkCmdBeginRenderPass2(VkCommandBuffer commandBuffer,
-                                        const VkRenderPassBeginInfo* pRenderPassBegin,
-                                        const VkSubpassBeginInfo* pSubpassBeginInfo) {
+void gfxstream_vk_CmdBeginRenderPass2(VkCommandBuffer commandBuffer,
+                                      const VkRenderPassBeginInfo* pRenderPassBegin,
+                                      const VkSubpassBeginInfo* pSubpassBeginInfo) {
     AEMU_SCOPED_TRACE("vkCmdBeginRenderPass2");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdBeginRenderPass2(commandBuffer, pRenderPassBegin, pSubpassBeginInfo,
-                                 true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        std::vector<VkRenderPassBeginInfo> internal_pRenderPassBegin(1);
+        for (uint32_t i = 0; i < 1; ++i) {
+            internal_pRenderPassBegin[i] = pRenderPassBegin[i];
+            /* VkRenderPassBeginInfo::renderPass */
+            VK_FROM_HANDLE(gfxstream_vk_render_pass, gfxstream_renderPass,
+                           internal_pRenderPassBegin[i].renderPass);
+            internal_pRenderPassBegin[i].renderPass = gfxstream_renderPass->internal_object;
+            /* VkRenderPassBeginInfo::framebuffer */
+            VK_FROM_HANDLE(gfxstream_vk_framebuffer, gfxstream_framebuffer,
+                           internal_pRenderPassBegin[i].framebuffer);
+            internal_pRenderPassBegin[i].framebuffer = gfxstream_framebuffer->internal_object;
+        }
+        vkEnc->vkCmdBeginRenderPass2(gfxstream_commandBuffer->internal_object,
+                                     internal_pRenderPassBegin.data(), pSubpassBeginInfo,
+                                     true /* do lock */);
+    }
 }
-static void entry_vkCmdNextSubpass2(VkCommandBuffer commandBuffer,
-                                    const VkSubpassBeginInfo* pSubpassBeginInfo,
-                                    const VkSubpassEndInfo* pSubpassEndInfo) {
+void gfxstream_vk_CmdNextSubpass2(VkCommandBuffer commandBuffer,
+                                  const VkSubpassBeginInfo* pSubpassBeginInfo,
+                                  const VkSubpassEndInfo* pSubpassEndInfo) {
     AEMU_SCOPED_TRACE("vkCmdNextSubpass2");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdNextSubpass2(commandBuffer, pSubpassBeginInfo, pSubpassEndInfo, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        vkEnc->vkCmdNextSubpass2(gfxstream_commandBuffer->internal_object, pSubpassBeginInfo,
+                                 pSubpassEndInfo, true /* do lock */);
+    }
 }
-static void entry_vkCmdEndRenderPass2(VkCommandBuffer commandBuffer,
-                                      const VkSubpassEndInfo* pSubpassEndInfo) {
+void gfxstream_vk_CmdEndRenderPass2(VkCommandBuffer commandBuffer,
+                                    const VkSubpassEndInfo* pSubpassEndInfo) {
     AEMU_SCOPED_TRACE("vkCmdEndRenderPass2");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdEndRenderPass2(commandBuffer, pSubpassEndInfo, true /* do lock */);
-}
-static void entry_vkResetQueryPool(VkDevice device, VkQueryPool queryPool, uint32_t firstQuery,
-                                   uint32_t queryCount) {
-    AEMU_SCOPED_TRACE("vkResetQueryPool");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkResetQueryPool(device, queryPool, firstQuery, queryCount, true /* do lock */);
-}
-static void dynCheck_entry_vkResetQueryPool(VkDevice device, VkQueryPool queryPool,
-                                            uint32_t firstQuery, uint32_t queryCount) {
-    auto resources = ResourceTracker::get();
-    if (resources->getApiVersionFromDevice(device) < VK_API_VERSION_1_2) {
-        sOnInvalidDynamicallyCheckedCall("vkResetQueryPool", "VK_VERSION_1_2");
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        vkEnc->vkCmdEndRenderPass2(gfxstream_commandBuffer->internal_object, pSubpassEndInfo,
+                                   true /* do lock */);
     }
-    AEMU_SCOPED_TRACE("vkResetQueryPool");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkResetQueryPool(device, queryPool, firstQuery, queryCount, true /* do lock */);
 }
-static VkResult entry_vkGetSemaphoreCounterValue(VkDevice device, VkSemaphore semaphore,
-                                                 uint64_t* pValue) {
+void gfxstream_vk_ResetQueryPool(VkDevice device, VkQueryPool queryPool, uint32_t firstQuery,
+                                 uint32_t queryCount) {
+    AEMU_SCOPED_TRACE("vkResetQueryPool");
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    VK_FROM_HANDLE(gfxstream_vk_query_pool, gfxstream_queryPool, queryPool);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkEnc->vkResetQueryPool(gfxstream_device->internal_object,
+                                gfxstream_queryPool->internal_object, firstQuery, queryCount,
+                                true /* do lock */);
+    }
+}
+VkResult gfxstream_vk_GetSemaphoreCounterValue(VkDevice device, VkSemaphore semaphore,
+                                               uint64_t* pValue) {
     AEMU_SCOPED_TRACE("vkGetSemaphoreCounterValue");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
     VkResult vkGetSemaphoreCounterValue_VkResult_return = (VkResult)0;
-    vkGetSemaphoreCounterValue_VkResult_return =
-        vkEnc->vkGetSemaphoreCounterValue(device, semaphore, pValue, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    VK_FROM_HANDLE(gfxstream_vk_semaphore, gfxstream_semaphore, semaphore);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkGetSemaphoreCounterValue_VkResult_return = vkEnc->vkGetSemaphoreCounterValue(
+            gfxstream_device->internal_object, gfxstream_semaphore->internal_object, pValue,
+            true /* do lock */);
+    }
     return vkGetSemaphoreCounterValue_VkResult_return;
 }
-static VkResult dynCheck_entry_vkGetSemaphoreCounterValue(VkDevice device, VkSemaphore semaphore,
-                                                          uint64_t* pValue) {
-    auto resources = ResourceTracker::get();
-    if (resources->getApiVersionFromDevice(device) < VK_API_VERSION_1_2) {
-        sOnInvalidDynamicallyCheckedCall("vkGetSemaphoreCounterValue", "VK_VERSION_1_2");
-    }
-    AEMU_SCOPED_TRACE("vkGetSemaphoreCounterValue");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    VkResult vkGetSemaphoreCounterValue_VkResult_return = (VkResult)0;
-    vkGetSemaphoreCounterValue_VkResult_return =
-        vkEnc->vkGetSemaphoreCounterValue(device, semaphore, pValue, true /* do lock */);
-    return vkGetSemaphoreCounterValue_VkResult_return;
-}
-static VkResult entry_vkWaitSemaphores(VkDevice device, const VkSemaphoreWaitInfo* pWaitInfo,
-                                       uint64_t timeout) {
+VkResult gfxstream_vk_WaitSemaphores(VkDevice device, const VkSemaphoreWaitInfo* pWaitInfo,
+                                     uint64_t timeout) {
     AEMU_SCOPED_TRACE("vkWaitSemaphores");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
     VkResult vkWaitSemaphores_VkResult_return = (VkResult)0;
-    vkWaitSemaphores_VkResult_return =
-        vkEnc->vkWaitSemaphores(device, pWaitInfo, timeout, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        std::vector<VkSemaphoreWaitInfo> internal_pWaitInfo(1);
+        std::vector<std::vector<VkSemaphore>> internal_VkSemaphoreWaitInfo_pSemaphores;
+        for (uint32_t i = 0; i < 1; ++i) {
+            internal_pWaitInfo[i] = pWaitInfo[i];
+            /* VkSemaphoreWaitInfo::pSemaphores */
+            internal_VkSemaphoreWaitInfo_pSemaphores.push_back(std::vector<VkSemaphore>());
+            internal_VkSemaphoreWaitInfo_pSemaphores[i] = transformVkSemaphoreList(
+                internal_pWaitInfo[i].pSemaphores, internal_pWaitInfo[i].semaphoreCount);
+            internal_pWaitInfo[i].pSemaphores = internal_VkSemaphoreWaitInfo_pSemaphores[i].data();
+            internal_pWaitInfo[i].semaphoreCount =
+                internal_VkSemaphoreWaitInfo_pSemaphores[i].size();
+        }
+        vkWaitSemaphores_VkResult_return =
+            vkEnc->vkWaitSemaphores(gfxstream_device->internal_object, internal_pWaitInfo.data(),
+                                    timeout, true /* do lock */);
+    }
     return vkWaitSemaphores_VkResult_return;
 }
-static VkResult dynCheck_entry_vkWaitSemaphores(VkDevice device,
-                                                const VkSemaphoreWaitInfo* pWaitInfo,
-                                                uint64_t timeout) {
-    auto resources = ResourceTracker::get();
-    if (resources->getApiVersionFromDevice(device) < VK_API_VERSION_1_2) {
-        sOnInvalidDynamicallyCheckedCall("vkWaitSemaphores", "VK_VERSION_1_2");
-    }
-    AEMU_SCOPED_TRACE("vkWaitSemaphores");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    VkResult vkWaitSemaphores_VkResult_return = (VkResult)0;
-    vkWaitSemaphores_VkResult_return =
-        vkEnc->vkWaitSemaphores(device, pWaitInfo, timeout, true /* do lock */);
-    return vkWaitSemaphores_VkResult_return;
-}
-static VkResult entry_vkSignalSemaphore(VkDevice device, const VkSemaphoreSignalInfo* pSignalInfo) {
+VkResult gfxstream_vk_SignalSemaphore(VkDevice device, const VkSemaphoreSignalInfo* pSignalInfo) {
     AEMU_SCOPED_TRACE("vkSignalSemaphore");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
     VkResult vkSignalSemaphore_VkResult_return = (VkResult)0;
-    vkSignalSemaphore_VkResult_return =
-        vkEnc->vkSignalSemaphore(device, pSignalInfo, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        std::vector<VkSemaphoreSignalInfo> internal_pSignalInfo(1);
+        for (uint32_t i = 0; i < 1; ++i) {
+            internal_pSignalInfo[i] = pSignalInfo[i];
+            /* VkSemaphoreSignalInfo::semaphore */
+            VK_FROM_HANDLE(gfxstream_vk_semaphore, gfxstream_semaphore,
+                           internal_pSignalInfo[i].semaphore);
+            internal_pSignalInfo[i].semaphore = gfxstream_semaphore->internal_object;
+        }
+        vkSignalSemaphore_VkResult_return = vkEnc->vkSignalSemaphore(
+            gfxstream_device->internal_object, internal_pSignalInfo.data(), true /* do lock */);
+    }
     return vkSignalSemaphore_VkResult_return;
 }
-static VkResult dynCheck_entry_vkSignalSemaphore(VkDevice device,
-                                                 const VkSemaphoreSignalInfo* pSignalInfo) {
-    auto resources = ResourceTracker::get();
-    if (resources->getApiVersionFromDevice(device) < VK_API_VERSION_1_2) {
-        sOnInvalidDynamicallyCheckedCall("vkSignalSemaphore", "VK_VERSION_1_2");
-    }
-    AEMU_SCOPED_TRACE("vkSignalSemaphore");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    VkResult vkSignalSemaphore_VkResult_return = (VkResult)0;
-    vkSignalSemaphore_VkResult_return =
-        vkEnc->vkSignalSemaphore(device, pSignalInfo, true /* do lock */);
-    return vkSignalSemaphore_VkResult_return;
-}
-static VkDeviceAddress entry_vkGetBufferDeviceAddress(VkDevice device,
-                                                      const VkBufferDeviceAddressInfo* pInfo) {
+VkDeviceAddress gfxstream_vk_GetBufferDeviceAddress(VkDevice device,
+                                                    const VkBufferDeviceAddressInfo* pInfo) {
     AEMU_SCOPED_TRACE("vkGetBufferDeviceAddress");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
     VkDeviceAddress vkGetBufferDeviceAddress_VkDeviceAddress_return = (VkDeviceAddress)0;
-    vkGetBufferDeviceAddress_VkDeviceAddress_return =
-        vkEnc->vkGetBufferDeviceAddress(device, pInfo, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        std::vector<VkBufferDeviceAddressInfo> internal_pInfo(1);
+        for (uint32_t i = 0; i < 1; ++i) {
+            internal_pInfo[i] = pInfo[i];
+            /* VkBufferDeviceAddressInfo::buffer */
+            VK_FROM_HANDLE(gfxstream_vk_buffer, gfxstream_buffer, internal_pInfo[i].buffer);
+            internal_pInfo[i].buffer = gfxstream_buffer->internal_object;
+        }
+        vkGetBufferDeviceAddress_VkDeviceAddress_return = vkEnc->vkGetBufferDeviceAddress(
+            gfxstream_device->internal_object, internal_pInfo.data(), true /* do lock */);
+    }
     return vkGetBufferDeviceAddress_VkDeviceAddress_return;
 }
-static VkDeviceAddress dynCheck_entry_vkGetBufferDeviceAddress(
-    VkDevice device, const VkBufferDeviceAddressInfo* pInfo) {
-    auto resources = ResourceTracker::get();
-    if (resources->getApiVersionFromDevice(device) < VK_API_VERSION_1_2) {
-        sOnInvalidDynamicallyCheckedCall("vkGetBufferDeviceAddress", "VK_VERSION_1_2");
-    }
-    AEMU_SCOPED_TRACE("vkGetBufferDeviceAddress");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    VkDeviceAddress vkGetBufferDeviceAddress_VkDeviceAddress_return = (VkDeviceAddress)0;
-    vkGetBufferDeviceAddress_VkDeviceAddress_return =
-        vkEnc->vkGetBufferDeviceAddress(device, pInfo, true /* do lock */);
-    return vkGetBufferDeviceAddress_VkDeviceAddress_return;
-}
-static uint64_t entry_vkGetBufferOpaqueCaptureAddress(VkDevice device,
-                                                      const VkBufferDeviceAddressInfo* pInfo) {
+uint64_t gfxstream_vk_GetBufferOpaqueCaptureAddress(VkDevice device,
+                                                    const VkBufferDeviceAddressInfo* pInfo) {
     AEMU_SCOPED_TRACE("vkGetBufferOpaqueCaptureAddress");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
     uint64_t vkGetBufferOpaqueCaptureAddress_uint64_t_return = (uint64_t)0;
-    vkGetBufferOpaqueCaptureAddress_uint64_t_return =
-        vkEnc->vkGetBufferOpaqueCaptureAddress(device, pInfo, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        std::vector<VkBufferDeviceAddressInfo> internal_pInfo(1);
+        for (uint32_t i = 0; i < 1; ++i) {
+            internal_pInfo[i] = pInfo[i];
+            /* VkBufferDeviceAddressInfo::buffer */
+            VK_FROM_HANDLE(gfxstream_vk_buffer, gfxstream_buffer, internal_pInfo[i].buffer);
+            internal_pInfo[i].buffer = gfxstream_buffer->internal_object;
+        }
+        vkGetBufferOpaqueCaptureAddress_uint64_t_return = vkEnc->vkGetBufferOpaqueCaptureAddress(
+            gfxstream_device->internal_object, internal_pInfo.data(), true /* do lock */);
+    }
     return vkGetBufferOpaqueCaptureAddress_uint64_t_return;
 }
-static uint64_t dynCheck_entry_vkGetBufferOpaqueCaptureAddress(
-    VkDevice device, const VkBufferDeviceAddressInfo* pInfo) {
-    auto resources = ResourceTracker::get();
-    if (resources->getApiVersionFromDevice(device) < VK_API_VERSION_1_2) {
-        sOnInvalidDynamicallyCheckedCall("vkGetBufferOpaqueCaptureAddress", "VK_VERSION_1_2");
-    }
-    AEMU_SCOPED_TRACE("vkGetBufferOpaqueCaptureAddress");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    uint64_t vkGetBufferOpaqueCaptureAddress_uint64_t_return = (uint64_t)0;
-    vkGetBufferOpaqueCaptureAddress_uint64_t_return =
-        vkEnc->vkGetBufferOpaqueCaptureAddress(device, pInfo, true /* do lock */);
-    return vkGetBufferOpaqueCaptureAddress_uint64_t_return;
-}
-static uint64_t entry_vkGetDeviceMemoryOpaqueCaptureAddress(
+uint64_t gfxstream_vk_GetDeviceMemoryOpaqueCaptureAddress(
     VkDevice device, const VkDeviceMemoryOpaqueCaptureAddressInfo* pInfo) {
     AEMU_SCOPED_TRACE("vkGetDeviceMemoryOpaqueCaptureAddress");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
     uint64_t vkGetDeviceMemoryOpaqueCaptureAddress_uint64_t_return = (uint64_t)0;
-    vkGetDeviceMemoryOpaqueCaptureAddress_uint64_t_return =
-        vkEnc->vkGetDeviceMemoryOpaqueCaptureAddress(device, pInfo, true /* do lock */);
-    return vkGetDeviceMemoryOpaqueCaptureAddress_uint64_t_return;
-}
-static uint64_t dynCheck_entry_vkGetDeviceMemoryOpaqueCaptureAddress(
-    VkDevice device, const VkDeviceMemoryOpaqueCaptureAddressInfo* pInfo) {
-    auto resources = ResourceTracker::get();
-    if (resources->getApiVersionFromDevice(device) < VK_API_VERSION_1_2) {
-        sOnInvalidDynamicallyCheckedCall("vkGetDeviceMemoryOpaqueCaptureAddress", "VK_VERSION_1_2");
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        std::vector<VkDeviceMemoryOpaqueCaptureAddressInfo> internal_pInfo(1);
+        for (uint32_t i = 0; i < 1; ++i) {
+            internal_pInfo[i] = pInfo[i];
+            /* VkDeviceMemoryOpaqueCaptureAddressInfo::memory */
+            VK_FROM_HANDLE(gfxstream_vk_device_memory, gfxstream_memory, internal_pInfo[i].memory);
+            internal_pInfo[i].memory = gfxstream_memory->internal_object;
+        }
+        vkGetDeviceMemoryOpaqueCaptureAddress_uint64_t_return =
+            vkEnc->vkGetDeviceMemoryOpaqueCaptureAddress(gfxstream_device->internal_object,
+                                                         internal_pInfo.data(), true /* do lock */);
     }
-    AEMU_SCOPED_TRACE("vkGetDeviceMemoryOpaqueCaptureAddress");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    uint64_t vkGetDeviceMemoryOpaqueCaptureAddress_uint64_t_return = (uint64_t)0;
-    vkGetDeviceMemoryOpaqueCaptureAddress_uint64_t_return =
-        vkEnc->vkGetDeviceMemoryOpaqueCaptureAddress(device, pInfo, true /* do lock */);
     return vkGetDeviceMemoryOpaqueCaptureAddress_uint64_t_return;
 }
 #endif
 #ifdef VK_VERSION_1_3
-static VkResult entry_vkGetPhysicalDeviceToolProperties(
+VkResult gfxstream_vk_GetPhysicalDeviceToolProperties(
     VkPhysicalDevice physicalDevice, uint32_t* pToolCount,
     VkPhysicalDeviceToolProperties* pToolProperties) {
     AEMU_SCOPED_TRACE("vkGetPhysicalDeviceToolProperties");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
     VkResult vkGetPhysicalDeviceToolProperties_VkResult_return = (VkResult)0;
-    vkGetPhysicalDeviceToolProperties_VkResult_return = vkEnc->vkGetPhysicalDeviceToolProperties(
-        physicalDevice, pToolCount, pToolProperties, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_physical_device, gfxstream_physicalDevice, physicalDevice);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkGetPhysicalDeviceToolProperties_VkResult_return =
+            vkEnc->vkGetPhysicalDeviceToolProperties(gfxstream_physicalDevice->internal_object,
+                                                     pToolCount, pToolProperties,
+                                                     true /* do lock */);
+    }
     return vkGetPhysicalDeviceToolProperties_VkResult_return;
 }
-static VkResult entry_vkCreatePrivateDataSlot(VkDevice device,
-                                              const VkPrivateDataSlotCreateInfo* pCreateInfo,
-                                              const VkAllocationCallbacks* pAllocator,
-                                              VkPrivateDataSlot* pPrivateDataSlot) {
+VkResult gfxstream_vk_CreatePrivateDataSlot(VkDevice device,
+                                            const VkPrivateDataSlotCreateInfo* pCreateInfo,
+                                            const VkAllocationCallbacks* pAllocator,
+                                            VkPrivateDataSlot* pPrivateDataSlot) {
     AEMU_SCOPED_TRACE("vkCreatePrivateDataSlot");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
     VkResult vkCreatePrivateDataSlot_VkResult_return = (VkResult)0;
-    vkCreatePrivateDataSlot_VkResult_return = vkEnc->vkCreatePrivateDataSlot(
-        device, pCreateInfo, pAllocator, pPrivateDataSlot, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkCreatePrivateDataSlot_VkResult_return =
+            vkEnc->vkCreatePrivateDataSlot(gfxstream_device->internal_object, pCreateInfo,
+                                           pAllocator, pPrivateDataSlot, true /* do lock */);
+    }
     return vkCreatePrivateDataSlot_VkResult_return;
 }
-static VkResult dynCheck_entry_vkCreatePrivateDataSlot(
-    VkDevice device, const VkPrivateDataSlotCreateInfo* pCreateInfo,
-    const VkAllocationCallbacks* pAllocator, VkPrivateDataSlot* pPrivateDataSlot) {
-    auto resources = ResourceTracker::get();
-    if (resources->getApiVersionFromDevice(device) < VK_API_VERSION_1_3) {
-        sOnInvalidDynamicallyCheckedCall("vkCreatePrivateDataSlot", "VK_VERSION_1_3");
-    }
-    AEMU_SCOPED_TRACE("vkCreatePrivateDataSlot");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    VkResult vkCreatePrivateDataSlot_VkResult_return = (VkResult)0;
-    vkCreatePrivateDataSlot_VkResult_return = vkEnc->vkCreatePrivateDataSlot(
-        device, pCreateInfo, pAllocator, pPrivateDataSlot, true /* do lock */);
-    return vkCreatePrivateDataSlot_VkResult_return;
-}
-static void entry_vkDestroyPrivateDataSlot(VkDevice device, VkPrivateDataSlot privateDataSlot,
-                                           const VkAllocationCallbacks* pAllocator) {
+void gfxstream_vk_DestroyPrivateDataSlot(VkDevice device, VkPrivateDataSlot privateDataSlot,
+                                         const VkAllocationCallbacks* pAllocator) {
     AEMU_SCOPED_TRACE("vkDestroyPrivateDataSlot");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkDestroyPrivateDataSlot(device, privateDataSlot, pAllocator, true /* do lock */);
-}
-static void dynCheck_entry_vkDestroyPrivateDataSlot(VkDevice device,
-                                                    VkPrivateDataSlot privateDataSlot,
-                                                    const VkAllocationCallbacks* pAllocator) {
-    auto resources = ResourceTracker::get();
-    if (resources->getApiVersionFromDevice(device) < VK_API_VERSION_1_3) {
-        sOnInvalidDynamicallyCheckedCall("vkDestroyPrivateDataSlot", "VK_VERSION_1_3");
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkEnc->vkDestroyPrivateDataSlot(gfxstream_device->internal_object, privateDataSlot,
+                                        pAllocator, true /* do lock */);
     }
-    AEMU_SCOPED_TRACE("vkDestroyPrivateDataSlot");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkDestroyPrivateDataSlot(device, privateDataSlot, pAllocator, true /* do lock */);
 }
-static VkResult entry_vkSetPrivateData(VkDevice device, VkObjectType objectType,
-                                       uint64_t objectHandle, VkPrivateDataSlot privateDataSlot,
-                                       uint64_t data) {
+VkResult gfxstream_vk_SetPrivateData(VkDevice device, VkObjectType objectType,
+                                     uint64_t objectHandle, VkPrivateDataSlot privateDataSlot,
+                                     uint64_t data) {
     AEMU_SCOPED_TRACE("vkSetPrivateData");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
     VkResult vkSetPrivateData_VkResult_return = (VkResult)0;
-    vkSetPrivateData_VkResult_return = vkEnc->vkSetPrivateData(
-        device, objectType, objectHandle, privateDataSlot, data, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkSetPrivateData_VkResult_return =
+            vkEnc->vkSetPrivateData(gfxstream_device->internal_object, objectType, objectHandle,
+                                    privateDataSlot, data, true /* do lock */);
+    }
     return vkSetPrivateData_VkResult_return;
 }
-static VkResult dynCheck_entry_vkSetPrivateData(VkDevice device, VkObjectType objectType,
-                                                uint64_t objectHandle,
-                                                VkPrivateDataSlot privateDataSlot, uint64_t data) {
-    auto resources = ResourceTracker::get();
-    if (resources->getApiVersionFromDevice(device) < VK_API_VERSION_1_3) {
-        sOnInvalidDynamicallyCheckedCall("vkSetPrivateData", "VK_VERSION_1_3");
-    }
-    AEMU_SCOPED_TRACE("vkSetPrivateData");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    VkResult vkSetPrivateData_VkResult_return = (VkResult)0;
-    vkSetPrivateData_VkResult_return = vkEnc->vkSetPrivateData(
-        device, objectType, objectHandle, privateDataSlot, data, true /* do lock */);
-    return vkSetPrivateData_VkResult_return;
-}
-static void entry_vkGetPrivateData(VkDevice device, VkObjectType objectType, uint64_t objectHandle,
-                                   VkPrivateDataSlot privateDataSlot, uint64_t* pData) {
+void gfxstream_vk_GetPrivateData(VkDevice device, VkObjectType objectType, uint64_t objectHandle,
+                                 VkPrivateDataSlot privateDataSlot, uint64_t* pData) {
     AEMU_SCOPED_TRACE("vkGetPrivateData");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkGetPrivateData(device, objectType, objectHandle, privateDataSlot, pData,
-                            true /* do lock */);
-}
-static void dynCheck_entry_vkGetPrivateData(VkDevice device, VkObjectType objectType,
-                                            uint64_t objectHandle,
-                                            VkPrivateDataSlot privateDataSlot, uint64_t* pData) {
-    auto resources = ResourceTracker::get();
-    if (resources->getApiVersionFromDevice(device) < VK_API_VERSION_1_3) {
-        sOnInvalidDynamicallyCheckedCall("vkGetPrivateData", "VK_VERSION_1_3");
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkEnc->vkGetPrivateData(gfxstream_device->internal_object, objectType, objectHandle,
+                                privateDataSlot, pData, true /* do lock */);
     }
-    AEMU_SCOPED_TRACE("vkGetPrivateData");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkGetPrivateData(device, objectType, objectHandle, privateDataSlot, pData,
-                            true /* do lock */);
 }
-static void entry_vkCmdSetEvent2(VkCommandBuffer commandBuffer, VkEvent event,
-                                 const VkDependencyInfo* pDependencyInfo) {
+void gfxstream_vk_CmdSetEvent2(VkCommandBuffer commandBuffer, VkEvent event,
+                               const VkDependencyInfo* pDependencyInfo) {
     AEMU_SCOPED_TRACE("vkCmdSetEvent2");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdSetEvent2(commandBuffer, event, pDependencyInfo, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    VK_FROM_HANDLE(gfxstream_vk_event, gfxstream_event, event);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        std::vector<VkDependencyInfo> internal_pDependencyInfo(1);
+        std::vector<std::vector<VkBufferMemoryBarrier2>>
+            internal_VkDependencyInfo_pBufferMemoryBarriers;
+        std::vector<std::vector<VkImageMemoryBarrier2>>
+            internal_VkDependencyInfo_pImageMemoryBarriers;
+        for (uint32_t i = 0; i < 1; ++i) {
+            internal_pDependencyInfo[i] = pDependencyInfo[i];
+            /* VkDependencyInfo::pBufferMemoryBarriers */
+            internal_VkDependencyInfo_pBufferMemoryBarriers.push_back(
+                std::vector<VkBufferMemoryBarrier2>());
+            internal_VkDependencyInfo_pBufferMemoryBarriers[i].reserve(
+                internal_pDependencyInfo[i].bufferMemoryBarrierCount);
+            memset(&internal_VkDependencyInfo_pBufferMemoryBarriers[i][0], 0,
+                   sizeof(VkBufferMemoryBarrier2) *
+                       internal_pDependencyInfo[i].bufferMemoryBarrierCount);
+            for (uint32_t j = 0; j < internal_pDependencyInfo[i].bufferMemoryBarrierCount; ++j) {
+                internal_VkDependencyInfo_pBufferMemoryBarriers[i][j] =
+                    internal_pDependencyInfo[i].pBufferMemoryBarriers[j];
+                /* VkBufferMemoryBarrier2::buffer */
+                VK_FROM_HANDLE(gfxstream_vk_buffer, gfxstream_buffer,
+                               internal_VkDependencyInfo_pBufferMemoryBarriers[i][j].buffer);
+                internal_VkDependencyInfo_pBufferMemoryBarriers[i][j].buffer =
+                    gfxstream_buffer->internal_object;
+            }
+            internal_pDependencyInfo[i].pBufferMemoryBarriers =
+                internal_VkDependencyInfo_pBufferMemoryBarriers[i].data();
+            /* VkDependencyInfo::pImageMemoryBarriers */
+            internal_VkDependencyInfo_pImageMemoryBarriers.push_back(
+                std::vector<VkImageMemoryBarrier2>());
+            internal_VkDependencyInfo_pImageMemoryBarriers[i].reserve(
+                internal_pDependencyInfo[i].imageMemoryBarrierCount);
+            memset(&internal_VkDependencyInfo_pImageMemoryBarriers[i][0], 0,
+                   sizeof(VkImageMemoryBarrier2) *
+                       internal_pDependencyInfo[i].imageMemoryBarrierCount);
+            for (uint32_t j = 0; j < internal_pDependencyInfo[i].imageMemoryBarrierCount; ++j) {
+                internal_VkDependencyInfo_pImageMemoryBarriers[i][j] =
+                    internal_pDependencyInfo[i].pImageMemoryBarriers[j];
+                /* VkImageMemoryBarrier2::image */
+                VK_FROM_HANDLE(gfxstream_vk_image, gfxstream_image,
+                               internal_VkDependencyInfo_pImageMemoryBarriers[i][j].image);
+                internal_VkDependencyInfo_pImageMemoryBarriers[i][j].image =
+                    gfxstream_image->internal_object;
+            }
+            internal_pDependencyInfo[i].pImageMemoryBarriers =
+                internal_VkDependencyInfo_pImageMemoryBarriers[i].data();
+        }
+        vkEnc->vkCmdSetEvent2(gfxstream_commandBuffer->internal_object,
+                              gfxstream_event->internal_object, internal_pDependencyInfo.data(),
+                              true /* do lock */);
+    }
 }
-static void entry_vkCmdResetEvent2(VkCommandBuffer commandBuffer, VkEvent event,
-                                   VkPipelineStageFlags2 stageMask) {
+void gfxstream_vk_CmdResetEvent2(VkCommandBuffer commandBuffer, VkEvent event,
+                                 VkPipelineStageFlags2 stageMask) {
     AEMU_SCOPED_TRACE("vkCmdResetEvent2");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdResetEvent2(commandBuffer, event, stageMask, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    VK_FROM_HANDLE(gfxstream_vk_event, gfxstream_event, event);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        vkEnc->vkCmdResetEvent2(gfxstream_commandBuffer->internal_object,
+                                gfxstream_event->internal_object, stageMask, true /* do lock */);
+    }
 }
-static void entry_vkCmdWaitEvents2(VkCommandBuffer commandBuffer, uint32_t eventCount,
-                                   const VkEvent* pEvents,
-                                   const VkDependencyInfo* pDependencyInfos) {
+void gfxstream_vk_CmdWaitEvents2(VkCommandBuffer commandBuffer, uint32_t eventCount,
+                                 const VkEvent* pEvents, const VkDependencyInfo* pDependencyInfos) {
     AEMU_SCOPED_TRACE("vkCmdWaitEvents2");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdWaitEvents2(commandBuffer, eventCount, pEvents, pDependencyInfos,
-                            true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        std::vector<VkEvent> internal_pEvents(eventCount);
+        for (uint32_t i = 0; i < eventCount; ++i) {
+            VK_FROM_HANDLE(gfxstream_vk_event, gfxstream_pEvents, pEvents[i]);
+            internal_pEvents[i] = gfxstream_pEvents->internal_object;
+        }
+        std::vector<VkDependencyInfo> internal_pDependencyInfos(eventCount);
+        std::vector<std::vector<VkBufferMemoryBarrier2>>
+            internal_VkDependencyInfo_pBufferMemoryBarriers;
+        std::vector<std::vector<VkImageMemoryBarrier2>>
+            internal_VkDependencyInfo_pImageMemoryBarriers;
+        for (uint32_t i = 0; i < eventCount; ++i) {
+            internal_pDependencyInfos[i] = pDependencyInfos[i];
+            /* VkDependencyInfo::pBufferMemoryBarriers */
+            internal_VkDependencyInfo_pBufferMemoryBarriers.push_back(
+                std::vector<VkBufferMemoryBarrier2>());
+            internal_VkDependencyInfo_pBufferMemoryBarriers[i].reserve(
+                internal_pDependencyInfos[i].bufferMemoryBarrierCount);
+            memset(&internal_VkDependencyInfo_pBufferMemoryBarriers[i][0], 0,
+                   sizeof(VkBufferMemoryBarrier2) *
+                       internal_pDependencyInfos[i].bufferMemoryBarrierCount);
+            for (uint32_t j = 0; j < internal_pDependencyInfos[i].bufferMemoryBarrierCount; ++j) {
+                internal_VkDependencyInfo_pBufferMemoryBarriers[i][j] =
+                    internal_pDependencyInfos[i].pBufferMemoryBarriers[j];
+                /* VkBufferMemoryBarrier2::buffer */
+                VK_FROM_HANDLE(gfxstream_vk_buffer, gfxstream_buffer,
+                               internal_VkDependencyInfo_pBufferMemoryBarriers[i][j].buffer);
+                internal_VkDependencyInfo_pBufferMemoryBarriers[i][j].buffer =
+                    gfxstream_buffer->internal_object;
+            }
+            internal_pDependencyInfos[i].pBufferMemoryBarriers =
+                internal_VkDependencyInfo_pBufferMemoryBarriers[i].data();
+            /* VkDependencyInfo::pImageMemoryBarriers */
+            internal_VkDependencyInfo_pImageMemoryBarriers.push_back(
+                std::vector<VkImageMemoryBarrier2>());
+            internal_VkDependencyInfo_pImageMemoryBarriers[i].reserve(
+                internal_pDependencyInfos[i].imageMemoryBarrierCount);
+            memset(&internal_VkDependencyInfo_pImageMemoryBarriers[i][0], 0,
+                   sizeof(VkImageMemoryBarrier2) *
+                       internal_pDependencyInfos[i].imageMemoryBarrierCount);
+            for (uint32_t j = 0; j < internal_pDependencyInfos[i].imageMemoryBarrierCount; ++j) {
+                internal_VkDependencyInfo_pImageMemoryBarriers[i][j] =
+                    internal_pDependencyInfos[i].pImageMemoryBarriers[j];
+                /* VkImageMemoryBarrier2::image */
+                VK_FROM_HANDLE(gfxstream_vk_image, gfxstream_image,
+                               internal_VkDependencyInfo_pImageMemoryBarriers[i][j].image);
+                internal_VkDependencyInfo_pImageMemoryBarriers[i][j].image =
+                    gfxstream_image->internal_object;
+            }
+            internal_pDependencyInfos[i].pImageMemoryBarriers =
+                internal_VkDependencyInfo_pImageMemoryBarriers[i].data();
+        }
+        vkEnc->vkCmdWaitEvents2(gfxstream_commandBuffer->internal_object, eventCount,
+                                internal_pEvents.data(), internal_pDependencyInfos.data(),
+                                true /* do lock */);
+    }
 }
-static void entry_vkCmdPipelineBarrier2(VkCommandBuffer commandBuffer,
-                                        const VkDependencyInfo* pDependencyInfo) {
+void gfxstream_vk_CmdPipelineBarrier2(VkCommandBuffer commandBuffer,
+                                      const VkDependencyInfo* pDependencyInfo) {
     AEMU_SCOPED_TRACE("vkCmdPipelineBarrier2");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdPipelineBarrier2(commandBuffer, pDependencyInfo, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        std::vector<VkDependencyInfo> internal_pDependencyInfo(1);
+        std::vector<std::vector<VkBufferMemoryBarrier2>>
+            internal_VkDependencyInfo_pBufferMemoryBarriers;
+        std::vector<std::vector<VkImageMemoryBarrier2>>
+            internal_VkDependencyInfo_pImageMemoryBarriers;
+        for (uint32_t i = 0; i < 1; ++i) {
+            internal_pDependencyInfo[i] = pDependencyInfo[i];
+            /* VkDependencyInfo::pBufferMemoryBarriers */
+            internal_VkDependencyInfo_pBufferMemoryBarriers.push_back(
+                std::vector<VkBufferMemoryBarrier2>());
+            internal_VkDependencyInfo_pBufferMemoryBarriers[i].reserve(
+                internal_pDependencyInfo[i].bufferMemoryBarrierCount);
+            memset(&internal_VkDependencyInfo_pBufferMemoryBarriers[i][0], 0,
+                   sizeof(VkBufferMemoryBarrier2) *
+                       internal_pDependencyInfo[i].bufferMemoryBarrierCount);
+            for (uint32_t j = 0; j < internal_pDependencyInfo[i].bufferMemoryBarrierCount; ++j) {
+                internal_VkDependencyInfo_pBufferMemoryBarriers[i][j] =
+                    internal_pDependencyInfo[i].pBufferMemoryBarriers[j];
+                /* VkBufferMemoryBarrier2::buffer */
+                VK_FROM_HANDLE(gfxstream_vk_buffer, gfxstream_buffer,
+                               internal_VkDependencyInfo_pBufferMemoryBarriers[i][j].buffer);
+                internal_VkDependencyInfo_pBufferMemoryBarriers[i][j].buffer =
+                    gfxstream_buffer->internal_object;
+            }
+            internal_pDependencyInfo[i].pBufferMemoryBarriers =
+                internal_VkDependencyInfo_pBufferMemoryBarriers[i].data();
+            /* VkDependencyInfo::pImageMemoryBarriers */
+            internal_VkDependencyInfo_pImageMemoryBarriers.push_back(
+                std::vector<VkImageMemoryBarrier2>());
+            internal_VkDependencyInfo_pImageMemoryBarriers[i].reserve(
+                internal_pDependencyInfo[i].imageMemoryBarrierCount);
+            memset(&internal_VkDependencyInfo_pImageMemoryBarriers[i][0], 0,
+                   sizeof(VkImageMemoryBarrier2) *
+                       internal_pDependencyInfo[i].imageMemoryBarrierCount);
+            for (uint32_t j = 0; j < internal_pDependencyInfo[i].imageMemoryBarrierCount; ++j) {
+                internal_VkDependencyInfo_pImageMemoryBarriers[i][j] =
+                    internal_pDependencyInfo[i].pImageMemoryBarriers[j];
+                /* VkImageMemoryBarrier2::image */
+                VK_FROM_HANDLE(gfxstream_vk_image, gfxstream_image,
+                               internal_VkDependencyInfo_pImageMemoryBarriers[i][j].image);
+                internal_VkDependencyInfo_pImageMemoryBarriers[i][j].image =
+                    gfxstream_image->internal_object;
+            }
+            internal_pDependencyInfo[i].pImageMemoryBarriers =
+                internal_VkDependencyInfo_pImageMemoryBarriers[i].data();
+        }
+        vkEnc->vkCmdPipelineBarrier2(gfxstream_commandBuffer->internal_object,
+                                     internal_pDependencyInfo.data(), true /* do lock */);
+    }
 }
-static void entry_vkCmdWriteTimestamp2(VkCommandBuffer commandBuffer, VkPipelineStageFlags2 stage,
-                                       VkQueryPool queryPool, uint32_t query) {
+void gfxstream_vk_CmdWriteTimestamp2(VkCommandBuffer commandBuffer, VkPipelineStageFlags2 stage,
+                                     VkQueryPool queryPool, uint32_t query) {
     AEMU_SCOPED_TRACE("vkCmdWriteTimestamp2");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdWriteTimestamp2(commandBuffer, stage, queryPool, query, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    VK_FROM_HANDLE(gfxstream_vk_query_pool, gfxstream_queryPool, queryPool);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        vkEnc->vkCmdWriteTimestamp2(gfxstream_commandBuffer->internal_object, stage,
+                                    gfxstream_queryPool->internal_object, query,
+                                    true /* do lock */);
+    }
 }
-static VkResult entry_vkQueueSubmit2(VkQueue queue, uint32_t submitCount,
-                                     const VkSubmitInfo2* pSubmits, VkFence fence) {
+VkResult gfxstream_vk_QueueSubmit2(VkQueue queue, uint32_t submitCount,
+                                   const VkSubmitInfo2* pSubmits, VkFence fence) {
     AEMU_SCOPED_TRACE("vkQueueSubmit2");
-    auto vkEnc = ResourceTracker::getQueueEncoder(queue);
     VkResult vkQueueSubmit2_VkResult_return = (VkResult)0;
-    auto resources = ResourceTracker::get();
-    vkQueueSubmit2_VkResult_return =
-        resources->on_vkQueueSubmit2(vkEnc, VK_SUCCESS, queue, submitCount, pSubmits, fence);
+    VK_FROM_HANDLE(gfxstream_vk_queue, gfxstream_queue, queue);
+    VK_FROM_HANDLE(gfxstream_vk_fence, gfxstream_fence, fence);
+    {
+        auto vkEnc =
+            gfxstream::vk::ResourceTracker::getQueueEncoder(gfxstream_queue->internal_object);
+        std::vector<VkSubmitInfo2> internal_pSubmits(submitCount);
+        std::vector<std::vector<VkSemaphoreSubmitInfo>> internal_VkSubmitInfo2_pWaitSemaphoreInfos;
+        std::vector<std::vector<VkCommandBufferSubmitInfo>>
+            internal_VkSubmitInfo2_pCommandBufferInfos;
+        std::vector<std::vector<VkSemaphoreSubmitInfo>>
+            internal_VkSubmitInfo2_pSignalSemaphoreInfos;
+        for (uint32_t i = 0; i < submitCount; ++i) {
+            internal_pSubmits[i] = pSubmits[i];
+            /* VkSubmitInfo2::pWaitSemaphoreInfos */
+            internal_VkSubmitInfo2_pWaitSemaphoreInfos.push_back(
+                std::vector<VkSemaphoreSubmitInfo>());
+            internal_VkSubmitInfo2_pWaitSemaphoreInfos[i] =
+                transformVkSemaphoreSubmitInfoList(internal_pSubmits[i].pWaitSemaphoreInfos,
+                                                   internal_pSubmits[i].waitSemaphoreInfoCount);
+            internal_pSubmits[i].pWaitSemaphoreInfos =
+                internal_VkSubmitInfo2_pWaitSemaphoreInfos[i].data();
+            internal_pSubmits[i].waitSemaphoreInfoCount =
+                internal_VkSubmitInfo2_pWaitSemaphoreInfos[i].size();
+            /* VkSubmitInfo2::pCommandBufferInfos */
+            internal_VkSubmitInfo2_pCommandBufferInfos.push_back(
+                std::vector<VkCommandBufferSubmitInfo>());
+            internal_VkSubmitInfo2_pCommandBufferInfos[i].reserve(
+                internal_pSubmits[i].commandBufferInfoCount);
+            memset(&internal_VkSubmitInfo2_pCommandBufferInfos[i][0], 0,
+                   sizeof(VkCommandBufferSubmitInfo) * internal_pSubmits[i].commandBufferInfoCount);
+            for (uint32_t j = 0; j < internal_pSubmits[i].commandBufferInfoCount; ++j) {
+                internal_VkSubmitInfo2_pCommandBufferInfos[i][j] =
+                    internal_pSubmits[i].pCommandBufferInfos[j];
+                /* VkCommandBufferSubmitInfo::commandBuffer */
+                VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer,
+                               internal_VkSubmitInfo2_pCommandBufferInfos[i][j].commandBuffer);
+                internal_VkSubmitInfo2_pCommandBufferInfos[i][j].commandBuffer =
+                    gfxstream_commandBuffer->internal_object;
+            }
+            internal_pSubmits[i].pCommandBufferInfos =
+                internal_VkSubmitInfo2_pCommandBufferInfos[i].data();
+            /* VkSubmitInfo2::pSignalSemaphoreInfos */
+            internal_VkSubmitInfo2_pSignalSemaphoreInfos.push_back(
+                std::vector<VkSemaphoreSubmitInfo>());
+            internal_VkSubmitInfo2_pSignalSemaphoreInfos[i] =
+                transformVkSemaphoreSubmitInfoList(internal_pSubmits[i].pSignalSemaphoreInfos,
+                                                   internal_pSubmits[i].signalSemaphoreInfoCount);
+            internal_pSubmits[i].pSignalSemaphoreInfos =
+                internal_VkSubmitInfo2_pSignalSemaphoreInfos[i].data();
+            internal_pSubmits[i].signalSemaphoreInfoCount =
+                internal_VkSubmitInfo2_pSignalSemaphoreInfos[i].size();
+        }
+        auto resources = gfxstream::vk::ResourceTracker::get();
+        vkQueueSubmit2_VkResult_return = resources->on_vkQueueSubmit2(
+            vkEnc, VK_SUCCESS, gfxstream_queue->internal_object, submitCount,
+            internal_pSubmits.data(),
+            gfxstream_fence ? gfxstream_fence->internal_object : VK_NULL_HANDLE);
+    }
     return vkQueueSubmit2_VkResult_return;
 }
-static void entry_vkCmdCopyBuffer2(VkCommandBuffer commandBuffer,
-                                   const VkCopyBufferInfo2* pCopyBufferInfo) {
+void gfxstream_vk_CmdCopyBuffer2(VkCommandBuffer commandBuffer,
+                                 const VkCopyBufferInfo2* pCopyBufferInfo) {
     AEMU_SCOPED_TRACE("vkCmdCopyBuffer2");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdCopyBuffer2(commandBuffer, pCopyBufferInfo, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        std::vector<VkCopyBufferInfo2> internal_pCopyBufferInfo(1);
+        for (uint32_t i = 0; i < 1; ++i) {
+            internal_pCopyBufferInfo[i] = pCopyBufferInfo[i];
+            /* VkCopyBufferInfo2::srcBuffer */
+            VK_FROM_HANDLE(gfxstream_vk_buffer, gfxstream_srcBuffer,
+                           internal_pCopyBufferInfo[i].srcBuffer);
+            internal_pCopyBufferInfo[i].srcBuffer = gfxstream_srcBuffer->internal_object;
+            /* VkCopyBufferInfo2::dstBuffer */
+            VK_FROM_HANDLE(gfxstream_vk_buffer, gfxstream_dstBuffer,
+                           internal_pCopyBufferInfo[i].dstBuffer);
+            internal_pCopyBufferInfo[i].dstBuffer = gfxstream_dstBuffer->internal_object;
+        }
+        vkEnc->vkCmdCopyBuffer2(gfxstream_commandBuffer->internal_object,
+                                internal_pCopyBufferInfo.data(), true /* do lock */);
+    }
 }
-static void entry_vkCmdCopyImage2(VkCommandBuffer commandBuffer,
-                                  const VkCopyImageInfo2* pCopyImageInfo) {
+void gfxstream_vk_CmdCopyImage2(VkCommandBuffer commandBuffer,
+                                const VkCopyImageInfo2* pCopyImageInfo) {
     AEMU_SCOPED_TRACE("vkCmdCopyImage2");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdCopyImage2(commandBuffer, pCopyImageInfo, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        std::vector<VkCopyImageInfo2> internal_pCopyImageInfo(1);
+        for (uint32_t i = 0; i < 1; ++i) {
+            internal_pCopyImageInfo[i] = pCopyImageInfo[i];
+            /* VkCopyImageInfo2::srcImage */
+            VK_FROM_HANDLE(gfxstream_vk_image, gfxstream_srcImage,
+                           internal_pCopyImageInfo[i].srcImage);
+            internal_pCopyImageInfo[i].srcImage = gfxstream_srcImage->internal_object;
+            /* VkCopyImageInfo2::dstImage */
+            VK_FROM_HANDLE(gfxstream_vk_image, gfxstream_dstImage,
+                           internal_pCopyImageInfo[i].dstImage);
+            internal_pCopyImageInfo[i].dstImage = gfxstream_dstImage->internal_object;
+        }
+        vkEnc->vkCmdCopyImage2(gfxstream_commandBuffer->internal_object,
+                               internal_pCopyImageInfo.data(), true /* do lock */);
+    }
 }
-static void entry_vkCmdCopyBufferToImage2(VkCommandBuffer commandBuffer,
-                                          const VkCopyBufferToImageInfo2* pCopyBufferToImageInfo) {
+void gfxstream_vk_CmdCopyBufferToImage2(VkCommandBuffer commandBuffer,
+                                        const VkCopyBufferToImageInfo2* pCopyBufferToImageInfo) {
     AEMU_SCOPED_TRACE("vkCmdCopyBufferToImage2");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdCopyBufferToImage2(commandBuffer, pCopyBufferToImageInfo, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        std::vector<VkCopyBufferToImageInfo2> internal_pCopyBufferToImageInfo(1);
+        for (uint32_t i = 0; i < 1; ++i) {
+            internal_pCopyBufferToImageInfo[i] = pCopyBufferToImageInfo[i];
+            /* VkCopyBufferToImageInfo2::srcBuffer */
+            VK_FROM_HANDLE(gfxstream_vk_buffer, gfxstream_srcBuffer,
+                           internal_pCopyBufferToImageInfo[i].srcBuffer);
+            internal_pCopyBufferToImageInfo[i].srcBuffer = gfxstream_srcBuffer->internal_object;
+            /* VkCopyBufferToImageInfo2::dstImage */
+            VK_FROM_HANDLE(gfxstream_vk_image, gfxstream_dstImage,
+                           internal_pCopyBufferToImageInfo[i].dstImage);
+            internal_pCopyBufferToImageInfo[i].dstImage = gfxstream_dstImage->internal_object;
+        }
+        vkEnc->vkCmdCopyBufferToImage2(gfxstream_commandBuffer->internal_object,
+                                       internal_pCopyBufferToImageInfo.data(), true /* do lock */);
+    }
 }
-static void entry_vkCmdCopyImageToBuffer2(VkCommandBuffer commandBuffer,
-                                          const VkCopyImageToBufferInfo2* pCopyImageToBufferInfo) {
+void gfxstream_vk_CmdCopyImageToBuffer2(VkCommandBuffer commandBuffer,
+                                        const VkCopyImageToBufferInfo2* pCopyImageToBufferInfo) {
     AEMU_SCOPED_TRACE("vkCmdCopyImageToBuffer2");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdCopyImageToBuffer2(commandBuffer, pCopyImageToBufferInfo, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        std::vector<VkCopyImageToBufferInfo2> internal_pCopyImageToBufferInfo(1);
+        for (uint32_t i = 0; i < 1; ++i) {
+            internal_pCopyImageToBufferInfo[i] = pCopyImageToBufferInfo[i];
+            /* VkCopyImageToBufferInfo2::srcImage */
+            VK_FROM_HANDLE(gfxstream_vk_image, gfxstream_srcImage,
+                           internal_pCopyImageToBufferInfo[i].srcImage);
+            internal_pCopyImageToBufferInfo[i].srcImage = gfxstream_srcImage->internal_object;
+            /* VkCopyImageToBufferInfo2::dstBuffer */
+            VK_FROM_HANDLE(gfxstream_vk_buffer, gfxstream_dstBuffer,
+                           internal_pCopyImageToBufferInfo[i].dstBuffer);
+            internal_pCopyImageToBufferInfo[i].dstBuffer = gfxstream_dstBuffer->internal_object;
+        }
+        vkEnc->vkCmdCopyImageToBuffer2(gfxstream_commandBuffer->internal_object,
+                                       internal_pCopyImageToBufferInfo.data(), true /* do lock */);
+    }
 }
-static void entry_vkCmdBlitImage2(VkCommandBuffer commandBuffer,
-                                  const VkBlitImageInfo2* pBlitImageInfo) {
+void gfxstream_vk_CmdBlitImage2(VkCommandBuffer commandBuffer,
+                                const VkBlitImageInfo2* pBlitImageInfo) {
     AEMU_SCOPED_TRACE("vkCmdBlitImage2");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdBlitImage2(commandBuffer, pBlitImageInfo, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        std::vector<VkBlitImageInfo2> internal_pBlitImageInfo(1);
+        for (uint32_t i = 0; i < 1; ++i) {
+            internal_pBlitImageInfo[i] = pBlitImageInfo[i];
+            /* VkBlitImageInfo2::srcImage */
+            VK_FROM_HANDLE(gfxstream_vk_image, gfxstream_srcImage,
+                           internal_pBlitImageInfo[i].srcImage);
+            internal_pBlitImageInfo[i].srcImage = gfxstream_srcImage->internal_object;
+            /* VkBlitImageInfo2::dstImage */
+            VK_FROM_HANDLE(gfxstream_vk_image, gfxstream_dstImage,
+                           internal_pBlitImageInfo[i].dstImage);
+            internal_pBlitImageInfo[i].dstImage = gfxstream_dstImage->internal_object;
+        }
+        vkEnc->vkCmdBlitImage2(gfxstream_commandBuffer->internal_object,
+                               internal_pBlitImageInfo.data(), true /* do lock */);
+    }
 }
-static void entry_vkCmdResolveImage2(VkCommandBuffer commandBuffer,
-                                     const VkResolveImageInfo2* pResolveImageInfo) {
+void gfxstream_vk_CmdResolveImage2(VkCommandBuffer commandBuffer,
+                                   const VkResolveImageInfo2* pResolveImageInfo) {
     AEMU_SCOPED_TRACE("vkCmdResolveImage2");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdResolveImage2(commandBuffer, pResolveImageInfo, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        std::vector<VkResolveImageInfo2> internal_pResolveImageInfo(1);
+        for (uint32_t i = 0; i < 1; ++i) {
+            internal_pResolveImageInfo[i] = pResolveImageInfo[i];
+            /* VkResolveImageInfo2::srcImage */
+            VK_FROM_HANDLE(gfxstream_vk_image, gfxstream_srcImage,
+                           internal_pResolveImageInfo[i].srcImage);
+            internal_pResolveImageInfo[i].srcImage = gfxstream_srcImage->internal_object;
+            /* VkResolveImageInfo2::dstImage */
+            VK_FROM_HANDLE(gfxstream_vk_image, gfxstream_dstImage,
+                           internal_pResolveImageInfo[i].dstImage);
+            internal_pResolveImageInfo[i].dstImage = gfxstream_dstImage->internal_object;
+        }
+        vkEnc->vkCmdResolveImage2(gfxstream_commandBuffer->internal_object,
+                                  internal_pResolveImageInfo.data(), true /* do lock */);
+    }
 }
-static void entry_vkCmdBeginRendering(VkCommandBuffer commandBuffer,
-                                      const VkRenderingInfo* pRenderingInfo) {
+void gfxstream_vk_CmdBeginRendering(VkCommandBuffer commandBuffer,
+                                    const VkRenderingInfo* pRenderingInfo) {
     AEMU_SCOPED_TRACE("vkCmdBeginRendering");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdBeginRendering(commandBuffer, pRenderingInfo, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        std::vector<VkRenderingInfo> internal_pRenderingInfo(1);
+        std::vector<std::vector<VkRenderingAttachmentInfo>>
+            internal_VkRenderingInfo_pColorAttachments;
+        std::vector<VkRenderingAttachmentInfo> internal_VkRenderingInfo_pDepthAttachment;
+        std::vector<VkRenderingAttachmentInfo> internal_VkRenderingInfo_pStencilAttachment;
+        for (uint32_t i = 0; i < 1; ++i) {
+            internal_pRenderingInfo[i] = pRenderingInfo[i];
+            /* VkRenderingInfo::pColorAttachments */
+            internal_VkRenderingInfo_pColorAttachments.push_back(
+                std::vector<VkRenderingAttachmentInfo>());
+            internal_VkRenderingInfo_pColorAttachments[i].reserve(
+                internal_pRenderingInfo[i].colorAttachmentCount);
+            memset(&internal_VkRenderingInfo_pColorAttachments[i][0], 0,
+                   sizeof(VkRenderingAttachmentInfo) *
+                       internal_pRenderingInfo[i].colorAttachmentCount);
+            for (uint32_t j = 0; j < internal_pRenderingInfo[i].colorAttachmentCount; ++j) {
+                internal_VkRenderingInfo_pColorAttachments[i][j] =
+                    internal_pRenderingInfo[i].pColorAttachments[j];
+                /* VkRenderingAttachmentInfo::imageView */
+                if (internal_VkRenderingInfo_pColorAttachments[i][j].imageView) {
+                    VK_FROM_HANDLE(gfxstream_vk_image_view, gfxstream_imageView,
+                                   internal_VkRenderingInfo_pColorAttachments[i][j].imageView);
+                    internal_VkRenderingInfo_pColorAttachments[i][j].imageView =
+                        gfxstream_imageView->internal_object;
+                }
+                /* VkRenderingAttachmentInfo::resolveImageView */
+                if (internal_VkRenderingInfo_pColorAttachments[i][j].resolveImageView) {
+                    VK_FROM_HANDLE(
+                        gfxstream_vk_image_view, gfxstream_resolveImageView,
+                        internal_VkRenderingInfo_pColorAttachments[i][j].resolveImageView);
+                    internal_VkRenderingInfo_pColorAttachments[i][j].resolveImageView =
+                        gfxstream_resolveImageView->internal_object;
+                }
+            }
+            internal_pRenderingInfo[i].pColorAttachments =
+                internal_VkRenderingInfo_pColorAttachments[i].data();
+            /* VkRenderingInfo::pDepthAttachment */
+            if (internal_pRenderingInfo[i].pDepthAttachment) {
+                internal_VkRenderingInfo_pDepthAttachment[i] =
+                    internal_pRenderingInfo[i].pDepthAttachment[0];
+                /* VkRenderingAttachmentInfo::imageView */
+                if (internal_VkRenderingInfo_pDepthAttachment[i].imageView) {
+                    VK_FROM_HANDLE(gfxstream_vk_image_view, gfxstream_imageView,
+                                   internal_VkRenderingInfo_pDepthAttachment[i].imageView);
+                    internal_VkRenderingInfo_pDepthAttachment[i].imageView =
+                        gfxstream_imageView->internal_object;
+                }
+                /* VkRenderingAttachmentInfo::resolveImageView */
+                if (internal_VkRenderingInfo_pDepthAttachment[i].resolveImageView) {
+                    VK_FROM_HANDLE(gfxstream_vk_image_view, gfxstream_resolveImageView,
+                                   internal_VkRenderingInfo_pDepthAttachment[i].resolveImageView);
+                    internal_VkRenderingInfo_pDepthAttachment[i].resolveImageView =
+                        gfxstream_resolveImageView->internal_object;
+                }
+                internal_pRenderingInfo[i].pDepthAttachment =
+                    &internal_VkRenderingInfo_pDepthAttachment[i];
+            }
+            /* VkRenderingInfo::pStencilAttachment */
+            if (internal_pRenderingInfo[i].pStencilAttachment) {
+                internal_VkRenderingInfo_pStencilAttachment[i] =
+                    internal_pRenderingInfo[i].pStencilAttachment[0];
+                /* VkRenderingAttachmentInfo::imageView */
+                if (internal_VkRenderingInfo_pStencilAttachment[i].imageView) {
+                    VK_FROM_HANDLE(gfxstream_vk_image_view, gfxstream_imageView,
+                                   internal_VkRenderingInfo_pStencilAttachment[i].imageView);
+                    internal_VkRenderingInfo_pStencilAttachment[i].imageView =
+                        gfxstream_imageView->internal_object;
+                }
+                /* VkRenderingAttachmentInfo::resolveImageView */
+                if (internal_VkRenderingInfo_pStencilAttachment[i].resolveImageView) {
+                    VK_FROM_HANDLE(gfxstream_vk_image_view, gfxstream_resolveImageView,
+                                   internal_VkRenderingInfo_pStencilAttachment[i].resolveImageView);
+                    internal_VkRenderingInfo_pStencilAttachment[i].resolveImageView =
+                        gfxstream_resolveImageView->internal_object;
+                }
+                internal_pRenderingInfo[i].pStencilAttachment =
+                    &internal_VkRenderingInfo_pStencilAttachment[i];
+            }
+        }
+        vkEnc->vkCmdBeginRendering(gfxstream_commandBuffer->internal_object,
+                                   internal_pRenderingInfo.data(), true /* do lock */);
+    }
 }
-static void entry_vkCmdEndRendering(VkCommandBuffer commandBuffer) {
+void gfxstream_vk_CmdEndRendering(VkCommandBuffer commandBuffer) {
     AEMU_SCOPED_TRACE("vkCmdEndRendering");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdEndRendering(commandBuffer, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        vkEnc->vkCmdEndRendering(gfxstream_commandBuffer->internal_object, true /* do lock */);
+    }
 }
-static void entry_vkCmdSetCullMode(VkCommandBuffer commandBuffer, VkCullModeFlags cullMode) {
+void gfxstream_vk_CmdSetCullMode(VkCommandBuffer commandBuffer, VkCullModeFlags cullMode) {
     AEMU_SCOPED_TRACE("vkCmdSetCullMode");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdSetCullMode(commandBuffer, cullMode, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        vkEnc->vkCmdSetCullMode(gfxstream_commandBuffer->internal_object, cullMode,
+                                true /* do lock */);
+    }
 }
-static void entry_vkCmdSetFrontFace(VkCommandBuffer commandBuffer, VkFrontFace frontFace) {
+void gfxstream_vk_CmdSetFrontFace(VkCommandBuffer commandBuffer, VkFrontFace frontFace) {
     AEMU_SCOPED_TRACE("vkCmdSetFrontFace");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdSetFrontFace(commandBuffer, frontFace, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        vkEnc->vkCmdSetFrontFace(gfxstream_commandBuffer->internal_object, frontFace,
+                                 true /* do lock */);
+    }
 }
-static void entry_vkCmdSetPrimitiveTopology(VkCommandBuffer commandBuffer,
-                                            VkPrimitiveTopology primitiveTopology) {
+void gfxstream_vk_CmdSetPrimitiveTopology(VkCommandBuffer commandBuffer,
+                                          VkPrimitiveTopology primitiveTopology) {
     AEMU_SCOPED_TRACE("vkCmdSetPrimitiveTopology");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdSetPrimitiveTopology(commandBuffer, primitiveTopology, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        vkEnc->vkCmdSetPrimitiveTopology(gfxstream_commandBuffer->internal_object,
+                                         primitiveTopology, true /* do lock */);
+    }
 }
-static void entry_vkCmdSetViewportWithCount(VkCommandBuffer commandBuffer, uint32_t viewportCount,
-                                            const VkViewport* pViewports) {
+void gfxstream_vk_CmdSetViewportWithCount(VkCommandBuffer commandBuffer, uint32_t viewportCount,
+                                          const VkViewport* pViewports) {
     AEMU_SCOPED_TRACE("vkCmdSetViewportWithCount");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdSetViewportWithCount(commandBuffer, viewportCount, pViewports, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        vkEnc->vkCmdSetViewportWithCount(gfxstream_commandBuffer->internal_object, viewportCount,
+                                         pViewports, true /* do lock */);
+    }
 }
-static void entry_vkCmdSetScissorWithCount(VkCommandBuffer commandBuffer, uint32_t scissorCount,
-                                           const VkRect2D* pScissors) {
+void gfxstream_vk_CmdSetScissorWithCount(VkCommandBuffer commandBuffer, uint32_t scissorCount,
+                                         const VkRect2D* pScissors) {
     AEMU_SCOPED_TRACE("vkCmdSetScissorWithCount");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdSetScissorWithCount(commandBuffer, scissorCount, pScissors, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        vkEnc->vkCmdSetScissorWithCount(gfxstream_commandBuffer->internal_object, scissorCount,
+                                        pScissors, true /* do lock */);
+    }
 }
-static void entry_vkCmdBindVertexBuffers2(VkCommandBuffer commandBuffer, uint32_t firstBinding,
-                                          uint32_t bindingCount, const VkBuffer* pBuffers,
-                                          const VkDeviceSize* pOffsets, const VkDeviceSize* pSizes,
-                                          const VkDeviceSize* pStrides) {
+void gfxstream_vk_CmdBindVertexBuffers2(VkCommandBuffer commandBuffer, uint32_t firstBinding,
+                                        uint32_t bindingCount, const VkBuffer* pBuffers,
+                                        const VkDeviceSize* pOffsets, const VkDeviceSize* pSizes,
+                                        const VkDeviceSize* pStrides) {
     AEMU_SCOPED_TRACE("vkCmdBindVertexBuffers2");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdBindVertexBuffers2(commandBuffer, firstBinding, bindingCount, pBuffers, pOffsets,
-                                   pSizes, pStrides, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        std::vector<VkBuffer> internal_pBuffers(bindingCount);
+        for (uint32_t i = 0; i < bindingCount; ++i) {
+            if (pBuffers) {
+                VK_FROM_HANDLE(gfxstream_vk_buffer, gfxstream_pBuffers, pBuffers[i]);
+                internal_pBuffers[i] = gfxstream_pBuffers->internal_object;
+            }
+        }
+        vkEnc->vkCmdBindVertexBuffers2(gfxstream_commandBuffer->internal_object, firstBinding,
+                                       bindingCount, internal_pBuffers.data(), pOffsets, pSizes,
+                                       pStrides, true /* do lock */);
+    }
 }
-static void entry_vkCmdSetDepthTestEnable(VkCommandBuffer commandBuffer, VkBool32 depthTestEnable) {
+void gfxstream_vk_CmdSetDepthTestEnable(VkCommandBuffer commandBuffer, VkBool32 depthTestEnable) {
     AEMU_SCOPED_TRACE("vkCmdSetDepthTestEnable");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdSetDepthTestEnable(commandBuffer, depthTestEnable, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        vkEnc->vkCmdSetDepthTestEnable(gfxstream_commandBuffer->internal_object, depthTestEnable,
+                                       true /* do lock */);
+    }
 }
-static void entry_vkCmdSetDepthWriteEnable(VkCommandBuffer commandBuffer,
-                                           VkBool32 depthWriteEnable) {
+void gfxstream_vk_CmdSetDepthWriteEnable(VkCommandBuffer commandBuffer, VkBool32 depthWriteEnable) {
     AEMU_SCOPED_TRACE("vkCmdSetDepthWriteEnable");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdSetDepthWriteEnable(commandBuffer, depthWriteEnable, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        vkEnc->vkCmdSetDepthWriteEnable(gfxstream_commandBuffer->internal_object, depthWriteEnable,
+                                        true /* do lock */);
+    }
 }
-static void entry_vkCmdSetDepthCompareOp(VkCommandBuffer commandBuffer,
-                                         VkCompareOp depthCompareOp) {
+void gfxstream_vk_CmdSetDepthCompareOp(VkCommandBuffer commandBuffer, VkCompareOp depthCompareOp) {
     AEMU_SCOPED_TRACE("vkCmdSetDepthCompareOp");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdSetDepthCompareOp(commandBuffer, depthCompareOp, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        vkEnc->vkCmdSetDepthCompareOp(gfxstream_commandBuffer->internal_object, depthCompareOp,
+                                      true /* do lock */);
+    }
 }
-static void entry_vkCmdSetDepthBoundsTestEnable(VkCommandBuffer commandBuffer,
-                                                VkBool32 depthBoundsTestEnable) {
+void gfxstream_vk_CmdSetDepthBoundsTestEnable(VkCommandBuffer commandBuffer,
+                                              VkBool32 depthBoundsTestEnable) {
     AEMU_SCOPED_TRACE("vkCmdSetDepthBoundsTestEnable");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdSetDepthBoundsTestEnable(commandBuffer, depthBoundsTestEnable, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        vkEnc->vkCmdSetDepthBoundsTestEnable(gfxstream_commandBuffer->internal_object,
+                                             depthBoundsTestEnable, true /* do lock */);
+    }
 }
-static void entry_vkCmdSetStencilTestEnable(VkCommandBuffer commandBuffer,
-                                            VkBool32 stencilTestEnable) {
+void gfxstream_vk_CmdSetStencilTestEnable(VkCommandBuffer commandBuffer,
+                                          VkBool32 stencilTestEnable) {
     AEMU_SCOPED_TRACE("vkCmdSetStencilTestEnable");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdSetStencilTestEnable(commandBuffer, stencilTestEnable, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        vkEnc->vkCmdSetStencilTestEnable(gfxstream_commandBuffer->internal_object,
+                                         stencilTestEnable, true /* do lock */);
+    }
 }
-static void entry_vkCmdSetStencilOp(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask,
-                                    VkStencilOp failOp, VkStencilOp passOp, VkStencilOp depthFailOp,
-                                    VkCompareOp compareOp) {
+void gfxstream_vk_CmdSetStencilOp(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask,
+                                  VkStencilOp failOp, VkStencilOp passOp, VkStencilOp depthFailOp,
+                                  VkCompareOp compareOp) {
     AEMU_SCOPED_TRACE("vkCmdSetStencilOp");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdSetStencilOp(commandBuffer, faceMask, failOp, passOp, depthFailOp, compareOp,
-                             true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        vkEnc->vkCmdSetStencilOp(gfxstream_commandBuffer->internal_object, faceMask, failOp, passOp,
+                                 depthFailOp, compareOp, true /* do lock */);
+    }
 }
-static void entry_vkCmdSetRasterizerDiscardEnable(VkCommandBuffer commandBuffer,
-                                                  VkBool32 rasterizerDiscardEnable) {
+void gfxstream_vk_CmdSetRasterizerDiscardEnable(VkCommandBuffer commandBuffer,
+                                                VkBool32 rasterizerDiscardEnable) {
     AEMU_SCOPED_TRACE("vkCmdSetRasterizerDiscardEnable");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdSetRasterizerDiscardEnable(commandBuffer, rasterizerDiscardEnable,
-                                           true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        vkEnc->vkCmdSetRasterizerDiscardEnable(gfxstream_commandBuffer->internal_object,
+                                               rasterizerDiscardEnable, true /* do lock */);
+    }
 }
-static void entry_vkCmdSetDepthBiasEnable(VkCommandBuffer commandBuffer, VkBool32 depthBiasEnable) {
+void gfxstream_vk_CmdSetDepthBiasEnable(VkCommandBuffer commandBuffer, VkBool32 depthBiasEnable) {
     AEMU_SCOPED_TRACE("vkCmdSetDepthBiasEnable");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdSetDepthBiasEnable(commandBuffer, depthBiasEnable, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        vkEnc->vkCmdSetDepthBiasEnable(gfxstream_commandBuffer->internal_object, depthBiasEnable,
+                                       true /* do lock */);
+    }
 }
-static void entry_vkCmdSetPrimitiveRestartEnable(VkCommandBuffer commandBuffer,
-                                                 VkBool32 primitiveRestartEnable) {
+void gfxstream_vk_CmdSetPrimitiveRestartEnable(VkCommandBuffer commandBuffer,
+                                               VkBool32 primitiveRestartEnable) {
     AEMU_SCOPED_TRACE("vkCmdSetPrimitiveRestartEnable");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdSetPrimitiveRestartEnable(commandBuffer, primitiveRestartEnable,
-                                          true /* do lock */);
-}
-static void entry_vkGetDeviceBufferMemoryRequirements(VkDevice device,
-                                                      const VkDeviceBufferMemoryRequirements* pInfo,
-                                                      VkMemoryRequirements2* pMemoryRequirements) {
-    AEMU_SCOPED_TRACE("vkGetDeviceBufferMemoryRequirements");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkGetDeviceBufferMemoryRequirements(device, pInfo, pMemoryRequirements,
-                                               true /* do lock */);
-}
-static void dynCheck_entry_vkGetDeviceBufferMemoryRequirements(
-    VkDevice device, const VkDeviceBufferMemoryRequirements* pInfo,
-    VkMemoryRequirements2* pMemoryRequirements) {
-    auto resources = ResourceTracker::get();
-    if (resources->getApiVersionFromDevice(device) < VK_API_VERSION_1_3) {
-        sOnInvalidDynamicallyCheckedCall("vkGetDeviceBufferMemoryRequirements", "VK_VERSION_1_3");
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        vkEnc->vkCmdSetPrimitiveRestartEnable(gfxstream_commandBuffer->internal_object,
+                                              primitiveRestartEnable, true /* do lock */);
     }
+}
+void gfxstream_vk_GetDeviceBufferMemoryRequirements(VkDevice device,
+                                                    const VkDeviceBufferMemoryRequirements* pInfo,
+                                                    VkMemoryRequirements2* pMemoryRequirements) {
     AEMU_SCOPED_TRACE("vkGetDeviceBufferMemoryRequirements");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkGetDeviceBufferMemoryRequirements(device, pInfo, pMemoryRequirements,
-                                               true /* do lock */);
-}
-static void entry_vkGetDeviceImageMemoryRequirements(VkDevice device,
-                                                     const VkDeviceImageMemoryRequirements* pInfo,
-                                                     VkMemoryRequirements2* pMemoryRequirements) {
-    AEMU_SCOPED_TRACE("vkGetDeviceImageMemoryRequirements");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkGetDeviceImageMemoryRequirements(device, pInfo, pMemoryRequirements,
-                                              true /* do lock */);
-}
-static void dynCheck_entry_vkGetDeviceImageMemoryRequirements(
-    VkDevice device, const VkDeviceImageMemoryRequirements* pInfo,
-    VkMemoryRequirements2* pMemoryRequirements) {
-    auto resources = ResourceTracker::get();
-    if (resources->getApiVersionFromDevice(device) < VK_API_VERSION_1_3) {
-        sOnInvalidDynamicallyCheckedCall("vkGetDeviceImageMemoryRequirements", "VK_VERSION_1_3");
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkEnc->vkGetDeviceBufferMemoryRequirements(gfxstream_device->internal_object, pInfo,
+                                                   pMemoryRequirements, true /* do lock */);
     }
-    AEMU_SCOPED_TRACE("vkGetDeviceImageMemoryRequirements");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkGetDeviceImageMemoryRequirements(device, pInfo, pMemoryRequirements,
-                                              true /* do lock */);
 }
-static void entry_vkGetDeviceImageSparseMemoryRequirements(
+void gfxstream_vk_GetDeviceImageMemoryRequirements(VkDevice device,
+                                                   const VkDeviceImageMemoryRequirements* pInfo,
+                                                   VkMemoryRequirements2* pMemoryRequirements) {
+    AEMU_SCOPED_TRACE("vkGetDeviceImageMemoryRequirements");
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkEnc->vkGetDeviceImageMemoryRequirements(gfxstream_device->internal_object, pInfo,
+                                                  pMemoryRequirements, true /* do lock */);
+    }
+}
+void gfxstream_vk_GetDeviceImageSparseMemoryRequirements(
     VkDevice device, const VkDeviceImageMemoryRequirements* pInfo,
     uint32_t* pSparseMemoryRequirementCount,
     VkSparseImageMemoryRequirements2* pSparseMemoryRequirements) {
     AEMU_SCOPED_TRACE("vkGetDeviceImageSparseMemoryRequirements");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkGetDeviceImageSparseMemoryRequirements(device, pInfo, pSparseMemoryRequirementCount,
-                                                    pSparseMemoryRequirements, true /* do lock */);
-}
-static void dynCheck_entry_vkGetDeviceImageSparseMemoryRequirements(
-    VkDevice device, const VkDeviceImageMemoryRequirements* pInfo,
-    uint32_t* pSparseMemoryRequirementCount,
-    VkSparseImageMemoryRequirements2* pSparseMemoryRequirements) {
-    auto resources = ResourceTracker::get();
-    if (resources->getApiVersionFromDevice(device) < VK_API_VERSION_1_3) {
-        sOnInvalidDynamicallyCheckedCall("vkGetDeviceImageSparseMemoryRequirements",
-                                         "VK_VERSION_1_3");
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkEnc->vkGetDeviceImageSparseMemoryRequirements(
+            gfxstream_device->internal_object, pInfo, pSparseMemoryRequirementCount,
+            pSparseMemoryRequirements, true /* do lock */);
     }
-    AEMU_SCOPED_TRACE("vkGetDeviceImageSparseMemoryRequirements");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkGetDeviceImageSparseMemoryRequirements(device, pInfo, pSparseMemoryRequirementCount,
-                                                    pSparseMemoryRequirements, true /* do lock */);
 }
 #endif
 #ifdef VK_KHR_surface
@@ -2171,140 +3720,236 @@
 #ifdef VK_KHR_xcb_surface
 #endif
 #ifdef VK_KHR_android_surface
-static VkResult entry_vkCreateAndroidSurfaceKHR(VkInstance instance,
-                                                const VkAndroidSurfaceCreateInfoKHR* pCreateInfo,
-                                                const VkAllocationCallbacks* pAllocator,
-                                                VkSurfaceKHR* pSurface) {
+VkResult gfxstream_vk_CreateAndroidSurfaceKHR(VkInstance instance,
+                                              const VkAndroidSurfaceCreateInfoKHR* pCreateInfo,
+                                              const VkAllocationCallbacks* pAllocator,
+                                              VkSurfaceKHR* pSurface) {
     AEMU_SCOPED_TRACE("vkCreateAndroidSurfaceKHR");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
     VkResult vkCreateAndroidSurfaceKHR_VkResult_return = (VkResult)0;
-    vkCreateAndroidSurfaceKHR_VkResult_return = vkEnc->vkCreateAndroidSurfaceKHR(
-        instance, pCreateInfo, pAllocator, pSurface, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_instance, gfxstream_instance, instance);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkCreateAndroidSurfaceKHR_VkResult_return =
+            vkEnc->vkCreateAndroidSurfaceKHR(gfxstream_instance->internal_object, pCreateInfo,
+                                             pAllocator, pSurface, true /* do lock */);
+    }
     return vkCreateAndroidSurfaceKHR_VkResult_return;
 }
 #endif
 #ifdef VK_KHR_win32_surface
 #endif
 #ifdef VK_KHR_dynamic_rendering
-static void entry_vkCmdBeginRenderingKHR(VkCommandBuffer commandBuffer,
-                                         const VkRenderingInfo* pRenderingInfo) {
+void gfxstream_vk_CmdBeginRenderingKHR(VkCommandBuffer commandBuffer,
+                                       const VkRenderingInfo* pRenderingInfo) {
     AEMU_SCOPED_TRACE("vkCmdBeginRenderingKHR");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdBeginRenderingKHR(commandBuffer, pRenderingInfo, true /* do lock */);
-}
-static void dynCheck_entry_vkCmdBeginRenderingKHR(VkCommandBuffer commandBuffer,
-                                                  const VkRenderingInfo* pRenderingInfo) {
-    auto resources = ResourceTracker::get();
-    VkDevice device = resources->getDevice(commandBuffer);
-    ;
-    if (!resources->hasDeviceExtension(device, "VK_KHR_dynamic_rendering")) {
-        sOnInvalidDynamicallyCheckedCall("vkCmdBeginRenderingKHR", "VK_KHR_dynamic_rendering");
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        std::vector<VkRenderingInfo> internal_pRenderingInfo(1);
+        std::vector<std::vector<VkRenderingAttachmentInfo>>
+            internal_VkRenderingInfo_pColorAttachments;
+        std::vector<VkRenderingAttachmentInfo> internal_VkRenderingInfo_pDepthAttachment;
+        std::vector<VkRenderingAttachmentInfo> internal_VkRenderingInfo_pStencilAttachment;
+        for (uint32_t i = 0; i < 1; ++i) {
+            internal_pRenderingInfo[i] = pRenderingInfo[i];
+            /* VkRenderingInfo::pColorAttachments */
+            internal_VkRenderingInfo_pColorAttachments.push_back(
+                std::vector<VkRenderingAttachmentInfo>());
+            internal_VkRenderingInfo_pColorAttachments[i].reserve(
+                internal_pRenderingInfo[i].colorAttachmentCount);
+            memset(&internal_VkRenderingInfo_pColorAttachments[i][0], 0,
+                   sizeof(VkRenderingAttachmentInfo) *
+                       internal_pRenderingInfo[i].colorAttachmentCount);
+            for (uint32_t j = 0; j < internal_pRenderingInfo[i].colorAttachmentCount; ++j) {
+                internal_VkRenderingInfo_pColorAttachments[i][j] =
+                    internal_pRenderingInfo[i].pColorAttachments[j];
+                /* VkRenderingAttachmentInfo::imageView */
+                if (internal_VkRenderingInfo_pColorAttachments[i][j].imageView) {
+                    VK_FROM_HANDLE(gfxstream_vk_image_view, gfxstream_imageView,
+                                   internal_VkRenderingInfo_pColorAttachments[i][j].imageView);
+                    internal_VkRenderingInfo_pColorAttachments[i][j].imageView =
+                        gfxstream_imageView->internal_object;
+                }
+                /* VkRenderingAttachmentInfo::resolveImageView */
+                if (internal_VkRenderingInfo_pColorAttachments[i][j].resolveImageView) {
+                    VK_FROM_HANDLE(
+                        gfxstream_vk_image_view, gfxstream_resolveImageView,
+                        internal_VkRenderingInfo_pColorAttachments[i][j].resolveImageView);
+                    internal_VkRenderingInfo_pColorAttachments[i][j].resolveImageView =
+                        gfxstream_resolveImageView->internal_object;
+                }
+            }
+            internal_pRenderingInfo[i].pColorAttachments =
+                internal_VkRenderingInfo_pColorAttachments[i].data();
+            /* VkRenderingInfo::pDepthAttachment */
+            if (internal_pRenderingInfo[i].pDepthAttachment) {
+                internal_VkRenderingInfo_pDepthAttachment[i] =
+                    internal_pRenderingInfo[i].pDepthAttachment[0];
+                /* VkRenderingAttachmentInfo::imageView */
+                if (internal_VkRenderingInfo_pDepthAttachment[i].imageView) {
+                    VK_FROM_HANDLE(gfxstream_vk_image_view, gfxstream_imageView,
+                                   internal_VkRenderingInfo_pDepthAttachment[i].imageView);
+                    internal_VkRenderingInfo_pDepthAttachment[i].imageView =
+                        gfxstream_imageView->internal_object;
+                }
+                /* VkRenderingAttachmentInfo::resolveImageView */
+                if (internal_VkRenderingInfo_pDepthAttachment[i].resolveImageView) {
+                    VK_FROM_HANDLE(gfxstream_vk_image_view, gfxstream_resolveImageView,
+                                   internal_VkRenderingInfo_pDepthAttachment[i].resolveImageView);
+                    internal_VkRenderingInfo_pDepthAttachment[i].resolveImageView =
+                        gfxstream_resolveImageView->internal_object;
+                }
+                internal_pRenderingInfo[i].pDepthAttachment =
+                    &internal_VkRenderingInfo_pDepthAttachment[i];
+            }
+            /* VkRenderingInfo::pStencilAttachment */
+            if (internal_pRenderingInfo[i].pStencilAttachment) {
+                internal_VkRenderingInfo_pStencilAttachment[i] =
+                    internal_pRenderingInfo[i].pStencilAttachment[0];
+                /* VkRenderingAttachmentInfo::imageView */
+                if (internal_VkRenderingInfo_pStencilAttachment[i].imageView) {
+                    VK_FROM_HANDLE(gfxstream_vk_image_view, gfxstream_imageView,
+                                   internal_VkRenderingInfo_pStencilAttachment[i].imageView);
+                    internal_VkRenderingInfo_pStencilAttachment[i].imageView =
+                        gfxstream_imageView->internal_object;
+                }
+                /* VkRenderingAttachmentInfo::resolveImageView */
+                if (internal_VkRenderingInfo_pStencilAttachment[i].resolveImageView) {
+                    VK_FROM_HANDLE(gfxstream_vk_image_view, gfxstream_resolveImageView,
+                                   internal_VkRenderingInfo_pStencilAttachment[i].resolveImageView);
+                    internal_VkRenderingInfo_pStencilAttachment[i].resolveImageView =
+                        gfxstream_resolveImageView->internal_object;
+                }
+                internal_pRenderingInfo[i].pStencilAttachment =
+                    &internal_VkRenderingInfo_pStencilAttachment[i];
+            }
+        }
+        vkEnc->vkCmdBeginRenderingKHR(gfxstream_commandBuffer->internal_object,
+                                      internal_pRenderingInfo.data(), true /* do lock */);
     }
-    AEMU_SCOPED_TRACE("vkCmdBeginRenderingKHR");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdBeginRenderingKHR(commandBuffer, pRenderingInfo, true /* do lock */);
 }
-static void entry_vkCmdEndRenderingKHR(VkCommandBuffer commandBuffer) {
+void gfxstream_vk_CmdEndRenderingKHR(VkCommandBuffer commandBuffer) {
     AEMU_SCOPED_TRACE("vkCmdEndRenderingKHR");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdEndRenderingKHR(commandBuffer, true /* do lock */);
-}
-static void dynCheck_entry_vkCmdEndRenderingKHR(VkCommandBuffer commandBuffer) {
-    auto resources = ResourceTracker::get();
-    VkDevice device = resources->getDevice(commandBuffer);
-    ;
-    if (!resources->hasDeviceExtension(device, "VK_KHR_dynamic_rendering")) {
-        sOnInvalidDynamicallyCheckedCall("vkCmdEndRenderingKHR", "VK_KHR_dynamic_rendering");
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        vkEnc->vkCmdEndRenderingKHR(gfxstream_commandBuffer->internal_object, true /* do lock */);
     }
-    AEMU_SCOPED_TRACE("vkCmdEndRenderingKHR");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdEndRenderingKHR(commandBuffer, true /* do lock */);
 }
 #endif
 #ifdef VK_KHR_get_physical_device_properties2
-static void entry_vkGetPhysicalDeviceFeatures2KHR(VkPhysicalDevice physicalDevice,
-                                                  VkPhysicalDeviceFeatures2* pFeatures) {
+void gfxstream_vk_GetPhysicalDeviceFeatures2KHR(VkPhysicalDevice physicalDevice,
+                                                VkPhysicalDeviceFeatures2* pFeatures) {
     AEMU_SCOPED_TRACE("vkGetPhysicalDeviceFeatures2KHR");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkGetPhysicalDeviceFeatures2KHR(physicalDevice, pFeatures, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_physical_device, gfxstream_physicalDevice, physicalDevice);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkEnc->vkGetPhysicalDeviceFeatures2KHR(gfxstream_physicalDevice->internal_object, pFeatures,
+                                               true /* do lock */);
+    }
 }
-static void entry_vkGetPhysicalDeviceProperties2KHR(VkPhysicalDevice physicalDevice,
-                                                    VkPhysicalDeviceProperties2* pProperties) {
+void gfxstream_vk_GetPhysicalDeviceProperties2KHR(VkPhysicalDevice physicalDevice,
+                                                  VkPhysicalDeviceProperties2* pProperties) {
     AEMU_SCOPED_TRACE("vkGetPhysicalDeviceProperties2KHR");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkGetPhysicalDeviceProperties2KHR(physicalDevice, pProperties, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_physical_device, gfxstream_physicalDevice, physicalDevice);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkEnc->vkGetPhysicalDeviceProperties2KHR(gfxstream_physicalDevice->internal_object,
+                                                 pProperties, true /* do lock */);
+    }
 }
-static void entry_vkGetPhysicalDeviceFormatProperties2KHR(VkPhysicalDevice physicalDevice,
-                                                          VkFormat format,
-                                                          VkFormatProperties2* pFormatProperties) {
+void gfxstream_vk_GetPhysicalDeviceFormatProperties2KHR(VkPhysicalDevice physicalDevice,
+                                                        VkFormat format,
+                                                        VkFormatProperties2* pFormatProperties) {
     AEMU_SCOPED_TRACE("vkGetPhysicalDeviceFormatProperties2KHR");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkGetPhysicalDeviceFormatProperties2KHR(physicalDevice, format, pFormatProperties,
-                                                   true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_physical_device, gfxstream_physicalDevice, physicalDevice);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkEnc->vkGetPhysicalDeviceFormatProperties2KHR(gfxstream_physicalDevice->internal_object,
+                                                       format, pFormatProperties,
+                                                       true /* do lock */);
+    }
 }
-static VkResult entry_vkGetPhysicalDeviceImageFormatProperties2KHR(
+VkResult gfxstream_vk_GetPhysicalDeviceImageFormatProperties2KHR(
     VkPhysicalDevice physicalDevice, const VkPhysicalDeviceImageFormatInfo2* pImageFormatInfo,
     VkImageFormatProperties2* pImageFormatProperties) {
     AEMU_SCOPED_TRACE("vkGetPhysicalDeviceImageFormatProperties2KHR");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
     VkResult vkGetPhysicalDeviceImageFormatProperties2KHR_VkResult_return = (VkResult)0;
-    auto resources = ResourceTracker::get();
-    vkGetPhysicalDeviceImageFormatProperties2KHR_VkResult_return =
-        resources->on_vkGetPhysicalDeviceImageFormatProperties2KHR(
-            vkEnc, VK_SUCCESS, physicalDevice, pImageFormatInfo, pImageFormatProperties);
+    VK_FROM_HANDLE(gfxstream_vk_physical_device, gfxstream_physicalDevice, physicalDevice);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        auto resources = gfxstream::vk::ResourceTracker::get();
+        vkGetPhysicalDeviceImageFormatProperties2KHR_VkResult_return =
+            resources->on_vkGetPhysicalDeviceImageFormatProperties2KHR(
+                vkEnc, VK_SUCCESS, gfxstream_physicalDevice->internal_object, pImageFormatInfo,
+                pImageFormatProperties);
+    }
     return vkGetPhysicalDeviceImageFormatProperties2KHR_VkResult_return;
 }
-static void entry_vkGetPhysicalDeviceQueueFamilyProperties2KHR(
+void gfxstream_vk_GetPhysicalDeviceQueueFamilyProperties2KHR(
     VkPhysicalDevice physicalDevice, uint32_t* pQueueFamilyPropertyCount,
     VkQueueFamilyProperties2* pQueueFamilyProperties) {
     AEMU_SCOPED_TRACE("vkGetPhysicalDeviceQueueFamilyProperties2KHR");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkGetPhysicalDeviceQueueFamilyProperties2KHR(physicalDevice, pQueueFamilyPropertyCount,
-                                                        pQueueFamilyProperties, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_physical_device, gfxstream_physicalDevice, physicalDevice);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkEnc->vkGetPhysicalDeviceQueueFamilyProperties2KHR(
+            gfxstream_physicalDevice->internal_object, pQueueFamilyPropertyCount,
+            pQueueFamilyProperties, true /* do lock */);
+    }
 }
-static void entry_vkGetPhysicalDeviceMemoryProperties2KHR(
+void gfxstream_vk_GetPhysicalDeviceMemoryProperties2KHR(
     VkPhysicalDevice physicalDevice, VkPhysicalDeviceMemoryProperties2* pMemoryProperties) {
     AEMU_SCOPED_TRACE("vkGetPhysicalDeviceMemoryProperties2KHR");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkGetPhysicalDeviceMemoryProperties2KHR(physicalDevice, pMemoryProperties,
-                                                   true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_physical_device, gfxstream_physicalDevice, physicalDevice);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkEnc->vkGetPhysicalDeviceMemoryProperties2KHR(gfxstream_physicalDevice->internal_object,
+                                                       pMemoryProperties, true /* do lock */);
+    }
 }
-static void entry_vkGetPhysicalDeviceSparseImageFormatProperties2KHR(
+void gfxstream_vk_GetPhysicalDeviceSparseImageFormatProperties2KHR(
     VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSparseImageFormatInfo2* pFormatInfo,
     uint32_t* pPropertyCount, VkSparseImageFormatProperties2* pProperties) {
     AEMU_SCOPED_TRACE("vkGetPhysicalDeviceSparseImageFormatProperties2KHR");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkGetPhysicalDeviceSparseImageFormatProperties2KHR(
-        physicalDevice, pFormatInfo, pPropertyCount, pProperties, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_physical_device, gfxstream_physicalDevice, physicalDevice);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkEnc->vkGetPhysicalDeviceSparseImageFormatProperties2KHR(
+            gfxstream_physicalDevice->internal_object, pFormatInfo, pPropertyCount, pProperties,
+            true /* do lock */);
+    }
 }
 #endif
 #ifdef VK_KHR_maintenance1
-static void entry_vkTrimCommandPoolKHR(VkDevice device, VkCommandPool commandPool,
-                                       VkCommandPoolTrimFlags flags) {
+void gfxstream_vk_TrimCommandPoolKHR(VkDevice device, VkCommandPool commandPool,
+                                     VkCommandPoolTrimFlags flags) {
     AEMU_SCOPED_TRACE("vkTrimCommandPoolKHR");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkTrimCommandPoolKHR(device, commandPool, flags, true /* do lock */);
-}
-static void dynCheck_entry_vkTrimCommandPoolKHR(VkDevice device, VkCommandPool commandPool,
-                                                VkCommandPoolTrimFlags flags) {
-    auto resources = ResourceTracker::get();
-    if (!resources->hasDeviceExtension(device, "VK_KHR_maintenance1")) {
-        sOnInvalidDynamicallyCheckedCall("vkTrimCommandPoolKHR", "VK_KHR_maintenance1");
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    VK_FROM_HANDLE(gfxstream_vk_command_pool, gfxstream_commandPool, commandPool);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkEnc->vkTrimCommandPoolKHR(gfxstream_device->internal_object,
+                                    gfxstream_commandPool->internal_object, flags,
+                                    true /* do lock */);
     }
-    AEMU_SCOPED_TRACE("vkTrimCommandPoolKHR");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkTrimCommandPoolKHR(device, commandPool, flags, true /* do lock */);
 }
 #endif
 #ifdef VK_KHR_external_memory_capabilities
-static void entry_vkGetPhysicalDeviceExternalBufferPropertiesKHR(
+void gfxstream_vk_GetPhysicalDeviceExternalBufferPropertiesKHR(
     VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalBufferInfo* pExternalBufferInfo,
     VkExternalBufferProperties* pExternalBufferProperties) {
     AEMU_SCOPED_TRACE("vkGetPhysicalDeviceExternalBufferPropertiesKHR");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    auto resources = ResourceTracker::get();
-    resources->on_vkGetPhysicalDeviceExternalBufferPropertiesKHR(
-        vkEnc, physicalDevice, pExternalBufferInfo, pExternalBufferProperties);
+    VK_FROM_HANDLE(gfxstream_vk_physical_device, gfxstream_physicalDevice, physicalDevice);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        auto resources = gfxstream::vk::ResourceTracker::get();
+        resources->on_vkGetPhysicalDeviceExternalBufferPropertiesKHR(
+            vkEnc, gfxstream_physicalDevice->internal_object, pExternalBufferInfo,
+            pExternalBufferProperties);
+    }
 }
 #endif
 #ifdef VK_KHR_external_memory
@@ -2314,14 +3959,18 @@
 #ifdef VK_KHR_external_memory_fd
 #endif
 #ifdef VK_KHR_external_semaphore_capabilities
-static void entry_vkGetPhysicalDeviceExternalSemaphorePropertiesKHR(
+void gfxstream_vk_GetPhysicalDeviceExternalSemaphorePropertiesKHR(
     VkPhysicalDevice physicalDevice,
     const VkPhysicalDeviceExternalSemaphoreInfo* pExternalSemaphoreInfo,
     VkExternalSemaphoreProperties* pExternalSemaphoreProperties) {
     AEMU_SCOPED_TRACE("vkGetPhysicalDeviceExternalSemaphorePropertiesKHR");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkGetPhysicalDeviceExternalSemaphorePropertiesKHR(
-        physicalDevice, pExternalSemaphoreInfo, pExternalSemaphoreProperties, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_physical_device, gfxstream_physicalDevice, physicalDevice);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkEnc->vkGetPhysicalDeviceExternalSemaphorePropertiesKHR(
+            gfxstream_physicalDevice->internal_object, pExternalSemaphoreInfo,
+            pExternalSemaphoreProperties, true /* do lock */);
+    }
 }
 #endif
 #ifdef VK_KHR_external_semaphore
@@ -2329,51 +3978,47 @@
 #ifdef VK_KHR_external_semaphore_win32
 #endif
 #ifdef VK_KHR_external_semaphore_fd
-static VkResult entry_vkImportSemaphoreFdKHR(
+VkResult gfxstream_vk_ImportSemaphoreFdKHR(
     VkDevice device, const VkImportSemaphoreFdInfoKHR* pImportSemaphoreFdInfo) {
     AEMU_SCOPED_TRACE("vkImportSemaphoreFdKHR");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
     VkResult vkImportSemaphoreFdKHR_VkResult_return = (VkResult)0;
-    auto resources = ResourceTracker::get();
-    vkImportSemaphoreFdKHR_VkResult_return =
-        resources->on_vkImportSemaphoreFdKHR(vkEnc, VK_SUCCESS, device, pImportSemaphoreFdInfo);
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        std::vector<VkImportSemaphoreFdInfoKHR> internal_pImportSemaphoreFdInfo(1);
+        for (uint32_t i = 0; i < 1; ++i) {
+            internal_pImportSemaphoreFdInfo[i] = pImportSemaphoreFdInfo[i];
+            /* VkImportSemaphoreFdInfoKHR::semaphore */
+            VK_FROM_HANDLE(gfxstream_vk_semaphore, gfxstream_semaphore,
+                           internal_pImportSemaphoreFdInfo[i].semaphore);
+            internal_pImportSemaphoreFdInfo[i].semaphore = gfxstream_semaphore->internal_object;
+        }
+        auto resources = gfxstream::vk::ResourceTracker::get();
+        vkImportSemaphoreFdKHR_VkResult_return = resources->on_vkImportSemaphoreFdKHR(
+            vkEnc, VK_SUCCESS, gfxstream_device->internal_object,
+            internal_pImportSemaphoreFdInfo.data());
+    }
     return vkImportSemaphoreFdKHR_VkResult_return;
 }
-static VkResult dynCheck_entry_vkImportSemaphoreFdKHR(
-    VkDevice device, const VkImportSemaphoreFdInfoKHR* pImportSemaphoreFdInfo) {
-    auto resources = ResourceTracker::get();
-    if (!resources->hasDeviceExtension(device, "VK_KHR_external_semaphore_fd")) {
-        sOnInvalidDynamicallyCheckedCall("vkImportSemaphoreFdKHR", "VK_KHR_external_semaphore_fd");
-    }
-    AEMU_SCOPED_TRACE("vkImportSemaphoreFdKHR");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    VkResult vkImportSemaphoreFdKHR_VkResult_return = (VkResult)0;
-    vkImportSemaphoreFdKHR_VkResult_return =
-        resources->on_vkImportSemaphoreFdKHR(vkEnc, VK_SUCCESS, device, pImportSemaphoreFdInfo);
-    return vkImportSemaphoreFdKHR_VkResult_return;
-}
-static VkResult entry_vkGetSemaphoreFdKHR(VkDevice device,
-                                          const VkSemaphoreGetFdInfoKHR* pGetFdInfo, int* pFd) {
+VkResult gfxstream_vk_GetSemaphoreFdKHR(VkDevice device, const VkSemaphoreGetFdInfoKHR* pGetFdInfo,
+                                        int* pFd) {
     AEMU_SCOPED_TRACE("vkGetSemaphoreFdKHR");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
     VkResult vkGetSemaphoreFdKHR_VkResult_return = (VkResult)0;
-    auto resources = ResourceTracker::get();
-    vkGetSemaphoreFdKHR_VkResult_return =
-        resources->on_vkGetSemaphoreFdKHR(vkEnc, VK_SUCCESS, device, pGetFdInfo, pFd);
-    return vkGetSemaphoreFdKHR_VkResult_return;
-}
-static VkResult dynCheck_entry_vkGetSemaphoreFdKHR(VkDevice device,
-                                                   const VkSemaphoreGetFdInfoKHR* pGetFdInfo,
-                                                   int* pFd) {
-    auto resources = ResourceTracker::get();
-    if (!resources->hasDeviceExtension(device, "VK_KHR_external_semaphore_fd")) {
-        sOnInvalidDynamicallyCheckedCall("vkGetSemaphoreFdKHR", "VK_KHR_external_semaphore_fd");
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        std::vector<VkSemaphoreGetFdInfoKHR> internal_pGetFdInfo(1);
+        for (uint32_t i = 0; i < 1; ++i) {
+            internal_pGetFdInfo[i] = pGetFdInfo[i];
+            /* VkSemaphoreGetFdInfoKHR::semaphore */
+            VK_FROM_HANDLE(gfxstream_vk_semaphore, gfxstream_semaphore,
+                           internal_pGetFdInfo[i].semaphore);
+            internal_pGetFdInfo[i].semaphore = gfxstream_semaphore->internal_object;
+        }
+        auto resources = gfxstream::vk::ResourceTracker::get();
+        vkGetSemaphoreFdKHR_VkResult_return = resources->on_vkGetSemaphoreFdKHR(
+            vkEnc, VK_SUCCESS, gfxstream_device->internal_object, internal_pGetFdInfo.data(), pFd);
     }
-    AEMU_SCOPED_TRACE("vkGetSemaphoreFdKHR");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    VkResult vkGetSemaphoreFdKHR_VkResult_return = (VkResult)0;
-    vkGetSemaphoreFdKHR_VkResult_return =
-        resources->on_vkGetSemaphoreFdKHR(vkEnc, VK_SUCCESS, device, pGetFdInfo, pFd);
     return vkGetSemaphoreFdKHR_VkResult_return;
 }
 #endif
@@ -2382,228 +4027,189 @@
 #ifdef VK_KHR_incremental_present
 #endif
 #ifdef VK_KHR_descriptor_update_template
-static VkResult entry_vkCreateDescriptorUpdateTemplateKHR(
+VkResult gfxstream_vk_CreateDescriptorUpdateTemplateKHR(
     VkDevice device, const VkDescriptorUpdateTemplateCreateInfo* pCreateInfo,
     const VkAllocationCallbacks* pAllocator,
     VkDescriptorUpdateTemplate* pDescriptorUpdateTemplate) {
     AEMU_SCOPED_TRACE("vkCreateDescriptorUpdateTemplateKHR");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
     VkResult vkCreateDescriptorUpdateTemplateKHR_VkResult_return = (VkResult)0;
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    struct gfxstream_vk_descriptor_update_template* gfxstream_pDescriptorUpdateTemplate =
+        (gfxstream_vk_descriptor_update_template*)vk_object_zalloc(
+            &gfxstream_device->vk, pAllocator, sizeof(gfxstream_vk_descriptor_update_template),
+            VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE);
     vkCreateDescriptorUpdateTemplateKHR_VkResult_return =
-        vkEnc->vkCreateDescriptorUpdateTemplateKHR(device, pCreateInfo, pAllocator,
-                                                   pDescriptorUpdateTemplate, true /* do lock */);
-    return vkCreateDescriptorUpdateTemplateKHR_VkResult_return;
-}
-static VkResult dynCheck_entry_vkCreateDescriptorUpdateTemplateKHR(
-    VkDevice device, const VkDescriptorUpdateTemplateCreateInfo* pCreateInfo,
-    const VkAllocationCallbacks* pAllocator,
-    VkDescriptorUpdateTemplate* pDescriptorUpdateTemplate) {
-    auto resources = ResourceTracker::get();
-    if (!resources->hasDeviceExtension(device, "VK_KHR_descriptor_update_template")) {
-        sOnInvalidDynamicallyCheckedCall("vkCreateDescriptorUpdateTemplateKHR",
-                                         "VK_KHR_descriptor_update_template");
+        gfxstream_pDescriptorUpdateTemplate ? VK_SUCCESS : VK_ERROR_OUT_OF_HOST_MEMORY;
+    if (VK_SUCCESS == vkCreateDescriptorUpdateTemplateKHR_VkResult_return) {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        std::vector<VkDescriptorUpdateTemplateCreateInfo> internal_pCreateInfo(1);
+        for (uint32_t i = 0; i < 1; ++i) {
+            internal_pCreateInfo[i] = pCreateInfo[i];
+            /* VkDescriptorUpdateTemplateCreateInfo::descriptorSetLayout */
+            if (internal_pCreateInfo[i].descriptorSetLayout) {
+                VK_FROM_HANDLE(gfxstream_vk_descriptor_set_layout, gfxstream_descriptorSetLayout,
+                               internal_pCreateInfo[i].descriptorSetLayout);
+                internal_pCreateInfo[i].descriptorSetLayout =
+                    gfxstream_descriptorSetLayout->internal_object;
+            }
+            /* VkDescriptorUpdateTemplateCreateInfo::pipelineLayout */
+            if (internal_pCreateInfo[i].pipelineLayout) {
+                VK_FROM_HANDLE(gfxstream_vk_pipeline_layout, gfxstream_pipelineLayout,
+                               internal_pCreateInfo[i].pipelineLayout);
+                internal_pCreateInfo[i].pipelineLayout = gfxstream_pipelineLayout->internal_object;
+            }
+        }
+        vkCreateDescriptorUpdateTemplateKHR_VkResult_return =
+            vkEnc->vkCreateDescriptorUpdateTemplateKHR(
+                gfxstream_device->internal_object, internal_pCreateInfo.data(), pAllocator,
+                &gfxstream_pDescriptorUpdateTemplate->internal_object, true /* do lock */);
     }
-    AEMU_SCOPED_TRACE("vkCreateDescriptorUpdateTemplateKHR");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    VkResult vkCreateDescriptorUpdateTemplateKHR_VkResult_return = (VkResult)0;
-    vkCreateDescriptorUpdateTemplateKHR_VkResult_return =
-        vkEnc->vkCreateDescriptorUpdateTemplateKHR(device, pCreateInfo, pAllocator,
-                                                   pDescriptorUpdateTemplate, true /* do lock */);
+    *pDescriptorUpdateTemplate =
+        gfxstream_vk_descriptor_update_template_to_handle(gfxstream_pDescriptorUpdateTemplate);
     return vkCreateDescriptorUpdateTemplateKHR_VkResult_return;
 }
-static void entry_vkDestroyDescriptorUpdateTemplateKHR(
+void gfxstream_vk_DestroyDescriptorUpdateTemplateKHR(
     VkDevice device, VkDescriptorUpdateTemplate descriptorUpdateTemplate,
     const VkAllocationCallbacks* pAllocator) {
     AEMU_SCOPED_TRACE("vkDestroyDescriptorUpdateTemplateKHR");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkDestroyDescriptorUpdateTemplateKHR(device, descriptorUpdateTemplate, pAllocator,
-                                                true /* do lock */);
-}
-static void dynCheck_entry_vkDestroyDescriptorUpdateTemplateKHR(
-    VkDevice device, VkDescriptorUpdateTemplate descriptorUpdateTemplate,
-    const VkAllocationCallbacks* pAllocator) {
-    auto resources = ResourceTracker::get();
-    if (!resources->hasDeviceExtension(device, "VK_KHR_descriptor_update_template")) {
-        sOnInvalidDynamicallyCheckedCall("vkDestroyDescriptorUpdateTemplateKHR",
-                                         "VK_KHR_descriptor_update_template");
+    if (VK_NULL_HANDLE == descriptorUpdateTemplate) {
+        return;
     }
-    AEMU_SCOPED_TRACE("vkDestroyDescriptorUpdateTemplateKHR");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkDestroyDescriptorUpdateTemplateKHR(device, descriptorUpdateTemplate, pAllocator,
-                                                true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    VK_FROM_HANDLE(gfxstream_vk_descriptor_update_template, gfxstream_descriptorUpdateTemplate,
+                   descriptorUpdateTemplate);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkEnc->vkDestroyDescriptorUpdateTemplateKHR(
+            gfxstream_device->internal_object,
+            gfxstream_descriptorUpdateTemplate ? gfxstream_descriptorUpdateTemplate->internal_object
+                                               : VK_NULL_HANDLE,
+            pAllocator, true /* do lock */);
+    }
+    vk_object_free(&gfxstream_device->vk, pAllocator, (void*)gfxstream_descriptorUpdateTemplate);
 }
-static void entry_vkUpdateDescriptorSetWithTemplateKHR(
+void gfxstream_vk_UpdateDescriptorSetWithTemplateKHR(
     VkDevice device, VkDescriptorSet descriptorSet,
     VkDescriptorUpdateTemplate descriptorUpdateTemplate, const void* pData) {
     AEMU_SCOPED_TRACE("vkUpdateDescriptorSetWithTemplateKHR");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkUpdateDescriptorSetWithTemplateKHR(device, descriptorSet, descriptorUpdateTemplate,
-                                                pData, true /* do lock */);
-}
-static void dynCheck_entry_vkUpdateDescriptorSetWithTemplateKHR(
-    VkDevice device, VkDescriptorSet descriptorSet,
-    VkDescriptorUpdateTemplate descriptorUpdateTemplate, const void* pData) {
-    auto resources = ResourceTracker::get();
-    if (!resources->hasDeviceExtension(device, "VK_KHR_descriptor_update_template")) {
-        sOnInvalidDynamicallyCheckedCall("vkUpdateDescriptorSetWithTemplateKHR",
-                                         "VK_KHR_descriptor_update_template");
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    VK_FROM_HANDLE(gfxstream_vk_descriptor_update_template, gfxstream_descriptorUpdateTemplate,
+                   descriptorUpdateTemplate);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkEnc->vkUpdateDescriptorSetWithTemplateKHR(
+            gfxstream_device->internal_object, descriptorSet,
+            gfxstream_descriptorUpdateTemplate->internal_object, pData, true /* do lock */);
     }
-    AEMU_SCOPED_TRACE("vkUpdateDescriptorSetWithTemplateKHR");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkUpdateDescriptorSetWithTemplateKHR(device, descriptorSet, descriptorUpdateTemplate,
-                                                pData, true /* do lock */);
 }
 #endif
 #ifdef VK_KHR_imageless_framebuffer
 #endif
 #ifdef VK_KHR_create_renderpass2
-static VkResult entry_vkCreateRenderPass2KHR(VkDevice device,
-                                             const VkRenderPassCreateInfo2* pCreateInfo,
-                                             const VkAllocationCallbacks* pAllocator,
-                                             VkRenderPass* pRenderPass) {
+VkResult gfxstream_vk_CreateRenderPass2KHR(VkDevice device,
+                                           const VkRenderPassCreateInfo2* pCreateInfo,
+                                           const VkAllocationCallbacks* pAllocator,
+                                           VkRenderPass* pRenderPass) {
     AEMU_SCOPED_TRACE("vkCreateRenderPass2KHR");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
     VkResult vkCreateRenderPass2KHR_VkResult_return = (VkResult)0;
-    vkCreateRenderPass2KHR_VkResult_return = vkEnc->vkCreateRenderPass2KHR(
-        device, pCreateInfo, pAllocator, pRenderPass, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    struct gfxstream_vk_render_pass* gfxstream_pRenderPass =
+        (gfxstream_vk_render_pass*)vk_object_zalloc(&gfxstream_device->vk, pAllocator,
+                                                    sizeof(gfxstream_vk_render_pass),
+                                                    VK_OBJECT_TYPE_RENDER_PASS);
+    vkCreateRenderPass2KHR_VkResult_return =
+        gfxstream_pRenderPass ? VK_SUCCESS : VK_ERROR_OUT_OF_HOST_MEMORY;
+    if (VK_SUCCESS == vkCreateRenderPass2KHR_VkResult_return) {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkCreateRenderPass2KHR_VkResult_return = vkEnc->vkCreateRenderPass2KHR(
+            gfxstream_device->internal_object, pCreateInfo, pAllocator,
+            &gfxstream_pRenderPass->internal_object, true /* do lock */);
+    }
+    *pRenderPass = gfxstream_vk_render_pass_to_handle(gfxstream_pRenderPass);
     return vkCreateRenderPass2KHR_VkResult_return;
 }
-static VkResult dynCheck_entry_vkCreateRenderPass2KHR(VkDevice device,
-                                                      const VkRenderPassCreateInfo2* pCreateInfo,
-                                                      const VkAllocationCallbacks* pAllocator,
-                                                      VkRenderPass* pRenderPass) {
-    auto resources = ResourceTracker::get();
-    if (!resources->hasDeviceExtension(device, "VK_KHR_create_renderpass2")) {
-        sOnInvalidDynamicallyCheckedCall("vkCreateRenderPass2KHR", "VK_KHR_create_renderpass2");
+void gfxstream_vk_CmdNextSubpass2KHR(VkCommandBuffer commandBuffer,
+                                     const VkSubpassBeginInfo* pSubpassBeginInfo,
+                                     const VkSubpassEndInfo* pSubpassEndInfo) {
+    AEMU_SCOPED_TRACE("vkCmdNextSubpass2KHR");
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        vkEnc->vkCmdNextSubpass2KHR(gfxstream_commandBuffer->internal_object, pSubpassBeginInfo,
+                                    pSubpassEndInfo, true /* do lock */);
     }
-    AEMU_SCOPED_TRACE("vkCreateRenderPass2KHR");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    VkResult vkCreateRenderPass2KHR_VkResult_return = (VkResult)0;
-    vkCreateRenderPass2KHR_VkResult_return = vkEnc->vkCreateRenderPass2KHR(
-        device, pCreateInfo, pAllocator, pRenderPass, true /* do lock */);
-    return vkCreateRenderPass2KHR_VkResult_return;
 }
-static void entry_vkCmdBeginRenderPass2KHR(VkCommandBuffer commandBuffer,
-                                           const VkRenderPassBeginInfo* pRenderPassBegin,
-                                           const VkSubpassBeginInfo* pSubpassBeginInfo) {
-    AEMU_SCOPED_TRACE("vkCmdBeginRenderPass2KHR");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdBeginRenderPass2KHR(commandBuffer, pRenderPassBegin, pSubpassBeginInfo,
-                                    true /* do lock */);
-}
-static void dynCheck_entry_vkCmdBeginRenderPass2KHR(VkCommandBuffer commandBuffer,
-                                                    const VkRenderPassBeginInfo* pRenderPassBegin,
-                                                    const VkSubpassBeginInfo* pSubpassBeginInfo) {
-    auto resources = ResourceTracker::get();
-    VkDevice device = resources->getDevice(commandBuffer);
-    ;
-    if (!resources->hasDeviceExtension(device, "VK_KHR_create_renderpass2")) {
-        sOnInvalidDynamicallyCheckedCall("vkCmdBeginRenderPass2KHR", "VK_KHR_create_renderpass2");
-    }
-    AEMU_SCOPED_TRACE("vkCmdBeginRenderPass2KHR");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdBeginRenderPass2KHR(commandBuffer, pRenderPassBegin, pSubpassBeginInfo,
-                                    true /* do lock */);
-}
-static void entry_vkCmdNextSubpass2KHR(VkCommandBuffer commandBuffer,
-                                       const VkSubpassBeginInfo* pSubpassBeginInfo,
+void gfxstream_vk_CmdEndRenderPass2KHR(VkCommandBuffer commandBuffer,
                                        const VkSubpassEndInfo* pSubpassEndInfo) {
-    AEMU_SCOPED_TRACE("vkCmdNextSubpass2KHR");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdNextSubpass2KHR(commandBuffer, pSubpassBeginInfo, pSubpassEndInfo,
-                                true /* do lock */);
-}
-static void dynCheck_entry_vkCmdNextSubpass2KHR(VkCommandBuffer commandBuffer,
-                                                const VkSubpassBeginInfo* pSubpassBeginInfo,
-                                                const VkSubpassEndInfo* pSubpassEndInfo) {
-    auto resources = ResourceTracker::get();
-    VkDevice device = resources->getDevice(commandBuffer);
-    ;
-    if (!resources->hasDeviceExtension(device, "VK_KHR_create_renderpass2")) {
-        sOnInvalidDynamicallyCheckedCall("vkCmdNextSubpass2KHR", "VK_KHR_create_renderpass2");
-    }
-    AEMU_SCOPED_TRACE("vkCmdNextSubpass2KHR");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdNextSubpass2KHR(commandBuffer, pSubpassBeginInfo, pSubpassEndInfo,
-                                true /* do lock */);
-}
-static void entry_vkCmdEndRenderPass2KHR(VkCommandBuffer commandBuffer,
-                                         const VkSubpassEndInfo* pSubpassEndInfo) {
     AEMU_SCOPED_TRACE("vkCmdEndRenderPass2KHR");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdEndRenderPass2KHR(commandBuffer, pSubpassEndInfo, true /* do lock */);
-}
-static void dynCheck_entry_vkCmdEndRenderPass2KHR(VkCommandBuffer commandBuffer,
-                                                  const VkSubpassEndInfo* pSubpassEndInfo) {
-    auto resources = ResourceTracker::get();
-    VkDevice device = resources->getDevice(commandBuffer);
-    ;
-    if (!resources->hasDeviceExtension(device, "VK_KHR_create_renderpass2")) {
-        sOnInvalidDynamicallyCheckedCall("vkCmdEndRenderPass2KHR", "VK_KHR_create_renderpass2");
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        vkEnc->vkCmdEndRenderPass2KHR(gfxstream_commandBuffer->internal_object, pSubpassEndInfo,
+                                      true /* do lock */);
     }
-    AEMU_SCOPED_TRACE("vkCmdEndRenderPass2KHR");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdEndRenderPass2KHR(commandBuffer, pSubpassEndInfo, true /* do lock */);
 }
 #endif
 #ifdef VK_KHR_external_fence_capabilities
-static void entry_vkGetPhysicalDeviceExternalFencePropertiesKHR(
+void gfxstream_vk_GetPhysicalDeviceExternalFencePropertiesKHR(
     VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalFenceInfo* pExternalFenceInfo,
     VkExternalFenceProperties* pExternalFenceProperties) {
     AEMU_SCOPED_TRACE("vkGetPhysicalDeviceExternalFencePropertiesKHR");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    auto resources = ResourceTracker::get();
-    resources->on_vkGetPhysicalDeviceExternalFencePropertiesKHR(
-        vkEnc, physicalDevice, pExternalFenceInfo, pExternalFenceProperties);
+    VK_FROM_HANDLE(gfxstream_vk_physical_device, gfxstream_physicalDevice, physicalDevice);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        auto resources = gfxstream::vk::ResourceTracker::get();
+        resources->on_vkGetPhysicalDeviceExternalFencePropertiesKHR(
+            vkEnc, gfxstream_physicalDevice->internal_object, pExternalFenceInfo,
+            pExternalFenceProperties);
+    }
 }
 #endif
 #ifdef VK_KHR_external_fence
 #endif
 #ifdef VK_KHR_external_fence_fd
-static VkResult entry_vkImportFenceFdKHR(VkDevice device,
-                                         const VkImportFenceFdInfoKHR* pImportFenceFdInfo) {
+VkResult gfxstream_vk_ImportFenceFdKHR(VkDevice device,
+                                       const VkImportFenceFdInfoKHR* pImportFenceFdInfo) {
     AEMU_SCOPED_TRACE("vkImportFenceFdKHR");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
     VkResult vkImportFenceFdKHR_VkResult_return = (VkResult)0;
-    auto resources = ResourceTracker::get();
-    vkImportFenceFdKHR_VkResult_return =
-        resources->on_vkImportFenceFdKHR(vkEnc, VK_SUCCESS, device, pImportFenceFdInfo);
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        std::vector<VkImportFenceFdInfoKHR> internal_pImportFenceFdInfo(1);
+        for (uint32_t i = 0; i < 1; ++i) {
+            internal_pImportFenceFdInfo[i] = pImportFenceFdInfo[i];
+            /* VkImportFenceFdInfoKHR::fence */
+            VK_FROM_HANDLE(gfxstream_vk_fence, gfxstream_fence,
+                           internal_pImportFenceFdInfo[i].fence);
+            internal_pImportFenceFdInfo[i].fence = gfxstream_fence->internal_object;
+        }
+        auto resources = gfxstream::vk::ResourceTracker::get();
+        vkImportFenceFdKHR_VkResult_return =
+            resources->on_vkImportFenceFdKHR(vkEnc, VK_SUCCESS, gfxstream_device->internal_object,
+                                             internal_pImportFenceFdInfo.data());
+    }
     return vkImportFenceFdKHR_VkResult_return;
 }
-static VkResult dynCheck_entry_vkImportFenceFdKHR(
-    VkDevice device, const VkImportFenceFdInfoKHR* pImportFenceFdInfo) {
-    auto resources = ResourceTracker::get();
-    if (!resources->hasDeviceExtension(device, "VK_KHR_external_fence_fd")) {
-        sOnInvalidDynamicallyCheckedCall("vkImportFenceFdKHR", "VK_KHR_external_fence_fd");
-    }
-    AEMU_SCOPED_TRACE("vkImportFenceFdKHR");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    VkResult vkImportFenceFdKHR_VkResult_return = (VkResult)0;
-    vkImportFenceFdKHR_VkResult_return =
-        resources->on_vkImportFenceFdKHR(vkEnc, VK_SUCCESS, device, pImportFenceFdInfo);
-    return vkImportFenceFdKHR_VkResult_return;
-}
-static VkResult entry_vkGetFenceFdKHR(VkDevice device, const VkFenceGetFdInfoKHR* pGetFdInfo,
-                                      int* pFd) {
+VkResult gfxstream_vk_GetFenceFdKHR(VkDevice device, const VkFenceGetFdInfoKHR* pGetFdInfo,
+                                    int* pFd) {
     AEMU_SCOPED_TRACE("vkGetFenceFdKHR");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
     VkResult vkGetFenceFdKHR_VkResult_return = (VkResult)0;
-    auto resources = ResourceTracker::get();
-    vkGetFenceFdKHR_VkResult_return =
-        resources->on_vkGetFenceFdKHR(vkEnc, VK_SUCCESS, device, pGetFdInfo, pFd);
-    return vkGetFenceFdKHR_VkResult_return;
-}
-static VkResult dynCheck_entry_vkGetFenceFdKHR(VkDevice device,
-                                               const VkFenceGetFdInfoKHR* pGetFdInfo, int* pFd) {
-    auto resources = ResourceTracker::get();
-    if (!resources->hasDeviceExtension(device, "VK_KHR_external_fence_fd")) {
-        sOnInvalidDynamicallyCheckedCall("vkGetFenceFdKHR", "VK_KHR_external_fence_fd");
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        std::vector<VkFenceGetFdInfoKHR> internal_pGetFdInfo(1);
+        for (uint32_t i = 0; i < 1; ++i) {
+            internal_pGetFdInfo[i] = pGetFdInfo[i];
+            /* VkFenceGetFdInfoKHR::fence */
+            VK_FROM_HANDLE(gfxstream_vk_fence, gfxstream_fence, internal_pGetFdInfo[i].fence);
+            internal_pGetFdInfo[i].fence = gfxstream_fence->internal_object;
+        }
+        auto resources = gfxstream::vk::ResourceTracker::get();
+        vkGetFenceFdKHR_VkResult_return = resources->on_vkGetFenceFdKHR(
+            vkEnc, VK_SUCCESS, gfxstream_device->internal_object, internal_pGetFdInfo.data(), pFd);
     }
-    AEMU_SCOPED_TRACE("vkGetFenceFdKHR");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    VkResult vkGetFenceFdKHR_VkResult_return = (VkResult)0;
-    vkGetFenceFdKHR_VkResult_return =
-        resources->on_vkGetFenceFdKHR(vkEnc, VK_SUCCESS, device, pGetFdInfo, pFd);
     return vkGetFenceFdKHR_VkResult_return;
 }
 #endif
@@ -2614,189 +4220,165 @@
 #ifdef VK_KHR_storage_buffer_storage_class
 #endif
 #ifdef VK_KHR_get_memory_requirements2
-static void entry_vkGetImageMemoryRequirements2KHR(VkDevice device,
-                                                   const VkImageMemoryRequirementsInfo2* pInfo,
-                                                   VkMemoryRequirements2* pMemoryRequirements) {
+void gfxstream_vk_GetImageMemoryRequirements2KHR(VkDevice device,
+                                                 const VkImageMemoryRequirementsInfo2* pInfo,
+                                                 VkMemoryRequirements2* pMemoryRequirements) {
     AEMU_SCOPED_TRACE("vkGetImageMemoryRequirements2KHR");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    auto resources = ResourceTracker::get();
-    resources->on_vkGetImageMemoryRequirements2KHR(vkEnc, device, pInfo, pMemoryRequirements);
-}
-static void dynCheck_entry_vkGetImageMemoryRequirements2KHR(
-    VkDevice device, const VkImageMemoryRequirementsInfo2* pInfo,
-    VkMemoryRequirements2* pMemoryRequirements) {
-    auto resources = ResourceTracker::get();
-    if (!resources->hasDeviceExtension(device, "VK_KHR_get_memory_requirements2")) {
-        sOnInvalidDynamicallyCheckedCall("vkGetImageMemoryRequirements2KHR",
-                                         "VK_KHR_get_memory_requirements2");
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        std::vector<VkImageMemoryRequirementsInfo2> internal_pInfo(1);
+        for (uint32_t i = 0; i < 1; ++i) {
+            internal_pInfo[i] = pInfo[i];
+            /* VkImageMemoryRequirementsInfo2::image */
+            VK_FROM_HANDLE(gfxstream_vk_image, gfxstream_image, internal_pInfo[i].image);
+            internal_pInfo[i].image = gfxstream_image->internal_object;
+        }
+        auto resources = gfxstream::vk::ResourceTracker::get();
+        resources->on_vkGetImageMemoryRequirements2KHR(vkEnc, gfxstream_device->internal_object,
+                                                       internal_pInfo.data(), pMemoryRequirements);
     }
-    AEMU_SCOPED_TRACE("vkGetImageMemoryRequirements2KHR");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    resources->on_vkGetImageMemoryRequirements2KHR(vkEnc, device, pInfo, pMemoryRequirements);
 }
-static void entry_vkGetBufferMemoryRequirements2KHR(VkDevice device,
-                                                    const VkBufferMemoryRequirementsInfo2* pInfo,
-                                                    VkMemoryRequirements2* pMemoryRequirements) {
+void gfxstream_vk_GetBufferMemoryRequirements2KHR(VkDevice device,
+                                                  const VkBufferMemoryRequirementsInfo2* pInfo,
+                                                  VkMemoryRequirements2* pMemoryRequirements) {
     AEMU_SCOPED_TRACE("vkGetBufferMemoryRequirements2KHR");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    auto resources = ResourceTracker::get();
-    resources->on_vkGetBufferMemoryRequirements2KHR(vkEnc, device, pInfo, pMemoryRequirements);
-}
-static void dynCheck_entry_vkGetBufferMemoryRequirements2KHR(
-    VkDevice device, const VkBufferMemoryRequirementsInfo2* pInfo,
-    VkMemoryRequirements2* pMemoryRequirements) {
-    auto resources = ResourceTracker::get();
-    if (!resources->hasDeviceExtension(device, "VK_KHR_get_memory_requirements2")) {
-        sOnInvalidDynamicallyCheckedCall("vkGetBufferMemoryRequirements2KHR",
-                                         "VK_KHR_get_memory_requirements2");
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        std::vector<VkBufferMemoryRequirementsInfo2> internal_pInfo(1);
+        for (uint32_t i = 0; i < 1; ++i) {
+            internal_pInfo[i] = pInfo[i];
+            /* VkBufferMemoryRequirementsInfo2::buffer */
+            VK_FROM_HANDLE(gfxstream_vk_buffer, gfxstream_buffer, internal_pInfo[i].buffer);
+            internal_pInfo[i].buffer = gfxstream_buffer->internal_object;
+        }
+        auto resources = gfxstream::vk::ResourceTracker::get();
+        resources->on_vkGetBufferMemoryRequirements2KHR(vkEnc, gfxstream_device->internal_object,
+                                                        internal_pInfo.data(), pMemoryRequirements);
     }
-    AEMU_SCOPED_TRACE("vkGetBufferMemoryRequirements2KHR");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    resources->on_vkGetBufferMemoryRequirements2KHR(vkEnc, device, pInfo, pMemoryRequirements);
 }
-static void entry_vkGetImageSparseMemoryRequirements2KHR(
+void gfxstream_vk_GetImageSparseMemoryRequirements2KHR(
     VkDevice device, const VkImageSparseMemoryRequirementsInfo2* pInfo,
     uint32_t* pSparseMemoryRequirementCount,
     VkSparseImageMemoryRequirements2* pSparseMemoryRequirements) {
     AEMU_SCOPED_TRACE("vkGetImageSparseMemoryRequirements2KHR");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkGetImageSparseMemoryRequirements2KHR(device, pInfo, pSparseMemoryRequirementCount,
-                                                  pSparseMemoryRequirements, true /* do lock */);
-}
-static void dynCheck_entry_vkGetImageSparseMemoryRequirements2KHR(
-    VkDevice device, const VkImageSparseMemoryRequirementsInfo2* pInfo,
-    uint32_t* pSparseMemoryRequirementCount,
-    VkSparseImageMemoryRequirements2* pSparseMemoryRequirements) {
-    auto resources = ResourceTracker::get();
-    if (!resources->hasDeviceExtension(device, "VK_KHR_get_memory_requirements2")) {
-        sOnInvalidDynamicallyCheckedCall("vkGetImageSparseMemoryRequirements2KHR",
-                                         "VK_KHR_get_memory_requirements2");
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        std::vector<VkImageSparseMemoryRequirementsInfo2> internal_pInfo(1);
+        for (uint32_t i = 0; i < 1; ++i) {
+            internal_pInfo[i] = pInfo[i];
+            /* VkImageSparseMemoryRequirementsInfo2::image */
+            VK_FROM_HANDLE(gfxstream_vk_image, gfxstream_image, internal_pInfo[i].image);
+            internal_pInfo[i].image = gfxstream_image->internal_object;
+        }
+        vkEnc->vkGetImageSparseMemoryRequirements2KHR(
+            gfxstream_device->internal_object, internal_pInfo.data(), pSparseMemoryRequirementCount,
+            pSparseMemoryRequirements, true /* do lock */);
     }
-    AEMU_SCOPED_TRACE("vkGetImageSparseMemoryRequirements2KHR");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkGetImageSparseMemoryRequirements2KHR(device, pInfo, pSparseMemoryRequirementCount,
-                                                  pSparseMemoryRequirements, true /* do lock */);
 }
 #endif
 #ifdef VK_KHR_image_format_list
 #endif
 #ifdef VK_KHR_sampler_ycbcr_conversion
-static VkResult entry_vkCreateSamplerYcbcrConversionKHR(
+VkResult gfxstream_vk_CreateSamplerYcbcrConversionKHR(
     VkDevice device, const VkSamplerYcbcrConversionCreateInfo* pCreateInfo,
     const VkAllocationCallbacks* pAllocator, VkSamplerYcbcrConversion* pYcbcrConversion) {
     AEMU_SCOPED_TRACE("vkCreateSamplerYcbcrConversionKHR");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
     VkResult vkCreateSamplerYcbcrConversionKHR_VkResult_return = (VkResult)0;
-    auto resources = ResourceTracker::get();
-    vkCreateSamplerYcbcrConversionKHR_VkResult_return =
-        resources->on_vkCreateSamplerYcbcrConversionKHR(vkEnc, VK_SUCCESS, device, pCreateInfo,
-                                                        pAllocator, pYcbcrConversion);
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        auto resources = gfxstream::vk::ResourceTracker::get();
+        vkCreateSamplerYcbcrConversionKHR_VkResult_return =
+            resources->on_vkCreateSamplerYcbcrConversionKHR(
+                vkEnc, VK_SUCCESS, gfxstream_device->internal_object, pCreateInfo, pAllocator,
+                pYcbcrConversion);
+    }
     return vkCreateSamplerYcbcrConversionKHR_VkResult_return;
 }
-static VkResult dynCheck_entry_vkCreateSamplerYcbcrConversionKHR(
-    VkDevice device, const VkSamplerYcbcrConversionCreateInfo* pCreateInfo,
-    const VkAllocationCallbacks* pAllocator, VkSamplerYcbcrConversion* pYcbcrConversion) {
-    auto resources = ResourceTracker::get();
-    if (!resources->hasDeviceExtension(device, "VK_KHR_sampler_ycbcr_conversion")) {
-        sOnInvalidDynamicallyCheckedCall("vkCreateSamplerYcbcrConversionKHR",
-                                         "VK_KHR_sampler_ycbcr_conversion");
-    }
-    AEMU_SCOPED_TRACE("vkCreateSamplerYcbcrConversionKHR");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    VkResult vkCreateSamplerYcbcrConversionKHR_VkResult_return = (VkResult)0;
-    vkCreateSamplerYcbcrConversionKHR_VkResult_return =
-        resources->on_vkCreateSamplerYcbcrConversionKHR(vkEnc, VK_SUCCESS, device, pCreateInfo,
-                                                        pAllocator, pYcbcrConversion);
-    return vkCreateSamplerYcbcrConversionKHR_VkResult_return;
-}
-static void entry_vkDestroySamplerYcbcrConversionKHR(VkDevice device,
-                                                     VkSamplerYcbcrConversion ycbcrConversion,
-                                                     const VkAllocationCallbacks* pAllocator) {
+void gfxstream_vk_DestroySamplerYcbcrConversionKHR(VkDevice device,
+                                                   VkSamplerYcbcrConversion ycbcrConversion,
+                                                   const VkAllocationCallbacks* pAllocator) {
     AEMU_SCOPED_TRACE("vkDestroySamplerYcbcrConversionKHR");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    auto resources = ResourceTracker::get();
-    resources->on_vkDestroySamplerYcbcrConversionKHR(vkEnc, device, ycbcrConversion, pAllocator);
-}
-static void dynCheck_entry_vkDestroySamplerYcbcrConversionKHR(
-    VkDevice device, VkSamplerYcbcrConversion ycbcrConversion,
-    const VkAllocationCallbacks* pAllocator) {
-    auto resources = ResourceTracker::get();
-    if (!resources->hasDeviceExtension(device, "VK_KHR_sampler_ycbcr_conversion")) {
-        sOnInvalidDynamicallyCheckedCall("vkDestroySamplerYcbcrConversionKHR",
-                                         "VK_KHR_sampler_ycbcr_conversion");
+    if (VK_NULL_HANDLE == ycbcrConversion) {
+        return;
     }
-    AEMU_SCOPED_TRACE("vkDestroySamplerYcbcrConversionKHR");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    resources->on_vkDestroySamplerYcbcrConversionKHR(vkEnc, device, ycbcrConversion, pAllocator);
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        auto resources = gfxstream::vk::ResourceTracker::get();
+        resources->on_vkDestroySamplerYcbcrConversionKHR(vkEnc, gfxstream_device->internal_object,
+                                                         ycbcrConversion, pAllocator);
+    }
 }
 #endif
 #ifdef VK_KHR_bind_memory2
-static VkResult entry_vkBindBufferMemory2KHR(VkDevice device, uint32_t bindInfoCount,
-                                             const VkBindBufferMemoryInfo* pBindInfos) {
+VkResult gfxstream_vk_BindBufferMemory2KHR(VkDevice device, uint32_t bindInfoCount,
+                                           const VkBindBufferMemoryInfo* pBindInfos) {
     AEMU_SCOPED_TRACE("vkBindBufferMemory2KHR");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
     VkResult vkBindBufferMemory2KHR_VkResult_return = (VkResult)0;
-    auto resources = ResourceTracker::get();
-    vkBindBufferMemory2KHR_VkResult_return =
-        resources->on_vkBindBufferMemory2KHR(vkEnc, VK_SUCCESS, device, bindInfoCount, pBindInfos);
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        std::vector<VkBindBufferMemoryInfo> internal_pBindInfos(bindInfoCount);
+        for (uint32_t i = 0; i < bindInfoCount; ++i) {
+            internal_pBindInfos[i] = pBindInfos[i];
+            /* VkBindBufferMemoryInfo::buffer */
+            VK_FROM_HANDLE(gfxstream_vk_buffer, gfxstream_buffer, internal_pBindInfos[i].buffer);
+            internal_pBindInfos[i].buffer = gfxstream_buffer->internal_object;
+            /* VkBindBufferMemoryInfo::memory */
+            VK_FROM_HANDLE(gfxstream_vk_device_memory, gfxstream_memory,
+                           internal_pBindInfos[i].memory);
+            internal_pBindInfos[i].memory = gfxstream_memory->internal_object;
+        }
+        auto resources = gfxstream::vk::ResourceTracker::get();
+        vkBindBufferMemory2KHR_VkResult_return = resources->on_vkBindBufferMemory2KHR(
+            vkEnc, VK_SUCCESS, gfxstream_device->internal_object, bindInfoCount,
+            internal_pBindInfos.data());
+    }
     return vkBindBufferMemory2KHR_VkResult_return;
 }
-static VkResult dynCheck_entry_vkBindBufferMemory2KHR(VkDevice device, uint32_t bindInfoCount,
-                                                      const VkBindBufferMemoryInfo* pBindInfos) {
-    auto resources = ResourceTracker::get();
-    if (!resources->hasDeviceExtension(device, "VK_KHR_bind_memory2")) {
-        sOnInvalidDynamicallyCheckedCall("vkBindBufferMemory2KHR", "VK_KHR_bind_memory2");
-    }
-    AEMU_SCOPED_TRACE("vkBindBufferMemory2KHR");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    VkResult vkBindBufferMemory2KHR_VkResult_return = (VkResult)0;
-    vkBindBufferMemory2KHR_VkResult_return =
-        resources->on_vkBindBufferMemory2KHR(vkEnc, VK_SUCCESS, device, bindInfoCount, pBindInfos);
-    return vkBindBufferMemory2KHR_VkResult_return;
-}
-static VkResult entry_vkBindImageMemory2KHR(VkDevice device, uint32_t bindInfoCount,
-                                            const VkBindImageMemoryInfo* pBindInfos) {
+VkResult gfxstream_vk_BindImageMemory2KHR(VkDevice device, uint32_t bindInfoCount,
+                                          const VkBindImageMemoryInfo* pBindInfos) {
     AEMU_SCOPED_TRACE("vkBindImageMemory2KHR");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
     VkResult vkBindImageMemory2KHR_VkResult_return = (VkResult)0;
-    auto resources = ResourceTracker::get();
-    vkBindImageMemory2KHR_VkResult_return =
-        resources->on_vkBindImageMemory2KHR(vkEnc, VK_SUCCESS, device, bindInfoCount, pBindInfos);
-    return vkBindImageMemory2KHR_VkResult_return;
-}
-static VkResult dynCheck_entry_vkBindImageMemory2KHR(VkDevice device, uint32_t bindInfoCount,
-                                                     const VkBindImageMemoryInfo* pBindInfos) {
-    auto resources = ResourceTracker::get();
-    if (!resources->hasDeviceExtension(device, "VK_KHR_bind_memory2")) {
-        sOnInvalidDynamicallyCheckedCall("vkBindImageMemory2KHR", "VK_KHR_bind_memory2");
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        std::vector<VkBindImageMemoryInfo> internal_pBindInfos(bindInfoCount);
+        for (uint32_t i = 0; i < bindInfoCount; ++i) {
+            internal_pBindInfos[i] = pBindInfos[i];
+            /* VkBindImageMemoryInfo::image */
+            VK_FROM_HANDLE(gfxstream_vk_image, gfxstream_image, internal_pBindInfos[i].image);
+            internal_pBindInfos[i].image = gfxstream_image->internal_object;
+            /* VkBindImageMemoryInfo::memory */
+            if (internal_pBindInfos[i].memory) {
+                VK_FROM_HANDLE(gfxstream_vk_device_memory, gfxstream_memory,
+                               internal_pBindInfos[i].memory);
+                internal_pBindInfos[i].memory = gfxstream_memory->internal_object;
+            }
+        }
+        auto resources = gfxstream::vk::ResourceTracker::get();
+        vkBindImageMemory2KHR_VkResult_return = resources->on_vkBindImageMemory2KHR(
+            vkEnc, VK_SUCCESS, gfxstream_device->internal_object, bindInfoCount,
+            internal_pBindInfos.data());
     }
-    AEMU_SCOPED_TRACE("vkBindImageMemory2KHR");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    VkResult vkBindImageMemory2KHR_VkResult_return = (VkResult)0;
-    vkBindImageMemory2KHR_VkResult_return =
-        resources->on_vkBindImageMemory2KHR(vkEnc, VK_SUCCESS, device, bindInfoCount, pBindInfos);
     return vkBindImageMemory2KHR_VkResult_return;
 }
 #endif
 #ifdef VK_KHR_maintenance3
-static void entry_vkGetDescriptorSetLayoutSupportKHR(
+void gfxstream_vk_GetDescriptorSetLayoutSupportKHR(
     VkDevice device, const VkDescriptorSetLayoutCreateInfo* pCreateInfo,
     VkDescriptorSetLayoutSupport* pSupport) {
     AEMU_SCOPED_TRACE("vkGetDescriptorSetLayoutSupportKHR");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkGetDescriptorSetLayoutSupportKHR(device, pCreateInfo, pSupport, true /* do lock */);
-}
-static void dynCheck_entry_vkGetDescriptorSetLayoutSupportKHR(
-    VkDevice device, const VkDescriptorSetLayoutCreateInfo* pCreateInfo,
-    VkDescriptorSetLayoutSupport* pSupport) {
-    auto resources = ResourceTracker::get();
-    if (!resources->hasDeviceExtension(device, "VK_KHR_maintenance3")) {
-        sOnInvalidDynamicallyCheckedCall("vkGetDescriptorSetLayoutSupportKHR",
-                                         "VK_KHR_maintenance3");
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkEnc->vkGetDescriptorSetLayoutSupportKHR(gfxstream_device->internal_object, pCreateInfo,
+                                                  pSupport, true /* do lock */);
     }
-    AEMU_SCOPED_TRACE("vkGetDescriptorSetLayoutSupportKHR");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkGetDescriptorSetLayoutSupportKHR(device, pCreateInfo, pSupport, true /* do lock */);
 }
 #endif
 #ifdef VK_KHR_shader_subgroup_extended_types
@@ -2806,160 +4388,135 @@
 #ifdef VK_KHR_shader_terminate_invocation
 #endif
 #ifdef VK_KHR_buffer_device_address
-static VkDeviceAddress entry_vkGetBufferDeviceAddressKHR(VkDevice device,
-                                                         const VkBufferDeviceAddressInfo* pInfo) {
+VkDeviceAddress gfxstream_vk_GetBufferDeviceAddressKHR(VkDevice device,
+                                                       const VkBufferDeviceAddressInfo* pInfo) {
     AEMU_SCOPED_TRACE("vkGetBufferDeviceAddressKHR");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
     VkDeviceAddress vkGetBufferDeviceAddressKHR_VkDeviceAddress_return = (VkDeviceAddress)0;
-    vkGetBufferDeviceAddressKHR_VkDeviceAddress_return =
-        vkEnc->vkGetBufferDeviceAddressKHR(device, pInfo, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        std::vector<VkBufferDeviceAddressInfo> internal_pInfo(1);
+        for (uint32_t i = 0; i < 1; ++i) {
+            internal_pInfo[i] = pInfo[i];
+            /* VkBufferDeviceAddressInfo::buffer */
+            VK_FROM_HANDLE(gfxstream_vk_buffer, gfxstream_buffer, internal_pInfo[i].buffer);
+            internal_pInfo[i].buffer = gfxstream_buffer->internal_object;
+        }
+        vkGetBufferDeviceAddressKHR_VkDeviceAddress_return = vkEnc->vkGetBufferDeviceAddressKHR(
+            gfxstream_device->internal_object, internal_pInfo.data(), true /* do lock */);
+    }
     return vkGetBufferDeviceAddressKHR_VkDeviceAddress_return;
 }
-static VkDeviceAddress dynCheck_entry_vkGetBufferDeviceAddressKHR(
-    VkDevice device, const VkBufferDeviceAddressInfo* pInfo) {
-    auto resources = ResourceTracker::get();
-    if (!resources->hasDeviceExtension(device, "VK_KHR_buffer_device_address")) {
-        sOnInvalidDynamicallyCheckedCall("vkGetBufferDeviceAddressKHR",
-                                         "VK_KHR_buffer_device_address");
-    }
-    AEMU_SCOPED_TRACE("vkGetBufferDeviceAddressKHR");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    VkDeviceAddress vkGetBufferDeviceAddressKHR_VkDeviceAddress_return = (VkDeviceAddress)0;
-    vkGetBufferDeviceAddressKHR_VkDeviceAddress_return =
-        vkEnc->vkGetBufferDeviceAddressKHR(device, pInfo, true /* do lock */);
-    return vkGetBufferDeviceAddressKHR_VkDeviceAddress_return;
-}
-static uint64_t entry_vkGetBufferOpaqueCaptureAddressKHR(VkDevice device,
-                                                         const VkBufferDeviceAddressInfo* pInfo) {
+uint64_t gfxstream_vk_GetBufferOpaqueCaptureAddressKHR(VkDevice device,
+                                                       const VkBufferDeviceAddressInfo* pInfo) {
     AEMU_SCOPED_TRACE("vkGetBufferOpaqueCaptureAddressKHR");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
     uint64_t vkGetBufferOpaqueCaptureAddressKHR_uint64_t_return = (uint64_t)0;
-    vkGetBufferOpaqueCaptureAddressKHR_uint64_t_return =
-        vkEnc->vkGetBufferOpaqueCaptureAddressKHR(device, pInfo, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        std::vector<VkBufferDeviceAddressInfo> internal_pInfo(1);
+        for (uint32_t i = 0; i < 1; ++i) {
+            internal_pInfo[i] = pInfo[i];
+            /* VkBufferDeviceAddressInfo::buffer */
+            VK_FROM_HANDLE(gfxstream_vk_buffer, gfxstream_buffer, internal_pInfo[i].buffer);
+            internal_pInfo[i].buffer = gfxstream_buffer->internal_object;
+        }
+        vkGetBufferOpaqueCaptureAddressKHR_uint64_t_return =
+            vkEnc->vkGetBufferOpaqueCaptureAddressKHR(gfxstream_device->internal_object,
+                                                      internal_pInfo.data(), true /* do lock */);
+    }
     return vkGetBufferOpaqueCaptureAddressKHR_uint64_t_return;
 }
-static uint64_t dynCheck_entry_vkGetBufferOpaqueCaptureAddressKHR(
-    VkDevice device, const VkBufferDeviceAddressInfo* pInfo) {
-    auto resources = ResourceTracker::get();
-    if (!resources->hasDeviceExtension(device, "VK_KHR_buffer_device_address")) {
-        sOnInvalidDynamicallyCheckedCall("vkGetBufferOpaqueCaptureAddressKHR",
-                                         "VK_KHR_buffer_device_address");
-    }
-    AEMU_SCOPED_TRACE("vkGetBufferOpaqueCaptureAddressKHR");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    uint64_t vkGetBufferOpaqueCaptureAddressKHR_uint64_t_return = (uint64_t)0;
-    vkGetBufferOpaqueCaptureAddressKHR_uint64_t_return =
-        vkEnc->vkGetBufferOpaqueCaptureAddressKHR(device, pInfo, true /* do lock */);
-    return vkGetBufferOpaqueCaptureAddressKHR_uint64_t_return;
-}
-static uint64_t entry_vkGetDeviceMemoryOpaqueCaptureAddressKHR(
+uint64_t gfxstream_vk_GetDeviceMemoryOpaqueCaptureAddressKHR(
     VkDevice device, const VkDeviceMemoryOpaqueCaptureAddressInfo* pInfo) {
     AEMU_SCOPED_TRACE("vkGetDeviceMemoryOpaqueCaptureAddressKHR");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
     uint64_t vkGetDeviceMemoryOpaqueCaptureAddressKHR_uint64_t_return = (uint64_t)0;
-    vkGetDeviceMemoryOpaqueCaptureAddressKHR_uint64_t_return =
-        vkEnc->vkGetDeviceMemoryOpaqueCaptureAddressKHR(device, pInfo, true /* do lock */);
-    return vkGetDeviceMemoryOpaqueCaptureAddressKHR_uint64_t_return;
-}
-static uint64_t dynCheck_entry_vkGetDeviceMemoryOpaqueCaptureAddressKHR(
-    VkDevice device, const VkDeviceMemoryOpaqueCaptureAddressInfo* pInfo) {
-    auto resources = ResourceTracker::get();
-    if (!resources->hasDeviceExtension(device, "VK_KHR_buffer_device_address")) {
-        sOnInvalidDynamicallyCheckedCall("vkGetDeviceMemoryOpaqueCaptureAddressKHR",
-                                         "VK_KHR_buffer_device_address");
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        std::vector<VkDeviceMemoryOpaqueCaptureAddressInfo> internal_pInfo(1);
+        for (uint32_t i = 0; i < 1; ++i) {
+            internal_pInfo[i] = pInfo[i];
+            /* VkDeviceMemoryOpaqueCaptureAddressInfo::memory */
+            VK_FROM_HANDLE(gfxstream_vk_device_memory, gfxstream_memory, internal_pInfo[i].memory);
+            internal_pInfo[i].memory = gfxstream_memory->internal_object;
+        }
+        vkGetDeviceMemoryOpaqueCaptureAddressKHR_uint64_t_return =
+            vkEnc->vkGetDeviceMemoryOpaqueCaptureAddressKHR(
+                gfxstream_device->internal_object, internal_pInfo.data(), true /* do lock */);
     }
-    AEMU_SCOPED_TRACE("vkGetDeviceMemoryOpaqueCaptureAddressKHR");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    uint64_t vkGetDeviceMemoryOpaqueCaptureAddressKHR_uint64_t_return = (uint64_t)0;
-    vkGetDeviceMemoryOpaqueCaptureAddressKHR_uint64_t_return =
-        vkEnc->vkGetDeviceMemoryOpaqueCaptureAddressKHR(device, pInfo, true /* do lock */);
     return vkGetDeviceMemoryOpaqueCaptureAddressKHR_uint64_t_return;
 }
 #endif
 #ifdef VK_KHR_pipeline_executable_properties
-static VkResult entry_vkGetPipelineExecutablePropertiesKHR(
+VkResult gfxstream_vk_GetPipelineExecutablePropertiesKHR(
     VkDevice device, const VkPipelineInfoKHR* pPipelineInfo, uint32_t* pExecutableCount,
     VkPipelineExecutablePropertiesKHR* pProperties) {
     AEMU_SCOPED_TRACE("vkGetPipelineExecutablePropertiesKHR");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
     VkResult vkGetPipelineExecutablePropertiesKHR_VkResult_return = (VkResult)0;
-    vkGetPipelineExecutablePropertiesKHR_VkResult_return =
-        vkEnc->vkGetPipelineExecutablePropertiesKHR(device, pPipelineInfo, pExecutableCount,
-                                                    pProperties, true /* do lock */);
-    return vkGetPipelineExecutablePropertiesKHR_VkResult_return;
-}
-static VkResult dynCheck_entry_vkGetPipelineExecutablePropertiesKHR(
-    VkDevice device, const VkPipelineInfoKHR* pPipelineInfo, uint32_t* pExecutableCount,
-    VkPipelineExecutablePropertiesKHR* pProperties) {
-    auto resources = ResourceTracker::get();
-    if (!resources->hasDeviceExtension(device, "VK_KHR_pipeline_executable_properties")) {
-        sOnInvalidDynamicallyCheckedCall("vkGetPipelineExecutablePropertiesKHR",
-                                         "VK_KHR_pipeline_executable_properties");
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        std::vector<VkPipelineInfoKHR> internal_pPipelineInfo(1);
+        for (uint32_t i = 0; i < 1; ++i) {
+            internal_pPipelineInfo[i] = pPipelineInfo[i];
+            /* VkPipelineInfoKHR::pipeline */
+            VK_FROM_HANDLE(gfxstream_vk_pipeline, gfxstream_pipeline,
+                           internal_pPipelineInfo[i].pipeline);
+            internal_pPipelineInfo[i].pipeline = gfxstream_pipeline->internal_object;
+        }
+        vkGetPipelineExecutablePropertiesKHR_VkResult_return =
+            vkEnc->vkGetPipelineExecutablePropertiesKHR(
+                gfxstream_device->internal_object, internal_pPipelineInfo.data(), pExecutableCount,
+                pProperties, true /* do lock */);
     }
-    AEMU_SCOPED_TRACE("vkGetPipelineExecutablePropertiesKHR");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    VkResult vkGetPipelineExecutablePropertiesKHR_VkResult_return = (VkResult)0;
-    vkGetPipelineExecutablePropertiesKHR_VkResult_return =
-        vkEnc->vkGetPipelineExecutablePropertiesKHR(device, pPipelineInfo, pExecutableCount,
-                                                    pProperties, true /* do lock */);
     return vkGetPipelineExecutablePropertiesKHR_VkResult_return;
 }
-static VkResult entry_vkGetPipelineExecutableStatisticsKHR(
+VkResult gfxstream_vk_GetPipelineExecutableStatisticsKHR(
     VkDevice device, const VkPipelineExecutableInfoKHR* pExecutableInfo, uint32_t* pStatisticCount,
     VkPipelineExecutableStatisticKHR* pStatistics) {
     AEMU_SCOPED_TRACE("vkGetPipelineExecutableStatisticsKHR");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
     VkResult vkGetPipelineExecutableStatisticsKHR_VkResult_return = (VkResult)0;
-    vkGetPipelineExecutableStatisticsKHR_VkResult_return =
-        vkEnc->vkGetPipelineExecutableStatisticsKHR(device, pExecutableInfo, pStatisticCount,
-                                                    pStatistics, true /* do lock */);
-    return vkGetPipelineExecutableStatisticsKHR_VkResult_return;
-}
-static VkResult dynCheck_entry_vkGetPipelineExecutableStatisticsKHR(
-    VkDevice device, const VkPipelineExecutableInfoKHR* pExecutableInfo, uint32_t* pStatisticCount,
-    VkPipelineExecutableStatisticKHR* pStatistics) {
-    auto resources = ResourceTracker::get();
-    if (!resources->hasDeviceExtension(device, "VK_KHR_pipeline_executable_properties")) {
-        sOnInvalidDynamicallyCheckedCall("vkGetPipelineExecutableStatisticsKHR",
-                                         "VK_KHR_pipeline_executable_properties");
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        std::vector<VkPipelineExecutableInfoKHR> internal_pExecutableInfo(1);
+        for (uint32_t i = 0; i < 1; ++i) {
+            internal_pExecutableInfo[i] = pExecutableInfo[i];
+            /* VkPipelineExecutableInfoKHR::pipeline */
+            VK_FROM_HANDLE(gfxstream_vk_pipeline, gfxstream_pipeline,
+                           internal_pExecutableInfo[i].pipeline);
+            internal_pExecutableInfo[i].pipeline = gfxstream_pipeline->internal_object;
+        }
+        vkGetPipelineExecutableStatisticsKHR_VkResult_return =
+            vkEnc->vkGetPipelineExecutableStatisticsKHR(
+                gfxstream_device->internal_object, internal_pExecutableInfo.data(), pStatisticCount,
+                pStatistics, true /* do lock */);
     }
-    AEMU_SCOPED_TRACE("vkGetPipelineExecutableStatisticsKHR");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    VkResult vkGetPipelineExecutableStatisticsKHR_VkResult_return = (VkResult)0;
-    vkGetPipelineExecutableStatisticsKHR_VkResult_return =
-        vkEnc->vkGetPipelineExecutableStatisticsKHR(device, pExecutableInfo, pStatisticCount,
-                                                    pStatistics, true /* do lock */);
     return vkGetPipelineExecutableStatisticsKHR_VkResult_return;
 }
-static VkResult entry_vkGetPipelineExecutableInternalRepresentationsKHR(
+VkResult gfxstream_vk_GetPipelineExecutableInternalRepresentationsKHR(
     VkDevice device, const VkPipelineExecutableInfoKHR* pExecutableInfo,
     uint32_t* pInternalRepresentationCount,
     VkPipelineExecutableInternalRepresentationKHR* pInternalRepresentations) {
     AEMU_SCOPED_TRACE("vkGetPipelineExecutableInternalRepresentationsKHR");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
     VkResult vkGetPipelineExecutableInternalRepresentationsKHR_VkResult_return = (VkResult)0;
-    vkGetPipelineExecutableInternalRepresentationsKHR_VkResult_return =
-        vkEnc->vkGetPipelineExecutableInternalRepresentationsKHR(
-            device, pExecutableInfo, pInternalRepresentationCount, pInternalRepresentations,
-            true /* do lock */);
-    return vkGetPipelineExecutableInternalRepresentationsKHR_VkResult_return;
-}
-static VkResult dynCheck_entry_vkGetPipelineExecutableInternalRepresentationsKHR(
-    VkDevice device, const VkPipelineExecutableInfoKHR* pExecutableInfo,
-    uint32_t* pInternalRepresentationCount,
-    VkPipelineExecutableInternalRepresentationKHR* pInternalRepresentations) {
-    auto resources = ResourceTracker::get();
-    if (!resources->hasDeviceExtension(device, "VK_KHR_pipeline_executable_properties")) {
-        sOnInvalidDynamicallyCheckedCall("vkGetPipelineExecutableInternalRepresentationsKHR",
-                                         "VK_KHR_pipeline_executable_properties");
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        std::vector<VkPipelineExecutableInfoKHR> internal_pExecutableInfo(1);
+        for (uint32_t i = 0; i < 1; ++i) {
+            internal_pExecutableInfo[i] = pExecutableInfo[i];
+            /* VkPipelineExecutableInfoKHR::pipeline */
+            VK_FROM_HANDLE(gfxstream_vk_pipeline, gfxstream_pipeline,
+                           internal_pExecutableInfo[i].pipeline);
+            internal_pExecutableInfo[i].pipeline = gfxstream_pipeline->internal_object;
+        }
+        vkGetPipelineExecutableInternalRepresentationsKHR_VkResult_return =
+            vkEnc->vkGetPipelineExecutableInternalRepresentationsKHR(
+                gfxstream_device->internal_object, internal_pExecutableInfo.data(),
+                pInternalRepresentationCount, pInternalRepresentations, true /* do lock */);
     }
-    AEMU_SCOPED_TRACE("vkGetPipelineExecutableInternalRepresentationsKHR");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    VkResult vkGetPipelineExecutableInternalRepresentationsKHR_VkResult_return = (VkResult)0;
-    vkGetPipelineExecutableInternalRepresentationsKHR_VkResult_return =
-        vkEnc->vkGetPipelineExecutableInternalRepresentationsKHR(
-            device, pExecutableInfo, pInternalRepresentationCount, pInternalRepresentations,
-            true /* do lock */);
     return vkGetPipelineExecutableInternalRepresentationsKHR_VkResult_return;
 }
 #endif
@@ -2968,652 +4525,726 @@
 #ifdef VK_KHR_shader_non_semantic_info
 #endif
 #ifdef VK_KHR_synchronization2
-static void entry_vkCmdSetEvent2KHR(VkCommandBuffer commandBuffer, VkEvent event,
-                                    const VkDependencyInfo* pDependencyInfo) {
+void gfxstream_vk_CmdSetEvent2KHR(VkCommandBuffer commandBuffer, VkEvent event,
+                                  const VkDependencyInfo* pDependencyInfo) {
     AEMU_SCOPED_TRACE("vkCmdSetEvent2KHR");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdSetEvent2KHR(commandBuffer, event, pDependencyInfo, true /* do lock */);
-}
-static void dynCheck_entry_vkCmdSetEvent2KHR(VkCommandBuffer commandBuffer, VkEvent event,
-                                             const VkDependencyInfo* pDependencyInfo) {
-    auto resources = ResourceTracker::get();
-    VkDevice device = resources->getDevice(commandBuffer);
-    ;
-    if (!resources->hasDeviceExtension(device, "VK_KHR_synchronization2")) {
-        sOnInvalidDynamicallyCheckedCall("vkCmdSetEvent2KHR", "VK_KHR_synchronization2");
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    VK_FROM_HANDLE(gfxstream_vk_event, gfxstream_event, event);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        std::vector<VkDependencyInfo> internal_pDependencyInfo(1);
+        std::vector<std::vector<VkBufferMemoryBarrier2>>
+            internal_VkDependencyInfo_pBufferMemoryBarriers;
+        std::vector<std::vector<VkImageMemoryBarrier2>>
+            internal_VkDependencyInfo_pImageMemoryBarriers;
+        for (uint32_t i = 0; i < 1; ++i) {
+            internal_pDependencyInfo[i] = pDependencyInfo[i];
+            /* VkDependencyInfo::pBufferMemoryBarriers */
+            internal_VkDependencyInfo_pBufferMemoryBarriers.push_back(
+                std::vector<VkBufferMemoryBarrier2>());
+            internal_VkDependencyInfo_pBufferMemoryBarriers[i].reserve(
+                internal_pDependencyInfo[i].bufferMemoryBarrierCount);
+            memset(&internal_VkDependencyInfo_pBufferMemoryBarriers[i][0], 0,
+                   sizeof(VkBufferMemoryBarrier2) *
+                       internal_pDependencyInfo[i].bufferMemoryBarrierCount);
+            for (uint32_t j = 0; j < internal_pDependencyInfo[i].bufferMemoryBarrierCount; ++j) {
+                internal_VkDependencyInfo_pBufferMemoryBarriers[i][j] =
+                    internal_pDependencyInfo[i].pBufferMemoryBarriers[j];
+                /* VkBufferMemoryBarrier2::buffer */
+                VK_FROM_HANDLE(gfxstream_vk_buffer, gfxstream_buffer,
+                               internal_VkDependencyInfo_pBufferMemoryBarriers[i][j].buffer);
+                internal_VkDependencyInfo_pBufferMemoryBarriers[i][j].buffer =
+                    gfxstream_buffer->internal_object;
+            }
+            internal_pDependencyInfo[i].pBufferMemoryBarriers =
+                internal_VkDependencyInfo_pBufferMemoryBarriers[i].data();
+            /* VkDependencyInfo::pImageMemoryBarriers */
+            internal_VkDependencyInfo_pImageMemoryBarriers.push_back(
+                std::vector<VkImageMemoryBarrier2>());
+            internal_VkDependencyInfo_pImageMemoryBarriers[i].reserve(
+                internal_pDependencyInfo[i].imageMemoryBarrierCount);
+            memset(&internal_VkDependencyInfo_pImageMemoryBarriers[i][0], 0,
+                   sizeof(VkImageMemoryBarrier2) *
+                       internal_pDependencyInfo[i].imageMemoryBarrierCount);
+            for (uint32_t j = 0; j < internal_pDependencyInfo[i].imageMemoryBarrierCount; ++j) {
+                internal_VkDependencyInfo_pImageMemoryBarriers[i][j] =
+                    internal_pDependencyInfo[i].pImageMemoryBarriers[j];
+                /* VkImageMemoryBarrier2::image */
+                VK_FROM_HANDLE(gfxstream_vk_image, gfxstream_image,
+                               internal_VkDependencyInfo_pImageMemoryBarriers[i][j].image);
+                internal_VkDependencyInfo_pImageMemoryBarriers[i][j].image =
+                    gfxstream_image->internal_object;
+            }
+            internal_pDependencyInfo[i].pImageMemoryBarriers =
+                internal_VkDependencyInfo_pImageMemoryBarriers[i].data();
+        }
+        vkEnc->vkCmdSetEvent2KHR(gfxstream_commandBuffer->internal_object,
+                                 gfxstream_event->internal_object, internal_pDependencyInfo.data(),
+                                 true /* do lock */);
     }
-    AEMU_SCOPED_TRACE("vkCmdSetEvent2KHR");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdSetEvent2KHR(commandBuffer, event, pDependencyInfo, true /* do lock */);
 }
-static void entry_vkCmdResetEvent2KHR(VkCommandBuffer commandBuffer, VkEvent event,
-                                      VkPipelineStageFlags2 stageMask) {
+void gfxstream_vk_CmdResetEvent2KHR(VkCommandBuffer commandBuffer, VkEvent event,
+                                    VkPipelineStageFlags2 stageMask) {
     AEMU_SCOPED_TRACE("vkCmdResetEvent2KHR");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdResetEvent2KHR(commandBuffer, event, stageMask, true /* do lock */);
-}
-static void dynCheck_entry_vkCmdResetEvent2KHR(VkCommandBuffer commandBuffer, VkEvent event,
-                                               VkPipelineStageFlags2 stageMask) {
-    auto resources = ResourceTracker::get();
-    VkDevice device = resources->getDevice(commandBuffer);
-    ;
-    if (!resources->hasDeviceExtension(device, "VK_KHR_synchronization2")) {
-        sOnInvalidDynamicallyCheckedCall("vkCmdResetEvent2KHR", "VK_KHR_synchronization2");
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    VK_FROM_HANDLE(gfxstream_vk_event, gfxstream_event, event);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        vkEnc->vkCmdResetEvent2KHR(gfxstream_commandBuffer->internal_object,
+                                   gfxstream_event->internal_object, stageMask, true /* do lock */);
     }
-    AEMU_SCOPED_TRACE("vkCmdResetEvent2KHR");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdResetEvent2KHR(commandBuffer, event, stageMask, true /* do lock */);
 }
-static void entry_vkCmdWaitEvents2KHR(VkCommandBuffer commandBuffer, uint32_t eventCount,
-                                      const VkEvent* pEvents,
-                                      const VkDependencyInfo* pDependencyInfos) {
+void gfxstream_vk_CmdWaitEvents2KHR(VkCommandBuffer commandBuffer, uint32_t eventCount,
+                                    const VkEvent* pEvents,
+                                    const VkDependencyInfo* pDependencyInfos) {
     AEMU_SCOPED_TRACE("vkCmdWaitEvents2KHR");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdWaitEvents2KHR(commandBuffer, eventCount, pEvents, pDependencyInfos,
-                               true /* do lock */);
-}
-static void dynCheck_entry_vkCmdWaitEvents2KHR(VkCommandBuffer commandBuffer, uint32_t eventCount,
-                                               const VkEvent* pEvents,
-                                               const VkDependencyInfo* pDependencyInfos) {
-    auto resources = ResourceTracker::get();
-    VkDevice device = resources->getDevice(commandBuffer);
-    ;
-    if (!resources->hasDeviceExtension(device, "VK_KHR_synchronization2")) {
-        sOnInvalidDynamicallyCheckedCall("vkCmdWaitEvents2KHR", "VK_KHR_synchronization2");
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        std::vector<VkEvent> internal_pEvents(eventCount);
+        for (uint32_t i = 0; i < eventCount; ++i) {
+            VK_FROM_HANDLE(gfxstream_vk_event, gfxstream_pEvents, pEvents[i]);
+            internal_pEvents[i] = gfxstream_pEvents->internal_object;
+        }
+        std::vector<VkDependencyInfo> internal_pDependencyInfos(eventCount);
+        std::vector<std::vector<VkBufferMemoryBarrier2>>
+            internal_VkDependencyInfo_pBufferMemoryBarriers;
+        std::vector<std::vector<VkImageMemoryBarrier2>>
+            internal_VkDependencyInfo_pImageMemoryBarriers;
+        for (uint32_t i = 0; i < eventCount; ++i) {
+            internal_pDependencyInfos[i] = pDependencyInfos[i];
+            /* VkDependencyInfo::pBufferMemoryBarriers */
+            internal_VkDependencyInfo_pBufferMemoryBarriers.push_back(
+                std::vector<VkBufferMemoryBarrier2>());
+            internal_VkDependencyInfo_pBufferMemoryBarriers[i].reserve(
+                internal_pDependencyInfos[i].bufferMemoryBarrierCount);
+            memset(&internal_VkDependencyInfo_pBufferMemoryBarriers[i][0], 0,
+                   sizeof(VkBufferMemoryBarrier2) *
+                       internal_pDependencyInfos[i].bufferMemoryBarrierCount);
+            for (uint32_t j = 0; j < internal_pDependencyInfos[i].bufferMemoryBarrierCount; ++j) {
+                internal_VkDependencyInfo_pBufferMemoryBarriers[i][j] =
+                    internal_pDependencyInfos[i].pBufferMemoryBarriers[j];
+                /* VkBufferMemoryBarrier2::buffer */
+                VK_FROM_HANDLE(gfxstream_vk_buffer, gfxstream_buffer,
+                               internal_VkDependencyInfo_pBufferMemoryBarriers[i][j].buffer);
+                internal_VkDependencyInfo_pBufferMemoryBarriers[i][j].buffer =
+                    gfxstream_buffer->internal_object;
+            }
+            internal_pDependencyInfos[i].pBufferMemoryBarriers =
+                internal_VkDependencyInfo_pBufferMemoryBarriers[i].data();
+            /* VkDependencyInfo::pImageMemoryBarriers */
+            internal_VkDependencyInfo_pImageMemoryBarriers.push_back(
+                std::vector<VkImageMemoryBarrier2>());
+            internal_VkDependencyInfo_pImageMemoryBarriers[i].reserve(
+                internal_pDependencyInfos[i].imageMemoryBarrierCount);
+            memset(&internal_VkDependencyInfo_pImageMemoryBarriers[i][0], 0,
+                   sizeof(VkImageMemoryBarrier2) *
+                       internal_pDependencyInfos[i].imageMemoryBarrierCount);
+            for (uint32_t j = 0; j < internal_pDependencyInfos[i].imageMemoryBarrierCount; ++j) {
+                internal_VkDependencyInfo_pImageMemoryBarriers[i][j] =
+                    internal_pDependencyInfos[i].pImageMemoryBarriers[j];
+                /* VkImageMemoryBarrier2::image */
+                VK_FROM_HANDLE(gfxstream_vk_image, gfxstream_image,
+                               internal_VkDependencyInfo_pImageMemoryBarriers[i][j].image);
+                internal_VkDependencyInfo_pImageMemoryBarriers[i][j].image =
+                    gfxstream_image->internal_object;
+            }
+            internal_pDependencyInfos[i].pImageMemoryBarriers =
+                internal_VkDependencyInfo_pImageMemoryBarriers[i].data();
+        }
+        vkEnc->vkCmdWaitEvents2KHR(gfxstream_commandBuffer->internal_object, eventCount,
+                                   internal_pEvents.data(), internal_pDependencyInfos.data(),
+                                   true /* do lock */);
     }
-    AEMU_SCOPED_TRACE("vkCmdWaitEvents2KHR");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdWaitEvents2KHR(commandBuffer, eventCount, pEvents, pDependencyInfos,
-                               true /* do lock */);
 }
-static void entry_vkCmdPipelineBarrier2KHR(VkCommandBuffer commandBuffer,
-                                           const VkDependencyInfo* pDependencyInfo) {
+void gfxstream_vk_CmdPipelineBarrier2KHR(VkCommandBuffer commandBuffer,
+                                         const VkDependencyInfo* pDependencyInfo) {
     AEMU_SCOPED_TRACE("vkCmdPipelineBarrier2KHR");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdPipelineBarrier2KHR(commandBuffer, pDependencyInfo, true /* do lock */);
-}
-static void dynCheck_entry_vkCmdPipelineBarrier2KHR(VkCommandBuffer commandBuffer,
-                                                    const VkDependencyInfo* pDependencyInfo) {
-    auto resources = ResourceTracker::get();
-    VkDevice device = resources->getDevice(commandBuffer);
-    ;
-    if (!resources->hasDeviceExtension(device, "VK_KHR_synchronization2")) {
-        sOnInvalidDynamicallyCheckedCall("vkCmdPipelineBarrier2KHR", "VK_KHR_synchronization2");
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        std::vector<VkDependencyInfo> internal_pDependencyInfo(1);
+        std::vector<std::vector<VkBufferMemoryBarrier2>>
+            internal_VkDependencyInfo_pBufferMemoryBarriers;
+        std::vector<std::vector<VkImageMemoryBarrier2>>
+            internal_VkDependencyInfo_pImageMemoryBarriers;
+        for (uint32_t i = 0; i < 1; ++i) {
+            internal_pDependencyInfo[i] = pDependencyInfo[i];
+            /* VkDependencyInfo::pBufferMemoryBarriers */
+            internal_VkDependencyInfo_pBufferMemoryBarriers.push_back(
+                std::vector<VkBufferMemoryBarrier2>());
+            internal_VkDependencyInfo_pBufferMemoryBarriers[i].reserve(
+                internal_pDependencyInfo[i].bufferMemoryBarrierCount);
+            memset(&internal_VkDependencyInfo_pBufferMemoryBarriers[i][0], 0,
+                   sizeof(VkBufferMemoryBarrier2) *
+                       internal_pDependencyInfo[i].bufferMemoryBarrierCount);
+            for (uint32_t j = 0; j < internal_pDependencyInfo[i].bufferMemoryBarrierCount; ++j) {
+                internal_VkDependencyInfo_pBufferMemoryBarriers[i][j] =
+                    internal_pDependencyInfo[i].pBufferMemoryBarriers[j];
+                /* VkBufferMemoryBarrier2::buffer */
+                VK_FROM_HANDLE(gfxstream_vk_buffer, gfxstream_buffer,
+                               internal_VkDependencyInfo_pBufferMemoryBarriers[i][j].buffer);
+                internal_VkDependencyInfo_pBufferMemoryBarriers[i][j].buffer =
+                    gfxstream_buffer->internal_object;
+            }
+            internal_pDependencyInfo[i].pBufferMemoryBarriers =
+                internal_VkDependencyInfo_pBufferMemoryBarriers[i].data();
+            /* VkDependencyInfo::pImageMemoryBarriers */
+            internal_VkDependencyInfo_pImageMemoryBarriers.push_back(
+                std::vector<VkImageMemoryBarrier2>());
+            internal_VkDependencyInfo_pImageMemoryBarriers[i].reserve(
+                internal_pDependencyInfo[i].imageMemoryBarrierCount);
+            memset(&internal_VkDependencyInfo_pImageMemoryBarriers[i][0], 0,
+                   sizeof(VkImageMemoryBarrier2) *
+                       internal_pDependencyInfo[i].imageMemoryBarrierCount);
+            for (uint32_t j = 0; j < internal_pDependencyInfo[i].imageMemoryBarrierCount; ++j) {
+                internal_VkDependencyInfo_pImageMemoryBarriers[i][j] =
+                    internal_pDependencyInfo[i].pImageMemoryBarriers[j];
+                /* VkImageMemoryBarrier2::image */
+                VK_FROM_HANDLE(gfxstream_vk_image, gfxstream_image,
+                               internal_VkDependencyInfo_pImageMemoryBarriers[i][j].image);
+                internal_VkDependencyInfo_pImageMemoryBarriers[i][j].image =
+                    gfxstream_image->internal_object;
+            }
+            internal_pDependencyInfo[i].pImageMemoryBarriers =
+                internal_VkDependencyInfo_pImageMemoryBarriers[i].data();
+        }
+        vkEnc->vkCmdPipelineBarrier2KHR(gfxstream_commandBuffer->internal_object,
+                                        internal_pDependencyInfo.data(), true /* do lock */);
     }
-    AEMU_SCOPED_TRACE("vkCmdPipelineBarrier2KHR");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdPipelineBarrier2KHR(commandBuffer, pDependencyInfo, true /* do lock */);
 }
-static void entry_vkCmdWriteTimestamp2KHR(VkCommandBuffer commandBuffer,
-                                          VkPipelineStageFlags2 stage, VkQueryPool queryPool,
-                                          uint32_t query) {
+void gfxstream_vk_CmdWriteTimestamp2KHR(VkCommandBuffer commandBuffer, VkPipelineStageFlags2 stage,
+                                        VkQueryPool queryPool, uint32_t query) {
     AEMU_SCOPED_TRACE("vkCmdWriteTimestamp2KHR");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdWriteTimestamp2KHR(commandBuffer, stage, queryPool, query, true /* do lock */);
-}
-static void dynCheck_entry_vkCmdWriteTimestamp2KHR(VkCommandBuffer commandBuffer,
-                                                   VkPipelineStageFlags2 stage,
-                                                   VkQueryPool queryPool, uint32_t query) {
-    auto resources = ResourceTracker::get();
-    VkDevice device = resources->getDevice(commandBuffer);
-    ;
-    if (!resources->hasDeviceExtension(device, "VK_KHR_synchronization2")) {
-        sOnInvalidDynamicallyCheckedCall("vkCmdWriteTimestamp2KHR", "VK_KHR_synchronization2");
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    VK_FROM_HANDLE(gfxstream_vk_query_pool, gfxstream_queryPool, queryPool);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        vkEnc->vkCmdWriteTimestamp2KHR(gfxstream_commandBuffer->internal_object, stage,
+                                       gfxstream_queryPool->internal_object, query,
+                                       true /* do lock */);
     }
-    AEMU_SCOPED_TRACE("vkCmdWriteTimestamp2KHR");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdWriteTimestamp2KHR(commandBuffer, stage, queryPool, query, true /* do lock */);
 }
-static VkResult entry_vkQueueSubmit2KHR(VkQueue queue, uint32_t submitCount,
-                                        const VkSubmitInfo2* pSubmits, VkFence fence) {
+VkResult gfxstream_vk_QueueSubmit2KHR(VkQueue queue, uint32_t submitCount,
+                                      const VkSubmitInfo2* pSubmits, VkFence fence) {
     AEMU_SCOPED_TRACE("vkQueueSubmit2KHR");
-    auto vkEnc = ResourceTracker::getQueueEncoder(queue);
     VkResult vkQueueSubmit2KHR_VkResult_return = (VkResult)0;
-    vkQueueSubmit2KHR_VkResult_return =
-        vkEnc->vkQueueSubmit2KHR(queue, submitCount, pSubmits, fence, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_queue, gfxstream_queue, queue);
+    VK_FROM_HANDLE(gfxstream_vk_fence, gfxstream_fence, fence);
+    {
+        auto vkEnc =
+            gfxstream::vk::ResourceTracker::getQueueEncoder(gfxstream_queue->internal_object);
+        std::vector<VkSubmitInfo2> internal_pSubmits(submitCount);
+        std::vector<std::vector<VkSemaphoreSubmitInfo>> internal_VkSubmitInfo2_pWaitSemaphoreInfos;
+        std::vector<std::vector<VkCommandBufferSubmitInfo>>
+            internal_VkSubmitInfo2_pCommandBufferInfos;
+        std::vector<std::vector<VkSemaphoreSubmitInfo>>
+            internal_VkSubmitInfo2_pSignalSemaphoreInfos;
+        for (uint32_t i = 0; i < submitCount; ++i) {
+            internal_pSubmits[i] = pSubmits[i];
+            /* VkSubmitInfo2::pWaitSemaphoreInfos */
+            internal_VkSubmitInfo2_pWaitSemaphoreInfos.push_back(
+                std::vector<VkSemaphoreSubmitInfo>());
+            internal_VkSubmitInfo2_pWaitSemaphoreInfos[i] =
+                transformVkSemaphoreSubmitInfoList(internal_pSubmits[i].pWaitSemaphoreInfos,
+                                                   internal_pSubmits[i].waitSemaphoreInfoCount);
+            internal_pSubmits[i].pWaitSemaphoreInfos =
+                internal_VkSubmitInfo2_pWaitSemaphoreInfos[i].data();
+            internal_pSubmits[i].waitSemaphoreInfoCount =
+                internal_VkSubmitInfo2_pWaitSemaphoreInfos[i].size();
+            /* VkSubmitInfo2::pCommandBufferInfos */
+            internal_VkSubmitInfo2_pCommandBufferInfos.push_back(
+                std::vector<VkCommandBufferSubmitInfo>());
+            internal_VkSubmitInfo2_pCommandBufferInfos[i].reserve(
+                internal_pSubmits[i].commandBufferInfoCount);
+            memset(&internal_VkSubmitInfo2_pCommandBufferInfos[i][0], 0,
+                   sizeof(VkCommandBufferSubmitInfo) * internal_pSubmits[i].commandBufferInfoCount);
+            for (uint32_t j = 0; j < internal_pSubmits[i].commandBufferInfoCount; ++j) {
+                internal_VkSubmitInfo2_pCommandBufferInfos[i][j] =
+                    internal_pSubmits[i].pCommandBufferInfos[j];
+                /* VkCommandBufferSubmitInfo::commandBuffer */
+                VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer,
+                               internal_VkSubmitInfo2_pCommandBufferInfos[i][j].commandBuffer);
+                internal_VkSubmitInfo2_pCommandBufferInfos[i][j].commandBuffer =
+                    gfxstream_commandBuffer->internal_object;
+            }
+            internal_pSubmits[i].pCommandBufferInfos =
+                internal_VkSubmitInfo2_pCommandBufferInfos[i].data();
+            /* VkSubmitInfo2::pSignalSemaphoreInfos */
+            internal_VkSubmitInfo2_pSignalSemaphoreInfos.push_back(
+                std::vector<VkSemaphoreSubmitInfo>());
+            internal_VkSubmitInfo2_pSignalSemaphoreInfos[i] =
+                transformVkSemaphoreSubmitInfoList(internal_pSubmits[i].pSignalSemaphoreInfos,
+                                                   internal_pSubmits[i].signalSemaphoreInfoCount);
+            internal_pSubmits[i].pSignalSemaphoreInfos =
+                internal_VkSubmitInfo2_pSignalSemaphoreInfos[i].data();
+            internal_pSubmits[i].signalSemaphoreInfoCount =
+                internal_VkSubmitInfo2_pSignalSemaphoreInfos[i].size();
+        }
+        vkQueueSubmit2KHR_VkResult_return = vkEnc->vkQueueSubmit2KHR(
+            gfxstream_queue->internal_object, submitCount, internal_pSubmits.data(),
+            gfxstream_fence ? gfxstream_fence->internal_object : VK_NULL_HANDLE,
+            true /* do lock */);
+    }
     return vkQueueSubmit2KHR_VkResult_return;
 }
-static void entry_vkCmdWriteBufferMarker2AMD(VkCommandBuffer commandBuffer,
-                                             VkPipelineStageFlags2 stage, VkBuffer dstBuffer,
-                                             VkDeviceSize dstOffset, uint32_t marker) {
+void gfxstream_vk_CmdWriteBufferMarker2AMD(VkCommandBuffer commandBuffer,
+                                           VkPipelineStageFlags2 stage, VkBuffer dstBuffer,
+                                           VkDeviceSize dstOffset, uint32_t marker) {
     AEMU_SCOPED_TRACE("vkCmdWriteBufferMarker2AMD");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdWriteBufferMarker2AMD(commandBuffer, stage, dstBuffer, dstOffset, marker,
-                                      true /* do lock */);
-}
-static void dynCheck_entry_vkCmdWriteBufferMarker2AMD(VkCommandBuffer commandBuffer,
-                                                      VkPipelineStageFlags2 stage,
-                                                      VkBuffer dstBuffer, VkDeviceSize dstOffset,
-                                                      uint32_t marker) {
-    auto resources = ResourceTracker::get();
-    VkDevice device = resources->getDevice(commandBuffer);
-    ;
-    if (!resources->hasDeviceExtension(device, "VK_KHR_synchronization2")) {
-        sOnInvalidDynamicallyCheckedCall("vkCmdWriteBufferMarker2AMD", "VK_KHR_synchronization2");
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    VK_FROM_HANDLE(gfxstream_vk_buffer, gfxstream_dstBuffer, dstBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        vkEnc->vkCmdWriteBufferMarker2AMD(gfxstream_commandBuffer->internal_object, stage,
+                                          gfxstream_dstBuffer->internal_object, dstOffset, marker,
+                                          true /* do lock */);
     }
-    AEMU_SCOPED_TRACE("vkCmdWriteBufferMarker2AMD");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdWriteBufferMarker2AMD(commandBuffer, stage, dstBuffer, dstOffset, marker,
-                                      true /* do lock */);
 }
-static void entry_vkGetQueueCheckpointData2NV(VkQueue queue, uint32_t* pCheckpointDataCount,
-                                              VkCheckpointData2NV* pCheckpointData) {
+void gfxstream_vk_GetQueueCheckpointData2NV(VkQueue queue, uint32_t* pCheckpointDataCount,
+                                            VkCheckpointData2NV* pCheckpointData) {
     AEMU_SCOPED_TRACE("vkGetQueueCheckpointData2NV");
-    auto vkEnc = ResourceTracker::getQueueEncoder(queue);
-    vkEnc->vkGetQueueCheckpointData2NV(queue, pCheckpointDataCount, pCheckpointData,
-                                       true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_queue, gfxstream_queue, queue);
+    {
+        auto vkEnc =
+            gfxstream::vk::ResourceTracker::getQueueEncoder(gfxstream_queue->internal_object);
+        vkEnc->vkGetQueueCheckpointData2NV(gfxstream_queue->internal_object, pCheckpointDataCount,
+                                           pCheckpointData, true /* do lock */);
+    }
 }
 #endif
 #ifdef VK_KHR_zero_initialize_workgroup_memory
 #endif
 #ifdef VK_KHR_copy_commands2
-static void entry_vkCmdCopyBuffer2KHR(VkCommandBuffer commandBuffer,
-                                      const VkCopyBufferInfo2* pCopyBufferInfo) {
+void gfxstream_vk_CmdCopyBuffer2KHR(VkCommandBuffer commandBuffer,
+                                    const VkCopyBufferInfo2* pCopyBufferInfo) {
     AEMU_SCOPED_TRACE("vkCmdCopyBuffer2KHR");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdCopyBuffer2KHR(commandBuffer, pCopyBufferInfo, true /* do lock */);
-}
-static void dynCheck_entry_vkCmdCopyBuffer2KHR(VkCommandBuffer commandBuffer,
-                                               const VkCopyBufferInfo2* pCopyBufferInfo) {
-    auto resources = ResourceTracker::get();
-    VkDevice device = resources->getDevice(commandBuffer);
-    ;
-    if (!resources->hasDeviceExtension(device, "VK_KHR_copy_commands2")) {
-        sOnInvalidDynamicallyCheckedCall("vkCmdCopyBuffer2KHR", "VK_KHR_copy_commands2");
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        std::vector<VkCopyBufferInfo2> internal_pCopyBufferInfo(1);
+        for (uint32_t i = 0; i < 1; ++i) {
+            internal_pCopyBufferInfo[i] = pCopyBufferInfo[i];
+            /* VkCopyBufferInfo2::srcBuffer */
+            VK_FROM_HANDLE(gfxstream_vk_buffer, gfxstream_srcBuffer,
+                           internal_pCopyBufferInfo[i].srcBuffer);
+            internal_pCopyBufferInfo[i].srcBuffer = gfxstream_srcBuffer->internal_object;
+            /* VkCopyBufferInfo2::dstBuffer */
+            VK_FROM_HANDLE(gfxstream_vk_buffer, gfxstream_dstBuffer,
+                           internal_pCopyBufferInfo[i].dstBuffer);
+            internal_pCopyBufferInfo[i].dstBuffer = gfxstream_dstBuffer->internal_object;
+        }
+        vkEnc->vkCmdCopyBuffer2KHR(gfxstream_commandBuffer->internal_object,
+                                   internal_pCopyBufferInfo.data(), true /* do lock */);
     }
-    AEMU_SCOPED_TRACE("vkCmdCopyBuffer2KHR");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdCopyBuffer2KHR(commandBuffer, pCopyBufferInfo, true /* do lock */);
 }
-static void entry_vkCmdCopyImage2KHR(VkCommandBuffer commandBuffer,
-                                     const VkCopyImageInfo2* pCopyImageInfo) {
+void gfxstream_vk_CmdCopyImage2KHR(VkCommandBuffer commandBuffer,
+                                   const VkCopyImageInfo2* pCopyImageInfo) {
     AEMU_SCOPED_TRACE("vkCmdCopyImage2KHR");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdCopyImage2KHR(commandBuffer, pCopyImageInfo, true /* do lock */);
-}
-static void dynCheck_entry_vkCmdCopyImage2KHR(VkCommandBuffer commandBuffer,
-                                              const VkCopyImageInfo2* pCopyImageInfo) {
-    auto resources = ResourceTracker::get();
-    VkDevice device = resources->getDevice(commandBuffer);
-    ;
-    if (!resources->hasDeviceExtension(device, "VK_KHR_copy_commands2")) {
-        sOnInvalidDynamicallyCheckedCall("vkCmdCopyImage2KHR", "VK_KHR_copy_commands2");
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        std::vector<VkCopyImageInfo2> internal_pCopyImageInfo(1);
+        for (uint32_t i = 0; i < 1; ++i) {
+            internal_pCopyImageInfo[i] = pCopyImageInfo[i];
+            /* VkCopyImageInfo2::srcImage */
+            VK_FROM_HANDLE(gfxstream_vk_image, gfxstream_srcImage,
+                           internal_pCopyImageInfo[i].srcImage);
+            internal_pCopyImageInfo[i].srcImage = gfxstream_srcImage->internal_object;
+            /* VkCopyImageInfo2::dstImage */
+            VK_FROM_HANDLE(gfxstream_vk_image, gfxstream_dstImage,
+                           internal_pCopyImageInfo[i].dstImage);
+            internal_pCopyImageInfo[i].dstImage = gfxstream_dstImage->internal_object;
+        }
+        vkEnc->vkCmdCopyImage2KHR(gfxstream_commandBuffer->internal_object,
+                                  internal_pCopyImageInfo.data(), true /* do lock */);
     }
-    AEMU_SCOPED_TRACE("vkCmdCopyImage2KHR");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdCopyImage2KHR(commandBuffer, pCopyImageInfo, true /* do lock */);
 }
-static void entry_vkCmdCopyBufferToImage2KHR(
-    VkCommandBuffer commandBuffer, const VkCopyBufferToImageInfo2* pCopyBufferToImageInfo) {
+void gfxstream_vk_CmdCopyBufferToImage2KHR(VkCommandBuffer commandBuffer,
+                                           const VkCopyBufferToImageInfo2* pCopyBufferToImageInfo) {
     AEMU_SCOPED_TRACE("vkCmdCopyBufferToImage2KHR");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdCopyBufferToImage2KHR(commandBuffer, pCopyBufferToImageInfo, true /* do lock */);
-}
-static void dynCheck_entry_vkCmdCopyBufferToImage2KHR(
-    VkCommandBuffer commandBuffer, const VkCopyBufferToImageInfo2* pCopyBufferToImageInfo) {
-    auto resources = ResourceTracker::get();
-    VkDevice device = resources->getDevice(commandBuffer);
-    ;
-    if (!resources->hasDeviceExtension(device, "VK_KHR_copy_commands2")) {
-        sOnInvalidDynamicallyCheckedCall("vkCmdCopyBufferToImage2KHR", "VK_KHR_copy_commands2");
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        std::vector<VkCopyBufferToImageInfo2> internal_pCopyBufferToImageInfo(1);
+        for (uint32_t i = 0; i < 1; ++i) {
+            internal_pCopyBufferToImageInfo[i] = pCopyBufferToImageInfo[i];
+            /* VkCopyBufferToImageInfo2::srcBuffer */
+            VK_FROM_HANDLE(gfxstream_vk_buffer, gfxstream_srcBuffer,
+                           internal_pCopyBufferToImageInfo[i].srcBuffer);
+            internal_pCopyBufferToImageInfo[i].srcBuffer = gfxstream_srcBuffer->internal_object;
+            /* VkCopyBufferToImageInfo2::dstImage */
+            VK_FROM_HANDLE(gfxstream_vk_image, gfxstream_dstImage,
+                           internal_pCopyBufferToImageInfo[i].dstImage);
+            internal_pCopyBufferToImageInfo[i].dstImage = gfxstream_dstImage->internal_object;
+        }
+        vkEnc->vkCmdCopyBufferToImage2KHR(gfxstream_commandBuffer->internal_object,
+                                          internal_pCopyBufferToImageInfo.data(),
+                                          true /* do lock */);
     }
-    AEMU_SCOPED_TRACE("vkCmdCopyBufferToImage2KHR");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdCopyBufferToImage2KHR(commandBuffer, pCopyBufferToImageInfo, true /* do lock */);
 }
-static void entry_vkCmdCopyImageToBuffer2KHR(
-    VkCommandBuffer commandBuffer, const VkCopyImageToBufferInfo2* pCopyImageToBufferInfo) {
+void gfxstream_vk_CmdCopyImageToBuffer2KHR(VkCommandBuffer commandBuffer,
+                                           const VkCopyImageToBufferInfo2* pCopyImageToBufferInfo) {
     AEMU_SCOPED_TRACE("vkCmdCopyImageToBuffer2KHR");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdCopyImageToBuffer2KHR(commandBuffer, pCopyImageToBufferInfo, true /* do lock */);
-}
-static void dynCheck_entry_vkCmdCopyImageToBuffer2KHR(
-    VkCommandBuffer commandBuffer, const VkCopyImageToBufferInfo2* pCopyImageToBufferInfo) {
-    auto resources = ResourceTracker::get();
-    VkDevice device = resources->getDevice(commandBuffer);
-    ;
-    if (!resources->hasDeviceExtension(device, "VK_KHR_copy_commands2")) {
-        sOnInvalidDynamicallyCheckedCall("vkCmdCopyImageToBuffer2KHR", "VK_KHR_copy_commands2");
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        std::vector<VkCopyImageToBufferInfo2> internal_pCopyImageToBufferInfo(1);
+        for (uint32_t i = 0; i < 1; ++i) {
+            internal_pCopyImageToBufferInfo[i] = pCopyImageToBufferInfo[i];
+            /* VkCopyImageToBufferInfo2::srcImage */
+            VK_FROM_HANDLE(gfxstream_vk_image, gfxstream_srcImage,
+                           internal_pCopyImageToBufferInfo[i].srcImage);
+            internal_pCopyImageToBufferInfo[i].srcImage = gfxstream_srcImage->internal_object;
+            /* VkCopyImageToBufferInfo2::dstBuffer */
+            VK_FROM_HANDLE(gfxstream_vk_buffer, gfxstream_dstBuffer,
+                           internal_pCopyImageToBufferInfo[i].dstBuffer);
+            internal_pCopyImageToBufferInfo[i].dstBuffer = gfxstream_dstBuffer->internal_object;
+        }
+        vkEnc->vkCmdCopyImageToBuffer2KHR(gfxstream_commandBuffer->internal_object,
+                                          internal_pCopyImageToBufferInfo.data(),
+                                          true /* do lock */);
     }
-    AEMU_SCOPED_TRACE("vkCmdCopyImageToBuffer2KHR");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdCopyImageToBuffer2KHR(commandBuffer, pCopyImageToBufferInfo, true /* do lock */);
 }
-static void entry_vkCmdBlitImage2KHR(VkCommandBuffer commandBuffer,
-                                     const VkBlitImageInfo2* pBlitImageInfo) {
+void gfxstream_vk_CmdBlitImage2KHR(VkCommandBuffer commandBuffer,
+                                   const VkBlitImageInfo2* pBlitImageInfo) {
     AEMU_SCOPED_TRACE("vkCmdBlitImage2KHR");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdBlitImage2KHR(commandBuffer, pBlitImageInfo, true /* do lock */);
-}
-static void dynCheck_entry_vkCmdBlitImage2KHR(VkCommandBuffer commandBuffer,
-                                              const VkBlitImageInfo2* pBlitImageInfo) {
-    auto resources = ResourceTracker::get();
-    VkDevice device = resources->getDevice(commandBuffer);
-    ;
-    if (!resources->hasDeviceExtension(device, "VK_KHR_copy_commands2")) {
-        sOnInvalidDynamicallyCheckedCall("vkCmdBlitImage2KHR", "VK_KHR_copy_commands2");
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        std::vector<VkBlitImageInfo2> internal_pBlitImageInfo(1);
+        for (uint32_t i = 0; i < 1; ++i) {
+            internal_pBlitImageInfo[i] = pBlitImageInfo[i];
+            /* VkBlitImageInfo2::srcImage */
+            VK_FROM_HANDLE(gfxstream_vk_image, gfxstream_srcImage,
+                           internal_pBlitImageInfo[i].srcImage);
+            internal_pBlitImageInfo[i].srcImage = gfxstream_srcImage->internal_object;
+            /* VkBlitImageInfo2::dstImage */
+            VK_FROM_HANDLE(gfxstream_vk_image, gfxstream_dstImage,
+                           internal_pBlitImageInfo[i].dstImage);
+            internal_pBlitImageInfo[i].dstImage = gfxstream_dstImage->internal_object;
+        }
+        vkEnc->vkCmdBlitImage2KHR(gfxstream_commandBuffer->internal_object,
+                                  internal_pBlitImageInfo.data(), true /* do lock */);
     }
-    AEMU_SCOPED_TRACE("vkCmdBlitImage2KHR");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdBlitImage2KHR(commandBuffer, pBlitImageInfo, true /* do lock */);
 }
-static void entry_vkCmdResolveImage2KHR(VkCommandBuffer commandBuffer,
-                                        const VkResolveImageInfo2* pResolveImageInfo) {
+void gfxstream_vk_CmdResolveImage2KHR(VkCommandBuffer commandBuffer,
+                                      const VkResolveImageInfo2* pResolveImageInfo) {
     AEMU_SCOPED_TRACE("vkCmdResolveImage2KHR");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdResolveImage2KHR(commandBuffer, pResolveImageInfo, true /* do lock */);
-}
-static void dynCheck_entry_vkCmdResolveImage2KHR(VkCommandBuffer commandBuffer,
-                                                 const VkResolveImageInfo2* pResolveImageInfo) {
-    auto resources = ResourceTracker::get();
-    VkDevice device = resources->getDevice(commandBuffer);
-    ;
-    if (!resources->hasDeviceExtension(device, "VK_KHR_copy_commands2")) {
-        sOnInvalidDynamicallyCheckedCall("vkCmdResolveImage2KHR", "VK_KHR_copy_commands2");
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        std::vector<VkResolveImageInfo2> internal_pResolveImageInfo(1);
+        for (uint32_t i = 0; i < 1; ++i) {
+            internal_pResolveImageInfo[i] = pResolveImageInfo[i];
+            /* VkResolveImageInfo2::srcImage */
+            VK_FROM_HANDLE(gfxstream_vk_image, gfxstream_srcImage,
+                           internal_pResolveImageInfo[i].srcImage);
+            internal_pResolveImageInfo[i].srcImage = gfxstream_srcImage->internal_object;
+            /* VkResolveImageInfo2::dstImage */
+            VK_FROM_HANDLE(gfxstream_vk_image, gfxstream_dstImage,
+                           internal_pResolveImageInfo[i].dstImage);
+            internal_pResolveImageInfo[i].dstImage = gfxstream_dstImage->internal_object;
+        }
+        vkEnc->vkCmdResolveImage2KHR(gfxstream_commandBuffer->internal_object,
+                                     internal_pResolveImageInfo.data(), true /* do lock */);
     }
-    AEMU_SCOPED_TRACE("vkCmdResolveImage2KHR");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdResolveImage2KHR(commandBuffer, pResolveImageInfo, true /* do lock */);
 }
 #endif
 #ifdef VK_KHR_format_feature_flags2
 #endif
 #ifdef VK_KHR_maintenance4
-static void entry_vkGetDeviceBufferMemoryRequirementsKHR(
+void gfxstream_vk_GetDeviceBufferMemoryRequirementsKHR(
     VkDevice device, const VkDeviceBufferMemoryRequirements* pInfo,
     VkMemoryRequirements2* pMemoryRequirements) {
     AEMU_SCOPED_TRACE("vkGetDeviceBufferMemoryRequirementsKHR");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkGetDeviceBufferMemoryRequirementsKHR(device, pInfo, pMemoryRequirements,
-                                                  true /* do lock */);
-}
-static void dynCheck_entry_vkGetDeviceBufferMemoryRequirementsKHR(
-    VkDevice device, const VkDeviceBufferMemoryRequirements* pInfo,
-    VkMemoryRequirements2* pMemoryRequirements) {
-    auto resources = ResourceTracker::get();
-    if (!resources->hasDeviceExtension(device, "VK_KHR_maintenance4")) {
-        sOnInvalidDynamicallyCheckedCall("vkGetDeviceBufferMemoryRequirementsKHR",
-                                         "VK_KHR_maintenance4");
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkEnc->vkGetDeviceBufferMemoryRequirementsKHR(gfxstream_device->internal_object, pInfo,
+                                                      pMemoryRequirements, true /* do lock */);
     }
-    AEMU_SCOPED_TRACE("vkGetDeviceBufferMemoryRequirementsKHR");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkGetDeviceBufferMemoryRequirementsKHR(device, pInfo, pMemoryRequirements,
-                                                  true /* do lock */);
 }
-static void entry_vkGetDeviceImageMemoryRequirementsKHR(
-    VkDevice device, const VkDeviceImageMemoryRequirements* pInfo,
-    VkMemoryRequirements2* pMemoryRequirements) {
+void gfxstream_vk_GetDeviceImageMemoryRequirementsKHR(VkDevice device,
+                                                      const VkDeviceImageMemoryRequirements* pInfo,
+                                                      VkMemoryRequirements2* pMemoryRequirements) {
     AEMU_SCOPED_TRACE("vkGetDeviceImageMemoryRequirementsKHR");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkGetDeviceImageMemoryRequirementsKHR(device, pInfo, pMemoryRequirements,
-                                                 true /* do lock */);
-}
-static void dynCheck_entry_vkGetDeviceImageMemoryRequirementsKHR(
-    VkDevice device, const VkDeviceImageMemoryRequirements* pInfo,
-    VkMemoryRequirements2* pMemoryRequirements) {
-    auto resources = ResourceTracker::get();
-    if (!resources->hasDeviceExtension(device, "VK_KHR_maintenance4")) {
-        sOnInvalidDynamicallyCheckedCall("vkGetDeviceImageMemoryRequirementsKHR",
-                                         "VK_KHR_maintenance4");
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkEnc->vkGetDeviceImageMemoryRequirementsKHR(gfxstream_device->internal_object, pInfo,
+                                                     pMemoryRequirements, true /* do lock */);
     }
-    AEMU_SCOPED_TRACE("vkGetDeviceImageMemoryRequirementsKHR");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkGetDeviceImageMemoryRequirementsKHR(device, pInfo, pMemoryRequirements,
-                                                 true /* do lock */);
 }
-static void entry_vkGetDeviceImageSparseMemoryRequirementsKHR(
+void gfxstream_vk_GetDeviceImageSparseMemoryRequirementsKHR(
     VkDevice device, const VkDeviceImageMemoryRequirements* pInfo,
     uint32_t* pSparseMemoryRequirementCount,
     VkSparseImageMemoryRequirements2* pSparseMemoryRequirements) {
     AEMU_SCOPED_TRACE("vkGetDeviceImageSparseMemoryRequirementsKHR");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkGetDeviceImageSparseMemoryRequirementsKHR(device, pInfo, pSparseMemoryRequirementCount,
-                                                       pSparseMemoryRequirements,
-                                                       true /* do lock */);
-}
-static void dynCheck_entry_vkGetDeviceImageSparseMemoryRequirementsKHR(
-    VkDevice device, const VkDeviceImageMemoryRequirements* pInfo,
-    uint32_t* pSparseMemoryRequirementCount,
-    VkSparseImageMemoryRequirements2* pSparseMemoryRequirements) {
-    auto resources = ResourceTracker::get();
-    if (!resources->hasDeviceExtension(device, "VK_KHR_maintenance4")) {
-        sOnInvalidDynamicallyCheckedCall("vkGetDeviceImageSparseMemoryRequirementsKHR",
-                                         "VK_KHR_maintenance4");
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkEnc->vkGetDeviceImageSparseMemoryRequirementsKHR(
+            gfxstream_device->internal_object, pInfo, pSparseMemoryRequirementCount,
+            pSparseMemoryRequirements, true /* do lock */);
     }
-    AEMU_SCOPED_TRACE("vkGetDeviceImageSparseMemoryRequirementsKHR");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkGetDeviceImageSparseMemoryRequirementsKHR(device, pInfo, pSparseMemoryRequirementCount,
-                                                       pSparseMemoryRequirements,
-                                                       true /* do lock */);
 }
 #endif
 #ifdef VK_KHR_maintenance5
-static void entry_vkCmdBindIndexBuffer2KHR(VkCommandBuffer commandBuffer, VkBuffer buffer,
-                                           VkDeviceSize offset, VkDeviceSize size,
-                                           VkIndexType indexType) {
+void gfxstream_vk_CmdBindIndexBuffer2KHR(VkCommandBuffer commandBuffer, VkBuffer buffer,
+                                         VkDeviceSize offset, VkDeviceSize size,
+                                         VkIndexType indexType) {
     AEMU_SCOPED_TRACE("vkCmdBindIndexBuffer2KHR");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdBindIndexBuffer2KHR(commandBuffer, buffer, offset, size, indexType,
-                                    true /* do lock */);
-}
-static void dynCheck_entry_vkCmdBindIndexBuffer2KHR(VkCommandBuffer commandBuffer, VkBuffer buffer,
-                                                    VkDeviceSize offset, VkDeviceSize size,
-                                                    VkIndexType indexType) {
-    auto resources = ResourceTracker::get();
-    VkDevice device = resources->getDevice(commandBuffer);
-    ;
-    if (!resources->hasDeviceExtension(device, "VK_KHR_maintenance5")) {
-        sOnInvalidDynamicallyCheckedCall("vkCmdBindIndexBuffer2KHR", "VK_KHR_maintenance5");
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    VK_FROM_HANDLE(gfxstream_vk_buffer, gfxstream_buffer, buffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        vkEnc->vkCmdBindIndexBuffer2KHR(gfxstream_commandBuffer->internal_object,
+                                        gfxstream_buffer->internal_object, offset, size, indexType,
+                                        true /* do lock */);
     }
-    AEMU_SCOPED_TRACE("vkCmdBindIndexBuffer2KHR");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdBindIndexBuffer2KHR(commandBuffer, buffer, offset, size, indexType,
-                                    true /* do lock */);
 }
-static void entry_vkGetRenderingAreaGranularityKHR(VkDevice device,
-                                                   const VkRenderingAreaInfoKHR* pRenderingAreaInfo,
-                                                   VkExtent2D* pGranularity) {
+void gfxstream_vk_GetRenderingAreaGranularityKHR(VkDevice device,
+                                                 const VkRenderingAreaInfoKHR* pRenderingAreaInfo,
+                                                 VkExtent2D* pGranularity) {
     AEMU_SCOPED_TRACE("vkGetRenderingAreaGranularityKHR");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkGetRenderingAreaGranularityKHR(device, pRenderingAreaInfo, pGranularity,
-                                            true /* do lock */);
-}
-static void dynCheck_entry_vkGetRenderingAreaGranularityKHR(
-    VkDevice device, const VkRenderingAreaInfoKHR* pRenderingAreaInfo, VkExtent2D* pGranularity) {
-    auto resources = ResourceTracker::get();
-    if (!resources->hasDeviceExtension(device, "VK_KHR_maintenance5")) {
-        sOnInvalidDynamicallyCheckedCall("vkGetRenderingAreaGranularityKHR", "VK_KHR_maintenance5");
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkEnc->vkGetRenderingAreaGranularityKHR(gfxstream_device->internal_object,
+                                                pRenderingAreaInfo, pGranularity,
+                                                true /* do lock */);
     }
-    AEMU_SCOPED_TRACE("vkGetRenderingAreaGranularityKHR");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkGetRenderingAreaGranularityKHR(device, pRenderingAreaInfo, pGranularity,
-                                            true /* do lock */);
 }
-static void entry_vkGetDeviceImageSubresourceLayoutKHR(VkDevice device,
-                                                       const VkDeviceImageSubresourceInfoKHR* pInfo,
-                                                       VkSubresourceLayout2KHR* pLayout) {
+void gfxstream_vk_GetDeviceImageSubresourceLayoutKHR(VkDevice device,
+                                                     const VkDeviceImageSubresourceInfoKHR* pInfo,
+                                                     VkSubresourceLayout2KHR* pLayout) {
     AEMU_SCOPED_TRACE("vkGetDeviceImageSubresourceLayoutKHR");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkGetDeviceImageSubresourceLayoutKHR(device, pInfo, pLayout, true /* do lock */);
-}
-static void dynCheck_entry_vkGetDeviceImageSubresourceLayoutKHR(
-    VkDevice device, const VkDeviceImageSubresourceInfoKHR* pInfo,
-    VkSubresourceLayout2KHR* pLayout) {
-    auto resources = ResourceTracker::get();
-    if (!resources->hasDeviceExtension(device, "VK_KHR_maintenance5")) {
-        sOnInvalidDynamicallyCheckedCall("vkGetDeviceImageSubresourceLayoutKHR",
-                                         "VK_KHR_maintenance5");
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkEnc->vkGetDeviceImageSubresourceLayoutKHR(gfxstream_device->internal_object, pInfo,
+                                                    pLayout, true /* do lock */);
     }
-    AEMU_SCOPED_TRACE("vkGetDeviceImageSubresourceLayoutKHR");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkGetDeviceImageSubresourceLayoutKHR(device, pInfo, pLayout, true /* do lock */);
 }
-static void entry_vkGetImageSubresourceLayout2KHR(VkDevice device, VkImage image,
-                                                  const VkImageSubresource2KHR* pSubresource,
-                                                  VkSubresourceLayout2KHR* pLayout) {
+void gfxstream_vk_GetImageSubresourceLayout2KHR(VkDevice device, VkImage image,
+                                                const VkImageSubresource2KHR* pSubresource,
+                                                VkSubresourceLayout2KHR* pLayout) {
     AEMU_SCOPED_TRACE("vkGetImageSubresourceLayout2KHR");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkGetImageSubresourceLayout2KHR(device, image, pSubresource, pLayout,
-                                           true /* do lock */);
-}
-static void dynCheck_entry_vkGetImageSubresourceLayout2KHR(
-    VkDevice device, VkImage image, const VkImageSubresource2KHR* pSubresource,
-    VkSubresourceLayout2KHR* pLayout) {
-    auto resources = ResourceTracker::get();
-    if (!resources->hasDeviceExtension(device, "VK_KHR_maintenance5")) {
-        sOnInvalidDynamicallyCheckedCall("vkGetImageSubresourceLayout2KHR", "VK_KHR_maintenance5");
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    VK_FROM_HANDLE(gfxstream_vk_image, gfxstream_image, image);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkEnc->vkGetImageSubresourceLayout2KHR(gfxstream_device->internal_object,
+                                               gfxstream_image->internal_object, pSubresource,
+                                               pLayout, true /* do lock */);
     }
-    AEMU_SCOPED_TRACE("vkGetImageSubresourceLayout2KHR");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkGetImageSubresourceLayout2KHR(device, image, pSubresource, pLayout,
-                                           true /* do lock */);
 }
 #endif
 #ifdef VK_ANDROID_native_buffer
-static VkResult entry_vkGetSwapchainGrallocUsageANDROID(VkDevice device, VkFormat format,
-                                                        VkImageUsageFlags imageUsage,
-                                                        int* grallocUsage) {
+VkResult gfxstream_vk_GetSwapchainGrallocUsageANDROID(VkDevice device, VkFormat format,
+                                                      VkImageUsageFlags imageUsage,
+                                                      int* grallocUsage) {
     AEMU_SCOPED_TRACE("vkGetSwapchainGrallocUsageANDROID");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
     VkResult vkGetSwapchainGrallocUsageANDROID_VkResult_return = (VkResult)0;
-    vkGetSwapchainGrallocUsageANDROID_VkResult_return = vkEnc->vkGetSwapchainGrallocUsageANDROID(
-        device, format, imageUsage, grallocUsage, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkGetSwapchainGrallocUsageANDROID_VkResult_return =
+            vkEnc->vkGetSwapchainGrallocUsageANDROID(gfxstream_device->internal_object, format,
+                                                     imageUsage, grallocUsage, true /* do lock */);
+    }
     return vkGetSwapchainGrallocUsageANDROID_VkResult_return;
 }
-static VkResult dynCheck_entry_vkGetSwapchainGrallocUsageANDROID(VkDevice device, VkFormat format,
-                                                                 VkImageUsageFlags imageUsage,
-                                                                 int* grallocUsage) {
-    auto resources = ResourceTracker::get();
-    if (!resources->hasDeviceExtension(device, "VK_ANDROID_native_buffer")) {
-        sOnInvalidDynamicallyCheckedCall("vkGetSwapchainGrallocUsageANDROID",
-                                         "VK_ANDROID_native_buffer");
-    }
-    AEMU_SCOPED_TRACE("vkGetSwapchainGrallocUsageANDROID");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    VkResult vkGetSwapchainGrallocUsageANDROID_VkResult_return = (VkResult)0;
-    vkGetSwapchainGrallocUsageANDROID_VkResult_return = vkEnc->vkGetSwapchainGrallocUsageANDROID(
-        device, format, imageUsage, grallocUsage, true /* do lock */);
-    return vkGetSwapchainGrallocUsageANDROID_VkResult_return;
-}
-static VkResult entry_vkAcquireImageANDROID(VkDevice device, VkImage image, int nativeFenceFd,
-                                            VkSemaphore semaphore, VkFence fence) {
+VkResult gfxstream_vk_AcquireImageANDROID(VkDevice device, VkImage image, int nativeFenceFd,
+                                          VkSemaphore semaphore, VkFence fence) {
     AEMU_SCOPED_TRACE("vkAcquireImageANDROID");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
     VkResult vkAcquireImageANDROID_VkResult_return = (VkResult)0;
-    vkAcquireImageANDROID_VkResult_return = vkEnc->vkAcquireImageANDROID(
-        device, image, nativeFenceFd, semaphore, fence, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    VK_FROM_HANDLE(gfxstream_vk_image, gfxstream_image, image);
+    VK_FROM_HANDLE(gfxstream_vk_semaphore, gfxstream_semaphore, semaphore);
+    VK_FROM_HANDLE(gfxstream_vk_fence, gfxstream_fence, fence);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkAcquireImageANDROID_VkResult_return = vkEnc->vkAcquireImageANDROID(
+            gfxstream_device->internal_object, gfxstream_image->internal_object, nativeFenceFd,
+            gfxstream_semaphore ? gfxstream_semaphore->internal_object : VK_NULL_HANDLE,
+            gfxstream_fence ? gfxstream_fence->internal_object : VK_NULL_HANDLE,
+            true /* do lock */);
+    }
     return vkAcquireImageANDROID_VkResult_return;
 }
-static VkResult dynCheck_entry_vkAcquireImageANDROID(VkDevice device, VkImage image,
-                                                     int nativeFenceFd, VkSemaphore semaphore,
-                                                     VkFence fence) {
-    auto resources = ResourceTracker::get();
-    if (!resources->hasDeviceExtension(device, "VK_ANDROID_native_buffer")) {
-        sOnInvalidDynamicallyCheckedCall("vkAcquireImageANDROID", "VK_ANDROID_native_buffer");
-    }
-    AEMU_SCOPED_TRACE("vkAcquireImageANDROID");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    VkResult vkAcquireImageANDROID_VkResult_return = (VkResult)0;
-    vkAcquireImageANDROID_VkResult_return = vkEnc->vkAcquireImageANDROID(
-        device, image, nativeFenceFd, semaphore, fence, true /* do lock */);
-    return vkAcquireImageANDROID_VkResult_return;
-}
-static VkResult entry_vkQueueSignalReleaseImageANDROID(VkQueue queue, uint32_t waitSemaphoreCount,
-                                                       const VkSemaphore* pWaitSemaphores,
-                                                       VkImage image, int* pNativeFenceFd) {
+VkResult gfxstream_vk_QueueSignalReleaseImageANDROID(VkQueue queue, uint32_t waitSemaphoreCount,
+                                                     const VkSemaphore* pWaitSemaphores,
+                                                     VkImage image, int* pNativeFenceFd) {
     AEMU_SCOPED_TRACE("vkQueueSignalReleaseImageANDROID");
-    auto vkEnc = ResourceTracker::getQueueEncoder(queue);
     VkResult vkQueueSignalReleaseImageANDROID_VkResult_return = (VkResult)0;
-    auto resources = ResourceTracker::get();
-    vkQueueSignalReleaseImageANDROID_VkResult_return =
-        resources->on_vkQueueSignalReleaseImageANDROID(vkEnc, VK_SUCCESS, queue, waitSemaphoreCount,
-                                                       pWaitSemaphores, image, pNativeFenceFd);
+    VK_FROM_HANDLE(gfxstream_vk_queue, gfxstream_queue, queue);
+    VK_FROM_HANDLE(gfxstream_vk_image, gfxstream_image, image);
+    {
+        auto vkEnc =
+            gfxstream::vk::ResourceTracker::getQueueEncoder(gfxstream_queue->internal_object);
+        std::vector<VkSemaphore> internal_pWaitSemaphores(waitSemaphoreCount);
+        for (uint32_t i = 0; i < waitSemaphoreCount; ++i) {
+            if (pWaitSemaphores) {
+                VK_FROM_HANDLE(gfxstream_vk_semaphore, gfxstream_pWaitSemaphores,
+                               pWaitSemaphores[i]);
+                internal_pWaitSemaphores[i] = gfxstream_pWaitSemaphores->internal_object;
+            }
+        }
+        auto resources = gfxstream::vk::ResourceTracker::get();
+        vkQueueSignalReleaseImageANDROID_VkResult_return =
+            resources->on_vkQueueSignalReleaseImageANDROID(
+                vkEnc, VK_SUCCESS, gfxstream_queue->internal_object, waitSemaphoreCount,
+                internal_pWaitSemaphores.data(), gfxstream_image->internal_object, pNativeFenceFd);
+    }
     return vkQueueSignalReleaseImageANDROID_VkResult_return;
 }
-static VkResult entry_vkGetSwapchainGrallocUsage2ANDROID(
+VkResult gfxstream_vk_GetSwapchainGrallocUsage2ANDROID(
     VkDevice device, VkFormat format, VkImageUsageFlags imageUsage,
     VkSwapchainImageUsageFlagsANDROID swapchainImageUsage, uint64_t* grallocConsumerUsage,
     uint64_t* grallocProducerUsage) {
     AEMU_SCOPED_TRACE("vkGetSwapchainGrallocUsage2ANDROID");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
     VkResult vkGetSwapchainGrallocUsage2ANDROID_VkResult_return = (VkResult)0;
-    vkGetSwapchainGrallocUsage2ANDROID_VkResult_return = vkEnc->vkGetSwapchainGrallocUsage2ANDROID(
-        device, format, imageUsage, swapchainImageUsage, grallocConsumerUsage, grallocProducerUsage,
-        true /* do lock */);
-    return vkGetSwapchainGrallocUsage2ANDROID_VkResult_return;
-}
-static VkResult dynCheck_entry_vkGetSwapchainGrallocUsage2ANDROID(
-    VkDevice device, VkFormat format, VkImageUsageFlags imageUsage,
-    VkSwapchainImageUsageFlagsANDROID swapchainImageUsage, uint64_t* grallocConsumerUsage,
-    uint64_t* grallocProducerUsage) {
-    auto resources = ResourceTracker::get();
-    if (!resources->hasDeviceExtension(device, "VK_ANDROID_native_buffer")) {
-        sOnInvalidDynamicallyCheckedCall("vkGetSwapchainGrallocUsage2ANDROID",
-                                         "VK_ANDROID_native_buffer");
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkGetSwapchainGrallocUsage2ANDROID_VkResult_return =
+            vkEnc->vkGetSwapchainGrallocUsage2ANDROID(
+                gfxstream_device->internal_object, format, imageUsage, swapchainImageUsage,
+                grallocConsumerUsage, grallocProducerUsage, true /* do lock */);
     }
-    AEMU_SCOPED_TRACE("vkGetSwapchainGrallocUsage2ANDROID");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    VkResult vkGetSwapchainGrallocUsage2ANDROID_VkResult_return = (VkResult)0;
-    vkGetSwapchainGrallocUsage2ANDROID_VkResult_return = vkEnc->vkGetSwapchainGrallocUsage2ANDROID(
-        device, format, imageUsage, swapchainImageUsage, grallocConsumerUsage, grallocProducerUsage,
-        true /* do lock */);
     return vkGetSwapchainGrallocUsage2ANDROID_VkResult_return;
 }
 #endif
 #ifdef VK_EXT_transform_feedback
-static void entry_vkCmdBindTransformFeedbackBuffersEXT(VkCommandBuffer commandBuffer,
-                                                       uint32_t firstBinding, uint32_t bindingCount,
-                                                       const VkBuffer* pBuffers,
-                                                       const VkDeviceSize* pOffsets,
-                                                       const VkDeviceSize* pSizes) {
+void gfxstream_vk_CmdBindTransformFeedbackBuffersEXT(VkCommandBuffer commandBuffer,
+                                                     uint32_t firstBinding, uint32_t bindingCount,
+                                                     const VkBuffer* pBuffers,
+                                                     const VkDeviceSize* pOffsets,
+                                                     const VkDeviceSize* pSizes) {
     AEMU_SCOPED_TRACE("vkCmdBindTransformFeedbackBuffersEXT");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdBindTransformFeedbackBuffersEXT(commandBuffer, firstBinding, bindingCount, pBuffers,
-                                                pOffsets, pSizes, true /* do lock */);
-}
-static void dynCheck_entry_vkCmdBindTransformFeedbackBuffersEXT(
-    VkCommandBuffer commandBuffer, uint32_t firstBinding, uint32_t bindingCount,
-    const VkBuffer* pBuffers, const VkDeviceSize* pOffsets, const VkDeviceSize* pSizes) {
-    auto resources = ResourceTracker::get();
-    VkDevice device = resources->getDevice(commandBuffer);
-    ;
-    if (!resources->hasDeviceExtension(device, "VK_EXT_transform_feedback")) {
-        sOnInvalidDynamicallyCheckedCall("vkCmdBindTransformFeedbackBuffersEXT",
-                                         "VK_EXT_transform_feedback");
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        std::vector<VkBuffer> internal_pBuffers(bindingCount);
+        for (uint32_t i = 0; i < bindingCount; ++i) {
+            VK_FROM_HANDLE(gfxstream_vk_buffer, gfxstream_pBuffers, pBuffers[i]);
+            internal_pBuffers[i] = gfxstream_pBuffers->internal_object;
+        }
+        vkEnc->vkCmdBindTransformFeedbackBuffersEXT(
+            gfxstream_commandBuffer->internal_object, firstBinding, bindingCount,
+            internal_pBuffers.data(), pOffsets, pSizes, true /* do lock */);
     }
-    AEMU_SCOPED_TRACE("vkCmdBindTransformFeedbackBuffersEXT");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdBindTransformFeedbackBuffersEXT(commandBuffer, firstBinding, bindingCount, pBuffers,
-                                                pOffsets, pSizes, true /* do lock */);
 }
-static void entry_vkCmdBeginTransformFeedbackEXT(VkCommandBuffer commandBuffer,
-                                                 uint32_t firstCounterBuffer,
-                                                 uint32_t counterBufferCount,
-                                                 const VkBuffer* pCounterBuffers,
-                                                 const VkDeviceSize* pCounterBufferOffsets) {
-    AEMU_SCOPED_TRACE("vkCmdBeginTransformFeedbackEXT");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdBeginTransformFeedbackEXT(commandBuffer, firstCounterBuffer, counterBufferCount,
-                                          pCounterBuffers, pCounterBufferOffsets,
-                                          true /* do lock */);
-}
-static void dynCheck_entry_vkCmdBeginTransformFeedbackEXT(
-    VkCommandBuffer commandBuffer, uint32_t firstCounterBuffer, uint32_t counterBufferCount,
-    const VkBuffer* pCounterBuffers, const VkDeviceSize* pCounterBufferOffsets) {
-    auto resources = ResourceTracker::get();
-    VkDevice device = resources->getDevice(commandBuffer);
-    ;
-    if (!resources->hasDeviceExtension(device, "VK_EXT_transform_feedback")) {
-        sOnInvalidDynamicallyCheckedCall("vkCmdBeginTransformFeedbackEXT",
-                                         "VK_EXT_transform_feedback");
-    }
-    AEMU_SCOPED_TRACE("vkCmdBeginTransformFeedbackEXT");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdBeginTransformFeedbackEXT(commandBuffer, firstCounterBuffer, counterBufferCount,
-                                          pCounterBuffers, pCounterBufferOffsets,
-                                          true /* do lock */);
-}
-static void entry_vkCmdEndTransformFeedbackEXT(VkCommandBuffer commandBuffer,
+void gfxstream_vk_CmdBeginTransformFeedbackEXT(VkCommandBuffer commandBuffer,
                                                uint32_t firstCounterBuffer,
                                                uint32_t counterBufferCount,
                                                const VkBuffer* pCounterBuffers,
                                                const VkDeviceSize* pCounterBufferOffsets) {
+    AEMU_SCOPED_TRACE("vkCmdBeginTransformFeedbackEXT");
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        std::vector<VkBuffer> internal_pCounterBuffers(counterBufferCount);
+        for (uint32_t i = 0; i < counterBufferCount; ++i) {
+            if (pCounterBuffers) {
+                VK_FROM_HANDLE(gfxstream_vk_buffer, gfxstream_pCounterBuffers, pCounterBuffers[i]);
+                internal_pCounterBuffers[i] = gfxstream_pCounterBuffers->internal_object;
+            }
+        }
+        vkEnc->vkCmdBeginTransformFeedbackEXT(
+            gfxstream_commandBuffer->internal_object, firstCounterBuffer, counterBufferCount,
+            internal_pCounterBuffers.data(), pCounterBufferOffsets, true /* do lock */);
+    }
+}
+void gfxstream_vk_CmdEndTransformFeedbackEXT(VkCommandBuffer commandBuffer,
+                                             uint32_t firstCounterBuffer,
+                                             uint32_t counterBufferCount,
+                                             const VkBuffer* pCounterBuffers,
+                                             const VkDeviceSize* pCounterBufferOffsets) {
     AEMU_SCOPED_TRACE("vkCmdEndTransformFeedbackEXT");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdEndTransformFeedbackEXT(commandBuffer, firstCounterBuffer, counterBufferCount,
-                                        pCounterBuffers, pCounterBufferOffsets, true /* do lock */);
-}
-static void dynCheck_entry_vkCmdEndTransformFeedbackEXT(VkCommandBuffer commandBuffer,
-                                                        uint32_t firstCounterBuffer,
-                                                        uint32_t counterBufferCount,
-                                                        const VkBuffer* pCounterBuffers,
-                                                        const VkDeviceSize* pCounterBufferOffsets) {
-    auto resources = ResourceTracker::get();
-    VkDevice device = resources->getDevice(commandBuffer);
-    ;
-    if (!resources->hasDeviceExtension(device, "VK_EXT_transform_feedback")) {
-        sOnInvalidDynamicallyCheckedCall("vkCmdEndTransformFeedbackEXT",
-                                         "VK_EXT_transform_feedback");
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        std::vector<VkBuffer> internal_pCounterBuffers(counterBufferCount);
+        for (uint32_t i = 0; i < counterBufferCount; ++i) {
+            if (pCounterBuffers) {
+                VK_FROM_HANDLE(gfxstream_vk_buffer, gfxstream_pCounterBuffers, pCounterBuffers[i]);
+                internal_pCounterBuffers[i] = gfxstream_pCounterBuffers->internal_object;
+            }
+        }
+        vkEnc->vkCmdEndTransformFeedbackEXT(
+            gfxstream_commandBuffer->internal_object, firstCounterBuffer, counterBufferCount,
+            internal_pCounterBuffers.data(), pCounterBufferOffsets, true /* do lock */);
     }
-    AEMU_SCOPED_TRACE("vkCmdEndTransformFeedbackEXT");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdEndTransformFeedbackEXT(commandBuffer, firstCounterBuffer, counterBufferCount,
-                                        pCounterBuffers, pCounterBufferOffsets, true /* do lock */);
 }
-static void entry_vkCmdBeginQueryIndexedEXT(VkCommandBuffer commandBuffer, VkQueryPool queryPool,
-                                            uint32_t query, VkQueryControlFlags flags,
-                                            uint32_t index) {
+void gfxstream_vk_CmdBeginQueryIndexedEXT(VkCommandBuffer commandBuffer, VkQueryPool queryPool,
+                                          uint32_t query, VkQueryControlFlags flags,
+                                          uint32_t index) {
     AEMU_SCOPED_TRACE("vkCmdBeginQueryIndexedEXT");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdBeginQueryIndexedEXT(commandBuffer, queryPool, query, flags, index,
-                                     true /* do lock */);
-}
-static void dynCheck_entry_vkCmdBeginQueryIndexedEXT(VkCommandBuffer commandBuffer,
-                                                     VkQueryPool queryPool, uint32_t query,
-                                                     VkQueryControlFlags flags, uint32_t index) {
-    auto resources = ResourceTracker::get();
-    VkDevice device = resources->getDevice(commandBuffer);
-    ;
-    if (!resources->hasDeviceExtension(device, "VK_EXT_transform_feedback")) {
-        sOnInvalidDynamicallyCheckedCall("vkCmdBeginQueryIndexedEXT", "VK_EXT_transform_feedback");
-    }
-    AEMU_SCOPED_TRACE("vkCmdBeginQueryIndexedEXT");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdBeginQueryIndexedEXT(commandBuffer, queryPool, query, flags, index,
-                                     true /* do lock */);
-}
-static void entry_vkCmdEndQueryIndexedEXT(VkCommandBuffer commandBuffer, VkQueryPool queryPool,
-                                          uint32_t query, uint32_t index) {
-    AEMU_SCOPED_TRACE("vkCmdEndQueryIndexedEXT");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdEndQueryIndexedEXT(commandBuffer, queryPool, query, index, true /* do lock */);
-}
-static void dynCheck_entry_vkCmdEndQueryIndexedEXT(VkCommandBuffer commandBuffer,
-                                                   VkQueryPool queryPool, uint32_t query,
-                                                   uint32_t index) {
-    auto resources = ResourceTracker::get();
-    VkDevice device = resources->getDevice(commandBuffer);
-    ;
-    if (!resources->hasDeviceExtension(device, "VK_EXT_transform_feedback")) {
-        sOnInvalidDynamicallyCheckedCall("vkCmdEndQueryIndexedEXT", "VK_EXT_transform_feedback");
-    }
-    AEMU_SCOPED_TRACE("vkCmdEndQueryIndexedEXT");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdEndQueryIndexedEXT(commandBuffer, queryPool, query, index, true /* do lock */);
-}
-static void entry_vkCmdDrawIndirectByteCountEXT(VkCommandBuffer commandBuffer,
-                                                uint32_t instanceCount, uint32_t firstInstance,
-                                                VkBuffer counterBuffer,
-                                                VkDeviceSize counterBufferOffset,
-                                                uint32_t counterOffset, uint32_t vertexStride) {
-    AEMU_SCOPED_TRACE("vkCmdDrawIndirectByteCountEXT");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdDrawIndirectByteCountEXT(commandBuffer, instanceCount, firstInstance, counterBuffer,
-                                         counterBufferOffset, counterOffset, vertexStride,
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    VK_FROM_HANDLE(gfxstream_vk_query_pool, gfxstream_queryPool, queryPool);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        vkEnc->vkCmdBeginQueryIndexedEXT(gfxstream_commandBuffer->internal_object,
+                                         gfxstream_queryPool->internal_object, query, flags, index,
                                          true /* do lock */);
-}
-static void dynCheck_entry_vkCmdDrawIndirectByteCountEXT(
-    VkCommandBuffer commandBuffer, uint32_t instanceCount, uint32_t firstInstance,
-    VkBuffer counterBuffer, VkDeviceSize counterBufferOffset, uint32_t counterOffset,
-    uint32_t vertexStride) {
-    auto resources = ResourceTracker::get();
-    VkDevice device = resources->getDevice(commandBuffer);
-    ;
-    if (!resources->hasDeviceExtension(device, "VK_EXT_transform_feedback")) {
-        sOnInvalidDynamicallyCheckedCall("vkCmdDrawIndirectByteCountEXT",
-                                         "VK_EXT_transform_feedback");
     }
+}
+void gfxstream_vk_CmdEndQueryIndexedEXT(VkCommandBuffer commandBuffer, VkQueryPool queryPool,
+                                        uint32_t query, uint32_t index) {
+    AEMU_SCOPED_TRACE("vkCmdEndQueryIndexedEXT");
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    VK_FROM_HANDLE(gfxstream_vk_query_pool, gfxstream_queryPool, queryPool);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        vkEnc->vkCmdEndQueryIndexedEXT(gfxstream_commandBuffer->internal_object,
+                                       gfxstream_queryPool->internal_object, query, index,
+                                       true /* do lock */);
+    }
+}
+void gfxstream_vk_CmdDrawIndirectByteCountEXT(VkCommandBuffer commandBuffer, uint32_t instanceCount,
+                                              uint32_t firstInstance, VkBuffer counterBuffer,
+                                              VkDeviceSize counterBufferOffset,
+                                              uint32_t counterOffset, uint32_t vertexStride) {
     AEMU_SCOPED_TRACE("vkCmdDrawIndirectByteCountEXT");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdDrawIndirectByteCountEXT(commandBuffer, instanceCount, firstInstance, counterBuffer,
-                                         counterBufferOffset, counterOffset, vertexStride,
-                                         true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    VK_FROM_HANDLE(gfxstream_vk_buffer, gfxstream_counterBuffer, counterBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        vkEnc->vkCmdDrawIndirectByteCountEXT(
+            gfxstream_commandBuffer->internal_object, instanceCount, firstInstance,
+            gfxstream_counterBuffer->internal_object, counterBufferOffset, counterOffset,
+            vertexStride, true /* do lock */);
+    }
 }
 #endif
 #ifdef VK_AMD_gpu_shader_half_float
 #endif
 #ifdef VK_EXT_texture_compression_astc_hdr
 #endif
+#ifdef VK_EXT_depth_clip_enable
+#endif
 #ifdef VK_EXT_swapchain_colorspace
 #endif
 #ifdef VK_EXT_queue_family_foreign
@@ -3621,62 +5252,42 @@
 #ifdef VK_EXT_debug_utils
 #endif
 #ifdef VK_ANDROID_external_memory_android_hardware_buffer
-static VkResult entry_vkGetAndroidHardwareBufferPropertiesANDROID(
+VkResult gfxstream_vk_GetAndroidHardwareBufferPropertiesANDROID(
     VkDevice device, const AHardwareBuffer* buffer,
     VkAndroidHardwareBufferPropertiesANDROID* pProperties) {
     AEMU_SCOPED_TRACE("vkGetAndroidHardwareBufferPropertiesANDROID");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
     VkResult vkGetAndroidHardwareBufferPropertiesANDROID_VkResult_return = (VkResult)0;
-    auto resources = ResourceTracker::get();
-    vkGetAndroidHardwareBufferPropertiesANDROID_VkResult_return =
-        resources->on_vkGetAndroidHardwareBufferPropertiesANDROID(vkEnc, VK_SUCCESS, device, buffer,
-                                                                  pProperties);
-    return vkGetAndroidHardwareBufferPropertiesANDROID_VkResult_return;
-}
-static VkResult dynCheck_entry_vkGetAndroidHardwareBufferPropertiesANDROID(
-    VkDevice device, const AHardwareBuffer* buffer,
-    VkAndroidHardwareBufferPropertiesANDROID* pProperties) {
-    auto resources = ResourceTracker::get();
-    if (!resources->hasDeviceExtension(device,
-                                       "VK_ANDROID_external_memory_android_hardware_buffer")) {
-        sOnInvalidDynamicallyCheckedCall("vkGetAndroidHardwareBufferPropertiesANDROID",
-                                         "VK_ANDROID_external_memory_android_hardware_buffer");
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        auto resources = gfxstream::vk::ResourceTracker::get();
+        vkGetAndroidHardwareBufferPropertiesANDROID_VkResult_return =
+            resources->on_vkGetAndroidHardwareBufferPropertiesANDROID(
+                vkEnc, VK_SUCCESS, gfxstream_device->internal_object, buffer, pProperties);
     }
-    AEMU_SCOPED_TRACE("vkGetAndroidHardwareBufferPropertiesANDROID");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    VkResult vkGetAndroidHardwareBufferPropertiesANDROID_VkResult_return = (VkResult)0;
-    vkGetAndroidHardwareBufferPropertiesANDROID_VkResult_return =
-        resources->on_vkGetAndroidHardwareBufferPropertiesANDROID(vkEnc, VK_SUCCESS, device, buffer,
-                                                                  pProperties);
     return vkGetAndroidHardwareBufferPropertiesANDROID_VkResult_return;
 }
-static VkResult entry_vkGetMemoryAndroidHardwareBufferANDROID(
+VkResult gfxstream_vk_GetMemoryAndroidHardwareBufferANDROID(
     VkDevice device, const VkMemoryGetAndroidHardwareBufferInfoANDROID* pInfo,
     AHardwareBuffer** pBuffer) {
     AEMU_SCOPED_TRACE("vkGetMemoryAndroidHardwareBufferANDROID");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
     VkResult vkGetMemoryAndroidHardwareBufferANDROID_VkResult_return = (VkResult)0;
-    auto resources = ResourceTracker::get();
-    vkGetMemoryAndroidHardwareBufferANDROID_VkResult_return =
-        resources->on_vkGetMemoryAndroidHardwareBufferANDROID(vkEnc, VK_SUCCESS, device, pInfo,
-                                                              pBuffer);
-    return vkGetMemoryAndroidHardwareBufferANDROID_VkResult_return;
-}
-static VkResult dynCheck_entry_vkGetMemoryAndroidHardwareBufferANDROID(
-    VkDevice device, const VkMemoryGetAndroidHardwareBufferInfoANDROID* pInfo,
-    AHardwareBuffer** pBuffer) {
-    auto resources = ResourceTracker::get();
-    if (!resources->hasDeviceExtension(device,
-                                       "VK_ANDROID_external_memory_android_hardware_buffer")) {
-        sOnInvalidDynamicallyCheckedCall("vkGetMemoryAndroidHardwareBufferANDROID",
-                                         "VK_ANDROID_external_memory_android_hardware_buffer");
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        std::vector<VkMemoryGetAndroidHardwareBufferInfoANDROID> internal_pInfo(1);
+        for (uint32_t i = 0; i < 1; ++i) {
+            internal_pInfo[i] = pInfo[i];
+            /* VkMemoryGetAndroidHardwareBufferInfoANDROID::memory */
+            VK_FROM_HANDLE(gfxstream_vk_device_memory, gfxstream_memory, internal_pInfo[i].memory);
+            internal_pInfo[i].memory = gfxstream_memory->internal_object;
+        }
+        auto resources = gfxstream::vk::ResourceTracker::get();
+        vkGetMemoryAndroidHardwareBufferANDROID_VkResult_return =
+            resources->on_vkGetMemoryAndroidHardwareBufferANDROID(vkEnc, VK_SUCCESS,
+                                                                  gfxstream_device->internal_object,
+                                                                  internal_pInfo.data(), pBuffer);
     }
-    AEMU_SCOPED_TRACE("vkGetMemoryAndroidHardwareBufferANDROID");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    VkResult vkGetMemoryAndroidHardwareBufferANDROID_VkResult_return = (VkResult)0;
-    vkGetMemoryAndroidHardwareBufferANDROID_VkResult_return =
-        resources->on_vkGetMemoryAndroidHardwareBufferANDROID(vkEnc, VK_SUCCESS, device, pInfo,
-                                                              pBuffer);
     return vkGetMemoryAndroidHardwareBufferANDROID_VkResult_return;
 }
 #endif
@@ -3697,402 +5308,283 @@
 #ifdef VK_EXT_subgroup_size_control
 #endif
 #ifdef VK_EXT_tooling_info
-static VkResult entry_vkGetPhysicalDeviceToolPropertiesEXT(
+VkResult gfxstream_vk_GetPhysicalDeviceToolPropertiesEXT(
     VkPhysicalDevice physicalDevice, uint32_t* pToolCount,
     VkPhysicalDeviceToolProperties* pToolProperties) {
     AEMU_SCOPED_TRACE("vkGetPhysicalDeviceToolPropertiesEXT");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
     VkResult vkGetPhysicalDeviceToolPropertiesEXT_VkResult_return = (VkResult)0;
-    vkGetPhysicalDeviceToolPropertiesEXT_VkResult_return =
-        vkEnc->vkGetPhysicalDeviceToolPropertiesEXT(physicalDevice, pToolCount, pToolProperties,
-                                                    true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_physical_device, gfxstream_physicalDevice, physicalDevice);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkGetPhysicalDeviceToolPropertiesEXT_VkResult_return =
+            vkEnc->vkGetPhysicalDeviceToolPropertiesEXT(gfxstream_physicalDevice->internal_object,
+                                                        pToolCount, pToolProperties,
+                                                        true /* do lock */);
+    }
     return vkGetPhysicalDeviceToolPropertiesEXT_VkResult_return;
 }
 #endif
 #ifdef VK_EXT_provoking_vertex
 #endif
 #ifdef VK_EXT_line_rasterization
-static void entry_vkCmdSetLineStippleEXT(VkCommandBuffer commandBuffer, uint32_t lineStippleFactor,
-                                         uint16_t lineStipplePattern) {
+void gfxstream_vk_CmdSetLineStippleEXT(VkCommandBuffer commandBuffer, uint32_t lineStippleFactor,
+                                       uint16_t lineStipplePattern) {
     AEMU_SCOPED_TRACE("vkCmdSetLineStippleEXT");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdSetLineStippleEXT(commandBuffer, lineStippleFactor, lineStipplePattern,
-                                  true /* do lock */);
-}
-static void dynCheck_entry_vkCmdSetLineStippleEXT(VkCommandBuffer commandBuffer,
-                                                  uint32_t lineStippleFactor,
-                                                  uint16_t lineStipplePattern) {
-    auto resources = ResourceTracker::get();
-    VkDevice device = resources->getDevice(commandBuffer);
-    ;
-    if (!resources->hasDeviceExtension(device, "VK_EXT_line_rasterization")) {
-        sOnInvalidDynamicallyCheckedCall("vkCmdSetLineStippleEXT", "VK_EXT_line_rasterization");
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        vkEnc->vkCmdSetLineStippleEXT(gfxstream_commandBuffer->internal_object, lineStippleFactor,
+                                      lineStipplePattern, true /* do lock */);
     }
-    AEMU_SCOPED_TRACE("vkCmdSetLineStippleEXT");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdSetLineStippleEXT(commandBuffer, lineStippleFactor, lineStipplePattern,
-                                  true /* do lock */);
 }
 #endif
 #ifdef VK_EXT_index_type_uint8
 #endif
 #ifdef VK_EXT_extended_dynamic_state
-static void entry_vkCmdSetCullModeEXT(VkCommandBuffer commandBuffer, VkCullModeFlags cullMode) {
+void gfxstream_vk_CmdSetCullModeEXT(VkCommandBuffer commandBuffer, VkCullModeFlags cullMode) {
     AEMU_SCOPED_TRACE("vkCmdSetCullModeEXT");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdSetCullModeEXT(commandBuffer, cullMode, true /* do lock */);
-}
-static void dynCheck_entry_vkCmdSetCullModeEXT(VkCommandBuffer commandBuffer,
-                                               VkCullModeFlags cullMode) {
-    auto resources = ResourceTracker::get();
-    VkDevice device = resources->getDevice(commandBuffer);
-    ;
-    if (!resources->hasDeviceExtension(device, "VK_EXT_extended_dynamic_state")) {
-        sOnInvalidDynamicallyCheckedCall("vkCmdSetCullModeEXT", "VK_EXT_extended_dynamic_state");
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        vkEnc->vkCmdSetCullModeEXT(gfxstream_commandBuffer->internal_object, cullMode,
+                                   true /* do lock */);
     }
-    AEMU_SCOPED_TRACE("vkCmdSetCullModeEXT");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdSetCullModeEXT(commandBuffer, cullMode, true /* do lock */);
 }
-static void entry_vkCmdSetFrontFaceEXT(VkCommandBuffer commandBuffer, VkFrontFace frontFace) {
+void gfxstream_vk_CmdSetFrontFaceEXT(VkCommandBuffer commandBuffer, VkFrontFace frontFace) {
     AEMU_SCOPED_TRACE("vkCmdSetFrontFaceEXT");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdSetFrontFaceEXT(commandBuffer, frontFace, true /* do lock */);
-}
-static void dynCheck_entry_vkCmdSetFrontFaceEXT(VkCommandBuffer commandBuffer,
-                                                VkFrontFace frontFace) {
-    auto resources = ResourceTracker::get();
-    VkDevice device = resources->getDevice(commandBuffer);
-    ;
-    if (!resources->hasDeviceExtension(device, "VK_EXT_extended_dynamic_state")) {
-        sOnInvalidDynamicallyCheckedCall("vkCmdSetFrontFaceEXT", "VK_EXT_extended_dynamic_state");
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        vkEnc->vkCmdSetFrontFaceEXT(gfxstream_commandBuffer->internal_object, frontFace,
+                                    true /* do lock */);
     }
-    AEMU_SCOPED_TRACE("vkCmdSetFrontFaceEXT");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdSetFrontFaceEXT(commandBuffer, frontFace, true /* do lock */);
 }
-static void entry_vkCmdSetPrimitiveTopologyEXT(VkCommandBuffer commandBuffer,
-                                               VkPrimitiveTopology primitiveTopology) {
+void gfxstream_vk_CmdSetPrimitiveTopologyEXT(VkCommandBuffer commandBuffer,
+                                             VkPrimitiveTopology primitiveTopology) {
     AEMU_SCOPED_TRACE("vkCmdSetPrimitiveTopologyEXT");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdSetPrimitiveTopologyEXT(commandBuffer, primitiveTopology, true /* do lock */);
-}
-static void dynCheck_entry_vkCmdSetPrimitiveTopologyEXT(VkCommandBuffer commandBuffer,
-                                                        VkPrimitiveTopology primitiveTopology) {
-    auto resources = ResourceTracker::get();
-    VkDevice device = resources->getDevice(commandBuffer);
-    ;
-    if (!resources->hasDeviceExtension(device, "VK_EXT_extended_dynamic_state")) {
-        sOnInvalidDynamicallyCheckedCall("vkCmdSetPrimitiveTopologyEXT",
-                                         "VK_EXT_extended_dynamic_state");
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        vkEnc->vkCmdSetPrimitiveTopologyEXT(gfxstream_commandBuffer->internal_object,
+                                            primitiveTopology, true /* do lock */);
     }
-    AEMU_SCOPED_TRACE("vkCmdSetPrimitiveTopologyEXT");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdSetPrimitiveTopologyEXT(commandBuffer, primitiveTopology, true /* do lock */);
 }
-static void entry_vkCmdSetViewportWithCountEXT(VkCommandBuffer commandBuffer,
-                                               uint32_t viewportCount,
-                                               const VkViewport* pViewports) {
+void gfxstream_vk_CmdSetViewportWithCountEXT(VkCommandBuffer commandBuffer, uint32_t viewportCount,
+                                             const VkViewport* pViewports) {
     AEMU_SCOPED_TRACE("vkCmdSetViewportWithCountEXT");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdSetViewportWithCountEXT(commandBuffer, viewportCount, pViewports,
-                                        true /* do lock */);
-}
-static void dynCheck_entry_vkCmdSetViewportWithCountEXT(VkCommandBuffer commandBuffer,
-                                                        uint32_t viewportCount,
-                                                        const VkViewport* pViewports) {
-    auto resources = ResourceTracker::get();
-    VkDevice device = resources->getDevice(commandBuffer);
-    ;
-    if (!resources->hasDeviceExtension(device, "VK_EXT_extended_dynamic_state")) {
-        sOnInvalidDynamicallyCheckedCall("vkCmdSetViewportWithCountEXT",
-                                         "VK_EXT_extended_dynamic_state");
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        vkEnc->vkCmdSetViewportWithCountEXT(gfxstream_commandBuffer->internal_object, viewportCount,
+                                            pViewports, true /* do lock */);
     }
-    AEMU_SCOPED_TRACE("vkCmdSetViewportWithCountEXT");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdSetViewportWithCountEXT(commandBuffer, viewportCount, pViewports,
-                                        true /* do lock */);
 }
-static void entry_vkCmdSetScissorWithCountEXT(VkCommandBuffer commandBuffer, uint32_t scissorCount,
-                                              const VkRect2D* pScissors) {
+void gfxstream_vk_CmdSetScissorWithCountEXT(VkCommandBuffer commandBuffer, uint32_t scissorCount,
+                                            const VkRect2D* pScissors) {
     AEMU_SCOPED_TRACE("vkCmdSetScissorWithCountEXT");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdSetScissorWithCountEXT(commandBuffer, scissorCount, pScissors, true /* do lock */);
-}
-static void dynCheck_entry_vkCmdSetScissorWithCountEXT(VkCommandBuffer commandBuffer,
-                                                       uint32_t scissorCount,
-                                                       const VkRect2D* pScissors) {
-    auto resources = ResourceTracker::get();
-    VkDevice device = resources->getDevice(commandBuffer);
-    ;
-    if (!resources->hasDeviceExtension(device, "VK_EXT_extended_dynamic_state")) {
-        sOnInvalidDynamicallyCheckedCall("vkCmdSetScissorWithCountEXT",
-                                         "VK_EXT_extended_dynamic_state");
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        vkEnc->vkCmdSetScissorWithCountEXT(gfxstream_commandBuffer->internal_object, scissorCount,
+                                           pScissors, true /* do lock */);
     }
-    AEMU_SCOPED_TRACE("vkCmdSetScissorWithCountEXT");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdSetScissorWithCountEXT(commandBuffer, scissorCount, pScissors, true /* do lock */);
 }
-static void entry_vkCmdBindVertexBuffers2EXT(VkCommandBuffer commandBuffer, uint32_t firstBinding,
-                                             uint32_t bindingCount, const VkBuffer* pBuffers,
-                                             const VkDeviceSize* pOffsets,
-                                             const VkDeviceSize* pSizes,
-                                             const VkDeviceSize* pStrides) {
+void gfxstream_vk_CmdBindVertexBuffers2EXT(VkCommandBuffer commandBuffer, uint32_t firstBinding,
+                                           uint32_t bindingCount, const VkBuffer* pBuffers,
+                                           const VkDeviceSize* pOffsets, const VkDeviceSize* pSizes,
+                                           const VkDeviceSize* pStrides) {
     AEMU_SCOPED_TRACE("vkCmdBindVertexBuffers2EXT");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdBindVertexBuffers2EXT(commandBuffer, firstBinding, bindingCount, pBuffers, pOffsets,
-                                      pSizes, pStrides, true /* do lock */);
-}
-static void dynCheck_entry_vkCmdBindVertexBuffers2EXT(VkCommandBuffer commandBuffer,
-                                                      uint32_t firstBinding, uint32_t bindingCount,
-                                                      const VkBuffer* pBuffers,
-                                                      const VkDeviceSize* pOffsets,
-                                                      const VkDeviceSize* pSizes,
-                                                      const VkDeviceSize* pStrides) {
-    auto resources = ResourceTracker::get();
-    VkDevice device = resources->getDevice(commandBuffer);
-    ;
-    if (!resources->hasDeviceExtension(device, "VK_EXT_extended_dynamic_state")) {
-        sOnInvalidDynamicallyCheckedCall("vkCmdBindVertexBuffers2EXT",
-                                         "VK_EXT_extended_dynamic_state");
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        std::vector<VkBuffer> internal_pBuffers(bindingCount);
+        for (uint32_t i = 0; i < bindingCount; ++i) {
+            if (pBuffers) {
+                VK_FROM_HANDLE(gfxstream_vk_buffer, gfxstream_pBuffers, pBuffers[i]);
+                internal_pBuffers[i] = gfxstream_pBuffers->internal_object;
+            }
+        }
+        vkEnc->vkCmdBindVertexBuffers2EXT(gfxstream_commandBuffer->internal_object, firstBinding,
+                                          bindingCount, internal_pBuffers.data(), pOffsets, pSizes,
+                                          pStrides, true /* do lock */);
     }
-    AEMU_SCOPED_TRACE("vkCmdBindVertexBuffers2EXT");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdBindVertexBuffers2EXT(commandBuffer, firstBinding, bindingCount, pBuffers, pOffsets,
-                                      pSizes, pStrides, true /* do lock */);
 }
-static void entry_vkCmdSetDepthTestEnableEXT(VkCommandBuffer commandBuffer,
-                                             VkBool32 depthTestEnable) {
+void gfxstream_vk_CmdSetDepthTestEnableEXT(VkCommandBuffer commandBuffer,
+                                           VkBool32 depthTestEnable) {
     AEMU_SCOPED_TRACE("vkCmdSetDepthTestEnableEXT");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdSetDepthTestEnableEXT(commandBuffer, depthTestEnable, true /* do lock */);
-}
-static void dynCheck_entry_vkCmdSetDepthTestEnableEXT(VkCommandBuffer commandBuffer,
-                                                      VkBool32 depthTestEnable) {
-    auto resources = ResourceTracker::get();
-    VkDevice device = resources->getDevice(commandBuffer);
-    ;
-    if (!resources->hasDeviceExtension(device, "VK_EXT_extended_dynamic_state")) {
-        sOnInvalidDynamicallyCheckedCall("vkCmdSetDepthTestEnableEXT",
-                                         "VK_EXT_extended_dynamic_state");
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        vkEnc->vkCmdSetDepthTestEnableEXT(gfxstream_commandBuffer->internal_object, depthTestEnable,
+                                          true /* do lock */);
     }
-    AEMU_SCOPED_TRACE("vkCmdSetDepthTestEnableEXT");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdSetDepthTestEnableEXT(commandBuffer, depthTestEnable, true /* do lock */);
 }
-static void entry_vkCmdSetDepthWriteEnableEXT(VkCommandBuffer commandBuffer,
-                                              VkBool32 depthWriteEnable) {
+void gfxstream_vk_CmdSetDepthWriteEnableEXT(VkCommandBuffer commandBuffer,
+                                            VkBool32 depthWriteEnable) {
     AEMU_SCOPED_TRACE("vkCmdSetDepthWriteEnableEXT");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdSetDepthWriteEnableEXT(commandBuffer, depthWriteEnable, true /* do lock */);
-}
-static void dynCheck_entry_vkCmdSetDepthWriteEnableEXT(VkCommandBuffer commandBuffer,
-                                                       VkBool32 depthWriteEnable) {
-    auto resources = ResourceTracker::get();
-    VkDevice device = resources->getDevice(commandBuffer);
-    ;
-    if (!resources->hasDeviceExtension(device, "VK_EXT_extended_dynamic_state")) {
-        sOnInvalidDynamicallyCheckedCall("vkCmdSetDepthWriteEnableEXT",
-                                         "VK_EXT_extended_dynamic_state");
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        vkEnc->vkCmdSetDepthWriteEnableEXT(gfxstream_commandBuffer->internal_object,
+                                           depthWriteEnable, true /* do lock */);
     }
-    AEMU_SCOPED_TRACE("vkCmdSetDepthWriteEnableEXT");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdSetDepthWriteEnableEXT(commandBuffer, depthWriteEnable, true /* do lock */);
 }
-static void entry_vkCmdSetDepthCompareOpEXT(VkCommandBuffer commandBuffer,
-                                            VkCompareOp depthCompareOp) {
+void gfxstream_vk_CmdSetDepthCompareOpEXT(VkCommandBuffer commandBuffer,
+                                          VkCompareOp depthCompareOp) {
     AEMU_SCOPED_TRACE("vkCmdSetDepthCompareOpEXT");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdSetDepthCompareOpEXT(commandBuffer, depthCompareOp, true /* do lock */);
-}
-static void dynCheck_entry_vkCmdSetDepthCompareOpEXT(VkCommandBuffer commandBuffer,
-                                                     VkCompareOp depthCompareOp) {
-    auto resources = ResourceTracker::get();
-    VkDevice device = resources->getDevice(commandBuffer);
-    ;
-    if (!resources->hasDeviceExtension(device, "VK_EXT_extended_dynamic_state")) {
-        sOnInvalidDynamicallyCheckedCall("vkCmdSetDepthCompareOpEXT",
-                                         "VK_EXT_extended_dynamic_state");
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        vkEnc->vkCmdSetDepthCompareOpEXT(gfxstream_commandBuffer->internal_object, depthCompareOp,
+                                         true /* do lock */);
     }
-    AEMU_SCOPED_TRACE("vkCmdSetDepthCompareOpEXT");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdSetDepthCompareOpEXT(commandBuffer, depthCompareOp, true /* do lock */);
 }
-static void entry_vkCmdSetDepthBoundsTestEnableEXT(VkCommandBuffer commandBuffer,
-                                                   VkBool32 depthBoundsTestEnable) {
+void gfxstream_vk_CmdSetDepthBoundsTestEnableEXT(VkCommandBuffer commandBuffer,
+                                                 VkBool32 depthBoundsTestEnable) {
     AEMU_SCOPED_TRACE("vkCmdSetDepthBoundsTestEnableEXT");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdSetDepthBoundsTestEnableEXT(commandBuffer, depthBoundsTestEnable,
-                                            true /* do lock */);
-}
-static void dynCheck_entry_vkCmdSetDepthBoundsTestEnableEXT(VkCommandBuffer commandBuffer,
-                                                            VkBool32 depthBoundsTestEnable) {
-    auto resources = ResourceTracker::get();
-    VkDevice device = resources->getDevice(commandBuffer);
-    ;
-    if (!resources->hasDeviceExtension(device, "VK_EXT_extended_dynamic_state")) {
-        sOnInvalidDynamicallyCheckedCall("vkCmdSetDepthBoundsTestEnableEXT",
-                                         "VK_EXT_extended_dynamic_state");
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        vkEnc->vkCmdSetDepthBoundsTestEnableEXT(gfxstream_commandBuffer->internal_object,
+                                                depthBoundsTestEnable, true /* do lock */);
     }
-    AEMU_SCOPED_TRACE("vkCmdSetDepthBoundsTestEnableEXT");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdSetDepthBoundsTestEnableEXT(commandBuffer, depthBoundsTestEnable,
-                                            true /* do lock */);
 }
-static void entry_vkCmdSetStencilTestEnableEXT(VkCommandBuffer commandBuffer,
-                                               VkBool32 stencilTestEnable) {
+void gfxstream_vk_CmdSetStencilTestEnableEXT(VkCommandBuffer commandBuffer,
+                                             VkBool32 stencilTestEnable) {
     AEMU_SCOPED_TRACE("vkCmdSetStencilTestEnableEXT");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdSetStencilTestEnableEXT(commandBuffer, stencilTestEnable, true /* do lock */);
-}
-static void dynCheck_entry_vkCmdSetStencilTestEnableEXT(VkCommandBuffer commandBuffer,
-                                                        VkBool32 stencilTestEnable) {
-    auto resources = ResourceTracker::get();
-    VkDevice device = resources->getDevice(commandBuffer);
-    ;
-    if (!resources->hasDeviceExtension(device, "VK_EXT_extended_dynamic_state")) {
-        sOnInvalidDynamicallyCheckedCall("vkCmdSetStencilTestEnableEXT",
-                                         "VK_EXT_extended_dynamic_state");
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        vkEnc->vkCmdSetStencilTestEnableEXT(gfxstream_commandBuffer->internal_object,
+                                            stencilTestEnable, true /* do lock */);
     }
-    AEMU_SCOPED_TRACE("vkCmdSetStencilTestEnableEXT");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdSetStencilTestEnableEXT(commandBuffer, stencilTestEnable, true /* do lock */);
 }
-static void entry_vkCmdSetStencilOpEXT(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask,
-                                       VkStencilOp failOp, VkStencilOp passOp,
-                                       VkStencilOp depthFailOp, VkCompareOp compareOp) {
+void gfxstream_vk_CmdSetStencilOpEXT(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask,
+                                     VkStencilOp failOp, VkStencilOp passOp,
+                                     VkStencilOp depthFailOp, VkCompareOp compareOp) {
     AEMU_SCOPED_TRACE("vkCmdSetStencilOpEXT");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdSetStencilOpEXT(commandBuffer, faceMask, failOp, passOp, depthFailOp, compareOp,
-                                true /* do lock */);
-}
-static void dynCheck_entry_vkCmdSetStencilOpEXT(VkCommandBuffer commandBuffer,
-                                                VkStencilFaceFlags faceMask, VkStencilOp failOp,
-                                                VkStencilOp passOp, VkStencilOp depthFailOp,
-                                                VkCompareOp compareOp) {
-    auto resources = ResourceTracker::get();
-    VkDevice device = resources->getDevice(commandBuffer);
-    ;
-    if (!resources->hasDeviceExtension(device, "VK_EXT_extended_dynamic_state")) {
-        sOnInvalidDynamicallyCheckedCall("vkCmdSetStencilOpEXT", "VK_EXT_extended_dynamic_state");
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        vkEnc->vkCmdSetStencilOpEXT(gfxstream_commandBuffer->internal_object, faceMask, failOp,
+                                    passOp, depthFailOp, compareOp, true /* do lock */);
     }
-    AEMU_SCOPED_TRACE("vkCmdSetStencilOpEXT");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdSetStencilOpEXT(commandBuffer, faceMask, failOp, passOp, depthFailOp, compareOp,
-                                true /* do lock */);
 }
 #endif
 #ifdef VK_EXT_host_image_copy
-static VkResult entry_vkCopyMemoryToImageEXT(
+VkResult gfxstream_vk_CopyMemoryToImageEXT(
     VkDevice device, const VkCopyMemoryToImageInfoEXT* pCopyMemoryToImageInfo) {
     AEMU_SCOPED_TRACE("vkCopyMemoryToImageEXT");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
     VkResult vkCopyMemoryToImageEXT_VkResult_return = (VkResult)0;
-    vkCopyMemoryToImageEXT_VkResult_return =
-        vkEnc->vkCopyMemoryToImageEXT(device, pCopyMemoryToImageInfo, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        std::vector<VkCopyMemoryToImageInfoEXT> internal_pCopyMemoryToImageInfo(1);
+        for (uint32_t i = 0; i < 1; ++i) {
+            internal_pCopyMemoryToImageInfo[i] = pCopyMemoryToImageInfo[i];
+            /* VkCopyMemoryToImageInfoEXT::dstImage */
+            VK_FROM_HANDLE(gfxstream_vk_image, gfxstream_dstImage,
+                           internal_pCopyMemoryToImageInfo[i].dstImage);
+            internal_pCopyMemoryToImageInfo[i].dstImage = gfxstream_dstImage->internal_object;
+        }
+        vkCopyMemoryToImageEXT_VkResult_return = vkEnc->vkCopyMemoryToImageEXT(
+            gfxstream_device->internal_object, internal_pCopyMemoryToImageInfo.data(),
+            true /* do lock */);
+    }
     return vkCopyMemoryToImageEXT_VkResult_return;
 }
-static VkResult dynCheck_entry_vkCopyMemoryToImageEXT(
-    VkDevice device, const VkCopyMemoryToImageInfoEXT* pCopyMemoryToImageInfo) {
-    auto resources = ResourceTracker::get();
-    if (!resources->hasDeviceExtension(device, "VK_EXT_host_image_copy")) {
-        sOnInvalidDynamicallyCheckedCall("vkCopyMemoryToImageEXT", "VK_EXT_host_image_copy");
-    }
-    AEMU_SCOPED_TRACE("vkCopyMemoryToImageEXT");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    VkResult vkCopyMemoryToImageEXT_VkResult_return = (VkResult)0;
-    vkCopyMemoryToImageEXT_VkResult_return =
-        vkEnc->vkCopyMemoryToImageEXT(device, pCopyMemoryToImageInfo, true /* do lock */);
-    return vkCopyMemoryToImageEXT_VkResult_return;
-}
-static VkResult entry_vkCopyImageToMemoryEXT(
+VkResult gfxstream_vk_CopyImageToMemoryEXT(
     VkDevice device, const VkCopyImageToMemoryInfoEXT* pCopyImageToMemoryInfo) {
     AEMU_SCOPED_TRACE("vkCopyImageToMemoryEXT");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
     VkResult vkCopyImageToMemoryEXT_VkResult_return = (VkResult)0;
-    vkCopyImageToMemoryEXT_VkResult_return =
-        vkEnc->vkCopyImageToMemoryEXT(device, pCopyImageToMemoryInfo, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        std::vector<VkCopyImageToMemoryInfoEXT> internal_pCopyImageToMemoryInfo(1);
+        for (uint32_t i = 0; i < 1; ++i) {
+            internal_pCopyImageToMemoryInfo[i] = pCopyImageToMemoryInfo[i];
+            /* VkCopyImageToMemoryInfoEXT::srcImage */
+            VK_FROM_HANDLE(gfxstream_vk_image, gfxstream_srcImage,
+                           internal_pCopyImageToMemoryInfo[i].srcImage);
+            internal_pCopyImageToMemoryInfo[i].srcImage = gfxstream_srcImage->internal_object;
+        }
+        vkCopyImageToMemoryEXT_VkResult_return = vkEnc->vkCopyImageToMemoryEXT(
+            gfxstream_device->internal_object, internal_pCopyImageToMemoryInfo.data(),
+            true /* do lock */);
+    }
     return vkCopyImageToMemoryEXT_VkResult_return;
 }
-static VkResult dynCheck_entry_vkCopyImageToMemoryEXT(
-    VkDevice device, const VkCopyImageToMemoryInfoEXT* pCopyImageToMemoryInfo) {
-    auto resources = ResourceTracker::get();
-    if (!resources->hasDeviceExtension(device, "VK_EXT_host_image_copy")) {
-        sOnInvalidDynamicallyCheckedCall("vkCopyImageToMemoryEXT", "VK_EXT_host_image_copy");
-    }
-    AEMU_SCOPED_TRACE("vkCopyImageToMemoryEXT");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    VkResult vkCopyImageToMemoryEXT_VkResult_return = (VkResult)0;
-    vkCopyImageToMemoryEXT_VkResult_return =
-        vkEnc->vkCopyImageToMemoryEXT(device, pCopyImageToMemoryInfo, true /* do lock */);
-    return vkCopyImageToMemoryEXT_VkResult_return;
-}
-static VkResult entry_vkCopyImageToImageEXT(
-    VkDevice device, const VkCopyImageToImageInfoEXT* pCopyImageToImageInfo) {
+VkResult gfxstream_vk_CopyImageToImageEXT(VkDevice device,
+                                          const VkCopyImageToImageInfoEXT* pCopyImageToImageInfo) {
     AEMU_SCOPED_TRACE("vkCopyImageToImageEXT");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
     VkResult vkCopyImageToImageEXT_VkResult_return = (VkResult)0;
-    vkCopyImageToImageEXT_VkResult_return =
-        vkEnc->vkCopyImageToImageEXT(device, pCopyImageToImageInfo, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        std::vector<VkCopyImageToImageInfoEXT> internal_pCopyImageToImageInfo(1);
+        for (uint32_t i = 0; i < 1; ++i) {
+            internal_pCopyImageToImageInfo[i] = pCopyImageToImageInfo[i];
+            /* VkCopyImageToImageInfoEXT::srcImage */
+            VK_FROM_HANDLE(gfxstream_vk_image, gfxstream_srcImage,
+                           internal_pCopyImageToImageInfo[i].srcImage);
+            internal_pCopyImageToImageInfo[i].srcImage = gfxstream_srcImage->internal_object;
+            /* VkCopyImageToImageInfoEXT::dstImage */
+            VK_FROM_HANDLE(gfxstream_vk_image, gfxstream_dstImage,
+                           internal_pCopyImageToImageInfo[i].dstImage);
+            internal_pCopyImageToImageInfo[i].dstImage = gfxstream_dstImage->internal_object;
+        }
+        vkCopyImageToImageEXT_VkResult_return =
+            vkEnc->vkCopyImageToImageEXT(gfxstream_device->internal_object,
+                                         internal_pCopyImageToImageInfo.data(), true /* do lock */);
+    }
     return vkCopyImageToImageEXT_VkResult_return;
 }
-static VkResult dynCheck_entry_vkCopyImageToImageEXT(
-    VkDevice device, const VkCopyImageToImageInfoEXT* pCopyImageToImageInfo) {
-    auto resources = ResourceTracker::get();
-    if (!resources->hasDeviceExtension(device, "VK_EXT_host_image_copy")) {
-        sOnInvalidDynamicallyCheckedCall("vkCopyImageToImageEXT", "VK_EXT_host_image_copy");
-    }
-    AEMU_SCOPED_TRACE("vkCopyImageToImageEXT");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    VkResult vkCopyImageToImageEXT_VkResult_return = (VkResult)0;
-    vkCopyImageToImageEXT_VkResult_return =
-        vkEnc->vkCopyImageToImageEXT(device, pCopyImageToImageInfo, true /* do lock */);
-    return vkCopyImageToImageEXT_VkResult_return;
-}
-static VkResult entry_vkTransitionImageLayoutEXT(
+VkResult gfxstream_vk_TransitionImageLayoutEXT(
     VkDevice device, uint32_t transitionCount,
     const VkHostImageLayoutTransitionInfoEXT* pTransitions) {
     AEMU_SCOPED_TRACE("vkTransitionImageLayoutEXT");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
     VkResult vkTransitionImageLayoutEXT_VkResult_return = (VkResult)0;
-    vkTransitionImageLayoutEXT_VkResult_return = vkEnc->vkTransitionImageLayoutEXT(
-        device, transitionCount, pTransitions, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        std::vector<VkHostImageLayoutTransitionInfoEXT> internal_pTransitions(transitionCount);
+        for (uint32_t i = 0; i < transitionCount; ++i) {
+            internal_pTransitions[i] = pTransitions[i];
+            /* VkHostImageLayoutTransitionInfoEXT::image */
+            VK_FROM_HANDLE(gfxstream_vk_image, gfxstream_image, internal_pTransitions[i].image);
+            internal_pTransitions[i].image = gfxstream_image->internal_object;
+        }
+        vkTransitionImageLayoutEXT_VkResult_return =
+            vkEnc->vkTransitionImageLayoutEXT(gfxstream_device->internal_object, transitionCount,
+                                              internal_pTransitions.data(), true /* do lock */);
+    }
     return vkTransitionImageLayoutEXT_VkResult_return;
 }
-static VkResult dynCheck_entry_vkTransitionImageLayoutEXT(
-    VkDevice device, uint32_t transitionCount,
-    const VkHostImageLayoutTransitionInfoEXT* pTransitions) {
-    auto resources = ResourceTracker::get();
-    if (!resources->hasDeviceExtension(device, "VK_EXT_host_image_copy")) {
-        sOnInvalidDynamicallyCheckedCall("vkTransitionImageLayoutEXT", "VK_EXT_host_image_copy");
-    }
-    AEMU_SCOPED_TRACE("vkTransitionImageLayoutEXT");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    VkResult vkTransitionImageLayoutEXT_VkResult_return = (VkResult)0;
-    vkTransitionImageLayoutEXT_VkResult_return = vkEnc->vkTransitionImageLayoutEXT(
-        device, transitionCount, pTransitions, true /* do lock */);
-    return vkTransitionImageLayoutEXT_VkResult_return;
-}
-static void entry_vkGetImageSubresourceLayout2EXT(VkDevice device, VkImage image,
-                                                  const VkImageSubresource2KHR* pSubresource,
-                                                  VkSubresourceLayout2KHR* pLayout) {
+void gfxstream_vk_GetImageSubresourceLayout2EXT(VkDevice device, VkImage image,
+                                                const VkImageSubresource2KHR* pSubresource,
+                                                VkSubresourceLayout2KHR* pLayout) {
     AEMU_SCOPED_TRACE("vkGetImageSubresourceLayout2EXT");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkGetImageSubresourceLayout2EXT(device, image, pSubresource, pLayout,
-                                           true /* do lock */);
-}
-static void dynCheck_entry_vkGetImageSubresourceLayout2EXT(
-    VkDevice device, VkImage image, const VkImageSubresource2KHR* pSubresource,
-    VkSubresourceLayout2KHR* pLayout) {
-    auto resources = ResourceTracker::get();
-    if (!resources->hasDeviceExtension(device, "VK_EXT_host_image_copy")) {
-        sOnInvalidDynamicallyCheckedCall("vkGetImageSubresourceLayout2EXT",
-                                         "VK_EXT_host_image_copy");
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    VK_FROM_HANDLE(gfxstream_vk_image, gfxstream_image, image);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkEnc->vkGetImageSubresourceLayout2EXT(gfxstream_device->internal_object,
+                                               gfxstream_image->internal_object, pSubresource,
+                                               pLayout, true /* do lock */);
     }
-    AEMU_SCOPED_TRACE("vkGetImageSubresourceLayout2EXT");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkGetImageSubresourceLayout2EXT(device, image, pSubresource, pLayout,
-                                           true /* do lock */);
 }
 #endif
 #ifdef VK_EXT_swapchain_maintenance1
@@ -4106,92 +5598,54 @@
 #ifdef VK_EXT_custom_border_color
 #endif
 #ifdef VK_EXT_private_data
-static VkResult entry_vkCreatePrivateDataSlotEXT(VkDevice device,
-                                                 const VkPrivateDataSlotCreateInfo* pCreateInfo,
-                                                 const VkAllocationCallbacks* pAllocator,
-                                                 VkPrivateDataSlot* pPrivateDataSlot) {
+VkResult gfxstream_vk_CreatePrivateDataSlotEXT(VkDevice device,
+                                               const VkPrivateDataSlotCreateInfo* pCreateInfo,
+                                               const VkAllocationCallbacks* pAllocator,
+                                               VkPrivateDataSlot* pPrivateDataSlot) {
     AEMU_SCOPED_TRACE("vkCreatePrivateDataSlotEXT");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
     VkResult vkCreatePrivateDataSlotEXT_VkResult_return = (VkResult)0;
-    vkCreatePrivateDataSlotEXT_VkResult_return = vkEnc->vkCreatePrivateDataSlotEXT(
-        device, pCreateInfo, pAllocator, pPrivateDataSlot, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkCreatePrivateDataSlotEXT_VkResult_return =
+            vkEnc->vkCreatePrivateDataSlotEXT(gfxstream_device->internal_object, pCreateInfo,
+                                              pAllocator, pPrivateDataSlot, true /* do lock */);
+    }
     return vkCreatePrivateDataSlotEXT_VkResult_return;
 }
-static VkResult dynCheck_entry_vkCreatePrivateDataSlotEXT(
-    VkDevice device, const VkPrivateDataSlotCreateInfo* pCreateInfo,
-    const VkAllocationCallbacks* pAllocator, VkPrivateDataSlot* pPrivateDataSlot) {
-    auto resources = ResourceTracker::get();
-    if (!resources->hasDeviceExtension(device, "VK_EXT_private_data")) {
-        sOnInvalidDynamicallyCheckedCall("vkCreatePrivateDataSlotEXT", "VK_EXT_private_data");
-    }
-    AEMU_SCOPED_TRACE("vkCreatePrivateDataSlotEXT");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    VkResult vkCreatePrivateDataSlotEXT_VkResult_return = (VkResult)0;
-    vkCreatePrivateDataSlotEXT_VkResult_return = vkEnc->vkCreatePrivateDataSlotEXT(
-        device, pCreateInfo, pAllocator, pPrivateDataSlot, true /* do lock */);
-    return vkCreatePrivateDataSlotEXT_VkResult_return;
-}
-static void entry_vkDestroyPrivateDataSlotEXT(VkDevice device, VkPrivateDataSlot privateDataSlot,
-                                              const VkAllocationCallbacks* pAllocator) {
+void gfxstream_vk_DestroyPrivateDataSlotEXT(VkDevice device, VkPrivateDataSlot privateDataSlot,
+                                            const VkAllocationCallbacks* pAllocator) {
     AEMU_SCOPED_TRACE("vkDestroyPrivateDataSlotEXT");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkDestroyPrivateDataSlotEXT(device, privateDataSlot, pAllocator, true /* do lock */);
-}
-static void dynCheck_entry_vkDestroyPrivateDataSlotEXT(VkDevice device,
-                                                       VkPrivateDataSlot privateDataSlot,
-                                                       const VkAllocationCallbacks* pAllocator) {
-    auto resources = ResourceTracker::get();
-    if (!resources->hasDeviceExtension(device, "VK_EXT_private_data")) {
-        sOnInvalidDynamicallyCheckedCall("vkDestroyPrivateDataSlotEXT", "VK_EXT_private_data");
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkEnc->vkDestroyPrivateDataSlotEXT(gfxstream_device->internal_object, privateDataSlot,
+                                           pAllocator, true /* do lock */);
     }
-    AEMU_SCOPED_TRACE("vkDestroyPrivateDataSlotEXT");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkDestroyPrivateDataSlotEXT(device, privateDataSlot, pAllocator, true /* do lock */);
 }
-static VkResult entry_vkSetPrivateDataEXT(VkDevice device, VkObjectType objectType,
-                                          uint64_t objectHandle, VkPrivateDataSlot privateDataSlot,
-                                          uint64_t data) {
+VkResult gfxstream_vk_SetPrivateDataEXT(VkDevice device, VkObjectType objectType,
+                                        uint64_t objectHandle, VkPrivateDataSlot privateDataSlot,
+                                        uint64_t data) {
     AEMU_SCOPED_TRACE("vkSetPrivateDataEXT");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
     VkResult vkSetPrivateDataEXT_VkResult_return = (VkResult)0;
-    vkSetPrivateDataEXT_VkResult_return = vkEnc->vkSetPrivateDataEXT(
-        device, objectType, objectHandle, privateDataSlot, data, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkSetPrivateDataEXT_VkResult_return =
+            vkEnc->vkSetPrivateDataEXT(gfxstream_device->internal_object, objectType, objectHandle,
+                                       privateDataSlot, data, true /* do lock */);
+    }
     return vkSetPrivateDataEXT_VkResult_return;
 }
-static VkResult dynCheck_entry_vkSetPrivateDataEXT(VkDevice device, VkObjectType objectType,
-                                                   uint64_t objectHandle,
-                                                   VkPrivateDataSlot privateDataSlot,
-                                                   uint64_t data) {
-    auto resources = ResourceTracker::get();
-    if (!resources->hasDeviceExtension(device, "VK_EXT_private_data")) {
-        sOnInvalidDynamicallyCheckedCall("vkSetPrivateDataEXT", "VK_EXT_private_data");
-    }
-    AEMU_SCOPED_TRACE("vkSetPrivateDataEXT");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    VkResult vkSetPrivateDataEXT_VkResult_return = (VkResult)0;
-    vkSetPrivateDataEXT_VkResult_return = vkEnc->vkSetPrivateDataEXT(
-        device, objectType, objectHandle, privateDataSlot, data, true /* do lock */);
-    return vkSetPrivateDataEXT_VkResult_return;
-}
-static void entry_vkGetPrivateDataEXT(VkDevice device, VkObjectType objectType,
-                                      uint64_t objectHandle, VkPrivateDataSlot privateDataSlot,
-                                      uint64_t* pData) {
+void gfxstream_vk_GetPrivateDataEXT(VkDevice device, VkObjectType objectType, uint64_t objectHandle,
+                                    VkPrivateDataSlot privateDataSlot, uint64_t* pData) {
     AEMU_SCOPED_TRACE("vkGetPrivateDataEXT");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkGetPrivateDataEXT(device, objectType, objectHandle, privateDataSlot, pData,
-                               true /* do lock */);
-}
-static void dynCheck_entry_vkGetPrivateDataEXT(VkDevice device, VkObjectType objectType,
-                                               uint64_t objectHandle,
-                                               VkPrivateDataSlot privateDataSlot, uint64_t* pData) {
-    auto resources = ResourceTracker::get();
-    if (!resources->hasDeviceExtension(device, "VK_EXT_private_data")) {
-        sOnInvalidDynamicallyCheckedCall("vkGetPrivateDataEXT", "VK_EXT_private_data");
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkEnc->vkGetPrivateDataEXT(gfxstream_device->internal_object, objectType, objectHandle,
+                                   privateDataSlot, pData, true /* do lock */);
     }
-    AEMU_SCOPED_TRACE("vkGetPrivateDataEXT");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkGetPrivateDataEXT(device, objectType, objectHandle, privateDataSlot, pData,
-                               true /* do lock */);
 }
 #endif
 #ifdef VK_EXT_pipeline_creation_cache_control
@@ -4209,129 +5663,78 @@
 #ifdef VK_EXT_primitive_topology_list_restart
 #endif
 #ifdef VK_EXT_extended_dynamic_state2
-static void entry_vkCmdSetPatchControlPointsEXT(VkCommandBuffer commandBuffer,
-                                                uint32_t patchControlPoints) {
+void gfxstream_vk_CmdSetPatchControlPointsEXT(VkCommandBuffer commandBuffer,
+                                              uint32_t patchControlPoints) {
     AEMU_SCOPED_TRACE("vkCmdSetPatchControlPointsEXT");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdSetPatchControlPointsEXT(commandBuffer, patchControlPoints, true /* do lock */);
-}
-static void dynCheck_entry_vkCmdSetPatchControlPointsEXT(VkCommandBuffer commandBuffer,
-                                                         uint32_t patchControlPoints) {
-    auto resources = ResourceTracker::get();
-    VkDevice device = resources->getDevice(commandBuffer);
-    ;
-    if (!resources->hasDeviceExtension(device, "VK_EXT_extended_dynamic_state2")) {
-        sOnInvalidDynamicallyCheckedCall("vkCmdSetPatchControlPointsEXT",
-                                         "VK_EXT_extended_dynamic_state2");
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        vkEnc->vkCmdSetPatchControlPointsEXT(gfxstream_commandBuffer->internal_object,
+                                             patchControlPoints, true /* do lock */);
     }
-    AEMU_SCOPED_TRACE("vkCmdSetPatchControlPointsEXT");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdSetPatchControlPointsEXT(commandBuffer, patchControlPoints, true /* do lock */);
 }
-static void entry_vkCmdSetRasterizerDiscardEnableEXT(VkCommandBuffer commandBuffer,
-                                                     VkBool32 rasterizerDiscardEnable) {
+void gfxstream_vk_CmdSetRasterizerDiscardEnableEXT(VkCommandBuffer commandBuffer,
+                                                   VkBool32 rasterizerDiscardEnable) {
     AEMU_SCOPED_TRACE("vkCmdSetRasterizerDiscardEnableEXT");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdSetRasterizerDiscardEnableEXT(commandBuffer, rasterizerDiscardEnable,
-                                              true /* do lock */);
-}
-static void dynCheck_entry_vkCmdSetRasterizerDiscardEnableEXT(VkCommandBuffer commandBuffer,
-                                                              VkBool32 rasterizerDiscardEnable) {
-    auto resources = ResourceTracker::get();
-    VkDevice device = resources->getDevice(commandBuffer);
-    ;
-    if (!resources->hasDeviceExtension(device, "VK_EXT_extended_dynamic_state2")) {
-        sOnInvalidDynamicallyCheckedCall("vkCmdSetRasterizerDiscardEnableEXT",
-                                         "VK_EXT_extended_dynamic_state2");
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        vkEnc->vkCmdSetRasterizerDiscardEnableEXT(gfxstream_commandBuffer->internal_object,
+                                                  rasterizerDiscardEnable, true /* do lock */);
     }
-    AEMU_SCOPED_TRACE("vkCmdSetRasterizerDiscardEnableEXT");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdSetRasterizerDiscardEnableEXT(commandBuffer, rasterizerDiscardEnable,
-                                              true /* do lock */);
 }
-static void entry_vkCmdSetDepthBiasEnableEXT(VkCommandBuffer commandBuffer,
-                                             VkBool32 depthBiasEnable) {
+void gfxstream_vk_CmdSetDepthBiasEnableEXT(VkCommandBuffer commandBuffer,
+                                           VkBool32 depthBiasEnable) {
     AEMU_SCOPED_TRACE("vkCmdSetDepthBiasEnableEXT");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdSetDepthBiasEnableEXT(commandBuffer, depthBiasEnable, true /* do lock */);
-}
-static void dynCheck_entry_vkCmdSetDepthBiasEnableEXT(VkCommandBuffer commandBuffer,
-                                                      VkBool32 depthBiasEnable) {
-    auto resources = ResourceTracker::get();
-    VkDevice device = resources->getDevice(commandBuffer);
-    ;
-    if (!resources->hasDeviceExtension(device, "VK_EXT_extended_dynamic_state2")) {
-        sOnInvalidDynamicallyCheckedCall("vkCmdSetDepthBiasEnableEXT",
-                                         "VK_EXT_extended_dynamic_state2");
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        vkEnc->vkCmdSetDepthBiasEnableEXT(gfxstream_commandBuffer->internal_object, depthBiasEnable,
+                                          true /* do lock */);
     }
-    AEMU_SCOPED_TRACE("vkCmdSetDepthBiasEnableEXT");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdSetDepthBiasEnableEXT(commandBuffer, depthBiasEnable, true /* do lock */);
 }
-static void entry_vkCmdSetLogicOpEXT(VkCommandBuffer commandBuffer, VkLogicOp logicOp) {
+void gfxstream_vk_CmdSetLogicOpEXT(VkCommandBuffer commandBuffer, VkLogicOp logicOp) {
     AEMU_SCOPED_TRACE("vkCmdSetLogicOpEXT");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdSetLogicOpEXT(commandBuffer, logicOp, true /* do lock */);
-}
-static void dynCheck_entry_vkCmdSetLogicOpEXT(VkCommandBuffer commandBuffer, VkLogicOp logicOp) {
-    auto resources = ResourceTracker::get();
-    VkDevice device = resources->getDevice(commandBuffer);
-    ;
-    if (!resources->hasDeviceExtension(device, "VK_EXT_extended_dynamic_state2")) {
-        sOnInvalidDynamicallyCheckedCall("vkCmdSetLogicOpEXT", "VK_EXT_extended_dynamic_state2");
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        vkEnc->vkCmdSetLogicOpEXT(gfxstream_commandBuffer->internal_object, logicOp,
+                                  true /* do lock */);
     }
-    AEMU_SCOPED_TRACE("vkCmdSetLogicOpEXT");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdSetLogicOpEXT(commandBuffer, logicOp, true /* do lock */);
 }
-static void entry_vkCmdSetPrimitiveRestartEnableEXT(VkCommandBuffer commandBuffer,
-                                                    VkBool32 primitiveRestartEnable) {
+void gfxstream_vk_CmdSetPrimitiveRestartEnableEXT(VkCommandBuffer commandBuffer,
+                                                  VkBool32 primitiveRestartEnable) {
     AEMU_SCOPED_TRACE("vkCmdSetPrimitiveRestartEnableEXT");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdSetPrimitiveRestartEnableEXT(commandBuffer, primitiveRestartEnable,
-                                             true /* do lock */);
-}
-static void dynCheck_entry_vkCmdSetPrimitiveRestartEnableEXT(VkCommandBuffer commandBuffer,
-                                                             VkBool32 primitiveRestartEnable) {
-    auto resources = ResourceTracker::get();
-    VkDevice device = resources->getDevice(commandBuffer);
-    ;
-    if (!resources->hasDeviceExtension(device, "VK_EXT_extended_dynamic_state2")) {
-        sOnInvalidDynamicallyCheckedCall("vkCmdSetPrimitiveRestartEnableEXT",
-                                         "VK_EXT_extended_dynamic_state2");
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        vkEnc->vkCmdSetPrimitiveRestartEnableEXT(gfxstream_commandBuffer->internal_object,
+                                                 primitiveRestartEnable, true /* do lock */);
     }
-    AEMU_SCOPED_TRACE("vkCmdSetPrimitiveRestartEnableEXT");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCmdSetPrimitiveRestartEnableEXT(commandBuffer, primitiveRestartEnable,
-                                             true /* do lock */);
 }
 #endif
 #ifdef VK_GOOGLE_gfxstream
-static VkResult entry_vkMapMemoryIntoAddressSpaceGOOGLE(VkDevice device, VkDeviceMemory memory,
-                                                        uint64_t* pAddress) {
+VkResult gfxstream_vk_MapMemoryIntoAddressSpaceGOOGLE(VkDevice device, VkDeviceMemory memory,
+                                                      uint64_t* pAddress) {
     AEMU_SCOPED_TRACE("vkMapMemoryIntoAddressSpaceGOOGLE");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
     VkResult vkMapMemoryIntoAddressSpaceGOOGLE_VkResult_return = (VkResult)0;
-    vkMapMemoryIntoAddressSpaceGOOGLE_VkResult_return =
-        vkEnc->vkMapMemoryIntoAddressSpaceGOOGLE(device, memory, pAddress, true /* do lock */);
-    return vkMapMemoryIntoAddressSpaceGOOGLE_VkResult_return;
-}
-static VkResult dynCheck_entry_vkMapMemoryIntoAddressSpaceGOOGLE(VkDevice device,
-                                                                 VkDeviceMemory memory,
-                                                                 uint64_t* pAddress) {
-    auto resources = ResourceTracker::get();
-    if (!resources->hasDeviceExtension(device, "VK_GOOGLE_gfxstream")) {
-        sOnInvalidDynamicallyCheckedCall("vkMapMemoryIntoAddressSpaceGOOGLE",
-                                         "VK_GOOGLE_gfxstream");
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    VK_FROM_HANDLE(gfxstream_vk_device_memory, gfxstream_memory, memory);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkMapMemoryIntoAddressSpaceGOOGLE_VkResult_return =
+            vkEnc->vkMapMemoryIntoAddressSpaceGOOGLE(gfxstream_device->internal_object,
+                                                     gfxstream_memory->internal_object, pAddress,
+                                                     true /* do lock */);
     }
-    AEMU_SCOPED_TRACE("vkMapMemoryIntoAddressSpaceGOOGLE");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    VkResult vkMapMemoryIntoAddressSpaceGOOGLE_VkResult_return = (VkResult)0;
-    vkMapMemoryIntoAddressSpaceGOOGLE_VkResult_return =
-        vkEnc->vkMapMemoryIntoAddressSpaceGOOGLE(device, memory, pAddress, true /* do lock */);
     return vkMapMemoryIntoAddressSpaceGOOGLE_VkResult_return;
 }
-static void entry_vkUpdateDescriptorSetWithTemplateSizedGOOGLE(
+void gfxstream_vk_UpdateDescriptorSetWithTemplateSizedGOOGLE(
     VkDevice device, VkDescriptorSet descriptorSet,
     VkDescriptorUpdateTemplate descriptorUpdateTemplate, uint32_t imageInfoCount,
     uint32_t bufferInfoCount, uint32_t bufferViewCount, const uint32_t* pImageInfoEntryIndices,
@@ -4339,228 +5742,468 @@
     const VkDescriptorImageInfo* pImageInfos, const VkDescriptorBufferInfo* pBufferInfos,
     const VkBufferView* pBufferViews) {
     AEMU_SCOPED_TRACE("vkUpdateDescriptorSetWithTemplateSizedGOOGLE");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkUpdateDescriptorSetWithTemplateSizedGOOGLE(
-        device, descriptorSet, descriptorUpdateTemplate, imageInfoCount, bufferInfoCount,
-        bufferViewCount, pImageInfoEntryIndices, pBufferInfoEntryIndices, pBufferViewEntryIndices,
-        pImageInfos, pBufferInfos, pBufferViews, true /* do lock */);
-}
-static void dynCheck_entry_vkUpdateDescriptorSetWithTemplateSizedGOOGLE(
-    VkDevice device, VkDescriptorSet descriptorSet,
-    VkDescriptorUpdateTemplate descriptorUpdateTemplate, uint32_t imageInfoCount,
-    uint32_t bufferInfoCount, uint32_t bufferViewCount, const uint32_t* pImageInfoEntryIndices,
-    const uint32_t* pBufferInfoEntryIndices, const uint32_t* pBufferViewEntryIndices,
-    const VkDescriptorImageInfo* pImageInfos, const VkDescriptorBufferInfo* pBufferInfos,
-    const VkBufferView* pBufferViews) {
-    auto resources = ResourceTracker::get();
-    if (!resources->hasDeviceExtension(device, "VK_GOOGLE_gfxstream")) {
-        sOnInvalidDynamicallyCheckedCall("vkUpdateDescriptorSetWithTemplateSizedGOOGLE",
-                                         "VK_GOOGLE_gfxstream");
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    VK_FROM_HANDLE(gfxstream_vk_descriptor_update_template, gfxstream_descriptorUpdateTemplate,
+                   descriptorUpdateTemplate);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        std::vector<VkDescriptorImageInfo> internal_pImageInfos(imageInfoCount);
+        for (uint32_t i = 0; i < imageInfoCount; ++i) {
+            if (pImageInfos) {
+                internal_pImageInfos[i] = pImageInfos[i];
+                /* VkDescriptorImageInfo::imageView */
+                if (internal_pImageInfos[i].imageView) {
+                    VK_FROM_HANDLE(gfxstream_vk_image_view, gfxstream_imageView,
+                                   internal_pImageInfos[i].imageView);
+                    internal_pImageInfos[i].imageView = gfxstream_imageView->internal_object;
+                }
+            }
+        }
+        std::vector<VkDescriptorBufferInfo> internal_pBufferInfos(bufferInfoCount);
+        for (uint32_t i = 0; i < bufferInfoCount; ++i) {
+            if (pBufferInfos) {
+                internal_pBufferInfos[i] = pBufferInfos[i];
+                /* VkDescriptorBufferInfo::buffer */
+                if (internal_pBufferInfos[i].buffer) {
+                    VK_FROM_HANDLE(gfxstream_vk_buffer, gfxstream_buffer,
+                                   internal_pBufferInfos[i].buffer);
+                    internal_pBufferInfos[i].buffer = gfxstream_buffer->internal_object;
+                }
+            }
+        }
+        std::vector<VkBufferView> internal_pBufferViews(bufferViewCount);
+        for (uint32_t i = 0; i < bufferViewCount; ++i) {
+            if (pBufferViews) {
+                VK_FROM_HANDLE(gfxstream_vk_buffer_view, gfxstream_pBufferViews, pBufferViews[i]);
+                internal_pBufferViews[i] = gfxstream_pBufferViews->internal_object;
+            }
+        }
+        vkEnc->vkUpdateDescriptorSetWithTemplateSizedGOOGLE(
+            gfxstream_device->internal_object, descriptorSet,
+            gfxstream_descriptorUpdateTemplate->internal_object, imageInfoCount, bufferInfoCount,
+            bufferViewCount, pImageInfoEntryIndices, pBufferInfoEntryIndices,
+            pBufferViewEntryIndices, internal_pImageInfos.data(), internal_pBufferInfos.data(),
+            internal_pBufferViews.data(), true /* do lock */);
     }
-    AEMU_SCOPED_TRACE("vkUpdateDescriptorSetWithTemplateSizedGOOGLE");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkUpdateDescriptorSetWithTemplateSizedGOOGLE(
-        device, descriptorSet, descriptorUpdateTemplate, imageInfoCount, bufferInfoCount,
-        bufferViewCount, pImageInfoEntryIndices, pBufferInfoEntryIndices, pBufferViewEntryIndices,
-        pImageInfos, pBufferInfos, pBufferViews, true /* do lock */);
 }
-static void entry_vkBeginCommandBufferAsyncGOOGLE(VkCommandBuffer commandBuffer,
-                                                  const VkCommandBufferBeginInfo* pBeginInfo) {
+void gfxstream_vk_BeginCommandBufferAsyncGOOGLE(VkCommandBuffer commandBuffer,
+                                                const VkCommandBufferBeginInfo* pBeginInfo) {
     AEMU_SCOPED_TRACE("vkBeginCommandBufferAsyncGOOGLE");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkBeginCommandBufferAsyncGOOGLE(commandBuffer, pBeginInfo, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        std::vector<VkCommandBufferBeginInfo> internal_pBeginInfo(1);
+        std::vector<VkCommandBufferInheritanceInfo>
+            internal_VkCommandBufferBeginInfo_pInheritanceInfo;
+        for (uint32_t i = 0; i < 1; ++i) {
+            internal_pBeginInfo[i] = pBeginInfo[i];
+            /* VkCommandBufferBeginInfo::pInheritanceInfo */
+            if (internal_pBeginInfo[i].pInheritanceInfo) {
+                internal_VkCommandBufferBeginInfo_pInheritanceInfo[i] =
+                    internal_pBeginInfo[i].pInheritanceInfo[0];
+                /* VkCommandBufferInheritanceInfo::renderPass */
+                if (internal_VkCommandBufferBeginInfo_pInheritanceInfo[i].renderPass) {
+                    VK_FROM_HANDLE(
+                        gfxstream_vk_render_pass, gfxstream_renderPass,
+                        internal_VkCommandBufferBeginInfo_pInheritanceInfo[i].renderPass);
+                    internal_VkCommandBufferBeginInfo_pInheritanceInfo[i].renderPass =
+                        gfxstream_renderPass->internal_object;
+                }
+                /* VkCommandBufferInheritanceInfo::framebuffer */
+                if (internal_VkCommandBufferBeginInfo_pInheritanceInfo[i].framebuffer) {
+                    VK_FROM_HANDLE(
+                        gfxstream_vk_framebuffer, gfxstream_framebuffer,
+                        internal_VkCommandBufferBeginInfo_pInheritanceInfo[i].framebuffer);
+                    internal_VkCommandBufferBeginInfo_pInheritanceInfo[i].framebuffer =
+                        gfxstream_framebuffer->internal_object;
+                }
+                internal_pBeginInfo[i].pInheritanceInfo =
+                    &internal_VkCommandBufferBeginInfo_pInheritanceInfo[i];
+            }
+        }
+        vkEnc->vkBeginCommandBufferAsyncGOOGLE(gfxstream_commandBuffer->internal_object,
+                                               internal_pBeginInfo.data(), true /* do lock */);
+    }
 }
-static void entry_vkEndCommandBufferAsyncGOOGLE(VkCommandBuffer commandBuffer) {
+void gfxstream_vk_EndCommandBufferAsyncGOOGLE(VkCommandBuffer commandBuffer) {
     AEMU_SCOPED_TRACE("vkEndCommandBufferAsyncGOOGLE");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkEndCommandBufferAsyncGOOGLE(commandBuffer, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        vkEnc->vkEndCommandBufferAsyncGOOGLE(gfxstream_commandBuffer->internal_object,
+                                             true /* do lock */);
+    }
 }
-static void entry_vkResetCommandBufferAsyncGOOGLE(VkCommandBuffer commandBuffer,
-                                                  VkCommandBufferResetFlags flags) {
+void gfxstream_vk_ResetCommandBufferAsyncGOOGLE(VkCommandBuffer commandBuffer,
+                                                VkCommandBufferResetFlags flags) {
     AEMU_SCOPED_TRACE("vkResetCommandBufferAsyncGOOGLE");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkResetCommandBufferAsyncGOOGLE(commandBuffer, flags, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        vkEnc->vkResetCommandBufferAsyncGOOGLE(gfxstream_commandBuffer->internal_object, flags,
+                                               true /* do lock */);
+    }
 }
-static void entry_vkCommandBufferHostSyncGOOGLE(VkCommandBuffer commandBuffer,
-                                                uint32_t needHostSync, uint32_t sequenceNumber) {
+void gfxstream_vk_CommandBufferHostSyncGOOGLE(VkCommandBuffer commandBuffer, uint32_t needHostSync,
+                                              uint32_t sequenceNumber) {
     AEMU_SCOPED_TRACE("vkCommandBufferHostSyncGOOGLE");
-    auto vkEnc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
-    vkEnc->vkCommandBufferHostSyncGOOGLE(commandBuffer, needHostSync, sequenceNumber,
-                                         true /* do lock */);
-}
-static VkResult entry_vkCreateImageWithRequirementsGOOGLE(
-    VkDevice device, const VkImageCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator,
-    VkImage* pImage, VkMemoryRequirements* pMemoryRequirements) {
-    AEMU_SCOPED_TRACE("vkCreateImageWithRequirementsGOOGLE");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    VkResult vkCreateImageWithRequirementsGOOGLE_VkResult_return = (VkResult)0;
-    vkCreateImageWithRequirementsGOOGLE_VkResult_return =
-        vkEnc->vkCreateImageWithRequirementsGOOGLE(device, pCreateInfo, pAllocator, pImage,
-                                                   pMemoryRequirements, true /* do lock */);
-    return vkCreateImageWithRequirementsGOOGLE_VkResult_return;
-}
-static VkResult dynCheck_entry_vkCreateImageWithRequirementsGOOGLE(
-    VkDevice device, const VkImageCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator,
-    VkImage* pImage, VkMemoryRequirements* pMemoryRequirements) {
-    auto resources = ResourceTracker::get();
-    if (!resources->hasDeviceExtension(device, "VK_GOOGLE_gfxstream")) {
-        sOnInvalidDynamicallyCheckedCall("vkCreateImageWithRequirementsGOOGLE",
-                                         "VK_GOOGLE_gfxstream");
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder(
+            gfxstream_commandBuffer->internal_object);
+        vkEnc->vkCommandBufferHostSyncGOOGLE(gfxstream_commandBuffer->internal_object, needHostSync,
+                                             sequenceNumber, true /* do lock */);
     }
+}
+VkResult gfxstream_vk_CreateImageWithRequirementsGOOGLE(VkDevice device,
+                                                        const VkImageCreateInfo* pCreateInfo,
+                                                        const VkAllocationCallbacks* pAllocator,
+                                                        VkImage* pImage,
+                                                        VkMemoryRequirements* pMemoryRequirements) {
     AEMU_SCOPED_TRACE("vkCreateImageWithRequirementsGOOGLE");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
     VkResult vkCreateImageWithRequirementsGOOGLE_VkResult_return = (VkResult)0;
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    struct gfxstream_vk_image* gfxstream_pImage = (struct gfxstream_vk_image*)vk_image_create(
+        (vk_device*)gfxstream_device, pCreateInfo, pAllocator, sizeof(struct gfxstream_vk_image));
     vkCreateImageWithRequirementsGOOGLE_VkResult_return =
-        vkEnc->vkCreateImageWithRequirementsGOOGLE(device, pCreateInfo, pAllocator, pImage,
-                                                   pMemoryRequirements, true /* do lock */);
+        gfxstream_pImage ? VK_SUCCESS : VK_ERROR_OUT_OF_HOST_MEMORY;
+    if (VK_SUCCESS == vkCreateImageWithRequirementsGOOGLE_VkResult_return) {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkCreateImageWithRequirementsGOOGLE_VkResult_return =
+            vkEnc->vkCreateImageWithRequirementsGOOGLE(
+                gfxstream_device->internal_object, pCreateInfo, pAllocator,
+                &gfxstream_pImage->internal_object, pMemoryRequirements, true /* do lock */);
+    }
+    *pImage = gfxstream_vk_image_to_handle(gfxstream_pImage);
     return vkCreateImageWithRequirementsGOOGLE_VkResult_return;
 }
-static VkResult entry_vkCreateBufferWithRequirementsGOOGLE(
+VkResult gfxstream_vk_CreateBufferWithRequirementsGOOGLE(
     VkDevice device, const VkBufferCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator,
     VkBuffer* pBuffer, VkMemoryRequirements* pMemoryRequirements) {
     AEMU_SCOPED_TRACE("vkCreateBufferWithRequirementsGOOGLE");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
     VkResult vkCreateBufferWithRequirementsGOOGLE_VkResult_return = (VkResult)0;
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    struct gfxstream_vk_buffer* gfxstream_pBuffer = (struct gfxstream_vk_buffer*)vk_buffer_create(
+        (vk_device*)gfxstream_device, pCreateInfo, pAllocator, sizeof(struct gfxstream_vk_buffer));
     vkCreateBufferWithRequirementsGOOGLE_VkResult_return =
-        vkEnc->vkCreateBufferWithRequirementsGOOGLE(device, pCreateInfo, pAllocator, pBuffer,
-                                                    pMemoryRequirements, true /* do lock */);
+        gfxstream_pBuffer ? VK_SUCCESS : VK_ERROR_OUT_OF_HOST_MEMORY;
+    if (VK_SUCCESS == vkCreateBufferWithRequirementsGOOGLE_VkResult_return) {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkCreateBufferWithRequirementsGOOGLE_VkResult_return =
+            vkEnc->vkCreateBufferWithRequirementsGOOGLE(
+                gfxstream_device->internal_object, pCreateInfo, pAllocator,
+                &gfxstream_pBuffer->internal_object, pMemoryRequirements, true /* do lock */);
+    }
+    *pBuffer = gfxstream_vk_buffer_to_handle(gfxstream_pBuffer);
     return vkCreateBufferWithRequirementsGOOGLE_VkResult_return;
 }
-static VkResult dynCheck_entry_vkCreateBufferWithRequirementsGOOGLE(
-    VkDevice device, const VkBufferCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator,
-    VkBuffer* pBuffer, VkMemoryRequirements* pMemoryRequirements) {
-    auto resources = ResourceTracker::get();
-    if (!resources->hasDeviceExtension(device, "VK_GOOGLE_gfxstream")) {
-        sOnInvalidDynamicallyCheckedCall("vkCreateBufferWithRequirementsGOOGLE",
-                                         "VK_GOOGLE_gfxstream");
-    }
-    AEMU_SCOPED_TRACE("vkCreateBufferWithRequirementsGOOGLE");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    VkResult vkCreateBufferWithRequirementsGOOGLE_VkResult_return = (VkResult)0;
-    vkCreateBufferWithRequirementsGOOGLE_VkResult_return =
-        vkEnc->vkCreateBufferWithRequirementsGOOGLE(device, pCreateInfo, pAllocator, pBuffer,
-                                                    pMemoryRequirements, true /* do lock */);
-    return vkCreateBufferWithRequirementsGOOGLE_VkResult_return;
-}
-static VkResult entry_vkGetMemoryHostAddressInfoGOOGLE(VkDevice device, VkDeviceMemory memory,
-                                                       uint64_t* pAddress, uint64_t* pSize,
-                                                       uint64_t* pHostmemId) {
+VkResult gfxstream_vk_GetMemoryHostAddressInfoGOOGLE(VkDevice device, VkDeviceMemory memory,
+                                                     uint64_t* pAddress, uint64_t* pSize,
+                                                     uint64_t* pHostmemId) {
     AEMU_SCOPED_TRACE("vkGetMemoryHostAddressInfoGOOGLE");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
     VkResult vkGetMemoryHostAddressInfoGOOGLE_VkResult_return = (VkResult)0;
-    vkGetMemoryHostAddressInfoGOOGLE_VkResult_return = vkEnc->vkGetMemoryHostAddressInfoGOOGLE(
-        device, memory, pAddress, pSize, pHostmemId, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    VK_FROM_HANDLE(gfxstream_vk_device_memory, gfxstream_memory, memory);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkGetMemoryHostAddressInfoGOOGLE_VkResult_return = vkEnc->vkGetMemoryHostAddressInfoGOOGLE(
+            gfxstream_device->internal_object, gfxstream_memory->internal_object, pAddress, pSize,
+            pHostmemId, true /* do lock */);
+    }
     return vkGetMemoryHostAddressInfoGOOGLE_VkResult_return;
 }
-static VkResult dynCheck_entry_vkGetMemoryHostAddressInfoGOOGLE(VkDevice device,
-                                                                VkDeviceMemory memory,
-                                                                uint64_t* pAddress, uint64_t* pSize,
-                                                                uint64_t* pHostmemId) {
-    auto resources = ResourceTracker::get();
-    if (!resources->hasDeviceExtension(device, "VK_GOOGLE_gfxstream")) {
-        sOnInvalidDynamicallyCheckedCall("vkGetMemoryHostAddressInfoGOOGLE", "VK_GOOGLE_gfxstream");
-    }
-    AEMU_SCOPED_TRACE("vkGetMemoryHostAddressInfoGOOGLE");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    VkResult vkGetMemoryHostAddressInfoGOOGLE_VkResult_return = (VkResult)0;
-    vkGetMemoryHostAddressInfoGOOGLE_VkResult_return = vkEnc->vkGetMemoryHostAddressInfoGOOGLE(
-        device, memory, pAddress, pSize, pHostmemId, true /* do lock */);
-    return vkGetMemoryHostAddressInfoGOOGLE_VkResult_return;
-}
-static VkResult entry_vkFreeMemorySyncGOOGLE(VkDevice device, VkDeviceMemory memory,
-                                             const VkAllocationCallbacks* pAllocator) {
+VkResult gfxstream_vk_FreeMemorySyncGOOGLE(VkDevice device, VkDeviceMemory memory,
+                                           const VkAllocationCallbacks* pAllocator) {
     AEMU_SCOPED_TRACE("vkFreeMemorySyncGOOGLE");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
     VkResult vkFreeMemorySyncGOOGLE_VkResult_return = (VkResult)0;
-    vkFreeMemorySyncGOOGLE_VkResult_return =
-        vkEnc->vkFreeMemorySyncGOOGLE(device, memory, pAllocator, true /* do lock */);
+    if (VK_NULL_HANDLE == memory) {
+        return vkFreeMemorySyncGOOGLE_VkResult_return;
+    }
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    VK_FROM_HANDLE(gfxstream_vk_device_memory, gfxstream_memory, memory);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkFreeMemorySyncGOOGLE_VkResult_return = vkEnc->vkFreeMemorySyncGOOGLE(
+            gfxstream_device->internal_object,
+            gfxstream_memory ? gfxstream_memory->internal_object : VK_NULL_HANDLE, pAllocator,
+            true /* do lock */);
+    }
+    vk_device_memory_destroy(&gfxstream_device->vk, pAllocator, &gfxstream_memory->vk);
     return vkFreeMemorySyncGOOGLE_VkResult_return;
 }
-static VkResult dynCheck_entry_vkFreeMemorySyncGOOGLE(VkDevice device, VkDeviceMemory memory,
-                                                      const VkAllocationCallbacks* pAllocator) {
-    auto resources = ResourceTracker::get();
-    if (!resources->hasDeviceExtension(device, "VK_GOOGLE_gfxstream")) {
-        sOnInvalidDynamicallyCheckedCall("vkFreeMemorySyncGOOGLE", "VK_GOOGLE_gfxstream");
-    }
-    AEMU_SCOPED_TRACE("vkFreeMemorySyncGOOGLE");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    VkResult vkFreeMemorySyncGOOGLE_VkResult_return = (VkResult)0;
-    vkFreeMemorySyncGOOGLE_VkResult_return =
-        vkEnc->vkFreeMemorySyncGOOGLE(device, memory, pAllocator, true /* do lock */);
-    return vkFreeMemorySyncGOOGLE_VkResult_return;
-}
-static void entry_vkQueueHostSyncGOOGLE(VkQueue queue, uint32_t needHostSync,
-                                        uint32_t sequenceNumber) {
+void gfxstream_vk_QueueHostSyncGOOGLE(VkQueue queue, uint32_t needHostSync,
+                                      uint32_t sequenceNumber) {
     AEMU_SCOPED_TRACE("vkQueueHostSyncGOOGLE");
-    auto vkEnc = ResourceTracker::getQueueEncoder(queue);
-    vkEnc->vkQueueHostSyncGOOGLE(queue, needHostSync, sequenceNumber, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_queue, gfxstream_queue, queue);
+    {
+        auto vkEnc =
+            gfxstream::vk::ResourceTracker::getQueueEncoder(gfxstream_queue->internal_object);
+        vkEnc->vkQueueHostSyncGOOGLE(gfxstream_queue->internal_object, needHostSync, sequenceNumber,
+                                     true /* do lock */);
+    }
 }
-static void entry_vkQueueSubmitAsyncGOOGLE(VkQueue queue, uint32_t submitCount,
-                                           const VkSubmitInfo* pSubmits, VkFence fence) {
+void gfxstream_vk_QueueSubmitAsyncGOOGLE(VkQueue queue, uint32_t submitCount,
+                                         const VkSubmitInfo* pSubmits, VkFence fence) {
     AEMU_SCOPED_TRACE("vkQueueSubmitAsyncGOOGLE");
-    auto vkEnc = ResourceTracker::getQueueEncoder(queue);
-    vkEnc->vkQueueSubmitAsyncGOOGLE(queue, submitCount, pSubmits, fence, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_queue, gfxstream_queue, queue);
+    VK_FROM_HANDLE(gfxstream_vk_fence, gfxstream_fence, fence);
+    {
+        auto vkEnc =
+            gfxstream::vk::ResourceTracker::getQueueEncoder(gfxstream_queue->internal_object);
+        std::vector<VkSubmitInfo> internal_pSubmits(submitCount);
+        std::vector<std::vector<VkSemaphore>> internal_VkSubmitInfo_pWaitSemaphores;
+        std::vector<std::vector<VkCommandBuffer>> internal_VkSubmitInfo_pCommandBuffers;
+        std::vector<std::vector<VkSemaphore>> internal_VkSubmitInfo_pSignalSemaphores;
+        for (uint32_t i = 0; i < submitCount; ++i) {
+            internal_pSubmits[i] = pSubmits[i];
+            /* VkSubmitInfo::pWaitSemaphores */
+            internal_VkSubmitInfo_pWaitSemaphores.push_back(std::vector<VkSemaphore>());
+            internal_VkSubmitInfo_pWaitSemaphores[i] = transformVkSemaphoreList(
+                internal_pSubmits[i].pWaitSemaphores, internal_pSubmits[i].waitSemaphoreCount);
+            internal_pSubmits[i].pWaitSemaphores = internal_VkSubmitInfo_pWaitSemaphores[i].data();
+            internal_pSubmits[i].waitSemaphoreCount =
+                internal_VkSubmitInfo_pWaitSemaphores[i].size();
+            /* VkSubmitInfo::pCommandBuffers */
+            internal_VkSubmitInfo_pCommandBuffers.push_back(std::vector<VkCommandBuffer>());
+            internal_VkSubmitInfo_pCommandBuffers[i].reserve(
+                internal_pSubmits[i].commandBufferCount);
+            memset(&internal_VkSubmitInfo_pCommandBuffers[i][0], 0,
+                   sizeof(VkCommandBuffer) * internal_pSubmits[i].commandBufferCount);
+            for (uint32_t j = 0; j < internal_pSubmits[i].commandBufferCount; ++j) {
+                VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_pCommandBuffers,
+                               internal_pSubmits[i].pCommandBuffers[j]);
+                internal_VkSubmitInfo_pCommandBuffers[i][j] =
+                    gfxstream_pCommandBuffers->internal_object;
+            }
+            internal_pSubmits[i].pCommandBuffers = internal_VkSubmitInfo_pCommandBuffers[i].data();
+            /* VkSubmitInfo::pSignalSemaphores */
+            internal_VkSubmitInfo_pSignalSemaphores.push_back(std::vector<VkSemaphore>());
+            internal_VkSubmitInfo_pSignalSemaphores[i] = transformVkSemaphoreList(
+                internal_pSubmits[i].pSignalSemaphores, internal_pSubmits[i].signalSemaphoreCount);
+            internal_pSubmits[i].pSignalSemaphores =
+                internal_VkSubmitInfo_pSignalSemaphores[i].data();
+            internal_pSubmits[i].signalSemaphoreCount =
+                internal_VkSubmitInfo_pSignalSemaphores[i].size();
+        }
+        vkEnc->vkQueueSubmitAsyncGOOGLE(
+            gfxstream_queue->internal_object, submitCount, internal_pSubmits.data(),
+            gfxstream_fence ? gfxstream_fence->internal_object : VK_NULL_HANDLE,
+            true /* do lock */);
+    }
 }
-static void entry_vkQueueWaitIdleAsyncGOOGLE(VkQueue queue) {
+void gfxstream_vk_QueueWaitIdleAsyncGOOGLE(VkQueue queue) {
     AEMU_SCOPED_TRACE("vkQueueWaitIdleAsyncGOOGLE");
-    auto vkEnc = ResourceTracker::getQueueEncoder(queue);
-    vkEnc->vkQueueWaitIdleAsyncGOOGLE(queue, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_queue, gfxstream_queue, queue);
+    {
+        auto vkEnc =
+            gfxstream::vk::ResourceTracker::getQueueEncoder(gfxstream_queue->internal_object);
+        vkEnc->vkQueueWaitIdleAsyncGOOGLE(gfxstream_queue->internal_object, true /* do lock */);
+    }
 }
-static void entry_vkQueueBindSparseAsyncGOOGLE(VkQueue queue, uint32_t bindInfoCount,
-                                               const VkBindSparseInfo* pBindInfo, VkFence fence) {
+void gfxstream_vk_QueueBindSparseAsyncGOOGLE(VkQueue queue, uint32_t bindInfoCount,
+                                             const VkBindSparseInfo* pBindInfo, VkFence fence) {
     AEMU_SCOPED_TRACE("vkQueueBindSparseAsyncGOOGLE");
-    auto vkEnc = ResourceTracker::getQueueEncoder(queue);
-    vkEnc->vkQueueBindSparseAsyncGOOGLE(queue, bindInfoCount, pBindInfo, fence, true /* do lock */);
-}
-static void entry_vkGetLinearImageLayoutGOOGLE(VkDevice device, VkFormat format,
-                                               VkDeviceSize* pOffset,
-                                               VkDeviceSize* pRowPitchAlignment) {
-    AEMU_SCOPED_TRACE("vkGetLinearImageLayoutGOOGLE");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkGetLinearImageLayoutGOOGLE(device, format, pOffset, pRowPitchAlignment,
-                                        true /* do lock */);
-}
-static void dynCheck_entry_vkGetLinearImageLayoutGOOGLE(VkDevice device, VkFormat format,
-                                                        VkDeviceSize* pOffset,
-                                                        VkDeviceSize* pRowPitchAlignment) {
-    auto resources = ResourceTracker::get();
-    if (!resources->hasDeviceExtension(device, "VK_GOOGLE_gfxstream")) {
-        sOnInvalidDynamicallyCheckedCall("vkGetLinearImageLayoutGOOGLE", "VK_GOOGLE_gfxstream");
+    VK_FROM_HANDLE(gfxstream_vk_queue, gfxstream_queue, queue);
+    VK_FROM_HANDLE(gfxstream_vk_fence, gfxstream_fence, fence);
+    {
+        auto vkEnc =
+            gfxstream::vk::ResourceTracker::getQueueEncoder(gfxstream_queue->internal_object);
+        std::vector<VkBindSparseInfo> internal_pBindInfo(bindInfoCount);
+        std::vector<std::vector<VkSemaphore>> internal_VkBindSparseInfo_pWaitSemaphores;
+        std::vector<std::vector<VkSparseBufferMemoryBindInfo>>
+            internal_VkBindSparseInfo_pBufferBinds;
+        std::vector<std::vector<VkSparseMemoryBind>> internal_VkSparseBufferMemoryBindInfo_pBinds;
+        std::vector<std::vector<VkSparseImageOpaqueMemoryBindInfo>>
+            internal_VkBindSparseInfo_pImageOpaqueBinds;
+        std::vector<std::vector<VkSparseMemoryBind>>
+            internal_VkSparseImageOpaqueMemoryBindInfo_pBinds;
+        std::vector<std::vector<VkSparseImageMemoryBindInfo>> internal_VkBindSparseInfo_pImageBinds;
+        std::vector<std::vector<VkSparseImageMemoryBind>>
+            internal_VkSparseImageMemoryBindInfo_pBinds;
+        std::vector<std::vector<VkSemaphore>> internal_VkBindSparseInfo_pSignalSemaphores;
+        for (uint32_t i = 0; i < bindInfoCount; ++i) {
+            internal_pBindInfo[i] = pBindInfo[i];
+            /* VkBindSparseInfo::pWaitSemaphores */
+            internal_VkBindSparseInfo_pWaitSemaphores.push_back(std::vector<VkSemaphore>());
+            internal_VkBindSparseInfo_pWaitSemaphores[i] = transformVkSemaphoreList(
+                internal_pBindInfo[i].pWaitSemaphores, internal_pBindInfo[i].waitSemaphoreCount);
+            internal_pBindInfo[i].pWaitSemaphores =
+                internal_VkBindSparseInfo_pWaitSemaphores[i].data();
+            internal_pBindInfo[i].waitSemaphoreCount =
+                internal_VkBindSparseInfo_pWaitSemaphores[i].size();
+            /* VkBindSparseInfo::pBufferBinds */
+            internal_VkBindSparseInfo_pBufferBinds.push_back(
+                std::vector<VkSparseBufferMemoryBindInfo>());
+            internal_VkBindSparseInfo_pBufferBinds[i].reserve(
+                internal_pBindInfo[i].bufferBindCount);
+            memset(&internal_VkBindSparseInfo_pBufferBinds[i][0], 0,
+                   sizeof(VkSparseBufferMemoryBindInfo) * internal_pBindInfo[i].bufferBindCount);
+            for (uint32_t j = 0; j < internal_pBindInfo[i].bufferBindCount; ++j) {
+                internal_VkBindSparseInfo_pBufferBinds[i][j] =
+                    internal_pBindInfo[i].pBufferBinds[j];
+                /* VkSparseBufferMemoryBindInfo::buffer */
+                VK_FROM_HANDLE(gfxstream_vk_buffer, gfxstream_buffer,
+                               internal_VkBindSparseInfo_pBufferBinds[i][j].buffer);
+                internal_VkBindSparseInfo_pBufferBinds[i][j].buffer =
+                    gfxstream_buffer->internal_object;
+                /* VkSparseBufferMemoryBindInfo::pBinds */
+                internal_VkSparseBufferMemoryBindInfo_pBinds.push_back(
+                    std::vector<VkSparseMemoryBind>());
+                internal_VkSparseBufferMemoryBindInfo_pBinds[j].reserve(
+                    internal_VkBindSparseInfo_pBufferBinds[i][j].bindCount);
+                memset(&internal_VkSparseBufferMemoryBindInfo_pBinds[j][0], 0,
+                       sizeof(VkSparseMemoryBind) *
+                           internal_VkBindSparseInfo_pBufferBinds[i][j].bindCount);
+                for (uint32_t k = 0; k < internal_VkBindSparseInfo_pBufferBinds[i][j].bindCount;
+                     ++k) {
+                    internal_VkSparseBufferMemoryBindInfo_pBinds[j][k] =
+                        internal_VkBindSparseInfo_pBufferBinds[i][j].pBinds[k];
+                    /* VkSparseMemoryBind::memory */
+                    if (internal_VkSparseBufferMemoryBindInfo_pBinds[j][k].memory) {
+                        VK_FROM_HANDLE(gfxstream_vk_device_memory, gfxstream_memory,
+                                       internal_VkSparseBufferMemoryBindInfo_pBinds[j][k].memory);
+                        internal_VkSparseBufferMemoryBindInfo_pBinds[j][k].memory =
+                            gfxstream_memory->internal_object;
+                    }
+                }
+                internal_VkBindSparseInfo_pBufferBinds[i][j].pBinds =
+                    internal_VkSparseBufferMemoryBindInfo_pBinds[j].data();
+            }
+            internal_pBindInfo[i].pBufferBinds = internal_VkBindSparseInfo_pBufferBinds[i].data();
+            /* VkBindSparseInfo::pImageOpaqueBinds */
+            internal_VkBindSparseInfo_pImageOpaqueBinds.push_back(
+                std::vector<VkSparseImageOpaqueMemoryBindInfo>());
+            internal_VkBindSparseInfo_pImageOpaqueBinds[i].reserve(
+                internal_pBindInfo[i].imageOpaqueBindCount);
+            memset(&internal_VkBindSparseInfo_pImageOpaqueBinds[i][0], 0,
+                   sizeof(VkSparseImageOpaqueMemoryBindInfo) *
+                       internal_pBindInfo[i].imageOpaqueBindCount);
+            for (uint32_t j = 0; j < internal_pBindInfo[i].imageOpaqueBindCount; ++j) {
+                internal_VkBindSparseInfo_pImageOpaqueBinds[i][j] =
+                    internal_pBindInfo[i].pImageOpaqueBinds[j];
+                /* VkSparseImageOpaqueMemoryBindInfo::image */
+                VK_FROM_HANDLE(gfxstream_vk_image, gfxstream_image,
+                               internal_VkBindSparseInfo_pImageOpaqueBinds[i][j].image);
+                internal_VkBindSparseInfo_pImageOpaqueBinds[i][j].image =
+                    gfxstream_image->internal_object;
+                /* VkSparseImageOpaqueMemoryBindInfo::pBinds */
+                internal_VkSparseImageOpaqueMemoryBindInfo_pBinds.push_back(
+                    std::vector<VkSparseMemoryBind>());
+                internal_VkSparseImageOpaqueMemoryBindInfo_pBinds[j].reserve(
+                    internal_VkBindSparseInfo_pImageOpaqueBinds[i][j].bindCount);
+                memset(&internal_VkSparseImageOpaqueMemoryBindInfo_pBinds[j][0], 0,
+                       sizeof(VkSparseMemoryBind) *
+                           internal_VkBindSparseInfo_pImageOpaqueBinds[i][j].bindCount);
+                for (uint32_t l = 0;
+                     l < internal_VkBindSparseInfo_pImageOpaqueBinds[i][j].bindCount; ++l) {
+                    internal_VkSparseImageOpaqueMemoryBindInfo_pBinds[j][l] =
+                        internal_VkBindSparseInfo_pImageOpaqueBinds[i][j].pBinds[l];
+                    /* VkSparseMemoryBind::memory */
+                    if (internal_VkSparseImageOpaqueMemoryBindInfo_pBinds[j][l].memory) {
+                        VK_FROM_HANDLE(
+                            gfxstream_vk_device_memory, gfxstream_memory,
+                            internal_VkSparseImageOpaqueMemoryBindInfo_pBinds[j][l].memory);
+                        internal_VkSparseImageOpaqueMemoryBindInfo_pBinds[j][l].memory =
+                            gfxstream_memory->internal_object;
+                    }
+                }
+                internal_VkBindSparseInfo_pImageOpaqueBinds[i][j].pBinds =
+                    internal_VkSparseImageOpaqueMemoryBindInfo_pBinds[j].data();
+            }
+            internal_pBindInfo[i].pImageOpaqueBinds =
+                internal_VkBindSparseInfo_pImageOpaqueBinds[i].data();
+            /* VkBindSparseInfo::pImageBinds */
+            internal_VkBindSparseInfo_pImageBinds.push_back(
+                std::vector<VkSparseImageMemoryBindInfo>());
+            internal_VkBindSparseInfo_pImageBinds[i].reserve(internal_pBindInfo[i].imageBindCount);
+            memset(&internal_VkBindSparseInfo_pImageBinds[i][0], 0,
+                   sizeof(VkSparseImageMemoryBindInfo) * internal_pBindInfo[i].imageBindCount);
+            for (uint32_t j = 0; j < internal_pBindInfo[i].imageBindCount; ++j) {
+                internal_VkBindSparseInfo_pImageBinds[i][j] = internal_pBindInfo[i].pImageBinds[j];
+                /* VkSparseImageMemoryBindInfo::image */
+                VK_FROM_HANDLE(gfxstream_vk_image, gfxstream_image,
+                               internal_VkBindSparseInfo_pImageBinds[i][j].image);
+                internal_VkBindSparseInfo_pImageBinds[i][j].image =
+                    gfxstream_image->internal_object;
+                /* VkSparseImageMemoryBindInfo::pBinds */
+                internal_VkSparseImageMemoryBindInfo_pBinds.push_back(
+                    std::vector<VkSparseImageMemoryBind>());
+                internal_VkSparseImageMemoryBindInfo_pBinds[j].reserve(
+                    internal_VkBindSparseInfo_pImageBinds[i][j].bindCount);
+                memset(&internal_VkSparseImageMemoryBindInfo_pBinds[j][0], 0,
+                       sizeof(VkSparseImageMemoryBind) *
+                           internal_VkBindSparseInfo_pImageBinds[i][j].bindCount);
+                for (uint32_t m = 0; m < internal_VkBindSparseInfo_pImageBinds[i][j].bindCount;
+                     ++m) {
+                    internal_VkSparseImageMemoryBindInfo_pBinds[j][m] =
+                        internal_VkBindSparseInfo_pImageBinds[i][j].pBinds[m];
+                    /* VkSparseImageMemoryBind::memory */
+                    if (internal_VkSparseImageMemoryBindInfo_pBinds[j][m].memory) {
+                        VK_FROM_HANDLE(gfxstream_vk_device_memory, gfxstream_memory,
+                                       internal_VkSparseImageMemoryBindInfo_pBinds[j][m].memory);
+                        internal_VkSparseImageMemoryBindInfo_pBinds[j][m].memory =
+                            gfxstream_memory->internal_object;
+                    }
+                }
+                internal_VkBindSparseInfo_pImageBinds[i][j].pBinds =
+                    internal_VkSparseImageMemoryBindInfo_pBinds[j].data();
+            }
+            internal_pBindInfo[i].pImageBinds = internal_VkBindSparseInfo_pImageBinds[i].data();
+            /* VkBindSparseInfo::pSignalSemaphores */
+            internal_VkBindSparseInfo_pSignalSemaphores.push_back(std::vector<VkSemaphore>());
+            internal_VkBindSparseInfo_pSignalSemaphores[i] =
+                transformVkSemaphoreList(internal_pBindInfo[i].pSignalSemaphores,
+                                         internal_pBindInfo[i].signalSemaphoreCount);
+            internal_pBindInfo[i].pSignalSemaphores =
+                internal_VkBindSparseInfo_pSignalSemaphores[i].data();
+            internal_pBindInfo[i].signalSemaphoreCount =
+                internal_VkBindSparseInfo_pSignalSemaphores[i].size();
+        }
+        vkEnc->vkQueueBindSparseAsyncGOOGLE(
+            gfxstream_queue->internal_object, bindInfoCount, internal_pBindInfo.data(),
+            gfxstream_fence ? gfxstream_fence->internal_object : VK_NULL_HANDLE,
+            true /* do lock */);
     }
+}
+void gfxstream_vk_GetLinearImageLayoutGOOGLE(VkDevice device, VkFormat format,
+                                             VkDeviceSize* pOffset,
+                                             VkDeviceSize* pRowPitchAlignment) {
     AEMU_SCOPED_TRACE("vkGetLinearImageLayoutGOOGLE");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkGetLinearImageLayoutGOOGLE(device, format, pOffset, pRowPitchAlignment,
-                                        true /* do lock */);
-}
-static void entry_vkGetLinearImageLayout2GOOGLE(VkDevice device,
-                                                const VkImageCreateInfo* pCreateInfo,
-                                                VkDeviceSize* pOffset,
-                                                VkDeviceSize* pRowPitchAlignment) {
-    AEMU_SCOPED_TRACE("vkGetLinearImageLayout2GOOGLE");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkGetLinearImageLayout2GOOGLE(device, pCreateInfo, pOffset, pRowPitchAlignment,
-                                         true /* do lock */);
-}
-static void dynCheck_entry_vkGetLinearImageLayout2GOOGLE(VkDevice device,
-                                                         const VkImageCreateInfo* pCreateInfo,
-                                                         VkDeviceSize* pOffset,
-                                                         VkDeviceSize* pRowPitchAlignment) {
-    auto resources = ResourceTracker::get();
-    if (!resources->hasDeviceExtension(device, "VK_GOOGLE_gfxstream")) {
-        sOnInvalidDynamicallyCheckedCall("vkGetLinearImageLayout2GOOGLE", "VK_GOOGLE_gfxstream");
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkEnc->vkGetLinearImageLayoutGOOGLE(gfxstream_device->internal_object, format, pOffset,
+                                            pRowPitchAlignment, true /* do lock */);
     }
-    AEMU_SCOPED_TRACE("vkGetLinearImageLayout2GOOGLE");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkGetLinearImageLayout2GOOGLE(device, pCreateInfo, pOffset, pRowPitchAlignment,
-                                         true /* do lock */);
 }
-static void entry_vkQueueFlushCommandsGOOGLE(VkQueue queue, VkCommandBuffer commandBuffer,
-                                             VkDeviceSize dataSize, const void* pData) {
+void gfxstream_vk_GetLinearImageLayout2GOOGLE(VkDevice device, const VkImageCreateInfo* pCreateInfo,
+                                              VkDeviceSize* pOffset,
+                                              VkDeviceSize* pRowPitchAlignment) {
+    AEMU_SCOPED_TRACE("vkGetLinearImageLayout2GOOGLE");
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkEnc->vkGetLinearImageLayout2GOOGLE(gfxstream_device->internal_object, pCreateInfo,
+                                             pOffset, pRowPitchAlignment, true /* do lock */);
+    }
+}
+void gfxstream_vk_QueueFlushCommandsGOOGLE(VkQueue queue, VkCommandBuffer commandBuffer,
+                                           VkDeviceSize dataSize, const void* pData) {
     AEMU_SCOPED_TRACE("vkQueueFlushCommandsGOOGLE");
-    auto vkEnc = ResourceTracker::getQueueEncoder(queue);
-    vkEnc->vkQueueFlushCommandsGOOGLE(queue, commandBuffer, dataSize, pData, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_queue, gfxstream_queue, queue);
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    {
+        auto vkEnc =
+            gfxstream::vk::ResourceTracker::getQueueEncoder(gfxstream_queue->internal_object);
+        vkEnc->vkQueueFlushCommandsGOOGLE(gfxstream_queue->internal_object,
+                                          gfxstream_commandBuffer->internal_object, dataSize, pData,
+                                          true /* do lock */);
+    }
 }
-static void entry_vkQueueCommitDescriptorSetUpdatesGOOGLE(
+void gfxstream_vk_QueueCommitDescriptorSetUpdatesGOOGLE(
     VkQueue queue, uint32_t descriptorPoolCount, const VkDescriptorPool* pDescriptorPools,
     uint32_t descriptorSetCount, const VkDescriptorSetLayout* pSetLayouts,
     const uint64_t* pDescriptorSetPoolIds, const uint32_t* pDescriptorSetWhichPool,
@@ -4568,71 +6211,166 @@
     const uint32_t* pDescriptorWriteStartingIndices, uint32_t pendingDescriptorWriteCount,
     const VkWriteDescriptorSet* pPendingDescriptorWrites) {
     AEMU_SCOPED_TRACE("vkQueueCommitDescriptorSetUpdatesGOOGLE");
-    auto vkEnc = ResourceTracker::getQueueEncoder(queue);
-    vkEnc->vkQueueCommitDescriptorSetUpdatesGOOGLE(
-        queue, descriptorPoolCount, pDescriptorPools, descriptorSetCount, pSetLayouts,
-        pDescriptorSetPoolIds, pDescriptorSetWhichPool, pDescriptorSetPendingAllocation,
-        pDescriptorWriteStartingIndices, pendingDescriptorWriteCount, pPendingDescriptorWrites,
-        true /* do lock */);
-}
-static void entry_vkCollectDescriptorPoolIdsGOOGLE(VkDevice device, VkDescriptorPool descriptorPool,
-                                                   uint32_t* pPoolIdCount, uint64_t* pPoolIds) {
-    AEMU_SCOPED_TRACE("vkCollectDescriptorPoolIdsGOOGLE");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkCollectDescriptorPoolIdsGOOGLE(device, descriptorPool, pPoolIdCount, pPoolIds,
-                                            true /* do lock */);
-}
-static void dynCheck_entry_vkCollectDescriptorPoolIdsGOOGLE(VkDevice device,
-                                                            VkDescriptorPool descriptorPool,
-                                                            uint32_t* pPoolIdCount,
-                                                            uint64_t* pPoolIds) {
-    auto resources = ResourceTracker::get();
-    if (!resources->hasDeviceExtension(device, "VK_GOOGLE_gfxstream")) {
-        sOnInvalidDynamicallyCheckedCall("vkCollectDescriptorPoolIdsGOOGLE", "VK_GOOGLE_gfxstream");
+    VK_FROM_HANDLE(gfxstream_vk_queue, gfxstream_queue, queue);
+    {
+        auto vkEnc =
+            gfxstream::vk::ResourceTracker::getQueueEncoder(gfxstream_queue->internal_object);
+        std::vector<VkDescriptorPool> internal_pDescriptorPools(descriptorPoolCount);
+        for (uint32_t i = 0; i < descriptorPoolCount; ++i) {
+            VK_FROM_HANDLE(gfxstream_vk_descriptor_pool, gfxstream_pDescriptorPools,
+                           pDescriptorPools[i]);
+            internal_pDescriptorPools[i] = gfxstream_pDescriptorPools->internal_object;
+        }
+        std::vector<VkDescriptorSetLayout> internal_pSetLayouts(descriptorSetCount);
+        for (uint32_t i = 0; i < descriptorSetCount; ++i) {
+            VK_FROM_HANDLE(gfxstream_vk_descriptor_set_layout, gfxstream_pSetLayouts,
+                           pSetLayouts[i]);
+            internal_pSetLayouts[i] = gfxstream_pSetLayouts->internal_object;
+        }
+        std::vector<VkWriteDescriptorSet> internal_pPendingDescriptorWrites(
+            pendingDescriptorWriteCount);
+        std::vector<std::vector<VkDescriptorImageInfo>> internal_VkWriteDescriptorSet_pImageInfo;
+        std::vector<std::vector<VkDescriptorBufferInfo>> internal_VkWriteDescriptorSet_pBufferInfo;
+        std::vector<std::vector<VkBufferView>> internal_VkWriteDescriptorSet_pTexelBufferView;
+        for (uint32_t i = 0; i < pendingDescriptorWriteCount; ++i) {
+            internal_pPendingDescriptorWrites[i] = pPendingDescriptorWrites[i];
+            /* VkWriteDescriptorSet::pImageInfo */
+            internal_VkWriteDescriptorSet_pImageInfo.push_back(
+                std::vector<VkDescriptorImageInfo>());
+            internal_VkWriteDescriptorSet_pImageInfo[i].reserve(
+                internal_pPendingDescriptorWrites[i].descriptorCount);
+            memset(&internal_VkWriteDescriptorSet_pImageInfo[i][0], 0,
+                   sizeof(VkDescriptorImageInfo) *
+                       internal_pPendingDescriptorWrites[i].descriptorCount);
+            for (uint32_t j = 0; j < internal_pPendingDescriptorWrites[i].descriptorCount; ++j) {
+                if (internal_pPendingDescriptorWrites[i].pImageInfo) {
+                    internal_VkWriteDescriptorSet_pImageInfo[i][j] =
+                        internal_pPendingDescriptorWrites[i].pImageInfo[j];
+                    /* VkDescriptorImageInfo::imageView */
+                    if (internal_VkWriteDescriptorSet_pImageInfo[i][j].imageView) {
+                        VK_FROM_HANDLE(gfxstream_vk_image_view, gfxstream_imageView,
+                                       internal_VkWriteDescriptorSet_pImageInfo[i][j].imageView);
+                        internal_VkWriteDescriptorSet_pImageInfo[i][j].imageView =
+                            gfxstream_imageView->internal_object;
+                    }
+                }
+            }
+            internal_pPendingDescriptorWrites[i].pImageInfo =
+                internal_VkWriteDescriptorSet_pImageInfo[i].data();
+            /* VkWriteDescriptorSet::pBufferInfo */
+            internal_VkWriteDescriptorSet_pBufferInfo.push_back(
+                std::vector<VkDescriptorBufferInfo>());
+            internal_VkWriteDescriptorSet_pBufferInfo[i].reserve(
+                internal_pPendingDescriptorWrites[i].descriptorCount);
+            memset(&internal_VkWriteDescriptorSet_pBufferInfo[i][0], 0,
+                   sizeof(VkDescriptorBufferInfo) *
+                       internal_pPendingDescriptorWrites[i].descriptorCount);
+            for (uint32_t j = 0; j < internal_pPendingDescriptorWrites[i].descriptorCount; ++j) {
+                if (internal_pPendingDescriptorWrites[i].pBufferInfo) {
+                    internal_VkWriteDescriptorSet_pBufferInfo[i][j] =
+                        internal_pPendingDescriptorWrites[i].pBufferInfo[j];
+                    /* VkDescriptorBufferInfo::buffer */
+                    if (internal_VkWriteDescriptorSet_pBufferInfo[i][j].buffer) {
+                        VK_FROM_HANDLE(gfxstream_vk_buffer, gfxstream_buffer,
+                                       internal_VkWriteDescriptorSet_pBufferInfo[i][j].buffer);
+                        internal_VkWriteDescriptorSet_pBufferInfo[i][j].buffer =
+                            gfxstream_buffer->internal_object;
+                    }
+                }
+            }
+            internal_pPendingDescriptorWrites[i].pBufferInfo =
+                internal_VkWriteDescriptorSet_pBufferInfo[i].data();
+            /* VkWriteDescriptorSet::pTexelBufferView */
+            internal_VkWriteDescriptorSet_pTexelBufferView.push_back(std::vector<VkBufferView>());
+            internal_VkWriteDescriptorSet_pTexelBufferView[i].reserve(
+                internal_pPendingDescriptorWrites[i].descriptorCount);
+            memset(&internal_VkWriteDescriptorSet_pTexelBufferView[i][0], 0,
+                   sizeof(VkBufferView) * internal_pPendingDescriptorWrites[i].descriptorCount);
+            for (uint32_t j = 0; j < internal_pPendingDescriptorWrites[i].descriptorCount; ++j) {
+                if (internal_pPendingDescriptorWrites[i].pTexelBufferView) {
+                    VK_FROM_HANDLE(gfxstream_vk_buffer_view, gfxstream_pTexelBufferView,
+                                   internal_pPendingDescriptorWrites[i].pTexelBufferView[j]);
+                    internal_VkWriteDescriptorSet_pTexelBufferView[i][j] =
+                        gfxstream_pTexelBufferView->internal_object;
+                }
+            }
+            internal_pPendingDescriptorWrites[i].pTexelBufferView =
+                internal_VkWriteDescriptorSet_pTexelBufferView[i].data();
+        }
+        vkEnc->vkQueueCommitDescriptorSetUpdatesGOOGLE(
+            gfxstream_queue->internal_object, descriptorPoolCount, internal_pDescriptorPools.data(),
+            descriptorSetCount, internal_pSetLayouts.data(), pDescriptorSetPoolIds,
+            pDescriptorSetWhichPool, pDescriptorSetPendingAllocation,
+            pDescriptorWriteStartingIndices, pendingDescriptorWriteCount,
+            internal_pPendingDescriptorWrites.data(), true /* do lock */);
     }
-    AEMU_SCOPED_TRACE("vkCollectDescriptorPoolIdsGOOGLE");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkCollectDescriptorPoolIdsGOOGLE(device, descriptorPool, pPoolIdCount, pPoolIds,
-                                            true /* do lock */);
 }
-static void entry_vkQueueSignalReleaseImageANDROIDAsyncGOOGLE(VkQueue queue,
-                                                              uint32_t waitSemaphoreCount,
-                                                              const VkSemaphore* pWaitSemaphores,
-                                                              VkImage image) {
+void gfxstream_vk_CollectDescriptorPoolIdsGOOGLE(VkDevice device, VkDescriptorPool descriptorPool,
+                                                 uint32_t* pPoolIdCount, uint64_t* pPoolIds) {
+    AEMU_SCOPED_TRACE("vkCollectDescriptorPoolIdsGOOGLE");
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    VK_FROM_HANDLE(gfxstream_vk_descriptor_pool, gfxstream_descriptorPool, descriptorPool);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkEnc->vkCollectDescriptorPoolIdsGOOGLE(gfxstream_device->internal_object,
+                                                gfxstream_descriptorPool->internal_object,
+                                                pPoolIdCount, pPoolIds, true /* do lock */);
+    }
+}
+void gfxstream_vk_QueueSignalReleaseImageANDROIDAsyncGOOGLE(VkQueue queue,
+                                                            uint32_t waitSemaphoreCount,
+                                                            const VkSemaphore* pWaitSemaphores,
+                                                            VkImage image) {
     AEMU_SCOPED_TRACE("vkQueueSignalReleaseImageANDROIDAsyncGOOGLE");
-    auto vkEnc = ResourceTracker::getQueueEncoder(queue);
-    vkEnc->vkQueueSignalReleaseImageANDROIDAsyncGOOGLE(queue, waitSemaphoreCount, pWaitSemaphores,
-                                                       image, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_queue, gfxstream_queue, queue);
+    VK_FROM_HANDLE(gfxstream_vk_image, gfxstream_image, image);
+    {
+        auto vkEnc =
+            gfxstream::vk::ResourceTracker::getQueueEncoder(gfxstream_queue->internal_object);
+        std::vector<VkSemaphore> internal_pWaitSemaphores(waitSemaphoreCount);
+        for (uint32_t i = 0; i < waitSemaphoreCount; ++i) {
+            if (pWaitSemaphores) {
+                VK_FROM_HANDLE(gfxstream_vk_semaphore, gfxstream_pWaitSemaphores,
+                               pWaitSemaphores[i]);
+                internal_pWaitSemaphores[i] = gfxstream_pWaitSemaphores->internal_object;
+            }
+        }
+        vkEnc->vkQueueSignalReleaseImageANDROIDAsyncGOOGLE(
+            gfxstream_queue->internal_object, waitSemaphoreCount, internal_pWaitSemaphores.data(),
+            gfxstream_image->internal_object, true /* do lock */);
+    }
 }
-static void entry_vkQueueFlushCommandsFromAuxMemoryGOOGLE(VkQueue queue,
-                                                          VkCommandBuffer commandBuffer,
-                                                          VkDeviceMemory deviceMemory,
-                                                          VkDeviceSize dataOffset,
-                                                          VkDeviceSize dataSize) {
+void gfxstream_vk_QueueFlushCommandsFromAuxMemoryGOOGLE(VkQueue queue,
+                                                        VkCommandBuffer commandBuffer,
+                                                        VkDeviceMemory deviceMemory,
+                                                        VkDeviceSize dataOffset,
+                                                        VkDeviceSize dataSize) {
     AEMU_SCOPED_TRACE("vkQueueFlushCommandsFromAuxMemoryGOOGLE");
-    auto vkEnc = ResourceTracker::getQueueEncoder(queue);
-    vkEnc->vkQueueFlushCommandsFromAuxMemoryGOOGLE(queue, commandBuffer, deviceMemory, dataOffset,
-                                                   dataSize, true /* do lock */);
-}
-static VkResult entry_vkGetBlobGOOGLE(VkDevice device, VkDeviceMemory memory) {
-    AEMU_SCOPED_TRACE("vkGetBlobGOOGLE");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    VkResult vkGetBlobGOOGLE_VkResult_return = (VkResult)0;
-    vkGetBlobGOOGLE_VkResult_return = vkEnc->vkGetBlobGOOGLE(device, memory, true /* do lock */);
-    return vkGetBlobGOOGLE_VkResult_return;
-}
-static VkResult dynCheck_entry_vkGetBlobGOOGLE(VkDevice device, VkDeviceMemory memory) {
-    auto resources = ResourceTracker::get();
-    if (!resources->hasDeviceExtension(device, "VK_GOOGLE_gfxstream")) {
-        sOnInvalidDynamicallyCheckedCall("vkGetBlobGOOGLE", "VK_GOOGLE_gfxstream");
+    VK_FROM_HANDLE(gfxstream_vk_queue, gfxstream_queue, queue);
+    VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer);
+    VK_FROM_HANDLE(gfxstream_vk_device_memory, gfxstream_deviceMemory, deviceMemory);
+    {
+        auto vkEnc =
+            gfxstream::vk::ResourceTracker::getQueueEncoder(gfxstream_queue->internal_object);
+        vkEnc->vkQueueFlushCommandsFromAuxMemoryGOOGLE(
+            gfxstream_queue->internal_object, gfxstream_commandBuffer->internal_object,
+            gfxstream_deviceMemory->internal_object, dataOffset, dataSize, true /* do lock */);
     }
+}
+VkResult gfxstream_vk_GetBlobGOOGLE(VkDevice device, VkDeviceMemory memory) {
     AEMU_SCOPED_TRACE("vkGetBlobGOOGLE");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
     VkResult vkGetBlobGOOGLE_VkResult_return = (VkResult)0;
-    vkGetBlobGOOGLE_VkResult_return = vkEnc->vkGetBlobGOOGLE(device, memory, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    VK_FROM_HANDLE(gfxstream_vk_device_memory, gfxstream_memory, memory);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        vkGetBlobGOOGLE_VkResult_return =
+            vkEnc->vkGetBlobGOOGLE(gfxstream_device->internal_object,
+                                   gfxstream_memory->internal_object, true /* do lock */);
+    }
     return vkGetBlobGOOGLE_VkResult_return;
 }
-static void entry_vkUpdateDescriptorSetWithTemplateSized2GOOGLE(
+void gfxstream_vk_UpdateDescriptorSetWithTemplateSized2GOOGLE(
     VkDevice device, VkDescriptorSet descriptorSet,
     VkDescriptorUpdateTemplate descriptorUpdateTemplate, uint32_t imageInfoCount,
     uint32_t bufferInfoCount, uint32_t bufferViewCount, uint32_t inlineUniformBlockCount,
@@ -4641,3600 +6379,116 @@
     const VkDescriptorBufferInfo* pBufferInfos, const VkBufferView* pBufferViews,
     const uint8_t* pInlineUniformBlockData) {
     AEMU_SCOPED_TRACE("vkUpdateDescriptorSetWithTemplateSized2GOOGLE");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkUpdateDescriptorSetWithTemplateSized2GOOGLE(
-        device, descriptorSet, descriptorUpdateTemplate, imageInfoCount, bufferInfoCount,
-        bufferViewCount, inlineUniformBlockCount, pImageInfoEntryIndices, pBufferInfoEntryIndices,
-        pBufferViewEntryIndices, pImageInfos, pBufferInfos, pBufferViews, pInlineUniformBlockData,
-        true /* do lock */);
-}
-static void dynCheck_entry_vkUpdateDescriptorSetWithTemplateSized2GOOGLE(
-    VkDevice device, VkDescriptorSet descriptorSet,
-    VkDescriptorUpdateTemplate descriptorUpdateTemplate, uint32_t imageInfoCount,
-    uint32_t bufferInfoCount, uint32_t bufferViewCount, uint32_t inlineUniformBlockCount,
-    const uint32_t* pImageInfoEntryIndices, const uint32_t* pBufferInfoEntryIndices,
-    const uint32_t* pBufferViewEntryIndices, const VkDescriptorImageInfo* pImageInfos,
-    const VkDescriptorBufferInfo* pBufferInfos, const VkBufferView* pBufferViews,
-    const uint8_t* pInlineUniformBlockData) {
-    auto resources = ResourceTracker::get();
-    if (!resources->hasDeviceExtension(device, "VK_GOOGLE_gfxstream")) {
-        sOnInvalidDynamicallyCheckedCall("vkUpdateDescriptorSetWithTemplateSized2GOOGLE",
-                                         "VK_GOOGLE_gfxstream");
+    VK_FROM_HANDLE(gfxstream_vk_device, gfxstream_device, device);
+    VK_FROM_HANDLE(gfxstream_vk_descriptor_update_template, gfxstream_descriptorUpdateTemplate,
+                   descriptorUpdateTemplate);
+    {
+        auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder();
+        std::vector<VkDescriptorImageInfo> internal_pImageInfos(imageInfoCount);
+        for (uint32_t i = 0; i < imageInfoCount; ++i) {
+            if (pImageInfos) {
+                internal_pImageInfos[i] = pImageInfos[i];
+                /* VkDescriptorImageInfo::imageView */
+                if (internal_pImageInfos[i].imageView) {
+                    VK_FROM_HANDLE(gfxstream_vk_image_view, gfxstream_imageView,
+                                   internal_pImageInfos[i].imageView);
+                    internal_pImageInfos[i].imageView = gfxstream_imageView->internal_object;
+                }
+            }
+        }
+        std::vector<VkDescriptorBufferInfo> internal_pBufferInfos(bufferInfoCount);
+        for (uint32_t i = 0; i < bufferInfoCount; ++i) {
+            if (pBufferInfos) {
+                internal_pBufferInfos[i] = pBufferInfos[i];
+                /* VkDescriptorBufferInfo::buffer */
+                if (internal_pBufferInfos[i].buffer) {
+                    VK_FROM_HANDLE(gfxstream_vk_buffer, gfxstream_buffer,
+                                   internal_pBufferInfos[i].buffer);
+                    internal_pBufferInfos[i].buffer = gfxstream_buffer->internal_object;
+                }
+            }
+        }
+        std::vector<VkBufferView> internal_pBufferViews(bufferViewCount);
+        for (uint32_t i = 0; i < bufferViewCount; ++i) {
+            if (pBufferViews) {
+                VK_FROM_HANDLE(gfxstream_vk_buffer_view, gfxstream_pBufferViews, pBufferViews[i]);
+                internal_pBufferViews[i] = gfxstream_pBufferViews->internal_object;
+            }
+        }
+        vkEnc->vkUpdateDescriptorSetWithTemplateSized2GOOGLE(
+            gfxstream_device->internal_object, descriptorSet,
+            gfxstream_descriptorUpdateTemplate->internal_object, imageInfoCount, bufferInfoCount,
+            bufferViewCount, inlineUniformBlockCount, pImageInfoEntryIndices,
+            pBufferInfoEntryIndices, pBufferViewEntryIndices, internal_pImageInfos.data(),
+            internal_pBufferInfos.data(), internal_pBufferViews.data(), pInlineUniformBlockData,
+            true /* do lock */);
     }
-    AEMU_SCOPED_TRACE("vkUpdateDescriptorSetWithTemplateSized2GOOGLE");
-    auto vkEnc = ResourceTracker::getThreadLocalEncoder();
-    vkEnc->vkUpdateDescriptorSetWithTemplateSized2GOOGLE(
-        device, descriptorSet, descriptorUpdateTemplate, imageInfoCount, bufferInfoCount,
-        bufferViewCount, inlineUniformBlockCount, pImageInfoEntryIndices, pBufferInfoEntryIndices,
-        pBufferViewEntryIndices, pImageInfos, pBufferInfos, pBufferViews, pInlineUniformBlockData,
-        true /* do lock */);
 }
-static void entry_vkQueueSubmitAsync2GOOGLE(VkQueue queue, uint32_t submitCount,
-                                            const VkSubmitInfo2* pSubmits, VkFence fence) {
+void gfxstream_vk_QueueSubmitAsync2GOOGLE(VkQueue queue, uint32_t submitCount,
+                                          const VkSubmitInfo2* pSubmits, VkFence fence) {
     AEMU_SCOPED_TRACE("vkQueueSubmitAsync2GOOGLE");
-    auto vkEnc = ResourceTracker::getQueueEncoder(queue);
-    vkEnc->vkQueueSubmitAsync2GOOGLE(queue, submitCount, pSubmits, fence, true /* do lock */);
+    VK_FROM_HANDLE(gfxstream_vk_queue, gfxstream_queue, queue);
+    VK_FROM_HANDLE(gfxstream_vk_fence, gfxstream_fence, fence);
+    {
+        auto vkEnc =
+            gfxstream::vk::ResourceTracker::getQueueEncoder(gfxstream_queue->internal_object);
+        std::vector<VkSubmitInfo2> internal_pSubmits(submitCount);
+        std::vector<std::vector<VkSemaphoreSubmitInfo>> internal_VkSubmitInfo2_pWaitSemaphoreInfos;
+        std::vector<std::vector<VkCommandBufferSubmitInfo>>
+            internal_VkSubmitInfo2_pCommandBufferInfos;
+        std::vector<std::vector<VkSemaphoreSubmitInfo>>
+            internal_VkSubmitInfo2_pSignalSemaphoreInfos;
+        for (uint32_t i = 0; i < submitCount; ++i) {
+            internal_pSubmits[i] = pSubmits[i];
+            /* VkSubmitInfo2::pWaitSemaphoreInfos */
+            internal_VkSubmitInfo2_pWaitSemaphoreInfos.push_back(
+                std::vector<VkSemaphoreSubmitInfo>());
+            internal_VkSubmitInfo2_pWaitSemaphoreInfos[i] =
+                transformVkSemaphoreSubmitInfoList(internal_pSubmits[i].pWaitSemaphoreInfos,
+                                                   internal_pSubmits[i].waitSemaphoreInfoCount);
+            internal_pSubmits[i].pWaitSemaphoreInfos =
+                internal_VkSubmitInfo2_pWaitSemaphoreInfos[i].data();
+            internal_pSubmits[i].waitSemaphoreInfoCount =
+                internal_VkSubmitInfo2_pWaitSemaphoreInfos[i].size();
+            /* VkSubmitInfo2::pCommandBufferInfos */
+            internal_VkSubmitInfo2_pCommandBufferInfos.push_back(
+                std::vector<VkCommandBufferSubmitInfo>());
+            internal_VkSubmitInfo2_pCommandBufferInfos[i].reserve(
+                internal_pSubmits[i].commandBufferInfoCount);
+            memset(&internal_VkSubmitInfo2_pCommandBufferInfos[i][0], 0,
+                   sizeof(VkCommandBufferSubmitInfo) * internal_pSubmits[i].commandBufferInfoCount);
+            for (uint32_t j = 0; j < internal_pSubmits[i].commandBufferInfoCount; ++j) {
+                internal_VkSubmitInfo2_pCommandBufferInfos[i][j] =
+                    internal_pSubmits[i].pCommandBufferInfos[j];
+                /* VkCommandBufferSubmitInfo::commandBuffer */
+                VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer,
+                               internal_VkSubmitInfo2_pCommandBufferInfos[i][j].commandBuffer);
+                internal_VkSubmitInfo2_pCommandBufferInfos[i][j].commandBuffer =
+                    gfxstream_commandBuffer->internal_object;
+            }
+            internal_pSubmits[i].pCommandBufferInfos =
+                internal_VkSubmitInfo2_pCommandBufferInfos[i].data();
+            /* VkSubmitInfo2::pSignalSemaphoreInfos */
+            internal_VkSubmitInfo2_pSignalSemaphoreInfos.push_back(
+                std::vector<VkSemaphoreSubmitInfo>());
+            internal_VkSubmitInfo2_pSignalSemaphoreInfos[i] =
+                transformVkSemaphoreSubmitInfoList(internal_pSubmits[i].pSignalSemaphoreInfos,
+                                                   internal_pSubmits[i].signalSemaphoreInfoCount);
+            internal_pSubmits[i].pSignalSemaphoreInfos =
+                internal_VkSubmitInfo2_pSignalSemaphoreInfos[i].data();
+            internal_pSubmits[i].signalSemaphoreInfoCount =
+                internal_VkSubmitInfo2_pSignalSemaphoreInfos[i].size();
+        }
+        vkEnc->vkQueueSubmitAsync2GOOGLE(
+            gfxstream_queue->internal_object, submitCount, internal_pSubmits.data(),
+            gfxstream_fence ? gfxstream_fence->internal_object : VK_NULL_HANDLE,
+            true /* do lock */);
+    }
 }
 #endif
 #ifdef VK_EXT_load_store_op_none
 #endif
 #ifdef VK_EXT_image_compression_control_swapchain
 #endif
-void* goldfish_vulkan_get_proc_address(const char* name) {
-#ifdef VK_VERSION_1_0
-    if (!strcmp(name, "vkCreateInstance")) {
-        return (void*)entry_vkCreateInstance;
-    }
-    if (!strcmp(name, "vkDestroyInstance")) {
-        return (void*)entry_vkDestroyInstance;
-    }
-    if (!strcmp(name, "vkEnumeratePhysicalDevices")) {
-        return (void*)entry_vkEnumeratePhysicalDevices;
-    }
-    if (!strcmp(name, "vkGetPhysicalDeviceFeatures")) {
-        return (void*)entry_vkGetPhysicalDeviceFeatures;
-    }
-    if (!strcmp(name, "vkGetPhysicalDeviceFormatProperties")) {
-        return (void*)entry_vkGetPhysicalDeviceFormatProperties;
-    }
-    if (!strcmp(name, "vkGetPhysicalDeviceImageFormatProperties")) {
-        return (void*)entry_vkGetPhysicalDeviceImageFormatProperties;
-    }
-    if (!strcmp(name, "vkGetPhysicalDeviceProperties")) {
-        return (void*)entry_vkGetPhysicalDeviceProperties;
-    }
-    if (!strcmp(name, "vkGetPhysicalDeviceQueueFamilyProperties")) {
-        return (void*)entry_vkGetPhysicalDeviceQueueFamilyProperties;
-    }
-    if (!strcmp(name, "vkGetPhysicalDeviceMemoryProperties")) {
-        return (void*)entry_vkGetPhysicalDeviceMemoryProperties;
-    }
-    if (!strcmp(name, "vkGetInstanceProcAddr")) {
-        return (void*)entry_vkGetInstanceProcAddr;
-    }
-    if (!strcmp(name, "vkGetDeviceProcAddr")) {
-        return (void*)entry_vkGetDeviceProcAddr;
-    }
-    if (!strcmp(name, "vkCreateDevice")) {
-        return (void*)entry_vkCreateDevice;
-    }
-    if (!strcmp(name, "vkDestroyDevice")) {
-        return (void*)entry_vkDestroyDevice;
-    }
-    if (!strcmp(name, "vkEnumerateInstanceExtensionProperties")) {
-        return (void*)entry_vkEnumerateInstanceExtensionProperties;
-    }
-    if (!strcmp(name, "vkEnumerateDeviceExtensionProperties")) {
-        return (void*)entry_vkEnumerateDeviceExtensionProperties;
-    }
-    if (!strcmp(name, "vkEnumerateInstanceLayerProperties")) {
-        return (void*)entry_vkEnumerateInstanceLayerProperties;
-    }
-    if (!strcmp(name, "vkEnumerateDeviceLayerProperties")) {
-        return (void*)entry_vkEnumerateDeviceLayerProperties;
-    }
-    if (!strcmp(name, "vkGetDeviceQueue")) {
-        return (void*)entry_vkGetDeviceQueue;
-    }
-    if (!strcmp(name, "vkQueueSubmit")) {
-        return (void*)entry_vkQueueSubmit;
-    }
-    if (!strcmp(name, "vkQueueWaitIdle")) {
-        return (void*)entry_vkQueueWaitIdle;
-    }
-    if (!strcmp(name, "vkDeviceWaitIdle")) {
-        return (void*)entry_vkDeviceWaitIdle;
-    }
-    if (!strcmp(name, "vkAllocateMemory")) {
-        return (void*)entry_vkAllocateMemory;
-    }
-    if (!strcmp(name, "vkFreeMemory")) {
-        return (void*)entry_vkFreeMemory;
-    }
-    if (!strcmp(name, "vkMapMemory")) {
-        return (void*)entry_vkMapMemory;
-    }
-    if (!strcmp(name, "vkUnmapMemory")) {
-        return (void*)entry_vkUnmapMemory;
-    }
-    if (!strcmp(name, "vkFlushMappedMemoryRanges")) {
-        return (void*)entry_vkFlushMappedMemoryRanges;
-    }
-    if (!strcmp(name, "vkInvalidateMappedMemoryRanges")) {
-        return (void*)entry_vkInvalidateMappedMemoryRanges;
-    }
-    if (!strcmp(name, "vkGetDeviceMemoryCommitment")) {
-        return (void*)entry_vkGetDeviceMemoryCommitment;
-    }
-    if (!strcmp(name, "vkBindBufferMemory")) {
-        return (void*)entry_vkBindBufferMemory;
-    }
-    if (!strcmp(name, "vkBindImageMemory")) {
-        return (void*)entry_vkBindImageMemory;
-    }
-    if (!strcmp(name, "vkGetBufferMemoryRequirements")) {
-        return (void*)entry_vkGetBufferMemoryRequirements;
-    }
-    if (!strcmp(name, "vkGetImageMemoryRequirements")) {
-        return (void*)entry_vkGetImageMemoryRequirements;
-    }
-    if (!strcmp(name, "vkGetImageSparseMemoryRequirements")) {
-        return (void*)entry_vkGetImageSparseMemoryRequirements;
-    }
-    if (!strcmp(name, "vkGetPhysicalDeviceSparseImageFormatProperties")) {
-        return (void*)entry_vkGetPhysicalDeviceSparseImageFormatProperties;
-    }
-    if (!strcmp(name, "vkQueueBindSparse")) {
-        return (void*)entry_vkQueueBindSparse;
-    }
-    if (!strcmp(name, "vkCreateFence")) {
-        return (void*)entry_vkCreateFence;
-    }
-    if (!strcmp(name, "vkDestroyFence")) {
-        return (void*)entry_vkDestroyFence;
-    }
-    if (!strcmp(name, "vkResetFences")) {
-        return (void*)entry_vkResetFences;
-    }
-    if (!strcmp(name, "vkGetFenceStatus")) {
-        return (void*)entry_vkGetFenceStatus;
-    }
-    if (!strcmp(name, "vkWaitForFences")) {
-        return (void*)entry_vkWaitForFences;
-    }
-    if (!strcmp(name, "vkCreateSemaphore")) {
-        return (void*)entry_vkCreateSemaphore;
-    }
-    if (!strcmp(name, "vkDestroySemaphore")) {
-        return (void*)entry_vkDestroySemaphore;
-    }
-    if (!strcmp(name, "vkCreateEvent")) {
-        return (void*)entry_vkCreateEvent;
-    }
-    if (!strcmp(name, "vkDestroyEvent")) {
-        return (void*)entry_vkDestroyEvent;
-    }
-    if (!strcmp(name, "vkGetEventStatus")) {
-        return (void*)entry_vkGetEventStatus;
-    }
-    if (!strcmp(name, "vkSetEvent")) {
-        return (void*)entry_vkSetEvent;
-    }
-    if (!strcmp(name, "vkResetEvent")) {
-        return (void*)entry_vkResetEvent;
-    }
-    if (!strcmp(name, "vkCreateQueryPool")) {
-        return (void*)entry_vkCreateQueryPool;
-    }
-    if (!strcmp(name, "vkDestroyQueryPool")) {
-        return (void*)entry_vkDestroyQueryPool;
-    }
-    if (!strcmp(name, "vkGetQueryPoolResults")) {
-        return (void*)entry_vkGetQueryPoolResults;
-    }
-    if (!strcmp(name, "vkCreateBuffer")) {
-        return (void*)entry_vkCreateBuffer;
-    }
-    if (!strcmp(name, "vkDestroyBuffer")) {
-        return (void*)entry_vkDestroyBuffer;
-    }
-    if (!strcmp(name, "vkCreateBufferView")) {
-        return (void*)entry_vkCreateBufferView;
-    }
-    if (!strcmp(name, "vkDestroyBufferView")) {
-        return (void*)entry_vkDestroyBufferView;
-    }
-    if (!strcmp(name, "vkCreateImage")) {
-        return (void*)entry_vkCreateImage;
-    }
-    if (!strcmp(name, "vkDestroyImage")) {
-        return (void*)entry_vkDestroyImage;
-    }
-    if (!strcmp(name, "vkGetImageSubresourceLayout")) {
-        return (void*)entry_vkGetImageSubresourceLayout;
-    }
-    if (!strcmp(name, "vkCreateImageView")) {
-        return (void*)entry_vkCreateImageView;
-    }
-    if (!strcmp(name, "vkDestroyImageView")) {
-        return (void*)entry_vkDestroyImageView;
-    }
-    if (!strcmp(name, "vkCreateShaderModule")) {
-        return (void*)entry_vkCreateShaderModule;
-    }
-    if (!strcmp(name, "vkDestroyShaderModule")) {
-        return (void*)entry_vkDestroyShaderModule;
-    }
-    if (!strcmp(name, "vkCreatePipelineCache")) {
-        return (void*)entry_vkCreatePipelineCache;
-    }
-    if (!strcmp(name, "vkDestroyPipelineCache")) {
-        return (void*)entry_vkDestroyPipelineCache;
-    }
-    if (!strcmp(name, "vkGetPipelineCacheData")) {
-        return (void*)entry_vkGetPipelineCacheData;
-    }
-    if (!strcmp(name, "vkMergePipelineCaches")) {
-        return (void*)entry_vkMergePipelineCaches;
-    }
-    if (!strcmp(name, "vkCreateGraphicsPipelines")) {
-        return (void*)entry_vkCreateGraphicsPipelines;
-    }
-    if (!strcmp(name, "vkCreateComputePipelines")) {
-        return (void*)entry_vkCreateComputePipelines;
-    }
-    if (!strcmp(name, "vkDestroyPipeline")) {
-        return (void*)entry_vkDestroyPipeline;
-    }
-    if (!strcmp(name, "vkCreatePipelineLayout")) {
-        return (void*)entry_vkCreatePipelineLayout;
-    }
-    if (!strcmp(name, "vkDestroyPipelineLayout")) {
-        return (void*)entry_vkDestroyPipelineLayout;
-    }
-    if (!strcmp(name, "vkCreateSampler")) {
-        return (void*)entry_vkCreateSampler;
-    }
-    if (!strcmp(name, "vkDestroySampler")) {
-        return (void*)entry_vkDestroySampler;
-    }
-    if (!strcmp(name, "vkCreateDescriptorSetLayout")) {
-        return (void*)entry_vkCreateDescriptorSetLayout;
-    }
-    if (!strcmp(name, "vkDestroyDescriptorSetLayout")) {
-        return (void*)entry_vkDestroyDescriptorSetLayout;
-    }
-    if (!strcmp(name, "vkCreateDescriptorPool")) {
-        return (void*)entry_vkCreateDescriptorPool;
-    }
-    if (!strcmp(name, "vkDestroyDescriptorPool")) {
-        return (void*)entry_vkDestroyDescriptorPool;
-    }
-    if (!strcmp(name, "vkResetDescriptorPool")) {
-        return (void*)entry_vkResetDescriptorPool;
-    }
-    if (!strcmp(name, "vkAllocateDescriptorSets")) {
-        return (void*)entry_vkAllocateDescriptorSets;
-    }
-    if (!strcmp(name, "vkFreeDescriptorSets")) {
-        return (void*)entry_vkFreeDescriptorSets;
-    }
-    if (!strcmp(name, "vkUpdateDescriptorSets")) {
-        return (void*)entry_vkUpdateDescriptorSets;
-    }
-    if (!strcmp(name, "vkCreateFramebuffer")) {
-        return (void*)entry_vkCreateFramebuffer;
-    }
-    if (!strcmp(name, "vkDestroyFramebuffer")) {
-        return (void*)entry_vkDestroyFramebuffer;
-    }
-    if (!strcmp(name, "vkCreateRenderPass")) {
-        return (void*)entry_vkCreateRenderPass;
-    }
-    if (!strcmp(name, "vkDestroyRenderPass")) {
-        return (void*)entry_vkDestroyRenderPass;
-    }
-    if (!strcmp(name, "vkGetRenderAreaGranularity")) {
-        return (void*)entry_vkGetRenderAreaGranularity;
-    }
-    if (!strcmp(name, "vkCreateCommandPool")) {
-        return (void*)entry_vkCreateCommandPool;
-    }
-    if (!strcmp(name, "vkDestroyCommandPool")) {
-        return (void*)entry_vkDestroyCommandPool;
-    }
-    if (!strcmp(name, "vkResetCommandPool")) {
-        return (void*)entry_vkResetCommandPool;
-    }
-    if (!strcmp(name, "vkAllocateCommandBuffers")) {
-        return (void*)entry_vkAllocateCommandBuffers;
-    }
-    if (!strcmp(name, "vkFreeCommandBuffers")) {
-        return (void*)entry_vkFreeCommandBuffers;
-    }
-    if (!strcmp(name, "vkBeginCommandBuffer")) {
-        return (void*)entry_vkBeginCommandBuffer;
-    }
-    if (!strcmp(name, "vkEndCommandBuffer")) {
-        return (void*)entry_vkEndCommandBuffer;
-    }
-    if (!strcmp(name, "vkResetCommandBuffer")) {
-        return (void*)entry_vkResetCommandBuffer;
-    }
-    if (!strcmp(name, "vkCmdBindPipeline")) {
-        return (void*)entry_vkCmdBindPipeline;
-    }
-    if (!strcmp(name, "vkCmdSetViewport")) {
-        return (void*)entry_vkCmdSetViewport;
-    }
-    if (!strcmp(name, "vkCmdSetScissor")) {
-        return (void*)entry_vkCmdSetScissor;
-    }
-    if (!strcmp(name, "vkCmdSetLineWidth")) {
-        return (void*)entry_vkCmdSetLineWidth;
-    }
-    if (!strcmp(name, "vkCmdSetDepthBias")) {
-        return (void*)entry_vkCmdSetDepthBias;
-    }
-    if (!strcmp(name, "vkCmdSetBlendConstants")) {
-        return (void*)entry_vkCmdSetBlendConstants;
-    }
-    if (!strcmp(name, "vkCmdSetDepthBounds")) {
-        return (void*)entry_vkCmdSetDepthBounds;
-    }
-    if (!strcmp(name, "vkCmdSetStencilCompareMask")) {
-        return (void*)entry_vkCmdSetStencilCompareMask;
-    }
-    if (!strcmp(name, "vkCmdSetStencilWriteMask")) {
-        return (void*)entry_vkCmdSetStencilWriteMask;
-    }
-    if (!strcmp(name, "vkCmdSetStencilReference")) {
-        return (void*)entry_vkCmdSetStencilReference;
-    }
-    if (!strcmp(name, "vkCmdBindDescriptorSets")) {
-        return (void*)entry_vkCmdBindDescriptorSets;
-    }
-    if (!strcmp(name, "vkCmdBindIndexBuffer")) {
-        return (void*)entry_vkCmdBindIndexBuffer;
-    }
-    if (!strcmp(name, "vkCmdBindVertexBuffers")) {
-        return (void*)entry_vkCmdBindVertexBuffers;
-    }
-    if (!strcmp(name, "vkCmdDraw")) {
-        return (void*)entry_vkCmdDraw;
-    }
-    if (!strcmp(name, "vkCmdDrawIndexed")) {
-        return (void*)entry_vkCmdDrawIndexed;
-    }
-    if (!strcmp(name, "vkCmdDrawIndirect")) {
-        return (void*)entry_vkCmdDrawIndirect;
-    }
-    if (!strcmp(name, "vkCmdDrawIndexedIndirect")) {
-        return (void*)entry_vkCmdDrawIndexedIndirect;
-    }
-    if (!strcmp(name, "vkCmdDispatch")) {
-        return (void*)entry_vkCmdDispatch;
-    }
-    if (!strcmp(name, "vkCmdDispatchIndirect")) {
-        return (void*)entry_vkCmdDispatchIndirect;
-    }
-    if (!strcmp(name, "vkCmdCopyBuffer")) {
-        return (void*)entry_vkCmdCopyBuffer;
-    }
-    if (!strcmp(name, "vkCmdCopyImage")) {
-        return (void*)entry_vkCmdCopyImage;
-    }
-    if (!strcmp(name, "vkCmdBlitImage")) {
-        return (void*)entry_vkCmdBlitImage;
-    }
-    if (!strcmp(name, "vkCmdCopyBufferToImage")) {
-        return (void*)entry_vkCmdCopyBufferToImage;
-    }
-    if (!strcmp(name, "vkCmdCopyImageToBuffer")) {
-        return (void*)entry_vkCmdCopyImageToBuffer;
-    }
-    if (!strcmp(name, "vkCmdUpdateBuffer")) {
-        return (void*)entry_vkCmdUpdateBuffer;
-    }
-    if (!strcmp(name, "vkCmdFillBuffer")) {
-        return (void*)entry_vkCmdFillBuffer;
-    }
-    if (!strcmp(name, "vkCmdClearColorImage")) {
-        return (void*)entry_vkCmdClearColorImage;
-    }
-    if (!strcmp(name, "vkCmdClearDepthStencilImage")) {
-        return (void*)entry_vkCmdClearDepthStencilImage;
-    }
-    if (!strcmp(name, "vkCmdClearAttachments")) {
-        return (void*)entry_vkCmdClearAttachments;
-    }
-    if (!strcmp(name, "vkCmdResolveImage")) {
-        return (void*)entry_vkCmdResolveImage;
-    }
-    if (!strcmp(name, "vkCmdSetEvent")) {
-        return (void*)entry_vkCmdSetEvent;
-    }
-    if (!strcmp(name, "vkCmdResetEvent")) {
-        return (void*)entry_vkCmdResetEvent;
-    }
-    if (!strcmp(name, "vkCmdWaitEvents")) {
-        return (void*)entry_vkCmdWaitEvents;
-    }
-    if (!strcmp(name, "vkCmdPipelineBarrier")) {
-        return (void*)entry_vkCmdPipelineBarrier;
-    }
-    if (!strcmp(name, "vkCmdBeginQuery")) {
-        return (void*)entry_vkCmdBeginQuery;
-    }
-    if (!strcmp(name, "vkCmdEndQuery")) {
-        return (void*)entry_vkCmdEndQuery;
-    }
-    if (!strcmp(name, "vkCmdResetQueryPool")) {
-        return (void*)entry_vkCmdResetQueryPool;
-    }
-    if (!strcmp(name, "vkCmdWriteTimestamp")) {
-        return (void*)entry_vkCmdWriteTimestamp;
-    }
-    if (!strcmp(name, "vkCmdCopyQueryPoolResults")) {
-        return (void*)entry_vkCmdCopyQueryPoolResults;
-    }
-    if (!strcmp(name, "vkCmdPushConstants")) {
-        return (void*)entry_vkCmdPushConstants;
-    }
-    if (!strcmp(name, "vkCmdBeginRenderPass")) {
-        return (void*)entry_vkCmdBeginRenderPass;
-    }
-    if (!strcmp(name, "vkCmdNextSubpass")) {
-        return (void*)entry_vkCmdNextSubpass;
-    }
-    if (!strcmp(name, "vkCmdEndRenderPass")) {
-        return (void*)entry_vkCmdEndRenderPass;
-    }
-    if (!strcmp(name, "vkCmdExecuteCommands")) {
-        return (void*)entry_vkCmdExecuteCommands;
-    }
-#endif
-#ifdef VK_VERSION_1_1
-    if (!strcmp(name, "vkEnumerateInstanceVersion")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkBindBufferMemory2")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkBindImageMemory2")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkGetDeviceGroupPeerMemoryFeatures")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkCmdSetDeviceMask")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkCmdDispatchBase")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkEnumeratePhysicalDeviceGroups")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkGetImageMemoryRequirements2")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkGetBufferMemoryRequirements2")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkGetImageSparseMemoryRequirements2")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkGetPhysicalDeviceFeatures2")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkGetPhysicalDeviceProperties2")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkGetPhysicalDeviceFormatProperties2")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkGetPhysicalDeviceImageFormatProperties2")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkGetPhysicalDeviceQueueFamilyProperties2")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkGetPhysicalDeviceMemoryProperties2")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkGetPhysicalDeviceSparseImageFormatProperties2")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkTrimCommandPool")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkGetDeviceQueue2")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkCreateSamplerYcbcrConversion")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkDestroySamplerYcbcrConversion")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkCreateDescriptorUpdateTemplate")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkDestroyDescriptorUpdateTemplate")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkUpdateDescriptorSetWithTemplate")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkGetPhysicalDeviceExternalBufferProperties")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkGetPhysicalDeviceExternalFenceProperties")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkGetPhysicalDeviceExternalSemaphoreProperties")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkGetDescriptorSetLayoutSupport")) {
-        return nullptr;
-    }
-#endif
-#ifdef VK_VERSION_1_2
-    if (!strcmp(name, "vkCmdDrawIndirectCount")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkCmdDrawIndexedIndirectCount")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkCreateRenderPass2")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkCmdBeginRenderPass2")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkCmdNextSubpass2")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkCmdEndRenderPass2")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkResetQueryPool")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkGetSemaphoreCounterValue")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkWaitSemaphores")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkSignalSemaphore")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkGetBufferDeviceAddress")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkGetBufferOpaqueCaptureAddress")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkGetDeviceMemoryOpaqueCaptureAddress")) {
-        return nullptr;
-    }
-#endif
-#ifdef VK_VERSION_1_3
-    if (!strcmp(name, "vkGetPhysicalDeviceToolProperties")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkCreatePrivateDataSlot")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkDestroyPrivateDataSlot")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkSetPrivateData")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkGetPrivateData")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkCmdSetEvent2")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkCmdResetEvent2")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkCmdWaitEvents2")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkCmdPipelineBarrier2")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkCmdWriteTimestamp2")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkQueueSubmit2")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkCmdCopyBuffer2")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkCmdCopyImage2")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkCmdCopyBufferToImage2")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkCmdCopyImageToBuffer2")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkCmdBlitImage2")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkCmdResolveImage2")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkCmdBeginRendering")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkCmdEndRendering")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkCmdSetCullMode")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkCmdSetFrontFace")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkCmdSetPrimitiveTopology")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkCmdSetViewportWithCount")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkCmdSetScissorWithCount")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkCmdBindVertexBuffers2")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkCmdSetDepthTestEnable")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkCmdSetDepthWriteEnable")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkCmdSetDepthCompareOp")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkCmdSetDepthBoundsTestEnable")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkCmdSetStencilTestEnable")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkCmdSetStencilOp")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkCmdSetRasterizerDiscardEnable")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkCmdSetDepthBiasEnable")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkCmdSetPrimitiveRestartEnable")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkGetDeviceBufferMemoryRequirements")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkGetDeviceImageMemoryRequirements")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkGetDeviceImageSparseMemoryRequirements")) {
-        return nullptr;
-    }
-#endif
-#ifdef VK_KHR_android_surface
-    if (!strcmp(name, "vkCreateAndroidSurfaceKHR")) {
-        return nullptr;
-    }
-#endif
-#ifdef VK_KHR_dynamic_rendering
-    if (!strcmp(name, "vkCmdBeginRenderingKHR")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkCmdEndRenderingKHR")) {
-        return nullptr;
-    }
-#endif
-#ifdef VK_KHR_get_physical_device_properties2
-    if (!strcmp(name, "vkGetPhysicalDeviceFeatures2KHR")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkGetPhysicalDeviceProperties2KHR")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkGetPhysicalDeviceFormatProperties2KHR")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkGetPhysicalDeviceImageFormatProperties2KHR")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkGetPhysicalDeviceQueueFamilyProperties2KHR")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkGetPhysicalDeviceMemoryProperties2KHR")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkGetPhysicalDeviceSparseImageFormatProperties2KHR")) {
-        return nullptr;
-    }
-#endif
-#ifdef VK_KHR_maintenance1
-    if (!strcmp(name, "vkTrimCommandPoolKHR")) {
-        return nullptr;
-    }
-#endif
-#ifdef VK_KHR_external_memory_capabilities
-    if (!strcmp(name, "vkGetPhysicalDeviceExternalBufferPropertiesKHR")) {
-        return nullptr;
-    }
-#endif
-#ifdef VK_KHR_external_semaphore_capabilities
-    if (!strcmp(name, "vkGetPhysicalDeviceExternalSemaphorePropertiesKHR")) {
-        return nullptr;
-    }
-#endif
-#ifdef VK_KHR_external_semaphore_fd
-    if (!strcmp(name, "vkImportSemaphoreFdKHR")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkGetSemaphoreFdKHR")) {
-        return nullptr;
-    }
-#endif
-#ifdef VK_KHR_descriptor_update_template
-    if (!strcmp(name, "vkCreateDescriptorUpdateTemplateKHR")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkDestroyDescriptorUpdateTemplateKHR")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkUpdateDescriptorSetWithTemplateKHR")) {
-        return nullptr;
-    }
-#endif
-#ifdef VK_KHR_create_renderpass2
-    if (!strcmp(name, "vkCreateRenderPass2KHR")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkCmdBeginRenderPass2KHR")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkCmdNextSubpass2KHR")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkCmdEndRenderPass2KHR")) {
-        return nullptr;
-    }
-#endif
-#ifdef VK_KHR_external_fence_capabilities
-    if (!strcmp(name, "vkGetPhysicalDeviceExternalFencePropertiesKHR")) {
-        return nullptr;
-    }
-#endif
-#ifdef VK_KHR_external_fence_fd
-    if (!strcmp(name, "vkImportFenceFdKHR")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkGetFenceFdKHR")) {
-        return nullptr;
-    }
-#endif
-#ifdef VK_KHR_get_memory_requirements2
-    if (!strcmp(name, "vkGetImageMemoryRequirements2KHR")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkGetBufferMemoryRequirements2KHR")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkGetImageSparseMemoryRequirements2KHR")) {
-        return nullptr;
-    }
-#endif
-#ifdef VK_KHR_sampler_ycbcr_conversion
-    if (!strcmp(name, "vkCreateSamplerYcbcrConversionKHR")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkDestroySamplerYcbcrConversionKHR")) {
-        return nullptr;
-    }
-#endif
-#ifdef VK_KHR_bind_memory2
-    if (!strcmp(name, "vkBindBufferMemory2KHR")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkBindImageMemory2KHR")) {
-        return nullptr;
-    }
-#endif
-#ifdef VK_KHR_maintenance3
-    if (!strcmp(name, "vkGetDescriptorSetLayoutSupportKHR")) {
-        return nullptr;
-    }
-#endif
-#ifdef VK_KHR_buffer_device_address
-    if (!strcmp(name, "vkGetBufferDeviceAddressKHR")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkGetBufferOpaqueCaptureAddressKHR")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkGetDeviceMemoryOpaqueCaptureAddressKHR")) {
-        return nullptr;
-    }
-#endif
-#ifdef VK_KHR_pipeline_executable_properties
-    if (!strcmp(name, "vkGetPipelineExecutablePropertiesKHR")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkGetPipelineExecutableStatisticsKHR")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkGetPipelineExecutableInternalRepresentationsKHR")) {
-        return nullptr;
-    }
-#endif
-#ifdef VK_KHR_synchronization2
-    if (!strcmp(name, "vkCmdSetEvent2KHR")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkCmdResetEvent2KHR")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkCmdWaitEvents2KHR")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkCmdPipelineBarrier2KHR")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkCmdWriteTimestamp2KHR")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkQueueSubmit2KHR")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkCmdWriteBufferMarker2AMD")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkGetQueueCheckpointData2NV")) {
-        return nullptr;
-    }
-#endif
-#ifdef VK_KHR_copy_commands2
-    if (!strcmp(name, "vkCmdCopyBuffer2KHR")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkCmdCopyImage2KHR")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkCmdCopyBufferToImage2KHR")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkCmdCopyImageToBuffer2KHR")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkCmdBlitImage2KHR")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkCmdResolveImage2KHR")) {
-        return nullptr;
-    }
-#endif
-#ifdef VK_KHR_maintenance4
-    if (!strcmp(name, "vkGetDeviceBufferMemoryRequirementsKHR")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkGetDeviceImageMemoryRequirementsKHR")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkGetDeviceImageSparseMemoryRequirementsKHR")) {
-        return nullptr;
-    }
-#endif
-#ifdef VK_KHR_maintenance5
-    if (!strcmp(name, "vkCmdBindIndexBuffer2KHR")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkGetRenderingAreaGranularityKHR")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkGetDeviceImageSubresourceLayoutKHR")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkGetImageSubresourceLayout2KHR")) {
-        return nullptr;
-    }
-#endif
-#ifdef VK_ANDROID_native_buffer
-    if (!strcmp(name, "vkGetSwapchainGrallocUsageANDROID")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkAcquireImageANDROID")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkQueueSignalReleaseImageANDROID")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkGetSwapchainGrallocUsage2ANDROID")) {
-        return nullptr;
-    }
-#endif
-#ifdef VK_EXT_transform_feedback
-    if (!strcmp(name, "vkCmdBindTransformFeedbackBuffersEXT")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkCmdBeginTransformFeedbackEXT")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkCmdEndTransformFeedbackEXT")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkCmdBeginQueryIndexedEXT")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkCmdEndQueryIndexedEXT")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkCmdDrawIndirectByteCountEXT")) {
-        return nullptr;
-    }
-#endif
-#ifdef VK_ANDROID_external_memory_android_hardware_buffer
-    if (!strcmp(name, "vkGetAndroidHardwareBufferPropertiesANDROID")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkGetMemoryAndroidHardwareBufferANDROID")) {
-        return nullptr;
-    }
-#endif
-#ifdef VK_EXT_tooling_info
-    if (!strcmp(name, "vkGetPhysicalDeviceToolPropertiesEXT")) {
-        return nullptr;
-    }
-#endif
-#ifdef VK_EXT_line_rasterization
-    if (!strcmp(name, "vkCmdSetLineStippleEXT")) {
-        return nullptr;
-    }
-#endif
-#ifdef VK_EXT_extended_dynamic_state
-    if (!strcmp(name, "vkCmdSetCullModeEXT")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkCmdSetFrontFaceEXT")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkCmdSetPrimitiveTopologyEXT")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkCmdSetViewportWithCountEXT")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkCmdSetScissorWithCountEXT")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkCmdBindVertexBuffers2EXT")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkCmdSetDepthTestEnableEXT")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkCmdSetDepthWriteEnableEXT")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkCmdSetDepthCompareOpEXT")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkCmdSetDepthBoundsTestEnableEXT")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkCmdSetStencilTestEnableEXT")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkCmdSetStencilOpEXT")) {
-        return nullptr;
-    }
-#endif
-#ifdef VK_EXT_host_image_copy
-    if (!strcmp(name, "vkCopyMemoryToImageEXT")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkCopyImageToMemoryEXT")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkCopyImageToImageEXT")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkTransitionImageLayoutEXT")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkGetImageSubresourceLayout2EXT")) {
-        return nullptr;
-    }
-#endif
-#ifdef VK_EXT_private_data
-    if (!strcmp(name, "vkCreatePrivateDataSlotEXT")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkDestroyPrivateDataSlotEXT")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkSetPrivateDataEXT")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkGetPrivateDataEXT")) {
-        return nullptr;
-    }
-#endif
-#ifdef VK_EXT_extended_dynamic_state2
-    if (!strcmp(name, "vkCmdSetPatchControlPointsEXT")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkCmdSetRasterizerDiscardEnableEXT")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkCmdSetDepthBiasEnableEXT")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkCmdSetLogicOpEXT")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkCmdSetPrimitiveRestartEnableEXT")) {
-        return nullptr;
-    }
-#endif
-#ifdef VK_GOOGLE_gfxstream
-    if (!strcmp(name, "vkMapMemoryIntoAddressSpaceGOOGLE")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkUpdateDescriptorSetWithTemplateSizedGOOGLE")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkBeginCommandBufferAsyncGOOGLE")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkEndCommandBufferAsyncGOOGLE")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkResetCommandBufferAsyncGOOGLE")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkCommandBufferHostSyncGOOGLE")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkCreateImageWithRequirementsGOOGLE")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkCreateBufferWithRequirementsGOOGLE")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkGetMemoryHostAddressInfoGOOGLE")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkFreeMemorySyncGOOGLE")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkQueueHostSyncGOOGLE")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkQueueSubmitAsyncGOOGLE")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkQueueWaitIdleAsyncGOOGLE")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkQueueBindSparseAsyncGOOGLE")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkGetLinearImageLayoutGOOGLE")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkGetLinearImageLayout2GOOGLE")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkQueueFlushCommandsGOOGLE")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkQueueCommitDescriptorSetUpdatesGOOGLE")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkCollectDescriptorPoolIdsGOOGLE")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkQueueSignalReleaseImageANDROIDAsyncGOOGLE")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkQueueFlushCommandsFromAuxMemoryGOOGLE")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkGetBlobGOOGLE")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkUpdateDescriptorSetWithTemplateSized2GOOGLE")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkQueueSubmitAsync2GOOGLE")) {
-        return nullptr;
-    }
-#endif
-    return nullptr;
-}
-void* goldfish_vulkan_get_instance_proc_address(VkInstance instance, const char* name) {
-    auto resources = ResourceTracker::get();
-    bool has1_1OrHigher = resources->getApiVersionFromInstance(instance) >= VK_API_VERSION_1_1;
-    bool has1_2OrHigher = resources->getApiVersionFromInstance(instance) >= VK_API_VERSION_1_2;
-    bool has1_3OrHigher = resources->getApiVersionFromInstance(instance) >= VK_API_VERSION_1_3;
-#ifdef VK_VERSION_1_0
-    if (!strcmp(name, "vkCreateInstance")) {
-        return (void*)entry_vkCreateInstance;
-    }
-    if (!strcmp(name, "vkDestroyInstance")) {
-        return (void*)entry_vkDestroyInstance;
-    }
-    if (!strcmp(name, "vkEnumeratePhysicalDevices")) {
-        return (void*)entry_vkEnumeratePhysicalDevices;
-    }
-    if (!strcmp(name, "vkGetPhysicalDeviceFeatures")) {
-        return (void*)entry_vkGetPhysicalDeviceFeatures;
-    }
-    if (!strcmp(name, "vkGetPhysicalDeviceFormatProperties")) {
-        return (void*)entry_vkGetPhysicalDeviceFormatProperties;
-    }
-    if (!strcmp(name, "vkGetPhysicalDeviceImageFormatProperties")) {
-        return (void*)entry_vkGetPhysicalDeviceImageFormatProperties;
-    }
-    if (!strcmp(name, "vkGetPhysicalDeviceProperties")) {
-        return (void*)entry_vkGetPhysicalDeviceProperties;
-    }
-    if (!strcmp(name, "vkGetPhysicalDeviceQueueFamilyProperties")) {
-        return (void*)entry_vkGetPhysicalDeviceQueueFamilyProperties;
-    }
-    if (!strcmp(name, "vkGetPhysicalDeviceMemoryProperties")) {
-        return (void*)entry_vkGetPhysicalDeviceMemoryProperties;
-    }
-    if (!strcmp(name, "vkGetInstanceProcAddr")) {
-        return (void*)entry_vkGetInstanceProcAddr;
-    }
-    if (!strcmp(name, "vkGetDeviceProcAddr")) {
-        return (void*)entry_vkGetDeviceProcAddr;
-    }
-    if (!strcmp(name, "vkCreateDevice")) {
-        return (void*)entry_vkCreateDevice;
-    }
-    if (!strcmp(name, "vkDestroyDevice")) {
-        return (void*)entry_vkDestroyDevice;
-    }
-    if (!strcmp(name, "vkEnumerateInstanceExtensionProperties")) {
-        return (void*)entry_vkEnumerateInstanceExtensionProperties;
-    }
-    if (!strcmp(name, "vkEnumerateDeviceExtensionProperties")) {
-        return (void*)entry_vkEnumerateDeviceExtensionProperties;
-    }
-    if (!strcmp(name, "vkEnumerateInstanceLayerProperties")) {
-        return (void*)entry_vkEnumerateInstanceLayerProperties;
-    }
-    if (!strcmp(name, "vkEnumerateDeviceLayerProperties")) {
-        return (void*)entry_vkEnumerateDeviceLayerProperties;
-    }
-    if (!strcmp(name, "vkGetDeviceQueue")) {
-        return (void*)entry_vkGetDeviceQueue;
-    }
-    if (!strcmp(name, "vkQueueSubmit")) {
-        return (void*)entry_vkQueueSubmit;
-    }
-    if (!strcmp(name, "vkQueueWaitIdle")) {
-        return (void*)entry_vkQueueWaitIdle;
-    }
-    if (!strcmp(name, "vkDeviceWaitIdle")) {
-        return (void*)entry_vkDeviceWaitIdle;
-    }
-    if (!strcmp(name, "vkAllocateMemory")) {
-        return (void*)entry_vkAllocateMemory;
-    }
-    if (!strcmp(name, "vkFreeMemory")) {
-        return (void*)entry_vkFreeMemory;
-    }
-    if (!strcmp(name, "vkMapMemory")) {
-        return (void*)entry_vkMapMemory;
-    }
-    if (!strcmp(name, "vkUnmapMemory")) {
-        return (void*)entry_vkUnmapMemory;
-    }
-    if (!strcmp(name, "vkFlushMappedMemoryRanges")) {
-        return (void*)entry_vkFlushMappedMemoryRanges;
-    }
-    if (!strcmp(name, "vkInvalidateMappedMemoryRanges")) {
-        return (void*)entry_vkInvalidateMappedMemoryRanges;
-    }
-    if (!strcmp(name, "vkGetDeviceMemoryCommitment")) {
-        return (void*)entry_vkGetDeviceMemoryCommitment;
-    }
-    if (!strcmp(name, "vkBindBufferMemory")) {
-        return (void*)entry_vkBindBufferMemory;
-    }
-    if (!strcmp(name, "vkBindImageMemory")) {
-        return (void*)entry_vkBindImageMemory;
-    }
-    if (!strcmp(name, "vkGetBufferMemoryRequirements")) {
-        return (void*)entry_vkGetBufferMemoryRequirements;
-    }
-    if (!strcmp(name, "vkGetImageMemoryRequirements")) {
-        return (void*)entry_vkGetImageMemoryRequirements;
-    }
-    if (!strcmp(name, "vkGetImageSparseMemoryRequirements")) {
-        return (void*)entry_vkGetImageSparseMemoryRequirements;
-    }
-    if (!strcmp(name, "vkGetPhysicalDeviceSparseImageFormatProperties")) {
-        return (void*)entry_vkGetPhysicalDeviceSparseImageFormatProperties;
-    }
-    if (!strcmp(name, "vkQueueBindSparse")) {
-        return (void*)entry_vkQueueBindSparse;
-    }
-    if (!strcmp(name, "vkCreateFence")) {
-        return (void*)entry_vkCreateFence;
-    }
-    if (!strcmp(name, "vkDestroyFence")) {
-        return (void*)entry_vkDestroyFence;
-    }
-    if (!strcmp(name, "vkResetFences")) {
-        return (void*)entry_vkResetFences;
-    }
-    if (!strcmp(name, "vkGetFenceStatus")) {
-        return (void*)entry_vkGetFenceStatus;
-    }
-    if (!strcmp(name, "vkWaitForFences")) {
-        return (void*)entry_vkWaitForFences;
-    }
-    if (!strcmp(name, "vkCreateSemaphore")) {
-        return (void*)entry_vkCreateSemaphore;
-    }
-    if (!strcmp(name, "vkDestroySemaphore")) {
-        return (void*)entry_vkDestroySemaphore;
-    }
-    if (!strcmp(name, "vkCreateEvent")) {
-        return (void*)entry_vkCreateEvent;
-    }
-    if (!strcmp(name, "vkDestroyEvent")) {
-        return (void*)entry_vkDestroyEvent;
-    }
-    if (!strcmp(name, "vkGetEventStatus")) {
-        return (void*)entry_vkGetEventStatus;
-    }
-    if (!strcmp(name, "vkSetEvent")) {
-        return (void*)entry_vkSetEvent;
-    }
-    if (!strcmp(name, "vkResetEvent")) {
-        return (void*)entry_vkResetEvent;
-    }
-    if (!strcmp(name, "vkCreateQueryPool")) {
-        return (void*)entry_vkCreateQueryPool;
-    }
-    if (!strcmp(name, "vkDestroyQueryPool")) {
-        return (void*)entry_vkDestroyQueryPool;
-    }
-    if (!strcmp(name, "vkGetQueryPoolResults")) {
-        return (void*)entry_vkGetQueryPoolResults;
-    }
-    if (!strcmp(name, "vkCreateBuffer")) {
-        return (void*)entry_vkCreateBuffer;
-    }
-    if (!strcmp(name, "vkDestroyBuffer")) {
-        return (void*)entry_vkDestroyBuffer;
-    }
-    if (!strcmp(name, "vkCreateBufferView")) {
-        return (void*)entry_vkCreateBufferView;
-    }
-    if (!strcmp(name, "vkDestroyBufferView")) {
-        return (void*)entry_vkDestroyBufferView;
-    }
-    if (!strcmp(name, "vkCreateImage")) {
-        return (void*)entry_vkCreateImage;
-    }
-    if (!strcmp(name, "vkDestroyImage")) {
-        return (void*)entry_vkDestroyImage;
-    }
-    if (!strcmp(name, "vkGetImageSubresourceLayout")) {
-        return (void*)entry_vkGetImageSubresourceLayout;
-    }
-    if (!strcmp(name, "vkCreateImageView")) {
-        return (void*)entry_vkCreateImageView;
-    }
-    if (!strcmp(name, "vkDestroyImageView")) {
-        return (void*)entry_vkDestroyImageView;
-    }
-    if (!strcmp(name, "vkCreateShaderModule")) {
-        return (void*)entry_vkCreateShaderModule;
-    }
-    if (!strcmp(name, "vkDestroyShaderModule")) {
-        return (void*)entry_vkDestroyShaderModule;
-    }
-    if (!strcmp(name, "vkCreatePipelineCache")) {
-        return (void*)entry_vkCreatePipelineCache;
-    }
-    if (!strcmp(name, "vkDestroyPipelineCache")) {
-        return (void*)entry_vkDestroyPipelineCache;
-    }
-    if (!strcmp(name, "vkGetPipelineCacheData")) {
-        return (void*)entry_vkGetPipelineCacheData;
-    }
-    if (!strcmp(name, "vkMergePipelineCaches")) {
-        return (void*)entry_vkMergePipelineCaches;
-    }
-    if (!strcmp(name, "vkCreateGraphicsPipelines")) {
-        return (void*)entry_vkCreateGraphicsPipelines;
-    }
-    if (!strcmp(name, "vkCreateComputePipelines")) {
-        return (void*)entry_vkCreateComputePipelines;
-    }
-    if (!strcmp(name, "vkDestroyPipeline")) {
-        return (void*)entry_vkDestroyPipeline;
-    }
-    if (!strcmp(name, "vkCreatePipelineLayout")) {
-        return (void*)entry_vkCreatePipelineLayout;
-    }
-    if (!strcmp(name, "vkDestroyPipelineLayout")) {
-        return (void*)entry_vkDestroyPipelineLayout;
-    }
-    if (!strcmp(name, "vkCreateSampler")) {
-        return (void*)entry_vkCreateSampler;
-    }
-    if (!strcmp(name, "vkDestroySampler")) {
-        return (void*)entry_vkDestroySampler;
-    }
-    if (!strcmp(name, "vkCreateDescriptorSetLayout")) {
-        return (void*)entry_vkCreateDescriptorSetLayout;
-    }
-    if (!strcmp(name, "vkDestroyDescriptorSetLayout")) {
-        return (void*)entry_vkDestroyDescriptorSetLayout;
-    }
-    if (!strcmp(name, "vkCreateDescriptorPool")) {
-        return (void*)entry_vkCreateDescriptorPool;
-    }
-    if (!strcmp(name, "vkDestroyDescriptorPool")) {
-        return (void*)entry_vkDestroyDescriptorPool;
-    }
-    if (!strcmp(name, "vkResetDescriptorPool")) {
-        return (void*)entry_vkResetDescriptorPool;
-    }
-    if (!strcmp(name, "vkAllocateDescriptorSets")) {
-        return (void*)entry_vkAllocateDescriptorSets;
-    }
-    if (!strcmp(name, "vkFreeDescriptorSets")) {
-        return (void*)entry_vkFreeDescriptorSets;
-    }
-    if (!strcmp(name, "vkUpdateDescriptorSets")) {
-        return (void*)entry_vkUpdateDescriptorSets;
-    }
-    if (!strcmp(name, "vkCreateFramebuffer")) {
-        return (void*)entry_vkCreateFramebuffer;
-    }
-    if (!strcmp(name, "vkDestroyFramebuffer")) {
-        return (void*)entry_vkDestroyFramebuffer;
-    }
-    if (!strcmp(name, "vkCreateRenderPass")) {
-        return (void*)entry_vkCreateRenderPass;
-    }
-    if (!strcmp(name, "vkDestroyRenderPass")) {
-        return (void*)entry_vkDestroyRenderPass;
-    }
-    if (!strcmp(name, "vkGetRenderAreaGranularity")) {
-        return (void*)entry_vkGetRenderAreaGranularity;
-    }
-    if (!strcmp(name, "vkCreateCommandPool")) {
-        return (void*)entry_vkCreateCommandPool;
-    }
-    if (!strcmp(name, "vkDestroyCommandPool")) {
-        return (void*)entry_vkDestroyCommandPool;
-    }
-    if (!strcmp(name, "vkResetCommandPool")) {
-        return (void*)entry_vkResetCommandPool;
-    }
-    if (!strcmp(name, "vkAllocateCommandBuffers")) {
-        return (void*)entry_vkAllocateCommandBuffers;
-    }
-    if (!strcmp(name, "vkFreeCommandBuffers")) {
-        return (void*)entry_vkFreeCommandBuffers;
-    }
-    if (!strcmp(name, "vkBeginCommandBuffer")) {
-        return (void*)entry_vkBeginCommandBuffer;
-    }
-    if (!strcmp(name, "vkEndCommandBuffer")) {
-        return (void*)entry_vkEndCommandBuffer;
-    }
-    if (!strcmp(name, "vkResetCommandBuffer")) {
-        return (void*)entry_vkResetCommandBuffer;
-    }
-    if (!strcmp(name, "vkCmdBindPipeline")) {
-        return (void*)entry_vkCmdBindPipeline;
-    }
-    if (!strcmp(name, "vkCmdSetViewport")) {
-        return (void*)entry_vkCmdSetViewport;
-    }
-    if (!strcmp(name, "vkCmdSetScissor")) {
-        return (void*)entry_vkCmdSetScissor;
-    }
-    if (!strcmp(name, "vkCmdSetLineWidth")) {
-        return (void*)entry_vkCmdSetLineWidth;
-    }
-    if (!strcmp(name, "vkCmdSetDepthBias")) {
-        return (void*)entry_vkCmdSetDepthBias;
-    }
-    if (!strcmp(name, "vkCmdSetBlendConstants")) {
-        return (void*)entry_vkCmdSetBlendConstants;
-    }
-    if (!strcmp(name, "vkCmdSetDepthBounds")) {
-        return (void*)entry_vkCmdSetDepthBounds;
-    }
-    if (!strcmp(name, "vkCmdSetStencilCompareMask")) {
-        return (void*)entry_vkCmdSetStencilCompareMask;
-    }
-    if (!strcmp(name, "vkCmdSetStencilWriteMask")) {
-        return (void*)entry_vkCmdSetStencilWriteMask;
-    }
-    if (!strcmp(name, "vkCmdSetStencilReference")) {
-        return (void*)entry_vkCmdSetStencilReference;
-    }
-    if (!strcmp(name, "vkCmdBindDescriptorSets")) {
-        return (void*)entry_vkCmdBindDescriptorSets;
-    }
-    if (!strcmp(name, "vkCmdBindIndexBuffer")) {
-        return (void*)entry_vkCmdBindIndexBuffer;
-    }
-    if (!strcmp(name, "vkCmdBindVertexBuffers")) {
-        return (void*)entry_vkCmdBindVertexBuffers;
-    }
-    if (!strcmp(name, "vkCmdDraw")) {
-        return (void*)entry_vkCmdDraw;
-    }
-    if (!strcmp(name, "vkCmdDrawIndexed")) {
-        return (void*)entry_vkCmdDrawIndexed;
-    }
-    if (!strcmp(name, "vkCmdDrawIndirect")) {
-        return (void*)entry_vkCmdDrawIndirect;
-    }
-    if (!strcmp(name, "vkCmdDrawIndexedIndirect")) {
-        return (void*)entry_vkCmdDrawIndexedIndirect;
-    }
-    if (!strcmp(name, "vkCmdDispatch")) {
-        return (void*)entry_vkCmdDispatch;
-    }
-    if (!strcmp(name, "vkCmdDispatchIndirect")) {
-        return (void*)entry_vkCmdDispatchIndirect;
-    }
-    if (!strcmp(name, "vkCmdCopyBuffer")) {
-        return (void*)entry_vkCmdCopyBuffer;
-    }
-    if (!strcmp(name, "vkCmdCopyImage")) {
-        return (void*)entry_vkCmdCopyImage;
-    }
-    if (!strcmp(name, "vkCmdBlitImage")) {
-        return (void*)entry_vkCmdBlitImage;
-    }
-    if (!strcmp(name, "vkCmdCopyBufferToImage")) {
-        return (void*)entry_vkCmdCopyBufferToImage;
-    }
-    if (!strcmp(name, "vkCmdCopyImageToBuffer")) {
-        return (void*)entry_vkCmdCopyImageToBuffer;
-    }
-    if (!strcmp(name, "vkCmdUpdateBuffer")) {
-        return (void*)entry_vkCmdUpdateBuffer;
-    }
-    if (!strcmp(name, "vkCmdFillBuffer")) {
-        return (void*)entry_vkCmdFillBuffer;
-    }
-    if (!strcmp(name, "vkCmdClearColorImage")) {
-        return (void*)entry_vkCmdClearColorImage;
-    }
-    if (!strcmp(name, "vkCmdClearDepthStencilImage")) {
-        return (void*)entry_vkCmdClearDepthStencilImage;
-    }
-    if (!strcmp(name, "vkCmdClearAttachments")) {
-        return (void*)entry_vkCmdClearAttachments;
-    }
-    if (!strcmp(name, "vkCmdResolveImage")) {
-        return (void*)entry_vkCmdResolveImage;
-    }
-    if (!strcmp(name, "vkCmdSetEvent")) {
-        return (void*)entry_vkCmdSetEvent;
-    }
-    if (!strcmp(name, "vkCmdResetEvent")) {
-        return (void*)entry_vkCmdResetEvent;
-    }
-    if (!strcmp(name, "vkCmdWaitEvents")) {
-        return (void*)entry_vkCmdWaitEvents;
-    }
-    if (!strcmp(name, "vkCmdPipelineBarrier")) {
-        return (void*)entry_vkCmdPipelineBarrier;
-    }
-    if (!strcmp(name, "vkCmdBeginQuery")) {
-        return (void*)entry_vkCmdBeginQuery;
-    }
-    if (!strcmp(name, "vkCmdEndQuery")) {
-        return (void*)entry_vkCmdEndQuery;
-    }
-    if (!strcmp(name, "vkCmdResetQueryPool")) {
-        return (void*)entry_vkCmdResetQueryPool;
-    }
-    if (!strcmp(name, "vkCmdWriteTimestamp")) {
-        return (void*)entry_vkCmdWriteTimestamp;
-    }
-    if (!strcmp(name, "vkCmdCopyQueryPoolResults")) {
-        return (void*)entry_vkCmdCopyQueryPoolResults;
-    }
-    if (!strcmp(name, "vkCmdPushConstants")) {
-        return (void*)entry_vkCmdPushConstants;
-    }
-    if (!strcmp(name, "vkCmdBeginRenderPass")) {
-        return (void*)entry_vkCmdBeginRenderPass;
-    }
-    if (!strcmp(name, "vkCmdNextSubpass")) {
-        return (void*)entry_vkCmdNextSubpass;
-    }
-    if (!strcmp(name, "vkCmdEndRenderPass")) {
-        return (void*)entry_vkCmdEndRenderPass;
-    }
-    if (!strcmp(name, "vkCmdExecuteCommands")) {
-        return (void*)entry_vkCmdExecuteCommands;
-    }
-#endif
-#ifdef VK_VERSION_1_1
-    if (!strcmp(name, "vkEnumerateInstanceVersion")) {
-        return has1_1OrHigher ? (void*)entry_vkEnumerateInstanceVersion : nullptr;
-    }
-    if (!strcmp(name, "vkBindBufferMemory2")) {
-        return (void*)dynCheck_entry_vkBindBufferMemory2;
-    }
-    if (!strcmp(name, "vkBindImageMemory2")) {
-        return (void*)dynCheck_entry_vkBindImageMemory2;
-    }
-    if (!strcmp(name, "vkGetDeviceGroupPeerMemoryFeatures")) {
-        return (void*)dynCheck_entry_vkGetDeviceGroupPeerMemoryFeatures;
-    }
-    if (!strcmp(name, "vkCmdSetDeviceMask")) {
-        return has1_1OrHigher ? (void*)entry_vkCmdSetDeviceMask : nullptr;
-    }
-    if (!strcmp(name, "vkCmdDispatchBase")) {
-        return has1_1OrHigher ? (void*)entry_vkCmdDispatchBase : nullptr;
-    }
-    if (!strcmp(name, "vkEnumeratePhysicalDeviceGroups")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkGetImageMemoryRequirements2")) {
-        return (void*)dynCheck_entry_vkGetImageMemoryRequirements2;
-    }
-    if (!strcmp(name, "vkGetBufferMemoryRequirements2")) {
-        return (void*)dynCheck_entry_vkGetBufferMemoryRequirements2;
-    }
-    if (!strcmp(name, "vkGetImageSparseMemoryRequirements2")) {
-        return (void*)dynCheck_entry_vkGetImageSparseMemoryRequirements2;
-    }
-    if (!strcmp(name, "vkGetPhysicalDeviceFeatures2")) {
-        return has1_1OrHigher ? (void*)entry_vkGetPhysicalDeviceFeatures2 : nullptr;
-    }
-    if (!strcmp(name, "vkGetPhysicalDeviceProperties2")) {
-        return has1_1OrHigher ? (void*)entry_vkGetPhysicalDeviceProperties2 : nullptr;
-    }
-    if (!strcmp(name, "vkGetPhysicalDeviceFormatProperties2")) {
-        return has1_1OrHigher ? (void*)entry_vkGetPhysicalDeviceFormatProperties2 : nullptr;
-    }
-    if (!strcmp(name, "vkGetPhysicalDeviceImageFormatProperties2")) {
-        return has1_1OrHigher ? (void*)entry_vkGetPhysicalDeviceImageFormatProperties2 : nullptr;
-    }
-    if (!strcmp(name, "vkGetPhysicalDeviceQueueFamilyProperties2")) {
-        return has1_1OrHigher ? (void*)entry_vkGetPhysicalDeviceQueueFamilyProperties2 : nullptr;
-    }
-    if (!strcmp(name, "vkGetPhysicalDeviceMemoryProperties2")) {
-        return has1_1OrHigher ? (void*)entry_vkGetPhysicalDeviceMemoryProperties2 : nullptr;
-    }
-    if (!strcmp(name, "vkGetPhysicalDeviceSparseImageFormatProperties2")) {
-        return has1_1OrHigher ? (void*)entry_vkGetPhysicalDeviceSparseImageFormatProperties2
-                              : nullptr;
-    }
-    if (!strcmp(name, "vkTrimCommandPool")) {
-        return (void*)dynCheck_entry_vkTrimCommandPool;
-    }
-    if (!strcmp(name, "vkGetDeviceQueue2")) {
-        return (void*)dynCheck_entry_vkGetDeviceQueue2;
-    }
-    if (!strcmp(name, "vkCreateSamplerYcbcrConversion")) {
-        return (void*)dynCheck_entry_vkCreateSamplerYcbcrConversion;
-    }
-    if (!strcmp(name, "vkDestroySamplerYcbcrConversion")) {
-        return (void*)dynCheck_entry_vkDestroySamplerYcbcrConversion;
-    }
-    if (!strcmp(name, "vkCreateDescriptorUpdateTemplate")) {
-        return (void*)dynCheck_entry_vkCreateDescriptorUpdateTemplate;
-    }
-    if (!strcmp(name, "vkDestroyDescriptorUpdateTemplate")) {
-        return (void*)dynCheck_entry_vkDestroyDescriptorUpdateTemplate;
-    }
-    if (!strcmp(name, "vkUpdateDescriptorSetWithTemplate")) {
-        return (void*)dynCheck_entry_vkUpdateDescriptorSetWithTemplate;
-    }
-    if (!strcmp(name, "vkGetPhysicalDeviceExternalBufferProperties")) {
-        return has1_1OrHigher ? (void*)entry_vkGetPhysicalDeviceExternalBufferProperties : nullptr;
-    }
-    if (!strcmp(name, "vkGetPhysicalDeviceExternalFenceProperties")) {
-        return has1_1OrHigher ? (void*)entry_vkGetPhysicalDeviceExternalFenceProperties : nullptr;
-    }
-    if (!strcmp(name, "vkGetPhysicalDeviceExternalSemaphoreProperties")) {
-        return has1_1OrHigher ? (void*)entry_vkGetPhysicalDeviceExternalSemaphoreProperties
-                              : nullptr;
-    }
-    if (!strcmp(name, "vkGetDescriptorSetLayoutSupport")) {
-        return (void*)dynCheck_entry_vkGetDescriptorSetLayoutSupport;
-    }
-#endif
-#ifdef VK_VERSION_1_2
-    if (!strcmp(name, "vkCmdDrawIndirectCount")) {
-        return has1_2OrHigher ? (void*)entry_vkCmdDrawIndirectCount : nullptr;
-    }
-    if (!strcmp(name, "vkCmdDrawIndexedIndirectCount")) {
-        return has1_2OrHigher ? (void*)entry_vkCmdDrawIndexedIndirectCount : nullptr;
-    }
-    if (!strcmp(name, "vkCreateRenderPass2")) {
-        return (void*)dynCheck_entry_vkCreateRenderPass2;
-    }
-    if (!strcmp(name, "vkCmdBeginRenderPass2")) {
-        return has1_2OrHigher ? (void*)entry_vkCmdBeginRenderPass2 : nullptr;
-    }
-    if (!strcmp(name, "vkCmdNextSubpass2")) {
-        return has1_2OrHigher ? (void*)entry_vkCmdNextSubpass2 : nullptr;
-    }
-    if (!strcmp(name, "vkCmdEndRenderPass2")) {
-        return has1_2OrHigher ? (void*)entry_vkCmdEndRenderPass2 : nullptr;
-    }
-    if (!strcmp(name, "vkResetQueryPool")) {
-        return (void*)dynCheck_entry_vkResetQueryPool;
-    }
-    if (!strcmp(name, "vkGetSemaphoreCounterValue")) {
-        return (void*)dynCheck_entry_vkGetSemaphoreCounterValue;
-    }
-    if (!strcmp(name, "vkWaitSemaphores")) {
-        return (void*)dynCheck_entry_vkWaitSemaphores;
-    }
-    if (!strcmp(name, "vkSignalSemaphore")) {
-        return (void*)dynCheck_entry_vkSignalSemaphore;
-    }
-    if (!strcmp(name, "vkGetBufferDeviceAddress")) {
-        return (void*)dynCheck_entry_vkGetBufferDeviceAddress;
-    }
-    if (!strcmp(name, "vkGetBufferOpaqueCaptureAddress")) {
-        return (void*)dynCheck_entry_vkGetBufferOpaqueCaptureAddress;
-    }
-    if (!strcmp(name, "vkGetDeviceMemoryOpaqueCaptureAddress")) {
-        return (void*)dynCheck_entry_vkGetDeviceMemoryOpaqueCaptureAddress;
-    }
-#endif
-#ifdef VK_VERSION_1_3
-    if (!strcmp(name, "vkGetPhysicalDeviceToolProperties")) {
-        return has1_3OrHigher ? (void*)entry_vkGetPhysicalDeviceToolProperties : nullptr;
-    }
-    if (!strcmp(name, "vkCreatePrivateDataSlot")) {
-        return (void*)dynCheck_entry_vkCreatePrivateDataSlot;
-    }
-    if (!strcmp(name, "vkDestroyPrivateDataSlot")) {
-        return (void*)dynCheck_entry_vkDestroyPrivateDataSlot;
-    }
-    if (!strcmp(name, "vkSetPrivateData")) {
-        return (void*)dynCheck_entry_vkSetPrivateData;
-    }
-    if (!strcmp(name, "vkGetPrivateData")) {
-        return (void*)dynCheck_entry_vkGetPrivateData;
-    }
-    if (!strcmp(name, "vkCmdSetEvent2")) {
-        return has1_3OrHigher ? (void*)entry_vkCmdSetEvent2 : nullptr;
-    }
-    if (!strcmp(name, "vkCmdResetEvent2")) {
-        return has1_3OrHigher ? (void*)entry_vkCmdResetEvent2 : nullptr;
-    }
-    if (!strcmp(name, "vkCmdWaitEvents2")) {
-        return has1_3OrHigher ? (void*)entry_vkCmdWaitEvents2 : nullptr;
-    }
-    if (!strcmp(name, "vkCmdPipelineBarrier2")) {
-        return has1_3OrHigher ? (void*)entry_vkCmdPipelineBarrier2 : nullptr;
-    }
-    if (!strcmp(name, "vkCmdWriteTimestamp2")) {
-        return has1_3OrHigher ? (void*)entry_vkCmdWriteTimestamp2 : nullptr;
-    }
-    if (!strcmp(name, "vkQueueSubmit2")) {
-        return has1_3OrHigher ? (void*)entry_vkQueueSubmit2 : nullptr;
-    }
-    if (!strcmp(name, "vkCmdCopyBuffer2")) {
-        return has1_3OrHigher ? (void*)entry_vkCmdCopyBuffer2 : nullptr;
-    }
-    if (!strcmp(name, "vkCmdCopyImage2")) {
-        return has1_3OrHigher ? (void*)entry_vkCmdCopyImage2 : nullptr;
-    }
-    if (!strcmp(name, "vkCmdCopyBufferToImage2")) {
-        return has1_3OrHigher ? (void*)entry_vkCmdCopyBufferToImage2 : nullptr;
-    }
-    if (!strcmp(name, "vkCmdCopyImageToBuffer2")) {
-        return has1_3OrHigher ? (void*)entry_vkCmdCopyImageToBuffer2 : nullptr;
-    }
-    if (!strcmp(name, "vkCmdBlitImage2")) {
-        return has1_3OrHigher ? (void*)entry_vkCmdBlitImage2 : nullptr;
-    }
-    if (!strcmp(name, "vkCmdResolveImage2")) {
-        return has1_3OrHigher ? (void*)entry_vkCmdResolveImage2 : nullptr;
-    }
-    if (!strcmp(name, "vkCmdBeginRendering")) {
-        return has1_3OrHigher ? (void*)entry_vkCmdBeginRendering : nullptr;
-    }
-    if (!strcmp(name, "vkCmdEndRendering")) {
-        return has1_3OrHigher ? (void*)entry_vkCmdEndRendering : nullptr;
-    }
-    if (!strcmp(name, "vkCmdSetCullMode")) {
-        return has1_3OrHigher ? (void*)entry_vkCmdSetCullMode : nullptr;
-    }
-    if (!strcmp(name, "vkCmdSetFrontFace")) {
-        return has1_3OrHigher ? (void*)entry_vkCmdSetFrontFace : nullptr;
-    }
-    if (!strcmp(name, "vkCmdSetPrimitiveTopology")) {
-        return has1_3OrHigher ? (void*)entry_vkCmdSetPrimitiveTopology : nullptr;
-    }
-    if (!strcmp(name, "vkCmdSetViewportWithCount")) {
-        return has1_3OrHigher ? (void*)entry_vkCmdSetViewportWithCount : nullptr;
-    }
-    if (!strcmp(name, "vkCmdSetScissorWithCount")) {
-        return has1_3OrHigher ? (void*)entry_vkCmdSetScissorWithCount : nullptr;
-    }
-    if (!strcmp(name, "vkCmdBindVertexBuffers2")) {
-        return has1_3OrHigher ? (void*)entry_vkCmdBindVertexBuffers2 : nullptr;
-    }
-    if (!strcmp(name, "vkCmdSetDepthTestEnable")) {
-        return has1_3OrHigher ? (void*)entry_vkCmdSetDepthTestEnable : nullptr;
-    }
-    if (!strcmp(name, "vkCmdSetDepthWriteEnable")) {
-        return has1_3OrHigher ? (void*)entry_vkCmdSetDepthWriteEnable : nullptr;
-    }
-    if (!strcmp(name, "vkCmdSetDepthCompareOp")) {
-        return has1_3OrHigher ? (void*)entry_vkCmdSetDepthCompareOp : nullptr;
-    }
-    if (!strcmp(name, "vkCmdSetDepthBoundsTestEnable")) {
-        return has1_3OrHigher ? (void*)entry_vkCmdSetDepthBoundsTestEnable : nullptr;
-    }
-    if (!strcmp(name, "vkCmdSetStencilTestEnable")) {
-        return has1_3OrHigher ? (void*)entry_vkCmdSetStencilTestEnable : nullptr;
-    }
-    if (!strcmp(name, "vkCmdSetStencilOp")) {
-        return has1_3OrHigher ? (void*)entry_vkCmdSetStencilOp : nullptr;
-    }
-    if (!strcmp(name, "vkCmdSetRasterizerDiscardEnable")) {
-        return has1_3OrHigher ? (void*)entry_vkCmdSetRasterizerDiscardEnable : nullptr;
-    }
-    if (!strcmp(name, "vkCmdSetDepthBiasEnable")) {
-        return has1_3OrHigher ? (void*)entry_vkCmdSetDepthBiasEnable : nullptr;
-    }
-    if (!strcmp(name, "vkCmdSetPrimitiveRestartEnable")) {
-        return has1_3OrHigher ? (void*)entry_vkCmdSetPrimitiveRestartEnable : nullptr;
-    }
-    if (!strcmp(name, "vkGetDeviceBufferMemoryRequirements")) {
-        return (void*)dynCheck_entry_vkGetDeviceBufferMemoryRequirements;
-    }
-    if (!strcmp(name, "vkGetDeviceImageMemoryRequirements")) {
-        return (void*)dynCheck_entry_vkGetDeviceImageMemoryRequirements;
-    }
-    if (!strcmp(name, "vkGetDeviceImageSparseMemoryRequirements")) {
-        return (void*)dynCheck_entry_vkGetDeviceImageSparseMemoryRequirements;
-    }
-#endif
-#ifdef VK_KHR_android_surface
-    if (!strcmp(name, "vkCreateAndroidSurfaceKHR")) {
-        bool hasExt = resources->hasInstanceExtension(instance, "VK_KHR_android_surface");
-        return hasExt ? (void*)entry_vkCreateAndroidSurfaceKHR : nullptr;
-    }
-#endif
-#ifdef VK_KHR_dynamic_rendering
-    if (!strcmp(name, "vkCmdBeginRenderingKHR")) {
-        // TODO(b/236246382): Check support for device extension;
-        return (void*)dynCheck_entry_vkCmdBeginRenderingKHR;
-    }
-    if (!strcmp(name, "vkCmdEndRenderingKHR")) {
-        // TODO(b/236246382): Check support for device extension;
-        return (void*)dynCheck_entry_vkCmdEndRenderingKHR;
-    }
-#endif
-#ifdef VK_KHR_get_physical_device_properties2
-    if (!strcmp(name, "vkGetPhysicalDeviceFeatures2KHR")) {
-        bool hasExt =
-            resources->hasInstanceExtension(instance, "VK_KHR_get_physical_device_properties2");
-        return hasExt ? (void*)entry_vkGetPhysicalDeviceFeatures2KHR : nullptr;
-    }
-    if (!strcmp(name, "vkGetPhysicalDeviceProperties2KHR")) {
-        bool hasExt =
-            resources->hasInstanceExtension(instance, "VK_KHR_get_physical_device_properties2");
-        return hasExt ? (void*)entry_vkGetPhysicalDeviceProperties2KHR : nullptr;
-    }
-    if (!strcmp(name, "vkGetPhysicalDeviceFormatProperties2KHR")) {
-        bool hasExt =
-            resources->hasInstanceExtension(instance, "VK_KHR_get_physical_device_properties2");
-        return hasExt ? (void*)entry_vkGetPhysicalDeviceFormatProperties2KHR : nullptr;
-    }
-    if (!strcmp(name, "vkGetPhysicalDeviceImageFormatProperties2KHR")) {
-        bool hasExt =
-            resources->hasInstanceExtension(instance, "VK_KHR_get_physical_device_properties2");
-        return hasExt ? (void*)entry_vkGetPhysicalDeviceImageFormatProperties2KHR : nullptr;
-    }
-    if (!strcmp(name, "vkGetPhysicalDeviceQueueFamilyProperties2KHR")) {
-        bool hasExt =
-            resources->hasInstanceExtension(instance, "VK_KHR_get_physical_device_properties2");
-        return hasExt ? (void*)entry_vkGetPhysicalDeviceQueueFamilyProperties2KHR : nullptr;
-    }
-    if (!strcmp(name, "vkGetPhysicalDeviceMemoryProperties2KHR")) {
-        bool hasExt =
-            resources->hasInstanceExtension(instance, "VK_KHR_get_physical_device_properties2");
-        return hasExt ? (void*)entry_vkGetPhysicalDeviceMemoryProperties2KHR : nullptr;
-    }
-    if (!strcmp(name, "vkGetPhysicalDeviceSparseImageFormatProperties2KHR")) {
-        bool hasExt =
-            resources->hasInstanceExtension(instance, "VK_KHR_get_physical_device_properties2");
-        return hasExt ? (void*)entry_vkGetPhysicalDeviceSparseImageFormatProperties2KHR : nullptr;
-    }
-#endif
-#ifdef VK_KHR_maintenance1
-    if (!strcmp(name, "vkTrimCommandPoolKHR")) {
-        // TODO(b/236246382): Check support for device extension;
-        return (void*)dynCheck_entry_vkTrimCommandPoolKHR;
-    }
-#endif
-#ifdef VK_KHR_external_memory_capabilities
-    if (!strcmp(name, "vkGetPhysicalDeviceExternalBufferPropertiesKHR")) {
-        bool hasExt =
-            resources->hasInstanceExtension(instance, "VK_KHR_external_memory_capabilities");
-        return hasExt ? (void*)entry_vkGetPhysicalDeviceExternalBufferPropertiesKHR : nullptr;
-    }
-#endif
-#ifdef VK_KHR_external_semaphore_capabilities
-    if (!strcmp(name, "vkGetPhysicalDeviceExternalSemaphorePropertiesKHR")) {
-        bool hasExt =
-            resources->hasInstanceExtension(instance, "VK_KHR_external_semaphore_capabilities");
-        return hasExt ? (void*)entry_vkGetPhysicalDeviceExternalSemaphorePropertiesKHR : nullptr;
-    }
-#endif
-#ifdef VK_KHR_external_semaphore_fd
-    if (!strcmp(name, "vkImportSemaphoreFdKHR")) {
-        // TODO(b/236246382): Check support for device extension;
-        return (void*)dynCheck_entry_vkImportSemaphoreFdKHR;
-    }
-    if (!strcmp(name, "vkGetSemaphoreFdKHR")) {
-        // TODO(b/236246382): Check support for device extension;
-        return (void*)dynCheck_entry_vkGetSemaphoreFdKHR;
-    }
-#endif
-#ifdef VK_KHR_descriptor_update_template
-    if (!strcmp(name, "vkCreateDescriptorUpdateTemplateKHR")) {
-        // TODO(b/236246382): Check support for device extension;
-        return (void*)dynCheck_entry_vkCreateDescriptorUpdateTemplateKHR;
-    }
-    if (!strcmp(name, "vkDestroyDescriptorUpdateTemplateKHR")) {
-        // TODO(b/236246382): Check support for device extension;
-        return (void*)dynCheck_entry_vkDestroyDescriptorUpdateTemplateKHR;
-    }
-    if (!strcmp(name, "vkUpdateDescriptorSetWithTemplateKHR")) {
-        // TODO(b/236246382): Check support for device extension;
-        return (void*)dynCheck_entry_vkUpdateDescriptorSetWithTemplateKHR;
-    }
-#endif
-#ifdef VK_KHR_create_renderpass2
-    if (!strcmp(name, "vkCreateRenderPass2KHR")) {
-        // TODO(b/236246382): Check support for device extension;
-        return (void*)dynCheck_entry_vkCreateRenderPass2KHR;
-    }
-    if (!strcmp(name, "vkCmdBeginRenderPass2KHR")) {
-        // TODO(b/236246382): Check support for device extension;
-        return (void*)dynCheck_entry_vkCmdBeginRenderPass2KHR;
-    }
-    if (!strcmp(name, "vkCmdNextSubpass2KHR")) {
-        // TODO(b/236246382): Check support for device extension;
-        return (void*)dynCheck_entry_vkCmdNextSubpass2KHR;
-    }
-    if (!strcmp(name, "vkCmdEndRenderPass2KHR")) {
-        // TODO(b/236246382): Check support for device extension;
-        return (void*)dynCheck_entry_vkCmdEndRenderPass2KHR;
-    }
-#endif
-#ifdef VK_KHR_external_fence_capabilities
-    if (!strcmp(name, "vkGetPhysicalDeviceExternalFencePropertiesKHR")) {
-        bool hasExt =
-            resources->hasInstanceExtension(instance, "VK_KHR_external_fence_capabilities");
-        return hasExt ? (void*)entry_vkGetPhysicalDeviceExternalFencePropertiesKHR : nullptr;
-    }
-#endif
-#ifdef VK_KHR_external_fence_fd
-    if (!strcmp(name, "vkImportFenceFdKHR")) {
-        // TODO(b/236246382): Check support for device extension;
-        return (void*)dynCheck_entry_vkImportFenceFdKHR;
-    }
-    if (!strcmp(name, "vkGetFenceFdKHR")) {
-        // TODO(b/236246382): Check support for device extension;
-        return (void*)dynCheck_entry_vkGetFenceFdKHR;
-    }
-#endif
-#ifdef VK_KHR_get_memory_requirements2
-    if (!strcmp(name, "vkGetImageMemoryRequirements2KHR")) {
-        // TODO(b/236246382): Check support for device extension;
-        return (void*)dynCheck_entry_vkGetImageMemoryRequirements2KHR;
-    }
-    if (!strcmp(name, "vkGetBufferMemoryRequirements2KHR")) {
-        // TODO(b/236246382): Check support for device extension;
-        return (void*)dynCheck_entry_vkGetBufferMemoryRequirements2KHR;
-    }
-    if (!strcmp(name, "vkGetImageSparseMemoryRequirements2KHR")) {
-        // TODO(b/236246382): Check support for device extension;
-        return (void*)dynCheck_entry_vkGetImageSparseMemoryRequirements2KHR;
-    }
-#endif
-#ifdef VK_KHR_sampler_ycbcr_conversion
-    if (!strcmp(name, "vkCreateSamplerYcbcrConversionKHR")) {
-        // TODO(b/236246382): Check support for device extension;
-        return (void*)dynCheck_entry_vkCreateSamplerYcbcrConversionKHR;
-    }
-    if (!strcmp(name, "vkDestroySamplerYcbcrConversionKHR")) {
-        // TODO(b/236246382): Check support for device extension;
-        return (void*)dynCheck_entry_vkDestroySamplerYcbcrConversionKHR;
-    }
-#endif
-#ifdef VK_KHR_bind_memory2
-    if (!strcmp(name, "vkBindBufferMemory2KHR")) {
-        // TODO(b/236246382): Check support for device extension;
-        return (void*)dynCheck_entry_vkBindBufferMemory2KHR;
-    }
-    if (!strcmp(name, "vkBindImageMemory2KHR")) {
-        // TODO(b/236246382): Check support for device extension;
-        return (void*)dynCheck_entry_vkBindImageMemory2KHR;
-    }
-#endif
-#ifdef VK_KHR_maintenance3
-    if (!strcmp(name, "vkGetDescriptorSetLayoutSupportKHR")) {
-        // TODO(b/236246382): Check support for device extension;
-        return (void*)dynCheck_entry_vkGetDescriptorSetLayoutSupportKHR;
-    }
-#endif
-#ifdef VK_KHR_buffer_device_address
-    if (!strcmp(name, "vkGetBufferDeviceAddressKHR")) {
-        // TODO(b/236246382): Check support for device extension;
-        return (void*)dynCheck_entry_vkGetBufferDeviceAddressKHR;
-    }
-    if (!strcmp(name, "vkGetBufferOpaqueCaptureAddressKHR")) {
-        // TODO(b/236246382): Check support for device extension;
-        return (void*)dynCheck_entry_vkGetBufferOpaqueCaptureAddressKHR;
-    }
-    if (!strcmp(name, "vkGetDeviceMemoryOpaqueCaptureAddressKHR")) {
-        // TODO(b/236246382): Check support for device extension;
-        return (void*)dynCheck_entry_vkGetDeviceMemoryOpaqueCaptureAddressKHR;
-    }
-#endif
-#ifdef VK_KHR_pipeline_executable_properties
-    if (!strcmp(name, "vkGetPipelineExecutablePropertiesKHR")) {
-        // TODO(b/236246382): Check support for device extension;
-        return (void*)dynCheck_entry_vkGetPipelineExecutablePropertiesKHR;
-    }
-    if (!strcmp(name, "vkGetPipelineExecutableStatisticsKHR")) {
-        // TODO(b/236246382): Check support for device extension;
-        return (void*)dynCheck_entry_vkGetPipelineExecutableStatisticsKHR;
-    }
-    if (!strcmp(name, "vkGetPipelineExecutableInternalRepresentationsKHR")) {
-        // TODO(b/236246382): Check support for device extension;
-        return (void*)dynCheck_entry_vkGetPipelineExecutableInternalRepresentationsKHR;
-    }
-#endif
-#ifdef VK_KHR_synchronization2
-    if (!strcmp(name, "vkCmdSetEvent2KHR")) {
-        // TODO(b/236246382): Check support for device extension;
-        return (void*)dynCheck_entry_vkCmdSetEvent2KHR;
-    }
-    if (!strcmp(name, "vkCmdResetEvent2KHR")) {
-        // TODO(b/236246382): Check support for device extension;
-        return (void*)dynCheck_entry_vkCmdResetEvent2KHR;
-    }
-    if (!strcmp(name, "vkCmdWaitEvents2KHR")) {
-        // TODO(b/236246382): Check support for device extension;
-        return (void*)dynCheck_entry_vkCmdWaitEvents2KHR;
-    }
-    if (!strcmp(name, "vkCmdPipelineBarrier2KHR")) {
-        // TODO(b/236246382): Check support for device extension;
-        return (void*)dynCheck_entry_vkCmdPipelineBarrier2KHR;
-    }
-    if (!strcmp(name, "vkCmdWriteTimestamp2KHR")) {
-        // TODO(b/236246382): Check support for device extension;
-        return (void*)dynCheck_entry_vkCmdWriteTimestamp2KHR;
-    }
-    if (!strcmp(name, "vkQueueSubmit2KHR")) {
-        // TODO(b/236246382): Check support for device extension;
-        return (void*)entry_vkQueueSubmit2KHR;
-    }
-    if (!strcmp(name, "vkCmdWriteBufferMarker2AMD")) {
-        // TODO(b/236246382): Check support for device extension;
-        return (void*)dynCheck_entry_vkCmdWriteBufferMarker2AMD;
-    }
-    if (!strcmp(name, "vkGetQueueCheckpointData2NV")) {
-        // TODO(b/236246382): Check support for device extension;
-        return (void*)entry_vkGetQueueCheckpointData2NV;
-    }
-#endif
-#ifdef VK_KHR_copy_commands2
-    if (!strcmp(name, "vkCmdCopyBuffer2KHR")) {
-        // TODO(b/236246382): Check support for device extension;
-        return (void*)dynCheck_entry_vkCmdCopyBuffer2KHR;
-    }
-    if (!strcmp(name, "vkCmdCopyImage2KHR")) {
-        // TODO(b/236246382): Check support for device extension;
-        return (void*)dynCheck_entry_vkCmdCopyImage2KHR;
-    }
-    if (!strcmp(name, "vkCmdCopyBufferToImage2KHR")) {
-        // TODO(b/236246382): Check support for device extension;
-        return (void*)dynCheck_entry_vkCmdCopyBufferToImage2KHR;
-    }
-    if (!strcmp(name, "vkCmdCopyImageToBuffer2KHR")) {
-        // TODO(b/236246382): Check support for device extension;
-        return (void*)dynCheck_entry_vkCmdCopyImageToBuffer2KHR;
-    }
-    if (!strcmp(name, "vkCmdBlitImage2KHR")) {
-        // TODO(b/236246382): Check support for device extension;
-        return (void*)dynCheck_entry_vkCmdBlitImage2KHR;
-    }
-    if (!strcmp(name, "vkCmdResolveImage2KHR")) {
-        // TODO(b/236246382): Check support for device extension;
-        return (void*)dynCheck_entry_vkCmdResolveImage2KHR;
-    }
-#endif
-#ifdef VK_KHR_maintenance4
-    if (!strcmp(name, "vkGetDeviceBufferMemoryRequirementsKHR")) {
-        // TODO(b/236246382): Check support for device extension;
-        return (void*)dynCheck_entry_vkGetDeviceBufferMemoryRequirementsKHR;
-    }
-    if (!strcmp(name, "vkGetDeviceImageMemoryRequirementsKHR")) {
-        // TODO(b/236246382): Check support for device extension;
-        return (void*)dynCheck_entry_vkGetDeviceImageMemoryRequirementsKHR;
-    }
-    if (!strcmp(name, "vkGetDeviceImageSparseMemoryRequirementsKHR")) {
-        // TODO(b/236246382): Check support for device extension;
-        return (void*)dynCheck_entry_vkGetDeviceImageSparseMemoryRequirementsKHR;
-    }
-#endif
-#ifdef VK_KHR_maintenance5
-    if (!strcmp(name, "vkCmdBindIndexBuffer2KHR")) {
-        // TODO(b/236246382): Check support for device extension;
-        return (void*)dynCheck_entry_vkCmdBindIndexBuffer2KHR;
-    }
-    if (!strcmp(name, "vkGetRenderingAreaGranularityKHR")) {
-        // TODO(b/236246382): Check support for device extension;
-        return (void*)dynCheck_entry_vkGetRenderingAreaGranularityKHR;
-    }
-    if (!strcmp(name, "vkGetDeviceImageSubresourceLayoutKHR")) {
-        // TODO(b/236246382): Check support for device extension;
-        return (void*)dynCheck_entry_vkGetDeviceImageSubresourceLayoutKHR;
-    }
-    if (!strcmp(name, "vkGetImageSubresourceLayout2KHR")) {
-        // TODO(b/236246382): Check support for device extension;
-        return (void*)dynCheck_entry_vkGetImageSubresourceLayout2KHR;
-    }
-#endif
-#ifdef VK_ANDROID_native_buffer
-    if (!strcmp(name, "vkGetSwapchainGrallocUsageANDROID")) {
-        // TODO(b/236246382): Check support for device extension;
-        return (void*)dynCheck_entry_vkGetSwapchainGrallocUsageANDROID;
-    }
-    if (!strcmp(name, "vkAcquireImageANDROID")) {
-        // TODO(b/236246382): Check support for device extension;
-        return (void*)dynCheck_entry_vkAcquireImageANDROID;
-    }
-    if (!strcmp(name, "vkQueueSignalReleaseImageANDROID")) {
-        // TODO(b/236246382): Check support for device extension;
-        return (void*)entry_vkQueueSignalReleaseImageANDROID;
-    }
-    if (!strcmp(name, "vkGetSwapchainGrallocUsage2ANDROID")) {
-        // TODO(b/236246382): Check support for device extension;
-        return (void*)dynCheck_entry_vkGetSwapchainGrallocUsage2ANDROID;
-    }
-#endif
-#ifdef VK_EXT_transform_feedback
-    if (!strcmp(name, "vkCmdBindTransformFeedbackBuffersEXT")) {
-        // TODO(b/236246382): Check support for device extension;
-        return (void*)dynCheck_entry_vkCmdBindTransformFeedbackBuffersEXT;
-    }
-    if (!strcmp(name, "vkCmdBeginTransformFeedbackEXT")) {
-        // TODO(b/236246382): Check support for device extension;
-        return (void*)dynCheck_entry_vkCmdBeginTransformFeedbackEXT;
-    }
-    if (!strcmp(name, "vkCmdEndTransformFeedbackEXT")) {
-        // TODO(b/236246382): Check support for device extension;
-        return (void*)dynCheck_entry_vkCmdEndTransformFeedbackEXT;
-    }
-    if (!strcmp(name, "vkCmdBeginQueryIndexedEXT")) {
-        // TODO(b/236246382): Check support for device extension;
-        return (void*)dynCheck_entry_vkCmdBeginQueryIndexedEXT;
-    }
-    if (!strcmp(name, "vkCmdEndQueryIndexedEXT")) {
-        // TODO(b/236246382): Check support for device extension;
-        return (void*)dynCheck_entry_vkCmdEndQueryIndexedEXT;
-    }
-    if (!strcmp(name, "vkCmdDrawIndirectByteCountEXT")) {
-        // TODO(b/236246382): Check support for device extension;
-        return (void*)dynCheck_entry_vkCmdDrawIndirectByteCountEXT;
-    }
-#endif
-#ifdef VK_ANDROID_external_memory_android_hardware_buffer
-    if (!strcmp(name, "vkGetAndroidHardwareBufferPropertiesANDROID")) {
-        // TODO(b/236246382): Check support for device extension;
-        return (void*)dynCheck_entry_vkGetAndroidHardwareBufferPropertiesANDROID;
-    }
-    if (!strcmp(name, "vkGetMemoryAndroidHardwareBufferANDROID")) {
-        // TODO(b/236246382): Check support for device extension;
-        return (void*)dynCheck_entry_vkGetMemoryAndroidHardwareBufferANDROID;
-    }
-#endif
-#ifdef VK_EXT_tooling_info
-    if (!strcmp(name, "vkGetPhysicalDeviceToolPropertiesEXT")) {
-        // TODO(b/236246382): Check support for device extension;
-        return (void*)entry_vkGetPhysicalDeviceToolPropertiesEXT;
-    }
-#endif
-#ifdef VK_EXT_line_rasterization
-    if (!strcmp(name, "vkCmdSetLineStippleEXT")) {
-        // TODO(b/236246382): Check support for device extension;
-        return (void*)dynCheck_entry_vkCmdSetLineStippleEXT;
-    }
-#endif
-#ifdef VK_EXT_extended_dynamic_state
-    if (!strcmp(name, "vkCmdSetCullModeEXT")) {
-        // TODO(b/236246382): Check support for device extension;
-        return (void*)dynCheck_entry_vkCmdSetCullModeEXT;
-    }
-    if (!strcmp(name, "vkCmdSetFrontFaceEXT")) {
-        // TODO(b/236246382): Check support for device extension;
-        return (void*)dynCheck_entry_vkCmdSetFrontFaceEXT;
-    }
-    if (!strcmp(name, "vkCmdSetPrimitiveTopologyEXT")) {
-        // TODO(b/236246382): Check support for device extension;
-        return (void*)dynCheck_entry_vkCmdSetPrimitiveTopologyEXT;
-    }
-    if (!strcmp(name, "vkCmdSetViewportWithCountEXT")) {
-        // TODO(b/236246382): Check support for device extension;
-        return (void*)dynCheck_entry_vkCmdSetViewportWithCountEXT;
-    }
-    if (!strcmp(name, "vkCmdSetScissorWithCountEXT")) {
-        // TODO(b/236246382): Check support for device extension;
-        return (void*)dynCheck_entry_vkCmdSetScissorWithCountEXT;
-    }
-    if (!strcmp(name, "vkCmdBindVertexBuffers2EXT")) {
-        // TODO(b/236246382): Check support for device extension;
-        return (void*)dynCheck_entry_vkCmdBindVertexBuffers2EXT;
-    }
-    if (!strcmp(name, "vkCmdSetDepthTestEnableEXT")) {
-        // TODO(b/236246382): Check support for device extension;
-        return (void*)dynCheck_entry_vkCmdSetDepthTestEnableEXT;
-    }
-    if (!strcmp(name, "vkCmdSetDepthWriteEnableEXT")) {
-        // TODO(b/236246382): Check support for device extension;
-        return (void*)dynCheck_entry_vkCmdSetDepthWriteEnableEXT;
-    }
-    if (!strcmp(name, "vkCmdSetDepthCompareOpEXT")) {
-        // TODO(b/236246382): Check support for device extension;
-        return (void*)dynCheck_entry_vkCmdSetDepthCompareOpEXT;
-    }
-    if (!strcmp(name, "vkCmdSetDepthBoundsTestEnableEXT")) {
-        // TODO(b/236246382): Check support for device extension;
-        return (void*)dynCheck_entry_vkCmdSetDepthBoundsTestEnableEXT;
-    }
-    if (!strcmp(name, "vkCmdSetStencilTestEnableEXT")) {
-        // TODO(b/236246382): Check support for device extension;
-        return (void*)dynCheck_entry_vkCmdSetStencilTestEnableEXT;
-    }
-    if (!strcmp(name, "vkCmdSetStencilOpEXT")) {
-        // TODO(b/236246382): Check support for device extension;
-        return (void*)dynCheck_entry_vkCmdSetStencilOpEXT;
-    }
-#endif
-#ifdef VK_EXT_host_image_copy
-    if (!strcmp(name, "vkCopyMemoryToImageEXT")) {
-        // TODO(b/236246382): Check support for device extension;
-        return (void*)dynCheck_entry_vkCopyMemoryToImageEXT;
-    }
-    if (!strcmp(name, "vkCopyImageToMemoryEXT")) {
-        // TODO(b/236246382): Check support for device extension;
-        return (void*)dynCheck_entry_vkCopyImageToMemoryEXT;
-    }
-    if (!strcmp(name, "vkCopyImageToImageEXT")) {
-        // TODO(b/236246382): Check support for device extension;
-        return (void*)dynCheck_entry_vkCopyImageToImageEXT;
-    }
-    if (!strcmp(name, "vkTransitionImageLayoutEXT")) {
-        // TODO(b/236246382): Check support for device extension;
-        return (void*)dynCheck_entry_vkTransitionImageLayoutEXT;
-    }
-    if (!strcmp(name, "vkGetImageSubresourceLayout2EXT")) {
-        // TODO(b/236246382): Check support for device extension;
-        return (void*)dynCheck_entry_vkGetImageSubresourceLayout2EXT;
-    }
-#endif
-#ifdef VK_EXT_private_data
-    if (!strcmp(name, "vkCreatePrivateDataSlotEXT")) {
-        // TODO(b/236246382): Check support for device extension;
-        return (void*)dynCheck_entry_vkCreatePrivateDataSlotEXT;
-    }
-    if (!strcmp(name, "vkDestroyPrivateDataSlotEXT")) {
-        // TODO(b/236246382): Check support for device extension;
-        return (void*)dynCheck_entry_vkDestroyPrivateDataSlotEXT;
-    }
-    if (!strcmp(name, "vkSetPrivateDataEXT")) {
-        // TODO(b/236246382): Check support for device extension;
-        return (void*)dynCheck_entry_vkSetPrivateDataEXT;
-    }
-    if (!strcmp(name, "vkGetPrivateDataEXT")) {
-        // TODO(b/236246382): Check support for device extension;
-        return (void*)dynCheck_entry_vkGetPrivateDataEXT;
-    }
-#endif
-#ifdef VK_EXT_extended_dynamic_state2
-    if (!strcmp(name, "vkCmdSetPatchControlPointsEXT")) {
-        // TODO(b/236246382): Check support for device extension;
-        return (void*)dynCheck_entry_vkCmdSetPatchControlPointsEXT;
-    }
-    if (!strcmp(name, "vkCmdSetRasterizerDiscardEnableEXT")) {
-        // TODO(b/236246382): Check support for device extension;
-        return (void*)dynCheck_entry_vkCmdSetRasterizerDiscardEnableEXT;
-    }
-    if (!strcmp(name, "vkCmdSetDepthBiasEnableEXT")) {
-        // TODO(b/236246382): Check support for device extension;
-        return (void*)dynCheck_entry_vkCmdSetDepthBiasEnableEXT;
-    }
-    if (!strcmp(name, "vkCmdSetLogicOpEXT")) {
-        // TODO(b/236246382): Check support for device extension;
-        return (void*)dynCheck_entry_vkCmdSetLogicOpEXT;
-    }
-    if (!strcmp(name, "vkCmdSetPrimitiveRestartEnableEXT")) {
-        // TODO(b/236246382): Check support for device extension;
-        return (void*)dynCheck_entry_vkCmdSetPrimitiveRestartEnableEXT;
-    }
-#endif
-#ifdef VK_GOOGLE_gfxstream
-    if (!strcmp(name, "vkMapMemoryIntoAddressSpaceGOOGLE")) {
-        bool hasExt = resources->hasInstanceExtension(instance, "VK_GOOGLE_gfxstream");
-        return hasExt ? (void*)dynCheck_entry_vkMapMemoryIntoAddressSpaceGOOGLE : nullptr;
-    }
-    if (!strcmp(name, "vkUpdateDescriptorSetWithTemplateSizedGOOGLE")) {
-        bool hasExt = resources->hasInstanceExtension(instance, "VK_GOOGLE_gfxstream");
-        return hasExt ? (void*)dynCheck_entry_vkUpdateDescriptorSetWithTemplateSizedGOOGLE
-                      : nullptr;
-    }
-    if (!strcmp(name, "vkBeginCommandBufferAsyncGOOGLE")) {
-        bool hasExt = resources->hasInstanceExtension(instance, "VK_GOOGLE_gfxstream");
-        return hasExt ? (void*)entry_vkBeginCommandBufferAsyncGOOGLE : nullptr;
-    }
-    if (!strcmp(name, "vkEndCommandBufferAsyncGOOGLE")) {
-        bool hasExt = resources->hasInstanceExtension(instance, "VK_GOOGLE_gfxstream");
-        return hasExt ? (void*)entry_vkEndCommandBufferAsyncGOOGLE : nullptr;
-    }
-    if (!strcmp(name, "vkResetCommandBufferAsyncGOOGLE")) {
-        bool hasExt = resources->hasInstanceExtension(instance, "VK_GOOGLE_gfxstream");
-        return hasExt ? (void*)entry_vkResetCommandBufferAsyncGOOGLE : nullptr;
-    }
-    if (!strcmp(name, "vkCommandBufferHostSyncGOOGLE")) {
-        bool hasExt = resources->hasInstanceExtension(instance, "VK_GOOGLE_gfxstream");
-        return hasExt ? (void*)entry_vkCommandBufferHostSyncGOOGLE : nullptr;
-    }
-    if (!strcmp(name, "vkCreateImageWithRequirementsGOOGLE")) {
-        bool hasExt = resources->hasInstanceExtension(instance, "VK_GOOGLE_gfxstream");
-        return hasExt ? (void*)dynCheck_entry_vkCreateImageWithRequirementsGOOGLE : nullptr;
-    }
-    if (!strcmp(name, "vkCreateBufferWithRequirementsGOOGLE")) {
-        bool hasExt = resources->hasInstanceExtension(instance, "VK_GOOGLE_gfxstream");
-        return hasExt ? (void*)dynCheck_entry_vkCreateBufferWithRequirementsGOOGLE : nullptr;
-    }
-    if (!strcmp(name, "vkGetMemoryHostAddressInfoGOOGLE")) {
-        bool hasExt = resources->hasInstanceExtension(instance, "VK_GOOGLE_gfxstream");
-        return hasExt ? (void*)dynCheck_entry_vkGetMemoryHostAddressInfoGOOGLE : nullptr;
-    }
-    if (!strcmp(name, "vkFreeMemorySyncGOOGLE")) {
-        bool hasExt = resources->hasInstanceExtension(instance, "VK_GOOGLE_gfxstream");
-        return hasExt ? (void*)dynCheck_entry_vkFreeMemorySyncGOOGLE : nullptr;
-    }
-    if (!strcmp(name, "vkQueueHostSyncGOOGLE")) {
-        bool hasExt = resources->hasInstanceExtension(instance, "VK_GOOGLE_gfxstream");
-        return hasExt ? (void*)entry_vkQueueHostSyncGOOGLE : nullptr;
-    }
-    if (!strcmp(name, "vkQueueSubmitAsyncGOOGLE")) {
-        bool hasExt = resources->hasInstanceExtension(instance, "VK_GOOGLE_gfxstream");
-        return hasExt ? (void*)entry_vkQueueSubmitAsyncGOOGLE : nullptr;
-    }
-    if (!strcmp(name, "vkQueueWaitIdleAsyncGOOGLE")) {
-        bool hasExt = resources->hasInstanceExtension(instance, "VK_GOOGLE_gfxstream");
-        return hasExt ? (void*)entry_vkQueueWaitIdleAsyncGOOGLE : nullptr;
-    }
-    if (!strcmp(name, "vkQueueBindSparseAsyncGOOGLE")) {
-        bool hasExt = resources->hasInstanceExtension(instance, "VK_GOOGLE_gfxstream");
-        return hasExt ? (void*)entry_vkQueueBindSparseAsyncGOOGLE : nullptr;
-    }
-    if (!strcmp(name, "vkGetLinearImageLayoutGOOGLE")) {
-        bool hasExt = resources->hasInstanceExtension(instance, "VK_GOOGLE_gfxstream");
-        return hasExt ? (void*)dynCheck_entry_vkGetLinearImageLayoutGOOGLE : nullptr;
-    }
-    if (!strcmp(name, "vkGetLinearImageLayout2GOOGLE")) {
-        bool hasExt = resources->hasInstanceExtension(instance, "VK_GOOGLE_gfxstream");
-        return hasExt ? (void*)dynCheck_entry_vkGetLinearImageLayout2GOOGLE : nullptr;
-    }
-    if (!strcmp(name, "vkQueueFlushCommandsGOOGLE")) {
-        bool hasExt = resources->hasInstanceExtension(instance, "VK_GOOGLE_gfxstream");
-        return hasExt ? (void*)entry_vkQueueFlushCommandsGOOGLE : nullptr;
-    }
-    if (!strcmp(name, "vkQueueCommitDescriptorSetUpdatesGOOGLE")) {
-        bool hasExt = resources->hasInstanceExtension(instance, "VK_GOOGLE_gfxstream");
-        return hasExt ? (void*)entry_vkQueueCommitDescriptorSetUpdatesGOOGLE : nullptr;
-    }
-    if (!strcmp(name, "vkCollectDescriptorPoolIdsGOOGLE")) {
-        bool hasExt = resources->hasInstanceExtension(instance, "VK_GOOGLE_gfxstream");
-        return hasExt ? (void*)dynCheck_entry_vkCollectDescriptorPoolIdsGOOGLE : nullptr;
-    }
-    if (!strcmp(name, "vkQueueSignalReleaseImageANDROIDAsyncGOOGLE")) {
-        bool hasExt = resources->hasInstanceExtension(instance, "VK_GOOGLE_gfxstream");
-        return hasExt ? (void*)entry_vkQueueSignalReleaseImageANDROIDAsyncGOOGLE : nullptr;
-    }
-    if (!strcmp(name, "vkQueueFlushCommandsFromAuxMemoryGOOGLE")) {
-        bool hasExt = resources->hasInstanceExtension(instance, "VK_GOOGLE_gfxstream");
-        return hasExt ? (void*)entry_vkQueueFlushCommandsFromAuxMemoryGOOGLE : nullptr;
-    }
-    if (!strcmp(name, "vkGetBlobGOOGLE")) {
-        bool hasExt = resources->hasInstanceExtension(instance, "VK_GOOGLE_gfxstream");
-        return hasExt ? (void*)dynCheck_entry_vkGetBlobGOOGLE : nullptr;
-    }
-    if (!strcmp(name, "vkUpdateDescriptorSetWithTemplateSized2GOOGLE")) {
-        bool hasExt = resources->hasInstanceExtension(instance, "VK_GOOGLE_gfxstream");
-        return hasExt ? (void*)dynCheck_entry_vkUpdateDescriptorSetWithTemplateSized2GOOGLE
-                      : nullptr;
-    }
-    if (!strcmp(name, "vkQueueSubmitAsync2GOOGLE")) {
-        bool hasExt = resources->hasInstanceExtension(instance, "VK_GOOGLE_gfxstream");
-        return hasExt ? (void*)entry_vkQueueSubmitAsync2GOOGLE : nullptr;
-    }
-#endif
-    return nullptr;
-}
-void* goldfish_vulkan_get_device_proc_address(VkDevice device, const char* name) {
-    auto resources = ResourceTracker::get();
-    bool has1_1OrHigher = resources->getApiVersionFromDevice(device) >= VK_API_VERSION_1_1;
-    bool has1_2OrHigher = resources->getApiVersionFromDevice(device) >= VK_API_VERSION_1_2;
-    bool has1_3OrHigher = resources->getApiVersionFromDevice(device) >= VK_API_VERSION_1_3;
-#ifdef VK_VERSION_1_0
-    if (!strcmp(name, "vkCreateInstance")) {
-        return (void*)entry_vkCreateInstance;
-    }
-    if (!strcmp(name, "vkDestroyInstance")) {
-        return (void*)entry_vkDestroyInstance;
-    }
-    if (!strcmp(name, "vkEnumeratePhysicalDevices")) {
-        return (void*)entry_vkEnumeratePhysicalDevices;
-    }
-    if (!strcmp(name, "vkGetPhysicalDeviceFeatures")) {
-        return (void*)entry_vkGetPhysicalDeviceFeatures;
-    }
-    if (!strcmp(name, "vkGetPhysicalDeviceFormatProperties")) {
-        return (void*)entry_vkGetPhysicalDeviceFormatProperties;
-    }
-    if (!strcmp(name, "vkGetPhysicalDeviceImageFormatProperties")) {
-        return (void*)entry_vkGetPhysicalDeviceImageFormatProperties;
-    }
-    if (!strcmp(name, "vkGetPhysicalDeviceProperties")) {
-        return (void*)entry_vkGetPhysicalDeviceProperties;
-    }
-    if (!strcmp(name, "vkGetPhysicalDeviceQueueFamilyProperties")) {
-        return (void*)entry_vkGetPhysicalDeviceQueueFamilyProperties;
-    }
-    if (!strcmp(name, "vkGetPhysicalDeviceMemoryProperties")) {
-        return (void*)entry_vkGetPhysicalDeviceMemoryProperties;
-    }
-    if (!strcmp(name, "vkGetInstanceProcAddr")) {
-        return (void*)entry_vkGetInstanceProcAddr;
-    }
-    if (!strcmp(name, "vkGetDeviceProcAddr")) {
-        return (void*)entry_vkGetDeviceProcAddr;
-    }
-    if (!strcmp(name, "vkCreateDevice")) {
-        return (void*)entry_vkCreateDevice;
-    }
-    if (!strcmp(name, "vkDestroyDevice")) {
-        return (void*)entry_vkDestroyDevice;
-    }
-    if (!strcmp(name, "vkEnumerateInstanceExtensionProperties")) {
-        return (void*)entry_vkEnumerateInstanceExtensionProperties;
-    }
-    if (!strcmp(name, "vkEnumerateDeviceExtensionProperties")) {
-        return (void*)entry_vkEnumerateDeviceExtensionProperties;
-    }
-    if (!strcmp(name, "vkEnumerateInstanceLayerProperties")) {
-        return (void*)entry_vkEnumerateInstanceLayerProperties;
-    }
-    if (!strcmp(name, "vkEnumerateDeviceLayerProperties")) {
-        return (void*)entry_vkEnumerateDeviceLayerProperties;
-    }
-    if (!strcmp(name, "vkGetDeviceQueue")) {
-        return (void*)entry_vkGetDeviceQueue;
-    }
-    if (!strcmp(name, "vkQueueSubmit")) {
-        return (void*)entry_vkQueueSubmit;
-    }
-    if (!strcmp(name, "vkQueueWaitIdle")) {
-        return (void*)entry_vkQueueWaitIdle;
-    }
-    if (!strcmp(name, "vkDeviceWaitIdle")) {
-        return (void*)entry_vkDeviceWaitIdle;
-    }
-    if (!strcmp(name, "vkAllocateMemory")) {
-        return (void*)entry_vkAllocateMemory;
-    }
-    if (!strcmp(name, "vkFreeMemory")) {
-        return (void*)entry_vkFreeMemory;
-    }
-    if (!strcmp(name, "vkMapMemory")) {
-        return (void*)entry_vkMapMemory;
-    }
-    if (!strcmp(name, "vkUnmapMemory")) {
-        return (void*)entry_vkUnmapMemory;
-    }
-    if (!strcmp(name, "vkFlushMappedMemoryRanges")) {
-        return (void*)entry_vkFlushMappedMemoryRanges;
-    }
-    if (!strcmp(name, "vkInvalidateMappedMemoryRanges")) {
-        return (void*)entry_vkInvalidateMappedMemoryRanges;
-    }
-    if (!strcmp(name, "vkGetDeviceMemoryCommitment")) {
-        return (void*)entry_vkGetDeviceMemoryCommitment;
-    }
-    if (!strcmp(name, "vkBindBufferMemory")) {
-        return (void*)entry_vkBindBufferMemory;
-    }
-    if (!strcmp(name, "vkBindImageMemory")) {
-        return (void*)entry_vkBindImageMemory;
-    }
-    if (!strcmp(name, "vkGetBufferMemoryRequirements")) {
-        return (void*)entry_vkGetBufferMemoryRequirements;
-    }
-    if (!strcmp(name, "vkGetImageMemoryRequirements")) {
-        return (void*)entry_vkGetImageMemoryRequirements;
-    }
-    if (!strcmp(name, "vkGetImageSparseMemoryRequirements")) {
-        return (void*)entry_vkGetImageSparseMemoryRequirements;
-    }
-    if (!strcmp(name, "vkGetPhysicalDeviceSparseImageFormatProperties")) {
-        return (void*)entry_vkGetPhysicalDeviceSparseImageFormatProperties;
-    }
-    if (!strcmp(name, "vkQueueBindSparse")) {
-        return (void*)entry_vkQueueBindSparse;
-    }
-    if (!strcmp(name, "vkCreateFence")) {
-        return (void*)entry_vkCreateFence;
-    }
-    if (!strcmp(name, "vkDestroyFence")) {
-        return (void*)entry_vkDestroyFence;
-    }
-    if (!strcmp(name, "vkResetFences")) {
-        return (void*)entry_vkResetFences;
-    }
-    if (!strcmp(name, "vkGetFenceStatus")) {
-        return (void*)entry_vkGetFenceStatus;
-    }
-    if (!strcmp(name, "vkWaitForFences")) {
-        return (void*)entry_vkWaitForFences;
-    }
-    if (!strcmp(name, "vkCreateSemaphore")) {
-        return (void*)entry_vkCreateSemaphore;
-    }
-    if (!strcmp(name, "vkDestroySemaphore")) {
-        return (void*)entry_vkDestroySemaphore;
-    }
-    if (!strcmp(name, "vkCreateEvent")) {
-        return (void*)entry_vkCreateEvent;
-    }
-    if (!strcmp(name, "vkDestroyEvent")) {
-        return (void*)entry_vkDestroyEvent;
-    }
-    if (!strcmp(name, "vkGetEventStatus")) {
-        return (void*)entry_vkGetEventStatus;
-    }
-    if (!strcmp(name, "vkSetEvent")) {
-        return (void*)entry_vkSetEvent;
-    }
-    if (!strcmp(name, "vkResetEvent")) {
-        return (void*)entry_vkResetEvent;
-    }
-    if (!strcmp(name, "vkCreateQueryPool")) {
-        return (void*)entry_vkCreateQueryPool;
-    }
-    if (!strcmp(name, "vkDestroyQueryPool")) {
-        return (void*)entry_vkDestroyQueryPool;
-    }
-    if (!strcmp(name, "vkGetQueryPoolResults")) {
-        return (void*)entry_vkGetQueryPoolResults;
-    }
-    if (!strcmp(name, "vkCreateBuffer")) {
-        return (void*)entry_vkCreateBuffer;
-    }
-    if (!strcmp(name, "vkDestroyBuffer")) {
-        return (void*)entry_vkDestroyBuffer;
-    }
-    if (!strcmp(name, "vkCreateBufferView")) {
-        return (void*)entry_vkCreateBufferView;
-    }
-    if (!strcmp(name, "vkDestroyBufferView")) {
-        return (void*)entry_vkDestroyBufferView;
-    }
-    if (!strcmp(name, "vkCreateImage")) {
-        return (void*)entry_vkCreateImage;
-    }
-    if (!strcmp(name, "vkDestroyImage")) {
-        return (void*)entry_vkDestroyImage;
-    }
-    if (!strcmp(name, "vkGetImageSubresourceLayout")) {
-        return (void*)entry_vkGetImageSubresourceLayout;
-    }
-    if (!strcmp(name, "vkCreateImageView")) {
-        return (void*)entry_vkCreateImageView;
-    }
-    if (!strcmp(name, "vkDestroyImageView")) {
-        return (void*)entry_vkDestroyImageView;
-    }
-    if (!strcmp(name, "vkCreateShaderModule")) {
-        return (void*)entry_vkCreateShaderModule;
-    }
-    if (!strcmp(name, "vkDestroyShaderModule")) {
-        return (void*)entry_vkDestroyShaderModule;
-    }
-    if (!strcmp(name, "vkCreatePipelineCache")) {
-        return (void*)entry_vkCreatePipelineCache;
-    }
-    if (!strcmp(name, "vkDestroyPipelineCache")) {
-        return (void*)entry_vkDestroyPipelineCache;
-    }
-    if (!strcmp(name, "vkGetPipelineCacheData")) {
-        return (void*)entry_vkGetPipelineCacheData;
-    }
-    if (!strcmp(name, "vkMergePipelineCaches")) {
-        return (void*)entry_vkMergePipelineCaches;
-    }
-    if (!strcmp(name, "vkCreateGraphicsPipelines")) {
-        return (void*)entry_vkCreateGraphicsPipelines;
-    }
-    if (!strcmp(name, "vkCreateComputePipelines")) {
-        return (void*)entry_vkCreateComputePipelines;
-    }
-    if (!strcmp(name, "vkDestroyPipeline")) {
-        return (void*)entry_vkDestroyPipeline;
-    }
-    if (!strcmp(name, "vkCreatePipelineLayout")) {
-        return (void*)entry_vkCreatePipelineLayout;
-    }
-    if (!strcmp(name, "vkDestroyPipelineLayout")) {
-        return (void*)entry_vkDestroyPipelineLayout;
-    }
-    if (!strcmp(name, "vkCreateSampler")) {
-        return (void*)entry_vkCreateSampler;
-    }
-    if (!strcmp(name, "vkDestroySampler")) {
-        return (void*)entry_vkDestroySampler;
-    }
-    if (!strcmp(name, "vkCreateDescriptorSetLayout")) {
-        return (void*)entry_vkCreateDescriptorSetLayout;
-    }
-    if (!strcmp(name, "vkDestroyDescriptorSetLayout")) {
-        return (void*)entry_vkDestroyDescriptorSetLayout;
-    }
-    if (!strcmp(name, "vkCreateDescriptorPool")) {
-        return (void*)entry_vkCreateDescriptorPool;
-    }
-    if (!strcmp(name, "vkDestroyDescriptorPool")) {
-        return (void*)entry_vkDestroyDescriptorPool;
-    }
-    if (!strcmp(name, "vkResetDescriptorPool")) {
-        return (void*)entry_vkResetDescriptorPool;
-    }
-    if (!strcmp(name, "vkAllocateDescriptorSets")) {
-        return (void*)entry_vkAllocateDescriptorSets;
-    }
-    if (!strcmp(name, "vkFreeDescriptorSets")) {
-        return (void*)entry_vkFreeDescriptorSets;
-    }
-    if (!strcmp(name, "vkUpdateDescriptorSets")) {
-        return (void*)entry_vkUpdateDescriptorSets;
-    }
-    if (!strcmp(name, "vkCreateFramebuffer")) {
-        return (void*)entry_vkCreateFramebuffer;
-    }
-    if (!strcmp(name, "vkDestroyFramebuffer")) {
-        return (void*)entry_vkDestroyFramebuffer;
-    }
-    if (!strcmp(name, "vkCreateRenderPass")) {
-        return (void*)entry_vkCreateRenderPass;
-    }
-    if (!strcmp(name, "vkDestroyRenderPass")) {
-        return (void*)entry_vkDestroyRenderPass;
-    }
-    if (!strcmp(name, "vkGetRenderAreaGranularity")) {
-        return (void*)entry_vkGetRenderAreaGranularity;
-    }
-    if (!strcmp(name, "vkCreateCommandPool")) {
-        return (void*)entry_vkCreateCommandPool;
-    }
-    if (!strcmp(name, "vkDestroyCommandPool")) {
-        return (void*)entry_vkDestroyCommandPool;
-    }
-    if (!strcmp(name, "vkResetCommandPool")) {
-        return (void*)entry_vkResetCommandPool;
-    }
-    if (!strcmp(name, "vkAllocateCommandBuffers")) {
-        return (void*)entry_vkAllocateCommandBuffers;
-    }
-    if (!strcmp(name, "vkFreeCommandBuffers")) {
-        return (void*)entry_vkFreeCommandBuffers;
-    }
-    if (!strcmp(name, "vkBeginCommandBuffer")) {
-        return (void*)entry_vkBeginCommandBuffer;
-    }
-    if (!strcmp(name, "vkEndCommandBuffer")) {
-        return (void*)entry_vkEndCommandBuffer;
-    }
-    if (!strcmp(name, "vkResetCommandBuffer")) {
-        return (void*)entry_vkResetCommandBuffer;
-    }
-    if (!strcmp(name, "vkCmdBindPipeline")) {
-        return (void*)entry_vkCmdBindPipeline;
-    }
-    if (!strcmp(name, "vkCmdSetViewport")) {
-        return (void*)entry_vkCmdSetViewport;
-    }
-    if (!strcmp(name, "vkCmdSetScissor")) {
-        return (void*)entry_vkCmdSetScissor;
-    }
-    if (!strcmp(name, "vkCmdSetLineWidth")) {
-        return (void*)entry_vkCmdSetLineWidth;
-    }
-    if (!strcmp(name, "vkCmdSetDepthBias")) {
-        return (void*)entry_vkCmdSetDepthBias;
-    }
-    if (!strcmp(name, "vkCmdSetBlendConstants")) {
-        return (void*)entry_vkCmdSetBlendConstants;
-    }
-    if (!strcmp(name, "vkCmdSetDepthBounds")) {
-        return (void*)entry_vkCmdSetDepthBounds;
-    }
-    if (!strcmp(name, "vkCmdSetStencilCompareMask")) {
-        return (void*)entry_vkCmdSetStencilCompareMask;
-    }
-    if (!strcmp(name, "vkCmdSetStencilWriteMask")) {
-        return (void*)entry_vkCmdSetStencilWriteMask;
-    }
-    if (!strcmp(name, "vkCmdSetStencilReference")) {
-        return (void*)entry_vkCmdSetStencilReference;
-    }
-    if (!strcmp(name, "vkCmdBindDescriptorSets")) {
-        return (void*)entry_vkCmdBindDescriptorSets;
-    }
-    if (!strcmp(name, "vkCmdBindIndexBuffer")) {
-        return (void*)entry_vkCmdBindIndexBuffer;
-    }
-    if (!strcmp(name, "vkCmdBindVertexBuffers")) {
-        return (void*)entry_vkCmdBindVertexBuffers;
-    }
-    if (!strcmp(name, "vkCmdDraw")) {
-        return (void*)entry_vkCmdDraw;
-    }
-    if (!strcmp(name, "vkCmdDrawIndexed")) {
-        return (void*)entry_vkCmdDrawIndexed;
-    }
-    if (!strcmp(name, "vkCmdDrawIndirect")) {
-        return (void*)entry_vkCmdDrawIndirect;
-    }
-    if (!strcmp(name, "vkCmdDrawIndexedIndirect")) {
-        return (void*)entry_vkCmdDrawIndexedIndirect;
-    }
-    if (!strcmp(name, "vkCmdDispatch")) {
-        return (void*)entry_vkCmdDispatch;
-    }
-    if (!strcmp(name, "vkCmdDispatchIndirect")) {
-        return (void*)entry_vkCmdDispatchIndirect;
-    }
-    if (!strcmp(name, "vkCmdCopyBuffer")) {
-        return (void*)entry_vkCmdCopyBuffer;
-    }
-    if (!strcmp(name, "vkCmdCopyImage")) {
-        return (void*)entry_vkCmdCopyImage;
-    }
-    if (!strcmp(name, "vkCmdBlitImage")) {
-        return (void*)entry_vkCmdBlitImage;
-    }
-    if (!strcmp(name, "vkCmdCopyBufferToImage")) {
-        return (void*)entry_vkCmdCopyBufferToImage;
-    }
-    if (!strcmp(name, "vkCmdCopyImageToBuffer")) {
-        return (void*)entry_vkCmdCopyImageToBuffer;
-    }
-    if (!strcmp(name, "vkCmdUpdateBuffer")) {
-        return (void*)entry_vkCmdUpdateBuffer;
-    }
-    if (!strcmp(name, "vkCmdFillBuffer")) {
-        return (void*)entry_vkCmdFillBuffer;
-    }
-    if (!strcmp(name, "vkCmdClearColorImage")) {
-        return (void*)entry_vkCmdClearColorImage;
-    }
-    if (!strcmp(name, "vkCmdClearDepthStencilImage")) {
-        return (void*)entry_vkCmdClearDepthStencilImage;
-    }
-    if (!strcmp(name, "vkCmdClearAttachments")) {
-        return (void*)entry_vkCmdClearAttachments;
-    }
-    if (!strcmp(name, "vkCmdResolveImage")) {
-        return (void*)entry_vkCmdResolveImage;
-    }
-    if (!strcmp(name, "vkCmdSetEvent")) {
-        return (void*)entry_vkCmdSetEvent;
-    }
-    if (!strcmp(name, "vkCmdResetEvent")) {
-        return (void*)entry_vkCmdResetEvent;
-    }
-    if (!strcmp(name, "vkCmdWaitEvents")) {
-        return (void*)entry_vkCmdWaitEvents;
-    }
-    if (!strcmp(name, "vkCmdPipelineBarrier")) {
-        return (void*)entry_vkCmdPipelineBarrier;
-    }
-    if (!strcmp(name, "vkCmdBeginQuery")) {
-        return (void*)entry_vkCmdBeginQuery;
-    }
-    if (!strcmp(name, "vkCmdEndQuery")) {
-        return (void*)entry_vkCmdEndQuery;
-    }
-    if (!strcmp(name, "vkCmdResetQueryPool")) {
-        return (void*)entry_vkCmdResetQueryPool;
-    }
-    if (!strcmp(name, "vkCmdWriteTimestamp")) {
-        return (void*)entry_vkCmdWriteTimestamp;
-    }
-    if (!strcmp(name, "vkCmdCopyQueryPoolResults")) {
-        return (void*)entry_vkCmdCopyQueryPoolResults;
-    }
-    if (!strcmp(name, "vkCmdPushConstants")) {
-        return (void*)entry_vkCmdPushConstants;
-    }
-    if (!strcmp(name, "vkCmdBeginRenderPass")) {
-        return (void*)entry_vkCmdBeginRenderPass;
-    }
-    if (!strcmp(name, "vkCmdNextSubpass")) {
-        return (void*)entry_vkCmdNextSubpass;
-    }
-    if (!strcmp(name, "vkCmdEndRenderPass")) {
-        return (void*)entry_vkCmdEndRenderPass;
-    }
-    if (!strcmp(name, "vkCmdExecuteCommands")) {
-        return (void*)entry_vkCmdExecuteCommands;
-    }
-#endif
-#ifdef VK_VERSION_1_1
-    if (!strcmp(name, "vkEnumerateInstanceVersion")) {
-        return has1_1OrHigher ? (void*)entry_vkEnumerateInstanceVersion : nullptr;
-    }
-    if (!strcmp(name, "vkBindBufferMemory2")) {
-        return has1_1OrHigher ? (void*)entry_vkBindBufferMemory2 : nullptr;
-    }
-    if (!strcmp(name, "vkBindImageMemory2")) {
-        return has1_1OrHigher ? (void*)entry_vkBindImageMemory2 : nullptr;
-    }
-    if (!strcmp(name, "vkGetDeviceGroupPeerMemoryFeatures")) {
-        return has1_1OrHigher ? (void*)entry_vkGetDeviceGroupPeerMemoryFeatures : nullptr;
-    }
-    if (!strcmp(name, "vkCmdSetDeviceMask")) {
-        return has1_1OrHigher ? (void*)entry_vkCmdSetDeviceMask : nullptr;
-    }
-    if (!strcmp(name, "vkCmdDispatchBase")) {
-        return has1_1OrHigher ? (void*)entry_vkCmdDispatchBase : nullptr;
-    }
-    if (!strcmp(name, "vkEnumeratePhysicalDeviceGroups")) {
-        return nullptr;
-    }
-    if (!strcmp(name, "vkGetImageMemoryRequirements2")) {
-        return has1_1OrHigher ? (void*)entry_vkGetImageMemoryRequirements2 : nullptr;
-    }
-    if (!strcmp(name, "vkGetBufferMemoryRequirements2")) {
-        return has1_1OrHigher ? (void*)entry_vkGetBufferMemoryRequirements2 : nullptr;
-    }
-    if (!strcmp(name, "vkGetImageSparseMemoryRequirements2")) {
-        return has1_1OrHigher ? (void*)entry_vkGetImageSparseMemoryRequirements2 : nullptr;
-    }
-    if (!strcmp(name, "vkGetPhysicalDeviceFeatures2")) {
-        return has1_1OrHigher ? (void*)entry_vkGetPhysicalDeviceFeatures2 : nullptr;
-    }
-    if (!strcmp(name, "vkGetPhysicalDeviceProperties2")) {
-        return has1_1OrHigher ? (void*)entry_vkGetPhysicalDeviceProperties2 : nullptr;
-    }
-    if (!strcmp(name, "vkGetPhysicalDeviceFormatProperties2")) {
-        return has1_1OrHigher ? (void*)entry_vkGetPhysicalDeviceFormatProperties2 : nullptr;
-    }
-    if (!strcmp(name, "vkGetPhysicalDeviceImageFormatProperties2")) {
-        return has1_1OrHigher ? (void*)entry_vkGetPhysicalDeviceImageFormatProperties2 : nullptr;
-    }
-    if (!strcmp(name, "vkGetPhysicalDeviceQueueFamilyProperties2")) {
-        return has1_1OrHigher ? (void*)entry_vkGetPhysicalDeviceQueueFamilyProperties2 : nullptr;
-    }
-    if (!strcmp(name, "vkGetPhysicalDeviceMemoryProperties2")) {
-        return has1_1OrHigher ? (void*)entry_vkGetPhysicalDeviceMemoryProperties2 : nullptr;
-    }
-    if (!strcmp(name, "vkGetPhysicalDeviceSparseImageFormatProperties2")) {
-        return has1_1OrHigher ? (void*)entry_vkGetPhysicalDeviceSparseImageFormatProperties2
-                              : nullptr;
-    }
-    if (!strcmp(name, "vkTrimCommandPool")) {
-        return has1_1OrHigher ? (void*)entry_vkTrimCommandPool : nullptr;
-    }
-    if (!strcmp(name, "vkGetDeviceQueue2")) {
-        return has1_1OrHigher ? (void*)entry_vkGetDeviceQueue2 : nullptr;
-    }
-    if (!strcmp(name, "vkCreateSamplerYcbcrConversion")) {
-        return has1_1OrHigher ? (void*)entry_vkCreateSamplerYcbcrConversion : nullptr;
-    }
-    if (!strcmp(name, "vkDestroySamplerYcbcrConversion")) {
-        return has1_1OrHigher ? (void*)entry_vkDestroySamplerYcbcrConversion : nullptr;
-    }
-    if (!strcmp(name, "vkCreateDescriptorUpdateTemplate")) {
-        return has1_1OrHigher ? (void*)entry_vkCreateDescriptorUpdateTemplate : nullptr;
-    }
-    if (!strcmp(name, "vkDestroyDescriptorUpdateTemplate")) {
-        return has1_1OrHigher ? (void*)entry_vkDestroyDescriptorUpdateTemplate : nullptr;
-    }
-    if (!strcmp(name, "vkUpdateDescriptorSetWithTemplate")) {
-        return has1_1OrHigher ? (void*)entry_vkUpdateDescriptorSetWithTemplate : nullptr;
-    }
-    if (!strcmp(name, "vkGetPhysicalDeviceExternalBufferProperties")) {
-        return has1_1OrHigher ? (void*)entry_vkGetPhysicalDeviceExternalBufferProperties : nullptr;
-    }
-    if (!strcmp(name, "vkGetPhysicalDeviceExternalFenceProperties")) {
-        return has1_1OrHigher ? (void*)entry_vkGetPhysicalDeviceExternalFenceProperties : nullptr;
-    }
-    if (!strcmp(name, "vkGetPhysicalDeviceExternalSemaphoreProperties")) {
-        return has1_1OrHigher ? (void*)entry_vkGetPhysicalDeviceExternalSemaphoreProperties
-                              : nullptr;
-    }
-    if (!strcmp(name, "vkGetDescriptorSetLayoutSupport")) {
-        return has1_1OrHigher ? (void*)entry_vkGetDescriptorSetLayoutSupport : nullptr;
-    }
-#endif
-#ifdef VK_VERSION_1_2
-    if (!strcmp(name, "vkCmdDrawIndirectCount")) {
-        return has1_2OrHigher ? (void*)entry_vkCmdDrawIndirectCount : nullptr;
-    }
-    if (!strcmp(name, "vkCmdDrawIndexedIndirectCount")) {
-        return has1_2OrHigher ? (void*)entry_vkCmdDrawIndexedIndirectCount : nullptr;
-    }
-    if (!strcmp(name, "vkCreateRenderPass2")) {
-        return has1_2OrHigher ? (void*)entry_vkCreateRenderPass2 : nullptr;
-    }
-    if (!strcmp(name, "vkCmdBeginRenderPass2")) {
-        return has1_2OrHigher ? (void*)entry_vkCmdBeginRenderPass2 : nullptr;
-    }
-    if (!strcmp(name, "vkCmdNextSubpass2")) {
-        return has1_2OrHigher ? (void*)entry_vkCmdNextSubpass2 : nullptr;
-    }
-    if (!strcmp(name, "vkCmdEndRenderPass2")) {
-        return has1_2OrHigher ? (void*)entry_vkCmdEndRenderPass2 : nullptr;
-    }
-    if (!strcmp(name, "vkResetQueryPool")) {
-        return has1_2OrHigher ? (void*)entry_vkResetQueryPool : nullptr;
-    }
-    if (!strcmp(name, "vkGetSemaphoreCounterValue")) {
-        return has1_2OrHigher ? (void*)entry_vkGetSemaphoreCounterValue : nullptr;
-    }
-    if (!strcmp(name, "vkWaitSemaphores")) {
-        return has1_2OrHigher ? (void*)entry_vkWaitSemaphores : nullptr;
-    }
-    if (!strcmp(name, "vkSignalSemaphore")) {
-        return has1_2OrHigher ? (void*)entry_vkSignalSemaphore : nullptr;
-    }
-    if (!strcmp(name, "vkGetBufferDeviceAddress")) {
-        return has1_2OrHigher ? (void*)entry_vkGetBufferDeviceAddress : nullptr;
-    }
-    if (!strcmp(name, "vkGetBufferOpaqueCaptureAddress")) {
-        return has1_2OrHigher ? (void*)entry_vkGetBufferOpaqueCaptureAddress : nullptr;
-    }
-    if (!strcmp(name, "vkGetDeviceMemoryOpaqueCaptureAddress")) {
-        return has1_2OrHigher ? (void*)entry_vkGetDeviceMemoryOpaqueCaptureAddress : nullptr;
-    }
-#endif
-#ifdef VK_VERSION_1_3
-    if (!strcmp(name, "vkGetPhysicalDeviceToolProperties")) {
-        return has1_3OrHigher ? (void*)entry_vkGetPhysicalDeviceToolProperties : nullptr;
-    }
-    if (!strcmp(name, "vkCreatePrivateDataSlot")) {
-        return has1_3OrHigher ? (void*)entry_vkCreatePrivateDataSlot : nullptr;
-    }
-    if (!strcmp(name, "vkDestroyPrivateDataSlot")) {
-        return has1_3OrHigher ? (void*)entry_vkDestroyPrivateDataSlot : nullptr;
-    }
-    if (!strcmp(name, "vkSetPrivateData")) {
-        return has1_3OrHigher ? (void*)entry_vkSetPrivateData : nullptr;
-    }
-    if (!strcmp(name, "vkGetPrivateData")) {
-        return has1_3OrHigher ? (void*)entry_vkGetPrivateData : nullptr;
-    }
-    if (!strcmp(name, "vkCmdSetEvent2")) {
-        return has1_3OrHigher ? (void*)entry_vkCmdSetEvent2 : nullptr;
-    }
-    if (!strcmp(name, "vkCmdResetEvent2")) {
-        return has1_3OrHigher ? (void*)entry_vkCmdResetEvent2 : nullptr;
-    }
-    if (!strcmp(name, "vkCmdWaitEvents2")) {
-        return has1_3OrHigher ? (void*)entry_vkCmdWaitEvents2 : nullptr;
-    }
-    if (!strcmp(name, "vkCmdPipelineBarrier2")) {
-        return has1_3OrHigher ? (void*)entry_vkCmdPipelineBarrier2 : nullptr;
-    }
-    if (!strcmp(name, "vkCmdWriteTimestamp2")) {
-        return has1_3OrHigher ? (void*)entry_vkCmdWriteTimestamp2 : nullptr;
-    }
-    if (!strcmp(name, "vkQueueSubmit2")) {
-        return has1_3OrHigher ? (void*)entry_vkQueueSubmit2 : nullptr;
-    }
-    if (!strcmp(name, "vkCmdCopyBuffer2")) {
-        return has1_3OrHigher ? (void*)entry_vkCmdCopyBuffer2 : nullptr;
-    }
-    if (!strcmp(name, "vkCmdCopyImage2")) {
-        return has1_3OrHigher ? (void*)entry_vkCmdCopyImage2 : nullptr;
-    }
-    if (!strcmp(name, "vkCmdCopyBufferToImage2")) {
-        return has1_3OrHigher ? (void*)entry_vkCmdCopyBufferToImage2 : nullptr;
-    }
-    if (!strcmp(name, "vkCmdCopyImageToBuffer2")) {
-        return has1_3OrHigher ? (void*)entry_vkCmdCopyImageToBuffer2 : nullptr;
-    }
-    if (!strcmp(name, "vkCmdBlitImage2")) {
-        return has1_3OrHigher ? (void*)entry_vkCmdBlitImage2 : nullptr;
-    }
-    if (!strcmp(name, "vkCmdResolveImage2")) {
-        return has1_3OrHigher ? (void*)entry_vkCmdResolveImage2 : nullptr;
-    }
-    if (!strcmp(name, "vkCmdBeginRendering")) {
-        return has1_3OrHigher ? (void*)entry_vkCmdBeginRendering : nullptr;
-    }
-    if (!strcmp(name, "vkCmdEndRendering")) {
-        return has1_3OrHigher ? (void*)entry_vkCmdEndRendering : nullptr;
-    }
-    if (!strcmp(name, "vkCmdSetCullMode")) {
-        return has1_3OrHigher ? (void*)entry_vkCmdSetCullMode : nullptr;
-    }
-    if (!strcmp(name, "vkCmdSetFrontFace")) {
-        return has1_3OrHigher ? (void*)entry_vkCmdSetFrontFace : nullptr;
-    }
-    if (!strcmp(name, "vkCmdSetPrimitiveTopology")) {
-        return has1_3OrHigher ? (void*)entry_vkCmdSetPrimitiveTopology : nullptr;
-    }
-    if (!strcmp(name, "vkCmdSetViewportWithCount")) {
-        return has1_3OrHigher ? (void*)entry_vkCmdSetViewportWithCount : nullptr;
-    }
-    if (!strcmp(name, "vkCmdSetScissorWithCount")) {
-        return has1_3OrHigher ? (void*)entry_vkCmdSetScissorWithCount : nullptr;
-    }
-    if (!strcmp(name, "vkCmdBindVertexBuffers2")) {
-        return has1_3OrHigher ? (void*)entry_vkCmdBindVertexBuffers2 : nullptr;
-    }
-    if (!strcmp(name, "vkCmdSetDepthTestEnable")) {
-        return has1_3OrHigher ? (void*)entry_vkCmdSetDepthTestEnable : nullptr;
-    }
-    if (!strcmp(name, "vkCmdSetDepthWriteEnable")) {
-        return has1_3OrHigher ? (void*)entry_vkCmdSetDepthWriteEnable : nullptr;
-    }
-    if (!strcmp(name, "vkCmdSetDepthCompareOp")) {
-        return has1_3OrHigher ? (void*)entry_vkCmdSetDepthCompareOp : nullptr;
-    }
-    if (!strcmp(name, "vkCmdSetDepthBoundsTestEnable")) {
-        return has1_3OrHigher ? (void*)entry_vkCmdSetDepthBoundsTestEnable : nullptr;
-    }
-    if (!strcmp(name, "vkCmdSetStencilTestEnable")) {
-        return has1_3OrHigher ? (void*)entry_vkCmdSetStencilTestEnable : nullptr;
-    }
-    if (!strcmp(name, "vkCmdSetStencilOp")) {
-        return has1_3OrHigher ? (void*)entry_vkCmdSetStencilOp : nullptr;
-    }
-    if (!strcmp(name, "vkCmdSetRasterizerDiscardEnable")) {
-        return has1_3OrHigher ? (void*)entry_vkCmdSetRasterizerDiscardEnable : nullptr;
-    }
-    if (!strcmp(name, "vkCmdSetDepthBiasEnable")) {
-        return has1_3OrHigher ? (void*)entry_vkCmdSetDepthBiasEnable : nullptr;
-    }
-    if (!strcmp(name, "vkCmdSetPrimitiveRestartEnable")) {
-        return has1_3OrHigher ? (void*)entry_vkCmdSetPrimitiveRestartEnable : nullptr;
-    }
-    if (!strcmp(name, "vkGetDeviceBufferMemoryRequirements")) {
-        return has1_3OrHigher ? (void*)entry_vkGetDeviceBufferMemoryRequirements : nullptr;
-    }
-    if (!strcmp(name, "vkGetDeviceImageMemoryRequirements")) {
-        return has1_3OrHigher ? (void*)entry_vkGetDeviceImageMemoryRequirements : nullptr;
-    }
-    if (!strcmp(name, "vkGetDeviceImageSparseMemoryRequirements")) {
-        return has1_3OrHigher ? (void*)entry_vkGetDeviceImageSparseMemoryRequirements : nullptr;
-    }
-#endif
-#ifdef VK_KHR_android_surface
-    if (!strcmp(name, "vkCreateAndroidSurfaceKHR")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_KHR_android_surface");
-        return hasExt ? (void*)entry_vkCreateAndroidSurfaceKHR : nullptr;
-    }
-#endif
-#ifdef VK_KHR_dynamic_rendering
-    if (!strcmp(name, "vkCmdBeginRenderingKHR")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_KHR_dynamic_rendering");
-        return hasExt ? (void*)entry_vkCmdBeginRenderingKHR : nullptr;
-    }
-    if (!strcmp(name, "vkCmdEndRenderingKHR")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_KHR_dynamic_rendering");
-        return hasExt ? (void*)entry_vkCmdEndRenderingKHR : nullptr;
-    }
-#endif
-#ifdef VK_KHR_get_physical_device_properties2
-    if (!strcmp(name, "vkGetPhysicalDeviceFeatures2KHR")) {
-        bool hasExt =
-            resources->hasDeviceExtension(device, "VK_KHR_get_physical_device_properties2");
-        return hasExt ? (void*)entry_vkGetPhysicalDeviceFeatures2KHR : nullptr;
-    }
-    if (!strcmp(name, "vkGetPhysicalDeviceProperties2KHR")) {
-        bool hasExt =
-            resources->hasDeviceExtension(device, "VK_KHR_get_physical_device_properties2");
-        return hasExt ? (void*)entry_vkGetPhysicalDeviceProperties2KHR : nullptr;
-    }
-    if (!strcmp(name, "vkGetPhysicalDeviceFormatProperties2KHR")) {
-        bool hasExt =
-            resources->hasDeviceExtension(device, "VK_KHR_get_physical_device_properties2");
-        return hasExt ? (void*)entry_vkGetPhysicalDeviceFormatProperties2KHR : nullptr;
-    }
-    if (!strcmp(name, "vkGetPhysicalDeviceImageFormatProperties2KHR")) {
-        bool hasExt =
-            resources->hasDeviceExtension(device, "VK_KHR_get_physical_device_properties2");
-        return hasExt ? (void*)entry_vkGetPhysicalDeviceImageFormatProperties2KHR : nullptr;
-    }
-    if (!strcmp(name, "vkGetPhysicalDeviceQueueFamilyProperties2KHR")) {
-        bool hasExt =
-            resources->hasDeviceExtension(device, "VK_KHR_get_physical_device_properties2");
-        return hasExt ? (void*)entry_vkGetPhysicalDeviceQueueFamilyProperties2KHR : nullptr;
-    }
-    if (!strcmp(name, "vkGetPhysicalDeviceMemoryProperties2KHR")) {
-        bool hasExt =
-            resources->hasDeviceExtension(device, "VK_KHR_get_physical_device_properties2");
-        return hasExt ? (void*)entry_vkGetPhysicalDeviceMemoryProperties2KHR : nullptr;
-    }
-    if (!strcmp(name, "vkGetPhysicalDeviceSparseImageFormatProperties2KHR")) {
-        bool hasExt =
-            resources->hasDeviceExtension(device, "VK_KHR_get_physical_device_properties2");
-        return hasExt ? (void*)entry_vkGetPhysicalDeviceSparseImageFormatProperties2KHR : nullptr;
-    }
-#endif
-#ifdef VK_KHR_maintenance1
-    if (!strcmp(name, "vkTrimCommandPoolKHR")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_KHR_maintenance1");
-        return hasExt ? (void*)entry_vkTrimCommandPoolKHR : nullptr;
-    }
-#endif
-#ifdef VK_KHR_external_memory_capabilities
-    if (!strcmp(name, "vkGetPhysicalDeviceExternalBufferPropertiesKHR")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_KHR_external_memory_capabilities");
-        return hasExt ? (void*)entry_vkGetPhysicalDeviceExternalBufferPropertiesKHR : nullptr;
-    }
-#endif
-#ifdef VK_KHR_external_semaphore_capabilities
-    if (!strcmp(name, "vkGetPhysicalDeviceExternalSemaphorePropertiesKHR")) {
-        bool hasExt =
-            resources->hasDeviceExtension(device, "VK_KHR_external_semaphore_capabilities");
-        return hasExt ? (void*)entry_vkGetPhysicalDeviceExternalSemaphorePropertiesKHR : nullptr;
-    }
-#endif
-#ifdef VK_KHR_external_semaphore_fd
-    if (!strcmp(name, "vkImportSemaphoreFdKHR")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_KHR_external_semaphore_fd");
-        return hasExt ? (void*)entry_vkImportSemaphoreFdKHR : nullptr;
-    }
-    if (!strcmp(name, "vkGetSemaphoreFdKHR")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_KHR_external_semaphore_fd");
-        return hasExt ? (void*)entry_vkGetSemaphoreFdKHR : nullptr;
-    }
-#endif
-#ifdef VK_KHR_descriptor_update_template
-    if (!strcmp(name, "vkCreateDescriptorUpdateTemplateKHR")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_KHR_descriptor_update_template");
-        return hasExt ? (void*)entry_vkCreateDescriptorUpdateTemplateKHR : nullptr;
-    }
-    if (!strcmp(name, "vkDestroyDescriptorUpdateTemplateKHR")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_KHR_descriptor_update_template");
-        return hasExt ? (void*)entry_vkDestroyDescriptorUpdateTemplateKHR : nullptr;
-    }
-    if (!strcmp(name, "vkUpdateDescriptorSetWithTemplateKHR")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_KHR_descriptor_update_template");
-        return hasExt ? (void*)entry_vkUpdateDescriptorSetWithTemplateKHR : nullptr;
-    }
-#endif
-#ifdef VK_KHR_create_renderpass2
-    if (!strcmp(name, "vkCreateRenderPass2KHR")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_KHR_create_renderpass2");
-        return hasExt ? (void*)entry_vkCreateRenderPass2KHR : nullptr;
-    }
-    if (!strcmp(name, "vkCmdBeginRenderPass2KHR")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_KHR_create_renderpass2");
-        return hasExt ? (void*)entry_vkCmdBeginRenderPass2KHR : nullptr;
-    }
-    if (!strcmp(name, "vkCmdNextSubpass2KHR")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_KHR_create_renderpass2");
-        return hasExt ? (void*)entry_vkCmdNextSubpass2KHR : nullptr;
-    }
-    if (!strcmp(name, "vkCmdEndRenderPass2KHR")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_KHR_create_renderpass2");
-        return hasExt ? (void*)entry_vkCmdEndRenderPass2KHR : nullptr;
-    }
-#endif
-#ifdef VK_KHR_external_fence_capabilities
-    if (!strcmp(name, "vkGetPhysicalDeviceExternalFencePropertiesKHR")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_KHR_external_fence_capabilities");
-        return hasExt ? (void*)entry_vkGetPhysicalDeviceExternalFencePropertiesKHR : nullptr;
-    }
-#endif
-#ifdef VK_KHR_external_fence_fd
-    if (!strcmp(name, "vkImportFenceFdKHR")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_KHR_external_fence_fd");
-        return hasExt ? (void*)entry_vkImportFenceFdKHR : nullptr;
-    }
-    if (!strcmp(name, "vkGetFenceFdKHR")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_KHR_external_fence_fd");
-        return hasExt ? (void*)entry_vkGetFenceFdKHR : nullptr;
-    }
-#endif
-#ifdef VK_KHR_get_memory_requirements2
-    if (!strcmp(name, "vkGetImageMemoryRequirements2KHR")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_KHR_get_memory_requirements2");
-        return hasExt ? (void*)entry_vkGetImageMemoryRequirements2KHR : nullptr;
-    }
-    if (!strcmp(name, "vkGetBufferMemoryRequirements2KHR")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_KHR_get_memory_requirements2");
-        return hasExt ? (void*)entry_vkGetBufferMemoryRequirements2KHR : nullptr;
-    }
-    if (!strcmp(name, "vkGetImageSparseMemoryRequirements2KHR")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_KHR_get_memory_requirements2");
-        return hasExt ? (void*)entry_vkGetImageSparseMemoryRequirements2KHR : nullptr;
-    }
-#endif
-#ifdef VK_KHR_sampler_ycbcr_conversion
-    if (!strcmp(name, "vkCreateSamplerYcbcrConversionKHR")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_KHR_sampler_ycbcr_conversion");
-        return hasExt ? (void*)entry_vkCreateSamplerYcbcrConversionKHR : nullptr;
-    }
-    if (!strcmp(name, "vkDestroySamplerYcbcrConversionKHR")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_KHR_sampler_ycbcr_conversion");
-        return hasExt ? (void*)entry_vkDestroySamplerYcbcrConversionKHR : nullptr;
-    }
-#endif
-#ifdef VK_KHR_bind_memory2
-    if (!strcmp(name, "vkBindBufferMemory2KHR")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_KHR_bind_memory2");
-        return hasExt ? (void*)entry_vkBindBufferMemory2KHR : nullptr;
-    }
-    if (!strcmp(name, "vkBindImageMemory2KHR")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_KHR_bind_memory2");
-        return hasExt ? (void*)entry_vkBindImageMemory2KHR : nullptr;
-    }
-#endif
-#ifdef VK_KHR_maintenance3
-    if (!strcmp(name, "vkGetDescriptorSetLayoutSupportKHR")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_KHR_maintenance3");
-        return hasExt ? (void*)entry_vkGetDescriptorSetLayoutSupportKHR : nullptr;
-    }
-#endif
-#ifdef VK_KHR_buffer_device_address
-    if (!strcmp(name, "vkGetBufferDeviceAddressKHR")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_KHR_buffer_device_address");
-        return hasExt ? (void*)entry_vkGetBufferDeviceAddressKHR : nullptr;
-    }
-    if (!strcmp(name, "vkGetBufferOpaqueCaptureAddressKHR")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_KHR_buffer_device_address");
-        return hasExt ? (void*)entry_vkGetBufferOpaqueCaptureAddressKHR : nullptr;
-    }
-    if (!strcmp(name, "vkGetDeviceMemoryOpaqueCaptureAddressKHR")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_KHR_buffer_device_address");
-        return hasExt ? (void*)entry_vkGetDeviceMemoryOpaqueCaptureAddressKHR : nullptr;
-    }
-#endif
-#ifdef VK_KHR_pipeline_executable_properties
-    if (!strcmp(name, "vkGetPipelineExecutablePropertiesKHR")) {
-        bool hasExt =
-            resources->hasDeviceExtension(device, "VK_KHR_pipeline_executable_properties");
-        return hasExt ? (void*)entry_vkGetPipelineExecutablePropertiesKHR : nullptr;
-    }
-    if (!strcmp(name, "vkGetPipelineExecutableStatisticsKHR")) {
-        bool hasExt =
-            resources->hasDeviceExtension(device, "VK_KHR_pipeline_executable_properties");
-        return hasExt ? (void*)entry_vkGetPipelineExecutableStatisticsKHR : nullptr;
-    }
-    if (!strcmp(name, "vkGetPipelineExecutableInternalRepresentationsKHR")) {
-        bool hasExt =
-            resources->hasDeviceExtension(device, "VK_KHR_pipeline_executable_properties");
-        return hasExt ? (void*)entry_vkGetPipelineExecutableInternalRepresentationsKHR : nullptr;
-    }
-#endif
-#ifdef VK_KHR_synchronization2
-    if (!strcmp(name, "vkCmdSetEvent2KHR")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_KHR_synchronization2");
-        return hasExt ? (void*)entry_vkCmdSetEvent2KHR : nullptr;
-    }
-    if (!strcmp(name, "vkCmdResetEvent2KHR")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_KHR_synchronization2");
-        return hasExt ? (void*)entry_vkCmdResetEvent2KHR : nullptr;
-    }
-    if (!strcmp(name, "vkCmdWaitEvents2KHR")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_KHR_synchronization2");
-        return hasExt ? (void*)entry_vkCmdWaitEvents2KHR : nullptr;
-    }
-    if (!strcmp(name, "vkCmdPipelineBarrier2KHR")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_KHR_synchronization2");
-        return hasExt ? (void*)entry_vkCmdPipelineBarrier2KHR : nullptr;
-    }
-    if (!strcmp(name, "vkCmdWriteTimestamp2KHR")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_KHR_synchronization2");
-        return hasExt ? (void*)entry_vkCmdWriteTimestamp2KHR : nullptr;
-    }
-    if (!strcmp(name, "vkQueueSubmit2KHR")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_KHR_synchronization2");
-        return hasExt ? (void*)entry_vkQueueSubmit2KHR : nullptr;
-    }
-    if (!strcmp(name, "vkCmdWriteBufferMarker2AMD")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_KHR_synchronization2");
-        return hasExt ? (void*)entry_vkCmdWriteBufferMarker2AMD : nullptr;
-    }
-    if (!strcmp(name, "vkGetQueueCheckpointData2NV")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_KHR_synchronization2");
-        return hasExt ? (void*)entry_vkGetQueueCheckpointData2NV : nullptr;
-    }
-#endif
-#ifdef VK_KHR_copy_commands2
-    if (!strcmp(name, "vkCmdCopyBuffer2KHR")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_KHR_copy_commands2");
-        return hasExt ? (void*)entry_vkCmdCopyBuffer2KHR : nullptr;
-    }
-    if (!strcmp(name, "vkCmdCopyImage2KHR")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_KHR_copy_commands2");
-        return hasExt ? (void*)entry_vkCmdCopyImage2KHR : nullptr;
-    }
-    if (!strcmp(name, "vkCmdCopyBufferToImage2KHR")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_KHR_copy_commands2");
-        return hasExt ? (void*)entry_vkCmdCopyBufferToImage2KHR : nullptr;
-    }
-    if (!strcmp(name, "vkCmdCopyImageToBuffer2KHR")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_KHR_copy_commands2");
-        return hasExt ? (void*)entry_vkCmdCopyImageToBuffer2KHR : nullptr;
-    }
-    if (!strcmp(name, "vkCmdBlitImage2KHR")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_KHR_copy_commands2");
-        return hasExt ? (void*)entry_vkCmdBlitImage2KHR : nullptr;
-    }
-    if (!strcmp(name, "vkCmdResolveImage2KHR")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_KHR_copy_commands2");
-        return hasExt ? (void*)entry_vkCmdResolveImage2KHR : nullptr;
-    }
-#endif
-#ifdef VK_KHR_maintenance4
-    if (!strcmp(name, "vkGetDeviceBufferMemoryRequirementsKHR")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_KHR_maintenance4");
-        return hasExt ? (void*)entry_vkGetDeviceBufferMemoryRequirementsKHR : nullptr;
-    }
-    if (!strcmp(name, "vkGetDeviceImageMemoryRequirementsKHR")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_KHR_maintenance4");
-        return hasExt ? (void*)entry_vkGetDeviceImageMemoryRequirementsKHR : nullptr;
-    }
-    if (!strcmp(name, "vkGetDeviceImageSparseMemoryRequirementsKHR")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_KHR_maintenance4");
-        return hasExt ? (void*)entry_vkGetDeviceImageSparseMemoryRequirementsKHR : nullptr;
-    }
-#endif
-#ifdef VK_KHR_maintenance5
-    if (!strcmp(name, "vkCmdBindIndexBuffer2KHR")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_KHR_maintenance5");
-        return hasExt ? (void*)entry_vkCmdBindIndexBuffer2KHR : nullptr;
-    }
-    if (!strcmp(name, "vkGetRenderingAreaGranularityKHR")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_KHR_maintenance5");
-        return hasExt ? (void*)entry_vkGetRenderingAreaGranularityKHR : nullptr;
-    }
-    if (!strcmp(name, "vkGetDeviceImageSubresourceLayoutKHR")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_KHR_maintenance5");
-        return hasExt ? (void*)entry_vkGetDeviceImageSubresourceLayoutKHR : nullptr;
-    }
-    if (!strcmp(name, "vkGetImageSubresourceLayout2KHR")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_KHR_maintenance5");
-        return hasExt ? (void*)entry_vkGetImageSubresourceLayout2KHR : nullptr;
-    }
-#endif
-#ifdef VK_ANDROID_native_buffer
-    if (!strcmp(name, "vkGetSwapchainGrallocUsageANDROID")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_ANDROID_native_buffer");
-        return hasExt ? (void*)entry_vkGetSwapchainGrallocUsageANDROID : nullptr;
-    }
-    if (!strcmp(name, "vkAcquireImageANDROID")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_ANDROID_native_buffer");
-        return hasExt ? (void*)entry_vkAcquireImageANDROID : nullptr;
-    }
-    if (!strcmp(name, "vkQueueSignalReleaseImageANDROID")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_ANDROID_native_buffer");
-        return hasExt ? (void*)entry_vkQueueSignalReleaseImageANDROID : nullptr;
-    }
-    if (!strcmp(name, "vkGetSwapchainGrallocUsage2ANDROID")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_ANDROID_native_buffer");
-        return hasExt ? (void*)entry_vkGetSwapchainGrallocUsage2ANDROID : nullptr;
-    }
-#endif
-#ifdef VK_EXT_transform_feedback
-    if (!strcmp(name, "vkCmdBindTransformFeedbackBuffersEXT")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_EXT_transform_feedback");
-        return hasExt ? (void*)entry_vkCmdBindTransformFeedbackBuffersEXT : nullptr;
-    }
-    if (!strcmp(name, "vkCmdBeginTransformFeedbackEXT")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_EXT_transform_feedback");
-        return hasExt ? (void*)entry_vkCmdBeginTransformFeedbackEXT : nullptr;
-    }
-    if (!strcmp(name, "vkCmdEndTransformFeedbackEXT")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_EXT_transform_feedback");
-        return hasExt ? (void*)entry_vkCmdEndTransformFeedbackEXT : nullptr;
-    }
-    if (!strcmp(name, "vkCmdBeginQueryIndexedEXT")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_EXT_transform_feedback");
-        return hasExt ? (void*)entry_vkCmdBeginQueryIndexedEXT : nullptr;
-    }
-    if (!strcmp(name, "vkCmdEndQueryIndexedEXT")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_EXT_transform_feedback");
-        return hasExt ? (void*)entry_vkCmdEndQueryIndexedEXT : nullptr;
-    }
-    if (!strcmp(name, "vkCmdDrawIndirectByteCountEXT")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_EXT_transform_feedback");
-        return hasExt ? (void*)entry_vkCmdDrawIndirectByteCountEXT : nullptr;
-    }
-#endif
-#ifdef VK_ANDROID_external_memory_android_hardware_buffer
-    if (!strcmp(name, "vkGetAndroidHardwareBufferPropertiesANDROID")) {
-        bool hasExt = resources->hasDeviceExtension(
-            device, "VK_ANDROID_external_memory_android_hardware_buffer");
-        return hasExt ? (void*)entry_vkGetAndroidHardwareBufferPropertiesANDROID : nullptr;
-    }
-    if (!strcmp(name, "vkGetMemoryAndroidHardwareBufferANDROID")) {
-        bool hasExt = resources->hasDeviceExtension(
-            device, "VK_ANDROID_external_memory_android_hardware_buffer");
-        return hasExt ? (void*)entry_vkGetMemoryAndroidHardwareBufferANDROID : nullptr;
-    }
-#endif
-#ifdef VK_EXT_tooling_info
-    if (!strcmp(name, "vkGetPhysicalDeviceToolPropertiesEXT")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_EXT_tooling_info");
-        return hasExt ? (void*)entry_vkGetPhysicalDeviceToolPropertiesEXT : nullptr;
-    }
-#endif
-#ifdef VK_EXT_line_rasterization
-    if (!strcmp(name, "vkCmdSetLineStippleEXT")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_EXT_line_rasterization");
-        return hasExt ? (void*)entry_vkCmdSetLineStippleEXT : nullptr;
-    }
-#endif
-#ifdef VK_EXT_extended_dynamic_state
-    if (!strcmp(name, "vkCmdSetCullModeEXT")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_EXT_extended_dynamic_state");
-        return hasExt ? (void*)entry_vkCmdSetCullModeEXT : nullptr;
-    }
-    if (!strcmp(name, "vkCmdSetFrontFaceEXT")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_EXT_extended_dynamic_state");
-        return hasExt ? (void*)entry_vkCmdSetFrontFaceEXT : nullptr;
-    }
-    if (!strcmp(name, "vkCmdSetPrimitiveTopologyEXT")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_EXT_extended_dynamic_state");
-        return hasExt ? (void*)entry_vkCmdSetPrimitiveTopologyEXT : nullptr;
-    }
-    if (!strcmp(name, "vkCmdSetViewportWithCountEXT")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_EXT_extended_dynamic_state");
-        return hasExt ? (void*)entry_vkCmdSetViewportWithCountEXT : nullptr;
-    }
-    if (!strcmp(name, "vkCmdSetScissorWithCountEXT")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_EXT_extended_dynamic_state");
-        return hasExt ? (void*)entry_vkCmdSetScissorWithCountEXT : nullptr;
-    }
-    if (!strcmp(name, "vkCmdBindVertexBuffers2EXT")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_EXT_extended_dynamic_state");
-        return hasExt ? (void*)entry_vkCmdBindVertexBuffers2EXT : nullptr;
-    }
-    if (!strcmp(name, "vkCmdSetDepthTestEnableEXT")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_EXT_extended_dynamic_state");
-        return hasExt ? (void*)entry_vkCmdSetDepthTestEnableEXT : nullptr;
-    }
-    if (!strcmp(name, "vkCmdSetDepthWriteEnableEXT")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_EXT_extended_dynamic_state");
-        return hasExt ? (void*)entry_vkCmdSetDepthWriteEnableEXT : nullptr;
-    }
-    if (!strcmp(name, "vkCmdSetDepthCompareOpEXT")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_EXT_extended_dynamic_state");
-        return hasExt ? (void*)entry_vkCmdSetDepthCompareOpEXT : nullptr;
-    }
-    if (!strcmp(name, "vkCmdSetDepthBoundsTestEnableEXT")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_EXT_extended_dynamic_state");
-        return hasExt ? (void*)entry_vkCmdSetDepthBoundsTestEnableEXT : nullptr;
-    }
-    if (!strcmp(name, "vkCmdSetStencilTestEnableEXT")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_EXT_extended_dynamic_state");
-        return hasExt ? (void*)entry_vkCmdSetStencilTestEnableEXT : nullptr;
-    }
-    if (!strcmp(name, "vkCmdSetStencilOpEXT")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_EXT_extended_dynamic_state");
-        return hasExt ? (void*)entry_vkCmdSetStencilOpEXT : nullptr;
-    }
-#endif
-#ifdef VK_EXT_host_image_copy
-    if (!strcmp(name, "vkCopyMemoryToImageEXT")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_EXT_host_image_copy");
-        return hasExt ? (void*)entry_vkCopyMemoryToImageEXT : nullptr;
-    }
-    if (!strcmp(name, "vkCopyImageToMemoryEXT")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_EXT_host_image_copy");
-        return hasExt ? (void*)entry_vkCopyImageToMemoryEXT : nullptr;
-    }
-    if (!strcmp(name, "vkCopyImageToImageEXT")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_EXT_host_image_copy");
-        return hasExt ? (void*)entry_vkCopyImageToImageEXT : nullptr;
-    }
-    if (!strcmp(name, "vkTransitionImageLayoutEXT")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_EXT_host_image_copy");
-        return hasExt ? (void*)entry_vkTransitionImageLayoutEXT : nullptr;
-    }
-    if (!strcmp(name, "vkGetImageSubresourceLayout2EXT")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_EXT_host_image_copy");
-        return hasExt ? (void*)entry_vkGetImageSubresourceLayout2EXT : nullptr;
-    }
-#endif
-#ifdef VK_EXT_private_data
-    if (!strcmp(name, "vkCreatePrivateDataSlotEXT")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_EXT_private_data");
-        return hasExt ? (void*)entry_vkCreatePrivateDataSlotEXT : nullptr;
-    }
-    if (!strcmp(name, "vkDestroyPrivateDataSlotEXT")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_EXT_private_data");
-        return hasExt ? (void*)entry_vkDestroyPrivateDataSlotEXT : nullptr;
-    }
-    if (!strcmp(name, "vkSetPrivateDataEXT")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_EXT_private_data");
-        return hasExt ? (void*)entry_vkSetPrivateDataEXT : nullptr;
-    }
-    if (!strcmp(name, "vkGetPrivateDataEXT")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_EXT_private_data");
-        return hasExt ? (void*)entry_vkGetPrivateDataEXT : nullptr;
-    }
-#endif
-#ifdef VK_EXT_extended_dynamic_state2
-    if (!strcmp(name, "vkCmdSetPatchControlPointsEXT")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_EXT_extended_dynamic_state2");
-        return hasExt ? (void*)entry_vkCmdSetPatchControlPointsEXT : nullptr;
-    }
-    if (!strcmp(name, "vkCmdSetRasterizerDiscardEnableEXT")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_EXT_extended_dynamic_state2");
-        return hasExt ? (void*)entry_vkCmdSetRasterizerDiscardEnableEXT : nullptr;
-    }
-    if (!strcmp(name, "vkCmdSetDepthBiasEnableEXT")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_EXT_extended_dynamic_state2");
-        return hasExt ? (void*)entry_vkCmdSetDepthBiasEnableEXT : nullptr;
-    }
-    if (!strcmp(name, "vkCmdSetLogicOpEXT")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_EXT_extended_dynamic_state2");
-        return hasExt ? (void*)entry_vkCmdSetLogicOpEXT : nullptr;
-    }
-    if (!strcmp(name, "vkCmdSetPrimitiveRestartEnableEXT")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_EXT_extended_dynamic_state2");
-        return hasExt ? (void*)entry_vkCmdSetPrimitiveRestartEnableEXT : nullptr;
-    }
-#endif
-#ifdef VK_GOOGLE_gfxstream
-    if (!strcmp(name, "vkMapMemoryIntoAddressSpaceGOOGLE")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_GOOGLE_gfxstream");
-        return hasExt ? (void*)entry_vkMapMemoryIntoAddressSpaceGOOGLE : nullptr;
-    }
-    if (!strcmp(name, "vkUpdateDescriptorSetWithTemplateSizedGOOGLE")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_GOOGLE_gfxstream");
-        return hasExt ? (void*)entry_vkUpdateDescriptorSetWithTemplateSizedGOOGLE : nullptr;
-    }
-    if (!strcmp(name, "vkBeginCommandBufferAsyncGOOGLE")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_GOOGLE_gfxstream");
-        return hasExt ? (void*)entry_vkBeginCommandBufferAsyncGOOGLE : nullptr;
-    }
-    if (!strcmp(name, "vkEndCommandBufferAsyncGOOGLE")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_GOOGLE_gfxstream");
-        return hasExt ? (void*)entry_vkEndCommandBufferAsyncGOOGLE : nullptr;
-    }
-    if (!strcmp(name, "vkResetCommandBufferAsyncGOOGLE")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_GOOGLE_gfxstream");
-        return hasExt ? (void*)entry_vkResetCommandBufferAsyncGOOGLE : nullptr;
-    }
-    if (!strcmp(name, "vkCommandBufferHostSyncGOOGLE")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_GOOGLE_gfxstream");
-        return hasExt ? (void*)entry_vkCommandBufferHostSyncGOOGLE : nullptr;
-    }
-    if (!strcmp(name, "vkCreateImageWithRequirementsGOOGLE")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_GOOGLE_gfxstream");
-        return hasExt ? (void*)entry_vkCreateImageWithRequirementsGOOGLE : nullptr;
-    }
-    if (!strcmp(name, "vkCreateBufferWithRequirementsGOOGLE")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_GOOGLE_gfxstream");
-        return hasExt ? (void*)entry_vkCreateBufferWithRequirementsGOOGLE : nullptr;
-    }
-    if (!strcmp(name, "vkGetMemoryHostAddressInfoGOOGLE")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_GOOGLE_gfxstream");
-        return hasExt ? (void*)entry_vkGetMemoryHostAddressInfoGOOGLE : nullptr;
-    }
-    if (!strcmp(name, "vkFreeMemorySyncGOOGLE")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_GOOGLE_gfxstream");
-        return hasExt ? (void*)entry_vkFreeMemorySyncGOOGLE : nullptr;
-    }
-    if (!strcmp(name, "vkQueueHostSyncGOOGLE")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_GOOGLE_gfxstream");
-        return hasExt ? (void*)entry_vkQueueHostSyncGOOGLE : nullptr;
-    }
-    if (!strcmp(name, "vkQueueSubmitAsyncGOOGLE")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_GOOGLE_gfxstream");
-        return hasExt ? (void*)entry_vkQueueSubmitAsyncGOOGLE : nullptr;
-    }
-    if (!strcmp(name, "vkQueueWaitIdleAsyncGOOGLE")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_GOOGLE_gfxstream");
-        return hasExt ? (void*)entry_vkQueueWaitIdleAsyncGOOGLE : nullptr;
-    }
-    if (!strcmp(name, "vkQueueBindSparseAsyncGOOGLE")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_GOOGLE_gfxstream");
-        return hasExt ? (void*)entry_vkQueueBindSparseAsyncGOOGLE : nullptr;
-    }
-    if (!strcmp(name, "vkGetLinearImageLayoutGOOGLE")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_GOOGLE_gfxstream");
-        return hasExt ? (void*)entry_vkGetLinearImageLayoutGOOGLE : nullptr;
-    }
-    if (!strcmp(name, "vkGetLinearImageLayout2GOOGLE")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_GOOGLE_gfxstream");
-        return hasExt ? (void*)entry_vkGetLinearImageLayout2GOOGLE : nullptr;
-    }
-    if (!strcmp(name, "vkQueueFlushCommandsGOOGLE")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_GOOGLE_gfxstream");
-        return hasExt ? (void*)entry_vkQueueFlushCommandsGOOGLE : nullptr;
-    }
-    if (!strcmp(name, "vkQueueCommitDescriptorSetUpdatesGOOGLE")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_GOOGLE_gfxstream");
-        return hasExt ? (void*)entry_vkQueueCommitDescriptorSetUpdatesGOOGLE : nullptr;
-    }
-    if (!strcmp(name, "vkCollectDescriptorPoolIdsGOOGLE")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_GOOGLE_gfxstream");
-        return hasExt ? (void*)entry_vkCollectDescriptorPoolIdsGOOGLE : nullptr;
-    }
-    if (!strcmp(name, "vkQueueSignalReleaseImageANDROIDAsyncGOOGLE")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_GOOGLE_gfxstream");
-        return hasExt ? (void*)entry_vkQueueSignalReleaseImageANDROIDAsyncGOOGLE : nullptr;
-    }
-    if (!strcmp(name, "vkQueueFlushCommandsFromAuxMemoryGOOGLE")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_GOOGLE_gfxstream");
-        return hasExt ? (void*)entry_vkQueueFlushCommandsFromAuxMemoryGOOGLE : nullptr;
-    }
-    if (!strcmp(name, "vkGetBlobGOOGLE")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_GOOGLE_gfxstream");
-        return hasExt ? (void*)entry_vkGetBlobGOOGLE : nullptr;
-    }
-    if (!strcmp(name, "vkUpdateDescriptorSetWithTemplateSized2GOOGLE")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_GOOGLE_gfxstream");
-        return hasExt ? (void*)entry_vkUpdateDescriptorSetWithTemplateSized2GOOGLE : nullptr;
-    }
-    if (!strcmp(name, "vkQueueSubmitAsync2GOOGLE")) {
-        bool hasExt = resources->hasDeviceExtension(device, "VK_GOOGLE_gfxstream");
-        return hasExt ? (void*)entry_vkQueueSubmitAsync2GOOGLE : nullptr;
-    }
+#ifdef VK_QNX_external_memory_screen_buffer
 #endif
-    return nullptr;
-}
-
-}  // namespace vk
-}  // namespace gfxstream
diff --git a/guest/vulkan_enc/gfxstream_vk_private.cpp b/guest/vulkan_enc/gfxstream_vk_private.cpp
new file mode 100644
index 0000000..ba552ea
--- /dev/null
+++ b/guest/vulkan_enc/gfxstream_vk_private.cpp
@@ -0,0 +1,53 @@
+// Copyright (C) 2023 The Android Open Source Project
+//
+// 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.
+
+#include "gfxstream_vk_private.h"
+
+#include "vk_sync_dummy.h"
+
+static bool isNoopSemaphore(gfxstream_vk_semaphore* semaphore) {
+    /* Under the assumption that Mesa VK runtime queue submission is used, WSI flow
+     * sets this temporary state to a dummy sync type (when no explicit dma-buf
+     * synchronization is available). For gfxstream case, ignore this semaphore
+     * when this is the case. Synchronization will be done on the host.
+     */
+    return (semaphore && semaphore->vk.temporary &&
+            vk_sync_type_is_dummy(semaphore->vk.temporary->type));
+}
+
+std::vector<VkSemaphore> transformVkSemaphoreList(const VkSemaphore* pSemaphores,
+                                                  uint32_t semaphoreCount) {
+    std::vector<VkSemaphore> outSemaphores;
+    for (uint32_t j = 0; j < semaphoreCount; ++j) {
+        VK_FROM_HANDLE(gfxstream_vk_semaphore, gfxstream_semaphore, pSemaphores[j]);
+        if (!isNoopSemaphore(gfxstream_semaphore)) {
+            outSemaphores.push_back(gfxstream_semaphore->internal_object);
+        }
+    }
+    return outSemaphores;
+}
+
+std::vector<VkSemaphoreSubmitInfo> transformVkSemaphoreSubmitInfoList(
+    const VkSemaphoreSubmitInfo* pSemaphoreSubmitInfos, uint32_t semaphoreSubmitInfoCount) {
+    std::vector<VkSemaphoreSubmitInfo> outSemaphoreSubmitInfo;
+    for (uint32_t j = 0; j < semaphoreSubmitInfoCount; ++j) {
+        VkSemaphoreSubmitInfo outInfo = pSemaphoreSubmitInfos[j];
+        VK_FROM_HANDLE(gfxstream_vk_semaphore, gfxstream_semaphore, outInfo.semaphore);
+        if (!isNoopSemaphore(gfxstream_semaphore)) {
+            outInfo.semaphore = gfxstream_semaphore->internal_object;
+            outSemaphoreSubmitInfo.push_back(outInfo);
+        }
+    }
+    return outSemaphoreSubmitInfo;
+}
diff --git a/guest/vulkan_enc/gfxstream_vk_private.h b/guest/vulkan_enc/gfxstream_vk_private.h
new file mode 100644
index 0000000..5062854
--- /dev/null
+++ b/guest/vulkan_enc/gfxstream_vk_private.h
@@ -0,0 +1,246 @@
+/*
+ * Copyright © 2023 Google Inc.
+ *
+ * derived from panvk_private.h driver which is:
+ * Copyright © 2021 Collabora Ltd.
+ * Copyright © 2016 Red Hat.
+ * Copyright © 2016 Bas Nieuwenhuizen
+ * Copyright © 2015 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef GFXSTREAM_VK_PRIVATE_H
+#define GFXSTREAM_VK_PRIVATE_H
+
+#include <assert.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <vulkan/vk_icd.h>
+#include <vulkan/vulkan.h>
+
+#include <vector>
+
+#include "gfxstream_vk_entrypoints.h"
+#include "vk_alloc.h"
+#include "vk_buffer.h"
+#include "vk_buffer_view.h"
+#include "vk_command_buffer.h"
+#include "vk_command_pool.h"
+#include "vk_descriptor_update_template.h"
+#include "vk_device.h"
+#include "vk_device_memory.h"
+#include "vk_extensions.h"
+#include "vk_fence.h"
+#include "vk_image.h"
+#include "vk_instance.h"
+#include "vk_log.h"
+#include "vk_object.h"
+#include "vk_physical_device.h"
+#include "vk_query_pool.h"
+#include "vk_queue.h"
+#include "vk_semaphore.h"
+#include "vulkan/wsi/wsi_common.h"
+
+struct gfxstream_vk_instance {
+    struct vk_instance vk;
+    uint32_t api_version;
+    VkInstance internal_object;
+};
+
+struct gfxstream_vk_physical_device {
+    struct vk_physical_device vk;
+
+    struct wsi_device wsi_device;
+    const struct vk_sync_type* sync_types[2];
+    struct gfxstream_vk_instance* instance;
+    VkPhysicalDevice internal_object;
+};
+
+struct gfxstream_vk_device {
+    struct vk_device vk;
+
+    struct vk_device_dispatch_table cmd_dispatch;
+    struct gfxstream_vk_physical_device* physical_device;
+    VkDevice internal_object;
+};
+
+struct gfxstream_vk_queue {
+    struct vk_queue vk;
+    struct gfxstream_vk_device* device;
+    VkQueue internal_object;
+};
+
+struct gfxstream_vk_pipeline_cache {
+    struct vk_object_base base;
+    VkPipelineCache internal_object;
+};
+
+struct gfxstream_vk_device_memory {
+    struct vk_device_memory vk;
+    VkDeviceMemory internal_object;
+};
+
+struct gfxstream_vk_descriptor_set_layout {
+    struct vk_object_base base;
+    VkDescriptorSetLayout internal_object;
+};
+
+struct gfxstream_vk_pipeline_layout {
+    struct vk_object_base base;
+    VkPipelineLayout internal_object;
+};
+
+struct gfxstream_vk_descriptor_pool {
+    struct vk_object_base base;
+    VkDescriptorPool internal_object;
+};
+
+struct gfxstream_vk_buffer {
+    struct vk_buffer vk;
+    VkBuffer internal_object;
+};
+
+struct gfxstream_vk_command_pool {
+    struct vk_command_pool vk;
+    VkCommandPool internal_object;
+};
+
+struct gfxstream_vk_command_buffer {
+    struct vk_command_buffer vk;
+    VkCommandBuffer internal_object;
+};
+
+struct gfxstream_vk_event {
+    struct vk_object_base base;
+    VkEvent internal_object;
+};
+
+struct gfxstream_vk_pipeline {
+    struct vk_object_base base;
+    VkPipeline internal_object;
+};
+
+struct gfxstream_vk_image {
+    struct vk_image vk;
+    VkImage internal_object;
+};
+
+struct gfxstream_vk_image_view {
+    struct vk_image_view vk;
+    VkImageView internal_object;
+};
+
+struct gfxstream_vk_buffer_view {
+    struct vk_buffer_view vk;
+    VkBufferView internal_object;
+};
+
+struct gfxstream_vk_framebuffer {
+    struct vk_object_base base;
+    VkFramebuffer internal_object;
+};
+
+struct gfxstream_vk_render_pass {
+    struct vk_object_base base;
+    VkRenderPass internal_object;
+};
+
+struct gfxstream_vk_fence {
+    struct vk_fence vk;
+    VkFence internal_object;
+};
+
+struct gfxstream_vk_semaphore {
+    struct vk_semaphore vk;
+    VkSemaphore internal_object;
+};
+
+struct gfxstream_vk_query_pool {
+    struct vk_query_pool vk;
+    VkQueryPool internal_object;
+};
+
+struct gfxstream_vk_shader_module {
+    struct vk_object_base base;
+    VkShaderModule internal_object;
+};
+
+struct gfxstream_vk_descriptor_update_template {
+    struct vk_object_base base;
+    VkDescriptorUpdateTemplate internal_object;
+};
+
+VK_DEFINE_HANDLE_CASTS(gfxstream_vk_command_buffer, vk.base, VkCommandBuffer,
+                       VK_OBJECT_TYPE_COMMAND_BUFFER)
+VK_DEFINE_HANDLE_CASTS(gfxstream_vk_device, vk.base, VkDevice, VK_OBJECT_TYPE_DEVICE)
+VK_DEFINE_HANDLE_CASTS(gfxstream_vk_instance, vk.base, VkInstance, VK_OBJECT_TYPE_INSTANCE)
+VK_DEFINE_HANDLE_CASTS(gfxstream_vk_physical_device, vk.base, VkPhysicalDevice,
+                       VK_OBJECT_TYPE_PHYSICAL_DEVICE)
+VK_DEFINE_HANDLE_CASTS(gfxstream_vk_queue, vk.base, VkQueue, VK_OBJECT_TYPE_QUEUE)
+
+VK_DEFINE_NONDISP_HANDLE_CASTS(gfxstream_vk_command_pool, vk.base, VkCommandPool,
+                               VK_OBJECT_TYPE_COMMAND_POOL)
+VK_DEFINE_NONDISP_HANDLE_CASTS(gfxstream_vk_buffer, vk.base, VkBuffer, VK_OBJECT_TYPE_BUFFER)
+VK_DEFINE_NONDISP_HANDLE_CASTS(gfxstream_vk_buffer_view, vk.base, VkBufferView,
+                               VK_OBJECT_TYPE_BUFFER_VIEW)
+VK_DEFINE_NONDISP_HANDLE_CASTS(gfxstream_vk_descriptor_pool, base, VkDescriptorPool,
+                               VK_OBJECT_TYPE_DESCRIPTOR_POOL)
+VK_DEFINE_NONDISP_HANDLE_CASTS(gfxstream_vk_descriptor_set_layout, base, VkDescriptorSetLayout,
+                               VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT)
+VK_DEFINE_NONDISP_HANDLE_CASTS(gfxstream_vk_device_memory, vk.base, VkDeviceMemory,
+                               VK_OBJECT_TYPE_DEVICE_MEMORY)
+VK_DEFINE_NONDISP_HANDLE_CASTS(gfxstream_vk_event, base, VkEvent, VK_OBJECT_TYPE_EVENT)
+VK_DEFINE_NONDISP_HANDLE_CASTS(gfxstream_vk_framebuffer, base, VkFramebuffer,
+                               VK_OBJECT_TYPE_FRAMEBUFFER)
+VK_DEFINE_NONDISP_HANDLE_CASTS(gfxstream_vk_image, vk.base, VkImage, VK_OBJECT_TYPE_IMAGE)
+VK_DEFINE_NONDISP_HANDLE_CASTS(gfxstream_vk_image_view, vk.base, VkImageView,
+                               VK_OBJECT_TYPE_IMAGE_VIEW);
+VK_DEFINE_NONDISP_HANDLE_CASTS(gfxstream_vk_pipeline_cache, base, VkPipelineCache,
+                               VK_OBJECT_TYPE_PIPELINE_CACHE)
+VK_DEFINE_NONDISP_HANDLE_CASTS(gfxstream_vk_pipeline, base, VkPipeline, VK_OBJECT_TYPE_PIPELINE)
+VK_DEFINE_NONDISP_HANDLE_CASTS(gfxstream_vk_pipeline_layout, base, VkPipelineLayout,
+                               VK_OBJECT_TYPE_PIPELINE_LAYOUT)
+VK_DEFINE_NONDISP_HANDLE_CASTS(gfxstream_vk_render_pass, base, VkRenderPass,
+                               VK_OBJECT_TYPE_RENDER_PASS)
+VK_DEFINE_NONDISP_HANDLE_CASTS(gfxstream_vk_fence, vk.base, VkFence, VK_OBJECT_TYPE_FENCE)
+VK_DEFINE_NONDISP_HANDLE_CASTS(gfxstream_vk_semaphore, vk.base, VkSemaphore,
+                               VK_OBJECT_TYPE_SEMAPHORE)
+VK_DEFINE_NONDISP_HANDLE_CASTS(gfxstream_vk_query_pool, vk.base, VkQueryPool,
+                               VK_OBJECT_TYPE_QUERY_POOL)
+VK_DEFINE_NONDISP_HANDLE_CASTS(gfxstream_vk_shader_module, base, VkShaderModule,
+                               VK_OBJECT_TYPE_SHADER_MODULE)
+VK_DEFINE_NONDISP_HANDLE_CASTS(gfxstream_vk_descriptor_update_template, base,
+                               VkDescriptorUpdateTemplate,
+                               VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE)
+
+VkResult gfxstream_vk_wsi_init(struct gfxstream_vk_physical_device* physical_device);
+
+void gfxstream_vk_wsi_finish(struct gfxstream_vk_physical_device* physical_device);
+
+std::vector<VkSemaphore> transformVkSemaphoreList(const VkSemaphore* pSemaphores,
+                                                  uint32_t semaphoreCount);
+
+std::vector<VkSemaphoreSubmitInfo> transformVkSemaphoreSubmitInfoList(
+    const VkSemaphoreSubmitInfo* pSemaphoreSubmitInfos, uint32_t semaphoreSubmitInfoCount);
+
+#endif /* GFXSTREAM_VK_PRIVATE_H */
diff --git a/guest/vulkan_enc/goldfish_vk_counting_guest.cpp b/guest/vulkan_enc/goldfish_vk_counting_guest.cpp
index baa197b..0ca2b28 100644
--- a/guest/vulkan_enc/goldfish_vk_counting_guest.cpp
+++ b/guest/vulkan_enc/goldfish_vk_counting_guest.cpp
@@ -6411,6 +6411,39 @@
 #endif
 #ifdef VK_EXT_texture_compression_astc_hdr
 #endif
+#ifdef VK_EXT_depth_clip_enable
+void count_VkPhysicalDeviceDepthClipEnableFeaturesEXT(
+    uint32_t featureBits, VkStructureType rootType,
+    const VkPhysicalDeviceDepthClipEnableFeaturesEXT* toCount, size_t* count) {
+    (void)featureBits;
+    (void)rootType;
+    (void)toCount;
+    (void)count;
+    *count += sizeof(VkStructureType);
+    if (rootType == VK_STRUCTURE_TYPE_MAX_ENUM) {
+        rootType = toCount->sType;
+    }
+    count_extension_struct(featureBits, rootType, toCount->pNext, count);
+    *count += sizeof(VkBool32);
+}
+
+void count_VkPipelineRasterizationDepthClipStateCreateInfoEXT(
+    uint32_t featureBits, VkStructureType rootType,
+    const VkPipelineRasterizationDepthClipStateCreateInfoEXT* toCount, size_t* count) {
+    (void)featureBits;
+    (void)rootType;
+    (void)toCount;
+    (void)count;
+    *count += sizeof(VkStructureType);
+    if (rootType == VK_STRUCTURE_TYPE_MAX_ENUM) {
+        rootType = toCount->sType;
+    }
+    count_extension_struct(featureBits, rootType, toCount->pNext, count);
+    *count += sizeof(VkPipelineRasterizationDepthClipStateCreateFlagsEXT);
+    *count += sizeof(VkBool32);
+}
+
+#endif
 #ifdef VK_EXT_swapchain_colorspace
 #endif
 #ifdef VK_EXT_queue_family_foreign
@@ -7232,6 +7265,8 @@
 }
 
 #endif
+#ifdef VK_QNX_external_memory_screen_buffer
+#endif
 void count_extension_struct(uint32_t featureBits, VkStructureType rootType,
                             const void* structExtension, size_t* count) {
     VkInstanceCreateInfo* structAccess = (VkInstanceCreateInfo*)(structExtension);
@@ -8127,6 +8162,24 @@
             break;
         }
 #endif
+#ifdef VK_EXT_depth_clip_enable
+        case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLIP_ENABLE_FEATURES_EXT: {
+            count_VkPhysicalDeviceDepthClipEnableFeaturesEXT(
+                featureBits, rootType,
+                reinterpret_cast<const VkPhysicalDeviceDepthClipEnableFeaturesEXT*>(
+                    structExtension),
+                count);
+            break;
+        }
+        case VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_DEPTH_CLIP_STATE_CREATE_INFO_EXT: {
+            count_VkPipelineRasterizationDepthClipStateCreateInfoEXT(
+                featureBits, rootType,
+                reinterpret_cast<const VkPipelineRasterizationDepthClipStateCreateInfoEXT*>(
+                    structExtension),
+                count);
+            break;
+        }
+#endif
 #ifdef VK_EXT_vertex_attribute_divisor
         case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_PROPERTIES_EXT: {
             count_VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT(
diff --git a/guest/vulkan_enc/goldfish_vk_counting_guest.h b/guest/vulkan_enc/goldfish_vk_counting_guest.h
index 3b6e71a..d8db6b2 100644
--- a/guest/vulkan_enc/goldfish_vk_counting_guest.h
+++ b/guest/vulkan_enc/goldfish_vk_counting_guest.h
@@ -1512,6 +1512,16 @@
                       count_VkPhysicalDeviceTextureCompressionASTCHDRFeaturesEXT)
 
 #endif
+#ifdef VK_EXT_depth_clip_enable
+void count_VkPhysicalDeviceDepthClipEnableFeaturesEXT(
+    uint32_t featureBits, VkStructureType rootType,
+    const VkPhysicalDeviceDepthClipEnableFeaturesEXT* toCount, size_t* count);
+
+void count_VkPipelineRasterizationDepthClipStateCreateInfoEXT(
+    uint32_t featureBits, VkStructureType rootType,
+    const VkPipelineRasterizationDepthClipStateCreateInfoEXT* toCount, size_t* count);
+
+#endif
 #ifdef VK_EXT_swapchain_colorspace
 #endif
 #ifdef VK_EXT_queue_family_foreign
@@ -1799,6 +1809,8 @@
     const VkPhysicalDeviceImageCompressionControlSwapchainFeaturesEXT* toCount, size_t* count);
 
 #endif
+#ifdef VK_QNX_external_memory_screen_buffer
+#endif
 
 }  // namespace vk
 }  // namespace gfxstream
diff --git a/guest/vulkan_enc/goldfish_vk_deepcopy_guest.cpp b/guest/vulkan_enc/goldfish_vk_deepcopy_guest.cpp
index a9edede..23cc624 100644
--- a/guest/vulkan_enc/goldfish_vk_deepcopy_guest.cpp
+++ b/guest/vulkan_enc/goldfish_vk_deepcopy_guest.cpp
@@ -7395,6 +7395,54 @@
 #endif
 #ifdef VK_EXT_texture_compression_astc_hdr
 #endif
+#ifdef VK_EXT_depth_clip_enable
+void deepcopy_VkPhysicalDeviceDepthClipEnableFeaturesEXT(
+    Allocator* alloc, VkStructureType rootType,
+    const VkPhysicalDeviceDepthClipEnableFeaturesEXT* from,
+    VkPhysicalDeviceDepthClipEnableFeaturesEXT* to) {
+    (void)alloc;
+    (void)rootType;
+    *to = *from;
+    if (rootType == VK_STRUCTURE_TYPE_MAX_ENUM) {
+        rootType = from->sType;
+    }
+    const void* from_pNext = from;
+    size_t pNext_size = 0u;
+    while (!pNext_size && from_pNext) {
+        from_pNext = static_cast<const vk_struct_common*>(from_pNext)->pNext;
+        pNext_size = goldfish_vk_extension_struct_size(rootType, from_pNext);
+    }
+    to->pNext = nullptr;
+    if (pNext_size) {
+        to->pNext = (void*)alloc->alloc(pNext_size);
+        deepcopy_extension_struct(alloc, rootType, from_pNext, (void*)(to->pNext));
+    }
+}
+
+void deepcopy_VkPipelineRasterizationDepthClipStateCreateInfoEXT(
+    Allocator* alloc, VkStructureType rootType,
+    const VkPipelineRasterizationDepthClipStateCreateInfoEXT* from,
+    VkPipelineRasterizationDepthClipStateCreateInfoEXT* to) {
+    (void)alloc;
+    (void)rootType;
+    *to = *from;
+    if (rootType == VK_STRUCTURE_TYPE_MAX_ENUM) {
+        rootType = from->sType;
+    }
+    const void* from_pNext = from;
+    size_t pNext_size = 0u;
+    while (!pNext_size && from_pNext) {
+        from_pNext = static_cast<const vk_struct_common*>(from_pNext)->pNext;
+        pNext_size = goldfish_vk_extension_struct_size(rootType, from_pNext);
+    }
+    to->pNext = nullptr;
+    if (pNext_size) {
+        to->pNext = (void*)alloc->alloc(pNext_size);
+        deepcopy_extension_struct(alloc, rootType, from_pNext, (void*)(to->pNext));
+    }
+}
+
+#endif
 #ifdef VK_EXT_swapchain_colorspace
 #endif
 #ifdef VK_EXT_queue_family_foreign
@@ -8513,6 +8561,8 @@
 }
 
 #endif
+#ifdef VK_QNX_external_memory_screen_buffer
+#endif
 void deepcopy_extension_struct(Allocator* alloc, VkStructureType rootType,
                                const void* structExtension, void* structExtension_out) {
     if (!structExtension) {
@@ -9462,6 +9512,25 @@
             break;
         }
 #endif
+#ifdef VK_EXT_depth_clip_enable
+        case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLIP_ENABLE_FEATURES_EXT: {
+            deepcopy_VkPhysicalDeviceDepthClipEnableFeaturesEXT(
+                alloc, rootType,
+                reinterpret_cast<const VkPhysicalDeviceDepthClipEnableFeaturesEXT*>(
+                    structExtension),
+                reinterpret_cast<VkPhysicalDeviceDepthClipEnableFeaturesEXT*>(structExtension_out));
+            break;
+        }
+        case VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_DEPTH_CLIP_STATE_CREATE_INFO_EXT: {
+            deepcopy_VkPipelineRasterizationDepthClipStateCreateInfoEXT(
+                alloc, rootType,
+                reinterpret_cast<const VkPipelineRasterizationDepthClipStateCreateInfoEXT*>(
+                    structExtension),
+                reinterpret_cast<VkPipelineRasterizationDepthClipStateCreateInfoEXT*>(
+                    structExtension_out));
+            break;
+        }
+#endif
 #ifdef VK_EXT_vertex_attribute_divisor
         case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_PROPERTIES_EXT: {
             deepcopy_VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT(
diff --git a/guest/vulkan_enc/goldfish_vk_deepcopy_guest.h b/guest/vulkan_enc/goldfish_vk_deepcopy_guest.h
index f6a7fdb..da8bc90 100644
--- a/guest/vulkan_enc/goldfish_vk_deepcopy_guest.h
+++ b/guest/vulkan_enc/goldfish_vk_deepcopy_guest.h
@@ -1653,6 +1653,18 @@
                       deepcopy_VkPhysicalDeviceTextureCompressionASTCHDRFeaturesEXT)
 
 #endif
+#ifdef VK_EXT_depth_clip_enable
+void deepcopy_VkPhysicalDeviceDepthClipEnableFeaturesEXT(
+    Allocator* alloc, VkStructureType rootType,
+    const VkPhysicalDeviceDepthClipEnableFeaturesEXT* from,
+    VkPhysicalDeviceDepthClipEnableFeaturesEXT* to);
+
+void deepcopy_VkPipelineRasterizationDepthClipStateCreateInfoEXT(
+    Allocator* alloc, VkStructureType rootType,
+    const VkPipelineRasterizationDepthClipStateCreateInfoEXT* from,
+    VkPipelineRasterizationDepthClipStateCreateInfoEXT* to);
+
+#endif
 #ifdef VK_EXT_swapchain_colorspace
 #endif
 #ifdef VK_EXT_queue_family_foreign
@@ -1975,6 +1987,8 @@
     VkPhysicalDeviceImageCompressionControlSwapchainFeaturesEXT* to);
 
 #endif
+#ifdef VK_QNX_external_memory_screen_buffer
+#endif
 
 }  // namespace vk
 }  // namespace gfxstream
diff --git a/guest/vulkan_enc/goldfish_vk_extension_structs_guest.cpp b/guest/vulkan_enc/goldfish_vk_extension_structs_guest.cpp
index 0a20303..979fed2 100644
--- a/guest/vulkan_enc/goldfish_vk_extension_structs_guest.cpp
+++ b/guest/vulkan_enc/goldfish_vk_extension_structs_guest.cpp
@@ -140,6 +140,8 @@
 #endif
 #ifdef VK_EXT_texture_compression_astc_hdr
 #endif
+#ifdef VK_EXT_depth_clip_enable
+#endif
 #ifdef VK_EXT_swapchain_colorspace
 #endif
 #ifdef VK_EXT_queue_family_foreign
@@ -210,6 +212,8 @@
 #endif
 #ifdef VK_EXT_image_compression_control_swapchain
 #endif
+#ifdef VK_QNX_external_memory_screen_buffer
+#endif
 uint32_t goldfish_vk_struct_type(const void* structExtension) {
     const uint32_t asStructType = *(reinterpret_cast<const uint32_t*>(structExtension));
     return asStructType;
@@ -609,6 +613,14 @@
             return sizeof(VkPipelineRasterizationStateStreamCreateInfoEXT);
         }
 #endif
+#ifdef VK_EXT_depth_clip_enable
+        case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLIP_ENABLE_FEATURES_EXT: {
+            return sizeof(VkPhysicalDeviceDepthClipEnableFeaturesEXT);
+        }
+        case VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_DEPTH_CLIP_STATE_CREATE_INFO_EXT: {
+            return sizeof(VkPipelineRasterizationDepthClipStateCreateInfoEXT);
+        }
+#endif
 #ifdef VK_EXT_vertex_attribute_divisor
         case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_PROPERTIES_EXT: {
             return sizeof(VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT);
@@ -1154,6 +1166,14 @@
             return sizeof(VkPipelineRasterizationStateStreamCreateInfoEXT);
         }
 #endif
+#ifdef VK_EXT_depth_clip_enable
+        case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLIP_ENABLE_FEATURES_EXT: {
+            return sizeof(VkPhysicalDeviceDepthClipEnableFeaturesEXT);
+        }
+        case VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_DEPTH_CLIP_STATE_CREATE_INFO_EXT: {
+            return sizeof(VkPipelineRasterizationDepthClipStateCreateInfoEXT);
+        }
+#endif
 #ifdef VK_EXT_vertex_attribute_divisor
         case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_PROPERTIES_EXT: {
             return sizeof(VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT);
diff --git a/guest/vulkan_enc/goldfish_vk_extension_structs_guest.h b/guest/vulkan_enc/goldfish_vk_extension_structs_guest.h
index 0064c66..71c7390 100644
--- a/guest/vulkan_enc/goldfish_vk_extension_structs_guest.h
+++ b/guest/vulkan_enc/goldfish_vk_extension_structs_guest.h
@@ -160,6 +160,8 @@
 #endif
 #ifdef VK_EXT_texture_compression_astc_hdr
 #endif
+#ifdef VK_EXT_depth_clip_enable
+#endif
 #ifdef VK_EXT_swapchain_colorspace
 #endif
 #ifdef VK_EXT_queue_family_foreign
@@ -230,6 +232,8 @@
 #endif
 #ifdef VK_EXT_image_compression_control_swapchain
 #endif
+#ifdef VK_QNX_external_memory_screen_buffer
+#endif
 
 }  // namespace vk
 }  // namespace gfxstream
diff --git a/guest/vulkan_enc/goldfish_vk_marshaling_guest.cpp b/guest/vulkan_enc/goldfish_vk_marshaling_guest.cpp
index a36522b..3edd322 100644
--- a/guest/vulkan_enc/goldfish_vk_marshaling_guest.cpp
+++ b/guest/vulkan_enc/goldfish_vk_marshaling_guest.cpp
@@ -12008,6 +12008,60 @@
 #endif
 #ifdef VK_EXT_texture_compression_astc_hdr
 #endif
+#ifdef VK_EXT_depth_clip_enable
+void marshal_VkPhysicalDeviceDepthClipEnableFeaturesEXT(
+    VulkanStreamGuest* vkStream, VkStructureType rootType,
+    const VkPhysicalDeviceDepthClipEnableFeaturesEXT* forMarshaling) {
+    (void)rootType;
+    vkStream->write((VkStructureType*)&forMarshaling->sType, sizeof(VkStructureType));
+    if (rootType == VK_STRUCTURE_TYPE_MAX_ENUM) {
+        rootType = forMarshaling->sType;
+    }
+    marshal_extension_struct(vkStream, rootType, forMarshaling->pNext);
+    vkStream->write((VkBool32*)&forMarshaling->depthClipEnable, sizeof(VkBool32));
+}
+
+void unmarshal_VkPhysicalDeviceDepthClipEnableFeaturesEXT(
+    VulkanStreamGuest* vkStream, VkStructureType rootType,
+    VkPhysicalDeviceDepthClipEnableFeaturesEXT* forUnmarshaling) {
+    (void)rootType;
+    vkStream->read((VkStructureType*)&forUnmarshaling->sType, sizeof(VkStructureType));
+    if (rootType == VK_STRUCTURE_TYPE_MAX_ENUM) {
+        rootType = forUnmarshaling->sType;
+    }
+    unmarshal_extension_struct(vkStream, rootType, (void*)(forUnmarshaling->pNext));
+    vkStream->read((VkBool32*)&forUnmarshaling->depthClipEnable, sizeof(VkBool32));
+}
+
+void marshal_VkPipelineRasterizationDepthClipStateCreateInfoEXT(
+    VulkanStreamGuest* vkStream, VkStructureType rootType,
+    const VkPipelineRasterizationDepthClipStateCreateInfoEXT* forMarshaling) {
+    (void)rootType;
+    vkStream->write((VkStructureType*)&forMarshaling->sType, sizeof(VkStructureType));
+    if (rootType == VK_STRUCTURE_TYPE_MAX_ENUM) {
+        rootType = forMarshaling->sType;
+    }
+    marshal_extension_struct(vkStream, rootType, forMarshaling->pNext);
+    vkStream->write((VkPipelineRasterizationDepthClipStateCreateFlagsEXT*)&forMarshaling->flags,
+                    sizeof(VkPipelineRasterizationDepthClipStateCreateFlagsEXT));
+    vkStream->write((VkBool32*)&forMarshaling->depthClipEnable, sizeof(VkBool32));
+}
+
+void unmarshal_VkPipelineRasterizationDepthClipStateCreateInfoEXT(
+    VulkanStreamGuest* vkStream, VkStructureType rootType,
+    VkPipelineRasterizationDepthClipStateCreateInfoEXT* forUnmarshaling) {
+    (void)rootType;
+    vkStream->read((VkStructureType*)&forUnmarshaling->sType, sizeof(VkStructureType));
+    if (rootType == VK_STRUCTURE_TYPE_MAX_ENUM) {
+        rootType = forUnmarshaling->sType;
+    }
+    unmarshal_extension_struct(vkStream, rootType, (void*)(forUnmarshaling->pNext));
+    vkStream->read((VkPipelineRasterizationDepthClipStateCreateFlagsEXT*)&forUnmarshaling->flags,
+                   sizeof(VkPipelineRasterizationDepthClipStateCreateFlagsEXT));
+    vkStream->read((VkBool32*)&forUnmarshaling->depthClipEnable, sizeof(VkBool32));
+}
+
+#endif
 #ifdef VK_EXT_swapchain_colorspace
 #endif
 #ifdef VK_EXT_queue_family_foreign
@@ -13393,6 +13447,8 @@
 }
 
 #endif
+#ifdef VK_QNX_external_memory_screen_buffer
+#endif
 void marshal_extension_struct(VulkanStreamGuest* vkStream, VkStructureType rootType,
                               const void* structExtension) {
     VkInstanceCreateInfo* structAccess = (VkInstanceCreateInfo*)(structExtension);
@@ -14212,6 +14268,22 @@
             break;
         }
 #endif
+#ifdef VK_EXT_depth_clip_enable
+        case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLIP_ENABLE_FEATURES_EXT: {
+            marshal_VkPhysicalDeviceDepthClipEnableFeaturesEXT(
+                vkStream, rootType,
+                reinterpret_cast<const VkPhysicalDeviceDepthClipEnableFeaturesEXT*>(
+                    structExtension));
+            break;
+        }
+        case VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_DEPTH_CLIP_STATE_CREATE_INFO_EXT: {
+            marshal_VkPipelineRasterizationDepthClipStateCreateInfoEXT(
+                vkStream, rootType,
+                reinterpret_cast<const VkPipelineRasterizationDepthClipStateCreateInfoEXT*>(
+                    structExtension));
+            break;
+        }
+#endif
 #ifdef VK_EXT_vertex_attribute_divisor
         case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_PROPERTIES_EXT: {
             marshal_VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT(
@@ -15295,6 +15367,21 @@
             break;
         }
 #endif
+#ifdef VK_EXT_depth_clip_enable
+        case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLIP_ENABLE_FEATURES_EXT: {
+            unmarshal_VkPhysicalDeviceDepthClipEnableFeaturesEXT(
+                vkStream, rootType,
+                reinterpret_cast<VkPhysicalDeviceDepthClipEnableFeaturesEXT*>(structExtension_out));
+            break;
+        }
+        case VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_DEPTH_CLIP_STATE_CREATE_INFO_EXT: {
+            unmarshal_VkPipelineRasterizationDepthClipStateCreateInfoEXT(
+                vkStream, rootType,
+                reinterpret_cast<VkPipelineRasterizationDepthClipStateCreateInfoEXT*>(
+                    structExtension_out));
+            break;
+        }
+#endif
 #ifdef VK_EXT_vertex_attribute_divisor
         case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_PROPERTIES_EXT: {
             unmarshal_VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT(
diff --git a/guest/vulkan_enc/goldfish_vk_marshaling_guest.h b/guest/vulkan_enc/goldfish_vk_marshaling_guest.h
index 39877d3..008d90e 100644
--- a/guest/vulkan_enc/goldfish_vk_marshaling_guest.h
+++ b/guest/vulkan_enc/goldfish_vk_marshaling_guest.h
@@ -3148,6 +3148,24 @@
                       unmarshal_VkPhysicalDeviceTextureCompressionASTCHDRFeaturesEXT)
 
 #endif
+#ifdef VK_EXT_depth_clip_enable
+void marshal_VkPhysicalDeviceDepthClipEnableFeaturesEXT(
+    VulkanStreamGuest* vkStream, VkStructureType rootType,
+    const VkPhysicalDeviceDepthClipEnableFeaturesEXT* forMarshaling);
+
+void unmarshal_VkPhysicalDeviceDepthClipEnableFeaturesEXT(
+    VulkanStreamGuest* vkStream, VkStructureType rootType,
+    VkPhysicalDeviceDepthClipEnableFeaturesEXT* forUnmarshaling);
+
+void marshal_VkPipelineRasterizationDepthClipStateCreateInfoEXT(
+    VulkanStreamGuest* vkStream, VkStructureType rootType,
+    const VkPipelineRasterizationDepthClipStateCreateInfoEXT* forMarshaling);
+
+void unmarshal_VkPipelineRasterizationDepthClipStateCreateInfoEXT(
+    VulkanStreamGuest* vkStream, VkStructureType rootType,
+    VkPipelineRasterizationDepthClipStateCreateInfoEXT* forUnmarshaling);
+
+#endif
 #ifdef VK_EXT_swapchain_colorspace
 #endif
 #ifdef VK_EXT_queue_family_foreign
@@ -3706,6 +3724,8 @@
     VkPhysicalDeviceImageCompressionControlSwapchainFeaturesEXT* forUnmarshaling);
 
 #endif
+#ifdef VK_QNX_external_memory_screen_buffer
+#endif
 const char* api_opcode_to_string(const uint32_t opcode);
 
 #define OP_vkFirst_old 20000
diff --git a/guest/vulkan_enc/goldfish_vk_private_defs.h b/guest/vulkan_enc/goldfish_vk_private_defs.h
index 0867320..d50e6f1 100644
--- a/guest/vulkan_enc/goldfish_vk_private_defs.h
+++ b/guest/vulkan_enc/goldfish_vk_private_defs.h
@@ -23,16 +23,16 @@
 
 #ifdef __cplusplus
 
-template<class T, typename F>
+template <class T, typename F>
 bool arrayany(const T* arr, uint32_t begin, uint32_t end, const F& func) {
     const T* e = arr + end;
     return std::find_if(arr + begin, e, func) != e;
 }
 
-#define DEFINE_ALIAS_FUNCTION(ORIGINAL_FN, ALIAS_FN) \
-template <typename... Args> \
-inline auto ALIAS_FN(Args&&... args) -> decltype(ORIGINAL_FN(std::forward<Args>(args)...)) { \
-  return ORIGINAL_FN(std::forward<Args>(args)...); \
-}
+#define DEFINE_ALIAS_FUNCTION(ORIGINAL_FN, ALIAS_FN)                                             \
+    template <typename... Args>                                                                  \
+    inline auto ALIAS_FN(Args&&... args) -> decltype(ORIGINAL_FN(std::forward<Args>(args)...)) { \
+        return ORIGINAL_FN(std::forward<Args>(args)...);                                         \
+    }
 
 #endif
diff --git a/guest/vulkan_enc/goldfish_vk_reserved_marshaling_guest.cpp b/guest/vulkan_enc/goldfish_vk_reserved_marshaling_guest.cpp
index 71f3a94..6c223e7 100644
--- a/guest/vulkan_enc/goldfish_vk_reserved_marshaling_guest.cpp
+++ b/guest/vulkan_enc/goldfish_vk_reserved_marshaling_guest.cpp
@@ -8086,6 +8086,41 @@
 #endif
 #ifdef VK_EXT_texture_compression_astc_hdr
 #endif
+#ifdef VK_EXT_depth_clip_enable
+void reservedmarshal_VkPhysicalDeviceDepthClipEnableFeaturesEXT(
+    VulkanStreamGuest* vkStream, VkStructureType rootType,
+    const VkPhysicalDeviceDepthClipEnableFeaturesEXT* forMarshaling, uint8_t** ptr) {
+    (void)vkStream;
+    (void)rootType;
+    memcpy(*ptr, (VkStructureType*)&forMarshaling->sType, sizeof(VkStructureType));
+    *ptr += sizeof(VkStructureType);
+    if (rootType == VK_STRUCTURE_TYPE_MAX_ENUM) {
+        rootType = forMarshaling->sType;
+    }
+    reservedmarshal_extension_struct(vkStream, rootType, forMarshaling->pNext, ptr);
+    memcpy(*ptr, (VkBool32*)&forMarshaling->depthClipEnable, sizeof(VkBool32));
+    *ptr += sizeof(VkBool32);
+}
+
+void reservedmarshal_VkPipelineRasterizationDepthClipStateCreateInfoEXT(
+    VulkanStreamGuest* vkStream, VkStructureType rootType,
+    const VkPipelineRasterizationDepthClipStateCreateInfoEXT* forMarshaling, uint8_t** ptr) {
+    (void)vkStream;
+    (void)rootType;
+    memcpy(*ptr, (VkStructureType*)&forMarshaling->sType, sizeof(VkStructureType));
+    *ptr += sizeof(VkStructureType);
+    if (rootType == VK_STRUCTURE_TYPE_MAX_ENUM) {
+        rootType = forMarshaling->sType;
+    }
+    reservedmarshal_extension_struct(vkStream, rootType, forMarshaling->pNext, ptr);
+    memcpy(*ptr, (VkPipelineRasterizationDepthClipStateCreateFlagsEXT*)&forMarshaling->flags,
+           sizeof(VkPipelineRasterizationDepthClipStateCreateFlagsEXT));
+    *ptr += sizeof(VkPipelineRasterizationDepthClipStateCreateFlagsEXT);
+    memcpy(*ptr, (VkBool32*)&forMarshaling->depthClipEnable, sizeof(VkBool32));
+    *ptr += sizeof(VkBool32);
+}
+
+#endif
 #ifdef VK_EXT_swapchain_colorspace
 #endif
 #ifdef VK_EXT_queue_family_foreign
@@ -8994,6 +9029,8 @@
 }
 
 #endif
+#ifdef VK_QNX_external_memory_screen_buffer
+#endif
 void reservedmarshal_extension_struct(VulkanStreamGuest* vkStream, VkStructureType rootType,
                                       const void* structExtension, uint8_t** ptr) {
     VkInstanceCreateInfo* structAccess = (VkInstanceCreateInfo*)(structExtension);
@@ -9880,6 +9917,24 @@
             break;
         }
 #endif
+#ifdef VK_EXT_depth_clip_enable
+        case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLIP_ENABLE_FEATURES_EXT: {
+            reservedmarshal_VkPhysicalDeviceDepthClipEnableFeaturesEXT(
+                vkStream, rootType,
+                reinterpret_cast<const VkPhysicalDeviceDepthClipEnableFeaturesEXT*>(
+                    structExtension),
+                ptr);
+            break;
+        }
+        case VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_DEPTH_CLIP_STATE_CREATE_INFO_EXT: {
+            reservedmarshal_VkPipelineRasterizationDepthClipStateCreateInfoEXT(
+                vkStream, rootType,
+                reinterpret_cast<const VkPipelineRasterizationDepthClipStateCreateInfoEXT*>(
+                    structExtension),
+                ptr);
+            break;
+        }
+#endif
 #ifdef VK_EXT_vertex_attribute_divisor
         case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_PROPERTIES_EXT: {
             reservedmarshal_VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT(
diff --git a/guest/vulkan_enc/goldfish_vk_reserved_marshaling_guest.h b/guest/vulkan_enc/goldfish_vk_reserved_marshaling_guest.h
index f1a8a1c..ac2de29 100644
--- a/guest/vulkan_enc/goldfish_vk_reserved_marshaling_guest.h
+++ b/guest/vulkan_enc/goldfish_vk_reserved_marshaling_guest.h
@@ -1685,6 +1685,16 @@
                       reservedmarshal_VkPhysicalDeviceTextureCompressionASTCHDRFeaturesEXT)
 
 #endif
+#ifdef VK_EXT_depth_clip_enable
+void reservedmarshal_VkPhysicalDeviceDepthClipEnableFeaturesEXT(
+    VulkanStreamGuest* vkStream, VkStructureType rootType,
+    const VkPhysicalDeviceDepthClipEnableFeaturesEXT* forMarshaling, uint8_t** ptr);
+
+void reservedmarshal_VkPipelineRasterizationDepthClipStateCreateInfoEXT(
+    VulkanStreamGuest* vkStream, VkStructureType rootType,
+    const VkPipelineRasterizationDepthClipStateCreateInfoEXT* forMarshaling, uint8_t** ptr);
+
+#endif
 #ifdef VK_EXT_swapchain_colorspace
 #endif
 #ifdef VK_EXT_queue_family_foreign
@@ -1991,6 +2001,8 @@
     uint8_t** ptr);
 
 #endif
+#ifdef VK_QNX_external_memory_screen_buffer
+#endif
 
 }  // namespace vk
 }  // namespace gfxstream
diff --git a/guest/vulkan_enc/goldfish_vk_transform_guest.cpp b/guest/vulkan_enc/goldfish_vk_transform_guest.cpp
index 8eb7cd7..8aa5c7d 100644
--- a/guest/vulkan_enc/goldfish_vk_transform_guest.cpp
+++ b/guest/vulkan_enc/goldfish_vk_transform_guest.cpp
@@ -6870,6 +6870,46 @@
 #endif
 #ifdef VK_EXT_texture_compression_astc_hdr
 #endif
+#ifdef VK_EXT_depth_clip_enable
+void transform_tohost_VkPhysicalDeviceDepthClipEnableFeaturesEXT(
+    ResourceTracker* resourceTracker, VkPhysicalDeviceDepthClipEnableFeaturesEXT* toTransform) {
+    (void)resourceTracker;
+    (void)toTransform;
+    if (toTransform->pNext) {
+        transform_tohost_extension_struct(resourceTracker, (void*)(toTransform->pNext));
+    }
+}
+
+void transform_fromhost_VkPhysicalDeviceDepthClipEnableFeaturesEXT(
+    ResourceTracker* resourceTracker, VkPhysicalDeviceDepthClipEnableFeaturesEXT* toTransform) {
+    (void)resourceTracker;
+    (void)toTransform;
+    if (toTransform->pNext) {
+        transform_fromhost_extension_struct(resourceTracker, (void*)(toTransform->pNext));
+    }
+}
+
+void transform_tohost_VkPipelineRasterizationDepthClipStateCreateInfoEXT(
+    ResourceTracker* resourceTracker,
+    VkPipelineRasterizationDepthClipStateCreateInfoEXT* toTransform) {
+    (void)resourceTracker;
+    (void)toTransform;
+    if (toTransform->pNext) {
+        transform_tohost_extension_struct(resourceTracker, (void*)(toTransform->pNext));
+    }
+}
+
+void transform_fromhost_VkPipelineRasterizationDepthClipStateCreateInfoEXT(
+    ResourceTracker* resourceTracker,
+    VkPipelineRasterizationDepthClipStateCreateInfoEXT* toTransform) {
+    (void)resourceTracker;
+    (void)toTransform;
+    if (toTransform->pNext) {
+        transform_fromhost_extension_struct(resourceTracker, (void*)(toTransform->pNext));
+    }
+}
+
+#endif
 #ifdef VK_EXT_swapchain_colorspace
 #endif
 #ifdef VK_EXT_queue_family_foreign
@@ -7826,6 +7866,8 @@
 }
 
 #endif
+#ifdef VK_QNX_external_memory_screen_buffer
+#endif
 void transform_tohost_extension_struct(ResourceTracker* resourceTracker,
                                        void* structExtension_out) {
     if (!structExtension_out) {
@@ -8600,6 +8642,21 @@
             break;
         }
 #endif
+#ifdef VK_EXT_depth_clip_enable
+        case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLIP_ENABLE_FEATURES_EXT: {
+            transform_tohost_VkPhysicalDeviceDepthClipEnableFeaturesEXT(
+                resourceTracker,
+                reinterpret_cast<VkPhysicalDeviceDepthClipEnableFeaturesEXT*>(structExtension_out));
+            break;
+        }
+        case VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_DEPTH_CLIP_STATE_CREATE_INFO_EXT: {
+            transform_tohost_VkPipelineRasterizationDepthClipStateCreateInfoEXT(
+                resourceTracker,
+                reinterpret_cast<VkPipelineRasterizationDepthClipStateCreateInfoEXT*>(
+                    structExtension_out));
+            break;
+        }
+#endif
 #ifdef VK_EXT_vertex_attribute_divisor
         case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_PROPERTIES_EXT: {
             transform_tohost_VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT(
@@ -9631,6 +9688,21 @@
             break;
         }
 #endif
+#ifdef VK_EXT_depth_clip_enable
+        case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLIP_ENABLE_FEATURES_EXT: {
+            transform_fromhost_VkPhysicalDeviceDepthClipEnableFeaturesEXT(
+                resourceTracker,
+                reinterpret_cast<VkPhysicalDeviceDepthClipEnableFeaturesEXT*>(structExtension_out));
+            break;
+        }
+        case VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_DEPTH_CLIP_STATE_CREATE_INFO_EXT: {
+            transform_fromhost_VkPipelineRasterizationDepthClipStateCreateInfoEXT(
+                resourceTracker,
+                reinterpret_cast<VkPipelineRasterizationDepthClipStateCreateInfoEXT*>(
+                    structExtension_out));
+            break;
+        }
+#endif
 #ifdef VK_EXT_vertex_attribute_divisor
         case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_PROPERTIES_EXT: {
             transform_fromhost_VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT(
diff --git a/guest/vulkan_enc/goldfish_vk_transform_guest.h b/guest/vulkan_enc/goldfish_vk_transform_guest.h
index 6dff96d..fb8ef89 100644
--- a/guest/vulkan_enc/goldfish_vk_transform_guest.h
+++ b/guest/vulkan_enc/goldfish_vk_transform_guest.h
@@ -2663,6 +2663,22 @@
                       transform_fromhost_VkPhysicalDeviceTextureCompressionASTCHDRFeaturesEXT)
 
 #endif
+#ifdef VK_EXT_depth_clip_enable
+void transform_tohost_VkPhysicalDeviceDepthClipEnableFeaturesEXT(
+    ResourceTracker* resourceTracker, VkPhysicalDeviceDepthClipEnableFeaturesEXT* toTransform);
+
+void transform_fromhost_VkPhysicalDeviceDepthClipEnableFeaturesEXT(
+    ResourceTracker* resourceTracker, VkPhysicalDeviceDepthClipEnableFeaturesEXT* toTransform);
+
+void transform_tohost_VkPipelineRasterizationDepthClipStateCreateInfoEXT(
+    ResourceTracker* resourceTracker,
+    VkPipelineRasterizationDepthClipStateCreateInfoEXT* toTransform);
+
+void transform_fromhost_VkPipelineRasterizationDepthClipStateCreateInfoEXT(
+    ResourceTracker* resourceTracker,
+    VkPipelineRasterizationDepthClipStateCreateInfoEXT* toTransform);
+
+#endif
 #ifdef VK_EXT_swapchain_colorspace
 #endif
 #ifdef VK_EXT_queue_family_foreign
@@ -3131,6 +3147,8 @@
     VkPhysicalDeviceImageCompressionControlSwapchainFeaturesEXT* toTransform);
 
 #endif
+#ifdef VK_QNX_external_memory_screen_buffer
+#endif
 
 }  // namespace vk
 }  // namespace gfxstream
diff --git a/guest/vulkan_enc/meson.build b/guest/vulkan_enc/meson.build
index c94dd0d..33709bb 100644
--- a/guest/vulkan_enc/meson.build
+++ b/guest/vulkan_enc/meson.build
@@ -1,6 +1,17 @@
 # Copyright 2022 Android Open Source Project
 # SPDX-License-Identifier: MIT
 
+gfxstream_vk_entrypoints = custom_target(
+  'gfxstream_vk_entrypoints',
+  input : [vk_entrypoints_gen, vk_api_xml],
+  output : ['gfxstream_vk_entrypoints.h', 'gfxstream_vk_entrypoints.c'],
+  command : [
+    prog_python, '@INPUT0@', '--xml', '@INPUT1@', '--proto', '--weak',
+    '--out-h', '@OUTPUT0@', '--out-c', '@OUTPUT1@', '--prefix', 'gfxstream_vk',
+    '--beta', with_vulkan_beta.to_string()
+  ],
+)
+
 files_lib_vulkan_enc = files(
   'CommandBufferStagingStream.cpp',
   'DescriptorSetVirtualization.cpp',
@@ -19,16 +30,5 @@
   'goldfish_vk_marshaling_guest.cpp',
   'goldfish_vk_reserved_marshaling_guest.cpp',
   'goldfish_vk_transform_guest.cpp',
-)
-
-lib_vulkan_enc = static_library(
-   'vulkan_enc',
-   files_lib_vulkan_enc,
-   cpp_args: cpp_args,
-   include_directories: [inc_android_emu, inc_guest_iostream, inc_android_compat,
-                         inc_opengl_codec, inc_render_enc, inc_system,
-                         inc_goldfish_address_space, inc_platform,
-                         inc_vulkan_headers, inc_opengl_headers, inc_codec_common],
-   link_with: [lib_platform],
-   dependencies: dependency('libdrm'),
+  'gfxstream_vk_private.cpp',
 )
diff --git a/guest/vulkan_enc/vk_format_info.h b/guest/vulkan_enc/vk_format_info.h
index 9fbc82a..2d5d84e 100644
--- a/guest/vulkan_enc/vk_format_info.h
+++ b/guest/vulkan_enc/vk_format_info.h
@@ -35,8 +35,8 @@
     HAL_PIXEL_FORMAT_YV12 = 842094169,
 };
 #endif
-#include <vulkan/vulkan.h>
 #include <vndk/hardware_buffer.h>
+#include <vulkan/vulkan.h>
 
 namespace gfxstream {
 namespace vk {
@@ -55,165 +55,149 @@
 // formats such as AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420 could be
 // either VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM or
 // VK_FORMAT_G8_B8R8_2PLANE_420_UNORM.
-static inline VkFormat
-vk_format_from_android(unsigned android_format)
-{
-   switch (android_format) {
-   case AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM:
-      return VK_FORMAT_R8G8B8A8_UNORM;
-   case AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM:
-      return VK_FORMAT_R8G8B8A8_UNORM;
-   case AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM:
-      return VK_FORMAT_R8G8B8_UNORM;
-   case AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM:
-      return VK_FORMAT_R5G6B5_UNORM_PACK16;
-   case AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT:
-      return VK_FORMAT_R16G16B16A16_SFLOAT;
-   case AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM:
-      return VK_FORMAT_A2B10G10R10_UNORM_PACK32;
-   case HAL_PIXEL_FORMAT_NV12_Y_TILED_INTEL:
-   case AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420:
-      return VK_FORMAT_G8_B8R8_2PLANE_420_UNORM;
+static inline VkFormat vk_format_from_android(unsigned android_format) {
+    switch (android_format) {
+        case AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM:
+            return VK_FORMAT_R8G8B8A8_UNORM;
+        case AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM:
+            return VK_FORMAT_R8G8B8A8_UNORM;
+        case AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM:
+            return VK_FORMAT_R8G8B8_UNORM;
+        case AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM:
+            return VK_FORMAT_R5G6B5_UNORM_PACK16;
+        case AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT:
+            return VK_FORMAT_R16G16B16A16_SFLOAT;
+        case AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM:
+            return VK_FORMAT_A2B10G10R10_UNORM_PACK32;
+        case HAL_PIXEL_FORMAT_NV12_Y_TILED_INTEL:
+        case AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420:
+            return VK_FORMAT_G8_B8R8_2PLANE_420_UNORM;
 #if __ANDROID_API__ >= 30
-   case AHARDWAREBUFFER_FORMAT_YCbCr_P010:
-      return VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16;
+        case AHARDWAREBUFFER_FORMAT_YCbCr_P010:
+            return VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16;
 #endif
 #ifdef VK_USE_PLATFORM_ANDROID_KHR
-   case HAL_PIXEL_FORMAT_YV12:
-   case OMX_COLOR_FormatYUV420Planar:
-      return VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM;
-   case AHARDWAREBUFFER_FORMAT_BLOB:
+        case HAL_PIXEL_FORMAT_YV12:
+        case OMX_COLOR_FormatYUV420Planar:
+            return VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM;
+        case AHARDWAREBUFFER_FORMAT_BLOB:
 #endif
-   default:
-      return VK_FORMAT_UNDEFINED;
-   }
+        default:
+            return VK_FORMAT_UNDEFINED;
+    }
 }
 
-static inline unsigned
-android_format_from_vk(VkFormat vk_format)
-{
-   switch (vk_format) {
-   case VK_FORMAT_R8G8B8A8_UNORM:
-      return AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM;
-   case VK_FORMAT_R8G8B8_UNORM:
-      return AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM;
-   case VK_FORMAT_R5G6B5_UNORM_PACK16:
-      return AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM;
-   case VK_FORMAT_R16G16B16A16_SFLOAT:
-      return AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT;
-   case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
-      return AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM;
-   case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:
-      return HAL_PIXEL_FORMAT_NV12_Y_TILED_INTEL;
-   case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM:
-      return HAL_PIXEL_FORMAT_YV12;
-   default:
-      return AHARDWAREBUFFER_FORMAT_BLOB;
-   }
+static inline unsigned android_format_from_vk(VkFormat vk_format) {
+    switch (vk_format) {
+        case VK_FORMAT_R8G8B8A8_UNORM:
+            return AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM;
+        case VK_FORMAT_R8G8B8_UNORM:
+            return AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM;
+        case VK_FORMAT_R5G6B5_UNORM_PACK16:
+            return AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM;
+        case VK_FORMAT_R16G16B16A16_SFLOAT:
+            return AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT;
+        case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
+            return AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM;
+        case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:
+            return HAL_PIXEL_FORMAT_NV12_Y_TILED_INTEL;
+        case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM:
+            return HAL_PIXEL_FORMAT_YV12;
+        default:
+            return AHARDWAREBUFFER_FORMAT_BLOB;
+    }
 }
 
-static inline bool
-android_format_is_yuv(unsigned android_format)
-{
-   switch (android_format) {
-   case AHARDWAREBUFFER_FORMAT_BLOB:
-   case AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM:
-   case AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM:
-   case AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM:
-   case AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM:
-   case AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT:
-   case AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM:
-   case AHARDWAREBUFFER_FORMAT_D16_UNORM:
-   case AHARDWAREBUFFER_FORMAT_D24_UNORM:
-   case AHARDWAREBUFFER_FORMAT_D24_UNORM_S8_UINT:
-   case AHARDWAREBUFFER_FORMAT_D32_FLOAT:
-   case AHARDWAREBUFFER_FORMAT_D32_FLOAT_S8_UINT:
-   case AHARDWAREBUFFER_FORMAT_S8_UINT:
-      return false;
-   case HAL_PIXEL_FORMAT_NV12_Y_TILED_INTEL:
-   case OMX_COLOR_FormatYUV420Planar:
-   case HAL_PIXEL_FORMAT_YV12:
+static inline bool android_format_is_yuv(unsigned android_format) {
+    switch (android_format) {
+        case AHARDWAREBUFFER_FORMAT_BLOB:
+        case AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM:
+        case AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM:
+        case AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM:
+        case AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM:
+        case AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT:
+        case AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM:
+        case AHARDWAREBUFFER_FORMAT_D16_UNORM:
+        case AHARDWAREBUFFER_FORMAT_D24_UNORM:
+        case AHARDWAREBUFFER_FORMAT_D24_UNORM_S8_UINT:
+        case AHARDWAREBUFFER_FORMAT_D32_FLOAT:
+        case AHARDWAREBUFFER_FORMAT_D32_FLOAT_S8_UINT:
+        case AHARDWAREBUFFER_FORMAT_S8_UINT:
+            return false;
+        case HAL_PIXEL_FORMAT_NV12_Y_TILED_INTEL:
+        case OMX_COLOR_FormatYUV420Planar:
+        case HAL_PIXEL_FORMAT_YV12:
 #if __ANDROID_API__ >= 30
-   case AHARDWAREBUFFER_FORMAT_YCbCr_P010:
+        case AHARDWAREBUFFER_FORMAT_YCbCr_P010:
 #endif
-   case AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420:
-      return true;
-   default:
-      ALOGE("%s: unhandled format: %d", __FUNCTION__, android_format);
-      return false;
-   }
+        case AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420:
+            return true;
+        default:
+            ALOGE("%s: unhandled format: %d", __FUNCTION__, android_format);
+            return false;
+    }
 }
 
-static inline VkImageAspectFlags
-vk_format_aspects(VkFormat format)
-{
-   switch (format) {
-   case VK_FORMAT_UNDEFINED:
-      return 0;
+static inline VkImageAspectFlags vk_format_aspects(VkFormat format) {
+    switch (format) {
+        case VK_FORMAT_UNDEFINED:
+            return 0;
 
-   case VK_FORMAT_S8_UINT:
-      return VK_IMAGE_ASPECT_STENCIL_BIT;
+        case VK_FORMAT_S8_UINT:
+            return VK_IMAGE_ASPECT_STENCIL_BIT;
 
-   case VK_FORMAT_D16_UNORM_S8_UINT:
-   case VK_FORMAT_D24_UNORM_S8_UINT:
-   case VK_FORMAT_D32_SFLOAT_S8_UINT:
-      return VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
+        case VK_FORMAT_D16_UNORM_S8_UINT:
+        case VK_FORMAT_D24_UNORM_S8_UINT:
+        case VK_FORMAT_D32_SFLOAT_S8_UINT:
+            return VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
 
-   case VK_FORMAT_D16_UNORM:
-   case VK_FORMAT_X8_D24_UNORM_PACK32:
-   case VK_FORMAT_D32_SFLOAT:
-      return VK_IMAGE_ASPECT_DEPTH_BIT;
+        case VK_FORMAT_D16_UNORM:
+        case VK_FORMAT_X8_D24_UNORM_PACK32:
+        case VK_FORMAT_D32_SFLOAT:
+            return VK_IMAGE_ASPECT_DEPTH_BIT;
 
-   case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM:
-   case VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM:
-   case VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM:
-   case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16:
-   case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16:
-   case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16:
-   case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16:
-   case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16:
-   case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16:
-   case VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM:
-   case VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM:
-   case VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM:
-      return (VK_IMAGE_ASPECT_PLANE_0_BIT |
-              VK_IMAGE_ASPECT_PLANE_1_BIT |
-              VK_IMAGE_ASPECT_PLANE_2_BIT);
+        case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM:
+        case VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM:
+        case VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM:
+        case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16:
+        case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16:
+        case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16:
+        case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16:
+        case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16:
+        case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16:
+        case VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM:
+        case VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM:
+        case VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM:
+            return (VK_IMAGE_ASPECT_PLANE_0_BIT | VK_IMAGE_ASPECT_PLANE_1_BIT |
+                    VK_IMAGE_ASPECT_PLANE_2_BIT);
 
-   case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:
-   case VK_FORMAT_G8_B8R8_2PLANE_422_UNORM:
-   case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16:
-   case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16:
-   case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16:
-   case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16:
-   case VK_FORMAT_G16_B16R16_2PLANE_420_UNORM:
-   case VK_FORMAT_G16_B16R16_2PLANE_422_UNORM:
-      return (VK_IMAGE_ASPECT_PLANE_0_BIT |
-              VK_IMAGE_ASPECT_PLANE_1_BIT);
+        case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:
+        case VK_FORMAT_G8_B8R8_2PLANE_422_UNORM:
+        case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16:
+        case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16:
+        case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16:
+        case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16:
+        case VK_FORMAT_G16_B16R16_2PLANE_420_UNORM:
+        case VK_FORMAT_G16_B16R16_2PLANE_422_UNORM:
+            return (VK_IMAGE_ASPECT_PLANE_0_BIT | VK_IMAGE_ASPECT_PLANE_1_BIT);
 
-   default:
-      return VK_IMAGE_ASPECT_COLOR_BIT;
-   }
+        default:
+            return VK_IMAGE_ASPECT_COLOR_BIT;
+    }
 }
 
-static inline bool
-vk_format_is_color(VkFormat format)
-{
-   return vk_format_aspects(format) == VK_IMAGE_ASPECT_COLOR_BIT;
+static inline bool vk_format_is_color(VkFormat format) {
+    return vk_format_aspects(format) == VK_IMAGE_ASPECT_COLOR_BIT;
 }
 
-static inline bool
-vk_format_is_depth_or_stencil(VkFormat format)
-{
-   const VkImageAspectFlags aspects = vk_format_aspects(format);
-   return aspects & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT);
+static inline bool vk_format_is_depth_or_stencil(VkFormat format) {
+    const VkImageAspectFlags aspects = vk_format_aspects(format);
+    return aspects & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT);
 }
 
-static inline bool
-vk_format_has_depth(VkFormat format)
-{
-   const VkImageAspectFlags aspects = vk_format_aspects(format);
-   return aspects & VK_IMAGE_ASPECT_DEPTH_BIT;
+static inline bool vk_format_has_depth(VkFormat format) {
+    const VkImageAspectFlags aspects = vk_format_aspects(format);
+    return aspects & VK_IMAGE_ASPECT_DEPTH_BIT;
 }
 
 }  // namespace vk
diff --git a/guest/vulkan_enc/vk_platform_compat.h b/guest/vulkan_enc/vk_platform_compat.h
index e182bac..38f78cd 100644
--- a/guest/vulkan_enc/vk_platform_compat.h
+++ b/guest/vulkan_enc/vk_platform_compat.h
@@ -18,13 +18,13 @@
 #if VK_HEADER_VERSION < 76
 
 typedef struct VkBaseOutStructure {
-    VkStructureType               sType;
-    struct VkBaseOutStructure*    pNext;
+    VkStructureType sType;
+    struct VkBaseOutStructure* pNext;
 } VkBaseOutStructure;
 
 typedef struct VkBaseInStructure {
-    VkStructureType                    sType;
-    const struct VkBaseInStructure*    pNext;
+    VkStructureType sType;
+    const struct VkBaseInStructure* pNext;
 } VkBaseInStructure;
 
-#endif // VK_HEADER_VERSION < 76
+#endif  // VK_HEADER_VERSION < 76
diff --git a/guest/vulkan_enc/vk_struct_id.h b/guest/vulkan_enc/vk_struct_id.h
index 0ca2ff5..eaae46b 100644
--- a/guest/vulkan_enc/vk_struct_id.h
+++ b/guest/vulkan_enc/vk_struct_id.h
@@ -20,18 +20,25 @@
 #include "vk_android_native_buffer_gfxstream.h"
 #include "vulkan_gfxstream.h"
 
-namespace gfxstream {
-namespace vk {
+// anonymous
+namespace {
 
-template <class T> struct vk_get_vk_struct_id;
+template <class T>
+struct vk_get_vk_struct_id;
 
-#define REGISTER_VK_STRUCT_ID(T, ID) \
-    template <> struct vk_get_vk_struct_id<T> { static constexpr VkStructureType id = ID; }
+#define REGISTER_VK_STRUCT_ID(T, ID)              \
+    template <>                                   \
+    struct vk_get_vk_struct_id<T> {               \
+        static constexpr VkStructureType id = ID; \
+    }
 
 #ifdef VK_USE_PLATFORM_ANDROID_KHR
-REGISTER_VK_STRUCT_ID(VkAndroidHardwareBufferPropertiesANDROID, VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_PROPERTIES_ANDROID);
-REGISTER_VK_STRUCT_ID(VkAndroidHardwareBufferFormatPropertiesANDROID, VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_ANDROID);
-REGISTER_VK_STRUCT_ID(VkAndroidHardwareBufferUsageANDROID, VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_USAGE_ANDROID);
+REGISTER_VK_STRUCT_ID(VkAndroidHardwareBufferPropertiesANDROID,
+                      VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_PROPERTIES_ANDROID);
+REGISTER_VK_STRUCT_ID(VkAndroidHardwareBufferFormatPropertiesANDROID,
+                      VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_ANDROID);
+REGISTER_VK_STRUCT_ID(VkAndroidHardwareBufferUsageANDROID,
+                      VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_USAGE_ANDROID);
 #endif
 REGISTER_VK_STRUCT_ID(VkBufferCreateInfo, VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO);
 REGISTER_VK_STRUCT_ID(VkImageCreateInfo, VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO);
@@ -40,52 +47,79 @@
 REGISTER_VK_STRUCT_ID(VkNativeBufferANDROID, VK_STRUCTURE_TYPE_NATIVE_BUFFER_ANDROID);
 REGISTER_VK_STRUCT_ID(VkExternalFormatANDROID, VK_STRUCTURE_TYPE_EXTERNAL_FORMAT_ANDROID);
 #endif
-REGISTER_VK_STRUCT_ID(VkExternalMemoryBufferCreateInfo, VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO);
-REGISTER_VK_STRUCT_ID(VkExternalMemoryImageCreateInfo, VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO);
+REGISTER_VK_STRUCT_ID(VkExternalMemoryBufferCreateInfo,
+                      VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO);
+REGISTER_VK_STRUCT_ID(VkExternalMemoryImageCreateInfo,
+                      VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO);
 REGISTER_VK_STRUCT_ID(VkMemoryAllocateInfo, VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO);
-REGISTER_VK_STRUCT_ID(VkMemoryDedicatedAllocateInfo, VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO);
-REGISTER_VK_STRUCT_ID(VkMemoryDedicatedRequirements, VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS);
+REGISTER_VK_STRUCT_ID(VkMemoryDedicatedAllocateInfo,
+                      VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO);
+REGISTER_VK_STRUCT_ID(VkMemoryDedicatedRequirements,
+                      VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS);
 #ifdef VK_USE_PLATFORM_ANDROID_KHR
-REGISTER_VK_STRUCT_ID(VkImportAndroidHardwareBufferInfoANDROID, VK_STRUCTURE_TYPE_IMPORT_ANDROID_HARDWARE_BUFFER_INFO_ANDROID);
+REGISTER_VK_STRUCT_ID(VkImportAndroidHardwareBufferInfoANDROID,
+                      VK_STRUCTURE_TYPE_IMPORT_ANDROID_HARDWARE_BUFFER_INFO_ANDROID);
 #endif
+REGISTER_VK_STRUCT_ID(VkImportMemoryFdInfoKHR, VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR);
 REGISTER_VK_STRUCT_ID(VkExportMemoryAllocateInfo, VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO);
 REGISTER_VK_STRUCT_ID(VkMemoryRequirements2, VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2);
 REGISTER_VK_STRUCT_ID(VkSemaphoreCreateInfo, VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO);
-REGISTER_VK_STRUCT_ID(VkExportSemaphoreCreateInfoKHR, VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO_KHR);
-REGISTER_VK_STRUCT_ID(VkSamplerYcbcrConversionCreateInfo, VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO);
+REGISTER_VK_STRUCT_ID(VkExportSemaphoreCreateInfoKHR,
+                      VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO_KHR);
+REGISTER_VK_STRUCT_ID(VkSamplerYcbcrConversionCreateInfo,
+                      VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO);
 REGISTER_VK_STRUCT_ID(VkImportColorBufferGOOGLE, VK_STRUCTURE_TYPE_IMPORT_COLOR_BUFFER_GOOGLE);
 REGISTER_VK_STRUCT_ID(VkImageViewCreateInfo, VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO);
 #ifdef VK_USE_PLATFORM_FUCHSIA
-REGISTER_VK_STRUCT_ID(VkImportMemoryBufferCollectionFUCHSIA, VK_STRUCTURE_TYPE_IMPORT_MEMORY_BUFFER_COLLECTION_FUCHSIA);
-REGISTER_VK_STRUCT_ID(VkImportMemoryZirconHandleInfoFUCHSIA, VK_STRUCTURE_TYPE_IMPORT_MEMORY_ZIRCON_HANDLE_INFO_FUCHSIA);
-REGISTER_VK_STRUCT_ID(VkBufferCollectionImageCreateInfoFUCHSIA, VK_STRUCTURE_TYPE_BUFFER_COLLECTION_IMAGE_CREATE_INFO_FUCHSIA);
-REGISTER_VK_STRUCT_ID(VkBufferCollectionBufferCreateInfoFUCHSIA, VK_STRUCTURE_TYPE_BUFFER_COLLECTION_BUFFER_CREATE_INFO_FUCHSIA);
+REGISTER_VK_STRUCT_ID(VkImportMemoryBufferCollectionFUCHSIA,
+                      VK_STRUCTURE_TYPE_IMPORT_MEMORY_BUFFER_COLLECTION_FUCHSIA);
+REGISTER_VK_STRUCT_ID(VkImportMemoryZirconHandleInfoFUCHSIA,
+                      VK_STRUCTURE_TYPE_IMPORT_MEMORY_ZIRCON_HANDLE_INFO_FUCHSIA);
+REGISTER_VK_STRUCT_ID(VkBufferCollectionImageCreateInfoFUCHSIA,
+                      VK_STRUCTURE_TYPE_BUFFER_COLLECTION_IMAGE_CREATE_INFO_FUCHSIA);
+REGISTER_VK_STRUCT_ID(VkBufferCollectionBufferCreateInfoFUCHSIA,
+                      VK_STRUCTURE_TYPE_BUFFER_COLLECTION_BUFFER_CREATE_INFO_FUCHSIA);
 #endif  // VK_USE_PLATFORM_FUCHSIA
 REGISTER_VK_STRUCT_ID(VkSamplerCreateInfo, VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO);
-REGISTER_VK_STRUCT_ID(VkSamplerCustomBorderColorCreateInfoEXT, VK_STRUCTURE_TYPE_SAMPLER_CUSTOM_BORDER_COLOR_CREATE_INFO_EXT);
-REGISTER_VK_STRUCT_ID(VkSamplerYcbcrConversionInfo, VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO);
+REGISTER_VK_STRUCT_ID(VkSamplerCustomBorderColorCreateInfoEXT,
+                      VK_STRUCTURE_TYPE_SAMPLER_CUSTOM_BORDER_COLOR_CREATE_INFO_EXT);
+REGISTER_VK_STRUCT_ID(VkSamplerYcbcrConversionInfo,
+                      VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO);
 REGISTER_VK_STRUCT_ID(VkFenceCreateInfo, VK_STRUCTURE_TYPE_FENCE_CREATE_INFO);
 REGISTER_VK_STRUCT_ID(VkExportFenceCreateInfo, VK_STRUCTURE_TYPE_EXPORT_FENCE_CREATE_INFO);
 REGISTER_VK_STRUCT_ID(VkImportBufferGOOGLE, VK_STRUCTURE_TYPE_IMPORT_BUFFER_GOOGLE);
 REGISTER_VK_STRUCT_ID(VkCreateBlobGOOGLE, VK_STRUCTURE_TYPE_CREATE_BLOB_GOOGLE);
-REGISTER_VK_STRUCT_ID(VkExternalImageFormatProperties, VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES);
-REGISTER_VK_STRUCT_ID(VkPhysicalDeviceImageFormatInfo2, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2);
-REGISTER_VK_STRUCT_ID(VkPhysicalDeviceExternalImageFormatInfo, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO);
+REGISTER_VK_STRUCT_ID(VkExternalImageFormatProperties,
+                      VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES);
+REGISTER_VK_STRUCT_ID(VkPhysicalDeviceImageFormatInfo2,
+                      VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2);
+REGISTER_VK_STRUCT_ID(VkPhysicalDeviceExternalImageFormatInfo,
+                      VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO);
 REGISTER_VK_STRUCT_ID(VkSemaphoreTypeCreateInfo, VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO);
 REGISTER_VK_STRUCT_ID(VkPhysicalDeviceFeatures2, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2);
 REGISTER_VK_STRUCT_ID(VkPhysicalDeviceProperties2, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2);
-REGISTER_VK_STRUCT_ID(VkPhysicalDeviceDeviceMemoryReportFeaturesEXT, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEVICE_MEMORY_REPORT_FEATURES_EXT);
+REGISTER_VK_STRUCT_ID(VkPhysicalDeviceDeviceMemoryReportFeaturesEXT,
+                      VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEVICE_MEMORY_REPORT_FEATURES_EXT);
 REGISTER_VK_STRUCT_ID(VkMemoryAllocateFlagsInfo, VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_FLAGS_INFO);
-REGISTER_VK_STRUCT_ID(VkMemoryOpaqueCaptureAddressAllocateInfo, VK_STRUCTURE_TYPE_MEMORY_OPAQUE_CAPTURE_ADDRESS_ALLOCATE_INFO);
+REGISTER_VK_STRUCT_ID(VkMemoryOpaqueCaptureAddressAllocateInfo,
+                      VK_STRUCTURE_TYPE_MEMORY_OPAQUE_CAPTURE_ADDRESS_ALLOCATE_INFO);
 REGISTER_VK_STRUCT_ID(VkBindImageMemoryInfo, VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO);
-REGISTER_VK_STRUCT_ID(VkBindImageMemorySwapchainInfoKHR, VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_SWAPCHAIN_INFO_KHR);
-REGISTER_VK_STRUCT_ID(VkBufferOpaqueCaptureAddressCreateInfo, VK_STRUCTURE_TYPE_BUFFER_OPAQUE_CAPTURE_ADDRESS_CREATE_INFO);
-REGISTER_VK_STRUCT_ID(VkBufferDeviceAddressCreateInfoEXT, VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_CREATE_INFO_EXT);
-REGISTER_VK_STRUCT_ID(VkGraphicsPipelineCreateInfo, VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO);
-REGISTER_VK_STRUCT_ID(VkPipelineRenderingCreateInfo, VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO);
-REGISTER_VK_STRUCT_ID(VkPhysicalDeviceExternalSemaphoreInfo, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO);
+REGISTER_VK_STRUCT_ID(VkBindImageMemorySwapchainInfoKHR,
+                      VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_SWAPCHAIN_INFO_KHR);
+REGISTER_VK_STRUCT_ID(VkBufferOpaqueCaptureAddressCreateInfo,
+                      VK_STRUCTURE_TYPE_BUFFER_OPAQUE_CAPTURE_ADDRESS_CREATE_INFO);
+REGISTER_VK_STRUCT_ID(VkBufferDeviceAddressCreateInfoEXT,
+                      VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_CREATE_INFO_EXT);
+REGISTER_VK_STRUCT_ID(VkGraphicsPipelineCreateInfo,
+                      VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO);
+REGISTER_VK_STRUCT_ID(VkPipelineRenderingCreateInfo,
+                      VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO);
+REGISTER_VK_STRUCT_ID(VkPhysicalDeviceExternalSemaphoreInfo,
+                      VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO);
+REGISTER_VK_STRUCT_ID(VkRenderPassBeginInfo, VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO);
+REGISTER_VK_STRUCT_ID(VkRenderPassAttachmentBeginInfo,
+                      VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO);
 
 #undef REGISTER_VK_STRUCT_ID
 
-}  // namespace vk
-}  // namespace gfxstream
+}  // namespace
diff --git a/guest/vulkan_enc/vk_util.h b/guest/vulkan_enc/vk_util.h
index 2e3267f..e18bdde 100644
--- a/guest/vulkan_enc/vk_util.h
+++ b/guest/vulkan_enc/vk_util.h
@@ -25,29 +25,29 @@
 
 /* common inlines and macros for vulkan drivers */
 
-#include <vulkan/vulkan.h>
 #include <stdlib.h>
+#include <vulkan/vulkan.h>
+
 #include "vk_struct_id.h"
 
-namespace gfxstream {
-namespace vk {
+namespace {  // anonymous
 
 struct vk_struct_common {
     VkStructureType sType;
-    struct vk_struct_common *pNext;
+    struct vk_struct_common* pNext;
 };
 
 struct vk_struct_chain_iterator {
     vk_struct_common* value;
 };
 
-#define vk_foreach_struct(__iter, __start) \
-   for (struct vk_struct_common *__iter = (struct vk_struct_common *)(__start); \
-        __iter; __iter = __iter->pNext)
+#define vk_foreach_struct(__iter, __start)                                              \
+    for (struct vk_struct_common* __iter = (struct vk_struct_common*)(__start); __iter; \
+         __iter = __iter->pNext)
 
-#define vk_foreach_struct_const(__iter, __start) \
-   for (const struct vk_struct_common *__iter = (const struct vk_struct_common *)(__start); \
-        __iter; __iter = __iter->pNext)
+#define vk_foreach_struct_const(__iter, __start)                                            \
+    for (const struct vk_struct_common* __iter = (const struct vk_struct_common*)(__start); \
+         __iter; __iter = __iter->pNext)
 
 /**
  * A wrapper for a Vulkan output array. A Vulkan output array is one that
@@ -79,92 +79,84 @@
  *    }
  */
 struct __vk_outarray {
-   /** May be null. */
-   void *data;
+    /** May be null. */
+    void* data;
 
-   /**
-    * Capacity, in number of elements. Capacity is unlimited (UINT32_MAX) if
-    * data is null.
-    */
-   uint32_t cap;
+    /**
+     * Capacity, in number of elements. Capacity is unlimited (UINT32_MAX) if
+     * data is null.
+     */
+    uint32_t cap;
 
-   /**
-    * Count of elements successfully written to the array. Every write is
-    * considered successful if data is null.
-    */
-   uint32_t *filled_len;
+    /**
+     * Count of elements successfully written to the array. Every write is
+     * considered successful if data is null.
+     */
+    uint32_t* filled_len;
 
-   /**
-    * Count of elements that would have been written to the array if its
-    * capacity were sufficient. Vulkan functions often return VK_INCOMPLETE
-    * when `*filled_len < wanted_len`.
-    */
-   uint32_t wanted_len;
+    /**
+     * Count of elements that would have been written to the array if its
+     * capacity were sufficient. Vulkan functions often return VK_INCOMPLETE
+     * when `*filled_len < wanted_len`.
+     */
+    uint32_t wanted_len;
 };
 
-static inline void
-__vk_outarray_init(struct __vk_outarray *a,
-                   void *data, uint32_t * len)
-{
-   a->data = data;
-   a->cap = *len;
-   a->filled_len = len;
-   *a->filled_len = 0;
-   a->wanted_len = 0;
+static inline void __vk_outarray_init(struct __vk_outarray* a, void* data, uint32_t* len) {
+    a->data = data;
+    a->cap = *len;
+    a->filled_len = len;
+    *a->filled_len = 0;
+    a->wanted_len = 0;
 
-   if (a->data == NULL)
-      a->cap = UINT32_MAX;
+    if (a->data == NULL) a->cap = UINT32_MAX;
 }
 
-static inline VkResult
-__vk_outarray_status(const struct __vk_outarray *a)
-{
-   if (*a->filled_len < a->wanted_len)
-      return VK_INCOMPLETE;
-   else
-      return VK_SUCCESS;
+static inline VkResult __vk_outarray_status(const struct __vk_outarray* a) {
+    if (*a->filled_len < a->wanted_len)
+        return VK_INCOMPLETE;
+    else
+        return VK_SUCCESS;
 }
 
-static inline void *
-__vk_outarray_next(struct __vk_outarray *a, size_t elem_size)
-{
-   void *p = NULL;
+static inline void* __vk_outarray_next(struct __vk_outarray* a, size_t elem_size) {
+    void* p = NULL;
 
-   a->wanted_len += 1;
+    a->wanted_len += 1;
 
-   if (*a->filled_len >= a->cap)
-      return NULL;
+    if (*a->filled_len >= a->cap) return NULL;
 
-   if (a->data != NULL)
-      p = ((uint8_t*)a->data) + (*a->filled_len) * elem_size;
+    if (a->data != NULL) p = ((uint8_t*)a->data) + (*a->filled_len) * elem_size;
 
-   *a->filled_len += 1;
+    *a->filled_len += 1;
 
-   return p;
+    return p;
 }
 
-#define vk_outarray(elem_t) \
-   struct { \
-      struct __vk_outarray base; \
-      elem_t meta[]; \
-   }
+#define vk_outarray(elem_t)        \
+    struct {                       \
+        struct __vk_outarray base; \
+        elem_t meta[];             \
+    }
 
 #define vk_outarray_typeof_elem(a) __typeof__((a)->meta[0])
 #define vk_outarray_sizeof_elem(a) sizeof((a)->meta[0])
 
-#define vk_outarray_init(a, data, len) \
-   __vk_outarray_init(&(a)->base, (data), (len))
+#define vk_outarray_init(a, data, len) __vk_outarray_init(&(a)->base, (data), (len))
 
-#define VK_OUTARRAY_MAKE(name, data, len) \
-   vk_outarray(__typeof__((data)[0])) name; \
-   vk_outarray_init(&name, (data), (len))
+#define VK_OUTARRAY_MAKE(name, data, len)    \
+    vk_outarray(__typeof__((data)[0])) name; \
+    vk_outarray_init(&name, (data), (len))
 
-#define vk_outarray_status(a) \
-   __vk_outarray_status(&(a)->base)
+#define VK_OUTARRAY_MAKE_TYPED(type, name, data, len) \
+    vk_outarray(type) name;                           \
+    vk_outarray_init(&name, (data), (len))
 
-#define vk_outarray_next(a) \
-   ((vk_outarray_typeof_elem(a) *) \
-      __vk_outarray_next(&(a)->base, vk_outarray_sizeof_elem(a)))
+#define vk_outarray_status(a) __vk_outarray_status(&(a)->base)
+
+#define vk_outarray_next(a) vk_outarray_next_typed(vk_outarray_typeof_elem(a), a)
+#define vk_outarray_next_typed(type, a) \
+    ((type*)__vk_outarray_next(&(a)->base, vk_outarray_sizeof_elem(a)))
 
 /**
  * Append to a Vulkan output array.
@@ -186,31 +178,30 @@
  * points to the newly appended element.
  */
 #define vk_outarray_append(a, elem) \
-   for (vk_outarray_typeof_elem(a) *elem = vk_outarray_next(a); \
-        elem != NULL; elem = NULL)
+    for (vk_outarray_typeof_elem(a)* elem = vk_outarray_next(a); elem != NULL; elem = NULL)
 
-static inline void *
-__vk_find_struct(void *start, VkStructureType sType)
-{
-   vk_foreach_struct(s, start) {
-      if (s->sType == sType)
-         return s;
-   }
+#define vk_outarray_append_typed(type, a, elem) \
+    for (type* elem = vk_outarray_next_typed(type, a); elem != NULL; elem = NULL)
 
-   return NULL;
+static inline void* __vk_find_struct(void* start, VkStructureType sType) {
+    vk_foreach_struct(s, start) {
+        if (s->sType == sType) return s;
+    }
+
+    return NULL;
 }
 
-template <class T, class H> T* vk_find_struct(H* head)
-{
+template <class T, class H>
+T* vk_find_struct(H* head) {
     (void)vk_get_vk_struct_id<H>::id;
     return static_cast<T*>(__vk_find_struct(static_cast<void*>(head), vk_get_vk_struct_id<T>::id));
 }
 
-template <class T, class H> const T* vk_find_struct(const H* head)
-{
+template <class T, class H>
+const T* vk_find_struct(const H* head) {
     (void)vk_get_vk_struct_id<H>::id;
     return static_cast<const T*>(__vk_find_struct(const_cast<void*>(static_cast<const void*>(head)),
-                                 vk_get_vk_struct_id<T>::id));
+                                                  vk_get_vk_struct_id<T>::id));
 }
 
 uint32_t vk_get_driver_version(void);
@@ -219,25 +210,25 @@
 
 #define VK_EXT_OFFSET (1000000000UL)
 #define VK_ENUM_EXTENSION(__enum) \
-   ((__enum) >= VK_EXT_OFFSET ? ((((__enum) - VK_EXT_OFFSET) / 1000UL) + 1) : 0)
-#define VK_ENUM_OFFSET(__enum) \
-   ((__enum) >= VK_EXT_OFFSET ? ((__enum) % 1000) : (__enum))
+    ((__enum) >= VK_EXT_OFFSET ? ((((__enum)-VK_EXT_OFFSET) / 1000UL) + 1) : 0)
+#define VK_ENUM_OFFSET(__enum) ((__enum) >= VK_EXT_OFFSET ? ((__enum) % 1000) : (__enum))
 
-template <class T> T vk_make_orphan_copy(const T& vk_struct) {
+template <class T>
+T vk_make_orphan_copy(const T& vk_struct) {
     T copy = vk_struct;
     copy.pNext = NULL;
     return copy;
 }
 
-template <class T> vk_struct_chain_iterator vk_make_chain_iterator(T* vk_struct)
-{
+template <class T>
+vk_struct_chain_iterator vk_make_chain_iterator(T* vk_struct) {
     (void)vk_get_vk_struct_id<T>::id;
-    vk_struct_chain_iterator result = { reinterpret_cast<vk_struct_common*>(vk_struct) };
+    vk_struct_chain_iterator result = {reinterpret_cast<vk_struct_common*>(vk_struct)};
     return result;
 }
 
-template <class T> void vk_append_struct(vk_struct_chain_iterator* i, T* vk_struct)
-{
+template <class T>
+void vk_append_struct(vk_struct_chain_iterator* i, T* vk_struct) {
     (void)vk_get_vk_struct_id<T>::id;
 
     vk_struct_common* p = i->value;
@@ -245,13 +236,12 @@
         ::abort();
     }
 
-    p->pNext = reinterpret_cast<vk_struct_common *>(vk_struct);
+    p->pNext = reinterpret_cast<vk_struct_common*>(vk_struct);
     vk_struct->pNext = NULL;
 
     *i = vk_make_chain_iterator(vk_struct);
 }
 
-}  // namespace vk
-}  // namespace gfxstream
+}  // namespace
 
 #endif /* VK_UTIL_H */