summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--recipes-graphics/vulkan/vulkan-wsi-layer/0001-MGS-9070-add-arm-r56p0-wsi-layer-changes.patch1244
-rw-r--r--recipes-graphics/vulkan/vulkan-wsi-layer/0001-wayland-Add-C-guard-before-__STDC_VERSION__-define.patch21
-rw-r--r--recipes-graphics/vulkan/vulkan-wsi-layer/0002-MGS-6823-nxp-Add-support-of-VK_COMPOSITE_ALPHA_OPAQU.patch243
-rw-r--r--recipes-graphics/vulkan/vulkan-wsi-layer/0002-wsialloc-initialize-local_strides-array.patch32
-rw-r--r--recipes-graphics/vulkan/vulkan-wsi-layer/0003-MGS-6801-ccc-vkmark-on-wayland.patch (renamed from recipes-graphics/vulkan/vulkan-wsi-layer/0001-MGS-6801-ccc-vkmark-on-wayland.patch)19
-rw-r--r--recipes-graphics/vulkan/vulkan-wsi-layer/0003-Update-minimum-version-of-CMake.patch32
-rw-r--r--recipes-graphics/vulkan/vulkan-wsi-layer/0004-Add-support-VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR.patch155
-rw-r--r--recipes-graphics/vulkan/vulkan-wsi-layer/0005-MGS-7487-nxp-fix-Vulkan-test-report-warning-msg.patch53
-rw-r--r--recipes-graphics/vulkan/vulkan-wsi-layer/0006-MGS-9060-mali-fix-swapchainMaintenance1-incorrectly-.patch55
-rw-r--r--recipes-graphics/vulkan/vulkan-wsi-layer/0007-MGS-6283-nxp-fix-segfault-in-opaque-alpha-init-on-OO.patch79
-rw-r--r--recipes-graphics/vulkan/vulkan-wsi-layer_git.bb12
11 files changed, 1646 insertions, 299 deletions
diff --git a/recipes-graphics/vulkan/vulkan-wsi-layer/0001-MGS-9070-add-arm-r56p0-wsi-layer-changes.patch b/recipes-graphics/vulkan/vulkan-wsi-layer/0001-MGS-9070-add-arm-r56p0-wsi-layer-changes.patch
new file mode 100644
index 000000000..c9b3a4ff8
--- /dev/null
+++ b/recipes-graphics/vulkan/vulkan-wsi-layer/0001-MGS-9070-add-arm-r56p0-wsi-layer-changes.patch
@@ -0,0 +1,1244 @@
1From b93b676cf60577d496f026d820215b14f9973030 Mon Sep 17 00:00:00 2001
2From: Joshua Wienecke <joshua.wienecke_1@nxp.com>
3Date: Mon, 3 Aug 2026 11:24:22 -0500
4Subject: [PATCH 1/7] MGS-9070 add arm r56p0 wsi layer changes
5
6https://developer.arm.com/downloads/-/Vulkan%20WSI%20Layer
7VX501X08X-SW-99009-r56p0-18eac0
8
9Upstream-Status: Pending
10
11Signed-off-by: Joshua Wienecke <joshua.wienecke_1@nxp.com>
12---
13 CMakeLists.txt | 30 +++++++++++++------------
14 README.md | 5 +----
15 layer/calibrated_timestamps_api.cpp | 4 +++-
16 layer/calibrated_timestamps_api.hpp | 4 +++-
17 layer/layer.cpp | 17 +++++++++-----
18 layer/present_timing_api.cpp | 13 +++++++----
19 layer/private_data.cpp | 4 +++-
20 layer/private_data.hpp | 18 ++++++++++-----
21 layer/surface_api.cpp | 4 +++-
22 layer/swapchain_api.cpp | 7 ++++--
23 layer/wsi_layer_experimental.hpp | 18 +++++++++++++++
24 wsi/display/surface_properties.cpp | 2 ++
25 wsi/display/surface_properties.hpp | 4 +++-
26 wsi/extensions/present_timing.cpp | 27 +++++++---------------
27 wsi/extensions/present_timing.hpp | 6 +++--
28 wsi/headless/present_timing_handler.cpp | 7 ++++--
29 wsi/headless/present_timing_handler.hpp | 6 ++++-
30 wsi/headless/surface_properties.cpp | 8 ++++++-
31 wsi/headless/surface_properties.hpp | 4 +++-
32 wsi/headless/swapchain.cpp | 11 +++++++--
33 wsi/surface_properties.cpp | 2 ++
34 wsi/surface_properties.hpp | 6 ++++-
35 wsi/swapchain_base.cpp | 8 +++++--
36 wsi/swapchain_base.hpp | 4 ++++
37 wsi/wayland/present_id_wayland.cpp | 5 ++++-
38 wsi/wayland/present_id_wayland.hpp | 6 ++++-
39 wsi/wayland/present_timing_handler.hpp | 6 ++++-
40 wsi/wayland/surface_properties.cpp | 7 +++++-
41 wsi/wayland/surface_properties.hpp | 4 +++-
42 wsi/wayland/swapchain.cpp | 24 ++++++++++++++++++--
43 30 files changed, 193 insertions(+), 78 deletions(-)
44
45diff --git a/CMakeLists.txt b/CMakeLists.txt
46index e383aef..04e66c3 100644
47--- a/CMakeLists.txt
48+++ b/CMakeLists.txt
49@@ -51,12 +51,7 @@ string(APPEND CMAKE_C_FLAGS
50 set(CMAKE_CXX_STANDARD 17)
51 set(CMAKE_CXX_STANDARD_REQUIRED ON)
52
53-if ("${CMAKE_C_FLAGS} ${CMAKE_CXX_FLAGS} ${CMAKE_EXE_LINKER_FLAGS} ${CMAKE_SHARED_LINKER_FLAGS}" MATCHES "(^| )-fsanitize=")
54- message(STATUS "Sanitizer-enabled build detected; not forcing -Wl,--no-undefined")
55-else()
56- set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--no-undefined")
57-endif()
58-
59+set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--no-undefined")
60 set(CMAKE_CXX_VISIBILITY_PRESET hidden)
61 set(CMAKE_C_VISIBILITY_PRESET hidden)
62 set(CMAKE_VISIBILITY_INLINES_HIDDEN YES)
63@@ -157,14 +152,17 @@ if(BUILD_WSI_WAYLAND)
64 wsi/wayland/surface_properties.cpp
65 wsi/wayland/surface.cpp
66 wsi/wayland/wl_helpers.cpp
67- wsi/wayland/present_id_wayland.cpp
68- wsi/wayland/present_timing_handler.cpp
69- wsi/wayland/present_wait_wayland.cpp
70 wsi/wayland/swapchain.cpp
71- wsi/wayland/wp_presentation_feedback.cpp
72+ wsi/wayland/present_wait_wayland.cpp
73 wsi/extensions/external_memory_extension.cpp
74 wsi/image_backing_memory_external.cpp)
75
76+ if(VULKAN_WSI_LAYER_EXPERIMENTAL)
77+ target_sources(wayland_wsi PRIVATE wsi/wayland/present_id_wayland.cpp)
78+ target_sources(wayland_wsi PRIVATE wsi/wayland/present_timing_handler.cpp)
79+ target_sources(wayland_wsi PRIVATE wsi/wayland/wp_presentation_feedback.cpp)
80+ endif()
81+
82 pkg_check_modules(WAYLAND_CLIENT REQUIRED wayland-client)
83 message(STATUS "Using Wayland client include directories: ${WAYLAND_CLIENT_INCLUDE_DIRS}")
84 message(STATUS "Using Wayland client cflags: ${WAYLAND_CLIENT_CFLAGS}")
85@@ -245,10 +243,13 @@ if(BUILD_WSI_HEADLESS)
86 wsi/headless/surface_properties.cpp
87 wsi/headless/surface.cpp
88 wsi/headless/swapchain.cpp
89- wsi/headless/present_timing_handler.cpp
90 wsi/headless/present_wait_headless.cpp
91 wsi/image_backing_memory_device.cpp)
92
93+ if(VULKAN_WSI_LAYER_EXPERIMENTAL)
94+ target_sources(wsi_headless PRIVATE wsi/headless/present_timing_handler.cpp)
95+ endif()
96+
97 target_include_directories(wsi_headless PRIVATE
98 ${PROJECT_SOURCE_DIR}
99 ${VULKAN_CXX_INCLUDE}
100@@ -306,7 +307,6 @@ add_library(${PROJECT_NAME} SHARED
101 layer/surface_api.cpp
102 layer/swapchain_api.cpp
103 layer/swapchain_maintenance_api.cpp
104- layer/present_timing_api.cpp
105 layer/present_wait_api.cpp
106 util/timed_semaphore.cpp
107 util/custom_allocator.cpp
108@@ -320,7 +320,6 @@ add_library(${PROJECT_NAME} SHARED
109 wsi/extensions/present_wait.cpp
110 wsi/extensions/frame_boundary.cpp
111 wsi/extensions/mutable_format_extension.cpp
112- wsi/extensions/present_timing.cpp
113 util/wsi_extension.cpp
114 wsi/extensions/swapchain_maintenance.cpp
115 wsi/surface_properties.cpp
116@@ -330,13 +329,16 @@ add_library(${PROJECT_NAME} SHARED
117 wsi/vulkan_image_handle_creator.cpp
118 wsi/swapchain_image_factory.cpp
119 wsi/swapchain_image.cpp)
120-
121 if (VULKAN_WSI_LAYER_EXPERIMENTAL)
122+ target_sources(${PROJECT_NAME} PUBLIC ${PROJECT_SOURCE_DIR}/layer/present_timing_api.cpp)
123+ target_sources(${PROJECT_NAME} PUBLIC ${PROJECT_SOURCE_DIR}/wsi/extensions/present_timing.cpp)
124 add_definitions("-DVULKAN_WSI_LAYER_EXPERIMENTAL=1")
125 else()
126+ list(APPEND JSON_COMMANDS COMMAND sed -Ei '/VK_EXT_present_timing/d' ${CMAKE_CURRENT_BINARY_DIR}/VkLayer_window_system_integration.json)
127 add_definitions("-DVULKAN_WSI_LAYER_EXPERIMENTAL=0")
128 endif()
129
130+
131 if((CMAKE_BUILD_TYPE MATCHES "^[Dd]ebug$") OR (CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo"))
132 target_sources(${PROJECT_NAME} PUBLIC util/debug.cpp)
133 endif()
134diff --git a/README.md b/README.md
135index ab82e53..082677a 100644
136--- a/README.md
137+++ b/README.md
138@@ -35,8 +35,7 @@ implements the following extensions:
139 * VK_EXT_present_mode_fifo_latest_ready (For Headless and Wayland only)
140 * VK_KHR_present_mode_fifo_latest_ready (For Headless and Wayland only)
141 * VK_KHR_swapchain_mutable_format (For Headless and Wayland only)
142- * VK_EXT_present_timing (For Headless and Wayland only)
143-
144+
145 ## Building
146
147 ### Dependencies
148@@ -53,8 +52,6 @@ The ICDs installed in the system are required to support the following extension
149 * VK_KHR_external_fence_capabilities
150 * VK_KHR_external_semaphore_capabilities
151 * VK_KHR_external_memory_capabilities
152-* Device extensions (required when Headless/Wayland support is enabled):
153- * VK_KHR_calibrated_timestamps
154 * Device extensions (only required when Wayland support is enabled):
155 * VK_EXT_image_drm_format_modifier
156 * VK_KHR_image_format_list
157diff --git a/layer/calibrated_timestamps_api.cpp b/layer/calibrated_timestamps_api.cpp
158index cc9c174..4ca5aa0 100644
159--- a/layer/calibrated_timestamps_api.cpp
160+++ b/layer/calibrated_timestamps_api.cpp
161@@ -1,5 +1,5 @@
162 /*
163- * Copyright (c) 2025-2026 Arm Limited.
164+ * Copyright (c) 2025 Arm Limited.
165 *
166 * SPDX-License-Identifier: MIT
167 *
168@@ -31,6 +31,7 @@
169 #include <wsi/extensions/present_timing.hpp>
170 #include <wsi/swapchain_base.hpp>
171
172+#if VULKAN_WSI_LAYER_EXPERIMENTAL
173 VWL_VKAPI_CALL(VkResult)
174 wsi_layer_vkGetCalibratedTimestampsKHR(VkDevice device, uint32_t timestampCount,
175 const VkCalibratedTimestampInfoKHR *pTimestampInfos, uint64_t *pTimestamps,
176@@ -172,3 +173,4 @@ wsi_layer_vkGetPhysicalDeviceCalibrateableTimeDomainsEXT(VkPhysicalDevice physic
177 {
178 return wsi_layer_vkGetPhysicalDeviceCalibrateableTimeDomainsKHR(physicalDevice, pTimeDomainCount, pTimeDomains);
179 }
180+#endif /* VULKAN_WSI_LAYER_EXPERIMENTAL */
181diff --git a/layer/calibrated_timestamps_api.hpp b/layer/calibrated_timestamps_api.hpp
182index d1eee9c..fbe6e0e 100644
183--- a/layer/calibrated_timestamps_api.hpp
184+++ b/layer/calibrated_timestamps_api.hpp
185@@ -1,5 +1,5 @@
186 /*
187- * Copyright (c) 2025-2026 Arm Limited.
188+ * Copyright (c) 2025 Arm Limited.
189 *
190 * SPDX-License-Identifier: MIT
191 *
192@@ -32,6 +32,7 @@
193 #pragma once
194 #include "util/macros.hpp"
195
196+#if VULKAN_WSI_LAYER_EXPERIMENTAL
197 VWL_VKAPI_CALL(VkResult)
198 wsi_layer_vkGetCalibratedTimestampsEXT(VkDevice device, uint32_t timestampCount,
199 const VkCalibratedTimestampInfoKHR *pTimestampInfos, uint64_t *pTimestamps,
200@@ -48,3 +49,4 @@ wsi_layer_vkGetPhysicalDeviceCalibrateableTimeDomainsKHR(VkPhysicalDevice physic
201 VWL_VKAPI_CALL(VkResult)
202 wsi_layer_vkGetPhysicalDeviceCalibrateableTimeDomainsEXT(VkPhysicalDevice physicalDevice, uint32_t *pTimeDomainCount,
203 VkTimeDomainEXT *pTimeDomains) VWL_API_POST;
204+#endif
205diff --git a/layer/layer.cpp b/layer/layer.cpp
206index 6117c15..106000d 100644
207--- a/layer/layer.cpp
208+++ b/layer/layer.cpp
209@@ -1,5 +1,5 @@
210 /*
211- * Copyright (c) 2016-2026 Arm Limited.
212+ * Copyright (c) 2016-2025 Arm Limited.
213 *
214 * SPDX-License-Identifier: MIT
215 *
216@@ -31,8 +31,8 @@
217 #include <vulkan/vulkan.h>
218
219 #include "layer/calibrated_timestamps_api.hpp"
220-#include "present_timing_api.hpp"
221 #include "present_wait_api.hpp"
222+#include "wsi_layer_experimental.hpp"
223 #include "private_data.hpp"
224 #include "surface_api.hpp"
225 #include "swapchain_api.hpp"
226@@ -246,13 +246,16 @@ VKAPI_ATTR VkResult create_device(VkPhysicalDevice physicalDevice, const VkDevic
227 util::vector<const char *> modified_enabled_extensions{ allocator };
228 util::extension_list enabled_extensions{ allocator };
229
230+#if VULKAN_WSI_LAYER_EXPERIMENTAL
231 VkPhysicalDeviceMaintenance9FeaturesKHR maintenance9_features = {};
232+#endif /* VULKAN_WSI_LAYER_EXPERIMENTAL */
233 const util::wsi_platform_set &enabled_platforms = inst_data.get_enabled_platforms();
234 if (!enabled_platforms.empty())
235 {
236 TRY_LOG_CALL(enabled_extensions.add(pCreateInfo->ppEnabledExtensionNames, pCreateInfo->enabledExtensionCount));
237 TRY_LOG_CALL(wsi::add_device_extensions_required_by_layer(physicalDevice, enabled_platforms, enabled_extensions,
238 inst_data.api_version));
239+#if VULKAN_WSI_LAYER_EXPERIMENTAL
240 auto present_timing_supported = wsi::present_timing_dependencies_supported(physicalDevice);
241 if (std::holds_alternative<VkResult>(present_timing_supported))
242 {
243@@ -283,6 +286,7 @@ VKAPI_ATTR VkResult create_device(VkPhysicalDevice physicalDevice, const VkDevic
244 modified_info.pNext = &maintenance9_features;
245 }
246 }
247+#endif /* VULKAN_WSI_LAYER_EXPERIMENTAL */
248
249 TRY_LOG_CALL(enabled_extensions.get_extension_strings(modified_enabled_extensions));
250
251@@ -594,6 +598,7 @@ wsi_layer_vkGetPhysicalDeviceFeatures2(VkPhysicalDevice physical_device,
252 }
253 }
254
255+#if VULKAN_WSI_LAYER_EXPERIMENTAL
256 auto *present_timing_features = util::find_extension<VkPhysicalDevicePresentTimingFeaturesEXT>(
257 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_TIMING_FEATURES_EXT, pFeatures->pNext);
258 if (present_timing_features != nullptr)
259@@ -610,6 +615,7 @@ wsi_layer_vkGetPhysicalDeviceFeatures2(VkPhysicalDevice physical_device,
260 present_timing_features->presentAtAbsoluteTime = VK_TRUE;
261 present_timing_features->presentAtRelativeTime = VK_TRUE;
262 }
263+#endif
264
265 auto *present_mode_fifo_latest_ready_features =
266 util::find_extension<VkPhysicalDevicePresentModeFifoLatestReadyFeaturesEXT>(
267@@ -673,7 +679,7 @@ wsi_layer_vkGetDeviceProcAddr(VkDevice device, const char *funcName) VWL_API_POS
268 {
269 GET_PROC_ADDR(vkGetSwapchainStatusKHR);
270 }
271-
272+#if VULKAN_WSI_LAYER_EXPERIMENTAL
273 if (device_data.is_device_extension_enabled(VK_EXT_PRESENT_TIMING_EXTENSION_NAME))
274 {
275 GET_PROC_ADDR(vkSetSwapchainPresentTimingQueueSizeEXT);
276@@ -686,7 +692,7 @@ wsi_layer_vkGetDeviceProcAddr(VkDevice device, const char *funcName) VWL_API_POS
277 GET_PROC_ADDR(vkGetCalibratedTimestampsEXT);
278 }
279 }
280-
281+#endif
282 GET_PROC_ADDR(vkDestroyDevice);
283 GET_PROC_ADDR(vkCreateImage);
284
285@@ -803,9 +809,10 @@ wsi_layer_vkGetInstanceProcAddr(VkInstance instance, const char *funcName) VWL_A
286 GET_PROC_ADDR(vkGetPhysicalDeviceSurfaceCapabilities2KHR);
287 GET_PROC_ADDR(vkGetPhysicalDeviceSurfaceFormats2KHR);
288 }
289-
290+#if VULKAN_WSI_LAYER_EXPERIMENTAL
291 GET_PROC_ADDR(vkGetPhysicalDeviceCalibrateableTimeDomainsKHR);
292 GET_PROC_ADDR(vkGetPhysicalDeviceCalibrateableTimeDomainsEXT);
293+#endif
294
295 if (instance_data.is_instance_extension_enabled(VK_EXT_DISPLAY_SURFACE_COUNTER_EXTENSION_NAME))
296 {
297diff --git a/layer/present_timing_api.cpp b/layer/present_timing_api.cpp
298index 376e39f..16dce6f 100644
299--- a/layer/present_timing_api.cpp
300+++ b/layer/present_timing_api.cpp
301@@ -1,5 +1,5 @@
302 /*
303- * Copyright (c) 2024-2026 Arm Limited.
304+ * Copyright (c) 2024-2025 Arm Limited.
305 *
306 * SPDX-License-Identifier: MIT
307 *
308@@ -28,12 +28,13 @@
309 * @brief Contains the Vulkan entrypoints for the present timing.
310 */
311 #include <cassert>
312+#include "wsi_layer_experimental.hpp"
313
314-#include "present_timing_api.hpp"
315 #include <wsi/extensions/present_timing.hpp>
316 #include <wsi/swapchain_base.hpp>
317 #include "util/macros.hpp"
318
319+#if VULKAN_WSI_LAYER_EXPERIMENTAL
320 /**
321 * @brief Implements vkSetSwapchainPresentTimingQueueSizeEXT Vulkan entrypoint.
322 */
323@@ -92,8 +93,11 @@ wsi_layer_vkGetSwapchainTimeDomainPropertiesEXT(VkDevice device, VkSwapchainKHR
324 return device_data.disp.GetSwapchainTimeDomainPropertiesEXT(device, swapchain, pSwapchainTimeDomainProperties,
325 pTimeDomainsCounter);
326 }
327- return wsi::swapchain_time_domains::get_swapchain_time_domain_properties(pSwapchainTimeDomainProperties,
328- pTimeDomainsCounter);
329+
330+ auto *sc = reinterpret_cast<wsi::swapchain_base *>(swapchain);
331+ auto *ext = sc->get_swapchain_extension<wsi::wsi_ext_present_timing>(true);
332+ return ext->get_swapchain_time_domains().get_swapchain_time_domain_properties(pSwapchainTimeDomainProperties,
333+ pTimeDomainsCounter);
334 }
335
336 /**
337@@ -115,3 +119,4 @@ wsi_layer_vkGetPastPresentationTimingEXT(
338 auto *ext = sc->get_swapchain_extension<wsi::wsi_ext_present_timing>(true);
339 return ext->get_past_presentation_results(pPastPresentationTimingProperties, pPastPresentationTimingInfo->flags);
340 }
341+#endif /* VULKAN_WSI_LAYER_EXPERIMENTAL */
342diff --git a/layer/private_data.cpp b/layer/private_data.cpp
343index 973a60c..30464ca 100644
344--- a/layer/private_data.cpp
345+++ b/layer/private_data.cpp
346@@ -1,5 +1,5 @@
347 /*
348- * Copyright (c) 2018-2026 Arm Limited.
349+ * Copyright (c) 2018-2025 Arm Limited.
350 *
351 * SPDX-License-Identifier: MIT
352 *
353@@ -472,7 +472,9 @@ device_private_data::device_private_data(instance_private_data &inst_data, VkPhy
354 , compression_control_enabled{ false }
355 , present_id_enabled { false }
356 , swapchain_maintenance1_enabled{ false }
357+#if VULKAN_WSI_LAYER_EXPERIMENTAL
358 , present_timing_enabled { true }
359+#endif
360 , present_wait2_enabled { false }
361 , present_id2_enabled { false }
362 , present_mode_fifo_latest_ready_enabled { false }
363diff --git a/layer/private_data.hpp b/layer/private_data.hpp
364index dcf1bfa..edb1526 100644
365--- a/layer/private_data.hpp
366+++ b/layer/private_data.hpp
367@@ -1,5 +1,5 @@
368 /*
369- * Copyright (c) 2018-2026 Arm Limited.
370+ * Copyright (c) 2018-2025 Arm Limited.
371 *
372 * SPDX-License-Identifier: MIT
373 *
374@@ -24,7 +24,7 @@
375
376 #pragma once
377
378-#include <layer/present_timing_api.hpp>
379+#include <layer/wsi_layer_experimental.hpp>
380
381 #include <util/platform_set.hpp>
382 #include <util/custom_allocator.hpp>
383@@ -379,7 +379,15 @@ private:
384 * alias: Name of the promoted entrypoint alias if different to entrypoint_name.
385 */
386
387+#if VULKAN_WSI_LAYER_EXPERIMENTAL
388+#define DEVICE_ENTRYPOINTS_LIST_EXPERIMENTAL(EP) \
389+ EP(GetSwapchainTimeDomainPropertiesEXT, VK_EXT_PRESENT_TIMING_EXTENSION_NAME, API_VERSION_MAX, false, ) \
390+ EP(GetSwapchainTimingPropertiesEXT, VK_EXT_PRESENT_TIMING_EXTENSION_NAME, API_VERSION_MAX, false, ) \
391+ EP(SetSwapchainPresentTimingQueueSizeEXT, VK_EXT_PRESENT_TIMING_EXTENSION_NAME, API_VERSION_MAX, false, ) \
392+ EP(GetPastPresentationTimingEXT, VK_EXT_PRESENT_TIMING_EXTENSION_NAME, API_VERSION_MAX, false, )
393+#else
394 #define DEVICE_ENTRYPOINTS_LIST_EXPERIMENTAL(EP)
395+#endif
396
397 /* Define a list of custom entrypoints that might rely on preprocessor conditions and similar */
398 #define DEVICE_ENTRYPOINTS_LIST_EXPANSION(EP) DEVICE_ENTRYPOINTS_LIST_EXPERIMENTAL(EP)
399@@ -473,10 +481,6 @@ private:
400 EP(WaitForPresentKHR, VK_KHR_PRESENT_WAIT_EXTENSION_NAME, API_VERSION_MAX, false, ) \
401 /* VK_KHR_present_wait2 */ \
402 EP(WaitForPresent2KHR, VK_KHR_PRESENT_WAIT_2_EXTENSION_NAME, API_VERSION_MAX, false, ) \
403- EP(GetSwapchainTimeDomainPropertiesEXT, VK_EXT_PRESENT_TIMING_EXTENSION_NAME, API_VERSION_MAX, false, ) \
404- EP(GetSwapchainTimingPropertiesEXT, VK_EXT_PRESENT_TIMING_EXTENSION_NAME, API_VERSION_MAX, false, ) \
405- EP(SetSwapchainPresentTimingQueueSizeEXT, VK_EXT_PRESENT_TIMING_EXTENSION_NAME, API_VERSION_MAX, false, ) \
406- EP(GetPastPresentationTimingEXT, VK_EXT_PRESENT_TIMING_EXTENSION_NAME, API_VERSION_MAX, false, ) \
407 /* Custom entrypoints */ \
408 DEVICE_ENTRYPOINTS_LIST_EXPANSION(EP)
409
410@@ -1095,10 +1099,12 @@ private:
411 */
412 bool present_wait_enabled{ false };
413
414+#if VULKAN_WSI_LAYER_EXPERIMENTAL
415 /**
416 * @brief Stores whether the device has enabled support for the present timing features.
417 */
418 bool present_timing_enabled{ false };
419+#endif
420
421 /**
422 * @brief Stores whether the device supports the present wait2 feature.
423diff --git a/layer/surface_api.cpp b/layer/surface_api.cpp
424index 7a7e24f..dde362d 100644
425--- a/layer/surface_api.cpp
426+++ b/layer/surface_api.cpp
427@@ -1,5 +1,5 @@
428 /*
429- * Copyright (c) 2016-2017, 2019, 2021-2022, 2024-2026 Arm Limited.
430+ * Copyright (c) 2016-2017, 2019, 2021-2022, 2024-2025 Arm Limited.
431 *
432 * SPDX-License-Identifier: MIT
433 *
434@@ -119,12 +119,14 @@ wsi_layer_vkGetPhysicalDeviceSurfaceCapabilities2KHR(VkPhysicalDevice physicalDe
435 wsi::surface_properties *props = wsi::get_surface_properties(instance, pSurfaceInfo->surface);
436 assert(props != nullptr);
437
438+#if VULKAN_WSI_LAYER_EXPERIMENTAL
439 auto *surf_caps_ext = util::find_extension<VkPresentTimingSurfaceCapabilitiesEXT>(
440 VK_STRUCTURE_TYPE_PRESENT_TIMING_SURFACE_CAPABILITIES_EXT, pSurfaceCapabilities);
441 if (surf_caps_ext != nullptr)
442 {
443 TRY_LOG_CALL(props->get_present_timing_surface_caps(physicalDevice, surf_caps_ext));
444 }
445+#endif
446
447 auto shared_present_surface_cap_struct = util::find_extension<VkSharedPresentSurfaceCapabilitiesKHR>(
448 VK_STRUCTURE_TYPE_SHARED_PRESENT_SURFACE_CAPABILITIES_KHR, pSurfaceCapabilities);
449diff --git a/layer/swapchain_api.cpp b/layer/swapchain_api.cpp
450index 9a4f8f9..2c5dbd8 100644
451--- a/layer/swapchain_api.cpp
452+++ b/layer/swapchain_api.cpp
453@@ -1,5 +1,5 @@
454 /*
455- * Copyright (c) 2017, 2019, 2021-2026 Arm Limited.
456+ * Copyright (c) 2017, 2019, 2021-2025 Arm Limited.
457 *
458 * SPDX-License-Identifier: MIT
459 *
460@@ -218,13 +218,14 @@ wsi_layer_vkQueuePresentKHR(VkQueue queue, const VkPresentInfoKHR *pPresentInfo)
461 VK_STRUCTURE_TYPE_SWAPCHAIN_PRESENT_FENCE_INFO_EXT, present_info->pNext);
462 const auto swapchain_present_mode_info = util::find_extension<VkSwapchainPresentModeInfoEXT>(
463 VK_STRUCTURE_TYPE_SWAPCHAIN_PRESENT_MODE_INFO_EXT, present_info->pNext);
464+#if VULKAN_WSI_LAYER_EXPERIMENTAL
465 const auto present_timings_info =
466 util::find_extension<VkPresentTimingsInfoEXT>(VK_STRUCTURE_TYPE_PRESENT_TIMINGS_INFO_EXT, present_info->pNext);
467 if (present_timings_info)
468 {
469 assert(present_timings_info->swapchainCount == pPresentInfo->swapchainCount);
470 }
471-
472+#endif
473 for (uint32_t i = 0; i < pPresentInfo->swapchainCount; ++i)
474 {
475 VkSwapchainKHR swapc = pPresentInfo->pSwapchains[i];
476@@ -259,11 +260,13 @@ wsi_layer_vkQueuePresentKHR(VkQueue queue, const VkPresentInfoKHR *pPresentInfo)
477 present_params.use_image_present_semaphore = use_image_present_semaphore;
478 present_params.handle_present_frame_boundary_event = frame_boundary_event_handled;
479
480+#if VULKAN_WSI_LAYER_EXPERIMENTAL
481 if (present_timings_info)
482 {
483 present_params.m_present_timing_info = present_timings_info->pTimingInfos[i];
484 present_params.m_present_timing_info.pNext = nullptr;
485 }
486+#endif
487 VkResult res = sc->queue_present(queue, present_info, present_params);
488 if (pPresentInfo->pResults != nullptr)
489 {
490diff --git a/layer/wsi_layer_experimental.hpp b/layer/wsi_layer_experimental.hpp
491index 8e86520..d7251a5 100644
492--- a/layer/wsi_layer_experimental.hpp
493+++ b/layer/wsi_layer_experimental.hpp
494@@ -34,4 +34,22 @@
495
496 #if VULKAN_WSI_LAYER_EXPERIMENTAL
497
498+VWL_VKAPI_CALL(VkResult)
499+wsi_layer_vkSetSwapchainPresentTimingQueueSizeEXT(VkDevice device, VkSwapchainKHR swapchain,
500+ uint32_t size) VWL_API_POST;
501+
502+VWL_VKAPI_CALL(VkResult)
503+wsi_layer_vkGetSwapchainTimingPropertiesEXT(VkDevice device, VkSwapchainKHR swapchain,
504+ VkSwapchainTimingPropertiesEXT *pSwapchainTimingProperties,
505+ uint64_t *pSwapchainTimingPropertiesCounter) VWL_API_POST;
506+VWL_VKAPI_CALL(VkResult)
507+wsi_layer_vkGetSwapchainTimeDomainPropertiesEXT(VkDevice device, VkSwapchainKHR swapchain,
508+ VkSwapchainTimeDomainPropertiesEXT *pSwapchainTimeDomainProperties,
509+ uint64_t *pTimeDomainsCounter) VWL_API_POST;
510+
511+VWL_VKAPI_CALL(VkResult)
512+wsi_layer_vkGetPastPresentationTimingEXT(
513+ VkDevice device, const VkPastPresentationTimingInfoEXT *pPastPresentationTimingInfo,
514+ VkPastPresentationTimingPropertiesEXT *pPastPresentationTimingProperties) VWL_API_POST;
515+
516 #endif
517diff --git a/wsi/display/surface_properties.cpp b/wsi/display/surface_properties.cpp
518index b8b54b0..8139130 100644
519--- a/wsi/display/surface_properties.cpp
520+++ b/wsi/display/surface_properties.cpp
521@@ -569,6 +569,7 @@ bool surface_properties::is_surface_extension_enabled(const layer::instance_priv
522 return instance_data.is_instance_extension_enabled(VK_KHR_SURFACE_EXTENSION_NAME);
523 }
524
525+#if VULKAN_WSI_LAYER_EXPERIMENTAL
526 VkResult surface_properties::get_present_timing_surface_caps_internal(
527 VkPhysicalDevice, VkPresentTimingSurfaceCapabilitiesEXT *present_timing_surface_caps)
528 {
529@@ -579,6 +580,7 @@ VkResult surface_properties::get_present_timing_surface_caps_internal(
530
531 return VK_SUCCESS;
532 }
533+#endif
534
535 surface_properties &surface_properties::get_instance()
536 {
537diff --git a/wsi/display/surface_properties.hpp b/wsi/display/surface_properties.hpp
538index 3ef8300..c8e68b5 100644
539--- a/wsi/display/surface_properties.hpp
540+++ b/wsi/display/surface_properties.hpp
541@@ -1,5 +1,5 @@
542 /*
543- * Copyright (c) 2024-2026 Arm Limited.
544+ * Copyright (c) 2024-2025 Arm Limited.
545 *
546 * SPDX-License-Identifier: MIT
547 *
548@@ -82,8 +82,10 @@ private:
549 void get_surface_present_scaling_and_gravity(VkSurfacePresentScalingCapabilitiesEXT *scaling_capabilities) override;
550 void populate_present_mode_compatibilities() override;
551
552+#if VULKAN_WSI_LAYER_EXPERIMENTAL
553 VkResult get_present_timing_surface_caps_internal(
554 VkPhysicalDevice physical_device, VkPresentTimingSurfaceCapabilitiesEXT *present_timing_surface_caps) override;
555+#endif
556 };
557
558 } /* namespace display */
559diff --git a/wsi/extensions/present_timing.cpp b/wsi/extensions/present_timing.cpp
560index d0335c4..4b6aa1a 100644
561--- a/wsi/extensions/present_timing.cpp
562+++ b/wsi/extensions/present_timing.cpp
563@@ -34,6 +34,7 @@
564
565 #include "present_timing.hpp"
566
567+#if VULKAN_WSI_LAYER_EXPERIMENTAL
568 namespace wsi
569 {
570 /* VK_PRESENT_STAGE_QUEUE_OPERATIONS_END_BIT_EXT,
571@@ -131,10 +132,7 @@ swapchain_presentation_timing *wsi_ext_present_timing::get_pending_stage_timing(
572 {
573 if (auto *entry = get_pending_stage_entry(image_index, stage))
574 {
575- if (auto stage_timing_optional = entry->get_stage_timing(stage))
576- {
577- return &stage_timing_optional->get();
578- }
579+ return &entry->get_stage_timing(stage)->get();
580 }
581 return nullptr;
582 }
583@@ -386,8 +384,7 @@ VkResult wsi_ext_present_timing::get_past_presentation_results(
584 return VK_SUCCESS;
585 }
586
587- uint64_t timing_count = 0;
588- uint64_t removed_entries = 0;
589+ uint64_t timing_count = 0, removed_entries = 0;
590 VkPastPresentationTimingEXT *timings = past_present_timing_properties->pPresentationTimings;
591 const bool allow_partial = (flags & VK_PAST_PRESENTATION_TIMING_ALLOW_PARTIAL_RESULTS_BIT_EXT) != 0;
592 const bool allow_out_of_order = (flags & VK_PAST_PRESENTATION_TIMING_ALLOW_OUT_OF_ORDER_RESULTS_BIT_EXT) != 0;
593@@ -508,11 +505,7 @@ std::optional<bool> swapchain_presentation_entry::is_complete(VkPresentStageFlag
594 bool swapchain_presentation_entry::is_pending(VkPresentStageFlagBitsEXT stage)
595 {
596 auto stage_timing_optional = get_stage_timing(stage);
597- if (!stage_timing_optional.has_value())
598- {
599- return false;
600- }
601- return !stage_timing_optional->get().m_set;
602+ return stage_timing_optional.has_value() ? !stage_timing_optional->get().m_set : false;
603 }
604
605 bool swapchain_presentation_entry::has_outstanding_stages()
606@@ -579,17 +572,11 @@ std::optional<std::reference_wrapper<swapchain_presentation_timing>> swapchain_p
607 void swapchain_presentation_entry::set_stage_timing(VkPresentStageFlagBitsEXT stage, uint64_t time)
608 {
609 auto stage_timing_optional = get_stage_timing(stage);
610- if (!stage_timing_optional.has_value())
611- {
612- return;
613- }
614-
615- auto &stage_timing = stage_timing_optional->get();
616- if (stage_timing.m_set)
617+ if (stage_timing_optional->get().m_set)
618 {
619 return;
620 }
621- stage_timing.set_time(time);
622+ stage_timing_optional->get().set_time(time);
623 }
624
625 void swapchain_presentation_entry::populate(VkPastPresentationTimingEXT &timing)
626@@ -745,3 +732,5 @@ std::variant<bool, VkResult> present_timing_dependencies_supported(VkPhysicalDev
627 return maintenance9.maintenance9 != VK_FALSE;
628 }
629 } /* namespace wsi */
630+
631+#endif /* VULKAN_WSI_LAYER_EXPERIMENTAL */
632diff --git a/wsi/extensions/present_timing.hpp b/wsi/extensions/present_timing.hpp
633index 0e590a7..98e2467 100644
634--- a/wsi/extensions/present_timing.hpp
635+++ b/wsi/extensions/present_timing.hpp
636@@ -42,14 +42,15 @@
637 #include <variant>
638 #include <cmath>
639
640+#include <layer/wsi_layer_experimental.hpp>
641 #include <layer/private_data.hpp>
642-#include <layer/present_timing_api.hpp>
643 #include <util/custom_allocator.hpp>
644 #include <util/custom_mutex.hpp>
645 #include <util/macros.hpp>
646 #include <util/wsi_extension.hpp>
647 #include <wsi/swapchain_base.hpp>
648
649+#if VULKAN_WSI_LAYER_EXPERIMENTAL
650 namespace wsi
651 {
652
653@@ -145,7 +146,7 @@ struct swapchain_presentation_entry
654 * keeps the status of whether the slot had already been copied to
655 * the results.
656 */
657- bool copied{ false };
658+ bool copied;
659
660 /**
661 * The variables to keep timing stages.
662@@ -845,3 +846,4 @@ inline uint64_t ticks_to_ns(uint64_t ticks, const float &timestamp_period)
663 }
664
665 } /* namespace wsi */
666+#endif
667diff --git a/wsi/headless/present_timing_handler.cpp b/wsi/headless/present_timing_handler.cpp
668index 246a76e..8f7bfdb 100644
669--- a/wsi/headless/present_timing_handler.cpp
670+++ b/wsi/headless/present_timing_handler.cpp
671@@ -27,6 +27,7 @@
672 *
673 * @brief Contains the functionality to implement features for present timing extension.
674 */
675+#if VULKAN_WSI_LAYER_EXPERIMENTAL
676 #include <cstdint>
677 #include <array>
678 #include <algorithm>
679@@ -153,7 +154,7 @@ std::optional<uint64_t> wsi_ext_present_timing_headless::get_current_clock_time_
680 return std::nullopt;
681 }
682
683- return (static_cast<uint64_t>(now.tv_sec) * static_cast<uint64_t>(1e9)) + static_cast<uint64_t>(now.tv_nsec);
684+ return static_cast<uint64_t>(now.tv_sec) * static_cast<uint64_t>(1e9) + static_cast<uint64_t>(now.tv_nsec);
685 }
686
687 std::optional<uint64_t> wsi_ext_present_timing_headless::get_first_pixel_visible_timestamp_for_last_image() const
688@@ -162,7 +163,7 @@ std::optional<uint64_t> wsi_ext_present_timing_headless::get_first_pixel_visible
689 {
690 return std::nullopt;
691 }
692- return m_first_pixel_visible_timestamp_for_last_image;
693+ return m_first_pixel_visible_timestamp_for_last_image.value();
694 }
695
696 void wsi_ext_present_timing_headless::set_first_pixel_visible_timestamp_for_last_image(uint64_t timestamp)
697@@ -182,3 +183,5 @@ VkPresentStageFlagsEXT wsi_ext_present_timing_headless::stages_supported()
698 }
699 return stages;
700 }
701+
702+#endif
703diff --git a/wsi/headless/present_timing_handler.hpp b/wsi/headless/present_timing_handler.hpp
704index f2d58c2..dd5396c 100644
705--- a/wsi/headless/present_timing_handler.hpp
706+++ b/wsi/headless/present_timing_handler.hpp
707@@ -1,5 +1,5 @@
708 /*
709- * Copyright (c) 2025-2026 Arm Limited.
710+ * Copyright (c) 2025 Arm Limited.
711 *
712 * SPDX-License-Identifier: MIT
713 *
714@@ -29,6 +29,8 @@
715 */
716 #pragma once
717
718+#if VULKAN_WSI_LAYER_EXPERIMENTAL
719+
720 #include <wsi/extensions/present_timing.hpp>
721 #include <wsi/swapchain_base.hpp>
722
723@@ -107,3 +109,5 @@ private:
724 */
725 bool m_is_swapchain_using_shared_present_mode;
726 };
727+
728+#endif
729diff --git a/wsi/headless/surface_properties.cpp b/wsi/headless/surface_properties.cpp
730index 3bfe538..2c39518 100644
731--- a/wsi/headless/surface_properties.cpp
732+++ b/wsi/headless/surface_properties.cpp
733@@ -34,11 +34,15 @@
734 #include <vulkan/vulkan.h>
735
736 #include <layer/private_data.hpp>
737-#include "present_timing_handler.hpp"
738+
739 #include "surface_properties.hpp"
740 #include "surface.hpp"
741 #include "util/macros.hpp"
742
743+#if VULKAN_WSI_LAYER_EXPERIMENTAL
744+#include "present_timing_handler.hpp"
745+#endif
746+
747 namespace wsi
748 {
749 namespace headless
750@@ -245,6 +249,7 @@ bool surface_properties::is_compatible_present_modes(VkPresentModeKHR present_mo
751 return m_compatible_present_modes.is_compatible_present_modes(present_mode_a, present_mode_b);
752 }
753
754+#if VULKAN_WSI_LAYER_EXPERIMENTAL
755 VkResult surface_properties::get_present_timing_surface_caps_internal(
756 VkPhysicalDevice physical_device, VkPresentTimingSurfaceCapabilitiesEXT *present_timing_surface_caps)
757 {
758@@ -275,6 +280,7 @@ VkResult surface_properties::get_present_timing_surface_caps_internal(
759
760 return VK_SUCCESS;
761 }
762+#endif
763
764 } /* namespace headless */
765 } /* namespace wsi */
766diff --git a/wsi/headless/surface_properties.hpp b/wsi/headless/surface_properties.hpp
767index 51e80f6..82cd693 100644
768--- a/wsi/headless/surface_properties.hpp
769+++ b/wsi/headless/surface_properties.hpp
770@@ -1,5 +1,5 @@
771 /*
772- * Copyright (c) 2017-2019, 2022-2026 Arm Limited.
773+ * Copyright (c) 2017-2019, 2022-2025 Arm Limited.
774 *
775 * SPDX-License-Identifier: MIT
776 *
777@@ -75,8 +75,10 @@ private:
778
779 void get_surface_present_scaling_and_gravity(VkSurfacePresentScalingCapabilitiesEXT *scaling_capabilities) override;
780
781+#if VULKAN_WSI_LAYER_EXPERIMENTAL
782 VkResult get_present_timing_surface_caps_internal(
783 VkPhysicalDevice physical_device, VkPresentTimingSurfaceCapabilitiesEXT *present_timing_surface_caps) override;
784+#endif
785 };
786
787 } /* namespace headless */
788diff --git a/wsi/headless/swapchain.cpp b/wsi/headless/swapchain.cpp
789index bf15d73..09a6dbf 100644
790--- a/wsi/headless/swapchain.cpp
791+++ b/wsi/headless/swapchain.cpp
792@@ -99,6 +99,7 @@ VkResult swapchain::add_required_extensions(VkDevice device, const VkSwapchainCr
793 }
794 }
795
796+#if VULKAN_WSI_LAYER_EXPERIMENTAL
797 bool swapchain_support_enabled = swapchain_create_info->flags & VK_SWAPCHAIN_CREATE_PRESENT_TIMING_BIT_EXT;
798 if (swapchain_support_enabled)
799 {
800@@ -108,6 +109,7 @@ VkResult swapchain::add_required_extensions(VkDevice device, const VkSwapchainCr
801 return VK_ERROR_OUT_OF_HOST_MEMORY;
802 }
803 }
804+#endif
805
806 bool present_wait2;
807 constexpr VkSwapchainCreateFlagsKHR present_wait2_mask =
808@@ -174,6 +176,7 @@ VkResult swapchain::allocate_and_bind_swapchain_image(swapchain_image &image)
809
810 void swapchain::present_image(const pending_present_request &pending_present)
811 {
812+#if VULKAN_WSI_LAYER_EXPERIMENTAL
813 auto *ext_present_timing = get_swapchain_extension<wsi_ext_present_timing_headless>();
814 if (ext_present_timing)
815 {
816@@ -199,19 +202,20 @@ void swapchain::present_image(const pending_present_request &pending_present)
817 absolute_future_present_time_ns = presentation_target->m_target_present_time;
818 }
819 auto current_time_ns = ext_present_timing->get_current_clock_time_ns();
820- if (current_time_ns.has_value() && current_time_ns.value() < absolute_future_present_time_ns)
821+ if (*current_time_ns < absolute_future_present_time_ns)
822 {
823 /* Sleep until we can schedule the image for completion.
824 * This is OK as the sleep should only be dispatched on the page_flip thread and not on main. */
825 assert(m_page_flip_thread_run);
826
827- const auto time_diff = static_cast<int64_t>(absolute_future_present_time_ns - current_time_ns.value());
828+ int64_t time_diff = static_cast<int64_t>(absolute_future_present_time_ns - *current_time_ns);
829 std::this_thread::sleep_for(std::chrono::nanoseconds(time_diff));
830 }
831 }
832
833 ext_present_timing->remove_presentation_target_entry(pending_present.image_index);
834 }
835+#endif
836
837 auto *ext = get_swapchain_extension<wsi_ext_present_id>();
838 if (ext != nullptr)
839@@ -219,6 +223,7 @@ void swapchain::present_image(const pending_present_request &pending_present)
840 ext->mark_delivered(pending_present.present_id);
841 }
842
843+#if VULKAN_WSI_LAYER_EXPERIMENTAL
844 if (ext_present_timing && ext_present_timing->get_monotonic_domain().has_value())
845 {
846 auto current_time = ext_present_timing->get_current_clock_time_ns();
847@@ -239,6 +244,8 @@ void swapchain::present_image(const pending_present_request &pending_present)
848 ext_present_timing->set_pending_stage_time(pending_present.image_index, stage, *current_time);
849 }
850 }
851+#endif
852+
853 unpresent_image(pending_present.image_index);
854 }
855
856diff --git a/wsi/surface_properties.cpp b/wsi/surface_properties.cpp
857index 673bc5a..0299c9e 100644
858--- a/wsi/surface_properties.cpp
859+++ b/wsi/surface_properties.cpp
860@@ -141,6 +141,7 @@ void get_surface_capabilities_common(VkPhysicalDevice physical_device, VkSurface
861 VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
862 }
863
864+#if VULKAN_WSI_LAYER_EXPERIMENTAL
865 /**
866 * @brief Get the present timing surface capabilities for the specific VkSurface type.
867 */
868@@ -162,5 +163,6 @@ VkResult surface_properties::get_present_timing_surface_caps(
869
870 return VK_SUCCESS;
871 }
872+#endif /* VULKAN_WSI_LAYER_EXPERIMENTAL */
873
874 } /* namespace wsi */
875diff --git a/wsi/surface_properties.hpp b/wsi/surface_properties.hpp
876index 92d270a..ce996a9 100644
877--- a/wsi/surface_properties.hpp
878+++ b/wsi/surface_properties.hpp
879@@ -31,7 +31,7 @@
880 #pragma once
881
882 #include <vulkan/vulkan.h>
883-#include "layer/present_timing_api.hpp"
884+#include "layer/wsi_layer_experimental.hpp"
885 #include "layer/private_data.hpp"
886 #include "util/custom_allocator.hpp"
887 #include "util/drm/drm_utils.hpp"
888@@ -119,11 +119,13 @@ public:
889
890 virtual bool is_compatible_present_modes(VkPresentModeKHR present_mode_a, VkPresentModeKHR present_mode_b) = 0;
891
892+#if VULKAN_WSI_LAYER_EXPERIMENTAL
893 /**
894 * @brief Get the present timing surface capabilities for the specific VkSurface type.
895 */
896 VkResult get_present_timing_surface_caps(VkPhysicalDevice physical_device,
897 VkPresentTimingSurfaceCapabilitiesEXT *present_timing_surface_caps);
898+#endif /* VULKAN_WSI_LAYER_EXPERIMENTAL */
899
900 /**
901 * @brief Virtual destructor.
902@@ -136,11 +138,13 @@ private:
903 */
904 virtual void populate_present_mode_compatibilities() = 0;
905
906+#if VULKAN_WSI_LAYER_EXPERIMENTAL
907 /**
908 * @brief Get the present timing surface capabilities for the specific VkSurface type.
909 */
910 virtual VkResult get_present_timing_surface_caps_internal(
911 VkPhysicalDevice physical_device, VkPresentTimingSurfaceCapabilitiesEXT *present_timing_surface_caps) = 0;
912+#endif /* VULKAN_WSI_LAYER_EXPERIMENTAL */
913 };
914
915 class surface_format_properties
916diff --git a/wsi/swapchain_base.cpp b/wsi/swapchain_base.cpp
917index eb5f0f1..eaf4ff4 100644
918--- a/wsi/swapchain_base.cpp
919+++ b/wsi/swapchain_base.cpp
920@@ -597,6 +597,7 @@ VkResult swapchain_base::queue_present(VkQueue queue, const VkPresentInfoKHR *pr
921 }
922 }
923
924+#if VULKAN_WSI_LAYER_EXPERIMENTAL
925 const VkPresentTimingInfoEXT *present_timing_info = nullptr;
926 const auto *present_timings_info =
927 util::find_extension<VkPresentTimingsInfoEXT>(VK_STRUCTURE_TYPE_PRESENT_TIMINGS_INFO_EXT, present_info->pNext);
928@@ -610,7 +611,7 @@ VkResult swapchain_base::queue_present(VkQueue queue, const VkPresentInfoKHR *pr
929 TRY(ext_present_timing->queue_has_space());
930 }
931 }
932-
933+#endif
934 if (submit_info.switch_presentation_mode)
935 {
936 /* Assert when a presentation mode switch is requested and the swapchain_maintenance1 extension which implements this is not available */
937@@ -651,6 +652,7 @@ VkResult swapchain_base::queue_present(VkQueue queue, const VkPresentInfoKHR *pr
938 signal_semaphores[count_signal_semaphores++] =
939 m_swapchain_images[submit_info.pending_present.image_index].get_present_fence_wait_semaphore();
940 }
941+#if VULKAN_WSI_LAYER_EXPERIMENTAL
942 if ((present_timing_info != nullptr) &&
943 (present_timing_info->presentStageQueries & VK_PRESENT_STAGE_QUEUE_OPERATIONS_END_BIT_EXT))
944 {
945@@ -661,7 +663,7 @@ VkResult swapchain_base::queue_present(VkQueue queue, const VkPresentInfoKHR *pr
946 ext_present_timing->get_image_present_semaphore(submit_info.pending_present.image_index);
947 }
948 }
949-
950+#endif
951 queue_submit_semaphores semaphores = {
952 wait_semaphores,
953 sem_count,
954@@ -683,12 +685,14 @@ VkResult swapchain_base::queue_present(VkQueue queue, const VkPresentInfoKHR *pr
955 TRY(sync_queue_submit(m_device_data, queue, submit_info.present_fence, present_fence_semaphores));
956 }
957
958+#if VULKAN_WSI_LAYER_EXPERIMENTAL
959 if (present_timing_info != nullptr)
960 {
961 auto *ext_present_timing = get_swapchain_extension<wsi::wsi_ext_present_timing>(true);
962 TRY_LOG_CALL(ext_present_timing->add_presentation_entry(
963 queue, submit_info.pending_present.present_id, submit_info.pending_present.image_index, *present_timing_info));
964 }
965+#endif
966 TRY(notify_presentation_engine(submit_info.pending_present));
967
968 return VK_SUCCESS;
969diff --git a/wsi/swapchain_base.hpp b/wsi/swapchain_base.hpp
970index 0847248..f23669f 100644
971--- a/wsi/swapchain_base.hpp
972+++ b/wsi/swapchain_base.hpp
973@@ -100,16 +100,20 @@ struct swapchain_presentation_parameters
974 */
975 VkBool32 handle_present_frame_boundary_event{ true };
976
977+#if VULKAN_WSI_LAYER_EXPERIMENTAL
978 /**
979 * The present timing info.
980 */
981 VkPresentTimingInfoEXT m_present_timing_info;
982+#endif
983 };
984
985 enum signal_semaphores_type
986 {
987 SIGNAL_SEMAPHORE_PRESENT_FENCE,
988+#if VULKAN_WSI_LAYER_EXPERIMENTAL
989 SIGNAL_SEMAPHORE_PRESENT_TIMING,
990+#endif
991 SIGNAL_SEMAPHORE_MAX_NUM,
992 };
993
994diff --git a/wsi/wayland/present_id_wayland.cpp b/wsi/wayland/present_id_wayland.cpp
995index aa4e227..0804da1 100644
996--- a/wsi/wayland/present_id_wayland.cpp
997+++ b/wsi/wayland/present_id_wayland.cpp
998@@ -1,5 +1,5 @@
999 /*
1000- * Copyright (c) 2025-2026 Arm Limited.
1001+ * Copyright (c) 2025 Arm Limited.
1002 *
1003 * SPDX-License-Identifier: MIT
1004 *
1005@@ -27,6 +27,7 @@
1006 *
1007 * @brief Contains the functionality to implement Wayland specific features for present ID extension.
1008 */
1009+#if VULKAN_WSI_LAYER_EXPERIMENTAL
1010
1011 #include <util/custom_mutex.hpp>
1012 #include "present_id_wayland.hpp"
1013@@ -104,3 +105,5 @@ void wsi_ext_present_id_wayland::remove_from_pending_present_feedback_list(uint6
1014
1015 } // namespace wayland
1016 } // namespace wsi
1017+
1018+#endif /* VULKAN_WSI_LAYER_EXPERIMENTAL */
1019diff --git a/wsi/wayland/present_id_wayland.hpp b/wsi/wayland/present_id_wayland.hpp
1020index af7d87f..2d27f8d 100644
1021--- a/wsi/wayland/present_id_wayland.hpp
1022+++ b/wsi/wayland/present_id_wayland.hpp
1023@@ -1,5 +1,5 @@
1024 /*
1025- * Copyright (c) 2025-2026 Arm Limited.
1026+ * Copyright (c) 2025 Arm Limited.
1027 *
1028 * SPDX-License-Identifier: MIT
1029 *
1030@@ -29,6 +29,8 @@
1031 */
1032 #pragma once
1033
1034+#if VULKAN_WSI_LAYER_EXPERIMENTAL
1035+
1036 #include <wsi/extensions/present_id.hpp>
1037 #include <util/ring_buffer.hpp>
1038 #include "surface_properties.hpp"
1039@@ -95,3 +97,5 @@ private:
1040
1041 } // namespace wayland
1042 } // namespace wsi
1043+
1044+#endif /* VULKAN_WSI_LAYER_EXPERIMENTAL */
1045diff --git a/wsi/wayland/present_timing_handler.hpp b/wsi/wayland/present_timing_handler.hpp
1046index 4e1c202..343c3ea 100644
1047--- a/wsi/wayland/present_timing_handler.hpp
1048+++ b/wsi/wayland/present_timing_handler.hpp
1049@@ -1,5 +1,5 @@
1050 /*
1051- * Copyright (c) 2025-2026 Arm Limited.
1052+ * Copyright (c) 2025 Arm Limited.
1053 *
1054 * SPDX-License-Identifier: MIT
1055 *
1056@@ -29,6 +29,8 @@
1057 */
1058 #pragma once
1059
1060+#if VULKAN_WSI_LAYER_EXPERIMENTAL
1061+
1062 #include <optional>
1063 #include <array>
1064
1065@@ -176,3 +178,5 @@ private:
1066
1067 } // namespace wayland
1068 } // namespace wsi
1069+
1070+#endif
1071diff --git a/wsi/wayland/surface_properties.cpp b/wsi/wayland/surface_properties.cpp
1072index 72602d1..1dcbf07 100644
1073--- a/wsi/wayland/surface_properties.cpp
1074+++ b/wsi/wayland/surface_properties.cpp
1075@@ -36,7 +36,6 @@
1076 #include <algorithm>
1077 #include <array>
1078 #include <cstring>
1079-#include "present_timing_handler.hpp"
1080 #include "surface_properties.hpp"
1081 #include "surface.hpp"
1082 #include "layer/private_data.hpp"
1083@@ -47,6 +46,10 @@
1084 #include "util/macros.hpp"
1085 #include "util/helpers.hpp"
1086
1087+#if VULKAN_WSI_LAYER_EXPERIMENTAL
1088+#include "present_timing_handler.hpp"
1089+#endif
1090+
1091 namespace wsi
1092 {
1093 namespace wayland
1094@@ -451,6 +454,7 @@ bool surface_properties::is_compatible_present_modes(VkPresentModeKHR present_mo
1095 return m_compatible_present_modes.is_compatible_present_modes(present_mode_a, present_mode_b);
1096 }
1097
1098+#if VULKAN_WSI_LAYER_EXPERIMENTAL
1099 VkResult surface_properties::get_present_timing_surface_caps_internal(
1100 VkPhysicalDevice physical_device, VkPresentTimingSurfaceCapabilitiesEXT *present_timing_surface_caps)
1101 {
1102@@ -499,6 +503,7 @@ VkResult surface_properties::get_present_timing_surface_caps_internal(
1103
1104 return VK_SUCCESS;
1105 }
1106+#endif
1107
1108 } // namespace wayland
1109 } // namespace wsi
1110diff --git a/wsi/wayland/surface_properties.hpp b/wsi/wayland/surface_properties.hpp
1111index 034f567..4953e6d 100644
1112--- a/wsi/wayland/surface_properties.hpp
1113+++ b/wsi/wayland/surface_properties.hpp
1114@@ -1,5 +1,5 @@
1115 /*
1116- * Copyright (c) 2017-2019, 2021-2026 Arm Limited.
1117+ * Copyright (c) 2017-2019, 2021-2025 Arm Limited.
1118 *
1119 * SPDX-License-Identifier: MIT
1120 *
1121@@ -95,8 +95,10 @@ private:
1122
1123 void get_surface_present_scaling_and_gravity(VkSurfacePresentScalingCapabilitiesEXT *scaling_capabilities) override;
1124
1125+#if VULKAN_WSI_LAYER_EXPERIMENTAL
1126 VkResult get_present_timing_surface_caps_internal(
1127 VkPhysicalDevice physical_device, VkPresentTimingSurfaceCapabilitiesEXT *present_timing_surface_caps) override;
1128+#endif
1129 };
1130
1131 } // namespace wayland
1132diff --git a/wsi/wayland/swapchain.cpp b/wsi/wayland/swapchain.cpp
1133index 4346d69..62ce5ce 100644
1134--- a/wsi/wayland/swapchain.cpp
1135+++ b/wsi/wayland/swapchain.cpp
1136@@ -1,5 +1,5 @@
1137 /*
1138- * Copyright (c) 2017-2026 Arm Limited.
1139+ * Copyright (c) 2017-2025 Arm Limited.
1140 *
1141 * SPDX-License-Identifier: MIT
1142 *
1143@@ -123,7 +123,11 @@ VkResult swapchain::add_required_extensions(VkDevice device, const VkSwapchainCr
1144 if (m_device_data.is_present_id_enabled() ||
1145 (swapchain_create_info->flags & VK_SWAPCHAIN_CREATE_PRESENT_ID_2_BIT_KHR))
1146 {
1147+#if VULKAN_WSI_LAYER_EXPERIMENTAL
1148 if (!add_swapchain_extension(m_allocator.make_unique<wsi_ext_present_id_wayland>()))
1149+#else
1150+ if (!add_swapchain_extension(m_allocator.make_unique<wsi_ext_present_id>()))
1151+#endif
1152 {
1153 return VK_ERROR_OUT_OF_HOST_MEMORY;
1154 }
1155@@ -159,6 +163,7 @@ VkResult swapchain::add_required_extensions(VkDevice device, const VkSwapchainCr
1156 }
1157 }
1158
1159+#if VULKAN_WSI_LAYER_EXPERIMENTAL
1160 bool swapchain_support_enabled = swapchain_create_info->flags & VK_SWAPCHAIN_CREATE_PRESENT_TIMING_BIT_EXT;
1161 if (swapchain_support_enabled)
1162 {
1163@@ -182,6 +187,8 @@ VkResult swapchain::add_required_extensions(VkDevice device, const VkSwapchainCr
1164 return VK_ERROR_OUT_OF_HOST_MEMORY;
1165 }
1166 }
1167+#endif
1168+
1169 return VK_SUCCESS;
1170 }
1171
1172@@ -218,12 +225,13 @@ VkResult swapchain::init_platform(VkDevice device, const VkSwapchainCreateInfoKH
1173 {
1174 present_wait->set_wayland_dispatcher(m_display, m_buffer_queue);
1175 }
1176-
1177+#if VULKAN_WSI_LAYER_EXPERIMENTAL
1178 auto *present_timing_ext = get_swapchain_extension<wsi_ext_present_timing_wayland>();
1179 if (present_timing_ext != nullptr)
1180 {
1181 present_timing_ext->init(m_display, m_buffer_queue);
1182 }
1183+#endif
1184
1185 auto wsi_allocator = swapchain_wsialloc_allocator::create();
1186 if (!wsi_allocator.has_value())
1187@@ -296,6 +304,7 @@ void swapchain::release_buffer(struct wl_buffer *wayl_buffer)
1188 auto data = m_swapchain_images[i].get_data<wayland_image_data>();
1189 if (data && data->get_buffer() == wayl_buffer)
1190 {
1191+#if VULKAN_WSI_LAYER_EXPERIMENTAL
1192 /* Some compositors might not deliver wp_presentation_feedback events if the images are pushed to compositor quick enough
1193 * in presentation modes that allow it (mailbox). If that happens, double check if these images were submitted for feedback
1194 * and handle it as a 'image discarded' event. */
1195@@ -309,6 +318,8 @@ void swapchain::release_buffer(struct wl_buffer *wayl_buffer)
1196 {
1197 present_id_ext->mark_buffer_release(i);
1198 }
1199+#endif
1200+
1201 unpresent_image(i);
1202 break;
1203 }
1204@@ -422,6 +433,7 @@ void swapchain::present_image(const pending_present_request &pending_present)
1205 }
1206 }
1207
1208+#if VULKAN_WSI_LAYER_EXPERIMENTAL
1209 auto *present_id_ext = get_swapchain_extension<wsi_ext_present_id_wayland>();
1210 if (present_id_ext != nullptr)
1211 {
1212@@ -462,6 +474,7 @@ void swapchain::present_image(const pending_present_request &pending_present)
1213 register_wp_presentation_feedback_listener(feedback, feedback_obj);
1214 }
1215 }
1216+#endif
1217
1218 wl_surface_commit(m_surface);
1219 int res = wl_display_flush(m_display);
1220@@ -472,14 +485,21 @@ void swapchain::present_image(const pending_present_request &pending_present)
1221 set_error_state(VK_ERROR_SURFACE_LOST_KHR);
1222 }
1223
1224+#if VULKAN_WSI_LAYER_EXPERIMENTAL
1225 auto *ext = get_swapchain_extension<wsi_ext_present_id_wayland>();
1226 if (ext != nullptr)
1227 {
1228 if (m_wsi_surface->get_presentation_time_interface() == nullptr)
1229+#else
1230+ auto *ext = get_swapchain_extension<wsi_ext_present_id>();
1231+ if (ext != nullptr)
1232+#endif
1233 {
1234 ext->mark_delivered(pending_present.present_id);
1235 }
1236+#if VULKAN_WSI_LAYER_EXPERIMENTAL
1237 }
1238+#endif
1239 }
1240
1241 bool swapchain::free_image_found()
1242--
12432.43.0
1244
diff --git a/recipes-graphics/vulkan/vulkan-wsi-layer/0001-wayland-Add-C-guard-before-__STDC_VERSION__-define.patch b/recipes-graphics/vulkan/vulkan-wsi-layer/0001-wayland-Add-C-guard-before-__STDC_VERSION__-define.patch
index ca76a1231..1705f1472 100644
--- a/recipes-graphics/vulkan/vulkan-wsi-layer/0001-wayland-Add-C-guard-before-__STDC_VERSION__-define.patch
+++ b/recipes-graphics/vulkan/vulkan-wsi-layer/0001-wayland-Add-C-guard-before-__STDC_VERSION__-define.patch
@@ -1,4 +1,4 @@
1From aa5d634a607d58f45cc9ccbdc1f80c94685a45a2 Mon Sep 17 00:00:00 2001 1From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
2From: Franz Schnyder <franz.schnyder@toradex.com> 2From: Franz Schnyder <franz.schnyder@toradex.com>
3Date: Wed, 3 Jun 2026 10:00:55 +0200 3Date: Wed, 3 Jun 2026 10:00:55 +0200
4Subject: [PATCH] wayland: Add C++ guard before __STDC_VERSION__ define 4Subject: [PATCH] wayland: Add C++ guard before __STDC_VERSION__ define
@@ -18,7 +18,7 @@ Signed-off-by: Franz Schnyder <franz.schnyder@toradex.com>
18 5 files changed, 14 insertions(+) 18 5 files changed, 14 insertions(+)
19 19
20diff --git a/wsi/wayland/surface.hpp b/wsi/wayland/surface.hpp 20diff --git a/wsi/wayland/surface.hpp b/wsi/wayland/surface.hpp
21index f060f00..92aa598 100644 21index a882782..6557161 100644
22--- a/wsi/wayland/surface.hpp 22--- a/wsi/wayland/surface.hpp
23+++ b/wsi/wayland/surface.hpp 23+++ b/wsi/wayland/surface.hpp
24@@ -28,9 +28,12 @@ 24@@ -28,9 +28,12 @@
@@ -31,11 +31,11 @@ index f060f00..92aa598 100644
31 #endif 31 #endif
32+#endif 32+#endif
33+ 33+
34 #include <sys/types.h>
34 #include <wayland-client.h> 35 #include <wayland-client.h>
35 36
36 #include "wsi/surface.hpp"
37diff --git a/wsi/wayland/surface_properties.cpp b/wsi/wayland/surface_properties.cpp 37diff --git a/wsi/wayland/surface_properties.cpp b/wsi/wayland/surface_properties.cpp
38index e6435b9..caf840d 100644 38index 92faa57..3102a55 100644
39--- a/wsi/wayland/surface_properties.cpp 39--- a/wsi/wayland/surface_properties.cpp
40+++ b/wsi/wayland/surface_properties.cpp 40+++ b/wsi/wayland/surface_properties.cpp
41@@ -24,9 +24,11 @@ 41@@ -24,9 +24,11 @@
@@ -51,10 +51,10 @@ index e6435b9..caf840d 100644
51 #include <wayland-client.h> 51 #include <wayland-client.h>
52 #include <linux-dmabuf-unstable-v1-client-protocol.h> 52 #include <linux-dmabuf-unstable-v1-client-protocol.h>
53diff --git a/wsi/wayland/swapchain.hpp b/wsi/wayland/swapchain.hpp 53diff --git a/wsi/wayland/swapchain.hpp b/wsi/wayland/swapchain.hpp
54index 7667324..95096f8 100644 54index ac645fd..6af628f 100644
55--- a/wsi/wayland/swapchain.hpp 55--- a/wsi/wayland/swapchain.hpp
56+++ b/wsi/wayland/swapchain.hpp 56+++ b/wsi/wayland/swapchain.hpp
57@@ -31,9 +31,12 @@ extern "C" { 57@@ -32,9 +32,12 @@ extern "C" {
58 #include <vulkan/vk_icd.h> 58 #include <vulkan/vk_icd.h>
59 } 59 }
60 60
@@ -66,9 +66,9 @@ index 7667324..95096f8 100644
66+ 66+
67 #include <wayland-client.h> 67 #include <wayland-client.h>
68 #include <linux-dmabuf-unstable-v1-client-protocol.h> 68 #include <linux-dmabuf-unstable-v1-client-protocol.h>
69 #include "util/wsialloc/wsialloc.h" 69 #include "surface.hpp"
70diff --git a/wsi/wayland/wl_helpers.hpp b/wsi/wayland/wl_helpers.hpp 70diff --git a/wsi/wayland/wl_helpers.hpp b/wsi/wayland/wl_helpers.hpp
71index 1f6bad6..2ca131b 100644 71index 5bf507a..28eafbd 100644
72--- a/wsi/wayland/wl_helpers.hpp 72--- a/wsi/wayland/wl_helpers.hpp
73+++ b/wsi/wayland/wl_helpers.hpp 73+++ b/wsi/wayland/wl_helpers.hpp
74@@ -26,9 +26,12 @@ 74@@ -26,9 +26,12 @@
@@ -85,7 +85,7 @@ index 1f6bad6..2ca131b 100644
85 85
86 #include "util/custom_allocator.hpp" 86 #include "util/custom_allocator.hpp"
87diff --git a/wsi/wayland/wl_object_owner.hpp b/wsi/wayland/wl_object_owner.hpp 87diff --git a/wsi/wayland/wl_object_owner.hpp b/wsi/wayland/wl_object_owner.hpp
88index d317e28..564fd5a 100644 88index a3befef..654e1c5 100644
89--- a/wsi/wayland/wl_object_owner.hpp 89--- a/wsi/wayland/wl_object_owner.hpp
90+++ b/wsi/wayland/wl_object_owner.hpp 90+++ b/wsi/wayland/wl_object_owner.hpp
91@@ -24,9 +24,12 @@ 91@@ -24,9 +24,12 @@
@@ -101,6 +101,3 @@ index d317e28..564fd5a 100644
101 #include <wayland-client.h> 101 #include <wayland-client.h>
102 #include <linux-dmabuf-unstable-v1-client-protocol.h> 102 #include <linux-dmabuf-unstable-v1-client-protocol.h>
103 #include <linux-explicit-synchronization-unstable-v1-protocol.h> 103 #include <linux-explicit-synchronization-unstable-v1-protocol.h>
104--
1052.43.0
106
diff --git a/recipes-graphics/vulkan/vulkan-wsi-layer/0002-MGS-6823-nxp-Add-support-of-VK_COMPOSITE_ALPHA_OPAQU.patch b/recipes-graphics/vulkan/vulkan-wsi-layer/0002-MGS-6823-nxp-Add-support-of-VK_COMPOSITE_ALPHA_OPAQU.patch
deleted file mode 100644
index 290946124..000000000
--- a/recipes-graphics/vulkan/vulkan-wsi-layer/0002-MGS-6823-nxp-Add-support-of-VK_COMPOSITE_ALPHA_OPAQU.patch
+++ /dev/null
@@ -1,243 +0,0 @@
1From 4293d8835eaa45168c070793eefd8867c6ec7605 Mon Sep 17 00:00:00 2001
2From: Yuan Tian <yuan.tian@nxp.com>
3Date: Thu, 27 Jul 2023 18:25:16 +0800
4Subject: [PATCH 2/2] MGS-6823 [#nxp] Add support of
5 VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR feature
6
7Mali vulkan driver doesn't support VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR. It caused unwanted blending effect in many vulkan cases.
8Add support of this feature to solve the problem.
9
10Upstream-Status: Inappropriate [embedded specific]
11Signed-off-by: Yuan Tian <yuan.tian@nxp.com>
12Signed-off-by: Jiyu Yang <jiyu.yang@nxp.com>
13---
14 wsi/wayland/swapchain.cpp | 161 ++++++++++++++++++++++++++++++++++++++
15 wsi/wayland/swapchain.hpp | 9 +++
16 2 files changed, 170 insertions(+)
17
18Index: git/wsi/wayland/swapchain.cpp
19===================================================================
20--- git.orig/wsi/wayland/swapchain.cpp
21+++ git/wsi/wayland/swapchain.cpp
22@@ -38,6 +38,7 @@
23 #include <cstdio>
24 #include <climits>
25 #include <functional>
26+#include <poll.h>
27
28 #include "util/drm/drm_utils.hpp"
29 #include "util/log.hpp"
30@@ -72,12 +73,152 @@ swapchain::~swapchain()
31 wsialloc_delete(m_wsi_allocator);
32 }
33 m_wsi_allocator = nullptr;
34+ if (wlc.opaque_region)
35+ {
36+ wl_compositor_destroy(wlc.wl_compositor);
37+ wl_registry_destroy(wlc.registry);
38+ wl_region_destroy(wlc.opaque_region);
39+ wlc = {0};
40+ }
41 if (m_buffer_queue != nullptr)
42 {
43 wl_event_queue_destroy(m_buffer_queue);
44 }
45 }
46
47+static inline int
48+poll_event(struct wl_display *wl_dpy, short int events, int timeout)
49+{
50+ int ret;
51+ struct pollfd pfd[1];
52+
53+ pfd[0].fd = wl_display_get_fd(wl_dpy);
54+ pfd[0].events = events;
55+
56+ do
57+ {
58+ ret = poll(pfd, 1, timeout);
59+ }
60+ while (ret == -1 && errno == EINTR);
61+
62+ return ret;
63+}
64+
65+static int
66+dispatch_queue_op(struct wl_display *wl_dpy,
67+ struct wl_event_queue *wl_queue, int timeout)
68+{
69+ int ret;
70+
71+ if (wl_display_prepare_read_queue(wl_dpy, wl_queue) == -1)
72+ {
73+ return wl_display_dispatch_queue_pending(wl_dpy, wl_queue);
74+ }
75+
76+ for (;;)
77+ {
78+ ret = wl_display_flush(wl_dpy);
79+
80+ if (ret != -1 || errno != EAGAIN)
81+ break;
82+
83+ if (poll_event(wl_dpy, POLLOUT, -1) == -1)
84+ {
85+ wl_display_cancel_read(wl_dpy);
86+ return -1;
87+ }
88+ }
89+
90+ /* Don't stop if flushing hits an EPIPE; continue so we can read any
91+ * protocol error that may have triggered it. */
92+ if (ret < 0 && errno != EPIPE)
93+ {
94+ wl_display_cancel_read(wl_dpy);
95+ return -1;
96+ }
97+
98+ ret = poll_event(wl_dpy, POLLIN, timeout);
99+
100+ /* cancel read when on error or timeout. */
101+ if (ret == -1 || ret == 0)
102+ {
103+ wl_display_cancel_read(wl_dpy);
104+ return ret;
105+ }
106+
107+ if (wl_display_read_events(wl_dpy) == -1)
108+ return -1;
109+
110+ return wl_display_dispatch_queue_pending(wl_dpy, wl_queue);
111+}
112+
113+static void
114+sync_callback(void *data, struct wl_callback *callback, uint32_t serial)
115+{
116+ int *done = (int *)data;
117+
118+ *done = 1;
119+ wl_callback_destroy(callback);
120+}
121+
122+static const struct wl_callback_listener sync_listener = {
123+ sync_callback
124+};
125+
126+static int
127+roundtrip_queue(struct wl_display *wl_dpy, struct wl_event_queue *wl_queue)
128+{
129+ struct wl_callback *callback;
130+ int done, ret = 0;
131+
132+ done = 0;
133+
134+ /*
135+ * This is to block read & dispatch events in other threads, so that the
136+ * callback is with correct queue and listener when 'done' event.
137+ */
138+ while (wl_display_prepare_read_queue(wl_dpy, wl_queue) == -1)
139+ wl_display_dispatch_queue_pending(wl_dpy, wl_queue);
140+
141+ callback = wl_display_sync(wl_dpy);
142+
143+ if (callback == NULL)
144+ {
145+ wl_display_cancel_read(wl_dpy);
146+ return -1;
147+ }
148+
149+ wl_proxy_set_queue((struct wl_proxy *) callback, wl_queue);
150+ wl_callback_add_listener(callback, &sync_listener, &done);
151+
152+ wl_display_cancel_read(wl_dpy);
153+
154+ while (!done && ret >= 0)
155+ ret = dispatch_queue_op(wl_dpy, wl_queue, 5);
156+
157+ if (ret == -1 && !done)
158+ wl_callback_destroy(callback);
159+
160+ return ret;
161+}
162+
163+static void
164+registry_handle_global(void *data, struct wl_registry *registry, uint32_t name,
165+ const char *interface, uint32_t version)
166+{
167+ wl_context *pwlc = (wl_context *)data;
168+
169+ if(!pwlc->wl_compositor)
170+ {
171+ pwlc->wl_compositor = (wl_compositor *)wl_registry_bind(registry, name, &wl_compositor_interface, 1);
172+ wl_proxy_set_queue((struct wl_proxy *)pwlc->wl_compositor, pwlc->wl_queue);
173+ }
174+}
175+
176+static const struct wl_registry_listener registry_listener = {
177+ registry_handle_global
178+};
179+
180 VkResult swapchain::init_platform(VkDevice device, const VkSwapchainCreateInfoKHR *swapchain_create_info,
181 bool &use_presentation_thread)
182 {
183@@ -124,6 +265,21 @@ VkResult swapchain::init_platform(VkDevi
184 use_presentation_thread =
185 WAYLAND_FIFO_PRESENTATION_THREAD_ENABLED && (m_present_mode != VK_PRESENT_MODE_MAILBOX_KHR);
186
187+ if (swapchain_create_info->compositeAlpha & VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR)
188+ {
189+ wlc.wl_queue = m_buffer_queue;
190+ wlc.registry = wl_display_get_registry(m_display);
191+ wl_proxy_set_queue((struct wl_proxy *)(wlc.registry), m_buffer_queue);
192+ wl_registry_add_listener(wlc.registry, &registry_listener, &wlc);
193+
194+ roundtrip_queue(m_display, m_buffer_queue);
195+
196+ wlc.opaque_region = wl_compositor_create_region(wlc.wl_compositor);
197+ wl_proxy_set_queue((struct wl_proxy *)(wlc.opaque_region), m_buffer_queue);
198+
199+ wl_region_add(wlc.opaque_region, 0, 0, swapchain_create_info->imageExtent.width, swapchain_create_info->imageExtent.height);
200+ }
201+
202 return VK_SUCCESS;
203 }
204
205@@ -494,6 +650,11 @@ void swapchain::present_image(const pend
206 set_error_state(VK_ERROR_SURFACE_LOST_KHR);
207 }
208
209+ if (wlc.opaque_region)
210+ {
211+ wl_surface_set_opaque_region(m_surface, wlc.opaque_region);
212+ }
213+
214 wl_surface_attach(m_surface, image_data->buffer, 0, 0);
215
216 auto present_sync_fd = image_data->present_fence.export_sync_fd();
217Index: git/wsi/wayland/swapchain.hpp
218===================================================================
219--- git.orig/wsi/wayland/swapchain.hpp
220+++ git/wsi/wayland/swapchain.hpp
221@@ -78,6 +78,14 @@ struct image_creation_parameters
222 }
223 };
224
225+struct wl_context
226+{
227+ struct wl_event_queue *wl_queue;
228+ struct wl_compositor *wl_compositor;
229+ struct wl_registry *registry;
230+ struct wl_region *opaque_region;
231+};
232+
233 class swapchain : public wsi::swapchain_base
234 {
235 public:
236@@ -190,6 +198,7 @@ private:
237
238 struct wl_display *m_display;
239 struct wl_surface *m_surface;
240+ struct wl_context wlc = {0};
241 /** Raw pointer to the WSI Surface that this swapchain was created from. The Vulkan specification ensures that the
242 * surface is valid until swapchain is destroyed. */
243 surface *m_wsi_surface;
diff --git a/recipes-graphics/vulkan/vulkan-wsi-layer/0002-wsialloc-initialize-local_strides-array.patch b/recipes-graphics/vulkan/vulkan-wsi-layer/0002-wsialloc-initialize-local_strides-array.patch
new file mode 100644
index 000000000..a60dd20d0
--- /dev/null
+++ b/recipes-graphics/vulkan/vulkan-wsi-layer/0002-wsialloc-initialize-local_strides-array.patch
@@ -0,0 +1,32 @@
1From 9486151f7cebe8e093109751c24a2ffcd22d538e Mon Sep 17 00:00:00 2001
2From: Jiyu Yang <jiyu.yang@nxp.com>
3Date: Sat, 25 Jul 2026 06:48:45 +0800
4Subject: [PATCH 2/7] wsialloc: initialize local_strides array
5
6Initialize local_strides to zero to silence GCC
7-Wmaybe-uninitialized warnings and avoid -Werror build
8failures.
9
10Upstream-Status: Pending
11
12Signed-off-by: Jiyu Yang <jiyu.yang@nxp.com>
13---
14 util/wsialloc/wsialloc_helpers.c | 2 +-
15 1 file changed, 1 insertion(+), 1 deletion(-)
16
17diff --git a/util/wsialloc/wsialloc_helpers.c b/util/wsialloc/wsialloc_helpers.c
18index a87c5aa..2e93335 100644
19--- a/util/wsialloc/wsialloc_helpers.c
20+++ b/util/wsialloc/wsialloc_helpers.c
21@@ -137,7 +137,7 @@ wsialloc_error wsiallocp_alloc(wsialloc_allocator *allocator, wsiallocp_alloc_ca
22 return WSIALLOC_ERROR_INVALID;
23 }
24
25- int local_strides[WSIALLOC_MAX_PLANES];
26+ int local_strides[WSIALLOC_MAX_PLANES] = {0};
27 uint32_t local_offsets[WSIALLOC_MAX_PLANES];
28 wsialloc_error err = WSIALLOC_ERROR_NONE;
29 wsialloc_format_descriptor selected_format_desc = {};
30--
312.43.0
32
diff --git a/recipes-graphics/vulkan/vulkan-wsi-layer/0001-MGS-6801-ccc-vkmark-on-wayland.patch b/recipes-graphics/vulkan/vulkan-wsi-layer/0003-MGS-6801-ccc-vkmark-on-wayland.patch
index fb6bb1e17..0d82fb04e 100644
--- a/recipes-graphics/vulkan/vulkan-wsi-layer/0001-MGS-6801-ccc-vkmark-on-wayland.patch
+++ b/recipes-graphics/vulkan/vulkan-wsi-layer/0003-MGS-6801-ccc-vkmark-on-wayland.patch
@@ -1,30 +1,33 @@
1From ada74fb0ca3099f33d173eb664bd7e42025a3277 Mon Sep 17 00:00:00 2001 1From b50f2acc42779130025c0d484f79a8360d289338 Mon Sep 17 00:00:00 2001
2From: Prabhu Sundararaj <prabhu.sundararaj@nxp.com> 2From: Prabhu Sundararaj <prabhu.sundararaj@nxp.com>
3Date: Mon, 9 Dec 2024 09:15:11 +0800 3Date: Mon, 9 Dec 2024 09:15:11 +0800
4Subject: [PATCH 1/2] MGS-6801 [#ccc] vkmark on wayland 4Subject: [PATCH 3/7] MGS-6801 [#ccc] vkmark on wayland
5 5
6Extend the wayland surface properties with VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR 6Extend the wayland surface properties with VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR
7 7
8Upstream-Status: Inappropriate [embedded specific] 8Upstream-Status: Inappropriate [embedded specific]
9
9Signed-off-by: Prabhu Sundararaj <prabhu.sundararaj@nxp.com> 10Signed-off-by: Prabhu Sundararaj <prabhu.sundararaj@nxp.com>
10Signed-off-by: Jiyu Yang <jiyu.yang@nxp.com> 11Signed-off-by: Jiyu Yang <jiyu.yang@nxp.com>
11--- 12---
12 wsi/wayland/surface_properties.cpp | 2 +- 13 wsi/wayland/surface_properties.cpp | 4 ++--
13 1 file changed, 1 insertion(+), 1 deletion(-) 14 1 file changed, 2 insertions(+), 2 deletions(-)
14 15
15diff --git a/wsi/wayland/surface_properties.cpp b/wsi/wayland/surface_properties.cpp 16diff --git a/wsi/wayland/surface_properties.cpp b/wsi/wayland/surface_properties.cpp
16index e6435b9..bc1a737 100644 17index 1dcbf07..92faa57 100644
17--- a/wsi/wayland/surface_properties.cpp 18--- a/wsi/wayland/surface_properties.cpp
18+++ b/wsi/wayland/surface_properties.cpp 19+++ b/wsi/wayland/surface_properties.cpp
19@@ -89,7 +89,7 @@ VkResult surface_properties::get_surface_capabilities(VkPhysicalDevice physical_ 20@@ -94,8 +94,8 @@ VkResult surface_properties::get_surface_capabilities(VkPhysicalDevice physical_
21 get_surface_capabilities_common(physical_device, pSurfaceCapabilities, &override_params);
20 22
21 /* Composite alpha */ 23 /* Composite alpha */
22 pSurfaceCapabilities->supportedCompositeAlpha = static_cast<VkCompositeAlphaFlagBitsKHR>( 24- pSurfaceCapabilities->supportedCompositeAlpha = static_cast<VkCompositeAlphaFlagsKHR>(
23- VK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR | VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR); 25- VK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR | VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR);
26+ pSurfaceCapabilities->supportedCompositeAlpha = static_cast<VkCompositeAlphaFlagBitsKHR>(
24+ VK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR | VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR); 27+ VK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR | VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR);
25 return VK_SUCCESS; 28 return VK_SUCCESS;
26 } 29 }
27 30
28-- 31--
292.37.1 322.43.0
30 33
diff --git a/recipes-graphics/vulkan/vulkan-wsi-layer/0003-Update-minimum-version-of-CMake.patch b/recipes-graphics/vulkan/vulkan-wsi-layer/0003-Update-minimum-version-of-CMake.patch
deleted file mode 100644
index 0bc00de02..000000000
--- a/recipes-graphics/vulkan/vulkan-wsi-layer/0003-Update-minimum-version-of-CMake.patch
+++ /dev/null
@@ -1,32 +0,0 @@
1From 0c4ed8178a25135ced9df8c8a8909e2882bfe869 Mon Sep 17 00:00:00 2001
2From: Maged Elnaggar <maged.elnaggar@arm.com>
3Date: Tue, 17 Jun 2025 10:33:44 +0000
4Subject: [PATCH] Update minimum version of CMake
5
6Set CMake minimum required version range to 3.4.3...4.0
7to silence compatibility errors in CMake 4.0
8by explicitly opting into all policies up to 4.0
9
10Upstream-Status: Backport [https://gitlab.freedesktop.org/mesa/vulkan-wsi-layer/-/commit/1eafebc56a7f735cd4e8298956d596c64ac9f681]
11Signed-off-by: Maged Elnaggar <maged.elnaggar@arm.com>
12Change-Id: I2e0527dde4e764e9c17f519fc0ddd3c0e382fa31
13---
14 CMakeLists.txt | 2 +-
15 1 file changed, 1 insertion(+), 1 deletion(-)
16
17diff --git a/CMakeLists.txt b/CMakeLists.txt
18index 4dc800c..b91cd54 100644
19--- a/CMakeLists.txt
20+++ b/CMakeLists.txt
21@@ -20,7 +20,7 @@
22 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 # SOFTWARE.
24
25-cmake_minimum_required(VERSION 3.4.3)
26+cmake_minimum_required(VERSION 3.4.3...4.0)
27 project(VkLayer_window_system_integration)
28
29 find_package(PkgConfig REQUIRED)
30--
312.34.1
32
diff --git a/recipes-graphics/vulkan/vulkan-wsi-layer/0004-Add-support-VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR.patch b/recipes-graphics/vulkan/vulkan-wsi-layer/0004-Add-support-VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR.patch
new file mode 100644
index 000000000..477ea6453
--- /dev/null
+++ b/recipes-graphics/vulkan/vulkan-wsi-layer/0004-Add-support-VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR.patch
@@ -0,0 +1,155 @@
1From 9ae01fc4d5f2b015568007728dc1bae30ec7880e Mon Sep 17 00:00:00 2001
2From: Yuan Tian <yuan.tian@nxp.com>
3Date: Sat, 25 Jul 2026 14:16:23 +0800
4Subject: [PATCH 4/7] Add support VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR
5
6Mali vulkan driver doesn't support VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR. It
7caused unwanted blending effect in many vulkan cases. Add support of this
8feature to solve the problem.
9
10JIRA#MGS-6823/MGS-6828
11
12Upstream-Status: Pending
13
14Signed-off-by: Yuan Tian <yuan.tian@nxp.com>
15Signed-off-by: Jiyu Yang <jiyu.yang@nxp.com>
16---
17 wsi/wayland/swapchain.cpp | 64 ++++++++++++++++++++++++++++++++++++++-
18 wsi/wayland/swapchain.hpp | 10 ++++++
19 2 files changed, 73 insertions(+), 1 deletion(-)
20
21diff --git a/wsi/wayland/swapchain.cpp b/wsi/wayland/swapchain.cpp
22index 62ce5ce..a6fc962 100644
23--- a/wsi/wayland/swapchain.cpp
24+++ b/wsi/wayland/swapchain.cpp
25@@ -1,5 +1,6 @@
26 /*
27- * Copyright (c) 2017-2025 Arm Limited.
28+ * Copyright (c) 2017-2026 Arm Limited.
29+ * Copyright (c) 2026 NXP
30 *
31 * SPDX-License-Identifier: MIT
32 *
33@@ -112,10 +113,43 @@ swapchain::~swapchain()
34 }
35
36 wl_display_roundtrip_queue(m_display, m_buffer_queue);
37+ if (wlc.opaque_region)
38+ {
39+ wl_region_destroy(wlc.opaque_region);
40+ wl_compositor_destroy(wlc.wl_compositor);
41+ wl_registry_destroy(wlc.registry);
42+ wlc = {};
43+ }
44 wl_event_queue_destroy(m_buffer_queue);
45 }
46 }
47
48+static void
49+registry_handle_global_remove(void * /* data */, struct wl_registry * /* registry */,
50+ uint32_t /* name */)
51+{
52+ /* nothing to do */
53+}
54+
55+static void
56+registry_handle_global(void *data, struct wl_registry *registry, uint32_t name,
57+ const char *interface, uint32_t /* version */)
58+{
59+ wl_context *pwlc = (wl_context *)data;
60+
61+ if (!pwlc->wl_compositor && strcmp(interface, wl_compositor_interface.name) == 0)
62+ {
63+ pwlc->wl_compositor = (struct wl_compositor *)wl_registry_bind(registry, name,
64+ &wl_compositor_interface, 1);
65+ wl_proxy_set_queue((struct wl_proxy *)pwlc->wl_compositor, pwlc->wl_queue);
66+ }
67+}
68+
69+static const struct wl_registry_listener registry_listener = {
70+ registry_handle_global,
71+ registry_handle_global_remove
72+};
73+
74 VkResult swapchain::add_required_extensions(VkDevice device, const VkSwapchainCreateInfoKHR *swapchain_create_info)
75 {
76 UNUSED(device);
77@@ -245,6 +279,30 @@ VkResult swapchain::init_platform(VkDevice device, const VkSwapchainCreateInfoKH
78 return VK_ERROR_OUT_OF_HOST_MEMORY;
79 }
80
81+ if (swapchain_create_info->compositeAlpha & VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR)
82+ {
83+ wlc.wl_queue = m_buffer_queue;
84+ wlc.registry = wl_display_get_registry(m_display);
85+ wl_proxy_set_queue((struct wl_proxy *)wlc.registry, m_buffer_queue);
86+ wl_registry_add_listener(wlc.registry, &registry_listener, &wlc);
87+
88+ wl_display_roundtrip_queue(m_display, m_buffer_queue);
89+
90+ if (wlc.wl_compositor)
91+ {
92+ wlc.opaque_region = wl_compositor_create_region(wlc.wl_compositor);
93+ wl_proxy_set_queue((struct wl_proxy *)wlc.opaque_region, m_buffer_queue);
94+ wl_region_add(wlc.opaque_region, 0, 0,
95+ (int32_t)swapchain_create_info->imageExtent.width,
96+ (int32_t)swapchain_create_info->imageExtent.height);
97+ } else {
98+ WSI_LOG_WARNING("Error adding to pending present feedback list");
99+ wl_registry_destroy(wlc.registry);
100+ wlc = {};
101+ // fallback: continue without opaque
102+ }
103+ }
104+
105 return init_image_factory(*swapchain_create_info);
106 }
107
108@@ -408,6 +466,10 @@ void swapchain::present_image(const pending_present_request &pending_present)
109 set_error_state(VK_ERROR_SURFACE_LOST_KHR);
110 }
111
112+ if (wlc.opaque_region)
113+ {
114+ wl_surface_set_opaque_region(m_surface, wlc.opaque_region);
115+ }
116 wl_surface_attach(m_surface, image_data->get_buffer(), 0, 0);
117
118 auto present_sync_fd = static_cast<sync_fd_fence_sync *>(image.get_present_fence())->export_sync_fd();
119diff --git a/wsi/wayland/swapchain.hpp b/wsi/wayland/swapchain.hpp
120index 5fabb5c..ac645fd 100644
121--- a/wsi/wayland/swapchain.hpp
122+++ b/wsi/wayland/swapchain.hpp
123@@ -1,5 +1,6 @@
124 /*
125 * Copyright (c) 2017-2025 Arm Limited.
126+ * Copyright (c) 2026 NXP
127 *
128 * SPDX-License-Identifier: MIT
129 *
130@@ -51,6 +52,14 @@ namespace wsi
131 namespace wayland
132 {
133
134+struct wl_context
135+{
136+ struct wl_event_queue *wl_queue;
137+ struct wl_compositor *wl_compositor;
138+ struct wl_registry *registry;
139+ struct wl_region *opaque_region;
140+};
141+
142 class swapchain : public wsi::swapchain_base
143 {
144 public:
145@@ -156,6 +165,7 @@ private:
146 const VkSwapchainCreateInfoKHR &swapchain_create_info);
147
148 struct wl_display *m_display;
149+ struct wl_context wlc{};
150 struct wl_surface *m_surface;
151 /** Raw pointer to the WSI Surface that this swapchain was created from. The Vulkan specification ensures that the
152 * surface is valid until swapchain is destroyed. */
153--
1542.43.0
155
diff --git a/recipes-graphics/vulkan/vulkan-wsi-layer/0005-MGS-7487-nxp-fix-Vulkan-test-report-warning-msg.patch b/recipes-graphics/vulkan/vulkan-wsi-layer/0005-MGS-7487-nxp-fix-Vulkan-test-report-warning-msg.patch
new file mode 100644
index 000000000..c553f42e6
--- /dev/null
+++ b/recipes-graphics/vulkan/vulkan-wsi-layer/0005-MGS-7487-nxp-fix-Vulkan-test-report-warning-msg.patch
@@ -0,0 +1,53 @@
1From dd35a08cb11eccf49e6cca8fd0a1d8d4af3cf4bb Mon Sep 17 00:00:00 2001
2From: Yuan Tian <yuan.tian@nxp.com>
3Date: Thu, 23 Nov 2023 01:55:05 +0800
4Subject: [PATCH 5/7] MGS-7487 [#nxp] fix Vulkan test report warning msg
5
6destroy wl_compositor and wl_registry attached to opaque region for VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR to fix warnings.
7
8warning: queue 0xaaaaa6940 destroyed while proxies still attached:
9wl_compositor@18 still attached
10wl_registry@16 still attached
11
12Upstream-Status: Pending
13
14Signed-off-by: Yuan Tian <yuan.tian@nxp.com>
15---
16 wsi/wayland/swapchain.cpp | 14 +++++++-------
17 1 file changed, 7 insertions(+), 7 deletions(-)
18
19diff --git a/wsi/wayland/swapchain.cpp b/wsi/wayland/swapchain.cpp
20index a6fc962..a92e6c5 100644
21--- a/wsi/wayland/swapchain.cpp
22+++ b/wsi/wayland/swapchain.cpp
23@@ -101,6 +101,13 @@ swapchain::~swapchain()
24 {
25 teardown();
26
27+ if (wlc.opaque_region)
28+ {
29+ wl_compositor_destroy(wlc.wl_compositor);
30+ wl_registry_destroy(wlc.registry);
31+ wl_region_destroy(wlc.opaque_region);
32+ wlc = {};
33+ }
34 if (m_buffer_queue != nullptr)
35 {
36 for (auto &img : m_swapchain_images)
37@@ -113,13 +120,6 @@ swapchain::~swapchain()
38 }
39
40 wl_display_roundtrip_queue(m_display, m_buffer_queue);
41- if (wlc.opaque_region)
42- {
43- wl_region_destroy(wlc.opaque_region);
44- wl_compositor_destroy(wlc.wl_compositor);
45- wl_registry_destroy(wlc.registry);
46- wlc = {};
47- }
48 wl_event_queue_destroy(m_buffer_queue);
49 }
50 }
51--
522.43.0
53
diff --git a/recipes-graphics/vulkan/vulkan-wsi-layer/0006-MGS-9060-mali-fix-swapchainMaintenance1-incorrectly-.patch b/recipes-graphics/vulkan/vulkan-wsi-layer/0006-MGS-9060-mali-fix-swapchainMaintenance1-incorrectly-.patch
new file mode 100644
index 000000000..e2fd23c9e
--- /dev/null
+++ b/recipes-graphics/vulkan/vulkan-wsi-layer/0006-MGS-9060-mali-fix-swapchainMaintenance1-incorrectly-.patch
@@ -0,0 +1,55 @@
1From 0079f524f444725d997a65e965c11d715c02099e Mon Sep 17 00:00:00 2001
2From: Prabhu Sundararaj <prabhu.sundararaj@nxp.com>
3Date: Wed, 29 Jul 2026 21:38:59 -0500
4Subject: [PATCH 6/7] MGS-9060 [#mali] fix swapchainMaintenance1 incorrectly
5 reported as unsupported
6
7When VK_KHR_display is enabled alongside a supported surface extension
8(e.g. VK_KHR_wayland_surface), set_swapchain_maintenance1_state()
9unconditionally sets swapchainMaintenance1 to false because display
10WSI does not support it. This causes CTS failures:
11- dEQP-VK.info.device_mandatory_features reports swapchainMaintenance1
12 as not supported, violating the spec requirement that the feature
13 must be VK_TRUE when VK_KHR_swapchain_maintenance1 is advertised.
14- dEQP-VK.api.device_init.create_device_unsupported_features.
15 swapchain_maintenance1_features_khr fails because driver does not
16 reject enabling an unsupported feature.
17
18vulkaninfo enables both VK_KHR_display and VK_KHR_wayland_surface as
19instance extensions. The original code disables swapchainMaintenance1
20whenever VK_KHR_display is present, even if a supported surface
21(wayland/headless) is also enabled.
22
23Fix: Only disable swapchainMaintenance1 when VK_KHR_display is the
24only surface type enabled, allowing wayland and headless paths to
25correctly report the feature as supported.
26
27Upstream-Status: Pending
28
29Signed-off-by: Prabhu Sundararaj <prabhu.sundararaj@nxp.com>
30---
31 wsi/wsi_factory.cpp | 7 +++++--
32 1 file changed, 5 insertions(+), 2 deletions(-)
33
34diff --git a/wsi/wsi_factory.cpp b/wsi/wsi_factory.cpp
35index f281b8a..f33362e 100644
36--- a/wsi/wsi_factory.cpp
37+++ b/wsi/wsi_factory.cpp
38@@ -294,9 +294,12 @@ void set_swapchain_maintenance1_state(VkPhysicalDevice physicalDevice,
39 if (swapchain_maintenance1_features != nullptr)
40 {
41 auto &instance = layer::instance_private_data::get(physicalDevice);
42- if (instance.is_instance_extension_enabled(VK_KHR_DISPLAY_EXTENSION_NAME))
43+ if (instance.is_instance_extension_enabled(VK_KHR_DISPLAY_EXTENSION_NAME) &&
44+ !instance.is_instance_extension_enabled("VK_KHR_wayland_surface") &&
45+ !instance.is_instance_extension_enabled("VK_EXT_headless_surface"))
46 {
47- /* Display WSI does not support swapchain maintenance1. */
48+ /* Display WSI does not support swapchain maintenance1, but only
49+ * disable it when display is the only surface type enabled. */
50 swapchain_maintenance1_features->swapchainMaintenance1 = false;
51 return;
52 }
53--
542.43.0
55
diff --git a/recipes-graphics/vulkan/vulkan-wsi-layer/0007-MGS-6283-nxp-fix-segfault-in-opaque-alpha-init-on-OO.patch b/recipes-graphics/vulkan/vulkan-wsi-layer/0007-MGS-6283-nxp-fix-segfault-in-opaque-alpha-init-on-OO.patch
new file mode 100644
index 000000000..db92e1784
--- /dev/null
+++ b/recipes-graphics/vulkan/vulkan-wsi-layer/0007-MGS-6283-nxp-fix-segfault-in-opaque-alpha-init-on-OO.patch
@@ -0,0 +1,79 @@
1From 14b398d9ff968f0638e540bdf903fc524db108f4 Mon Sep 17 00:00:00 2001
2From: Ryan Zhang <ryan.zhang@nxp.com>
3Date: Fri, 31 Jul 2026 14:08:58 +0800
4Subject: [PATCH 7/7] MGS-6283 [#nxp] fix segfault in opaque alpha init on OOM
5 or missing compositor
6
7The opaque region setup code added by MGS-6283 does not check for
8NULL returns from wl_display_get_registry, wl_registry_bind (via
9roundtrip callback), or wl_compositor_create_region. When any of
10these fail (e.g. during simulate_oom tests), subsequent calls on
11NULL pointers cause a segfault in wl_proxy_get_version.
12
13Add NULL checks for wlc.registry, wlc.wl_compositor, and
14wlc.opaque_region. On failure, clean up any partially created
15objects and return VK_SUCCESS to allow the swapchain to proceed
16without opaque region support.
17
18Fixes: dEQP-VK.wsi.wayland.swapchain.simulate_oom.*
19
20Upstream-Status: Inappropriate [embedded specific]
21
22Signed-off-by: Prabhu Sundararaj <prabhu.sundararaj@nxp.com>
23---
24 wsi/wayland/swapchain.cpp | 31 +++++++++++++++++++++----------
25 1 file changed, 21 insertions(+), 10 deletions(-)
26
27diff --git a/wsi/wayland/swapchain.cpp b/wsi/wayland/swapchain.cpp
28index a92e6c5..5face8e 100644
29--- a/wsi/wayland/swapchain.cpp
30+++ b/wsi/wayland/swapchain.cpp
31@@ -283,24 +283,35 @@ VkResult swapchain::init_platform(VkDevice device, const VkSwapchainCreateInfoKH
32 {
33 wlc.wl_queue = m_buffer_queue;
34 wlc.registry = wl_display_get_registry(m_display);
35+ if (wlc.registry == nullptr)
36+ {
37+ return VK_SUCCESS;
38+ }
39 wl_proxy_set_queue((struct wl_proxy *)wlc.registry, m_buffer_queue);
40 wl_registry_add_listener(wlc.registry, &registry_listener, &wlc);
41
42 wl_display_roundtrip_queue(m_display, m_buffer_queue);
43
44- if (wlc.wl_compositor)
45+ if (wlc.wl_compositor == nullptr)
46+ {
47+ wl_registry_destroy(wlc.registry);
48+ wlc.registry = nullptr;
49+ return VK_SUCCESS;
50+ }
51+
52+ wlc.opaque_region = wl_compositor_create_region(wlc.wl_compositor);
53+ if (wlc.opaque_region == nullptr)
54 {
55- wlc.opaque_region = wl_compositor_create_region(wlc.wl_compositor);
56- wl_proxy_set_queue((struct wl_proxy *)wlc.opaque_region, m_buffer_queue);
57- wl_region_add(wlc.opaque_region, 0, 0,
58- (int32_t)swapchain_create_info->imageExtent.width,
59- (int32_t)swapchain_create_info->imageExtent.height);
60- } else {
61- WSI_LOG_WARNING("Error adding to pending present feedback list");
62+ wl_compositor_destroy(wlc.wl_compositor);
63+ wlc.wl_compositor = nullptr;
64 wl_registry_destroy(wlc.registry);
65- wlc = {};
66- // fallback: continue without opaque
67+ wlc.registry = nullptr;
68+ return VK_SUCCESS;
69 }
70+ wl_proxy_set_queue((struct wl_proxy *)wlc.opaque_region, m_buffer_queue);
71+ wl_region_add(wlc.opaque_region, 0, 0,
72+ (int32_t)swapchain_create_info->imageExtent.width,
73+ (int32_t)swapchain_create_info->imageExtent.height);
74 }
75
76 return init_image_factory(*swapchain_create_info);
77--
782.43.0
79
diff --git a/recipes-graphics/vulkan/vulkan-wsi-layer_git.bb b/recipes-graphics/vulkan/vulkan-wsi-layer_git.bb
index 0bbebf5c2..92009ed60 100644
--- a/recipes-graphics/vulkan/vulkan-wsi-layer_git.bb
+++ b/recipes-graphics/vulkan/vulkan-wsi-layer_git.bb
@@ -9,11 +9,15 @@ DEPENDS = "libdrm vulkan-loader"
9PV = "0.0+git${SRCPV}" 9PV = "0.0+git${SRCPV}"
10 10
11SRC_URI = "git://gitlab.freedesktop.org/mesa/vulkan-wsi-layer.git;protocol=https;branch=main \ 11SRC_URI = "git://gitlab.freedesktop.org/mesa/vulkan-wsi-layer.git;protocol=https;branch=main \
12 file://0001-MGS-6801-ccc-vkmark-on-wayland.patch \ 12 file://0001-MGS-9070-add-arm-r56p0-wsi-layer-changes.patch \
13 file://0002-MGS-6823-nxp-Add-support-of-VK_COMPOSITE_ALPHA_OPAQU.patch \ 13 file://0002-wsialloc-initialize-local_strides-array.patch \
14 file://0003-Update-minimum-version-of-CMake.patch \ 14 file://0003-MGS-6801-ccc-vkmark-on-wayland.patch \
15 file://0004-Add-support-VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR.patch \
16 file://0005-MGS-7487-nxp-fix-Vulkan-test-report-warning-msg.patch \
17 file://0006-MGS-9060-mali-fix-swapchainMaintenance1-incorrectly-.patch \
18 file://0007-MGS-6283-nxp-fix-segfault-in-opaque-alpha-init-on-OO.patch \
15 file://0001-wayland-Add-C-guard-before-__STDC_VERSION__-define.patch" 19 file://0001-wayland-Add-C-guard-before-__STDC_VERSION__-define.patch"
16SRCREV = "cb1a50cf7e640ad7306e673131ded98c0f133628" 20SRCREV = "c4993dd16baf288c4b696e56ecf7cd03839a6f8b"
17 21
18REQUIRED_DISTRO_FEATURES = "vulkan" 22REQUIRED_DISTRO_FEATURES = "vulkan"
19 23