Merge pull request #832 from per-mathisen-arm/master
Add support for rendering with the headless extension
This commit is contained in:
commit
0887881eac
6 changed files with 68 additions and 5 deletions
|
|
@ -18,6 +18,7 @@ include_directories(base)
|
||||||
OPTION(USE_D2D_WSI "Build the project using Direct to Display swapchain" OFF)
|
OPTION(USE_D2D_WSI "Build the project using Direct to Display swapchain" OFF)
|
||||||
OPTION(USE_DIRECTFB_WSI "Build the project using DirectFB swapchain" OFF)
|
OPTION(USE_DIRECTFB_WSI "Build the project using DirectFB swapchain" OFF)
|
||||||
OPTION(USE_WAYLAND_WSI "Build the project using Wayland swapchain" OFF)
|
OPTION(USE_WAYLAND_WSI "Build the project using Wayland swapchain" OFF)
|
||||||
|
OPTION(USE_HEADLESS "Build the project using headless extension swapchain" OFF)
|
||||||
|
|
||||||
set(RESOURCE_INSTALL_DIR "" CACHE PATH "Path to install resources to (leave empty for running uninstalled)")
|
set(RESOURCE_INSTALL_DIR "" CACHE PATH "Path to install resources to (leave empty for running uninstalled)")
|
||||||
|
|
||||||
|
|
@ -79,6 +80,8 @@ ELSEIF(LINUX)
|
||||||
execute_process(COMMAND ${WAYLAND_SCANNER} client-header ${protocol_dir}/stable/xdg-shell/xdg-shell.xml ${CMAKE_BINARY_DIR}/xdg-shell-client-protocol.h
|
execute_process(COMMAND ${WAYLAND_SCANNER} client-header ${protocol_dir}/stable/xdg-shell/xdg-shell.xml ${CMAKE_BINARY_DIR}/xdg-shell-client-protocol.h
|
||||||
COMMAND ${WAYLAND_SCANNER} private-code ${protocol_dir}/stable/xdg-shell/xdg-shell.xml ${CMAKE_BINARY_DIR}/xdg-shell-protocol.c)
|
COMMAND ${WAYLAND_SCANNER} private-code ${protocol_dir}/stable/xdg-shell/xdg-shell.xml ${CMAKE_BINARY_DIR}/xdg-shell-protocol.c)
|
||||||
include_directories(${CMAKE_BINARY_DIR})
|
include_directories(${CMAKE_BINARY_DIR})
|
||||||
|
ELSEIF(USE_HEADLESS)
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DVK_USE_PLATFORM_HEADLESS_EXT")
|
||||||
ELSE(USE_D2D_WSI)
|
ELSE(USE_D2D_WSI)
|
||||||
find_package(XCB REQUIRED)
|
find_package(XCB REQUIRED)
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DVK_USE_PLATFORM_XCB_KHR")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DVK_USE_PLATFORM_XCB_KHR")
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ void VulkanSwapChain::initSurface(wl_display *display, wl_surface *window)
|
||||||
void VulkanSwapChain::initSurface(xcb_connection_t* connection, xcb_window_t window)
|
void VulkanSwapChain::initSurface(xcb_connection_t* connection, xcb_window_t window)
|
||||||
#elif (defined(VK_USE_PLATFORM_IOS_MVK) || defined(VK_USE_PLATFORM_MACOS_MVK))
|
#elif (defined(VK_USE_PLATFORM_IOS_MVK) || defined(VK_USE_PLATFORM_MACOS_MVK))
|
||||||
void VulkanSwapChain::initSurface(void* view)
|
void VulkanSwapChain::initSurface(void* view)
|
||||||
#elif defined(_DIRECT2DISPLAY)
|
#elif (defined(_DIRECT2DISPLAY) || defined(VK_USE_PLATFORM_HEADLESS_EXT))
|
||||||
void VulkanSwapChain::initSurface(uint32_t width, uint32_t height)
|
void VulkanSwapChain::initSurface(uint32_t width, uint32_t height)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
|
|
@ -75,6 +75,14 @@ void VulkanSwapChain::initSurface(uint32_t width, uint32_t height)
|
||||||
surfaceCreateInfo.connection = connection;
|
surfaceCreateInfo.connection = connection;
|
||||||
surfaceCreateInfo.window = window;
|
surfaceCreateInfo.window = window;
|
||||||
err = vkCreateXcbSurfaceKHR(instance, &surfaceCreateInfo, nullptr, &surface);
|
err = vkCreateXcbSurfaceKHR(instance, &surfaceCreateInfo, nullptr, &surface);
|
||||||
|
#elif defined(VK_USE_PLATFORM_HEADLESS_EXT)
|
||||||
|
VkHeadlessSurfaceCreateInfoEXT surfaceCreateInfo = {};
|
||||||
|
surfaceCreateInfo.sType = VK_STRUCTURE_TYPE_HEADLESS_SURFACE_CREATE_INFO_EXT;
|
||||||
|
PFN_vkCreateHeadlessSurfaceEXT fpCreateHeadlessSurfaceEXT = (PFN_vkCreateHeadlessSurfaceEXT)vkGetInstanceProcAddr(instance, "vkCreateHeadlessSurfaceEXT");
|
||||||
|
if (!fpCreateHeadlessSurfaceEXT){
|
||||||
|
vks::tools::exitFatal("Could not fetch function pointer for the headless extension!", -1);
|
||||||
|
}
|
||||||
|
err = fpCreateHeadlessSurfaceEXT(instance, &surfaceCreateInfo, nullptr, &surface);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (err != VK_SUCCESS) {
|
if (err != VK_SUCCESS) {
|
||||||
|
|
|
||||||
|
|
@ -66,9 +66,11 @@ public:
|
||||||
void initSurface(xcb_connection_t* connection, xcb_window_t window);
|
void initSurface(xcb_connection_t* connection, xcb_window_t window);
|
||||||
#elif (defined(VK_USE_PLATFORM_IOS_MVK) || defined(VK_USE_PLATFORM_MACOS_MVK))
|
#elif (defined(VK_USE_PLATFORM_IOS_MVK) || defined(VK_USE_PLATFORM_MACOS_MVK))
|
||||||
void initSurface(void* view);
|
void initSurface(void* view);
|
||||||
#elif defined(_DIRECT2DISPLAY)
|
#elif (defined(_DIRECT2DISPLAY) || defined(VK_USE_PLATFORM_HEADLESS_EXT))
|
||||||
void initSurface(uint32_t width, uint32_t height);
|
void initSurface(uint32_t width, uint32_t height);
|
||||||
|
#if defined(_DIRECT2DISPLAY)
|
||||||
void createDirect2DisplaySurface(uint32_t width, uint32_t height);
|
void createDirect2DisplaySurface(uint32_t width, uint32_t height);
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
void connect(VkInstance instance, VkPhysicalDevice physicalDevice, VkDevice device);
|
void connect(VkInstance instance, VkPhysicalDevice physicalDevice, VkDevice device);
|
||||||
void create(uint32_t* width, uint32_t* height, bool vsync = false);
|
void create(uint32_t* width, uint32_t* height, bool vsync = false);
|
||||||
|
|
|
||||||
|
|
@ -51,6 +51,8 @@ VkResult VulkanExampleBase::createInstance(bool enableValidation)
|
||||||
instanceExtensions.push_back(VK_MVK_IOS_SURFACE_EXTENSION_NAME);
|
instanceExtensions.push_back(VK_MVK_IOS_SURFACE_EXTENSION_NAME);
|
||||||
#elif defined(VK_USE_PLATFORM_MACOS_MVK)
|
#elif defined(VK_USE_PLATFORM_MACOS_MVK)
|
||||||
instanceExtensions.push_back(VK_MVK_MACOS_SURFACE_EXTENSION_NAME);
|
instanceExtensions.push_back(VK_MVK_MACOS_SURFACE_EXTENSION_NAME);
|
||||||
|
#elif defined(VK_USE_PLATFORM_HEADLESS_EXT)
|
||||||
|
instanceExtensions.push_back(VK_EXT_HEADLESS_SURFACE_EXTENSION_NAME);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Get extensions supported by the instance and store for later use
|
// Get extensions supported by the instance and store for later use
|
||||||
|
|
@ -584,6 +586,40 @@ void VulkanExampleBase::renderLoop()
|
||||||
}
|
}
|
||||||
updateOverlay();
|
updateOverlay();
|
||||||
}
|
}
|
||||||
|
#elif defined(VK_USE_PLATFORM_HEADLESS_EXT)
|
||||||
|
while (!quit)
|
||||||
|
{
|
||||||
|
auto tStart = std::chrono::high_resolution_clock::now();
|
||||||
|
if (viewUpdated)
|
||||||
|
{
|
||||||
|
viewUpdated = false;
|
||||||
|
viewChanged();
|
||||||
|
}
|
||||||
|
render();
|
||||||
|
frameCounter++;
|
||||||
|
auto tEnd = std::chrono::high_resolution_clock::now();
|
||||||
|
auto tDiff = std::chrono::duration<double, std::milli>(tEnd - tStart).count();
|
||||||
|
frameTimer = tDiff / 1000.0f;
|
||||||
|
camera.update(frameTimer);
|
||||||
|
if (camera.moving())
|
||||||
|
{
|
||||||
|
viewUpdated = true;
|
||||||
|
}
|
||||||
|
// Convert to clamped timer value
|
||||||
|
timer += timerSpeed * frameTimer;
|
||||||
|
if (timer > 1.0)
|
||||||
|
{
|
||||||
|
timer -= 1.0f;
|
||||||
|
}
|
||||||
|
float fpsTimer = std::chrono::duration<double, std::milli>(tEnd - lastTimestamp).count();
|
||||||
|
if (fpsTimer > 1000.0f)
|
||||||
|
{
|
||||||
|
lastFPS = (float)frameCounter * (1000.0f / fpsTimer);
|
||||||
|
frameCounter = 0;
|
||||||
|
lastTimestamp = tEnd;
|
||||||
|
}
|
||||||
|
updateOverlay();
|
||||||
|
}
|
||||||
#elif (defined(VK_USE_PLATFORM_MACOS_MVK) && defined(VK_EXAMPLE_XCODE_GENERATED))
|
#elif (defined(VK_USE_PLATFORM_MACOS_MVK) && defined(VK_EXAMPLE_XCODE_GENERATED))
|
||||||
[NSApp run];
|
[NSApp run];
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -2431,6 +2467,10 @@ void VulkanExampleBase::handleEvent(const xcb_generic_event_t *event)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
void VulkanExampleBase::setupWindow()
|
||||||
|
{
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void VulkanExampleBase::viewChanged() {}
|
void VulkanExampleBase::viewChanged() {}
|
||||||
|
|
@ -2696,14 +2736,14 @@ void VulkanExampleBase::initSwapchain()
|
||||||
swapChain.initSurface(androidApp->window);
|
swapChain.initSurface(androidApp->window);
|
||||||
#elif (defined(VK_USE_PLATFORM_IOS_MVK) || defined(VK_USE_PLATFORM_MACOS_MVK))
|
#elif (defined(VK_USE_PLATFORM_IOS_MVK) || defined(VK_USE_PLATFORM_MACOS_MVK))
|
||||||
swapChain.initSurface(view);
|
swapChain.initSurface(view);
|
||||||
#elif defined(_DIRECT2DISPLAY)
|
|
||||||
swapChain.initSurface(width, height);
|
|
||||||
#elif defined(VK_USE_PLATFORM_DIRECTFB_EXT)
|
#elif defined(VK_USE_PLATFORM_DIRECTFB_EXT)
|
||||||
swapChain.initSurface(dfb, surface);
|
swapChain.initSurface(dfb, surface);
|
||||||
#elif defined(VK_USE_PLATFORM_WAYLAND_KHR)
|
#elif defined(VK_USE_PLATFORM_WAYLAND_KHR)
|
||||||
swapChain.initSurface(display, surface);
|
swapChain.initSurface(display, surface);
|
||||||
#elif defined(VK_USE_PLATFORM_XCB_KHR)
|
#elif defined(VK_USE_PLATFORM_XCB_KHR)
|
||||||
swapChain.initSurface(connection, window);
|
swapChain.initSurface(connection, window);
|
||||||
|
#elif (defined(_DIRECT2DISPLAY) || defined(VK_USE_PLATFORM_HEADLESS_EXT))
|
||||||
|
swapChain.initSurface(width, height);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -283,6 +283,8 @@ public:
|
||||||
xcb_screen_t *screen;
|
xcb_screen_t *screen;
|
||||||
xcb_window_t window;
|
xcb_window_t window;
|
||||||
xcb_intern_atom_reply_t *atom_wm_delete_window;
|
xcb_intern_atom_reply_t *atom_wm_delete_window;
|
||||||
|
#elif defined(VK_USE_PLATFORM_HEADLESS_EXT)
|
||||||
|
bool quit = false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
VulkanExampleBase(bool enableValidation = false);
|
VulkanExampleBase(bool enableValidation = false);
|
||||||
|
|
@ -356,6 +358,8 @@ public:
|
||||||
xcb_window_t setupWindow();
|
xcb_window_t setupWindow();
|
||||||
void initxcbConnection();
|
void initxcbConnection();
|
||||||
void handleEvent(const xcb_generic_event_t *event);
|
void handleEvent(const xcb_generic_event_t *event);
|
||||||
|
#else
|
||||||
|
void setupWindow();
|
||||||
#endif
|
#endif
|
||||||
/** @brief (Virtual) Creates the application wide Vulkan instance */
|
/** @brief (Virtual) Creates the application wide Vulkan instance */
|
||||||
virtual VkResult createInstance(bool enableValidation);
|
virtual VkResult createInstance(bool enableValidation);
|
||||||
|
|
@ -480,7 +484,7 @@ int main(const int argc, const char *argv[]) \
|
||||||
delete(vulkanExample); \
|
delete(vulkanExample); \
|
||||||
return 0; \
|
return 0; \
|
||||||
}
|
}
|
||||||
#elif defined(VK_USE_PLATFORM_WAYLAND_KHR)
|
#elif (defined(VK_USE_PLATFORM_WAYLAND_KHR) || defined(VK_USE_PLATFORM_HEADLESS_EXT))
|
||||||
#define VULKAN_EXAMPLE_MAIN() \
|
#define VULKAN_EXAMPLE_MAIN() \
|
||||||
VulkanExample *vulkanExample; \
|
VulkanExample *vulkanExample; \
|
||||||
int main(const int argc, const char *argv[]) \
|
int main(const int argc, const char *argv[]) \
|
||||||
|
|
|
||||||
|
|
@ -1188,6 +1188,7 @@ int main(const int argc, const char *argv[])
|
||||||
|
|
||||||
// Linux entry point
|
// Linux entry point
|
||||||
VulkanExample *vulkanExample;
|
VulkanExample *vulkanExample;
|
||||||
|
#if defined(VK_USE_PLATFORM_XCB_KHR)
|
||||||
static void handleEvent(const xcb_generic_event_t *event)
|
static void handleEvent(const xcb_generic_event_t *event)
|
||||||
{
|
{
|
||||||
if (vulkanExample != NULL)
|
if (vulkanExample != NULL)
|
||||||
|
|
@ -1195,6 +1196,11 @@ static void handleEvent(const xcb_generic_event_t *event)
|
||||||
vulkanExample->handleEvent(event);
|
vulkanExample->handleEvent(event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
static void handleEvent()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#endif
|
||||||
int main(const int argc, const char *argv[])
|
int main(const int argc, const char *argv[])
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < argc; i++) { VulkanExample::args.push_back(argv[i]); };
|
for (size_t i = 0; i < argc; i++) { VulkanExample::args.push_back(argv[i]); };
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue