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