Add Direct-to-Display support using KMS/DRM

Bug: b/176909700
Change-Id: I5cecfbdfc4b5fc28180b1421c36ce94813605bd5
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/51508
Kokoro-Result: kokoro <noreply+kokoro@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
Tested-by: Nicolas Caramelli <caramelli.devel@gmail.com>
Commit-Queue: Nicolas Caramelli <caramelli.devel@gmail.com>
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 55b7fc9..6d243b8 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -98,6 +98,10 @@
     find_library(DIRECTFB directfb)
     find_path(DIRECTFB_INCLUDE_DIR directfb/directfb.h)
 endif(SWIFTSHADER_BUILD_WSI_DIRECTFB)
+if(SWIFTSHADER_BUILD_WSI_D2D)
+    find_library(D2D drm)
+    find_path(D2D_INCLUDE_DIR libdrm/drm.h)
+endif(SWIFTSHADER_BUILD_WSI_D2D)
 
 ###########################################################
 # Options
@@ -126,6 +130,7 @@
 option_if_not_defined(SWIFTSHADER_BUILD_VULKAN "Build the Vulkan library" TRUE)
 option_if_not_defined(SWIFTSHADER_BUILD_WSI_WAYLAND "Build the Wayland WSI support" FALSE)
 option_if_not_defined(SWIFTSHADER_BUILD_WSI_DIRECTFB "Build the DirectFB WSI support" FALSE)
+option_if_not_defined(SWIFTSHADER_BUILD_WSI_D2D "Build the Direct-to-Display WSI support" FALSE)
 option_if_not_defined(SWIFTSHADER_BUILD_PVR "Build the PowerVR examples" TRUE)
 option_if_not_defined(SWIFTSHADER_GET_PVR "Check out the PowerVR submodule" FALSE)
 option_if_not_defined(SWIFTSHADER_BUILD_ANGLE "Build angle" FALSE)
@@ -705,6 +710,10 @@
         list(APPEND OS_LIBS "${DIRECTFB}")
         include_directories(${DIRECTFB_INCLUDE_DIR}/directfb)
     endif(SWIFTSHADER_BUILD_WSI_DIRECTFB)
+    if(SWIFTSHADER_BUILD_WSI_D2D)
+        list(APPEND OS_LIBS "${D2D}")
+        include_directories(${D2D_INCLUDE_DIR}/libdrm)
+    endif(SWIFTSHADER_BUILD_WSI_D2D)
 elseif(FUCHSIA)
     set(OS_LIBS zircon)
 elseif(APPLE)
@@ -795,6 +804,11 @@
                 target_compile_definitions(vk_base INTERFACE "VK_USE_PLATFORM_DIRECTFB_EXT")
             endif()
         endif(SWIFTSHADER_BUILD_WSI_DIRECTFB)
+        if(SWIFTSHADER_BUILD_WSI_D2D)
+            if(D2D)
+                target_compile_definitions(vk_base INTERFACE "VK_USE_PLATFORM_DISPLAY_KHR")
+            endif()
+        endif(SWIFTSHADER_BUILD_WSI_D2D)
     elseif(APPLE)
         target_compile_definitions(vk_base INTERFACE "VK_USE_PLATFORM_MACOS_MVK")
     elseif(FUCHSIA)
diff --git a/src/Vulkan/VkGetProcAddress.cpp b/src/Vulkan/VkGetProcAddress.cpp
index 10cc5e3..9b7c516 100644
--- a/src/Vulkan/VkGetProcAddress.cpp
+++ b/src/Vulkan/VkGetProcAddress.cpp
@@ -124,6 +124,16 @@
 	MAKE_VULKAN_INSTANCE_ENTRY(vkCreateDirectFBSurfaceEXT),
 	MAKE_VULKAN_INSTANCE_ENTRY(vkGetPhysicalDeviceDirectFBPresentationSupportEXT),
 #endif
