Better 32 bit Windows Fix

The initial issue that the workaround was fixing was that, on x86,
there are various C calling conventions (__stdcall, __fastcall,
__vectorcall) that mangle in the number of bytes used to pass the
parameters. Both Clang and the Visual Studio compiler were crashing
while attempting to calculate the number of bytes necessary so that
it can mangle the name of the function. It needs the mangled name
to emit deviceFunctionPointers, which is some large table of
function pointers. The crashes happened because not all of the
parameters of the function in question are complete, i.e. some of
them are uninstantiated templates or forward declarations.

The fix is then to include template instantiation directly into
the VK_DEFINE_NON_DISPATCHABLE_HANDLE macro. Because template
instantiation of an already specialized template causes a warning
(treated as an error in Chromium), an extra layer of indirection
was added to make sure we don't hit this issue.

Bug b/129979580

Change-Id: Id811b107be51f494f45fab2ff0cec18e7cfbafaf
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/32449
Presubmit-Ready: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
Tested-by: Alexis Hétu <sugoi@google.com>
diff --git a/src/Vulkan/BUILD.gn b/src/Vulkan/BUILD.gn
index 2090f65..2627f03 100644
--- a/src/Vulkan/BUILD.gn
+++ b/src/Vulkan/BUILD.gn
@@ -109,8 +109,11 @@
   output_name = "libvulkan"
   output_dir = "$root_out_dir/swiftshader"
 
-  ldflags = [ "-Wl,--version-script=" +
-              rebase_path("libvk_swiftshader.lds", root_build_dir) ]
+  if (is_linux)
+  {
+    ldflags = [ "-Wl,--version-script=" +
+                rebase_path("libvk_swiftshader.lds", root_build_dir) ]
+  }
 
   deps = [
     "../Device",
diff --git a/src/Vulkan/VkGetProcAddress.cpp b/src/Vulkan/VkGetProcAddress.cpp
index 55cd84a..9ef61b5 100644
--- a/src/Vulkan/VkGetProcAddress.cpp
+++ b/src/Vulkan/VkGetProcAddress.cpp
@@ -428,37 +428,4 @@
 	}
 };
 
-#endif
-
-#if defined(_MSC_VER) && !defined(_WIN64)
-namespace
-{
-	// The following function is a hack to allow compilation in Visual Studio using the 32 bit compiler"
-	// "fatal error C1001: An internal error has occurred in the compiler.

-	//  (compiler file 'd:\agent\_work\1\s\src\vctools\compiler\utc\src\p2\main.c', line 187)"
-	void Dummy()
-	{
-		{ VkSemaphore handle; }
-		{ VkFence handle; }
-		{ VkDeviceMemory handle; }
-		{ VkBuffer handle; }
-		{ VkImage handle; }
-		{ VkEvent handle; }
-		{ VkQueryPool handle; }
-		{ VkBufferView handle; }
-		{ VkImageView handle; }
-		{ VkShaderModule handle; }
-		{ VkPipelineCache handle; }
-		{ VkPipelineLayout handle; }
-		{ VkRenderPass handle; }
-		{ VkPipeline handle; }
-		{ VkDescriptorSetLayout handle; }
-		{ VkSampler handle; }
-		{ VkDescriptorPool handle; }
-		{ VkFramebuffer handle; }
-		{ VkCommandPool handle; }
-		{ VkSamplerYcbcrConversion handle; }

-		{ VkDescriptorUpdateTemplate handle; }

-	}
-}
 #endif
\ No newline at end of file
diff --git a/src/Vulkan/VulkanPlatform.h b/src/Vulkan/VulkanPlatform.h
index 068d3eb..cdbda52 100644
--- a/src/Vulkan/VulkanPlatform.h
+++ b/src/Vulkan/VulkanPlatform.h
@@ -18,10 +18,10 @@
 #include <cstddef>
 #include <cstdint>
 
