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(&notifier->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