+#ifdef VK_USE_PLATFORM_DISPLAY_KHR
+	// VK_KHR_display
+	MAKE_VULKAN_INSTANCE_ENTRY(vkCreateDisplayModeKHR),
+	MAKE_VULKAN_INSTANCE_ENTRY(vkCreateDisplayPlaneSurfaceKHR),
+	MAKE_VULKAN_INSTANCE_ENTRY(vkGetDisplayModePropertiesKHR),
+	MAKE_VULKAN_INSTANCE_ENTRY(vkGetDisplayPlaneCapabilitiesKHR),
+	MAKE_VULKAN_INSTANCE_ENTRY(vkGetDisplayPlaneSupportedDisplaysKHR),
+	MAKE_VULKAN_INSTANCE_ENTRY(vkGetPhysicalDeviceDisplayPlanePropertiesKHR),
+	MAKE_VULKAN_INSTANCE_ENTRY(vkGetPhysicalDeviceDisplayPropertiesKHR),
+#endif
 #ifdef VK_USE_PLATFORM_MACOS_MVK
 	// VK_MVK_macos_surface
 	MAKE_VULKAN_INSTANCE_ENTRY(vkCreateMacOSSurfaceMVK),
diff --git a/src/Vulkan/libVulkan.cpp b/src/Vulkan/libVulkan.cpp
index f1054fe..ba5981d 100644
--- a/src/Vulkan/libVulkan.cpp
+++ b/src/Vulkan/libVulkan.cpp
@@ -65,6 +65,10 @@
 #	include "WSI/DirectFBSurfaceEXT.hpp"
 #endif
 
+#ifdef VK_USE_PLATFORM_DISPLAY_KHR
+#	include "WSI/DisplaySurfaceKHR.hpp"
+#endif
+
 #ifdef VK_USE_PLATFORM_WIN32_KHR
 #	include "WSI/Win32SurfaceKHR.hpp"
 #endif
@@ -319,6 +323,9 @@
 #ifdef VK_USE_PLATFORM_DIRECTFB_EXT
 	{ VK_EXT_DIRECTFB_SURFACE_EXTENSION_NAME, VK_EXT_DIRECTFB_SURFACE_SPEC_VERSION },
 #endif
+#ifdef VK_USE_PLATFORM_DISPLAY_KHR
+	{ VK_KHR_DISPLAY_EXTENSION_NAME, VK_KHR_DISPLAY_SPEC_VERSION },
+#endif
 #ifdef VK_USE_PLATFORM_MACOS_MVK
 	{ VK_MVK_MACOS_SURFACE_EXTENSION_NAME, VK_MVK_MACOS_SURFACE_SPEC_VERSION },
 #endif
@@ -3595,6 +3602,64 @@
 }
 #endif
 
