Add support for rendering for the headless extension
This commit is contained in:
parent
a2a604be47
commit
45ba247b55
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_DIRECTFB_WSI "Build the project using DirectFB 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)")
|
||||
|
||||
|
|
@ -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
|
||||
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})
|
||||
ELSEIF(USE_HEADLESS)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DVK_USE_PLATFORM_HEADLESS_EXT")
|
||||
ELSE(USE_D2D_WSI)
|
||||
find_package(XCB REQUIRED)
|
||||
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)
|
||||
#elif (defined(VK_USE_PLATFORM_IOS_MVK) || defined(VK_USE_PLATFORM_MACOS_MVK))
|
||||
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)
|
||||
#endif
|
||||
{
|
||||
|
|
@ -75,6 +75,14 @@ void VulkanSwapChain::initSurface(uint32_t width, uint32_t height)
|
|||
surfaceCreateInfo.connection = connection;
|
||||
surfaceCreateInfo.window = window;
|
||||
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
|
||||
|
||||
if (err != VK_SUCCESS) {
|
||||
|
|
|
|||
|
|
@ -66,9 +66,11 @@ public:
|
|||
void initSurface(xcb_connection_t* connection, xcb_window_t window);
|
||||
#elif (defined(VK_USE_PLATFORM_IOS_MVK) || defined(VK_USE_PLATFORM_MACOS_MVK))
|
||||
void initSurface(void* view);
|
||||
#elif defined(_DIRECT2DISPLAY)
|
||||
#elif (defined(_DIRECT2DISPLAY) || defined(VK_USE_PLATFORM_HEADLESS_EXT))
|
||||
void initSurface(uint32_t width, uint32_t height);
|
||||
#if defined(_DIRECT2DISPLAY)
|
||||
void createDirect2DisplaySurface(uint32_t width, uint32_t height);
|
||||
#endif
|
||||
#endif
|
||||
void connect(VkInstance instance, VkPhysicalDevice physicalDevice, VkDevice device);
|
||||
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);
|
||||
#elif defined(VK_USE_PLATFORM_MACOS_MVK)
|
||||
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
|
||||
|
||||
// Get extensions supported by the instance and store for later use
|
||||
|
|
@ -584,6 +586,40 @@ void VulkanExampleBase::renderLoop()
|
|||
}
|
||||
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))
|
||||
[NSApp run];
|
||||
#endif
|
||||
|
|
@ -2425,6 +2461,10 @@ void VulkanExampleBase::handleEvent(const xcb_generic_event_t *event)
|
|||
break;
|
||||
}
|
||||
}
|
||||
#else
|
||||
void VulkanExampleBase::setupWindow()
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
void VulkanExampleBase::viewChanged() {}
|
||||
|
|
@ -2690,14 +2730,14 @@ void VulkanExampleBase::initSwapchain()
|
|||
swapChain.initSurface(androidApp->window);
|
||||
#elif (defined(VK_USE_PLATFORM_IOS_MVK) || defined(VK_USE_PLATFORM_MACOS_MVK))
|
||||
swapChain.initSurface(view);
|
||||
#elif defined(_DIRECT2DISPLAY)
|
||||
swapChain.initSurface(width, height);
|
||||
#elif defined(VK_USE_PLATFORM_DIRECTFB_EXT)
|
||||
swapChain.initSurface(dfb, surface);
|
||||
#elif defined(VK_USE_PLATFORM_WAYLAND_KHR)
|
||||
swapChain.initSurface(display, surface);
|
||||
#elif defined(VK_USE_PLATFORM_XCB_KHR)
|
||||
swapChain.initSurface(connection, window);
|
||||
#elif (defined(_DIRECT2DISPLAY) || defined(VK_USE_PLATFORM_HEADLESS_EXT))
|
||||
swapChain.initSurface(width, height);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -283,6 +283,8 @@ public:
|
|||
xcb_screen_t *screen;
|
||||
xcb_window_t window;
|
||||
xcb_intern_atom_reply_t *atom_wm_delete_window;
|
||||
#elif defined(VK_USE_PLATFORM_HEADLESS_EXT)
|
||||
bool quit = false;
|
||||
#endif
|
||||
|
||||
VulkanExampleBase(bool enableValidation = false);
|
||||
|
|
@ -356,6 +358,8 @@ public:
|
|||
xcb_window_t setupWindow();
|
||||
void initxcbConnection();
|
||||
void handleEvent(const xcb_generic_event_t *event);
|
||||
#else
|
||||
void setupWindow();
|
||||
#endif
|
||||
/** @brief (Virtual) Creates the application wide Vulkan instance */
|
||||
virtual VkResult createInstance(bool enableValidation);
|
||||
|
|
@ -480,7 +484,7 @@ int main(const int argc, const char *argv[]) \
|
|||
delete(vulkanExample); \
|
||||
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() \
|
||||
VulkanExample *vulkanExample; \
|
||||
int main(const int argc, const char *argv[]) \
|
||||
|
|
|
|||
|
|
@ -1188,6 +1188,7 @@ int main(const int argc, const char *argv[])
|
|||
|
||||
// Linux entry point
|
||||
VulkanExample *vulkanExample;
|
||||
#if defined(VK_USE_PLATFORM_XCB_KHR)
|
||||
static void handleEvent(const xcb_generic_event_t *event)
|
||||
{
|
||||
if (vulkanExample != NULL)
|
||||
|
|
@ -1195,6 +1196,11 @@ static void handleEvent(const xcb_generic_event_t *event)
|
|||
vulkanExample->handleEvent(event);
|
||||
}
|
||||
}
|
||||
#else
|
||||
static void handleEvent()
|
||||
{
|
||||
}
|
||||
#endif
|
||||
int main(const int argc, const char *argv[])
|
||||
{
|
||||
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