Add unity build support

This commit is contained in:
Jérôme Leclercq
2022-03-15 08:26:57 +01:00
parent 0a4fd8f56d
commit 6bd9f1a9e4
109 changed files with 964 additions and 680 deletions

View File

@@ -10,14 +10,8 @@
namespace Nz::ShaderAst
{
namespace
namespace NAZARA_ANONYMOUS_NAMESPACE
{
template<typename T, typename U>
std::unique_ptr<T> static_unique_pointer_cast(std::unique_ptr<U>&& ptr)
{
return std::unique_ptr<T>(static_cast<T*>(ptr.release()));
}
template <typename T>
struct is_complete_helper
{
@@ -1138,6 +1132,8 @@ namespace Nz::ShaderAst
template<BinaryType Type>
ExpressionPtr AstConstantPropagationVisitor::PropagateBinaryConstant(const ConstantValueExpression& lhs, const ConstantValueExpression& rhs)
{
NAZARA_USE_ANONYMOUS_NAMESPACE
std::unique_ptr<ConstantValueExpression> optimized;
std::visit([&](auto&& arg1)
{
@@ -1167,6 +1163,8 @@ namespace Nz::ShaderAst
template<typename TargetType>
ExpressionPtr AstConstantPropagationVisitor::PropagateSingleValueCast(const ConstantValueExpression& operand)
{
NAZARA_USE_ANONYMOUS_NAMESPACE
std::unique_ptr<ConstantValueExpression> optimized;
std::visit([&](auto&& arg)
@@ -1184,6 +1182,8 @@ namespace Nz::ShaderAst
template<std::size_t TargetComponentCount>
ExpressionPtr AstConstantPropagationVisitor::PropagateConstantSwizzle(const std::array<UInt32, 4>& components, const ConstantValueExpression& operand)
{
NAZARA_USE_ANONYMOUS_NAMESPACE
std::unique_ptr<ConstantValueExpression> optimized;
std::visit([&](auto&& arg)
{
@@ -1204,6 +1204,8 @@ namespace Nz::ShaderAst
template<UnaryType Type>
ExpressionPtr AstConstantPropagationVisitor::PropagateUnaryConstant(const ConstantValueExpression& operand)
{
NAZARA_USE_ANONYMOUS_NAMESPACE
std::unique_ptr<ConstantValueExpression> optimized;
std::visit([&](auto&& arg)
{
@@ -1227,6 +1229,8 @@ namespace Nz::ShaderAst
template<typename TargetType>
ExpressionPtr AstConstantPropagationVisitor::PropagateVec2Cast(TargetType v1, TargetType v2)
{
NAZARA_USE_ANONYMOUS_NAMESPACE
std::unique_ptr<ConstantValueExpression> optimized;
using CCType = CastConstant<Vector2<TargetType>, TargetType, TargetType>;
@@ -1240,6 +1244,8 @@ namespace Nz::ShaderAst
template<typename TargetType>
ExpressionPtr AstConstantPropagationVisitor::PropagateVec3Cast(TargetType v1, TargetType v2, TargetType v3)
{
NAZARA_USE_ANONYMOUS_NAMESPACE
std::unique_ptr<ConstantValueExpression> optimized;
using CCType = CastConstant<Vector3<TargetType>, TargetType, TargetType, TargetType>;
@@ -1253,6 +1259,8 @@ namespace Nz::ShaderAst
template<typename TargetType>
ExpressionPtr AstConstantPropagationVisitor::PropagateVec4Cast(TargetType v1, TargetType v2, TargetType v3, TargetType v4)
{
NAZARA_USE_ANONYMOUS_NAMESPACE
std::unique_ptr<ConstantValueExpression> optimized;
using CCType = CastConstant<Vector4<TargetType>, TargetType, TargetType, TargetType, TargetType>;

View File

@@ -12,8 +12,8 @@ namespace Nz::ShaderAst
{
namespace
{
constexpr UInt32 s_magicNumber = 0x4E534852;
constexpr UInt32 s_currentVersion = 1;
constexpr UInt32 s_shaderAstMagicNumber = 0x4E534852;
constexpr UInt32 s_shaderAstCurrentVersion = 1;
class ShaderSerializerVisitor : public AstExpressionVisitor, public AstStatementVisitor
{
@@ -375,7 +375,7 @@ namespace Nz::ShaderAst
void ShaderAstSerializer::Serialize(ModulePtr& module)
{
m_stream << s_magicNumber << s_currentVersion;
m_stream << s_shaderAstMagicNumber << s_shaderAstCurrentVersion;
SerializeModule(module);
@@ -588,11 +588,11 @@ namespace Nz::ShaderAst
UInt32 magicNumber;
UInt32 version;
m_stream >> magicNumber;
if (magicNumber != s_magicNumber)
if (magicNumber != s_shaderAstMagicNumber)
throw std::runtime_error("invalid shader file");
m_stream >> version;
if (version > s_currentVersion)
if (version > s_shaderAstCurrentVersion)
throw std::runtime_error("unsupported version");
ModulePtr module;

View File

@@ -7,23 +7,6 @@
namespace Nz::ShaderAst
{
namespace
{
template<typename T> T& Retrieve(std::unordered_map<std::size_t, T>& map, std::size_t id)
{
auto it = map.find(id);
assert(it != map.end());
return it->second;
}
template<typename T> const T& Retrieve(const std::unordered_map<std::size_t, T>& map, std::size_t id)
{
auto it = map.find(id);
assert(it != map.end());
return it->second;
}
}
void DependencyCheckerVisitor::Process(Statement& statement, const Config& config)
{
m_config = config;

View File

@@ -25,19 +25,10 @@
namespace Nz::ShaderAst
{
namespace
struct SanitizeVisitor::AstError
{
struct AstError
{
std::string errMsg;
};
template<typename T, typename U>
std::unique_ptr<T> static_unique_pointer_cast(std::unique_ptr<U>&& ptr)
{
return std::unique_ptr<T>(SafeCast<T*>(ptr.release()));
}
}
std::string errMsg;
};
struct SanitizeVisitor::CurrentFunctionData
{
@@ -446,7 +437,7 @@ namespace Nz::ShaderAst
for (auto& index : node.indices)
MandatoryExpr(index);
auto clone = static_unique_pointer_cast<AccessIndexExpression>(AstCloner::Clone(node));
auto clone = StaticUniquePointerCast<AccessIndexExpression>(AstCloner::Clone(node));
Validate(*clone);
// TODO: Handle AccessIndex on structs with m_context->options.useIdentifierAccessesForStructs
@@ -478,7 +469,7 @@ namespace Nz::ShaderAst
MandatoryExpr(node.left);
MandatoryExpr(node.right);
auto clone = static_unique_pointer_cast<AssignExpression>(AstCloner::Clone(node));
auto clone = StaticUniquePointerCast<AssignExpression>(AstCloner::Clone(node));
Validate(*clone);
return clone;
@@ -486,7 +477,7 @@ namespace Nz::ShaderAst
ExpressionPtr SanitizeVisitor::Clone(BinaryExpression& node)
{
auto clone = static_unique_pointer_cast<BinaryExpression>(AstCloner::Clone(node));
auto clone = StaticUniquePointerCast<BinaryExpression>(AstCloner::Clone(node));
Validate(*clone);
return clone;
@@ -590,7 +581,7 @@ namespace Nz::ShaderAst
ExpressionPtr SanitizeVisitor::Clone(CastExpression& node)
{
auto clone = static_unique_pointer_cast<CastExpression>(AstCloner::Clone(node));
auto clone = StaticUniquePointerCast<CastExpression>(AstCloner::Clone(node));
Validate(*clone);
const ExpressionType& targetType = clone->targetType.GetResultingValue();
@@ -690,7 +681,7 @@ namespace Nz::ShaderAst
if (std::holds_alternative<NoValue>(node.value))
throw std::runtime_error("expected a value");
auto clone = static_unique_pointer_cast<ConstantValueExpression>(AstCloner::Clone(node));
auto clone = StaticUniquePointerCast<ConstantValueExpression>(AstCloner::Clone(node));
clone->cachedExpressionType = GetExpressionType(clone->value);
return clone;
@@ -772,7 +763,7 @@ namespace Nz::ShaderAst
ExpressionPtr SanitizeVisitor::Clone(UnaryExpression& node)
{
auto clone = static_unique_pointer_cast<UnaryExpression>(AstCloner::Clone(node));
auto clone = StaticUniquePointerCast<UnaryExpression>(AstCloner::Clone(node));
Validate(*clone);
return clone;
@@ -780,7 +771,7 @@ namespace Nz::ShaderAst
ExpressionPtr SanitizeVisitor::Clone(VariableValueExpression& node)
{
auto clone = static_unique_pointer_cast<VariableValueExpression>(AstCloner::Clone(node));
auto clone = StaticUniquePointerCast<VariableValueExpression>(AstCloner::Clone(node));
Validate(*clone);
return clone;
@@ -887,7 +878,7 @@ namespace Nz::ShaderAst
StatementPtr SanitizeVisitor::Clone(DeclareConstStatement& node)
{
auto clone = static_unique_pointer_cast<DeclareConstStatement>(AstCloner::Clone(node));
auto clone = StaticUniquePointerCast<DeclareConstStatement>(AstCloner::Clone(node));
if (!clone->expression)
throw AstError{ "const variables must have an expression" };
@@ -917,7 +908,7 @@ namespace Nz::ShaderAst
{
assert(m_context);
auto clone = static_unique_pointer_cast<DeclareExternalStatement>(AstCloner::Clone(node));
auto clone = StaticUniquePointerCast<DeclareExternalStatement>(AstCloner::Clone(node));
UInt32 defaultBlockSet = 0;
if (clone->bindingSet.HasValue())
@@ -1051,7 +1042,7 @@ namespace Nz::ShaderAst
if (m_context->currentFunction)
throw AstError{ "options must be declared outside of functions" };
auto clone = static_unique_pointer_cast<DeclareOptionStatement>(AstCloner::Clone(node));
auto clone = StaticUniquePointerCast<DeclareOptionStatement>(AstCloner::Clone(node));
if (clone->optName.empty())
throw AstError{ "empty option name" };
@@ -1083,7 +1074,7 @@ namespace Nz::ShaderAst
if (m_context->currentFunction)
throw AstError{ "structs must be declared outside of functions" };
auto clone = static_unique_pointer_cast<DeclareStructStatement>(AstCloner::Clone(node));
auto clone = StaticUniquePointerCast<DeclareStructStatement>(AstCloner::Clone(node));
if (clone->isExported.HasValue())
clone->isExported = ComputeExprValue(clone->isExported);
@@ -1140,7 +1131,7 @@ namespace Nz::ShaderAst
if (!m_context->currentFunction)
throw AstError{ "global variables outside of external blocks are forbidden" };
auto clone = static_unique_pointer_cast<DeclareVariableStatement>(AstCloner::Clone(node));
auto clone = StaticUniquePointerCast<DeclareVariableStatement>(AstCloner::Clone(node));
Validate(*clone);
return clone;
@@ -1615,7 +1606,7 @@ namespace Nz::ShaderAst
MandatoryExpr(node.condition);
MandatoryStatement(node.body);
auto clone = static_unique_pointer_cast<WhileStatement>(AstCloner::Clone(node));
auto clone = StaticUniquePointerCast<WhileStatement>(AstCloner::Clone(node));
Validate(*clone);
ExpressionValue<LoopUnroll> unrollValue;
@@ -1902,7 +1893,7 @@ namespace Nz::ShaderAst
};
// Run optimizer on constant value to hopefully retrieve a single constant value
return static_unique_pointer_cast<T>(ShaderAst::PropagateConstants(node, optimizerOptions));
return StaticUniquePointerCast<T>(ShaderAst::PropagateConstants(node, optimizerOptions));
}
void SanitizeVisitor::PreregisterIndices(const Module& module)

View File

@@ -22,19 +22,12 @@ namespace Nz
{
namespace
{
static const char* s_flipYUniformName = "_NzFlipYValue";
static const char* s_inputPrefix = "_NzIn_";
static const char* s_outputPrefix = "_NzOut_";
static const char* s_outputVarName = "_nzOutput";
static const char* s_glslWriterFlipYUniformName = "_NzFlipYValue";
static const char* s_glslWriterInputPrefix = "_NzIn_";
static const char* s_glslWriterOutputPrefix = "_NzOut_";
static const char* s_glslWriterOutputVarName = "_nzOutput";
template<typename T> const T& Retrieve(const std::unordered_map<std::size_t, T>& map, std::size_t id)
{
auto it = map.find(id);
assert(it != map.end());
return it->second;
}
struct PreVisitor : ShaderAst::AstRecursiveVisitor
struct GlslWriterPreVisitor : ShaderAst::AstRecursiveVisitor
{
using AstRecursiveVisitor::Visit;
@@ -110,13 +103,13 @@ namespace Nz
ShaderAst::DeclareFunctionStatement* entryPoint = nullptr;
};
struct Builtin
struct GlslBuiltin
{
std::string identifier;
ShaderStageTypeFlags stageFlags;
};
std::unordered_map<ShaderAst::BuiltinEntry, Builtin> s_builtinMapping = {
std::unordered_map<ShaderAst::BuiltinEntry, GlslBuiltin> s_glslBuiltinMapping = {
{ ShaderAst::BuiltinEntry::FragCoord, { "gl_FragCoord", ShaderStageType::Fragment } },
{ ShaderAst::BuiltinEntry::FragDepth, { "gl_FragDepth", ShaderStageType::Fragment } },
{ ShaderAst::BuiltinEntry::VertexPosition, { "gl_Position", ShaderStageType::Vertex } }
@@ -152,7 +145,7 @@ namespace Nz
std::vector<InOutField> outputFields;
Bitset<> declaredFunctions;
const GlslWriter::BindingMapping& bindingMapping;
PreVisitor previsitor;
GlslWriterPreVisitor previsitor;
const States* states = nullptr;
bool isInEntryPoint = false;
unsigned int indentLevel = 0;
@@ -249,7 +242,7 @@ namespace Nz
const char* GlslWriter::GetFlipYUniformName()
{
return s_flipYUniformName;
return s_glslWriterFlipYUniformName;
}
ShaderAst::SanitizeVisitor::Options GlslWriter::GetSanitizeOptions()
@@ -724,10 +717,10 @@ namespace Nz
if (member.builtin.HasValue())
{
auto it = s_builtinMapping.find(member.builtin.GetResultingValue());
assert(it != s_builtinMapping.end());
auto it = s_glslBuiltinMapping.find(member.builtin.GetResultingValue());
assert(it != s_glslBuiltinMapping.end());
const Builtin& builtin = it->second;
const GlslBuiltin& builtin = it->second;
if (m_currentState->stage && !builtin.stageFlags.Test(*m_currentState->stage))
continue; //< This builtin is not active in this stage, skip it
@@ -770,12 +763,12 @@ namespace Nz
const auto& inputStruct = Retrieve(m_currentState->structs, inputStructIndex);
AppendCommentSection("Inputs");
AppendInOut(inputStruct, m_currentState->inputFields, "in", s_inputPrefix);
AppendInOut(inputStruct, m_currentState->inputFields, "in", s_glslWriterInputPrefix);
}
if (m_currentState->stage == ShaderStageType::Vertex && m_environment.flipYPosition)
{
AppendLine("uniform float ", s_flipYUniformName, ";");
AppendLine("uniform float ", s_glslWriterFlipYUniformName, ";");
AppendLine();
}
@@ -787,7 +780,7 @@ namespace Nz
const auto& outputStruct = Retrieve(m_currentState->structs, outputStructIndex);
AppendCommentSection("Outputs");
AppendInOut(outputStruct, m_currentState->outputFields, "out", s_outputPrefix);
AppendInOut(outputStruct, m_currentState->outputFields, "out", s_glslWriterOutputPrefix);
}
}
@@ -1344,11 +1337,11 @@ namespace Nz
else
{
AppendLine();
Append(structData.nameOverride, " ", s_outputVarName, " = ");
Append(structData.nameOverride, " ", s_glslWriterOutputVarName, " = ");
node.returnExpr->Visit(*this);
AppendLine(";");
outputStructVarName = s_outputVarName;
outputStructVarName = s_glslWriterOutputVarName;
}
AppendLine();
@@ -1362,7 +1355,7 @@ namespace Nz
{
// https://veldrid.dev/articles/backend-differences.html
if (m_environment.flipYPosition)
AppendLine(targetName, ".y *= ", s_flipYUniformName, ";");
AppendLine(targetName, ".y *= ", s_glslWriterFlipYUniformName, ";");
if (m_environment.remapZPosition)
AppendLine(targetName, ".z = ", targetName, ".z * 2.0 - ", targetName, ".w; ");

View File

@@ -17,16 +17,6 @@
namespace Nz
{
namespace
{
template<typename T> const T& Retrieve(const std::unordered_map<std::size_t, T>& map, std::size_t id)
{
auto it = map.find(id);
assert(it != map.end());
return it->second;
}
}
struct LangWriter::BindingAttribute
{
const ShaderAst::ExpressionValue<UInt32>& bindingIndex;

View File

@@ -12,7 +12,7 @@
namespace Nz::ShaderLang
{
namespace
namespace NAZARA_ANONYMOUS_NAMESPACE
{
std::unordered_map<std::string, ShaderAst::DepthWriteMode> s_depthWriteModes = {
{ "greater", ShaderAst::DepthWriteMode::Greater },
@@ -58,15 +58,6 @@ namespace Nz::ShaderLang
{ "never", ShaderAst::LoopUnroll::Never }
};
template<typename T, typename U>
std::optional<T> BoundCast(U val)
{
if (val < std::numeric_limits<T>::min() || val > std::numeric_limits<T>::max())
return std::nullopt;
return static_cast<T>(val);
}
template<typename T>
void HandleUniqueAttribute(const std::string_view& attributeName, ShaderAst::ExpressionValue<T>& targetAttribute, ShaderAst::ExprValue::Param&& param)
{
@@ -491,6 +482,8 @@ namespace Nz::ShaderLang
ShaderAst::StatementPtr Parser::ParseExternalBlock(std::vector<ShaderAst::ExprValue> attributes)
{
NAZARA_USE_ANONYMOUS_NAMESPACE
Expect(Advance(), TokenType::External);
Expect(Advance(), TokenType::OpenCurlyBracket);
@@ -573,6 +566,8 @@ namespace Nz::ShaderLang
ShaderAst::StatementPtr Parser::ParseForDeclaration(std::vector<ShaderAst::ExprValue> attributes)
{
NAZARA_USE_ANONYMOUS_NAMESPACE
Expect(Advance(), TokenType::For);
std::string varName = ParseIdentifierAsName();
@@ -647,6 +642,8 @@ namespace Nz::ShaderLang
ShaderAst::StatementPtr Parser::ParseFunctionDeclaration(std::vector<ShaderAst::ExprValue> attributes)
{
NAZARA_USE_ANONYMOUS_NAMESPACE
Expect(Advance(), TokenType::FunctionDeclaration);
std::string functionName = ParseIdentifierAsName();
@@ -941,6 +938,8 @@ namespace Nz::ShaderLang
ShaderAst::StatementPtr Parser::ParseStructDeclaration(std::vector<ShaderAst::ExprValue> attributes)
{
NAZARA_USE_ANONYMOUS_NAMESPACE
Expect(Advance(), TokenType::Struct);
ShaderAst::StructDescription description;
@@ -1083,6 +1082,8 @@ namespace Nz::ShaderLang
ShaderAst::StatementPtr Parser::ParseWhileStatement(std::vector<ShaderAst::ExprValue> attributes)
{
NAZARA_USE_ANONYMOUS_NAMESPACE
Expect(Advance(), TokenType::While);
Expect(Advance(), TokenType::OpenParenthesis);
@@ -1353,6 +1354,8 @@ namespace Nz::ShaderLang
ShaderAst::AttributeType Parser::ParseIdentifierAsAttributeType()
{
NAZARA_USE_ANONYMOUS_NAMESPACE
const Token& identifierToken = Expect(Advance(), TokenType::Identifier);
const std::string& identifier = std::get<std::string>(identifierToken.data);

View File

@@ -3,6 +3,7 @@
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Shader/SpirvAstVisitor.hpp>
#include <Nazara/Core/Algorithm.hpp>
#include <Nazara/Core/CallOnExit.hpp>
#include <Nazara/Core/StackArray.hpp>
#include <Nazara/Core/StackVector.hpp>
@@ -15,16 +16,6 @@
namespace Nz
{
namespace
{
template<typename T> const T& Retrieve(const std::unordered_map<std::size_t, T>& map, std::size_t id)
{
auto it = map.find(id);
assert(it != map.end());
return it->second;
}
}
UInt32 SpirvAstVisitor::AllocateResultId()
{
return m_writer.AllocateResultId();

View File

@@ -15,11 +15,7 @@ namespace Nz
{
namespace
{
template<class... Ts> struct overloaded : Ts... { using Ts::operator()...; };
template<class... Ts> overloaded(Ts...) -> overloaded<Ts...>;
StructFieldType TypeToStructFieldType(const SpirvConstantCache::AnyType& type)
StructFieldType SpirvTypeToStructFieldType(const SpirvConstantCache::AnyType& type)
{
if (std::holds_alternative<SpirvConstantCache::Bool>(type))
return StructFieldType::Bool1;
@@ -920,12 +916,12 @@ namespace Nz
std::size_t SpirvConstantCache::RegisterArrayField(FieldOffsets& fieldOffsets, const Bool& type, std::size_t arrayLength) const
{
return fieldOffsets.AddFieldArray(TypeToStructFieldType(type), arrayLength);
return fieldOffsets.AddFieldArray(SpirvTypeToStructFieldType(type), arrayLength);
}
std::size_t SpirvConstantCache::RegisterArrayField(FieldOffsets& fieldOffsets, const Float& type, std::size_t arrayLength) const
{
return fieldOffsets.AddFieldArray(TypeToStructFieldType(type), arrayLength);
return fieldOffsets.AddFieldArray(SpirvTypeToStructFieldType(type), arrayLength);
}
std::size_t SpirvConstantCache::RegisterArrayField(FieldOffsets& /*fieldOffsets*/, const Function& /*type*/, std::size_t /*arrayLength*/) const
@@ -940,7 +936,7 @@ namespace Nz
std::size_t SpirvConstantCache::RegisterArrayField(FieldOffsets& fieldOffsets, const Integer& type, std::size_t arrayLength) const
{
return fieldOffsets.AddFieldArray(TypeToStructFieldType(type), arrayLength);
return fieldOffsets.AddFieldArray(SpirvTypeToStructFieldType(type), arrayLength);
}
std::size_t SpirvConstantCache::RegisterArrayField(FieldOffsets& fieldOffsets, const Matrix& type, std::size_t arrayLength) const
@@ -949,7 +945,7 @@ namespace Nz
throw std::runtime_error("unexpected column type");
const Vector& vecType = std::get<Vector>(type.columnType->type);
return fieldOffsets.AddMatrixArray(TypeToStructFieldType(vecType.componentType->type), type.columnCount, vecType.componentCount, true, arrayLength);
return fieldOffsets.AddMatrixArray(SpirvTypeToStructFieldType(vecType.componentType->type), type.columnCount, vecType.componentCount, true, arrayLength);
}
std::size_t SpirvConstantCache::RegisterArrayField(FieldOffsets& /*fieldOffsets*/, const Pointer& /*type*/, std::size_t /*arrayLength*/) const
@@ -979,7 +975,7 @@ namespace Nz
std::size_t SpirvConstantCache::RegisterArrayField(FieldOffsets& fieldOffsets, const Vector& type, std::size_t arrayLength) const
{
assert(type.componentCount > 0 && type.componentCount <= 4);
return fieldOffsets.AddFieldArray(static_cast<StructFieldType>(UnderlyingCast(TypeToStructFieldType(type.componentType->type)) + type.componentCount), arrayLength);
return fieldOffsets.AddFieldArray(static_cast<StructFieldType>(UnderlyingCast(SpirvTypeToStructFieldType(type.componentType->type)) + type.componentCount), arrayLength);
}
std::size_t SpirvConstantCache::RegisterArrayField(FieldOffsets& /*fieldOffsets*/, const Void& /*type*/, std::size_t /*arrayLength*/) const
@@ -998,7 +994,7 @@ namespace Nz
{
UInt32 resultId = id;
std::visit(overloaded
std::visit(Overloaded
{
[&](const AnyConstant& constant) { Write(constant, resultId, constants); },
[&](const AnyType& type) { Write(type, resultId, annotations, constants, debugInfos); },

View File

@@ -11,17 +11,11 @@
namespace Nz
{
namespace
{
template<class... Ts> struct overloaded : Ts... { using Ts::operator()...; };
template<class... Ts> overloaded(Ts...) -> overloaded<Ts...>;
}
UInt32 SpirvExpressionLoad::Evaluate(ShaderAst::Expression& node)
{
node.Visit(*this);
return std::visit(overloaded
return std::visit(Overloaded
{
[this](const Pointer& pointer) -> UInt32
{
@@ -89,7 +83,7 @@ namespace Nz
assert(node.indices.size() == 1);
UInt32 indexId = m_visitor.EvaluateExpression(node.indices.front());
std::visit(overloaded
std::visit(Overloaded
{
[&](const Pointer& pointer)
{

View File

@@ -3,6 +3,7 @@
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Shader/SpirvExpressionStore.hpp>
#include <Nazara/Core/Algorithm.hpp>
#include <Nazara/Core/StackArray.hpp>
#include <Nazara/Shader/SpirvAstVisitor.hpp>
#include <Nazara/Shader/SpirvBlock.hpp>
@@ -12,17 +13,11 @@
namespace Nz
{
namespace
{
template<class... Ts> struct overloaded : Ts... { using Ts::operator()...; };
template<class... Ts> overloaded(Ts...)->overloaded<Ts...>;
}
void SpirvExpressionStore::Store(ShaderAst::ExpressionPtr& node, UInt32 resultId)
{
node->Visit(*this);
std::visit(overloaded
std::visit(Overloaded
{
[&](const Pointer& pointer)
{
@@ -93,7 +88,7 @@ namespace Nz
const ShaderAst::ExpressionType& exprType = GetExpressionType(node);
std::visit(overloaded
std::visit(Overloaded
{
[&](const Pointer& pointer)
{
@@ -118,7 +113,7 @@ namespace Nz
{
node.expression->Visit(*this);
std::visit(overloaded
std::visit(Overloaded
{
[&](const Pointer& pointer)
{

View File

@@ -29,34 +29,20 @@ namespace Nz
{
namespace
{
struct Builtin
struct SpirvBuiltin
{
const char* debugName;
ShaderStageTypeFlags compatibleStages;
SpirvBuiltIn decoration;
};
template<typename T> T& Retrieve(std::unordered_map<std::size_t, T>& map, std::size_t id)
{
auto it = map.find(id);
assert(it != map.end());
return it->second;
}
template<typename T> const T& Retrieve(const std::unordered_map<std::size_t, T>& map, std::size_t id)
{
auto it = map.find(id);
assert(it != map.end());
return it->second;
}
std::unordered_map<ShaderAst::BuiltinEntry, Builtin> s_builtinMapping = {
std::unordered_map<ShaderAst::BuiltinEntry, SpirvBuiltin> s_spirvBuiltinMapping = {
{ ShaderAst::BuiltinEntry::FragCoord, { "FragmentCoordinates", ShaderStageType::Fragment, SpirvBuiltIn::FragCoord } },
{ ShaderAst::BuiltinEntry::FragDepth, { "FragmentDepth", ShaderStageType::Fragment, SpirvBuiltIn::FragDepth } },
{ ShaderAst::BuiltinEntry::VertexPosition, { "VertexPosition", ShaderStageType::Vertex, SpirvBuiltIn::Position } }
};
class PreVisitor : public ShaderAst::AstRecursiveVisitor
class SpirvPreVisitor : public ShaderAst::AstRecursiveVisitor
{
public:
struct UniformVar
@@ -74,7 +60,7 @@ namespace Nz
using FunctionContainer = std::vector<std::reference_wrapper<ShaderAst::DeclareFunctionStatement>>;
using StructContainer = std::vector<ShaderAst::StructDescription*>;
PreVisitor(SpirvConstantCache& constantCache, std::unordered_map<std::size_t, SpirvAstVisitor::FuncData>& funcs) :
SpirvPreVisitor(SpirvConstantCache& constantCache, std::unordered_map<std::size_t, SpirvAstVisitor::FuncData>& funcs) :
m_constantCache(constantCache),
m_funcs(funcs)
{
@@ -411,10 +397,10 @@ namespace Nz
{
if (member.builtin.HasValue())
{
auto it = s_builtinMapping.find(member.builtin.GetResultingValue());
assert(it != s_builtinMapping.end());
auto it = s_spirvBuiltinMapping.find(member.builtin.GetResultingValue());
assert(it != s_spirvBuiltinMapping.end());
Builtin& builtin = it->second;
SpirvBuiltin& builtin = it->second;
if ((builtin.compatibleStages & entryPointType) == 0)
return 0;
@@ -481,7 +467,7 @@ namespace Nz
std::vector<UInt32> resultIds;
UInt32 nextVarIndex = 1;
SpirvConstantCache constantTypeCache; //< init after nextVarIndex
PreVisitor* previsitor;
SpirvPreVisitor* previsitor;
// Output
SpirvSection header;
@@ -546,7 +532,7 @@ namespace Nz
});
// Register all extended instruction sets
PreVisitor previsitor(state.constantTypeCache, state.funcs);
SpirvPreVisitor previsitor(state.constantTypeCache, state.funcs);
for (const auto& importedModule : targetModule->importedModules)
importedModule.module->rootNode->Visit(previsitor);