Implement VK_KHR_win32_surface
Bug: b/139184291
Change-Id: Iab77a5ac5894aec60fc70f2630b6d2a2b232d253
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/30435
Reviewed-by: Ben Clayton <bclayton@google.com>
Tested-by: Nicolas Capens <nicolascapens@google.com>
Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
diff --git a/CMakeLists.txt b/CMakeLists.txt
index d2efade..bbe06ab 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -394,15 +394,6 @@
set_cpp_flag("-fPIC")
endif()
- if(WIN32)
- set_cpp_flag("-DVK_USE_PLATFORM_WIN32_KHR")
- elseif(LINUX)
- set_cpp_flag("-DUSE_X11=1")
- set_cpp_flag("-DVK_USE_PLATFORM_XLIB_KHR")
- elseif(APPLE)
- set_cpp_flag("-DVK_USE_PLATFORM_MACOS_MVK")
- endif()
-
# Use -g3 to have even more debug info
set_cpp_flag("-g -g3" DEBUG)
set_cpp_flag("-g -g3" RELWITHDEBINFO)
@@ -1779,7 +1770,11 @@
list(APPEND EGL_LIST ${OPENGL_DIR}/libEGL/libEGL.rc)
list(APPEND GLES2_LIST ${OPENGL_DIR}/libGLESv2/libGLESv2.rc)
list(APPEND GLES_CM_LIST ${OPENGL_DIR}/libGLES_CM/libGLES_CM.rc)
- list(APPEND VULKAN_LIST ${VULKAN_DIR}/Vulkan.rc)
+ list(APPEND VULKAN_LIST
+ ${VULKAN_DIR}/Vulkan.rc
+ ${SOURCE_DIR}/WSI/Win32SurfaceKHR.cpp
+ ${SOURCE_DIR}/WSI/Win32SurfaceKHR.hpp
+ )
elseif(LINUX)
list(APPEND SWIFTSHADER_LIST
${SOURCE_DIR}/Main/FrameBufferX11.cpp
@@ -1927,6 +1922,9 @@
COMPILE_DEFINITIONS "EGL_EGLEXT_PROTOTYPES; EGLAPI=; NO_SANITIZE_FUNCTION=;$<$<CONFIG:Debug>:DEBUGGER_WAIT_DIALOG>"
PREFIX ""
)
+ if(LINUX)
+ set_property(TARGET libEGL APPEND PROPERTY COMPILE_DEFINITIONS "USE_X11=1")
+ endif()
if (ANDROID)
set_target_properties(libEGL PROPERTIES SUFFIX "_swiftshader.so")
endif ()
@@ -2005,6 +2003,18 @@
COMPILE_DEFINITIONS "VK_EXPORT=;NO_SANITIZE_FUNCTION=;$<$<CONFIG:Debug>:DEBUGGER_WAIT_DIALOG>"
PREFIX ""
)
+
+ if(WIN32)
+ set_property(TARGET libvk_swiftshader APPEND
+ PROPERTY COMPILE_DEFINITIONS "VK_USE_PLATFORM_WIN32_KHR")
+ elseif(LINUX)
+ set_property(TARGET libvk_swiftshader APPEND
+ PROPERTY COMPILE_DEFINITIONS "VK_USE_PLATFORM_XLIB_KHR")
+ elseif(APPLE)
+ set_property(TARGET libvk_swiftshader APPEND
+ PROPERTY COMPILE_DEFINITIONS "VK_USE_PLATFORM_MACOS_MVK")
+ endif()
+
set_shared_library_export_map(libvk_swiftshader ${SOURCE_DIR}/Vulkan)
target_link_libraries(libvk_swiftshader ${Reactor} ${OS_LIBS} SPIRV-Tools SPIRV-Tools-opt)
add_custom_command(
diff --git a/src/Pipeline/SpirvShader.hpp b/src/Pipeline/SpirvShader.hpp
index 2c78203..2d06679 100644
--- a/src/Pipeline/SpirvShader.hpp
+++ b/src/Pipeline/SpirvShader.hpp
@@ -41,6 +41,8 @@
#include <unordered_set>
#include <vector>
+#undef Yield // b/127920555
+
namespace vk
{
class PipelineLayout;
diff --git a/src/Vulkan/VkGetProcAddress.cpp b/src/Vulkan/VkGetProcAddress.cpp
index c132e7f..c8e5ace 100644
--- a/src/Vulkan/VkGetProcAddress.cpp
+++ b/src/Vulkan/VkGetProcAddress.cpp
@@ -97,6 +97,10 @@
// VK_MVK_macos_surface
MAKE_VULKAN_INSTANCE_ENTRY(vkCreateMacOSSurfaceMVK),
#endif
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+ // VK_KHR_win32_surface
+ MAKE_VULKAN_INSTANCE_ENTRY(vkCreateWin32SurfaceKHR),
+#endif
};
#undef MAKE_VULKAN_INSTANCE_ENTRY
diff --git a/src/Vulkan/libVulkan.cpp b/src/Vulkan/libVulkan.cpp
index dbd2644..2a843b2 100644
--- a/src/Vulkan/libVulkan.cpp
+++ b/src/Vulkan/libVulkan.cpp
@@ -50,6 +50,10 @@
#include "WSI/XlibSurfaceKHR.hpp"
#endif
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+#include "WSI/Win32SurfaceKHR.hpp"
+#endif
+
#ifdef __ANDROID__
#include <vulkan/vk_android_native_buffer.h>
#include "System/GrallocAndroid.hpp"
@@ -142,6 +146,9 @@
#ifdef VK_USE_PLATFORM_MACOS_MVK
{ VK_MVK_MACOS_SURFACE_EXTENSION_NAME, VK_MVK_MACOS_SURFACE_SPEC_VERSION },
#endif
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+ { VK_KHR_WIN32_SURFACE_EXTENSION_NAME, VK_KHR_WIN32_SURFACE_SPEC_VERSION },
+#endif
};
static const VkExtensionProperties deviceExtensionProperties[] =
@@ -2628,6 +2635,16 @@
}
#endif
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateWin32SurfaceKHR(VkInstance instance, const VkWin32SurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface)
+{
+ TRACE("(VkInstance instance = %p, VkWin32SurfaceCreateInfoKHR* pCreateInfo = %p, VkAllocationCallbacks* pAllocator = %p, VkSurface* pSurface = %p)",
+ instance, pCreateInfo, pAllocator, pSurface);
+
+ return vk::Win32SurfaceKHR::Create(pAllocator, pCreateInfo, pSurface);
+}
+#endif
+
#ifndef __ANDROID__
VKAPI_ATTR void VKAPI_CALL vkDestroySurfaceKHR(VkInstance instance, VkSurfaceKHR surface, const VkAllocationCallbacks* pAllocator)
{
diff --git a/src/Vulkan/libvk_swiftshader.def b/src/Vulkan/libvk_swiftshader.def
index cfa6d81..f0de6a5 100644
--- a/src/Vulkan/libvk_swiftshader.def
+++ b/src/Vulkan/libvk_swiftshader.def
@@ -213,4 +213,6 @@
vkGetPhysicalDeviceSurfaceSupportKHR
vkGetPhysicalDeviceSurfaceCapabilitiesKHR
vkGetPhysicalDeviceSurfaceFormatsKHR
- vkGetPhysicalDeviceSurfacePresentModesKHR
\ No newline at end of file
+ vkGetPhysicalDeviceSurfacePresentModesKHR
+ ; VK_KHR_win32_surface
+ vkCreateWin32SurfaceKHR
\ No newline at end of file
diff --git a/src/Vulkan/vulkan.vcxproj b/src/Vulkan/vulkan.vcxproj
index 162f3f2..5a1fac8 100644
--- a/src/Vulkan/vulkan.vcxproj
+++ b/src/Vulkan/vulkan.vcxproj
@@ -62,7 +62,7 @@
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>$(SolutionDir)include;$(SolutionDir)third_party\SPIRV-Headers\include;$(SolutionDir)third_party\SPIRV-Tools\include;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>VK_EXPORT=;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;NOMINMAX;_SECURE_SCL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>VK_USE_PLATFORM_WIN32_KHR;VK_EXPORT=;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;NOMINMAX;_SECURE_SCL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<AdditionalOptions>/permissive- %(AdditionalOptions)</AdditionalOptions>
<TreatSpecificWarningsAsErrors>4018;5038;4838</TreatSpecificWarningsAsErrors>
@@ -89,7 +89,7 @@
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>$(SolutionDir)include;$(SolutionDir)third_party\SPIRV-Headers\include;$(SolutionDir)third_party\SPIRV-Tools\include;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>VK_EXPORT=;_DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;NOMINMAX;DEBUGGER_WAIT_DIALOG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>VK_USE_PLATFORM_WIN32_KHR;VK_EXPORT=;_DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;NOMINMAX;DEBUGGER_WAIT_DIALOG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<AdditionalOptions>/permissive- %(AdditionalOptions)</AdditionalOptions>
<TreatSpecificWarningsAsErrors>4018;5038;4838</TreatSpecificWarningsAsErrors>
@@ -109,6 +109,7 @@
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
+ <ClCompile Include="..\WSI\Win32SurfaceKHR.cpp" />
<ClCompile Include="libVulkan.cpp" />
<ClCompile Include="main.cpp" />
<ClCompile Include="VkBuffer.cpp" />
@@ -189,6 +190,7 @@
</ClCompile>
</ItemGroup>
<ItemGroup>
+ <ClInclude Include="..\WSI\Win32SurfaceKHR.hpp" />
<ClInclude Include="resource.h" />
<ClInclude Include="Version.h" />
<ClInclude Include="VkBuffer.hpp" />
diff --git a/src/Vulkan/vulkan.vcxproj.filters b/src/Vulkan/vulkan.vcxproj.filters
index 4f325dc..68eea69 100644
--- a/src/Vulkan/vulkan.vcxproj.filters
+++ b/src/Vulkan/vulkan.vcxproj.filters
@@ -252,6 +252,9 @@
<ClCompile Include="..\WSI\VkSwapchainKHR.cpp">
<Filter>Source Files\WSI</Filter>
</ClCompile>
+ <ClCompile Include="..\WSI\Win32SurfaceKHR.cpp">
+ <Filter>Source Files\WSI</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="resource.h">
@@ -510,6 +513,9 @@
<ClInclude Include="..\WSI\VkSwapchainKHR.hpp">
<Filter>Header Files\WSI</Filter>
</ClInclude>
+ <ClInclude Include="..\WSI\Win32SurfaceKHR.hpp">
+ <Filter>Header Files\WSI</Filter>
+ </ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="libvk_swiftshader.def" />
diff --git a/src/WSI/VkSurfaceKHR.hpp b/src/WSI/VkSurfaceKHR.hpp
index e25e95d..2badec7 100644
--- a/src/WSI/VkSurfaceKHR.hpp
+++ b/src/WSI/VkSurfaceKHR.hpp
@@ -16,7 +16,9 @@
#define SWIFTSHADER_VKSURFACEKHR_HPP_
#include "Vulkan/VkObject.hpp"
+#include "Vulkan/VkImage.hpp"
#include <Vulkan/VulkanPlatform.h>
+
#include <vector>
namespace vk
@@ -24,7 +26,7 @@
enum PresentImageStatus
{
- NONEXISTENT, // Image wasn't made
+ NONEXISTENT, // Image wasn't created
AVAILABLE,
DRAWING,
PRESENTING,
diff --git a/src/WSI/Win32SurfaceKHR.cpp b/src/WSI/Win32SurfaceKHR.cpp
new file mode 100644
index 0000000..81073e9
--- /dev/null
+++ b/src/WSI/Win32SurfaceKHR.cpp
@@ -0,0 +1,110 @@
+// Copyright 2019 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 "Win32SurfaceKHR.hpp"
+
+#include "Vulkan/VkDeviceMemory.hpp"
+#include "Vulkan/VkDebug.hpp"
+
+#define WIN32_LEAN_AND_MEAN
+#include <Windows.h>
+#include <string.h>
+
+namespace vk {
+
+Win32SurfaceKHR::Win32SurfaceKHR(const VkWin32SurfaceCreateInfoKHR *pCreateInfo, void *mem) :
+ hinstance(pCreateInfo->hinstance),
+ hwnd(pCreateInfo->hwnd)
+{
+ ASSERT(IsWindow(hwnd) == TRUE);
+
+ RECT clientRect = {};
+ BOOL status = GetClientRect(hwnd, &clientRect);
+ ASSERT(status != 0);
+
+ windowContext = GetDC(hwnd);
+ bitmapContext = CreateCompatibleDC(windowContext);
+
+ BITMAPINFO bitmapInfo = {};
+ bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFO);
+ bitmapInfo.bmiHeader.biBitCount = 32;
+ bitmapInfo.bmiHeader.biPlanes = 1;
+ bitmapInfo.bmiHeader.biHeight = clientRect.top - clientRect.bottom;
+ bitmapInfo.bmiHeader.biWidth = clientRect.right - clientRect.left;
+ bitmapInfo.bmiHeader.biCompression = BI_RGB;
+
+ bitmap = CreateDIBSection(bitmapContext, &bitmapInfo, DIB_RGB_COLORS, &framebuffer, 0, 0);
+ ASSERT(bitmap != NULL);
+ SelectObject(bitmapContext, bitmap);
+}
+
+void Win32SurfaceKHR::destroySurface(const VkAllocationCallbacks *pAllocator)
+{
+ SelectObject(bitmapContext, NULL);
+ DeleteObject(bitmap);
+ ReleaseDC(hwnd, windowContext);
+ DeleteDC(bitmapContext);
+}
+
+size_t Win32SurfaceKHR::ComputeRequiredAllocationSize(const VkWin32SurfaceCreateInfoKHR *pCreateInfo)
+{
+ return 0;
+}
+
+void Win32SurfaceKHR::getSurfaceCapabilities(VkSurfaceCapabilitiesKHR *pSurfaceCapabilities) const
+{
+ SurfaceKHR::getSurfaceCapabilities(pSurfaceCapabilities);
+
+ RECT clientRect = {};
+ BOOL status = GetClientRect(hwnd, &clientRect);
+ ASSERT(status != 0);
+
+ int windowWidth = clientRect.right - clientRect.left;
+ int windowHeight = clientRect.bottom - clientRect.top;
+
+ VkExtent2D extent = {static_cast<uint32_t>(windowWidth), static_cast<uint32_t>(windowHeight)};
+ pSurfaceCapabilities->currentExtent = extent;
+ pSurfaceCapabilities->minImageExtent = extent;
+ pSurfaceCapabilities->maxImageExtent = extent;
+}
+
+void Win32SurfaceKHR::attachImage(PresentImage* image)
+{
+ // Nothing to do here, the current implementation based on GDI blits on
+ // present instead of associating the image with the surface.
+}
+
+void Win32SurfaceKHR::detachImage(PresentImage* image)
+{
+ // Nothing to do here, the current implementation based on GDI blits on
+ // present instead of associating the image with the surface.
+}
+
+void Win32SurfaceKHR::present(PresentImage* image)
+{
+ if(!framebuffer)
+ {
+ return;
+ }
+
+ VkExtent3D extent = image->getImage()->getMipLevelExtent(VK_IMAGE_ASPECT_COLOR_BIT, 0);
+
+ // FIXME(b/139184291): Assumes B8G8R8A8 surface without stride padding.
+ size_t bytes = extent.width * extent.height * 4;
+ memcpy(framebuffer, image->getImageMemory()->getOffsetPointer(0), bytes);
+
+ StretchBlt(windowContext, 0, 0, extent.width, extent.height, bitmapContext, 0, 0, extent.width, extent.height, SRCCOPY);
+}
+
+}
\ No newline at end of file
diff --git a/src/WSI/Win32SurfaceKHR.hpp b/src/WSI/Win32SurfaceKHR.hpp
new file mode 100644
index 0000000..8a28a71
--- /dev/null
+++ b/src/WSI/Win32SurfaceKHR.hpp
@@ -0,0 +1,56 @@
+// Copyright 2019 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_WIN32SURFACEKHR_HPP
+#define SWIFTSHADER_WIN32SURFACEKHR_HPP
+
+#include "Vulkan/VkObject.hpp"
+#include "Vulkan/VkImage.hpp"
+#include "VkSurfaceKHR.hpp"
+
+#define WIN32_LEAN_AND_MEAN
+#include <Windows.h>
+#include "vulkan/vulkan_win32.h"
+
+#include <map>
+
+namespace vk {
+
+class Win32SurfaceKHR : public SurfaceKHR, public ObjectBase<Win32SurfaceKHR, VkSurfaceKHR> {
+public:
+ Win32SurfaceKHR(const VkWin32SurfaceCreateInfoKHR *pCreateInfo, void *mem);
+
+ void destroySurface(const VkAllocationCallbacks *pAllocator) override;
+
+ static size_t ComputeRequiredAllocationSize(const VkWin32SurfaceCreateInfoKHR *pCreateInfo);
+
+ void getSurfaceCapabilities(VkSurfaceCapabilitiesKHR *pSurfaceCapabilities) const override;
+
+ virtual void attachImage(PresentImage* image) override;
+ virtual void detachImage(PresentImage* image) override;
+ void present(PresentImage* image) override;
+
+private:
+ const HINSTANCE hinstance;
+ const HWND hwnd;
+
+ HDC windowContext = {};
+ HDC bitmapContext = {};
+
+ HBITMAP bitmap = {};
+ void *framebuffer = nullptr;
+};
+
+}
+#endif //SWIFTSHADER_WIN32SURFACEKHR_HPP
diff --git a/src/WSI/XlibSurfaceKHR.cpp b/src/WSI/XlibSurfaceKHR.cpp
index 0891c22..a193c23 100644
--- a/src/WSI/XlibSurfaceKHR.cpp
+++ b/src/WSI/XlibSurfaceKHR.cpp
@@ -1,3 +1,6 @@
+// Copyright 2019 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
//
diff --git a/src/WSI/XlibSurfaceKHR.hpp b/src/WSI/XlibSurfaceKHR.hpp
index c923a32..0dcb5e4 100644
--- a/src/WSI/XlibSurfaceKHR.hpp
+++ b/src/WSI/XlibSurfaceKHR.hpp
@@ -39,8 +39,8 @@
void present(PresentImage* image) override;
private:
- Display *pDisplay;
- Window window;
+ Display *const pDisplay;
+ const Window window;
GC gc;
Visual *visual = nullptr;
std::map<PresentImage*, XImage*> imageMap;