Add basic VkSurfaceKHR (Xlib only for now)

Should pass the following deqp tests:
dEQP-VK.wsi.xlib.surface.create
dEQP-VK.wsi.xlib.surface.query_supportS
dEQP-VK.wsi.xlib.surface.query_capabilities
dEQP-VK.wsi.xlib.surface.query_formatsW
dEQP-VK.wsi.xlib.surface.query_present_modes
dEQP-VK.wsi.xlib.surface.destroy_null_handle
dEQP-VK.wsi.xlib.surface.initial_size
dEQP-VK.wsi.xlib.surface.resizeSW

Bug: b/124265819
Change-Id: I92da1cc8d60923ea97aa26d3d6a098274c6e06b7
Reviewed-on: https://swiftshader-review.googlesource.com/c/25308
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
Reviewed-by: Corentin Wallez <cwallez@google.com>
Tested-by: Hernan Liatis <hliatis@google.com>
Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
diff --git a/src/Vulkan/VkDestroy.h b/src/Vulkan/VkDestroy.h
index 25ef90a..2bdad4e 100644
--- a/src/Vulkan/VkDestroy.h
+++ b/src/Vulkan/VkDestroy.h
@@ -34,6 +34,7 @@
 #include "VkSemaphore.hpp"
 #include "VkShaderModule.hpp"
 #include "VkRenderPass.hpp"
+#include "WSI/VkSurfaceKHR.hpp"
 
 namespace vk
 {
diff --git a/src/Vulkan/VkGetProcAddress.cpp b/src/Vulkan/VkGetProcAddress.cpp
index c60aaad..1c2ddd6 100644
--- a/src/Vulkan/VkGetProcAddress.cpp
+++ b/src/Vulkan/VkGetProcAddress.cpp
@@ -17,6 +17,8 @@
 #include <unordered_map>
 #include <string>
 
+#include <vulkan/vulkan.h>
+
 namespace vk
 {
 
@@ -72,6 +74,14 @@
 	MAKE_VULKAN_INSTANCE_ENTRY(vkGetPhysicalDeviceQueueFamilyProperties2KHR),
 	MAKE_VULKAN_INSTANCE_ENTRY(vkGetPhysicalDeviceMemoryProperties2KHR),
 	MAKE_VULKAN_INSTANCE_ENTRY(vkGetPhysicalDeviceSparseImageFormatProperties2KHR),
+	MAKE_VULKAN_INSTANCE_ENTRY(vkDestroySurfaceKHR),
+#ifdef VK_USE_PLATFORM_XLIB_KHR
+	MAKE_VULKAN_INSTANCE_ENTRY(vkCreateXlibSurfaceKHR),
+#endif
+	MAKE_VULKAN_INSTANCE_ENTRY(vkGetPhysicalDeviceSurfaceSupportKHR),
+	MAKE_VULKAN_INSTANCE_ENTRY(vkGetPhysicalDeviceSurfaceCapabilitiesKHR),
+	MAKE_VULKAN_INSTANCE_ENTRY(vkGetPhysicalDeviceSurfaceFormatsKHR),
+	MAKE_VULKAN_INSTANCE_ENTRY(vkGetPhysicalDeviceSurfacePresentModesKHR),
 };
 #undef MAKE_VULKAN_INSTANCE_ENTRY
 
diff --git a/src/Vulkan/libVulkan.cpp b/src/Vulkan/libVulkan.cpp
index 8822500..b0ebe63 100644
--- a/src/Vulkan/libVulkan.cpp
+++ b/src/Vulkan/libVulkan.cpp
@@ -41,6 +41,10 @@
 #include "VkShaderModule.hpp"
 #include "VkRenderPass.hpp"
 
+#ifdef VK_USE_PLATFORM_XLIB_KHR
+#include "WSI/XlibSurfaceKHR.hpp"
+#endif
+
 #include <algorithm>
 #include <cstring>
 #include <string>
@@ -2046,4 +2050,69 @@
 	vk::Cast(device)->getDescriptorSetLayoutSupport(pCreateInfo, pSupport);
 }
 
