Add DirectFB support for Vulkan WSI
Bug: b/162574690
Change-Id: I825af0494737ec9090da9580dfd876db88e3c289
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/47368
Kokoro-Result: kokoro <noreply+kokoro@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
Tested-by: Nicolas Caramelli <caramelli.devel@gmail.com>
diff --git a/CMakeLists.txt b/CMakeLists.txt
index a966fc6..87a5dba 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -89,6 +89,10 @@
if(SWIFTSHADER_BUILD_WSI_WAYLAND)
find_library(WAYLAND wayland-client)
endif(SWIFTSHADER_BUILD_WSI_WAYLAND)
+if(SWIFTSHADER_BUILD_WSI_DIRECTFB)
+ find_library(DIRECTFB directfb)
+ find_path(DIRECTFB_INCLUDE_DIR directfb/directfb.h)
+endif(SWIFTSHADER_BUILD_WSI_DIRECTFB)
###########################################################
# Options
@@ -116,6 +120,7 @@
option_if_not_defined(SWIFTSHADER_BUILD_GLES_CM "Build the OpenGL ES 1.1 library" TRUE)
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_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)
@@ -647,6 +652,10 @@
if(SWIFTSHADER_BUILD_WSI_WAYLAND)
list(APPEND OS_LIBS "${WAYLAND}")
endif(SWIFTSHADER_BUILD_WSI_WAYLAND)
+ if(SWIFTSHADER_BUILD_WSI_DIRECTFB)
+ list(APPEND OS_LIBS "${DIRECTFB}")
+ include_directories(${DIRECTFB_INCLUDE_DIR}/directfb)
+ endif(SWIFTSHADER_BUILD_WSI_DIRECTFB)
elseif(FUCHSIA)
set(OS_LIBS zircon)
elseif(APPLE)
@@ -732,6 +741,11 @@
target_compile_definitions(vk_base INTERFACE "VK_USE_PLATFORM_WAYLAND_KHR")
endif()
endif(SWIFTSHADER_BUILD_WSI_WAYLAND)
+ if(SWIFTSHADER_BUILD_WSI_DIRECTFB)
+ if(DIRECTFB AND DIRECTFB_INCLUDE_DIR)
+ target_compile_definitions(vk_base INTERFACE "VK_USE_PLATFORM_DIRECTFB_EXT")
+ endif()
+ endif(SWIFTSHADER_BUILD_WSI_DIRECTFB)
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 dfa3bb8..49784ac 100644
--- a/src/Vulkan/VkGetProcAddress.cpp
+++ b/src/Vulkan/VkGetProcAddress.cpp
@@ -119,6 +119,11 @@
MAKE_VULKAN_INSTANCE_ENTRY(vkCreateWaylandSurfaceKHR),
MAKE_VULKAN_INSTANCE_ENTRY(vkGetPhysicalDeviceWaylandPresentationSupportKHR),
#endif
+#ifdef VK_USE_PLATFORM_DIRECTFB_EXT
+ // VK_EXT_directfb_surface
+ MAKE_VULKAN_INSTANCE_ENTRY(vkCreateDirectFBSurfaceEXT),
+ MAKE_VULKAN_INSTANCE_ENTRY(vkGetPhysicalDeviceDirectFBPresentationSupportEXT),
+#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 efb2bf4..b630658 100644
--- a/src/Vulkan/libVulkan.cpp
+++ b/src/Vulkan/libVulkan.cpp
@@ -61,6 +61,10 @@
# include "WSI/WaylandSurfaceKHR.hpp"
#endif
+#ifdef VK_USE_PLATFORM_DIRECTFB_EXT
+# include "WSI/DirectFBSurfaceEXT.hpp"
+#endif
+
#ifdef VK_USE_PLATFORM_WIN32_KHR
# include "WSI/Win32SurfaceKHR.hpp"
#endif
@@ -308,6 +312,9 @@
#ifdef VK_USE_PLATFORM_WAYLAND_KHR
{ VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME, VK_KHR_WAYLAND_SURFACE_SPEC_VERSION },
#endif
+#ifdef VK_USE_PLATFORM_DIRECTFB_EXT
+ { VK_EXT_DIRECTFB_SURFACE_EXTENSION_NAME, VK_EXT_DIRECTFB_SURFACE_SPEC_VERSION },
+#endif
#ifdef VK_USE_PLATFORM_MACOS_MVK
{ VK_MVK_MACOS_SURFACE_EXTENSION_NAME, VK_MVK_MACOS_SURFACE_SPEC_VERSION },
#endif
@@ -3478,6 +3485,24 @@
}
#endif
+#ifdef VK_USE_PLATFORM_DIRECTFB_EXT
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateDirectFBSurfaceEXT(VkInstance instance, const VkDirectFBSurfaceCreateInfoEXT *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface)
+{
+ TRACE("(VkInstance instance = %p, VkDirectFBSurfaceCreateInfoEXT* pCreateInfo = %p, VkAllocationCallbacks* pAllocator = %p, VkSurface* pSurface = %p)",
+ instance, pCreateInfo, pAllocator, pSurface);
+
+ return vk::DirectFBSurfaceEXT::Create(pAllocator, pCreateInfo, pSurface);
+}
+
+VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceDirectFBPresentationSupportEXT(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, IDirectFB *dfb)
+{
+ TRACE("(VkPhysicalDevice physicalDevice = %p, uint32_t queueFamilyIndex = %d, IDirectFB* dfb = %p)",
+ physicalDevice, int(queueFamilyIndex), dfb);
+
+ return VK_TRUE;
+}
+#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 d161c5a..1f7025e 100644
--- a/src/WSI/CMakeLists.txt
+++ b/src/WSI/CMakeLists.txt
@@ -52,6 +52,13 @@
WaylandSurfaceKHR.hpp
)
endif()
+
+ if(DIRECTFB)
+ list(APPEND WSI_SRC_FILES
+ DirectFBSurfaceEXT.cpp
+ DirectFBSurfaceEXT.hpp
+ )
+ endif()
elseif(APPLE)
list(APPEND WSI_SRC_FILES
MetalSurface.mm
diff --git a/src/WSI/DirectFBSurfaceEXT.cpp b/src/WSI/DirectFBSurfaceEXT.cpp
new file mode 100644
index 0000000..f9f0a22
--- /dev/null
+++ b/src/WSI/DirectFBSurfaceEXT.cpp
@@ -0,0 +1,89 @@
+// 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 "DirectFBSurfaceEXT.hpp"
+
+#include "Vulkan/VkDeviceMemory.hpp"
+#include "Vulkan/VkImage.hpp"
+
+namespace vk {
+
+DirectFBSurfaceEXT::DirectFBSurfaceEXT(const VkDirectFBSurfaceCreateInfoEXT *pCreateInfo, void *mem)
+ : dfb(pCreateInfo->dfb)
+ , surface(pCreateInfo->surface)
+{
+}
+
+void DirectFBSurfaceEXT::destroySurface(const VkAllocationCallbacks *pAllocator)
+{
+}
+
+size_t DirectFBSurfaceEXT::ComputeRequiredAllocationSize(const VkDirectFBSurfaceCreateInfoEXT *pCreateInfo)
+{
+ return 0;
+}
+
+void DirectFBSurfaceEXT::getSurfaceCapabilities(VkSurfaceCapabilitiesKHR *pSurfaceCapabilities) const
+{
+ SurfaceKHR::getSurfaceCapabilities(pSurfaceCapabilities);
+
+ int width, height;
+ surface->GetSize(surface, &width, &height);
+ VkExtent2D extent = { static_cast<uint32_t>(width), static_cast<uint32_t>(height) };
+
+ pSurfaceCapabilities->currentExtent = extent;
+ pSurfaceCapabilities->minImageExtent = extent;
+ pSurfaceCapabilities->maxImageExtent = extent;
+}
+
+void DirectFBSurfaceEXT::attachImage(PresentImage *image)
+{
+ DFBSurfaceDescription desc;
+ desc.flags = static_cast<DFBSurfaceDescriptionFlags>(DSDESC_PIXELFORMAT | DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PREALLOCATED);
+ desc.pixelformat = DSPF_RGB32;
+ const VkExtent3D &extent = image->getImage()->getExtent();
+ desc.width = extent.width;
+ desc.height = extent.height;
+ desc.preallocated[0].data = image->getImageMemory()->getOffsetPointer(0);
+ desc.preallocated[0].pitch = image->getImage()->rowPitchBytes(VK_IMAGE_ASPECT_COLOR_BIT, 0);
+ IDirectFBSurface *dfbImage;
+ dfb->CreateSurface(dfb, &desc, &dfbImage);
+ imageMap[image] = dfbImage;
+}
+
+void DirectFBSurfaceEXT::detachImage(PresentImage *image)
+{
+ auto it = imageMap.find(image);
+ if(it != imageMap.end())
+ {
+ IDirectFBSurface *dfbImage = it->second;
+ dfbImage->Release(dfbImage);
+ imageMap.erase(it);
+ }
+}
+
+VkResult DirectFBSurfaceEXT::present(PresentImage *image)
+{
+ auto it = imageMap.find(image);
+ if(it != imageMap.end())
+ {
+ IDirectFBSurface *dfbImage = it->second;
+ surface->Blit(surface, dfbImage, NULL, 0, 0);
+ surface->Flip(surface, NULL, DSFLIP_WAITFORSYNC);
+ }
+
+ return VK_SUCCESS;
+}
+
+} // namespace vk
diff --git a/src/WSI/DirectFBSurfaceEXT.hpp b/src/WSI/DirectFBSurfaceEXT.hpp
new file mode 100644
index 0000000..07cd600
--- /dev/null
+++ b/src/WSI/DirectFBSurfaceEXT.hpp
@@ -0,0 +1,50 @@
+// 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_DIRECTFBSURFACEEXT_HPP
+#define SWIFTSHADER_DIRECTFBSURFACEEXT_HPP
+
+#include "VkSurfaceKHR.hpp"
+#include "Vulkan/VkObject.hpp"
+
+#include <directfb.h>
+#include <vulkan/vulkan_directfb.h>
+
+#include <unordered_map>
+
+namespace vk {
+
+class DirectFBSurfaceEXT : public SurfaceKHR, public ObjectBase<DirectFBSurfaceEXT, VkSurfaceKHR>
+{
+public:
+ DirectFBSurfaceEXT(const VkDirectFBSurfaceCreateInfoEXT *pCreateInfo, void *mem);
+
+ void destroySurface(const VkAllocationCallbacks *pAllocator) override;
+
+ static size_t ComputeRequiredAllocationSize(const VkDirectFBSurfaceCreateInfoEXT *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:
+ IDirectFB *dfb;
+ IDirectFBSurface *surface;
+ std::unordered_map<PresentImage *, IDirectFBSurface *> imageMap;
+};
+
+} // namespace vk
+#endif //SWIFTSHADER_DIRECTFBSURFACEEXT_HPP