Merge pull request #325 from DigitalPulseSoftware/shader-nodes

Add ShaderNode editor
This commit is contained in:
Jérôme Leclercq 2020-08-25 12:21:46 +02:00 committed by GitHub
commit fa6d026edc
294 changed files with 36144 additions and 1730 deletions

4
.gitignore vendored
View File

@ -1,6 +1,10 @@
# Nazara build # Nazara build
build/config.lua build/config.lua
# Nazara binaries
bin/*
# Build files
build/gmake*/ build/gmake*/
build/vs*/ build/vs*/

View File

@ -0,0 +1,9 @@
// This file was automatically generated
#pragma once
#ifndef NDK_COMPONENTS_GLOBAL_HPP
#define NDK_COMPONENTS_GLOBAL_HPP
#endif // NDK_COMPONENTS_GLOBAL_HPP

View File

@ -0,0 +1,9 @@
// This file was automatically generated
#pragma once
#ifndef NDK_SYSTEMS_GLOBAL_HPP
#define NDK_SYSTEMS_GLOBAL_HPP
#endif // NDK_SYSTEMS_GLOBAL_HPP

View File

@ -0,0 +1,9 @@
// This file was automatically generated
#pragma once
#ifndef NDK_WIDGETS_GLOBAL_HPP
#define NDK_WIDGETS_GLOBAL_HPP
#endif // NDK_WIDGETS_GLOBAL_HPP

View File

@ -24,3 +24,18 @@ ServerMode = false
-- Builds modules as one united library (useless on POSIX systems) -- Builds modules as one united library (useless on POSIX systems)
UniteModules = false UniteModules = false
-- Qt5 directories (required for ShaderNodes editor)
--Qt5IncludeDir = [[C:\Projets\Libs\Qt\5.15.0\msvc2019\include]]
--Qt5BinDir_x86 = [[C:\Projets\Libs\Qt\5.15.0\msvc2019\bin]]
--Qt5BinDir_x64 = [[C:\Projets\Libs\Qt\5.15.0\msvc2019_64\bin]]
--Qt5LibDir_x86 = [[C:\Projets\Libs\Qt\5.15.0\msvc2019\lib]]
--Qt5LibDir_x64 = [[C:\Projets\Libs\Qt\5.15.0\msvc2019_64\lib]]
-- QtNodes directories (required for ShaderNodes editor)
--QtNodesIncludeDir = [[C:\Projets\Libs\nodeeditor\include]]
--QtNodesBinDir_x86 = [[C:\Projets\Libs\nodeeditor\build32\bin\Release]]
--QtNodesBinDir_x64 = [[C:\Projets\Libs\nodeeditor\build64\bin\Release]]
--QtNodesLibDir_x86 = [[C:\Projets\Libs\nodeeditor\build32\lib\Release]]
--QtNodesLibDir_x64 = [[C:\Projets\Libs\nodeeditor\build64\lib\Release]]

View File

@ -0,0 +1,223 @@
ACTION.Name = "UpdateSpirV"
ACTION.Description = "Download and parse the SpirV grammar and generate a .cpp file for it"
local spirvGrammarURI = "https://raw.githubusercontent.com/KhronosGroup/SPIRV-Headers/master/include/spirv/unified1/spirv.core.grammar.json"
ACTION.Function = function()
io.write("Downloading Spir-V grammar... ")
local content, resultStr, resultCode = http.get(spirvGrammarURI, {
headers = { "From: Premake", "Referer: Premake" }
})
if (resultCode ~= 200) then
error("Failed to download SpirV grammar: " .. resultStr)
end
print("Done")
local result, err = json.decode(content)
assert(result, err)
local instructions = {}
local instructionById = {}
for _, instruction in pairs(result.instructions) do
local duplicateId = instructionById[instruction.opcode]
if (duplicateId == nil) then
table.insert(instructions, instruction)
instructionById[instruction.opcode] = #instructions
else
instructions[duplicateId] = instruction
end
end
local operands = {}
local operandByInstruction = {}
for _, instruction in pairs(instructions) do
if (instruction.operands) then
local firstId = #operands
local operandCount = #instruction.operands
for _, operand in pairs(instruction.operands) do
table.insert(operands, operand)
end
operandByInstruction[instruction.opcode] = { firstId = firstId, count = operandCount }
end
end
local headerFile = io.open("../include/Nazara/Shader/SpirvData.hpp", "w+")
assert(headerFile, "failed to open Spir-V header")
headerFile:write([[
// Copyright (C) ]] .. os.date("%Y") .. [[ 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"
// This file was generated automatically, please do not edit
#pragma once
#ifndef NAZARA_SPIRVDATA_HPP
#define NAZARA_SPIRVDATA_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Shader/Config.hpp>
namespace Nz
{
]])
-- SpirV operations
headerFile:write([[
enum class SpirvOp
{
]])
for _, instruction in pairs(result.instructions) do
headerFile:write("\t\t" .. instruction.opname .. " = " .. instruction.opcode .. ",\n")
end
headerFile:write([[
};
]])
-- SpirV operands
headerFile:write([[
enum class SpirvOperandKind
{
]])
for _, operand in pairs(result.operand_kinds) do
headerFile:write("\t\t" .. operand.kind .. ",\n")
end
headerFile:write([[
};
]])
-- SpirV enums
for _, operand in pairs(result.operand_kinds) do
if (operand.category == "ValueEnum") then
headerFile:write([[
enum class Spirv]] .. operand.kind .. [[
{
]])
for _, enumerant in pairs(operand.enumerants) do
local eName = enumerant.enumerant:match("^%d") and operand.kind .. enumerant.enumerant or enumerant.enumerant
headerFile:write([[
]] .. eName .. [[ = ]] .. enumerant.value .. [[,
]])
end
headerFile:write([[
};
]])
end
end
-- Struct
headerFile:write([[
struct SpirvInstruction
{
struct Operand
{
SpirvOperandKind kind;
const char* name;
};
SpirvOp op;
const char* name;
const Operand* operands;
std::size_t minOperandCount;
};
]])
-- Functions signatures
headerFile:write([[
NAZARA_SHADER_API const SpirvInstruction* GetInstructionData(UInt16 op);
]])
headerFile:write([[
}
#endif
]])
local sourceFile = io.open("../src/Nazara/Shader/SpirvData.cpp", "w+")
assert(sourceFile, "failed to open Spir-V source")
sourceFile:write([[
// Copyright (C) ]] .. os.date("%Y") .. [[ 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"
// This file was generated automatically, please do not edit
#include <Nazara/Shader/SpirvData.hpp>
#include <algorithm>
#include <array>
#include <cassert>
namespace Nz
{
static constexpr std::array<SpirvInstruction::Operand, ]] .. #operands .. [[> s_operands = {
{
]])
for _, operand in pairs(operands) do
sourceFile:write([[
{
SpirvOperandKind::]] .. operand.kind .. [[,
R"(]] .. (operand.name or operand.kind) .. [[)"
},
]])
end
sourceFile:write([[
}
};
static std::array<SpirvInstruction, ]] .. #instructions .. [[> s_instructions = {
{
]])
for _, instruction in pairs(instructions) do
local opByInstruction = operandByInstruction[instruction.opcode]
sourceFile:write([[
{
SpirvOp::]] .. instruction.opname .. [[,
R"(]] .. instruction.opname .. [[)",
]] .. (opByInstruction and "&s_operands[" .. opByInstruction.firstId .. "]" or "nullptr") .. [[,
]] .. (opByInstruction and opByInstruction.count or "0") .. [[,
},
]])
end
sourceFile:write([[
}
};
]])
-- Operand to string
sourceFile:write([[
const SpirvInstruction* GetInstructionData(UInt16 op)
{
auto it = std::lower_bound(std::begin(s_instructions), std::end(s_instructions), op, [](const SpirvInstruction& inst, UInt16 op) { return UInt16(inst.op) < op; });
if (it != std::end(s_instructions) && UInt16(it->op) == op)
return &*it;
else
return nullptr;
}
]])
sourceFile:write([[
}
]])
end

View File

@ -699,6 +699,24 @@ local PosixOSes = {
["solaris"] = true ["solaris"] = true
} }
local function ProcessOption(libName, option, enable)
return libName:gsub("%%" .. option .. "%((.+)%)", enable and "%1" or "")
end
local function HandleLib(infoTable, libName)
local debugDynamic = ProcessOption(ProcessOption(libName, "d", true), "s", false)
local debugStatic = ProcessOption(ProcessOption(libName, "d", true), "s", true)
local releaseStatic = ProcessOption(ProcessOption(libName, "d", false), "s", true)
local releaseDynamic = ProcessOption(ProcessOption(libName, "d", false), "s", false)
table.insert(infoTable.ConfigurationLibraries.DebugStatic, debugStatic)
table.insert(infoTable.ConfigurationLibraries.ReleaseStatic, releaseStatic)
table.insert(infoTable.ConfigurationLibraries.ReleaseWithDebugStatic, releaseStatic)
table.insert(infoTable.ConfigurationLibraries.DebugDynamic, debugDynamic)
table.insert(infoTable.ConfigurationLibraries.ReleaseDynamic, releaseDynamic)
table.insert(infoTable.ConfigurationLibraries.ReleaseWithDebugDynamic, releaseDynamic)
end
function NazaraBuild:Process(infoTable) function NazaraBuild:Process(infoTable)
if (infoTable.Excluded) then if (infoTable.Excluded) then
return false return false
@ -718,16 +736,11 @@ function NazaraBuild:Process(infoTable)
if (_OPTIONS["united"]) then if (_OPTIONS["united"]) then
library = "NazaraEngine" library = "NazaraEngine"
else else
library = "Nazara" .. libraryTable.Name library = "Nazara" .. libraryTable.Name .. "%s(-s)%d(-d)"
end end
if (not self.Config["UniteModules"] or infoTable.Type ~= "Module") then if (not self.Config["UniteModules"] or infoTable.Type ~= "Module") then
table.insert(infoTable.ConfigurationLibraries.DebugStatic, library .. "-s-d") HandleLib(infoTable, library)
table.insert(infoTable.ConfigurationLibraries.ReleaseStatic, library .. "-s")
table.insert(infoTable.ConfigurationLibraries.ReleaseWithDebugStatic, library .. "-s")
table.insert(infoTable.ConfigurationLibraries.DebugDynamic, library .. "-d")
table.insert(infoTable.ConfigurationLibraries.ReleaseDynamic, library)
table.insert(infoTable.ConfigurationLibraries.ReleaseWithDebugDynamic, library)
end end
elseif (libraryTable.Type == "ExternLib") then elseif (libraryTable.Type == "ExternLib") then
library = libraryTable.Name library = libraryTable.Name
@ -735,15 +748,10 @@ function NazaraBuild:Process(infoTable)
if (self.Config["BuildDependencies"]) then if (self.Config["BuildDependencies"]) then
table.insert(libraries, library) table.insert(libraries, library)
else else
table.insert(infoTable.ConfigurationLibraries.DebugStatic, library .. "-s-d") HandleLib(infoTable, library)
table.insert(infoTable.ConfigurationLibraries.ReleaseStatic, library .. "-s")
table.insert(infoTable.ConfigurationLibraries.ReleaseWithDebugStatic, library .. "-s")
table.insert(infoTable.ConfigurationLibraries.DebugDynamic, library .. "-s-d")
table.insert(infoTable.ConfigurationLibraries.ReleaseDynamic, library .. "-s")
table.insert(infoTable.ConfigurationLibraries.ReleaseWithDebugDynamic, library .. "-s")
end end
elseif (libraryTable.Type == "Tool") then elseif (libraryTable.Type == "Tool") then
library = "Nazara" .. libraryTable.Name library = "Nazara" .. libraryTable.Name .. "%s(-s)%d(-d)"
-- Import tools includes -- Import tools includes
for k,v in ipairs(libraryTable.Includes) do for k,v in ipairs(libraryTable.Includes) do
@ -761,19 +769,14 @@ function NazaraBuild:Process(infoTable)
end end
end end
table.insert(infoTable.ConfigurationLibraries.DebugStatic, library .. "-s-d") HandleLib(infoTable, library)
table.insert(infoTable.ConfigurationLibraries.ReleaseStatic, library .. "-s")
table.insert(infoTable.ConfigurationLibraries.ReleaseWithDebugStatic, library .. "-s")
table.insert(infoTable.ConfigurationLibraries.DebugDynamic, library .. "-d")
table.insert(infoTable.ConfigurationLibraries.ReleaseDynamic, library)
table.insert(infoTable.ConfigurationLibraries.ReleaseWithDebugDynamic, library)
else else
infoTable.Excluded = true infoTable.Excluded = true
infoTable.ExcludeReason = "dependency " .. library .. " has invalid type \"" .. libraryTable.Type .. "\"" infoTable.ExcludeReason = "dependency " .. library .. " has invalid type \"" .. libraryTable.Type .. "\""
return false return false
end end
else else
table.insert(libraries, library) HandleLib(infoTable, library)
end end
end end
infoTable.Libraries = libraries infoTable.Libraries = libraries
@ -881,9 +884,11 @@ function NazaraBuild:PreconfigGenericProject()
filter("configurations:*Dynamic") filter("configurations:*Dynamic")
kind("SharedLib") kind("SharedLib")
-- Enable MSVC conformance (not required but better) -- Enable MSVC conformance (not required but better) and some extra warnings
filter("action:vs*") filter("action:vs*")
buildoptions({"/permissive-", "/Zc:__cplusplus", "/Zc:referenceBinding", "/Zc:throwingNew"}) buildoptions({"/permissive-", "/Zc:__cplusplus", "/Zc:referenceBinding", "/Zc:throwingNew"})
--enablewarnings("4062") -- switch case not handled
buildoptions("/w44062") -- looks like enablewarnings is broken currently for msvc
-- Enable SSE math and vectorization optimizations -- Enable SSE math and vectorization optimizations
filter({"configurations:Release*", clangGccActions}) filter({"configurations:Release*", clangGccActions})

View File

@ -2,12 +2,9 @@ MODULE.Name = "Renderer"
MODULE.ClientOnly = true MODULE.ClientOnly = true
MODULE.Defines = {
"NAZARA_RENDERER_OPENGL"
}
MODULE.Libraries = { MODULE.Libraries = {
"NazaraCore", "NazaraCore",
"NazaraShader",
"NazaraUtility", "NazaraUtility",
"NazaraPlatform" "NazaraPlatform"
} }
@ -22,14 +19,3 @@ MODULE.OsFiles.Posix = {
"../src/Nazara/Renderer/GLX/**.cpp" "../src/Nazara/Renderer/GLX/**.cpp"
} }
MODULE.OsLibraries.Windows = {
"gdi32",
"opengl32",
"winmm"
}
MODULE.OsLibraries.Posix = {
"GL",
"X11"
}

View File

@ -0,0 +1,6 @@
MODULE.Name = "Shader"
MODULE.Libraries = {
"NazaraCore",
"NazaraUtility"
}

View File

