Add versioning to wsialloc interface
authorDennis Tsiang <dennis.tsiang@arm.com>
Mon, 15 Nov 2021 13:59:10 +0000 (13:59 +0000)
committerDennis Tsiang <dennis.tsiang@arm.com>
Mon, 15 Nov 2021 13:59:10 +0000 (13:59 +0000)
The wsialloc interface now has explicit versioning which is used to
ensure that wsialloc implementations are compatible with the interface.
wsialloc implementations should define which version they are using and
upon version mismatch compilation will fail.

Also:
- add new WSIALLOC_MAX_PLANE macro to define the maximum number of
planes that the wsialloc should support.

Change-Id: I211fc4341f249deff0c005d946c483ba47366600
Signed-off-by: Dennis Tsiang <dennis.tsiang@arm.com>
CMakeLists.txt
util/drm/format_table.h
util/wsialloc/wsialloc.h
util/wsialloc/wsialloc_ion.c
wsi/wayland/swapchain.cpp

index 608a92c013ddacd3f7df3702388ff19f3d0b35dd..00019331f03c940bd488cab53ef5fa1dedbeecda 100644 (file)
@@ -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)
index 7943800bb0c4bc12332862900e9bde6dbe365d89..0b4137e63850d484cb5d41aff2304c8af5d929dc 100644 (file)
 
 #include <vulkan/vulkan.h>
 #include <drm_fourcc.h>
+#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;
 
index d07e0b94fbfbbd27c7f6496d8fe7b341dff5633d..e6a463a51894693bb4ac42963e11f6a421c5dfec 100644 (file)
@@ -53,7 +53,42 @@ 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.
index a51561efd59609bed40ce3bd52b6282d5c107161..c9bdeca0115053f27f4a0b16a182ce55f0434cf5 100644 (file)
 #include <unistd.h>
 #include <string.h>
 
+/**
+ * @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 = {};
 
index fc9c8317e31f8fa11f7dfee04eb7d193cd73c1b6..f4d62d7a3e4ffd5293de009136b6873c47860133 100644 (file)
@@ -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.");