Mesa (main): radv: allow applications to dynamically change RADV_FORCE_VRS
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Wed Feb 16 08:49:13 UTC 2022
Module: Mesa
Branch: main
Commit: c50557d9612a975fd8983438a80ea7a1208698fa
URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=c50557d9612a975fd8983438a80ea7a1208698fa
Author: Samuel Pitoiset <samuel.pitoiset at gmail.com>
Date: Tue Jan 25 17:05:17 2022 +0100
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 at gmail.com>
Reviewed-by: Bas Nieuwenhuizen <bas at basnieuwenhuizen.nl>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/14713>
---
src/amd/vulkan/radv_device.c | 109 +++++++++++++++++++++++++++++++++++++++++-
src/amd/vulkan/radv_private.h | 10 +++-
2 files changed, 117 insertions(+), 2 deletions(-)
diff --git a/src/amd/vulkan/radv_device.c b/src/amd/vulkan/radv_device.c
index aba59b8f58b..26fed37adac 100644
--- a/src/amd/vulkan/radv_device.c
+++ b/src/amd/vulkan/radv_device.c
@@ -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);
diff --git a/src/amd/vulkan/radv_private.h b/src/amd/vulkan/radv_private.h
index b63166653b6..39b006ed838 100644
--- a/src/amd/vulkan/radv_private.h
+++ b/src/amd/vulkan/radv_private.h
@@ -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. */
More information about the mesa-commit
mailing list