diff --git a/CMakeLists.txt b/CMakeLists.txt index 169749217..740336227 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -378,6 +378,10 @@ endif() if(NOT DEFINED XRT_FEATURE_OPENXR_VISIBILITY_MASK) set(XRT_FEATURE_OPENXR_VISIBILITY_MASK ON) endif() +option( + XRT_FEATURE_OPENXR_VULKAN_SWAPCHAIN_FORMAT_LIST + "Enable support for the XR_KHR_vulkan_swapchain_format_list extension" ON + ) # Interaction extension support. if(NOT DEFINED XRT_FEATURE_OPENXR_INTERACTION_EXT_EYE_GAZE) @@ -635,6 +639,7 @@ message(STATUS "# FEATURE_OPENXR_OVERLAY: ${XRT_FEATURE message(STATUS "# FEATURE_OPENXR_SPACE_LOCAL_FLOOR: ${XRT_FEATURE_OPENXR_SPACE_LOCAL_FLOOR}") message(STATUS "# FEATURE_OPENXR_SPACE_UNBOUNDED: ${XRT_FEATURE_OPENXR_SPACE_UNBOUNDED}") message(STATUS "# FEATURE_OPENXR_VISIBILITY_MASK ${XRT_FEATURE_OPENXR_VISIBILITY_MASK}") +message(STATUS "# FEATURE_OPENXR_VULKAN_SWAPCHAIN_FORMAT_LIST ${XRT_FEATURE_OPENXR_VULKAN_SWAPCHAIN_FORMAT_LIST}") message(STATUS "# FEATURE_RENDERDOC: ${XRT_FEATURE_RENDERDOC}") message(STATUS "# FEATURE_SERVICE: ${XRT_FEATURE_SERVICE}") message(STATUS "# FEATURE_SERVICE_SYSTEMD: ${XRT_FEATURE_SERVICE_SYSTEMD}") diff --git a/scripts/generate_oxr_ext_support.py b/scripts/generate_oxr_ext_support.py index c1380e96e..0cf72777b 100755 --- a/scripts/generate_oxr_ext_support.py +++ b/scripts/generate_oxr_ext_support.py @@ -52,6 +52,7 @@ EXTENSIONS = ( ['XR_KHR_visibility_mask', 'XRT_FEATURE_OPENXR_VISIBILITY_MASK'], ['XR_KHR_vulkan_enable', 'XR_USE_GRAPHICS_API_VULKAN'], ['XR_KHR_vulkan_enable2', 'XR_USE_GRAPHICS_API_VULKAN'], + ['XR_KHR_vulkan_swapchain_format_list', 'XR_USE_GRAPHICS_API_VULKAN', 'XRT_FEATURE_OPENXR_VULKAN_SWAPCHAIN_FORMAT_LIST'], ['XR_KHR_win32_convert_performance_counter_time', 'XR_USE_PLATFORM_WIN32'], ['XR_EXT_debug_utils', 'XRT_FEATURE_OPENXR_DEBUG_UTILS'], ['XR_EXT_dpad_binding'], diff --git a/src/xrt/state_trackers/oxr/oxr_api_swapchain.c b/src/xrt/state_trackers/oxr/oxr_api_swapchain.c index 2b96ac5cb..81a21ddfa 100644 --- a/src/xrt/state_trackers/oxr/oxr_api_swapchain.c +++ b/src/xrt/state_trackers/oxr/oxr_api_swapchain.c @@ -12,6 +12,7 @@ #include "util/u_debug.h" #include "util/u_trace_marker.h" +#include "oxr_chain.h" #include "oxr_objects.h" #include "oxr_logger.h" #include "oxr_two_call.h" @@ -116,6 +117,27 @@ oxr_xrCreateSwapchain(XrSession session, const XrSwapchainCreateInfo *createInfo "(createInfo->format == 0x%04" PRIx64 ") is not supported", createInfo->format); } +#ifdef OXR_HAVE_KHR_vulkan_swapchain_format_list + const XrVulkanSwapchainFormatListCreateInfoKHR *format_list = NULL; + if (sess->sys->inst->extensions.KHR_vulkan_swapchain_format_list) { + format_list = OXR_GET_INPUT_FROM_CHAIN(createInfo, XR_TYPE_VULKAN_SWAPCHAIN_FORMAT_LIST_CREATE_INFO_KHR, + XrVulkanSwapchainFormatListCreateInfoKHR); + } + + if (format_list) { + if ((createInfo->usageFlags & XR_SWAPCHAIN_USAGE_MUTABLE_FORMAT_BIT) == 0) { + return oxr_error(&log, XR_ERROR_VALIDATION_FAILURE, + "(createInfo->usageFlags) passing in XrVulkanSwapchainFormatListCreateInfoKHR " + "requires the XR_SWAPCHAIN_USAGE_MUTABLE_FORMAT_BIT bit set"); + } + + if (sess->gfx_ext != OXR_SESSION_GRAPHICS_EXT_VULKAN) { + return oxr_error(&log, XR_ERROR_VALIDATION_FAILURE, + "XrVulkanSwapchainFormatListCreateInfoKHR used with non-Vulkan graphics API."); + } + } +#endif + ret = sess->create_swapchain(&log, sess, createInfo, &sc); if (ret != XR_SUCCESS) { return ret; diff --git a/src/xrt/state_trackers/oxr/oxr_extension_support.h b/src/xrt/state_trackers/oxr/oxr_extension_support.h index b2ec20531..c9c64855f 100644 --- a/src/xrt/state_trackers/oxr/oxr_extension_support.h +++ b/src/xrt/state_trackers/oxr/oxr_extension_support.h @@ -234,6 +234,18 @@ #endif +/* + * XR_KHR_vulkan_swapchain_format_list + */ +#if defined(XR_KHR_vulkan_swapchain_format_list) && defined(XR_USE_GRAPHICS_API_VULKAN) +#define OXR_HAVE_KHR_vulkan_swapchain_format_list +#define OXR_EXTENSION_SUPPORT_KHR_vulkan_swapchain_format_list(_) \ + _(KHR_vulkan_swapchain_format_list, KHR_VULKAN_SWAPCHAIN_FORMAT_LIST) +#else +#define OXR_EXTENSION_SUPPORT_KHR_vulkan_swapchain_format_list(_) +#endif + + /* * XR_KHR_win32_convert_performance_counter_time */ @@ -548,6 +560,7 @@ OXR_EXTENSION_SUPPORT_KHR_visibility_mask(_) \ OXR_EXTENSION_SUPPORT_KHR_vulkan_enable(_) \ OXR_EXTENSION_SUPPORT_KHR_vulkan_enable2(_) \ + OXR_EXTENSION_SUPPORT_KHR_vulkan_swapchain_format_list(_) \ OXR_EXTENSION_SUPPORT_KHR_win32_convert_performance_counter_time(_) \ OXR_EXTENSION_SUPPORT_EXT_debug_utils(_) \ OXR_EXTENSION_SUPPORT_EXT_dpad_binding(_) \ diff --git a/src/xrt/state_trackers/oxr/oxr_swapchain.c b/src/xrt/state_trackers/oxr/oxr_swapchain.c index db90e7d65..ceecc972c 100644 --- a/src/xrt/state_trackers/oxr/oxr_swapchain.c +++ b/src/xrt/state_trackers/oxr/oxr_swapchain.c @@ -10,6 +10,7 @@ #include "util/u_debug.h" #include "util/u_misc.h" +#include "oxr_chain.h" #include "oxr_objects.h" #include "oxr_logger.h" #include "oxr_handle.h" @@ -276,16 +277,38 @@ oxr_swapchain_common_create(struct oxr_logger *log, { xrt_result_t xret = XRT_SUCCESS; - struct xrt_swapchain_create_info info; - info.create = convert_create_flags(createInfo->createFlags); - info.bits = convert_usage_bits(createInfo->usageFlags); - info.format = createInfo->format; - info.sample_count = createInfo->sampleCount; - info.width = createInfo->width; - info.height = createInfo->height; - info.face_count = createInfo->faceCount; - info.array_size = createInfo->arraySize; - info.mip_count = createInfo->mipCount; + struct xrt_swapchain_create_info info = { + .create = convert_create_flags(createInfo->createFlags), + .bits = convert_usage_bits(createInfo->usageFlags), + .format = createInfo->format, + .sample_count = createInfo->sampleCount, + .width = createInfo->width, + .height = createInfo->height, + .face_count = createInfo->faceCount, + .array_size = createInfo->arraySize, + .mip_count = createInfo->mipCount, + }; + +#ifdef OXR_HAVE_KHR_vulkan_swapchain_format_list + const XrVulkanSwapchainFormatListCreateInfoKHR *format_list = NULL; + if (sess->sys->inst->extensions.KHR_vulkan_swapchain_format_list) { + format_list = OXR_GET_INPUT_FROM_CHAIN(createInfo, XR_TYPE_VULKAN_SWAPCHAIN_FORMAT_LIST_CREATE_INFO_KHR, + XrVulkanSwapchainFormatListCreateInfoKHR); + } + + if (format_list) { + // Check in oxr_api_swapchain.c verification. + assert((createInfo->usageFlags & XR_SWAPCHAIN_USAGE_MUTABLE_FORMAT_BIT) == 0); + + if (format_list->viewFormatCount > ARRAY_SIZE(info.formats)) { + /* Hardcoded limit of 8 formats */ + return oxr_error(log, XR_ERROR_RUNTIME_FAILURE, "Too many formats"); + } + + info.format_count = format_list->viewFormatCount; + memcpy(info.formats, format_list->viewFormats, sizeof(uint32_t) * info.format_count); + } +#endif struct xrt_swapchain *xsc = NULL; // Has to be NULL. xret = xrt_comp_create_swapchain(sess->compositor, &info, &xsc);