@ -27,6 +27,7 @@ TOOL.Files = {
TOOL.Libraries = { TOOL.Libraries = {
"NazaraCore", "NazaraCore",
"NazaraRenderer", "NazaraRenderer",
"NazaraShader",
"NazaraUtility" "NazaraUtility"
} }

View File

@ -0,0 +1,92 @@
TOOL.Name = "ShaderNodes"
TOOL.ClientOnly = true
TOOL.EnableConsole = true
TOOL.Kind = "Application"
TOOL.TargetDirectory = "../bin"
TOOL.Defines = {
"NODE_EDITOR_SHARED"
}
TOOL.Includes = {
"../include",
"../extlibs/include",
"../src"
}
TOOL.Files = {
"../src/ShaderNode/**.hpp",
"../src/ShaderNode/**.inl",
"../src/ShaderNode/**.cpp"
}
TOOL.Libraries = {
"NazaraCore%s(-s)%d(-d)",
"NazaraShader%s(-s)%d(-d)",
"NazaraUtility%s(-s)%d(-d)",
"Qt5Core%d(d)",
"Qt5Gui%d(d)",
"Qt5Widgets%d(d)",
"nodes%d(d)"
}
local function AppendValues(tab, value)
if (type(value) == "table") then
for _, v in pairs(value) do
AppendValues(tab, v)
end
else
table.insert(tab, value)
end
end
function TOOL:ValidateLib(libName)
local config = NazaraBuild:GetConfig()
local includes = config[libName .. "IncludeDir"]
local binDir32 = config[libName .. "BinDir_x86"]
local binDir64 = config[libName .. "BinDir_x64"]
local libDir32 = config[libName .. "LibDir_x86"]
local libDir64 = config[libName .. "LibDir_x64"]
if (not includes) then
return false, "missing " .. libName .. " includes directories in config.lua"
end
if (not libDir32 and not libDir64) then
return false, "missing " .. libName .. " library search directories in config.lua"
end
AppendValues(self.Includes, includes)
if (binDir32) then
AppendValues(self.BinaryPaths.x86, binDir32)
end
if (binDir64) then
AppendValues(self.BinaryPaths.x64, binDir64)
end
if (libDir32) then
AppendValues(self.LibraryPaths.x86, libDir32)
end
if (libDir64) then
AppendValues(self.LibraryPaths.x64, libDir64)
end
return true
end
function TOOL:Validate()
local success, err = self:ValidateLib("Qt5")
if (not success) then
return false, err
end
local success, err = self:ValidateLib("QtNodes")
if (not success) then
return false, err
end
return true
end

View File

@ -28,6 +28,7 @@ TOOL.Files = {
TOOL.Libraries = { TOOL.Libraries = {
"NazaraCore", "NazaraCore",
"NazaraRenderer", "NazaraRenderer",
"NazaraShader",
"NazaraUtility" "NazaraUtility"
} }

View File

@ -3,8 +3,6 @@
#include <array> #include <array>
#include <iostream> #include <iostream>
#define SPIRV 1
int main() int main()
{ {
Nz::Initializer<Nz::Renderer> loader; Nz::Initializer<Nz::Renderer> loader;
@ -29,35 +27,19 @@ int main()
std::shared_ptr<Nz::RenderDevice> device = window.GetRenderDevice(); std::shared_ptr<Nz::RenderDevice> device = window.GetRenderDevice();
#if SPIRV auto fragmentShader = device->InstantiateShaderStage(Nz::ShaderStageType::Fragment, Nz::ShaderLanguage::NazaraBinary, "frag.shader");
auto fragmentShader = device->InstantiateShaderStage(Nz::ShaderStageType::Fragment, Nz::ShaderLanguage::SpirV, "resources/shaders/triangle.frag.spv");
if (!fragmentShader) if (!fragmentShader)
{ {
std::cout << "Failed to instantiate fragment shader" << std::endl; std::cout << "Failed to instantiate fragment shader" << std::endl;
return __LINE__; return __LINE__;
} }
auto vertexShader = device->InstantiateShaderStage(Nz::ShaderStageType::Vertex, Nz::ShaderLanguage::SpirV, "resources/shaders/triangle.vert.spv"); auto vertexShader = device->InstantiateShaderStage(Nz::ShaderStageType::Vertex, Nz::ShaderLanguage::NazaraBinary, "vert.shader");
if (!vertexShader) if (!vertexShader)
{ {
std::cout << "Failed to instantiate fragment shader" << std::endl; std::cout << "Failed to instantiate fragment shader" << std::endl;
return __LINE__; return __LINE__;
} }
#else
auto fragmentShader = device->InstantiateShaderStage(Nz::ShaderStageType::Fragment, Nz::ShaderLanguage::GLSL, "resources/shaders/triangle.frag");
if (!fragmentShader)
{
std::cout << "Failed to instantiate fragment shader" << std::endl;
return __LINE__;
}
auto vertexShader = device->InstantiateShaderStage(Nz::ShaderStageType::Vertex, Nz::ShaderLanguage::GLSL, "resources/shaders/triangle.vert");
if (!vertexShader)
{
std::cout << "Failed to instantiate fragment shader" << std::endl;
return __LINE__;
}
#endif
Nz::MeshRef drfreak = Nz::Mesh::LoadFromFile("resources/Spaceship/spaceship.obj", meshParams); Nz::MeshRef drfreak = Nz::Mesh::LoadFromFile("resources/Spaceship/spaceship.obj", meshParams);
@ -229,6 +211,8 @@ int main()
Nz::Clock secondClock; Nz::Clock secondClock;
unsigned int fps = 0; unsigned int fps = 0;
Nz::Mouse::SetRelativeMouseMode(true);
while (window.IsOpen()) while (window.IsOpen())
{ {
Nz::WindowEvent event; Nz::WindowEvent event;
@ -252,10 +236,6 @@ int main()
camAngles.pitch = Nz::Clamp(camAngles.pitch + event.mouseMove.deltaY*sensitivity, -89.f, 89.f); camAngles.pitch = Nz::Clamp(camAngles.pitch + event.mouseMove.deltaY*sensitivity, -89.f, 89.f);
camQuat = camAngles; camQuat = camAngles;
// Pour éviter que le curseur ne sorte de l'écran, nous le renvoyons au centre de la fenêtre
// Cette fonction est codée de sorte à ne pas provoquer d'évènement MouseMoved
Nz::Mouse::SetPosition(windowSize.x / 2, windowSize.y / 2, window);
break; break;
} }
} }

BIN
examples/bin/frag.shader Normal file

Binary file not shown.

BIN
examples/bin/test.spirv Normal file

Binary file not shown.

BIN
examples/bin/vert.shader Normal file

Binary file not shown.

View File

@ -62,6 +62,7 @@
#include <Nazara/Core/MemoryStream.hpp> #include <Nazara/Core/MemoryStream.hpp>
#include <Nazara/Core/MemoryView.hpp> #include <Nazara/Core/MemoryView.hpp>
#include <Nazara/Core/MovablePtr.hpp> #include <Nazara/Core/MovablePtr.hpp>
#include <Nazara/Core/MovableValue.hpp>
#include <Nazara/Core/ObjectHandle.hpp> #include <Nazara/Core/ObjectHandle.hpp>
#include <Nazara/Core/ObjectLibrary.hpp> #include <Nazara/Core/ObjectLibrary.hpp>
#include <Nazara/Core/ObjectRef.hpp> #include <Nazara/Core/ObjectRef.hpp>

View File

@ -400,7 +400,7 @@ namespace Nz
if (squaredDistance > squaredRadius) if (squaredDistance > squaredRadius)
return false; // if the ray is further than the radius return false; // if the ray is further than the radius
// Calcul des points d'intersection si besoin // Compute intersections points if required
if (closestHit || furthestHit) if (closestHit || furthestHit)
{ {
T deltaLambda = std::sqrt(squaredRadius - squaredDistance); T deltaLambda = std::sqrt(squaredRadius - squaredDistance);

View File

@ -54,7 +54,7 @@ namespace Nz
Vector2& Set(T X, T Y); Vector2& Set(T X, T Y);
Vector2& Set(T scale); Vector2& Set(T scale);
Vector2& Set(const T vec[2]); Vector2& Set(const T* vec);
Vector2& Set(const Vector3<T>& vec); Vector2& Set(const Vector3<T>& vec);
Vector2& Set(const Vector4<T>& vec); Vector2& Set(const Vector4<T>& vec);
template<typename U> Vector2& Set(const Vector2<U>& vec); template<typename U> Vector2& Set(const Vector2<U>& vec);
@ -63,8 +63,8 @@ namespace Nz
String ToString() const; String ToString() const;
operator T* (); T& operator[](std::size_t i);
operator const T* () const; T operator[](std::size_t i) const;
const Vector2& operator+() const; const Vector2& operator+() const;
Vector2 operator-() const; Vector2 operator-() const;

View File

@ -363,9 +363,8 @@ namespace Nz
* *
* \param vec[2] vec[0] is X component and vec[1] is Y component * \param vec[2] vec[0] is X component and vec[1] is Y component
*/ */
template<typename T> template<typename T>
Vector2<T>& Vector2<T>::Set(const T vec[2]) Vector2<T>& Vector2<T>::Set(const T* vec)
{ {
x = vec[0]; x = vec[0];
y = vec[1]; y = vec[1];
@ -451,29 +450,25 @@ namespace Nz
} }
/*! /*!
* \brief Converts vector to pointer to its own data * \brief Access a vector component by index
* \return A pointer to the own data * \return X, Y depending on index (0, 1)
*
* \remark Access to index greather than 1 is undefined behavior
*/ */
template<typename T> template<typename T>
Vector2<T>::operator T* () T& Vector2<T>::operator[](std::size_t i)
{ {
return &x; NazaraAssert(i < 2, "index out of range");
return *(&x + i);
} }
/*! /*!
* \brief Converts vector to const pointer to its own data * \brief Access a vector component by index
* \return A constant pointer to the own data * \return X, Y depending on index (0, 1)
*
* \remark Access to index greather than 1 is undefined behavior
*/ */
template<typename T> template<typename T>
Vector2<T>::operator const T* () const T Vector2<T>::operator[](std::size_t i) const
{ {
return &x; NazaraAssert(i < 2, "index out of range");
return *(&x + i);
} }
/*! /*!

View File

@ -65,7 +65,7 @@ namespace Nz
Vector3& Set(T X, T Y, T Z); Vector3& Set(T X, T Y, T Z);
Vector3& Set(T X, const Vector2<T>& vec); Vector3& Set(T X, const Vector2<T>& vec);
Vector3& Set(T scale); Vector3& Set(T scale);
Vector3& Set(const T vec[3]); Vector3& Set(const T* vec);
Vector3& Set(const Vector2<T>& vec, T Z = 0.0); Vector3& Set(const Vector2<T>& vec, T Z = 0.0);
template<typename U> Vector3& Set(const Vector3<U>& vec); template<typename U> Vector3& Set(const Vector3<U>& vec);
Vector3& Set(const Vector4<T>& vec); Vector3& Set(const Vector4<T>& vec);
@ -74,8 +74,8 @@ namespace Nz
String ToString() const; String ToString() const;
operator T* (); T& operator[](std::size_t i);
operator const T* () const; T operator[](std::size_t i) const;
const Vector3& operator+() const; const Vector3& operator+() const;
Vector3 operator-() const; Vector3 operator-() const;

View File

@ -498,7 +498,7 @@ namespace Nz
* \param vec[3] vec[0] is X component, vec[1] is Y component and vec[2] is Z component * \param vec[3] vec[0] is X component, vec[1] is Y component and vec[2] is Z component
*/ */
template<typename T> template<typename T>
Vector3<T>& Vector3<T>::Set(const T vec[3]) Vector3<T>& Vector3<T>::Set(const T* vec)
{ {
x = vec[0]; x = vec[0];
y = vec[1]; y = vec[1];
@ -583,27 +583,25 @@ namespace Nz
} }
/*! /*!
* \brief Converts vector to pointer to its own data * \brief Access a vector component by index
* \return A pointer to the own data * \return X, Y, Z depending on index (0, 1, 2)
*
* \remark Access to index greather than 2 is undefined behavior
*/ */
template<typename T> template<typename T>
Vector3<T>::operator T* () T& Vector3<T>::operator[](std::size_t i)
{ {
return &x; NazaraAssert(i < 3, "index out of range");
return *(&x + i);
} }
/*! /*!
* \brief Converts vector to const pointer to its own data * \brief Access a vector component by index
* \return A constant pointer to the own data * \return X, Y, Z depending on index (0, 1, 2)
*
* \remark Access to index greather than 2 is undefined behavior
*/ */
template<typename T> template<typename T>
Vector3<T>::operator const T* () const T Vector3<T>::operator[](std::size_t i) const
{ {
return &x; NazaraAssert(i < 3, "index out of range");
return *(&x + i);
} }
/*! /*!

View File

@ -54,15 +54,15 @@ namespace Nz
Vector4& Set(T X, const Vector2<T>& vec, T W); Vector4& Set(T X, const Vector2<T>& vec, T W);
Vector4& Set(T X, const Vector3<T>& vec); Vector4& Set(T X, const Vector3<T>& vec);
Vector4& Set(T scale); Vector4& Set(T scale);
Vector4& Set(const T vec[4]); Vector4& Set(const T* vec);
Vector4& Set(const Vector2<T>& vec, T Z = 0.0, T W = 1.0); Vector4& Set(const Vector2<T>& vec, T Z = 0.0, T W = 1.0);
Vector4& Set(const Vector3<T>& vec, T W = 1.0); Vector4& Set(const Vector3<T>& vec, T W = 1.0);
template<typename U> Vector4& Set(const Vector4<U>& vec); template<typename U> Vector4& Set(const Vector4<U>& vec);
String ToString() const; String ToString() const;
operator T* (); T& operator[](std::size_t i);
operator const T* () const; T operator[](std::size_t i) const;
const Vector4& operator+() const; const Vector4& operator+() const;
Vector4 operator-() const; Vector4 operator-() const;

View File

@ -413,9 +413,8 @@ namespace Nz
* *
* \param vec[4] vec[0] is X component, vec[1] is Y component, vec[2] is Z component and vec[3] is W component * \param vec[4] vec[0] is X component, vec[1] is Y component, vec[2] is Z component and vec[3] is W component
*/ */
template<typename T> template<typename T>
Vector4<T>& Vector4<T>::Set(const T vec[4]) Vector4<T>& Vector4<T>::Set(const T* vec)
{ {
x = vec[0]; x = vec[0];
y = vec[1]; y = vec[1];
@ -495,29 +494,25 @@ namespace Nz
} }
/*! /*!
* \brief Converts vector to pointer to its own data * \brief Access a vector component by index
* \return A pointer to the own data * \return X, Y, Z depending on index (0, 1, 2)
*
* \remark Access to index greather than 3 is undefined behavior
*/ */
template<typename T> template<typename T>
Vector4<T>::operator T* () T& Vector4<T>::operator[](std::size_t i)
{ {
return &x; NazaraAssert(i < 4, "index out of range");
return *(&x + i);
} }
/*! /*!
* \brief Converts vector to const pointer to its own data * \brief Access a vector component by index
* \return A constant pointer to the own data * \return X, Y, Z depending on index (0, 1, 2)
*
* \remark Access to index greather than 3 is undefined behavior
*/ */
template<typename T> template<typename T>
Vector4<T>::operator const T* () const T Vector4<T>::operator[](std::size_t i) const
{ {
return &x; NazaraAssert(i < 4, "index out of range");
return *(&x + i);
} }
/*! /*!

View File

@ -0,0 +1,56 @@
// This file was automatically generated
/*
Nazara Engine - OpenGL
Copyright (C) 2015 Jérôme "Lynix" Leclercq (Lynix680@gmail.com)
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#pragma once
#ifndef NAZARA_GLOBAL_OPENGLRENDERER_HPP
#define NAZARA_GLOBAL_OPENGLRENDERER_HPP
#include <Nazara/OpenGLRenderer/Config.hpp>
#include <Nazara/OpenGLRenderer/DummySurface.hpp>
#include <Nazara/OpenGLRenderer/OpenGLBuffer.hpp>
#include <Nazara/OpenGLRenderer/OpenGLCommandBuffer.hpp>
#include <Nazara/OpenGLRenderer/OpenGLCommandBufferBuilder.hpp>
#include <Nazara/OpenGLRenderer/OpenGLCommandPool.hpp>
#include <Nazara/OpenGLRenderer/OpenGLDevice.hpp>
#include <Nazara/OpenGLRenderer/OpenGLFramebuffer.hpp>
#include <Nazara/OpenGLRenderer/OpenGLRenderer.hpp>
#include <Nazara/OpenGLRenderer/OpenGLRenderImage.hpp>
#include <Nazara/OpenGLRenderer/OpenGLRenderPass.hpp>
#include <Nazara/OpenGLRenderer/OpenGLRenderPipeline.hpp>
#include <Nazara/OpenGLRenderer/OpenGLRenderPipelineLayout.hpp>
#include <Nazara/OpenGLRenderer/OpenGLRenderWindow.hpp>
#include <Nazara/OpenGLRenderer/OpenGLShaderBinding.hpp>
#include <Nazara/OpenGLRenderer/OpenGLShaderStage.hpp>
#include <Nazara/OpenGLRenderer/OpenGLTexture.hpp>
#include <Nazara/OpenGLRenderer/OpenGLTextureSampler.hpp>
#include <Nazara/OpenGLRenderer/OpenGLUploadPool.hpp>
#include <Nazara/OpenGLRenderer/OpenGLVaoCache.hpp>
#include <Nazara/OpenGLRenderer/OpenGLWindowFramebuffer.hpp>
#include <Nazara/OpenGLRenderer/Utils.hpp>
#include <Nazara/OpenGLRenderer/Wrapper.hpp>
#endif // NAZARA_GLOBAL_OPENGLRENDERER_HPP

View File

@ -50,4 +50,4 @@
#define NAZARA_OPENGLRENDERER_API #define NAZARA_OPENGLRENDERER_API
#endif #endif
#endif // NAZARA_CONFIG_MODULENAME_HPP #endif // NAZARA_CONFIG_OPENGLRENDERER_HPP

View File

@ -4,8 +4,8 @@
#pragma once #pragma once
#ifndef NAZARA_CONFIG_CHECK_OPENGLE_HPP #ifndef NAZARA_CONFIG_CHECK_OPENGLRENDERER_HPP
#define NAZARA_CONFIG_CHECK_OPENGLE_HPP #define NAZARA_CONFIG_CHECK_OPENGLRENDERER_HPP
/// Ce fichier sert à vérifier la valeur des constantes du fichier Config.hpp /// Ce fichier sert à vérifier la valeur des constantes du fichier Config.hpp
@ -15,8 +15,8 @@
// On force la valeur de MANAGE_MEMORY en mode debug // On force la valeur de MANAGE_MEMORY en mode debug
#if defined(NAZARA_DEBUG) && !NAZARA_OPENGLRENDERER_MANAGE_MEMORY #if defined(NAZARA_DEBUG) && !NAZARA_OPENGLRENDERER_MANAGE_MEMORY
#undef NAZARA_MODULENAME_MANAGE_MEMORY #undef NAZARA_OPENGLRENDERER_MANAGE_MEMORY
#define NAZARA_MODULENAME_MANAGE_MEMORY 0 #define NAZARA_OPENGLRENDERER_MANAGE_MEMORY 0
#endif #endif
#endif // NAZARA_CONFIG_CHECK_OPENGLRENDERER_HPP #endif // NAZARA_CONFIG_CHECK_OPENGLRENDERER_HPP

View File

@ -3,6 +3,6 @@
// For conditions of distribution and use, see copyright notice in Config.hpp // For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/OpenGLRenderer/Config.hpp> #include <Nazara/OpenGLRenderer/Config.hpp>
#if NAZARA_MODULENAME_MANAGE_MEMORY #if NAZARA_OPENGLRENDERER_MANAGE_MEMORY
#include <Nazara/Core/Debug/NewRedefinition.hpp> #include <Nazara/Core/Debug/NewRedefinition.hpp>
#endif #endif

View File

@ -3,7 +3,7 @@
// For conditions of distribution and use, see copyright notice in Config.hpp // For conditions of distribution and use, see copyright notice in Config.hpp
// On suppose que Debug.hpp a déjà été inclus, tout comme Config.hpp // On suppose que Debug.hpp a déjà été inclus, tout comme Config.hpp
#if NAZARA_MODULENAME_MANAGE_MEMORY #if NAZARA_OPENGLRENDERER_MANAGE_MEMORY
#undef delete #undef delete
#undef new #undef new
#endif #endif

View File

@ -1,4 +1,4 @@
// Copyright (C) 2015 Jérôme Leclercq // Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - OpenGL Renderer" // This file is part of the "Nazara Engine - OpenGL Renderer"
// For conditions of distribution and use, see copyright notice in Config.hpp // For conditions of distribution and use, see copyright notice in Config.hpp

View File

@ -1,4 +1,4 @@
// Copyright (C) 2015 Jérôme Leclercq // Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - OpenGL Renderer" // This file is part of the "Nazara Engine - OpenGL Renderer"
// For conditions of distribution and use, see copyright notice in Config.hpp // For conditions of distribution and use, see copyright notice in Config.hpp

View File

@ -1,4 +1,4 @@
// Copyright (C) 2015 Jérôme Leclercq // Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - OpenGL Renderer" // This file is part of the "Nazara Engine - OpenGL Renderer"
// For conditions of distribution and use, see copyright notice in Config.hpp // For conditions of distribution and use, see copyright notice in Config.hpp

View File

@ -1,4 +1,4 @@
// Copyright (C) 2015 Jérôme Leclercq // Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - OpenGL Renderer" // This file is part of the "Nazara Engine - OpenGL Renderer"
// For conditions of distribution and use, see copyright notice in Config.hpp // For conditions of distribution and use, see copyright notice in Config.hpp

View File

@ -1,4 +1,4 @@
// Copyright (C) 2015 Jérôme Leclercq // Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - OpenGL Renderer" // This file is part of the "Nazara Engine - OpenGL Renderer"
// For conditions of distribution and use, see copyright notice in Config.hpp // For conditions of distribution and use, see copyright notice in Config.hpp

View File

@ -1,4 +1,4 @@
// Copyright (C) 2015 Jérôme Leclercq // Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - OpenGL Renderer" // This file is part of the "Nazara Engine - OpenGL Renderer"
// For conditions of distribution and use, see copyright notice in Config.hpp // For conditions of distribution and use, see copyright notice in Config.hpp

View File

@ -12,10 +12,24 @@
#include <Nazara/Renderer/Enums.hpp> #include <Nazara/Renderer/Enums.hpp>
#include <Nazara/Utility/Enums.hpp> #include <Nazara/Utility/Enums.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/Loader.hpp> #include <Nazara/OpenGLRenderer/Wrapper/Loader.hpp>
#include <optional>
#include <string> #include <string>
namespace Nz namespace Nz
{ {
struct GLTextureFormat
{
GLint internalFormat;
GLenum format;
GLenum type;
GLenum swizzleR;
GLenum swizzleG;
GLenum swizzleB;
GLenum swizzleA;
};
inline std::optional<GLTextureFormat> DescribeTextureFormat(PixelFormat pixelFormat);
inline GLenum ToOpenGL(BlendFunc blendFunc); inline GLenum ToOpenGL(BlendFunc blendFunc);
inline GLenum ToOpenGL(FaceSide filter); inline GLenum ToOpenGL(FaceSide filter);
inline GLenum ToOpenGL(SamplerFilter filter); inline GLenum ToOpenGL(SamplerFilter filter);

View File

@ -10,6 +10,19 @@
namespace Nz namespace Nz
{ {
inline std::optional<GLTextureFormat> DescribeTextureFormat(PixelFormat pixelFormat)
{
switch (pixelFormat)
{
case PixelFormat_A8: return GLTextureFormat { GL_R8, GL_RED, GL_UNSIGNED_BYTE, GL_ZERO, GL_ZERO, GL_ZERO, GL_RED };
case PixelFormat_RGB8: return GLTextureFormat { GL_SRGB8, GL_RGB, GL_UNSIGNED_BYTE, GL_RED, GL_GREEN, GL_BLUE, GL_ZERO };
case PixelFormat_RGBA8: return GLTextureFormat { GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_BYTE, GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA };
}
NazaraError("Unhandled PixelFormat 0x" + String::Number(UnderlyingCast(pixelFormat), 16));
return {};
}
inline GLenum ToOpenGL(BlendFunc blendFunc) inline GLenum ToOpenGL(BlendFunc blendFunc)
{ {
switch (blendFunc) switch (blendFunc)

View File

@ -68,12 +68,12 @@ namespace Nz::GL
context.glSpecializeShaderARB(m_objectId, pEntryPoint, numSpecializationConstants, pConstantIndex, pConstantValue); context.glSpecializeShaderARB(m_objectId, pEntryPoint, numSpecializationConstants, pConstantIndex, pConstantValue);
} }
inline GLuint Shader::CreateHelper(OpenGLDevice& device, const Context& context, GLenum shaderStage) inline GLuint Shader::CreateHelper(OpenGLDevice& /*device*/, const Context& context, GLenum shaderStage)
{ {
return context.glCreateShader(shaderStage); return context.glCreateShader(shaderStage);
} }
inline void Shader::DestroyHelper(OpenGLDevice& device, const Context& context, GLuint objectId) inline void Shader::DestroyHelper(OpenGLDevice& /*device*/, const Context& context, GLuint objectId)
{ {
context.glDeleteShader(objectId); context.glDeleteShader(objectId);
} }

View File

@ -29,7 +29,7 @@ namespace Nz::GL
inline void SetParameterfv(GLenum pname, const GLfloat* param); inline void SetParameterfv(GLenum pname, const GLfloat* param);
inline void SetParameteriv(GLenum pname, const GLint* param); inline void SetParameteriv(GLenum pname, const GLint* param);
inline void TexImage2D(GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLint border); inline void TexImage2D(GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type);
inline void TexImage2D(GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void* data); inline void TexImage2D(GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void* data);
inline void TexSubImage2D(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* data); inline void TexSubImage2D(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* data);
@ -39,6 +39,8 @@ namespace Nz::GL
private: private:
static inline GLuint CreateHelper(OpenGLDevice& device, const Context& context); static inline GLuint CreateHelper(OpenGLDevice& device, const Context& context);
static inline void DestroyHelper(OpenGLDevice& device, const Context& context, GLuint objectId); static inline void DestroyHelper(OpenGLDevice& device, const Context& context, GLuint objectId);
TextureTarget m_target;
}; };
} }

