Shader: Replace indices-based option keys by CRC32
This commit is contained in:
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user