diff --git a/src/effect_reshade.cpp b/src/effect_reshade.cpp index 3eaf6bc..13f5e68 100644 --- a/src/effect_reshade.cpp +++ b/src/effect_reshade.cpp @@ -6,6 +6,7 @@ #include #include +#include #include "image_view.hpp" #include "descriptor_set.hpp" @@ -378,6 +379,64 @@ namespace vkBasalt //pipeline + // Configure effect + std::vector specMapEntrys; + std::vector specData; + + for (uint32_t specId = 0, offset = 0; auto& opt : module.spec_constants) + { + if (!opt.name.empty()) + { + auto val = pConfig->getOption(opt.name); + if (!val.empty()) + { + std::variant convertedValue; + offset = static_cast(specData.size()); + switch(opt.type.base) + { + case reshadefx::type::t_bool: + convertedValue = (val == "true" || val == "1") ? 1 : 0; + specData.resize(offset + sizeof(VkBool32)); + std::memcpy(specData.data() + offset, &convertedValue, sizeof(VkBool32)); + specMapEntrys.push_back({specId, offset, sizeof(VkBool32)}); + break; + case reshadefx::type::t_int: + convertedValue = std::stoi(val); + specData.resize(offset + sizeof(int32_t)); + std::memcpy(specData.data() + offset, &convertedValue, sizeof(int32_t)); + specMapEntrys.push_back({specId, offset, sizeof(int32_t)}); + break; + case reshadefx::type::t_uint: + convertedValue = static_cast(std::stoul(val)); + specData.resize(offset + sizeof(uint32_t)); + std::memcpy(specData.data() + offset, &convertedValue, sizeof(uint32_t)); + specMapEntrys.push_back({specId, offset, sizeof(uint32_t)}); + break; + case reshadefx::type::t_float: + convertedValue = std::stof(val); + specData.resize(offset + sizeof(float)); + std::memcpy(specData.data() + offset, &convertedValue, sizeof(float)); + specMapEntrys.push_back({specId, offset, sizeof(float)}); + break; + default: + // do nothing + break; + } + } + } + specId++; + } + + VkSpecializationInfo specializationInfo; + if (specMapEntrys.size() > 0) { + specializationInfo = { + .mapEntryCount = static_cast(specMapEntrys.size()), + .pMapEntries = specMapEntrys.data(), + .dataSize = specData.size(), + .pData = specData.data() + }; + } + VkPipelineShaderStageCreateInfo shaderStageCreateInfoVert; shaderStageCreateInfoVert.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; shaderStageCreateInfoVert.pNext = nullptr; @@ -385,7 +444,7 @@ namespace vkBasalt shaderStageCreateInfoVert.stage = VK_SHADER_STAGE_VERTEX_BIT; shaderStageCreateInfoVert.module = shaderModule; shaderStageCreateInfoVert.pName = pass.vs_entry_point.c_str(); - shaderStageCreateInfoVert.pSpecializationInfo = nullptr; + shaderStageCreateInfoVert.pSpecializationInfo = (specMapEntrys.size() > 0) ? &specializationInfo : nullptr; VkPipelineShaderStageCreateInfo shaderStageCreateInfoFrag; shaderStageCreateInfoFrag.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; @@ -394,7 +453,7 @@ namespace vkBasalt shaderStageCreateInfoFrag.stage = VK_SHADER_STAGE_FRAGMENT_BIT; shaderStageCreateInfoFrag.module = shaderModule; shaderStageCreateInfoFrag.pName = pass.ps_entry_point.c_str(); - shaderStageCreateInfoFrag.pSpecializationInfo = nullptr; + shaderStageCreateInfoFrag.pSpecializationInfo = (specMapEntrys.size() > 0) ? &specializationInfo : nullptr; VkPipelineShaderStageCreateInfo shaderStages[] = {shaderStageCreateInfoVert,shaderStageCreateInfoFrag};