Add support for creating Vulkan window surfaces.
This commit is contained in:
parent
8886134156
commit
6272f853c1
36 changed files with 16176 additions and 0 deletions
|
@ -43,6 +43,8 @@ set(SRC
|
|||
${SRCROOT}/VideoMode.cpp
|
||||
${INCROOT}/VideoMode.hpp
|
||||
${SRCROOT}/VideoModeImpl.hpp
|
||||
${SRCROOT}/Vulkan.cpp
|
||||
${INCROOT}/Vulkan.hpp
|
||||
${SRCROOT}/Window.cpp
|
||||
${INCROOT}/Window.hpp
|
||||
${SRCROOT}/WindowBase.cpp
|
||||
|
@ -70,6 +72,8 @@ if(SFML_OS_WINDOWS)
|
|||
${SRCROOT}/Win32/SensorImpl.hpp
|
||||
${SRCROOT}/Win32/SensorImpl.cpp
|
||||
${SRCROOT}/Win32/VideoModeImpl.cpp
|
||||
${SRCROOT}/Win32/VulkanImplWin32.cpp
|
||||
${SRCROOT}/Win32/VulkanImplWin32.hpp
|
||||
${SRCROOT}/Win32/WindowImplWin32.cpp
|
||||
${SRCROOT}/Win32/WindowImplWin32.hpp
|
||||
)
|
||||
|
@ -90,6 +94,8 @@ elseif(SFML_OS_LINUX OR SFML_OS_FREEBSD OR SFML_OS_OPENBSD)
|
|||
${SRCROOT}/Unix/SensorImpl.cpp
|
||||
${SRCROOT}/Unix/SensorImpl.hpp
|
||||
${SRCROOT}/Unix/VideoModeImpl.cpp
|
||||
${SRCROOT}/Unix/VulkanImplX11.cpp
|
||||
${SRCROOT}/Unix/VulkanImplX11.hpp
|
||||
${SRCROOT}/Unix/WindowImplX11.cpp
|
||||
${SRCROOT}/Unix/WindowImplX11.hpp
|
||||
)
|
||||
|
@ -233,6 +239,9 @@ if ((NOT BUILD_SHARED_LIBS) AND SFML_OS_MACOSX)
|
|||
target_link_libraries(sfml-window PRIVATE -ObjC)
|
||||
endif()
|
||||
|
||||
# Vulkan headers
|
||||
target_include_directories(sfml-window PRIVATE "${PROJECT_SOURCE_DIR}/extlibs/headers/vulkan")
|
||||
|
||||
# find and setup usage for external libraries
|
||||
if(SFML_OS_LINUX OR SFML_OS_FREEBSD OR SFML_OPENBSD)
|
||||
sfml_find_package(X11 INCLUDE "X11_INCLUDE_DIR" LINK "X11_X11_LIB" "X11_Xrandr_LIB")
|
||||
|
|
225
src/SFML/Window/Unix/VulkanImplX11.cpp
Normal file
225
src/SFML/Window/Unix/VulkanImplX11.cpp
Normal file
|
@ -0,0 +1,225 @@
|
|||
////////////////////////////////////////////////////////////
|
||||
//
|
||||
// SFML - Simple and Fast Multimedia Library
|
||||
// Copyright (C) 2007-2019 Laurent Gomila (laurent@sfml-dev.org)
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied warranty.
|
||||
// In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it freely,
|
||||
// subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented;
|
||||
// you must not claim that you wrote the original software.
|
||||
// If you use this software in a product, an acknowledgment
|
||||
// in the product documentation would be appreciated but is not required.
|
||||
//
|
||||
// 2. Altered source versions must be plainly marked as such,
|
||||
// and must not be misrepresented as being the original software.
|
||||
//
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
//
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/Window/Unix/VulkanImplX11.hpp>
|
||||
#include <SFML/Window/Unix/Display.hpp>
|
||||
#include <dlfcn.h>
|
||||
#define VK_USE_PLATFORM_XLIB_KHR
|
||||
#define VK_NO_PROTOTYPES
|
||||
#include <vulkan.h>
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <cstring>
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
struct VulkanLibraryWrapper
|
||||
{
|
||||
VulkanLibraryWrapper() :
|
||||
library(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
~VulkanLibraryWrapper()
|
||||
{
|
||||
if (library)
|
||||
dlclose(library);
|
||||
}
|
||||
|
||||
// Try to load the library and all the required entry points
|
||||
bool loadLibrary()
|
||||
{
|
||||
if (library)
|
||||
return true;
|
||||
|
||||
library = dlopen("libvulkan.so.1", RTLD_LAZY);
|
||||
|
||||
if (!library)
|
||||
return false;
|
||||
|
||||
if (!loadEntryPoint(vkGetInstanceProcAddr, "vkGetInstanceProcAddr"))
|
||||
{
|
||||
dlclose(library);
|
||||
library = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!loadEntryPoint(vkEnumerateInstanceLayerProperties, "vkEnumerateInstanceLayerProperties"))
|
||||
{
|
||||
dlclose(library);
|
||||
library = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!loadEntryPoint(vkEnumerateInstanceExtensionProperties, "vkEnumerateInstanceExtensionProperties"))
|
||||
{
|
||||
dlclose(library);
|
||||
library = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool loadEntryPoint(T& entryPoint, const char* name)
|
||||
{
|
||||
entryPoint = reinterpret_cast<T>(dlsym(library, name));
|
||||
|
||||
return (entryPoint != NULL);
|
||||
}
|
||||
|
||||
void* library;
|
||||
|
||||
PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr;
|
||||
PFN_vkEnumerateInstanceLayerProperties vkEnumerateInstanceLayerProperties;
|
||||
PFN_vkEnumerateInstanceExtensionProperties vkEnumerateInstanceExtensionProperties;
|
||||
};
|
||||
|
||||
VulkanLibraryWrapper wrapper;
|
||||
}
|
||||
|
||||
|
||||
namespace sf
|
||||
{
|
||||
namespace priv
|
||||
{
|
||||
////////////////////////////////////////////////////////////
|
||||
bool VulkanImplX11::isAvailable(bool requireGraphics)
|
||||
{
|
||||
static bool checked = false;
|
||||
static bool computeAvailable = false;
|
||||
static bool graphicsAvailable = false;
|
||||
|
||||
if (!checked)
|
||||
{
|
||||
checked = true;
|
||||
|
||||
// Check if the library is available
|
||||
computeAvailable = wrapper.loadLibrary();
|
||||
|
||||
// To check for instance extensions we don't need to differentiate between graphics and compute
|
||||
graphicsAvailable = computeAvailable;
|
||||
|
||||
if (graphicsAvailable)
|
||||
{
|
||||
// Retrieve the available instance extensions
|
||||
std::vector<VkExtensionProperties> extensionProperties;
|
||||
|
||||
uint32_t extensionCount = 0;
|
||||
|
||||
wrapper.vkEnumerateInstanceExtensionProperties(0, &extensionCount, NULL);
|
||||
|
||||
extensionProperties.resize(extensionCount);
|
||||
|
||||
wrapper.vkEnumerateInstanceExtensionProperties(0, &extensionCount, &extensionProperties[0]);
|
||||
|
||||
// Check if the necessary extensions are available
|
||||
bool has_VK_KHR_surface = false;
|
||||
bool has_VK_KHR_platform_surface = false;
|
||||
|
||||
for (std::vector<VkExtensionProperties>::const_iterator iter = extensionProperties.begin(); iter != extensionProperties.end(); ++iter)
|
||||
{
|
||||
if (!std::strcmp(iter->extensionName, VK_KHR_SURFACE_EXTENSION_NAME))
|
||||
{
|
||||
has_VK_KHR_surface = true;
|
||||
}
|
||||
else if (!std::strcmp(iter->extensionName, VK_KHR_XLIB_SURFACE_EXTENSION_NAME))
|
||||
{
|
||||
has_VK_KHR_platform_surface = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!has_VK_KHR_surface || !has_VK_KHR_platform_surface)
|
||||
graphicsAvailable = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (requireGraphics)
|
||||
return graphicsAvailable;
|
||||
|
||||
return computeAvailable;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
VulkanFunctionPointer VulkanImplX11::getFunction(const char* name)
|
||||
{
|
||||
if (!isAvailable(false))
|
||||
return 0;
|
||||
|
||||
return reinterpret_cast<VulkanFunctionPointer>(dlsym(wrapper.library, name));
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
const std::vector<const char*>& VulkanImplX11::getGraphicsRequiredInstanceExtensions()
|
||||
{
|
||||
static std::vector<const char*> extensions;
|
||||
|
||||
if (extensions.empty())
|
||||
{
|
||||
extensions.push_back(VK_KHR_SURFACE_EXTENSION_NAME);
|
||||
extensions.push_back(VK_KHR_XLIB_SURFACE_EXTENSION_NAME);
|
||||
}
|
||||
|
||||
return extensions;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
bool VulkanImplX11::createVulkanSurface(const VkInstance& instance, WindowHandle windowHandle, VkSurfaceKHR& surface, const VkAllocationCallbacks* allocator)
|
||||
{
|
||||
if (!isAvailable())
|
||||
return false;
|
||||
|
||||
// Make a copy of the instance handle since we get it passed as a reference
|
||||
VkInstance inst = instance;
|
||||
|
||||
PFN_vkCreateXlibSurfaceKHR vkCreateXlibSurfaceKHR = reinterpret_cast<PFN_vkCreateXlibSurfaceKHR>(wrapper.vkGetInstanceProcAddr(inst, "vkCreateXlibSurfaceKHR"));
|
||||
|
||||
if (!vkCreateXlibSurfaceKHR)
|
||||
return false;
|
||||
|
||||
// Since the surface is basically attached to the window, the connection
|
||||
// to the X display will stay open even after we open and close it here
|
||||
VkXlibSurfaceCreateInfoKHR surfaceCreateInfo = VkXlibSurfaceCreateInfoKHR();
|
||||
surfaceCreateInfo.sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR;
|
||||
surfaceCreateInfo.dpy = OpenDisplay();
|
||||
surfaceCreateInfo.window = windowHandle;
|
||||
|
||||
bool result = (vkCreateXlibSurfaceKHR(instance, &surfaceCreateInfo, allocator, &surface) == VK_SUCCESS);
|
||||
|
||||
CloseDisplay(surfaceCreateInfo.dpy);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace priv
|
||||
|
||||
} // namespace sf
|
103
src/SFML/Window/Unix/VulkanImplX11.hpp
Normal file
103
src/SFML/Window/Unix/VulkanImplX11.hpp
Normal file
|
@ -0,0 +1,103 @@
|
|||
////////////////////////////////////////////////////////////
|
||||
//
|
||||
// SFML - Simple and Fast Multimedia Library
|
||||
// Copyright (C) 2007-2019 Laurent Gomila (laurent@sfml-dev.org)
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied warranty.
|
||||
// In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it freely,
|
||||
// subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented;
|
||||
// you must not claim that you wrote the original software.
|
||||
// If you use this software in a product, an acknowledgment
|
||||
// in the product documentation would be appreciated but is not required.
|
||||
//
|
||||
// 2. Altered source versions must be plainly marked as such,
|
||||
// and must not be misrepresented as being the original software.
|
||||
//
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
//
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef SFML_VULKANIMPLX11_HPP
|
||||
#define SFML_VULKANIMPLX11_HPP
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/Window/Vulkan.hpp>
|
||||
#include <SFML/Window/WindowHandle.hpp>
|
||||
#include <vector>
|
||||
|
||||
|
||||
namespace sf
|
||||
{
|
||||
namespace priv
|
||||
{
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Linux (X11) implementation of Vulkan
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
class VulkanImplX11
|
||||
{
|
||||
public:
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Tell whether or not the system supports Vulkan
|
||||
///
|
||||
/// This function should always be called before using
|
||||
/// the Vulkan features. If it returns false, then
|
||||
/// any attempt to use Vulkan will fail.
|
||||
///
|
||||
/// If only compute is required, set \a requireGraphics
|
||||
/// to false to skip checking for the extensions necessary
|
||||
/// for graphics rendering.
|
||||
///
|
||||
/// \param requireGraphics
|
||||
///
|
||||
/// \return True if Vulkan is supported, false otherwise
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
static bool isAvailable(bool requireGraphics = true);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Get the address of a Vulkan function
|
||||
///
|
||||
/// \param name Name of the function to get the address of
|
||||
///
|
||||
/// \return Address of the Vulkan function, 0 on failure
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
static VulkanFunctionPointer getFunction(const char* name);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Get Vulkan instance extensions required for graphics
|
||||
///
|
||||
/// \return Vulkan instance extensions required for graphics
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
static const std::vector<const char*>& getGraphicsRequiredInstanceExtensions();
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Create a Vulkan rendering surface
|
||||
///
|
||||
/// \param instance Vulkan instance
|
||||
/// \param windowHandle Handle to the window to create the surface for
|
||||
/// \param surface Created surface
|
||||
/// \param allocator Allocator to use
|
||||
///
|
||||
/// \return True if surface creation was successful, false otherwise
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
static bool createVulkanSurface(const VkInstance& instance, WindowHandle windowHandle, VkSurfaceKHR& surface, const VkAllocationCallbacks* allocator);
|
||||
};
|
||||
|
||||
} // namespace priv
|
||||
|
||||
} // namespace sf
|
||||
|
||||
|
||||
#endif // SFML_VULKANIMPLX11_HPP
|
95
src/SFML/Window/Vulkan.cpp
Normal file
95
src/SFML/Window/Vulkan.cpp
Normal file
|
@ -0,0 +1,95 @@
|
|||
////////////////////////////////////////////////////////////
|
||||
//
|
||||
// SFML - Simple and Fast Multimedia Library
|
||||
// Copyright (C) 2007-2019 Laurent Gomila (laurent@sfml-dev.org)
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied warranty.
|
||||
// In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it freely,
|
||||
// subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented;
|
||||
// you must not claim that you wrote the original software.
|
||||
// If you use this software in a product, an acknowledgment
|
||||
// in the product documentation would be appreciated but is not required.
|
||||
//
|
||||
// 2. Altered source versions must be plainly marked as such,
|
||||
// and must not be misrepresented as being the original software.
|
||||
//
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
//
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/Window/Vulkan.hpp>
|
||||
|
||||
#if defined(SFML_SYSTEM_WINDOWS)
|
||||
|
||||
#include <SFML/Window/Win32/VulkanImplWin32.hpp>
|
||||
typedef sf::priv::VulkanImplWin32 VulkanImplType;
|
||||
|
||||
#elif defined(SFML_SYSTEM_LINUX) || defined(SFML_SYSTEM_FREEBSD) || defined(SFML_SYSTEM_OPENBSD)
|
||||
|
||||
#include <SFML/Window/Unix/VulkanImplX11.hpp>
|
||||
typedef sf::priv::VulkanImplX11 VulkanImplType;
|
||||
|
||||
#else
|
||||
|
||||
#define SFML_VULKAN_IMPLEMENTATION_NOT_AVAILABLE
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
namespace sf
|
||||
{
|
||||
////////////////////////////////////////////////////////////
|
||||
bool Vulkan::isAvailable(bool requireGraphics)
|
||||
{
|
||||
#if defined(SFML_VULKAN_IMPLEMENTATION_NOT_AVAILABLE)
|
||||
|
||||
return false;
|
||||
|
||||
#else
|
||||
|
||||
return VulkanImplType::isAvailable(requireGraphics);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
VulkanFunctionPointer Vulkan::getFunction(const char* name)
|
||||
{
|
||||
#if defined(SFML_VULKAN_IMPLEMENTATION_NOT_AVAILABLE)
|
||||
|
||||
return NULL;
|
||||
|
||||
#else
|
||||
|
||||
return VulkanImplType::getFunction(name);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
const std::vector<const char*>& Vulkan::getGraphicsRequiredInstanceExtensions()
|
||||
{
|
||||
#if defined(SFML_VULKAN_IMPLEMENTATION_NOT_AVAILABLE)
|
||||
|
||||
static const std::vector<const char*> empty;
|
||||
|
||||
return empty;
|
||||
|
||||
#else
|
||||
|
||||
return VulkanImplType::getGraphicsRequiredInstanceExtensions();
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace sf
|
219
src/SFML/Window/Win32/VulkanImplWin32.cpp
Normal file
219
src/SFML/Window/Win32/VulkanImplWin32.cpp
Normal file
|
@ -0,0 +1,219 @@
|
|||
////////////////////////////////////////////////////////////
|
||||
//
|
||||
// SFML - Simple and Fast Multimedia Library
|
||||
// Copyright (C) 2007-2019 Laurent Gomila (laurent@sfml-dev.org)
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied warranty.
|
||||
// In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it freely,
|
||||
// subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented;
|
||||
// you must not claim that you wrote the original software.
|
||||
// If you use this software in a product, an acknowledgment
|
||||
// in the product documentation would be appreciated but is not required.
|
||||
//
|
||||
// 2. Altered source versions must be plainly marked as such,
|
||||
// and must not be misrepresented as being the original software.
|
||||
//
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
//
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/Window/Win32/VulkanImplWin32.hpp>
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#define VK_USE_PLATFORM_WIN32_KHR
|
||||
#define VK_NO_PROTOTYPES
|
||||
#include <vulkan.h>
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <cstring>
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
struct VulkanLibraryWrapper
|
||||
{
|
||||
VulkanLibraryWrapper() :
|
||||
library(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
~VulkanLibraryWrapper()
|
||||
{
|
||||
if (library)
|
||||
FreeLibrary(library);
|
||||
}
|
||||
|
||||
// Try to load the library and all the required entry points
|
||||
bool loadLibrary()
|
||||
{
|
||||
if (library)
|
||||
return true;
|
||||
|
||||
library = LoadLibraryA("vulkan-1.dll");
|
||||
|
||||
if (!library)
|
||||
return false;
|
||||
|
||||
if (!loadEntryPoint(vkGetInstanceProcAddr, "vkGetInstanceProcAddr"))
|
||||
{
|
||||
FreeLibrary(library);
|
||||
library = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!loadEntryPoint(vkEnumerateInstanceLayerProperties, "vkEnumerateInstanceLayerProperties"))
|
||||
{
|
||||
FreeLibrary(library);
|
||||
library = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!loadEntryPoint(vkEnumerateInstanceExtensionProperties, "vkEnumerateInstanceExtensionProperties"))
|
||||
{
|
||||
FreeLibrary(library);
|
||||
library = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool loadEntryPoint(T& entryPoint, const char* name)
|
||||
{
|
||||
entryPoint = reinterpret_cast<T>(GetProcAddress(library, name));
|
||||
|
||||
return (entryPoint != NULL);
|
||||
}
|
||||
|
||||
HMODULE library;
|
||||
|
||||
PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr;
|
||||
PFN_vkEnumerateInstanceLayerProperties vkEnumerateInstanceLayerProperties;
|
||||
PFN_vkEnumerateInstanceExtensionProperties vkEnumerateInstanceExtensionProperties;
|
||||
};
|
||||
|
||||
VulkanLibraryWrapper wrapper;
|
||||
}
|
||||
|
||||
|
||||
namespace sf
|
||||
{
|
||||
namespace priv
|
||||
{
|
||||
////////////////////////////////////////////////////////////
|
||||
bool VulkanImplWin32::isAvailable(bool requireGraphics)
|
||||
{
|
||||
static bool checked = false;
|
||||
static bool computeAvailable = false;
|
||||
static bool graphicsAvailable = false;
|
||||
|
||||
if (!checked)
|
||||
{
|
||||
checked = true;
|
||||
|
||||
// Check if the library is available
|
||||
computeAvailable = wrapper.loadLibrary();
|
||||
|
||||
// To check for instance extensions we don't need to differentiate between graphics and compute
|
||||
graphicsAvailable = computeAvailable;
|
||||
|
||||
if (graphicsAvailable)
|
||||
{
|
||||
// Retrieve the available instance extensions
|
||||
std::vector<VkExtensionProperties> extensionProperties;
|
||||
|
||||
uint32_t extensionCount = 0;
|
||||
|
||||
wrapper.vkEnumerateInstanceExtensionProperties(0, &extensionCount, NULL);
|
||||
|
||||
extensionProperties.resize(extensionCount);
|
||||
|
||||
wrapper.vkEnumerateInstanceExtensionProperties(0, &extensionCount, &extensionProperties[0]);
|
||||
|
||||
// Check if the necessary extensions are available
|
||||
bool has_VK_KHR_surface = false;
|
||||
bool has_VK_KHR_platform_surface = false;
|
||||
|
||||
for (std::vector<VkExtensionProperties>::const_iterator iter = extensionProperties.begin(); iter != extensionProperties.end(); ++iter)
|
||||
{
|
||||
if (!std::strcmp(iter->extensionName, VK_KHR_SURFACE_EXTENSION_NAME))
|
||||
{
|
||||
has_VK_KHR_surface = true;
|
||||
}
|
||||
else if (!std::strcmp(iter->extensionName, VK_KHR_WIN32_SURFACE_EXTENSION_NAME))
|
||||
{
|
||||
has_VK_KHR_platform_surface = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!has_VK_KHR_surface || !has_VK_KHR_platform_surface)
|
||||
graphicsAvailable = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (requireGraphics)
|
||||
return graphicsAvailable;
|
||||
|
||||
return computeAvailable;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
VulkanFunctionPointer VulkanImplWin32::getFunction(const char* name)
|
||||
{
|
||||
if (!isAvailable(false))
|
||||
return 0;
|
||||
|
||||
return reinterpret_cast<VulkanFunctionPointer>(GetProcAddress(wrapper.library, name));
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
const std::vector<const char*>& VulkanImplWin32::getGraphicsRequiredInstanceExtensions()
|
||||
{
|
||||
static std::vector<const char*> extensions;
|
||||
|
||||
if (extensions.empty())
|
||||
{
|
||||
extensions.push_back(VK_KHR_SURFACE_EXTENSION_NAME);
|
||||
extensions.push_back(VK_KHR_WIN32_SURFACE_EXTENSION_NAME);
|
||||
}
|
||||
|
||||
return extensions;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
bool VulkanImplWin32::createVulkanSurface(const VkInstance& instance, WindowHandle windowHandle, VkSurfaceKHR& surface, const VkAllocationCallbacks* allocator)
|
||||
{
|
||||
if (!isAvailable())
|
||||
return false;
|
||||
|
||||
// Make a copy of the instance handle since we get it passed as a reference
|
||||
VkInstance inst = instance;
|
||||
|
||||
PFN_vkCreateWin32SurfaceKHR vkCreateWin32SurfaceKHR = reinterpret_cast<PFN_vkCreateWin32SurfaceKHR>(wrapper.vkGetInstanceProcAddr(inst, "vkCreateWin32SurfaceKHR"));
|
||||
|
||||
if (!vkCreateWin32SurfaceKHR)
|
||||
return false;
|
||||
|
||||
VkWin32SurfaceCreateInfoKHR surfaceCreateInfo = VkWin32SurfaceCreateInfoKHR();
|
||||
surfaceCreateInfo.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR;
|
||||
surfaceCreateInfo.hinstance = GetModuleHandleA(NULL);
|
||||
surfaceCreateInfo.hwnd = windowHandle;
|
||||
|
||||
return (vkCreateWin32SurfaceKHR(instance, &surfaceCreateInfo, allocator, &surface) == VK_SUCCESS);
|
||||
}
|
||||
|
||||
} // namespace priv
|
||||
|
||||
} // namespace sf
|
103
src/SFML/Window/Win32/VulkanImplWin32.hpp
Normal file
103
src/SFML/Window/Win32/VulkanImplWin32.hpp
Normal file
|
@ -0,0 +1,103 @@
|
|||
////////////////////////////////////////////////////////////
|
||||
//
|
||||
// SFML - Simple and Fast Multimedia Library
|
||||
// Copyright (C) 2007-2019 Laurent Gomila (laurent@sfml-dev.org)
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied warranty.
|
||||
// In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it freely,
|
||||
// subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented;
|
||||
// you must not claim that you wrote the original software.
|
||||
// If you use this software in a product, an acknowledgment
|
||||
// in the product documentation would be appreciated but is not required.
|
||||
//
|
||||
// 2. Altered source versions must be plainly marked as such,
|
||||
// and must not be misrepresented as being the original software.
|
||||
//
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
//
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef SFML_VULKANIMPLWIN32_HPP
|
||||
#define SFML_VULKANIMPLWIN32_HPP
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/Window/Vulkan.hpp>
|
||||
#include <SFML/Window/WindowHandle.hpp>
|
||||
#include <vector>
|
||||
|
||||
|
||||
namespace sf
|
||||
{
|
||||
namespace priv
|
||||
{
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Windows implementation of Vulkan
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
class VulkanImplWin32
|
||||
{
|
||||
public:
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Tell whether or not the system supports Vulkan
|
||||
///
|
||||
/// This function should always be called before using
|
||||
/// the Vulkan features. If it returns false, then
|
||||
/// any attempt to use Vulkan will fail.
|
||||
///
|
||||
/// If only compute is required, set \a requireGraphics
|
||||
/// to false to skip checking for the extensions necessary
|
||||
/// for graphics rendering.
|
||||
///
|
||||
/// \param requireGraphics
|
||||
///
|
||||
/// \return True if Vulkan is supported, false otherwise
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
static bool isAvailable(bool requireGraphics = true);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Get the address of a Vulkan function
|
||||
///
|
||||
/// \param name Name of the function to get the address of
|
||||
///
|
||||
/// \return Address of the Vulkan function, 0 on failure
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
static VulkanFunctionPointer getFunction(const char* name);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Get Vulkan instance extensions required for graphics
|
||||
///
|
||||
/// \return Vulkan instance extensions required for graphics
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
static const std::vector<const char*>& getGraphicsRequiredInstanceExtensions();
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Create a Vulkan rendering surface
|
||||
///
|
||||
/// \param instance Vulkan instance
|
||||
/// \param windowHandle Handle to the window to create the surface for
|
||||
/// \param surface Created surface
|
||||
/// \param allocator Allocator to use
|
||||
///
|
||||
/// \return True if surface creation was successful, false otherwise
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
static bool createVulkanSurface(const VkInstance& instance, WindowHandle windowHandle, VkSurfaceKHR& surface, const VkAllocationCallbacks* allocator);
|
||||
};
|
||||
|
||||
} // namespace priv
|
||||
|
||||
} // namespace sf
|
||||
|
||||
|
||||
#endif // SFML_VULKANIMPLWIN32_HPP
|
|
@ -308,6 +308,13 @@ WindowHandle WindowBase::getSystemHandle() const
|
|||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
bool WindowBase::createVulkanSurface(const VkInstance& instance, VkSurfaceKHR& surface, const VkAllocationCallbacks* allocator)
|
||||
{
|
||||
return m_impl ? m_impl->createVulkanSurface(instance, surface, allocator) : false;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void WindowBase::onCreate()
|
||||
{
|
||||
|
|
|
@ -38,26 +38,38 @@
|
|||
#include <SFML/Window/Win32/WindowImplWin32.hpp>
|
||||
typedef sf::priv::WindowImplWin32 WindowImplType;
|
||||
|
||||
#include <SFML/Window/Win32/VulkanImplWin32.hpp>
|
||||
typedef sf::priv::VulkanImplWin32 VulkanImplType;
|
||||
|
||||
#elif defined(SFML_SYSTEM_LINUX) || defined(SFML_SYSTEM_FREEBSD) || defined(SFML_SYSTEM_OPENBSD)
|
||||
|
||||
#include <SFML/Window/Unix/WindowImplX11.hpp>
|
||||
typedef sf::priv::WindowImplX11 WindowImplType;
|
||||
|
||||
#include <SFML/Window/Unix/VulkanImplX11.hpp>
|
||||
typedef sf::priv::VulkanImplX11 VulkanImplType;
|
||||
|
||||
#elif defined(SFML_SYSTEM_MACOS)
|
||||
|
||||
#include <SFML/Window/OSX/WindowImplCocoa.hpp>
|
||||
typedef sf::priv::WindowImplCocoa WindowImplType;
|
||||
|
||||
#define SFML_VULKAN_IMPLEMENTATION_NOT_AVAILABLE
|
||||
|
||||
#elif defined(SFML_SYSTEM_IOS)
|
||||
|
||||
#include <SFML/Window/iOS/WindowImplUIKit.hpp>
|
||||
typedef sf::priv::WindowImplUIKit WindowImplType;
|
||||
|
||||
#define SFML_VULKAN_IMPLEMENTATION_NOT_AVAILABLE
|
||||
|
||||
#elif defined(SFML_SYSTEM_ANDROID)
|
||||
|
||||
#include <SFML/Window/Android/WindowImplAndroid.hpp>
|
||||
typedef sf::priv::WindowImplAndroid WindowImplType;
|
||||
|
||||
#define SFML_VULKAN_IMPLEMENTATION_NOT_AVAILABLE
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -261,6 +273,21 @@ void WindowImpl::processSensorEvents()
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
bool WindowImpl::createVulkanSurface(const VkInstance& instance, VkSurfaceKHR& surface, const VkAllocationCallbacks* allocator)
|
||||
{
|
||||
#if defined(SFML_VULKAN_IMPLEMENTATION_NOT_AVAILABLE)
|
||||
|
||||
return false;
|
||||
|
||||
#else
|
||||
|
||||
return VulkanImplType::createVulkanSurface(instance, getSystemHandle(), surface, allocator);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace priv
|
||||
|
||||
} // namespace sf
|
||||
|
|
|
@ -227,6 +227,18 @@ public:
|
|||
////////////////////////////////////////////////////////////
|
||||
virtual bool hasFocus() const = 0;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Create a Vulkan rendering surface
|
||||
///
|
||||
/// \param instance Vulkan instance
|
||||
/// \param surface Created surface
|
||||
/// \param allocator Allocator to use
|
||||
///
|
||||
/// \return True if surface creation was successful, false otherwise
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
bool createVulkanSurface(const VkInstance& instance, VkSurfaceKHR& surface, const VkAllocationCallbacks* allocator);
|
||||
|
||||
protected:
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue