mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-23 19:50:11 +01:00
radv: allow applications to dynamically change RADV_FORCE_VRS
This introduces inotify support in RADV to handle changes from the RADV_FORCE_VRS_CONFIG_FILE. This is similar to MangoHUD. I'm personally not sure it's the best solution but let's try this way and change it later if we have issues (or if we have a lightweight solution). Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com> Reviewed-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/14713>
This commit is contained in:
parent
5e2d9202e2
commit
c50557d961
2 changed files with 117 additions and 2 deletions
|
|
@ -35,6 +35,10 @@
|
|||
#include <sys/sysmacros.h>
|
||||
#endif
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <sys/inotify.h>
|
||||
#endif
|
||||
|
||||
#include "util/debug.h"
|
||||
#include "util/disk_cache.h"
|
||||
#include "radv_cs.h"
|
||||
|
|
@ -2942,6 +2946,12 @@ radv_parse_vrs_rates(const char *str)
|
|||
return RADV_FORCE_VRS_1x1;
|
||||
}
|
||||
|
||||
static const char *
|
||||
radv_get_force_vrs_config_file(void)
|
||||
{
|
||||
return getenv("RADV_FORCE_VRS_CONFIG_FILE");
|
||||
}
|
||||
|
||||
static enum radv_force_vrs
|
||||
radv_parse_force_vrs_config_file(const char *config_file)
|
||||
{
|
||||
|
|
@ -2964,6 +2974,98 @@ radv_parse_force_vrs_config_file(const char *config_file)
|
|||
return force_vrs;
|
||||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
|
||||
#define BUF_LEN ((10 * (sizeof(struct inotify_event) + NAME_MAX + 1)))
|
||||
|
||||
static int
|
||||
radv_notifier_thread_run(void *data)
|
||||
{
|
||||
struct radv_device *device = data;
|
||||
struct radv_notifier *notifier = &device->notifier;
|
||||
char buf[BUF_LEN];
|
||||
|
||||
while (!notifier->quit) {
|
||||
const char *file = radv_get_force_vrs_config_file();
|
||||
struct timespec tm = { .tv_nsec = 100000000 }; /* 1OOms */
|
||||
int length, i = 0;
|
||||
|
||||
length = read(notifier->fd, buf, BUF_LEN);
|
||||
while (i < length) {
|
||||
struct inotify_event *event = (struct inotify_event *)&buf[i];
|
||||
|
||||
i += sizeof(struct inotify_event) + event->len;
|
||||
if (event->mask & IN_MODIFY || event->mask & IN_DELETE_SELF) {
|
||||
/* Sleep 100ms for editors that use a temporary file and delete the original. */
|
||||
thrd_sleep(&tm, NULL);
|
||||
device->force_vrs = radv_parse_force_vrs_config_file(file);
|
||||
|
||||
fprintf(stderr, "radv: Updated the per-vertex VRS rate to '%d'.\n", device->force_vrs);
|
||||
|
||||
if (event->mask & IN_DELETE_SELF) {
|
||||
inotify_rm_watch(notifier->fd, notifier->watch);
|
||||
notifier->watch = inotify_add_watch(notifier->fd, file, IN_MODIFY | IN_DELETE_SELF);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
thrd_sleep(&tm, NULL);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static int
|
||||
radv_device_init_notifier(struct radv_device *device)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return true;
|
||||
#else
|
||||
struct radv_notifier *notifier = &device->notifier;
|
||||
const char *file = radv_get_force_vrs_config_file();
|
||||
int ret;
|
||||
|
||||
notifier->fd = inotify_init1(IN_NONBLOCK);
|
||||
if (notifier->fd < 0)
|
||||
return false;
|
||||
|
||||
notifier->watch = inotify_add_watch(notifier->fd, file, IN_MODIFY | IN_DELETE_SELF);
|
||||
if (notifier->watch < 0)
|
||||
goto fail_watch;
|
||||
|
||||
ret = thrd_create(¬ifier->thread, radv_notifier_thread_run, device);
|
||||
if (ret)
|
||||
goto fail_thread;
|
||||
|
||||
return true;
|
||||
|
||||
fail_thread:
|
||||
inotify_rm_watch(notifier->fd, notifier->watch);
|
||||
fail_watch:
|
||||
close(notifier->fd);
|
||||
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
radv_device_finish_notifier(struct radv_device *device)
|
||||
{
|
||||
#ifndef _WIN32
|
||||
struct radv_notifier *notifier = &device->notifier;
|
||||
|
||||
if (!notifier->thread)
|
||||
return;
|
||||
|
||||
notifier->quit = true;
|
||||
thrd_join(notifier->thread, NULL);
|
||||
inotify_rm_watch(notifier->fd, notifier->watch);
|
||||
close(notifier->fd);
|
||||
#endif
|
||||
}
|
||||
|
||||
VKAPI_ATTR VkResult VKAPI_CALL
|
||||
radv_CreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo *pCreateInfo,
|
||||
const VkAllocationCallbacks *pAllocator, VkDevice *pDevice)
|
||||
|
|
@ -3253,9 +3355,13 @@ radv_CreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo *pCr
|
|||
|
||||
if (device->physical_device->rad_info.chip_class >= GFX10_3) {
|
||||
if (getenv("RADV_FORCE_VRS_CONFIG_FILE")) {
|
||||
const char *file = getenv("RADV_FORCE_VRS_CONFIG_FILE");
|
||||
const char *file = radv_get_force_vrs_config_file();
|
||||
|
||||
device->force_vrs = radv_parse_force_vrs_config_file(file);
|
||||
|
||||
if (!radv_device_init_notifier(device)) {
|
||||
fprintf(stderr, "radv: Failed to initialize the notifier for RADV_FORCE_VRS_CONFIG_FILE!\n");
|
||||
}
|
||||
} else if (getenv("RADV_FORCE_VRS")) {
|
||||
const char *vrs_rates = getenv("RADV_FORCE_VRS");
|
||||
|
||||
|
|
@ -3328,6 +3434,7 @@ fail:
|
|||
if (device->gfx_init)
|
||||
device->ws->buffer_destroy(device->ws, device->gfx_init);
|
||||
|
||||
radv_device_finish_notifier(device);
|
||||
radv_device_finish_vs_prologs(device);
|
||||
radv_device_finish_border_color(device);
|
||||
|
||||
|
|
|
|||
|
|
@ -748,6 +748,13 @@ enum radv_force_vrs {
|
|||
RADV_FORCE_VRS_1x2,
|
||||
};
|
||||
|
||||
struct radv_notifier {
|
||||
int fd;
|
||||
int watch;
|
||||
bool quit;
|
||||
thrd_t thread;
|
||||
};
|
||||
|
||||
struct radv_device {
|
||||
struct vk_device vk;
|
||||
|
||||
|
|
@ -849,7 +856,8 @@ struct radv_device {
|
|||
uint64_t allocated_memory_size[VK_MAX_MEMORY_HEAPS];
|
||||
mtx_t overallocation_mutex;
|
||||
|
||||
/* Whether the user forced VRS rates on GFX10.3+. */
|
||||
/* RADV_FORCE_VRS. */
|
||||
struct radv_notifier notifier;
|
||||
enum radv_force_vrs force_vrs;
|
||||
|
||||
/* Depth image for VRS when not bound by the app. */
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue