ShaderLang: Add support for length intrinsic
This commit is contained in:
parent
24f7b75654
commit
51ecff2912
|
|
@ -54,9 +54,10 @@ namespace Nz::ShaderAst
|
|||
|
||||
enum class IntrinsicType
|
||||
{
|
||||
CrossProduct,
|
||||
DotProduct,
|
||||
SampleTexture
|
||||
CrossProduct = 0,
|
||||
DotProduct = 1,
|
||||
Length = 3,
|
||||
SampleTexture = 2,
|
||||
};
|
||||
|
||||
enum class MemoryLayout
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@ namespace Nz
|
|||
SpirvConstantCache::TypePtr BuildFunctionType(const ShaderAst::DeclareFunctionStatement& functionNode);
|
||||
|
||||
UInt32 GetConstantId(const ShaderAst::ConstantValue& value) const;
|
||||
UInt32 GetExtendedInstructionSet(const std::string& instructionSetName) const;
|
||||
UInt32 GetExtVarPointerId(std::size_t varIndex) const;
|
||||
UInt32 GetFunctionTypeId(const ShaderAst::DeclareFunctionStatement& functionNode);
|
||||
UInt32 GetPointerTypeId(const ShaderAst::ExpressionType& type, SpirvStorageClass storageClass) const;
|
||||
|
|
|
|||
|
|
@ -466,6 +466,21 @@ namespace Nz::ShaderAst
|
|||
break;
|
||||
}
|
||||
|
||||
case IntrinsicType::Length:
|
||||
{
|
||||
if (clone->parameters.size() != 1)
|
||||
throw AstError{ "Expected only one parameters" };
|
||||
|
||||
for (auto& param : clone->parameters)
|
||||
MandatoryExpr(param);
|
||||
|
||||
const ExpressionType& type = GetExpressionType(*clone->parameters.front());
|
||||
if (!IsVectorType(type))
|
||||
throw AstError{ "Expected a vector" };
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case IntrinsicType::SampleTexture:
|
||||
{
|
||||
if (clone->parameters.size() != 2)
|
||||
|
|
@ -479,6 +494,8 @@ namespace Nz::ShaderAst
|
|||
|
||||
if (!IsVectorType(GetExpressionType(*clone->parameters[1])))
|
||||
throw AstError{ "Second parameter must be a vector" };
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -496,6 +513,7 @@ namespace Nz::ShaderAst
|
|||
}
|
||||
|
||||
case IntrinsicType::DotProduct:
|
||||
case IntrinsicType::Length:
|
||||
{
|
||||
ExpressionType type = GetExpressionType(*clone->parameters.front());
|
||||
if (!IsVectorType(type))
|
||||
|
|
|
|||
|
|
@ -806,6 +806,10 @@ namespace Nz
|
|||
Append("dot");
|
||||
break;
|
||||
|
||||
case ShaderAst::IntrinsicType::Length:
|
||||
Append("length");
|
||||
break;
|
||||
|
||||
case ShaderAst::IntrinsicType::SampleTexture:
|
||||
Append("texture");
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -654,6 +654,10 @@ namespace Nz
|
|||
Append("dot");
|
||||
break;
|
||||
|
||||
case ShaderAst::IntrinsicType::Length:
|
||||
Append("length");
|
||||
break;
|
||||
|
||||
case ShaderAst::IntrinsicType::SampleTexture:
|
||||
Append("texture");
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ namespace Nz::ShaderLang
|
|||
std::unordered_map<std::string, ShaderAst::IntrinsicType> s_identifierToIntrinsic = {
|
||||
{ "cross", ShaderAst::IntrinsicType::CrossProduct },
|
||||
{ "dot", ShaderAst::IntrinsicType::DotProduct },
|
||||
{ "length", ShaderAst::IntrinsicType::Length },
|
||||
};
|
||||
|
||||
std::unordered_map<std::string, ShaderAst::AttributeType> s_identifierToAttributeType = {
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
#include <Nazara/Shader/SpirvExpressionLoad.hpp>
|
||||
#include <Nazara/Shader/SpirvExpressionStore.hpp>
|
||||
#include <Nazara/Shader/SpirvWriter.hpp>
|
||||
#include <SpirV/GLSL.std.450.h>
|
||||
#include <Nazara/Shader/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
|
|
@ -600,7 +601,7 @@ namespace Nz
|
|||
m_instructions.Append(SpirvOp::OpFunctionEnd);
|
||||
}
|
||||
|
||||
void SpirvAstVisitor::Visit(ShaderAst::DeclareOptionStatement& node)
|
||||
void SpirvAstVisitor::Visit(ShaderAst::DeclareOptionStatement& /*node*/)
|
||||
{
|
||||
/* nothing to do */
|
||||
}
|
||||
|
|
@ -666,6 +667,25 @@ namespace Nz
|
|||
break;
|
||||
}
|
||||
|
||||
case ShaderAst::IntrinsicType::Length:
|
||||
{
|
||||
UInt32 glslInstructionSet = m_writer.GetExtendedInstructionSet("GLSL.std.450");
|
||||
|
||||
const ShaderAst::ExpressionType& vecExprType = GetExpressionType(*node.parameters[0]);
|
||||
assert(IsVectorType(vecExprType));
|
||||
|
||||
const ShaderAst::VectorType& vecType = std::get<ShaderAst::VectorType>(vecExprType);
|
||||
UInt32 typeId = m_writer.GetTypeId(vecType.type);
|
||||
|
||||
UInt32 vec = EvaluateExpression(node.parameters[0]);
|
||||
|
||||
UInt32 resultId = m_writer.AllocateResultId();
|
||||
|
||||
m_currentBlock->Append(SpirvOp::OpExtInst, typeId, resultId, glslInstructionSet, GLSLstd450Length, vec);
|
||||
PushResultId(resultId);
|
||||
break;
|
||||
}
|
||||
|
||||
case ShaderAst::IntrinsicType::SampleTexture:
|
||||
{
|
||||
UInt32 typeId = m_writer.GetTypeId(ShaderAst::VectorType{4, ShaderAst::PrimitiveType::Float32});
|
||||
|
|
|
|||
|
|
@ -274,6 +274,7 @@ namespace Nz
|
|||
{
|
||||
// Require GLSL.std.450
|
||||
case ShaderAst::IntrinsicType::CrossProduct:
|
||||
case ShaderAst::IntrinsicType::Length:
|
||||
extInsts.emplace("GLSL.std.450");
|
||||
break;
|
||||
|
||||
|
|
@ -363,7 +364,7 @@ namespace Nz
|
|||
UInt32 id;
|
||||
};
|
||||
|
||||
std::unordered_map<std::string, UInt32> extensionInstructions;
|
||||
std::unordered_map<std::string, UInt32> extensionInstructionSet;
|
||||
std::unordered_map<std::string, UInt32> varToResult;
|
||||
std::vector<SpirvAstVisitor::FuncData> funcs;
|
||||
std::vector<UInt32> resultIds;
|
||||
|
|
@ -408,7 +409,7 @@ namespace Nz
|
|||
m_currentState->preVisitor = &preVisitor;
|
||||
|
||||
for (const std::string& extInst : preVisitor.extInsts)
|
||||
state.extensionInstructions[extInst] = AllocateResultId();
|
||||
state.extensionInstructionSet[extInst] = AllocateResultId();
|
||||
|
||||
SpirvAstVisitor visitor(*this, state.instructions, state.funcs);
|
||||
targetAst->Visit(visitor);
|
||||
|
|
@ -465,7 +466,7 @@ namespace Nz
|
|||
|
||||
m_currentState->header.Append(SpirvOp::OpCapability, SpirvCapability::Shader);
|
||||
|
||||
for (const auto& [extInst, resultId] : m_currentState->extensionInstructions)
|
||||
for (const auto& [extInst, resultId] : m_currentState->extensionInstructionSet)
|
||||
m_currentState->header.Append(SpirvOp::OpExtInstImport, resultId, extInst);
|
||||
|
||||
m_currentState->header.Append(SpirvOp::OpMemoryModel, SpirvAddressingModel::Logical, SpirvMemoryModel::GLSL450);
|
||||
|
|
@ -534,6 +535,14 @@ namespace Nz
|
|||
return m_currentState->constantTypeCache.GetId(*m_currentState->constantTypeCache.BuildConstant(value));
|
||||
}
|
||||
|
||||
UInt32 SpirvWriter::GetExtendedInstructionSet(const std::string& instructionSetName) const
|
||||
{
|
||||
auto it = m_currentState->extensionInstructionSet.find(instructionSetName);
|
||||
assert(it != m_currentState->extensionInstructionSet.end());
|
||||
|
||||
return it->second;
|
||||
}
|
||||
|
||||
UInt32 SpirvWriter::GetExtVarPointerId(std::size_t extVarIndex) const
|
||||
{
|
||||
auto it = m_currentState->preVisitor->extVars.find(extVarIndex);
|
||||
|
|
|
|||
Loading…
Reference in New Issue