+VKAPI_ATTR void VKAPI_CALL vkDestroySurfaceKHR(VkInstance instance, VkSurfaceKHR surface, const VkAllocationCallbacks* pAllocator)
+{
+    TRACE("(VkInstance instance = 0x%X, VkSurfaceKHR surface = 0x%X, const VkAllocationCallbacks* pAllocator = 0x%X)",
+            instance, surface, pAllocator);
+
+    vk::destroy(surface, pAllocator);
+}
+
+#ifdef VK_USE_PLATFORM_XLIB_KHR
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateXlibSurfaceKHR(VkInstance instance, const VkXlibSurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface)
+{
+	TRACE("(VkInstance instance = 0x%X, VkXlibSurfaceCreateInfoKHR* pCreateInfo = 0x%X, VkAllocationCallbacks* pAllocator = 0x%X, VkSurface* pSurface = 0x%X)",
+			instance, pCreateInfo, pAllocator, pSurface);
+
+	return vk::XlibSurfaceKHR::Create(pAllocator, pCreateInfo, pSurface);
+}
+#endif
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, VkSurfaceKHR surface, VkBool32* pSupported)
+{
+	TRACE("(VkPhysicalDevice physicalDevice = 0x%X, uint32_t queueFamilyIndex = 0x%X, VkSurface surface = 0x%X, VKBool32* pSupported = 0x%X)",
+			physicalDevice, queueFamilyIndex, surface, pSupported);
+
+	*pSupported =  VK_TRUE;
+	return VK_SUCCESS;
+}
+
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceCapabilitiesKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, VkSurfaceCapabilitiesKHR* pSurfaceCapabilities)
+{
+	TRACE("(VkPhysicalDevice physicalDevice = 0x%X, VkSurfaceKHR surface = 0x%X, VkSurfaceCapabilitiesKHR* pSurfaceCapabilities = 0x%X)",
+			physicalDevice, surface, pSurfaceCapabilities);
+
+	vk::Cast(surface)->getSurfaceCapabilities(pSurfaceCapabilities);
+	return VK_SUCCESS;
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint32_t* pSurfaceFormatCount, VkSurfaceFormatKHR* pSurfaceFormats)
+{
+	TRACE("(VkPhysicalDevice physicalDevice = 0x%X, VkSurfaceKHR surface = 0x%X. uint32_t* pSurfaceFormatCount = 0x%X, VkSurfaceFormatKHR* pSurfaceFormats)",
+			physicalDevice, surface, pSurfaceFormatCount, pSurfaceFormats);
+
+	if(!pSurfaceFormats)
+	{
+		*pSurfaceFormatCount = vk::Cast(surface)->getSurfaceFormatsCount();
+		return VK_SUCCESS;
+	}
+
+	return vk::Cast(surface)->getSurfaceFormats(pSurfaceFormatCount, pSurfaceFormats);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfacePresentModesKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint32_t* pPresentModeCount, VkPresentModeKHR* pPresentModes)
+{
+	TRACE("(VkPhysicalDevice physicalDevice = 0x%X, VkSurfaceKHR surface = 0x%X uint32_t* pPresentModeCount = 0x%X, VkPresentModeKHR* pPresentModes = 0x%X)",
+			physicalDevice, surface, pPresentModeCount, pPresentModes);
+
+	if(!pPresentModes)
+	{
+		*pPresentModeCount = vk::Cast(surface)->getPresentModeCount();
+		return VK_SUCCESS;
+	}
+
+	return vk::Cast(surface)->getPresentModes(pPresentModeCount, pPresentModes);
+}
+
 }
diff --git a/src/Vulkan/swiftshader_icd.def b/src/Vulkan/swiftshader_icd.def
index 86ab4ce..5605cbb 100644
--- a/src/Vulkan/swiftshader_icd.def
+++ b/src/Vulkan/swiftshader_icd.def
@@ -207,3 +207,9 @@
 	; VK_KHR_sampler_ycbcr_conversion

 	vkCreateSamplerYcbcrConversionKHR

 	vkDestroySamplerYcbcrConversionKHR

+	; VK_KHR_surface

+	vkDestroySurfaceKHR

+	vkGetPhysicalDeviceSurfaceSupportKHR

