diff --git a/BUILD.gn b/BUILD.gn
index 5e63b1923eb2a8a361aaca626eab448197d8031b..385ae8de852099fc4555701828b43c1174fdeb39 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -1,4 +1,4 @@
-source_set("goldfish_vulkan") {
+shared_library("vulkan_goldfish") {
   sources = [
     "android-emu/android/base/AlignedBuf.cpp",
     "android-emu/android/base/AlignedBuf.h",
@@ -84,6 +84,8 @@ source_set("goldfish_vulkan") {
     "-Wno-missing-field-initializers",
   ]
 
+  ldflags = [ "-static-libstdc++" ]
+
   if (target_os == "fuchsia") {
     sources += [ "fuchsia/port.cc" ]
 
diff --git a/system/gralloc/gralloc.cpp b/system/gralloc/gralloc.cpp
index aace8e3f3c8fab8138d03d63146c7c949c281fae..d39d99ab807dcfa29d2ec17f493fd14a197f1e5d 100644
--- a/system/gralloc/gralloc.cpp
+++ b/system/gralloc/gralloc.cpp
@@ -506,10 +506,6 @@ static int gralloc_alloc(alloc_device_t* dev,
             } else if (usage & GRALLOC_USAGE_HW_VIDEO_ENCODER) {
                 // Camera-to-encoder is NV21
                 format = HAL_PIXEL_FORMAT_YCrCb_420_SP;
-            } else if ((usage & GRALLOC_USAGE_HW_CAMERA_MASK) ==
-                    GRALLOC_USAGE_HW_CAMERA_ZSL) {
-                // Camera-to-ZSL-queue is RGB_888
-                format = HAL_PIXEL_FORMAT_RGB_888;
             }
         }
 
@@ -545,11 +541,6 @@ static int gralloc_alloc(alloc_device_t* dev,
             glFormat = GL_RGBA;
             glType = GL_UNSIGNED_BYTE;
             break;
-        case HAL_PIXEL_FORMAT_RGB_888:
-            bpp = 3;
-            glFormat = GL_RGB;
-            glType = GL_UNSIGNED_BYTE;
-            break;
         case HAL_PIXEL_FORMAT_RGB_565:
             bpp = 2;
             // Workaround: distinguish vs the RGB8/RGBA8
diff --git a/system/vulkan/func_table.cpp b/system/vulkan/func_table.cpp
index 14c8c323930fa65077df9a967f225108e52eab8f..44e385ded8f52fbe902dfce9aa4fc4dc8a4b94a9 100644
--- a/system/vulkan/func_table.cpp
+++ b/system/vulkan/func_table.cpp
@@ -1095,7 +1095,7 @@ static void entry_vkCmdSetDepthBias(
 }
 static void entry_vkCmdSetBlendConstants(
     VkCommandBuffer commandBuffer,
-    const float blendConstants)
+    const float blendConstants[4])
 {
     AEMU_SCOPED_TRACE("vkCmdSetBlendConstants");
     auto vkEnc = HostConnection::get()->vkEncoder();
diff --git a/system/vulkan/goldfish_vulkan.cpp b/system/vulkan/goldfish_vulkan.cpp
index 18a9424580b0ec4f5c0580063822eef1e49b2b87..3b38994d01c9b77e77015b7ddf7b075bde84c86c 100644
--- a/system/vulkan/goldfish_vulkan.cpp
+++ b/system/vulkan/goldfish_vulkan.cpp
@@ -208,6 +208,8 @@ PFN_vkVoidFunction GetInstanceProcAddr(VkInstance instance,
 
 namespace {
 
+#ifdef VK_USE_PLATFORM_ANDROID_KHR
+
 int OpenDevice(const hw_module_t* module, const char* id, hw_device_t** device);
 
 hw_module_methods_t goldfish_vulkan_module_methods = {
@@ -232,6 +234,8 @@ int CloseDevice(struct hw_device_t* /*device*/) {
     return 0;
 }
 
+#endif
+
 #define VK_HOST_CONNECTION(ret) \
     HostConnection *hostCon = HostConnection::get(); \
     if (!hostCon) { \
@@ -498,6 +502,8 @@ PFN_vkVoidFunction GetInstanceProcAddr(VkInstance instance, const char* name) {
     return (PFN_vkVoidFunction)(goldfish_vk::goldfish_vulkan_get_instance_proc_address(instance, name));
 }
 
+#ifdef VK_USE_PLATFORM_ANDROID_KHR
+
 hwvulkan_device_t goldfish_vulkan_device = {
     .common = {
         .tag = HARDWARE_DEVICE_TAG,
@@ -517,7 +523,19 @@ int OpenDevice(const hw_module_t* /*module*/,
 
     if (strcmp(id, HWVULKAN_DEVICE_0) == 0) {
         *device = &goldfish_vulkan_device.common;
+        goldfish_vk::ResourceTracker::get();
+        return 0;
+    }
+    return -ENOENT;
+}
+
+#endif
+
 #ifdef VK_USE_PLATFORM_FUCHSIA
+
+class VulkanDevice {
+public:
+    VulkanDevice() {
         goldfish_vk::ResourceTracker::get()->setColorBufferFunctions(
             [](uint32_t width, uint32_t height, uint32_t format) {
                 VK_HOST_CONNECTION((uint32_t)0)
@@ -532,12 +550,29 @@ int OpenDevice(const hw_module_t* /*module*/,
                 VK_HOST_CONNECTION()
                 rcEnc->rcCloseColorBuffer(rcEnc, id);
             });
-#else
-        goldfish_vk::ResourceTracker::get();
-#endif
-        return 0;
     }
-    return -ENOENT;
+
+    static VulkanDevice& GetInstance() {
+        static VulkanDevice g_instance;
+        return g_instance;
+    }
+
+    PFN_vkVoidFunction GetInstanceProcAddr(VkInstance instance, const char* name) {
+        return ::GetInstanceProcAddr(instance, name);
+    }
+};
+
+extern "C" __attribute__((visibility("default"))) PFN_vkVoidFunction
+vk_icdGetInstanceProcAddr(VkInstance instance, const char* name) {
+    return VulkanDevice::GetInstance().GetInstanceProcAddr(instance, name);
 }
 
+extern "C" __attribute__((visibility("default"))) VkResult
+vk_icdNegotiateLoaderICDInterfaceVersion(uint32_t* pSupportedVersion) {
+    *pSupportedVersion = std::min(*pSupportedVersion, 3u);
+    return VK_SUCCESS;
+}
+
+#endif
+
 } // namespace
diff --git a/system/vulkan_enc/VkEncoder.cpp b/system/vulkan_enc/VkEncoder.cpp
index b97f120e8650c9c3f4a5231c4b3a5654d5ed84bf..42487ea1b686672b86fdb0023b40e4cb9d02db0a 100644
--- a/system/vulkan_enc/VkEncoder.cpp
+++ b/system/vulkan_enc/VkEncoder.cpp
@@ -7137,7 +7137,7 @@ void VkEncoder::vkCmdSetDepthBias(
 
 void VkEncoder::vkCmdSetBlendConstants(
     VkCommandBuffer commandBuffer,
-    const float blendConstants)
+    const float blendConstants[4])
 {
     AEMU_SCOPED_TRACE("vkCmdSetBlendConstants encode");
     mImpl->log("start vkCmdSetBlendConstants");
diff --git a/system/vulkan_enc/VkEncoder.h b/system/vulkan_enc/VkEncoder.h
index 16df497f6f881c0a8e609e93f6770cbb1be6b5e7..8328b321edb5f431bf3e411d8c50134318cf58ca 100644
--- a/system/vulkan_enc/VkEncoder.h
+++ b/system/vulkan_enc/VkEncoder.h
@@ -473,7 +473,7 @@ public:
         float depthBiasSlopeFactor);
     void vkCmdSetBlendConstants(
     VkCommandBuffer commandBuffer,
-        const float blendConstants);
+        const float blendConstants[4]);
     void vkCmdSetDepthBounds(
     VkCommandBuffer commandBuffer,
         float minDepthBounds,