Shader: Replace indices-based option keys by CRC32

This commit is contained in:
Jérôme Leclercq
2022-03-06 19:13:38 +01:00
parent 505d996c88
commit a7acf32886
18 changed files with 92 additions and 152 deletions

View File

@@ -22,12 +22,19 @@ namespace Nz
struct MaterialPipelineInfo : RenderStates
{
struct Option
{
UInt32 hash;
ShaderAst::ConstantValue value;
};
struct Shader
{
std::array<ShaderAst::ConstantValue, 32> optionValues;
std::shared_ptr<UberShader> uberShader;
};
std::array<Option, 32> optionValues;
std::size_t optionCount = 0;
std::vector<Shader> shaders;
std::shared_ptr<const MaterialSettings> settings;
};

View File

@@ -32,13 +32,20 @@ namespace Nz
#define NazaraPipelineMember(field) if (lhs.field != rhs.field) return false
NazaraPipelineMember(settings);
NazaraPipelineMember(optionCount);
for (std::size_t i = 0; i < lhs.shaders.size(); ++i)
{
if (lhs.shaders[i].optionValues != rhs.shaders[i].optionValues)
if (lhs.shaders[i].uberShader != rhs.shaders[i].uberShader)
return false;
}
for (std::size_t i = 0; i < lhs.optionCount; ++i)
{
if (lhs.optionValues[i].hash != rhs.optionValues[i].hash)
return false;
if (lhs.shaders[i].uberShader != rhs.shaders[i].uberShader)
if (lhs.optionValues[i].value != rhs.optionValues[i].value)
return false;
}
@@ -72,14 +79,15 @@ namespace std
NazaraPipelineMember(settings.get()); //< Hash pointer
for (const auto& shader : pipelineInfo.shaders)
for (std::size_t i = 0; i < pipelineInfo.optionCount; ++i)
{
for (const auto& value : shader.optionValues)
Nz::HashCombine(seed, value);
Nz::HashCombine(seed, shader.uberShader.get());
Nz::HashCombine(seed, pipelineInfo.optionValues[i].hash);
Nz::HashCombine(seed, pipelineInfo.optionValues[i].value);
}
for (const auto& shader : pipelineInfo.shaders)
Nz::HashCombine(seed, shader.uberShader.get());
NazaraUnused(parameterIndex);
#undef NazaraPipelineMember

View File

@@ -57,7 +57,7 @@ namespace Nz
static constexpr std::size_t InvalidIndex = std::numeric_limits<std::size_t>::max();
static inline void BuildOption(std::vector<Option>& options, const std::vector<std::shared_ptr<UberShader>>& uberShaders, std::string optionName, const std::string& shaderOptionName);
static inline void BuildOption(std::vector<Option>& options, std::string optionName, const std::string& shaderOptionName);
struct Builder
{
@@ -74,7 +74,7 @@ namespace Nz
struct Option
{
std::string name;
std::vector<std::optional<std::size_t>> optionIndexByShader;
UInt32 hash;
};
struct UniformVariable

View File

@@ -3,6 +3,7 @@
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Graphics/MaterialSettings.hpp>
#include <Nazara/Core/Algorithm.hpp>
#include <Nazara/Graphics/Graphics.hpp>
#include <cassert>
#include <Nazara/Graphics/Debug.hpp>
@@ -169,31 +170,14 @@ namespace Nz
return InvalidIndex;
}
inline void MaterialSettings::BuildOption(std::vector<Option>& options, const std::vector<std::shared_ptr<UberShader>>& uberShaders, std::string optionName, const std::string& shaderOptionName)
inline void MaterialSettings::BuildOption(std::vector<Option>& options, std::string optionName, const std::string& shaderOptionName)
{
std::vector<std::optional<std::size_t>> shaderOptions;
UInt32 optionHash = CRC32(shaderOptionName);
for (std::size_t shaderIndex = 0; shaderIndex < uberShaders.size(); ++shaderIndex)
{
const auto& uberShader = uberShaders[shaderIndex];
const UberShader::Option* optionData;
if (uberShader->HasOption(shaderOptionName, &optionData))
{
if (shaderIndex >= shaderOptions.size())
shaderOptions.resize(shaderIndex + 1);
shaderOptions[shaderIndex] = optionData->index;
}
}
if (std::any_of(shaderOptions.begin(), shaderOptions.end(), [&](std::optional<std::size_t> optionIndex) { return optionIndex.has_value(); }))
{
options.push_back({
std::move(optionName),
shaderOptions
});
}
options.push_back({
std::move(optionName),
optionHash
});
}
inline MaterialSettings::Builder::Builder()

View File

@@ -38,11 +38,9 @@ namespace Nz
inline void UpdateConfig(Config& config, const std::vector<RenderPipelineInfo::VertexBufferData>& vertexBuffers);
inline void UpdateConfigCallback(ConfigCallback callback);
static constexpr std::size_t MaximumOptionValue = 32;
struct Config
{
std::array<ShaderAst::ConstantValue, MaximumOptionValue> optionValues;
std::unordered_map<UInt32, ShaderAst::ConstantValue> optionValues;
};
struct ConfigEqual
@@ -57,7 +55,7 @@ namespace Nz
struct Option
{
std::size_t index;
UInt32 hash;
};
private:

View File

@@ -37,20 +37,17 @@ namespace Nz
inline bool UberShader::ConfigEqual::operator()(const Config& lhs, const Config& rhs) const
{
for (std::size_t i = 0; i < lhs.optionValues.size(); ++i)
{
if (lhs.optionValues[i] != rhs.optionValues[i])
return false;
}
return true;
return lhs.optionValues == rhs.optionValues;
}
inline std::size_t UberShader::ConfigHasher::operator()(const Config& config) const
{
std::size_t hash = 0;
for (std::size_t i = 0; i < config.optionValues.size(); ++i)
HashCombine(hash, config.optionValues[i]);
for (auto&& [key, value] : config.optionValues)
{
HashCombine(hash, key);
HashCombine(hash, value);
}
return hash;
}

View File

@@ -44,7 +44,7 @@ namespace Nz::ShaderAst
{
std::function<ModulePtr(const std::vector<std::string>& /*modulePath*/)> moduleCallback;
std::unordered_set<std::string> reservedIdentifiers;
std::unordered_map<std::size_t, ConstantValue> optionValues;
std::unordered_map<UInt32, ConstantValue> optionValues;
bool makeVariableNameUnique = false;
bool reduceLoopsToWhile = false;
bool removeConstDeclaration = false;

View File

@@ -48,7 +48,7 @@ namespace Nz
};
static const char* GetFlipYUniformName();
static ShaderAst::ModulePtr Sanitize(const ShaderAst::Module& module, std::unordered_map<std::size_t, ShaderAst::ConstantValue> optionValues, std::string* error = nullptr);
static ShaderAst::ModulePtr Sanitize(const ShaderAst::Module& module, std::unordered_map<UInt32, ShaderAst::ConstantValue> optionValues, std::string* error = nullptr);
private:
void Append(const ShaderAst::ArrayType& type);

View File

@@ -27,7 +27,7 @@ namespace Nz
struct States
{
std::unordered_map<std::size_t, ShaderAst::ConstantValue> optionValues;
std::unordered_map<UInt32, ShaderAst::ConstantValue> optionValues;
bool optimize = false;
bool sanitized = false;
};