From a9f70c9e9f37687e44ffa374866063c8a420d73a Mon Sep 17 00:00:00 2001 From: wheaney <42350981+wheaney@users.noreply.github.com> Date: Fri, 22 Sep 2023 22:59:10 -0700 Subject: [PATCH] Add support for runtime uniform variables, using shared memory for cross-process communication --- src/reshade_uniforms.cpp | 65 ++++++++++++++++++++++++++++++++++++++++ src/reshade_uniforms.hpp | 14 +++++++++ 2 files changed, 79 insertions(+) diff --git a/src/reshade_uniforms.cpp b/src/reshade_uniforms.cpp index b66670d8..2c7cee66 100644 --- a/src/reshade_uniforms.cpp +++ b/src/reshade_uniforms.cpp @@ -4,11 +4,14 @@ #include #include #include +#include #include #include "logger.hpp" +const std::string defaultRuntimePathnamePrefix = "/tmp/shader_runtime_"; + namespace vkBasalt { void enumerateReshadeUniforms(reshadefx::module module) @@ -76,6 +79,10 @@ namespace vkBasalt { uniforms.push_back(std::shared_ptr(new DepthUniform(uniform))); } + else if (!source.empty()) + { + uniforms.push_back(std::shared_ptr(new RuntimeUniform(uniform))); + } } return uniforms; } @@ -380,4 +387,62 @@ namespace vkBasalt DepthUniform::~DepthUniform() { } + + ////////////////////////////////////////////////////////////////////////////////////////////////////////// + RuntimeUniform::RuntimeUniform(reshadefx::uniform_info uniformInfo) + { + auto source = std::find_if(uniformInfo.annotations.begin(), uniformInfo.annotations.end(), [](const auto& a) { return a.name == "source"; }); + defaultValue = 0.0; + if (auto defaultValueAnnotation = + std::find_if(uniformInfo.annotations.begin(), uniformInfo.annotations.end(), [](const auto& a) { return a.name == "defaultValue"; }); + defaultValueAnnotation != uniformInfo.annotations.end()) + { + defaultValue = defaultValueAnnotation->type.is_floating_point() ? defaultValueAnnotation->value.as_float[0] : 0.0f; + } + + if (auto pathnameAnnotation = + std::find_if(uniformInfo.annotations.begin(), uniformInfo.annotations.end(), [](const auto& a) { return a.name == "pathname"; }); + pathnameAnnotation != uniformInfo.annotations.end()) + { + pathname = new char[pathnameAnnotation->value.string_data.length() + 1]; + strcpy(pathname, pathnameAnnotation->value.string_data.c_str()); + } + else + { + pathname = new char[defaultRuntimePathnamePrefix.length() + source->value.string_data.length() + 1]; + std::string tmp_pathname = defaultRuntimePathnamePrefix + source->value.string_data; + strcpy(pathname, tmp_pathname.c_str()); + } + + projId = 0; + if (auto projIdAnnotation = + std::find_if(uniformInfo.annotations.begin(), uniformInfo.annotations.end(), [](const auto& a) { return a.name == "projId"; }); + projIdAnnotation != uniformInfo.annotations.end()) + { + projId = projIdAnnotation->value.as_int[0]; + } + shmKey = ftok(pathname, projId); + + Logger::debug("Found runtime uniform: " + std::to_string(defaultValue) + " " + pathname + " " + std::to_string(projId) + "\n"); + offset = uniformInfo.offset; + size = uniformInfo.size; + } + void RuntimeUniform::update(void* mapedBuffer) + { + float *value = &defaultValue; + bool needs_detach = false; + if (shmKey != -1) { + int shmId = shmget(shmKey,sizeof(*value),0444); // read-only + if (shmId != -1) { + value = (float*) shmat(shmId,(void*)0,0); + needs_detach = true; + } + } + std::memcpy((uint8_t*) mapedBuffer + offset, value, sizeof(*value)); + if (needs_detach) + shmdt(value); + } + RuntimeUniform::~RuntimeUniform() + { + } } // namespace vkBasalt diff --git a/src/reshade_uniforms.hpp b/src/reshade_uniforms.hpp index a41b28c9..16f698c7 100644 --- a/src/reshade_uniforms.hpp +++ b/src/reshade_uniforms.hpp @@ -139,6 +139,20 @@ namespace vkBasalt void virtual update(void* mapedBuffer) override; virtual ~DepthUniform(); }; + + class RuntimeUniform : public ReshadeUniform + { + public: + RuntimeUniform(reshadefx::uniform_info uniformInfo); + void virtual update(void* mapedBuffer) override; + virtual ~RuntimeUniform(); + + private: + float defaultValue; + char* pathname; + int projId; + key_t shmKey; + }; } // namespace vkBasalt #endif // RESHADE_UNIFORMS_HPP_INCLUDED