Shader: Add basic support for Branch node in spir-v

This commit is contained in:
Jérôme Leclercq
2021-01-04 10:27:08 +01:00
parent 44bc86d082
commit 4d63d6e022
16 changed files with 186 additions and 48 deletions

View File

@@ -4,13 +4,14 @@
#pragma once
#ifndef NAZARA_SPIRVEXPRESSIONLOAD_HPP
#define NAZARA_SPIRVEXPRESSIONLOAD_HPP
#ifndef NAZARA_SPIRVASTVISITOR_HPP
#define NAZARA_SPIRVASTVISITOR_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Shader/Config.hpp>
#include <Nazara/Shader/ShaderAstVisitorExcept.hpp>
#include <Nazara/Shader/ShaderVarVisitorExcept.hpp>
#include <Nazara/Shader/SpirvBlock.hpp>
#include <vector>
namespace Nz
@@ -20,7 +21,7 @@ namespace Nz
class NAZARA_SHADER_API SpirvAstVisitor : public ShaderAstVisitorExcept
{
public:
inline SpirvAstVisitor(SpirvWriter& writer);
inline SpirvAstVisitor(SpirvWriter& writer, std::vector<SpirvBlock>& blocks);
SpirvAstVisitor(const SpirvAstVisitor&) = delete;
SpirvAstVisitor(SpirvAstVisitor&&) = delete;
~SpirvAstVisitor() = default;
@@ -31,6 +32,7 @@ namespace Nz
void Visit(ShaderNodes::AccessMember& node) override;
void Visit(ShaderNodes::AssignOp& node) override;
void Visit(ShaderNodes::BinaryOp& node) override;
void Visit(ShaderNodes::Branch& node) override;
void Visit(ShaderNodes::Cast& node) override;
void Visit(ShaderNodes::ConditionalExpression& node) override;
void Visit(ShaderNodes::ConditionalStatement& node) override;
@@ -51,6 +53,8 @@ namespace Nz
void PushResultId(UInt32 value);
UInt32 PopResultId();
SpirvBlock* m_currentBlock;
std::vector<SpirvBlock>& m_blocks;
std::vector<UInt32> m_resultIds;
SpirvWriter& m_writer;
};

View File

@@ -7,9 +7,11 @@
namespace Nz
{
inline SpirvAstVisitor::SpirvAstVisitor(SpirvWriter& writer) :
inline SpirvAstVisitor::SpirvAstVisitor(SpirvWriter& writer, std::vector<SpirvBlock>& blocks) :
m_blocks(blocks),
m_writer(writer)
{
m_currentBlock = &m_blocks.back();
}
}

View File

@@ -0,0 +1,38 @@
// Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - Shader generator"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_SPIRVBLOCK_HPP
#define NAZARA_SPIRVBLOCK_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Shader/SpirvSection.hpp>
#include <Nazara/Shader/SpirvWriter.hpp>
#include <string>
#include <vector>
namespace Nz
{
class NAZARA_SHADER_API SpirvBlock : public SpirvSection
{
public:
inline SpirvBlock(SpirvWriter& writer);
SpirvBlock(const SpirvBlock&) = default;
SpirvBlock(SpirvBlock&&) = default;
~SpirvBlock() = default;
inline UInt32 GetLabelId() const;
SpirvBlock& operator=(const SpirvBlock&) = delete;
SpirvBlock& operator=(SpirvBlock&&) = default;
private:
UInt32 m_labelId;
};
}
#include <Nazara/Shader/SpirvBlock.inl>
#endif

View File

@@ -0,0 +1,22 @@
// Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - Shader generator"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Shader/SpirvBlock.hpp>
#include <Nazara/Shader/Debug.hpp>
namespace Nz
{
inline SpirvBlock::SpirvBlock(SpirvWriter& writer)
{
m_labelId = writer.AllocateResultId();
Append(SpirvOp::OpLabel, m_labelId);
}
inline UInt32 SpirvBlock::GetLabelId() const
{
return m_labelId;
}
}
#include <Nazara/Shader/DebugOff.hpp>

View File

@@ -4,8 +4,8 @@
#pragma once
#ifndef NAZARA_SPIRVEXPRESSIONLOADACCESSMEMBER_HPP
#define NAZARA_SPIRVEXPRESSIONLOADACCESSMEMBER_HPP
#ifndef NAZARA_SPIRVEXPRESSIONLOAD_HPP
#define NAZARA_SPIRVEXPRESSIONLOAD_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Shader/Config.hpp>
@@ -16,12 +16,13 @@
namespace Nz
{
class SpirvBlock;
class SpirvWriter;
class NAZARA_SHADER_API SpirvExpressionLoad : public ShaderAstVisitorExcept, public ShaderVarVisitorExcept
{
public:
inline SpirvExpressionLoad(SpirvWriter& writer);
inline SpirvExpressionLoad(SpirvWriter& writer, SpirvBlock& block);
SpirvExpressionLoad(const SpirvExpressionLoad&) = delete;
SpirvExpressionLoad(SpirvExpressionLoad&&) = delete;
~SpirvExpressionLoad() = default;
@@ -53,6 +54,7 @@ namespace Nz
UInt32 resultId;
};
SpirvBlock& m_block;
SpirvWriter& m_writer;
std::variant<std::monostate, Pointer, Value> m_value;
};