View File

@ -13,7 +13,8 @@ namespace Nz::GL
assert(m_objectId); assert(m_objectId);
const Context& context = EnsureDeviceContext(); const Context& context = EnsureDeviceContext();
context.glTexParameterf(m_objectId, pname, param); context.BindTexture(m_target, m_objectId);
context.glTexParameterf(ToOpenGL(m_target), pname, param);
} }
inline void Texture::SetParameteri(GLenum pname, GLint param) inline void Texture::SetParameteri(GLenum pname, GLint param)
@ -21,7 +22,8 @@ namespace Nz::GL
assert(m_objectId); assert(m_objectId);
const Context& context = EnsureDeviceContext(); const Context& context = EnsureDeviceContext();
context.glTexParameteri(m_objectId, pname, param); context.BindTexture(m_target, m_objectId);
context.glTexParameteri(ToOpenGL(m_target), pname, param);
} }
inline void Texture::SetParameterfv(GLenum pname, const GLfloat* param) inline void Texture::SetParameterfv(GLenum pname, const GLfloat* param)
@ -29,7 +31,8 @@ namespace Nz::GL
assert(m_objectId); assert(m_objectId);
const Context& context = EnsureDeviceContext(); const Context& context = EnsureDeviceContext();
context.glTexParameterfv(m_objectId, pname, param); context.BindTexture(m_target, m_objectId);
context.glTexParameterfv(ToOpenGL(m_target), pname, param);
} }
inline void Texture::SetParameteriv(GLenum pname, const GLint* param) inline void Texture::SetParameteriv(GLenum pname, const GLint* param)
@ -37,38 +40,39 @@ namespace Nz::GL
assert(m_objectId); assert(m_objectId);
const Context& context = EnsureDeviceContext(); const Context& context = EnsureDeviceContext();
context.glTexParameteriv(m_objectId, pname, param); context.BindTexture(m_target, m_objectId);
context.glTexParameteriv(ToOpenGL(m_target), pname, param);
} }
inline void Texture::TexImage2D(GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLint border) inline void Texture::TexImage2D(GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type)
{ {
return TexImage2D(level, internalFormat, width, height, border, GL_RGB, GL_UNSIGNED_BYTE, nullptr); return TexImage2D(level, internalFormat, width, height, border, format, type, nullptr);
} }
inline void Texture::TexImage2D(GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void* data) inline void Texture::TexImage2D(GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void* data)
{ {
const Context& context = EnsureDeviceContext(); m_target = TextureTarget::Target2D;
context.BindTexture(TextureTarget::Target2D, m_objectId);
context.glTexImage2D(GL_TEXTURE_2D, level, internalFormat, width, height, border, format, type, data); const Context& context = EnsureDeviceContext();
context.BindTexture(m_target, m_objectId);
context.glTexImage2D(ToOpenGL(m_target), level, internalFormat, width, height, border, format, type, data);
//< TODO: Handle errors //< TODO: Handle errors
} }
inline void Texture::TexSubImage2D(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* data) inline void Texture::TexSubImage2D(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* data)
{ {
const Context& context = EnsureDeviceContext(); const Context& context = EnsureDeviceContext();
context.BindTexture(TextureTarget::Target2D, m_objectId); context.BindTexture(m_target, m_objectId);
context.glTexSubImage2D(ToOpenGL(m_target), level, xoffset, yoffset, width, height, format, type, data);
context.glTexSubImage2D(GL_TEXTURE_2D, level, xoffset, yoffset, width, height, format, type, data);
//< TODO: Handle errors //< TODO: Handle errors
} }
inline GLuint Texture::CreateHelper(OpenGLDevice& device, const Context& context) inline GLuint Texture::CreateHelper(OpenGLDevice& device, const Context& context)
{ {
GLuint sampler = 0; GLuint texture = 0;
context.glGenTextures(1U, &sampler); context.glGenTextures(1U, &texture);
return sampler; return texture;
} }
inline void Texture::DestroyHelper(OpenGLDevice& device, const Context& context, GLuint objectId) inline void Texture::DestroyHelper(OpenGLDevice& device, const Context& context, GLuint objectId)

View File

@ -38,6 +38,10 @@
extBegin(WGL_EXT_extensions_string) \ extBegin(WGL_EXT_extensions_string) \
extFunc(wglGetExtensionsStringEXT, PFNWGLGETEXTENSIONSSTRINGEXTPROC) \ extFunc(wglGetExtensionsStringEXT, PFNWGLGETEXTENSIONSSTRINGEXTPROC) \
extEnd() \ extEnd() \
\
extBegin(WGL_EXT_swap_control) \
extFunc(wglSwapIntervalEXT, PFNWGLSWAPINTERVALEXTPROC) \
extEnd()
#define NAZARA_OPENGLRENDERER_FOREACH_GDI32_FUNC(func) \ #define NAZARA_OPENGLRENDERER_FOREACH_GDI32_FUNC(func) \
func(ChoosePixelFormat, PFNCHOOSEPIXELFORMATPROC) \ func(ChoosePixelFormat, PFNCHOOSEPIXELFORMATPROC) \

View File

@ -36,7 +36,6 @@
#include <Nazara/Renderer/DebugDrawer.hpp> #include <Nazara/Renderer/DebugDrawer.hpp>
#include <Nazara/Renderer/Enums.hpp> #include <Nazara/Renderer/Enums.hpp>
#include <Nazara/Renderer/Framebuffer.hpp> #include <Nazara/Renderer/Framebuffer.hpp>
#include <Nazara/Renderer/GlslWriter.hpp>
#include <Nazara/Renderer/RenderBuffer.hpp> #include <Nazara/Renderer/RenderBuffer.hpp>
#include <Nazara/Renderer/RenderBufferView.hpp> #include <Nazara/Renderer/RenderBufferView.hpp>
#include <Nazara/Renderer/RenderDevice.hpp> #include <Nazara/Renderer/RenderDevice.hpp>
@ -52,11 +51,8 @@
#include <Nazara/Renderer/RenderWindow.hpp> #include <Nazara/Renderer/RenderWindow.hpp>
#include <Nazara/Renderer/RenderWindowImpl.hpp> #include <Nazara/Renderer/RenderWindowImpl.hpp>
#include <Nazara/Renderer/RenderWindowParameters.hpp> #include <Nazara/Renderer/RenderWindowParameters.hpp>
#include <Nazara/Renderer/ShaderAst.hpp>
#include <Nazara/Renderer/ShaderBinding.hpp> #include <Nazara/Renderer/ShaderBinding.hpp>
#include <Nazara/Renderer/ShaderBuilder.hpp>
#include <Nazara/Renderer/ShaderStageImpl.hpp> #include <Nazara/Renderer/ShaderStageImpl.hpp>
#include <Nazara/Renderer/ShaderWriter.hpp>
#include <Nazara/Renderer/Texture.hpp> #include <Nazara/Renderer/Texture.hpp>
#include <Nazara/Renderer/TextureSampler.hpp> #include <Nazara/Renderer/TextureSampler.hpp>
#include <Nazara/Renderer/UploadPool.hpp> #include <Nazara/Renderer/UploadPool.hpp>

View File

