···268268{
269269 struct xrt_system_compositor_info *sys_info = &c->sys_info;
270270271271- // Required by OpenXR spec.
271271+ /*
272272+ * Required by OpenXR spec (minimum 16).
273273+ *
274274+ * NOTE: When using Vulkan compositor components (c/render, c/util),
275275+ * call render_max_layers_capable() to clamp this value based on
276276+ * actual device limits.
277277+ */
272278 sys_info->max_layers = XRT_MAX_LAYERS;
273279274280 uint32_t view_count = xdev->hmd->view_count;
+18
src/xrt/compositor/render/render_interface.h
···9393//! The binding that the shared layer fragment shader has its source on.
9494#define RENDER_BINDING_LAYER_SHARED_SRC 1
95959696+/*!
9797+ * The maximum number samplers per view that can be used by the compute shader
9898+ * for layer composition (layer.comp)
9999+ */
100100+#define RENDER_CS_MAX_SAMPLERS_PER_VIEW 2
9610197102/*
98103 *
99104 * Util functions.
100105 *
101106 */
107107+108108+/*!
109109+ * Determines the maximum number of compositor layers supported based on Vulkan
110110+ * device limits and the composition path being used.
111111+ *
112112+ * @param vk Vulkan bundle containing device properties
113113+ * @param use_compute True if using compute pipeline path, false for graphics
114114+ * @param desired_max_layers Maximum layers requested by the compositor
115115+ * @return Actual maximum layers supported, clamped by device limits (minimum 16)
116116+ *
117117+ */
118118+uint32_t
119119+render_max_layers_capable(const struct vk_bundle *vk, bool use_compute, uint32_t desired_max_layers);
102120103121/*!
104122 * Create a simplified projection matrix for timewarp.
+49
src/xrt/compositor/render/render_util.c
···8787 *
8888 */
89899090+uint32_t
9191+render_max_layers_capable(const struct vk_bundle *vk, bool use_compute, uint32_t desired_max_layers)
9292+{
9393+ /*!
9494+ * Graphics pipeline:
9595+ *
9696+ * This path has no relevant Vulkan device limits that would
9797+ * constrain the maximum number of layers (each layer uses a single descriptor
9898+ * set bound individually per draw).
9999+ */
100100+ if (!use_compute) {
101101+ // The min required by OpenXR spec is 16.
102102+ return MAX(desired_max_layers, 16);
103103+ }
104104+105105+ /*!
106106+ * Compute pipeline:
107107+ *
108108+ * Clamp max layers based on compute pipeline descriptor limits.
109109+ *
110110+ * The compute path uses an array of combined image samplers, with
111111+ * @ref samplers_per_layer samplers needed per layer. We check both the
112112+ * per-stage sampler and sampled image limits, then calculate the
113113+ * maximum number of complete layers that fit within those limits.
114114+ */
115115+ uint32_t desired_image_sampler_count = desired_max_layers * RENDER_CS_MAX_SAMPLERS_PER_VIEW;
116116+117117+ const uint32_t max_sizes[] = {
118118+ vk->limits.max_per_stage_descriptor_samplers,
119119+ vk->limits.max_per_stage_descriptor_sampled_images,
120120+ };
121121+ for (uint32_t i = 0; i < ARRAY_SIZE(max_sizes); ++i) {
122122+ desired_image_sampler_count = MIN(desired_image_sampler_count, max_sizes[i]);
123123+ }
124124+125125+ const uint32_t calculated_max_layers = desired_image_sampler_count / RENDER_CS_MAX_SAMPLERS_PER_VIEW;
126126+127127+ if (calculated_max_layers < 16) {
128128+ VK_WARN(vk,
129129+ "Device supports only %u compositor layers due to Vulkan limits. "
130130+ "which is below Vulkan minimum of 16. "
131131+ "This may indicate a driver bug. Attempting 16 anyway.",
132132+ calculated_max_layers);
133133+ }
134134+135135+ // The min required by OpenXR spec is 16.
136136+ return MAX(calculated_max_layers, 16);
137137+}
138138+90139void
91140render_calc_time_warp_matrix(const struct xrt_pose *src_pose,
92141 const struct xrt_fov *src_fov,
+7-1
src/xrt/targets/sdl_test/sdl_compositor.c
···256256{
257257 struct xrt_system_compositor_info *sys_info = &c->sys_info;
258258259259- // Required by OpenXR spec.
259259+ /*
260260+ * Required by OpenXR spec (minimum 16).
261261+ *
262262+ * NOTE: When using Vulkan compositor components (c/render, c/util),
263263+ * call render_max_layers_capable() to clamp this value based on
264264+ * actual device limits.
265265+ */
260266 sys_info->max_layers = XRT_MAX_LAYERS;
261267262268 // UUIDs and LUID already set in vk init.