-template<typename HandleType> class VkNonDispatchableHandleBase
+template<typename HandleType> class VkHandle
 {
 public:
-	VkNonDispatchableHandleBase(HandleType handle)
+	VkHandle(HandleType handle)
 	{
 		u.dummy = 0;
 		u.handle = handle;
@@ -52,20 +52,15 @@
 	PointerHandleUnion u;
 };
 
-template<typename T> class VkNonDispatchableHandle : public VkNonDispatchableHandleBase<T>
+template<typename T> class VkNonDispatchableHandleBase : public VkHandle<T>
 {
 public:
 	using HandleType = T;
 
-	VkNonDispatchableHandle() : VkNonDispatchableHandleBase<T>(nullptr)
+	VkNonDispatchableHandleBase(HandleType handle) : VkHandle<T>(handle)
 	{
 	}
 
-	VkNonDispatchableHandle(HandleType handle) : VkNonDispatchableHandleBase<T>(handle)
-	{
-		static_assert(sizeof(VkNonDispatchableHandle) == sizeof(uint64_t), "Size is not 64 bits!");
-	}
-
 	void operator=(HandleType handle)
 	{
 		this->set(handle);
@@ -75,14 +70,13 @@
 // VkDescriptorSet objects are really just memory in the VkDescriptorPool
 // object, so define different/more convenient operators for this object.
 struct VkDescriptorSet_T;
-template<> class VkNonDispatchableHandle<VkDescriptorSet_T*> : public VkNonDispatchableHandleBase<uint8_t*>
+template<> class VkNonDispatchableHandleBase<VkDescriptorSet_T*> : public VkHandle<uint8_t*>
 {
 public:
 	using HandleType = uint8_t*;
 
-	VkNonDispatchableHandle(HandleType handle) : VkNonDispatchableHandleBase<uint8_t*>(handle)
+	VkNonDispatchableHandleBase(HandleType handle) : VkHandle<uint8_t*>(handle)
 	{
-		static_assert(sizeof(VkNonDispatchableHandle) == sizeof(uint64_t), "Size is not 64 bits!");
 	}
 
 	HandleType operator+(ptrdiff_t rhs) const
@@ -101,9 +95,23 @@
 	}
 };
 
+template<typename T> class VkNonDispatchableHandle : public VkNonDispatchableHandleBase<T>
+{
+public:
+	VkNonDispatchableHandle() : VkNonDispatchableHandleBase<T>(nullptr)
+	{
+	}
+
+	VkNonDispatchableHandle(typename VkNonDispatchableHandleBase<T>::HandleType handle) : VkNonDispatchableHandleBase<T>(handle)
+	{
+		static_assert(sizeof(VkNonDispatchableHandle) == sizeof(uint64_t), "Size is not 64 bits!");
+	}
+};
+
 #define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) \
 	typedef struct object##_T *object##Ptr; \
-	typedef VkNonDispatchableHandle<object##Ptr> object;
+	typedef VkNonDispatchableHandle<object##Ptr> object; \
+    template class VkNonDispatchableHandle<object##Ptr>;
 
 #include <vulkan/vulkan.h>
 
diff --git a/src/WSI/BUILD.gn b/src/WSI/BUILD.gn
index 603032a..2314d4b 100644
--- a/src/WSI/BUILD.gn
+++ b/src/WSI/BUILD.gn
@@ -20,12 +20,17 @@
     "VkSurfaceKHR.hpp",
     "VkSwapchainKHR.cpp",
     "VkSwapchainKHR.hpp",
-    "XlibSurfaceKHR.cpp",
-    "XlibSurfaceKHR.hpp",
-    "libX11.cpp",
-    "libX11.hpp",
   ]
 
+  if (is_linux) {
+    sources += [
+      "XlibSurfaceKHR.cpp",
+      "XlibSurfaceKHR.hpp",
+      "libX11.cpp",
+      "libX11.hpp",
+    ]
+  }
+
   include_dirs = [
     "..",
     "../../include",