@ -49,27 +49,10 @@ namespace Nz
GLSL, GLSL,
HLSL, HLSL,
MSL, MSL,
NazaraBinary,
SpirV SpirV
}; };
enum class ShaderStageType
{
Fragment,
Vertex,
Max = Vertex
};
template<>
struct EnumAsFlags<ShaderStageType>
{
static constexpr ShaderStageType max = ShaderStageType::Max;
};
using ShaderStageTypeFlags = Flags<ShaderStageType>;
constexpr ShaderStageTypeFlags ShaderStageType_All = ShaderStageType::Fragment | ShaderStageType::Vertex;
enum class QueueType enum class QueueType
{ {
Compute, Compute,

View File

@ -1,88 +0,0 @@
// Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - Renderer module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_GLSLWRITER_HPP
#define NAZARA_GLSLWRITER_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Core/StringStream.hpp>
#include <Nazara/Renderer/Config.hpp>
#include <Nazara/Renderer/ShaderWriter.hpp>
#include <set>
#include <unordered_map>
namespace Nz
{
class NAZARA_RENDERER_API GlslWriter : public ShaderWriter
{
public:
GlslWriter();
GlslWriter(const GlslWriter&) = delete;
GlslWriter(GlslWriter&&) = delete;
~GlslWriter() = default;
Nz::String Generate(const ShaderAst::StatementPtr& node) override;
void RegisterFunction(const String& name, ShaderAst::StatementPtr statement, std::initializer_list<ShaderAst::NamedVariablePtr> parameters, ShaderAst::ExpressionType ret) override;
void RegisterVariable(ShaderAst::VariableType kind, const String& name, ShaderAst::ExpressionType type) override;
void SetGlslVersion(unsigned int version);
void Write(const ShaderAst::AssignOp& node) override;
void Write(const ShaderAst::Branch& node) override;
void Write(const ShaderAst::BinaryOp& node) override;
void Write(const ShaderAst::BuiltinVariable& node) override;
void Write(const ShaderAst::Cast& node) override;
void Write(const ShaderAst::Constant& node) override;
void Write(const ShaderAst::ExpressionStatement& node) override;
void Write(const ShaderAst::NamedVariable& node) override;
void Write(const ShaderAst::NodePtr& node) override;
void Write(const ShaderAst::StatementBlock& node) override;
void Write(const ShaderAst::SwizzleOp& node) override;
private:
struct Function;
using VariableContainer = std::set<std::pair<ShaderAst::ExpressionType, String>>;
void Append(ShaderAst::BuiltinEntry builtin);
void Append(ShaderAst::ExpressionType type);
void Append(const String& txt);
void AppendCommentSection(const String& section);
void AppendFunction(Function& func);
void AppendLine(const String& txt = String());
void DeclareVariables(const VariableContainer& variables, const String& keyword = String(), const String& section = String());
void EnterScope();
void LeaveScope();
struct Function
{
VariableContainer variables;
std::vector<ShaderAst::NamedVariablePtr> parameters;
ShaderAst::ExpressionType retType;
ShaderAst::StatementPtr node;
String name;
};
struct State
{
VariableContainer inputs;
VariableContainer outputs;
VariableContainer uniforms;
StringStream stream;
unsigned int indentLevel = 0;
};
std::unordered_map<String, Function> m_functions;
Function* m_currentFunction;
State* m_currentState;
unsigned int m_glslVersion;
};
}
#endif // NAZARA_GLSLWRITER_HPP

View File

@ -10,6 +10,7 @@
#include <Nazara/Core/MovablePtr.hpp> #include <Nazara/Core/MovablePtr.hpp>
#include <Nazara/Renderer/Enums.hpp> #include <Nazara/Renderer/Enums.hpp>
#include <Nazara/Renderer/ShaderBinding.hpp> #include <Nazara/Renderer/ShaderBinding.hpp>
#include <Nazara/Utility/Enums.hpp>
#include <memory> #include <memory>
#include <string> #include <string>
#include <vector> #include <vector>

View File

@ -1,292 +0,0 @@
// Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - Renderer module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_SHADER_AST_HPP
#define NAZARA_SHADER_AST_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Core/String.hpp>
#include <Nazara/Math/Vector2.hpp>
#include <Nazara/Math/Vector3.hpp>
#include <Nazara/Math/Vector4.hpp>
#include <Nazara/Renderer/Config.hpp>
#include <array>
namespace Nz
{
class ShaderWriter;
namespace ShaderAst
{
enum class AssignType
{
Simple //< =
};
enum class BinaryType
{
Add, //< +
Substract, //< -
Multiply, //< *
Divide, //< /
Equality //< ==
};
enum class BuiltinEntry
{
VertexPosition, // gl_Position
};
enum class ExpressionType
{
Boolean, // bool
Float1, // float
Float2, // vec2
Float3, // vec3
Float4, // vec4
Mat4x4, // mat4
Void // void
};
enum class SwizzleComponent
{
First,
Second,
Third,
Fourth
};
enum class VariableType
{
Builtin,
Input,
Output,
Parameter,
Uniform,
Variable
};
//////////////////////////////////////////////////////////////////////////
class Node;
using NodePtr = std::shared_ptr<Node>;
class NAZARA_RENDERER_API Node
{
public:
virtual ~Node() = default;
virtual void Register(ShaderWriter& visitor) = 0;
virtual void Visit(ShaderWriter& visitor) = 0;
static inline unsigned int GetComponentCount(ExpressionType type);
static inline ExpressionType GetComponentType(ExpressionType type);
};
class Statement;
using StatementPtr = std::shared_ptr<Statement>;
class NAZARA_RENDERER_API Statement : public Node
{
};
class Expression;
using ExpressionPtr = std::shared_ptr<Expression>;
class NAZARA_RENDERER_API Expression : public Node
{
public:
virtual ExpressionType GetExpressionType() const = 0;
};
class NAZARA_RENDERER_API ExpressionStatement : public Statement
{
public:
inline explicit ExpressionStatement(ExpressionPtr expr);
void Register(ShaderWriter& visitor) override;
void Visit(ShaderWriter& visitor) override;
ExpressionPtr expression;
};
//////////////////////////////////////////////////////////////////////////
class NAZARA_RENDERER_API ConditionalStatement : public Statement
{
public:
inline ConditionalStatement(const String& condition, StatementPtr statementPtr);
void Register(ShaderWriter& visitor) override;
void Visit(ShaderWriter& visitor) override;
String conditionName;
StatementPtr statement;
};
class NAZARA_RENDERER_API StatementBlock : public Statement
{
public:
template<typename... Args> explicit StatementBlock(Args&&... args);
void Register(ShaderWriter& visitor) override;
void Visit(ShaderWriter& visitor) override;
std::vector<StatementPtr> statements;
};
class Variable;
using VariablePtr = std::shared_ptr<Variable>;
class NAZARA_RENDERER_API Variable : public Expression
{
public:
inline Variable(VariableType varKind, ExpressionType varType);
ExpressionType GetExpressionType() const override;
ExpressionType type;
VariableType kind;
};
class NAZARA_RENDERER_API BuiltinVariable : public Variable
{
public:
inline BuiltinVariable(BuiltinEntry variable, ExpressionType varType);
void Register(ShaderWriter& visitor) override;
void Visit(ShaderWriter& visitor) override;
BuiltinEntry var;
};
class NamedVariable;
using NamedVariablePtr = std::shared_ptr<NamedVariable>;
class NAZARA_RENDERER_API NamedVariable : public Variable
{
public:
inline NamedVariable(VariableType varKind, const Nz::String& varName, ExpressionType varType);
void Register(ShaderWriter& visitor) override;
void Visit(ShaderWriter& visitor) override;
Nz::String name;
};
//////////////////////////////////////////////////////////////////////////
class NAZARA_RENDERER_API AssignOp : public Expression
{
public:
inline AssignOp(AssignType Op, VariablePtr Var, ExpressionPtr Right);
ExpressionType GetExpressionType() const override;
void Register(ShaderWriter& visitor) override;
void Visit(ShaderWriter& visitor) override;
AssignType op;
VariablePtr variable;
ExpressionPtr right;
};
class NAZARA_RENDERER_API BinaryOp : public Expression
{
public:
inline BinaryOp(BinaryType Op, ExpressionPtr Left, ExpressionPtr Right);
ExpressionType GetExpressionType() const override;
void Register(ShaderWriter& visitor) override;
void Visit(ShaderWriter& visitor) override;
BinaryType op;
ExpressionPtr left;
ExpressionPtr right;
};
class NAZARA_RENDERER_API Branch : public Statement
{
public:
inline Branch(ExpressionPtr condition, StatementPtr trueStatement, StatementPtr falseStatement = nullptr);
void Register(ShaderWriter& visitor) override;
void Visit(ShaderWriter& visitor) override;
struct ConditionalStatement
{
ExpressionPtr condition;
StatementPtr statement;
};
std::vector<ConditionalStatement> condStatements;
StatementPtr elseStatement;
};
class NAZARA_RENDERER_API Cast : public Expression
{
public:
inline Cast(ExpressionType castTo, ExpressionPtr first, ExpressionPtr second = nullptr, ExpressionPtr third = nullptr, ExpressionPtr fourth = nullptr);
ExpressionType GetExpressionType() const override;
void Register(ShaderWriter& visitor) override;
void Visit(ShaderWriter& visitor) override;
ExpressionType exprType;
std::array<ExpressionPtr, 4> expressions;
};
class NAZARA_RENDERER_API Constant : public Expression
{
public:
inline explicit Constant(bool value);
inline explicit Constant(float value);
inline explicit Constant(const Vector2f& value);
inline explicit Constant(const Vector3f& value);
inline explicit Constant(const Vector4f& value);
ExpressionType GetExpressionType() const override;
void Register(ShaderWriter& visitor) override;
void Visit(ShaderWriter& visitor) override;
ExpressionType exprType;
union
{
bool bool1;
float vec1;
Vector2f vec2;
Vector3f vec3;
Vector4f vec4;
} values;
};
class NAZARA_RENDERER_API SwizzleOp : public Expression
{
public:
inline SwizzleOp(ExpressionPtr expressionPtr, std::initializer_list<SwizzleComponent> swizzleComponents);
ExpressionType GetExpressionType() const override;
void Register(ShaderWriter& visitor) override;
void Visit(ShaderWriter& visitor) override;
std::array<SwizzleComponent, 4> components;
std::size_t componentCount;
ExpressionPtr expression;
};
}
}
#include <Nazara/Renderer/ShaderAst.inl>
#endif // NAZARA_SHADER_AST_HPP

View File

@ -1,231 +0,0 @@
// Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - Renderer module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Renderer/Debug.hpp>
namespace Nz
{
namespace ShaderAst
{
inline unsigned int Node::GetComponentCount(ExpressionType type)
{
switch (type)
{
case ExpressionType::Float2:
return 2;
case ExpressionType::Float3:
return 3;
case ExpressionType::Float4:
return 4;
case ExpressionType::Mat4x4:
return 4;
default:
return 1;
}
}
inline ExpressionType Node::GetComponentType(ExpressionType type)
{
switch (type)
{
case ExpressionType::Float2:
case ExpressionType::Float3:
case ExpressionType::Float4:
return ExpressionType::Float1;
case ExpressionType::Mat4x4:
return ExpressionType::Float4;
default:
return type;
}
}
inline ExpressionStatement::ExpressionStatement(ExpressionPtr expr) :
expression(std::move(expr))
{
}
inline ConditionalStatement::ConditionalStatement(const String& condition, StatementPtr statementPtr) :
conditionName(condition),
statement(std::move(statementPtr))
{
}
template<typename... Args>
StatementBlock::StatementBlock(Args&& ...args) :
statements({std::forward<Args>(args)...})
{
}
inline Variable::Variable(VariableType varKind, ExpressionType varType) :
type(varType),
kind(varKind)
{
}
inline BuiltinVariable::BuiltinVariable(BuiltinEntry variable, ExpressionType varType) :
Variable(VariableType::Builtin, varType),
var(variable)
{
}
inline NamedVariable::NamedVariable(VariableType varKind, const Nz::String& varName, ExpressionType varType) :
Variable(varKind, varType),
name(varName)
{
}
inline AssignOp::AssignOp(AssignType Op, VariablePtr Var, ExpressionPtr Right) :
op(Op),
variable(std::move(Var)),
right(std::move(Right))
{
}
inline BinaryOp::BinaryOp(BinaryType Op, ExpressionPtr Left, ExpressionPtr Right) :
op(Op),
left(std::move(Left)),
right(std::move(Right))
{
ExpressionType leftType = left->GetExpressionType();
ExpressionType rightType = right->GetExpressionType();
if (leftType != rightType)
{
switch (op)
{
case BinaryType::Add:
case BinaryType::Equality:
case BinaryType::Substract:
{
//TODO: AstParseError
throw std::runtime_error("Left expression type must match right expression type");
}
case BinaryType::Multiply:
case BinaryType::Divide:
{
switch (leftType)
{
case ExpressionType::Float2:
case ExpressionType::Float3:
case ExpressionType::Float4:
{
if (rightType != ExpressionType::Float1)
throw std::runtime_error("Left expression type is not compatible with right expression type");
break;
}
case ExpressionType::Mat4x4:
{
switch (rightType)
{
case ExpressionType::Float1:
case ExpressionType::Float4:
case ExpressionType::Mat4x4:
break;
//TODO: AstParseError
default:
throw std::runtime_error("Left expression type is not compatible with right expression type");
}
break;
}
default:
//TODO: AstParseError
throw std::runtime_error("Left expression type must match right expression type");
}
}
}
}
}
inline Branch::Branch(ExpressionPtr condition, StatementPtr trueStatement, StatementPtr falseStatement)
{
condStatements.emplace_back(ConditionalStatement{ std::move(condition), std::move(trueStatement) });
elseStatement = std::move(falseStatement);
}
inline Cast::Cast(ExpressionType castTo, ExpressionPtr first, ExpressionPtr second, ExpressionPtr third, ExpressionPtr fourth) :
exprType(castTo),
expressions({ {first, second, third, fourth} })
{
unsigned int componentCount = 0;
unsigned int requiredComponents = GetComponentCount(exprType);
for (const auto& exprPtr : expressions)
{
if (!exprPtr)
break;
componentCount += GetComponentCount(exprPtr->GetExpressionType());
}
//TODO: AstParseError
if (componentCount != requiredComponents)
throw std::runtime_error("Component count doesn't match required component count");
}
inline Constant::Constant(bool value) :
exprType(ExpressionType::Boolean)
{
values.bool1 = value;
}
inline Constant::Constant(float value) :
exprType(ExpressionType::Float1)
{
values.vec1 = value;
}
inline Constant::Constant(const Vector2f& value) :
exprType(ExpressionType::Float2)
{
values.vec2 = value;
}
inline Constant::Constant(const Vector3f& value) :
exprType(ExpressionType::Float3)
{
values.vec3 = value;
}
inline Constant::Constant(const Vector4f& value) :
exprType(ExpressionType::Float4)
{
values.vec4 = value;
}
inline SwizzleOp::SwizzleOp(ExpressionPtr expressionPtr, std::initializer_list<SwizzleComponent> swizzleComponents) :
componentCount(swizzleComponents.size()),
expression(expressionPtr)
{
if (componentCount > 4)
throw std::runtime_error("Cannot swizzle more than four elements");
switch (expressionPtr->GetExpressionType())
{
case ExpressionType::Float1:
case ExpressionType::Float2:
case ExpressionType::Float3:
case ExpressionType::Float4:
break;
default:
throw std::runtime_error("Cannot swizzle this type");
}
std::copy(swizzleComponents.begin(), swizzleComponents.end(), components.begin());
}
}
}
#include <Nazara/Renderer/DebugOff.hpp>

View File

@ -1,79 +0,0 @@
// Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - Renderer module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_SHADER_BUILDER_HPP
#define NAZARA_SHADER_BUILDER_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Renderer/ShaderAst.hpp>
#include <memory>
namespace Nz { namespace ShaderBuilder
{
template<ShaderAst::AssignType op>
struct AssignOpBuilder
{
constexpr AssignOpBuilder() {}
std::shared_ptr<ShaderAst::AssignOp> operator()(const ShaderAst::VariablePtr& left, const ShaderAst::ExpressionPtr& right) const;
};
template<ShaderAst::BinaryType op>
struct BinOpBuilder
{
constexpr BinOpBuilder() {}
std::shared_ptr<ShaderAst::BinaryOp> operator()(const ShaderAst::ExpressionPtr& left, const ShaderAst::ExpressionPtr& right) const;
};
struct BuiltinBuilder
{
constexpr BuiltinBuilder() {}
inline std::shared_ptr<ShaderAst::Variable> operator()(ShaderAst::BuiltinEntry builtin) const;
};
template<typename T>
struct GenBuilder
{
constexpr GenBuilder() {}
template<typename... Args> std::shared_ptr<T> operator()(Args&&... args) const;
};
template<ShaderAst::VariableType type>
struct VarBuilder
{
constexpr VarBuilder() {}
template<typename... Args> std::shared_ptr<ShaderAst::Variable> operator()(Args&&... args) const;
};
constexpr BinOpBuilder<ShaderAst::BinaryType::Add> Add;
constexpr AssignOpBuilder<ShaderAst::AssignType::Simple> Assign;
constexpr BuiltinBuilder Builtin;
constexpr GenBuilder<ShaderAst::StatementBlock> Block;
constexpr GenBuilder<ShaderAst::Branch> Branch;
constexpr GenBuilder<ShaderAst::ConditionalStatement> ConditionalStatement;
constexpr GenBuilder<ShaderAst::Constant> Constant;
constexpr BinOpBuilder<ShaderAst::BinaryType::Divide> Divide;
constexpr BinOpBuilder<ShaderAst::BinaryType::Equality> Equal;
constexpr GenBuilder<ShaderAst::ExpressionStatement> ExprStatement;
constexpr VarBuilder<ShaderAst::VariableType::Input> Input;
constexpr BinOpBuilder<ShaderAst::BinaryType::Multiply> Multiply;
constexpr VarBuilder<ShaderAst::VariableType::Output> Output;
constexpr VarBuilder<ShaderAst::VariableType::Parameter> Parameter;
constexpr GenBuilder<ShaderAst::SwizzleOp> Swizzle;
constexpr BinOpBuilder<ShaderAst::BinaryType::Substract> Substract;
constexpr VarBuilder<ShaderAst::VariableType::Uniform> Uniform;
constexpr VarBuilder<ShaderAst::VariableType::Variable> Variable;
template<ShaderAst::ExpressionType Type, typename... Args> std::shared_ptr<ShaderAst::Cast> Cast(Args&&... args);
} }
#include <Nazara/Renderer/ShaderBuilder.inl>
#endif // NAZARA_SHADER_BUILDER_HPP

View File

@ -1,59 +0,0 @@
// Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - Renderer module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Renderer/ShaderBuilder.hpp>
#include <Nazara/Renderer/Debug.hpp>
namespace Nz { namespace ShaderBuilder
{
template<typename T>
template<typename... Args>
std::shared_ptr<T> GenBuilder<T>::operator()(Args&&... args) const
{
return std::make_shared<T>(std::forward<Args>(args)...);
}
template<ShaderAst::AssignType op>
std::shared_ptr<ShaderAst::AssignOp> AssignOpBuilder<op>::operator()(const ShaderAst::VariablePtr& left, const ShaderAst::ExpressionPtr& right) const
{
return std::make_shared<ShaderAst::AssignOp>(op, left, right);
}
template<ShaderAst::BinaryType op>
std::shared_ptr<ShaderAst::BinaryOp> BinOpBuilder<op>::operator()(const ShaderAst::ExpressionPtr& left, const ShaderAst::ExpressionPtr& right) const
{
return std::make_shared<ShaderAst::BinaryOp>(op, left, right);
}
inline std::shared_ptr<ShaderAst::Variable> BuiltinBuilder::operator()(ShaderAst::BuiltinEntry builtin) const
{
ShaderAst::ExpressionType exprType = ShaderAst::ExpressionType::Void;
switch (builtin)
{
case ShaderAst::BuiltinEntry::VertexPosition:
exprType = ShaderAst::ExpressionType::Float4;
break;
}
NazaraAssert(exprType != ShaderAst::ExpressionType::Void, "Unhandled builtin");
return std::make_shared<ShaderAst::BuiltinVariable>(builtin, exprType);
}
template<ShaderAst::VariableType type>
template<typename... Args>
std::shared_ptr<ShaderAst::Variable> VarBuilder<type>::operator()(Args&&... args) const
{
return std::make_shared<ShaderAst::NamedVariable>(type, std::forward<Args>(args)...);
}
template<ShaderAst::ExpressionType Type, typename... Args>
std::shared_ptr<ShaderAst::Cast> Cast(Args&&... args)
{
return std::make_shared<ShaderAst::Cast>(Type, std::forward<Args>(args)...);
}
} }
#include <Nazara/Renderer/DebugOff.hpp>

View File

@ -1,52 +0,0 @@
// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Engine - Renderer module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_SHADERWRITER_HPP
#define NAZARA_SHADERWRITER_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Core/String.hpp>
#include <Nazara/Renderer/Config.hpp>
#include <Nazara/Renderer/ShaderAst.hpp>
#include <unordered_set>
namespace Nz
{
class NAZARA_RENDERER_API ShaderWriter
{
public:
ShaderWriter() = default;
ShaderWriter(const ShaderWriter&) = delete;
ShaderWriter(ShaderWriter&&) = delete;
virtual ~ShaderWriter();
void EnableCondition(const String& name, bool cond);
bool IsConditionEnabled(const String& name) const;
virtual Nz::String Generate(const ShaderAst::StatementPtr& node) = 0;
virtual void RegisterFunction(const String& name, ShaderAst::StatementPtr node, std::initializer_list<ShaderAst::NamedVariablePtr> parameters, ShaderAst::ExpressionType ret) = 0;
virtual void RegisterVariable(ShaderAst::VariableType kind, const String& name, ShaderAst::ExpressionType type) = 0;
virtual void Write(const ShaderAst::AssignOp& node) = 0;
virtual void Write(const ShaderAst::Branch& node) = 0;
virtual void Write(const ShaderAst::BinaryOp& node) = 0;
virtual void Write(const ShaderAst::BuiltinVariable& node) = 0;
virtual void Write(const ShaderAst::Cast& node) = 0;
virtual void Write(const ShaderAst::Constant& node) = 0;
virtual void Write(const ShaderAst::ExpressionStatement& node) = 0;
virtual void Write(const ShaderAst::NamedVariable& node) = 0;
virtual void Write(const ShaderAst::NodePtr& node) = 0;
virtual void Write(const ShaderAst::StatementBlock& node) = 0;
virtual void Write(const ShaderAst::SwizzleOp& node) = 0;
private:
std::unordered_set<String> m_conditions;
};
}
#endif // NAZARA_SHADERWRITER_HPP

50
include/Nazara/Shader.hpp Normal file
View File

@ -0,0 +1,50 @@
// This file was automatically generated
/*
Nazara Engine - Module name
Copyright (C) 2020 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#pragma once
#ifndef NAZARA_GLOBAL_SHADER_HPP
#define NAZARA_GLOBAL_SHADER_HPP
#include <Nazara/Shader/Config.hpp>
#include <Nazara/Shader/GlslWriter.hpp>
#include <Nazara/Shader/Shader.hpp>
#include <Nazara/Shader/ShaderAst.hpp>
#include <Nazara/Shader/ShaderAstCloner.hpp>
#include <Nazara/Shader/ShaderAstRecursiveVisitor.hpp>
#include <Nazara/Shader/ShaderAstSerializer.hpp>
#include <Nazara/Shader/ShaderAstValidator.hpp>
#include <Nazara/Shader/ShaderAstVisitor.hpp>
#include <Nazara/Shader/ShaderBuilder.hpp>
#include <Nazara/Shader/ShaderEnums.hpp>
#include <Nazara/Shader/ShaderExpressionType.hpp>
#include <Nazara/Shader/ShaderNodes.hpp>
#include <Nazara/Shader/ShaderVariables.hpp>
#include <Nazara/Shader/ShaderVarVisitor.hpp>
#include <Nazara/Shader/ShaderWriter.hpp>
#include <Nazara/Shader/SpirvWriter.hpp>
#endif // NAZARA_GLOBAL_SHADER_HPP

View File

@ -0,0 +1,53 @@
/*
Nazara Engine - Shader generator
Copyright (C) 2020 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#pragma once
#ifndef NAZARA_CONFIG_SHADER_HPP
#define NAZARA_CONFIG_SHADER_HPP
/// Each modification of a parameter needs a recompilation of the module
// Use the MemoryManager to manage dynamic allocations (can detect memory leak but allocations/frees are slower)
#define NAZARA_SHADER_MANAGE_MEMORY 0
// Activate the security tests based on the code (Advised for development)
#define NAZARA_SHADER_SAFE 1
/// Each modification of a parameter following implies a modification (often minor) of the code
/// Checking the values and types of certain constants
#include <Nazara/Shader/ConfigCheck.hpp>
#if !defined(NAZARA_STATIC)
#ifdef NAZARA_SHADER_BUILD
#define NAZARA_SHADER_API NAZARA_EXPORT
#else
#define NAZARA_SHADER_API NAZARA_IMPORT
#endif
#else
#define NAZARA_SHADER_API
#endif
#endif // NAZARA_CONFIG_SHADER_HPP

View File

@ -0,0 +1,22 @@
// Copyright (C) YEAR AUTHORS
// 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_CONFIG_CHECK_SHADER_HPP
#define NAZARA_CONFIG_CHECK_SHADER_HPP
/// This file is used to check the constant values defined in Config.hpp
#include <type_traits>
#define CheckType(name, type, err) static_assert(std::is_ ##type <decltype(name)>::value, #type err)
#define CheckTypeAndVal(name, type, op, val, err) static_assert(std::is_ ##type <decltype(name)>::value && name op val, #type err)
// We force the value of MANAGE_MEMORY in debug
#if defined(NAZARA_DEBUG) && !NAZARA_SHADER_MANAGE_MEMORY
#undef NAZARA_SHADER_MANAGE_MEMORY
#define NAZARA_SHADER_MANAGE_MEMORY 0
#endif
#endif // NAZARA_CONFIG_CHECK_SHADER_HPP

View File

@ -0,0 +1,8 @@
// Copyright (C) YEAR AUTHORS
// 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/Config.hpp>
#if NAZARA_SHADER_MANAGE_MEMORY
#include <Nazara/Core/Debug/NewRedefinition.hpp>
#endif

View File

@ -0,0 +1,9 @@
// Copyright (C) YEAR AUTHORS
// This file is part of the "Nazara Engine - Shader generator"
// For conditions of distribution and use, see copyright notice in Config.hpp
// We suppose that Debug.hpp is already included, same goes for Config.hpp
#if NAZARA_SHADER_MANAGE_MEMORY
#undef delete
#undef new
#endif

View File

@ -0,0 +1,110 @@
// Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - Renderer module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_GLSLWRITER_HPP
#define NAZARA_GLSLWRITER_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Shader/Config.hpp>
#include <Nazara/Shader/ShaderAst.hpp>
#include <Nazara/Shader/ShaderVarVisitor.hpp>
#include <Nazara/Shader/ShaderAstVisitor.hpp>
#include <Nazara/Shader/ShaderWriter.hpp>
#include <set>
#include <sstream>
#include <string>
#include <unordered_map>
namespace Nz
{
class NAZARA_SHADER_API GlslWriter : public ShaderWriter, public ShaderVarVisitor, public ShaderAstVisitor
{
public:
struct Environment;
using ExtSupportCallback = std::function<bool(const std::string_view& name)>;
GlslWriter();
GlslWriter(const GlslWriter&) = delete;
GlslWriter(GlslWriter&&) = delete;
~GlslWriter() = default;
std::string Generate(const ShaderAst& shader) override;
void SetEnv(Environment environment);
struct Environment
{
ExtSupportCallback extCallback;
unsigned int glMajorVersion = 3;
unsigned int glMinorVersion = 0;
bool glES = false;
bool flipYPosition = false;
};
private:
void Append(ShaderExpressionType type);
void Append(ShaderNodes::BuiltinEntry builtin);
void Append(ShaderNodes::BasicType type);
void Append(ShaderNodes::MemoryLayout layout);
template<typename T> void Append(const T& param);
void AppendCommentSection(const std::string& section);
void AppendField(const std::string& structName, std::size_t* memberIndex, std::size_t remainingMembers);
void AppendFunction(const ShaderAst::Function& func);
void AppendFunctionPrototype(const ShaderAst::Function& func);
void AppendLine(const std::string& txt = {});
template<typename T> void DeclareVariables(const ShaderAst& shader, const std::vector<T>& variables, const std::string& keyword = {}, const std::string& section = {});
void EnterScope();
void LeaveScope();
using ShaderVarVisitor::Visit;
using ShaderAstVisitor::Visit;
void Visit(ShaderNodes::ExpressionPtr& expr, bool encloseIfRequired = false);
void Visit(ShaderNodes::AccessMember& node) override;
void Visit(ShaderNodes::AssignOp& node) override;
void Visit(ShaderNodes::Branch& node) override;
void Visit(ShaderNodes::BinaryOp& node) override;
void Visit(ShaderNodes::BuiltinVariable& var) override;
void Visit(ShaderNodes::Cast& node) override;
void Visit(ShaderNodes::Constant& node) override;
void Visit(ShaderNodes::DeclareVariable& node) override;
void Visit(ShaderNodes::ExpressionStatement& node) override;
void Visit(ShaderNodes::Identifier& node) override;
void Visit(ShaderNodes::InputVariable& var) override;
void Visit(ShaderNodes::IntrinsicCall& node) override;
void Visit(ShaderNodes::LocalVariable& var) override;
void Visit(ShaderNodes::ParameterVariable& var) override;
void Visit(ShaderNodes::OutputVariable& var) override;
void Visit(ShaderNodes::Sample2D& node) override;
void Visit(ShaderNodes::StatementBlock& node) override;
void Visit(ShaderNodes::SwizzleOp& node) override;
void Visit(ShaderNodes::UniformVariable& var) override;
static bool HasExplicitBinding(const ShaderAst& shader);
static bool HasExplicitLocation(const ShaderAst& shader);
struct Context
{
const ShaderAst* shader = nullptr;
const ShaderAst::Function* currentFunction = nullptr;
};
struct State
{
std::stringstream stream;
unsigned int indentLevel = 0;
};
Context m_context;
Environment m_environment;
State* m_currentState;
};
}
#include <Nazara/Shader/GlslWriter.inl>
#endif // NAZARA_GLSLWRITER_HPP

View File

@ -0,0 +1,132 @@
// 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/GlslWriter.hpp>
#include <type_traits>
#include <Nazara/Shader/Debug.hpp>
namespace Nz
{
template<typename T>
void GlslWriter::Append(const T& param)
{
NazaraAssert(m_currentState, "This function should only be called while processing an AST");
m_currentState->stream << param;
}
template<typename T>
void GlslWriter::DeclareVariables(const ShaderAst& shader, const std::vector<T>& variables, const std::string& keyword, const std::string& section)
{
if (!variables.empty())
{
if (!section.empty())
AppendCommentSection(section);
for (const auto& var : variables)
{
if constexpr (std::is_same_v<T, ShaderAst::InputOutput>)
{
if (var.locationIndex)
{
Append("layout(location = ");
Append(*var.locationIndex);
Append(") ");
}
if (!keyword.empty())
{
Append(keyword);
Append(" ");
}
Append(var.type);
Append(" ");
Append(var.name);
AppendLine(";");
}
else if constexpr (std::is_same_v<T, ShaderAst::Uniform>)
{
if (var.bindingIndex || var.memoryLayout)
{
Append("layout(");
bool first = true;
if (var.bindingIndex)
{
if (!first)
Append(", ");
Append("binding = ");
Append(*var.bindingIndex);
first = false;
}
if (var.memoryLayout)
{
if (!first)
Append(", ");
Append(*var.memoryLayout);
first = false;
}
Append(") ");
}
if (!keyword.empty())
{
Append(keyword);
Append(" ");
}
std::visit([&](auto&& arg)
{
using T = std::decay_t<decltype(arg)>;
if constexpr (std::is_same_v<T, ShaderNodes::BasicType>)
{
Append(arg);
Append(" ");
Append(var.name);
}
else if constexpr (std::is_same_v<T, std::string>)
{
const auto& structs = shader.GetStructs();
auto it = std::find_if(structs.begin(), structs.end(), [&](const auto& s) { return s.name == arg; });
if (it == structs.end())
throw std::runtime_error("struct " + arg + " has not been defined");
const auto& s = *it;
AppendLine(var.name + "_interface");
AppendLine("{");
for (const auto& m : s.members)
{
Append("\t");
Append(m.type);
Append(" ");
Append(m.name);
AppendLine(";");
}
Append("} ");
Append(var.name);
}
else
static_assert(AlwaysFalse<T>::value, "non-exhaustive visitor");
}, var.type);
AppendLine(";");
AppendLine();
}
}
AppendLine();
}
}
}
#include <Nazara/Shader/DebugOff.hpp>

View File

@ -0,0 +1,33 @@
// Copyright (C) YEAR AUTHORS
// This file is part of the "Nazara Engine - Module name"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_SHADER_HPP
#define NAZARA_SHADER_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Core/Initializer.hpp>
#include <Nazara/Shader/Config.hpp>
namespace Nz
{
class NAZARA_SHADER_API Shader
{
public:
Shader() = delete;
~Shader() = delete;
static bool Initialize();
static bool IsInitialized();
static void Uninitialize();
private:
static unsigned int s_moduleReferenceCounter;
};
}
#endif // NAZARA_SHADER_HPP

View File

@ -0,0 +1,115 @@
// Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - Renderer module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_SHADER_AST_HPP
#define NAZARA_SHADER_AST_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Shader/ShaderExpressionType.hpp>
#include <Nazara/Shader/ShaderNodes.hpp>
#include <Nazara/Utility/Enums.hpp>
#include <optional>
#include <unordered_map>
#include <vector>
namespace Nz
{
class NAZARA_SHADER_API ShaderAst
{
public:
struct Function;
struct FunctionParameter;
struct InputOutput;
struct Struct;
struct StructMember;
struct Uniform;
struct VariableBase;
inline ShaderAst(ShaderStageType shaderStage);
ShaderAst(const ShaderAst&) = default;
ShaderAst(ShaderAst&&) = default;
~ShaderAst() = default;
void AddFunction(std::string name, ShaderNodes::StatementPtr statement, std::vector<FunctionParameter> parameters = {}, ShaderNodes::BasicType returnType = ShaderNodes::BasicType::Void);
void AddInput(std::string name, ShaderExpressionType type, std::optional<std::size_t> locationIndex = {});
void AddOutput(std::string name, ShaderExpressionType type, std::optional<std::size_t> locationIndex = {});
void AddStruct(std::string name, std::vector<StructMember> members);
void AddUniform(std::string name, ShaderExpressionType type, std::optional<std::size_t> bindingIndex = {}, std::optional<ShaderNodes::MemoryLayout> memoryLayout = {});
inline const Function& GetFunction(std::size_t i) const;
inline std::size_t GetFunctionCount() const;
inline const std::vector<Function>& GetFunctions() const;
inline const InputOutput& GetInput(std::size_t i) const;
inline std::size_t GetInputCount() const;
inline const std::vector<InputOutput>& GetInputs() const;
inline const InputOutput& GetOutput(std::size_t i) const;
inline std::size_t GetOutputCount() const;
inline const std::vector<InputOutput>& GetOutputs() const;
inline ShaderStageType GetStage() const;
inline const Struct& GetStruct(std::size_t i) const;
inline std::size_t GetStructCount() const;
inline const std::vector<Struct>& GetStructs() const;
inline const Uniform& GetUniform(std::size_t i) const;
inline std::size_t GetUniformCount() const;
inline const std::vector<Uniform>& GetUniforms() const;
ShaderAst& operator=(const ShaderAst&) = default;
ShaderAst& operator=(ShaderAst&&) = default;
struct VariableBase
{
std::string name;
ShaderExpressionType type;
};
struct FunctionParameter : VariableBase
{
};
struct Function
{
std::string name;
std::vector<FunctionParameter> parameters;
ShaderNodes::BasicType returnType;
ShaderNodes::StatementPtr statement;
};
struct InputOutput : VariableBase
{
std::optional<std::size_t> locationIndex;
};
struct Uniform : VariableBase
{
std::optional<std::size_t> bindingIndex;
std::optional<ShaderNodes::MemoryLayout> memoryLayout;
};
struct Struct
{
std::string name;
std::vector<StructMember> members;
};
struct StructMember
{
std::string name;
ShaderExpressionType type;
};
private:
std::vector<Function> m_functions;
std::vector<InputOutput> m_inputs;
std::vector<InputOutput> m_outputs;
std::vector<Struct> m_structs;
std::vector<Uniform> m_uniforms;
ShaderStageType m_stage;
};
}
#include <Nazara/Shader/ShaderAst.inl>
#endif // NAZARA_SHADER_AST_HPP

View File

@ -0,0 +1,101 @@
// 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/ShaderAst.hpp>
#include <Nazara/Shader/Debug.hpp>
namespace Nz
{
inline ShaderAst::ShaderAst(ShaderStageType shaderStage) :
m_stage(shaderStage)
{
}
inline auto ShaderAst::GetFunction(std::size_t i) const -> const Function&
{
assert(i < m_functions.size());
return m_functions[i];
}
inline std::size_t ShaderAst::GetFunctionCount() const
{
return m_functions.size();
}
inline auto ShaderAst::GetFunctions() const -> const std::vector<Function>&
{
return m_functions;
}
inline auto ShaderAst::GetInput(std::size_t i) const -> const InputOutput&
{
assert(i < m_inputs.size());
return m_inputs[i];
}
inline std::size_t ShaderAst::GetInputCount() const
{
return m_inputs.size();
}
inline auto ShaderAst::GetInputs() const -> const std::vector<InputOutput>&
{
return m_inputs;
}
inline auto ShaderAst::GetOutput(std::size_t i) const -> const InputOutput&
{
assert(i < m_outputs.size());
return m_outputs[i];
}
inline std::size_t ShaderAst::GetOutputCount() const
{
return m_outputs.size();
}
inline auto ShaderAst::GetOutputs() const -> const std::vector<InputOutput>&
{
return m_outputs;
}
inline ShaderStageType ShaderAst::GetStage() const
{
return m_stage;
}
inline auto ShaderAst::GetStruct(std::size_t i) const -> const Struct&
{
assert(i < m_structs.size());
return m_structs[i];
}
inline std::size_t ShaderAst::GetStructCount() const
{
return m_structs.size();
}
inline auto ShaderAst::GetStructs() const -> const std::vector<Struct>&
{
return m_structs;
}
inline auto ShaderAst::GetUniform(std::size_t i) const -> const Uniform&
{
assert(i < m_uniforms.size());
return m_uniforms[i];
}
inline std::size_t ShaderAst::GetUniformCount() const
{
return m_uniforms.size();
}
inline auto ShaderAst::GetUniforms() const -> const std::vector<Uniform>&
{
return m_uniforms;
}
}
#include <Nazara/Shader/DebugOff.hpp>

View File

@ -0,0 +1,74 @@
// 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_SHADERASTCLONER_HPP
#define NAZARA_SHADERASTCLONER_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Shader/Config.hpp>
#include <Nazara/Shader/ShaderAstVisitor.hpp>
#include <Nazara/Shader/ShaderVarVisitor.hpp>
#include <vector>
namespace Nz
{
class NAZARA_SHADER_API ShaderAstCloner : public ShaderAstVisitor, public ShaderVarVisitor
{
public:
ShaderAstCloner() = default;
ShaderAstCloner(const ShaderAstCloner&) = default;
ShaderAstCloner(ShaderAstCloner&&) = default;
~ShaderAstCloner() = default;
ShaderNodes::StatementPtr Clone(const ShaderNodes::StatementPtr& statement);
ShaderAstCloner& operator=(const ShaderAstCloner&) = default;
ShaderAstCloner& operator=(ShaderAstCloner&&) = default;
protected:
ShaderNodes::ExpressionPtr CloneExpression(const ShaderNodes::ExpressionPtr& expr);
ShaderNodes::StatementPtr CloneStatement(const ShaderNodes::StatementPtr& statement);
ShaderNodes::VariablePtr CloneVariable(const ShaderNodes::VariablePtr& statement);
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::Constant& node) override;
void Visit(ShaderNodes::DeclareVariable& node) override;
void Visit(ShaderNodes::ExpressionStatement& node) override;
void Visit(ShaderNodes::Identifier& node) override;
void Visit(ShaderNodes::IntrinsicCall& node) override;
void Visit(ShaderNodes::Sample2D& node) override;
void Visit(ShaderNodes::StatementBlock& node) override;
void Visit(ShaderNodes::SwizzleOp& node) override;
void Visit(ShaderNodes::BuiltinVariable& var) override;
void Visit(ShaderNodes::InputVariable& var) override;
void Visit(ShaderNodes::LocalVariable& var) override;
void Visit(ShaderNodes::OutputVariable& var) override;
void Visit(ShaderNodes::ParameterVariable& var) override;
void Visit(ShaderNodes::UniformVariable& var) override;
void PushExpression(ShaderNodes::ExpressionPtr expression);
void PushStatement(ShaderNodes::StatementPtr statement);
void PushVariable(ShaderNodes::VariablePtr variable);
ShaderNodes::ExpressionPtr PopExpression();
ShaderNodes::StatementPtr PopStatement();
ShaderNodes::VariablePtr PopVariable();
private:
std::vector<ShaderNodes::ExpressionPtr> m_expressionStack;
std::vector<ShaderNodes::StatementPtr> m_statementStack;
std::vector<ShaderNodes::VariablePtr> m_variableStack;
};
}
#include <Nazara/Shader/ShaderAstCloner.inl>
#endif

View File

@ -0,0 +1,12 @@
// 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/ShaderAstCloner.hpp>
#include <Nazara/Shader/Debug.hpp>
namespace Nz
{
}
#include <Nazara/Shader/DebugOff.hpp>

View File

@ -0,0 +1,42 @@
// 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_SHADER_RECURSIVE_VISITOR_HPP
#define NAZARA_SHADER_RECURSIVE_VISITOR_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Shader/Config.hpp>
#include <Nazara/Shader/ShaderAstVisitor.hpp>
namespace Nz
{
class NAZARA_SHADER_API ShaderAstRecursiveVisitor : public ShaderAstVisitor
{
public:
ShaderAstRecursiveVisitor() = default;
~ShaderAstRecursiveVisitor() = default;
using ShaderAstVisitor::Visit;
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::Constant& node) override;
void Visit(ShaderNodes::DeclareVariable& node) override;
void Visit(ShaderNodes::ExpressionStatement& node) override;
void Visit(ShaderNodes::Identifier& node) override;
void Visit(ShaderNodes::IntrinsicCall& node) override;
void Visit(ShaderNodes::Sample2D& node) override;
void Visit(ShaderNodes::StatementBlock& node) override;
void Visit(ShaderNodes::SwizzleOp& node) override;
};
}
#include <Nazara/Shader/ShaderAstRecursiveVisitor.inl>
#endif

View File

@ -0,0 +1,12 @@
// 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/ShaderAstRecursiveVisitor.hpp>
#include <Nazara/Shader/Debug.hpp>
namespace Nz
{
}
#include <Nazara/Shader/DebugOff.hpp>

View File

@ -0,0 +1,143 @@
// 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_SHADERSERIALIZER_HPP
#define NAZARA_SHADERSERIALIZER_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Core/ByteArray.hpp>
#include <Nazara/Core/ByteStream.hpp>
#include <Nazara/Shader/Config.hpp>
#include <Nazara/Shader/ShaderAst.hpp>
#include <Nazara/Shader/ShaderNodes.hpp>
#include <Nazara/Shader/ShaderVariables.hpp>
namespace Nz
{
class NAZARA_SHADER_API ShaderAstSerializerBase
{
public:
ShaderAstSerializerBase() = default;
ShaderAstSerializerBase(const ShaderAstSerializerBase&) = delete;
ShaderAstSerializerBase(ShaderAstSerializerBase&&) = delete;
~ShaderAstSerializerBase() = default;
void Serialize(ShaderNodes::AccessMember& node);
void Serialize(ShaderNodes::AssignOp& node);
void Serialize(ShaderNodes::BinaryOp& node);
void Serialize(ShaderNodes::BuiltinVariable& var);
void Serialize(ShaderNodes::Branch& node);
void Serialize(ShaderNodes::Cast& node);
void Serialize(ShaderNodes::Constant& node);
void Serialize(ShaderNodes::DeclareVariable& node);
void Serialize(ShaderNodes::ExpressionStatement& node);
void Serialize(ShaderNodes::Identifier& node);
void Serialize(ShaderNodes::IntrinsicCall& node);
void Serialize(ShaderNodes::NamedVariable& var);
void Serialize(ShaderNodes::Sample2D& node);
void Serialize(ShaderNodes::StatementBlock& node);
void Serialize(ShaderNodes::SwizzleOp& node);
protected:
template<typename T> void Container(T& container);
template<typename T> void Enum(T& enumVal);
template<typename T> void OptEnum(std::optional<T>& optVal);
template<typename T> void OptVal(std::optional<T>& optVal);
virtual bool IsWriting() const = 0;
virtual void Node(ShaderNodes::NodePtr& node) = 0;
template<typename T> void Node(std::shared_ptr<T>& node);
virtual void Type(ShaderExpressionType& type) = 0;
virtual void Value(bool& val) = 0;
virtual void Value(float& val) = 0;
virtual void Value(std::string& val) = 0;
virtual void Value(Int32& val) = 0;
virtual void Value(Vector2f& val) = 0;
virtual void Value(Vector3f& val) = 0;
virtual void Value(Vector4f& val) = 0;
virtual void Value(Vector2i32& val) = 0;
virtual void Value(Vector3i32& val) = 0;
virtual void Value(Vector4i32& val) = 0;
virtual void Value(UInt8& val) = 0;
virtual void Value(UInt16& val) = 0;
virtual void Value(UInt32& val) = 0;
inline void Value(std::size_t& val);
virtual void Variable(ShaderNodes::VariablePtr& var) = 0;
template<typename T> void Variable(std::shared_ptr<T>& var);
};
class NAZARA_SHADER_API ShaderAstSerializer final : public ShaderAstSerializerBase
{
public:
inline ShaderAstSerializer(ByteStream& stream);
~ShaderAstSerializer() = default;
void Serialize(const ShaderAst& shader);
private:
bool IsWriting() const override;
void Node(const ShaderNodes::NodePtr& node);
void Node(ShaderNodes::NodePtr& node) override;
void Type(ShaderExpressionType& type) override;
void Value(bool& val) override;
void Value(float& val) override;
void Value(std::string& val) override;
void Value(Int32& val) override;
void Value(Vector2f& val) override;
void Value(Vector3f& val) override;
void Value(Vector4f& val) override;
void Value(Vector2i32& val) override;
void Value(Vector3i32& val) override;
void Value(Vector4i32& val) override;
void Value(UInt8& val) override;
void Value(UInt16& val) override;
void Value(UInt32& val) override;
void Variable(ShaderNodes::VariablePtr& var) override;
ByteStream& m_stream;
};
class NAZARA_SHADER_API ShaderAstUnserializer final : public ShaderAstSerializerBase
{
public:
ShaderAstUnserializer(ByteStream& stream);
~ShaderAstUnserializer() = default;
ShaderAst Unserialize();
private:
bool IsWriting() const override;
void Node(ShaderNodes::NodePtr& node) override;
void Type(ShaderExpressionType& type) override;
void Value(bool& val) override;
void Value(float& val) override;
void Value(std::string& val) override;
void Value(Int32& val) override;
void Value(Vector2f& val) override;
void Value(Vector3f& val) override;
void Value(Vector4f& val) override;
void Value(Vector2i32& val) override;
void Value(Vector3i32& val) override;
void Value(Vector4i32& val) override;
void Value(UInt8& val) override;
void Value(UInt16& val) override;
void Value(UInt32& val) override;
void Variable(ShaderNodes::VariablePtr& var) override;
ByteStream& m_stream;
};
NAZARA_SHADER_API ByteArray SerializeShader(const ShaderAst& shader);
NAZARA_SHADER_API ShaderAst UnserializeShader(ByteStream& stream);
}
#include <Nazara/Shader/ShaderAstSerializer.inl>
#endif

View File

@ -0,0 +1,127 @@
// 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/ShaderAstSerializer.hpp>
#include <Nazara/Shader/Debug.hpp>
namespace Nz
{
template<typename T>
void ShaderAstSerializerBase::Container(T& container)
{
bool isWriting = IsWriting();
UInt32 size;
if (isWriting)
size = UInt32(container.size());
Value(size);
if (!isWriting)
container.resize(size);
}
template<typename T>
void ShaderAstSerializerBase::Enum(T& enumVal)
{
bool isWriting = IsWriting();
UInt32 value;
if (isWriting)
value = static_cast<UInt32>(enumVal);
Value(value);
if (!isWriting)
enumVal = static_cast<T>(value);
}
template<typename T>
void ShaderAstSerializerBase::OptEnum(std::optional<T>& optVal)
{
bool isWriting = IsWriting();
bool hasValue;
if (isWriting)
hasValue = optVal.has_value();
Value(hasValue);
if (!isWriting && hasValue)
optVal.emplace();
if (optVal.has_value())
Enum(optVal.value());
}
template<typename T>
void ShaderAstSerializerBase::OptVal(std::optional<T>& optVal)
{
bool isWriting = IsWriting();
bool hasValue;
if (isWriting)
hasValue = optVal.has_value();
Value(hasValue);
if (!isWriting && hasValue)
optVal.emplace();
if (optVal.has_value())
Value(optVal.value());
}
template<typename T>
void ShaderAstSerializerBase::Node(std::shared_ptr<T>& node)
{
bool isWriting = IsWriting();
ShaderNodes::NodePtr value;
if (isWriting)
value = node;
Node(value);
if (!isWriting)
node = std::static_pointer_cast<T>(value);
}
template<typename T>
void ShaderAstSerializerBase::Variable(std::shared_ptr<T>& var)
{
bool isWriting = IsWriting();
ShaderNodes::VariablePtr value;
if (isWriting)
value = var;
Variable(value);
if (!isWriting)
var = std::static_pointer_cast<T>(value);
}
inline void ShaderAstSerializerBase::Value(std::size_t& val)
{
bool isWriting = IsWriting();
UInt32 value;
if (isWriting)
value = static_cast<UInt32>(val);
Value(value);
if (!isWriting)
val = static_cast<std::size_t>(value);
}
inline ShaderAstSerializer::ShaderAstSerializer(ByteStream& stream) :
m_stream(stream)
{
}
inline ShaderAstUnserializer::ShaderAstUnserializer(ByteStream& stream) :
m_stream(stream)
{
}
}
#include <Nazara/Shader/DebugOff.hpp>

View File

@ -0,0 +1,72 @@
// 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_SHADERVALIDATOR_HPP
#define NAZARA_SHADERVALIDATOR_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Core/ByteArray.hpp>
#include <Nazara/Core/ByteStream.hpp>
#include <Nazara/Shader/Config.hpp>
#include <Nazara/Shader/ShaderAst.hpp>
#include <Nazara/Shader/ShaderAstRecursiveVisitor.hpp>
#include <Nazara/Shader/ShaderVarVisitor.hpp>
namespace Nz
{
class NAZARA_SHADER_API ShaderAstValidator : public ShaderAstRecursiveVisitor, public ShaderVarVisitor
{
public:
inline ShaderAstValidator(const ShaderAst& shader);
ShaderAstValidator(const ShaderAstValidator&) = delete;
ShaderAstValidator(ShaderAstValidator&&) = delete;
~ShaderAstValidator() = default;
bool Validate(std::string* error = nullptr);
private:
const ShaderNodes::ExpressionPtr& MandatoryExpr(const ShaderNodes::ExpressionPtr& node);
const ShaderNodes::NodePtr& MandatoryNode(const ShaderNodes::NodePtr& node);
void TypeMustMatch(const ShaderNodes::ExpressionPtr& left, const ShaderNodes::ExpressionPtr& right);
void TypeMustMatch(const ShaderExpressionType& left, const ShaderExpressionType& right);
const ShaderAst::StructMember& CheckField(const std::string& structName, std::size_t* memberIndex, std::size_t remainingMembers);
using ShaderAstRecursiveVisitor::Visit;
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::Constant& node) override;
void Visit(ShaderNodes::DeclareVariable& node) override;
void Visit(ShaderNodes::ExpressionStatement& node) override;
void Visit(ShaderNodes::Identifier& node) override;
void Visit(ShaderNodes::IntrinsicCall& node) override;
void Visit(ShaderNodes::Sample2D& node) override;
void Visit(ShaderNodes::StatementBlock& node) override;
void Visit(ShaderNodes::SwizzleOp& node) override;
using ShaderVarVisitor::Visit;
void Visit(ShaderNodes::BuiltinVariable& var) override;
void Visit(ShaderNodes::InputVariable& var) override;
void Visit(ShaderNodes::LocalVariable& var) override;
void Visit(ShaderNodes::OutputVariable& var) override;
void Visit(ShaderNodes::ParameterVariable& var) override;
void Visit(ShaderNodes::UniformVariable& var) override;
struct Context;
const ShaderAst& m_shader;
Context* m_context;
};
NAZARA_SHADER_API bool ValidateShader(const ShaderAst& shader, std::string* error = nullptr);
}
#include <Nazara/Shader/ShaderAstValidator.inl>
#endif

View File

@ -0,0 +1,16 @@
// 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/ShaderAstValidator.hpp>
#include <Nazara/Shader/Debug.hpp>
namespace Nz
{
ShaderAstValidator::ShaderAstValidator(const ShaderAst& shader) :
m_shader(shader)
{
}
}
#include <Nazara/Shader/DebugOff.hpp>

View File

@ -0,0 +1,50 @@
// 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_SHADERASTVISITOR_HPP
#define NAZARA_SHADERASTVISITOR_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Shader/Config.hpp>
#include <Nazara/Shader/ShaderNodes.hpp>
#include <string>
#include <unordered_set>
namespace Nz
{
class NAZARA_SHADER_API ShaderAstVisitor
{
public:
ShaderAstVisitor() = default;
ShaderAstVisitor(const ShaderAstVisitor&) = delete;
ShaderAstVisitor(ShaderAstVisitor&&) = delete;
virtual ~ShaderAstVisitor();
void EnableCondition(const std::string& name, bool cond);
bool IsConditionEnabled(const std::string& name) const;
void Visit(const ShaderNodes::NodePtr& node);
virtual void Visit(ShaderNodes::AccessMember& node) = 0;
virtual void Visit(ShaderNodes::AssignOp& node) = 0;
virtual void Visit(ShaderNodes::BinaryOp& node) = 0;
virtual void Visit(ShaderNodes::Branch& node) = 0;
virtual void Visit(ShaderNodes::Cast& node) = 0;
virtual void Visit(ShaderNodes::Constant& node) = 0;
virtual void Visit(ShaderNodes::DeclareVariable& node) = 0;
virtual void Visit(ShaderNodes::ExpressionStatement& node) = 0;
virtual void Visit(ShaderNodes::Identifier& node) = 0;
virtual void Visit(ShaderNodes::IntrinsicCall& node) = 0;
virtual void Visit(ShaderNodes::Sample2D& node) = 0;
virtual void Visit(ShaderNodes::StatementBlock& node) = 0;
virtual void Visit(ShaderNodes::SwizzleOp& node) = 0;
private:
std::unordered_set<std::string> m_conditions;
};
}
#endif

View File

@ -0,0 +1,36 @@
// 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_SHADERASTVISITOREXCEPT_HPP
#define NAZARA_SHADERASTVISITOREXCEPT_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Shader/Config.hpp>
#include <Nazara/Shader/ShaderAstVisitor.hpp>
namespace Nz
{
class NAZARA_SHADER_API ShaderAstVisitorExcept : public ShaderAstVisitor
{
public:
using ShaderAstVisitor::Visit;
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::Constant& node) override;
void Visit(ShaderNodes::DeclareVariable& node) override;
void Visit(ShaderNodes::ExpressionStatement& node) override;
void Visit(ShaderNodes::Identifier& node) override;
void Visit(ShaderNodes::IntrinsicCall& node) override;
void Visit(ShaderNodes::Sample2D& node) override;
void Visit(ShaderNodes::StatementBlock& node) override;
void Visit(ShaderNodes::SwizzleOp& node) override;
};
}
#endif

View File

@ -0,0 +1,76 @@
// 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_SHADER_BUILDER_HPP
#define NAZARA_SHADER_BUILDER_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Shader/ShaderNodes.hpp>
#include <memory>
namespace Nz::ShaderBuilder
{
template<ShaderNodes::AssignType op>
struct AssignOpBuilder
{
constexpr AssignOpBuilder() = default;
std::shared_ptr<ShaderNodes::AssignOp> operator()(const ShaderNodes::ExpressionPtr& left, const ShaderNodes::ExpressionPtr& right) const;
};
template<ShaderNodes::BinaryType op>
struct BinOpBuilder
{
constexpr BinOpBuilder() = default;
std::shared_ptr<ShaderNodes::BinaryOp> operator()(const ShaderNodes::ExpressionPtr& left, const ShaderNodes::ExpressionPtr& right) const;
};
struct BuiltinBuilder
{
constexpr BuiltinBuilder() = default;
inline std::shared_ptr<ShaderNodes::Variable> operator()(ShaderNodes::BuiltinEntry builtin) const;
};
template<typename T>
struct GenBuilder
{
constexpr GenBuilder() = default;
template<typename... Args> std::shared_ptr<T> operator()(Args&&... args) const;
};
constexpr GenBuilder<ShaderNodes::AccessMember> AccessMember;
constexpr BinOpBuilder<ShaderNodes::BinaryType::Add> Add;
constexpr AssignOpBuilder<ShaderNodes::AssignType::Simple> Assign;
constexpr BuiltinBuilder Builtin;
constexpr GenBuilder<ShaderNodes::StatementBlock> Block;
constexpr GenBuilder<ShaderNodes::Branch> Branch;
constexpr GenBuilder<ShaderNodes::ConditionalStatement> ConditionalStatement;
constexpr GenBuilder<ShaderNodes::Constant> Constant;
constexpr GenBuilder<ShaderNodes::DeclareVariable> DeclareVariable;
constexpr BinOpBuilder<ShaderNodes::BinaryType::Divide> Divide;
constexpr BinOpBuilder<ShaderNodes::BinaryType::Equality> Equal;
constexpr GenBuilder<ShaderNodes::ExpressionStatement> ExprStatement;
constexpr GenBuilder<ShaderNodes::Identifier> Identifier;
constexpr GenBuilder<ShaderNodes::IntrinsicCall> IntrinsicCall;
constexpr GenBuilder<ShaderNodes::InputVariable> Input;
constexpr GenBuilder<ShaderNodes::LocalVariable> Local;
constexpr BinOpBuilder<ShaderNodes::BinaryType::Multiply> Multiply;
constexpr GenBuilder<ShaderNodes::OutputVariable> Output;
constexpr GenBuilder<ShaderNodes::ParameterVariable> Parameter;
constexpr GenBuilder<ShaderNodes::Sample2D> Sample2D;
constexpr GenBuilder<ShaderNodes::SwizzleOp> Swizzle;
constexpr BinOpBuilder<ShaderNodes::BinaryType::Substract> Substract;
constexpr GenBuilder<ShaderNodes::UniformVariable> Uniform;
template<ShaderNodes::BasicType Type, typename... Args> std::shared_ptr<ShaderNodes::Cast> Cast(Args&&... args);
}
#include <Nazara/Shader/ShaderBuilder.inl>
#endif // NAZARA_SHADER_BUILDER_HPP

View File

@ -0,0 +1,52 @@
// 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/ShaderBuilder.hpp>
#include <Nazara/Shader/Debug.hpp>
namespace Nz::ShaderBuilder
{
template<typename T>
template<typename... Args>
std::shared_ptr<T> GenBuilder<T>::operator()(Args&&... args) const
{
return T::Build(std::forward<Args>(args)...);
}
template<ShaderNodes::AssignType op>
std::shared_ptr<ShaderNodes::AssignOp> AssignOpBuilder<op>::operator()(const ShaderNodes::ExpressionPtr& left, const ShaderNodes::ExpressionPtr& right) const
{
return ShaderNodes::AssignOp::Build(op, left, right);
}
template<ShaderNodes::BinaryType op>
std::shared_ptr<ShaderNodes::BinaryOp> BinOpBuilder<op>::operator()(const ShaderNodes::ExpressionPtr& left, const ShaderNodes::ExpressionPtr& right) const
{
return ShaderNodes::BinaryOp::Build(op, left, right);
}
inline std::shared_ptr<ShaderNodes::Variable> BuiltinBuilder::operator()(ShaderNodes::BuiltinEntry builtin) const
{
ShaderNodes::BasicType exprType = ShaderNodes::BasicType::Void;
switch (builtin)
{
case ShaderNodes::BuiltinEntry::VertexPosition:
exprType = ShaderNodes::BasicType::Float4;
break;
}
NazaraAssert(exprType != ShaderNodes::BasicType::Void, "Unhandled builtin");
return ShaderNodes::BuiltinVariable::Build(builtin, exprType);
}
template<ShaderNodes::BasicType Type, typename... Args>
std::shared_ptr<ShaderNodes::Cast> Cast(Args&&... args)
{
return ShaderNodes::Cast::Build(Type, std::forward<Args>(args)...);
}
}
#include <Nazara/Shader/DebugOff.hpp>

View File

@ -0,0 +1,32 @@
// 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_SHADER_CONSTANTVALUE_HPP
#define NAZARA_SHADER_CONSTANTVALUE_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Math/Vector2.hpp>
#include <Nazara/Math/Vector3.hpp>
#include <Nazara/Math/Vector4.hpp>
#include <variant>
namespace Nz
{
using ShaderConstantValue = std::variant<
bool,
float,
Int32,
UInt32,
Vector2f,
Vector3f,
Vector4f,
Vector2i32,
Vector3i32,
Vector4i32
>;
}
#endif

View File

@ -0,0 +1,121 @@
// 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_SHADER_ENUMS_HPP
#define NAZARA_SHADER_ENUMS_HPP
#include <Nazara/Prerequisites.hpp>
namespace Nz::ShaderNodes
{
enum class AssignType
{
Simple //< =
};
enum class BasicType
{
Boolean, //< bool
Float1, //< float
Float2, //< vec2
Float3, //< vec3
Float4, //< vec4
Int1, //< int
Int2, //< ivec2
Int3, //< ivec3
Int4, //< ivec4
Mat4x4, //< mat4
Sampler2D, //< sampler2D
Void, //< void
UInt1, //< uint
UInt2, //< uvec2
UInt3, //< uvec3
UInt4 //< uvec4
};
enum class BinaryType
{
Add, //< +
Substract, //< -
Multiply, //< *
Divide, //< /
Equality //< ==
};
enum class BuiltinEntry
{
VertexPosition, // gl_Position
};
enum class ExpressionCategory
{
LValue,
RValue
};
enum class IntrinsicType
{
CrossProduct,
DotProduct
};
enum class MemoryLayout
{
Std140
};
enum class NodeType
{
None = -1,
AccessMember,
AssignOp,
BinaryOp,
Branch,
Cast,
Constant,
ConditionalStatement,
DeclareVariable,
ExpressionStatement,
Identifier,
IntrinsicCall,
Sample2D,
SwizzleOp,
StatementBlock
};
enum class SsaInstruction
{
OpAdd,
OpDiv,
OpMul,
OpSub,
OpSample
};
enum class SwizzleComponent
{
First,
Second,
Third,
Fourth
};
enum class VariableType
{
None = -1,
BuiltinVariable,
InputVariable,
LocalVariable,
OutputVariable,
ParameterVariable,
UniformVariable
};
}
#endif // NAZARA_SHADER_ENUMS_HPP

View File

@ -0,0 +1,20 @@
// 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_SHADER_EXPRESSIONTYPE_HPP
#define NAZARA_SHADER_EXPRESSIONTYPE_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Shader/ShaderEnums.hpp>
#include <string>
#include <variant>
namespace Nz
{
using ShaderExpressionType = std::variant<ShaderNodes::BasicType, std::string>;
}
#endif // NAZARA_SHADER_EXPRESSIONTYPE_HPP

View File

@ -0,0 +1,283 @@
// 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_SHADER_NODES_HPP
#define NAZARA_SHADER_NODES_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Math/Vector2.hpp>
#include <Nazara/Math/Vector3.hpp>
#include <Nazara/Math/Vector4.hpp>
#include <Nazara/Shader/Config.hpp>
#include <Nazara/Shader/ShaderConstantValue.hpp>
#include <Nazara/Shader/ShaderEnums.hpp>
#include <Nazara/Shader/ShaderExpressionType.hpp>
#include <Nazara/Shader/ShaderVariables.hpp>
#include <array>
#include <optional>
#include <string>
namespace Nz
{
class ShaderAstVisitor;
namespace ShaderNodes
{
class Node;
using NodePtr = std::shared_ptr<Node>;
class NAZARA_SHADER_API Node
{
public:
virtual ~Node();
inline NodeType GetType() const;
inline bool IsStatement() const;
virtual void Visit(ShaderAstVisitor& visitor) = 0;
static inline unsigned int GetComponentCount(BasicType type);
static inline BasicType GetComponentType(BasicType type);
protected:
inline Node(NodeType type, bool isStatement);
private:
NodeType m_type;
bool m_isStatement;
};
class Expression;
using ExpressionPtr = std::shared_ptr<Expression>;
class NAZARA_SHADER_API Expression : public Node
{
public:
inline Expression(NodeType type);
virtual ExpressionCategory GetExpressionCategory() const;
virtual ShaderExpressionType GetExpressionType() const = 0;
};
class Statement;
using StatementPtr = std::shared_ptr<Statement>;
class NAZARA_SHADER_API Statement : public Node
{
public:
inline Statement(NodeType type);
};
struct NAZARA_SHADER_API ExpressionStatement : public Statement
{
inline ExpressionStatement();
void Visit(ShaderAstVisitor& visitor) override;
ExpressionPtr expression;
static inline std::shared_ptr<ExpressionStatement> Build(ExpressionPtr expr);
};
//////////////////////////////////////////////////////////////////////////
struct NAZARA_SHADER_API ConditionalStatement : public Statement
{
inline ConditionalStatement();
void Visit(ShaderAstVisitor& visitor) override;
std::string conditionName;
StatementPtr statement;
static inline std::shared_ptr<ConditionalStatement> Build(std::string condition, StatementPtr statementPtr);
};
struct NAZARA_SHADER_API StatementBlock : public Statement
{
inline StatementBlock();
void Visit(ShaderAstVisitor& visitor) override;
std::vector<StatementPtr> statements;
static inline std::shared_ptr<StatementBlock> Build(std::vector<StatementPtr> statements);
template<typename... Args> static std::shared_ptr<StatementBlock> Build(Args&&... args);
};
struct NAZARA_SHADER_API DeclareVariable : public Statement
{
inline DeclareVariable();
void Visit(ShaderAstVisitor& visitor) override;
ExpressionPtr expression;
VariablePtr variable;
static inline std::shared_ptr<DeclareVariable> Build(VariablePtr variable, ExpressionPtr expression = nullptr);
};
struct NAZARA_SHADER_API Identifier : public Expression
{
inline Identifier();
ExpressionCategory GetExpressionCategory() const override;
ShaderExpressionType GetExpressionType() const override;
void Visit(ShaderAstVisitor& visitor) override;
VariablePtr var;
static inline std::shared_ptr<Identifier> Build(VariablePtr variable);
};
struct NAZARA_SHADER_API AccessMember : public Expression
{
inline AccessMember();
ExpressionCategory GetExpressionCategory() const override;
ShaderExpressionType GetExpressionType() const override;
void Visit(ShaderAstVisitor& visitor) override;
ExpressionPtr structExpr;
ShaderExpressionType exprType;
std::vector<std::size_t> memberIndices;
static inline std::shared_ptr<AccessMember> Build(ExpressionPtr structExpr, std::size_t memberIndex, ShaderExpressionType exprType);
static inline std::shared_ptr<AccessMember> Build(ExpressionPtr structExpr, std::vector<std::size_t> memberIndices, ShaderExpressionType exprType);
};
//////////////////////////////////////////////////////////////////////////
struct NAZARA_SHADER_API AssignOp : public Expression
{
inline AssignOp();
ShaderExpressionType GetExpressionType() const override;
void Visit(ShaderAstVisitor& visitor) override;
AssignType op;
ExpressionPtr left;
ExpressionPtr right;
static inline std::shared_ptr<AssignOp> Build(AssignType op, ExpressionPtr left, ExpressionPtr right);
};
struct NAZARA_SHADER_API BinaryOp : public Expression
{
inline BinaryOp();
ShaderExpressionType GetExpressionType() const override;
void Visit(ShaderAstVisitor& visitor) override;
BinaryType op;
ExpressionPtr left;
ExpressionPtr right;
static inline std::shared_ptr<BinaryOp> Build(BinaryType op, ExpressionPtr left, ExpressionPtr right);
};
struct NAZARA_SHADER_API Branch : public Statement
{
struct ConditionalStatement;
inline Branch();
void Visit(ShaderAstVisitor& visitor) override;
std::vector<ConditionalStatement> condStatements;
StatementPtr elseStatement;
struct ConditionalStatement
{
ExpressionPtr condition;
StatementPtr statement;
};
static inline std::shared_ptr<Branch> Build(ExpressionPtr condition, StatementPtr trueStatement, StatementPtr falseStatement = nullptr);
static inline std::shared_ptr<Branch> Build(std::vector<ConditionalStatement> statements, StatementPtr elseStatement = nullptr);
};
struct NAZARA_SHADER_API Cast : public Expression
{
inline Cast();
ShaderExpressionType GetExpressionType() const override;
void Visit(ShaderAstVisitor& visitor) override;
BasicType exprType;
std::array<ExpressionPtr, 4> expressions;
static inline std::shared_ptr<Cast> Build(BasicType castTo, ExpressionPtr first, ExpressionPtr second = nullptr, ExpressionPtr third = nullptr, ExpressionPtr fourth = nullptr);
static inline std::shared_ptr<Cast> Build(BasicType castTo, ExpressionPtr* expressions, std::size_t expressionCount);
};
struct NAZARA_SHADER_API Constant : public Expression
{
inline Constant();
ShaderExpressionType GetExpressionType() const override;
void Visit(ShaderAstVisitor& visitor) override;
ShaderConstantValue value;
template<typename T> static std::shared_ptr<Constant> Build(const T& value);
};
struct NAZARA_SHADER_API SwizzleOp : public Expression
{
inline SwizzleOp();
ExpressionCategory GetExpressionCategory() const override;
ShaderExpressionType GetExpressionType() const override;
void Visit(ShaderAstVisitor& visitor) override;
std::array<SwizzleComponent, 4> components;
std::size_t componentCount;
ExpressionPtr expression;
static inline std::shared_ptr<SwizzleOp> Build(ExpressionPtr expressionPtr, SwizzleComponent swizzleComponent);
static inline std::shared_ptr<SwizzleOp> Build(ExpressionPtr expressionPtr, std::initializer_list<SwizzleComponent> swizzleComponents);
static inline std::shared_ptr<SwizzleOp> Build(ExpressionPtr expressionPtr, const SwizzleComponent* components, std::size_t componentCount);
};
//////////////////////////////////////////////////////////////////////////
struct NAZARA_SHADER_API Sample2D : public Expression
{
inline Sample2D();
ShaderExpressionType GetExpressionType() const override;
void Visit(ShaderAstVisitor& visitor) override;
ExpressionPtr sampler;
ExpressionPtr coordinates;
static inline std::shared_ptr<Sample2D> Build(ExpressionPtr samplerPtr, ExpressionPtr coordinatesPtr);
};
//////////////////////////////////////////////////////////////////////////
struct NAZARA_SHADER_API IntrinsicCall : public Expression
{
inline IntrinsicCall();
ShaderExpressionType GetExpressionType() const override;
void Visit(ShaderAstVisitor& visitor) override;
IntrinsicType intrinsic;
std::vector<ExpressionPtr> parameters;
static inline std::shared_ptr<IntrinsicCall> Build(IntrinsicType intrinsic, std::vector<ExpressionPtr> parameters);
};
}
}
#include <Nazara/Shader/ShaderNodes.inl>
#endif

View File

@ -0,0 +1,348 @@
// 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/ShaderNodes.hpp>
#include <Nazara/Shader/Debug.hpp>
namespace Nz::ShaderNodes
{
inline Node::Node(NodeType type, bool isStatement) :
m_type(type),
m_isStatement(isStatement)
{
}
inline NodeType ShaderNodes::Node::GetType() const
{
return m_type;
}
inline bool Node::IsStatement() const
{
return m_isStatement;
}
inline unsigned int Node::GetComponentCount(BasicType type)
{
switch (type)
{
case BasicType::Float2:
case BasicType::Int2:
return 2;
case BasicType::Float3:
case BasicType::Int3:
return 3;
case BasicType::Float4:
case BasicType::Int4:
return 4;
case BasicType::Mat4x4:
return 4;
default:
return 1;
}
}
inline BasicType Node::GetComponentType(BasicType type)
{
switch (type)
{
case BasicType::Float2:
case BasicType::Float3:
case BasicType::Float4:
return BasicType::Float1;
case BasicType::Int2:
case BasicType::Int3:
case BasicType::Int4:
return BasicType::Int1;
case BasicType::Mat4x4:
return BasicType::Float4;
default:
return type;
}
}
inline Expression::Expression(NodeType type) :
Node(type, false)
{
}
inline Statement::Statement(NodeType type) :
Node(type, true)
{
}
inline ExpressionStatement::ExpressionStatement() :
Statement(NodeType::ExpressionStatement)
{
}
inline std::shared_ptr<ExpressionStatement> ExpressionStatement::Build(ExpressionPtr expr)
{
auto node = std::make_shared<ExpressionStatement>();
node->expression = std::move(expr);
return node;
}
inline ConditionalStatement::ConditionalStatement() :
Statement(NodeType::ConditionalStatement)
{
}
inline std::shared_ptr<ConditionalStatement> ConditionalStatement::Build(std::string condition, StatementPtr statementPtr)
{
auto node = std::make_shared<ConditionalStatement>();
node->conditionName = std::move(condition);
node->statement = std::move(statementPtr);
return node;
}
inline StatementBlock::StatementBlock() :
Statement(NodeType::StatementBlock)
{
}
inline std::shared_ptr<StatementBlock> StatementBlock::Build(std::vector<StatementPtr> statements)
{
auto node = std::make_shared<StatementBlock>();
node->statements = std::move(statements);
return node;
}
template<typename... Args>
std::shared_ptr<StatementBlock> StatementBlock::Build(Args&&... args)
{
auto node = std::make_shared<StatementBlock>();
node->statements = std::vector<StatementPtr>({ std::forward<Args>(args)... });
return node;
}
inline DeclareVariable::DeclareVariable() :
Statement(NodeType::DeclareVariable)
{
}
inline std::shared_ptr<DeclareVariable> DeclareVariable::Build(VariablePtr variable, ExpressionPtr expression)
{
auto node = std::make_shared<DeclareVariable>();
node->expression = std::move(expression);
node->variable = std::move(variable);
return node;
}
inline Identifier::Identifier() :
Expression(NodeType::Identifier)
{
}
inline std::shared_ptr<Identifier> Identifier::Build(VariablePtr variable)
{
auto node = std::make_shared<Identifier>();
node->var = std::move(variable);
return node;
}
inline AccessMember::AccessMember() :
Expression(NodeType::AccessMember)
{
}
inline std::shared_ptr<AccessMember> AccessMember::Build(ExpressionPtr structExpr, std::size_t memberIndex, ShaderExpressionType exprType)
{
return Build(std::move(structExpr), std::vector<std::size_t>{ memberIndex }, exprType);
}
inline std::shared_ptr<AccessMember> AccessMember::Build(ExpressionPtr structExpr, std::vector<std::size_t> memberIndices, ShaderExpressionType exprType)
{
auto node = std::make_shared<AccessMember>();
node->exprType = std::move(exprType);
node->memberIndices = std::move(memberIndices);
node->structExpr = std::move(structExpr);
return node;
}
inline AssignOp::AssignOp() :
Expression(NodeType::AssignOp)
{
}
inline std::shared_ptr<AssignOp> AssignOp::Build(AssignType op, ExpressionPtr left, ExpressionPtr right)
{
auto node = std::make_shared<AssignOp>();
node->op = op;
node->left = std::move(left);
node->right = std::move(right);
return node;
}
inline BinaryOp::BinaryOp() :
Expression(NodeType::BinaryOp)
{
}
inline std::shared_ptr<BinaryOp> BinaryOp::Build(BinaryType op, ExpressionPtr left, ExpressionPtr right)
{
auto node = std::make_shared<BinaryOp>();
node->op = op;
node->left = std::move(left);
node->right = std::move(right);
return node;
}
inline Branch::Branch() :
Statement(NodeType::Branch)
{
}
inline std::shared_ptr<Branch> Branch::Build(ExpressionPtr condition, StatementPtr trueStatement, StatementPtr falseStatement)
{
auto node = std::make_shared<Branch>();
node->condStatements.emplace_back(ConditionalStatement{ std::move(condition), std::move(trueStatement) });
node->elseStatement = std::move(falseStatement);
return node;
}
inline std::shared_ptr<Branch> Branch::Build(std::vector<ConditionalStatement> statements, StatementPtr elseStatement)
{
auto node = std::make_shared<Branch>();
node->condStatements = std::move(statements);
node->elseStatement = std::move(elseStatement);
return node;
}
inline Cast::Cast() :
Expression(NodeType::Cast)
{
}
inline std::shared_ptr<Cast> Cast::Build(BasicType castTo, ExpressionPtr first, ExpressionPtr second, ExpressionPtr third, ExpressionPtr fourth)
{
auto node = std::make_shared<Cast>();
node->exprType = castTo;
node->expressions = { {first, second, third, fourth} };
return node;
}
inline std::shared_ptr<Cast> Cast::Build(BasicType castTo, ExpressionPtr* Expressions, std::size_t expressionCount)
{
auto node = std::make_shared<Cast>();
node->exprType = castTo;
for (std::size_t i = 0; i < expressionCount; ++i)
node->expressions[i] = Expressions[i];
return node;
}
inline Constant::Constant() :
Expression(NodeType::Constant)
{
}
template<typename T>
std::shared_ptr<Constant> Nz::ShaderNodes::Constant::Build(const T& value)
{
auto node = std::make_shared<Constant>();
node->value = value;
return node;
}
inline SwizzleOp::SwizzleOp() :
Expression(NodeType::SwizzleOp)
{
}
inline std::shared_ptr<SwizzleOp> SwizzleOp::Build(ExpressionPtr expressionPtr, SwizzleComponent swizzleComponent)
{
return Build(std::move(expressionPtr), { swizzleComponent });
}
inline std::shared_ptr<SwizzleOp> SwizzleOp::Build(ExpressionPtr expressionPtr, std::initializer_list<SwizzleComponent> swizzleComponents)
{
auto node = std::make_shared<SwizzleOp>();
node->componentCount = swizzleComponents.size();
node->expression = std::move(expressionPtr);
std::copy(swizzleComponents.begin(), swizzleComponents.end(), node->components.begin());
return node;
}
inline std::shared_ptr<SwizzleOp> SwizzleOp::Build(ExpressionPtr expressionPtr, const SwizzleComponent* components, std::size_t componentCount)
{
auto node = std::make_shared<SwizzleOp>();
assert(componentCount < node->components.size());
node->componentCount = componentCount;
node->expression = std::move(expressionPtr);
std::copy(components, components + componentCount, node->components.begin());
return node;
}
inline Sample2D::Sample2D() :
Expression(NodeType::Sample2D)
{
}
inline std::shared_ptr<Sample2D> Sample2D::Build(ExpressionPtr samplerPtr, ExpressionPtr coordinatesPtr)
{
auto node = std::make_shared<Sample2D>();
node->coordinates = std::move(coordinatesPtr);
node->sampler = std::move(samplerPtr);
return node;
}
inline IntrinsicCall::IntrinsicCall() :
Expression(NodeType::IntrinsicCall)
{
}
inline std::shared_ptr<IntrinsicCall> IntrinsicCall::Build(IntrinsicType intrinsic, std::vector<ExpressionPtr> parameters)
{
auto node = std::make_shared<IntrinsicCall>();
node->intrinsic = intrinsic;
node->parameters = std::move(parameters);
return node;
}
}
#include <Nazara/Shader/DebugOff.hpp>

View File

@ -0,0 +1,35 @@
// Copyright (C) 2015 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_SHADERVARVISITOR_HPP
#define NAZARA_SHADERVARVISITOR_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Shader/Config.hpp>
#include <Nazara/Shader/ShaderVariables.hpp>
namespace Nz
{
class NAZARA_SHADER_API ShaderVarVisitor
{
public:
ShaderVarVisitor() = default;
ShaderVarVisitor(const ShaderVarVisitor&) = delete;
ShaderVarVisitor(ShaderVarVisitor&&) = delete;
virtual ~ShaderVarVisitor();
void Visit(const ShaderNodes::VariablePtr& node);
virtual void Visit(ShaderNodes::BuiltinVariable& var) = 0;
virtual void Visit(ShaderNodes::InputVariable& var) = 0;
virtual void Visit(ShaderNodes::LocalVariable& var) = 0;
virtual void Visit(ShaderNodes::OutputVariable& var) = 0;
virtual void Visit(ShaderNodes::ParameterVariable& var) = 0;
virtual void Visit(ShaderNodes::UniformVariable& var) = 0;
};
}
#endif

View File

@ -0,0 +1,28 @@
// Copyright (C) 2015 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_SHADERVARVISITOREXCEPT_HPP
#define NAZARA_SHADERVARVISITOREXCEPT_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Shader/ShaderVarVisitor.hpp>
namespace Nz
{
class NAZARA_SHADER_API ShaderVarVisitorExcept : public ShaderVarVisitor
{
public:
using ShaderVarVisitor::Visit;
void Visit(ShaderNodes::BuiltinVariable& var) override;
void Visit(ShaderNodes::InputVariable& var) override;
void Visit(ShaderNodes::LocalVariable& var) override;
void Visit(ShaderNodes::OutputVariable& var) override;
void Visit(ShaderNodes::ParameterVariable& var) override;
void Visit(ShaderNodes::UniformVariable& var) override;
};
}
#endif

View File

@ -0,0 +1,128 @@
// 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_SHADER_VARIABLES_HPP
#define NAZARA_SHADER_VARIABLES_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Math/Vector2.hpp>
#include <Nazara/Math/Vector3.hpp>
#include <Nazara/Math/Vector4.hpp>
#include <Nazara/Shader/Config.hpp>
#include <Nazara/Shader/ShaderExpressionType.hpp>
#include <array>
#include <memory>
#include <optional>
#include <string>
namespace Nz
{
class ShaderVarVisitor;
namespace ShaderNodes
{
struct Variable;
using VariablePtr = std::shared_ptr<Variable>;
struct NAZARA_SHADER_API Variable : std::enable_shared_from_this<Variable>
{
virtual ~Variable();
virtual VariableType GetType() const = 0;
virtual void Visit(ShaderVarVisitor& visitor) = 0;
ShaderExpressionType type;
};
struct BuiltinVariable;
using BuiltinVariablePtr = std::shared_ptr<BuiltinVariable>;
struct NAZARA_SHADER_API BuiltinVariable : public Variable
{
BuiltinEntry entry;
VariableType GetType() const override;
void Visit(ShaderVarVisitor& visitor) override;
static inline std::shared_ptr<BuiltinVariable> Build(BuiltinEntry entry, ShaderExpressionType varType);
};
struct NamedVariable;
using NamedVariablePtr = std::shared_ptr<NamedVariable>;
struct NAZARA_SHADER_API NamedVariable : public Variable
{
std::string name;
};
struct InputVariable;
using InputVariablePtr = std::shared_ptr<InputVariable>;
struct NAZARA_SHADER_API InputVariable : public NamedVariable
{
VariableType GetType() const override;
void Visit(ShaderVarVisitor& visitor) override;
static inline std::shared_ptr<InputVariable> Build(std::string varName, ShaderExpressionType varType);
};
struct LocalVariable;
using LocalVariablePtr = std::shared_ptr<LocalVariable>;
struct NAZARA_SHADER_API LocalVariable : public NamedVariable
{
VariableType GetType() const override;
void Visit(ShaderVarVisitor& visitor) override;
static inline std::shared_ptr<LocalVariable> Build(std::string varName, ShaderExpressionType varType);
};
struct OutputVariable;
using OutputVariablePtr = std::shared_ptr<OutputVariable>;
struct NAZARA_SHADER_API OutputVariable : public NamedVariable
{
VariableType GetType() const override;
void Visit(ShaderVarVisitor& visitor) override;
static inline std::shared_ptr<OutputVariable> Build(std::string varName, ShaderExpressionType varType);
};
struct ParameterVariable;
using ParameterVariablePtr = std::shared_ptr<ParameterVariable>;
struct NAZARA_SHADER_API ParameterVariable : public NamedVariable
{
VariableType GetType() const override;
void Visit(ShaderVarVisitor& visitor) override;
static inline std::shared_ptr<ParameterVariable> Build(std::string varName, ShaderExpressionType varType);
};
struct UniformVariable;
using UniformVariablePtr = std::shared_ptr<UniformVariable>;
struct NAZARA_SHADER_API UniformVariable : public NamedVariable
{
VariableType GetType() const override;
void Visit(ShaderVarVisitor& visitor) override;
static inline std::shared_ptr<UniformVariable> Build(std::string varName, ShaderExpressionType varType);
};
}
}
#include <Nazara/Shader/ShaderVariables.inl>
#endif

View File

@ -0,0 +1,65 @@
// 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/ShaderVariables.hpp>
#include <Nazara/Shader/Debug.hpp>
namespace Nz::ShaderNodes
{
inline std::shared_ptr<BuiltinVariable> BuiltinVariable::Build(BuiltinEntry variable, ShaderExpressionType varType)
{
auto node = std::make_shared<BuiltinVariable>();
node->entry = variable;
node->type = varType;
return node;
}
inline std::shared_ptr<InputVariable> InputVariable::Build(std::string varName, ShaderExpressionType varType)
{
auto node = std::make_shared<InputVariable>();
node->name = std::move(varName);
node->type = varType;
return node;
}
inline std::shared_ptr<LocalVariable> LocalVariable::Build(std::string varName, ShaderExpressionType varType)
{
auto node = std::make_shared<LocalVariable>();
node->name = std::move(varName);
node->type = varType;
return node;
}
inline std::shared_ptr<OutputVariable> OutputVariable::Build(std::string varName, ShaderExpressionType varType)
{
auto node = std::make_shared<OutputVariable>();
node->name = std::move(varName);
node->type = varType;
return node;
}
inline std::shared_ptr<ParameterVariable> ParameterVariable::Build(std::string varName, ShaderExpressionType varType)
{
auto node = std::make_shared<ParameterVariable>();
node->name = std::move(varName);
node->type = varType;
return node;
}
inline std::shared_ptr<UniformVariable> UniformVariable::Build(std::string varName, ShaderExpressionType varType)
{
auto node = std::make_shared<UniformVariable>();
node->name = std::move(varName);
node->type = varType;
return node;
}
}
#include <Nazara/Shader/DebugOff.hpp>

View File

@ -0,0 +1,30 @@
// Copyright (C) 2015 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_SHADERWRITER_HPP
#define NAZARA_SHADERWRITER_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Shader/Config.hpp>
#include <string>
namespace Nz
{
class ShaderAst;
class NAZARA_SHADER_API ShaderWriter
{
public:
ShaderWriter() = default;
ShaderWriter(const ShaderWriter&) = default;
ShaderWriter(ShaderWriter&&) = default;
virtual ~ShaderWriter();
virtual std::string Generate(const ShaderAst& shader) = 0;
};
}
#endif // NAZARA_SHADERWRITER_HPP

View File

@ -0,0 +1,58 @@
// 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_SPIRVEXPRESSIONLOAD_HPP
#define NAZARA_SPIRVEXPRESSIONLOAD_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Shader/Config.hpp>
#include <Nazara/Shader/ShaderAstVisitorExcept.hpp>
#include <Nazara/Shader/ShaderVarVisitorExcept.hpp>
#include <vector>
namespace Nz
{
class SpirvWriter;
class NAZARA_SHADER_API SpirvAstVisitor : public ShaderAstVisitorExcept
{
public:
inline SpirvAstVisitor(SpirvWriter& writer);
SpirvAstVisitor(const SpirvAstVisitor&) = delete;
SpirvAstVisitor(SpirvAstVisitor&&) = delete;
~SpirvAstVisitor() = default;
UInt32 EvaluateExpression(const ShaderNodes::ExpressionPtr& expr);
using ShaderAstVisitorExcept::Visit;
void Visit(ShaderNodes::AccessMember& node) override;
void Visit(ShaderNodes::AssignOp& node) override;
void Visit(ShaderNodes::BinaryOp& node) override;
void Visit(ShaderNodes::Cast& node) override;
void Visit(ShaderNodes::Constant& node) override;
void Visit(ShaderNodes::DeclareVariable& node) override;
void Visit(ShaderNodes::ExpressionStatement& node) override;
void Visit(ShaderNodes::Identifier& node) override;
void Visit(ShaderNodes::IntrinsicCall& node) override;
void Visit(ShaderNodes::Sample2D& node) override;
void Visit(ShaderNodes::StatementBlock& node) override;
void Visit(ShaderNodes::SwizzleOp& node) override;
SpirvAstVisitor& operator=(const SpirvAstVisitor&) = delete;
SpirvAstVisitor& operator=(SpirvAstVisitor&&) = delete;
private:
void PushResultId(UInt32 value);
UInt32 PopResultId();
std::vector<UInt32> m_resultIds;
SpirvWriter& m_writer;
};
}
#include <Nazara/Shader/SpirvAstVisitor.inl>
#endif

View File

@ -0,0 +1,16 @@
// 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/SpirvAstVisitor.hpp>
#include <Nazara/Shader/Debug.hpp>
namespace Nz
{
inline SpirvAstVisitor::SpirvAstVisitor(SpirvWriter& writer) :
m_writer(writer)
{
}
}
#include <Nazara/Shader/DebugOff.hpp>

View File

@ -0,0 +1,197 @@
// 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_SPIRVCONSTANTCACHE_HPP
#define NAZARA_SPIRVCONSTANTCACHE_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Shader/ShaderConstantValue.hpp>
#include <Nazara/Shader/ShaderEnums.hpp>
#include <Nazara/Shader/ShaderExpressionType.hpp>
#include <Nazara/Shader/SpirvData.hpp>
#include <memory>
#include <optional>
#include <string>
#include <variant>
#include <vector>
namespace Nz
{
class ShaderAst;
class SpirvSection;
class NAZARA_SHADER_API SpirvConstantCache
{
public:
SpirvConstantCache(UInt32& resultId);
SpirvConstantCache(const SpirvConstantCache& cache) = delete;
SpirvConstantCache(SpirvConstantCache&& cache) noexcept;
~SpirvConstantCache();
struct Constant;
struct Type;
using ConstantPtr = std::shared_ptr<Constant>;
using TypePtr = std::shared_ptr<Type>;
struct Bool {};
struct Float
{
UInt32 width;
};
struct Integer
{
UInt32 width;
bool signedness;
};
struct Void {};
struct Vector
{
TypePtr componentType;
UInt32 componentCount;
};
struct Matrix
{
TypePtr columnType;
UInt32 columnCount;
};
struct Image
{
std::optional<SpirvAccessQualifier> qualifier;
std::optional<bool> depth;
std::optional<bool> sampled;
SpirvDim dim;
SpirvImageFormat format;
TypePtr sampledType;
bool arrayed;
bool multisampled;
};
struct Pointer
{
TypePtr type;
SpirvStorageClass storageClass;
};
struct Function
{
TypePtr returnType;
std::vector<TypePtr> parameters;
};
struct SampledImage
{
TypePtr image;
};
struct Structure
{
struct Member
{
std::string name;
TypePtr type;
};
std::string name;
std::vector<Member> members;
};
using AnyType = std::variant<Bool, Float, Function, Image, Integer, Matrix, Pointer, SampledImage, Structure, Vector, Void>;
struct ConstantBool
{
bool value;
};
struct ConstantComposite
{
TypePtr type;
std::vector<ConstantPtr> values;
};
struct ConstantScalar
{
std::variant<float, double, Nz::Int32, Nz::Int64, Nz::UInt32, Nz::UInt64> value;
};
using AnyConstant = std::variant<ConstantBool, ConstantComposite, ConstantScalar>;
struct Variable
{
std::string debugName;
TypePtr type;
SpirvStorageClass storageClass;
std::optional<ConstantPtr> initializer;
};
using BaseType = std::variant<Bool, Float, Integer, Vector, Matrix, Image>;
using CompositeValue = std::variant<ConstantBool, ConstantScalar, ConstantComposite>;
using PointerOrBaseType = std::variant<BaseType, Pointer>;
using PrimitiveType = std::variant<Bool, Float, Integer>;
using ScalarType = std::variant<Float, Integer>;
struct Constant
{
Constant(AnyConstant c) :
constant(std::move(c))
{
}
AnyConstant constant;
};
struct Type
{
Type(AnyType c) :
type(std::move(c))
{
}
AnyType type;
};
UInt32 GetId(const Constant& c);
UInt32 GetId(const Type& t);
UInt32 GetId(const Variable& v);
UInt32 Register(Constant c);
UInt32 Register(Type t);
UInt32 Register(Variable v);
void Write(SpirvSection& annotations, SpirvSection& constants, SpirvSection& debugInfos);
SpirvConstantCache& operator=(const SpirvConstantCache& cache) = delete;
SpirvConstantCache& operator=(SpirvConstantCache&& cache) noexcept;
static ConstantPtr BuildConstant(const ShaderConstantValue& value);
static TypePtr BuildPointerType(const ShaderNodes::BasicType& type, SpirvStorageClass storageClass);
static TypePtr BuildPointerType(const ShaderAst& shader, const ShaderExpressionType& type, SpirvStorageClass storageClass);
static TypePtr BuildType(const ShaderNodes::BasicType& type);
static TypePtr BuildType(const ShaderAst& shader, const ShaderExpressionType& type);
private:
struct DepRegisterer;
struct Eq;
struct Internal;
void Write(const AnyConstant& constant, UInt32 resultId, SpirvSection& constants);
void Write(const AnyType& type, UInt32 resultId, SpirvSection& annotations, SpirvSection& constants, SpirvSection& debugInfos);
void WriteStruct(const Structure& structData, UInt32 resultId, SpirvSection& annotations, SpirvSection& constants, SpirvSection& debugInfos);
std::unique_ptr<Internal> m_internal;
};
}
#include <Nazara/Shader/SpirvConstantCache.inl>
#endif

View File

@ -0,0 +1,12 @@
// 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/SpirvConstantCache.hpp>
#include <Nazara/Shader/Debug.hpp>
namespace Nz
{
}
#include <Nazara/Shader/DebugOff.hpp>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,63 @@
// 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_SPIRVEXPRESSIONLOADACCESSMEMBER_HPP
#define NAZARA_SPIRVEXPRESSIONLOADACCESSMEMBER_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Shader/Config.hpp>
#include <Nazara/Shader/ShaderAstVisitorExcept.hpp>
#include <Nazara/Shader/ShaderVarVisitorExcept.hpp>
#include <Nazara/Shader/SpirvData.hpp>
#include <vector>
namespace Nz
{
class SpirvWriter;
class NAZARA_SHADER_API SpirvExpressionLoad : public ShaderAstVisitorExcept, public ShaderVarVisitorExcept
{
public:
inline SpirvExpressionLoad(SpirvWriter& writer);
SpirvExpressionLoad(const SpirvExpressionLoad&) = delete;
SpirvExpressionLoad(SpirvExpressionLoad&&) = delete;
~SpirvExpressionLoad() = default;
UInt32 Evaluate(ShaderNodes::Expression& node);
using ShaderAstVisitor::Visit;
void Visit(ShaderNodes::AccessMember& node) override;
void Visit(ShaderNodes::Identifier& node) override;
using ShaderVarVisitor::Visit;
void Visit(ShaderNodes::InputVariable& var) override;
void Visit(ShaderNodes::LocalVariable& var) override;
void Visit(ShaderNodes::UniformVariable& var) override;
SpirvExpressionLoad& operator=(const SpirvExpressionLoad&) = delete;
SpirvExpressionLoad& operator=(SpirvExpressionLoad&&) = delete;
private:
struct Pointer
{
SpirvStorageClass storage;
UInt32 resultId;
UInt32 pointedTypeId;
};
struct Value
{
UInt32 resultId;
};
SpirvWriter& m_writer;
std::variant<std::monostate, Pointer, Value> m_value;
};
}
#include <Nazara/Shader/SpirvExpressionLoad.inl>
#endif

View File

@ -0,0 +1,16 @@
// 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/SpirvExpressionLoad.hpp>
#include <Nazara/Shader/Debug.hpp>
namespace Nz
{
inline SpirvExpressionLoad::SpirvExpressionLoad(SpirvWriter& writer) :
m_writer(writer)
{
}
}
#include <Nazara/Shader/DebugOff.hpp>

View File

@ -0,0 +1,63 @@
// 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_SPIRVEXPRESSIONSTORE_HPP
#define NAZARA_SPIRVEXPRESSIONSTORE_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Shader/Config.hpp>
#include <Nazara/Shader/ShaderAstVisitorExcept.hpp>
#include <Nazara/Shader/ShaderVarVisitorExcept.hpp>
#include <Nazara/Shader/SpirvData.hpp>
namespace Nz
{
class SpirvSection;
class SpirvWriter;
class NAZARA_SHADER_API SpirvExpressionStore : public ShaderAstVisitorExcept, public ShaderVarVisitorExcept
{
public:
inline SpirvExpressionStore(SpirvWriter& writer);
SpirvExpressionStore(const SpirvExpressionStore&) = delete;
SpirvExpressionStore(SpirvExpressionStore&&) = delete;
~SpirvExpressionStore() = default;
void Store(const ShaderNodes::ExpressionPtr& node, UInt32 resultId);
using ShaderAstVisitorExcept::Visit;
void Visit(ShaderNodes::AccessMember& node) override;
void Visit(ShaderNodes::Identifier& node) override;
void Visit(ShaderNodes::SwizzleOp& node) override;
using ShaderVarVisitorExcept::Visit;
void Visit(ShaderNodes::BuiltinVariable& var) override;
void Visit(ShaderNodes::LocalVariable& var) override;
void Visit(ShaderNodes::OutputVariable& var) override;
SpirvExpressionStore& operator=(const SpirvExpressionStore&) = delete;
SpirvExpressionStore& operator=(SpirvExpressionStore&&) = delete;
private:
struct LocalVar
{
std::string varName;
};
struct Pointer
{
SpirvStorageClass storage;
UInt32 resultId;
};
SpirvWriter& m_writer;
std::variant<std::monostate, LocalVar, Pointer> m_value;
};
}
#include <Nazara/Shader/SpirvExpressionStore.inl>
#endif

View File

@ -0,0 +1,16 @@
// 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/SpirvExpressionStore.hpp>
#include <Nazara/Shader/Debug.hpp>
namespace Nz
{
inline SpirvExpressionStore::SpirvExpressionStore(SpirvWriter& writer) :
m_writer(writer)
{
}
}
#include <Nazara/Shader/DebugOff.hpp>

View File

@ -0,0 +1,50 @@
// 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_SPIRVPRINTER_HPP
#define NAZARA_SPIRVPRINTER_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Shader/Config.hpp>
#include <string>
namespace Nz
{
class NAZARA_SHADER_API SpirvPrinter
{
public:
struct Settings;
inline SpirvPrinter();
SpirvPrinter(const SpirvPrinter&) = default;
SpirvPrinter(SpirvPrinter&&) = default;
~SpirvPrinter() = default;
std::string Print(const UInt32* codepoints, std::size_t count, const Settings& settings = Settings());
SpirvPrinter& operator=(const SpirvPrinter&) = default;
SpirvPrinter& operator=(SpirvPrinter&&) = default;
struct Settings
{
bool printHeader = true;
bool printParameters = true;
};
private:
void AppendInstruction();
std::string ReadString();
UInt32 ReadWord();
struct State;
State* m_currentState;
};
}
#include <Nazara/Shader/SpirvPrinter.inl>
#endif

View File

@ -0,0 +1,16 @@
// 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/SpirvPrinter.hpp>
#include <Nazara/Shader/Debug.hpp>
namespace Nz
{
inline SpirvPrinter::SpirvPrinter() :
m_currentState(nullptr)
{
}
}
#include <Nazara/Shader/DebugOff.hpp>

View File

@ -0,0 +1,73 @@
// 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_SPIRVSECTION_HPP
#define NAZARA_SPIRVSECTION_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Shader/ShaderEnums.hpp>
#include <Nazara/Shader/SpirvData.hpp>
#include <string>
#include <vector>
namespace Nz
{
class NAZARA_SHADER_API SpirvSection
{
public:
struct OpSize;
struct Raw;
SpirvSection() = default;
SpirvSection(const SpirvSection& cache) = default;
SpirvSection(SpirvSection&& cache) = default;
~SpirvSection() = default;
inline std::size_t Append(const char* str);
inline std::size_t Append(const std::string_view& str);
inline std::size_t Append(const std::string& str);
inline std::size_t Append(UInt32 value);
inline std::size_t Append(SpirvOp opcode, const OpSize& wordCount);
std::size_t Append(const Raw& raw);
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 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 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;
struct OpSize
{
unsigned int wc;
};
struct Raw
{
const void* ptr;
std::size_t size;
};
static inline UInt32 BuildOpcode(SpirvOp opcode, unsigned int wordCount);
private:
std::vector<UInt32> m_bytecode;
};
}
#include <Nazara/Shader/SpirvSection.inl>
#endif

View File

@ -0,0 +1,146 @@
// 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/SpirvSection.hpp>
#include <Nazara/Shader/Debug.hpp>
namespace Nz
{
inline std::size_t SpirvSection::Append(const char* str)
{
return Append(std::string_view(str));
}
inline std::size_t SpirvSection::Append(const std::string_view& str)
{
std::size_t offset = GetOutputOffset();
std::size_t size4 = CountWord(str);
for (std::size_t i = 0; i < size4; ++i)
{
UInt32 codepoint = 0;
for (std::size_t j = 0; j < 4; ++j)
{
std::size_t pos = i * 4 + j;
if (pos < str.size())
codepoint |= UInt32(str[pos]) << (j * 8);
}
Append(codepoint);
}
return offset;
}
inline std::size_t SpirvSection::Append(const std::string& str)
{
return Append(std::string_view(str));
}
inline std::size_t SpirvSection::Append(UInt32 value)
{
std::size_t offset = GetOutputOffset();
m_bytecode.push_back(value);
return offset;
}
inline std::size_t SpirvSection::Append(SpirvOp opcode, const OpSize& wordCount)
{
return Append(BuildOpcode(opcode, wordCount.wc));
}
inline std::size_t SpirvSection::Append(std::initializer_list<UInt32> codepoints)
{
std::size_t offset = GetOutputOffset();
for (UInt32 cp : codepoints)
Append(cp);
return offset;
}
template<typename ...Args>
std::size_t SpirvSection::Append(SpirvOp opcode, const Args&... args)
{
unsigned int wordCount = 1 + (CountWord(args) + ... + 0);
std::size_t offset = Append(opcode, OpSize{ wordCount });
if constexpr (sizeof...(args) > 0)
(Append(args), ...);
return offset;
}
template<typename F> std::size_t SpirvSection::AppendVariadic(SpirvOp opcode, F&& callback)
{
std::size_t offset = Append(0); //< Will be filled later
unsigned int wordCount = 1;
auto appendFunctor = [&](const auto& value)
{
wordCount += CountWord(value);
Append(value);
};
callback(appendFunctor);
m_bytecode[offset] = BuildOpcode(opcode, wordCount);
return offset;
}
template<typename T>
std::size_t SpirvSection::Append(T value)
{
return Append(static_cast<UInt32>(value));
}
template<typename T>
unsigned int SpirvSection::CountWord(const T& /*value*/)
{
return 1;
}
template<typename T1, typename T2, typename ...Args>
unsigned int SpirvSection::CountWord(const T1& value, const T2& value2, const Args&... rest)
{
return CountWord(value) + CountWord(value2) + (CountWord(rest) + ...);
}
inline unsigned int SpirvSection::CountWord(const char* str)
{
return CountWord(std::string_view(str));
}
inline unsigned int Nz::SpirvSection::CountWord(const std::string& str)
{
return CountWord(std::string_view(str));
}
inline unsigned int SpirvSection::CountWord(const Raw& raw)
{
return static_cast<unsigned int>((raw.size + sizeof(UInt32) - 1) / sizeof(UInt32));
}
inline unsigned int SpirvSection::CountWord(const std::string_view& str)
{
return (static_cast<unsigned int>(str.size() + 1) + sizeof(UInt32) - 1) / sizeof(UInt32); //< + 1 for null character
}
inline const std::vector<UInt32>& SpirvSection::GetBytecode() const
{
return m_bytecode;
}
inline std::size_t SpirvSection::GetOutputOffset() const
{
return m_bytecode.size();
}
inline UInt32 SpirvSection::BuildOpcode(SpirvOp opcode, unsigned int wordCount)
{
return UInt32(opcode) | UInt32(wordCount) << 16;
}
}
#include <Nazara/Shader/DebugOff.hpp>

View File

@ -0,0 +1,111 @@
// 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_SPIRVWRITER_HPP
#define NAZARA_SPIRVWRITER_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Shader/Config.hpp>
#include <Nazara/Shader/ShaderAst.hpp>
#include <Nazara/Shader/ShaderAstVisitor.hpp>
#include <Nazara/Shader/ShaderConstantValue.hpp>
#include <Nazara/Shader/ShaderVarVisitor.hpp>
#include <Nazara/Shader/ShaderWriter.hpp>
#include <Nazara/Shader/SpirvConstantCache.hpp>
#include <string>
#include <string_view>
#include <unordered_map>
namespace Nz
{
class SpirvSection;
class NAZARA_SHADER_API SpirvWriter
{
friend class SpirvAstVisitor;
friend class SpirvExpressionLoad;
friend class SpirvExpressionStore;
friend class SpirvVisitor;
public:
struct Environment;
SpirvWriter();
SpirvWriter(const SpirvWriter&) = delete;
SpirvWriter(SpirvWriter&&) = delete;
~SpirvWriter() = default;
std::vector<UInt32> Generate(const ShaderAst& shader);
void SetEnv(Environment environment);
struct Environment
{
UInt32 spvMajorVersion = 1;
UInt32 spvMinorVersion = 0;
};
private:
struct ExtVar;
struct OnlyCache {};
UInt32 AllocateResultId();
void AppendHeader();
UInt32 GetConstantId(const ShaderConstantValue& value) const;
UInt32 GetFunctionTypeId(ShaderExpressionType retType, const std::vector<ShaderAst::FunctionParameter>& parameters);
const ExtVar& GetBuiltinVariable(ShaderNodes::BuiltinEntry builtin) const;
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;
UInt32 ReadInputVariable(const std::string& name);
std::optional<UInt32> ReadInputVariable(const std::string& name, OnlyCache);
UInt32 ReadLocalVariable(const std::string& name);
std::optional<UInt32> ReadLocalVariable(const std::string& name, OnlyCache);
UInt32 ReadUniformVariable(const std::string& name);
std::optional<UInt32> ReadUniformVariable(const std::string& name, OnlyCache);
UInt32 ReadVariable(ExtVar& var);
std::optional<UInt32> ReadVariable(const ExtVar& var, OnlyCache);
UInt32 RegisterConstant(const ShaderConstantValue& value);
UInt32 RegisterFunctionType(ShaderExpressionType retType, const std::vector<ShaderAst::FunctionParameter>& parameters);
UInt32 RegisterPointerType(ShaderExpressionType type, SpirvStorageClass storageClass);
UInt32 RegisterType(ShaderExpressionType type);
void WriteLocalVariable(std::string name, UInt32 resultId);
static void MergeBlocks(std::vector<UInt32>& output, const SpirvSection& from);
struct Context
{
const ShaderAst* shader = nullptr;
const ShaderAst::Function* currentFunction = nullptr;
};
struct ExtVar
{
UInt32 pointerTypeId;
UInt32 typeId;
UInt32 varId;
std::optional<UInt32> valueId;
};
struct State;
Context m_context;
Environment m_environment;
State* m_currentState;
};
}
#include <Nazara/Shader/SpirvWriter.inl>
#endif

