diff --git a/CMakeLists.txt b/CMakeLists.txt index 608a92c..0001933 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -80,10 +80,11 @@ if(BUILD_DRM_UTILS) target_sources(drm_utils PRIVATE util/drm/format_table.c) target_include_directories(drm_utils PRIVATE ${VULKAN_CXX_INCLUDE}) target_include_directories(drm_utils PUBLIC ${LIBDRM_INCLUDE_DIRS}) + target_include_directories(drm_utils PUBLIC util/wsialloc) target_compile_options(drm_utils PUBLIC ${LIBDRM_CFLAGS}) endif() -# External WSI Alloctator +# External WSI Allocator if(NOT SELECT_EXTERNAL_ALLOCATOR STREQUAL "none" AND EXTERNAL_WSIALLOC_LIBRARY STREQUAL "") add_library(wsialloc STATIC) set_target_properties(wsialloc PROPERTIES C_STANDARD 99) diff --git a/util/drm/format_table.h b/util/drm/format_table.h index 7943800..0b4137e 100644 --- a/util/drm/format_table.h +++ b/util/drm/format_table.h @@ -26,22 +26,20 @@ #include #include +#include "wsialloc.h" /* Define DRM linear modifier for compatibility with older DRM header versions. */ #ifndef DRM_FORMAT_MOD_LINEAR #define DRM_FORMAT_MOD_LINEAR 0 #endif -/* Maximum number of planes that can be returned */ -#define WSIALLOCP_MAX_PLANES 4 - #define NELEMS(x) (sizeof(x) / sizeof(x[0])) typedef struct fmt_spec { uint32_t drm_format; uint32_t nr_planes; - uint8_t bpp[WSIALLOCP_MAX_PLANES]; + uint8_t bpp[WSIALLOC_MAX_PLANES]; VkFormat vk_format; } fmt_spec; diff --git a/util/wsialloc/wsialloc.h b/util/wsialloc/wsialloc.h index d07e0b9..e6a463a 100644 --- a/util/wsialloc/wsialloc.h +++ b/util/wsialloc/wsialloc.h @@ -53,8 +53,43 @@ extern "C" { * All API Public entry points are implemented in a way that is thread safe, and the client does not need to be * concerned with locking when using these APIs. If implementers make use of non-threadsafe functions, writable global * data etc they must make appropriate use of locks. + * + * Version History: + * 1 - Initial wsialloc interface */ +#define WSIALLOC_INTERFACE_VERSION 1 + +#define WSIALLOC_CONCAT(x, y) x##y +#define WSIALLOC_SYMBOL_VERSION(symbol, version) WSIALLOC_CONCAT(symbol, version) + +/** + * @brief This symbol must be defined by any implementation of the wsialloc interface as defined in this header. + * + * A wsialloc implementation defining this symbol is declaring it implements + * the exact version of the wsialloc interface defined in this header. + */ +#define WSIALLOC_IMPLEMENTATION_VERSION_SYMBOL \ + WSIALLOC_SYMBOL_VERSION(wsialloc_symbol_version_, WSIALLOC_INTERFACE_VERSION) +extern const uint32_t WSIALLOC_IMPLEMENTATION_VERSION_SYMBOL; + +/** + * @brief Aborts if the wsialloc implementation version is not the expected one. + * + * This macro calls abort() if the version of the wsialloc implementation that was linked to the code using this + * macro is not matching the version defined in the wsialloc.h header that is being included. This can be useful + * to catch compatibility issues in code that links to an external static library implementing the wsialloc + * interface. + */ +#define WSIALLOC_ASSERT_VERSION() \ + if (WSIALLOC_IMPLEMENTATION_VERSION_SYMBOL != WSIALLOC_INTERFACE_VERSION) \ + { \ + abort(); \ + } + +/* Maximum number of planes that can be returned */ +#define WSIALLOC_MAX_PLANES 4 + /** * @brief Allocator type. * diff --git a/util/wsialloc/wsialloc_ion.c b/util/wsialloc/wsialloc_ion.c index a51561e..c9bdeca 100644 --- a/util/wsialloc/wsialloc_ion.c +++ b/util/wsialloc/wsialloc_ion.c @@ -39,6 +39,20 @@ #include #include +/** + * @brief Version of the wsialloc interface we are implementing in this file. + * + * This should only be increased when this implementation is updated to match newer versions of wsialloc.h. + */ +#define WSIALLOC_IMPLEMENTATION_VERSION 1 + +/* Ensure we are implementing the wsialloc version matching the wsialloc.h header we are using. */ +#if WSIALLOC_IMPLEMENTATION_VERSION != WSIALLOC_INTERFACE_VERSION +#error "Version mismatch between wsialloc implementation and interface version" +#endif + +const uint32_t WSIALLOC_IMPLEMENTATION_VERSION_SYMBOL = WSIALLOC_IMPLEMENTATION_VERSION; + /** Default alignment */ #define WSIALLOCP_MIN_ALIGN_SZ (64u) /** Maximum image size allowed for each dimension */ @@ -252,7 +266,7 @@ static const fmt_spec *find_format(uint32_t fourcc) if (fourcc == fourcc_format_table[i].drm_format) { const fmt_spec *found_fmt = &fourcc_format_table[i]; - assert(found_fmt->nr_planes <= WSIALLOCP_MAX_PLANES); + assert(found_fmt->nr_planes <= WSIALLOC_MAX_PLANES); return found_fmt; } @@ -298,9 +312,9 @@ wsialloc_error wsialloc_alloc(wsialloc_allocator *allocator, const wsialloc_allo return WSIALLOC_ERROR_INVALID; } - int local_strides[WSIALLOCP_MAX_PLANES]; - int local_fds[WSIALLOCP_MAX_PLANES] = { -1 }; - int local_offsets[WSIALLOCP_MAX_PLANES]; + int local_strides[WSIALLOC_MAX_PLANES]; + int local_fds[WSIALLOC_MAX_PLANES] = { -1 }; + int local_offsets[WSIALLOC_MAX_PLANES]; wsialloc_error err = WSIALLOC_ERROR_NONE; wsialloc_format_descriptor selected_format_desc = {}; diff --git a/wsi/wayland/swapchain.cpp b/wsi/wayland/swapchain.cpp index fc9c831..f4d62d7 100644 --- a/wsi/wayland/swapchain.cpp +++ b/wsi/wayland/swapchain.cpp @@ -128,6 +128,7 @@ VkResult swapchain::init_platform(VkDevice device, const VkSwapchainCreateInfoKH return VK_ERROR_INITIALIZATION_FAILED; } + WSIALLOC_ASSERT_VERSION(); if (wsialloc_new(&m_wsi_allocator) != WSIALLOC_ERROR_NONE) { WSI_LOG_ERROR("Failed to create wsi allocator.");