public inbox for git-commits@fedoraproject.org
help / color / mirror / Atom feed
* [rpms/wivrn] f44: Update to 26.6 (fedora#2487858).
@ 2026-06-11 15:15 Jonathan Steffan
  0 siblings, 0 replies; only message in thread
From: Jonathan Steffan @ 2026-06-11 15:15 UTC (permalink / raw)
  To: git-commits

A new commit has been pushed.

Repo   : rpms/wivrn
Branch : f44
Commit : 078b99f733a96dff9adfcf5f13d28142f61113e4
Author : Jonathan Steffan <jsteffan@fedoraproject.org>
Date   : 2026-06-11T09:02:10-06:00
Stats  : +166/-1833 in 16 file(s)
URL    : https://src.fedoraproject.org/rpms/wivrn/c/078b99f733a96dff9adfcf5f13d28142f61113e4?branch=f44

Log:
Update to 26.6 (fedora#2487858).

---
diff --git a/.gitignore b/.gitignore
index b3f28c1..bce0361 100644
--- a/.gitignore
+++ b/.gitignore
@@ -26,3 +26,5 @@
 /monado-src-723652b545a79609f9f04cb89fcbf807d9d6451a.tar.bz2
 /WiVRn-26.2.2.tar.gz
 /WiVRn-v26.2.3.tar.gz
+/WiVRn-v26.6.tar.gz
+/monado-src-1b526bb3a0ff326ecd05af4c2c541407f53c6d4b.tar.bz2

diff --git a/0001-c-multi-early-wake-of-compositor.patch b/0001-c-multi-early-wake-of-compositor.patch
index dae3788..03cb41e 100644
--- a/0001-c-multi-early-wake-of-compositor.patch
+++ b/0001-c-multi-early-wake-of-compositor.patch
@@ -1,4 +1,4 @@
-From 2884795b7d352e3e45348473a17660a568260d6e Mon Sep 17 00:00:00 2001
+From de3b592fc26d7b26b4850fcc78d7e6b21147f76b Mon Sep 17 00:00:00 2001
 From: Patrick Nicolas <patricknicolas@laposte.net>
 Date: Tue, 22 Oct 2024 15:23:19 +0200
 Subject: [PATCH 1/8] c/multi: early wake of compositor
@@ -10,7 +10,7 @@ Subject: [PATCH 1/8] c/multi: early wake of compositor
  3 files changed, 41 insertions(+), 7 deletions(-)
 
 diff --git a/src/xrt/compositor/multi/comp_multi_compositor.c b/src/xrt/compositor/multi/comp_multi_compositor.c
-index 94cea110e..88347a092 100644
+index 33675d43f..71c5ebf9e 100644
 --- a/src/xrt/compositor/multi/comp_multi_compositor.c
 +++ b/src/xrt/compositor/multi/comp_multi_compositor.c
 @@ -236,7 +236,21 @@ wait_for_scheduled_free(struct multi_compositor *mc)
@@ -36,10 +36,10 @@ index 94cea110e..88347a092 100644
  
  static void *
 diff --git a/src/xrt/compositor/multi/comp_multi_private.h b/src/xrt/compositor/multi/comp_multi_private.h
-index 3351defa4..e8f0c8295 100644
+index 6c7ec05f8..588878e38 100644
 --- a/src/xrt/compositor/multi/comp_multi_private.h
 +++ b/src/xrt/compositor/multi/comp_multi_private.h
-@@ -359,6 +359,10 @@ struct multi_system_compositor
+@@ -365,6 +365,10 @@ struct multi_system_compositor
  	 */
  	struct os_mutex list_and_timing_lock;
  
@@ -51,19 +51,19 @@ index 3351defa4..e8f0c8295 100644
  	{
  		int64_t predicted_display_time_ns;
 diff --git a/src/xrt/compositor/multi/comp_multi_system.c b/src/xrt/compositor/multi/comp_multi_system.c
-index 4db923457..80cbbbc26 100644
+index 5a4f35b81..cbda39c24 100644
 --- a/src/xrt/compositor/multi/comp_multi_system.c
 +++ b/src/xrt/compositor/multi/comp_multi_system.c
-@@ -24,6 +24,8 @@
- #include "util/u_trace_marker.h"
- #include "util/u_distortion_mesh.h"
+@@ -14,6 +14,8 @@
+ #include "xrt/xrt_defines.h"
+ #include "xrt/xrt_session.h"
  
 +#include "math/m_api.h"
 +
- #ifdef XRT_OS_LINUX
- #include "util/u_linux.h"
- #endif
-@@ -393,17 +395,24 @@ broadcast_timings_to_pacers(struct multi_system_compositor *msc,
+ #include "os/os_time.h"
+ #include "os/os_threading.h"
+ 
+@@ -426,17 +428,24 @@ broadcast_timings_to_pacers(struct multi_system_compositor *msc,
  }
  
  static void
@@ -93,7 +93,7 @@ index 4db923457..80cbbbc26 100644
  }
  
  static void
-@@ -530,10 +539,13 @@ multi_main_loop(struct multi_system_compositor *msc)
+@@ -562,10 +571,13 @@ multi_main_loop(struct multi_system_compositor *msc)
  		broadcast_timings_to_clients(msc, predicted_display_time_ns);
  
  		// Now we can wait.
@@ -109,7 +109,7 @@ index 4db923457..80cbbbc26 100644
  
  		// Now we know the diff, broadcast to pacers.
  		broadcast_timings_to_pacers(msc, predicted_display_time_ns, predicted_display_period_ns, diff_ns);
-@@ -721,6 +733,8 @@ system_compositor_destroy(struct xrt_system_compositor *xsc)
+@@ -785,6 +797,8 @@ system_compositor_destroy(struct xrt_system_compositor *xsc)
  	xrt_comp_native_destroy(&msc->xcn);
  
  	os_mutex_destroy(&msc->list_and_timing_lock);
@@ -118,8 +118,8 @@ index 4db923457..80cbbbc26 100644
  
  	free(msc);
  }
-@@ -775,6 +789,8 @@ comp_multi_create_system_compositor(struct xrt_compositor_native *xcn,
- 	msc->sessions.state = do_warm_start ? MULTI_SYSTEM_STATE_INIT_WARM_START : MULTI_SYSTEM_STATE_STOPPED;
+@@ -843,6 +857,8 @@ comp_multi_create_system_compositor(struct xrt_compositor_native *xcn,
+ 	msc->get_view_config_callback = get_view_config_callback;
  
  	os_mutex_init(&msc->list_and_timing_lock);
 +	os_mutex_init(&msc->wake_mutex);
@@ -128,5 +128,5 @@ index 4db923457..80cbbbc26 100644
  	//! @todo Make the clients not go from IDLE to READY before we have completed a first frame.
  	// Make sure there is at least some sort of valid frame data here.
 -- 
-2.53.0
+2.54.0
 

diff --git a/0002-Use-extern-socket-fd.patch b/0002-Use-extern-socket-fd.patch
index de6ac4a..8f507e1 100644
--- a/0002-Use-extern-socket-fd.patch
+++ b/0002-Use-extern-socket-fd.patch
@@ -1,4 +1,4 @@
-From 8d22720c9574146f7115f5ba7ac39f3c4e4f48ae Mon Sep 17 00:00:00 2001
+From 22d9bf87e9dd6a0d5970258a6b6cd6ca82c3bb26 Mon Sep 17 00:00:00 2001
 From: Patrick Nicolas <patricknicolas@laposte.net>
 Date: Tue, 8 Oct 2024 22:13:15 +0200
 Subject: [PATCH 2/8] Use extern socket fd
@@ -8,10 +8,10 @@ Subject: [PATCH 2/8] Use extern socket fd
  1 file changed, 8 insertions(+)
 
 diff --git a/src/xrt/ipc/server/ipc_server_mainloop_linux.c b/src/xrt/ipc/server/ipc_server_mainloop_linux.c
-index 36bf3e31d..e40447bb2 100644
+index a0bef3dde..453dd38ca 100644
 --- a/src/xrt/ipc/server/ipc_server_mainloop_linux.c
 +++ b/src/xrt/ipc/server/ipc_server_mainloop_linux.c
-@@ -48,6 +48,8 @@
+@@ -50,6 +50,8 @@
  #endif
  
  
@@ -20,7 +20,7 @@ index 36bf3e31d..e40447bb2 100644
  /*
   *
   * Static functions.
-@@ -56,6 +58,12 @@
+@@ -58,6 +60,12 @@
  static int
  get_systemd_socket(struct ipc_server_mainloop *ml, int *out_fd)
  {
@@ -34,5 +34,5 @@ index 36bf3e31d..e40447bb2 100644
  	// We may have been launched with socket activation
  	int num_fds = sd_listen_fds(0);
 -- 
-2.53.0
+2.54.0
 

diff --git a/0003-change-environment-blend-mode-selection-logic.patch b/0003-change-environment-blend-mode-selection-logic.patch
index 487fffb..2529eaa 100644
--- a/0003-change-environment-blend-mode-selection-logic.patch
+++ b/0003-change-environment-blend-mode-selection-logic.patch
@@ -1,4 +1,4 @@
-From dc8c6b0fdd002631827528b0cd831e762cf74c31 Mon Sep 17 00:00:00 2001
+From 3c7450d800b0e3f35440f41d3bfcf5b5abe6dfe8 Mon Sep 17 00:00:00 2001
 From: galister <85970-galister@users.noreply.gitlab.freedesktop.org>
 Date: Sat, 23 Nov 2024 02:42:12 +0900
 Subject: [PATCH 3/8] change environment blend mode selection logic
@@ -8,10 +8,10 @@ Subject: [PATCH 3/8] change environment blend mode selection logic
  1 file changed, 17 insertions(+), 9 deletions(-)
 
 diff --git a/src/xrt/compositor/multi/comp_multi_system.c b/src/xrt/compositor/multi/comp_multi_system.c
-index 80cbbbc26..4a397d7ec 100644
+index cbda39c24..c0c6c9f60 100644
 --- a/src/xrt/compositor/multi/comp_multi_system.c
 +++ b/src/xrt/compositor/multi/comp_multi_system.c
-@@ -233,23 +233,31 @@ find_active_blend_mode(struct multi_compositor **overlay_sorted_clients, size_t
+@@ -231,23 +231,31 @@ find_active_blend_mode(struct multi_compositor **overlay_sorted_clients, size_t
  	if (overlay_sorted_clients == NULL)
  		return XRT_BLEND_MODE_OPAQUE;
  
@@ -53,5 +53,5 @@ index 80cbbbc26..4a397d7ec 100644
  }
  
 -- 
-2.53.0
+2.54.0
 

diff --git a/0004-st-oxr-forward-0-refresh-rate.patch b/0004-st-oxr-forward-0-refresh-rate.patch
index b997ae4..6a4fecf 100644
--- a/0004-st-oxr-forward-0-refresh-rate.patch
+++ b/0004-st-oxr-forward-0-refresh-rate.patch
@@ -1,4 +1,4 @@
-From f4b4c07740dcc58438340171ec473570b002b379 Mon Sep 17 00:00:00 2001
+From b26876c29205f2d2fb07fbdbe009d5635eb32bfd Mon Sep 17 00:00:00 2001
 From: Patrick Nicolas <patricknicolas@laposte.net>
 Date: Sat, 15 Mar 2025 22:19:48 +0100
 Subject: [PATCH 4/8] st/oxr: forward 0 refresh rate
@@ -9,10 +9,10 @@ Subject: [PATCH 4/8] st/oxr: forward 0 refresh rate
  2 files changed, 2 insertions(+), 6 deletions(-)
 
 diff --git a/src/xrt/compositor/main/comp_compositor.c b/src/xrt/compositor/main/comp_compositor.c
-index b6c4947bf..0e8ed02b7 100644
+index b44271622..a1e112e89 100644
 --- a/src/xrt/compositor/main/comp_compositor.c
 +++ b/src/xrt/compositor/main/comp_compositor.c
-@@ -372,7 +372,7 @@ compositor_request_display_refresh_rate(struct xrt_compositor *xc, float display
+@@ -391,7 +391,7 @@ compositor_request_display_refresh_rate(struct xrt_compositor *xc, float display
  	if (c->target && c->target->request_refresh_rate) {
  		xrt_result_t result = comp_target_request_refresh_rate(c->target, display_refresh_rate_hz);
  		// Assume refresh rate change is immediate
@@ -22,7 +22,7 @@ index b6c4947bf..0e8ed02b7 100644
  		return result;
  	}
 diff --git a/src/xrt/state_trackers/oxr/oxr_api_session.c b/src/xrt/state_trackers/oxr/oxr_api_session.c
-index 587cdf28f..b1f96df54 100644
+index 09297f885..9f3a7ebc2 100644
 --- a/src/xrt/state_trackers/oxr/oxr_api_session.c
 +++ b/src/xrt/state_trackers/oxr/oxr_api_session.c
 @@ -455,15 +455,11 @@ oxr_xrRequestDisplayRefreshRateFB(XrSession session, float displayRefreshRate)
@@ -43,5 +43,5 @@ index 587cdf28f..b1f96df54 100644
  		if ((int)(displayRefreshRate * 100.0f) == (int)(sess->sys->xsysc->info.refresh_rates_hz[i] * 100.0f)) {
  			found = true;
 -- 
-2.53.0
+2.54.0
 

diff --git a/0005-Replace-distortion-with-foveation.patch b/0005-Replace-distortion-with-foveation.patch
deleted file mode 100644
index f2ed3ba..0000000
--- a/0005-Replace-distortion-with-foveation.patch
+++ /dev/null
@@ -1,1644 +0,0 @@
-From 73f329eaba1e46bf62ff6579e27cd39f0d9e6730 Mon Sep 17 00:00:00 2001
-From: Patrick Nicolas <patricknicolas@laposte.net>
-Date: Wed, 11 Sep 2024 22:56:29 +0200
-Subject: [PATCH 5/8] Replace distortion with foveation
-
----
- src/xrt/compositor/main/comp_renderer.c       |   6 +-
- src/xrt/compositor/main/comp_target.h         |   3 +-
- src/xrt/compositor/render/CMakeLists.txt      |   2 +-
- src/xrt/compositor/render/render_compute.c    | 410 +++++++-----------
- src/xrt/compositor/render/render_interface.h  |  95 ++--
- src/xrt/compositor/render/render_resources.c  | 106 ++---
- src/xrt/compositor/shaders/CMakeLists.txt     |   2 +-
- src/xrt/compositor/shaders/clear.comp         |   4 +-
- src/xrt/compositor/shaders/distortion.comp    | 182 ++++----
- .../compositor/util/comp_high_level_render.c  |   6 +-
- .../compositor/util/comp_high_level_render.h  |   9 +-
- src/xrt/compositor/util/comp_render.h         |  11 +-
- src/xrt/compositor/util/comp_render_cs.c      | 112 ++---
- 13 files changed, 356 insertions(+), 592 deletions(-)
-
-diff --git a/src/xrt/compositor/main/comp_renderer.c b/src/xrt/compositor/main/comp_renderer.c
-index f6c403015..ff9728a59 100644
---- a/src/xrt/compositor/main/comp_renderer.c
-+++ b/src/xrt/compositor/main/comp_renderer.c
-@@ -983,7 +983,8 @@ dispatch_compute(struct comp_renderer *r,
- 
- 	// Target Vulkan resources..
- 	VkImage target_image = r->c->target->images[r->acquired_buffer].handle;
--	VkImageView target_storage_view = r->c->target->images[r->acquired_buffer].view;
-+	VkImageView target_storage_view_y = r->c->target->images[r->acquired_buffer].view;
-+	VkImageView target_storage_view_cbcr = r->c->target->images[r->acquired_buffer].view_cbcr;
- 
- 	// Target view information.
- 	struct render_viewport_data target_viewport_datas[XRT_MAX_VIEWS];
-@@ -1000,7 +1001,8 @@ dispatch_compute(struct comp_renderer *r,
- 	    eye_poses,                       //
- 	    fovs,                            //
- 	    target_image,                    //
--	    target_storage_view,             //
-+	    target_storage_view_y,           //
-+	    target_storage_view_cbcr,        //
- 	    target_viewport_datas);          //
- 
- 	// Everything is ready, submit to the queue.
-diff --git a/src/xrt/compositor/main/comp_target.h b/src/xrt/compositor/main/comp_target.h
-index 953052155..68ca15cb9 100644
---- a/src/xrt/compositor/main/comp_target.h
-+++ b/src/xrt/compositor/main/comp_target.h
-@@ -62,7 +62,8 @@ enum comp_target_display_timing_usage
- struct comp_target_image
- {
- 	VkImage handle;
--	VkImageView view;
-+	VkImageView view; // Y
-+	VkImageView view_cbcr;
- };
- 
- /*!
-diff --git a/src/xrt/compositor/render/CMakeLists.txt b/src/xrt/compositor/render/CMakeLists.txt
-index 8b0014d39..60afb0ce2 100644
---- a/src/xrt/compositor/render/CMakeLists.txt
-+++ b/src/xrt/compositor/render/CMakeLists.txt
-@@ -10,7 +10,7 @@ add_library(
- 	comp_render STATIC
- 	render_buffer.c
- 	render_compute.c
--	render_distortion.c
-+	# render/render_distortion.c implemented in wivrn
- 	render_gfx.c
- 	render_interface.h
- 	render_resources.c
-diff --git a/src/xrt/compositor/render/render_compute.c b/src/xrt/compositor/render/render_compute.c
-index 62d7138b9..44c3f0aee 100644
---- a/src/xrt/compositor/render/render_compute.c
-+++ b/src/xrt/compositor/render/render_compute.c
-@@ -86,8 +86,10 @@ update_compute_layer_descriptor_set(struct vk_bundle *vk,
-                                     VkSampler src_samplers[RENDER_MAX_IMAGES_SIZE],
-                                     VkImageView src_image_views[RENDER_MAX_IMAGES_SIZE],
-                                     uint32_t image_count,
--                                    uint32_t target_binding,
--                                    VkImageView target_image_view,
-+                                    uint32_t target_binding_y,
-+                                    uint32_t target_binding_cbcr,
-+                                    VkImageView target_image_view_y,
-+                                    VkImageView target_image_view_cbcr,
-                                     uint32_t ubo_binding,
-                                     VkBuffer ubo_buffer,
-                                     VkDeviceSize ubo_size,
-@@ -100,8 +102,13 @@ update_compute_layer_descriptor_set(struct vk_bundle *vk,
- 		src_image_info[i].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
- 	}
- 
--	VkDescriptorImageInfo target_image_info = {
--	    .imageView = target_image_view,
-+	VkDescriptorImageInfo target_image_info_y = {
-+	    .imageView = target_image_view_y,
-+	    .imageLayout = VK_IMAGE_LAYOUT_GENERAL,
-+	};
-+
-+	VkDescriptorImageInfo target_image_info_cbcr = {
-+	    .imageView = target_image_view_cbcr,
- 	    .imageLayout = VK_IMAGE_LAYOUT_GENERAL,
- 	};
- 
-@@ -111,7 +118,7 @@ update_compute_layer_descriptor_set(struct vk_bundle *vk,
- 	    .range = ubo_size,
- 	};
- 
--	VkWriteDescriptorSet write_descriptor_sets[3] = {
-+	VkWriteDescriptorSet write_descriptor_sets[4] = {
- 	    {
- 	        .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
- 	        .dstSet = descriptor_set,
-@@ -123,10 +130,10 @@ update_compute_layer_descriptor_set(struct vk_bundle *vk,
- 	    {
- 	        .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
- 	        .dstSet = descriptor_set,
--	        .dstBinding = target_binding,
-+	        .dstBinding = target_binding_y,
- 	        .descriptorCount = 1,
- 	        .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
--	        .pImageInfo = &target_image_info,
-+	        .pImageInfo = &target_image_info_y,
- 	    },
- 	    {
- 	        .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
-@@ -136,6 +143,14 @@ update_compute_layer_descriptor_set(struct vk_bundle *vk,
- 	        .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
- 	        .pBufferInfo = &buffer_info,
- 	    },
-+	    {
-+	        .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
-+	        .dstSet = descriptor_set,
-+	        .dstBinding = target_binding_cbcr,
-+	        .descriptorCount = 1,
-+	        .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
-+	        .pImageInfo = &target_image_info_cbcr,
-+	    },
- 	};
- 
- 	vk->vkUpdateDescriptorSets(            //
-@@ -152,10 +167,12 @@ update_compute_shared_descriptor_set(struct vk_bundle *vk,
-                                      VkSampler src_samplers[XRT_MAX_VIEWS],
-                                      VkImageView src_image_views[XRT_MAX_VIEWS],
-                                      uint32_t distortion_binding,
--                                     VkSampler distortion_samplers[3 * XRT_MAX_VIEWS],
--                                     VkImageView distortion_image_views[3 * XRT_MAX_VIEWS],
--                                     uint32_t target_binding,
--                                     VkImageView target_image_view,
-+                                     VkDeviceSize foveation_size,
-+                                     VkBuffer foveation_buffer,
-+                                     uint32_t target_binding_y,
-+                                     uint32_t target_binding_cbcr,
-+                                     VkImageView target_image_view_y,
-+                                     VkImageView target_image_view_cbcr,
-                                      uint32_t ubo_binding,
-                                      VkBuffer ubo_buffer,
-                                      VkDeviceSize ubo_size,
-@@ -169,15 +186,19 @@ update_compute_shared_descriptor_set(struct vk_bundle *vk,
- 		src_image_info[i].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
- 	}
- 
--	VkDescriptorImageInfo distortion_image_info[3 * XRT_MAX_VIEWS];
--	for (uint32_t i = 0; i < 3 * view_count; ++i) {
--		distortion_image_info[i].sampler = distortion_samplers[i];
--		distortion_image_info[i].imageView = distortion_image_views[i];
--		distortion_image_info[i].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
--	}
-+	VkDescriptorBufferInfo foveation_buffer_info = {
-+	    .buffer = foveation_buffer,
-+	    .offset = 0,
-+	    .range = foveation_size,
-+	};
- 
--	VkDescriptorImageInfo target_image_info = {
--	    .imageView = target_image_view,
-+	VkDescriptorImageInfo target_image_y_info = {
-+	    .imageView = target_image_view_y,
-+	    .imageLayout = VK_IMAGE_LAYOUT_GENERAL,
-+	};
-+
-+	VkDescriptorImageInfo target_image_cbcr_info = {
-+	    .imageView = target_image_view_cbcr,
- 	    .imageLayout = VK_IMAGE_LAYOUT_GENERAL,
- 	};
- 
-@@ -187,7 +208,7 @@ update_compute_shared_descriptor_set(struct vk_bundle *vk,
- 	    .range = ubo_size,
- 	};
- 
--	VkWriteDescriptorSet write_descriptor_sets[4] = {
-+	VkWriteDescriptorSet write_descriptor_sets[5] = {
- 	    {
- 	        .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
- 	        .dstSet = descriptor_set,
-@@ -200,17 +221,17 @@ update_compute_shared_descriptor_set(struct vk_bundle *vk,
- 	        .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
- 	        .dstSet = descriptor_set,
- 	        .dstBinding = distortion_binding,
--	        .descriptorCount = 3 * view_count,
--	        .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
--	        .pImageInfo = distortion_image_info,
-+	        .descriptorCount = 1,
-+	        .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
-+	        .pBufferInfo = &foveation_buffer_info,
- 	    },
- 	    {
- 	        .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
- 	        .dstSet = descriptor_set,
--	        .dstBinding = target_binding,
-+	        .dstBinding = target_binding_y,
- 	        .descriptorCount = 1,
- 	        .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
--	        .pImageInfo = &target_image_info,
-+	        .pImageInfo = &target_image_y_info,
- 	    },
- 	    {
- 	        .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
-@@ -220,6 +241,14 @@ update_compute_shared_descriptor_set(struct vk_bundle *vk,
- 	        .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
- 	        .pBufferInfo = &buffer_info,
- 	    },
-+	    {
-+	        .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
-+	        .dstSet = descriptor_set,
-+	        .dstBinding = target_binding_cbcr,
-+	        .descriptorCount = 1,
-+	        .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
-+	        .pImageInfo = &target_image_cbcr_info,
-+	    },
- 	};
- 
- 	vk->vkUpdateDescriptorSets(            //
-@@ -278,129 +307,6 @@ update_compute_descriptor_set_target(struct vk_bundle *vk,
- 	    NULL);                             // pDescriptorCopies
- }
- 
--static void
--dispatch_project_pipeline(struct render_compute *render,
--                          VkSampler src_samplers[XRT_MAX_VIEWS],
--                          VkImageView src_image_views[XRT_MAX_VIEWS],
--                          const struct xrt_normalized_rect src_norm_rects[XRT_MAX_VIEWS],
--                          VkImage target_image,
--                          VkImageView target_image_view,
--                          const struct render_viewport_data views[XRT_MAX_VIEWS],
--                          VkPipeline pipeline)
--{
--	struct vk_bundle *vk = vk_from_render(render);
--	struct render_resources *r = render->r;
--
--
--	/*
--	 * UBO
--	 */
--
--	struct render_compute_distortion_ubo_data *data =
--	    (struct render_compute_distortion_ubo_data *)r->compute.distortion.ubo.mapped;
--	for (uint32_t i = 0; i < render->r->view_count; ++i) {
--		data->views[i] = views[i];
--		data->post_transforms[i] = src_norm_rects[i];
--	}
--
--
--	/*
--	 * Source, target and distortion images.
--	 */
--
--	VkImageSubresourceRange subresource_range = {
--	    .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
--	    .baseMipLevel = 0,
--	    .levelCount = VK_REMAINING_MIP_LEVELS,
--	    .baseArrayLayer = 0,
--	    .layerCount = VK_REMAINING_ARRAY_LAYERS,
--	};
--
--	vk_cmd_image_barrier_gpu_locked( //
--	    vk,                          //
--	    r->cmd,                      //
--	    target_image,                //
--	    0,                           //
--	    VK_ACCESS_SHADER_WRITE_BIT,  //
--	    VK_IMAGE_LAYOUT_UNDEFINED,   //
--	    VK_IMAGE_LAYOUT_GENERAL,     //
--	    subresource_range);          //
--
--	VkSampler sampler = r->samplers.clamp_to_edge;
--	VkSampler distortion_samplers[3 * XRT_MAX_VIEWS];
--	for (uint32_t i = 0; i < render->r->view_count; ++i) {
--		distortion_samplers[3 * i + 0] = sampler;
--		distortion_samplers[3 * i + 1] = sampler;
--		distortion_samplers[3 * i + 2] = sampler;
--	}
--
--	update_compute_shared_descriptor_set( //
--	    vk,                               //
--	    r->compute.src_binding,           //
--	    src_samplers,                     //
--	    src_image_views,                  //
--	    r->compute.distortion_binding,    //
--	    distortion_samplers,              //
--	    r->distortion.image_views,        //
--	    r->compute.target_binding,        //
--	    target_image_view,                //
--	    r->compute.ubo_binding,           //
--	    r->compute.distortion.ubo.buffer, //
--	    VK_WHOLE_SIZE,                    //
--	    render->shared_descriptor_set,    //
--	    render->r->view_count);           //
--
--	vk->vkCmdBindPipeline(              //
--	    r->cmd,                         //
--	    VK_PIPELINE_BIND_POINT_COMPUTE, // pipelineBindPoint
--	    pipeline);                      // pipeline
--
--	vk->vkCmdBindDescriptorSets(               //
--	    r->cmd,                                //
--	    VK_PIPELINE_BIND_POINT_COMPUTE,        // pipelineBindPoint
--	    r->compute.distortion.pipeline_layout, // layout
--	    0,                                     // firstSet
--	    1,                                     // descriptorSetCount
--	    &render->shared_descriptor_set,        // pDescriptorSets
--	    0,                                     // dynamicOffsetCount
--	    NULL);                                 // pDynamicOffsets
--
--
--	uint32_t w = 0, h = 0;
--	calc_dispatch_dims_views(views, render->r->view_count, &w, &h);
--	assert(w != 0 && h != 0);
--
--	vk->vkCmdDispatch( //
--	    r->cmd,        //
--	    w,             // groupCountX
--	    h,             // groupCountY
--	    2);            // groupCountZ
--
--	VkImageMemoryBarrier memoryBarrier = {
--	    .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
--	    .srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT,
--	    .dstAccessMask = VK_ACCESS_MEMORY_READ_BIT,
--	    .oldLayout = VK_IMAGE_LAYOUT_GENERAL,
--	    .newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
--	    .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
--	    .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
--	    .image = target_image,
--	    .subresourceRange = subresource_range,
--	};
--
--	vk->vkCmdPipelineBarrier(                 //
--	    r->cmd,                               //
--	    VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, //
--	    VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,    //
--	    0,                                    //
--	    0,                                    //
--	    NULL,                                 //
--	    0,                                    //
--	    NULL,                                 //
--	    1,                                    //
--	    &memoryBarrier);                      //
--}
--
- 
- /*
-  *
-@@ -518,7 +424,8 @@ render_compute_layers(struct render_compute *render,
-                       VkSampler src_samplers[RENDER_MAX_IMAGES_SIZE],
-                       VkImageView src_image_views[RENDER_MAX_IMAGES_SIZE],
-                       uint32_t num_srcs,
--                      VkImageView target_image_view,
-+                      VkImageView target_image_view_y,
-+                      VkImageView target_image_view_cbcr,
-                       const struct render_viewport_data *view,
-                       bool do_timewarp)
- {
-@@ -538,8 +445,10 @@ render_compute_layers(struct render_compute *render,
- 	    src_samplers,                    //
- 	    src_image_views,                 //
- 	    num_srcs,                        //
--	    r->compute.target_binding,       //
--	    target_image_view,               //
-+	    r->compute.target_binding_y,     //
-+	    r->compute.target_binding_cbcr,  //
-+	    target_image_view_y,             //
-+	    target_image_view_cbcr,          //
- 	    r->compute.ubo_binding,          //
- 	    ubo,                             //
- 	    VK_WHOLE_SIZE,                   //
-@@ -574,19 +483,18 @@ render_compute_layers(struct render_compute *render,
- }
- 
- void
--render_compute_projection_timewarp(struct render_compute *render,
--                                   VkSampler src_samplers[XRT_MAX_VIEWS],
--                                   VkImageView src_image_views[XRT_MAX_VIEWS],
--                                   const struct xrt_normalized_rect src_norm_rects[XRT_MAX_VIEWS],
--                                   const struct xrt_pose src_poses[XRT_MAX_VIEWS],
--                                   const struct xrt_fov src_fovs[XRT_MAX_VIEWS],
--                                   const struct xrt_pose new_poses_scanout_begin[XRT_MAX_VIEWS],
--                                   const struct xrt_pose new_poses_scanout_end[XRT_MAX_VIEWS],
--                                   VkImage target_image,
--                                   VkImageView target_image_view,
--                                   const struct render_viewport_data views[XRT_MAX_VIEWS])
-+render_compute_projection(struct render_compute *render,
-+                          VkSampler src_samplers[XRT_MAX_VIEWS],
-+                          VkImageView src_image_views[XRT_MAX_VIEWS],
-+                          const struct xrt_normalized_rect src_norm_rects[XRT_MAX_VIEWS],
-+                          VkImage target_image,
-+                          VkImageView target_image_view_y,
-+                          VkImageView target_image_view_cbcr,
-+                          const struct render_viewport_data views[XRT_MAX_VIEWS])
- {
- 	assert(render->r != NULL);
-+
-+	struct vk_bundle *vk = vk_from_render(render);
- 	struct render_resources *r = render->r;
- 
- 
-@@ -594,108 +502,110 @@ render_compute_projection_timewarp(struct render_compute *render,
- 	 * UBO
- 	 */
- 
--	struct xrt_matrix_4x4 time_warp_matrix_scanout_begin[XRT_MAX_VIEWS];
--	struct xrt_matrix_4x4 time_warp_matrix_scanout_end[XRT_MAX_VIEWS];
--	for (uint32_t i = 0; i < render->r->view_count; ++i) {
--		render_calc_time_warp_matrix(            //
--		    &src_poses[i],                       //
--		    &src_fovs[i],                        //
--		    &new_poses_scanout_begin[i],         //
--		    &time_warp_matrix_scanout_begin[i]); //
--
--		render_calc_time_warp_matrix(          //
--		    &src_poses[i],                     //
--		    &src_fovs[i],                      //
--		    &new_poses_scanout_end[i],         //
--		    &time_warp_matrix_scanout_end[i]); //
--	}
--
- 	struct render_compute_distortion_ubo_data *data =
- 	    (struct render_compute_distortion_ubo_data *)r->compute.distortion.ubo.mapped;
- 	for (uint32_t i = 0; i < render->r->view_count; ++i) {
- 		data->views[i] = views[i];
--		data->pre_transforms[i] = r->distortion.uv_to_tanangle[i];
--		data->transform_timewarp_scanout_begin[i] = time_warp_matrix_scanout_begin[i];
--		data->transform_timewarp_scanout_end[i] = time_warp_matrix_scanout_end[i];
- 		data->post_transforms[i] = src_norm_rects[i];
- 	}
- 
--	dispatch_project_pipeline(render, src_samplers, src_image_views, src_norm_rects, target_image,
--	                          target_image_view, views, r->compute.distortion.timewarp_pipeline);
--}
- 
-+	/*
-+	 * Source, target and distortion images.
-+	 */
- 
--/*
-- * This function is intended to be used on content already timewarped to new_poses_scanout_begin.
-- * It performs only the timewarp nesscary to compensate for the time delta between the start and end of
-- * scanout.
-- */
--void
--render_compute_projection_scanout_compensation(struct render_compute *render,
--                                               VkSampler src_samplers[XRT_MAX_VIEWS],
--                                               VkImageView src_image_views[XRT_MAX_VIEWS],
--                                               const struct xrt_normalized_rect src_rects[XRT_MAX_VIEWS],
--                                               const struct xrt_fov src_fovs[XRT_MAX_VIEWS],
--                                               const struct xrt_pose new_poses_scanout_begin[XRT_MAX_VIEWS],
--                                               const struct xrt_pose new_poses_scanout_end[XRT_MAX_VIEWS],
--                                               VkImage target_image,
--                                               VkImageView target_image_view,
--                                               const struct render_viewport_data views[XRT_MAX_VIEWS])
--{
--	assert(render->r != NULL);
--	struct render_resources *r = render->r;
-+	VkImageSubresourceRange subresource_range = {
-+	    .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
-+	    .baseMipLevel = 0,
-+	    .levelCount = VK_REMAINING_MIP_LEVELS,
-+	    .baseArrayLayer = 0,
-+	    .layerCount = VK_REMAINING_ARRAY_LAYERS,
-+	};
- 
-+	vk_cmd_image_barrier_gpu_locked( //
-+	    vk,                          //
-+	    r->cmd,                      //
-+	    target_image,                //
-+	    0,                           //
-+	    VK_ACCESS_SHADER_WRITE_BIT,  //
-+	    VK_IMAGE_LAYOUT_UNDEFINED,   //
-+	    VK_IMAGE_LAYOUT_GENERAL,     //
-+	    subresource_range);          //
- 
--	/*
--	 * UBO
--	 */
-+	update_compute_shared_descriptor_set( //
-+	    vk,                               //
-+	    r->compute.src_binding,           //
-+	    src_samplers,                     //
-+	    src_image_views,                  //
-+	    r->compute.distortion_binding,    //
-+	    VK_WHOLE_SIZE,                    //
-+	    r->distortion.buffer,             //
-+	    r->compute.target_binding_y,      //
-+	    r->compute.target_binding_cbcr,   //
-+	    target_image_view_y,              //
-+	    target_image_view_cbcr,           //
-+	    r->compute.ubo_binding,           //
-+	    r->compute.distortion.ubo.buffer, //
-+	    VK_WHOLE_SIZE,                    //
-+	    render->shared_descriptor_set,    //
-+	    render->r->view_count);           //
- 
--	struct xrt_matrix_4x4 time_warp_matrix_scanout_begin[XRT_MAX_VIEWS];
--	struct xrt_matrix_4x4 time_warp_matrix_scanout_end[XRT_MAX_VIEWS];
--	for (uint32_t i = 0; i < render->r->view_count; ++i) {
--		render_calc_time_warp_projection(&src_fovs[i], &time_warp_matrix_scanout_begin[i]);
-+	vk->vkCmdBindPipeline(               //
-+	    r->cmd,                          //
-+	    VK_PIPELINE_BIND_POINT_COMPUTE,  // pipelineBindPoint
-+	    r->compute.distortion.pipeline); // pipeline
- 
--		render_calc_time_warp_matrix(          //
--		    &new_poses_scanout_begin[i],       //
--		    &src_fovs[i],                      //
--		    &new_poses_scanout_end[i],         //
--		    &time_warp_matrix_scanout_end[i]); //
--	}
-+	vk->vkCmdBindDescriptorSets(               //
-+	    r->cmd,                                //
-+	    VK_PIPELINE_BIND_POINT_COMPUTE,        // pipelineBindPoint
-+	    r->compute.distortion.pipeline_layout, // layout
-+	    0,                                     // firstSet
-+	    1,                                     // descriptorSetCount
-+	    &render->shared_descriptor_set,        // pDescriptorSets
-+	    0,                                     // dynamicOffsetCount
-+	    NULL);                                 // pDynamicOffsets
- 
--	struct render_compute_distortion_ubo_data *data =
--	    (struct render_compute_distortion_ubo_data *)r->compute.distortion.ubo.mapped;
--	for (uint32_t i = 0; i < render->r->view_count; ++i) {
--		data->views[i] = views[i];
--		data->pre_transforms[i] = r->distortion.uv_to_tanangle[i];
--		data->transform_timewarp_scanout_begin[i] = time_warp_matrix_scanout_begin[i];
--		data->transform_timewarp_scanout_end[i] = time_warp_matrix_scanout_end[i];
--		data->post_transforms[i] = src_rects[i];
--	}
- 
--	dispatch_project_pipeline(render, src_samplers, src_image_views, src_rects, target_image, target_image_view,
--	                          views, r->compute.distortion.timewarp_pipeline);
--}
-+	uint32_t w = 0, h = 0;
-+	calc_dispatch_dims_views(views, render->r->view_count, &w, &h);
-+	assert(w != 0 && h != 0);
- 
--void
--render_compute_projection_no_timewarp(struct render_compute *render,
--                                      VkSampler src_samplers[XRT_MAX_VIEWS],
--                                      VkImageView src_image_views[XRT_MAX_VIEWS],
--                                      const struct xrt_normalized_rect src_rects[XRT_MAX_VIEWS],
--                                      VkImage target_image,
--                                      VkImageView target_image_view,
--                                      const struct render_viewport_data views[XRT_MAX_VIEWS])
--{
--	assert(render->r != NULL);
--	struct render_resources *r = render->r;
-+	vk->vkCmdDispatch( //
-+	    r->cmd,        //
-+	    w,             // groupCountX
-+	    h,             // groupCountY
-+	    2);            // groupCountZ
-+
-+	VkImageMemoryBarrier memoryBarrier = {
-+	    .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
-+	    .srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT,
-+	    .dstAccessMask = VK_ACCESS_MEMORY_READ_BIT,
-+	    .oldLayout = VK_IMAGE_LAYOUT_GENERAL,
-+	    .newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
-+	    .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
-+	    .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
-+	    .image = target_image,
-+	    .subresourceRange = subresource_range,
-+	};
- 
--	dispatch_project_pipeline(render, src_samplers, src_image_views, src_rects, target_image, target_image_view,
--	                          views, r->compute.distortion.pipeline);
-+	vk->vkCmdPipelineBarrier(                 //
-+	    r->cmd,                               //
-+	    VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, //
-+	    VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,    //
-+	    0,                                    //
-+	    0,                                    //
-+	    NULL,                                 //
-+	    0,                                    //
-+	    NULL,                                 //
-+	    1,                                    //
-+	    &memoryBarrier);                      //
- }
- 
- void
- render_compute_clear(struct render_compute *render,
-                      VkImage target_image,
--                     VkImageView target_image_view,
-+                     VkImageView target_image_view_y,
-+                     VkImageView target_image_view_cbcr,
-                      const struct render_viewport_data views[XRT_MAX_VIEWS])
- {
- 	assert(render->r != NULL);
-@@ -745,13 +655,9 @@ render_compute_clear(struct render_compute *render,
- 	VkSampler sampler = r->samplers.mock;
- 	VkSampler src_samplers[XRT_MAX_VIEWS];
- 	VkImageView src_image_views[XRT_MAX_VIEWS];
--	VkSampler distortion_samplers[3 * XRT_MAX_VIEWS];
- 	for (uint32_t i = 0; i < render->r->view_count; ++i) {
- 		src_samplers[i] = sampler;
- 		src_image_views[i] = r->mock.color.image_view;
--		distortion_samplers[3 * i + 0] = sampler;
--		distortion_samplers[3 * i + 1] = sampler;
--		distortion_samplers[3 * i + 2] = sampler;
- 	}
- 
- 	update_compute_shared_descriptor_set( //
-@@ -760,10 +666,12 @@ render_compute_clear(struct render_compute *render,
- 	    src_samplers,                     //
- 	    src_image_views,                  //
- 	    r->compute.distortion_binding,    //
--	    distortion_samplers,              //
--	    r->distortion.image_views,        //
--	    r->compute.target_binding,        //
--	    target_image_view,                //
-+	    VK_WHOLE_SIZE,                    //
-+	    r->distortion.buffer,             //
-+	    r->compute.target_binding_y,      //
-+	    r->compute.target_binding_cbcr,   //
-+	    target_image_view_y,              //
-+	    target_image_view_cbcr,           //
- 	    r->compute.ubo_binding,           //
- 	    r->compute.clear.ubo.buffer,      //
- 	    VK_WHOLE_SIZE,                    // ubo_size
-@@ -801,7 +709,7 @@ render_compute_clear(struct render_compute *render,
- 	    .srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT,
- 	    .dstAccessMask = VK_ACCESS_MEMORY_READ_BIT,
- 	    .oldLayout = VK_IMAGE_LAYOUT_GENERAL,
--	    .newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
-+	    .newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
- 	    .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
- 	    .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
- 	    .image = target_image,
-diff --git a/src/xrt/compositor/render/render_interface.h b/src/xrt/compositor/render/render_interface.h
-index 2b7893881..3c59645dc 100644
---- a/src/xrt/compositor/render/render_interface.h
-+++ b/src/xrt/compositor/render/render_interface.h
-@@ -82,12 +82,8 @@ extern "C" {
- #define RENDER_MAX_LAYER_RUNS_SIZE (XRT_MAX_VIEWS)
- #define RENDER_MAX_LAYER_RUNS_COUNT(RENDER_RESOURCES) (RENDER_RESOURCES->view_count)
- 
--//! Distortion image dimension in pixels
--#define RENDER_DISTORTION_IMAGE_DIMENSIONS (128)
--
--//! How many distortion images we have, one for each channel (3 rgb) and per view.
--#define RENDER_DISTORTION_IMAGES_SIZE (3 * XRT_MAX_VIEWS)
--#define RENDER_DISTORTION_IMAGES_COUNT(RENDER_RESOURCES) (3 * RENDER_RESOURCES->view_count)
-+//! Foveation buffer dimension in pixels (including past-the end pixel)
-+#define RENDER_FOVEATION_BUFFER_DIMENSIONS (4096 + 1)
- 
- //! The binding that the layer projection and quad shader have their UBO on.
- #define RENDER_BINDING_LAYER_SHARED_UBO 0
-@@ -120,12 +116,6 @@ extern "C" {
- uint32_t
- render_max_layers_capable(const struct vk_bundle *vk, bool use_compute, uint32_t desired_max_layers);
- 
--/*!
-- * Create a simplified projection matrix for timewarp.
-- */
--void
--render_calc_time_warp_projection(const struct xrt_fov *fov, struct xrt_matrix_4x4 *result);
--
- /*!
-  * Calculates a timewarp matrix which takes in NDC coords and gives out results
-  * in [-1, 1] space that needs a perspective divide.
-@@ -465,7 +455,8 @@ struct render_resources
- 		uint32_t distortion_binding;
- 
- 		//! Writing the image out too.
--		uint32_t target_binding;
-+		uint32_t target_binding_y;
-+		uint32_t target_binding_cbcr;
- 
- 		//! Uniform data binding.
- 		uint32_t ubo_binding;
-@@ -502,9 +493,6 @@ struct render_resources
- 			//! Doesn't depend on target so is static.
- 			VkPipeline pipeline;
- 
--			//! Doesn't depend on target so is static.
--			VkPipeline timewarp_pipeline;
--
- 			//! Target info.
- 			struct render_buffer ubo;
- 		} distortion;
-@@ -526,17 +514,11 @@ struct render_resources
- 		//! Transform to go from UV to tangle angles.
- 		struct xrt_normalized_rect uv_to_tanangle[XRT_MAX_VIEWS];
- 
--		//! Backing memory to distortion images.
--		VkDeviceMemory device_memories[RENDER_DISTORTION_IMAGES_SIZE];
--
--		//! Distortion images.
--		VkImage images[RENDER_DISTORTION_IMAGES_SIZE];
-+		//! Backing memory to foveation buffers.
-+		VkDeviceMemory device_memory;
- 
--		//! The views into the distortion images.
--		VkImageView image_views[RENDER_DISTORTION_IMAGES_SIZE];
--
--		//! Whether distortion images have been pre-rotated 90 degrees.
--		bool pre_rotated;
-+		//! Foveation buffer.
-+		VkBuffer buffer;
- 	} distortion;
- };
- 
-@@ -1262,6 +1244,7 @@ struct render_compute_layer_ubo_data
- 	//! Timewarp matrices
- 	struct xrt_matrix_4x4 transforms_timewarp[RENDER_MAX_LAYERS];
- 
-+
- 	/*!
- 	 * For quad layers
- 	 */
-@@ -1307,6 +1290,14 @@ struct render_compute_distortion_ubo_data
- 	struct xrt_matrix_4x4 transform_timewarp_scanout_end[XRT_MAX_VIEWS];
- };
- 
-+struct render_compute_distortion_foveation_data
-+{
-+	// For each output pixel: index of the first pixel to read.
-+	// contains 1 additional value at the end for past-the end pixel
-+	uint32_t x[XRT_MAX_VIEWS * RENDER_FOVEATION_BUFFER_DIMENSIONS];
-+	uint32_t y[XRT_MAX_VIEWS * RENDER_FOVEATION_BUFFER_DIMENSIONS];
-+};
-+
- /*!
-  * Init struct and create resources needed for compute rendering.
-  *
-@@ -1360,7 +1351,8 @@ render_compute_layers(struct render_compute *render,
-                       VkSampler src_samplers[RENDER_MAX_IMAGES_SIZE],
-                       VkImageView src_image_views[RENDER_MAX_IMAGES_SIZE],
-                       uint32_t num_srcs,
--                      VkImageView target_image_view,
-+                      VkImageView target_image_view_y,
-+                      VkImageView target_image_view_cbcr,
-                       const struct render_viewport_data *view,
-                       bool timewarp);
- 
-@@ -1368,44 +1360,14 @@ render_compute_layers(struct render_compute *render,
-  * @public @memberof render_compute
-  */
- void
--render_compute_projection_timewarp(struct render_compute *render,
--                                   VkSampler src_samplers[XRT_MAX_VIEWS],
--                                   VkImageView src_image_views[XRT_MAX_VIEWS],
--                                   const struct xrt_normalized_rect src_rects[XRT_MAX_VIEWS],
--                                   const struct xrt_pose src_poses[XRT_MAX_VIEWS],
--                                   const struct xrt_fov src_fovs[XRT_MAX_VIEWS],
--                                   const struct xrt_pose new_poses_scanout_begin[XRT_MAX_VIEWS],
--                                   const struct xrt_pose new_poses_scanout_end[XRT_MAX_VIEWS],
--                                   VkImage target_image,
--                                   VkImageView target_image_view,
--                                   const struct render_viewport_data views[XRT_MAX_VIEWS]);
--
--/*!
-- * @public @memberof render_compute
-- */
--void
--render_compute_projection_scanout_compensation(struct render_compute *render,
--                                               VkSampler src_samplers[XRT_MAX_VIEWS],
--                                               VkImageView src_image_views[XRT_MAX_VIEWS],
--                                               const struct xrt_normalized_rect src_rects[XRT_MAX_VIEWS],
--                                               const struct xrt_fov src_fovs[XRT_MAX_VIEWS],
--                                               const struct xrt_pose new_poses_scanout_begin[XRT_MAX_VIEWS],
--                                               const struct xrt_pose new_poses_scanout_end[XRT_MAX_VIEWS],
--                                               VkImage target_image,
--                                               VkImageView target_image_view,
--                                               const struct render_viewport_data views[XRT_MAX_VIEWS]);
--
--/*!
-- * @public @memberof render_compute
-- */
--void
--render_compute_projection_no_timewarp(struct render_compute *render,
--                                      VkSampler src_samplers[XRT_MAX_VIEWS],
--                                      VkImageView src_image_views[XRT_MAX_VIEWS],
--                                      const struct xrt_normalized_rect src_rects[XRT_MAX_VIEWS],
--                                      VkImage target_image,
--                                      VkImageView target_image_view,
--                                      const struct render_viewport_data views[XRT_MAX_VIEWS]);
-+render_compute_projection(struct render_compute *render,
-+                          VkSampler src_samplers[XRT_MAX_VIEWS],
-+                          VkImageView src_image_views[XRT_MAX_VIEWS],
-+                          const struct xrt_normalized_rect src_rects[XRT_MAX_VIEWS],
-+                          VkImage target_image,
-+                          VkImageView target_image_view_y,
-+                          VkImageView target_image_view_cbcr,
-+                          const struct render_viewport_data views[XRT_MAX_VIEWS]);
- 
- /*!
-  * @public @memberof render_compute
-@@ -1413,7 +1375,8 @@ render_compute_projection_no_timewarp(struct render_compute *render,
- void
- render_compute_clear(struct render_compute *render,
-                      VkImage target_image,
--                     VkImageView target_image_view,
-+                     VkImageView target_image_view_y,
-+                     VkImageView target_image_view_cbcr,
-                      const struct render_viewport_data views[XRT_MAX_VIEWS]);
- 
- 
-diff --git a/src/xrt/compositor/render/render_resources.c b/src/xrt/compositor/render/render_resources.c
-index d28caaed8..5232a774d 100644
---- a/src/xrt/compositor/render/render_resources.c
-+++ b/src/xrt/compositor/render/render_resources.c
-@@ -184,14 +184,15 @@ init_mesh_ubo_buffers(struct vk_bundle *vk, struct render_buffer ubo[XRT_MAX_VIE
- XRT_CHECK_RESULT static VkResult
- create_compute_layer_descriptor_set_layout(struct vk_bundle *vk,
-                                            uint32_t src_binding,
--                                           uint32_t target_binding,
-+                                           uint32_t target_binding_y,
-+                                           uint32_t target_binding_cbcr,
-                                            uint32_t ubo_binding,
-                                            uint32_t source_images_count,
-                                            VkDescriptorSetLayout *out_descriptor_set_layout)
- {
- 	VkResult ret;
- 
--	VkDescriptorSetLayoutBinding set_layout_bindings[3] = {
-+	VkDescriptorSetLayoutBinding set_layout_bindings[4] = {
- 	    {
- 	        .binding = src_binding,
- 	        .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
-@@ -199,7 +200,7 @@ create_compute_layer_descriptor_set_layout(struct vk_bundle *vk,
- 	        .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
- 	    },
- 	    {
--	        .binding = target_binding,
-+	        .binding = target_binding_y,
- 	        .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
- 	        .descriptorCount = 1,
- 	        .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
-@@ -210,6 +211,12 @@ create_compute_layer_descriptor_set_layout(struct vk_bundle *vk,
- 	        .descriptorCount = 1,
- 	        .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
- 	    },
-+	    {
-+	        .binding = target_binding_cbcr,
-+	        .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
-+	        .descriptorCount = 1,
-+	        .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
-+	    },
- 	};
- 
- 	VkDescriptorSetLayoutCreateInfo set_layout_info = {
-@@ -235,13 +242,14 @@ XRT_CHECK_RESULT static VkResult
- create_compute_distortion_descriptor_set_layout(struct vk_bundle *vk,
-                                                 uint32_t src_binding,
-                                                 uint32_t distortion_binding,
--                                                uint32_t target_binding,
-+                                                uint32_t target_binding_y,
-+                                                uint32_t target_binding_cbcr,
-                                                 uint32_t ubo_binding,
-                                                 VkDescriptorSetLayout *out_descriptor_set_layout)
- {
- 	VkResult ret;
- 
--	VkDescriptorSetLayoutBinding set_layout_bindings[4] = {
-+	VkDescriptorSetLayoutBinding set_layout_bindings[5] = {
- 	    {
- 	        .binding = src_binding,
- 	        .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
-@@ -250,12 +258,12 @@ create_compute_distortion_descriptor_set_layout(struct vk_bundle *vk,
- 	    },
- 	    {
- 	        .binding = distortion_binding,
--	        .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
--	        .descriptorCount = 6,
-+	        .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
-+	        .descriptorCount = 1,
- 	        .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
- 	    },
- 	    {
--	        .binding = target_binding,
-+	        .binding = target_binding_y,
- 	        .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
- 	        .descriptorCount = 1,
- 	        .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
-@@ -266,6 +274,12 @@ create_compute_distortion_descriptor_set_layout(struct vk_bundle *vk,
- 	        .descriptorCount = 1,
- 	        .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
- 	    },
-+	    {
-+	        .binding = target_binding_cbcr,
-+	        .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
-+	        .descriptorCount = 1,
-+	        .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
-+	    },
- 	};
- 
- 	VkDescriptorSetLayoutCreateInfo set_layout_info = {
-@@ -295,12 +309,6 @@ struct compute_layer_params
- 	uint32_t image_array_size;
- };
- 
--struct compute_distortion_params
--{
--	uint32_t distortion_texel_count;
--	VkBool32 do_timewarp;
--};
--
- XRT_CHECK_RESULT static VkResult
- create_compute_layer_pipeline(struct vk_bundle *vk,
-                               VkPipelineCache pipeline_cache,
-@@ -345,35 +353,15 @@ create_compute_distortion_pipeline(struct vk_bundle *vk,
-                                    VkPipelineCache pipeline_cache,
-                                    VkShaderModule shader,
-                                    VkPipelineLayout pipeline_layout,
--                                   const struct compute_distortion_params *params,
-                                    VkPipeline *out_compute_pipeline)
- {
--#define ENTRY(ID, FIELD)                                                                                               \
--	{                                                                                                              \
--	    .constantID = ID,                                                                                          \
--	    .offset = offsetof(struct compute_distortion_params, FIELD),                                               \
--	    sizeof(params->FIELD),                                                                                     \
--	}
--
--	VkSpecializationMapEntry entries[2] = {
--	    ENTRY(0, distortion_texel_count),
--	    ENTRY(1, do_timewarp),
--	};
--#undef ENTRY
--
--	VkSpecializationInfo specialization_info = {
--	    .mapEntryCount = ARRAY_SIZE(entries),
--	    .pMapEntries = entries,
--	    .dataSize = sizeof(*params),
--	    .pData = params,
--	};
- 
- 	return vk_create_compute_pipeline( //
- 	    vk,                            // vk_bundle
- 	    pipeline_cache,                // pipeline_cache
- 	    shader,                        // shader
- 	    pipeline_layout,               // pipeline_layout
--	    &specialization_info,          // specialization_info
-+	    NULL,                          // specialization_info
- 	    out_compute_pipeline);         // out_compute_pipeline
- }
- 
-@@ -539,8 +527,9 @@ render_resources_init(struct render_resources *r,
- 	}
- 	r->compute.src_binding = 0;
- 	r->compute.distortion_binding = 1;
--	r->compute.target_binding = 2;
-+	r->compute.target_binding_y = 2;
- 	r->compute.ubo_binding = 3;
-+	r->compute.target_binding_cbcr = 4;
- 
- 	r->compute.layer.image_array_size =
- 	    MIN(vk->limits.max_per_stage_descriptor_sampled_images, RENDER_MAX_IMAGES_SIZE);
-@@ -834,9 +823,9 @@ render_resources_init(struct render_resources *r,
- 	struct vk_descriptor_pool_info compute_pool_info = {
- 	    .uniform_per_descriptor_count = 1,
- 	    // layer images
--	    .sampler_per_descriptor_count = r->compute.layer.image_array_size + RENDER_DISTORTION_IMAGES_COUNT(r),
-+	    .sampler_per_descriptor_count = r->compute.layer.image_array_size,
- 	    .storage_image_per_descriptor_count = 1,
--	    .storage_buffer_per_descriptor_count = 0,
-+	    .storage_buffer_per_descriptor_count = 1,
- 	    .descriptor_count = compute_descriptor_count,
- 	    .freeable = false,
- 	};
-@@ -856,7 +845,8 @@ render_resources_init(struct render_resources *r,
- 	ret = create_compute_layer_descriptor_set_layout( //
- 	    vk,                                           // vk_bundle
- 	    r->compute.src_binding,                       // src_binding,
--	    r->compute.target_binding,                    // target_binding,
-+	    r->compute.target_binding_y,                  // target_binding_y,
-+	    r->compute.target_binding_cbcr,               // target_binding_cbcr,
- 	    r->compute.ubo_binding,                       // ubo_binding,
- 	    r->compute.layer.image_array_size,            // source_images_count,
- 	    &r->compute.layer.descriptor_set_layout);     // out_descriptor_set_layout
-@@ -937,7 +927,8 @@ render_resources_init(struct render_resources *r,
- 	    vk,                                                // vk_bundle
- 	    r->compute.src_binding,                            // src_binding,
- 	    r->compute.distortion_binding,                     // distortion_binding,
--	    r->compute.target_binding,                         // target_binding,
-+	    r->compute.target_binding_y,                       // target_binding_y,
-+	    r->compute.target_binding_cbcr,                    // target_binding_cbcr,
- 	    r->compute.ubo_binding,                            // ubo_binding,
- 	    &r->compute.distortion.descriptor_set_layout);     // out_descriptor_set_layout
- 	VK_CHK_WITH_RET(ret, "create_compute_distortion_descriptor_set_layout", false);
-@@ -954,39 +945,16 @@ render_resources_init(struct render_resources *r,
- 	VK_NAME_PIPELINE_LAYOUT(vk, r->compute.distortion.pipeline_layout,
- 	                        "render_resources compute distortion pipeline layout");
- 
--	struct compute_distortion_params distortion_params = {
--	    .distortion_texel_count = RENDER_DISTORTION_IMAGE_DIMENSIONS,
--	    .do_timewarp = false,
--	};
--
- 	ret = create_compute_distortion_pipeline(  //
- 	    vk,                                    // vk_bundle
- 	    r->pipeline_cache,                     // pipeline_cache
- 	    r->shaders->distortion_comp,           // shader
- 	    r->compute.distortion.pipeline_layout, // pipeline_layout
--	    &distortion_params,                    // params
- 	    &r->compute.distortion.pipeline);      // out_compute_pipeline
- 	VK_CHK_WITH_RET(ret, "create_compute_distortion_pipeline", false);
- 
- 	VK_NAME_PIPELINE(vk, r->compute.distortion.pipeline, "render_resources compute distortion pipeline");
- 
--	struct compute_distortion_params distortion_timewarp_params = {
--	    .distortion_texel_count = RENDER_DISTORTION_IMAGE_DIMENSIONS,
--	    .do_timewarp = true,
--	};
--
--	ret = create_compute_distortion_pipeline(      //
--	    vk,                                        // vk_bundle
--	    r->pipeline_cache,                         // pipeline_cache
--	    r->shaders->distortion_comp,               // shader
--	    r->compute.distortion.pipeline_layout,     // pipeline_layout
--	    &distortion_timewarp_params,               // params
--	    &r->compute.distortion.timewarp_pipeline); // out_compute_pipeline
--	VK_CHK_WITH_RET(ret, "create_compute_distortion_pipeline", false);
--
--	VK_NAME_PIPELINE(vk, r->compute.distortion.timewarp_pipeline,
--	                 "render_resources compute distortion timewarp pipeline");
--
- 	size_t distortion_ubo_size = sizeof(struct render_compute_distortion_ubo_data);
- 
- 	ret = render_buffer_init(       //
-@@ -1039,15 +1007,8 @@ render_resources_init(struct render_resources *r,
- 	 * Compute distortion textures, not created until later.
- 	 */
- 
--	for (uint32_t i = 0; i < RENDER_DISTORTION_IMAGES_COUNT(r); i++) {
--		r->distortion.image_views[i] = VK_NULL_HANDLE;
--	}
--	for (uint32_t i = 0; i < RENDER_DISTORTION_IMAGES_COUNT(r); i++) {
--		r->distortion.images[i] = VK_NULL_HANDLE;
--	}
--	for (uint32_t i = 0; i < RENDER_DISTORTION_IMAGES_COUNT(r); i++) {
--		r->distortion.device_memories[i] = VK_NULL_HANDLE;
--	}
-+	r->distortion.buffer = VK_NULL_HANDLE;
-+	r->distortion.device_memory = VK_NULL_HANDLE;
- 
- 
- 	/*
-@@ -1124,7 +1085,6 @@ render_resources_fini(struct render_resources *r)
- 
- 	D(DescriptorSetLayout, r->compute.distortion.descriptor_set_layout);
- 	D(Pipeline, r->compute.distortion.pipeline);
--	D(Pipeline, r->compute.distortion.timewarp_pipeline);
- 	D(PipelineLayout, r->compute.distortion.pipeline_layout);
- 
- 	D(Pipeline, r->compute.clear.pipeline);
-diff --git a/src/xrt/compositor/shaders/CMakeLists.txt b/src/xrt/compositor/shaders/CMakeLists.txt
-index d8aca97e2..ffc79ca6e 100644
---- a/src/xrt/compositor/shaders/CMakeLists.txt
-+++ b/src/xrt/compositor/shaders/CMakeLists.txt
-@@ -25,7 +25,7 @@ set(SHADERS
- spirv_shaders(
- 	SHADER_HEADERS
- 	SPIRV_VERSION
--	1.0 # Currently targeting Vulkan 1.0
-+	1.6 # Currently targeting Vulkan 1.6
- 	SOURCES
- 	${SHADERS}
- 	)
-diff --git a/src/xrt/compositor/shaders/clear.comp b/src/xrt/compositor/shaders/clear.comp
-index 1f0e732b8..e02307415 100644
---- a/src/xrt/compositor/shaders/clear.comp
-+++ b/src/xrt/compositor/shaders/clear.comp
-@@ -10,7 +10,7 @@
- 
- layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
- 
--layout(set = 0, binding = 2) uniform writeonly restrict image2D target;
-+layout(set = 0, binding = 2) uniform writeonly restrict image2DArray target;
- layout(set = 0, binding = 3) uniform restrict Config
- {
- 	ivec4 views[2];
-@@ -35,5 +35,5 @@ void main()
- 
- 	vec4 colour = vec4(0, 0, 0, 1.0);
- 
--	imageStore(target, ivec2(offset.x + ix, offset.y + iy), colour);
-+	imageStore(target, ivec3(offset.x + ix, offset.y + iy, 0), colour);
- }
-diff --git a/src/xrt/compositor/shaders/distortion.comp b/src/xrt/compositor/shaders/distortion.comp
-index 0b28d8bf3..df2b612b0 100644
---- a/src/xrt/compositor/shaders/distortion.comp
-+++ b/src/xrt/compositor/shaders/distortion.comp
-@@ -4,136 +4,106 @@
- 
- #version 460
- #extension GL_GOOGLE_include_directive : require
-+#extension GL_KHR_shader_subgroup_basic: require
-+#extension GL_KHR_shader_subgroup_shuffle: require
- 
- #include "srgb.inc.glsl"
- 
--
--// The size of the distortion texture dimensions in texels.
--layout(constant_id = 0) const int distortion_texel_count = 2;
--
--// Should we do timewarp.
--layout(constant_id = 1) const bool do_timewarp = false;
--
- layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
- 
-+#define MAX_DIM 4097
-+#define MAX_SAMPLES 4
-+
- layout(set = 0, binding = 0) uniform sampler2D source[2];
--layout(set = 0, binding = 1) uniform sampler2D distortion[6];
--layout(set = 0, binding = 2) uniform writeonly restrict image2D target;
-+layout(set = 0, binding = 1, std430) buffer restrict Foveation
-+{
-+	uint x[2*MAX_DIM];
-+	uint y[2*MAX_DIM];
-+} foveation;
-+
-+layout(set = 0, binding = 2) uniform writeonly restrict image2DArray luma;
- layout(set = 0, binding = 3, std140) uniform restrict Config
- {
- 	ivec4 views[2];
- 	vec4 pre_transform[2];
- 	vec4 post_transform[2];
--	mat4 transform_timewarp_scanout_begin[2];
--	mat4 transform_timewarp_scanout_end[2];
--}ubo;
--
--
--vec2 position_to_uv(ivec2 extent, uint ix, uint iy)
--{
--	// Turn the index into floating point.
--	vec2 xy = vec2(float(ix), float(iy));
--
--	// The inverse of the extent of the target image is the pixel size in [0 .. 1] space.
--	vec2 extent_pixel_size = vec2(1.0 / float(extent.x), 1.0 / float(extent.y));
--
--	// Per-target pixel we move the size of the pixels.
--	vec2 dist_uv = xy * extent_pixel_size;
--
--	// Emulate a triangle sample position by offset half target pixel size.
--	dist_uv = dist_uv + extent_pixel_size / 2.0;
--
--
--	// To correctly sample we need to put position (0, 0) in the
--	// middle of the (0, 0) texel in the distortion textures. That's why we
--	// offset with half the texel size, pushing all samples into the middle
--	// of each texels, a kin to a vertex buffer. We need to put uv coord
--	// (1, 1) in the middle of the last texel, that pixel is (size - 1)
--	// texels away from the first texel. So we need to scale [0 .. 1] to
--	// [0 .. size - 1].
--
--#define DIM (float(distortion_texel_count))
--#define STRETCH ((DIM - 1.0) / DIM)
--#define OFFSET (1.0 / (DIM * 2.0))
--
--	dist_uv = (dist_uv * STRETCH) + OFFSET;
--
--	return dist_uv;
--}
--
--vec2 transform_uv_subimage(vec2 uv, uint iz)
-+	mat4 transform[2];
-+} ubo;
-+layout(set = 0, binding = 4) uniform writeonly restrict image2DArray chroma;
-+
-+const mat3 color_space = mat3(
-+// clang-format off
-+//         R        G        B
-+/* Y */ 0.2126,  0.7152,  0.0722,
-+/* Cb*/-0.1146, -0.3854,  0.5,
-+/* Cr*/ 0.5   , -0.4542, -0.0458);
-+//clang-format: on
-+
-+vec3 rgb_to_ycbcr(vec3 color)
- {
--	vec2 values = uv;
--
--	// To deal with OpenGL flip and sub image view.
--	values.xy = values.xy * ubo.post_transform[iz].zw + ubo.post_transform[iz].xy;
--
--	// Ready to be used.
--	return values.xy;
--}
--
--vec2 transform_uv_timewarp(vec2 uv, uint iz)
--{
--	vec4 values = vec4(uv, -1, 1);
--
--	// From uv to tan angle (tangent space).
--	values.xy = values.xy * ubo.pre_transform[iz].zw + ubo.pre_transform[iz].xy;
--	values.y = -values.y; // Flip to OpenXR coordinate system.
--
--	// Timewarp including scanline timewarp for rolling refresh panels.
--	values = ubo.transform_timewarp_scanout_begin[iz] * values * (1 - uv.y) +
--	         ubo.transform_timewarp_scanout_end[iz] * values * uv.y;
--	values.xy = values.xy * (1.0 / max(values.w, 0.00001));
--
--	// From [-1, 1] to [0, 1]
--	values.xy = values.xy * 0.5 + 0.5;
--
--	// Done.
--	return values.xy;
--}
--
--vec2 transform_uv(vec2 uv, uint iz)
--{
--	if (do_timewarp) {
--		uv = transform_uv_timewarp(uv, iz);
--	}
--
--	return transform_uv_subimage(uv, iz);
-+	return transpose(color_space) * color + vec3(0, 0.5, 0.5);
- }
- 
- void main()
- {
--	uint ix = gl_GlobalInvocationID.x;
--	uint iy = gl_GlobalInvocationID.y;
- 	uint iz = gl_GlobalInvocationID.z;
- 
- 	ivec2 offset = ivec2(ubo.views[iz].xy);
--	ivec2 extent = ivec2(ubo.views[iz].zw);
--
--	if (ix >= extent.x || iy >= extent.y) {
-+	uint iy = gl_GlobalInvocationID.y;
-+	uint ymin = foveation.y[MAX_DIM * iz + iy];
-+	uint ymax = foveation.y[MAX_DIM * iz + iy + 1];
-+	if (ymin == ymax)
- 		return;
-+	if (ymin > ymax)
-+	{
-+		uint tmp = ymin;
-+		ymin = ymax;
-+		ymax = tmp;
- 	}
-+	uint ix = gl_GlobalInvocationID.x;
- 
--	vec2 dist_uv = position_to_uv(extent, ix, iy);
--
--	vec2 r_uv = texture(distortion[iz + 0], dist_uv).xy;
--	vec2 g_uv = texture(distortion[iz + 2], dist_uv).xy;
--	vec2 b_uv = texture(distortion[iz + 4], dist_uv).xy;
-+	uint xmin = foveation.x[MAX_DIM * iz + ix];
-+	uint xmax = foveation.x[MAX_DIM * iz + ix + 1];
-+	if (xmin == xmax)
-+		return;
- 
--	// Do any transformation needed.
--	r_uv = transform_uv(r_uv, iz);
--	g_uv = transform_uv(g_uv, iz);
--	b_uv = transform_uv(b_uv, iz);
-+	uint xstep = (xmax - xmin + MAX_SAMPLES - 1) / MAX_SAMPLES;
-+	uint ystep = (ymax - ymin + MAX_SAMPLES - 1) / MAX_SAMPLES;
- 
--	// Sample the source with distorted and chromatic-aberration corrected samples.
--	vec4 colour = vec4(              //
--	    texture(source[iz], r_uv).r, //
--	    texture(source[iz], g_uv).g, //
--	    texture(source[iz], b_uv).b, //
--	    1);                          //
-+	vec4 colour = vec4(0);
-+	uint count = 0;
-+	for (uint y = ymin ; y < ymax; y += ystep) {
-+		for (uint x = xmin ; x < xmax; x += xstep) {
-+			colour += texelFetch(source[iz], ivec2(x, y), 0);
-+			++count;
-+		}
-+	}
-+	colour /= count;
-+	colour.xyz = rgb_to_ycbcr(from_linear_to_srgb(colour.rgb));
-+
-+	imageStore(luma, ivec3(ix, iy, iz), vec4(colour.x));
-+
-+	vec4 sum = colour;
-+	for (uint i = 0 ; i < gl_SubgroupSize; ++i)
-+	{
-+		uvec3 other = subgroupShuffle(gl_GlobalInvocationID, i);
-+		vec4 c = subgroupShuffle(colour, i);
-+		if (
-+			other == gl_GlobalInvocationID + uvec3(1, 0, 0)
-+			|| other == gl_GlobalInvocationID + uvec3(0, 1, 0)
-+			|| other == gl_GlobalInvocationID + uvec3(1, 1, 0))
-+		{
-+			sum += c;
-+		}
-+	}
- 
--	// Do colour correction here since there are no automatic conversion in hardware available.
--	colour = vec4(from_linear_to_srgb(colour.rgb), 1);
-+	if (ix %2 == 0 && iy %2 == 0)
-+	{
-+		// actual chroma
-+		imageStore(chroma, ivec3(gl_GlobalInvocationID.xy/2, iz), vec4(sum.y, sum.z, 0, 0) / 4);
- 
--	imageStore(target, ivec2(offset.x + ix, offset.y + iy), colour);
-+		// alpha in luma
-+		imageStore(luma, ivec3(offset.xy/2 + gl_GlobalInvocationID.xy/2, 2), vec4(sum.w, 0, 0, 0) / 4);
-+		imageStore(chroma, ivec3(offset.xy/2 + gl_GlobalInvocationID.xy/2, 2), vec4(0.5, 0.5, 0, 0));
-+	}
- }
-diff --git a/src/xrt/compositor/util/comp_high_level_render.c b/src/xrt/compositor/util/comp_high_level_render.c
-index d8bf54569..0dae0dfc8 100644
---- a/src/xrt/compositor/util/comp_high_level_render.c
-+++ b/src/xrt/compositor/util/comp_high_level_render.c
-@@ -194,14 +194,16 @@ chl_frame_state_cs_set_views(struct chl_frame_state *frame_state,
- void
- chl_frame_state_cs_set_target(struct chl_frame_state *frame_state,
-                               VkImage target_image,
--                              VkImageView target_storage_view,
-+                              VkImageView target_storage_view_y,
-+                              VkImageView target_storage_view_cbcr,
-                               const struct render_viewport_data views[XRT_MAX_VIEWS])
- {
- 	// Add the target info.
- 	comp_render_cs_add_target( //
- 	    &frame_state->data,    // data
- 	    target_image,          // target_image
--	    target_storage_view);  // target_unorm_view
-+	    target_storage_view_y,
-+	    target_storage_view_cbcr);  // target_unorm_view
- 
- 	for (uint32_t i = 0; i < frame_state->view_count; i++) {
- 		// Which image of the scratch images for this view are we using.
-diff --git a/src/xrt/compositor/util/comp_high_level_render.h b/src/xrt/compositor/util/comp_high_level_render.h
-index 55ee67f78..12fc6dd10 100644
---- a/src/xrt/compositor/util/comp_high_level_render.h
-+++ b/src/xrt/compositor/util/comp_high_level_render.h
-@@ -188,7 +188,8 @@ chl_frame_state_cs_set_views(struct chl_frame_state *frame_state,
- void
- chl_frame_state_cs_set_target(struct chl_frame_state *frame_state,
-                               VkImage target_image,
--                              VkImageView target_storage_view,
-+                              VkImageView target_storage_view_y,
-+                              VkImageView target_storage_view_cbcr,
-                               const struct render_viewport_data views[XRT_MAX_VIEWS]);
- 
- /*!
-@@ -206,7 +207,8 @@ chl_frame_state_cs_default_pipeline(struct chl_frame_state *frame_state,
-                                     const struct xrt_pose eye_poses[XRT_MAX_VIEWS],
-                                     const struct xrt_fov fovs[XRT_MAX_VIEWS],
-                                     VkImage target_image,
--                                    VkImageView target_storage_view,
-+                                    VkImageView target_storage_view_y,
-+                                    VkImageView target_storage_view_cbcr,
-                                     const struct render_viewport_data target_viewport_datas[XRT_MAX_VIEWS])
- {
- 	chl_frame_state_cs_set_views(  //
-@@ -220,7 +222,8 @@ chl_frame_state_cs_default_pipeline(struct chl_frame_state *frame_state,
- 	chl_frame_state_cs_set_target( //
- 	    frame_state,               //
- 	    target_image,              //
--	    target_storage_view,       //
-+	    target_storage_view_y,     //
-+	    target_storage_view_cbcr,  //
- 	    target_viewport_datas);    //
- 
- 	// Start the compute pipeline.
-diff --git a/src/xrt/compositor/util/comp_render.h b/src/xrt/compositor/util/comp_render.h
-index bd7ab2957..c2b95d68d 100644
---- a/src/xrt/compositor/util/comp_render.h
-+++ b/src/xrt/compositor/util/comp_render.h
-@@ -205,7 +205,8 @@ struct comp_render_dispatch_data
- 			VkImage image;
- 
- 			//! Target image view for distortion.
--			VkImageView storage_view;
-+			VkImageView storage_view_y;
-+			VkImageView storage_view_cbcr;
- 		} cs;
- 	} target;
- };
-@@ -509,14 +510,15 @@ comp_render_gfx_dispatch(struct render_gfx *render,
-  * @param target_storage_view Corresponding image view
-  */
- static inline void
--comp_render_cs_add_target(struct comp_render_dispatch_data *data, VkImage target_image, VkImageView target_storage_view)
-+comp_render_cs_add_target(struct comp_render_dispatch_data *data, VkImage target_image, VkImageView target_storage_view_y, VkImageView target_storage_view_cbcr)
- {
- 	// Error tracking.
- 	data->target.initialized = true;
- 
- 	// When writing into the target.
- 	data->target.cs.image = target_image;
--	data->target.cs.storage_view = target_storage_view;
-+	data->target.cs.storage_view_y = target_storage_view_y;
-+	data->target.cs.storage_view_cbcr = target_storage_view_cbcr;
- }
- 
- /*!
-@@ -618,7 +620,8 @@ comp_render_cs_layer(struct render_compute *render,
-                      const struct xrt_pose *world_pose_scanout_end,
-                      const struct xrt_pose *eye_pose,
-                      const VkImage target_image,
--                     const VkImageView target_image_view,
-+                     const VkImageView target_image_view_y,
-+                     const VkImageView target_image_view_cbcr,
-                      const struct render_viewport_data *target_view,
-                      bool do_timewarp);
- 
-diff --git a/src/xrt/compositor/util/comp_render_cs.c b/src/xrt/compositor/util/comp_render_cs.c
-index 6e93eabe8..4a304c6f7 100644
---- a/src/xrt/compositor/util/comp_render_cs.c
-+++ b/src/xrt/compositor/util/comp_render_cs.c
-@@ -370,7 +370,8 @@ crc_clear_output(struct render_compute *render, const struct comp_render_dispatc
- 	render_compute_clear(          //
- 	    render,                    //
- 	    d->target.cs.image,        //
--	    d->target.cs.storage_view, // target_image_view
-+	    d->target.cs.storage_view_y, // target_image_view_y
-+	    d->target.cs.storage_view_cbcr, // target_image_view_cbcr
- 	    target_viewport_datas);    // views
- }
- 
-@@ -396,9 +397,6 @@ crc_distortion_after_squash(struct render_compute *render, const struct comp_ren
- 	VkSampler src_samplers[XRT_MAX_VIEWS];
- 	struct render_viewport_data target_viewport_datas[XRT_MAX_VIEWS];
- 	struct xrt_normalized_rect src_norm_rects[XRT_MAX_VIEWS];
--	struct xrt_fov src_fovs[XRT_MAX_VIEWS];
--	struct xrt_pose world_poses_scanout_begin[XRT_MAX_VIEWS];
--	struct xrt_pose world_poses_scanout_end[XRT_MAX_VIEWS];
- 
- 	for (uint32_t i = 0; i < d->target.view_count; i++) {
- 		// Data to be filled in.
-@@ -416,36 +414,17 @@ crc_distortion_after_squash(struct render_compute *render, const struct comp_ren
- 		src_norm_rects[i] = src_norm_rect;
- 		src_samplers[i] = clamp_to_border_black;
- 		target_viewport_datas[i] = viewport_data;
--
--		if (d->do_timewarp) {
--			world_poses_scanout_begin[i] = d->views[i].world_pose_scanout_begin;
--			world_poses_scanout_end[i] = d->views[i].world_pose_scanout_end;
--			src_fovs[i] = d->views[i].fov;
--		}
- 	}
- 
--	if (!d->do_timewarp) {
--		render_compute_projection_no_timewarp( //
--		    render,                            //
--		    src_samplers,                      //
--		    src_image_views,                   //
--		    src_norm_rects,                    //
--		    d->target.cs.image,                //
--		    d->target.cs.storage_view,         // target_image_view
--		    target_viewport_datas);            // views
--	} else {
--		render_compute_projection_scanout_compensation( //
--		    render,                                     //
--		    src_samplers,                               //
--		    src_image_views,                            //
--		    src_norm_rects,                             //
--		    src_fovs,                                   //
--		    world_poses_scanout_begin,                  //
--		    world_poses_scanout_end,                    //
--		    d->target.cs.image,                         //
--		    d->target.cs.storage_view,                  // target_image_view
--		    target_viewport_datas);                     // views
--	}
-+	render_compute_projection(     //
-+	    render,                    //
-+	    src_samplers,              //
-+	    src_image_views,           //
-+	    src_norm_rects,            //
-+	    d->target.cs.image,        //
-+	    d->target.cs.storage_view_y, // target_image_view_y
-+	    d->target.cs.storage_view_cbcr, // target_image_view_cbcr
-+	    target_viewport_datas);    // views
- }
- 
- /// Fast path
-@@ -471,20 +450,12 @@ crc_distortion_fast_path(struct render_compute *render,
- 	VkSampler src_samplers[XRT_MAX_VIEWS];
- 	struct render_viewport_data target_viewport_datas[XRT_MAX_VIEWS];
- 	struct xrt_normalized_rect src_norm_rects[XRT_MAX_VIEWS];
--	struct xrt_fov src_fovs[XRT_MAX_VIEWS];
--	struct xrt_pose src_poses[XRT_MAX_VIEWS];
--	struct xrt_pose world_poses_scanout_begin[XRT_MAX_VIEWS];
--	struct xrt_pose world_poses_scanout_end[XRT_MAX_VIEWS];
- 
- 	for (uint32_t i = 0; i < d->target.view_count; i++) {
- 		// Data to be filled in.
- 		VkImageView src_image_view;
- 		struct render_viewport_data viewport_data;
- 		struct xrt_normalized_rect src_norm_rect;
--		struct xrt_fov src_fov;
--		struct xrt_pose src_pose;
--		struct xrt_pose world_pose_scanout_begin;
--		struct xrt_pose world_pose_scanout_end;
- 		uint32_t array_index = vds[i]->sub.array_index;
- 		const struct comp_swapchain_image *image = get_layer_image(layer, i, vds[i]->sub.image_index);
- 
-@@ -492,10 +463,6 @@ crc_distortion_fast_path(struct render_compute *render,
- 		src_image_view = get_image_view(image, data->flags, array_index);
- 		src_norm_rect = vds[i]->sub.norm_rect;
- 		viewport_data = d->views[i].target.viewport_data;
--		src_fov = vds[i]->fov;
--		src_pose = vds[i]->pose;
--		world_pose_scanout_begin = d->views[i].world_pose_scanout_begin;
--		world_pose_scanout_end = d->views[i].world_pose_scanout_end;
- 
- 		// No layer squasher has handled this for us already
- 		if (data->flip_y) {
-@@ -508,35 +475,17 @@ crc_distortion_fast_path(struct render_compute *render,
- 		src_norm_rects[i] = src_norm_rect;
- 		src_samplers[i] = clamp_to_border_black;
- 		target_viewport_datas[i] = viewport_data;
--		src_fovs[i] = src_fov;
--		src_poses[i] = src_pose;
--		world_poses_scanout_begin[i] = world_pose_scanout_begin;
--		world_poses_scanout_end[i] = world_pose_scanout_end;
- 	}
- 
--	if (!d->do_timewarp) {
--		render_compute_projection_no_timewarp( //
--		    render,                            //
--		    src_samplers,                      //
--		    src_image_views,                   //
--		    src_norm_rects,                    //
--		    d->target.cs.image,                //
--		    d->target.cs.storage_view,         //
--		    target_viewport_datas);            //
--	} else {
--		render_compute_projection_timewarp( //
--		    render,                         //
--		    src_samplers,                   //
--		    src_image_views,                //
--		    src_norm_rects,                 //
--		    src_poses,                      //
--		    src_fovs,                       //
--		    world_poses_scanout_begin,      //
--		    world_poses_scanout_end,        //
--		    d->target.cs.image,             //
--		    d->target.cs.storage_view,      //
--		    target_viewport_datas);         //
--	}
-+	render_compute_projection(          //
-+	    render,                         //
-+	    src_samplers,                   //
-+	    src_image_views,                //
-+	    src_norm_rects,                 //
-+	    d->target.cs.image,             //
-+	    d->target.cs.storage_view_y,    //
-+	    d->target.cs.storage_view_cbcr, //
-+	    target_viewport_datas);         //
- }
- 
- 
-@@ -556,7 +505,8 @@ comp_render_cs_layer(struct render_compute *render,
-                      const struct xrt_pose *world_pose_scanout_end,
-                      const struct xrt_pose *eye_pose,
-                      const VkImage target_image,
--                     const VkImageView target_image_view,
-+                     const VkImageView target_image_view_y,
-+                     const VkImageView target_image_view_cbcr,
-                      const struct render_viewport_data *target_view,
-                      bool do_timewarp)
- {
-@@ -564,9 +514,9 @@ comp_render_cs_layer(struct render_compute *render,
- 	VkSampler clamp_to_border_black = render->r->samplers.clamp_to_border_black;
- 
- 	// Not the transform of the views, but the inverse: actual view matrices.
--	struct xrt_matrix_4x4 world_view_mat_scanout_begin, eye_view;
-+	struct xrt_matrix_4x4 world_view_mat_scanout_begin, eye_view_mat;
- 	math_matrix_4x4_view_from_pose(world_pose_scanout_begin, &world_view_mat_scanout_begin);
--	math_matrix_4x4_view_from_pose(eye_pose, &eye_view);
-+	math_matrix_4x4_view_from_pose(eye_pose, &eye_view_mat);
- 
- 	struct render_buffer *ubo = &render->r->compute.layer.ubos[view_index];
- 	struct render_compute_layer_ubo_data *ubo_data = ubo->mapped;
-@@ -618,7 +568,7 @@ comp_render_cs_layer(struct render_compute *render,
- 		case XRT_LAYER_CYLINDER:
- 			do_cs_cylinder_layer(              //
- 			    layer,                         // layer
--			    &eye_view,                     // eye_view_mat
-+			    &eye_view_mat,                 // eye_view_mat
- 			    &world_view_mat_scanout_begin, // world_view_mat
- 			    view_index,                    // view_index
- 			    cur_layer,                     // cur_layer
-@@ -633,7 +583,7 @@ comp_render_cs_layer(struct render_compute *render,
- 		case XRT_LAYER_EQUIRECT2:
- 			do_cs_equirect2_layer(             //
- 			    layer,                         // layer
--			    &eye_view,                     // eye_view_mat
-+			    &eye_view_mat,                 // eye_view_mat
- 			    &world_view_mat_scanout_begin, // world_view_mat
- 			    view_index,                    // view_index
- 			    cur_layer,                     // cur_layer
-@@ -649,7 +599,7 @@ comp_render_cs_layer(struct render_compute *render,
- 		case XRT_LAYER_PROJECTION: {
- 			do_cs_projection_layer(       //
- 			    layer,                    // layer
--			    world_pose_scanout_begin, // world_pose_scanout_begin
-+			    world_pose_scanout_begin, // world_pose
- 			    view_index,               // view_index
- 			    cur_layer,                // cur_layer
- 			    cur_image,                // cur_image
-@@ -664,8 +614,8 @@ comp_render_cs_layer(struct render_compute *render,
- 		case XRT_LAYER_QUAD: {
- 			do_cs_quad_layer(                  //
- 			    layer,                         // layer
--			    &eye_view,                     // eye_view_mat
--			    &world_view_mat_scanout_begin, // world_view_mat_scanout_begin
-+			    &eye_view_mat,                 // eye_view_mat
-+			    &world_view_mat_scanout_begin, // world_view_mat
- 			    view_index,                    // view_index
- 			    cur_layer,                     // cur_layer
- 			    cur_image,                     // cur_image
-@@ -716,7 +666,8 @@ comp_render_cs_layer(struct render_compute *render,
- 	    src_samplers,      //
- 	    src_image_views,   //
- 	    cur_image,         //
--	    target_image_view, //
-+	    target_image_view_y, //
-+	    target_image_view_cbcr, //
- 	    target_view,       //
- 	    do_timewarp);      //
- }
-@@ -753,6 +704,7 @@ comp_render_cs_layers(struct render_compute *render,
- 		    &view->eye_pose,                 //
- 		    view->squash.image,              //
- 		    view->squash.cs.storage_view,    //
-+		    view->squash.cs.storage_view,    //
- 		    &view->squash.viewport_data,     //
- 		    d->do_timewarp);                 //
- 	}
--- 
-2.53.0
-

diff --git a/0005-d-steamvr_lh-prevent-crash-on-vive-pro2-WiVRn.patch b/0005-d-steamvr_lh-prevent-crash-on-vive-pro2-WiVRn.patch
new file mode 100644
index 0000000..698c0ad
--- /dev/null
+++ b/0005-d-steamvr_lh-prevent-crash-on-vive-pro2-WiVRn.patch
@@ -0,0 +1,25 @@
+From 7230746571d1256d32557fd99528ac90a1d75957 Mon Sep 17 00:00:00 2001
+From: no name <git-am@invalid>
+Date: Sun, 28 Sep 2025 11:33:10 +0200
+Subject: [PATCH 5/8] d/steamvr_lh: prevent crash on vive pro2/WiVRn
+
+---
+ src/xrt/drivers/steamvr_lh/steamvr_lh.cpp | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/xrt/drivers/steamvr_lh/steamvr_lh.cpp b/src/xrt/drivers/steamvr_lh/steamvr_lh.cpp
+index 347d22068..d34d3331e 100644
+--- a/src/xrt/drivers/steamvr_lh/steamvr_lh.cpp
++++ b/src/xrt/drivers/steamvr_lh/steamvr_lh.cpp
+@@ -985,7 +985,7 @@ steamvr_lh_create_devices(struct xrt_prober *xp, struct xrt_system_devices **out
+ 
+ 	// Include the HMD
+ 	if (svrs->ctx->hmd) {
+-		if (svrs->ctx->hmd->variant == VIVE_VARIANT_PRO2 && !svrs->ctx->hmd->init_vive_pro_2(xp)) {
++		if (xp && svrs->ctx->hmd->variant == VIVE_VARIANT_PRO2 && !svrs->ctx->hmd->init_vive_pro_2(xp)) {
+ 			U_LOG_IFL_W(level, "Found Vive Pro 2, but failed to initialize.");
+ 		}
+ 
+-- 
+2.54.0
+

diff --git a/0006-d-steamvr_lh-prevent-crash-on-vive-pro2-WiVRn.patch b/0006-d-steamvr_lh-prevent-crash-on-vive-pro2-WiVRn.patch
deleted file mode 100644
index f06c1e9..0000000
--- a/0006-d-steamvr_lh-prevent-crash-on-vive-pro2-WiVRn.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-From 9d1294834f49fc90ea22f5d841d7c0e5c0c1045d Mon Sep 17 00:00:00 2001
-From: no name <git-am@invalid>
-Date: Sun, 28 Sep 2025 11:33:10 +0200
-Subject: [PATCH 6/8] d/steamvr_lh: prevent crash on vive pro2/WiVRn
-
----
- src/xrt/drivers/steamvr_lh/steamvr_lh.cpp | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/src/xrt/drivers/steamvr_lh/steamvr_lh.cpp b/src/xrt/drivers/steamvr_lh/steamvr_lh.cpp
-index 25c68a0ea..86baa9fd4 100644
---- a/src/xrt/drivers/steamvr_lh/steamvr_lh.cpp
-+++ b/src/xrt/drivers/steamvr_lh/steamvr_lh.cpp
-@@ -913,7 +913,7 @@ steamvr_lh_create_devices(struct xrt_prober *xp, struct xrt_system_devices **out
- 
- 	// Include the HMD
- 	if (svrs->ctx->hmd) {
--		if (svrs->ctx->hmd->variant == VIVE_VARIANT_PRO2 && !svrs->ctx->hmd->init_vive_pro_2(xp)) {
-+		if (xp && svrs->ctx->hmd->variant == VIVE_VARIANT_PRO2 && !svrs->ctx->hmd->init_vive_pro_2(xp)) {
- 			U_LOG_IFL_W(level, "Found Vive Pro 2, but failed to initialize.");
- 		}
- 
--- 
-2.53.0
-

diff --git a/0006-st-oxr-push-XrEventDataInteractionProfileChanged-whe.patch b/0006-st-oxr-push-XrEventDataInteractionProfileChanged-whe.patch
new file mode 100644
index 0000000..44f0322
--- /dev/null
+++ b/0006-st-oxr-push-XrEventDataInteractionProfileChanged-whe.patch
@@ -0,0 +1,27 @@
+From f400f0e63259bcadd9a7955ae0275caa5aea3ded Mon Sep 17 00:00:00 2001
+From: Sapphire <imsapphire0@gmail.com>
+Date: Fri, 7 Nov 2025 20:41:16 -0600
+Subject: [PATCH 6/8] st/oxr: push XrEventDataInteractionProfileChanged when
+ profile changes to NULL
+
+---
+ src/xrt/state_trackers/oxr/actions/oxr_input.c | 3 ---
+ 1 file changed, 3 deletions(-)
+
+diff --git a/src/xrt/state_trackers/oxr/actions/oxr_input.c b/src/xrt/state_trackers/oxr/actions/oxr_input.c
+index 2bd3ea009..93659ba35 100644
+--- a/src/xrt/state_trackers/oxr/actions/oxr_input.c
++++ b/src/xrt/state_trackers/oxr/actions/oxr_input.c
+@@ -1932,9 +1932,6 @@ session_update_action_bindings(struct oxr_logger *log,
+ #define POPULATE_PROFILE(X)                                                                                            \
+ 	do {                                                                                                           \
+ 		XrPath path = profiles.X != NULL ? profiles.X->path : XR_NULL_PATH;                                    \
+-		if (path == XR_NULL_PATH) {                                                                            \
+-			break; /* Only update on "active" interaction profiles per sub-action path. */                 \
+-		}                                                                                                      \
+ 		if (action_context->X != path) {                                                                       \
+ 			action_context->X = path;                                                                      \
+ 			interaction_profile_changed = true;                                                            \
+-- 
+2.54.0
+

diff --git a/0007-don-t-verify-GL-stuff.patch b/0007-don-t-verify-GL-stuff.patch
new file mode 100644
index 0000000..d3b28c4
--- /dev/null
+++ b/0007-don-t-verify-GL-stuff.patch
@@ -0,0 +1,33 @@
+From 0832cc9a2ccd0f67b3bd3a11ec1b1d1398dfebda Mon Sep 17 00:00:00 2001
+From: no name <git-am@invalid>
+Date: Sun, 25 Jan 2026 10:09:10 +0100
+Subject: [PATCH 7/8] don't verify GL stuff
+
+---
+ src/xrt/state_trackers/oxr/oxr_verify.c | 10 ----------
+ 1 file changed, 10 deletions(-)
+
+diff --git a/src/xrt/state_trackers/oxr/oxr_verify.c b/src/xrt/state_trackers/oxr/oxr_verify.c
+index 8f35222cf..1418a8231 100644
+--- a/src/xrt/state_trackers/oxr/oxr_verify.c
++++ b/src/xrt/state_trackers/oxr/oxr_verify.c
+@@ -610,16 +610,6 @@ oxr_verify_XrGraphicsBindingOpenGLXlibKHR(struct oxr_logger *log, const XrGraphi
+ 		                 "XrGraphicsBindingOpenGLXlibKHR::glxDrawable is NULL");
+ 	}
+ 
+-	if (next->glxFBConfig == NULL) {
+-		return oxr_error(log, XR_ERROR_GRAPHICS_DEVICE_INVALID,
+-		                 "XrGraphicsBindingOpenGLXlibKHR::glxFBConfig is NULL");
+-	}
+-
+-	if (next->visualid == 0) {
+-		return oxr_error(log, XR_ERROR_GRAPHICS_DEVICE_INVALID,
+-		                 "XrGraphicsBindingOpenGLXlibKHR::visualid is 0");
+-	}
+-
+ 	return XR_SUCCESS;
+ }
+ 
+-- 
+2.54.0
+

diff --git a/0007-st-oxr-push-XrEventDataInteractionProfileChanged-whe.patch b/0007-st-oxr-push-XrEventDataInteractionProfileChanged-whe.patch
deleted file mode 100644
index fddf9dc..0000000
--- a/0007-st-oxr-push-XrEventDataInteractionProfileChanged-whe.patch
+++ /dev/null
@@ -1,49 +0,0 @@
-From b9af535cf229acdbf7f1b534e9804c1b4e3fa3e1 Mon Sep 17 00:00:00 2001
-From: Sapphire <imsapphire0@gmail.com>
-Date: Fri, 7 Nov 2025 20:41:16 -0600
-Subject: [PATCH 7/8] st/oxr: push XrEventDataInteractionProfileChanged when
- profile changes to NULL
-
----
- src/xrt/state_trackers/oxr/oxr_input.c | 15 +++++----------
- 1 file changed, 5 insertions(+), 10 deletions(-)
-
-diff --git a/src/xrt/state_trackers/oxr/oxr_input.c b/src/xrt/state_trackers/oxr/oxr_input.c
-index df2b479eb..c4b36ba81 100644
---- a/src/xrt/state_trackers/oxr/oxr_input.c
-+++ b/src/xrt/state_trackers/oxr/oxr_input.c
-@@ -1881,26 +1881,21 @@ oxr_session_update_action_bindings(struct oxr_logger *log, struct oxr_session *s
- 		}
- 	}
- 
--	/*
--	 * This code will only send events (and update the bindings) if there
--	 * is a profile mapped to the subaction path. Meaning it won't update
--	 * the cache or generate events when a controller goes away, basically
--	 * latching the interaction profile to the last active device.
--	 */
-+	bool any_profile_changed = false;
- #define POPULATE_PROFILE(X)                                                                                            \
- 	do {                                                                                                           \
- 		XrPath path = profiles.X != NULL ? profiles.X->path : XR_NULL_PATH;                                    \
--		if (path == XR_NULL_PATH) {                                                                            \
--			break; /* Only update on "active" interaction profiles per sub-action path. */                 \
--		}                                                                                                      \
- 		if (sess->X != path) {                                                                                 \
- 			sess->X = path;                                                                                \
--			oxr_event_push_XrEventDataInteractionProfileChanged(log, sess);                                \
-+			any_profile_changed = true;                                                                    \
- 		}                                                                                                      \
- 	} while (false);
- 	OXR_FOR_EACH_VALID_SUBACTION_PATH(POPULATE_PROFILE)
- #undef POPULATE_PROFILE
- 
-+	if (any_profile_changed) {
-+		oxr_event_push_XrEventDataInteractionProfileChanged(log, sess);
-+	}
- 	return oxr_session_success_result(sess);
- }
- 
--- 
-2.53.0
-

diff --git a/0008-Don-t-get-pose-data-for-fast-path.patch b/0008-Don-t-get-pose-data-for-fast-path.patch
deleted file mode 100644
index febab3b..0000000
--- a/0008-Don-t-get-pose-data-for-fast-path.patch
+++ /dev/null
@@ -1,40 +0,0 @@
-From 02206ede3aae832be5024263a805cafee2264080 Mon Sep 17 00:00:00 2001
-From: no name <git-am@invalid>
-Date: Thu, 15 Jan 2026 12:13:06 +0100
-Subject: [PATCH 8/8] Don't get pose data for fast path
-
----
- src/xrt/compositor/main/comp_renderer.c | 17 +++++++++--------
- 1 file changed, 9 insertions(+), 8 deletions(-)
-
-diff --git a/src/xrt/compositor/main/comp_renderer.c b/src/xrt/compositor/main/comp_renderer.c
-index ff9728a59..08cdef540 100644
---- a/src/xrt/compositor/main/comp_renderer.c
-+++ b/src/xrt/compositor/main/comp_renderer.c
-@@ -972,14 +972,15 @@ dispatch_compute(struct comp_renderer *r,
- 	struct xrt_pose world_poses_scanout_begin[XRT_MAX_VIEWS];
- 	struct xrt_pose world_poses_scanout_end[XRT_MAX_VIEWS];
- 	struct xrt_pose eye_poses[XRT_MAX_VIEWS];
--	calc_pose_data(                //
--	    r,                         //
--	    fov_source,                //
--	    fovs,                      //
--	    world_poses_scanout_begin, //
--	    world_poses_scanout_end,   //
--	    eye_poses,                 //
--	    render->r->view_count);    //
-+	if (!c->base.frame_params.one_projection_layer_fast_path)
-+		calc_pose_data(                //
-+		    r,                         //
-+		    fov_source,                //
-+		    fovs,                      //
-+		    world_poses_scanout_begin, //
-+		    world_poses_scanout_end,   //
-+		    eye_poses,                 //
-+		    render->r->view_count);    //
- 
- 	// Target Vulkan resources..
- 	VkImage target_image = r->c->target->images[r->acquired_buffer].handle;
--- 
-2.53.0
-

diff --git a/0008-configure-u_git_tag-in-WiVRn.patch b/0008-configure-u_git_tag-in-WiVRn.patch
new file mode 100644
index 0000000..2ba5f58
--- /dev/null
+++ b/0008-configure-u_git_tag-in-WiVRn.patch
@@ -0,0 +1,37 @@
+From d79de5d82def9641484b8d88212d3c2e97e38734 Mon Sep 17 00:00:00 2001
+From: no name <git-am@invalid>
+Date: Fri, 20 Mar 2026 16:51:18 +0100
+Subject: [PATCH 8/8] configure u_git_tag in WiVRn
+
+---
+ src/xrt/auxiliary/util/CMakeLists.txt | 7 +------
+ 1 file changed, 1 insertion(+), 6 deletions(-)
+
+diff --git a/src/xrt/auxiliary/util/CMakeLists.txt b/src/xrt/auxiliary/util/CMakeLists.txt
+index 79646b181..21adcd446 100644
+--- a/src/xrt/auxiliary/util/CMakeLists.txt
++++ b/src/xrt/auxiliary/util/CMakeLists.txt
+@@ -10,11 +10,6 @@
+ # by applications like the OpenXR runtime library.
+ #
+ 
+-configure_file(
+-	"${CMAKE_CURRENT_SOURCE_DIR}/u_git_tag.c.in" "${CMAKE_CURRENT_BINARY_DIR}/u_git_tag.c"
+-	@ONLY
+-	)
+-
+ add_library(
+ 	aux_util STATIC
+ 	u_autoexpgain.c
+@@ -120,7 +115,7 @@ add_library(
+ 	u_worker.cpp
+ 	u_worker.h
+ 	u_worker.hpp
+-	"${CMAKE_CURRENT_BINARY_DIR}/u_git_tag.c"
++	"${U_GIT_TAG_CPP}"
+ 	)
+ target_link_libraries(
+ 	aux_util
+-- 
+2.54.0
+

diff --git a/0009-don-t-verify-GL-stuff.patch b/0009-don-t-verify-GL-stuff.patch
deleted file mode 100644
index 520c543..0000000
--- a/0009-don-t-verify-GL-stuff.patch
+++ /dev/null
@@ -1,33 +0,0 @@
-From 6f17ee6c92b62a2418164f627775f267eb6d19fc Mon Sep 17 00:00:00 2001
-From: no name <git-am@invalid>
-Date: Sun, 25 Jan 2026 10:09:10 +0100
-Subject: [PATCH] don't verify GL stuff
-
----
- src/xrt/state_trackers/oxr/oxr_verify.c | 10 ----------
- 1 file changed, 10 deletions(-)
-
-diff --git a/src/xrt/state_trackers/oxr/oxr_verify.c b/src/xrt/state_trackers/oxr/oxr_verify.c
-index e9197d501..71f81c954 100644
---- a/src/xrt/state_trackers/oxr/oxr_verify.c
-+++ b/src/xrt/state_trackers/oxr/oxr_verify.c
-@@ -608,16 +608,6 @@ oxr_verify_XrGraphicsBindingOpenGLXlibKHR(struct oxr_logger *log, const XrGraphi
- 		                 "XrGraphicsBindingOpenGLXlibKHR::glxDrawable is NULL");
- 	}
- 
--	if (next->glxFBConfig == NULL) {
--		return oxr_error(log, XR_ERROR_GRAPHICS_DEVICE_INVALID,
--		                 "XrGraphicsBindingOpenGLXlibKHR::glxFBConfig is NULL");
--	}
--
--	if (next->visualid == 0) {
--		return oxr_error(log, XR_ERROR_GRAPHICS_DEVICE_INVALID,
--		                 "XrGraphicsBindingOpenGLXlibKHR::visualid is 0");
--	}
--
- 	return XR_SUCCESS;
- }
- 
--- 
-2.52.0
-

diff --git a/sources b/sources
index e5724b9..c0b769b 100644
--- a/sources
+++ b/sources
@@ -1,2 +1,2 @@
-SHA512 (WiVRn-v26.2.3.tar.gz) = 95f15cc827f86e98f01fe2791e8acc1a641853765ce355ca8f124b3364eb600aa839d8d7e54447af9bbb42cef40f83c6426c930f019ae1b8db416d1be89dcd4f
-SHA512 (monado-src-723652b545a79609f9f04cb89fcbf807d9d6451a.tar.bz2) = 37770e8bbde48e701365148804cac5260765d50f376e0a0a283b7b34279faf1a9889d1ced843999e00b2ff6734452896a2a7d5c061946450c7d89a83eced8765
+SHA512 (WiVRn-v26.6.tar.gz) = dd3c948348981ad4cf62b16a52b950e3c9e8827dc8c83c733af23e9cc35f51434d6e9f798dda323adc29dc3b1e167c5c29f390fec2469183e45c096ea358e84c
+SHA512 (monado-src-1b526bb3a0ff326ecd05af4c2c541407f53c6d4b.tar.bz2) = 662bf90d5a38e05c5909ed8d1a5c099979ae49ec6f7a71552a9d0c625ddda29f6b631e0feca8a01a6bb6eefcd6aacfbc81207f2852466165c561973df1cddf97

diff --git a/wivrn.spec b/wivrn.spec
index 1d70cc6..d8ec7bb 100644
--- a/wivrn.spec
+++ b/wivrn.spec
@@ -7,13 +7,13 @@
 # WiVRn is based on Monado, we need the full source
 # Monado base source (find in monado-rev file)
 %global forgeurl1      https://gitlab.freedesktop.org/monado/monado
-%global commit1        723652b545a79609f9f04cb89fcbf807d9d6451a
+%global commit1        1b526bb3a0ff326ecd05af4c2c541407f53c6d4b
 %global monado_version 25.1.0
 
 %forgemeta
 
 Name:           wivrn
-Version:        26.2.3
+Version:        26.6
 Release:        %autorelease
 Summary:        An OpenXR streaming application to a standalone headset
 
@@ -103,15 +103,14 @@ Patch0003:      https://raw.githubusercontent.com/WiVRn/WiVRn/refs/tags/%{tag0}/
 # downstream-only - WiVRn specific Monado patches
 Patch0004:      https://raw.githubusercontent.com/WiVRn/WiVRn/refs/tags/%{tag0}/patches/monado/0004-st-oxr-forward-0-refresh-rate.patch
 # downstream-only - WiVRn specific Monado patches
-Patch0005:      https://raw.githubusercontent.com/WiVRn/WiVRn/refs/tags/%{tag0}/patches/monado/0005-Replace-distortion-with-foveation.patch
+Patch0005:      https://raw.githubusercontent.com/WiVRn/WiVRn/refs/tags/%{tag0}/patches/monado/0005-d-steamvr_lh-prevent-crash-on-vive-pro2-WiVRn.patch
 # downstream-only - WiVRn specific Monado patches
-Patch0006:      https://raw.githubusercontent.com/WiVRn/WiVRn/refs/tags/%{tag0}/patches/monado/0006-d-steamvr_lh-prevent-crash-on-vive-pro2-WiVRn.patch
+Patch0006:      https://raw.githubusercontent.com/WiVRn/WiVRn/refs/tags/%{tag0}/patches/monado/0006-st-oxr-push-XrEventDataInteractionProfileChanged-whe.patch
 # downstream-only - WiVRn specific Monado patches
-Patch0007:      https://raw.githubusercontent.com/WiVRn/WiVRn/refs/tags/%{tag0}/patches/monado/0007-st-oxr-push-XrEventDataInteractionProfileChanged-whe.patch
+Patch0007:      https://raw.githubusercontent.com/WiVRn/WiVRn/refs/tags/%{tag0}/patches/monado/0007-don-t-verify-GL-stuff.patch
 # downstream-only - WiVRn specific Monado patches
-Patch0008:      https://raw.githubusercontent.com/WiVRn/WiVRn/refs/tags/%{tag0}/patches/monado/0008-Don-t-get-pose-data-for-fast-path.patch
-# downstream-only - WiVRn specific Monado patches
-Patch0009:      https://raw.githubusercontent.com/WiVRn/WiVRn/refs/tags/%{tag0}/patches/monado/0009-don-t-verify-GL-stuff.patch
+Patch0008:      https://raw.githubusercontent.com/WiVRn/WiVRn/refs/tags/%{tag0}/patches/monado/0008-configure-u_git_tag-in-WiVRn.patch
+
 
 # If BuildRequires change, be sure to update envision-wivrn Requires
 # https://src.fedoraproject.org/rpms/envision/blob/rawhide/f/envision.spec
@@ -188,6 +187,7 @@ BuildRequires:  qcoro-qt6-devel
 BuildRequires:  qt6-qtbase-private-devel
 BuildRequires:  qt6-qtdeclarative-devel
 BuildRequires:  qt6qml(org.kde.desktop)
+BuildRequires:  spirv-tools
 BuildRequires:  systemd-rpm-macros
 
 Requires:       android-tools
@@ -248,7 +248,6 @@ pushd _deps/monado-src
 %patch -P0006 -p1
 %patch -P0007 -p1
 %patch -P0008 -p1
-%patch -P0009 -p1
 popd
 
 
@@ -261,6 +260,7 @@ popd
   -DFETCHCONTENT_BASE_DIR="_deps" \
   -DFETCHCONTENT_FULLY_DISCONNECTED=ON \
   -DGIT_DESC=v%{version} \
+  -DGIT_COMMIT=v%{version} \
   -DOVR_COMPAT_SEARCH_PATH=%{_libdir}/opencomposite/runtime \
   -DWIVRN_BUILD_CLIENT=OFF \
   -DWIVRN_BUILD_DASHBOARD=ON \

^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2026-06-11 15:15 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-06-11 15:15 [rpms/wivrn] f44: Update to 26.6 (fedora#2487858) Jonathan Steffan

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox