chore: Update to Mesa 24 with Nobara & Valve patches

This commit is contained in:
Kyle Gospodnetich 2024-04-17 08:50:44 -07:00
parent bbcba4f65d
commit e65500efa4
6 changed files with 1751 additions and 351 deletions

View File

@ -0,0 +1,41 @@
From 97f5721bfc4bbbce5c3a39cf48eeb6ad1fb9cf97 Mon Sep 17 00:00:00 2001
From: Jose Maria Casanova Crespo <jmcasanova@igalia.com>
Date: Mon, 15 Apr 2024 12:22:31 +0200
Subject: [PATCH] broadcom/compiler: needs_quad_helper_invocation enable
PER_QUAD TMU access
We take advantage of the needs_quad_helper_invocation information to
only enable the PER_QUAD TMU access on Fragment Shaders when it is needed.
PER_QUAD access is also disabled on stages different to fragment shader.
Being enabled was causing MMU errors when TMU was doing indexed by vertexid
reads on disabled lanes on vertex stage. This problem was exercised by some
shaders from the GTK new GSK_RENDERER=ngl that were accessing a constant buffer
offset[6], but having PER_QUAD enabled on the TMU access by VertexID was
doing hidden incorrect access to not existing vertex 6 and 7 as TMU was
accessing the full quad.
cc: mesa-stable
Reviewed-by: Iago Toral Quiroga <itoral@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/28740>
---
src/broadcom/compiler/nir_to_vir.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/broadcom/compiler/nir_to_vir.c b/src/broadcom/compiler/nir_to_vir.c
index ff98e4b5961..0303ca96103 100644
--- a/src/broadcom/compiler/nir_to_vir.c
+++ b/src/broadcom/compiler/nir_to_vir.c
@@ -656,6 +656,8 @@ ntq_emit_tmu_general(struct v3d_compile *c, nir_intrinsic_instr *instr,
*/
uint32_t perquad =
is_load && !vir_in_nonuniform_control_flow(c) &&
+ c->s->info.stage == MESA_SHADER_FRAGMENT &&
+ c->s->info.fs.needs_quad_helper_invocations &&
!c->emitted_discard ?
GENERAL_TMU_LOOKUP_PER_QUAD :
GENERAL_TMU_LOOKUP_PER_PIXEL;
--
2.44.0

1666
spec_files/mesa/25352.patch Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,204 +0,0 @@
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

View File

@ -1,42 +0,0 @@
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: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/26927>
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;
}''',

View File

@ -5,10 +5,11 @@
%global with_va 1
%if !0%{?rhel}
%global with_nine 1
%global with_nvk %{with vulkan_hw}
%global with_omx 1
%global with_opencl 1
%endif
%global base_vulkan ,amd,nouveau-experimental
%global base_vulkan ,amd
%endif
%ifarch %{ix86} x86_64
@ -34,7 +35,7 @@
%global with_tegra 1
%global with_v3d 1
%global with_xa 1
%global extra_platform_vulkan ,broadcom,freedreno,panfrost
%global extra_platform_vulkan ,broadcom,freedreno,panfrost,imagination-experimental
%endif
%ifnarch s390x
@ -57,13 +58,13 @@
%bcond_with valgrind
%endif
%global vulkan_drivers swrast%{?base_vulkan}%{?intel_platform_vulkan}%{?extra_platform_vulkan}
%global vulkan_drivers swrast%{?base_vulkan}%{?intel_platform_vulkan}%{?extra_platform_vulkan}%{?with_nvk:,nouveau-experimental}
Name: mesa
Summary: Mesa graphics libraries
%global ver 23.3.6
%global ver 24.0.5
Version: %{lua:ver = string.gsub(rpm.expand("%{ver}"), "-", "~"); print(ver)}
Release: 100.bazzite.{{{ git_dir_version }}}
Release: %autorelease
License: MIT AND BSD-3-Clause AND SGI-B-2.0
URL: http://www.mesa3d.org
@ -74,15 +75,18 @@ Source0: https://archive.mesa3d.org/mesa-%{ver}.tar.xz
Source1: Mesa-MLAA-License-Clarification-Email.txt
Patch10: gnome-shell-glthread-disable.patch
Patch12: mesa-meson-c99.patch
# Backport of https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/28740
# to fix rendering issues using GTK's GSK_RENDERER=ngl on Raspberry Pi:
# https://bugzilla.redhat.com/show_bug.cgi?id=2269412
Patch11: 0001-broadcom-compiler-needs_quad_helper_invocation-enabl.patch
# https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/26105/
Patch30: 26105.patch
# https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/25352
Patch20: 25352.patch
# https://gitlab.com/evlaV/mesa/
Patch40: valve.patch
Patch21: valve.patch
BuildRequires: meson >= 1.2.0
BuildRequires: meson >= 1.3.0
BuildRequires: gcc
BuildRequires: gcc-c++
BuildRequires: gettext
@ -140,7 +144,7 @@ BuildRequires: pkgconfig(libomxil-bellagio)
BuildRequires: pkgconfig(libelf)
BuildRequires: pkgconfig(libglvnd) >= 1.3.2
BuildRequires: llvm-devel >= 7.0.0
%if 0%{?with_opencl}
%if 0%{?with_opencl} || 0%{?with_nvk}
BuildRequires: clang-devel
BuildRequires: bindgen
BuildRequires: rust-packaging
@ -148,6 +152,12 @@ BuildRequires: pkgconfig(libclc)
BuildRequires: pkgconfig(SPIRV-Tools)
BuildRequires: pkgconfig(LLVMSPIRVLib)
%endif
%if 0%{?with_nvk}
BuildRequires: (crate(proc-macro2) >= 1.0.56 with crate(proc-macro2) < 2)
BuildRequires: (crate(quote) >= 1.0.25 with crate(quote) < 2)
BuildRequires: (crate(syn/clone-impls) >= 2.0.15 with crate(syn/clone-impls) < 3)
BuildRequires: (crate(unicode-ident) >= 1.0.6 with crate(unicode-ident) < 2)
%endif
%if %{with valgrind}
BuildRequires: pkgconfig(valgrind)
%endif
@ -371,6 +381,18 @@ cp %{SOURCE1} docs/
# ensure standard Rust compiler flags are set
export RUSTFLAGS="%build_rustflags"
%if 0%{?with_nvk}
export MESON_PACKAGE_CACHE_DIR="%{cargo_registry}/"
# So... Meson can't actually find them without tweaks
%define inst_crate_nameversion() %(basename %{cargo_registry}/%{1}-*)
%define rewrite_wrap_file() sed -e "/source.*/d" -e "s/%{1}-.*/%{inst_crate_nameversion %{1}}/" -i subprojects/%{1}.wrap
%rewrite_wrap_file proc-macro2
%rewrite_wrap_file quote
%rewrite_wrap_file syn
%rewrite_wrap_file unicode-ident
%endif
# 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
@ -411,7 +433,6 @@ export RUSTFLAGS="%build_rustflags"
-Dllvm=enabled \
-Dshared-llvm=enabled \
-Dvalgrind=%{?with_valgrind:enabled}%{!?with_valgrind:disabled} \
-Dxlib-lease=enabled \
-Dbuild-tests=false \
-Dselinux=true \
%if !0%{?with_libunwind}
@ -449,11 +470,6 @@ for i in libOSMesa*.so libGL.so ; do
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
@ -541,9 +557,7 @@ rm -Rf %{buildroot}%{_datadir}/drirc.d/00-mesa-defaults.conf
%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
@ -609,20 +623,26 @@ rm -Rf %{buildroot}%{_datadir}/drirc.d/00-mesa-defaults.conf
%if 0%{?with_kmsro}
%{_libdir}/dri/armada-drm_dri.so
%{_libdir}/dri/exynos_dri.so
%{_libdir}/dri/gm12u320_dri.so
%{_libdir}/dri/hdlcd_dri.so
%{_libdir}/dri/hx8357d_dri.so
%{_libdir}/dri/ili9163_dri.so
%{_libdir}/dri/ili9225_dri.so
%{_libdir}/dri/ili9341_dri.so
%{_libdir}/dri/ili9486_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/panel-mipi-dbi_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/sti_dri.so
%{_libdir}/dri/sun4i-drm_dri.so
%{_libdir}/dri/udl_dri.so
%endif
%if 0%{?with_vulkan_hw}
%{_libdir}/dri/zink_dri.so
@ -664,12 +684,12 @@ rm -Rf %{buildroot}%{_datadir}/drirc.d/00-mesa-defaults.conf
%{_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
%if 0%{?with_nvk}
%{_libdir}/libvulkan_nouveau.so
%{_datadir}/vulkan/icd.d/nouveau_icd.*.json
%endif
%ifarch %{ix86} x86_64
%{_libdir}/libvulkan_intel.so
%{_datadir}/vulkan/icd.d/intel_icd.*.json
@ -683,6 +703,9 @@ rm -Rf %{buildroot}%{_datadir}/drirc.d/00-mesa-defaults.conf
%{_datadir}/vulkan/icd.d/freedreno_icd.*.json
%{_libdir}/libvulkan_panfrost.so
%{_datadir}/vulkan/icd.d/panfrost_icd.*.json
%{_libdir}/libpowervr_rogue.so
%{_libdir}/libvulkan_powervr_mesa.so
%{_datadir}/vulkan/icd.d/powervr_mesa_icd.*.json
%endif
%endif

View File

@ -140,90 +140,6 @@ index 35f9991ba2f..154cf809a69 100644
],
build_by_default : false,
)
diff --git a/src/vulkan/wsi/wsi_common_x11.c b/src/vulkan/wsi/wsi_common_x11.c
index 72ff193d30a..996fc230673 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)
@@ -1103,6 +1128,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,
@@ -1852,6 +1879,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];
@@ -2610,6 +2643,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);
@@ -2722,6 +2759,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