diff --git a/Containerfile b/Containerfile
index a1c689c4..f63b1567 100644
--- a/Containerfile
+++ b/Containerfile
@@ -172,6 +172,20 @@ RUN rpm-ostree override replace \
--from repo=updates \
libmount \
|| true && \
+ rpm-ostree override replace \
+ --experimental \
+ --from repo=updates-archive \
+ glibc-headers \
+ glibc-devel \
+ || true && \
+ rpm-ostree override replace \
+ --experimental \
+ --from repo=updates \
+ glibc \
+ glibc-common \
+ glibc-all-langpacks \
+ glibc-gconv-extra \
+ || true && \
rpm-ostree override remove \
glibc32 \
|| true
@@ -200,7 +214,9 @@ RUN rpm-ostree override replace \
bluez-cups \
bluez-libs \
bluez-obexd \
- xorg-x11-server-Xwayland
+ xorg-x11-server-Xwayland && \
+ rpm-ostree install \
+ mesa-vdpau-drivers-freeworld.x86_64
# Remove unneeded packages
RUN rpm-ostree override remove \
@@ -268,7 +284,13 @@ RUN rpm-ostree install \
glow \
gum \
setools \
- redhat-lsb-core && \
+ redhat-lsb-core \
+ cockpit-networkmanager \
+ cockpit-podman \
+ cockpit-selinux \
+ cockpit-system \
+ cockpit-navigator \
+ cockpit-storaged && \
pip install --prefix=/usr topgrade && \
rpm-ostree install \
ublue-update && \
@@ -287,7 +309,6 @@ RUN rpm-ostree install \
at-spi2-core.i686 \
atk.i686 \
vulkan-loader.i686 \
- mesa-vulkan-drivers.i686 \
alsa-lib.i686 \
fontconfig.i686 \
gtk2.i686 \
@@ -310,10 +331,14 @@ RUN rpm-ostree install \
libatomic.i686 \
pipewire-alsa.i686 \
clinfo && \
+ sed -i '0,/enabled=1/s//enabled=0/' /etc/yum.repos.d/fedora-updates.repo && \
+ rpm-ostree install \
+ mesa-vulkan-drivers.i686 \
+ mesa-va-drivers-freeworld.i686 \
+ mesa-vdpau-drivers-freeworld.i686 && \
sed -i '0,/enabled=0/s//enabled=1/' /etc/yum.repos.d/rpmfusion-nonfree-steam.repo && \
sed -i '0,/enabled=1/s//enabled=0/' /etc/yum.repos.d/rpmfusion-nonfree.repo && \
sed -i '0,/enabled=1/s//enabled=0/' /etc/yum.repos.d/rpmfusion-nonfree-updates.repo && \
- sed -i '0,/enabled=1/s//enabled=0/' /etc/yum.repos.d/fedora-updates.repo && \
rpm-ostree install \
steam && \
sed -i '0,/enabled=1/s//enabled=0/' /etc/yum.repos.d/rpmfusion-nonfree-steam.repo && \
diff --git a/README-SPA.md b/README-SPA.md
index facd0cfe..50cedf90 100644
--- a/README-SPA.md
+++ b/README-SPA.md
@@ -13,15 +13,16 @@
- [Características de **todas** las imágenes de Bazzite](#about--features)
- [Características de las imágenes para **Computadoras de Escritorio**](#desktop)
- [Características de las imágenes para **Steam Deck/HTPC**](#steam-deckhome-theater-pcs-htpcs)
- - [Computadoras Handheld Alternativas](#alternative-handhelds)
+ - [Computadoras Handheld Alternativas](#alternative-handhelds)
- [Características de las imágenes con el entorno de escritorio **GNOME**](#gnome)
- [Características del Upstream](#features-from-upstream)
- [¿Por qué?](#why)
- [Mira como luce Bazzite (Capturas de Pantalla)](#showcase)
- [Documentación y Boletín informativo/Newsletters (En inglés)](#documentation--newsletters)
- [Paquetes Personalizados](#custom-packages)
+- [Verificación de la Imagen](#verification)
- [Arranque Seguro (Secure Boot)](#secure-boot)
-- [Verificación y Métricas](#verification)
+- [Métricas](#contributor-metrics)
- [Gracias Especiales](#special-thanks)
- [Créalo tu Mismo](#build-your-own)
- [Comunidad (en inglés)](#join-the-community)
@@ -39,16 +40,16 @@ Bazzite es creado con [ublue-os/main](https://github.com/ublue-os/main) y [ublue
- Utilizamos el [kernel fsync](https://copr.fedorainfracloud.org/coprs/sentry/kernel-fsync/) para obtener compatibilidad con HDR (alto rango dinámico) y un soporte expandido de hardware, además de otra gran cantidad de parches incluidos.
- HDR esta disponible en la sesión de Gamescope.
- Drivers propietarios de NVIDIA pre-instalados.
-- El nuevo driver de Vulkan, NVK, esta disponibles en imágenes sin el driver proprietario de NVIDIA.
- Soporte total de decodificación acelerada por hardware del codec de video H264.
- Soporte completo para los tiempos de ejecución (runtimes) de ROCM OpenCL/HIP de AMD
-- Drivers [xone](https://github.com/medusalix/xone), [xpadneo](https://github.com/atar-axis/xpadneo), y [xpad-noone](https://github.com/ublue-os/xpad-noone) para mandos de videojuegos de Xbox.
+- Se incluye el driver [xone](https://github.com/medusalix/xone), para mandos de videojuegos de Xbox.
- Soporte completo de [DisplayLink](https://www.synaptics.com/products/displaylink-graphics).
- Incluye los temas para KDE de SteamOS, hechos por Valve.
- También se incluyen temas opcionales de GTK3/4 inspirados en Valve, que igualan a los temas Vapor y VGUI2 de SteamOS. Para poderlos utilizar, solo tienes que instalar [Gradience](https://flathub.org/apps/com.github.GradienceTeam.Gradience).
- [LatencyFleX](https://github.com/ishitatsuyuki/LatencyFleX), [vkBasalt](https://github.com/DadSchoorse/vkBasalt), [MangoHud](https://github.com/flightlessmango/Mangohud), y [OBS VkCapture](https://github.com/nowrep/obs-vkcapture) instalados y disponibles por defecto.
+- Utilizamos [TuneD](https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html/monitoring_and_managing_system_status_and_performance/getting-started-with-tuned_monitoring-and-managing-system-status-and-performance) en lugar de PPD, para una integración completa con GNOME, KDE, y Game Mode. Esta es una herramienta tan increiblemente poderosa, que Red Hat ofrece [clases para aprender a utilizarla](https://www.redhat.com/en/services/training/rh442-red-hat-enterprise-performance-tuning).
- Soporte para [Wallpaper Engine](https://www.wallpaperengine.io/en). (Solo en KDE)
-- Incluida la [extensión de la shell para mostrar las propiedades de ROMs](https://github.com/GerbilSoft/rom-properties) (usados para la emulación de consolas) en el navegador de archivos.
+- Incluida una [extensión de la shell para mostrar las propiedades de ROMs](https://github.com/GerbilSoft/rom-properties) (usados para la emulación de consolas) en el navegador de archivos.
- Soporte completo para [Winesync/Fastsync/NTsync](https://github.com/Frogging-Family/wine-tkg-git/issues/936).
- [Distrobox](https://github.com/89luca89/distrobox) pre-instalado con actualizaciones automáticas para los contenedores creados.
- Se usa por defecto la [terminal Prompt](https://gitlab.gnome.org/chergert/prompt) en todas las imágenes. Esta terminal esta especificamente diseñada para el flujo de trabajo basado en contenedores que usamos en Bazzite. Si deseas regresar a como estaba antes, simplemente ejecuta el siguiente comando en una terminal: `ujust restore-original-terminal`
@@ -59,7 +60,6 @@ Bazzite es creado con [ublue-os/main](https://github.com/ublue-os/main) y [ublue
- Uso del [control de congestión TCP BBR hecho por Google](https://github.com/google/bbr) por defecto.
- [Input Remapper](https://github.com/sezanzeb/input-remapper) pre-instalado y habilitado. (Disponible pero desactivado por defecto en la variante Deck, puede ser habilitado ejecutando el siguiente comando en una terminal: `ujust restore-input-remapper`)
- El portal de Bazzite (Bazzite Portal) provee una manera fácil de instalar un sin fin de aplicaciones y ajustes, incluyendo la instalación de [LACT](https://github.com/ilya-zlobintsev/LACT) (para mejor controlar tu GPU de AMD) y [GreenWithEnvy](https://gitlab.com/leinardi/gwe) (para mejor controlar tu GPU de NVIDIA).
-- Gestor de paquetes [Nix](https://nixos.org/) con la opción de instalar [Fleek](https://getfleek.dev/) usando el `ujust`.
- Opción para instalar el gestor de paquetes [Brew](https://brew.sh/) usando el Bazzite Portal.
- [Waydroid](https://waydro.id/) pre-instalado para correr aplicaciones de Android. Para configurarlo, usa esta [guía rápida (en inglés)](https://universal-blue.discourse.group/docs?topic=32).
- Administra tus aplicaciones usando [Flatseal](https://github.com/tchx84/Flatseal), [Warehouse](https://github.com/flattool/warehouse), y [Gear Lever](https://github.com/mijorus/gearlever).
@@ -69,7 +69,7 @@ Bazzite es creado con [ublue-os/main](https://github.com/ublue-os/main) y [ublue
- Driver [GCAdapter_OC](https://github.com/hannesmann/gcadapter-oc-kmod) para aumentar la frecuencia del reloj (overclocking) del adaptador para el mando de videojuegos del Gamecube de Nintendo para obtener una taza de sondeo (polling rate) de 1000hz.
- Soporte fuera de la caja para los teclados hechos por [Wooting](https://wooting.io/).
- Soporte incorporado de las GPU de las familias (HD 7000) y Sea Islands (HD 8000) de AMD bajo el driver `amdgpu`.
-- Un parche esta disponible [para un bug en juegos de 32 bits que usen el motor Source 1](https://github.com/ValveSoftware/Source-1-Games/issues/5043)[(Por ejemplo: TF2)](https://github.com/ValveSoftware/Source-1-Games/issues/5043) que provoca que el juego se bloqueé al ser iniciado, para aplicar el parche, ejecuta el siguiente comando en una terminal: `ujust patch-source1-tcmalloc`
+- Un parche esta disponible [para un bug en juegos de 32 bits que usen el motor Source 1](https://github.com/ValveSoftware/Source-1-Games/issues/5043)[(Por ejemplo: TF2)](https://github.com/ValveSoftware/Source-1-Games/issues/5043) que provoca que el juego se congele al ser iniciado, para aplicar el parche, ejecuta el siguiente comando en una terminal: `ujust patch-source1-tcmalloc`
- [XwaylandVideoBridge](https://invent.kde.org/system/xwaylandvideobridge) esta disponible para hacer posible compartir tu pantalla con Discord usando Wayland.
- [Webapp Manager](https://github.com/linuxmint/webapp-manager) esta disponible para crear aplicaciones de sitios web con una variedad de navegadores web, incluyendo Firefox.
@@ -96,7 +96,7 @@ Si deseas realizar un rebase a la imagen **para computadoras de escritorio con u
rpm-ostree rebase ostree-unverified-registry:ghcr.io/ublue-os/bazzite-nvidia:stable
```
-**Para usuarios con Secure Boot habilitado:** Ejecuta el comando `ujust enroll-secure-boot-key` en una terminal e introduce la contraseña `ublue-os` si el sistema te lo requiere para registrar la clave de seguridad requerida.
+**Para usuarios con Secure Boot habilitado:** Sigue nuestra [documentación para usuarios de Secure Boot](#secure-boot) antes de cambiar la base.
### Steam Deck/Computadoras para Cine en Casa (HTPCs)
@@ -105,7 +105,7 @@ rpm-ostree rebase ostree-unverified-registry:ghcr.io/ublue-os/bazzite-nvidia:sta
Esta variante esta diseñada para usarse como una alternativa de SteamOS en la Steam Deck, e igualmente para proporcionar una experiencia como de consola de videojuegos en HTPCs y otros dispositivos portátiles, disponible como `bazzite-deck`:
-- Al arrancar tu dispositivo, inicia directamente en el modo de juego (Gamemode), emulando el mismo comportamiento que SteamOS.
+- Al arrancar tu dispositivo, inicia directamente en Game Mode, emulando el mismo comportamiento que SteamOS.
- **Se aplica el servicio `duperemove` automáticamente el cual recorta por mucho el tamaño del directorio compatdata, el directorio usado por Proton para almacenar los prefijos de WINE para correr juegos de Windows en Linux.**
- **Incluye la versión mas actual de Mesa, el cual crea cachés de shaders mas pequeños, y los cuales no son requeridos para prevenir tirones/parones.**
- **Habilidad de arrancar el sistema incluso si el disco esta lleno.**
@@ -117,7 +117,7 @@ Esta variante esta diseñada para usarse como una alternativa de SteamOS en la S
- Incluye los parches de [SteamOS BTRFS](https://gitlab.com/popsulfr/steamos-btrfs) por defecto, los cuales proveen soporte completo del sistema de archivos BTRFS para tarjetas SD.
- Se incluye una copia portada de [SDGyroDSU](https://github.com/kmicki/SteamDeckGyroDSU), habilitada por defecto.
- Opción para instalar [Decky Loader](https://github.com/SteamDeckHomebrew/decky-loader), [EmuDeck](https://www.emudeck.com/), [RetroDECK](https://retrodeck.net/), y [ProtonUp-Qt](https://davidotek.github.io/protonup-qt/), ademas de un sin fin de paquetes útiles al momento de instalar el sistema.
-- Un sistema personalizado de actualizaciones que permite que tanto el sistema operativo, los Flatpaks, los paquetes Nix (Usando Fleek), y las imagenes de Distrobox sean actualizables directamente desde la interfaz de Gamemode.
+- Un sistema personalizado de actualizaciones que permite que tanto el sistema operativo, los Flatpaks, los paquetes Nix (Usando Fleek), y las imagenes de Distrobox sean actualizables directamente desde la interfaz de Gamemode gracias al poder de [ublue-update](https://github.com/ublue-os/ublue-update) y [topgrade](https://github.com/topgrade-rs/topgrade).
- Soporte incluido para el arranque dual (dual-boot) con Windows, gracias a que se deja intacta la instalación de GRUB por defecto de Fedora.
- ¿Algo se rompió o dejo de funcionar después de actualizar?, ¡descuida!, puedes fácilmente retroceder a una versión previa de Bazzite, gracias a la función de reversión (rollback) de `rpm-ostree`. Inclusive puedes seleccionar imágenes previas del sistema directamente desde el menú que aparece al arrancar tu dispositivo.
- Steam y Lutris vienen pre-instalados en la imagen como paquetes en capas (layered).
@@ -148,20 +148,69 @@ Si deseas cambiar la base (rebase) de una imagen upstream existente de un sistem
```bash
rpm-ostree rebase ostree-unverified-registry:ghcr.io/ublue-os/bazzite-deck:stable
```
+
#### Computadoras handheld alternativas
-Si estas usando esta imagen en otras computadoras Handheld que no son la Steam Deck, como la Legion Go o la AYN Loki Max, puedes controlar el TDP usando el plugin de Decky Loader llamado SimpleDeckyTDP, esto también aplica para aquellas computadoras Handheld que usan una imagen personalizada basada en `-deck` que brindan soporte especializado a ciertos dispositivos como la Ally.
+Si estas usando esta imagen en otras computadoras Handheld que no son la Steam Deck, puedes controlar el TDP usando el plugin de Decky Loader llamado SimpleDeckyTDP.
+
- Primero, instala Decky Loader ejecutando el siguiente comando en una terminal: `ujust get-decky`
- Despues, instala SimpleDeckyTDP ejecutando el siguiente comando en una terminal: `ujust get-simpledeckytdp`
-Si estas usando una computadora Handheld que tiene soporte por parte de [hhd](https://github.com/hhd-dev/hhd), tambien puedes obtener un plugin que integra esta funcionalidad con game mode, solo ejecuta el siguiente comando en una terminal: `ujust get-hhd-decky`
+Si estas usando una computadora Handheld que tiene soporte por parte de [hhd](https://github.com/hhd-dev/hhd) (Como la Lenovo Legion Go o la ASUS ROG Ally), tambien puedes obtener un plugin que integra esta funcionalidad en Game Mode, solo ejecuta el siguiente comando en una terminal: `ujust get-hhd-decky`
+
+**Igualmente, asegurate de tambien leer la [documentación de HHD (en inglés)](https://github.com/hhd-dev/hhd#after-install), algunas computadoras Handheld requieren ciertos ajustes o tweaks especificos para funcionar correctamente.**
+
+Tambien incluimos ciertos comandos de `ujust` para instalar varios temas para CSS Loader que no estan disponibles en su propia tienda. Si instalas estos temas, estos tambien serán actualizados automáticamente junto con Bazzite.
+
+```bash
+# Instala el tema de la ROG Ally para CSS Loader (https://github.com/semakusut/SBP-ROG-Ally)
+ujust install-rog-ally-theme
+
+# Instala el tema de la Lenovo Legion Go para CSS Loader (https://github.com/frazse/SBP-Legion-Go-Theme)
+ujust install-legion-go-theme
+
+# Instala el tema para pasar los glifos de Playstation a Xbox (PS5-to-Xbox) para hhd y CSS Loader (https://github.com/frazse/PS5-to-Xbox-glyphs)
+ujust install-hhd-xbox-glyph-theme
+```
+
+#### ASUS Ally
+
+Bazzite tiene imágenes especificas para la ASUS ROG Ally, debido a los requerimientos adicionales en cuanto drivers y software especificos para ese hardware. Puedes escoger las imágenes `-ally` desde el instalador de Bazzite, o puedes cambiar de base (rebase) utilizando cualquiera de los siguientes comandos en una terminal:
+
+Para usar KDE (Entorno default de SteamOS):
+
+```bash
+rpm-ostree rebase ostree-unverified-registry:ghcr.io/ublue-os/bazzite-ally:stable
+```
+
+Para usar GNOME:
+
+```bash
+rpm-ostree rebase ostree-unverified-registry:ghcr.io/ublue-os/bazzite-ally-gnome:stable
+```
+
+#### Framegame
+
+[¿Te armaste una de estas bellezas?](https://www.youtube.com/watch?v=zd6WtTUf-30), tambien tenemos una imagen especifica para ti. Esta es la variante Deck de nuestras imágenes para las laptops de Framework.
+
+Para usar KDE (Entorno default de SteamOS):
+
+```bash
+rpm-ostree rebase ostree-unverified-registry:ghcr.io/ublue-os/bazzite-framegame:stable
+```
+
+Para usar GNOME:
+
+```bash
+rpm-ostree rebase ostree-unverified-registry:ghcr.io/ublue-os/bazzite-framegame-gnome:stable
+```
### GNOME
-Las sub-variantes con el entorno de escritorio GNOME están disponibles tanto para la variante para **Computadoras de Escritorio**, como la de **Steam Deck/HTPCs**. Estas imágenes cuentan con las siguientes características adicionales:
+Las sub-variantes con el entorno de escritorio GNOME están disponibles tanto para las imágenes para **Computadoras de Escritorio**, como las de **Steam Deck/HTPCs**. Estas imágenes cuentan con las siguientes características adicionales:
- [Soporte tanto para pantallas con tasa de refresco variable y como para la escala fraccional de la interfaz de usuario bajo el servidor gráfico Wayland](https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1154).
-- Menú personalizado en la barra superior para regresar al modo de juego (gamemode), lanzar Steam, y para abrir otras utilidades.
+- Menú personalizado en la barra superior para regresar a Game Mode, lanzar Steam, y para abrir otras utilidades.
- [GSConnect](https://extensions.gnome.org/extension/1319/gsconnect/), la versión de KDE Connect para GNOME, viene pre-instalado y listo para usarse.
- La [extension Hanabi](https://github.com/jeffshee/gnome-ext-hanabi) viene incluida, la cual ofrece características similares al Wallpaper Engine en KDE.
- Numerosas extensiones opcionales pre-instaladas, incluyendo [importantísimos parches para una mejor experiencia del usuario](https://www.youtube.com/watch?v=nbCg9_YgKgM).
@@ -170,9 +219,7 @@ Las sub-variantes con el entorno de escritorio GNOME están disponibles tanto pa
> \[!IMPORTANT\]\
> \**Las imágenes de disco (ISOs) pueden descargarse desde nuestra página de lanzamientos (releases) [aquí (en inglés)](https://github.com/ublue-os/bazzite/releases), también puedes encontrar una útil guía de instalación [aquí (en inglés)](https://universal-blue.discourse.group/docs?topic=30).** Si experimentas errores y/o problemas instalando Bazzite, checa nuestra [guía de solución de problemas (en inglés)](https://universal-blue.discourse.group/docs?topic=34).
-Si estas actualmente usando una imagen de Universal Blue, por favor [sigue estas instrucciones (en inglés)](https://universal-blue.org/images/#image-list).
-
-Si deseas cambiar la base (rebase) de una imagen upstream existente de un sistema ostree de Fedora Silverblue/Kinoite a la imagen **para computadoras de escritorio con una GPU AMD ó Intel**, ejecuta el siguiente comando en una terminal:
+Si deseas cambiar la base (rebase) a la imagen **para computadoras de escritorio con una GPU AMD ó Intel**, ejecuta el siguiente comando en una terminal:
```bash
rpm-ostree rebase ostree-unverified-registry:ghcr.io/ublue-os/bazzite-gnome:stable
@@ -187,19 +234,18 @@ rpm-ostree rebase ostree-unverified-registry:ghcr.io/ublue-os/bazzite-gnome-nvid
> \[!WARNING\]\
> **Debido a un bug en upstream, Bazzite no puede ser utilizado por el momento en Steam Decks con solo 64 GB de almacenamiento eMMC. Ampliar tu almacenamiento cambiando el disco interno soluciona este problema.**
-> \[!IMPORTANT]
-> Los dispositivos que **NO** son una Steam Deck, también pueden utilizar las imágenes bazzite-deck, sin embargo tienen que usar una GPU de AMD o Intel, GPUs de NVIDIA no son compatibles por el momento con esta variante.
-
-Si necesitas realizar un rebase a la imagen **para Steam Deck/HTPC**, ejecuta el siguiente comando en una terminal:
+Si necesitas realizar un rebase a la imagen **para Steam Deck/HTPC con GPUs AMD ó Intel**, ejecuta el siguiente comando en una terminal:
```bash
rpm-ostree rebase ostree-unverified-registry:ghcr.io/ublue-os/bazzite-deck-gnome:stable
```
+**Para usuarios con Secure Boot habilitado:** Sigue nuestra [documentación para usuarios de Secure Boot](#secure-boot) antes de cambiar la base.
### Características del Upstream
#### Universal Blue
+- Drivers propietarios de NVIDIA pre-instalados. (Solo para imágenes NVDIA)
- Flathub se encuentra habilitado por defecto.
- Lanzador de comandos [`ujust`](https://github.com/casey/just) incluido, con diversos comandos muy convenientes.
- Codecs multimedia fuera de la caja.
@@ -247,9 +293,9 @@ Lee nuestras [preguntas frecuentes](https://universal-blue.discourse.group/docs?
- [Guía para Configurar el Arranque Dual con Windows (Dual Boot)](https://universal-blue.discourse.group/docs?topic=129)
- [Documentación Miscelánea](https://universal-blue.discourse.group/docs?topic=287)
-Puedes encontrar documentación adicional relacionada al proyecto [aquí](https://universal-blue.discourse.group/docs).
+Puedes encontrar documentación adicional relacionada al proyecto [aquí](https://universal-blue.discourse.group/docs?category=5).
-Checa nuestros [boletines informativos](https://universal-blue.discourse.group/tag/bazzite-buzz), estos son publicados regularmente y los cuales hablan de las últimas actualizaciones del proyecto.
+Checa nuestros [boletines informativos (disponibles en español](https://universal-blue.discourse.group/tag/bazzite-buzz), estos son publicados regularmente y los cuales hablan de las últimas actualizaciones del proyecto.
## Paquetes Personalizados
@@ -327,18 +373,30 @@ cosign verify --key cosign.pub ghcr.io/ublue-os/bazzite
El Arranque Seguro (Secure Boot) tiene soporte gracias a nuestra llave digital personalizada. La llave pública puede encontrarse en la raíz de [este](https://github.com/ublue-os/bazzite/blob/main/secure_boot.der) repositorio.
-
Si gustas registrar esta llave antes de instalar Bazzite, descarga la llave y ejecuta el siguiente comando en una terminal:
```bash
sudo mokutil --timeout -1
sudo mokutil --import secure_boot.der
```
+Alternativamente, los usuarios que ya cuenten con una imagen de Universal Blue instalada, pueden ejecutar el siguiente comando en una terminal: `ujust enroll-secure-boot-key`.
+
+Si se te pide una contraseña, introduce `ublue-os`.
### Métricas de Contribución
![Bazzite](https://repobeats.axiom.co/api/embed/86b500d79c613015ad16f56df76c8e13f3fd98ae.svg "Repobeats analytics image")
+#### Historial de Estrellas
+
+
+
+
+
## Gracias Especiales
Bazzite es producto de esfuerzo comunitario, y no existiría sin la contribución de todos. A continuación, están listadas unas cuantas personas que nos han ayudado a lo largo del camino:
diff --git a/spec_files/mangohud/fedora.patch b/spec_files/mangohud/fedora.patch
new file mode 100644
index 00000000..c20a2f9a
--- /dev/null
+++ b/spec_files/mangohud/fedora.patch
@@ -0,0 +1,10 @@
+diff --git a/bin/mangoplot.py b/bin/mangoplot.py
+index 7d82b3a..b974aa7 100755
+--- a/bin/mangoplot.py
++++ b/bin/mangoplot.py
+@@ -1,4 +1,4 @@
+-#!/usr/bin/env python
++#!/usr/bin/python3
+
+ r"""
+ Script to plot all the MangoHud benchmarks contained in a given folder.
diff --git a/spec_files/mangohud/mangohud.spec b/spec_files/mangohud/mangohud.spec
new file mode 100644
index 00000000..2666cfb0
--- /dev/null
+++ b/spec_files/mangohud/mangohud.spec
@@ -0,0 +1,298 @@
+## START: Set by rpmautospec
+## (rpmautospec version 0.3.8)
+## RPMAUTOSPEC: autorelease
+%define autorelease(e:s:pb:n) %{?-p:0.}%{lua:
+ release_number = 1;
+ base_release_number = tonumber(rpm.expand("%{?-b*}%{!?-b:1}"));
+ print(release_number + base_release_number - 1);
+}%{?-e:.%{-e*}}%{?-s:.%{-s*}}%{!?-n:%{?dist}}
+## END: Set by rpmautospec
+
+## START: Set by rpmautospec
+## (rpmautospec version 0.3.5)
+## RPMAUTOSPEC: autorelease, autochangelog
+%define autorelease(e:s:pb:n) %{?-p:0.}%{lua:
+ release_number = 12;
+ base_release_number = tonumber(rpm.expand("%{?-b*}%{!?-b:1}"));
+ print(release_number + base_release_number - 1);
+}%{?-e:.%{-e*}}%{?-s:.%{-s*}}%{!?-n:%{?dist}}
+## END: Set by rpmautospec
+
+%global appname MangoHud
+
+%global imgui_ver 1.81
+%global imgui_wrap_ver 1
+
+%global tarball_version %%(echo %{version} | tr '~' '-')
+
+# Tests requires bundled stuff. Disable for now.
+%bcond_with tests
+
+Name: mangohud
+Version: 0.7.0
+Release: 100.bazzite.{{{ git_dir_version }}}
+Summary: Vulkan and OpenGL overlay for monitoring FPS, temperatures, CPU/GPU load
+
+License: MIT
+URL: https://github.com/flightlessmango/MangoHud
+Source0: %{url}/archive/refs/tags/v%{version}.tar.gz
+Source1: https://github.com/ocornut/imgui/archive/v%{imgui_ver}/imgui-%{imgui_ver}.tar.gz
+Source2: https://wrapdb.mesonbuild.com/v1/projects/imgui/%{imgui_ver}/%{imgui_wrap_ver}/get_zip#/imgui-%{imgui_ver}-%{imgui_wrap_ver}-wrap.zip
+Patch0: fedora.patch
+
+BuildRequires: appstream
+BuildRequires: dbus-devel
+BuildRequires: gcc-c++
+BuildRequires: git-core
+BuildRequires: glew-devel
+BuildRequires: glfw-devel
+BuildRequires: glslang-devel
+BuildRequires: libappstream-glib
+BuildRequires: libstdc++-static
+BuildRequires: mesa-libGL-devel
+BuildRequires: meson >= 0.60
+BuildRequires: python3-mako
+BuildRequires: pkgconfig(dbus-1)
+BuildRequires: pkgconfig(dri)
+BuildRequires: pkgconfig(gl)
+BuildRequires: pkgconfig(glew)
+BuildRequires: pkgconfig(glfw3)
+BuildRequires: pkgconfig(libdrm)
+
+BuildRequires: pkgconfig(spdlog)
+BuildRequires: pkgconfig(nlohmann_json)
+BuildRequires: pkgconfig(vulkan)
+BuildRequires: pkgconfig(wayland-client)
+BuildRequires: pkgconfig(x11)
+BuildRequires: cmake(VulkanHeaders)
+
+%if %{with tests}
+BuildRequires: libcmocka-devel
+%endif
+
+Requires: hicolor-icon-theme
+Requires: vulkan-loader%{?_isa}
+
+Recommends: (mangohud(x86-32) if glibc(x86-32))
+
+Suggests: goverlay
+
+Provides: bundled(imgui) = %{imgui_ver}
+
+%global _description %{expand:
+A Vulkan and OpenGL overlay for monitoring FPS, temperatures, CPU/GPU load and
+more.}
+
+%description %{_description}
+
+
+%prep
+%autosetup -n %{appname}-%{version} -p1
+%setup -qn %{appname}-%{version} -DTa1
+%setup -qn %{appname}-%{version} -DTa2
+
+mkdir subprojects/imgui
+mv imgui-%{imgui_ver} subprojects/
+
+
+%build
+%meson \
+ --wrap-mode=forcefallback \
+ -Dinclude_doc=true \
+ -Dwith_wayland=enabled \
+ -Dwith_xnvctrl=disabled \
+ -Dmangoapp=true \
+ -Dmangoapp_layer=true \
+ -Dmangohudctl=true \
+ %if %{with tests}
+ -Dtests=enabled \
+ %else
+ -Dtests=disabled \
+ %endif
+ %{nil}
+%meson_build
+
+
+%install
+%meson_install
+
+
+%check
+# https://github.com/flightlessmango/MangoHud/issues/812
+# ? tag-invalid : stock icon is not valid [io.github.flightlessmango.mangohud]
+%dnl appstream-util validate-relax --nonet %{buildroot}%{_metainfodir}/*.xml
+%if %{with tests}
+%meson_test
+%endif
+
+
+%files
+%license LICENSE
+%doc README.md
+%{_bindir}/%{name}*
+%{_bindir}/mangoapp
+%{_bindir}/mangoplot
+%{_datadir}/icons/hicolor/scalable/*/*.svg
+%{_datadir}/vulkan/implicit_layer.d/*Mango*.json
+%{_docdir}/%{name}/*
+%{_libdir}/%{name}/*
+%{_mandir}/man1/%{name}.1*
+%{_mandir}/man1/mangoapp.1*
+%{_metainfodir}/*.metainfo.xml
+%{_libdir}/%{name}/libMangoApp.so
+
+
+%changelog
+* Mon Oct 02 2023 Artem Polishchuk - 0.7.0-6
+- build: Fix description about 'mangoplot'
+
+* Mon Oct 02 2023 Artem Polishchuk - 0.7.0-5
+- build: mangohud-mangoplot as Suggests
+
+* Thu Sep 28 2023 Artem Polishchuk - 0.7.0-4
+- build: Add missed deps for mangoplot
+
+* Thu Sep 28 2023 Artem Polishchuk - 0.7.0-3
+- build: Package mangoplot as separate sub-package
+
+* Thu Sep 28 2023 Artem Polishchuk - 0.7.0-2
+- build: Upload sources
+
+* Thu Sep 28 2023 Artem Polishchuk - 0.7.0-1
+- build: Update to 0.7.0
+
+* Sun Sep 10 2023 Artem Polishchuk - 0.6.9.1-11
+- build: Backport upstream patch
+
+* Sun Sep 10 2023 Artem Polishchuk - 0.6.9.1-10
+- test: Skip for s390x arch
+
+* Sun Sep 10 2023 Artem Polishchuk - 0.6.9.1-9
+- build: Drop BR: pkgconfig(vulkan)
+
+* Sun Sep 10 2023 Artem Polishchuk - 0.6.9.1-8
+- test: Fix and enable tests
+
+* Sun Sep 10 2023 Artem Polishchuk - 0.6.9.1-7
+- style: Minor Spec file update
+
+* Sun Sep 10 2023 Artem Polishchuk - 0.6.9.1-6
+- build: Bundle vulkan-headers to fix FTBFS
+
+* Thu Jul 20 2023 Fedora Release Engineering - 0.6.9.1-5
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild
+
+* Tue Jul 11 2023 Artem Polishchuk - 0.6.9.1-4
+- build: mangohud relies on old Vulkan-headers < 1.3.241
+
+* Sat Jul 08 2023 Vitaly Zaitsev - 0.6.9.1-3
+- Rebuilt due to spdlog 1.12 update.
+
+* Wed Jun 28 2023 Vitaly Zaitsev - 0.6.9.1-2
+- Rebuilt due to fmt 10 update.
+
+* Wed Apr 19 2023 Artem Polishchuk - 0.6.9.1-1
+- build: Update to 0.6.9-1
+
+* Fri Apr 14 2023 Artem Polishchuk - 0.6.9-1
+- build: Update to 0.6.9
+
+* Tue Mar 14 2023 Artem Polishchuk - 0.6.8-4
+- build: Fix FTBFS 38
+
+* Thu Jan 19 2023 Fedora Release Engineering - 0.6.8-3
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild
+
+* Thu Nov 03 2022 Vitaly Zaitsev - 0.6.8-2
+- Rebuilt due to spdlog update.
+
+* Tue Aug 02 2022 Artem Polishchuk - 0.6.8-1
+- chore(update): 0.6.8
+
+* Thu Jul 21 2022 Fedora Release Engineering - 0.6.7.1-4
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild
+
+* Tue Jul 19 2022 Mamoru TASAKA - 0.6.7.1-3
+- Rebuild for fmt-9
+
+* Fri May 13 2022 Artem Polishchuk - 0.6.7.1-2
+- fix: Upload sources
+
+* Fri May 13 2022 Artem Polishchuk - 0.6.7.1-1
+- chore(update): 0.6.7-1
+
+* Wed May 04 2022 Artem Polishchuk - 0.6.7-1
+- chore(update): 0.6.7
+
+* Thu Jan 20 2022 Fedora Release Engineering - 0.6.6-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild
+
+* Mon Oct 18 2021 Artem Polishchuk - 0.6.6-1
+- chore(update): 0.6.6
+
+* Thu Oct 07 2021 Artem Polishchuk - 0.6.5-3
+- build: Fix multilib dep | rh#1830718
+
+* Thu Jul 22 2021 Fedora Release Engineering - 0.6.5-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild
+
+* Thu Jul 08 2021 Artem Polishchuk - 0.6.5-1
+- build(update): 0.6.5
+
+* Thu Jun 24 2021 Artem Polishchuk - 0.6.4-1
+- build(update): 0.6.4
+
+* Sat Jun 12 2021 Artem Polishchuk - 0.6.3-1
+- build(update): 0.6.3
+
+* Fri Jun 11 2021 Artem Polishchuk - 0.6.2-1
+- build(update): 0.6.2
+
+* Wed Jan 27 2021 Artem Polishchuk - 0.6.1-3
+- build: Install 32-bit version automagically if multilib packages already
+ installed on end user machine
+
+* Tue Jan 26 2021 Fedora Release Engineering - 0.6.1-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild
+
+* Sun Nov 29 2020 Artem Polishchuk - 0.6.1-1
+- build(update): 0.6.1
+
+* Sun Nov 29 2020 Artem Polishchuk - 0.6.0-2
+- fix: version in HUD | GH-411
+
+* Sat Nov 28 2020 Artem Polishchuk - 0.6.0-1
+- build(update): 0.6.0
+
+* Sun Aug 16 2020 Artem Polishchuk - 0.5.1-1
+- Update to 0.5.1
+
+* Tue Jul 28 2020 Fedora Release Engineering - 0.4.1-3
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild
+
+* Sat Jun 13 2020 Artem Polishchuk - 0.4.1-2
+- Add patch which fix F33 build | GH-213
+
+* Thu Jun 11 2020 Artem Polishchuk - 0.4.1-1
+- Update to 0.4.1
+- Disable LTO
+
+* Sat May 02 2020 Artem Polishchuk - 0.3.5-1
+- Update to 0.3.5
+- Remove ExclusiveArch. Now compiles on all arches, see GitHub#88.
+
+* Thu Mar 26 2020 Artem Polishchuk - 0.3.1-2
+- Add GUI fron-end 'goverlay' as very weak dep
+
+* Wed Mar 18 2020 Artem Polishchuk - 0.3.1-1
+- Update to 0.3.1
+
+* Sun Mar 15 2020 Artem Polishchuk - 0.3.0-1
+- Update to 0.3.0
+
+* Fri Feb 14 2020 Artem Polishchuk - 0.2.0-11
+- Initial package
+- Thanks for help with packaging to:
+ gasinvein
+ Vitaly Zaitsev
+
diff --git a/spec_files/mesa/old/26105.patch b/spec_files/mesa/old/26105.patch
new file mode 100644
index 00000000..6af0603d
--- /dev/null
+++ b/spec_files/mesa/old/26105.patch
@@ -0,0 +1,204 @@
+diff --git a/src/amd/compiler/aco_instruction_selection.cpp b/src/amd/compiler/aco_instruction_selection.cpp
+index 561f3cc02e0..ebc54a900e3 100644
+--- a/src/amd/compiler/aco_instruction_selection.cpp
++++ b/src/amd/compiler/aco_instruction_selection.cpp
+@@ -12526,7 +12526,8 @@ select_rt_prolog(Program* program, ac_shader_config* config,
+ */
+ PhysReg out_uniform_shader_addr = get_arg_reg(out_args, out_args->rt.uniform_shader_addr);
+ PhysReg out_launch_size_x = get_arg_reg(out_args, out_args->rt.launch_size);
+- PhysReg out_launch_size_z = out_launch_size_x.advance(8);
++ PhysReg out_launch_size_y = out_launch_size_x.advance(4);
++ PhysReg out_launch_size_z = out_launch_size_y.advance(4);
+ PhysReg out_launch_ids[3];
+ for (unsigned i = 0; i < 3; i++)
+ out_launch_ids[i] = get_arg_reg(out_args, out_args->rt.launch_id).advance(i * 4);
+@@ -12534,9 +12535,13 @@ select_rt_prolog(Program* program, ac_shader_config* config,
+ PhysReg out_record_ptr = get_arg_reg(out_args, out_args->rt.shader_record);
+
+ /* Temporaries: */
+- num_sgprs = align(num_sgprs, 2) + 4;
+- PhysReg tmp_raygen_sbt = PhysReg{num_sgprs - 4};
+- PhysReg tmp_ring_offsets = PhysReg{num_sgprs - 2};
++ num_sgprs = align(num_sgprs, 2);
++ PhysReg tmp_raygen_sbt = PhysReg{num_sgprs};
++ num_sgprs += 2;
++ PhysReg tmp_ring_offsets = PhysReg{num_sgprs};
++ num_sgprs += 2;
++
++ PhysReg tmp_invocation_idx = PhysReg{256 + num_vgprs++};
+
+ /* Confirm some assumptions about register aliasing */
+ assert(in_ring_offsets == out_uniform_shader_addr);
+@@ -12610,6 +12615,36 @@ select_rt_prolog(Program* program, ac_shader_config* config,
+ bld.vop1(aco_opcode::v_mov_b32, Definition(out_record_ptr.advance(4), v1),
+ Operand(tmp_raygen_sbt.advance(4), s1));
+
++ /* For 1D dispatches converted into 2D ones, we need to fix up the launch IDs.
++ * Calculating the 1D launch ID is: id = local_invocation_index + (wg_id.x * wg_size).
++ * in_wg_id_x now holds wg_id.x * wg_size.
++ */
++ bld.sop2(aco_opcode::s_lshl_b32, Definition(in_wg_id_x, s1), Definition(scc, s1),
++ Operand(in_wg_id_x, s1), Operand::c32(program->workgroup_size == 32 ? 5 : 6));
++
++ /* Calculate and add local_invocation_index */
++ bld.vop3(aco_opcode::v_mbcnt_lo_u32_b32, Definition(tmp_invocation_idx, v1), Operand::c32(-1u),
++ Operand(in_wg_id_x, s1));
++ if (program->wave_size == 64) {
++ if (program->gfx_level <= GFX7)
++ bld.vop2(aco_opcode::v_mbcnt_hi_u32_b32, Definition(tmp_invocation_idx, v1),
++ Operand::c32(-1u), Operand(tmp_invocation_idx, v1));
++ else
++ bld.vop3(aco_opcode::v_mbcnt_hi_u32_b32_e64, Definition(tmp_invocation_idx, v1),
++ Operand::c32(-1u), Operand(tmp_invocation_idx, v1));
++ }
++
++ /* Make fixup operations a no-op if this is not a converted 2D dispatch. */
++ bld.sopc(aco_opcode::s_cmp_lg_u32, Definition(scc, s1),
++ Operand::c32(ACO_RT_CONVERTED_2D_LAUNCH_SIZE), Operand(out_launch_size_y, s1));
++ bld.sop2(Builder::s_cselect, Definition(vcc, bld.lm),
++ Operand::c32_or_c64(-1u, program->wave_size == 64),
++ Operand::c32_or_c64(0, program->wave_size == 64), Operand(scc, s1));
++ bld.vop2(aco_opcode::v_cndmask_b32, Definition(out_launch_ids[0], v1),
++ Operand(tmp_invocation_idx, v1), Operand(out_launch_ids[0], v1), Operand(vcc, bld.lm));
++ bld.vop2(aco_opcode::v_cndmask_b32, Definition(out_launch_ids[1], v1), Operand::zero(),
++ Operand(out_launch_ids[1], v1), Operand(vcc, bld.lm));
++
+ /* jump to raygen */
+ bld.sop1(aco_opcode::s_setpc_b64, Operand(out_uniform_shader_addr, s2));
+
+diff --git a/src/amd/compiler/aco_interface.h b/src/amd/compiler/aco_interface.h
+index 8f35e18b5b0..9d2c1dbb2af 100644
+--- a/src/amd/compiler/aco_interface.h
++++ b/src/amd/compiler/aco_interface.h
+@@ -32,6 +32,9 @@
+ extern "C" {
+ #endif
+
++/* Special launch size to indicate this dispatch is a 1D dispatch converted into a 2D one */
++#define ACO_RT_CONVERTED_2D_LAUNCH_SIZE -1u
++
+ typedef struct nir_shader nir_shader;
+ struct ac_shader_config;
+ struct aco_shader_info;
+diff --git a/src/amd/vulkan/radv_cmd_buffer.c b/src/amd/vulkan/radv_cmd_buffer.c
+index cdede679552..c7dd4b216d4 100644
+--- a/src/amd/vulkan/radv_cmd_buffer.c
++++ b/src/amd/vulkan/radv_cmd_buffer.c
+@@ -42,6 +42,8 @@
+ #include "ac_debug.h"
+ #include "ac_shader_args.h"
+
++#include "aco_interface.h"
++
+ #include "util/fast_idiv_by_const.h"
+
+ enum {
+@@ -10003,7 +10005,26 @@ enum radv_rt_mode {
+ };
+
+ static void
+-radv_trace_rays(struct radv_cmd_buffer *cmd_buffer, const VkTraceRaysIndirectCommand2KHR *tables, uint64_t indirect_va,
++radv_upload_trace_rays_params(struct radv_cmd_buffer *cmd_buffer, VkTraceRaysIndirectCommand2KHR *tables,
++ enum radv_rt_mode mode, uint64_t *launch_size_va, uint64_t *sbt_va)
++{
++ uint32_t upload_size = mode == radv_rt_mode_direct ? sizeof(VkTraceRaysIndirectCommand2KHR)
++ : offsetof(VkTraceRaysIndirectCommand2KHR, width);
++
++ uint32_t offset;
++ if (!radv_cmd_buffer_upload_data(cmd_buffer, upload_size, tables, &offset))
++ return;
++
++ uint64_t upload_va = radv_buffer_get_va(cmd_buffer->upload.upload_bo) + offset;
++
++ if (mode == radv_rt_mode_direct)
++ *launch_size_va = upload_va + offsetof(VkTraceRaysIndirectCommand2KHR, width);
++ if (sbt_va)
++ *sbt_va = upload_va;
++}
++
++static void
++radv_trace_rays(struct radv_cmd_buffer *cmd_buffer, VkTraceRaysIndirectCommand2KHR *tables, uint64_t indirect_va,
+ enum radv_rt_mode mode)
+ {
+ if (cmd_buffer->device->instance->debug_flags & RADV_DEBUG_NO_RT)
+@@ -10024,34 +10045,43 @@ radv_trace_rays(struct radv_cmd_buffer *cmd_buffer, const VkTraceRaysIndirectCom
+ cmd_buffer->compute_scratch_size_per_wave_needed =
+ MAX2(cmd_buffer->compute_scratch_size_per_wave_needed, scratch_bytes_per_wave);
+
++ /* Since the workgroup size is 8x4 (or 8x8), 1D dispatches can only fill 8 threads per wave at most. To increase
++ * occupancy, it's beneficial to convert to a 2D dispatch in these cases. */
++ if (tables && tables->height == 1 && tables->width >= cmd_buffer->state.rt_prolog->info.cs.block_size[0])
++ tables->height = ACO_RT_CONVERTED_2D_LAUNCH_SIZE;
++
+ struct radv_dispatch_info info = {0};
+ info.unaligned = true;
+
+- uint64_t launch_size_va;
+- uint64_t sbt_va;
++ uint64_t launch_size_va = 0;
++ uint64_t sbt_va = 0;
+
+ if (mode != radv_rt_mode_indirect2) {
+- uint32_t upload_size = mode == radv_rt_mode_direct ? sizeof(VkTraceRaysIndirectCommand2KHR)
+- : offsetof(VkTraceRaysIndirectCommand2KHR, width);
+-
+- uint32_t offset;
+- if (!radv_cmd_buffer_upload_data(cmd_buffer, upload_size, tables, &offset))
+- return;
+-
+- uint64_t upload_va = radv_buffer_get_va(cmd_buffer->upload.upload_bo) + offset;
+-
+- launch_size_va =
+- (mode == radv_rt_mode_direct) ? upload_va + offsetof(VkTraceRaysIndirectCommand2KHR, width) : indirect_va;
+- sbt_va = upload_va;
++ launch_size_va = indirect_va;
++ radv_upload_trace_rays_params(cmd_buffer, tables, mode, &launch_size_va, &sbt_va);
+ } else {
+ launch_size_va = indirect_va + offsetof(VkTraceRaysIndirectCommand2KHR, width);
+ sbt_va = indirect_va;
+ }
+
++ uint32_t remaining_ray_count = 0;
++
+ if (mode == radv_rt_mode_direct) {
+ info.blocks[0] = tables->width;
+ info.blocks[1] = tables->height;
+ info.blocks[2] = tables->depth;
++
++ if (tables->height == ACO_RT_CONVERTED_2D_LAUNCH_SIZE) {
++ /* We need the ray count for the 2D dispatch to be a multiple of the y block size for the division to work, and
++ * a multiple of the x block size because the invocation offset must be a multiple of the block size when
++ * dispatching the remaining rays. Fortunately, the x block size is itself a multiple of the y block size, so
++ * we only need to ensure that the ray count is a multiple of the x block size. */
++ remaining_ray_count = tables->width % rt_prolog->info.cs.block_size[0];
++
++ uint32_t ray_count = tables->width - remaining_ray_count;
++ info.blocks[0] = ray_count / rt_prolog->info.cs.block_size[1];
++ info.blocks[1] = rt_prolog->info.cs.block_size[1];
++ }
+ } else
+ info.va = launch_size_va;
+
+@@ -10085,6 +10115,22 @@ radv_trace_rays(struct radv_cmd_buffer *cmd_buffer, const VkTraceRaysIndirectCom
+ assert(cmd_buffer->cs->cdw <= cdw_max);
+
+ radv_dispatch(cmd_buffer, &info, pipeline, rt_prolog, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR);
++
++ if (remaining_ray_count) {
++ info.blocks[0] = remaining_ray_count;
++ info.blocks[1] = 1;
++ info.offsets[0] = tables->width - remaining_ray_count;
++
++ /* Reset the ray launch size so the prolog doesn't think this is a converted dispatch */
++ tables->height = 1;
++ radv_upload_trace_rays_params(cmd_buffer, tables, mode, &launch_size_va, NULL);
++ if (size_loc->sgpr_idx != -1) {
++ radv_emit_shader_pointer(cmd_buffer->device, cmd_buffer->cs, base_reg + size_loc->sgpr_idx * 4, launch_size_va,
++ true);
++ }
++
++ radv_dispatch(cmd_buffer, &info, pipeline, rt_prolog, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR);
++ }
+ }
+
+ VKAPI_ATTR void VKAPI_CALL
diff --git a/spec_files/mesa/old/Mesa-MLAA-License-Clarification-Email.txt b/spec_files/mesa/old/Mesa-MLAA-License-Clarification-Email.txt
new file mode 100644
index 00000000..30bdf2e9
--- /dev/null
+++ b/spec_files/mesa/old/Mesa-MLAA-License-Clarification-Email.txt
@@ -0,0 +1,117 @@
+
+Subject: RE: Question about Mesa MLAA license
+From: Jorge Jimenez
+Date: 01/08/2013 12:50 PM
+To: Tom Callaway
+CC: "jorge@iryoku.com"
+
+Yes to both questions.
+
+Thanks,
+Jorge
+
+From: Tom Callaway
+Sent: January 8, 2013 6:49 PM
+To: Jorge Jimenez
+CC: jorge@iryoku.com
+Subject: Re: Question about Mesa MLAA license
+
+On 01/08/2013 12:39 PM, Jorge Jimenez wrote:
+> Hi Tom,
+>
+> What we meant with that is that we made an exception for clause 2.
+> Instead of clause 2, in the case of the Mesa project, you have to name
+> the technique Jimenez's MLAA in the config options of Mesa. We did that
+> just to allow them to solve license issues. This exception should be for
+> the Mesa project, and any project using Mesa, like Fedora.
+>
+> We want to widespread usage of our MLAA, so we want to avoid any kind of
+> license complications. Hope current one is good for Fedora, if not
+> please tell, and we'll see what we can do!
+
+Okay, a few more questions:
+
+* If Fedora decides to simply reproduce the quoted statement:
+"Uses Jimenez's MLAA. Copyright (C) 2010 by Jorge Jimenez, Belen Masia,
+Jose I. Echevarria, Fernando Navarro and Diego Gutierrez."
+
+Specifically, if this is done as part of documentation included with
+Mesa, is that sufficient to meet clause 2 even if the Mesa config option
+is not set as described in your exception?
+
+* Currently, the Mesa config option for MLAA says: "Morphological
+anti-aliasing based on Jimenez\' MLAA. 0 to disable, 8 for default
+quality". Is this in compliance with your exception?
+
+Thanks again,
+
+~tom
+
+==
+Fedora Project
+
+Subject: RE: Question about Mesa MLAA license
+From: Jorge Jimenez
+Date: 01/08/2013 12:39 PM
+To: "jorge@iryoku.com" , Tom Callaway
+
+Hi Tom,
+
+What we meant with that is that we made an exception for clause 2.
+Instead of clause 2, in the case of the Mesa project, you have to name
+the technique Jimenez's MLAA in the config options of Mesa. We did that
+just to allow them to solve license issues. This exception should be for
+the Mesa project, and any project using Mesa, like Fedora.
+
+We want to widespread usage of our MLAA, so we want to avoid any kind of
+license complications. Hope current one is good for Fedora, if not
+please tell, and we'll see what we can do!
+
+Cheers,
+Jorge
+
+From: Tom Callaway
+Sent: January 8, 2013 6:30 PM
+To: jorge@iryoku.com
+Subject: Question about Mesa MLAA license
+
+Jorge,
+
+Thanks for all of your fantastic graphics work! I have been auditing
+Fedora (a popular distribution of Linux) for license compliance and I
+came across your MLAA code in Mesa.
+
+The license says:
+
+ * 2. Redistributions in binary form must reproduce the following
+statement:
+ *
+ * "Uses Jimenez's MLAA. Copyright (C) 2010 by Jorge Jimenez, Belen Masia,
+ * Jose I. Echevarria, Fernando Navarro and Diego Gutierrez."
+ *
+ * Only for use in the Mesa project, this point 2 is filled by naming the
+ * technique Jimenez's MLAA in the Mesa config options.
+
+That wording is unclear. When you say "Only for use in the Mesa
+project...", it seems like you could either be saying:
+
+- This code may only be used as part of Mesa.
+
+OR
+
+- In Mesa, you can comply with clause 2 by simply selecting "Jimenez's
+MLAA" in the Mesa config options.
+
+*****
+
+If the first item is true, then we may have to remove the MLAA code from
+Fedora's copy of Mesa. However, looking at the license on your SMAA
+code, I do not believe it to be the case. Please let me know either way!
+
+Thanks in advance,
+
+Tom Callaway
+Fedora Legal
+
+==
+Fedora Project
diff --git a/spec_files/mesa/old/gnome-shell-glthread-disable.patch b/spec_files/mesa/old/gnome-shell-glthread-disable.patch
new file mode 100644
index 00000000..b2caeb8d
--- /dev/null
+++ b/spec_files/mesa/old/gnome-shell-glthread-disable.patch
@@ -0,0 +1,11 @@
+diff -up mesa-22.3.0-rc4/src/util/00-mesa-defaults.conf.dma mesa-22.3.0-rc4/src/util/00-mesa-defaults.conf
+--- mesa-22.3.0-rc4/src/util/00-mesa-defaults.conf.dma 2022-11-25 10:32:32.175879868 +1000
++++ mesa-22.3.0-rc4/src/util/00-mesa-defaults.conf 2022-11-25 10:32:43.743067470 +1000
+@@ -653,6 +653,7 @@ TODO: document the other workarounds.
+
+
+
++
+
+
+
diff --git a/spec_files/mesa/old/mesa-meson-c99.patch b/spec_files/mesa/old/mesa-meson-c99.patch
new file mode 100644
index 00000000..6cbb0536
--- /dev/null
+++ b/spec_files/mesa/old/mesa-meson-c99.patch
@@ -0,0 +1,42 @@
+meson: C type error in strtod_l/strtof_l probe
+
+Future compilers will fail compilation due to the C type error:
+
+…/testfile.c: In function 'main':
+…/testfile.c:12:30: error: passing argument 2 of 'strtod_l' from incompatible pointer type
+ 12 | double d = strtod_l(s, end, loc);
+ | ^~~
+ | |
+ | char *
+/usr/include/stdlib.h:416:43: note: expected 'char ** restrict' but argument is of type 'char *'
+ 416 | char **__restrict __endptr, locale_t __loc)
+ | ~~~~~~~~~~~~~~~~~~^~~~~~~~
+…/testfile.c:13:29: error: passing argument 2 of 'strtof_l' from incompatible pointer type
+ 13 | float f = strtof_l(s, end, loc);
+ | ^~~
+ | |
+ | char *
+/usr/include/stdlib.h:420:42: note: expected 'char ** restrict' but argument is of type 'char *'
+ 420 | char **__restrict __endptr, locale_t __loc)
+ | ~~~~~~~~~~~~~~~~~~^~~~~~~~
+
+This means that the probe no longer tests is objective and always
+fails.
+
+Submitted upstream:
+
+diff --git a/meson.build b/meson.build
+index 35cc5f1cd5fd9079..1a5d2ba492be0b31 100644
+--- a/meson.build
++++ b/meson.build
+@@ -1425,8 +1425,8 @@ if cc.links('''
+ locale_t loc = newlocale(LC_CTYPE_MASK, "C", NULL);
+ const char *s = "1.0";
+ char *end;
+- double d = strtod_l(s, end, loc);
+- float f = strtof_l(s, end, loc);
++ double d = strtod_l(s, &end, loc);
++ float f = strtof_l(s, &end, loc);
+ freelocale(loc);
+ return 0;
+ }''',
diff --git a/spec_files/mesa/old/mesa.spec b/spec_files/mesa/old/mesa.spec
new file mode 100644
index 00000000..5d3971e3
--- /dev/null
+++ b/spec_files/mesa/old/mesa.spec
@@ -0,0 +1,691 @@
+%ifnarch s390x
+%global with_hardware 1
+%global with_vulkan_hw 1
+%global with_vdpau 1
+%global with_va 1
+%if !0%{?rhel}
+%global with_nine 1
+%global with_omx 1
+%global with_opencl 1
+%endif
+%global base_vulkan ,amd,nouveau-experimental
+%endif
+
+%ifarch %{ix86} x86_64
+%global with_crocus 1
+%global with_i915 1
+%if !0%{?rhel}
+%global with_intel_clc 1
+%endif
+%global with_iris 1
+%global with_xa 1
+%global intel_platform_vulkan ,intel,intel_hasvk
+%endif
+
+%ifarch aarch64 x86_64 %{ix86}
+%if !0%{?rhel}
+%global with_lima 1
+%global with_vc4 1
+%endif
+%global with_etnaviv 1
+%global with_freedreno 1
+%global with_kmsro 1
+%global with_panfrost 1
+%global with_tegra 1
+%global with_v3d 1
+%global with_xa 1
+%global extra_platform_vulkan ,broadcom,freedreno,panfrost
+%endif
+
+%ifnarch s390x
+%if !0%{?rhel}
+%global with_r300 1
+%global with_r600 1
+%endif
+%global with_radeonsi 1
+%global with_vmware 1
+%endif
+
+%if !0%{?rhel}
+%global with_libunwind 1
+%global with_lmsensors 1
+%endif
+
+%ifarch %{valgrind_arches}
+%bcond_without valgrind
+%else
+%bcond_with valgrind
+%endif
+
+%global vulkan_drivers swrast%{?base_vulkan}%{?intel_platform_vulkan}%{?extra_platform_vulkan}
+
+Name: mesa
+Summary: Mesa graphics libraries
+%global ver 23.3.3
+Version: %{lua:ver = string.gsub(rpm.expand("%{ver}"), "-", "~"); print(ver)}
+Release: 100.bazzite.{{{ git_dir_version }}}
+License: MIT AND BSD-3-Clause AND SGI-B-2.0
+URL: http://www.mesa3d.org
+
+Source0: https://archive.mesa3d.org/mesa-%{ver}.tar.xz
+# src/gallium/auxiliary/postprocess/pp_mlaa* have an ... interestingly worded license.
+# Source1 contains email correspondence clarifying the license terms.
+# Fedora opts to ignore the optional part of clause 2 and treat that code as 2 clause BSD.
+Source1: Mesa-MLAA-License-Clarification-Email.txt
+
+Patch10: gnome-shell-glthread-disable.patch
+Patch11: zink-fix-resizable-bar-detection-logic.patch
+Patch12: mesa-meson-c99.patch
+
+# https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/26105/
+Patch30: 26105.patch
+
+# https://gitlab.com/evlaV/mesa/
+Patch40: valve.patch
+
+BuildRequires: meson >= 1.2.0
+BuildRequires: gcc
+BuildRequires: gcc-c++
+BuildRequires: gettext
+%if 0%{?with_hardware}
+BuildRequires: kernel-headers
+%endif
+# We only check for the minimum version of pkgconfig(libdrm) needed so that the
+# SRPMs for each arch still have the same build dependencies. See:
+# https://bugzilla.redhat.com/show_bug.cgi?id=1859515
+BuildRequires: pkgconfig(libdrm) >= 2.4.97
+%if 0%{?with_libunwind}
+BuildRequires: pkgconfig(libunwind)
+%endif
+BuildRequires: pkgconfig(expat)
+BuildRequires: pkgconfig(zlib) >= 1.2.3
+BuildRequires: pkgconfig(libzstd)
+BuildRequires: pkgconfig(libselinux)
+BuildRequires: pkgconfig(wayland-scanner)
+BuildRequires: pkgconfig(wayland-protocols) >= 1.8
+BuildRequires: pkgconfig(wayland-client) >= 1.11
+BuildRequires: pkgconfig(wayland-server) >= 1.11
+BuildRequires: pkgconfig(wayland-egl-backend) >= 3
+BuildRequires: pkgconfig(x11)
+BuildRequires: pkgconfig(xext)
+BuildRequires: pkgconfig(xdamage) >= 1.1
+BuildRequires: pkgconfig(xfixes)
+BuildRequires: pkgconfig(xcb-glx) >= 1.8.1
+BuildRequires: pkgconfig(xxf86vm)
+BuildRequires: pkgconfig(xcb)
+BuildRequires: pkgconfig(x11-xcb)
+BuildRequires: pkgconfig(xcb-dri2) >= 1.8
+BuildRequires: pkgconfig(xcb-dri3)
+BuildRequires: pkgconfig(xcb-present)
+BuildRequires: pkgconfig(xcb-sync)
+BuildRequires: pkgconfig(xshmfence) >= 1.1
+BuildRequires: pkgconfig(dri2proto) >= 2.8
+BuildRequires: pkgconfig(glproto) >= 1.4.14
+BuildRequires: pkgconfig(xcb-xfixes)
+BuildRequires: pkgconfig(xcb-randr)
+BuildRequires: pkgconfig(xrandr) >= 1.3
+BuildRequires: bison
+BuildRequires: flex
+%if 0%{?with_lmsensors}
+BuildRequires: lm_sensors-devel
+%endif
+%if 0%{?with_vdpau}
+BuildRequires: pkgconfig(vdpau) >= 1.1
+%endif
+%if 0%{?with_va}
+BuildRequires: pkgconfig(libva) >= 0.38.0
+%endif
+%if 0%{?with_omx}
+BuildRequires: pkgconfig(libomxil-bellagio)
+%endif
+BuildRequires: pkgconfig(libelf)
+BuildRequires: pkgconfig(libglvnd) >= 1.3.2
+BuildRequires: llvm-devel >= 7.0.0
+%if 0%{?with_opencl}
+BuildRequires: clang-devel
+BuildRequires: bindgen
+BuildRequires: rust-packaging
+BuildRequires: pkgconfig(libclc)
+BuildRequires: pkgconfig(SPIRV-Tools)
+BuildRequires: pkgconfig(LLVMSPIRVLib)
+%endif
+%if %{with valgrind}
+BuildRequires: pkgconfig(valgrind)
+%endif
+BuildRequires: python3-devel
+BuildRequires: python3-mako
+%if 0%{?with_intel_clc}
+BuildRequires: python3-ply
+%endif
+BuildRequires: vulkan-headers
+BuildRequires: glslang
+%if 0%{?with_vulkan_hw}
+BuildRequires: pkgconfig(vulkan)
+%endif
+
+%description
+%{summary}.
+
+%package filesystem
+Summary: Mesa driver filesystem
+Provides: mesa-dri-filesystem = %{?epoch:%{epoch}:}%{version}-%{release}
+
+%description filesystem
+%{summary}.
+
+%package libGL
+Summary: Mesa libGL runtime libraries
+Requires: %{name}-libglapi%{?_isa} = %{?epoch:%{epoch}:}%{version}-%{release}
+Requires: libglvnd-glx%{?_isa} >= 1:1.3.2
+Recommends: %{name}-dri-drivers%{?_isa} = %{?epoch:%{epoch}:}%{version}-%{release}
+
+%description libGL
+%{summary}.
+
+%package libGL-devel
+Summary: Mesa libGL development package
+Requires: %{name}-libGL%{?_isa} = %{?epoch:%{epoch}:}%{version}-%{release}
+Requires: libglvnd-devel%{?_isa} >= 1:1.3.2
+Provides: libGL-devel
+Provides: libGL-devel%{?_isa}
+Recommends: gl-manpages
+
+%description libGL-devel
+%{summary}.
+
+%package libEGL
+Summary: Mesa libEGL runtime libraries
+Requires: libglvnd-egl%{?_isa} >= 1:1.3.2
+Requires: %{name}-libgbm%{?_isa} = %{?epoch:%{epoch}:}%{version}-%{release}
+Requires: %{name}-libglapi%{?_isa} = %{?epoch:%{epoch}:}%{version}-%{release}
+Recommends: %{name}-dri-drivers%{?_isa} = %{?epoch:%{epoch}:}%{version}-%{release}
+
+%description libEGL
+%{summary}.
+
+%package libEGL-devel
+Summary: Mesa libEGL development package
+Requires: %{name}-libEGL%{?_isa} = %{?epoch:%{epoch}:}%{version}-%{release}
+Requires: libglvnd-devel%{?_isa} >= 1:1.3.2
+Requires: %{name}-khr-devel%{?_isa}
+Provides: libEGL-devel
+Provides: libEGL-devel%{?_isa}
+
+%description libEGL-devel
+%{summary}.
+
+%package dri-drivers
+Summary: Mesa-based DRI drivers
+Requires: %{name}-filesystem%{?_isa} = %{?epoch:%{epoch}:}%{version}-%{release}
+Requires: %{name}-libglapi%{?_isa} = %{?epoch:%{epoch}:}%{version}-%{release}
+%if 0%{?with_va}
+Recommends: %{name}-va-drivers%{?_isa}
+%endif
+
+%description dri-drivers
+%{summary}.
+
+%if 0%{?with_omx}
+%package omx-drivers
+Summary: Mesa-based OMX drivers
+Requires: %{name}-filesystem%{?_isa} = %{?epoch:%{epoch}:}%{version}-%{release}
+
+%description omx-drivers
+%{summary}.
+%endif
+
+%if 0%{?with_va}
+%package va-drivers
+Summary: Mesa-based VA-API video acceleration drivers
+Requires: %{name}-filesystem%{?_isa} = %{?epoch:%{epoch}:}%{version}-%{release}
+Obsoletes: %{name}-vaapi-drivers < 22.2.0-5
+
+%description va-drivers
+%{summary}.
+%endif
+
+%if 0%{?with_vdpau}
+%package vdpau-drivers
+Summary: Mesa-based VDPAU drivers
+Requires: %{name}-filesystem%{?_isa} = %{?epoch:%{epoch}:}%{version}-%{release}
+
+%description vdpau-drivers
+%{summary}.
+%endif
+
+%package libOSMesa
+Summary: Mesa offscreen rendering libraries
+Requires: %{name}-libglapi%{?_isa} = %{?epoch:%{epoch}:}%{version}-%{release}
+Provides: libOSMesa
+Provides: libOSMesa%{?_isa}
+
+%description libOSMesa
+%{summary}.
+
+%package libOSMesa-devel
+Summary: Mesa offscreen rendering development package
+Requires: %{name}-libOSMesa%{?_isa} = %{?epoch:%{epoch}:}%{version}-%{release}
+
+%description libOSMesa-devel
+%{summary}.
+
+%package libgbm
+Summary: Mesa gbm runtime library
+Provides: libgbm
+Provides: libgbm%{?_isa}
+Recommends: %{name}-dri-drivers%{?_isa} = %{?epoch:%{epoch}:}%{version}-%{release}
+# If mesa-dri-drivers are installed, they must match in version. This is here to prevent using
+# older mesa-dri-drivers together with a newer mesa-libgbm and its dependants.
+# See https://bugzilla.redhat.com/show_bug.cgi?id=2193135 .
+Requires: (%{name}-dri-drivers%{?_isa} = %{?epoch:%{epoch}:}%{version}-%{release} if %{name}-dri-drivers%{?_isa})
+
+%description libgbm
+%{summary}.
+
+%package libgbm-devel
+Summary: Mesa libgbm development package
+Requires: %{name}-libgbm%{?_isa} = %{?epoch:%{epoch}:}%{version}-%{release}
+Provides: libgbm-devel
+Provides: libgbm-devel%{?_isa}
+
+%description libgbm-devel
+%{summary}.
+
+%if 0%{?with_xa}
+%package libxatracker
+Summary: Mesa XA state tracker
+Provides: libxatracker
+Provides: libxatracker%{?_isa}
+
+%description libxatracker
+%{summary}.
+
+%package libxatracker-devel
+Summary: Mesa XA state tracker development package
+Requires: %{name}-libxatracker%{?_isa} = %{?epoch:%{epoch}:}%{version}-%{release}
+Provides: libxatracker-devel
+Provides: libxatracker-devel%{?_isa}
+
+%description libxatracker-devel
+%{summary}.
+%endif
+
+%package libglapi
+Summary: Mesa shared glapi
+Provides: libglapi
+Provides: libglapi%{?_isa}
+# If mesa-dri-drivers are installed, they must match in version. This is here to prevent using
+# older mesa-dri-drivers together with a newer mesa-libglapi or its dependants.
+# See https://bugzilla.redhat.com/show_bug.cgi?id=2193135 .
+Requires: (%{name}-dri-drivers%{?_isa} = %{?epoch:%{epoch}:}%{version}-%{release} if %{name}-dri-drivers%{?_isa})
+
+%description libglapi
+%{summary}.
+
+%if 0%{?with_opencl}
+%package libOpenCL
+Summary: Mesa OpenCL runtime library
+Requires: ocl-icd%{?_isa}
+Requires: libclc%{?_isa}
+Requires: %{name}-libgbm%{?_isa} = %{?epoch:%{epoch}:}%{version}-%{release}
+Requires: opencl-filesystem
+
+%description libOpenCL
+%{summary}.
+
+%package libOpenCL-devel
+Summary: Mesa OpenCL development package
+Requires: %{name}-libOpenCL%{?_isa} = %{?epoch:%{epoch}:}%{version}-%{release}
+
+%description libOpenCL-devel
+%{summary}.
+%endif
+
+%if 0%{?with_nine}
+%package libd3d
+Summary: Mesa Direct3D9 state tracker
+
+%description libd3d
+%{summary}.
+
+%package libd3d-devel
+Summary: Mesa Direct3D9 state tracker development package
+Requires: %{name}-libd3d%{?_isa} = %{?epoch:%{epoch}:}%{version}-%{release}
+
+%description libd3d-devel
+%{summary}.
+%endif
+
+%package vulkan-drivers
+Summary: Mesa Vulkan drivers
+Requires: vulkan%{_isa}
+Obsoletes: mesa-vulkan-devel < %{?epoch:%{epoch}:}%{version}-%{release}
+
+%description vulkan-drivers
+The drivers with support for the Vulkan API.
+
+%prep
+%autosetup -n %{name}-%{ver} -p1
+cp %{SOURCE1} docs/
+
+%build
+# ensure standard Rust compiler flags are set
+export RUSTFLAGS="%build_rustflags"
+
+# We've gotten a report that enabling LTO for mesa breaks some games. See
+# https://bugzilla.redhat.com/show_bug.cgi?id=1862771 for details.
+# Disable LTO for now
+%define _lto_cflags %{nil}
+
+%meson \
+ -Dplatforms=x11,wayland \
+ -Ddri3=enabled \
+ -Dosmesa=true \
+%if 0%{?with_hardware}
+ -Dgallium-drivers=swrast,virgl,nouveau%{?with_r300:,r300}%{?with_crocus:,crocus}%{?with_i915:,i915}%{?with_iris:,iris}%{?with_vmware:,svga}%{?with_radeonsi:,radeonsi}%{?with_r600:,r600}%{?with_freedreno:,freedreno}%{?with_etnaviv:,etnaviv}%{?with_tegra:,tegra}%{?with_vc4:,vc4}%{?with_v3d:,v3d}%{?with_kmsro:,kmsro}%{?with_lima:,lima}%{?with_panfrost:,panfrost}%{?with_vulkan_hw:,zink} \
+%else
+ -Dgallium-drivers=swrast,virgl \
+%endif
+ -Dgallium-vdpau=%{?with_vdpau:enabled}%{!?with_vdpau:disabled} \
+ -Dgallium-omx=%{?with_omx:bellagio}%{!?with_omx:disabled} \
+ -Dgallium-va=%{?with_va:enabled}%{!?with_va:disabled} \
+ -Dgallium-xa=%{?with_xa:enabled}%{!?with_xa:disabled} \
+ -Dgallium-nine=%{?with_nine:true}%{!?with_nine:false} \
+ -Dgallium-opencl=%{?with_opencl:icd}%{!?with_opencl:disabled} \
+%if 0%{?with_opencl}
+ -Dgallium-rusticl=true \
+%endif
+ -Dvulkan-drivers=%{?vulkan_drivers} \
+ -Dvulkan-layers=device-select \
+ -Dshared-glapi=enabled \
+ -Dgles1=enabled \
+ -Dgles2=enabled \
+ -Dopengl=true \
+ -Dgbm=enabled \
+ -Dglx=dri \
+ -Degl=enabled \
+ -Dglvnd=true \
+%if 0%{?with_intel_clc}
+ -Dintel-clc=enabled \
+%endif
+ -Dmicrosoft-clc=disabled \
+ -Dllvm=enabled \
+ -Dshared-llvm=enabled \
+ -Dvalgrind=%{?with_valgrind:enabled}%{!?with_valgrind:disabled} \
+ -Dxlib-lease=enabled \
+ -Dbuild-tests=false \
+ -Dselinux=true \
+%if !0%{?with_libunwind}
+ -Dlibunwind=disabled \
+%endif
+%if !0%{?with_lmsensors}
+ -Dlmsensors=disabled \
+%endif
+ -Dandroid-libbacktrace=disabled \
+%ifarch %{ix86}
+ -Dglx-read-only-text=true
+%endif
+ %{nil}
+%meson_build
+
+%install
+%meson_install
+
+# libvdpau opens the versioned name, don't bother including the unversioned
+rm -vf %{buildroot}%{_libdir}/vdpau/*.so
+# likewise glvnd
+rm -vf %{buildroot}%{_libdir}/libGLX_mesa.so
+rm -vf %{buildroot}%{_libdir}/libEGL_mesa.so
+# XXX can we just not build this
+rm -vf %{buildroot}%{_libdir}/libGLES*
+
+# glvnd needs a default provider for indirect rendering where it cannot
+# determine the vendor
+ln -s %{_libdir}/libGLX_mesa.so.0 %{buildroot}%{_libdir}/libGLX_system.so.0
+
+# this keeps breaking, check it early. note that the exit from eu-ftr is odd.
+pushd %{buildroot}%{_libdir}
+for i in libOSMesa*.so libGL.so ; do
+ eu-findtextrel $i && exit 1
+done
+popd
+
+%ifarch %{ix86}
+rm -Rf %{buildroot}%{_datadir}/drirc.d/00-radv-defaults.conf
+rm -Rf %{buildroot}%{_datadir}/drirc.d/00-mesa-defaults.conf
+%endif
+
+%files filesystem
+%doc docs/Mesa-MLAA-License-Clarification-Email.txt
+%dir %{_libdir}/dri
+%if 0%{?with_hardware}
+%if 0%{?with_vdpau}
+%dir %{_libdir}/vdpau
+%endif
+%endif
+
+%files libGL
+%{_libdir}/libGLX_mesa.so.0*
+%{_libdir}/libGLX_system.so.0*
+%files libGL-devel
+%dir %{_includedir}/GL/internal
+%{_includedir}/GL/internal/dri_interface.h
+%{_libdir}/pkgconfig/dri.pc
+%{_libdir}/libglapi.so
+
+%files libEGL
+%{_datadir}/glvnd/egl_vendor.d/50_mesa.json
+%{_libdir}/libEGL_mesa.so.0*
+%files libEGL-devel
+%dir %{_includedir}/EGL
+%{_includedir}/EGL/eglext_angle.h
+%{_includedir}/EGL/eglmesaext.h
+
+%files libglapi
+%{_libdir}/libglapi.so.0
+%{_libdir}/libglapi.so.0.*
+
+%files libOSMesa
+%{_libdir}/libOSMesa.so.8*
+%files libOSMesa-devel
+%dir %{_includedir}/GL
+%{_includedir}/GL/osmesa.h
+%{_libdir}/libOSMesa.so
+%{_libdir}/pkgconfig/osmesa.pc
+
+%files libgbm
+%{_libdir}/libgbm.so.1
+%{_libdir}/libgbm.so.1.*
+%files libgbm-devel
+%{_libdir}/libgbm.so
+%{_includedir}/gbm.h
+%{_libdir}/pkgconfig/gbm.pc
+
+%if 0%{?with_xa}
+%files libxatracker
+%if 0%{?with_hardware}
+%{_libdir}/libxatracker.so.2
+%{_libdir}/libxatracker.so.2.*
+%endif
+
+%files libxatracker-devel
+%if 0%{?with_hardware}
+%{_libdir}/libxatracker.so
+%{_includedir}/xa_tracker.h
+%{_includedir}/xa_composite.h
+%{_includedir}/xa_context.h
+%{_libdir}/pkgconfig/xatracker.pc
+%endif
+%endif
+
+%if 0%{?with_opencl}
+%files libOpenCL
+%{_libdir}/libMesaOpenCL.so.*
+%{_libdir}/libRusticlOpenCL.so.*
+%{_sysconfdir}/OpenCL/vendors/mesa.icd
+%{_sysconfdir}/OpenCL/vendors/rusticl.icd
+%files libOpenCL-devel
+%{_libdir}/libMesaOpenCL.so
+%{_libdir}/libRusticlOpenCL.so
+%endif
+
+%if 0%{?with_nine}
+%files libd3d
+%dir %{_libdir}/d3d/
+%{_libdir}/d3d/*.so.*
+
+%files libd3d-devel
+%{_libdir}/pkgconfig/d3d.pc
+%{_includedir}/d3dadapter/
+%{_libdir}/d3d/*.so
+%endif
+
+%files dri-drivers
+%dir %{_datadir}/drirc.d
+%ifarch aarch64 x86_64
+%{_datadir}/drirc.d/00-mesa-defaults.conf
+%endif
+%{_libdir}/dri/kms_swrast_dri.so
+%{_libdir}/dri/swrast_dri.so
+%{_libdir}/dri/virtio_gpu_dri.so
+
+%if 0%{?with_hardware}
+%if 0%{?with_r300}
+%{_libdir}/dri/r300_dri.so
+%endif
+%if 0%{?with_radeonsi}
+%if 0%{?with_r600}
+%{_libdir}/dri/r600_dri.so
+%endif
+%{_libdir}/dri/radeonsi_dri.so
+%endif
+%ifarch %{ix86} x86_64
+%{_libdir}/dri/crocus_dri.so
+%{_libdir}/dri/i915_dri.so
+%{_libdir}/dri/iris_dri.so
+%endif
+%ifarch aarch64 x86_64 %{ix86}
+%{_libdir}/dri/ingenic-drm_dri.so
+%{_libdir}/dri/imx-drm_dri.so
+%{_libdir}/dri/imx-lcdif_dri.so
+%{_libdir}/dri/kirin_dri.so
+%{_libdir}/dri/komeda_dri.so
+%{_libdir}/dri/mali-dp_dri.so
+%{_libdir}/dri/mcde_dri.so
+%{_libdir}/dri/mxsfb-drm_dri.so
+%{_libdir}/dri/rcar-du_dri.so
+%{_libdir}/dri/stm_dri.so
+%endif
+%if 0%{?with_vc4}
+%{_libdir}/dri/vc4_dri.so
+%endif
+%if 0%{?with_v3d}
+%{_libdir}/dri/v3d_dri.so
+%endif
+%if 0%{?with_freedreno}
+%{_libdir}/dri/kgsl_dri.so
+%{_libdir}/dri/msm_dri.so
+%endif
+%if 0%{?with_etnaviv}
+%{_libdir}/dri/etnaviv_dri.so
+%endif
+%if 0%{?with_tegra}
+%{_libdir}/dri/tegra_dri.so
+%endif
+%if 0%{?with_lima}
+%{_libdir}/dri/lima_dri.so
+%endif
+%if 0%{?with_panfrost}
+%{_libdir}/dri/panfrost_dri.so
+%endif
+%{_libdir}/dri/nouveau_dri.so
+%if 0%{?with_vmware}
+%{_libdir}/dri/vmwgfx_dri.so
+%endif
+%endif
+%if 0%{?with_opencl}
+%dir %{_libdir}/gallium-pipe
+%{_libdir}/gallium-pipe/*.so
+%endif
+%if 0%{?with_kmsro}
+%{_libdir}/dri/armada-drm_dri.so
+%{_libdir}/dri/exynos_dri.so
+%{_libdir}/dri/hdlcd_dri.so
+%{_libdir}/dri/hx8357d_dri.so
+%{_libdir}/dri/ili9225_dri.so
+%{_libdir}/dri/ili9341_dri.so
+%{_libdir}/dri/imx-dcss_dri.so
+%{_libdir}/dri/mediatek_dri.so
+%{_libdir}/dri/meson_dri.so
+%{_libdir}/dri/mi0283qt_dri.so
+%{_libdir}/dri/pl111_dri.so
+%{_libdir}/dri/repaper_dri.so
+%{_libdir}/dri/rockchip_dri.so
+%{_libdir}/dri/st7586_dri.so
+%{_libdir}/dri/st7735r_dri.so
+%{_libdir}/dri/sun4i-drm_dri.so
+%endif
+%if 0%{?with_vulkan_hw}
+%{_libdir}/dri/zink_dri.so
+%endif
+
+%if 0%{?with_omx}
+%files omx-drivers
+%{_libdir}/bellagio/libomx_mesa.so
+%endif
+
+%if 0%{?with_va}
+%files va-drivers
+%{_libdir}/dri/nouveau_drv_video.so
+%if 0%{?with_r600}
+%{_libdir}/dri/r600_drv_video.so
+%endif
+%if 0%{?with_radeonsi}
+%{_libdir}/dri/radeonsi_drv_video.so
+%endif
+%{_libdir}/dri/virtio_gpu_drv_video.so
+%endif
+
+%if 0%{?with_vdpau}
+%files vdpau-drivers
+%{_libdir}/vdpau/libvdpau_nouveau.so.1*
+%if 0%{?with_r600}
+%{_libdir}/vdpau/libvdpau_r600.so.1*
+%endif
+%if 0%{?with_radeonsi}
+%{_libdir}/vdpau/libvdpau_radeonsi.so.1*
+%endif
+%{_libdir}/vdpau/libvdpau_virtio_gpu.so.1*
+%endif
+
+%files vulkan-drivers
+%{_libdir}/libvulkan_lvp.so
+%{_datadir}/vulkan/icd.d/lvp_icd.*.json
+%{_libdir}/libVkLayer_MESA_device_select.so
+%{_datadir}/vulkan/implicit_layer.d/VkLayer_MESA_device_select.json
+%if 0%{?with_vulkan_hw}
+%{_libdir}/libvulkan_radeon.so
+%ifarch aarch64 x86_64
+%{_datadir}/drirc.d/00-radv-defaults.conf
+%endif
+%{_datadir}/vulkan/icd.d/radeon_icd.*.json
+%{_libdir}/libvulkan_nouveau.so
+%{_datadir}/vulkan/icd.d/nouveau_icd.*.json
+%ifarch %{ix86} x86_64
+%{_libdir}/libvulkan_intel.so
+%{_datadir}/vulkan/icd.d/intel_icd.*.json
+%{_libdir}/libvulkan_intel_hasvk.so
+%{_datadir}/vulkan/icd.d/intel_hasvk_icd.*.json
+%endif
+%ifarch aarch64 x86_64 %{ix86}
+%{_libdir}/libvulkan_broadcom.so
+%{_datadir}/vulkan/icd.d/broadcom_icd.*.json
+%{_libdir}/libvulkan_freedreno.so
+%{_datadir}/vulkan/icd.d/freedreno_icd.*.json
+%{_libdir}/libvulkan_panfrost.so
+%{_datadir}/vulkan/icd.d/panfrost_icd.*.json
+%endif
+%endif
+
+%changelog
+%autochangelog
diff --git a/spec_files/mesa/old/valve.patch b/spec_files/mesa/old/valve.patch
new file mode 100644
index 00000000..627f45c2
--- /dev/null
+++ b/spec_files/mesa/old/valve.patch
@@ -0,0 +1,1670 @@
+From 39b7df3a64e9cfe9c649cd7cda896cef57ae2270 Mon Sep 17 00:00:00 2001
+From: Derek Foreman
+Date: Wed, 20 Sep 2023 10:40:33 -0500
+Subject: [PATCH 1/7] vulkan/wsi/wayland: refactor wayland dispatch code
+
+We currently have two similar but different bits of code to dispatch
+wayland event queues. Pull out as much common code as possible.
+
+Signed-off-by: Derek Foreman
+---
+ src/vulkan/wsi/wsi_common_wayland.c | 399 +++++++++++++++-------------
+ 1 file changed, 208 insertions(+), 191 deletions(-)
+
+diff --git a/src/vulkan/wsi/wsi_common_wayland.c b/src/vulkan/wsi/wsi_common_wayland.c
+index 22e26bacbc5..d8ae6e36626 100644
+--- a/src/vulkan/wsi/wsi_common_wayland.c
++++ b/src/vulkan/wsi/wsi_common_wayland.c
+@@ -96,6 +96,11 @@ struct wsi_wl_display {
+ struct wl_display *wl_display;
+ /* Actually a proxy wrapper around the event queue */
+ struct wl_display *wl_display_wrapper;
++
++ pthread_mutex_t wl_fd_lock;
++ pthread_cond_t wl_fd_reader_finished;
++ bool wl_fd_read_in_progress;
++
+ struct wl_event_queue *queue;
+
+ struct wl_shm *wl_shm;
+@@ -157,6 +162,8 @@ struct wsi_wl_surface {
+ struct wsi_wl_swapchain {
+ struct wsi_swapchain base;
+
++ struct wl_event_queue *queue;
++
+ struct wsi_wl_surface *wsi_wl_surface;
+ struct wp_tearing_control_v1 *tearing_control;
+
+@@ -180,10 +187,7 @@ struct wsi_wl_swapchain {
+ pthread_mutex_t lock; /* protects all members */
+ uint64_t max_completed;
+ struct wl_list outstanding_list;
+- pthread_cond_t list_advanced;
+- struct wl_event_queue *queue;
+ struct wp_presentation *wp_presentation;
+- bool dispatch_in_progress;
+ } present_ids;
+
+ struct wsi_wl_image images[0];
+@@ -208,6 +212,135 @@ find_format(struct u_vector *formats, VkFormat format)
+ return NULL;
+ }
+
++static int
++wsi_wl_display_read_queue_with_timeout_internal(struct wsi_wl_display *wsi_wl_display,
++ struct wl_event_queue *queue,
++ uint64_t atimeout)
++{
++ uint64_t current_time_nsec;
++ struct timespec rel_timeout, end_time, current_time;
++ int ret;
++
++ if (wl_display_prepare_read_queue(wsi_wl_display->wl_display, queue) < 0) {
++ /* Another thread might have read events for our queue already. Go
++ * back to dispatch them.
++ */
++ pthread_mutex_unlock(&wsi_wl_display->wl_fd_lock);
++ if (errno == EAGAIN)
++ return VK_SUCCESS;
++
++ return VK_ERROR_OUT_OF_DATE_KHR;
++ }
++
++ wsi_wl_display->wl_fd_read_in_progress = true;
++ pthread_mutex_unlock(&wsi_wl_display->wl_fd_lock);
++
++ while (1) {
++ struct pollfd pollfd = {
++ .fd = wl_display_get_fd(wsi_wl_display->wl_display),
++ .events = POLLIN
++ };
++
++ current_time_nsec = os_time_get_nano();
++ if (current_time_nsec > atimeout) {
++ rel_timeout.tv_sec = 0;
++ rel_timeout.tv_nsec = 0;
++ } else {
++ timespec_from_nsec(¤t_time, current_time_nsec);
++ timespec_from_nsec(&end_time, atimeout);
++ timespec_sub(&rel_timeout, &end_time, ¤t_time);
++ }
++
++ ret = ppoll(&pollfd, 1, &rel_timeout, NULL);
++ if (ret < 0) {
++ if (errno == EINTR || errno == EAGAIN)
++ continue;
++
++ ret = VK_ERROR_OUT_OF_DATE_KHR;
++ } else if (ret == 0)
++ ret = VK_TIMEOUT;
++ else
++ ret = VK_SUCCESS;
++
++ break;
++ }
++
++ if (ret != VK_SUCCESS) {
++ wl_display_cancel_read(wsi_wl_display->wl_display);
++ } else {
++ ret = wl_display_read_events(wsi_wl_display->wl_display);
++ if (ret != 0)
++ ret = VK_ERROR_OUT_OF_DATE_KHR;
++ }
++
++ pthread_mutex_lock(&wsi_wl_display->wl_fd_lock);
++ wsi_wl_display->wl_fd_read_in_progress = false;
++ pthread_cond_broadcast(&wsi_wl_display->wl_fd_reader_finished);
++ return ret;
++}
++
++static int
++wsi_wl_display_dispatch_queue_with_timeout(struct wsi_wl_display *wsi_wl_display,
++ struct wl_event_queue *queue,
++ uint64_t timeout)
++{
++ int err;
++ int n_events;
++ uint64_t atimeout, now;
++
++ if (timeout == UINT64_MAX)
++ atimeout = timeout;
++ else
++ atimeout = os_time_get_absolute_timeout(timeout);
++
++ while (1) {
++ n_events = wl_display_dispatch_queue_pending(wsi_wl_display->wl_display,
++ queue);
++ if (n_events > 0) {
++ err = VK_SUCCESS;
++ break;
++ }
++ pthread_mutex_lock(&wsi_wl_display->wl_fd_lock);
++
++ if (wsi_wl_display->wl_fd_read_in_progress) {
++ struct timespec end_time;
++
++ timespec_from_nsec(&end_time, atimeout);
++
++ err = pthread_cond_timedwait(&wsi_wl_display->wl_fd_reader_finished,
++ &wsi_wl_display->wl_fd_lock,
++ &end_time);
++ if (err) {
++ if (errno == ETIMEDOUT)
++ err = VK_TIMEOUT;
++ else
++ err = VK_ERROR_OUT_OF_DATE_KHR;
++ } else {
++ /* We don't know if the other thread actually
++ * dispatched anything, so let the caller decide
++ * whether it should continue.
++ */
++ err = VK_INCOMPLETE;
++ }
++ } else {
++ err = wsi_wl_display_read_queue_with_timeout_internal(wsi_wl_display,
++ queue,
++ timeout);
++ }
++
++ pthread_mutex_unlock(&wsi_wl_display->wl_fd_lock);
++
++ now = os_time_get_nano();
++ if (now > atimeout) {
++ err = VK_TIMEOUT;
++ break;
++ }
++
++ }
++
++ return err;
++}
++
+ static struct wsi_wl_format *
+ wsi_wl_display_add_vk_format(struct wsi_wl_display *display,
+ struct u_vector *formats,
+@@ -833,6 +966,8 @@ wsi_wl_display_finish(struct wsi_wl_display *display)
+ wl_proxy_wrapper_destroy(display->wl_display_wrapper);
+ if (display->queue)
+ wl_event_queue_destroy(display->queue);
++ pthread_mutex_destroy(&display->wl_fd_lock);
++ pthread_cond_destroy(&display->wl_fd_reader_finished);
+ }
+
+ static VkResult
+@@ -851,6 +986,11 @@ wsi_wl_display_init(struct wsi_wayland *wsi_wl,
+ display->wl_display = wl_display;
+ display->sw = sw;
+
++ display->wl_fd_read_in_progress = false;
++ pthread_mutex_init(&display->wl_fd_lock, NULL);
++ if (!wsi_init_pthread_cond_monotonic(&display->wl_fd_reader_finished))
++ goto fail;
++
+ display->queue = wl_display_create_queue(wl_display);
+ if (!display->queue) {
+ result = VK_ERROR_OUT_OF_HOST_MEMORY;
+@@ -951,6 +1091,7 @@ fail_registry:
+ wl_registry_destroy(registry);
+
+ fail:
++ pthread_mutex_destroy(&display->wl_fd_lock);
+ wsi_wl_display_finish(display);
+ return result;
+ }
+@@ -1675,19 +1816,15 @@ wsi_wl_swapchain_wait_for_present(struct wsi_swapchain *wsi_chain,
+ uint64_t timeout)
+ {
+ struct wsi_wl_swapchain *chain = (struct wsi_wl_swapchain *)wsi_chain;
+- struct wl_display *wl_display = chain->wsi_wl_surface->display->wl_display;
+- struct timespec end_time;
+- int wl_fd = wl_display_get_fd(wl_display);
+- VkResult ret;
+- int err;
++ uint64_t end_time, time_left, now;
++ int ret;
++ bool expired = false;
++ bool finished;
+
+- uint64_t atimeout;
+- if (timeout == 0 || timeout == UINT64_MAX)
+- atimeout = timeout;
++ if (timeout == UINT64_MAX)
++ end_time = timeout;
+ else
+- atimeout = os_time_get_absolute_timeout(timeout);
+-
+- timespec_from_nsec(&end_time, atimeout);
++ end_time = os_time_get_absolute_timeout(timeout);
+
+ /* Need to observe that the swapchain semaphore has been unsignalled,
+ * as this is guaranteed when a present is complete. */
+@@ -1703,141 +1840,45 @@ wsi_wl_swapchain_wait_for_present(struct wsi_swapchain *wsi_chain,
+ return VK_SUCCESS;
+ }
+
++ while (1) {
++ ret = wl_display_dispatch_queue_pending(chain->wsi_wl_surface->display->wl_display,
++ chain->queue);
++ if (ret < 0)
++ return VK_ERROR_OUT_OF_DATE_KHR;
++
+ /* PresentWait can be called concurrently.
+ * If there is contention on this mutex, it means there is currently a dispatcher in flight holding the lock.
+ * The lock is only held while there is forward progress processing events from Wayland,
+ * so there should be no problem locking without timeout.
+ * We would like to be able to support timeout = 0 to query the current max_completed count.
+ * A timedlock with no timeout can be problematic in that scenario. */
+- err = pthread_mutex_lock(&chain->present_ids.lock);
+- if (err != 0)
+- return VK_ERROR_OUT_OF_DATE_KHR;
+-
+- if (chain->present_ids.max_completed >= present_id) {
++ pthread_mutex_lock(&chain->present_ids.lock);
++ finished = chain->present_ids.max_completed >= present_id;
+ pthread_mutex_unlock(&chain->present_ids.lock);
+- return VK_SUCCESS;
+- }
+-
+- /* Someone else is dispatching events; wait for them to update the chain
+- * status and wake us up. */
+- while (chain->present_ids.dispatch_in_progress) {
+- /* We only own the lock when the wait succeeds. */
+- err = pthread_cond_timedwait(&chain->present_ids.list_advanced,
+- &chain->present_ids.lock, &end_time);
+-
+- if (err == ETIMEDOUT) {
+- pthread_mutex_unlock(&chain->present_ids.lock);
+- return VK_TIMEOUT;
+- } else if (err != 0) {
+- pthread_mutex_unlock(&chain->present_ids.lock);
+- return VK_ERROR_OUT_OF_DATE_KHR;
+- }
+-
+- if (chain->present_ids.max_completed >= present_id) {
+- pthread_mutex_unlock(&chain->present_ids.lock);
++ if (finished)
+ return VK_SUCCESS;
+- }
+-
+- /* Whoever was previously dispatching the events isn't anymore, so we
+- * will take over and fall through below. */
+- if (!chain->present_ids.dispatch_in_progress)
+- break;
+- }
+-
+- assert(!chain->present_ids.dispatch_in_progress);
+- chain->present_ids.dispatch_in_progress = true;
+-
+- /* Whether or not we were dispatching the events before, we are now: pull
+- * all the new events from our event queue, post them, and wake up everyone
+- * else who might be waiting. */
+- while (1) {
+- ret = wl_display_dispatch_queue_pending(wl_display, chain->present_ids.queue);
+- if (ret < 0) {
+- ret = VK_ERROR_OUT_OF_DATE_KHR;
+- goto relinquish_dispatch;
+- }
+-
+- /* Some events dispatched: check the new completions. */
+- if (ret > 0) {
+- /* Completed our own present; stop our own dispatching and let
+- * someone else pick it up. */
+- if (chain->present_ids.max_completed >= present_id) {
+- ret = VK_SUCCESS;
+- goto relinquish_dispatch;
+- }
+-
+- /* Wake up other waiters who may have been unblocked by the events
+- * we just read. */
+- pthread_cond_broadcast(&chain->present_ids.list_advanced);
+- }
+-
+- /* Check for timeout, and relinquish the dispatch to another thread
+- * if we're over our budget. */
+- uint64_t current_time_nsec = os_time_get_nano();
+- if (current_time_nsec > atimeout) {
+- ret = VK_TIMEOUT;
+- goto relinquish_dispatch;
+- }
+-
+- /* To poll and read from WL fd safely, we must be cooperative.
+- * See wl_display_prepare_read_queue in https://wayland.freedesktop.org/docs/html/apb.html */
+-
+- /* Try to read events from the server. */
+- ret = wl_display_prepare_read_queue(wl_display, chain->present_ids.queue);
+- if (ret < 0) {
+- /* Another thread might have read events for our queue already. Go
+- * back to dispatch them.
+- */
+- if (errno == EAGAIN)
+- continue;
+- ret = VK_ERROR_OUT_OF_DATE_KHR;
+- goto relinquish_dispatch;
+- }
+
+- /* Drop the lock around poll, so people can wait whilst we sleep. */
+- pthread_mutex_unlock(&chain->present_ids.lock);
+-
+- struct pollfd pollfd = {
+- .fd = wl_fd,
+- .events = POLLIN
+- };
+- struct timespec current_time, rel_timeout;
+- timespec_from_nsec(¤t_time, current_time_nsec);
+- timespec_sub(&rel_timeout, &end_time, ¤t_time);
+- ret = ppoll(&pollfd, 1, &rel_timeout, NULL);
++ if (expired)
++ return VK_TIMEOUT;
+
+- /* Re-lock after poll; either we're dispatching events under the lock or
+- * bouncing out from an error also under the lock. We can't use timedlock
+- * here because we need to acquire to clear dispatch_in_progress. */
+- pthread_mutex_lock(&chain->present_ids.lock);
++ now = os_time_get_nano();
++ if (now > end_time)
++ time_left = 0;
++ else
++ time_left = end_time - now;
+
+- if (ret <= 0) {
+- int lerrno = errno;
+- wl_display_cancel_read(wl_display);
+- if (ret < 0) {
+- /* If ppoll() was interrupted, try again. */
+- if (lerrno == EINTR || lerrno == EAGAIN)
+- continue;
+- ret = VK_ERROR_OUT_OF_DATE_KHR;
+- goto relinquish_dispatch;
+- }
+- assert(ret == 0);
++ ret = wsi_wl_display_dispatch_queue_with_timeout(chain->wsi_wl_surface->display,
++ chain->queue,
++ time_left);
++ if (ret == VK_INCOMPLETE)
+ continue;
+- }
+
+- ret = wl_display_read_events(wl_display);
+- if (ret < 0) {
+- ret = VK_ERROR_OUT_OF_DATE_KHR;
+- goto relinquish_dispatch;
+- }
+- }
++ if (ret != VK_SUCCESS && ret != VK_TIMEOUT)
++ return ret;
+
+-relinquish_dispatch:
+- assert(chain->present_ids.dispatch_in_progress);
+- chain->present_ids.dispatch_in_progress = false;
+- pthread_cond_broadcast(&chain->present_ids.list_advanced);
+- pthread_mutex_unlock(&chain->present_ids.lock);
+- return ret;
++ if (time_left == 0)
++ expired = true;
++ }
+ }
+
+ static VkResult
+@@ -1847,19 +1888,18 @@ wsi_wl_swapchain_acquire_next_image(struct wsi_swapchain *wsi_chain,
+ {
+ struct wsi_wl_swapchain *chain = (struct wsi_wl_swapchain *)wsi_chain;
+ struct wsi_wl_surface *wsi_wl_surface = chain->wsi_wl_surface;
+- struct timespec start_time, end_time;
+- struct timespec rel_timeout;
+- int wl_fd = wl_display_get_fd(wsi_wl_surface->display->wl_display);
+-
+- timespec_from_nsec(&rel_timeout, info->timeout);
++ uint64_t end_time, time_left, now;
++ bool expired = false;
++ int ret;
+
+- clock_gettime(CLOCK_MONOTONIC, &start_time);
+- timespec_add(&end_time, &rel_timeout, &start_time);
++ if (info->timeout == UINT64_MAX)
++ end_time = info->timeout;
++ else
++ end_time = os_time_get_absolute_timeout(info->timeout);
+
+ while (1) {
+- /* Try to dispatch potential events. */
+- int ret = wl_display_dispatch_queue_pending(wsi_wl_surface->display->wl_display,
+- wsi_wl_surface->display->queue);
++ ret = wl_display_dispatch_queue_pending(wsi_wl_surface->display->wl_display,
++ wsi_wl_surface->display->queue);
+ if (ret < 0)
+ return VK_ERROR_OUT_OF_DATE_KHR;
+
+@@ -1873,46 +1913,26 @@ wsi_wl_swapchain_acquire_next_image(struct wsi_swapchain *wsi_chain,
+ }
+ }
+
+- /* Check for timeout. */
+- struct timespec current_time;
+- clock_gettime(CLOCK_MONOTONIC, ¤t_time);
+- if (timespec_after(¤t_time, &end_time))
+- return (info->timeout ? VK_TIMEOUT : VK_NOT_READY);
++ if (expired)
++ return info->timeout ? VK_TIMEOUT : VK_NOT_READY;
+
+- /* Try to read events from the server. */
+- ret = wl_display_prepare_read_queue(wsi_wl_surface->display->wl_display,
+- wsi_wl_surface->display->queue);
+- if (ret < 0) {
+- /* Another thread might have read events for our queue already. Go
+- * back to dispatch them.
+- */
+- if (errno == EAGAIN)
+- continue;
+- return VK_ERROR_OUT_OF_DATE_KHR;
+- }
++ now = os_time_get_nano();
++ if (now > end_time)
++ time_left = 0;
++ else
++ time_left = end_time - now;
+
+- struct pollfd pollfd = {
+- .fd = wl_fd,
+- .events = POLLIN
+- };
+- timespec_sub(&rel_timeout, &end_time, ¤t_time);
+- ret = ppoll(&pollfd, 1, &rel_timeout, NULL);
+- if (ret <= 0) {
+- int lerrno = errno;
+- wl_display_cancel_read(wsi_wl_surface->display->wl_display);
+- if (ret < 0) {
+- /* If ppoll() was interrupted, try again. */
+- if (lerrno == EINTR || lerrno == EAGAIN)
+- continue;
+- return VK_ERROR_OUT_OF_DATE_KHR;
+- }
+- assert(ret == 0);
++ ret = wsi_wl_display_dispatch_queue_with_timeout(wsi_wl_surface->display,
++ wsi_wl_surface->display->queue,
++ time_left);
++ if (ret == VK_ERROR_OUT_OF_DATE_KHR)
++ return ret;
++
++ if (ret == VK_INCOMPLETE)
+ continue;
+- }
+
+- ret = wl_display_read_events(wsi_wl_surface->display->wl_display);
+- if (ret < 0)
+- return VK_ERROR_OUT_OF_DATE_KHR;
++ if (ret == VK_TIMEOUT)
++ expired = true;
+ }
+ }
+
+@@ -1933,9 +1953,10 @@ presentation_handle_presented(void *data,
+ {
+ struct wsi_wl_present_id *id = data;
+
+- /* present_ids.lock already held around dispatch */
++ pthread_mutex_lock(&id->chain->present_ids.lock);
+ if (id->present_id > id->chain->present_ids.max_completed)
+ id->chain->present_ids.max_completed = id->present_id;
++ pthread_mutex_unlock(&id->chain->present_ids.lock);
+
+ wp_presentation_feedback_destroy(feedback);
+ wl_list_remove(&id->link);
+@@ -1948,9 +1969,10 @@ presentation_handle_discarded(void *data,
+ {
+ struct wsi_wl_present_id *id = data;
+
+- /* present_ids.lock already held around dispatch */
++ pthread_mutex_lock(&id->chain->present_ids.lock);
+ if (id->present_id > id->chain->present_ids.max_completed)
+ id->chain->present_ids.max_completed = id->present_id;
++ pthread_mutex_unlock(&id->chain->present_ids.lock);
+
+ wp_presentation_feedback_destroy(feedback);
+ wl_list_remove(&id->link);
+@@ -2198,8 +2220,6 @@ wsi_wl_swapchain_chain_free(struct wsi_wl_swapchain *chain,
+ chain->wsi_wl_surface->chain = NULL;
+
+ if (chain->present_ids.wp_presentation) {
+- assert(!chain->present_ids.dispatch_in_progress);
+-
+ /* In VK_EXT_swapchain_maintenance1 there is no requirement to wait for all present IDs to be complete.
+ * Waiting for the swapchain fence is enough.
+ * Just clean up anything user did not wait for. */
+@@ -2211,7 +2231,6 @@ wsi_wl_swapchain_chain_free(struct wsi_wl_swapchain *chain,
+ }
+
+ wl_proxy_wrapper_destroy(chain->present_ids.wp_presentation);
+- pthread_cond_destroy(&chain->present_ids.list_advanced);
+ pthread_mutex_destroy(&chain->present_ids.lock);
+ }
+
+@@ -2383,18 +2402,16 @@ wsi_wl_surface_create_swapchain(VkIcdSurfaceBase *icd_surface,
+ chain->drm_modifiers = drm_modifiers_copy;
+ }
+
++ chain->queue = wl_display_create_queue(chain->wsi_wl_surface->display->wl_display);
++
+ if (chain->wsi_wl_surface->display->wp_presentation_notwrapped) {
+- if (!wsi_init_pthread_cond_monotonic(&chain->present_ids.list_advanced))
+- goto fail;
+ pthread_mutex_init(&chain->present_ids.lock, NULL);
+
+ wl_list_init(&chain->present_ids.outstanding_list);
+- chain->present_ids.queue =
+- wl_display_create_queue(chain->wsi_wl_surface->display->wl_display);
+ chain->present_ids.wp_presentation =
+ wl_proxy_create_wrapper(chain->wsi_wl_surface->display->wp_presentation_notwrapped);
+ wl_proxy_set_queue((struct wl_proxy *) chain->present_ids.wp_presentation,
+- chain->present_ids.queue);
++ chain->queue);
+ }
+
+ chain->fifo_ready = true;
+--
+2.42.0
+
+
+From ad381d34e00a89f1961cf345668b939830ed1d39 Mon Sep 17 00:00:00 2001
+From: Derek Foreman
+Date: Fri, 10 Nov 2023 07:25:35 -0600
+Subject: [PATCH 2/7] vulkan/wsi/wayland: Use commit_timing/commit_queue
+ protocol for FIFO
+
+The commit_timing protocol allows us to set a presentation timestamp,
+and the commit_queue protocol allows us to request FIFO semantics for
+committed state (instead of the default mailbox).
+
+I these are available, use them to implement Vulkan's FIFO presentation
+mode.
+
+Signed-off-by: Derek Foreman
+---
+ src/egl/wayland/wayland-drm/meson.build | 2 +
+ src/vulkan/wsi/meson.build | 2 +
+ src/vulkan/wsi/wsi_common_wayland.c | 138 +++++++++++++++++++++---
+ 3 files changed, 130 insertions(+), 12 deletions(-)
+
+diff --git a/src/egl/wayland/wayland-drm/meson.build b/src/egl/wayland/wayland-drm/meson.build
+index ac822acec67..8b6044f09e5 100644
+--- a/src/egl/wayland/wayland-drm/meson.build
++++ b/src/egl/wayland/wayland-drm/meson.build
+@@ -59,6 +59,8 @@ libwayland_drm = static_library(
+ # here for now as the maybe-least-bad solution.
+ wp_dir = dep_wl_protocols.get_variable(pkgconfig : 'pkgdatadir', internal : 'pkgdatadir')
+ wp_protos = {
++ 'commit-queue-v1': 'staging/commit-queue/commit-queue-v1.xml',
++ 'commit-timing-v1': 'staging/commit-timing/commit-timing-v1.xml',
+ 'linux-dmabuf-unstable-v1': 'unstable/linux-dmabuf/linux-dmabuf-unstable-v1.xml',
+ 'presentation-time': 'stable/presentation-time/presentation-time.xml',
+ 'tearing-control-v1': 'staging/tearing-control/tearing-control-v1.xml',
+diff --git a/src/vulkan/wsi/meson.build b/src/vulkan/wsi/meson.build
+index 9d0db011767..83ad71f06fa 100644
+--- a/src/vulkan/wsi/meson.build
++++ b/src/vulkan/wsi/meson.build
+@@ -31,6 +31,8 @@ endif
+
+ if with_platform_wayland
+ files_vulkan_wsi += files('wsi_common_wayland.c')
++ files_vulkan_wsi += wp_files['commit-queue-v1']
++ files_vulkan_wsi += wp_files['commit-timing-v1']
+ files_vulkan_wsi += wp_files['linux-dmabuf-unstable-v1']
+ files_vulkan_wsi += wp_files['presentation-time']
+ files_vulkan_wsi += wp_files['tearing-control-v1']
+diff --git a/src/vulkan/wsi/wsi_common_wayland.c b/src/vulkan/wsi/wsi_common_wayland.c
+index d8ae6e36626..dd78d98dfce 100644
+--- a/src/vulkan/wsi/wsi_common_wayland.c
++++ b/src/vulkan/wsi/wsi_common_wayland.c
+@@ -41,6 +41,8 @@
+ #include "vk_util.h"
+ #include "wsi_common_entrypoints.h"
+ #include "wsi_common_private.h"
++#include "commit-queue-v1-client-protocol.h"
++#include "commit-timing-v1-client-protocol.h"
+ #include "linux-dmabuf-unstable-v1-client-protocol.h"
+ #include "presentation-time-client-protocol.h"
+ #include "tearing-control-v1-client-protocol.h"
+@@ -113,6 +115,9 @@ struct wsi_wl_display {
+ /* users want per-chain wsi_wl_swapchain->present_ids.wp_presentation */
+ struct wp_presentation *wp_presentation_notwrapped;
+
++ struct wp_commit_queue_manager_v1 *commit_queue_manager;
++ struct wp_commit_timing_manager_v1 *commit_timing_manager;
++
+ struct wsi_wayland *wsi_wl;
+
+ /* Formats populated by zwp_linux_dmabuf_v1 or wl_shm interfaces */
+@@ -135,6 +140,7 @@ struct wsi_wayland {
+
+ struct wsi_wl_image {
+ struct wsi_image base;
++ struct wsi_wl_swapchain *chain;
+ struct wl_buffer *buffer;
+ bool busy;
+ int shm_fd;
+@@ -166,6 +172,9 @@ struct wsi_wl_swapchain {
+
+ struct wsi_wl_surface *wsi_wl_surface;
+ struct wp_tearing_control_v1 *tearing_control;
++ struct wp_commit_queue_v1 *commit_queue;
++ struct wp_commit_timer_v1 *commit_timer;
++ bool can_timestamp;
+
+ struct wl_callback *frame;
+
+@@ -181,13 +190,17 @@ struct wsi_wl_swapchain {
+ const uint64_t *drm_modifiers;
+
+ VkPresentModeKHR present_mode;
+- bool fifo_ready;
++ bool legacy_fifo_ready;
++
++ uint64_t last_target_time;
+
+ struct {
+ pthread_mutex_t lock; /* protects all members */
+ uint64_t max_completed;
+ struct wl_list outstanding_list;
+ struct wp_presentation *wp_presentation;
++ uint64_t phase_time;
++ unsigned int refresh_nsec;
+ } present_ids;
+
+ struct wsi_wl_image images[0];
+@@ -934,6 +947,12 @@ registry_handle_global(void *data, struct wl_registry *registry,
+ } else if (strcmp(interface, wp_tearing_control_manager_v1_interface.name) == 0) {
+ display->tearing_control_manager =
+ wl_registry_bind(registry, name, &wp_tearing_control_manager_v1_interface, 1);
++ } else if (strcmp(interface, wp_commit_timing_manager_v1_interface.name) == 0) {
++ display->commit_timing_manager =
++ wl_registry_bind(registry, name, &wp_commit_timing_manager_v1_interface, 1);
++ } else if (strcmp(interface, wp_commit_queue_manager_v1_interface.name) == 0) {
++ display->commit_queue_manager =
++ wl_registry_bind(registry, name, &wp_commit_queue_manager_v1_interface, 1);
+ }
+ }
+
+@@ -960,6 +979,10 @@ wsi_wl_display_finish(struct wsi_wl_display *display)
+ zwp_linux_dmabuf_v1_destroy(display->wl_dmabuf);
+ if (display->wp_presentation_notwrapped)
+ wp_presentation_destroy(display->wp_presentation_notwrapped);
++ if (display->commit_queue_manager)
++ wp_commit_queue_manager_v1_destroy(display->commit_queue_manager);
++ if (display->commit_timing_manager)
++ wp_commit_timing_manager_v1_destroy(display->commit_timing_manager);
+ if (display->tearing_control_manager)
+ wp_tearing_control_manager_v1_destroy(display->tearing_control_manager);
+ if (display->wl_display_wrapper)
+@@ -1922,6 +1945,16 @@ wsi_wl_swapchain_acquire_next_image(struct wsi_swapchain *wsi_chain,
+ else
+ time_left = end_time - now;
+
++ /* If we can use timestamps, we want to make sure to dispatch the queue
++ * feedback events are in so we can get a refresh rate and a vsync time to
++ * phase lock to */
++ if (chain->can_timestamp) {
++ ret = wl_display_dispatch_queue_pending(wsi_wl_surface->display->wl_display,
++ chain->queue);
++ if (ret < 0)
++ return VK_ERROR_OUT_OF_DATE_KHR;
++ }
++
+ ret = wsi_wl_display_dispatch_queue_with_timeout(wsi_wl_surface->display,
+ wsi_wl_surface->display->queue,
+ time_left);
+@@ -1952,10 +1985,16 @@ presentation_handle_presented(void *data,
+ uint32_t flags)
+ {
+ struct wsi_wl_present_id *id = data;
++ struct timespec presentation_time;
+
+ pthread_mutex_lock(&id->chain->present_ids.lock);
+ if (id->present_id > id->chain->present_ids.max_completed)
+ id->chain->present_ids.max_completed = id->present_id;
++
++ presentation_time.tv_sec = ((uint64_t)tv_sec_hi << 32) + tv_sec_lo;
++ presentation_time.tv_nsec = tv_nsec;
++ id->chain->present_ids.phase_time = timespec_to_nsec(&presentation_time);
++ id->chain->present_ids.refresh_nsec = refresh;
+ pthread_mutex_unlock(&id->chain->present_ids.lock);
+
+ wp_presentation_feedback_destroy(feedback);
+@@ -1991,8 +2030,10 @@ frame_handle_done(void *data, struct wl_callback *callback, uint32_t serial)
+ {
+ struct wsi_wl_swapchain *chain = data;
+
++ assert(!chain->can_timestamp);
++
+ chain->frame = NULL;
+- chain->fifo_ready = true;
++ chain->legacy_fifo_ready = true;
+
+ wl_callback_destroy(callback);
+ }
+@@ -2001,6 +2042,46 @@ static const struct wl_callback_listener frame_listener = {
+ frame_handle_done,
+ };
+
++static void
++set_timestamp(struct wsi_wl_swapchain *chain)
++{
++ uint64_t now, target;
++ struct timespec target_ts;
++ uint64_t refresh;
++ uint64_t phase_time;
++
++ now = os_time_get_nano();
++
++ pthread_mutex_lock(&chain->present_ids.lock);
++ phase_time = chain->present_ids.phase_time;
++ refresh = chain->present_ids.refresh_nsec;
++ pthread_mutex_unlock(&chain->present_ids.lock);
++
++ if (refresh == 0)
++ refresh = 16666666;
++
++ target = chain->last_target_time + refresh;
++
++ if (now > target) {
++ uint64_t offset;
++
++ if (phase_time > now)
++ now = phase_time;
++
++ offset = (now - phase_time) % refresh;
++ target = now - offset + refresh;
++ }
++
++ timespec_from_nsec(&target_ts, target);
++ wp_commit_timer_v1_set_timestamp(chain->commit_timer,
++ target_ts.tv_sec >> 32, target_ts.tv_sec,
++ target_ts.tv_nsec);
++
++ wp_commit_queue_v1_set_queue_mode(chain->commit_queue,
++ WP_COMMIT_QUEUE_V1_QUEUE_MODE_FIFO);
++ chain->last_target_time = target;
++}
++
+ static VkResult
+ wsi_wl_swapchain_queue_present(struct wsi_swapchain *wsi_chain,
+ uint32_t image_index,
+@@ -2009,6 +2090,7 @@ wsi_wl_swapchain_queue_present(struct wsi_swapchain *wsi_chain,
+ {
+ struct wsi_wl_swapchain *chain = (struct wsi_wl_swapchain *)wsi_chain;
+ struct wsi_wl_surface *wsi_wl_surface = chain->wsi_wl_surface;
++ bool mode_fifo = chain->base.present_mode == VK_PRESENT_MODE_FIFO_KHR;
+
+ if (chain->buffer_type == WSI_WL_BUFFER_SHM_MEMCPY) {
+ struct wsi_wl_image *image = &chain->images[image_index];
+@@ -2018,7 +2100,7 @@ wsi_wl_swapchain_queue_present(struct wsi_swapchain *wsi_chain,
+
+ /* For EXT_swapchain_maintenance1. We might have transitioned from FIFO to MAILBOX.
+ * In this case we need to let the FIFO request complete, before presenting MAILBOX. */
+- while (!chain->fifo_ready) {
++ while (!chain->can_timestamp && !chain->legacy_fifo_ready) {
+ int ret = wl_display_dispatch_queue(wsi_wl_surface->display->wl_display,
+ wsi_wl_surface->display->queue);
+ if (ret < 0)
+@@ -2041,16 +2123,19 @@ wsi_wl_swapchain_queue_present(struct wsi_swapchain *wsi_chain,
+ wl_surface_damage(wsi_wl_surface->surface, 0, 0, INT32_MAX, INT32_MAX);
+ }
+
+- if (chain->base.present_mode == VK_PRESENT_MODE_FIFO_KHR) {
+- chain->frame = wl_surface_frame(wsi_wl_surface->surface);
+- wl_callback_add_listener(chain->frame, &frame_listener, chain);
+- chain->fifo_ready = false;
+- } else {
+- /* If we present MAILBOX, any subsequent presentation in FIFO can replace this image. */
+- chain->fifo_ready = true;
++ if (!chain->can_timestamp) {
++ if (mode_fifo) {
++ chain->frame = wl_surface_frame(wsi_wl_surface->surface);
++ wl_callback_add_listener(chain->frame, &frame_listener, chain);
++ chain->legacy_fifo_ready = false;
++ } else {
++ /* If we present MAILBOX, any subsequent presentation in FIFO can replace this image. */
++ chain->legacy_fifo_ready = true;
++ }
+ }
+
+- if (present_id > 0 && chain->present_ids.wp_presentation) {
++ if (chain->present_ids.wp_presentation &&
++ (present_id > 0 || (chain->can_timestamp && mode_fifo))) {
+ struct wsi_wl_present_id *id =
+ vk_zalloc(chain->wsi_wl_surface->display->wsi_wl->alloc, sizeof(*id), sizeof(uintptr_t),
+ VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
+@@ -2069,6 +2154,10 @@ wsi_wl_swapchain_queue_present(struct wsi_swapchain *wsi_chain,
+ }
+
+ chain->images[image_index].busy = true;
++
++ if (chain->can_timestamp && mode_fifo)
++ set_timestamp(chain);
++
+ wl_surface_commit(wsi_wl_surface->surface);
+ wl_display_flush(wsi_wl_surface->display->wl_display);
+
+@@ -2184,6 +2273,7 @@ wsi_wl_image_init(struct wsi_wl_swapchain *chain,
+ goto fail_image;
+
+ wl_buffer_add_listener(image->buffer, &buffer_listener, image);
++ image->chain = chain;
+
+ return VK_SUCCESS;
+
+@@ -2234,6 +2324,12 @@ wsi_wl_swapchain_chain_free(struct wsi_wl_swapchain *chain,
+ pthread_mutex_destroy(&chain->present_ids.lock);
+ }
+
++ if (chain->commit_queue)
++ wp_commit_queue_v1_destroy(chain->commit_queue);
++
++ if (chain->commit_timer)
++ wp_commit_timer_v1_destroy(chain->commit_timer);
++
+ vk_free(pAllocator, (void *)chain->drm_modifiers);
+
+ wsi_swapchain_finish(&chain->base);
+@@ -2290,6 +2386,15 @@ wsi_wl_surface_create_swapchain(VkIcdSurfaceBase *icd_surface,
+ wp_tearing_control_v1_destroy(old_chain->tearing_control);
+ old_chain->tearing_control = NULL;
+ }
++ if (old_chain->commit_queue) {
++ wp_commit_queue_v1_destroy(old_chain->commit_queue);
++ old_chain->commit_queue = NULL;
++ old_chain->can_timestamp = false;
++ }
++ if (old_chain->commit_timer) {
++ wp_commit_timer_v1_destroy(old_chain->commit_timer);
++ old_chain->commit_timer = NULL;
++ }
+ }
+
+ /* Take ownership of the wsi_wl_surface */
+@@ -2414,7 +2519,16 @@ wsi_wl_surface_create_swapchain(VkIcdSurfaceBase *icd_surface,
+ chain->queue);
+ }
+
+- chain->fifo_ready = true;
++ chain->legacy_fifo_ready = true;
++ struct wsi_wl_display *dpy = chain->wsi_wl_surface->display;
++ if (dpy->commit_queue_manager &&
++ dpy->commit_timing_manager) {
++ chain->commit_queue = wp_commit_queue_manager_v1_get_queue_controller(dpy->commit_queue_manager,
++ chain->wsi_wl_surface->surface);
++ chain->commit_timer = wp_commit_timing_manager_v1_get_timer(dpy->commit_timing_manager,
++ chain->wsi_wl_surface->surface);
++ chain->can_timestamp = true;
++ }
+
+ for (uint32_t i = 0; i < chain->base.image_count; i++) {
+ result = wsi_wl_image_init(chain, &chain->images[i],
+--
+2.42.0
+
+
+From dfa0495e9fbe27216cfbcfd3564eeeb1c00a4e6e Mon Sep 17 00:00:00 2001
+From: Simon Ser
+Date: Sat, 25 Nov 2023 16:25:58 +0100
+Subject: [PATCH 3/7] hack: rip out commit-timing-v1
+
+---
+ src/egl/wayland/wayland-drm/meson.build | 2 +-
+ src/vulkan/wsi/meson.build | 2 +-
+ src/vulkan/wsi/wsi_common_wayland.c | 24 ++----------------------
+ 3 files changed, 4 insertions(+), 24 deletions(-)
+
+diff --git a/src/egl/wayland/wayland-drm/meson.build b/src/egl/wayland/wayland-drm/meson.build
+index 8b6044f09e5..83a63385274 100644
+--- a/src/egl/wayland/wayland-drm/meson.build
++++ b/src/egl/wayland/wayland-drm/meson.build
+@@ -60,7 +60,7 @@ libwayland_drm = static_library(
+ wp_dir = dep_wl_protocols.get_variable(pkgconfig : 'pkgdatadir', internal : 'pkgdatadir')
+ wp_protos = {
+ 'commit-queue-v1': 'staging/commit-queue/commit-queue-v1.xml',
+- 'commit-timing-v1': 'staging/commit-timing/commit-timing-v1.xml',
++ #'commit-timing-v1': 'staging/commit-timing/commit-timing-v1.xml',
+ 'linux-dmabuf-unstable-v1': 'unstable/linux-dmabuf/linux-dmabuf-unstable-v1.xml',
+ 'presentation-time': 'stable/presentation-time/presentation-time.xml',
+ 'tearing-control-v1': 'staging/tearing-control/tearing-control-v1.xml',
+diff --git a/src/vulkan/wsi/meson.build b/src/vulkan/wsi/meson.build
+index 83ad71f06fa..dba95387975 100644
+--- a/src/vulkan/wsi/meson.build
++++ b/src/vulkan/wsi/meson.build
+@@ -32,7 +32,7 @@ endif
+ if with_platform_wayland
+ files_vulkan_wsi += files('wsi_common_wayland.c')
+ files_vulkan_wsi += wp_files['commit-queue-v1']
+- files_vulkan_wsi += wp_files['commit-timing-v1']
++ #files_vulkan_wsi += wp_files['commit-timing-v1']
+ files_vulkan_wsi += wp_files['linux-dmabuf-unstable-v1']
+ files_vulkan_wsi += wp_files['presentation-time']
+ files_vulkan_wsi += wp_files['tearing-control-v1']
+diff --git a/src/vulkan/wsi/wsi_common_wayland.c b/src/vulkan/wsi/wsi_common_wayland.c
+index dd78d98dfce..1efe9e449e8 100644
+--- a/src/vulkan/wsi/wsi_common_wayland.c
++++ b/src/vulkan/wsi/wsi_common_wayland.c
+@@ -42,7 +42,6 @@
+ #include "wsi_common_entrypoints.h"
+ #include "wsi_common_private.h"
+ #include "commit-queue-v1-client-protocol.h"
+-#include "commit-timing-v1-client-protocol.h"
+ #include "linux-dmabuf-unstable-v1-client-protocol.h"
+ #include "presentation-time-client-protocol.h"
+ #include "tearing-control-v1-client-protocol.h"
+@@ -116,7 +115,6 @@ struct wsi_wl_display {
+ struct wp_presentation *wp_presentation_notwrapped;
+
+ struct wp_commit_queue_manager_v1 *commit_queue_manager;
+- struct wp_commit_timing_manager_v1 *commit_timing_manager;
+
+ struct wsi_wayland *wsi_wl;
+
+@@ -173,7 +171,6 @@ struct wsi_wl_swapchain {
+ struct wsi_wl_surface *wsi_wl_surface;
+ struct wp_tearing_control_v1 *tearing_control;
+ struct wp_commit_queue_v1 *commit_queue;
+- struct wp_commit_timer_v1 *commit_timer;
+ bool can_timestamp;
+
+ struct wl_callback *frame;
+@@ -947,9 +944,6 @@ registry_handle_global(void *data, struct wl_registry *registry,
+ } else if (strcmp(interface, wp_tearing_control_manager_v1_interface.name) == 0) {
+ display->tearing_control_manager =
+ wl_registry_bind(registry, name, &wp_tearing_control_manager_v1_interface, 1);
+- } else if (strcmp(interface, wp_commit_timing_manager_v1_interface.name) == 0) {
+- display->commit_timing_manager =
+- wl_registry_bind(registry, name, &wp_commit_timing_manager_v1_interface, 1);
+ } else if (strcmp(interface, wp_commit_queue_manager_v1_interface.name) == 0) {
+ display->commit_queue_manager =
+ wl_registry_bind(registry, name, &wp_commit_queue_manager_v1_interface, 1);
+@@ -981,8 +975,6 @@ wsi_wl_display_finish(struct wsi_wl_display *display)
+ wp_presentation_destroy(display->wp_presentation_notwrapped);
+ if (display->commit_queue_manager)
+ wp_commit_queue_manager_v1_destroy(display->commit_queue_manager);
+- if (display->commit_timing_manager)
+- wp_commit_timing_manager_v1_destroy(display->commit_timing_manager);
+ if (display->tearing_control_manager)
+ wp_tearing_control_manager_v1_destroy(display->tearing_control_manager);
+ if (display->wl_display_wrapper)
+@@ -2073,9 +2065,6 @@ set_timestamp(struct wsi_wl_swapchain *chain)
+ }
+
+ timespec_from_nsec(&target_ts, target);
+- wp_commit_timer_v1_set_timestamp(chain->commit_timer,
+- target_ts.tv_sec >> 32, target_ts.tv_sec,
+- target_ts.tv_nsec);
+
+ wp_commit_queue_v1_set_queue_mode(chain->commit_queue,
+ WP_COMMIT_QUEUE_V1_QUEUE_MODE_FIFO);
+@@ -2091,6 +2080,7 @@ wsi_wl_swapchain_queue_present(struct wsi_swapchain *wsi_chain,
+ struct wsi_wl_swapchain *chain = (struct wsi_wl_swapchain *)wsi_chain;
+ struct wsi_wl_surface *wsi_wl_surface = chain->wsi_wl_surface;
+ bool mode_fifo = chain->base.present_mode == VK_PRESENT_MODE_FIFO_KHR;
++ //fprintf(stderr, "FIFO = %d\n", mode_fifo);
+
+ if (chain->buffer_type == WSI_WL_BUFFER_SHM_MEMCPY) {
+ struct wsi_wl_image *image = &chain->images[image_index];
+@@ -2327,9 +2317,6 @@ wsi_wl_swapchain_chain_free(struct wsi_wl_swapchain *chain,
+ if (chain->commit_queue)
+ wp_commit_queue_v1_destroy(chain->commit_queue);
+
+- if (chain->commit_timer)
+- wp_commit_timer_v1_destroy(chain->commit_timer);
+-
+ vk_free(pAllocator, (void *)chain->drm_modifiers);
+
+ wsi_swapchain_finish(&chain->base);
+@@ -2391,10 +2378,6 @@ wsi_wl_surface_create_swapchain(VkIcdSurfaceBase *icd_surface,
+ old_chain->commit_queue = NULL;
+ old_chain->can_timestamp = false;
+ }
+- if (old_chain->commit_timer) {
+- wp_commit_timer_v1_destroy(old_chain->commit_timer);
+- old_chain->commit_timer = NULL;
+- }
+ }
+
+ /* Take ownership of the wsi_wl_surface */
+@@ -2521,12 +2504,9 @@ wsi_wl_surface_create_swapchain(VkIcdSurfaceBase *icd_surface,
+
+ chain->legacy_fifo_ready = true;
+ struct wsi_wl_display *dpy = chain->wsi_wl_surface->display;
+- if (dpy->commit_queue_manager &&
+- dpy->commit_timing_manager) {
++ if (dpy->commit_queue_manager) {
+ chain->commit_queue = wp_commit_queue_manager_v1_get_queue_controller(dpy->commit_queue_manager,
+ chain->wsi_wl_surface->surface);
+- chain->commit_timer = wp_commit_timing_manager_v1_get_timer(dpy->commit_timing_manager,
+- chain->wsi_wl_surface->surface);
+ chain->can_timestamp = true;
+ }
+
+--
+2.42.0
+
+
+From fbb52f6f45b02583a0b496e4cc34af34251cb1bd Mon Sep 17 00:00:00 2001
+From: Joshua Ashton
+Date: Wed, 29 Nov 2023 11:06:51 +0000
+Subject: [PATCH 4/7] wsi: Use vendored gamescope-commit-queue-v1 protocol
+
+---
+ .../wayland-drm/gamescope-commit-queue-v1.xml | 181 ++++++++++++++++++
+ src/egl/wayland/wayland-drm/meson.build | 22 ++-
+ src/vulkan/wsi/meson.build | 2 +-
+ src/vulkan/wsi/wsi_common_wayland.c | 22 +--
+ 4 files changed, 214 insertions(+), 13 deletions(-)
+ create mode 100644 src/egl/wayland/wayland-drm/gamescope-commit-queue-v1.xml
+
+diff --git a/src/egl/wayland/wayland-drm/gamescope-commit-queue-v1.xml b/src/egl/wayland/wayland-drm/gamescope-commit-queue-v1.xml
+new file mode 100644
+index 00000000000..d460e0bc10f
+--- /dev/null
++++ b/src/egl/wayland/wayland-drm/gamescope-commit-queue-v1.xml
+@@ -0,0 +1,181 @@
++
++
++
++ Copyright © 2023 Valve Corporation
++
++ Permission is hereby granted, free of charge, to any person obtaining a
++ copy of this software and associated documentation files (the "Software"),
++ to deal in the Software without restriction, including without limitation
++ the rights to use, copy, modify, merge, publish, distribute, sublicense,
++ and/or sell copies of the Software, and to permit persons to whom the
++ Software is furnished to do so, subject to the following conditions:
++
++ The above copyright notice and this permission notice (including the next
++ paragraph) shall be included in all copies or substantial portions of the
++ Software.
++
++ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
++ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
++ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
++ THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
++ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
++ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
++ DEALINGS IN THE SOFTWARE.
++
++
++
++
++ By design Wayland uses a "mailbox" style presentation model. Under
++ the mailbox model, when wl_surface.commit is called, the currently
++ pending state is intended to replace the current state immediately.
++
++ If state is committed many times before the compositor repaints a
++ scene, each commit takes place immediately, updating the existing
++ state. When the compositor repaints the display only the most
++ recent accumulation of state is visible. This may lead to client
++ buffers being released without presentation if they were replaced
++ before being displayed.
++
++ There are other presentation models such as FIFO (First In First
++ Out) in which state commits are explicitly queued for future
++ repaint intervals, and client buffers should not be released
++ without being displayed.
++
++ Graphics APIs such as Vulkan aim to support these presentation
++ models, but they are not implementable on top of our mailbox model
++ without the ability to change the default surface state handling
++ behaviour.
++
++ This interface provides a way to control the compositor's surface
++ state handling to enable presentation models other than mailbox.
++
++ It does so by exposing control of a compositor surface state queue,
++ and specifying for each call of wl_surface.commit whether the
++ pending state should be handled in a mailbox or a FIFO fashion.
++
++ Warning! The protocol described in this file is currently in the testing
++ phase. Backward compatible changes may be added together with the
++ corresponding interface version bump. Backward incompatible changes can
++ only be done by creating a new major version of the extension.
++
++
++
++ These fatal protocol errors may be emitted in response to
++ illegal requests.
++
++
++
++
++
++
++ Informs the server that the client will no longer be using
++ this protocol object. Existing objects created by this object
++ are not affected.
++
++
++
++
++
++ Establish a queue controller for a surface.
++
++ Graphics APIs (EGL, Vulkan) will likely use this protocol
++ internally, so clients using them shouldn't directly use this
++ protocol on surfaces managed by those APIs, or a
++ queue_controller_already_exists protocol error will occur.
++
++
++
++
++
++
++
++
++ A queue controller for a surface.
++
++ A wayland compositor may implicitly queue surface state to
++ allow it to pick the most recently ready state at repaint time,
++ or to allow surface state to contain timing information.
++
++ The commit queue controller object allows explicit control over
++ the queue of upcoming surface state by allowing a client to attach
++ a queue drain mode to pending surface state before it calls
++ wl_surface.commit.
++
++
++
++
++ These fatal protocol errors may be emitted in response to
++ illegal requests.
++
++
++
++
++
++
++ This enum is used to choose how the compositor processes a queue
++ entry at output repaint time.
++
++
++
++ State from this queue slot may be updated immediately (without
++ completing a repaint) if newer state is ready to display at
++ repaint time.
++
++
++
++
++ This queue slot will be the last state update for this surface
++ that the compositor will process during the repaint in which
++ it is ready for display.
++
++ If the compositor is presenting with tearing, the surface state
++ must be made current for an iteration of the compositor's repaint
++ loop. This may result in the state being visible for a very short
++ duration, with visible artifacts, or even not visible at all for
++ surfaces that aren't full screen.
++
++ The compositor must not cause state processing to stall indefinitely
++ for a surface that is occluded or otherwise not visible. Instead,
++ if the compositor is choosing not to present a surface for reasons
++ unrelated to state readiness, the FIFO condition must be considered
++ satisfied at the moment new state becomes ready to replace the
++ undisplayed state.
++
++
++
++
++
++
++ This request adds a queue drain mode to the pending surface
++ state, which will be commit by the next wl_surface.commit.
++
++ This request tells the compositor how to process the state
++ from that commit when handling its internal state queue.
++
++ If the drain mode is "mailbox", the compositor may continue
++ processing the next state in the queue before it repaints
++ the display.
++
++ If the drain mode is "fifo", the compositor should ensure the
++ queue is not advanced until after this state has been current
++ for a repaint. The queue may be advance without repaint in the
++ case of off-screen or occluded surfaces.
++
++ The default drain mode when none is specified is "mailbox".
++
++
++
++
++
++
++ Informs the server that the client will no longer be using
++ this protocol object.
++
++ Surface state changes previously made by this protocol are
++ unaffected by this object's destruction.
++
++
++
++
+diff --git a/src/egl/wayland/wayland-drm/meson.build b/src/egl/wayland/wayland-drm/meson.build
+index 83a63385274..caba51b22a7 100644
+--- a/src/egl/wayland/wayland-drm/meson.build
++++ b/src/egl/wayland/wayland-drm/meson.build
+@@ -59,7 +59,7 @@ libwayland_drm = static_library(
+ # here for now as the maybe-least-bad solution.
+ wp_dir = dep_wl_protocols.get_variable(pkgconfig : 'pkgdatadir', internal : 'pkgdatadir')
+ wp_protos = {
+- 'commit-queue-v1': 'staging/commit-queue/commit-queue-v1.xml',
++ #'commit-queue-v1': 'staging/commit-queue/commit-queue-v1.xml',
+ #'commit-timing-v1': 'staging/commit-timing/commit-timing-v1.xml',
+ 'linux-dmabuf-unstable-v1': 'unstable/linux-dmabuf/linux-dmabuf-unstable-v1.xml',
+ 'presentation-time': 'stable/presentation-time/presentation-time.xml',
+@@ -81,3 +81,23 @@ foreach name, xml : wp_protos
+ )
+ wp_files += { name: [code, header] }
+ endforeach
++
++gamescope_protos = {
++ 'gamescope-commit-queue-v1': 'gamescope-commit-queue-v1.xml',
++}
++foreach name, xml : gamescope_protos
++ code = custom_target(
++ name + '-protocol.c',
++ input : xml,
++ output : name + '-protocol.c',
++ command : [prog_wl_scanner, wl_scanner_arg, '@INPUT@', '@OUTPUT@'],
++ )
++ header = custom_target(
++ name + '-client-protocol.h',
++ input : xml,
++ output : name + '-client-protocol.h',
++ command : [prog_wl_scanner, 'client-header', '@INPUT@', '@OUTPUT@'],
++ )
++ wp_files += { name: [code, header] }
++endforeach
++
+diff --git a/src/vulkan/wsi/meson.build b/src/vulkan/wsi/meson.build
+index dba95387975..fb0fab69ac6 100644
+--- a/src/vulkan/wsi/meson.build
++++ b/src/vulkan/wsi/meson.build
+@@ -31,7 +31,7 @@ endif
+
+ if with_platform_wayland
+ files_vulkan_wsi += files('wsi_common_wayland.c')
+- files_vulkan_wsi += wp_files['commit-queue-v1']
++ files_vulkan_wsi += wp_files['gamescope-commit-queue-v1']
+ #files_vulkan_wsi += wp_files['commit-timing-v1']
+ files_vulkan_wsi += wp_files['linux-dmabuf-unstable-v1']
+ files_vulkan_wsi += wp_files['presentation-time']
+diff --git a/src/vulkan/wsi/wsi_common_wayland.c b/src/vulkan/wsi/wsi_common_wayland.c
+index 1efe9e449e8..68d9088f936 100644
+--- a/src/vulkan/wsi/wsi_common_wayland.c
++++ b/src/vulkan/wsi/wsi_common_wayland.c
+@@ -41,7 +41,7 @@
+ #include "vk_util.h"
+ #include "wsi_common_entrypoints.h"
+ #include "wsi_common_private.h"
+-#include "commit-queue-v1-client-protocol.h"
++#include "gamescope-commit-queue-v1-client-protocol.h"
+ #include "linux-dmabuf-unstable-v1-client-protocol.h"
+ #include "presentation-time-client-protocol.h"
+ #include "tearing-control-v1-client-protocol.h"
+@@ -114,7 +114,7 @@ struct wsi_wl_display {
+ /* users want per-chain wsi_wl_swapchain->present_ids.wp_presentation */
+ struct wp_presentation *wp_presentation_notwrapped;
+
+- struct wp_commit_queue_manager_v1 *commit_queue_manager;
++ struct gamescope_commit_queue_manager_v1 *commit_queue_manager;
+
+ struct wsi_wayland *wsi_wl;
+
+@@ -170,7 +170,7 @@ struct wsi_wl_swapchain {
+
+ struct wsi_wl_surface *wsi_wl_surface;
+ struct wp_tearing_control_v1 *tearing_control;
+- struct wp_commit_queue_v1 *commit_queue;
++ struct gamescope_commit_queue_v1 *commit_queue;
+ bool can_timestamp;
+
+ struct wl_callback *frame;
+@@ -944,9 +944,9 @@ registry_handle_global(void *data, struct wl_registry *registry,
+ } else if (strcmp(interface, wp_tearing_control_manager_v1_interface.name) == 0) {
+ display->tearing_control_manager =
+ wl_registry_bind(registry, name, &wp_tearing_control_manager_v1_interface, 1);
+- } else if (strcmp(interface, wp_commit_queue_manager_v1_interface.name) == 0) {
++ } else if (strcmp(interface, gamescope_commit_queue_manager_v1_interface.name) == 0) {
+ display->commit_queue_manager =
+- wl_registry_bind(registry, name, &wp_commit_queue_manager_v1_interface, 1);
++ wl_registry_bind(registry, name, &gamescope_commit_queue_manager_v1_interface, 1);
+ }
+ }
+
+@@ -974,7 +974,7 @@ wsi_wl_display_finish(struct wsi_wl_display *display)
+ if (display->wp_presentation_notwrapped)
+ wp_presentation_destroy(display->wp_presentation_notwrapped);
+ if (display->commit_queue_manager)
+- wp_commit_queue_manager_v1_destroy(display->commit_queue_manager);
++ gamescope_commit_queue_manager_v1_destroy(display->commit_queue_manager);
+ if (display->tearing_control_manager)
+ wp_tearing_control_manager_v1_destroy(display->tearing_control_manager);
+ if (display->wl_display_wrapper)
+@@ -2066,8 +2066,8 @@ set_timestamp(struct wsi_wl_swapchain *chain)
+
+ timespec_from_nsec(&target_ts, target);
+
+- wp_commit_queue_v1_set_queue_mode(chain->commit_queue,
+- WP_COMMIT_QUEUE_V1_QUEUE_MODE_FIFO);
++ gamescope_commit_queue_v1_set_queue_mode(chain->commit_queue,
++ GAMESCOPE_COMMIT_QUEUE_V1_QUEUE_MODE_FIFO);
+ chain->last_target_time = target;
+ }
+
+@@ -2315,7 +2315,7 @@ wsi_wl_swapchain_chain_free(struct wsi_wl_swapchain *chain,
+ }
+
+ if (chain->commit_queue)
+- wp_commit_queue_v1_destroy(chain->commit_queue);
++ gamescope_commit_queue_v1_destroy(chain->commit_queue);
+
+ vk_free(pAllocator, (void *)chain->drm_modifiers);
+
+@@ -2374,7 +2374,7 @@ wsi_wl_surface_create_swapchain(VkIcdSurfaceBase *icd_surface,
+ old_chain->tearing_control = NULL;
+ }
+ if (old_chain->commit_queue) {
+- wp_commit_queue_v1_destroy(old_chain->commit_queue);
++ gamescope_commit_queue_v1_destroy(old_chain->commit_queue);
+ old_chain->commit_queue = NULL;
+ old_chain->can_timestamp = false;
+ }
+@@ -2505,7 +2505,7 @@ wsi_wl_surface_create_swapchain(VkIcdSurfaceBase *icd_surface,
+ chain->legacy_fifo_ready = true;
+ struct wsi_wl_display *dpy = chain->wsi_wl_surface->display;
+ if (dpy->commit_queue_manager) {
+- chain->commit_queue = wp_commit_queue_manager_v1_get_queue_controller(dpy->commit_queue_manager,
++ chain->commit_queue = gamescope_commit_queue_manager_v1_get_queue_controller(dpy->commit_queue_manager,
+ chain->wsi_wl_surface->surface);
+ chain->can_timestamp = true;
+ }
+--
+2.42.0
+
+
+From f0be8700af09a5a1c94d84c1b3b4ee3096de0b69 Mon Sep 17 00:00:00 2001
+From: Bas Nieuwenhuizen
+Date: Fri, 14 Jan 2022 15:58:45 +0100
+Subject: [PATCH 5/7] STEAMOS: radv: min image count override for FH5
+
+Otherwise in combination with the vblank time reservation in
+gamescope the game could get stuck in low power states.
+---
+ src/util/00-radv-defaults.conf | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/src/util/00-radv-defaults.conf b/src/util/00-radv-defaults.conf
+index 0dcec733e52..f0d535df2f8 100644
+--- a/src/util/00-radv-defaults.conf
++++ b/src/util/00-radv-defaults.conf
+@@ -188,5 +188,9 @@ Application bugs worked around in this file:
+
+
+
++
++
++
++
+
+
+--
+2.42.0
+
+
+From 2ab76c1153f55d82c3f49a25f8f8a1f1e1e74075 Mon Sep 17 00:00:00 2001
+From: Bas Nieuwenhuizen
+Date: Mon, 21 Feb 2022 18:43:54 +0100
+Subject: [PATCH 6/7] STEAMOS: Dynamic swapchain override for gamescope limiter
+
+---
+ src/loader/loader_dri3_helper.c | 42 +++++++++++++++++++++++++++++++--
+ src/loader/loader_dri3_helper.h | 1 +
+ src/loader/meson.build | 2 +-
+ src/vulkan/wsi/wsi_common_x11.c | 38 +++++++++++++++++++++++++++++
+ 4 files changed, 80 insertions(+), 3 deletions(-)
+
+diff --git a/src/loader/loader_dri3_helper.c b/src/loader/loader_dri3_helper.c
+index 2631a9e2fd5..dbf6db349c6 100644
+--- a/src/loader/loader_dri3_helper.c
++++ b/src/loader/loader_dri3_helper.c
+@@ -289,6 +289,30 @@ dri3_update_max_num_back(struct loader_dri3_drawable *draw)
+ }
+ }
+
++static unsigned
++gamescope_swapchain_override()
++{
++ const char *path = getenv("GAMESCOPE_LIMITER_FILE");
++ if (!path)
++ return 0;
++
++ static simple_mtx_t mtx = SIMPLE_MTX_INITIALIZER;
++ static int fd = -1;
++
++ simple_mtx_lock(&mtx);
++ if (fd < 0) {
++ fd = open(path, O_RDONLY);
++ }
++ simple_mtx_unlock(&mtx);
++
++ if (fd < 0)
++ return 0;
++
++ uint32_t override_value = 0;
++ pread(fd, &override_value, sizeof(override_value), 0);
++ return override_value;
++}
++
+ void
+ loader_dri3_set_swap_interval(struct loader_dri3_drawable *draw, int interval)
+ {
+@@ -303,10 +327,12 @@ loader_dri3_set_swap_interval(struct loader_dri3_drawable *draw, int interval)
+ * PS. changing from value A to B and A < B won't cause swap out of order but
+ * may still gets wrong target_msc value at the beginning.
+ */
+- if (draw->swap_interval != interval)
++ if (draw->orig_swap_interval != interval)
+ loader_dri3_swapbuffer_barrier(draw);
+
+- draw->swap_interval = interval;
++ draw->orig_swap_interval = interval;
++ if (gamescope_swapchain_override() != 1)
++ draw->swap_interval = interval;
+ }
+
+ static void
+@@ -438,6 +464,12 @@ loader_dri3_drawable_init(xcb_connection_t *conn,
+ draw->swap_interval = dri_get_initial_swap_interval(draw->dri_screen_render_gpu,
+ draw->ext->config);
+
++ draw->orig_swap_interval = draw->swap_interval;
++
++ unsigned gamescope_override = gamescope_swapchain_override();
++ if (gamescope_override == 1)
++ draw->swap_interval = 1;
++
+ dri3_update_max_num_back(draw);
+
+ /* Create a new drawable */
+@@ -1085,6 +1117,12 @@ loader_dri3_swap_buffers_msc(struct loader_dri3_drawable *draw,
+ if (draw->type == LOADER_DRI3_DRAWABLE_WINDOW) {
+ dri3_fence_reset(draw->conn, back);
+
++ unsigned gamescope_override = gamescope_swapchain_override();
++ if (gamescope_override == 1)
++ draw->swap_interval = 1;
++ else
++ draw->swap_interval = draw->orig_swap_interval;
++
+ /* Compute when we want the frame shown by taking the last known
+ * successful MSC and adding in a swap interval for each outstanding swap
+ * request. target_msc=divisor=remainder=0 means "Use glXSwapBuffers()
+diff --git a/src/loader/loader_dri3_helper.h b/src/loader/loader_dri3_helper.h
+index cc2362dd599..fe73b3f329c 100644
+--- a/src/loader/loader_dri3_helper.h
++++ b/src/loader/loader_dri3_helper.h
+@@ -178,6 +178,7 @@ struct loader_dri3_drawable {
+ bool block_on_depleted_buffers;
+ bool queries_buffer_age;
+ int swap_interval;
++ int orig_swap_interval;
+
+ struct loader_dri3_extensions *ext;
+ const struct loader_dri3_vtable *vtable;
+diff --git a/src/loader/meson.build b/src/loader/meson.build
+index 35f9991ba2f..154cf809a69 100644
+--- a/src/loader/meson.build
++++ b/src/loader/meson.build
+@@ -29,7 +29,7 @@ if with_platform_x11 and with_dri3
+ dependencies : [
+ idep_mesautil,
+ dep_libdrm, dep_xcb_dri3, dep_xcb_present, dep_xcb_sync, dep_xshmfence,
+- dep_xcb_xfixes,
++ dep_xcb_xfixes, dep_xcb_xrandr, idep_mesautil
+ ],
+ build_by_default : false,
+ )
+diff --git a/src/vulkan/wsi/wsi_common_x11.c b/src/vulkan/wsi/wsi_common_x11.c
+index cba1d1c5e7c..6d66387d5be 100644
+--- a/src/vulkan/wsi/wsi_common_x11.c
++++ b/src/vulkan/wsi/wsi_common_x11.c
+@@ -48,6 +48,7 @@
+ #include "util/hash_table.h"
+ #include "util/os_file.h"
+ #include "util/os_time.h"
++#include "util/simple_mtx.h"
+ #include "util/u_debug.h"
+ #include "util/u_thread.h"
+ #include "util/xmlconfig.h"
+@@ -219,6 +220,30 @@ wsi_x11_detect_xwayland(xcb_connection_t *conn,
+ return is_xwayland;
+ }
+
++static unsigned
++gamescope_swapchain_override()
++{
++ const char *path = getenv("GAMESCOPE_LIMITER_FILE");
++ if (!path)
++ return 0;
++
++ static simple_mtx_t mtx = SIMPLE_MTX_INITIALIZER;
++ static int fd = -1;
++
++ simple_mtx_lock(&mtx);
++ if (fd < 0) {
++ fd = open(path, O_RDONLY);
++ }
++ simple_mtx_unlock(&mtx);
++
++ if (fd < 0)
++ return 0;
++
++ uint32_t override_value = 0;
++ pread(fd, &override_value, sizeof(override_value), 0);
++ return override_value;
++}
++
+ static struct wsi_x11_connection *
+ wsi_x11_connection_create(struct wsi_device *wsi_dev,
+ xcb_connection_t *conn)
+@@ -1107,6 +1132,8 @@ struct x11_swapchain {
+ /* Total number of images returned to application in AcquireNextImage. */
+ uint64_t present_poll_acquire_count;
+
++ VkPresentModeKHR orig_present_mode;
++
+ struct x11_image images[0];
+ };
+ VK_DEFINE_NONDISP_HANDLE_CASTS(x11_swapchain, base.base, VkSwapchainKHR,
+@@ -1857,6 +1884,12 @@ x11_queue_present(struct wsi_swapchain *anv_chain,
+ if (chain->status < 0)
+ return chain->status;
+
++ unsigned gamescope_override = gamescope_swapchain_override();
++ if ((gamescope_override == 1 && chain->base.present_mode != VK_PRESENT_MODE_FIFO_KHR) ||
++ (gamescope_override != 1 && chain->base.present_mode != chain->orig_present_mode)) {
++ return x11_swapchain_result(chain, VK_ERROR_OUT_OF_DATE_KHR);
++ }
++
+ if (damage && damage->pRectangles && damage->rectangleCount > 0 &&
+ damage->rectangleCount <= MAX_DAMAGE_RECTS) {
+ xcb_rectangle_t rects[MAX_DAMAGE_RECTS];
+@@ -2615,6 +2648,10 @@ x11_surface_create_swapchain(VkIcdSurfaceBase *icd_surface,
+ xcb_void_cookie_t cookie;
+ VkResult result;
+ VkPresentModeKHR present_mode = wsi_swapchain_get_present_mode(wsi_device, pCreateInfo);
++ VkPresentModeKHR orig_present_mode = present_mode;
++
++ if (gamescope_swapchain_override() == 1)
++ present_mode = VK_PRESENT_MODE_FIFO_KHR;
+
+ assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR);
+
+@@ -2727,6 +2764,7 @@ x11_surface_create_swapchain(VkIcdSurfaceBase *icd_surface,
+ chain->base.wait_for_present = x11_wait_for_present;
+ chain->base.release_images = x11_release_images;
+ chain->base.present_mode = present_mode;
++ chain->orig_present_mode = orig_present_mode;
+ chain->base.image_count = num_images;
+ chain->conn = conn;
+ chain->window = window;
+--
+2.42.0
+
+
+From f00348f08f42a1ce3be4e71f9fba186fb629c723 Mon Sep 17 00:00:00 2001
+From: Friedrich Vock
+Date: Fri, 1 Dec 2023 15:18:44 +0100
+Subject: [PATCH 7/7] radv: Enable compute dispatch tunneling
+
+Compute tunneling can considerably lower the latency of high-priority
+compute work. Enabling it is beneficial in cases where high-priority
+work is dispatched while the GPU is already busy with other work (e.g.
+rendering on GFX). This is the case in VR compositors that dispatch
+latency-sensitive compositing work to ACE while GFX is busy rendering
+the next frame.
+---
+ src/amd/vulkan/radv_device.c | 7 +++++++
+ src/amd/vulkan/si_cmd_buffer.c | 2 ++
+ 2 files changed, 9 insertions(+)
+
+diff --git a/src/amd/vulkan/radv_device.c b/src/amd/vulkan/radv_device.c
+index 1bf900d073c..db5347dc0be 100644
+--- a/src/amd/vulkan/radv_device.c
++++ b/src/amd/vulkan/radv_device.c
+@@ -969,6 +969,13 @@ radv_CreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo *pCr
+ */
+ device->dispatch_initiator |= S_00B800_ORDER_MODE(1);
+ }
++ if (device->physical_device->rad_info.gfx_level >= GFX10) {
++ /* Enable asynchronous compute tunneling. The KMD restricts this feature
++ * to high-priority compute queues, so setting the bit on any other queue
++ * is a no-op. PAL always sets this bit as well.
++ */
++ device->dispatch_initiator |= S_00B800_TUNNEL_ENABLE(1);
++ }
+
+ /* Disable partial preemption for task shaders.
+ * The kernel may not support preemption, but PAL always sets this bit,
+diff --git a/src/amd/vulkan/si_cmd_buffer.c b/src/amd/vulkan/si_cmd_buffer.c
+index ecb00d98575..1b5e585ade4 100644
+--- a/src/amd/vulkan/si_cmd_buffer.c
++++ b/src/amd/vulkan/si_cmd_buffer.c
+@@ -113,6 +113,8 @@ si_emit_compute(struct radv_device *device, struct radeon_cmdbuf *cs)
+ radeon_emit(cs, 0); /* R_00B894_COMPUTE_USER_ACCUM_1 */
+ radeon_emit(cs, 0); /* R_00B898_COMPUTE_USER_ACCUM_2 */
+ radeon_emit(cs, 0); /* R_00B89C_COMPUTE_USER_ACCUM_3 */
++
++ radeon_set_sh_reg(cs, R_00B9F4_COMPUTE_DISPATCH_TUNNEL, 0);
+ }
+
+ /* This register has been moved to R_00CD20_COMPUTE_MAX_WAVE_ID
+--
+2.42.0
+
diff --git a/spec_files/mesa/old/zink-fix-resizable-bar-detection-logic.patch b/spec_files/mesa/old/zink-fix-resizable-bar-detection-logic.patch
new file mode 100644
index 00000000..4a5e916d
--- /dev/null
+++ b/spec_files/mesa/old/zink-fix-resizable-bar-detection-logic.patch
@@ -0,0 +1,39 @@
+From a077c14f150f1c4f670dce381ac2eb548f1a4ac2 Mon Sep 17 00:00:00 2001
+From: Alessandro Astone
+Date: Wed, 10 Jan 2024 17:24:30 +0100
+Subject: [PATCH] zink: Fix resizable BAR detection logic
+
+This was broken in two ways:
+* When looking for the MAX biggest_ram it was actually comparing
+ a candidate against biggest_vis_ram
+
+* mem_props.memoryTypes[] should be accessed with the memory type
+ index as found in heap_map
+
+Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/10341
+Cc: 23.3
+Part-of:
+---
+ src/gallium/drivers/zink/zink_screen.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/src/gallium/drivers/zink/zink_screen.c b/src/gallium/drivers/zink/zink_screen.c
+index 5a6d17cb4fa3..6697d7ab938c 100644
+--- a/src/gallium/drivers/zink/zink_screen.c
++++ b/src/gallium/drivers/zink/zink_screen.c
+@@ -3258,10 +3258,10 @@ zink_internal_create_screen(const struct pipe_screen_config *config, int64_t dev
+ {
+ uint64_t biggest_vis_vram = 0;
+ for (unsigned i = 0; i < screen->heap_count[ZINK_HEAP_DEVICE_LOCAL_VISIBLE]; i++)
+- biggest_vis_vram = MAX2(biggest_vis_vram, screen->info.mem_props.memoryHeaps[screen->info.mem_props.memoryTypes[i].heapIndex].size);
++ biggest_vis_vram = MAX2(biggest_vis_vram, screen->info.mem_props.memoryHeaps[screen->info.mem_props.memoryTypes[screen->heap_map[ZINK_HEAP_DEVICE_LOCAL_VISIBLE][i]].heapIndex].size);
+ uint64_t biggest_vram = 0;
+ for (unsigned i = 0; i < screen->heap_count[ZINK_HEAP_DEVICE_LOCAL]; i++)
+- biggest_vram = MAX2(biggest_vis_vram, screen->info.mem_props.memoryHeaps[screen->info.mem_props.memoryTypes[i].heapIndex].size);
++ biggest_vram = MAX2(biggest_vram, screen->info.mem_props.memoryHeaps[screen->info.mem_props.memoryTypes[screen->heap_map[ZINK_HEAP_DEVICE_LOCAL][i]].heapIndex].size);
+ /* determine if vis vram is roughly equal to total vram */
+ if (biggest_vis_vram > biggest_vram * 0.9)
+ screen->resizable_bar = true;
+--
+GitLab
+
diff --git a/spec_files/xorg-x11-server-Xwayland/0001-Valve.patch b/spec_files/xorg-x11-server-Xwayland/0001-Valve.patch
index 2d86c954..40d4144c 100644
--- a/spec_files/xorg-x11-server-Xwayland/0001-Valve.patch
+++ b/spec_files/xorg-x11-server-Xwayland/0001-Valve.patch
@@ -1,20 +1,21 @@
-From 654500be494e1a19f2d1bb44099f294805bec228 Mon Sep 17 00:00:00 2001
+From e496ed0a6b6c467ac01e33fa14e05dc2e0888a74 Mon Sep 17 00:00:00 2001
From: Kyle Gospodnetich
-Date: Fri, 15 Dec 2023 01:22:10 -0800
-Subject: [PATCH 1/2] Revert "xwayland: add support for wp-tearing-control-v1"
+Date: Wed, 31 Jan 2024 17:22:32 -0800
+Subject: [PATCH 1/4] Revert "xwayland: add support for wp-tearing-control-v1"
This reverts commit 1ce2025822244c85826ab36febfa5945186b4a2a.
---
hw/xwayland/meson.build | 3 ---
- hw/xwayland/xwayland-present.c | 13 +------------
+ hw/xwayland/xwayland-present.c | 21 +++------------------
+ hw/xwayland/xwayland-present.h | 1 -
hw/xwayland/xwayland-screen.c | 5 -----
hw/xwayland/xwayland-screen.h | 1 -
hw/xwayland/xwayland-window.c | 9 ---------
hw/xwayland/xwayland-window.h | 1 -
- 6 files changed, 1 insertion(+), 31 deletions(-)
+ 7 files changed, 3 insertions(+), 38 deletions(-)
diff --git a/hw/xwayland/meson.build b/hw/xwayland/meson.build
-index 57a01cef4..41be1240e 100644
+index 54529b64e..fbdbb2458 100644
--- a/hw/xwayland/meson.build
+++ b/hw/xwayland/meson.build
@@ -48,7 +48,6 @@ xdg_shell_xml = join_paths(protodir, 'stable', 'xdg-shell', 'xdg-shell.xml')
@@ -22,48 +23,47 @@ index 57a01cef4..41be1240e 100644
shortcuts_inhibit_xml = join_paths(protodir, 'unstable', 'keyboard-shortcuts-inhibit', 'keyboard-shortcuts-inhibit-unstable-v1.xml')
xwayland_shell_xml = join_paths(protodir, 'staging', 'xwayland-shell', 'xwayland-shell-v1.xml')
-tearing_xml = join_paths(protodir, 'staging', 'tearing-control', 'tearing-control-v1.xml')
- syncobj_xml = join_paths(protodir, 'staging', 'linux-drm-syncobj', 'linux-drm-syncobj-v1.xml')
client_header = generator(scanner,
-@@ -78,7 +77,6 @@ srcs += client_header.process(xdg_shell_xml)
+ output : '@BASENAME@-client-protocol.h',
+@@ -77,7 +76,6 @@ srcs += client_header.process(xdg_shell_xml)
srcs += client_header.process(drm_lease_xml)
srcs += client_header.process(shortcuts_inhibit_xml)
srcs += client_header.process(xwayland_shell_xml)
-srcs += client_header.process(tearing_xml)
- srcs += client_header.process(syncobj_xml)
srcs += code.process(relative_xml)
srcs += code.process(pointer_xml)
-@@ -92,7 +90,6 @@ srcs += code.process(xdg_shell_xml)
+ srcs += code.process(gestures_xml)
+@@ -90,7 +88,6 @@ srcs += code.process(xdg_shell_xml)
srcs += code.process(drm_lease_xml)
srcs += code.process(shortcuts_inhibit_xml)
srcs += code.process(xwayland_shell_xml)
-srcs += code.process(tearing_xml)
- srcs += code.process(syncobj_xml)
if build_ei
+ xwayland_dep += libei_dep
diff --git a/hw/xwayland/xwayland-present.c b/hw/xwayland/xwayland-present.c
-index f611bb9ec..be8d00c05 100644
+index 941be06da..bb3310dc9 100644
--- a/hw/xwayland/xwayland-present.c
+++ b/hw/xwayland/xwayland-present.c
-@@ -34,10 +34,9 @@
+@@ -34,9 +34,8 @@
#include "xwayland-pixmap.h"
#include "glamor.h"
-#include "tearing-control-v1-client-protocol.h"
- #include "linux-drm-syncobj-v1-client-protocol.h"
-#define XWL_PRESENT_CAPS PresentCapabilityAsync | PresentCapabilityAsyncMayTear
+#define XWL_PRESENT_CAPS PresentCapabilityAsync
/*
-@@ -889,16 +888,6 @@ xwl_present_flip(present_vblank_ptr vblank, RegionPtr damage)
+@@ -797,16 +796,6 @@ xwl_present_flip(present_vblank_ptr vblank, RegionPtr damage)
damage_box->x2 - damage_box->x1,
damage_box->y2 - damage_box->y1);
- if (xwl_window->tearing_control) {
- uint32_t hint;
-- if (event->options & PresentOptionAsyncMayTear)
+- if (event->async_may_tear)
- hint = WP_TEARING_CONTROL_V1_PRESENTATION_HINT_ASYNC;
- else
- hint = WP_TEARING_CONTROL_V1_PRESENTATION_HINT_VSYNC;
@@ -74,8 +74,38 @@ index f611bb9ec..be8d00c05 100644
wl_surface_commit(xwl_window->surface);
if (!vblank->sync_flip) {
+@@ -1010,15 +999,11 @@ xwl_present_pixmap(WindowPtr window,
+ }
+
+ vblank->event_id = ++xwl_present_event_id;
+- event->async_may_tear = options & PresentOptionAsyncMayTear;
+
+- /* Synchronous Xwayland presentations always complete (at least) one frame after they
++ /* Xwayland presentations always complete (at least) one frame after they
+ * are executed
+ */
+- if (event->async_may_tear)
+- vblank->exec_msc = vblank->target_msc;
+- else
+- vblank->exec_msc = vblank->target_msc - 1;
++ vblank->exec_msc = vblank->target_msc - 1;
+
+ vblank->queued = TRUE;
+ if (crtc_msc < vblank->exec_msc) {
+diff --git a/hw/xwayland/xwayland-present.h b/hw/xwayland/xwayland-present.h
+index 4fd1e579f..806272089 100644
+--- a/hw/xwayland/xwayland-present.h
++++ b/hw/xwayland/xwayland-present.h
+@@ -59,7 +59,6 @@ struct xwl_present_event {
+ present_vblank_rec vblank;
+
+ PixmapPtr pixmap;
+- Bool async_may_tear;
+ };
+
+ Bool xwl_present_entered_for_each_frame_callback(void);
diff --git a/hw/xwayland/xwayland-screen.c b/hw/xwayland/xwayland-screen.c
-index e4c212795..2d373ad8f 100644
+index cc14e0771..2bc553b50 100644
--- a/hw/xwayland/xwayland-screen.c
+++ b/hw/xwayland/xwayland-screen.c
@@ -63,7 +63,6 @@
@@ -83,10 +113,10 @@ index e4c212795..2d373ad8f 100644
#include "xdg-shell-client-protocol.h"
#include "xwayland-shell-v1-client-protocol.h"
-#include "tearing-control-v1-client-protocol.h"
- #include "linux-drm-syncobj-v1-client-protocol.h"
static DevPrivateKeyRec xwl_screen_private_key;
-@@ -463,10 +462,6 @@ registry_global(void *data, struct wl_registry *registry, uint32_t id,
+ static DevPrivateKeyRec xwl_client_private_key;
+@@ -462,10 +461,6 @@ registry_global(void *data, struct wl_registry *registry, uint32_t id,
xwl_screen->xwayland_shell =
wl_registry_bind(registry, id, &xwayland_shell_v1_interface, 1);
}
@@ -98,7 +128,7 @@ index e4c212795..2d373ad8f 100644
else if (xwl_screen->glamor) {
xwl_glamor_init_wl_registry(xwl_screen, registry, id, interface,
diff --git a/hw/xwayland/xwayland-screen.h b/hw/xwayland/xwayland-screen.h
-index fce351072..3e93f2512 100644
+index bd66dd681..656d2afde 100644
--- a/hw/xwayland/xwayland-screen.h
+++ b/hw/xwayland/xwayland-screen.h
@@ -110,7 +110,6 @@ struct xwl_screen {
@@ -106,11 +136,11 @@ index fce351072..3e93f2512 100644
struct wp_viewporter *viewporter;
struct xwayland_shell_v1 *xwayland_shell;
- struct wp_tearing_control_manager_v1 *tearing_control_manager;
- struct wp_linux_drm_syncobj_v1 *explicit_sync;
struct xorg_list drm_lease_devices;
struct xorg_list queued_drm_lease_devices;
+ struct xorg_list drm_leases;
diff --git a/hw/xwayland/xwayland-window.c b/hw/xwayland/xwayland-window.c
-index 070d40dc2..3319d7962 100644
+index 4978f37c7..b018d9656 100644
--- a/hw/xwayland/xwayland-window.c
+++ b/hw/xwayland/xwayland-window.c
@@ -46,7 +46,6 @@
@@ -121,7 +151,7 @@ index 070d40dc2..3319d7962 100644
#include "viewporter-client-protocol.h"
#include "xdg-shell-client-protocol.h"
#include "xwayland-shell-v1-client-protocol.h"
-@@ -942,11 +941,6 @@ ensure_surface_for_window(WindowPtr window)
+@@ -967,11 +966,6 @@ ensure_surface_for_window(WindowPtr window)
xwl_window_check_resolution_change_emulation(xwl_window);
}
@@ -133,18 +163,18 @@ index 070d40dc2..3319d7962 100644
return TRUE;
err:
-@@ -1157,9 +1151,6 @@ xwl_unrealize_window(WindowPtr window)
+@@ -1182,9 +1176,6 @@ xwl_unrealize_window(WindowPtr window)
xwl_present_for_each_frame_callback(xwl_window, xwl_present_unrealize_window);
#endif
- if (xwl_window->tearing_control)
- wp_tearing_control_v1_destroy(xwl_window->tearing_control);
-
- if (xwl_window->surface_sync)
- wp_linux_drm_syncobj_surface_v1_destroy(xwl_window->surface_sync);
-
+ release_wl_surface_for_window(xwl_window);
+ xorg_list_del(&xwl_window->link_damage);
+ xorg_list_del(&xwl_window->link_window);
diff --git a/hw/xwayland/xwayland-window.h b/hw/xwayland/xwayland-window.h
-index 51ce91b57..2d1bb1c08 100644
+index 7fbb2a623..f8200d537 100644
--- a/hw/xwayland/xwayland-window.h
+++ b/hw/xwayland/xwayland-window.h
@@ -121,7 +121,6 @@ struct xwl_window {
@@ -152,66 +182,65 @@ index 51ce91b57..2d1bb1c08 100644
/* If TRUE, the window buffer format supports scanout with implicit modifier */
Bool has_implicit_scanout_support;
- struct wp_tearing_control_v1 *tearing_control;
- struct wp_linux_drm_syncobj_surface_v1 *surface_sync;
};
+ struct xwl_window *xwl_window_get(WindowPtr window);
--
2.42.0
-From bd8b66f63a832798db890aa2d4212e9eceb84e66 Mon Sep 17 00:00:00 2001
-From: Kyle Gospodnetich
-Date: Thu, 14 Dec 2023 23:47:22 -0800
-Subject: [PATCH 2/2] Add Gamescope Tearing Protocol
+From 01a8a454f04dca944db446815f28bf46f8f822b6 Mon Sep 17 00:00:00 2001
+From: Joshua Ashton
+Date: Wed, 24 Aug 2022 23:16:24 +0000
+Subject: [PATCH 2/4] xwayland: Implement tearing protocol
---
hw/xwayland/meson.build | 3 +
- .../gamescope-tearing-control-unstable-v1.xml | 141 ++++++++++++++++++
- hw/xwayland/xwayland-output.c | 15 +-
- hw/xwayland/xwayland-present.c | 17 ++-
+ .../tearing-control-unstable-v1.xml | 142 ++++++++++++++++++
+ hw/xwayland/xwayland-present.c | 11 ++
hw/xwayland/xwayland-screen.c | 4 +
hw/xwayland/xwayland-screen.h | 1 +
hw/xwayland/xwayland-window.c | 11 ++
hw/xwayland/xwayland-window.h | 1 +
- 8 files changed, 191 insertions(+), 2 deletions(-)
- create mode 100644 hw/xwayland/protocols/unstable/tearing-control/gamescope-tearing-control-unstable-v1.xml
+ 7 files changed, 173 insertions(+)
+ create mode 100644 hw/xwayland/protocols/unstable/tearing-control/tearing-control-unstable-v1.xml
diff --git a/hw/xwayland/meson.build b/hw/xwayland/meson.build
-index 41be1240e..6b12f0ce7 100644
+index fbdbb2458..d29e55d7d 100644
--- a/hw/xwayland/meson.build
+++ b/hw/xwayland/meson.build
-@@ -48,6 +48,7 @@ xdg_shell_xml = join_paths(protodir, 'stable', 'xdg-shell', 'xdg-shell.xml')
+@@ -46,6 +46,7 @@ dmabuf_xml = join_paths(protodir, 'unstable', 'linux-dmabuf', 'linux-dmabuf-unst
+ viewporter_xml = join_paths(protodir, 'stable', 'viewporter', 'viewporter.xml')
+ xdg_shell_xml = join_paths(protodir, 'stable', 'xdg-shell', 'xdg-shell.xml')
drm_lease_xml = join_paths(protodir, 'staging', 'drm-lease', 'drm-lease-v1.xml')
++tearing_xml = join_paths('protocols', 'unstable', 'tearing-control', 'tearing-control-unstable-v1.xml')
shortcuts_inhibit_xml = join_paths(protodir, 'unstable', 'keyboard-shortcuts-inhibit', 'keyboard-shortcuts-inhibit-unstable-v1.xml')
xwayland_shell_xml = join_paths(protodir, 'staging', 'xwayland-shell', 'xwayland-shell-v1.xml')
-+tearing_xml = join_paths('protocols', 'unstable', 'tearing-control', 'gamescope-tearing-control-unstable-v1.xml')
- syncobj_xml = join_paths(protodir, 'staging', 'linux-drm-syncobj', 'linux-drm-syncobj-v1.xml')
- client_header = generator(scanner,
-@@ -77,6 +78,7 @@ srcs += client_header.process(xdg_shell_xml)
+@@ -74,6 +75,7 @@ srcs += client_header.process(dmabuf_xml)
+ srcs += client_header.process(viewporter_xml)
+ srcs += client_header.process(xdg_shell_xml)
srcs += client_header.process(drm_lease_xml)
++srcs += client_header.process(tearing_xml)
srcs += client_header.process(shortcuts_inhibit_xml)
srcs += client_header.process(xwayland_shell_xml)
-+srcs += client_header.process(tearing_xml)
- srcs += client_header.process(syncobj_xml)
srcs += code.process(relative_xml)
- srcs += code.process(pointer_xml)
-@@ -90,6 +92,7 @@ srcs += code.process(xdg_shell_xml)
+@@ -86,6 +88,7 @@ srcs += code.process(dmabuf_xml)
+ srcs += code.process(viewporter_xml)
+ srcs += code.process(xdg_shell_xml)
srcs += code.process(drm_lease_xml)
++srcs += code.process(tearing_xml)
srcs += code.process(shortcuts_inhibit_xml)
srcs += code.process(xwayland_shell_xml)
-+srcs += code.process(tearing_xml)
- srcs += code.process(syncobj_xml)
- if build_ei
-diff --git a/hw/xwayland/protocols/unstable/tearing-control/gamescope-tearing-control-unstable-v1.xml b/hw/xwayland/protocols/unstable/tearing-control/gamescope-tearing-control-unstable-v1.xml
+diff --git a/hw/xwayland/protocols/unstable/tearing-control/tearing-control-unstable-v1.xml b/hw/xwayland/protocols/unstable/tearing-control/tearing-control-unstable-v1.xml
new file mode 100644
-index 000000000..7cdb5dd57
+index 000000000..ce130718e
--- /dev/null
-+++ b/hw/xwayland/protocols/unstable/tearing-control/gamescope-tearing-control-unstable-v1.xml
-@@ -0,0 +1,141 @@
++++ b/hw/xwayland/protocols/unstable/tearing-control/tearing-control-unstable-v1.xml
+@@ -0,0 +1,142 @@
+
-+
++
+
+
+ Copyright © 2021 Xaver Hugl
@@ -236,7 +265,7 @@ index 000000000..7cdb5dd57
+ DEALINGS IN THE SOFTWARE.
+
+
-+
++
+
+ This global is a factory interface, allowing clients to request
+ the compositor to use asynchronous page flips on a per-surface basis.
@@ -260,7 +289,7 @@ index 000000000..7cdb5dd57
+
+
+ Destroy this tearing control factory object. Other objects, including
-+ gamescope_surface_tearing_control_v1 objects created by this factory,
++ zwp_surface_tearing_control_v1 objects created by this factory,
+ shall not be affected by this request.
+
+
@@ -275,19 +304,19 @@ index 000000000..7cdb5dd57
+ Instantiate an interface extension for the given wl_surface to
+ request asynchronous page flips for presentation.
+
-+ If the given wl_surface already has a gamescope_surface_tearing_control_v1
++ If the given wl_surface already has a zwp_surface_tearing_control_v1
+ object associated, the tearing_control_exists protocol error is raised.
+
+
+
+
+
+
+
-+
++
+
+ An additional interface to a wl_surface object, which allows the client
+ to hint to the compositor if and when it should use asynchronous page
@@ -351,167 +380,100 @@ index 000000000..7cdb5dd57
+
+
+
-\ No newline at end of file
-diff --git a/hw/xwayland/xwayland-output.c b/hw/xwayland/xwayland-output.c
-index fe7a9232e..ea95a6c64 100644
---- a/hw/xwayland/xwayland-output.c
-+++ b/hw/xwayland/xwayland-output.c
-@@ -338,6 +338,19 @@ const int32_t xwl_output_fake_modes[][2] = {
- { 640, 350 },
- };
-
-+/* Enables always exposing extra modes without
-+ * supporting viewporter.
-+ * Useful for some wayland compositors
-+ * that work kiosk-like with a single window, that handle scaling
-+ * themselves where viewporter wouldn't make sense.
-+ */
-+static Bool
-+always_expose_extra_modes(void)
-+{
-+ const char *extra_mode_env = getenv("XWAYLAND_FORCE_ENABLE_EXTRA_MODES");
-+ return extra_mode_env && atoi(extra_mode_env) != 0;
-+}
+
- /* Build an array with RRModes the first mode is the actual output mode, the
- * rest are fake modes from the xwl_output_fake_modes list. We do this for apps
- * which want to change resolution when they go fullscreen.
-@@ -363,7 +376,7 @@ output_get_rr_modes(struct xwl_output *xwl_output,
-
- *count = 1;
-
-- if (!xwl_screen_has_resolution_change_emulation(xwl_screen) && !xwl_screen->force_xrandr_emulation)
-+ if (!xwl_screen_has_resolution_change_emulation(xwl_screen) && !xwl_screen->force_xrandr_emulation && !always_expose_extra_modes())
- return rr_modes;
-
- /* Add fake modes */
diff --git a/hw/xwayland/xwayland-present.c b/hw/xwayland/xwayland-present.c
-index be8d00c05..600c0aaa7 100644
+index bb3310dc9..6f1d57a42 100644
--- a/hw/xwayland/xwayland-present.c
+++ b/hw/xwayland/xwayland-present.c
-@@ -34,6 +34,7 @@
+@@ -34,6 +34,8 @@
#include "xwayland-pixmap.h"
#include "glamor.h"
-+#include "gamescope-tearing-control-unstable-v1-client-protocol.h"
- #include "linux-drm-syncobj-v1-client-protocol.h"
++#include "tearing-control-unstable-v1-client-protocol.h"
++
#define XWL_PRESENT_CAPS PresentCapabilityAsync
-@@ -705,6 +706,7 @@ xwl_present_check_flip(RRCrtcPtr crtc,
- WindowPtr toplvl_window = xwl_present_toplvl_pixmap_window(present_window);
- struct xwl_window *xwl_window = xwl_window_from_window(present_window);
- ScreenPtr screen = pixmap->drawable.pScreen;
-+ PixmapPtr window_pixmap;
- struct xwl_screen *xwl_screen = xwl_screen_get(screen);
- if (reason)
-@@ -714,6 +716,7 @@ xwl_present_check_flip(RRCrtcPtr crtc,
- return FALSE;
-
- xwl_present_maybe_set_reason(xwl_window, reason);
-+ window_pixmap = screen->GetWindowPixmap(xwl_window->window);
-
- if (!crtc)
- return FALSE;
-@@ -742,6 +745,10 @@ xwl_present_check_flip(RRCrtcPtr crtc,
- if (!xwl_glamor_check_flip(present_window, pixmap))
- return FALSE;
-
-+ /* If this is a dummy window, we can always flip to it */
-+ if (window_pixmap->drawable.width == 1 && window_pixmap->drawable.height == 1)
-+ return TRUE;
-+
- /* If glamor doesn't support implicit sync and the compositor doesn't
- * support explicit sync, we cannot flip
- */
-@@ -753,7 +760,7 @@ xwl_present_check_flip(RRCrtcPtr crtc,
- * window's, e.g. because a client redirected this window or one of its
- * parents.
- */
-- if (screen->GetWindowPixmap(xwl_window->window) != screen->GetWindowPixmap(present_window))
-+ if (window_pixmap != screen->GetWindowPixmap(present_window))
- return FALSE;
-
- /*
-@@ -888,6 +895,14 @@ xwl_present_flip(present_vblank_ptr vblank, RegionPtr damage)
+@@ -796,6 +798,15 @@ xwl_present_flip(present_vblank_ptr vblank, RegionPtr damage)
damage_box->x2 - damage_box->x1,
damage_box->y2 - damage_box->y1);
++
+ // Josh: No support for VSync relaxed, this is something that should
+ // be determined by a user setting in gamescope.
+ if (xwl_window->tearing_control)
-+ gamescope_surface_tearing_control_v1_set_presentation_hint(xwl_window->tearing_control,
-+ vblank->sync_flip
-+ ? GAMESCOPE_SURFACE_TEARING_CONTROL_V1_PRESENTATION_HINT_VSYNC
-+ : GAMESCOPE_SURFACE_TEARING_CONTROL_V1_PRESENTATION_HINT_ASYNC);
++ zwp_surface_tearing_control_v1_set_presentation_hint(xwl_window->tearing_control,
++ sync_flip
++ ? ZWP_SURFACE_TEARING_CONTROL_V1_PRESENTATION_HINT_VSYNC
++ : ZWP_SURFACE_TEARING_CONTROL_V1_PRESENTATION_HINT_ASYNC);
+
wl_surface_commit(xwl_window->surface);
if (!vblank->sync_flip) {
diff --git a/hw/xwayland/xwayland-screen.c b/hw/xwayland/xwayland-screen.c
-index 2d373ad8f..3eb8ceee4 100644
+index 2bc553b50..e35861e46 100644
--- a/hw/xwayland/xwayland-screen.c
+++ b/hw/xwayland/xwayland-screen.c
-@@ -63,6 +63,7 @@
+@@ -62,6 +62,7 @@
+ #include "xdg-output-unstable-v1-client-protocol.h"
#include "viewporter-client-protocol.h"
#include "xdg-shell-client-protocol.h"
++#include "tearing-control-unstable-v1-client-protocol.h"
#include "xwayland-shell-v1-client-protocol.h"
-+#include "gamescope-tearing-control-unstable-v1-client-protocol.h"
- #include "linux-drm-syncobj-v1-client-protocol.h"
static DevPrivateKeyRec xwl_screen_private_key;
-@@ -462,6 +463,9 @@ registry_global(void *data, struct wl_registry *registry, uint32_t id,
+@@ -457,6 +458,9 @@ registry_global(void *data, struct wl_registry *registry, uint32_t id,
+ else if (strcmp(interface, "wp_viewporter") == 0) {
+ xwl_screen->viewporter = wl_registry_bind(registry, id, &wp_viewporter_interface, 1);
+ }
++ else if (strcmp(interface, "zwp_tearing_control_v1") == 0) {
++ xwl_screen->tearing_control = wl_registry_bind(registry, id, &zwp_tearing_control_v1_interface, 1);
++ }
+ else if (strcmp(interface, "xwayland_shell_v1") == 0 && xwl_screen->rootless) {
xwl_screen->xwayland_shell =
wl_registry_bind(registry, id, &xwayland_shell_v1_interface, 1);
- }
-+ else if (strcmp(interface, "gamescope_tearing_control_v1") == 0) {
-+ xwl_screen->tearing_control = wl_registry_bind(registry, id, &gamescope_tearing_control_v1_interface, 1);
-+ }
- #ifdef XWL_HAS_GLAMOR
- else if (xwl_screen->glamor) {
- xwl_glamor_init_wl_registry(xwl_screen, registry, id, interface,
diff --git a/hw/xwayland/xwayland-screen.h b/hw/xwayland/xwayland-screen.h
-index 3e93f2512..206a0d2ae 100644
+index 656d2afde..bf75278fd 100644
--- a/hw/xwayland/xwayland-screen.h
+++ b/hw/xwayland/xwayland-screen.h
-@@ -117,6 +117,7 @@ struct xwl_screen {
+@@ -113,6 +113,7 @@ struct xwl_screen {
+ struct xorg_list drm_lease_devices;
+ struct xorg_list queued_drm_lease_devices;
+ struct xorg_list drm_leases;
++ struct zwp_tearing_control_v1 *tearing_control;
struct xwl_output *fixed_output;
struct xorg_list pending_wl_surface_destroy;
uint64_t surface_association_serial;
-+ struct gamescope_tearing_control_v1 *tearing_control;
- uint32_t serial;
-
- #define XWL_FORMAT_ARGB8888 (1 << 0)
diff --git a/hw/xwayland/xwayland-window.c b/hw/xwayland/xwayland-window.c
-index 3319d7962..beef826a0 100644
+index b018d9656..7b3534385 100644
--- a/hw/xwayland/xwayland-window.c
+++ b/hw/xwayland/xwayland-window.c
-@@ -49,6 +49,7 @@
+@@ -48,6 +48,7 @@
+ #include "linux-dmabuf-unstable-v1-client-protocol.h"
#include "viewporter-client-protocol.h"
#include "xdg-shell-client-protocol.h"
++#include "tearing-control-unstable-v1-client-protocol.h"
#include "xwayland-shell-v1-client-protocol.h"
-+#include "gamescope-tearing-control-unstable-v1-client-protocol.h"
- #include "linux-drm-syncobj-v1-client-protocol.h"
#define DELAYED_WL_SURFACE_DESTROY 1000 /* ms */
-@@ -900,6 +901,11 @@ ensure_surface_for_window(WindowPtr window)
- xwl_screen->xwayland_shell, xwl_window->surface);
+@@ -920,6 +921,11 @@ ensure_surface_for_window(WindowPtr window)
+ goto err;
}
+ if (xwl_screen->tearing_control) {
+ xwl_window->tearing_control =
-+ gamescope_tearing_control_v1_get_tearing_control(xwl_screen->tearing_control, xwl_window->surface);
++ zwp_tearing_control_v1_get_tearing_control(xwl_screen->tearing_control, xwl_window->surface);
+ }
+
- if (!xwl_screen->rootless && !xwl_create_root_surface(xwl_window))
- goto err;
-
-@@ -1144,6 +1150,11 @@ xwl_unrealize_window(WindowPtr window)
+ if (xwl_screen->xwayland_shell) {
+ xwl_window->xwayland_surface = xwayland_shell_v1_get_xwayland_surface(
+ xwl_screen->xwayland_shell, xwl_window->surface);
+@@ -1169,6 +1175,11 @@ xwl_unrealize_window(WindowPtr window)
if (xwl_window_has_viewport_enabled(xwl_window))
xwl_window_disable_viewport(xwl_window);
+ if (xwl_window->tearing_control) {
-+ gamescope_surface_tearing_control_v1_destroy(xwl_window->tearing_control);
++ zwp_surface_tearing_control_v1_destroy(xwl_window->tearing_control);
+ xwl_window->tearing_control = NULL;
+ }
+
@@ -519,16 +481,248 @@ index 3319d7962..beef826a0 100644
#ifdef GLAMOR_HAS_GBM
diff --git a/hw/xwayland/xwayland-window.h b/hw/xwayland/xwayland-window.h
-index 2d1bb1c08..ed32a1a1c 100644
+index f8200d537..519d9394c 100644
--- a/hw/xwayland/xwayland-window.h
+++ b/hw/xwayland/xwayland-window.h
-@@ -121,6 +121,7 @@ struct xwl_window {
- struct xwl_dmabuf_feedback feedback;
- /* If TRUE, the window buffer format supports scanout with implicit modifier */
- Bool has_implicit_scanout_support;
+@@ -99,6 +99,7 @@ struct xwl_window {
+ struct wp_viewport *viewport;
+ float scale_x, scale_y;
+ struct xdg_surface *xdg_surface;
++ struct zwp_surface_tearing_control_v1 *tearing_control;
+ struct xdg_toplevel *xdg_toplevel;
+ WindowPtr window;
+ struct xorg_list link_damage;
+--
+2.42.0
+
+
+From 3357fc57deb1e397e6a2023a4b0254aeed957349 Mon Sep 17 00:00:00 2001
+From: Joshua Ashton
+Date: Wed, 31 Aug 2022 12:57:09 +0000
+Subject: [PATCH 3/4] Use gamescope tearing protocol instead
+
+Renamed to not clash
+---
+ hw/xwayland/meson.build | 2 +-
+ ...xml => gamescope-tearing-control-unstable-v1.xml} | 12 ++++++------
+ hw/xwayland/xwayland-present.c | 8 ++++----
+ hw/xwayland/xwayland-screen.c | 6 +++---
+ hw/xwayland/xwayland-screen.h | 2 +-
+ hw/xwayland/xwayland-window.c | 6 +++---
+ hw/xwayland/xwayland-window.h | 2 +-
+ 7 files changed, 19 insertions(+), 19 deletions(-)
+ rename hw/xwayland/protocols/unstable/tearing-control/{tearing-control-unstable-v1.xml => gamescope-tearing-control-unstable-v1.xml} (93%)
+
+diff --git a/hw/xwayland/meson.build b/hw/xwayland/meson.build
+index d29e55d7d..73f2bdd94 100644
+--- a/hw/xwayland/meson.build
++++ b/hw/xwayland/meson.build
+@@ -46,7 +46,7 @@ dmabuf_xml = join_paths(protodir, 'unstable', 'linux-dmabuf', 'linux-dmabuf-unst
+ viewporter_xml = join_paths(protodir, 'stable', 'viewporter', 'viewporter.xml')
+ xdg_shell_xml = join_paths(protodir, 'stable', 'xdg-shell', 'xdg-shell.xml')
+ drm_lease_xml = join_paths(protodir, 'staging', 'drm-lease', 'drm-lease-v1.xml')
+-tearing_xml = join_paths('protocols', 'unstable', 'tearing-control', 'tearing-control-unstable-v1.xml')
++tearing_xml = join_paths('protocols', 'unstable', 'tearing-control', 'gamescope-tearing-control-unstable-v1.xml')
+ shortcuts_inhibit_xml = join_paths(protodir, 'unstable', 'keyboard-shortcuts-inhibit', 'keyboard-shortcuts-inhibit-unstable-v1.xml')
+ xwayland_shell_xml = join_paths(protodir, 'staging', 'xwayland-shell', 'xwayland-shell-v1.xml')
+
+diff --git a/hw/xwayland/protocols/unstable/tearing-control/tearing-control-unstable-v1.xml b/hw/xwayland/protocols/unstable/tearing-control/gamescope-tearing-control-unstable-v1.xml
+similarity index 93%
+rename from hw/xwayland/protocols/unstable/tearing-control/tearing-control-unstable-v1.xml
+rename to hw/xwayland/protocols/unstable/tearing-control/gamescope-tearing-control-unstable-v1.xml
+index ce130718e..3c7cfb09e 100644
+--- a/hw/xwayland/protocols/unstable/tearing-control/tearing-control-unstable-v1.xml
++++ b/hw/xwayland/protocols/unstable/tearing-control/gamescope-tearing-control-unstable-v1.xml
+@@ -1,5 +1,5 @@
+
+-
++
+
+
+ Copyright © 2021 Xaver Hugl
+@@ -24,7 +24,7 @@
+ DEALINGS IN THE SOFTWARE.
+
+
+-
++
+
+ This global is a factory interface, allowing clients to request
+ the compositor to use asynchronous page flips on a per-surface basis.
+@@ -48,7 +48,7 @@
+
+
+ Destroy this tearing control factory object. Other objects, including
+- zwp_surface_tearing_control_v1 objects created by this factory,
++ gamescope_surface_tearing_control_v1 objects created by this factory,
+ shall not be affected by this request.
+
+
+@@ -63,19 +63,19 @@
+ Instantiate an interface extension for the given wl_surface to
+ request asynchronous page flips for presentation.
+
+- If the given wl_surface already has a zwp_surface_tearing_control_v1
++ If the given wl_surface already has a gamescope_surface_tearing_control_v1
+ object associated, the tearing_control_exists protocol error is raised.
+
+
+
+
+
+
+
+-
++
+
+ An additional interface to a wl_surface object, which allows the client
+ to hint to the compositor if and when it should use asynchronous page
+diff --git a/hw/xwayland/xwayland-present.c b/hw/xwayland/xwayland-present.c
+index 6f1d57a42..5cbd767c9 100644
+--- a/hw/xwayland/xwayland-present.c
++++ b/hw/xwayland/xwayland-present.c
+@@ -34,7 +34,7 @@
+ #include "xwayland-pixmap.h"
+ #include "glamor.h"
+
+-#include "tearing-control-unstable-v1-client-protocol.h"
++#include "gamescope-tearing-control-unstable-v1-client-protocol.h"
+
+
+ #define XWL_PRESENT_CAPS PresentCapabilityAsync
+@@ -802,10 +802,10 @@ xwl_present_flip(present_vblank_ptr vblank, RegionPtr damage)
+ // Josh: No support for VSync relaxed, this is something that should
+ // be determined by a user setting in gamescope.
+ if (xwl_window->tearing_control)
+- zwp_surface_tearing_control_v1_set_presentation_hint(xwl_window->tearing_control,
++ gamescope_surface_tearing_control_v1_set_presentation_hint(xwl_window->tearing_control,
+ sync_flip
+- ? ZWP_SURFACE_TEARING_CONTROL_V1_PRESENTATION_HINT_VSYNC
+- : ZWP_SURFACE_TEARING_CONTROL_V1_PRESENTATION_HINT_ASYNC);
++ ? GAMESCOPE_SURFACE_TEARING_CONTROL_V1_PRESENTATION_HINT_VSYNC
++ : GAMESCOPE_SURFACE_TEARING_CONTROL_V1_PRESENTATION_HINT_ASYNC);
+
+ wl_surface_commit(xwl_window->surface);
+
+diff --git a/hw/xwayland/xwayland-screen.c b/hw/xwayland/xwayland-screen.c
+index e35861e46..2a025db18 100644
+--- a/hw/xwayland/xwayland-screen.c
++++ b/hw/xwayland/xwayland-screen.c
+@@ -62,7 +62,7 @@
+ #include "xdg-output-unstable-v1-client-protocol.h"
+ #include "viewporter-client-protocol.h"
+ #include "xdg-shell-client-protocol.h"
+-#include "tearing-control-unstable-v1-client-protocol.h"
++#include "gamescope-tearing-control-unstable-v1-client-protocol.h"
+ #include "xwayland-shell-v1-client-protocol.h"
+
+ static DevPrivateKeyRec xwl_screen_private_key;
+@@ -458,8 +458,8 @@ registry_global(void *data, struct wl_registry *registry, uint32_t id,
+ else if (strcmp(interface, "wp_viewporter") == 0) {
+ xwl_screen->viewporter = wl_registry_bind(registry, id, &wp_viewporter_interface, 1);
+ }
+- else if (strcmp(interface, "zwp_tearing_control_v1") == 0) {
+- xwl_screen->tearing_control = wl_registry_bind(registry, id, &zwp_tearing_control_v1_interface, 1);
++ else if (strcmp(interface, "gamescope_tearing_control_v1") == 0) {
++ xwl_screen->tearing_control = wl_registry_bind(registry, id, &gamescope_tearing_control_v1_interface, 1);
+ }
+ else if (strcmp(interface, "xwayland_shell_v1") == 0 && xwl_screen->rootless) {
+ xwl_screen->xwayland_shell =
+diff --git a/hw/xwayland/xwayland-screen.h b/hw/xwayland/xwayland-screen.h
+index bf75278fd..d6b1a1d84 100644
+--- a/hw/xwayland/xwayland-screen.h
++++ b/hw/xwayland/xwayland-screen.h
+@@ -113,7 +113,7 @@ struct xwl_screen {
+ struct xorg_list drm_lease_devices;
+ struct xorg_list queued_drm_lease_devices;
+ struct xorg_list drm_leases;
+- struct zwp_tearing_control_v1 *tearing_control;
++ struct gamescope_tearing_control_v1 *tearing_control;
+ struct xwl_output *fixed_output;
+ struct xorg_list pending_wl_surface_destroy;
+ uint64_t surface_association_serial;
+diff --git a/hw/xwayland/xwayland-window.c b/hw/xwayland/xwayland-window.c
+index 7b3534385..d3bbe703d 100644
+--- a/hw/xwayland/xwayland-window.c
++++ b/hw/xwayland/xwayland-window.c
+@@ -48,7 +48,7 @@
+ #include "linux-dmabuf-unstable-v1-client-protocol.h"
+ #include "viewporter-client-protocol.h"
+ #include "xdg-shell-client-protocol.h"
+-#include "tearing-control-unstable-v1-client-protocol.h"
++#include "gamescope-tearing-control-unstable-v1-client-protocol.h"
+ #include "xwayland-shell-v1-client-protocol.h"
+
+ #define DELAYED_WL_SURFACE_DESTROY 1000 /* ms */
+@@ -923,7 +923,7 @@ ensure_surface_for_window(WindowPtr window)
+
+ if (xwl_screen->tearing_control) {
+ xwl_window->tearing_control =
+- zwp_tearing_control_v1_get_tearing_control(xwl_screen->tearing_control, xwl_window->surface);
++ gamescope_tearing_control_v1_get_tearing_control(xwl_screen->tearing_control, xwl_window->surface);
+ }
+
+ if (xwl_screen->xwayland_shell) {
+@@ -1176,7 +1176,7 @@ xwl_unrealize_window(WindowPtr window)
+ xwl_window_disable_viewport(xwl_window);
+
+ if (xwl_window->tearing_control) {
+- zwp_surface_tearing_control_v1_destroy(xwl_window->tearing_control);
++ gamescope_surface_tearing_control_v1_destroy(xwl_window->tearing_control);
+ xwl_window->tearing_control = NULL;
+ }
+
+diff --git a/hw/xwayland/xwayland-window.h b/hw/xwayland/xwayland-window.h
+index 519d9394c..95f770c07 100644
+--- a/hw/xwayland/xwayland-window.h
++++ b/hw/xwayland/xwayland-window.h
+@@ -99,7 +99,7 @@ struct xwl_window {
+ struct wp_viewport *viewport;
+ float scale_x, scale_y;
+ struct xdg_surface *xdg_surface;
+- struct zwp_surface_tearing_control_v1 *tearing_control;
+ struct gamescope_surface_tearing_control_v1 *tearing_control;
- struct wp_linux_drm_syncobj_surface_v1 *surface_sync;
- };
+ struct xdg_toplevel *xdg_toplevel;
+ WindowPtr window;
+ struct xorg_list link_damage;
+--
+2.42.0
+
+
+From c799ef123d1ed4eddc7972451b1b313b14195935 Mon Sep 17 00:00:00 2001
+From: Kyle Gospodnetich
+Date: Wed, 31 Jan 2024 17:36:04 -0800
+Subject: [PATCH 4/4] Fix missing sync_flip param
+
+---
+ hw/xwayland/xwayland-present.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/hw/xwayland/xwayland-present.c b/hw/xwayland/xwayland-present.c
+index 5cbd767c9..f22e8f987 100644
+--- a/hw/xwayland/xwayland-present.c
++++ b/hw/xwayland/xwayland-present.c
+@@ -754,7 +754,7 @@ xwl_present_clear_window_flip(WindowPtr window)
+ }
+
+ static Bool
+-xwl_present_flip(present_vblank_ptr vblank, RegionPtr damage)
++xwl_present_flip(present_vblank_ptr vblank, RegionPtr damage, Bool sync_flip)
+ {
+ WindowPtr present_window = vblank->window;
+ PixmapPtr pixmap = vblank->pixmap;
+@@ -873,7 +873,7 @@ xwl_present_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
+ } else
+ damage = RegionDuplicate(&window->clipList);
+
+- if (xwl_present_flip(vblank, damage)) {
++ if (xwl_present_flip(vblank, damage, vblank->sync_flip)) {
+ WindowPtr toplvl_window = xwl_present_toplvl_pixmap_window(vblank->window);
+ PixmapPtr old_pixmap = screen->GetWindowPixmap(window);
--
2.42.0
diff --git a/spec_files/xorg-x11-server-Xwayland/967.patch b/spec_files/xorg-x11-server-Xwayland/967.patch
deleted file mode 100644
index f8845320..00000000
--- a/spec_files/xorg-x11-server-Xwayland/967.patch
+++ /dev/null
@@ -1,2122 +0,0 @@
-From 78f590e35e91b69e5ca14e74e6f44b82fb7a401f Mon Sep 17 00:00:00 2001
-From: GloriousEggroll
-Date: Thu, 16 Nov 2023 00:32:36 -0700
-Subject: [PATCH] MR-967
-
----
- dri3/dri3.c | 15 ++
- dri3/dri3.h | 36 ++-
- dri3/dri3_priv.h | 3 +
- dri3/dri3_request.c | 125 +++++++++
- dri3/dri3_screen.c | 20 ++
- hw/xwayland/meson.build | 3 +
- hw/xwayland/xwayland-glamor-gbm.c | 356 +++++++++++++++++++++++++-
- hw/xwayland/xwayland-glamor.c | 108 ++++++++
- hw/xwayland/xwayland-glamor.h | 27 ++
- hw/xwayland/xwayland-present.c | 136 +++++++++-
- hw/xwayland/xwayland-present.h | 4 +-
- hw/xwayland/xwayland-screen.c | 1 +
- hw/xwayland/xwayland-screen.h | 9 +
- hw/xwayland/xwayland-window-buffers.c | 68 +++++
- hw/xwayland/xwayland-window.c | 11 +
- hw/xwayland/xwayland-window.h | 1 +
- include/protocol-versions.h | 4 +-
- present/present.c | 9 +
- present/present_execute.c | 37 ++-
- present/present_priv.h | 25 ++
- present/present_request.c | 169 +++++++++---
- present/present_scmd.c | 8 +
- present/present_screen.c | 1 +
- present/present_vblank.c | 36 +++
- 24 files changed, 1157 insertions(+), 55 deletions(-)
-
-diff --git a/dri3/dri3.c b/dri3/dri3.c
-index 1912529..f9c5172 100644
---- a/dri3/dri3.c
-+++ b/dri3/dri3.c
-@@ -63,6 +63,16 @@ dri3_screen_init(ScreenPtr screen, const dri3_screen_info_rec *info)
- return TRUE;
- }
-
-+RESTYPE dri3_syncobj_type;
-+
-+static int dri3_syncobj_free(void *data, XID id)
-+{
-+ struct dri3_syncobj *syncobj = data;
-+ if (--syncobj->refcount == 0)
-+ syncobj->free(syncobj);
-+ return 0;
-+}
-+
- void
- dri3_extension_init(void)
- {
-@@ -92,6 +102,11 @@ dri3_extension_init(void)
- if (!dri3_screen_init(screenInfo.screens[i], NULL))
- goto bail;
- }
-+
-+ dri3_syncobj_type = CreateNewResourceType(dri3_syncobj_free, "DRI3Syncobj");
-+ if (!dri3_syncobj_type)
-+ goto bail;
-+
- return;
-
- bail:
-diff --git a/dri3/dri3.h b/dri3/dri3.h
-index 02d3b03..f7f4bb1 100644
---- a/dri3/dri3.h
-+++ b/dri3/dri3.h
-@@ -28,7 +28,33 @@
- #include
- #include
-
--#define DRI3_SCREEN_INFO_VERSION 2
-+#define DRI3_SCREEN_INFO_VERSION 4
-+
-+extern RESTYPE dri3_syncobj_type;
-+
-+struct dri3_syncobj
-+{
-+ XID id;
-+ ScreenPtr screen;
-+ uint32_t refcount;
-+
-+ void (*free)(struct dri3_syncobj *syncobj);
-+ Bool (*check)(struct dri3_syncobj *syncobj, uint64_t point);
-+ int (*export_fence)(struct dri3_syncobj *syncobj, uint64_t point);
-+ void (*import_fence)(struct dri3_syncobj *syncobj, uint64_t point, int fd);
-+ void (*signal)(struct dri3_syncobj *syncobj, uint64_t point);
-+ void (*eventfd)(struct dri3_syncobj *syncobj, uint64_t point, int efd, Bool wait_avail);
-+};
-+
-+#define VERIFY_DRI3_SYNCOBJ(id, ptr, a)\
-+ do {\
-+ int rc = dixLookupResourceByType((void **)&(ptr), id,\
-+ dri3_syncobj_type, client, a);\
-+ if (rc != Success) {\
-+ client->errorValue = id;\
-+ return rc;\
-+ }\
-+ } while (0);
-
- typedef int (*dri3_open_proc)(ScreenPtr screen,
- RRProviderPtr provider,
-@@ -84,6 +110,11 @@ typedef int (*dri3_get_drawable_modifiers_proc) (DrawablePtr draw,
- uint32_t *num_modifiers,
- uint64_t **modifiers);
-
-+typedef struct dri3_syncobj *(*dri3_import_syncobj_proc) (ClientPtr client,
-+ ScreenPtr screen,
-+ XID id,
-+ int fd);
-+
- typedef struct dri3_screen_info {
- uint32_t version;
-
-@@ -101,6 +132,9 @@ typedef struct dri3_screen_info {
- dri3_get_modifiers_proc get_modifiers;
- dri3_get_drawable_modifiers_proc get_drawable_modifiers;
-
-+ /* Version 4 */
-+ dri3_import_syncobj_proc import_syncobj;
-+
- } dri3_screen_info_rec, *dri3_screen_info_ptr;
-
- extern _X_EXPORT Bool
-diff --git a/dri3/dri3_priv.h b/dri3/dri3_priv.h
-index f319d17..71d2da9 100644
---- a/dri3/dri3_priv.h
-+++ b/dri3/dri3_priv.h
-@@ -102,4 +102,7 @@ dri3_get_supported_modifiers(ScreenPtr screen, DrawablePtr drawable,
- CARD32 *num_screen_modifiers,
- CARD64 **screen_modifiers);
-
-+int
-+dri3_import_syncobj(ClientPtr client, ScreenPtr screen, XID id, int fd);
-+
- #endif /* _DRI3PRIV_H_ */
-diff --git a/dri3/dri3_request.c b/dri3/dri3_request.c
-index 6871689..520cd60 100644
---- a/dri3/dri3_request.c
-+++ b/dri3/dri3_request.c
-@@ -28,6 +28,17 @@
- #include
- #include
-
-+static Bool
-+dri3_screen_can_one_point_four(ScreenPtr screen)
-+{
-+ dri3_screen_priv_ptr dri3 = dri3_screen_priv(screen);
-+
-+ return dri3 &&
-+ dri3->info &&
-+ dri3->info->version >= 4 &&
-+ dri3->info->import_syncobj;
-+}
-+
- static Bool
- dri3_screen_can_one_point_two(ScreenPtr screen)
- {
-@@ -61,6 +72,10 @@ proc_dri3_query_version(ClientPtr client)
- rep.minorVersion = 0;
- break;
- }
-+ if (!dri3_screen_can_one_point_four(screenInfo.screens[i])) {
-+ rep.minorVersion = 2;
-+ break;
-+ }
- }
-
- for (int i = 0; i < screenInfo.numGPUScreens; i++) {
-@@ -68,6 +83,10 @@ proc_dri3_query_version(ClientPtr client)
- rep.minorVersion = 0;
- break;
- }
-+ if (!dri3_screen_can_one_point_four(screenInfo.gpuscreens[i])) {
-+ rep.minorVersion = 2;
-+ break;
-+ }
- }
-
- /* From DRI3 proto:
-@@ -554,6 +573,72 @@ proc_dri3_buffers_from_pixmap(ClientPtr client)
- return Success;
- }
-
-+static int
-+proc_dri3_set_drm_device_in_use(ClientPtr client)
-+{
-+ REQUEST(xDRI3SetDRMDeviceInUseReq);
-+ WindowPtr window;
-+ int status;
-+
-+ REQUEST_SIZE_MATCH(xDRI3SetDRMDeviceInUseReq);
-+ status = dixLookupWindow(&window, stuff->window, client,
-+ DixGetAttrAccess);
-+ if (status != Success)
-+ return status;
-+
-+ /* TODO Eventually we should use this information to have
-+ * DRI3GetSupportedModifiers return device-specific modifiers, but for now
-+ * we will ignore it until multi-device support is more complete.
-+ * Otherwise we can't advertise support for DRI3 1.4.
-+ */
-+ return Success;
-+}
-+
-+static int
-+proc_dri3_import_syncobj(ClientPtr client)
-+{
-+ REQUEST(xDRI3ImportSyncobjReq);
-+ DrawablePtr drawable;
-+ ScreenPtr screen;
-+ int fd;
-+ int status;
-+
-+ SetReqFds(client, 1);
-+ REQUEST_SIZE_MATCH(xDRI3ImportSyncobjReq);
-+ LEGAL_NEW_RESOURCE(stuff->syncobj, client);
-+
-+ status = dixLookupDrawable(&drawable, stuff->drawable, client,
-+ M_ANY, DixGetAttrAccess);
-+ if (status != Success)
-+ return status;
-+
-+ screen = drawable->pScreen;
-+
-+ fd = ReadFdFromClient(client);
-+ if (fd < 0)
-+ return BadValue;
-+
-+ return dri3_import_syncobj(client, screen, stuff->syncobj, fd);
-+}
-+
-+static int
-+proc_dri3_free_syncobj(ClientPtr client)
-+{
-+ REQUEST(xDRI3FreeSyncobjReq);
-+ struct dri3_syncobj *syncobj;
-+ int status;
-+
-+ REQUEST_SIZE_MATCH(xDRI3FreeSyncobjReq);
-+
-+ status = dixLookupResourceByType((void **) &syncobj, stuff->syncobj,
-+ dri3_syncobj_type, client, DixWriteAccess);
-+ if (status != Success)
-+ return status;
-+
-+ FreeResource(stuff->syncobj, dri3_syncobj_type);
-+ return Success;
-+}
-+
- int (*proc_dri3_vector[DRI3NumberRequests]) (ClientPtr) = {
- proc_dri3_query_version, /* 0 */
- proc_dri3_open, /* 1 */
-@@ -564,6 +649,9 @@ int (*proc_dri3_vector[DRI3NumberRequests]) (ClientPtr) = {
- proc_dri3_get_supported_modifiers, /* 6 */
- proc_dri3_pixmap_from_buffers, /* 7 */
- proc_dri3_buffers_from_pixmap, /* 8 */
-+ proc_dri3_set_drm_device_in_use, /* 9 */
-+ proc_dri3_import_syncobj, /* 10 */
-+ proc_dri3_free_syncobj, /* 11 */
- };
-
- int
-@@ -697,6 +785,40 @@ sproc_dri3_buffers_from_pixmap(ClientPtr client)
- return (*proc_dri3_vector[stuff->dri3ReqType]) (client);
- }
-
-+static int _X_COLD
-+sproc_dri3_set_drm_device_in_use(ClientPtr client)
-+{
-+ REQUEST(xDRI3SetDRMDeviceInUseReq);
-+ REQUEST_SIZE_MATCH(xDRI3SetDRMDeviceInUseReq);
-+ swapl(&stuff->window);
-+ swapl(&stuff->drmMajor);
-+ swapl(&stuff->drmMinor);
-+ return (*proc_dri3_vector[stuff->dri3ReqType]) (client);
-+}
-+
-+static int _X_COLD
-+sproc_dri3_import_syncobj(ClientPtr client)
-+{
-+ REQUEST(xDRI3ImportSyncobjReq);
-+ REQUEST_SIZE_MATCH(xDRI3ImportSyncobjReq);
-+
-+ swaps(&stuff->length);
-+ swapl(&stuff->syncobj);
-+ swapl(&stuff->drawable);
-+ return (*proc_dri3_vector[stuff->dri3ReqType]) (client);
-+}
-+
-+static int _X_COLD
-+sproc_dri3_free_syncobj(ClientPtr client)
-+{
-+ REQUEST(xDRI3FreeSyncobjReq);
-+ REQUEST_SIZE_MATCH(xDRI3FreeSyncobjReq);
-+
-+ swaps(&stuff->length);
-+ swapl(&stuff->syncobj);
-+ return (*proc_dri3_vector[stuff->dri3ReqType]) (client);
-+}
-+
- int (*sproc_dri3_vector[DRI3NumberRequests]) (ClientPtr) = {
- sproc_dri3_query_version, /* 0 */
- sproc_dri3_open, /* 1 */
-@@ -707,6 +829,9 @@ int (*sproc_dri3_vector[DRI3NumberRequests]) (ClientPtr) = {
- sproc_dri3_get_supported_modifiers, /* 6 */
- sproc_dri3_pixmap_from_buffers, /* 7 */
- sproc_dri3_buffers_from_pixmap, /* 8 */
-+ sproc_dri3_set_drm_device_in_use, /* 9 */
-+ sproc_dri3_import_syncobj, /* 10 */
-+ sproc_dri3_free_syncobj, /* 11 */
- };
-
- int _X_COLD
-diff --git a/dri3/dri3_screen.c b/dri3/dri3_screen.c
-index bc96e53..5614a22 100644
---- a/dri3/dri3_screen.c
-+++ b/dri3/dri3_screen.c
-@@ -272,3 +272,23 @@ dri3_get_supported_modifiers(ScreenPtr screen, DrawablePtr drawable,
-
- return Success;
- }
-+
-+int dri3_import_syncobj(ClientPtr client, ScreenPtr screen, XID id, int fd)
-+{
-+ const dri3_screen_info_rec *info = dri3_screen_priv(screen)->info;
-+ struct dri3_syncobj *syncobj = NULL;
-+
-+ if (info->version < 4 || !info->import_syncobj)
-+ return BadImplementation;
-+
-+ syncobj = info->import_syncobj(client, screen, id, fd);
-+ close(fd);
-+
-+ if (!syncobj)
-+ return BadAlloc;
-+
-+ if (!AddResource(id, dri3_syncobj_type, syncobj))
-+ return BadAlloc;
-+
-+ return Success;
-+}
-diff --git a/hw/xwayland/meson.build b/hw/xwayland/meson.build
-index 54529b6..57a01ce 100644
---- a/hw/xwayland/meson.build
-+++ b/hw/xwayland/meson.build
-@@ -49,6 +49,7 @@ drm_lease_xml = join_paths(protodir, 'staging', 'drm-lease', 'drm-lease-v1.xml')
- shortcuts_inhibit_xml = join_paths(protodir, 'unstable', 'keyboard-shortcuts-inhibit', 'keyboard-shortcuts-inhibit-unstable-v1.xml')
- xwayland_shell_xml = join_paths(protodir, 'staging', 'xwayland-shell', 'xwayland-shell-v1.xml')
- tearing_xml = join_paths(protodir, 'staging', 'tearing-control', 'tearing-control-v1.xml')
-+syncobj_xml = join_paths(protodir, 'staging', 'linux-drm-syncobj', 'linux-drm-syncobj-v1.xml')
-
- client_header = generator(scanner,
- output : '@BASENAME@-client-protocol.h',
-@@ -78,6 +79,7 @@ srcs += client_header.process(drm_lease_xml)
- srcs += client_header.process(shortcuts_inhibit_xml)
- srcs += client_header.process(xwayland_shell_xml)
- srcs += client_header.process(tearing_xml)
-+srcs += client_header.process(syncobj_xml)
- srcs += code.process(relative_xml)
- srcs += code.process(pointer_xml)
- srcs += code.process(gestures_xml)
-@@ -91,6 +93,7 @@ srcs += code.process(drm_lease_xml)
- srcs += code.process(shortcuts_inhibit_xml)
- srcs += code.process(xwayland_shell_xml)
- srcs += code.process(tearing_xml)
-+srcs += code.process(syncobj_xml)
-
- if build_ei
- xwayland_dep += libei_dep
-diff --git a/hw/xwayland/xwayland-glamor-gbm.c b/hw/xwayland/xwayland-glamor-gbm.c
-index cfcd39a..707b1b3 100644
---- a/hw/xwayland/xwayland-glamor-gbm.c
-+++ b/hw/xwayland/xwayland-glamor-gbm.c
-@@ -35,6 +35,9 @@
- #include
- #include
- #include
-+#include
-+#include
-+#include
-
- #define MESA_EGL_NO_X11_HEADERS
- #define EGL_NO_X11
-@@ -51,6 +54,7 @@
- #include "xwayland-screen.h"
-
- #include "linux-dmabuf-unstable-v1-client-protocol.h"
-+#include "linux-drm-syncobj-v1-client-protocol.h"
-
- struct xwl_gbm_private {
- drmDevice *device;
-@@ -569,6 +573,28 @@ xwl_glamor_gbm_get_wl_buffer_for_pixmap(PixmapPtr pixmap)
- return xwl_pixmap->buffer;
- }
-
-+static void
-+xwl_screen_destroy_explicit_sync(struct xwl_screen *xwl_screen)
-+{
-+ if (xwl_screen->glamor_syncobj) {
-+ xwl_screen->glamor_syncobj->free(xwl_screen->glamor_syncobj);
-+ xwl_screen->glamor_syncobj = NULL;
-+ }
-+
-+ if (xwl_screen->server_syncobj) {
-+ xwl_screen->server_syncobj->free(xwl_screen->server_syncobj);
-+ xwl_screen->server_syncobj = NULL;
-+ }
-+
-+ if (xwl_screen->explicit_sync) {
-+ wp_linux_drm_syncobj_v1_destroy(xwl_screen->explicit_sync);
-+ xwl_screen->explicit_sync = NULL;
-+ }
-+
-+ xwl_screen->glamor_timeline_point = 0;
-+ xwl_screen->server_timeline_point = 0;
-+}
-+
- static void
- xwl_glamor_gbm_cleanup(struct xwl_screen *xwl_screen)
- {
-@@ -583,6 +609,7 @@ xwl_glamor_gbm_cleanup(struct xwl_screen *xwl_screen)
- wl_drm_destroy(xwl_gbm->drm);
- if (xwl_gbm->gbm)
- gbm_device_destroy(xwl_gbm->gbm);
-+ xwl_screen_destroy_explicit_sync(xwl_screen);
-
- free(xwl_gbm);
- }
-@@ -827,7 +854,298 @@ glamor_egl_fd_from_pixmap(ScreenPtr screen, PixmapPtr pixmap,
- return -1;
- }
-
--static const dri3_screen_info_rec xwl_dri3_info = {
-+static int xwl_glamor_gbm_dmabuf_export_sync_file(PixmapPtr pixmap)
-+{
-+ struct xwl_pixmap *xwl_pixmap = xwl_pixmap_get(pixmap);
-+ int num_planes = gbm_bo_get_plane_count(xwl_pixmap->bo);
-+ int sync_file = -1;
-+ int p;
-+
-+ for (p = 0; p < num_planes; ++p) {
-+ int plane_fd = gbm_bo_get_fd_for_plane(xwl_pixmap->bo, p);
-+ struct dma_buf_export_sync_file export_args = { 0 };
-+ export_args.fd = -1;
-+ export_args.flags = DMA_BUF_SYNC_READ;
-+ drmIoctl(plane_fd, DMA_BUF_IOCTL_EXPORT_SYNC_FILE, &export_args);
-+ close(plane_fd);
-+ if (sync_file == -1) {
-+ sync_file = export_args.fd;
-+ } else {
-+ struct sync_merge_data merge_args = { 0 };
-+ merge_args.fd2 = export_args.fd;
-+ ioctl(sync_file, SYNC_IOC_MERGE, &merge_args);
-+ close(export_args.fd);
-+ close(sync_file);
-+ sync_file = merge_args.fence;
-+ }
-+ }
-+
-+ return sync_file;
-+}
-+
-+static void xwl_glamor_gbm_dmabuf_import_sync_file(PixmapPtr pixmap, int sync_file)
-+{
-+ struct xwl_pixmap *xwl_pixmap = xwl_pixmap_get(pixmap);
-+ int num_planes = gbm_bo_get_plane_count(xwl_pixmap->bo);
-+ int p;
-+
-+ for (p = 0; p < num_planes; ++p) {
-+ int plane_fd = gbm_bo_get_fd_for_plane(xwl_pixmap->bo, p);
-+ struct dma_buf_import_sync_file import_args = { 0 };
-+ import_args.fd = sync_file;
-+ import_args.flags = DMA_BUF_SYNC_READ;
-+ drmIoctl(plane_fd, DMA_BUF_IOCTL_IMPORT_SYNC_FILE, &import_args);
-+ close(plane_fd);
-+ }
-+ close(sync_file);
-+}
-+
-+struct xwl_dri3_syncobj
-+{
-+ struct dri3_syncobj base;
-+ uint32_t handle;
-+ struct wp_linux_drm_syncobj_timeline_v1 *timeline;
-+};
-+
-+static void
-+xwl_glamor_gbm_dri3_syncobj_passthrough(WindowPtr window,
-+ struct dri3_syncobj *acquire_syncobj,
-+ struct dri3_syncobj *release_syncobj,
-+ uint64_t acquire_point,
-+ uint64_t release_point)
-+{
-+ struct xwl_window *xwl_window = xwl_window_get(window);
-+ struct xwl_screen *xwl_screen = xwl_window->xwl_screen;
-+ struct xwl_dri3_syncobj *xwl_acquire_syncobj = (struct xwl_dri3_syncobj *)acquire_syncobj;
-+ struct xwl_dri3_syncobj *xwl_release_syncobj = (struct xwl_dri3_syncobj *)release_syncobj;
-+ uint32_t acquire_hi = acquire_point >> 32;
-+ uint32_t acquire_lo = acquire_point & 0xffffffff;
-+ uint32_t release_hi = release_point >> 32;
-+ uint32_t release_lo = release_point & 0xffffffff;
-+
-+ if (!xwl_window->surface_sync)
-+ xwl_window->surface_sync =
-+ wp_linux_drm_syncobj_v1_get_surface(xwl_screen->explicit_sync,
-+ xwl_window->surface);
-+
-+ wp_linux_drm_syncobj_surface_v1_set_acquire_point(xwl_window->surface_sync,
-+ xwl_acquire_syncobj->timeline,
-+ acquire_hi, acquire_lo);
-+ wp_linux_drm_syncobj_surface_v1_set_release_point(xwl_window->surface_sync,
-+ xwl_release_syncobj->timeline,
-+ release_hi, release_lo);
-+}
-+
-+static Bool
-+xwl_dri3_check_syncobj(struct dri3_syncobj *syncobj, uint64_t point)
-+{
-+ struct xwl_dri3_syncobj *xwl_syncobj = (struct xwl_dri3_syncobj *)syncobj;
-+ struct xwl_screen *xwl_screen = xwl_screen_get(syncobj->screen);
-+ struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen);
-+
-+ return !drmSyncobjTimelineWait(xwl_gbm->drm_fd,
-+ &xwl_syncobj->handle, &point, 1,
-+ 0 /* timeout */,
-+ DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT,
-+ NULL /* first_signaled */);
-+}
-+
-+extern int
-+drmSyncobjImportSyncFileTimeline(int fd, uint32_t handle,
-+ uint64_t point, int sync_file_fd)
-+ __attribute__((weak));
-+extern int
-+drmSyncobjExportSyncFileTimeline(int fd, uint32_t handle,
-+ uint64_t point, int *sync_file_fd)
-+ __attribute__((weak));
-+
-+static int
-+xwl_dri3_syncobj_export_fence(struct dri3_syncobj *syncobj, uint64_t point)
-+{
-+ struct xwl_dri3_syncobj *xwl_syncobj = (struct xwl_dri3_syncobj *)syncobj;
-+ struct xwl_screen *xwl_screen = xwl_screen_get(syncobj->screen);
-+ struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen);
-+ int fd = -1;
-+
-+ if (!drmSyncobjExportSyncFileTimeline ||
-+ drmSyncobjExportSyncFileTimeline(xwl_gbm->drm_fd,
-+ xwl_syncobj->handle,
-+ point, &fd)) {
-+ /* try legacy export procedure */
-+ uint32_t temp_syncobj;
-+ drmSyncobjCreate(xwl_gbm->drm_fd, 0, &temp_syncobj);
-+ drmSyncobjTransfer(xwl_gbm->drm_fd, temp_syncobj, 0,
-+ xwl_syncobj->handle, point, 0);
-+ drmSyncobjExportSyncFile(xwl_gbm->drm_fd, temp_syncobj, &fd);
-+ drmSyncobjDestroy(xwl_gbm->drm_fd, temp_syncobj);
-+ }
-+ return fd;
-+}
-+
-+static void
-+xwl_dri3_syncobj_import_fence(struct dri3_syncobj *syncobj,
-+ uint64_t point, int fd)
-+{
-+ struct xwl_dri3_syncobj *xwl_syncobj = (struct xwl_dri3_syncobj *)syncobj;
-+ struct xwl_screen *xwl_screen = xwl_screen_get(syncobj->screen);
-+ struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen);
-+
-+ if (!drmSyncobjImportSyncFileTimeline ||
-+ drmSyncobjImportSyncFileTimeline(xwl_gbm->drm_fd,
-+ xwl_syncobj->handle,
-+ point, fd)) {
-+ /* try legacy import procedure */
-+ uint32_t temp_syncobj;
-+ drmSyncobjCreate(xwl_gbm->drm_fd, 0, &temp_syncobj);
-+ drmSyncobjImportSyncFile(xwl_gbm->drm_fd, temp_syncobj, fd);
-+ drmSyncobjTransfer(xwl_gbm->drm_fd, xwl_syncobj->handle, point,
-+ temp_syncobj, 0, 0);
-+ drmSyncobjDestroy(xwl_gbm->drm_fd, temp_syncobj);
-+ }
-+ close(fd);
-+}
-+
-+static void
-+xwl_dri3_signal_syncobj(struct dri3_syncobj *syncobj, uint64_t point)
-+{
-+ struct xwl_dri3_syncobj *xwl_syncobj = (struct xwl_dri3_syncobj *)syncobj;
-+ struct xwl_screen *xwl_screen = xwl_screen_get(syncobj->screen);
-+ struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen);
-+
-+ drmSyncobjTimelineSignal(xwl_gbm->drm_fd, &xwl_syncobj->handle, &point, 1);
-+}
-+
-+static void
-+xwl_dri3_free_syncobj(struct dri3_syncobj *syncobj)
-+{
-+ struct xwl_dri3_syncobj *xwl_syncobj = (struct xwl_dri3_syncobj *)syncobj;
-+ struct xwl_screen *xwl_screen = xwl_screen_get(syncobj->screen);
-+ struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen);
-+
-+ if (xwl_syncobj->timeline)
-+ wp_linux_drm_syncobj_timeline_v1_destroy(xwl_syncobj->timeline);
-+
-+ if (xwl_syncobj->handle)
-+ drmSyncobjDestroy(xwl_gbm->drm_fd, xwl_syncobj->handle);
-+
-+ free(xwl_syncobj);
-+}
-+
-+static void
-+xwl_dri3_syncobj_eventfd(struct dri3_syncobj *syncobj, uint64_t point,
-+ int efd, Bool wait_avail)
-+{
-+ struct xwl_dri3_syncobj *xwl_syncobj = (struct xwl_dri3_syncobj *)syncobj;
-+ struct xwl_screen *xwl_screen = xwl_screen_get(syncobj->screen);
-+ struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen);
-+
-+ drmSyncobjEventfd(xwl_gbm->drm_fd, xwl_syncobj->handle, point, efd,
-+ wait_avail ? DRM_SYNCOBJ_WAIT_FLAGS_WAIT_AVAILABLE : 0);
-+}
-+
-+static struct dri3_syncobj *
-+xwl_dri3_create_syncobj(struct xwl_screen *xwl_screen, uint32_t handle)
-+{
-+ struct xwl_dri3_syncobj *syncobj = calloc(1, sizeof (*syncobj));
-+ struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen);
-+ int syncobj_fd = -1;
-+
-+ if (!syncobj)
-+ return NULL;
-+
-+ if (xwl_screen->explicit_sync) {
-+ if (drmSyncobjHandleToFD(xwl_gbm->drm_fd, handle, &syncobj_fd))
-+ goto fail;
-+
-+ syncobj->timeline =
-+ wp_linux_drm_syncobj_v1_import_timeline(xwl_screen->explicit_sync,
-+ syncobj_fd);
-+ close(syncobj_fd);
-+ if (!syncobj->timeline)
-+ goto fail;
-+ }
-+
-+ syncobj->handle = handle;
-+ syncobj->base.screen = xwl_screen->screen;
-+ syncobj->base.refcount = 1;
-+
-+ syncobj->base.free = xwl_dri3_free_syncobj;
-+ syncobj->base.check = xwl_dri3_check_syncobj;
-+ syncobj->base.export_fence = xwl_dri3_syncobj_export_fence;
-+ syncobj->base.import_fence = xwl_dri3_syncobj_import_fence;
-+ syncobj->base.signal = xwl_dri3_signal_syncobj;
-+ syncobj->base.eventfd = xwl_dri3_syncobj_eventfd;
-+ return &syncobj->base;
-+
-+fail:
-+ free(syncobj);
-+ return NULL;
-+}
-+
-+static struct dri3_syncobj *
-+xwl_dri3_import_syncobj(ClientPtr client, ScreenPtr screen, XID id, int fd)
-+{
-+ struct xwl_screen *xwl_screen = xwl_screen_get(screen);
-+ struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen);
-+ struct xwl_dri3_syncobj *syncobj = NULL;
-+ uint32_t handle;
-+
-+ if (drmSyncobjFDToHandle(xwl_gbm->drm_fd, fd, &handle))
-+ return NULL;
-+
-+ syncobj = (struct xwl_dri3_syncobj *)xwl_dri3_create_syncobj(xwl_screen, handle);
-+ if (!syncobj) {
-+ drmSyncobjDestroy(xwl_gbm->drm_fd, handle);
-+ return NULL;
-+ }
-+
-+ syncobj->base.id = id;
-+
-+ return &syncobj->base;
-+}
-+
-+static Bool
-+xwl_gbm_supports_syncobjs(struct xwl_screen *xwl_screen)
-+{
-+ struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen);
-+ uint64_t syncobj_cap = 0;
-+
-+ if (drmGetCap(xwl_gbm->drm_fd, DRM_CAP_SYNCOBJ_TIMELINE,
-+ &syncobj_cap) || !syncobj_cap)
-+ return FALSE;
-+
-+ /* Check if syncobj eventfd is supported. */
-+ drmSyncobjEventfd(xwl_gbm->drm_fd, 0, 0, -1, 0);
-+ if (errno != ENOENT)
-+ return FALSE;
-+
-+ return TRUE;
-+}
-+
-+static Bool
-+xwl_screen_init_explicit_sync(struct xwl_screen *xwl_screen)
-+{
-+ struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen);
-+ uint32_t glamor_syncobj_handle, server_syncobj_handle;
-+
-+ if (!xwl_screen->explicit_sync)
-+ return FALSE;
-+
-+ if (drmSyncobjCreate(xwl_gbm->drm_fd, 0, &glamor_syncobj_handle) ||
-+ drmSyncobjCreate(xwl_gbm->drm_fd, 0, &server_syncobj_handle))
-+ return FALSE;
-+
-+ xwl_screen->glamor_syncobj = xwl_dri3_create_syncobj(xwl_screen, glamor_syncobj_handle);
-+ xwl_screen->server_syncobj = xwl_dri3_create_syncobj(xwl_screen, server_syncobj_handle);
-+ if (!xwl_screen->glamor_syncobj || !xwl_screen->server_syncobj)
-+ return FALSE;
-+
-+ xwl_screen->glamor_timeline_point = 1;
-+ xwl_screen->server_timeline_point = 1;
-+ return TRUE;
-+}
-+
-+static dri3_screen_info_rec xwl_dri3_info = {
- .version = 2,
- .open = NULL,
- .pixmap_from_fds = glamor_pixmap_from_fds,
-@@ -836,6 +1154,7 @@ static const dri3_screen_info_rec xwl_dri3_info = {
- .get_formats = xwl_glamor_get_formats,
- .get_modifiers = xwl_glamor_get_modifiers,
- .get_drawable_modifiers = xwl_glamor_get_drawable_modifiers,
-+ .import_syncobj = NULL, /* need to check for kernel support */
- };
-
- static const char *
-@@ -997,6 +1316,11 @@ xwl_glamor_gbm_init_wl_registry(struct xwl_screen *xwl_screen,
- } else if (strcmp(name, "zwp_linux_dmabuf_v1") == 0) {
- xwl_screen_set_dmabuf_interface(xwl_screen, id, version);
- return TRUE;
-+ } else if (strcmp(name, "wp_linux_drm_syncobj_v1") == 0) {
-+ xwl_screen->explicit_sync =
-+ wl_registry_bind(xwl_screen->registry, id,
-+ &wp_linux_drm_syncobj_v1_interface,
-+ version);
- }
-
- /* no match */
-@@ -1120,7 +1444,7 @@ xwl_glamor_gbm_init_egl(struct xwl_screen *xwl_screen)
- struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen);
- EGLint major, minor;
- const GLubyte *renderer;
-- const char *gbm_backend_name;
-+ const char *gbm_backend_name, *egl_vendor;
-
- if (!xwl_gbm->fd_render_node && !xwl_gbm->drm_authenticated) {
- ErrorF("Failed to get wl_drm, disabling Glamor and DRI3\n");
-@@ -1181,6 +1505,22 @@ xwl_glamor_gbm_init_egl(struct xwl_screen *xwl_screen)
- if (gbm_backend_name && strcmp(gbm_backend_name, "drm") != 0)
- xwl_screen->glvnd_vendor = gbm_backend_name;
-
-+ egl_vendor = eglQueryString(xwl_screen->egl_display, EGL_VENDOR);
-+ /* NVIDIA driver does not support implicit sync */
-+ if (egl_vendor && strstr(egl_vendor, "NVIDIA"))
-+ xwl_screen->gbm_backend.backend_flags &=
-+ ~XWL_EGL_BACKEND_SUPPORTS_IMPLICIT_SYNC;
-+
-+ if (xwl_gbm_supports_syncobjs(xwl_screen) &&
-+ epoxy_has_egl_extension(xwl_screen->egl_display,
-+ "ANDROID_native_fence_sync"))
-+ xwl_screen->gbm_backend.backend_flags |=
-+ XWL_EGL_BACKEND_SUPPORTS_SYNCOBJS;
-+
-+ if (!xwl_glamor_supports_syncobjs(xwl_screen) ||
-+ !xwl_screen_init_explicit_sync(xwl_screen))
-+ xwl_screen_destroy_explicit_sync(xwl_screen);
-+
- return TRUE;
- error:
- if (xwl_screen->egl_display != EGL_NO_DISPLAY) {
-@@ -1198,6 +1538,11 @@ xwl_glamor_gbm_init_screen(struct xwl_screen *xwl_screen)
- {
- struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen);
-
-+ if (xwl_glamor_supports_syncobjs(xwl_screen)) {
-+ xwl_dri3_info.version = 4;
-+ xwl_dri3_info.import_syncobj = xwl_dri3_import_syncobj;
-+ }
-+
- if (!dri3_screen_init(xwl_screen->screen, &xwl_dri3_info)) {
- ErrorF("Failed to initialize dri3\n");
- goto error;
-@@ -1266,6 +1611,11 @@ xwl_glamor_init_gbm(struct xwl_screen *xwl_screen)
- xwl_screen->gbm_backend.get_main_device = xwl_gbm_get_main_device;
- xwl_screen->gbm_backend.is_available = TRUE;
- xwl_screen->gbm_backend.backend_flags = XWL_EGL_BACKEND_NEEDS_BUFFER_FLUSH |
-- XWL_EGL_BACKEND_NEEDS_N_BUFFERING;
-+ XWL_EGL_BACKEND_NEEDS_N_BUFFERING |
-+ /* may be overriden during EGL initialization */
-+ XWL_EGL_BACKEND_SUPPORTS_IMPLICIT_SYNC;
- xwl_screen->gbm_backend.create_pixmap_for_window = xwl_glamor_gbm_create_pixmap_for_window;
-+ xwl_screen->gbm_backend.dmabuf_export_sync_file = xwl_glamor_gbm_dmabuf_export_sync_file;
-+ xwl_screen->gbm_backend.dmabuf_import_sync_file = xwl_glamor_gbm_dmabuf_import_sync_file;
-+ xwl_screen->gbm_backend.dri3_syncobj_passthrough = xwl_glamor_gbm_dri3_syncobj_passthrough;
- }
-diff --git a/hw/xwayland/xwayland-glamor.c b/hw/xwayland/xwayland-glamor.c
-index c6aa8eb..b4e912c 100644
---- a/hw/xwayland/xwayland-glamor.c
-+++ b/hw/xwayland/xwayland-glamor.c
-@@ -1060,6 +1060,26 @@ xwl_glamor_needs_n_buffering(struct xwl_screen *xwl_screen)
- XWL_EGL_BACKEND_NEEDS_N_BUFFERING);
- }
-
-+Bool
-+xwl_glamor_supports_implicit_sync(struct xwl_screen *xwl_screen)
-+{
-+ if (!xwl_screen->glamor || !xwl_screen->egl_backend)
-+ return FALSE;
-+
-+ return xwl_screen->egl_backend->backend_flags &
-+ XWL_EGL_BACKEND_SUPPORTS_IMPLICIT_SYNC;
-+}
-+
-+Bool
-+xwl_glamor_supports_syncobjs(struct xwl_screen *xwl_screen)
-+{
-+ if (!xwl_screen->glamor || !xwl_screen->egl_backend)
-+ return FALSE;
-+
-+ return xwl_screen->egl_backend->backend_flags &
-+ XWL_EGL_BACKEND_SUPPORTS_SYNCOBJS;
-+}
-+
- PixmapPtr
- xwl_glamor_create_pixmap_for_window(struct xwl_window *xwl_window)
- {
-@@ -1074,6 +1094,94 @@ xwl_glamor_create_pixmap_for_window(struct xwl_window *xwl_window)
- return NullPixmap;
- }
-
-+int
-+xwl_glamor_get_fence(struct xwl_screen *xwl_screen)
-+{
-+ EGLint attribs[3];
-+ EGLSyncKHR sync;
-+ int fence_fd = -1;
-+
-+ if (!xwl_screen->glamor)
-+ return -1;
-+
-+ xwl_glamor_egl_make_current(xwl_screen);
-+
-+ attribs[0] = EGL_SYNC_NATIVE_FENCE_FD_ANDROID;
-+ attribs[1] = EGL_NO_NATIVE_FENCE_FD_ANDROID;
-+ attribs[2] = EGL_NONE;
-+ sync = eglCreateSyncKHR(xwl_screen->egl_display, EGL_SYNC_NATIVE_FENCE_ANDROID, attribs);
-+ if (sync != EGL_NO_SYNC_KHR) {
-+ fence_fd = eglDupNativeFenceFDANDROID(xwl_screen->egl_display, sync);
-+ eglDestroySyncKHR(xwl_screen->egl_display, sync);
-+ }
-+
-+ return fence_fd;
-+}
-+
-+void
-+xwl_glamor_wait_fence(struct xwl_screen *xwl_screen, int fence_fd)
-+{
-+ EGLint attribs[3];
-+ EGLSyncKHR sync;
-+
-+ if (!xwl_screen->glamor)
-+ return;
-+
-+ xwl_glamor_egl_make_current(xwl_screen);
-+
-+ attribs[0] = EGL_SYNC_NATIVE_FENCE_FD_ANDROID;
-+ attribs[1] = fence_fd;
-+ attribs[2] = EGL_NONE;
-+ sync = eglCreateSyncKHR(xwl_screen->egl_display, EGL_SYNC_NATIVE_FENCE_ANDROID, attribs);
-+ if (sync != EGL_NO_SYNC_KHR) {
-+ eglWaitSyncKHR(xwl_screen->egl_display, sync, 0);
-+ eglDestroySyncKHR(xwl_screen->egl_display, sync);
-+ }
-+}
-+
-+int
-+xwl_glamor_dmabuf_export_sync_file(PixmapPtr pixmap)
-+{
-+ ScreenPtr screen = pixmap->drawable.pScreen;
-+ struct xwl_screen *xwl_screen = xwl_screen_get(screen);
-+
-+ if (xwl_screen->glamor && xwl_screen->egl_backend &&
-+ xwl_screen->egl_backend->dmabuf_export_sync_file)
-+ return xwl_screen->egl_backend->dmabuf_export_sync_file(pixmap);
-+
-+ return -1;
-+}
-+
-+void
-+xwl_glamor_dmabuf_import_sync_file(PixmapPtr pixmap, int sync_file)
-+{
-+ ScreenPtr screen = pixmap->drawable.pScreen;
-+ struct xwl_screen *xwl_screen = xwl_screen_get(screen);
-+
-+ if (xwl_screen->glamor && xwl_screen->egl_backend &&
-+ xwl_screen->egl_backend->dmabuf_import_sync_file)
-+ xwl_screen->egl_backend->dmabuf_import_sync_file(pixmap, sync_file);
-+}
-+
-+void
-+xwl_glamor_dri3_syncobj_passthrough(WindowPtr window,
-+ struct dri3_syncobj *acquire_syncobj,
-+ struct dri3_syncobj *release_syncobj,
-+ uint64_t acquire_point,
-+ uint64_t release_point)
-+{
-+ ScreenPtr screen = window->drawable.pScreen;
-+ struct xwl_screen *xwl_screen = xwl_screen_get(screen);
-+
-+ if (xwl_screen->glamor && xwl_screen->egl_backend &&
-+ xwl_screen->egl_backend->dri3_syncobj_passthrough)
-+ xwl_screen->egl_backend->dri3_syncobj_passthrough(window,
-+ acquire_syncobj,
-+ release_syncobj,
-+ acquire_point,
-+ release_point);
-+}
-+
- void
- xwl_glamor_init_backends(struct xwl_screen *xwl_screen, Bool use_eglstream)
- {
-diff --git a/hw/xwayland/xwayland-glamor.h b/hw/xwayland/xwayland-glamor.h
-index 183fe75..d1a8982 100644
---- a/hw/xwayland/xwayland-glamor.h
-+++ b/hw/xwayland/xwayland-glamor.h
-@@ -34,11 +34,14 @@
- #include
-
- #include "xwayland-types.h"
-+#include "dri3.h"
-
- typedef enum _xwl_egl_backend_flags {
- XWL_EGL_BACKEND_NO_FLAG = 0,
- XWL_EGL_BACKEND_NEEDS_BUFFER_FLUSH = (1 << 0),
- XWL_EGL_BACKEND_NEEDS_N_BUFFERING = (1 << 1),
-+ XWL_EGL_BACKEND_SUPPORTS_IMPLICIT_SYNC = (1 << 2),
-+ XWL_EGL_BACKEND_SUPPORTS_SYNCOBJS = (1 << 3),
- } xwl_egl_backend_flags;
-
- struct xwl_egl_backend {
-@@ -107,6 +110,19 @@ struct xwl_egl_backend {
-
- /* Direct hook to create the backing pixmap for a window */
- PixmapPtr (*create_pixmap_for_window)(struct xwl_window *xwl_window);
-+
-+ /* Merge the implicit read fences of each plane into a sync file */
-+ int (*dmabuf_export_sync_file)(PixmapPtr pixmap);
-+
-+ /* Sets the implicit read fence of each plane to the given sync file */
-+ void (*dmabuf_import_sync_file)(PixmapPtr pixmap, int sync_file);
-+
-+ /* Sets the explicit sync acquire and release points for the given Window */
-+ void (*dri3_syncobj_passthrough)(WindowPtr window,
-+ struct dri3_syncobj *acquire_syncobj,
-+ struct dri3_syncobj *release_syncobj,
-+ uint64_t acquire_point,
-+ uint64_t release_point);
- };
-
- #ifdef XWL_HAS_GLAMOR
-@@ -135,6 +151,8 @@ Bool xwl_glamor_allow_commits(struct xwl_window *xwl_window);
- void xwl_glamor_egl_make_current(struct xwl_screen *xwl_screen);
- Bool xwl_glamor_needs_buffer_flush(struct xwl_screen *xwl_screen);
- Bool xwl_glamor_needs_n_buffering(struct xwl_screen *xwl_screen);
-+Bool xwl_glamor_supports_implicit_sync(struct xwl_screen *xwl_screen);
-+Bool xwl_glamor_supports_syncobjs(struct xwl_screen *xwl_screen);
- Bool xwl_glamor_is_modifier_supported(struct xwl_screen *xwl_screen,
- uint32_t format, uint64_t modifier);
- uint32_t wl_drm_format_for_depth(int depth);
-@@ -151,6 +169,15 @@ Bool xwl_glamor_get_drawable_modifiers(DrawablePtr drawable, uint32_t format,
- uint32_t *num_modifiers, uint64_t **modifiers);
- Bool xwl_glamor_check_flip(WindowPtr present_window, PixmapPtr pixmap);
- PixmapPtr xwl_glamor_create_pixmap_for_window (struct xwl_window *xwl_window);
-+int xwl_glamor_get_fence(struct xwl_screen *screen);
-+void xwl_glamor_wait_fence(struct xwl_screen *xwl_screen, int fence);
-+int xwl_glamor_dmabuf_export_sync_file(PixmapPtr pixmap);
-+void xwl_glamor_dmabuf_import_sync_file(PixmapPtr pixmap, int sync_file);
-+void xwl_glamor_dri3_syncobj_passthrough(WindowPtr window,
-+ struct dri3_syncobj *acquire_syncobj,
-+ struct dri3_syncobj *release_syncobj,
-+ uint64_t acquire_point,
-+ uint64_t release_point);
-
- #ifdef XV
- /* glamor Xv Adaptor */
-diff --git a/hw/xwayland/xwayland-present.c b/hw/xwayland/xwayland-present.c
-index 941be06..f611bb9 100644
---- a/hw/xwayland/xwayland-present.c
-+++ b/hw/xwayland/xwayland-present.c
-@@ -35,6 +35,7 @@
- #include "glamor.h"
-
- #include "tearing-control-v1-client-protocol.h"
-+#include "linux-drm-syncobj-v1-client-protocol.h"
-
- #define XWL_PRESENT_CAPS PresentCapabilityAsync | PresentCapabilityAsyncMayTear
-
-@@ -211,10 +212,18 @@ xwl_present_reset_timer(struct xwl_present_window *xwl_present_window)
- static void
- xwl_present_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc);
-
-+static int
-+xwl_present_queue_vblank(ScreenPtr screen,
-+ WindowPtr present_window,
-+ RRCrtcPtr crtc,
-+ uint64_t event_id,
-+ uint64_t msc);
-+
- static uint32_t
- xwl_present_query_capabilities(present_screen_priv_ptr screen_priv)
- {
-- return XWL_PRESENT_CAPS;
-+ struct xwl_screen *xwl_screen = xwl_screen_get(screen_priv->pScreen);
-+ return xwl_screen->present_capabilities;
- }
-
- static int
-@@ -233,6 +242,16 @@ xwl_present_get_ust_msc(ScreenPtr screen,
- return Success;
- }
-
-+static uint64_t
-+xwl_present_get_exec_msc(uint32_t options, uint64_t target_msc)
-+{
-+ /* Synchronous Xwayland presentations always complete (at least) one frame after they
-+ * are executed
-+ */
-+ return (options & PresentOptionAsyncMayTear) ?
-+ target_msc : target_msc - 1;
-+}
-+
- /*
- * When the wait fence or previous flip is completed, it's time
- * to re-try the request
-@@ -240,9 +259,27 @@ xwl_present_get_ust_msc(ScreenPtr screen,
- static void
- xwl_present_re_execute(present_vblank_ptr vblank)
- {
-+ struct xwl_present_event *event = xwl_present_event_from_vblank(vblank);
- uint64_t ust = 0, crtc_msc = 0;
-
- (void) xwl_present_get_ust_msc(vblank->screen, vblank->window, &ust, &crtc_msc);
-+ /* re-compute target / exec msc */
-+ vblank->target_msc = present_get_target_msc(0, crtc_msc,
-+ event->divisor,
-+ event->remainder,
-+ event->options);
-+ vblank->exec_msc = xwl_present_get_exec_msc(event->options,
-+ vblank->target_msc);
-+
-+ vblank->queued = TRUE;
-+ if (msc_is_after(vblank->exec_msc, crtc_msc) &&
-+ xwl_present_queue_vblank(vblank->screen, vblank->window,
-+ vblank->crtc,
-+ vblank->event_id,
-+ vblank->exec_msc) == Success) {
-+ return;
-+ }
-+
- xwl_present_execute(vblank, ust, crtc_msc);
- }
-
-@@ -281,6 +318,10 @@ xwl_present_free_event(struct xwl_present_event *event)
- static void
- xwl_present_free_idle_vblank(present_vblank_ptr vblank)
- {
-+ if (vblank->release_syncobj)
-+ vblank->release_syncobj->signal(vblank->release_syncobj,
-+ vblank->release_point);
-+
- present_pixmap_idle(vblank->pixmap, vblank->window, vblank->serial, vblank->idle_fence);
- xwl_present_free_event(xwl_present_event_from_vblank(vblank));
- }
-@@ -435,6 +476,7 @@ static void
- xwl_present_buffer_release(void *data)
- {
- struct xwl_present_window *xwl_present_window;
-+ struct xwl_screen *xwl_screen;
- struct xwl_present_event *event = data;
- present_vblank_ptr vblank;
-
-@@ -442,6 +484,16 @@ xwl_present_buffer_release(void *data)
- return;
-
- vblank = &event->vblank;
-+
-+ xwl_screen = xwl_screen_get(vblank->screen);
-+ if (vblank->release_syncobj && !xwl_screen->explicit_sync) {
-+ /* transfer implicit fence to release syncobj */
-+ int fence_fd = xwl_glamor_dmabuf_export_sync_file(vblank->pixmap);
-+ vblank->release_syncobj->import_fence(vblank->release_syncobj,
-+ vblank->release_point,
-+ fence_fd);
-+ }
-+
- present_pixmap_idle(vblank->pixmap, vblank->window, vblank->serial, vblank->idle_fence);
-
- xwl_present_window = xwl_present_window_priv(vblank->window);
-@@ -632,6 +684,15 @@ xwl_present_maybe_set_reason(struct xwl_window *xwl_window, PresentFlipReason *r
- }
- }
-
-+static int
-+xwl_present_flush_fenced(WindowPtr window)
-+{
-+ struct xwl_window *xwl_window = xwl_window_from_window(window);
-+ int fence = xwl_glamor_get_fence(xwl_window->xwl_screen);
-+ xwl_present_flush(window);
-+ return fence;
-+}
-+
- static Bool
- xwl_present_check_flip(RRCrtcPtr crtc,
- WindowPtr present_window,
-@@ -645,6 +706,7 @@ xwl_present_check_flip(RRCrtcPtr crtc,
- WindowPtr toplvl_window = xwl_present_toplvl_pixmap_window(present_window);
- struct xwl_window *xwl_window = xwl_window_from_window(present_window);
- ScreenPtr screen = pixmap->drawable.pScreen;
-+ struct xwl_screen *xwl_screen = xwl_screen_get(screen);
-
- if (reason)
- *reason = PRESENT_FLIP_REASON_UNKNOWN;
-@@ -681,6 +743,13 @@ xwl_present_check_flip(RRCrtcPtr crtc,
- if (!xwl_glamor_check_flip(present_window, pixmap))
- return FALSE;
-
-+ /* If glamor doesn't support implicit sync and the compositor doesn't
-+ * support explicit sync, we cannot flip
-+ */
-+ if (!xwl_glamor_supports_implicit_sync(xwl_screen) &&
-+ !xwl_screen->explicit_sync)
-+ return FALSE;
-+
- /* Can't flip if the window pixmap doesn't match the xwl_window parent
- * window's, e.g. because a client redirected this window or one of its
- * parents.
-@@ -759,6 +828,7 @@ xwl_present_flip(present_vblank_ptr vblank, RegionPtr damage)
- PixmapPtr pixmap = vblank->pixmap;
- struct xwl_window *xwl_window = xwl_window_from_window(present_window);
- struct xwl_present_window *xwl_present_window = xwl_present_window_priv(present_window);
-+ struct xwl_screen *xwl_screen = xwl_window->xwl_screen;
- BoxPtr damage_box;
- struct wl_buffer *buffer;
- struct xwl_present_event *event = xwl_present_event_from_vblank(vblank);
-@@ -778,6 +848,28 @@ xwl_present_flip(present_vblank_ptr vblank, RegionPtr damage)
-
- event->pixmap = pixmap;
-
-+ assert(xwl_glamor_supports_implicit_sync(xwl_screen) ||
-+ xwl_screen->explicit_sync);
-+
-+ if (vblank->acquire_syncobj && vblank->release_syncobj) {
-+ if (xwl_screen->explicit_sync)
-+ xwl_glamor_dri3_syncobj_passthrough(present_window,
-+ vblank->acquire_syncobj,
-+ vblank->release_syncobj,
-+ vblank->acquire_point,
-+ vblank->release_point);
-+ else {
-+ /* transfer from acquire syncobj to implicit fence */
-+ int fence_fd =
-+ vblank->acquire_syncobj->export_fence(vblank->acquire_syncobj,
-+ vblank->acquire_point);
-+ xwl_glamor_dmabuf_import_sync_file(vblank->pixmap, fence_fd);
-+ }
-+ } else if (xwl_window->surface_sync) {
-+ wp_linux_drm_syncobj_surface_v1_destroy(xwl_window->surface_sync);
-+ xwl_window->surface_sync = NULL;
-+ }
-+
- xwl_pixmap_set_buffer_release_cb(pixmap, xwl_present_buffer_release, event);
-
- /* We can flip directly to the main surface (full screen window without clips) */
-@@ -799,7 +891,7 @@ xwl_present_flip(present_vblank_ptr vblank, RegionPtr damage)
-
- if (xwl_window->tearing_control) {
- uint32_t hint;
-- if (event->async_may_tear)
-+ if (event->options & PresentOptionAsyncMayTear)
- hint = WP_TEARING_CONTROL_V1_PRESENTATION_HINT_ASYNC;
- else
- hint = WP_TEARING_CONTROL_V1_PRESENTATION_HINT_VSYNC;
-@@ -840,6 +932,7 @@ xwl_present_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
-
- xorg_list_del(&vblank->event_queue);
-
-+retry:
- if (present_execute_wait(vblank, crtc_msc))
- return;
-
-@@ -900,6 +993,8 @@ xwl_present_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
- }
-
- vblank->flip = FALSE;
-+ /* re-execute, falling through to copy */
-+ goto retry;
- }
- DebugPresent(("\tc %p %" PRIu64 ": %08" PRIx32 " -> %08" PRIx32 "\n",
- vblank, crtc_msc, vblank->pixmap->drawable.id, vblank->window->drawable.id));
-@@ -936,6 +1031,10 @@ xwl_present_pixmap(WindowPtr window,
- RRCrtcPtr target_crtc,
- SyncFence *wait_fence,
- SyncFence *idle_fence,
-+ struct dri3_syncobj *acquire_syncobj,
-+ struct dri3_syncobj *release_syncobj,
-+ uint64_t acquire_point,
-+ uint64_t release_point,
- uint32_t options,
- uint64_t target_window_msc,
- uint64_t divisor,
-@@ -952,11 +1051,17 @@ xwl_present_pixmap(WindowPtr window,
- ScreenPtr screen = window->drawable.pScreen;
- present_window_priv_ptr window_priv = present_get_window_priv(window, TRUE);
- present_screen_priv_ptr screen_priv = present_screen_priv(screen);
-+ struct xwl_screen *xwl_screen = xwl_screen_get(screen_priv->pScreen);
-+ uint32_t caps = xwl_screen->present_capabilities;
- struct xwl_present_event *event;
-
- if (!window_priv)
- return BadAlloc;
-
-+ if (!(caps & PresentCapabilitySyncobj) &&
-+ (acquire_syncobj || release_syncobj))
-+ return BadValue;
-+
- target_crtc = xwl_present_get_crtc(screen_priv, window);
-
- ret = xwl_present_get_ust_msc(screen, window, &ust, &crtc_msc);
-@@ -991,6 +1096,10 @@ xwl_present_pixmap(WindowPtr window,
- if (vblank->target_msc != target_msc)
- continue;
-
-+ if (vblank->release_syncobj)
-+ vblank->release_syncobj->signal(vblank->release_syncobj,
-+ vblank->release_point);
-+
- present_vblank_scrap(vblank);
- if (vblank->flip_ready)
- xwl_present_re_execute(vblank);
-@@ -1003,22 +1112,18 @@ xwl_present_pixmap(WindowPtr window,
-
- vblank = &event->vblank;
- if (!present_vblank_init(vblank, window, pixmap, serial, valid, update, x_off, y_off,
-- target_crtc, wait_fence, idle_fence, options, XWL_PRESENT_CAPS,
-- notifies, num_notifies, target_msc, crtc_msc)) {
-+ target_crtc, wait_fence, idle_fence,
-+ acquire_syncobj, release_syncobj, acquire_point, release_point,
-+ options, caps, notifies, num_notifies, target_msc, crtc_msc)) {
- present_vblank_destroy(vblank);
- return BadAlloc;
- }
-
- vblank->event_id = ++xwl_present_event_id;
-- event->async_may_tear = options & PresentOptionAsyncMayTear;
--
-- /* Synchronous Xwayland presentations always complete (at least) one frame after they
-- * are executed
-- */
-- if (event->async_may_tear)
-- vblank->exec_msc = vblank->target_msc;
-- else
-- vblank->exec_msc = vblank->target_msc - 1;
-+ event->options = options;
-+ event->divisor = divisor;
-+ event->remainder = remainder;
-+ vblank->exec_msc = xwl_present_get_exec_msc(options, vblank->target_msc);
-
- vblank->queued = TRUE;
- if (crtc_msc < vblank->exec_msc) {
-@@ -1067,6 +1172,10 @@ xwl_present_init(ScreenPtr screen)
- if (!dixRegisterPrivateKey(&xwl_present_window_private_key, PRIVATE_WINDOW, 0))
- return FALSE;
-
-+ xwl_screen->present_capabilities = XWL_PRESENT_CAPS;
-+ if (xwl_glamor_supports_syncobjs(xwl_screen))
-+ xwl_screen->present_capabilities |= PresentCapabilitySyncobj;
-+
- screen_priv->query_capabilities = xwl_present_query_capabilities;
- screen_priv->get_crtc = xwl_present_get_crtc;
-
-@@ -1077,6 +1186,7 @@ xwl_present_init(ScreenPtr screen)
- screen_priv->present_pixmap = xwl_present_pixmap;
- screen_priv->queue_vblank = xwl_present_queue_vblank;
- screen_priv->flush = xwl_present_flush;
-+ screen_priv->flush_fenced = xwl_present_flush_fenced;
- screen_priv->re_execute = xwl_present_re_execute;
-
- screen_priv->abort_vblank = xwl_present_abort_vblank;
-diff --git a/hw/xwayland/xwayland-present.h b/hw/xwayland/xwayland-present.h
-index 4fd1e57..ffc16f5 100644
---- a/hw/xwayland/xwayland-present.h
-+++ b/hw/xwayland/xwayland-present.h
-@@ -59,7 +59,9 @@ struct xwl_present_event {
- present_vblank_rec vblank;
-
- PixmapPtr pixmap;
-- Bool async_may_tear;
-+ uint32_t options;
-+ uint64_t divisor;
-+ uint64_t remainder;
- };
-
- Bool xwl_present_entered_for_each_frame_callback(void);
-diff --git a/hw/xwayland/xwayland-screen.c b/hw/xwayland/xwayland-screen.c
-index cc14e07..e4c2127 100644
---- a/hw/xwayland/xwayland-screen.c
-+++ b/hw/xwayland/xwayland-screen.c
-@@ -64,6 +64,7 @@
- #include "xdg-shell-client-protocol.h"
- #include "xwayland-shell-v1-client-protocol.h"
- #include "tearing-control-v1-client-protocol.h"
-+#include "linux-drm-syncobj-v1-client-protocol.h"
-
- static DevPrivateKeyRec xwl_screen_private_key;
- static DevPrivateKeyRec xwl_client_private_key;
-diff --git a/hw/xwayland/xwayland-screen.h b/hw/xwayland/xwayland-screen.h
-index bd66dd6..fce3510 100644
---- a/hw/xwayland/xwayland-screen.h
-+++ b/hw/xwayland/xwayland-screen.h
-@@ -111,6 +111,7 @@ struct xwl_screen {
- struct wp_viewporter *viewporter;
- struct xwayland_shell_v1 *xwayland_shell;
- struct wp_tearing_control_manager_v1 *tearing_control_manager;
-+ struct wp_linux_drm_syncobj_v1 *explicit_sync;
- struct xorg_list drm_lease_devices;
- struct xorg_list queued_drm_lease_devices;
- struct xorg_list drm_leases;
-@@ -145,6 +146,14 @@ struct xwl_screen {
- int libdecor_fd;
- struct libdecor *libdecor_context;
- #endif
-+
-+ uint32_t present_capabilities;
-+
-+ /* For use with explicit sync */
-+ struct dri3_syncobj *glamor_syncobj;
-+ struct dri3_syncobj *server_syncobj;
-+ uint64_t glamor_timeline_point;
-+ uint64_t server_timeline_point;
- };
-
- /* Apps which use randr/vidmode to change the mode when going fullscreen,
-diff --git a/hw/xwayland/xwayland-window-buffers.c b/hw/xwayland/xwayland-window-buffers.c
-index f7bb571..0b7cb5d 100644
---- a/hw/xwayland/xwayland-window-buffers.c
-+++ b/hw/xwayland/xwayland-window-buffers.c
-@@ -32,6 +32,13 @@
- #include "xwayland-pixmap.h"
- #include "xwayland-screen.h"
- #include "xwayland-window-buffers.h"
-+#include "dri3.h"
-+#ifdef XWL_HAS_GLAMOR
-+#include "glamor.h"
-+#endif
-+
-+#include
-+#include
-
- #define BUFFER_TIMEOUT 1 * 1000 /* ms */
-
-@@ -40,6 +47,8 @@ struct xwl_window_buffer {
- PixmapPtr pixmap;
- RegionPtr damage_region;
- Bool recycle_on_release;
-+ uint64_t release_point;
-+ int sync_fd;
- int refcnt;
- uint32_t time;
- struct xorg_list link_buffer;
-@@ -80,6 +89,7 @@ xwl_window_buffer_new(struct xwl_window *xwl_window)
- xwl_window_buffer->xwl_window = xwl_window;
- xwl_window_buffer->damage_region = RegionCreate(NullBox, 1);
- xwl_window_buffer->pixmap = NullPixmap;
-+ xwl_window_buffer->sync_fd = -1;
- xwl_window_buffer->refcnt = 1;
-
- xorg_list_append(&xwl_window_buffer->link_buffer,
-@@ -111,6 +121,9 @@ xwl_window_buffer_dispose(struct xwl_window_buffer *xwl_window_buffer)
- if (xwl_window_buffer->pixmap)
- xwl_window_buffer_destroy_pixmap (xwl_window_buffer);
-
-+ if (xwl_window_buffer->sync_fd >= 0)
-+ close(xwl_window_buffer->sync_fd);
-+
- xorg_list_del(&xwl_window_buffer->link_buffer);
- free(xwl_window_buffer);
-
-@@ -194,6 +207,7 @@ xwl_window_buffer_release_callback(void *data)
- {
- struct xwl_window_buffer *xwl_window_buffer = data;
- struct xwl_window *xwl_window = xwl_window_buffer->xwl_window;
-+ struct xwl_screen *xwl_screen = xwl_window->xwl_screen;
- struct xwl_window_buffer *oldest_available_buffer;
-
- /* Drop the reference on the buffer we took in get_pixmap. If that
-@@ -221,6 +235,14 @@ xwl_window_buffer_release_callback(void *data)
- struct xwl_window_buffer,
- link_buffer);
-
-+ if (xwl_window_buffer->release_point) {
-+ /* We will wait for this fence before re-using the buffer */
-+ xwl_window_buffer->sync_fd =
-+ xwl_screen->server_syncobj->export_fence(xwl_screen->server_syncobj,
-+ xwl_window_buffer->release_point);
-+ xwl_window_buffer->release_point = 0;
-+ }
-+
- /* Schedule next timer based on time of the oldest buffer */
- xwl_window->window_buffers_timer =
- TimerSet(xwl_window->window_buffers_timer,
-@@ -289,6 +311,34 @@ xwl_window_buffers_dispose(struct xwl_window *xwl_window)
- }
- }
-
-+static void
-+xwl_window_buffers_set_syncpts(struct xwl_window_buffer *xwl_window_buffer)
-+{
-+ struct xwl_window *xwl_window = xwl_window_buffer->xwl_window;
-+ struct xwl_screen *xwl_screen = xwl_window->xwl_screen;
-+ uint64_t acquire_point = xwl_screen->glamor_timeline_point++;
-+ uint64_t release_point = xwl_screen->server_timeline_point++;
-+
-+ int fence_fd = xwl_glamor_get_fence(xwl_screen);
-+ if (fence_fd >= 0) {
-+ xwl_screen->glamor_syncobj->import_fence(xwl_screen->glamor_syncobj,
-+ acquire_point, fence_fd);
-+ } else {
-+#ifdef XWL_HAS_GLAMOR
-+ glamor_finish(xwl_screen->screen);
-+#endif /* XWL_HAS_GLAMOR */
-+ xwl_screen->glamor_syncobj->signal(xwl_screen->glamor_syncobj,
-+ acquire_point);
-+ }
-+
-+ xwl_window_buffer->release_point = release_point;
-+ xwl_glamor_dri3_syncobj_passthrough(xwl_window->window,
-+ xwl_screen->glamor_syncobj,
-+ xwl_screen->server_syncobj,
-+ acquire_point,
-+ release_point);
-+}
-+
- PixmapPtr
- xwl_window_buffers_get_pixmap(struct xwl_window *xwl_window,
- RegionPtr damage_region)
-@@ -313,6 +363,14 @@ xwl_window_buffers_get_pixmap(struct xwl_window *xwl_window,
-
- full_damage = xwl_window_buffer->damage_region;
-
-+#ifdef XWL_HAS_GLAMOR
-+ if (xwl_window_buffer->sync_fd >= 0) {
-+ xwl_glamor_wait_fence(xwl_screen, xwl_window_buffer->sync_fd);
-+ close(xwl_window_buffer->sync_fd);
-+ xwl_window_buffer->sync_fd = -1;
-+ }
-+#endif /* XWL_HAS_GLAMOR */
-+
- if (xwl_window_buffer->pixmap) {
- BoxPtr pBox = RegionRects(full_damage);
- int nBox = RegionNumRects(full_damage);
-@@ -359,6 +417,16 @@ xwl_window_buffers_get_pixmap(struct xwl_window *xwl_window,
-
- /* Hold a reference on the buffer until it's released by the compositor */
- xwl_window_buffer->refcnt++;
-+
-+#ifdef XWL_HAS_GLAMOR
-+ if (!xwl_glamor_supports_implicit_sync(xwl_screen)) {
-+ if (xwl_screen->explicit_sync)
-+ xwl_window_buffers_set_syncpts(xwl_window_buffer);
-+ else
-+ glamor_finish(xwl_screen->screen);
-+ }
-+#endif /* XWL_HAS_GLAMOR */
-+
- xwl_pixmap_set_buffer_release_cb(xwl_window_buffer->pixmap,
- xwl_window_buffer_release_callback,
- xwl_window_buffer);
-diff --git a/hw/xwayland/xwayland-window.c b/hw/xwayland/xwayland-window.c
-index a4f02a0..070d40d 100644
---- a/hw/xwayland/xwayland-window.c
-+++ b/hw/xwayland/xwayland-window.c
-@@ -50,6 +50,7 @@
- #include "viewporter-client-protocol.h"
- #include "xdg-shell-client-protocol.h"
- #include "xwayland-shell-v1-client-protocol.h"
-+#include "linux-drm-syncobj-v1-client-protocol.h"
-
- #define DELAYED_WL_SURFACE_DESTROY 1000 /* ms */
-
-@@ -1159,6 +1160,9 @@ xwl_unrealize_window(WindowPtr window)
- if (xwl_window->tearing_control)
- wp_tearing_control_v1_destroy(xwl_window->tearing_control);
-
-+ if (xwl_window->surface_sync)
-+ wp_linux_drm_syncobj_surface_v1_destroy(xwl_window->surface_sync);
-+
- release_wl_surface_for_window(xwl_window);
- xorg_list_del(&xwl_window->link_damage);
- xorg_list_del(&xwl_window->link_window);
-@@ -1364,6 +1368,13 @@ xwl_window_attach_buffer(struct xwl_window *xwl_window)
- pixmap = xwl_window_buffers_get_pixmap(xwl_window, region);
-
- #ifdef XWL_HAS_GLAMOR
-+ if (xwl_glamor_supports_implicit_sync(xwl_screen) &&
-+ xwl_window->surface_sync) {
-+ /* prefer implicit sync when possible */
-+ wp_linux_drm_syncobj_surface_v1_destroy(xwl_window->surface_sync);
-+ xwl_window->surface_sync = NULL;
-+ }
-+
- if (xwl_screen->glamor)
- buffer = xwl_glamor_pixmap_get_wl_buffer(pixmap);
- else
-diff --git a/hw/xwayland/xwayland-window.h b/hw/xwayland/xwayland-window.h
-index 45ae16d..51ce91b 100644
---- a/hw/xwayland/xwayland-window.h
-+++ b/hw/xwayland/xwayland-window.h
-@@ -122,6 +122,7 @@ struct xwl_window {
- /* If TRUE, the window buffer format supports scanout with implicit modifier */
- Bool has_implicit_scanout_support;
- struct wp_tearing_control_v1 *tearing_control;
-+ struct wp_linux_drm_syncobj_surface_v1 *surface_sync;
- };
-
- struct xwl_window *xwl_window_get(WindowPtr window);
-diff --git a/include/protocol-versions.h b/include/protocol-versions.h
-index d7bfc6d..e28e238 100644
---- a/include/protocol-versions.h
-+++ b/include/protocol-versions.h
-@@ -48,7 +48,7 @@
-
- /* DRI3 */
- #define SERVER_DRI3_MAJOR_VERSION 1
--#define SERVER_DRI3_MINOR_VERSION 2
-+#define SERVER_DRI3_MINOR_VERSION 4
-
- /* DMX */
- #define SERVER_DMX_MAJOR_VERSION 2
-@@ -69,7 +69,7 @@
-
- /* Present */
- #define SERVER_PRESENT_MAJOR_VERSION 1
--#define SERVER_PRESENT_MINOR_VERSION 2
-+#define SERVER_PRESENT_MINOR_VERSION 4
-
- /* RandR */
- #define SERVER_RANDR_MAJOR_VERSION 1
-diff --git a/present/present.c b/present/present.c
-index 2118683..e0764fa 100644
---- a/present/present.c
-+++ b/present/present.c
-@@ -230,6 +230,10 @@ present_pixmap(WindowPtr window,
- RRCrtcPtr target_crtc,
- SyncFence *wait_fence,
- SyncFence *idle_fence,
-+ struct dri3_syncobj *acquire_syncobj,
-+ struct dri3_syncobj *release_syncobj,
-+ uint64_t acquire_point,
-+ uint64_t release_point,
- uint32_t options,
- uint64_t window_msc,
- uint64_t divisor,
-@@ -250,6 +254,10 @@ present_pixmap(WindowPtr window,
- target_crtc,
- wait_fence,
- idle_fence,
-+ acquire_syncobj,
-+ release_syncobj,
-+ acquire_point,
-+ release_point,
- options,
- window_msc,
- divisor,
-@@ -272,6 +280,7 @@ present_notify_msc(WindowPtr window,
- 0, 0,
- NULL,
- NULL, NULL,
-+ NULL, NULL, 0, 0,
- divisor == 0 ? PresentOptionAsync : 0,
- target_msc, divisor, remainder, NULL, 0);
- }
-diff --git a/present/present_execute.c b/present/present_execute.c
-index 68a5878..6d8ac29 100644
---- a/present/present_execute.c
-+++ b/present/present_execute.c
-@@ -21,6 +21,7 @@
- */
-
- #include "present_priv.h"
-+#include
-
- /*
- * Called when the wait fence is triggered; just gets the current msc/ust and
-@@ -37,6 +38,21 @@ present_wait_fence_triggered(void *param)
- screen_priv->re_execute(vblank);
- }
-
-+static void present_syncobj_triggered(int fd, int xevents, void *data)
-+{
-+ present_vblank_ptr vblank = data;
-+ ScreenPtr screen = vblank->screen;
-+ present_screen_priv_ptr screen_priv = present_screen_priv(screen);
-+ uint64_t efd_value;
-+
-+ read(fd, &efd_value, sizeof (efd_value));
-+ SetNotifyFd(fd, NULL, 0, NULL);
-+ close(fd);
-+ vblank->efd = -1;
-+
-+ screen_priv->re_execute(vblank);
-+}
-+
- Bool
- present_execute_wait(present_vblank_ptr vblank, uint64_t crtc_msc)
- {
-@@ -58,6 +74,19 @@ present_execute_wait(present_vblank_ptr vblank, uint64_t crtc_msc)
- return TRUE;
- }
- }
-+
-+ /* Defer execution of explicitly synchronized copies.
-+ * Flip synchronization is managed by the driver.
-+ */
-+ if (!vblank->flip && vblank->acquire_syncobj &&
-+ !vblank->acquire_syncobj->check(vblank->acquire_syncobj, vblank->acquire_point)) {
-+ vblank->efd = eventfd(0, EFD_CLOEXEC);
-+ SetNotifyFd(vblank->efd, present_syncobj_triggered, X_NOTIFY_READ, vblank);
-+ vblank->acquire_syncobj->eventfd(vblank->acquire_syncobj, vblank->acquire_point,
-+ vblank->efd, FALSE /* wait_avail */);
-+ return TRUE;
-+ }
-+
- return FALSE;
- }
-
-@@ -85,7 +114,13 @@ present_execute_copy(present_vblank_ptr vblank, uint64_t crtc_msc)
- * which is then freed, freeing the region
- */
- vblank->update = NULL;
-- screen_priv->flush(window);
-+ if (vblank->release_syncobj) {
-+ int fence_fd = screen_priv->flush_fenced(window);
-+ vblank->release_syncobj->import_fence(vblank->release_syncobj,
-+ vblank->release_point, fence_fd);
-+ } else {
-+ screen_priv->flush(window);
-+ }
-
- present_pixmap_idle(vblank->pixmap, vblank->window, vblank->serial, vblank->idle_fence);
- }
-diff --git a/present/present_priv.h b/present/present_priv.h
-index 4ad7298..727d523 100644
---- a/present/present_priv.h
-+++ b/present/present_priv.h
-@@ -36,6 +36,7 @@
- #include
- #include
- #include
-+#include "dri3.h"
-
- #if 0
- #define DebugPresent(x) ErrorF x
-@@ -90,6 +91,11 @@ struct present_vblank {
- Bool abort_flip; /* aborting this flip */
- PresentFlipReason reason; /* reason for which flip is not possible */
- Bool has_suboptimal; /* whether client can support SuboptimalCopy mode */
-+ struct dri3_syncobj *acquire_syncobj;
-+ struct dri3_syncobj *release_syncobj;
-+ uint64_t acquire_point;
-+ uint64_t release_point;
-+ int efd;
- };
-
- typedef struct present_screen_priv present_screen_priv_rec, *present_screen_priv_ptr;
-@@ -124,6 +130,10 @@ typedef int (*present_priv_pixmap_ptr)(WindowPtr window,
- RRCrtcPtr target_crtc,
- SyncFence *wait_fence,
- SyncFence *idle_fence,
-+ struct dri3_syncobj *acquire_syncobj,
-+ struct dri3_syncobj *release_syncobj,
-+ uint64_t acquire_point,
-+ uint64_t release_point,
- uint32_t options,
- uint64_t window_msc,
- uint64_t divisor,
-@@ -137,6 +147,7 @@ typedef int (*present_priv_queue_vblank_ptr)(ScreenPtr screen,
- uint64_t event_id,
- uint64_t msc);
- typedef void (*present_priv_flush_ptr)(WindowPtr window);
-+typedef int (*present_priv_flush_fenced_ptr)(WindowPtr window);
- typedef void (*present_priv_re_execute_ptr)(present_vblank_ptr vblank);
-
- typedef void (*present_priv_abort_vblank_ptr)(ScreenPtr screen,
-@@ -147,6 +158,7 @@ typedef void (*present_priv_abort_vblank_ptr)(ScreenPtr screen,
- typedef void (*present_priv_flip_destroy_ptr)(ScreenPtr screen);
-
- struct present_screen_priv {
-+ ScreenPtr pScreen;
- CloseScreenProcPtr CloseScreen;
- ConfigNotifyProcPtr ConfigNotify;
- DestroyWindowProcPtr DestroyWindow;
-@@ -180,6 +192,7 @@ struct present_screen_priv {
-
- present_priv_queue_vblank_ptr queue_vblank;
- present_priv_flush_ptr flush;
-+ present_priv_flush_fenced_ptr flush_fenced;
- present_priv_re_execute_ptr re_execute;
-
- present_priv_abort_vblank_ptr abort_vblank;
-@@ -290,6 +303,10 @@ present_pixmap(WindowPtr window,
- RRCrtcPtr target_crtc,
- SyncFence *wait_fence,
- SyncFence *idle_fence,
-+ struct dri3_syncobj *acquire_syncobj,
-+ struct dri3_syncobj *release_syncobj,
-+ uint64_t acquire_point,
-+ uint64_t release_point,
- uint32_t options,
- uint64_t target_msc,
- uint64_t divisor,
-@@ -464,6 +481,10 @@ present_vblank_init(present_vblank_ptr vblank,
- RRCrtcPtr target_crtc,
- SyncFence *wait_fence,
- SyncFence *idle_fence,
-+ struct dri3_syncobj *acquire_syncobj,
-+ struct dri3_syncobj *release_syncobj,
-+ uint64_t acquire_point,
-+ uint64_t release_point,
- uint32_t options,
- const uint32_t capabilities,
- present_notify_ptr notifies,
-@@ -482,6 +503,10 @@ present_vblank_create(WindowPtr window,
- RRCrtcPtr target_crtc,
- SyncFence *wait_fence,
- SyncFence *idle_fence,
-+ struct dri3_syncobj *acquire_syncobj,
-+ struct dri3_syncobj *release_syncobj,
-+ uint64_t acquire_point,
-+ uint64_t release_point,
- uint32_t options,
- const uint32_t capabilities,
- present_notify_ptr notifies,
-diff --git a/present/present_request.c b/present/present_request.c
-index f3e5679..1f4f8a4 100644
---- a/present/present_request.c
-+++ b/present/present_request.c
-@@ -79,79 +79,121 @@ proc_present_query_version(ClientPtr client)
- } while (0)
-
- static int
--proc_present_pixmap(ClientPtr client)
-+proc_present_pixmap_common(ClientPtr client,
-+ Window req_window,
-+ Pixmap req_pixmap,
-+ CARD32 req_serial,
-+ CARD32 req_valid,
-+ CARD32 req_update,
-+ INT16 req_x_off,
-+ INT16 req_y_off,
-+ CARD32 req_target_crtc,
-+ XSyncFence req_wait_fence,
-+ XSyncFence req_idle_fence,
-+ struct dri3_syncobj *acquire_syncobj,
-+ struct dri3_syncobj *release_syncobj,
-+ CARD64 req_acquire_point,
-+ CARD64 req_release_point,
-+ CARD32 req_options,
-+ CARD64 req_target_msc,
-+ CARD64 req_divisor,
-+ CARD64 req_remainder,
-+ size_t base_req_size,
-+ xPresentNotify *req_notifies)
- {
-- REQUEST(xPresentPixmapReq);
-- WindowPtr window;
-- PixmapPtr pixmap;
-- RegionPtr valid = NULL;
-- RegionPtr update = NULL;
-- SyncFence *wait_fence;
-- SyncFence *idle_fence;
-- RRCrtcPtr target_crtc;
-- int ret;
-- int nnotifies;
-- present_notify_ptr notifies = NULL;
--
-- REQUEST_AT_LEAST_SIZE(xPresentPixmapReq);
-- ret = dixLookupWindow(&window, stuff->window, client, DixWriteAccess);
-+ WindowPtr window;
-+ PixmapPtr pixmap;
-+ RegionPtr valid = NULL;
-+ RegionPtr update = NULL;
-+ RRCrtcPtr target_crtc;
-+ SyncFence *wait_fence;
-+ SyncFence *idle_fence;
-+ int nnotifies;
-+ present_notify_ptr notifies = NULL;
-+ int ret;
-+
-+ ret = dixLookupWindow(&window, req_window, client, DixWriteAccess);
- if (ret != Success)
- return ret;
-- ret = dixLookupResourceByType((void **) &pixmap, stuff->pixmap, RT_PIXMAP, client, DixReadAccess);
-+ ret = dixLookupResourceByType((void **) &pixmap, req_pixmap, RT_PIXMAP, client, DixReadAccess);
- if (ret != Success)
- return ret;
-
- if (window->drawable.depth != pixmap->drawable.depth)
- return BadMatch;
-
-- VERIFY_REGION_OR_NONE(valid, stuff->valid, client, DixReadAccess);
-- VERIFY_REGION_OR_NONE(update, stuff->update, client, DixReadAccess);
-+ VERIFY_REGION_OR_NONE(valid, req_valid, client, DixReadAccess);
-+ VERIFY_REGION_OR_NONE(update, req_update, client, DixReadAccess);
-+
-+ VERIFY_CRTC_OR_NONE(target_crtc, req_target_crtc, client, DixReadAccess);
-
-- VERIFY_CRTC_OR_NONE(target_crtc, stuff->target_crtc, client, DixReadAccess);
-+ VERIFY_FENCE_OR_NONE(wait_fence, req_wait_fence, client, DixReadAccess);
-+ VERIFY_FENCE_OR_NONE(idle_fence, req_idle_fence, client, DixWriteAccess);
-
-- VERIFY_FENCE_OR_NONE(wait_fence, stuff->wait_fence, client, DixReadAccess);
-- VERIFY_FENCE_OR_NONE(idle_fence, stuff->idle_fence, client, DixWriteAccess);
-+ if ((acquire_syncobj && req_acquire_point == 0) ||
-+ (release_syncobj && req_release_point == 0))
-+ return BadValue;
-
-- if (stuff->options & ~(PresentAllOptions)) {
-- client->errorValue = stuff->options;
-+ if (req_options & ~(PresentAllOptions)) {
-+ client->errorValue = req_options;
- return BadValue;
- }
-
- /*
- * Check to see if remainder is sane
- */
-- if (stuff->divisor == 0) {
-- if (stuff->remainder != 0) {
-- client->errorValue = (CARD32) stuff->remainder;
-+ if (req_divisor == 0) {
-+ if (req_remainder != 0) {
-+ client->errorValue = (CARD32)req_remainder;
- return BadValue;
- }
- } else {
-- if (stuff->remainder >= stuff->divisor) {
-- client->errorValue = (CARD32) stuff->remainder;
-+ if (req_remainder >= req_divisor) {
-+ client->errorValue = (CARD32)req_remainder;
- return BadValue;
- }
- }
-
-- nnotifies = (client->req_len << 2) - sizeof (xPresentPixmapReq);
-+ nnotifies = (client->req_len << 2) - base_req_size;
- if (nnotifies % sizeof (xPresentNotify))
- return BadLength;
-
- nnotifies /= sizeof (xPresentNotify);
- if (nnotifies) {
-- ret = present_create_notifies(client, nnotifies, (xPresentNotify *) (stuff + 1), ¬ifies);
-+ ret = present_create_notifies(client, nnotifies, req_notifies, ¬ifies);
- if (ret != Success)
- return ret;
- }
-
-- ret = present_pixmap(window, pixmap, stuff->serial, valid, update,
-- stuff->x_off, stuff->y_off, target_crtc,
-- wait_fence, idle_fence, stuff->options,
-- stuff->target_msc, stuff->divisor, stuff->remainder, notifies, nnotifies);
-+ ret = present_pixmap(window, pixmap, req_serial,
-+ valid, update, req_x_off, req_y_off, target_crtc,
-+ wait_fence, idle_fence,
-+ acquire_syncobj, release_syncobj,
-+ req_acquire_point, req_release_point,
-+ req_options, req_target_msc, req_divisor, req_remainder,
-+ notifies, nnotifies);
-+
- if (ret != Success)
- present_destroy_notifies(notifies, nnotifies);
- return ret;
- }
-
-+static int
-+proc_present_pixmap(ClientPtr client)
-+{
-+ REQUEST(xPresentPixmapReq);
-+ REQUEST_AT_LEAST_SIZE(xPresentPixmapReq);
-+ return proc_present_pixmap_common(client, stuff->window, stuff->pixmap, stuff->serial,
-+ stuff->valid, stuff->update, stuff->x_off, stuff->y_off,
-+ stuff->target_crtc,
-+ stuff->wait_fence, stuff->idle_fence,
-+ None, None, 0, 0,
-+ stuff->options, stuff->target_msc,
-+ stuff->divisor, stuff->remainder,
-+ sizeof (xPresentPixmapReq),
-+ (xPresentNotify *)(stuff + 1));
-+}
-+
- static int
- proc_present_notify_msc(ClientPtr client)
- {
-@@ -240,12 +282,36 @@ proc_present_query_capabilities (ClientPtr client)
- return Success;
- }
-
-+static int
-+proc_present_pixmap_synced (ClientPtr client)
-+{
-+ REQUEST(xPresentPixmapSyncedReq);
-+ struct dri3_syncobj *acquire_syncobj;
-+ struct dri3_syncobj *release_syncobj;
-+
-+ REQUEST_AT_LEAST_SIZE(xPresentPixmapSyncedReq);
-+ VERIFY_DRI3_SYNCOBJ(stuff->acquire_syncobj, acquire_syncobj, DixWriteAccess);
-+ VERIFY_DRI3_SYNCOBJ(stuff->release_syncobj, release_syncobj, DixWriteAccess);
-+
-+ return proc_present_pixmap_common(client, stuff->window, stuff->pixmap, stuff->serial,
-+ stuff->valid, stuff->update, stuff->x_off, stuff->y_off,
-+ stuff->target_crtc,
-+ None, None,
-+ acquire_syncobj, release_syncobj,
-+ stuff->acquire_point, stuff->release_point,
-+ stuff->options, stuff->target_msc,
-+ stuff->divisor, stuff->remainder,
-+ sizeof (xPresentPixmapSyncedReq),
-+ (xPresentNotify *)(stuff + 1));
-+}
-+
- static int (*proc_present_vector[PresentNumberRequests]) (ClientPtr) = {
- proc_present_query_version, /* 0 */
- proc_present_pixmap, /* 1 */
- proc_present_notify_msc, /* 2 */
- proc_present_select_input, /* 3 */
- proc_present_query_capabilities, /* 4 */
-+ proc_present_pixmap_synced, /* 5 */
- };
-
- int
-@@ -325,12 +391,47 @@ sproc_present_query_capabilities (ClientPtr client)
- return (*proc_present_vector[stuff->presentReqType]) (client);
- }
-
-+
-+static int _X_COLD
-+sproc_present_pixmap_synced(ClientPtr client)
-+{
-+ REQUEST(xPresentPixmapSyncedReq);
-+ REQUEST_AT_LEAST_SIZE(xPresentPixmapSyncedReq);
-+
-+ swaps(&stuff->length);
-+
-+ swapl(&stuff->window);
-+
-+ swapl(&stuff->pixmap);
-+ swapl(&stuff->serial);
-+
-+ swapl(&stuff->valid);
-+ swapl(&stuff->update);
-+
-+ swaps(&stuff->x_off);
-+ swaps(&stuff->y_off);
-+ swapl(&stuff->target_crtc);
-+
-+ swapl(&stuff->acquire_syncobj);
-+ swapl(&stuff->release_syncobj);
-+ swapll(&stuff->acquire_point);
-+ swapll(&stuff->release_point);
-+
-+ swapl(&stuff->options);
-+
-+ swapll(&stuff->target_msc);
-+ swapll(&stuff->divisor);
-+ swapll(&stuff->remainder);
-+ return (*proc_present_vector[stuff->presentReqType]) (client);
-+}
-+
- static int (*sproc_present_vector[PresentNumberRequests]) (ClientPtr) = {
- sproc_present_query_version, /* 0 */
- sproc_present_pixmap, /* 1 */
- sproc_present_notify_msc, /* 2 */
- sproc_present_select_input, /* 3 */
- sproc_present_query_capabilities, /* 4 */
-+ sproc_present_pixmap_synced, /* 5 */
- };
-
- int _X_COLD
-diff --git a/present/present_scmd.c b/present/present_scmd.c
-index d378f00..07dd41c 100644
---- a/present/present_scmd.c
-+++ b/present/present_scmd.c
-@@ -738,6 +738,10 @@ present_scmd_pixmap(WindowPtr window,
- RRCrtcPtr target_crtc,
- SyncFence *wait_fence,
- SyncFence *idle_fence,
-+ struct dri3_syncobj *acquire_syncobj,
-+ struct dri3_syncobj *release_syncobj,
-+ uint64_t acquire_point,
-+ uint64_t release_point,
- uint32_t options,
- uint64_t target_window_msc,
- uint64_t divisor,
-@@ -824,6 +828,10 @@ present_scmd_pixmap(WindowPtr window,
- target_crtc,
- wait_fence,
- idle_fence,
-+ acquire_syncobj,
-+ release_syncobj,
-+ acquire_point,
-+ release_point,
- options,
- screen_priv->info ? screen_priv->info->capabilities : 0,
- notifies,
-diff --git a/present/present_screen.c b/present/present_screen.c
-index 2c29aaf..df6a6a2 100644
---- a/present/present_screen.c
-+++ b/present/present_screen.c
-@@ -187,6 +187,7 @@ present_screen_priv_init(ScreenPtr screen)
- wrap(screen_priv, screen, ClipNotify, present_clip_notify);
-
- dixSetPrivate(&screen->devPrivates, &present_screen_private_key, screen_priv);
-+ screen_priv->pScreen = screen;
-
- return screen_priv;
- }
-diff --git a/present/present_vblank.c b/present/present_vblank.c
-index 4f94f16..2eb57ab 100644
---- a/present/present_vblank.c
-+++ b/present/present_vblank.c
-@@ -55,6 +55,10 @@ present_vblank_init(present_vblank_ptr vblank,
- RRCrtcPtr target_crtc,
- SyncFence *wait_fence,
- SyncFence *idle_fence,
-+ struct dri3_syncobj *acquire_syncobj,
-+ struct dri3_syncobj *release_syncobj,
-+ uint64_t acquire_point,
-+ uint64_t release_point,
- uint32_t options,
- const uint32_t capabilities,
- present_notify_ptr notifies,
-@@ -106,6 +110,7 @@ present_vblank_init(present_vblank_ptr vblank,
- vblank->notifies = notifies;
- vblank->num_notifies = num_notifies;
- vblank->has_suboptimal = (options & PresentOptionSuboptimal);
-+ vblank->efd = -1;
-
- if (pixmap != NULL &&
- !(options & PresentOptionCopy) &&
-@@ -135,6 +140,18 @@ present_vblank_init(present_vblank_ptr vblank,
- goto no_mem;
- }
-
-+ if (acquire_syncobj) {
-+ vblank->acquire_syncobj = acquire_syncobj;
-+ ++acquire_syncobj->refcount;
-+ vblank->acquire_point = acquire_point;
-+ }
-+
-+ if (release_syncobj) {
-+ vblank->release_syncobj = release_syncobj;
-+ ++release_syncobj->refcount;
-+ vblank->release_point = release_point;
-+ }
-+
- if (pixmap)
- DebugPresent(("q %" PRIu64 " %p %" PRIu64 ": %08" PRIx32 " -> %08" PRIx32 " (crtc %p) flip %d vsync %d serial %d\n",
- vblank->event_id, vblank, target_msc,
-@@ -158,6 +175,10 @@ present_vblank_create(WindowPtr window,
- RRCrtcPtr target_crtc,
- SyncFence *wait_fence,
- SyncFence *idle_fence,
-+ struct dri3_syncobj *acquire_syncobj,
-+ struct dri3_syncobj *release_syncobj,
-+ uint64_t acquire_point,
-+ uint64_t release_point,
- uint32_t options,
- const uint32_t capabilities,
- present_notify_ptr notifies,
-@@ -172,6 +193,8 @@ present_vblank_create(WindowPtr window,
-
- if (present_vblank_init(vblank, window, pixmap, serial, valid, update,
- x_off, y_off, target_crtc, wait_fence, idle_fence,
-+ acquire_syncobj, release_syncobj,
-+ acquire_point, release_point,
- options, capabilities, notifies, num_notifies,
- target_msc, crtc_msc))
- return vblank;
-@@ -229,5 +252,18 @@ present_vblank_destroy(present_vblank_ptr vblank)
- if (vblank->notifies)
- present_destroy_notifies(vblank->notifies, vblank->num_notifies);
-
-+ if (vblank->efd >= 0) {
-+ SetNotifyFd(vblank->efd, NULL, 0, NULL);
-+ close(vblank->efd);
-+ }
-+
-+ if (vblank->acquire_syncobj &&
-+ --vblank->acquire_syncobj->refcount == 0)
-+ vblank->acquire_syncobj->free(vblank->acquire_syncobj);
-+
-+ if (vblank->release_syncobj &&
-+ --vblank->release_syncobj->refcount == 0)
-+ vblank->release_syncobj->free(vblank->release_syncobj);
-+
- free(vblank);
- }
---
-2.41.0
-
diff --git a/spec_files/xorg-x11-server-Xwayland/old/0001-Valve.patch b/spec_files/xorg-x11-server-Xwayland/old/0001-Valve.patch
new file mode 100644
index 00000000..5c0bc7f4
--- /dev/null
+++ b/spec_files/xorg-x11-server-Xwayland/old/0001-Valve.patch
@@ -0,0 +1,729 @@
+From 0151613de184f0ac8bc2c685f37492919602e15f Mon Sep 17 00:00:00 2001
+From: Kyle Gospodnetich
+Date: Wed, 31 Jan 2024 17:22:32 -0800
+Subject: [PATCH 1/4] Revert "xwayland: add support for wp-tearing-control-v1"
+
+This reverts commit 1ce2025822244c85826ab36febfa5945186b4a2a.
+---
+ hw/xwayland/meson.build | 3 ---
+ hw/xwayland/xwayland-present.c | 21 +++------------------
+ hw/xwayland/xwayland-present.h | 1 -
+ hw/xwayland/xwayland-screen.c | 5 -----
+ hw/xwayland/xwayland-screen.h | 1 -
+ hw/xwayland/xwayland-window.c | 9 ---------
+ hw/xwayland/xwayland-window.h | 1 -
+ 7 files changed, 3 insertions(+), 38 deletions(-)
+
+diff --git a/hw/xwayland/meson.build b/hw/xwayland/meson.build
+index 54529b64e..fbdbb2458 100644
+--- a/hw/xwayland/meson.build
++++ b/hw/xwayland/meson.build
+@@ -48,7 +48,6 @@ xdg_shell_xml = join_paths(protodir, 'stable', 'xdg-shell', 'xdg-shell.xml')
+ drm_lease_xml = join_paths(protodir, 'staging', 'drm-lease', 'drm-lease-v1.xml')
+ shortcuts_inhibit_xml = join_paths(protodir, 'unstable', 'keyboard-shortcuts-inhibit', 'keyboard-shortcuts-inhibit-unstable-v1.xml')
+ xwayland_shell_xml = join_paths(protodir, 'staging', 'xwayland-shell', 'xwayland-shell-v1.xml')
+-tearing_xml = join_paths(protodir, 'staging', 'tearing-control', 'tearing-control-v1.xml')
+
+ client_header = generator(scanner,
+ output : '@BASENAME@-client-protocol.h',
+@@ -77,7 +76,6 @@ srcs += client_header.process(xdg_shell_xml)
+ srcs += client_header.process(drm_lease_xml)
+ srcs += client_header.process(shortcuts_inhibit_xml)
+ srcs += client_header.process(xwayland_shell_xml)
+-srcs += client_header.process(tearing_xml)
+ srcs += code.process(relative_xml)
+ srcs += code.process(pointer_xml)
+ srcs += code.process(gestures_xml)
+@@ -90,7 +88,6 @@ srcs += code.process(xdg_shell_xml)
+ srcs += code.process(drm_lease_xml)
+ srcs += code.process(shortcuts_inhibit_xml)
+ srcs += code.process(xwayland_shell_xml)
+-srcs += code.process(tearing_xml)
+
+ if build_ei
+ xwayland_dep += libei_dep
+diff --git a/hw/xwayland/xwayland-present.c b/hw/xwayland/xwayland-present.c
+index 941be06da..bb3310dc9 100644
+--- a/hw/xwayland/xwayland-present.c
++++ b/hw/xwayland/xwayland-present.c
+@@ -34,9 +34,8 @@
+ #include "xwayland-pixmap.h"
+ #include "glamor.h"
+
+-#include "tearing-control-v1-client-protocol.h"
+
+-#define XWL_PRESENT_CAPS PresentCapabilityAsync | PresentCapabilityAsyncMayTear
++#define XWL_PRESENT_CAPS PresentCapabilityAsync
+
+
+ /*
+@@ -797,16 +796,6 @@ xwl_present_flip(present_vblank_ptr vblank, RegionPtr damage)
+ damage_box->x2 - damage_box->x1,
+ damage_box->y2 - damage_box->y1);
+
+- if (xwl_window->tearing_control) {
+- uint32_t hint;
+- if (event->async_may_tear)
+- hint = WP_TEARING_CONTROL_V1_PRESENTATION_HINT_ASYNC;
+- else
+- hint = WP_TEARING_CONTROL_V1_PRESENTATION_HINT_VSYNC;
+-
+- wp_tearing_control_v1_set_presentation_hint(xwl_window->tearing_control, hint);
+- }
+-
+ wl_surface_commit(xwl_window->surface);
+
+ if (!vblank->sync_flip) {
+@@ -1010,15 +999,11 @@ xwl_present_pixmap(WindowPtr window,
+ }
+
+ vblank->event_id = ++xwl_present_event_id;
+- event->async_may_tear = options & PresentOptionAsyncMayTear;
+
+- /* Synchronous Xwayland presentations always complete (at least) one frame after they
++ /* Xwayland presentations always complete (at least) one frame after they
+ * are executed
+ */
+- if (event->async_may_tear)
+- vblank->exec_msc = vblank->target_msc;
+- else
+- vblank->exec_msc = vblank->target_msc - 1;
++ vblank->exec_msc = vblank->target_msc - 1;
+
+ vblank->queued = TRUE;
+ if (crtc_msc < vblank->exec_msc) {
+diff --git a/hw/xwayland/xwayland-present.h b/hw/xwayland/xwayland-present.h
+index 4fd1e579f..806272089 100644
+--- a/hw/xwayland/xwayland-present.h
++++ b/hw/xwayland/xwayland-present.h
+@@ -59,7 +59,6 @@ struct xwl_present_event {
+ present_vblank_rec vblank;
+
+ PixmapPtr pixmap;
+- Bool async_may_tear;
+ };
+
+ Bool xwl_present_entered_for_each_frame_callback(void);
+diff --git a/hw/xwayland/xwayland-screen.c b/hw/xwayland/xwayland-screen.c
+index cc14e0771..2bc553b50 100644
+--- a/hw/xwayland/xwayland-screen.c
++++ b/hw/xwayland/xwayland-screen.c
+@@ -63,7 +63,6 @@
+ #include "viewporter-client-protocol.h"
+ #include "xdg-shell-client-protocol.h"
+ #include "xwayland-shell-v1-client-protocol.h"
+-#include "tearing-control-v1-client-protocol.h"
+
+ static DevPrivateKeyRec xwl_screen_private_key;
+ static DevPrivateKeyRec xwl_client_private_key;
+@@ -462,10 +461,6 @@ registry_global(void *data, struct wl_registry *registry, uint32_t id,
+ xwl_screen->xwayland_shell =
+ wl_registry_bind(registry, id, &xwayland_shell_v1_interface, 1);
+ }
+- else if (strcmp(interface, "wp_tearing_control_manager_v1") == 0) {
+- xwl_screen->tearing_control_manager =
+- wl_registry_bind(registry, id, &wp_tearing_control_manager_v1_interface, 1);
+- }
+ #ifdef XWL_HAS_GLAMOR
+ else if (xwl_screen->glamor) {
+ xwl_glamor_init_wl_registry(xwl_screen, registry, id, interface,
+diff --git a/hw/xwayland/xwayland-screen.h b/hw/xwayland/xwayland-screen.h
+index bd66dd681..656d2afde 100644
+--- a/hw/xwayland/xwayland-screen.h
++++ b/hw/xwayland/xwayland-screen.h
+@@ -110,7 +110,6 @@ struct xwl_screen {
+ struct zxdg_output_manager_v1 *xdg_output_manager;
+ struct wp_viewporter *viewporter;
+ struct xwayland_shell_v1 *xwayland_shell;
+- struct wp_tearing_control_manager_v1 *tearing_control_manager;
+ struct xorg_list drm_lease_devices;
+ struct xorg_list queued_drm_lease_devices;
+ struct xorg_list drm_leases;
+diff --git a/hw/xwayland/xwayland-window.c b/hw/xwayland/xwayland-window.c
+index a4f02a058..54ba9d896 100644
+--- a/hw/xwayland/xwayland-window.c
++++ b/hw/xwayland/xwayland-window.c
+@@ -46,7 +46,6 @@
+ #include "xwayland-shm.h"
+
+ #include "linux-dmabuf-unstable-v1-client-protocol.h"
+-#include "tearing-control-v1-client-protocol.h"
+ #include "viewporter-client-protocol.h"
+ #include "xdg-shell-client-protocol.h"
+ #include "xwayland-shell-v1-client-protocol.h"
+@@ -941,11 +940,6 @@ ensure_surface_for_window(WindowPtr window)
+ xwl_window_check_resolution_change_emulation(xwl_window);
+ }
+
+- if (xwl_screen->tearing_control_manager) {
+- xwl_window->tearing_control = wp_tearing_control_manager_v1_get_tearing_control(
+- xwl_screen->tearing_control_manager, xwl_window->surface);
+- }
+-
+ return TRUE;
+
+ err:
+@@ -1156,9 +1150,6 @@ xwl_unrealize_window(WindowPtr window)
+ xwl_present_for_each_frame_callback(xwl_window, xwl_present_unrealize_window);
+ #endif
+
+- if (xwl_window->tearing_control)
+- wp_tearing_control_v1_destroy(xwl_window->tearing_control);
+-
+ release_wl_surface_for_window(xwl_window);
+ xorg_list_del(&xwl_window->link_damage);
+ xorg_list_del(&xwl_window->link_window);
+diff --git a/hw/xwayland/xwayland-window.h b/hw/xwayland/xwayland-window.h
+index 45ae16da0..92c700e41 100644
+--- a/hw/xwayland/xwayland-window.h
++++ b/hw/xwayland/xwayland-window.h
+@@ -121,7 +121,6 @@ struct xwl_window {
+ struct xwl_dmabuf_feedback feedback;
+ /* If TRUE, the window buffer format supports scanout with implicit modifier */
+ Bool has_implicit_scanout_support;
+- struct wp_tearing_control_v1 *tearing_control;
+ };
+
+ struct xwl_window *xwl_window_get(WindowPtr window);
+--
+2.42.0
+
+
+From 7e43bb1113e7732d587d783a8db7ae86aefdb04d Mon Sep 17 00:00:00 2001
+From: Joshua Ashton
+Date: Wed, 24 Aug 2022 23:16:24 +0000
+Subject: [PATCH 2/4] xwayland: Implement tearing protocol
+
+---
+ hw/xwayland/meson.build | 3 +
+ .../tearing-control-unstable-v1.xml | 142 ++++++++++++++++++
+ hw/xwayland/xwayland-present.c | 11 ++
+ hw/xwayland/xwayland-screen.c | 4 +
+ hw/xwayland/xwayland-screen.h | 1 +
+ hw/xwayland/xwayland-window.c | 11 ++
+ hw/xwayland/xwayland-window.h | 1 +
+ 7 files changed, 173 insertions(+)
+ create mode 100644 hw/xwayland/protocols/unstable/tearing-control/tearing-control-unstable-v1.xml
+
+diff --git a/hw/xwayland/meson.build b/hw/xwayland/meson.build
+index fbdbb2458..d29e55d7d 100644
+--- a/hw/xwayland/meson.build
++++ b/hw/xwayland/meson.build
+@@ -46,6 +46,7 @@ dmabuf_xml = join_paths(protodir, 'unstable', 'linux-dmabuf', 'linux-dmabuf-unst
+ viewporter_xml = join_paths(protodir, 'stable', 'viewporter', 'viewporter.xml')
+ xdg_shell_xml = join_paths(protodir, 'stable', 'xdg-shell', 'xdg-shell.xml')
+ drm_lease_xml = join_paths(protodir, 'staging', 'drm-lease', 'drm-lease-v1.xml')
++tearing_xml = join_paths('protocols', 'unstable', 'tearing-control', 'tearing-control-unstable-v1.xml')
+ shortcuts_inhibit_xml = join_paths(protodir, 'unstable', 'keyboard-shortcuts-inhibit', 'keyboard-shortcuts-inhibit-unstable-v1.xml')
+ xwayland_shell_xml = join_paths(protodir, 'staging', 'xwayland-shell', 'xwayland-shell-v1.xml')
+
+@@ -74,6 +75,7 @@ srcs += client_header.process(dmabuf_xml)
+ srcs += client_header.process(viewporter_xml)
+ srcs += client_header.process(xdg_shell_xml)
+ srcs += client_header.process(drm_lease_xml)
++srcs += client_header.process(tearing_xml)
+ srcs += client_header.process(shortcuts_inhibit_xml)
+ srcs += client_header.process(xwayland_shell_xml)
+ srcs += code.process(relative_xml)
+@@ -86,6 +88,7 @@ srcs += code.process(dmabuf_xml)
+ srcs += code.process(viewporter_xml)
+ srcs += code.process(xdg_shell_xml)
+ srcs += code.process(drm_lease_xml)
++srcs += code.process(tearing_xml)
+ srcs += code.process(shortcuts_inhibit_xml)
+ srcs += code.process(xwayland_shell_xml)
+
+diff --git a/hw/xwayland/protocols/unstable/tearing-control/tearing-control-unstable-v1.xml b/hw/xwayland/protocols/unstable/tearing-control/tearing-control-unstable-v1.xml
+new file mode 100644
+index 000000000..ce130718e
+--- /dev/null
++++ b/hw/xwayland/protocols/unstable/tearing-control/tearing-control-unstable-v1.xml
+@@ -0,0 +1,142 @@
++
++
++
++
++ Copyright © 2021 Xaver Hugl
++
++ Permission is hereby granted, free of charge, to any person obtaining a
++ copy of this software and associated documentation files (the "Software"),
++ to deal in the Software without restriction, including without limitation
++ the rights to use, copy, modify, merge, publish, distribute, sublicense,
++ and/or sell copies of the Software, and to permit persons to whom the
++ Software is furnished to do so, subject to the following conditions:
++
++ The above copyright notice and this permission notice (including the next
++ paragraph) shall be included in all copies or substantial portions of the
++ Software.
++
++ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
++ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
++ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
++ THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
++ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
++ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
++ DEALINGS IN THE SOFTWARE.
++
++
++
++
++ This global is a factory interface, allowing clients to request
++ the compositor to use asynchronous page flips on a per-surface basis.
++
++ Graphics APIs, like EGL or Vulkan, that manage the buffer queue and
++ commits of a wl_surface themselves, are likely to be using this
++ extension internally. If a client is using such an API for a
++ wl_surface, it should not directly use this extension on that surface,
++ to avoid raising a tearing_control_exists protocol error.
++
++ Warning! The protocol described in this file is experimental and
++ backward incompatible changes may be made. Backward compatible changes
++ may be added together with the corresponding interface version bump.
++ Backward incompatible changes are done by bumping the version number in
++ the protocol and interface names and resetting the interface version.
++ Once the protocol is to be declared stable, the 'z' prefix and the
++ version number in the protocol and interface names are removed and the
++ interface version number is reset.
++
++
++
++
++ Destroy this tearing control factory object. Other objects, including
++ zwp_surface_tearing_control_v1 objects created by this factory,
++ shall not be affected by this request.
++
++
++
++
++
++
++
++
++
++ Instantiate an interface extension for the given wl_surface to
++ request asynchronous page flips for presentation.
++
++ If the given wl_surface already has a zwp_surface_tearing_control_v1
++ object associated, the tearing_control_exists protocol error is raised.
++
++
++
++
++
++
++
++
++
++ An additional interface to a wl_surface object, which allows the client
++ to hint to the compositor if and when it should use asynchronous page
++ flips for presentation.
++
++
++
++
++ This enum provides information for if and when submitted frames from
++ the client may be presented with tearing. The possible values are:
++
++ VSYNC:
++ Presentation should be synchronized to the vertical retrace by the
++ display hardware so that tearing doesn't happen.
++
++ VSYNC_RELAXED:
++ Presentation should be synchronized to the vertical retrace by the
++ display hardware so that tearing doesn't happen as long as the client
++ submits new frame fast enough. If a frame is late for presentation,
++ that is, if more than one vertical retrace has occurred since the last
++ commit then the compositor should use asynchronous page flips to
++ immediately present the frame. This may cause visible tearing.
++ The compositor is encouraged to send requested frame callbacks as soon
++ as possible after such a late commit to make sure clients have as much
++ time as possible to render their next frame.
++
++ ASYNC:
++ Presentation should not be synchronized to the vertical retrace,
++ committed frames are meant to be immediately presented with asynchronous
++ page flips with as little delay as possible. Tearing will be visible.
++ The compositor is encouraged to send requested frame callbacks as soon
++ as possible after every commit.
++
++
++
++
++
++
++
++
++ Set the presentation hint for the associated wl_surface. See
++ presentation_hint for the description. This state is double-buffered
++ and is applied on the next wl_surface.commit.
++
++ The compositor is free to dynamically respect or ignore this hint based
++ on various conditions, including GPU capabilities and surface window
++ state.
++
++
++
++
++
++
++ Destroy this surface tearing object and remove the presentation hint.
++ The change will be applied on the next wl_surface.commit.
++
++
++
++
++
++
+diff --git a/hw/xwayland/xwayland-present.c b/hw/xwayland/xwayland-present.c
+index bb3310dc9..6f1d57a42 100644
+--- a/hw/xwayland/xwayland-present.c
++++ b/hw/xwayland/xwayland-present.c
+@@ -34,6 +34,8 @@
+ #include "xwayland-pixmap.h"
+ #include "glamor.h"
+
++#include "tearing-control-unstable-v1-client-protocol.h"
++
+
+ #define XWL_PRESENT_CAPS PresentCapabilityAsync
+
+@@ -796,6 +798,15 @@ xwl_present_flip(present_vblank_ptr vblank, RegionPtr damage)
+ damage_box->x2 - damage_box->x1,
+ damage_box->y2 - damage_box->y1);
+
++
++ // Josh: No support for VSync relaxed, this is something that should
++ // be determined by a user setting in gamescope.
++ if (xwl_window->tearing_control)
++ zwp_surface_tearing_control_v1_set_presentation_hint(xwl_window->tearing_control,
++ sync_flip
++ ? ZWP_SURFACE_TEARING_CONTROL_V1_PRESENTATION_HINT_VSYNC
++ : ZWP_SURFACE_TEARING_CONTROL_V1_PRESENTATION_HINT_ASYNC);
++
+ wl_surface_commit(xwl_window->surface);
+
+ if (!vblank->sync_flip) {
+diff --git a/hw/xwayland/xwayland-screen.c b/hw/xwayland/xwayland-screen.c
+index 2bc553b50..e35861e46 100644
+--- a/hw/xwayland/xwayland-screen.c
++++ b/hw/xwayland/xwayland-screen.c
+@@ -62,6 +62,7 @@
+ #include "xdg-output-unstable-v1-client-protocol.h"
+ #include "viewporter-client-protocol.h"
+ #include "xdg-shell-client-protocol.h"
++#include "tearing-control-unstable-v1-client-protocol.h"
+ #include "xwayland-shell-v1-client-protocol.h"
+
+ static DevPrivateKeyRec xwl_screen_private_key;
+@@ -457,6 +458,9 @@ registry_global(void *data, struct wl_registry *registry, uint32_t id,
+ else if (strcmp(interface, "wp_viewporter") == 0) {
+ xwl_screen->viewporter = wl_registry_bind(registry, id, &wp_viewporter_interface, 1);
+ }
++ else if (strcmp(interface, "zwp_tearing_control_v1") == 0) {
++ xwl_screen->tearing_control = wl_registry_bind(registry, id, &zwp_tearing_control_v1_interface, 1);
++ }
+ else if (strcmp(interface, "xwayland_shell_v1") == 0 && xwl_screen->rootless) {
+ xwl_screen->xwayland_shell =
+ wl_registry_bind(registry, id, &xwayland_shell_v1_interface, 1);
+diff --git a/hw/xwayland/xwayland-screen.h b/hw/xwayland/xwayland-screen.h
+index 656d2afde..bf75278fd 100644
+--- a/hw/xwayland/xwayland-screen.h
++++ b/hw/xwayland/xwayland-screen.h
+@@ -113,6 +113,7 @@ struct xwl_screen {
+ struct xorg_list drm_lease_devices;
+ struct xorg_list queued_drm_lease_devices;
+ struct xorg_list drm_leases;
++ struct zwp_tearing_control_v1 *tearing_control;
+ struct xwl_output *fixed_output;
+ struct xorg_list pending_wl_surface_destroy;
+ uint64_t surface_association_serial;
+diff --git a/hw/xwayland/xwayland-window.c b/hw/xwayland/xwayland-window.c
+index 54ba9d896..527f41c90 100644
+--- a/hw/xwayland/xwayland-window.c
++++ b/hw/xwayland/xwayland-window.c
+@@ -48,6 +48,7 @@
+ #include "linux-dmabuf-unstable-v1-client-protocol.h"
+ #include "viewporter-client-protocol.h"
+ #include "xdg-shell-client-protocol.h"
++#include "tearing-control-unstable-v1-client-protocol.h"
+ #include "xwayland-shell-v1-client-protocol.h"
+
+ #define DELAYED_WL_SURFACE_DESTROY 1000 /* ms */
+@@ -894,6 +895,11 @@ ensure_surface_for_window(WindowPtr window)
+ goto err;
+ }
+
++ if (xwl_screen->tearing_control) {
++ xwl_window->tearing_control =
++ zwp_tearing_control_v1_get_tearing_control(xwl_screen->tearing_control, xwl_window->surface);
++ }
++
+ if (xwl_screen->xwayland_shell) {
+ xwl_window->xwayland_surface = xwayland_shell_v1_get_xwayland_surface(
+ xwl_screen->xwayland_shell, xwl_window->surface);
+@@ -1143,6 +1149,11 @@ xwl_unrealize_window(WindowPtr window)
+ if (xwl_window_has_viewport_enabled(xwl_window))
+ xwl_window_disable_viewport(xwl_window);
+
++ if (xwl_window->tearing_control) {
++ zwp_surface_tearing_control_v1_destroy(xwl_window->tearing_control);
++ xwl_window->tearing_control = NULL;
++ }
++
+ xwl_dmabuf_feedback_destroy(&xwl_window->feedback);
+
+ #ifdef GLAMOR_HAS_GBM
+diff --git a/hw/xwayland/xwayland-window.h b/hw/xwayland/xwayland-window.h
+index 92c700e41..efbb1f2fc 100644
+--- a/hw/xwayland/xwayland-window.h
++++ b/hw/xwayland/xwayland-window.h
+@@ -99,6 +99,7 @@ struct xwl_window {
+ struct wp_viewport *viewport;
+ float scale_x, scale_y;
+ struct xdg_surface *xdg_surface;
++ struct zwp_surface_tearing_control_v1 *tearing_control;
+ struct xdg_toplevel *xdg_toplevel;
+ WindowPtr window;
+ struct xorg_list link_damage;
+--
+2.42.0
+
+
+From ac5a78ddabf16b6876bf286e93d770f50d8e9315 Mon Sep 17 00:00:00 2001
+From: Joshua Ashton
+Date: Wed, 31 Aug 2022 12:57:09 +0000
+Subject: [PATCH 3/4] Use gamescope tearing protocol instead
+
+Renamed to not clash
+---
+ hw/xwayland/meson.build | 2 +-
+ ...xml => gamescope-tearing-control-unstable-v1.xml} | 12 ++++++------
+ hw/xwayland/xwayland-present.c | 8 ++++----
+ hw/xwayland/xwayland-screen.c | 6 +++---
+ hw/xwayland/xwayland-screen.h | 2 +-
+ hw/xwayland/xwayland-window.c | 6 +++---
+ hw/xwayland/xwayland-window.h | 2 +-
+ 7 files changed, 19 insertions(+), 19 deletions(-)
+ rename hw/xwayland/protocols/unstable/tearing-control/{tearing-control-unstable-v1.xml => gamescope-tearing-control-unstable-v1.xml} (93%)
+
+diff --git a/hw/xwayland/meson.build b/hw/xwayland/meson.build
+index d29e55d7d..73f2bdd94 100644
+--- a/hw/xwayland/meson.build
++++ b/hw/xwayland/meson.build
+@@ -46,7 +46,7 @@ dmabuf_xml = join_paths(protodir, 'unstable', 'linux-dmabuf', 'linux-dmabuf-unst
+ viewporter_xml = join_paths(protodir, 'stable', 'viewporter', 'viewporter.xml')
+ xdg_shell_xml = join_paths(protodir, 'stable', 'xdg-shell', 'xdg-shell.xml')
+ drm_lease_xml = join_paths(protodir, 'staging', 'drm-lease', 'drm-lease-v1.xml')
+-tearing_xml = join_paths('protocols', 'unstable', 'tearing-control', 'tearing-control-unstable-v1.xml')
++tearing_xml = join_paths('protocols', 'unstable', 'tearing-control', 'gamescope-tearing-control-unstable-v1.xml')
+ shortcuts_inhibit_xml = join_paths(protodir, 'unstable', 'keyboard-shortcuts-inhibit', 'keyboard-shortcuts-inhibit-unstable-v1.xml')
+ xwayland_shell_xml = join_paths(protodir, 'staging', 'xwayland-shell', 'xwayland-shell-v1.xml')
+
+diff --git a/hw/xwayland/protocols/unstable/tearing-control/tearing-control-unstable-v1.xml b/hw/xwayland/protocols/unstable/tearing-control/gamescope-tearing-control-unstable-v1.xml
+similarity index 93%
+rename from hw/xwayland/protocols/unstable/tearing-control/tearing-control-unstable-v1.xml
+rename to hw/xwayland/protocols/unstable/tearing-control/gamescope-tearing-control-unstable-v1.xml
+index ce130718e..3c7cfb09e 100644
+--- a/hw/xwayland/protocols/unstable/tearing-control/tearing-control-unstable-v1.xml
++++ b/hw/xwayland/protocols/unstable/tearing-control/gamescope-tearing-control-unstable-v1.xml
+@@ -1,5 +1,5 @@
+
+-
++
+
+
+ Copyright © 2021 Xaver Hugl
+@@ -24,7 +24,7 @@
+ DEALINGS IN THE SOFTWARE.
+
+
+-
++
+
+ This global is a factory interface, allowing clients to request
+ the compositor to use asynchronous page flips on a per-surface basis.
+@@ -48,7 +48,7 @@
+
+
+ Destroy this tearing control factory object. Other objects, including
+- zwp_surface_tearing_control_v1 objects created by this factory,
++ gamescope_surface_tearing_control_v1 objects created by this factory,
+ shall not be affected by this request.
+
+
+@@ -63,19 +63,19 @@
+ Instantiate an interface extension for the given wl_surface to
+ request asynchronous page flips for presentation.
+
+- If the given wl_surface already has a zwp_surface_tearing_control_v1
++ If the given wl_surface already has a gamescope_surface_tearing_control_v1
+ object associated, the tearing_control_exists protocol error is raised.
+
+
+
+
+
+
+
+-
++
+
+ An additional interface to a wl_surface object, which allows the client
+ to hint to the compositor if and when it should use asynchronous page
+diff --git a/hw/xwayland/xwayland-present.c b/hw/xwayland/xwayland-present.c
+index 6f1d57a42..5cbd767c9 100644
+--- a/hw/xwayland/xwayland-present.c
++++ b/hw/xwayland/xwayland-present.c
+@@ -34,7 +34,7 @@
+ #include "xwayland-pixmap.h"
+ #include "glamor.h"
+
+-#include "tearing-control-unstable-v1-client-protocol.h"
++#include "gamescope-tearing-control-unstable-v1-client-protocol.h"
+
+
+ #define XWL_PRESENT_CAPS PresentCapabilityAsync
+@@ -802,10 +802,10 @@ xwl_present_flip(present_vblank_ptr vblank, RegionPtr damage)
+ // Josh: No support for VSync relaxed, this is something that should
+ // be determined by a user setting in gamescope.
+ if (xwl_window->tearing_control)
+- zwp_surface_tearing_control_v1_set_presentation_hint(xwl_window->tearing_control,
++ gamescope_surface_tearing_control_v1_set_presentation_hint(xwl_window->tearing_control,
+ sync_flip
+- ? ZWP_SURFACE_TEARING_CONTROL_V1_PRESENTATION_HINT_VSYNC
+- : ZWP_SURFACE_TEARING_CONTROL_V1_PRESENTATION_HINT_ASYNC);
++ ? GAMESCOPE_SURFACE_TEARING_CONTROL_V1_PRESENTATION_HINT_VSYNC
++ : GAMESCOPE_SURFACE_TEARING_CONTROL_V1_PRESENTATION_HINT_ASYNC);
+
+ wl_surface_commit(xwl_window->surface);
+
+diff --git a/hw/xwayland/xwayland-screen.c b/hw/xwayland/xwayland-screen.c
+index e35861e46..2a025db18 100644
+--- a/hw/xwayland/xwayland-screen.c
++++ b/hw/xwayland/xwayland-screen.c
+@@ -62,7 +62,7 @@
+ #include "xdg-output-unstable-v1-client-protocol.h"
+ #include "viewporter-client-protocol.h"
+ #include "xdg-shell-client-protocol.h"
+-#include "tearing-control-unstable-v1-client-protocol.h"
++#include "gamescope-tearing-control-unstable-v1-client-protocol.h"
+ #include "xwayland-shell-v1-client-protocol.h"
+
+ static DevPrivateKeyRec xwl_screen_private_key;
+@@ -458,8 +458,8 @@ registry_global(void *data, struct wl_registry *registry, uint32_t id,
+ else if (strcmp(interface, "wp_viewporter") == 0) {
+ xwl_screen->viewporter = wl_registry_bind(registry, id, &wp_viewporter_interface, 1);
+ }
+- else if (strcmp(interface, "zwp_tearing_control_v1") == 0) {
+- xwl_screen->tearing_control = wl_registry_bind(registry, id, &zwp_tearing_control_v1_interface, 1);
++ else if (strcmp(interface, "gamescope_tearing_control_v1") == 0) {
++ xwl_screen->tearing_control = wl_registry_bind(registry, id, &gamescope_tearing_control_v1_interface, 1);
+ }
+ else if (strcmp(interface, "xwayland_shell_v1") == 0 && xwl_screen->rootless) {
+ xwl_screen->xwayland_shell =
+diff --git a/hw/xwayland/xwayland-screen.h b/hw/xwayland/xwayland-screen.h
+index bf75278fd..d6b1a1d84 100644
+--- a/hw/xwayland/xwayland-screen.h
++++ b/hw/xwayland/xwayland-screen.h
+@@ -113,7 +113,7 @@ struct xwl_screen {
+ struct xorg_list drm_lease_devices;
+ struct xorg_list queued_drm_lease_devices;
+ struct xorg_list drm_leases;
+- struct zwp_tearing_control_v1 *tearing_control;
++ struct gamescope_tearing_control_v1 *tearing_control;
+ struct xwl_output *fixed_output;
+ struct xorg_list pending_wl_surface_destroy;
+ uint64_t surface_association_serial;
+diff --git a/hw/xwayland/xwayland-window.c b/hw/xwayland/xwayland-window.c
+index 527f41c90..3e42eb1c0 100644
+--- a/hw/xwayland/xwayland-window.c
++++ b/hw/xwayland/xwayland-window.c
+@@ -48,7 +48,7 @@
+ #include "linux-dmabuf-unstable-v1-client-protocol.h"
+ #include "viewporter-client-protocol.h"
+ #include "xdg-shell-client-protocol.h"
+-#include "tearing-control-unstable-v1-client-protocol.h"
++#include "gamescope-tearing-control-unstable-v1-client-protocol.h"
+ #include "xwayland-shell-v1-client-protocol.h"
+
+ #define DELAYED_WL_SURFACE_DESTROY 1000 /* ms */
+@@ -897,7 +897,7 @@ ensure_surface_for_window(WindowPtr window)
+
+ if (xwl_screen->tearing_control) {
+ xwl_window->tearing_control =
+- zwp_tearing_control_v1_get_tearing_control(xwl_screen->tearing_control, xwl_window->surface);
++ gamescope_tearing_control_v1_get_tearing_control(xwl_screen->tearing_control, xwl_window->surface);
+ }
+
+ if (xwl_screen->xwayland_shell) {
+@@ -1150,7 +1150,7 @@ xwl_unrealize_window(WindowPtr window)
+ xwl_window_disable_viewport(xwl_window);
+
+ if (xwl_window->tearing_control) {
+- zwp_surface_tearing_control_v1_destroy(xwl_window->tearing_control);
++ gamescope_surface_tearing_control_v1_destroy(xwl_window->tearing_control);
+ xwl_window->tearing_control = NULL;
+ }
+
+diff --git a/hw/xwayland/xwayland-window.h b/hw/xwayland/xwayland-window.h
+index efbb1f2fc..f62a7f1bd 100644
+--- a/hw/xwayland/xwayland-window.h
++++ b/hw/xwayland/xwayland-window.h
+@@ -99,7 +99,7 @@ struct xwl_window {
+ struct wp_viewport *viewport;
+ float scale_x, scale_y;
+ struct xdg_surface *xdg_surface;
+- struct zwp_surface_tearing_control_v1 *tearing_control;
++ struct gamescope_surface_tearing_control_v1 *tearing_control;
+ struct xdg_toplevel *xdg_toplevel;
+ WindowPtr window;
+ struct xorg_list link_damage;
+--
+2.42.0
+
+
+From c1451e6720b20505b7ce4fef3294a493fe4fe312 Mon Sep 17 00:00:00 2001
+From: Kyle Gospodnetich
+Date: Wed, 31 Jan 2024 17:36:04 -0800
+Subject: [PATCH 4/4] Fix missing sync_flip param
+
+---
+ hw/xwayland/xwayland-present.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/hw/xwayland/xwayland-present.c b/hw/xwayland/xwayland-present.c
+index 5cbd767c9..f22e8f987 100644
+--- a/hw/xwayland/xwayland-present.c
++++ b/hw/xwayland/xwayland-present.c
+@@ -754,7 +754,7 @@ xwl_present_clear_window_flip(WindowPtr window)
+ }
+
+ static Bool
+-xwl_present_flip(present_vblank_ptr vblank, RegionPtr damage)
++xwl_present_flip(present_vblank_ptr vblank, RegionPtr damage, Bool sync_flip)
+ {
+ WindowPtr present_window = vblank->window;
+ PixmapPtr pixmap = vblank->pixmap;
+@@ -873,7 +873,7 @@ xwl_present_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
+ } else
+ damage = RegionDuplicate(&window->clipList);
+
+- if (xwl_present_flip(vblank, damage)) {
++ if (xwl_present_flip(vblank, damage, vblank->sync_flip)) {
+ WindowPtr toplvl_window = xwl_present_toplvl_pixmap_window(vblank->window);
+ PixmapPtr old_pixmap = screen->GetWindowPixmap(window);
+
+--
+2.42.0
+
diff --git a/spec_files/xorg-x11-server-Xwayland/old/xorg-x11-server-Xwayland.spec b/spec_files/xorg-x11-server-Xwayland/old/xorg-x11-server-Xwayland.spec
new file mode 100644
index 00000000..f4fc5a99
--- /dev/null
+++ b/spec_files/xorg-x11-server-Xwayland/old/xorg-x11-server-Xwayland.spec
@@ -0,0 +1,279 @@
+%global commit 9a55c402aa803fb10e39ab4fd18a709d0cd06fd4
+%global shortcommit %(c=%{commit}; echo ${c:0:7})
+
+#global gitdate 20230426
+%global pkgname %{?gitdate:xserver}%{!?gitdate:xwayland}
+
+%global default_font_path "catalogue:/etc/X11/fontpath.d,built-ins"
+
+Summary: Xwayland
+Name: xorg-x11-server-Xwayland
+%global xwayland_version 23.2.2
+Version: %{xwayland_version}.bazzite.{{{ git_dir_version }}}
+Release: 1%{?gitdate:.%{gitdate}git%{shortcommit}}%{?dist}
+
+URL: http://www.x.org
+%if 0%{?gitdate}
+Source0: https://gitlab.freedesktop.org/xorg/%{pkgname}/-/archive/%{commit}/%{pkgname}-%{shortcommit}.tar.gz
+%else
+Source0: https://www.x.org/pub/individual/xserver/%{pkgname}-%{xwayland_version}.tar.xz
+%endif
+
+Patch1: 0001-Valve.patch
+
+License: MIT
+
+Requires: xorg-x11-server-common
+Requires: libEGL
+Requires: libepoxy >= 1.5.5
+
+BuildRequires: gcc
+BuildRequires: git-core
+BuildRequires: meson
+
+BuildRequires: wayland-devel
+BuildRequires: desktop-file-utils
+
+BuildRequires: pkgconfig(wayland-client) >= 1.21.0
+BuildRequires: pkgconfig(wayland-protocols) >= 1.30
+BuildRequires: pkgconfig(wayland-eglstream-protocols)
+
+BuildRequires: pkgconfig(epoxy) >= 1.5.5
+BuildRequires: pkgconfig(fontenc)
+BuildRequires: pkgconfig(libdrm) >= 2.4.89
+BuildRequires: pkgconfig(libssl)
+BuildRequires: pkgconfig(libtirpc)
+BuildRequires: pkgconfig(pixman-1)
+BuildRequires: pkgconfig(x11)
+BuildRequires: pkgconfig(xau)
+BuildRequires: pkgconfig(xdmcp)
+BuildRequires: pkgconfig(xext)
+BuildRequires: pkgconfig(xfixes)
+BuildRequires: pkgconfig(xfont2)
+BuildRequires: pkgconfig(xi)
+BuildRequires: pkgconfig(xinerama)
+BuildRequires: pkgconfig(xkbfile)
+BuildRequires: pkgconfig(xmu)
+BuildRequires: pkgconfig(xorg-macros) >= 1.17
+BuildRequires: pkgconfig(xpm)
+BuildRequires: pkgconfig(xrender)
+BuildRequires: pkgconfig(xres)
+BuildRequires: pkgconfig(xshmfence) >= 1.1
+BuildRequires: pkgconfig(xtrans) >= 1.3.2
+BuildRequires: pkgconfig(xtst)
+BuildRequires: pkgconfig(xv)
+BuildRequires: pkgconfig(libxcvt)
+BuildRequires: pkgconfig(libdecor-0) >= 0.1.1
+BuildRequires: pkgconfig(liboeffis-1.0) >= 1.0.0
+BuildRequires: pkgconfig(libei-1.0) >= 1.0.0
+BuildRequires: xorg-x11-proto-devel >= 2023.2-1
+
+BuildRequires: mesa-libGL-devel >= 9.2
+BuildRequires: mesa-libEGL-devel
+BuildRequires: mesa-libgbm-devel
+
+BuildRequires: audit-libs-devel
+BuildRequires: libselinux-devel >= 2.0.86-1
+
+# libunwind is Exclusive for the following arches
+%ifarch aarch64 %{arm} hppa ia64 mips ppc ppc64 %{ix86} x86_64
+%if !0%{?rhel}
+BuildRequires: libunwind-devel
+%endif
+%endif
+
+BuildRequires: pkgconfig(xcb-aux)
+BuildRequires: pkgconfig(xcb-image)
+BuildRequires: pkgconfig(xcb-icccm)
+BuildRequires: pkgconfig(xcb-keysyms)
+BuildRequires: pkgconfig(xcb-renderutil)
+
+%description
+Xwayland is an X server for running X clients under Wayland.
+
+%package devel
+Summary: Development package
+Requires: pkgconfig
+Requires: %{name}%{?_isa} = %{xwayland_version}-%{release}
+
+%description devel
+The development package provides the developmental files which are
+necessary for developing Wayland compositors using Xwayland.
+
+%prep
+%autosetup -S git_am -n %{pkgname}-%{?gitdate:%{commit}}%{!?gitdate:%{xwayland_version}}
+
+%build
+%meson \
+ %{?gitdate:-Dxwayland=true -D{xorg,xnest,xvfb,udev}=false} \
+ -Dxwayland_eglstream=true \
+ -Ddefault_font_path=%{default_font_path} \
+ -Dbuilder_string="Build ID: %{name} %{xwayland_version}-%{release}" \
+ -Dxkb_output_dir=%{_localstatedir}/lib/xkb \
+ -Dxcsecurity=true \
+ -Dglamor=true \
+ -Ddri3=true
+
+%meson_build
+
+%install
+%meson_install
+
+# Remove unwanted files/dirs
+rm $RPM_BUILD_ROOT%{_mandir}/man1/Xserver.1*
+rm -Rf $RPM_BUILD_ROOT%{_libdir}/xorg
+rm -Rf $RPM_BUILD_ROOT%{_includedir}/xorg
+rm -Rf $RPM_BUILD_ROOT%{_datadir}/aclocal
+rm -Rf $RPM_BUILD_ROOT%{_localstatedir}/lib/xkb
+
+%check
+desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop
+
+%files
+%{_bindir}/Xwayland
+%{_mandir}/man1/Xwayland.1*
+%{_datadir}/applications/org.freedesktop.Xwayland.desktop
+
+%files devel
+%{_libdir}/pkgconfig/xwayland.pc
+
+%changelog
+* Thu Oct 26 2023 Olivier Fourdan - 23.2.2-1
+- xwayland 23.2.2 - (#2246029)
+
+* Wed Oct 25 2023 Peter Hutterer - 23.2.1-2
+- Fix for CVE-2023-5367
+
+* Wed Sep 20 2023 Olivier Fourdan - 23.2.1-1
+- xwayland 23.2.1 - (#2239813)
+
+* Mon Sep 11 2023 Olivier Fourdan - 23.2.0-2
+- migrated to SPDX license
+
+* Wed Aug 16 2023 Olivier Fourdan - 23.2.0-1
+- xwayland 23.2.0
+
+* Wed Aug 2 2023 Olivier Fourdan - 23.1.99.902-1
+- xwayland 23.1.99.902 (xwayland 23.2.0 rc2)
+
+* Mon Jul 31 2023 Olivier Fourdan - 23.1.99.901-2
+- Fix devel package requires.
+
+* Wed Jul 19 2023 Olivier Fourdan - 23.1.99.901-1
+- xwayland 23.1.99.901 (xwayland 23.2.0 rc1)
+
+* Tue Jun 6 2023 Olivier Fourdan - 23.1.2-1
+- xwayland 23.1.2
+
+* Thu Apr 27 2023 Olivier Fourdan - 23.1.1-2
+- Fix spec file to build from git upstream - (#2190211)
+
+* Wed Mar 29 2023 Olivier Fourdan - 23.1.1-1
+- xwayland 23.1.1 - (#2182734)
+ CVE fix for: CVE-2023-1393
+
+* Wed Mar 22 2023 Olivier Fourdan - 23.1.0-1
+- xwayland 23.1.0 - (#2180913)
+
+* Thu Mar 9 2023 Olivier Fourdan - 23.0.99.902-1
+- xwayland 23.0.99.902 (xwayland 23.1.0 rc2) - (#2172415, #2173201)
+
+* Wed Feb 22 2023 Olivier Fourdan - 23.0.99.901-1
+- xwayland 23.0.99.901 (xwayland 23.1.0 rc1) - (#2172415)
+
+* Tue Feb 7 2023 Olivier Fourdan - 22.1.8-1
+- xwayland 22.1.8
+ Fixes CVE-2023-0494 (#2165995, #2167566, #2167734)
+
+* Sun Jan 29 2023 Stefan Bluhm - 22.1.7-4
+- Updated conditional Fedora statement.
+
+* Thu Jan 19 2023 Olivier Fourdan - 22.1.7-3
+- Use the recommended way to apply conditional patches without
+ conditionalizing the sources (for byte-swapped clients).
+
+* Tue Jan 17 2023 Olivier Fourdan - 22.1.7-2
+- Disallow byte-swapped clients on Fedora 38 and above (#2159489)
+
+* Mon Dec 19 2022 Olivier Fourdan - 22.1.7-1
+- xwayland 22.1.7
+
+* Wed Dec 14 2022 Peter Hutterer - 22.1.6-1
+- xwayland 22.1.6
+ Fixes CVE-2022-46340, CVE-2022-46341, CVE-2022-46342, CVE-2022-46343,
+ CVE-2022-46344, CVE-2022-4283
+
+* Wed Nov 2 2022 Olivier Fourdan - 22.1.5-1
+- xwayland 22.1.5 (#2139387)
+
+* Thu Oct 20 2022 Olivier Fourdan - 22.1.4-1
+- xwayland 22.1.4 (#2136518)
+
+* Sat Jul 23 2022 Fedora Release Engineering - 22.1.3-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild
+
+* Tue Jul 12 2022 Olivier Fourdan - 22.1.3-1
+- xwayland 22.1.3 - (#2106387)
+ Fix CVE-2022-2319/ZDI-CAN-16062, CVE-2022-2320/ZDI-CAN-16070
+
+* Wed May 25 2022 Olivier Fourdan - 22.1.2-1
+- xwayland 22.1.2 - (#2090172)
+
+* Thu Mar 31 2022 Olivier Fourdan - 22.1.1-1
+- xwayland 22.1.1 - (#2070435)
+
+* Wed Feb 16 2022 Olivier Fourdan - 22.1.0
+- xwayland 22.1.0 - (#2055270)
+
+* Wed Feb 2 2022 Olivier Fourdan - 22.0.99.902
+- xwayland 22.0.99.902 (xwayland 22.1.0 rc2) - (#2042521)
+
+* Tue Jan 25 2022 Olivier Fourdan - 22.0.99.901
+- xwayland 22.0.99.901 (xwayland 22.1.0 rc1) - (#2042521)
+
+* Sat Jan 22 2022 Fedora Release Engineering - 21.1.4-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild
+
+* Tue Dec 14 2021 Olivier Fourdan - 21.1.4
+- xwayland 21.1.4
+
+* Mon Nov 8 2021 Olivier Fourdan - 21.1.3
+- xwayland 21.1.3 - (#2016468)
+
+* Thu Oct 21 2021 Olivier Fourdan - 21.1.2.901-1
+- xwayland 21.1.2.901 (aka 21.1.3 RC1) - (#2015413)
+
+* Tue Sep 14 2021 Sahana Prasad - 21.1.2-3
+- Rebuilt with OpenSSL 3.0.0
+
+* Fri Jul 23 2021 Fedora Release Engineering - 21.1.2-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild
+
+* Fri Jul 9 2021 Olivier Fourdan - 21.1.2-1
+- xwayland 21.1.2
+
+* Thu Jul 1 2021 Olivier Fourdan - 21.1.1.901-1
+- xwayland 21.1.1.901
+
+* Mon Jun 21 2021 Olivier Fourdan - 21.1.1-3
+- Fix a use-after-free in the previous changes for GLX
+
+* Thu Jun 10 2021 Olivier Fourdan - 21.1.1-2
+- Backport fixes for GLX and EGLstream (#1948003)
+
+* Wed Apr 14 2021 Olivier Fourdan - 21.1.1-1
+- xwayland 21.1.1 (CVE-2021-3472 / ZDI-CAN-1259)
+
+* Thu Mar 18 2021 Olivier Fourdan - 21.1.0-1
+- xwayland 21.1.0
+
+* Thu Mar 4 2021 Olivier Fourdan - 21.0.99.902-1
+- xwayland 21.0.99.902
+- Remove xdmcp, udev, udev_kms build options
+- Stop overriding the vendor name, same as xorg-x11-server
+
+* Thu Feb 18 2021 Olivier Fourdan - 21.0.99.901-1
+- xwayland 21.0.99.901
+
+* Mon Feb 1 2021 Olivier Fourdan - 1.20.99.1-0.1.20210201git5429791
+- Initial import (#1912335).
diff --git a/spec_files/xorg-x11-server-Xwayland/xorg-x11-server-Xwayland.spec b/spec_files/xorg-x11-server-Xwayland/xorg-x11-server-Xwayland.spec
index 7dd69820..e56eaa94 100644
--- a/spec_files/xorg-x11-server-Xwayland/xorg-x11-server-Xwayland.spec
+++ b/spec_files/xorg-x11-server-Xwayland/xorg-x11-server-Xwayland.spec
@@ -19,7 +19,6 @@ Source0: https://gitlab.freedesktop.org/xorg/%{pkgname}/-/archive/%{commit}/%{
Source0: https://www.x.org/pub/individual/xserver/%{pkgname}-%{xwayland_version}.tar.xz
%endif
-Patch0: 967.patch
Patch1: 0001-Valve.patch
License: MIT
diff --git a/system_files/deck/shared/usr/share/ublue-os/firstboot/yafti.yml b/system_files/deck/shared/usr/share/ublue-os/firstboot/yafti.yml
index 7cfed7ca..50cb5e37 100644
--- a/system_files/deck/shared/usr/share/ublue-os/firstboot/yafti.yml
+++ b/system_files/deck/shared/usr/share/ublue-os/firstboot/yafti.yml
@@ -9,7 +9,7 @@ screens:
title: "Welcome to Bazzite (Steam Deck & HTPC Edition)"
icon: "/usr/share/ublue-os/bazzite/logo.svg"
description: |
- Configure your system to get started. Completion of this process is required for Game mode to function.
+ Configure your system to get started. This utility can be re-opened at any time, so don't feel like you have to get it perfect your first go-through.
configure-bazzite:
source: yafti.screen.package
values:
diff --git a/system_files/desktop/shared/usr/lib/systemd/system/sunshine-workaround.service b/system_files/desktop/shared/usr/lib/systemd/system/sunshine-workaround.service
index 0f564503..c4b1b737 100644
--- a/system_files/desktop/shared/usr/lib/systemd/system/sunshine-workaround.service
+++ b/system_files/desktop/shared/usr/lib/systemd/system/sunshine-workaround.service
@@ -6,13 +6,13 @@ After=local-fs.target
[Service]
Type=oneshot
# Copy if it doesn't exist
-ExecStartPre=/usr/bin/bash -c "[ -x /usr/local/bin/.sunshine ] || /usr/bin/cp $(readlink /usr/bin/sunshine) /usr/local/bin/.sunshine"
+ExecStartPre=/usr/bin/bash -c "[ -x /usr/local/bin/.sunshine ] || /usr/bin/cp $(readlink -f /usr/bin/sunshine) /usr/local/bin/.sunshine"
# This is faster than using .mount unit. Also allows for the previous line/cleanup
-ExecStartPre=/usr/bin/mount --bind /usr/local/bin/.sunshine /usr/bin/sunshine
+ExecStartPre=/usr/bin/bash -c "/usr/bin/mount --bind /usr/local/bin/.sunshine $(readlink -f /usr/bin/sunshine)"
# Fix caps
-ExecStart=/usr/sbin/setcap cap_sys_admin+p /usr/bin/sunshine
+ExecStart=/usr/bin/bash -c "/usr/sbin/setcap cap_sys_admin+p $(readlink -f /usr/bin/sunshine)"
# Clean-up after ourselves
-ExecStop=/usr/bin/umount /usr/bin/sunshine
+ExecStop=/usr/bin/bash -c "/usr/bin/umount $(readlink -f /usr/bin/sunshine)"
ExecStop=/usr/bin/rm /usr/local/bin/.sunshine
RemainAfterExit=yes
diff --git a/system_files/desktop/shared/usr/libexec/bazzite-hardware-setup b/system_files/desktop/shared/usr/libexec/bazzite-hardware-setup
index 45d9c1c2..ba142fec 100755
--- a/system_files/desktop/shared/usr/libexec/bazzite-hardware-setup
+++ b/system_files/desktop/shared/usr/libexec/bazzite-hardware-setup
@@ -179,16 +179,15 @@ if [[ $IMAGE_NAME =~ "deck" || $IMAGE_NAME =~ "ally" || $IMAGE_NAME =~ "framegam
systemctl enable --now jupiter-fan-control.service
systemctl enable --now vpower.service
+ systemctl enable --now ds-inhibit.service
else
echo "Generic device detected. Performing setup..."
if /usr/libexec/hardware/hhd-supported-hardware; then
- echo "HHD supported handheld detected, disabling handycon & ds-inhibit..."
+ echo "HHD supported handheld detected, disabling handycon"
systemctl disable --now handycon.service
- systemctl disable --now ds-inhibit.service
elif /usr/libexec/hardware/handycon-supported-hardware; then
- echo "HandyGCCS supported handheld detected, enabling handycon & ds-inhibit..."
+ echo "HandyGCCS supported handheld detected, enabling handycon"
systemctl enable --now handycon.service
- systemctl enable --now ds-inhbit.service
fi
systemctl disable --now jupiter-fan-control.service
systemctl disable --now vpower.service
diff --git a/system_files/desktop/shared/usr/share/ublue-os/firstboot/yafti.yml b/system_files/desktop/shared/usr/share/ublue-os/firstboot/yafti.yml
index 810d32f3..74a3213e 100644
--- a/system_files/desktop/shared/usr/share/ublue-os/firstboot/yafti.yml
+++ b/system_files/desktop/shared/usr/share/ublue-os/firstboot/yafti.yml
@@ -9,7 +9,7 @@ screens:
title: "Welcome to Bazzite"
icon: "/usr/share/ublue-os/bazzite/logo.svg"
description: |
- Configure your system to get started
+ Configure your system to get started. This utility can be re-opened at any time, so don't feel like you have to get it perfect your first go-through.
configure-bazzite:
source: yafti.screen.package
values:
diff --git a/system_files/desktop/shared/usr/share/ublue-os/motd/tips/10-ublue.md b/system_files/desktop/shared/usr/share/ublue-os/motd/tips/10-ublue.md
index 467497c3..74e38380 100644
--- a/system_files/desktop/shared/usr/share/ublue-os/motd/tips/10-ublue.md
+++ b/system_files/desktop/shared/usr/share/ublue-os/motd/tips/10-ublue.md
@@ -1,6 +1,7 @@
It is **always** better to install packages with Distrobox rather than layer them with rpm-ostree. `ujust distrobox` makes it easy! - [More about supported packages](https://universal-blue.discourse.group/docs?topic=35)
Packages installed in Distrobox can be exported to appear like any other application - [View documentation](https://github.com/89luca89/distrobox/blob/main/docs/usage/distrobox-export.md).
*Update break something?* You can roll back and pin the previous release or rebase by build date - [View our guide](https://universal-blue.discourse.group/docs?topic=36).
-*This isn't a distro*, this is a custom image built on Fedora technology - [View our mission](https://universal-blue.org/mission/)
+*This isn't a distro*, this is a custom image built on Fedora Atomic Desktop technology - [View our mission](https://universal-blue.org/mission/)
*Looking to dual-boot with Windows?* [Check out our dual booting guide](https://universal-blue.discourse.group/docs?topic=129).
**Support the app store!** [Donate to Flatpak](https://opencollective.com/flatpak)
+**H.264 hardware acceleration is supported out of the box.** No tweaks necessary!
diff --git a/system_files/desktop/shared/usr/share/ublue-os/motd/tips/20-bazzite.md b/system_files/desktop/shared/usr/share/ublue-os/motd/tips/20-bazzite.md
index 8c5bbfc4..9ef11886 100644
--- a/system_files/desktop/shared/usr/share/ublue-os/motd/tips/20-bazzite.md
+++ b/system_files/desktop/shared/usr/share/ublue-os/motd/tips/20-bazzite.md
@@ -8,5 +8,5 @@ Discover Overlay is preinstalled, allowing Discord to overlay your games during
Bazzite uses ZSTD compression in BTRFS by default, and deduplicates files across your entire drive. **More space for your games!**
*Have a large library of ROMs to manage?* ROM Properties Page shell extension is installed by default and makes it much easier, with thumbnails and additional info for all of your files.
*Need more control over your Flatpaks?* Check out the Warehouse and Flatseal applications to manage them.
-*Want more tips and tricks?* - [View the Miscellaneous Documentation](https://universal-blue.discourse.group/docs?topic=287)
+*Want more tips and tricks?* - [View Documentation](https://universal-blue.discourse.group/docs?topic=287)
*Desktop users: Want a to easily customize MangoHud and vkBasalt?* Use the GOverlay application as a graphical user interface to adjust settings.