View File

@ -0,0 +1,12 @@
// 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/SpirvWriter.hpp>
#include <Nazara/Shader/Debug.hpp>
namespace Nz
{
}
#include <Nazara/Shader/DebugOff.hpp>

View File

@ -40,6 +40,7 @@
#include <Nazara/Utility/Config.hpp> #include <Nazara/Utility/Config.hpp>
#include <Nazara/Utility/CubemapParams.hpp> #include <Nazara/Utility/CubemapParams.hpp>
#include <Nazara/Utility/Enums.hpp> #include <Nazara/Utility/Enums.hpp>
#include <Nazara/Utility/FieldOffsets.hpp>
#include <Nazara/Utility/Font.hpp> #include <Nazara/Utility/Font.hpp>
#include <Nazara/Utility/FontData.hpp> #include <Nazara/Utility/FontData.hpp>
#include <Nazara/Utility/FontGlyph.hpp> #include <Nazara/Utility/FontGlyph.hpp>

View File

@ -309,6 +309,58 @@ namespace Nz
SamplerWrap_Max = SamplerWrap_Repeat SamplerWrap_Max = SamplerWrap_Repeat
}; };
enum class ShaderStageType
{
Fragment,
Vertex,
Max = Vertex
};
template<>
struct EnumAsFlags<ShaderStageType>
{
static constexpr ShaderStageType max = ShaderStageType::Max;
};
using ShaderStageTypeFlags = Flags<ShaderStageType>;
constexpr ShaderStageTypeFlags ShaderStageType_All = ShaderStageType::Fragment | ShaderStageType::Vertex;
enum StructFieldType
{
StructFieldType_Bool1,
StructFieldType_Bool2,
StructFieldType_Bool3,
StructFieldType_Bool4,
StructFieldType_Float1,
StructFieldType_Float2,
StructFieldType_Float3,
StructFieldType_Float4,
StructFieldType_Double1,
StructFieldType_Double2,
StructFieldType_Double3,
StructFieldType_Double4,
StructFieldType_Int1,
StructFieldType_Int2,
StructFieldType_Int3,
StructFieldType_Int4,
StructFieldType_UInt1,
StructFieldType_UInt2,
StructFieldType_UInt3,
StructFieldType_UInt4,
StructFieldType_Max = StructFieldType_UInt4
};
enum StructLayout
{
StructLayout_Packed,
StructLayout_Std140,
StructLayout_Max = StructLayout_Std140
};
enum StencilOperation enum StencilOperation
{ {
StencilOperation_Decrement, StencilOperation_Decrement,

View File

@ -0,0 +1,52 @@
// Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - Utility module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_FIELDOFFSETS_HPP
#define NAZARA_FIELDOFFSETS_HPP
#include <Nazara/Utility/Config.hpp>
#include <Nazara/Utility/Enums.hpp>
namespace Nz
{
class NAZARA_UTILITY_API FieldOffsets
{
public:
inline FieldOffsets(StructLayout layout);
FieldOffsets(const FieldOffsets&) = default;
FieldOffsets(FieldOffsets&&) = default;
~FieldOffsets() = default;
std::size_t AddField(StructFieldType type);
std::size_t AddFieldArray(StructFieldType type, std::size_t arraySize);
std::size_t AddMatrix(StructFieldType cellType, unsigned int columns, unsigned int rows, bool columnMajor);
std::size_t AddMatrixArray(StructFieldType cellType, unsigned int columns, unsigned int rows, bool columnMajor, std::size_t arraySize);
std::size_t AddStruct(const FieldOffsets& fieldStruct);
std::size_t AddStructArray(const FieldOffsets& fieldStruct, std::size_t arraySize);
inline std::size_t GetLargestFieldAlignement() const;
inline std::size_t GetSize() const;
FieldOffsets& operator=(const FieldOffsets&) = default;
FieldOffsets& operator=(FieldOffsets&&) = default;
static std::size_t GetAlignement(StructLayout layout, StructFieldType fieldType);
static std::size_t GetCount(StructFieldType fieldType);
static std::size_t GetSize(StructFieldType fieldType);
private:
static inline std::size_t Align(std::size_t source, std::size_t alignment);
std::size_t m_largestFieldAlignment;
std::size_t m_offsetRounding;
std::size_t m_size;
StructLayout m_layout;
};
}
#include <Nazara/Utility/FieldOffsets.inl>
#endif // NAZARA_FIELDOFFSETS_HPP

Some files were not shown because too many files have changed in this diff Show More