From 5ea30829d37cc0dfc04fd3c70e73231ca32d56ec Mon Sep 17 00:00:00 2001 From: wheaney <42350981+wheaney@users.noreply.github.com> Date: Wed, 4 Oct 2023 09:21:44 -0700 Subject: [PATCH] Add type awareness to runtime uniforms, allowing for types like bool, float3, etc... --- src/reshade_uniforms.cpp | 90 +++++++++++++++++++++++++++++++--------- src/reshade_uniforms.hpp | 4 +- 2 files changed, 74 insertions(+), 20 deletions(-) diff --git a/src/reshade_uniforms.cpp b/src/reshade_uniforms.cpp index 2c7cee6..32bbc2b 100644 --- a/src/reshade_uniforms.cpp +++ b/src/reshade_uniforms.cpp @@ -7,6 +7,7 @@ #include #include +#include #include "logger.hpp" @@ -391,15 +392,10 @@ namespace vkBasalt ////////////////////////////////////////////////////////////////////////////////////////////////////////// RuntimeUniform::RuntimeUniform(reshadefx::uniform_info uniformInfo) { + offset = uniformInfo.offset; + size = uniformInfo.size; + type = uniformInfo.type; 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()) @@ -423,24 +419,80 @@ namespace vkBasalt } 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; + if (auto defaultValueAnnotation = + std::find_if(uniformInfo.annotations.begin(), uniformInfo.annotations.end(), [](const auto& a) { return a.name == "defaultValue"; }); + defaultValueAnnotation != uniformInfo.annotations.end()) + { + reshadefx::constant value = defaultValueAnnotation->value; + if (type.is_floating_point()) { + defaultValue = std::vector(value.as_float, value.as_float + type.components()); + Logger::debug(std::string("Found float* runtime uniform: ") + pathname + " " + std::to_string(projId) + + " of size " + std::to_string(type.components()) + "\n"); + } else if (type.is_boolean()) { + defaultValue = std::vector(value.as_uint, value.as_uint + type.components()); + Logger::debug(std::string("Found bool* runtime uniform: ") + pathname + " " + std::to_string(projId) + + " of size " + std::to_string(type.components()) + "\n"); + } else if (type.is_numeric()) { + if (type.is_signed()) { + defaultValue = std::vector(value.as_int, value.as_int + type.components()); + Logger::debug(std::string("Found int32_t* runtime uniform: ") + pathname + " " + std::to_string(projId) + + " of size " + std::to_string(type.components()) + "\n"); + } else { + defaultValue = std::vector(value.as_uint, value.as_uint + type.components()); + Logger::debug(std::string("Found uint32_t* runtime uniform: ") + pathname + " " + std::to_string(projId) + + " of size " + std::to_string(type.components()) + "\n"); + } + } else { + Logger::err("Tried to create a runtime uniform variable of an unsupported type"); + } + } } void RuntimeUniform::update(void* mapedBuffer) { - float *value = &defaultValue; - bool needs_detach = false; + std::variant, std::vector, std::vector, bool> value; if (shmKey != -1) { - int shmId = shmget(shmKey,sizeof(*value),0444); // read-only + int shmId = shmget(shmKey,size,0444); // read-only if (shmId != -1) { - value = (float*) shmat(shmId,(void*)0,0); - needs_detach = true; + if (type.is_floating_point()) { + float* raw_ptr = static_cast(shmat(shmId, nullptr, 0)); + value = std::vector(raw_ptr, raw_ptr + type.components()); + shmdt(raw_ptr); + } else if (type.is_boolean()) { + bool* raw_ptr = static_cast(shmat(shmId, nullptr, 0)); + + // convert to a uint32_t vector, that's how the reshade uniform code understands booleans + std::vector bools_as_uint; + for(size_t i = 0; i < type.components(); ++i) { + bools_as_uint.push_back(static_cast(raw_ptr[i])); + } + value = bools_as_uint; + shmdt(raw_ptr); + } else if (type.is_numeric()) { + if (type.is_signed()) { + int32_t* raw_ptr = static_cast(shmat(shmId, nullptr, 0)); + value = std::vector(raw_ptr, raw_ptr + type.components()); + shmdt(raw_ptr); + } else { + uint32_t* raw_ptr = static_cast(shmat(shmId, nullptr, 0)); + value = std::vector(raw_ptr, raw_ptr + type.components()); + shmdt(raw_ptr); + } + } } } - std::memcpy((uint8_t*) mapedBuffer + offset, value, sizeof(*value)); - if (needs_detach) - shmdt(value); + if (std::holds_alternative(value)) { + value = defaultValue; + } + if (std::holds_alternative>(value)) { + std::vector& vec = std::get>(value); + std::memcpy((uint8_t*) mapedBuffer + offset, vec.data(), vec.size() * sizeof(float)); + } else if (std::holds_alternative>(value)) { + std::vector& vec = std::get>(value); + std::memcpy((uint8_t*) mapedBuffer + offset, vec.data(), vec.size() * sizeof(int32_t)); + } else if (std::holds_alternative>(value)) { + std::vector& vec = std::get>(value); + std::memcpy((uint8_t*) mapedBuffer + offset, vec.data(), vec.size() * sizeof(uint32_t)); + } } RuntimeUniform::~RuntimeUniform() { diff --git a/src/reshade_uniforms.hpp b/src/reshade_uniforms.hpp index 16f698c..2d9d222 100644 --- a/src/reshade_uniforms.hpp +++ b/src/reshade_uniforms.hpp @@ -7,6 +7,7 @@ #include #include #include +#include #include "vulkan_include.hpp" @@ -148,7 +149,8 @@ namespace vkBasalt virtual ~RuntimeUniform(); private: - float defaultValue; + reshadefx::type type; + std::variant, std::vector, std::vector, bool> defaultValue; char* pathname; int projId; key_t shmKey;