Skip to content

Commit

Permalink
STEAMOS: Dynamic swapchain override for gamescope limiter for DRI3 only
Browse files Browse the repository at this point in the history
The original patch (from Bas) contained WSI VK support too but it's
been removed because the Gamescope WSI layer already handles that.

Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
  • Loading branch information
hakzsam committed Oct 31, 2024
1 parent bdb07d3 commit 27482ce
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 2 deletions.
42 changes: 40 additions & 2 deletions src/gallium/frontends/dri/loader_dri3_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,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)
{
Expand All @@ -288,10 +312,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
Expand Down Expand Up @@ -420,6 +446,12 @@ loader_dri3_drawable_init(xcb_connection_t *conn,

draw->swap_interval = dri_get_initial_swap_interval(draw->dri_screen_render_gpu);

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 */
Expand Down Expand Up @@ -1064,6 +1096,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()
Expand Down
1 change: 1 addition & 0 deletions src/gallium/frontends/dri/loader_dri3_helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ struct loader_dri3_drawable {
bool block_on_depleted_buffers;
bool queries_buffer_age;
int swap_interval;
int orig_swap_interval;

const struct loader_dri3_vtable *vtable;

Expand Down

0 comments on commit 27482ce

Please sign in to comment.