+	vkGetPhysicalDeviceSurfaceCapabilitiesKHR

+	vkGetPhysicalDeviceSurfaceFormatsKHR

+	vkGetPhysicalDeviceSurfacePresentModesKHR
\ No newline at end of file
diff --git a/src/WSI/VkSurfaceKHR.cpp b/src/WSI/VkSurfaceKHR.cpp
new file mode 100644
index 0000000..5734db7
--- /dev/null
+++ b/src/WSI/VkSurfaceKHR.cpp
@@ -0,0 +1,88 @@
+// Copyright 2018 The SwiftShader Authors. All Rights Reserved.
+//
+// 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 "VkSurfaceKHR.hpp"
+
+#include <algorithm>
+
+namespace vk
+{
+
+void SurfaceKHR::getSurfaceCapabilities(VkSurfaceCapabilitiesKHR *pSurfaceCapabilities) const
+{
+	pSurfaceCapabilities->minImageCount = 1;
+	pSurfaceCapabilities->maxImageCount = 0;
+
+	pSurfaceCapabilities->maxImageArrayLayers = 1;
+
+	pSurfaceCapabilities->supportedTransforms = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
+	pSurfaceCapabilities->currentTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
+	pSurfaceCapabilities->supportedCompositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
+	pSurfaceCapabilities->supportedUsageFlags = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
+}
+
+uint32_t SurfaceKHR::getSurfaceFormatsCount() const
+{
+	return surfaceFormats.size();
+}
+
+VkResult SurfaceKHR::getSurfaceFormats(uint32_t *pSurfaceFormatCount, VkSurfaceFormatKHR *pSurfaceFormats) const
+{
+	uint32_t count = getSurfaceFormatsCount();
+
+	uint32_t i;
+	for(i = 0; i < std::min(*pSurfaceFormatCount, count); i++)
+	{
+		pSurfaceFormats[i] = surfaceFormats[i];
+	}
+
+	*pSurfaceFormatCount = i;
+
+	if (*pSurfaceFormatCount < count)
+	{
+		return VK_INCOMPLETE;
+	}
+
+	return VK_SUCCESS;
+}
+
+uint32_t SurfaceKHR::getPresentModeCount() const
+{
+	return presentModes.size();
+}
+
+
+VkResult SurfaceKHR::getPresentModes(uint32_t *pPresentModeCount, VkPresentModeKHR *pPresentModes) const
+{
+	uint32_t count = getPresentModeCount();
+
+	uint32_t i;
+	for(i = 0; i < std::min(*pPresentModeCount, count); i++)
+	{
+		pPresentModes[i] = presentModes[i];
+	}
+
+	*pPresentModeCount = i;
+
+	if (*pPresentModeCount < count)
+	{
+		return VK_INCOMPLETE;
+	}
+
+	return VK_SUCCESS;
+}
+
+
+
+}
\ No newline at end of file
diff --git a/src/WSI/VkSurfaceKHR.hpp b/src/WSI/VkSurfaceKHR.hpp
new file mode 100644
index 0000000..65f815f
--- /dev/null
+++ b/src/WSI/VkSurfaceKHR.hpp
@@ -0,0 +1,67 @@
+// Copyright 2018 The SwiftShader Authors. All Rights Reserved.
+//
+// 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 SWIFTSHADER_VKSURFACEKHR_HPP_
+#define SWIFTSHADER_VKSURFACEKHR_HPP_
+
+#include "VkObject.hpp"
+#include <vulkan/vulkan.h>
+#include <vector>
+
+namespace vk
+{
+
+class SurfaceKHR
+{
+public:
+	operator VkSurfaceKHR()
+	{
+		return reinterpret_cast<VkSurfaceKHR>(this);
+	}
+
+	void destroy(const VkAllocationCallbacks* pAllocator)
+	{
+		destroySurface(pAllocator);
+	}
+
+	virtual void destroySurface(const VkAllocationCallbacks* pAllocator) = 0;
+
+	virtual void getSurfaceCapabilities(VkSurfaceCapabilitiesKHR* pSurfaceCapabilities) const;
+
+	uint32_t getSurfaceFormatsCount() const;
+	VkResult getSurfaceFormats(uint32_t* pSurfaceFormatCount, VkSurfaceFormatKHR* pSurfaceFormats) const;
+
+	uint32_t getPresentModeCount() const;
+	VkResult getPresentModes(uint32_t* pPresentModeCount, VkPresentModeKHR* pPresentModes) const;
+
+private:
+	const std::vector<VkSurfaceFormatKHR> surfaceFormats =
+	{
+		{VK_FORMAT_B8G8R8A8_UNORM, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR},
+	};
+
+	const std::vector<VkPresentModeKHR> presentModes =
+	{
+		VK_PRESENT_MODE_FIFO_KHR,
+	};
+};
+
+static inline SurfaceKHR* Cast(VkSurfaceKHR object)
+{
+	return reinterpret_cast<SurfaceKHR*>(object);
+}
+
+}
+
+#endif //SWIFTSHADER_VKSURFACEKHR_HPP_
diff --git a/src/WSI/XlibSurfaceKHR.cpp b/src/WSI/XlibSurfaceKHR.cpp
new file mode 100644
index 0000000..9dd7575
--- /dev/null
+++ b/src/WSI/XlibSurfaceKHR.cpp
@@ -0,0 +1,42 @@
+// 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 "XlibSurfaceKHR.hpp"
+
+namespace vk {
+
+XlibSurfaceKHR::XlibSurfaceKHR(const VkXlibSurfaceCreateInfoKHR *pCreateInfo, void *mem) :
+		pDisplay(pCreateInfo->dpy),
+		window(pCreateInfo->window) {
+
+}
+
+void XlibSurfaceKHR::destroySurface(const VkAllocationCallbacks *pAllocator) {
+
+}
+
+size_t XlibSurfaceKHR::ComputeRequiredAllocationSize(const VkXlibSurfaceCreateInfoKHR *pCreateInfo) {
+	return 0;
+}
+
+void XlibSurfaceKHR::getSurfaceCapabilities(VkSurfaceCapabilitiesKHR *pSurfaceCapabilities) const {
+	SurfaceKHR::getSurfaceCapabilities(pSurfaceCapabilities);
+
+	XWindowAttributes attr;
+	libX11->XGetWindowAttributes(pDisplay, window, &attr);
+	VkExtent2D extent = {static_cast<uint32_t>(attr.width), static_cast<uint32_t>(attr.height)};
+
+	pSurfaceCapabilities->currentExtent = extent;
+	pSurfaceCapabilities->minImageExtent = extent;
+	pSurfaceCapabilities->maxImageExtent = extent;
+}
+
+}
\ No newline at end of file
diff --git a/src/WSI/XlibSurfaceKHR.hpp b/src/WSI/XlibSurfaceKHR.hpp
new file mode 100644
index 0000000..150ea4b
--- /dev/null
+++ b/src/WSI/XlibSurfaceKHR.hpp
@@ -0,0 +1,43 @@
+// Copyright 2018 The SwiftShader Authors. All Rights Reserved.
+//
+// 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 SWIFTSHADER_XLIBSURFACEKHR_HPP
+#define SWIFTSHADER_XLIBSURFACEKHR_HPP
+
+#include "VkObject.hpp"
+#include "libX11.hpp"
+#include "VkSurfaceKHR.hpp"
+
+namespace vk {
+
+class XlibSurfaceKHR : public SurfaceKHR, public ObjectBase<XlibSurfaceKHR, VkSurfaceKHR> {
+public:
+	XlibSurfaceKHR(const VkXlibSurfaceCreateInfoKHR *pCreateInfo, void *mem);
+
+	~XlibSurfaceKHR() = delete;
+
+	void destroySurface(const VkAllocationCallbacks *pAllocator) override;
+
+	static size_t ComputeRequiredAllocationSize(const VkXlibSurfaceCreateInfoKHR *pCreateInfo);
+
+	void getSurfaceCapabilities(VkSurfaceCapabilitiesKHR *pSurfaceCapabilities) const override;
+
+private:
+	Display *pDisplay;
+	Window window;
+
+};
+
+}
+#endif //SWIFTSHADER_XLIBSURFACEKHR_HPP