View File

@@ -7,7 +7,8 @@
namespace Nz
{
inline SpirvExpressionLoad::SpirvExpressionLoad(SpirvWriter& writer) :
inline SpirvExpressionLoad::SpirvExpressionLoad(SpirvWriter& writer, SpirvBlock& block) :
m_block(block),
m_writer(writer)
{
}

View File

@@ -15,13 +15,13 @@
namespace Nz
{
class SpirvSection;
class SpirvBlock;
class SpirvWriter;
class NAZARA_SHADER_API SpirvExpressionStore : public ShaderAstVisitorExcept, public ShaderVarVisitorExcept
{
public:
inline SpirvExpressionStore(SpirvWriter& writer);
inline SpirvExpressionStore(SpirvWriter& writer, SpirvBlock& block);
SpirvExpressionStore(const SpirvExpressionStore&) = delete;
SpirvExpressionStore(SpirvExpressionStore&&) = delete;
~SpirvExpressionStore() = default;
@@ -53,6 +53,7 @@ namespace Nz
UInt32 resultId;
};
SpirvBlock& m_block;
SpirvWriter& m_writer;
std::variant<std::monostate, LocalVar, Pointer> m_value;
};

View File

@@ -7,7 +7,8 @@
namespace Nz
{
inline SpirvExpressionStore::SpirvExpressionStore(SpirvWriter& writer) :
inline SpirvExpressionStore::SpirvExpressionStore(SpirvWriter& writer, SpirvBlock& block) :
m_block(block),
m_writer(writer)
{
}

View File

@@ -22,8 +22,8 @@ namespace Nz
struct Raw;
SpirvSection() = default;
SpirvSection(const SpirvSection& cache) = default;
SpirvSection(SpirvSection&& cache) = default;
SpirvSection(const SpirvSection&) = default;
SpirvSection(SpirvSection&&) = default;
~SpirvSection() = default;
inline std::size_t Append(const char* str);
@@ -35,20 +35,21 @@ namespace Nz
inline std::size_t Append(std::initializer_list<UInt32> codepoints);
template<typename... Args> std::size_t Append(SpirvOp opcode, const Args&... args);
template<typename F> std::size_t AppendVariadic(SpirvOp opcode, F&& callback);
template<typename T> std::size_t Append(T value);
inline std::size_t Append(const SpirvSection& section);
template<typename T, typename = std::enable_if_t<std::is_integral_v<T> || std::is_enum_v<T>>> std::size_t Append(T value);
inline unsigned int CountWord(const char* str);
inline unsigned int CountWord(const std::string_view& str);
inline unsigned int CountWord(const std::string& str);
inline unsigned int CountWord(const Raw& raw);
template<typename T> unsigned int CountWord(const T& value);
template<typename T, typename = std::enable_if_t<std::is_integral_v<T> || std::is_enum_v<T>>> unsigned int CountWord(const T& value);
template<typename T1, typename T2, typename... Args> unsigned int CountWord(const T1& value, const T2& value2, const Args&... rest);
inline const std::vector<UInt32>& GetBytecode() const;
inline std::size_t GetOutputOffset() const;
SpirvSection& operator=(const SpirvSection& cache) = delete;
SpirvSection& operator=(SpirvSection&& cache) = default;
SpirvSection& operator=(const SpirvSection&) = delete;
SpirvSection& operator=(SpirvSection&&) = default;
struct OpSize
{

View File

@@ -61,6 +61,17 @@ namespace Nz
return offset;
}
inline std::size_t SpirvSection::Append(const SpirvSection& section)
{
const std::vector<UInt32>& bytecode = section.GetBytecode();
std::size_t offset = GetOutputOffset();
m_bytecode.resize(offset + bytecode.size());
std::copy(bytecode.begin(), bytecode.end(), m_bytecode.begin() + offset);
return offset;
}
template<typename ...Args>
std::size_t SpirvSection::Append(SpirvOp opcode, const Args&... args)
{
@@ -89,13 +100,13 @@ namespace Nz
return offset;
}
template<typename T>
template<typename T, typename>
std::size_t SpirvSection::Append(T value)
{
return Append(static_cast<UInt32>(value));
}
template<typename T>
template<typename T, typename>
unsigned int SpirvSection::CountWord(const T& /*value*/)
{
return 1;

View File

@@ -26,6 +26,7 @@ namespace Nz
class NAZARA_SHADER_API SpirvWriter : public ShaderWriter
{
friend class SpirvAstVisitor;
friend class SpirvBlock;
friend class SpirvExpressionLoad;
friend class SpirvExpressionStore;
friend class SpirvVisitor;
@@ -62,7 +63,6 @@ namespace Nz
const ExtVar& GetInputVariable(const std::string& name) const;
const ExtVar& GetOutputVariable(const std::string& name) const;
const ExtVar& GetUniformVariable(const std::string& name) const;
SpirvSection& GetInstructions();
UInt32 GetPointerTypeId(const ShaderExpressionType& type, SpirvStorageClass storageClass) const;
UInt32 GetTypeId(const ShaderExpressionType& type) const;