diff options
| author | Mike Gorchak <mgorchak@blackberry.com> | 2023-08-24 20:26:13 -0400 |
|---|---|---|
| committer | Charles Giessen <46324611+charles-lunarg@users.noreply.github.com> | 2023-08-24 20:21:53 -0600 |
| commit | c536182ca9fa2a149f0e42515909de5417655bc3 (patch) | |
| tree | 94cffdc2dfd8a7b125fb1fff0c9daf3c3ddfe739 /cube | |
| parent | 0c08a569d0a4d0990494490ced6a9bb35dfd5d88 (diff) | |
| download | usermoji-c536182ca9fa2a149f0e42515909de5417655bc3.tar.xz | |
Add QNX support (VK_QNX_screen_surface) to C and C++ variants of vkcube.
Additionally add support for RGB565 and RGBA5551 pixel formats, because
some Vulkan drivers under QNX report these formats first as preferable.
Diffstat (limited to 'cube')
| -rw-r--r-- | cube/cube.c | 201 | ||||
| -rw-r--r-- | cube/cube.cpp | 203 |
2 files changed, 403 insertions, 1 deletions
diff --git a/cube/cube.c b/cube/cube.c index c3e3613f..fc10edcd 100644 --- a/cube/cube.c +++ b/cube/cube.c @@ -33,6 +33,7 @@ #include <stdbool.h> #include <assert.h> #include <signal.h> +#include <errno.h> #if defined(VK_USE_PLATFORM_XLIB_KHR) || defined(VK_USE_PLATFORM_XCB_KHR) #include <X11/Xutil.h> #elif defined(VK_USE_PLATFORM_WAYLAND_KHR) @@ -359,7 +360,12 @@ struct demo { struct ANativeWindow *window; #elif defined(VK_USE_PLATFORM_METAL_EXT) void *caMetalLayer; +#elif defined(VK_USE_PLATFORM_SCREEN_QNX) + screen_context_t screen_context; + screen_window_t screen_window; + screen_event_t screen_event; #endif + VkSurfaceKHR surface; bool prepared; bool use_staging_buffer; @@ -2485,6 +2491,10 @@ static void demo_cleanup(struct demo *demo) { demo->event_buffer->Release(demo->event_buffer); demo->window->Release(demo->window); demo->dfb->Release(demo->dfb); +#elif defined(VK_USE_PLATFORM_SCREEN_QNX) + screen_destroy_event(demo->screen_event); + screen_destroy_window(demo->screen_window); + screen_destroy_context(demo->screen_context); #endif vkDestroyInstance(demo->inst, NULL); @@ -3157,6 +3167,170 @@ static void demo_run_display(struct demo *demo) { } } } +#elif defined(VK_USE_PLATFORM_SCREEN_QNX) + +#include <sys/keycodes.h> + +static void demo_run(struct demo *demo) { + int size[2] = { 0, 0 }; + screen_window_t win; + int val; + int rc; + + while (!demo->quit) { + while (!screen_get_event(demo->screen_context, demo->screen_event, demo->pause ? ~0 : 0)) { + rc = screen_get_event_property_iv(demo->screen_event, SCREEN_PROPERTY_TYPE, &val); + if (rc) { + printf("Cannot get SCREEN_PROPERTY_TYPE of the event! (%s)\n", strerror(errno)); + fflush(stdout); + demo->quit = true; + break; + } + if (val == SCREEN_EVENT_NONE) { + break; + } + switch (val) { + case SCREEN_EVENT_KEYBOARD: + rc = screen_get_event_property_iv(demo->screen_event, SCREEN_PROPERTY_FLAGS, &val); + if (rc) { + printf("Cannot get SCREEN_PROPERTY_FLAGS of the event! (%s)\n", strerror(errno)); + fflush(stdout); + demo->quit = true; + break; + } + if (val & KEY_DOWN) { + rc = screen_get_event_property_iv(demo->screen_event, SCREEN_PROPERTY_SYM, &val); + if (rc) { + printf("Cannot get SCREEN_PROPERTY_SYM of the event! (%s)\n", strerror(errno)); + fflush(stdout); + demo->quit = true; + break; + } + switch (val) { + case KEYCODE_ESCAPE: + demo->quit = true; + break; + case KEYCODE_SPACE: + demo->pause = !demo->pause; + break; + case KEYCODE_LEFT: + demo->spin_angle -= demo->spin_increment; + break; + case KEYCODE_RIGHT: + demo->spin_angle += demo->spin_increment; + break; + default: + break; + } + } + break; + case SCREEN_EVENT_PROPERTY: + rc = screen_get_event_property_pv(demo->screen_event, SCREEN_PROPERTY_WINDOW, (void **)&win); + if (rc) { + printf("Cannot get SCREEN_PROPERTY_WINDOW of the event! (%s)\n", strerror(errno)); + fflush(stdout); + demo->quit = true; + break; + } + rc = screen_get_event_property_iv(demo->screen_event, SCREEN_PROPERTY_NAME, &val); + if (rc) { + printf("Cannot get SCREEN_PROPERTY_NAME of the event! (%s)\n", strerror(errno)); + fflush(stdout); + demo->quit = true; + break; + } + if (win == demo->screen_window) { + switch(val) { + case SCREEN_PROPERTY_SIZE: + rc = screen_get_window_property_iv(win, SCREEN_PROPERTY_SIZE, size); + if (rc) { + printf("Cannot get SCREEN_PROPERTY_SIZE of the window in the event! (%s)\n", strerror(errno)); + fflush(stdout); + demo->quit = true; + break; + } + demo->width = size[0]; + demo->height = size[1]; + demo_resize(demo); + break; + default: + /* We are not interested in any other events for now */ + break; + } + } + break; + } + } + + if (demo->pause) { + } else { + demo_draw(demo); + demo->curFrame++; + if (demo->frameCount != INT32_MAX && demo->curFrame == demo->frameCount) { + demo->quit = true; + } + } + } +} + +static void demo_create_window(struct demo *demo) { + const char *idstr = APP_SHORT_NAME; + int size[2]; + int usage = SCREEN_USAGE_VULKAN; + int rc; + + rc = screen_create_context(&demo->screen_context, 0); + if (rc) { + printf("Cannot create QNX Screen context!\n"); + fflush(stdout); + exit(EXIT_FAILURE); + } + rc = screen_create_window(&demo->screen_window, demo->screen_context); + if (rc) { + printf("Cannot create QNX Screen window!\n"); + fflush(stdout); + exit(EXIT_FAILURE); + } + rc = screen_create_event(&demo->screen_event); + if (rc) { + printf("Cannot create QNX Screen event!\n"); + fflush(stdout); + exit(EXIT_FAILURE); + } + + /* Set window caption */ + screen_set_window_property_cv(demo->screen_window, SCREEN_PROPERTY_ID_STRING, strlen(idstr), idstr); + + /* Setup VULKAN usage flags */ + rc = screen_set_window_property_iv(demo->screen_window, SCREEN_PROPERTY_USAGE, &usage); + if (rc) { + printf("Cannot set SCREEN_USAGE_VULKAN flag!\n"); + fflush(stdout); + exit(EXIT_FAILURE); + } + + /* Setup window size */ + if ((demo->width == 0) || (demo->height == 0)) { + /* Obtain automatically set window size provided by WM */ + rc = screen_get_window_property_iv(demo->screen_window, SCREEN_PROPERTY_SIZE, size); + if (rc) { + printf("Cannot obtain current window size!\n"); + fflush(stdout); + exit(EXIT_FAILURE); + } + demo->width = size[0]; + demo->height = size[1]; + } else { + size[0] = demo->width; + size[1] = demo->height; + rc = screen_set_window_property_iv(demo->screen_window, SCREEN_PROPERTY_SIZE, size); + if (rc) { + printf("Cannot set window size!\n"); + fflush(stdout); + exit(EXIT_FAILURE); + } + } +} #endif /* @@ -3299,6 +3473,11 @@ static void demo_init_vk(struct demo *demo) { platformSurfaceExtFound = 1; demo->extension_names[demo->enabled_extension_count++] = VK_EXT_METAL_SURFACE_EXTENSION_NAME; } +#elif defined(VK_USE_PLATFORM_SCREEN_QNX) + if (!strcmp(VK_QNX_SCREEN_SURFACE_EXTENSION_NAME, instance_extensions[i].extensionName)) { + platformSurfaceExtFound = 1; + demo->extension_names[demo->enabled_extension_count++] = VK_QNX_SCREEN_SURFACE_EXTENSION_NAME; + } #endif if (!strcmp(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, instance_extensions[i].extensionName)) { demo->extension_names[demo->enabled_extension_count++] = VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME; @@ -3376,6 +3555,12 @@ static void demo_init_vk(struct demo *demo) { "Do you have a compatible Vulkan installable client driver (ICD) installed?\n" "Please look at the Getting Started guide for additional information.\n", "vkCreateInstance Failure"); +#elif defined(VK_USE_PLATFORM_SCREEN_QNX) + ERR_EXIT("vkEnumerateInstanceExtensionProperties failed to find the " VK_QNX_SCREEN_SURFACE_EXTENSION_NAME + " extension.\n\n" + "Do you have a compatible Vulkan installable client driver (ICD) installed?\n" + "Please look at the Getting Started guide for additional information.\n", + "vkCreateInstance Failure"); #endif } const VkApplicationInfo app = { @@ -3744,6 +3929,15 @@ static void demo_create_surface(struct demo *demo) { surface.pLayer = demo->caMetalLayer; err = vkCreateMetalSurfaceEXT(demo->inst, &surface, NULL, &demo->surface); +#elif defined(VK_USE_PLATFORM_SCREEN_QNX) + VkScreenSurfaceCreateInfoQNX createInfo; + createInfo.sType = VK_STRUCTURE_TYPE_SCREEN_SURFACE_CREATE_INFO_QNX; + createInfo.pNext = NULL; + createInfo.flags = 0; + createInfo.context = demo->screen_context; + createInfo.window = demo->screen_window; + + err = vkCreateScreenSurfaceQNX(demo->inst, &createInfo, NULL, &demo->surface); #endif assert(!err); } @@ -3755,7 +3949,10 @@ static VkSurfaceFormatKHR pick_surface_format(const VkSurfaceFormatKHR *surfaceF if (format == VK_FORMAT_R8G8B8A8_UNORM || format == VK_FORMAT_B8G8R8A8_UNORM || format == VK_FORMAT_A2B10G10R10_UNORM_PACK32 || format == VK_FORMAT_A2R10G10B10_UNORM_PACK32 || + format == VK_FORMAT_A1R5G5B5_UNORM_PACK16 || format == VK_FORMAT_R5G6B5_UNORM_PACK16 || format == VK_FORMAT_R16G16B16A16_SFLOAT) { + + return surfaceFormats[i]; } } @@ -4386,6 +4583,8 @@ int main(int argc, char **argv) { demo_create_window(&demo); #elif defined(VK_USE_PLATFORM_DIRECTFB_EXT) demo_create_directfb_window(&demo); +#elif defined(VK_USE_PLATFORM_SCREEN_QNX) + demo_create_window(&demo); #endif demo_init_vk_swapchain(&demo); @@ -4402,6 +4601,8 @@ int main(int argc, char **argv) { demo_run_directfb(&demo); #elif defined(VK_USE_PLATFORM_DISPLAY_KHR) demo_run_display(&demo); +#elif defined(VK_USE_PLATFORM_SCREEN_QNX) + demo_run(&demo); #endif demo_cleanup(&demo); diff --git a/cube/cube.cpp b/cube/cube.cpp index f7ddaf75..a59e6dbe 100644 --- a/cube/cube.cpp +++ b/cube/cube.cpp @@ -286,6 +286,9 @@ struct Demo { #elif defined(VK_USE_PLATFORM_DISPLAY_KHR) vk::Result create_display_surface(); void run_display(); +#elif defined(VK_USE_PLATFORM_SCREEN_QNX) + void run(); + void create_window(); #endif std::string name = "vkcubepp"; // Name to put on the window/icon @@ -322,6 +325,10 @@ struct Demo { IDirectFBEventBuffer *event_buffer = nullptr; #elif defined(VK_USE_PLATFORM_METAL_EXT) void *caMetalLayer; +#elif defined(VK_USE_PLATFORM_SCREEN_QNX) + screen_context_t screen_context = nullptr; + screen_window_t screen_window = nullptr; + screen_event_t screen_event = nullptr; #endif vk::SurfaceKHR surface; @@ -620,6 +627,10 @@ void Demo::cleanup() { event_buffer->Release(event_buffer); window->Release(window); dfb->Release(dfb); +#elif defined(VK_USE_PLATFORM_SCREEN_QNX) + screen_destroy_event(screen_event); + screen_destroy_window(screen_window); + screen_destroy_context(screen_context); #endif if (use_debug_messenger) { inst.destroyDebugUtilsMessengerEXT(debug_messenger); @@ -1195,6 +1206,11 @@ void Demo::init_vk() { platformSurfaceExtFound = 1; enabled_instance_extensions.push_back(VK_EXT_METAL_SURFACE_EXTENSION_NAME); } +#elif defined(VK_USE_PLATFORM_SCREEN_QNX) + else if (!strcmp(VK_QNX_SCREEN_SURFACE_EXTENSION_NAME, extension.extensionName)) { + platformSurfaceExtFound = 1; + enabled_instance_extensions.push_back(VK_QNX_SCREEN_SURFACE_EXTENSION_NAME); + } #endif } @@ -1250,6 +1266,13 @@ void Demo::init_vk() { "look at the Getting Started guide for additional " "information.\n", "vkCreateInstance Failure"); +#elif defined(VK_USE_PLATFORM_SCREEN_QNX) + ERR_EXIT("vkEnumerateInstanceExtensionProperties failed to find the " VK_QNX_SCREEN_SURFACE_EXTENSION_NAME + " extension.\n\nDo you have a compatible " + "Vulkan installable client driver (ICD) installed?\nPlease " + "look at the Getting Started guide for additional " + "information.\n", + "vkCreateInstance Failure"); #endif } @@ -1455,6 +1478,13 @@ void Demo::create_surface() { auto result = create_display_surface(); VERIFY(result == vk::Result::eSuccess); } +#elif defined(VK_USE_PLATFORM_SCREEN_QNX) + { + auto const createInfo = vk::ScreenSurfaceCreateInfoQNX().setContext(screen_context).setWindow(screen_window); + + auto result = inst.createScreenSurfaceQNX(&createInfo, nullptr, &surface); + VERIFY(result == vk::Result::eSuccess); + } #endif } @@ -2493,6 +2523,7 @@ vk::SurfaceFormatKHR Demo::pick_surface_format(const std::vector<vk::SurfaceForm if (format == vk::Format::eR8G8B8A8Unorm || format == vk::Format::eB8G8R8A8Unorm || format == vk::Format::eA2B10G10R10UnormPack32 || format == vk::Format::eA2R10G10B10UnormPack32 || + format == vk::Format::eA1R5G5B5UnormPack16 || format == vk::Format::eR5G6B5UnormPack16 || format == vk::Format::eR16G16B16A16Sfloat) { return surface_format; } @@ -3041,6 +3072,172 @@ void Demo::run_display() { } } } + +#elif defined(VK_USE_PLATFORM_SCREEN_QNX) +#include <sys/keycodes.h> + +void Demo::run() +{ + int size[2] = { 0, 0 }; + screen_window_t win; + int val; + int rc; + + while (!quit) { + while (!screen_get_event(screen_context, screen_event, pause ? ~0 : 0)) { + rc = screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_TYPE, &val); + if (rc) { + printf("Cannot get SCREEN_PROPERTY_TYPE of the event! (%s)\n", strerror(errno)); + fflush(stdout); + quit = true; + break; + } + if (val == SCREEN_EVENT_NONE) { + break; + } + switch (val) { + case SCREEN_EVENT_KEYBOARD: + rc = screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_FLAGS, &val); + if (rc) { + printf("Cannot get SCREEN_PROPERTY_FLAGS of the event! (%s)\n", strerror(errno)); + fflush(stdout); + quit = true; + break; + } + if (val & KEY_DOWN) { + rc = screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_SYM, &val); + if (rc) { + printf("Cannot get SCREEN_PROPERTY_SYM of the event! (%s)\n", strerror(errno)); + fflush(stdout); + quit = true; + break; + } + switch (val) { + case KEYCODE_ESCAPE: + quit = true; + break; + case KEYCODE_SPACE: + pause = !pause; + break; + case KEYCODE_LEFT: + spin_angle -= spin_increment; + break; + case KEYCODE_RIGHT: + spin_angle += spin_increment; + break; + default: + break; + } + } + break; + case SCREEN_EVENT_PROPERTY: + rc = screen_get_event_property_pv(screen_event, SCREEN_PROPERTY_WINDOW, (void **)&win); + if (rc) { + printf("Cannot get SCREEN_PROPERTY_WINDOW of the event! (%s)\n", strerror(errno)); + fflush(stdout); + quit = true; + break; + } + rc = screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_NAME, &val); + if (rc) { + printf("Cannot get SCREEN_PROPERTY_NAME of the event! (%s)\n", strerror(errno)); + fflush(stdout); + quit = true; + break; + } + if (win == screen_window) { + switch(val) { + case SCREEN_PROPERTY_SIZE: + rc = screen_get_window_property_iv(win, SCREEN_PROPERTY_SIZE, size); + if (rc) { + printf("Cannot get SCREEN_PROPERTY_SIZE of the window in the event! (%s)\n", strerror(errno)); + fflush(stdout); + quit = true; + break; + } + width = size[0]; + height = size[1]; + resize(); + break; + default: + /* We are not interested in any other events for now */ + break; + } + } + break; + } + } + + if (pause) { + } else { + update_data_buffer(); + draw(); + curFrame++; + if (frameCount != UINT32_MAX && curFrame == frameCount) { + quit = true; + } + } + } +} + +void Demo::create_window() +{ + const char *idstr = APP_SHORT_NAME; + int size[2]; + int usage = SCREEN_USAGE_VULKAN; + int rc; + + rc = screen_create_context(&screen_context, 0); + if (rc) { + printf("Cannot create QNX Screen context!\n"); + fflush(stdout); + exit(EXIT_FAILURE); + } + rc = screen_create_window(&screen_window, screen_context); + if (rc) { + printf("Cannot create QNX Screen window!\n"); + fflush(stdout); + exit(EXIT_FAILURE); + } + rc = screen_create_event(&screen_event); + if (rc) { + printf("Cannot create QNX Screen event!\n"); + fflush(stdout); + exit(EXIT_FAILURE); + } + + /* Set window caption */ + screen_set_window_property_cv(screen_window, SCREEN_PROPERTY_ID_STRING, strlen(idstr), idstr); + + /* Setup VULKAN usage flags */ + rc = screen_set_window_property_iv(screen_window, SCREEN_PROPERTY_USAGE, &usage); + if (rc) { + printf("Cannot set SCREEN_USAGE_VULKAN flag!\n"); + fflush(stdout); + exit(EXIT_FAILURE); + } + + /* Setup window size */ + if ((width == 0) || (height == 0)) { + rc = screen_get_window_property_iv(screen_window, SCREEN_PROPERTY_SIZE, size); + if (rc) { + printf("Cannot obtain current window size!\n"); + fflush(stdout); + exit(EXIT_FAILURE); + } + width = size[0]; + height = size[1]; + } else { + size[0] = width; + size[1] = height; + rc = screen_set_window_property_iv(screen_window, SCREEN_PROPERTY_SIZE, size); + if (rc) { + printf("Cannot set window size!\n"); + fflush(stdout); + exit(EXIT_FAILURE); + } + } +} #endif #if _WIN32 @@ -3187,7 +3384,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR pCmdLine, return static_cast<int>(msg.wParam); } -#elif defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) +#elif defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__QNX__) int main(int argc, char **argv) { Demo demo; @@ -3202,6 +3399,8 @@ int main(int argc, char **argv) { demo.create_window(); #elif defined(VK_USE_PLATFORM_DIRECTFB_EXT) demo.create_directfb_window(); +#elif defined(VK_USE_PLATFORM_SCREEN_QNX) + demo.create_window(); #endif demo.init_vk_swapchain(); @@ -3218,6 +3417,8 @@ int main(int argc, char **argv) { demo.run_directfb(); #elif defined(VK_USE_PLATFORM_DISPLAY_KHR) demo.run_display(); +#elif defined(VK_USE_PLATFORM_SCREEN_QNX) + demo.run(); #endif demo.cleanup(); |
