vulkan: Set up VkCmdBuffer dispatching

Change-Id: Ifb3cea05dab8828c2c00b8ed60c5ad991cdcbea7
(cherry picked from commit 10bf73e13b6904afa606fdcdc05bcc510c605180)
diff --git a/vulkan/libvulkan/loader.cpp b/vulkan/libvulkan/loader.cpp
index a99e90a..19ca9f2 100644
--- a/vulkan/libvulkan/loader.cpp
+++ b/vulkan/libvulkan/loader.cpp
@@ -494,6 +494,7 @@
         return GetGlobalDeviceProcAddr(name);
     // For special-case functions we always return the loader entry
     if (strcmp(name, "vkGetDeviceQueue") == 0 ||
+        strcmp(name, "vkCreateCommandBuffer") == 0 ||
         strcmp(name, "vkDestroyDevice") == 0) {
         return GetGlobalDeviceProcAddr(name);
     }
@@ -521,6 +522,27 @@
     return VK_SUCCESS;
 }
 
+VkResult CreateCommandBuffer(VkDevice drv_device,
+                             const VkCmdBufferCreateInfo* create_info,
+                             VkCmdBuffer* out_cmdbuf) {
+    const DeviceVtbl* vtbl = GetVtbl(drv_device);
+    VkCmdBuffer cmdbuf;
+    VkResult result =
+        vtbl->CreateCommandBuffer(drv_device, create_info, &cmdbuf);
+    if (result != VK_SUCCESS)
+        return result;
+    hwvulkan_dispatch_t* dispatch =
+        reinterpret_cast<hwvulkan_dispatch_t*>(cmdbuf);
+    if (dispatch->magic != HWVULKAN_DISPATCH_MAGIC) {
+        ALOGE("invalid VkCmdBuffer dispatch magic: 0x%" PRIxPTR,
+              dispatch->magic);
+        return VK_ERROR_INITIALIZATION_FAILED;
+    }
+    dispatch->vtbl = vtbl;
+    *out_cmdbuf = cmdbuf;
+    return VK_SUCCESS;
+}
+
 VkResult DestroyDevice(VkDevice drv_device) {
     const DeviceVtbl* vtbl = GetVtbl(drv_device);
     Device* device = static_cast<Device*>(vtbl->device);