+#ifdef VK_USE_PLATFORM_DISPLAY_KHR
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateDisplayModeKHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display, const VkDisplayModeCreateInfoKHR *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkDisplayModeKHR *pMode)
+{
+	TRACE("(VkPhysicalDevice physicalDevice = %p, VkDisplayKHR display = %p, VkDisplayModeCreateInfoKHR* pCreateInfo = %p, VkAllocationCallbacks* pAllocator = %p, VkDisplayModeKHR* pModei = %p)",
+	      physicalDevice, static_cast<void *>(display), pCreateInfo, pAllocator, pMode);
+
+	return VK_SUCCESS;
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateDisplayPlaneSurfaceKHR(VkInstance instance, const VkDisplaySurfaceCreateInfoKHR *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface)
+{
+	TRACE("(VkInstance instance = %p, VkDisplaySurfaceCreateInfoKHR* pCreateInfo = %p, VkAllocationCallbacks* pAllocator = %p, VkSurface* pSurface = %p)",
+	      instance, pCreateInfo, pAllocator, pSurface);
+
+	return vk::DisplaySurfaceKHR::Create(pAllocator, pCreateInfo, pSurface);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetDisplayModePropertiesKHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display, uint32_t *pPropertyCount, VkDisplayModePropertiesKHR *pProperties)
+{
+	TRACE("(VkPhysicalDevice physicalDevice = %p, VkDisplayKHR display = %p, uint32_t* pPropertyCount = %p, VkDisplayModePropertiesKHR* pProperties = %p)",
+	      physicalDevice, static_cast<void *>(display), pPropertyCount, pProperties);
+
+	return vk::DisplaySurfaceKHR::GetDisplayModeProperties(pPropertyCount, pProperties);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetDisplayPlaneCapabilitiesKHR(VkPhysicalDevice physicalDevice, VkDisplayModeKHR mode, uint32_t planeIndex, VkDisplayPlaneCapabilitiesKHR *pCapabilities)
+{
+	TRACE("(VkPhysicalDevice physicalDevice = %p, VkDisplayModeKHR mode = %p, uint32_t planeIndex = %d, VkDisplayPlaneCapabilitiesKHR* pCapabilities = %p)",
+	      physicalDevice, static_cast<void *>(mode), planeIndex, pCapabilities);
+
+	return vk::DisplaySurfaceKHR::GetDisplayPlaneCapabilities(pCapabilities);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetDisplayPlaneSupportedDisplaysKHR(VkPhysicalDevice physicalDevice, uint32_t planeIndex, uint32_t *pDisplayCount, VkDisplayKHR *pDisplays)
+{
+	TRACE("(VkPhysicalDevice physicalDevice = %p, uint32_t planeIndex = %d, uint32_t* pDisplayCount = %p, VkDisplayKHR* pDisplays = %p)",
+	      physicalDevice, planeIndex, pDisplayCount, pDisplays);
+
+	return vk::DisplaySurfaceKHR::GetDisplayPlaneSupportedDisplays(pDisplayCount, pDisplays);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceDisplayPlanePropertiesKHR(VkPhysicalDevice physicalDevice, uint32_t *pPropertyCount, VkDisplayPlanePropertiesKHR *pProperties)
+{
+	TRACE("(VkPhysicalDevice physicalDevice = %p, uint32_t* pPropertyCount = %p, VkDisplayPlanePropertiesKHR* pProperties = %p)",
+	      physicalDevice, pPropertyCount, pProperties);
+
+	return vk::DisplaySurfaceKHR::GetPhysicalDeviceDisplayPlaneProperties(pPropertyCount, pProperties);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceDisplayPropertiesKHR(VkPhysicalDevice physicalDevice, uint32_t *pPropertyCount, VkDisplayPropertiesKHR *pProperties)
+{
+	TRACE("(VkPhysicalDevice physicalDevice = %p, uint32_t* pPropertyCount = %p, VkDisplayPropertiesKHR* pProperties = %p)",
+	      physicalDevice, pPropertyCount, pProperties);
+
+	return vk::DisplaySurfaceKHR::GetPhysicalDeviceDisplayProperties(pPropertyCount, pProperties);
+}
+#endif
+
 #ifdef VK_USE_PLATFORM_MACOS_MVK
 VKAPI_ATTR VkResult VKAPI_CALL vkCreateMacOSSurfaceMVK(VkInstance instance, const VkMacOSSurfaceCreateInfoMVK *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface)
 {
diff --git a/src/WSI/CMakeLists.txt b/src/WSI/CMakeLists.txt
index 1f7025e..8ba95d5 100644
--- a/src/WSI/CMakeLists.txt
+++ b/src/WSI/CMakeLists.txt
@@ -59,6 +59,13 @@
             DirectFBSurfaceEXT.hpp
         )
     endif()
+
+    if(D2D)
+        list(APPEND WSI_SRC_FILES
+            DisplaySurfaceKHR.cpp
+            DisplaySurfaceKHR.hpp
+        )
+    endif()
 elseif(APPLE)
     list(APPEND WSI_SRC_FILES
         MetalSurface.mm
diff --git a/src/WSI/DisplaySurfaceKHR.cpp b/src/WSI/DisplaySurfaceKHR.cpp
new file mode 100644
index 0000000..ddee939
--- /dev/null
+++ b/src/WSI/DisplaySurfaceKHR.cpp
@@ -0,0 +1,230 @@
+// Copyright 2020 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 "DisplaySurfaceKHR.hpp"
+
+#include "Vulkan/VkDeviceMemory.hpp"
+#include "Vulkan/VkImage.hpp"
+
+#include <fcntl.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <unistd.h>
+#include <xf86drm.h>
+
+namespace vk {
+
+VkResult DisplaySurfaceKHR::GetDisplayModeProperties(uint32_t *pPropertyCount, VkDisplayModePropertiesKHR *pProperties)
+{
+	*pPropertyCount = 1;
+
+	if(pProperties)
+	{
+		int fd = open("/dev/dri/card0", O_RDWR);
+		drmModeRes *res = drmModeGetResources(fd);
+		drmModeConnector *connector = drmModeGetConnector(fd, res->connectors[0]);
+		pProperties->displayMode = (uintptr_t)connector->modes[0].name;
+		pProperties->parameters.visibleRegion.width = connector->modes[0].hdisplay;
+		pProperties->parameters.visibleRegion.height = connector->modes[0].vdisplay;
+		pProperties->parameters.refreshRate = connector->modes[0].vrefresh * 1000;
+		drmModeFreeConnector(connector);
+		drmModeFreeResources(res);
+		close(fd);
+	}
+
+	return VK_SUCCESS;
+}
+
+VkResult DisplaySurfaceKHR::GetDisplayPlaneCapabilities(VkDisplayPlaneCapabilitiesKHR *pCapabilities)
+{
+	int fd = open("/dev/dri/card0", O_RDWR);
+	drmModeRes *res = drmModeGetResources(fd);
+	drmModeConnector *connector = drmModeGetConnector(fd, res->connectors[0]);
+	pCapabilities->supportedAlpha = VK_DISPLAY_PLANE_ALPHA_OPAQUE_BIT_KHR;
+	pCapabilities->minSrcPosition.x = 0;
+	pCapabilities->minSrcPosition.y = 0;
+	pCapabilities->maxSrcPosition.x = 0;
+	pCapabilities->maxSrcPosition.y = 0;
+	pCapabilities->minSrcExtent.width = connector->modes[0].hdisplay;
+	pCapabilities->minSrcExtent.height = connector->modes[0].vdisplay;
+	pCapabilities->maxSrcExtent.width = connector->modes[0].hdisplay;
+	pCapabilities->maxSrcExtent.height = connector->modes[0].vdisplay;
+	pCapabilities->minDstPosition.x = 0;
+	pCapabilities->minDstPosition.y = 0;
+	pCapabilities->maxDstPosition.x = 0;
+	pCapabilities->maxDstPosition.y = 0;
+	pCapabilities->minDstExtent.width = connector->modes[0].hdisplay;
+	pCapabilities->minDstExtent.height = connector->modes[0].vdisplay;
+	pCapabilities->maxDstExtent.width = connector->modes[0].hdisplay;
+	pCapabilities->maxDstExtent.height = connector->modes[0].vdisplay;
+	drmModeFreeConnector(connector);
+	drmModeFreeResources(res);
+	close(fd);
+
+	return VK_SUCCESS;
+}
+
+VkResult DisplaySurfaceKHR::GetDisplayPlaneSupportedDisplays(uint32_t *pDisplayCount, VkDisplayKHR *pDisplays)
+{
+	*pDisplayCount = 1;
+
+	if(pDisplays)
+	{
+		int fd = open("/dev/dri/card0", O_RDWR);
+		drmModeRes *res = drmModeGetResources(fd);
+		*pDisplays = res->connectors[0];
+		drmModeFreeResources(res);
+		close(fd);
+	}
+
+	return VK_SUCCESS;
+}
+
+VkResult DisplaySurfaceKHR::GetPhysicalDeviceDisplayPlaneProperties(uint32_t *pPropertyCount, VkDisplayPlanePropertiesKHR *pProperties)
+{
+	*pPropertyCount = 1;
+
+	if(pProperties)
+	{
+		int fd = open("/dev/dri/card0", O_RDWR);
+		drmModeRes *res = drmModeGetResources(fd);
+		pProperties->currentDisplay = res->connectors[0];
+		pProperties->currentStackIndex = 0;
+		drmModeFreeResources(res);
+		close(fd);
+	}
+
+	return VK_SUCCESS;
+}
+
+VkResult DisplaySurfaceKHR::GetPhysicalDeviceDisplayProperties(uint32_t *pPropertyCount, VkDisplayPropertiesKHR *pProperties)
+{
+	*pPropertyCount = 1;
+
+	if(pProperties)
+	{
+		int fd = open("/dev/dri/card0", O_RDWR);
+		drmModeRes *res = drmModeGetResources(fd);
+		drmModeConnector *connector = drmModeGetConnector(fd, res->connectors[0]);
+		pProperties->display = res->connectors[0];
+		pProperties->displayName = "monitor";
+		pProperties->physicalDimensions.width = connector->mmWidth;
+		pProperties->physicalDimensions.height = connector->mmHeight;
+		if(pProperties->physicalDimensions.width <= 0 || pProperties->physicalDimensions.height <= 0)
+		{
+			pProperties->physicalDimensions.width = connector->modes[0].hdisplay * 25.4 / 96;
+			pProperties->physicalDimensions.height = connector->modes[0].vdisplay * 25.4 / 96;
+		}
+		pProperties->physicalResolution.width = connector->modes[0].hdisplay;
+		pProperties->physicalResolution.height = connector->modes[0].vdisplay;
+		pProperties->supportedTransforms = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
+		pProperties->planeReorderPossible = VK_FALSE;
+		pProperties->persistentContent = VK_FALSE;
+		drmModeFreeConnector(connector);
+		drmModeFreeResources(res);
+		close(fd);
+	}
+
+	return VK_SUCCESS;
+}
+
+DisplaySurfaceKHR::DisplaySurfaceKHR(const VkDisplaySurfaceCreateInfoKHR *pCreateInfo, void *mem)
+{
+	fd = open("/dev/dri/card0", O_RDWR);
+	drmModeRes *res = drmModeGetResources(fd);
+	connector_id = res->connectors[0];
+	drmModeFreeResources(res);
+	drmModeConnector *connector = drmModeGetConnector(fd, connector_id);
+	encoder_id = connector->encoder_id;
+	memcpy(&mode_info, &connector->modes[0], sizeof(drmModeModeInfo));
+	drmModeFreeConnector(connector);
+	drmModeEncoder *encoder = drmModeGetEncoder(fd, encoder_id);
+	crtc_id = encoder->crtc_id;
+	drmModeFreeEncoder(encoder);
+
+	crtc = drmModeGetCrtc(fd, crtc_id);
+
+	struct drm_mode_create_dumb creq;
+	memset(&creq, 0, sizeof(struct drm_mode_create_dumb));
+	creq.width = mode_info.hdisplay;
+	creq.height = mode_info.vdisplay;
+	creq.bpp = 32;
+	drmIoctl(fd, DRM_IOCTL_MODE_CREATE_DUMB, &creq);
+
+	handle = creq.handle;
+	width = creq.width;
+	height = creq.height;
+	pitch = creq.pitch;
+	size = creq.size;
+
+	drmModeAddFB(fd, width, height, 24, 32, pitch, handle, &fb_id);
+
+	struct drm_mode_map_dumb mreq;
+	memset(&mreq, 0, sizeof(struct drm_mode_map_dumb));
+	mreq.handle = handle;
+	drmIoctl(fd, DRM_IOCTL_MODE_MAP_DUMB, &mreq);
+
+	fb_buffer = static_cast<uint8_t *>(mmap(NULL, size, PROT_WRITE, MAP_SHARED, fd, mreq.offset));
+}
+
+void DisplaySurfaceKHR::destroySurface(const VkAllocationCallbacks *pAllocator)
+{
+	munmap(fb_buffer, size);
+
+	drmModeRmFB(fd, fb_id);
+
+	struct drm_mode_destroy_dumb dreq;
+	memset(&dreq, 0, sizeof(struct drm_mode_destroy_dumb));
+	dreq.handle = handle;
+	drmIoctl(fd, DRM_IOCTL_MODE_DESTROY_DUMB, &dreq);
+
+	drmModeSetCrtc(fd, crtc->crtc_id, crtc->buffer_id, crtc->x, crtc->y, &connector_id, 1, &crtc->mode);
+	drmModeFreeCrtc(crtc);
+
+	close(fd);
+}
+
+size_t DisplaySurfaceKHR::ComputeRequiredAllocationSize(const VkDisplaySurfaceCreateInfoKHR *pCreateInfo)
+{
+	return 0;
+}
+
+void DisplaySurfaceKHR::getSurfaceCapabilities(VkSurfaceCapabilitiesKHR *pSurfaceCapabilities) const
+{
+	SurfaceKHR::getSurfaceCapabilities(pSurfaceCapabilities);
+
+	VkExtent2D extent = { width, height };
+
+	pSurfaceCapabilities->currentExtent = extent;
+	pSurfaceCapabilities->minImageExtent = extent;
+	pSurfaceCapabilities->maxImageExtent = extent;
+}
+
+void DisplaySurfaceKHR::attachImage(PresentImage *image)
+{
+}
+
+void DisplaySurfaceKHR::detachImage(PresentImage *image)
+{
+}
+
+VkResult DisplaySurfaceKHR::present(PresentImage *image)
+{
+	image->getImage()->copyTo(fb_buffer, pitch);
+	drmModeSetCrtc(fd, crtc_id, fb_id, 0, 0, &connector_id, 1, &mode_info);
+
+	return VK_SUCCESS;
+}
+
+}  // namespace vk
diff --git a/src/WSI/DisplaySurfaceKHR.hpp b/src/WSI/DisplaySurfaceKHR.hpp
new file mode 100644
index 0000000..0cfe3ca
--- /dev/null
+++ b/src/WSI/DisplaySurfaceKHR.hpp
@@ -0,0 +1,63 @@
+// Copyright 2020 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_DISPLAYSURFACEKHR_HPP
+#define SWIFTSHADER_DISPLAYSURFACEKHR_HPP
+
+#include "VkSurfaceKHR.hpp"
+#include "Vulkan/VkObject.hpp"
+
+#include <xf86drmMode.h>
+
+namespace vk {
+
+class DisplaySurfaceKHR : public SurfaceKHR, public ObjectBase<DisplaySurfaceKHR, VkSurfaceKHR>
+{
+public:
+	static VkResult GetDisplayModeProperties(uint32_t *pPropertyCount, VkDisplayModePropertiesKHR *pProperties);
+	static VkResult GetDisplayPlaneCapabilities(VkDisplayPlaneCapabilitiesKHR *pCapabilities);
+	static VkResult GetDisplayPlaneSupportedDisplays(uint32_t *pDisplayCount, VkDisplayKHR *pDisplays);
+	static VkResult GetPhysicalDeviceDisplayPlaneProperties(uint32_t *pPropertyCount, VkDisplayPlanePropertiesKHR *pProperties);
+	static VkResult GetPhysicalDeviceDisplayProperties(uint32_t *pPropertyCount, VkDisplayPropertiesKHR *pProperties);
+
+	DisplaySurfaceKHR(const VkDisplaySurfaceCreateInfoKHR *pCreateInfo, void *mem);
+
+	void destroySurface(const VkAllocationCallbacks *pAllocator) override;
+
+	static size_t ComputeRequiredAllocationSize(const VkDisplaySurfaceCreateInfoKHR *pCreateInfo);
+
+	void getSurfaceCapabilities(VkSurfaceCapabilitiesKHR *pSurfaceCapabilities) const override;
+
+	virtual void attachImage(PresentImage *image) override;
+	virtual void detachImage(PresentImage *image) override;
+	VkResult present(PresentImage *image) override;
+
+private:
+	int fd;
+	uint32_t connector_id;
+	uint32_t encoder_id;
+	uint32_t crtc_id;
+	drmModeCrtc *crtc;
+	drmModeModeInfo mode_info;
+	uint32_t handle;
+	uint32_t width;
+	uint32_t height;
+	uint32_t pitch;
+	uint32_t size;
+	uint32_t fb_id;
+	uint8_t *fb_buffer;
+};
+
+}  // namespace vk
+#endif  //SWIFTSHADER_DISPLAYSURFACEKHR_HPP