mirror of
https://github.com/ublue-os/bazzite.git
synced 2025-01-16 16:10:58 +00:00
244 lines
8.1 KiB
Diff
244 lines
8.1 KiB
Diff
diff --git a/src/loader/loader_dri3_helper.c b/src/loader/loader_dri3_helper.c
|
|
index 11bf647..ffa3a02 100644
|
|
--- a/src/loader/loader_dri3_helper.c
|
|
+++ b/src/loader/loader_dri3_helper.c
|
|
@@ -37,13 +37,14 @@
|
|
#include "loader_dri_helper.h"
|
|
#include "loader_dri3_helper.h"
|
|
#include "util/macros.h"
|
|
+#include "util/simple_mtx.h"
|
|
#include "drm-uapi/drm_fourcc.h"
|
|
|
|
/**
|
|
* A cached blit context.
|
|
*/
|
|
struct loader_dri3_blit_context {
|
|
- mtx_t mtx;
|
|
+ simple_mtx_t mtx;
|
|
__DRIcontext *ctx;
|
|
__DRIscreen *cur_screen;
|
|
const __DRIcoreExtension *core;
|
|
@@ -51,7 +52,7 @@ struct loader_dri3_blit_context {
|
|
|
|
/* For simplicity we maintain the cache only for a single screen at a time */
|
|
static struct loader_dri3_blit_context blit_context = {
|
|
- _MTX_INITIALIZER_NP, NULL
|
|
+ SIMPLE_MTX_INITIALIZER, NULL
|
|
};
|
|
|
|
static void
|
|
@@ -162,7 +163,7 @@ static bool loader_dri3_have_image_blit(const struct loader_dri3_drawable *draw)
|
|
static __DRIcontext *
|
|
loader_dri3_blit_context_get(struct loader_dri3_drawable *draw)
|
|
{
|
|
- mtx_lock(&blit_context.mtx);
|
|
+ simple_mtx_lock(&blit_context.mtx);
|
|
|
|
if (blit_context.ctx && blit_context.cur_screen != draw->dri_screen_render_gpu) {
|
|
blit_context.core->destroyContext(blit_context.ctx);
|
|
@@ -186,7 +187,7 @@ loader_dri3_blit_context_get(struct loader_dri3_drawable *draw)
|
|
static void
|
|
loader_dri3_blit_context_put(void)
|
|
{
|
|
- mtx_unlock(&blit_context.mtx);
|
|
+ simple_mtx_unlock(&blit_context.mtx);
|
|
}
|
|
|
|
/**
|
|
@@ -288,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)
|
|
{
|
|
@@ -302,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
|
|
@@ -434,6 +461,12 @@ loader_dri3_drawable_init(xcb_connection_t *conn,
|
|
if (!draw->adaptive_sync)
|
|
set_adaptive_sync_property(conn, draw->drawable, false);
|
|
|
|
+ draw->orig_swap_interval = draw->swap_interval;
|
|
+
|
|
+ unsigned gamescope_override = gamescope_swapchain_override();
|
|
+ if (gamescope_override == 1)
|
|
+ draw->swap_interval = 1;
|
|
+
|
|
draw->swap_interval = dri_get_initial_swap_interval(draw->dri_screen_render_gpu,
|
|
draw->ext->config);
|
|
|
|
@@ -1091,6 +1124,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()
|
|
@@ -2357,12 +2396,12 @@ loader_dri3_swapbuffer_barrier(struct loader_dri3_drawable *draw)
|
|
void
|
|
loader_dri3_close_screen(__DRIscreen *dri_screen)
|
|
{
|
|
- mtx_lock(&blit_context.mtx);
|
|
+ simple_mtx_lock(&blit_context.mtx);
|
|
if (blit_context.ctx && blit_context.cur_screen == dri_screen) {
|
|
blit_context.core->destroyContext(blit_context.ctx);
|
|
blit_context.ctx = NULL;
|
|
}
|
|
- mtx_unlock(&blit_context.mtx);
|
|
+ simple_mtx_unlock(&blit_context.mtx);
|
|
}
|
|
|
|
/**
|
|
diff --git a/src/loader/loader_dri3_helper.h b/src/loader/loader_dri3_helper.h
|
|
index 1fd340b..b8f5eaa 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 81779a3..18c9fd9 100644
|
|
--- a/src/loader/meson.build
|
|
+++ b/src/loader/meson.build
|
|
@@ -28,7 +28,7 @@ if with_platform_x11 and with_dri3
|
|
include_directories : [inc_include, inc_src],
|
|
dependencies : [
|
|
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 a423559..5ed89cb 100644
|
|
--- a/src/vulkan/wsi/wsi_common_x11.c
|
|
+++ b/src/vulkan/wsi/wsi_common_x11.c
|
|
@@ -42,6 +42,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"
|
|
@@ -198,6 +199,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)
|
|
@@ -1074,6 +1099,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,
|
|
@@ -1802,6 +1829,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];
|
|
@@ -2554,6 +2587,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);
|
|
|
|
@@ -2666,6 +2703,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;
|