Implement Android Vulkan HAL module plumbing

The Android loader looks for the symbol `HMI` which describes the module
and provides pointers to the initial entrypoints. Add a minimal
implementation of that.

Based on docs: https://source.android.com/devices/graphics/implement-vulkan#driver_emun
Bug: b/122837488
Change-Id: I367bac2046368bc8a08334cfac2f339ca2c1eb5f
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/28410
Tested-by: Chris Forbes <chrisforbes@google.com>
Presubmit-Ready: Chris Forbes <chrisforbes@google.com>
Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
diff --git a/src/Android.bp b/src/Android.bp
index 0a57cad..caf4804 100644
--- a/src/Android.bp
+++ b/src/Android.bp
@@ -620,6 +620,7 @@
             relative_install_path: "hw",
             header_libs: [
                 "swiftshader_platform_headers",
+				"vulkan_headers",
             ],
             shared_libs: [
                 "libnativewindow",
diff --git a/src/Vulkan/VkGetProcAddress.cpp b/src/Vulkan/VkGetProcAddress.cpp
index 8960d72..8416b3b 100644
--- a/src/Vulkan/VkGetProcAddress.cpp
+++ b/src/Vulkan/VkGetProcAddress.cpp
@@ -19,6 +19,11 @@
 
 #include <vulkan/vulkan.h>
 
+#ifdef __ANDROID__
+#include <cerrno>
+#include <hardware/hwvulkan.h>
+#endif
+
 namespace vk
 {
 
@@ -301,3 +306,50 @@
 }
 
 }
+
+#ifdef __ANDROID__
+
+extern "C" hwvulkan_module_t HAL_MODULE_INFO_SYM;
+
+namespace {
+
+	int CloseDevice(struct hw_device_t *) { return 0; }
+
+	hwvulkan_device_t hal_device = {
+		.common = {
+			.tag = HARDWARE_DEVICE_TAG,
+			.version = HWVULKAN_DEVICE_API_VERSION_0_1,
+			.module = &HAL_MODULE_INFO_SYM.common,
+			.close = CloseDevice,
+		},
+		.EnumerateInstanceExtensionProperties = vkEnumerateInstanceExtensionProperties,
+		.CreateInstance = vkCreateInstance,
+		.GetInstanceProcAddr = vk::GetInstanceProcAddr,
+	};
+
+	int OpenDevice(const hw_module_t *module, const char *id, hw_device_t **device)
+	{
+		if (strcmp(id, HWVULKAN_DEVICE_0) != 0) return -ENOENT;
+		*device = &hal_device.common;
+		return 0;
+	}
+
+	hw_module_methods_t module_methods = { .open = OpenDevice };
+
+}
+
+extern "C" hwvulkan_module_t HAL_MODULE_INFO_SYM =
+{
+	.common =
+	{
+		.tag = HARDWARE_MODULE_TAG,
+		.module_api_version = HWVULKAN_MODULE_API_VERSION_0_1,
+		.hal_api_version = HARDWARE_HAL_API_VERSION,
+		.id = HWVULKAN_HARDWARE_MODULE_ID,
+		.name = "Swiftshader Pastel",
+		.author = "Google",
+		.methods = &module_methods,
+	}
+};
+
+#endif
diff --git a/src/Vulkan/libvk_swiftshader.lds b/src/Vulkan/libvk_swiftshader.lds
index f3cee5c..f31c0c0 100644
--- a/src/Vulkan/libvk_swiftshader.lds
+++ b/src/Vulkan/libvk_swiftshader.lds
@@ -8,6 +8,9 @@
 	_ZTS*;
 	_ZTI*;
 
+	# Android HAL module info object
+	HMI;
+
 local:
 	*;
 };