mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-23 22:00:13 +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>
|
#include <sys/sysmacros.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef _WIN32
|
||||||
|
#include <sys/inotify.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "util/debug.h"
|
#include "util/debug.h"
|
||||||
#include "util/disk_cache.h"
|
#include "util/disk_cache.h"
|
||||||
#include "radv_cs.h"
|
#include "radv_cs.h"
|
||||||
|
|
@ -2942,6 +2946,12 @@ radv_parse_vrs_rates(const char *str)
|
||||||
return RADV_FORCE_VRS_1x1;
|
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
|
static enum radv_force_vrs
|
||||||
radv_parse_force_vrs_config_file(const char *config_file)
|
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;
|
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
|
VKAPI_ATTR VkResult VKAPI_CALL
|
||||||
radv_CreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo *pCreateInfo,
|
radv_CreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo *pCreateInfo,
|
||||||
const VkAllocationCallbacks *pAllocator, VkDevice *pDevice)
|
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 (device->physical_device->rad_info.chip_class >= GFX10_3) {
|
||||||
if (getenv("RADV_FORCE_VRS_CONFIG_FILE")) {
|
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);
|
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")) {
|
} else if (getenv("RADV_FORCE_VRS")) {
|
||||||
const char *vrs_rates = getenv("RADV_FORCE_VRS");
|
const char *vrs_rates = getenv("RADV_FORCE_VRS");
|
||||||
|
|
||||||
|
|
@ -3328,6 +3434,7 @@ fail:
|
||||||
if (device->gfx_init)
|
if (device->gfx_init)
|
||||||
device->ws->buffer_destroy(device->ws, 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_vs_prologs(device);
|
||||||
radv_device_finish_border_color(device);
|
radv_device_finish_border_color(device);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -748,6 +748,13 @@ enum radv_force_vrs {
|
||||||
RADV_FORCE_VRS_1x2,
|
RADV_FORCE_VRS_1x2,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct radv_notifier {
|
||||||
|
int fd;
|
||||||
|
int watch;
|
||||||
|
bool quit;
|
||||||
|
thrd_t thread;
|
||||||
|
};
|
||||||
|
|
||||||
struct radv_device {
|
struct radv_device {
|
||||||
struct vk_device vk;
|
struct vk_device vk;
|
||||||
|
|
||||||
|
|
@ -849,7 +856,8 @@ struct radv_device {
|
||||||
uint64_t allocated_memory_size[VK_MAX_MEMORY_HEAPS];
|
uint64_t allocated_memory_size[VK_MAX_MEMORY_HEAPS];
|
||||||
mtx_t overallocation_mutex;
|
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;
|
enum radv_force_vrs force_vrs;
|
||||||
|
|
||||||
/* Depth image for VRS when not bound by the app. */
|
/* Depth image for VRS when not bound by the app. */
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue