diff --git a/bin/resources/Shader.glsl.binding.json b/bin/resources/Shader.glsl.binding.json
new file mode 100644
index 0000000..c6780d4
--- /dev/null
+++ b/bin/resources/Shader.glsl.binding.json
@@ -0,0 +1,10 @@
+{
+ "bindings": [
+ {
+ "set": 0,
+ "binding": 0,
+ "glsl_binding": 0
+ }
+ ],
+ "push_constant_binding": 1
+}
\ No newline at end of file
diff --git a/bin/resources/Shader.nzsl b/bin/resources/Shader.nzsl
index 8fbdcd5..a719d7c 100644
--- a/bin/resources/Shader.nzsl
+++ b/bin/resources/Shader.nzsl
@@ -8,6 +8,17 @@ import GetColor as Color from Color;
import * from DataStruct;
import * from OutputStruct;
+[layout(std140)]
+struct PushConstants
+{
+ color: vec4[f32]
+}
+
+external ExternalResources
+{
+ constants: push_constant[PushConstants]
+}
+
[entry(frag)]
fn main() -> Output
{
@@ -15,7 +26,7 @@ fn main() -> Output
data.color = Color();
let output: Output;
- output.color = GetColorFromData(data);
+ output.color = GetColorFromData(data) * ExternalResources.constants.color;
return output;
}
diff --git a/include/CNZSL/GlslWriter.h b/include/CNZSL/GlslWriter.h
index 7d7e6ed..0b940a9 100644
--- a/include/CNZSL/GlslWriter.h
+++ b/include/CNZSL/GlslWriter.h
@@ -21,7 +21,7 @@ extern "C"
#endif
typedef struct nzslGlslWriter nzslGlslWriter;
-typedef struct nzslGlslBindingMapping nzslGlslBindingMapping;
+typedef struct nzslGlslWriterParameters nzslGlslWriterParameters;
typedef struct nzslGlslOutput nzslGlslOutput;
typedef struct
@@ -34,16 +34,17 @@ typedef struct
int allowDrawParametersUniformsFallback;
} nzslGlslWriterEnvironment;
-CNZSL_API nzslGlslBindingMapping* nzslGlslBindingMappingCreate(void);
-CNZSL_API void nzslGlslBindingMappingDestroy(nzslGlslBindingMapping* bindingMappingPtr);
+CNZSL_API nzslGlslWriterParameters* nzslGlslWriterParametersCreate(void);
+CNZSL_API void nzslGlslWriterParametersDestroy(nzslGlslWriterParameters* parameterPtr);
-CNZSL_API void nzslGlslBindingMappingSetBinding(nzslGlslBindingMapping* bindingMappingPtr, uint32_t setIndex, uint32_t bindingIndex, unsigned int glBinding);
+CNZSL_API void nzslGlslWriterParametersSetBindingMapping(nzslGlslWriterParameters* parameterPtr, uint32_t setIndex, uint32_t bindingIndex, unsigned int glBinding);
+CNZSL_API void nzslGlslWriterParametersSetPushConstantBinding(nzslGlslWriterParameters* parameterPtr, unsigned int glBinding);
+CNZSL_API void nzslGlslWriterParametersSetShaderStage(nzslGlslWriterParameters* parameterPtr, nzslShaderStageType stage);
CNZSL_API nzslGlslWriter* nzslGlslWriterCreate(void);
CNZSL_API void nzslGlslWriterDestroy(nzslGlslWriter* writerPtr);
-CNZSL_API nzslGlslOutput* nzslGlslWriterGenerate(nzslGlslWriter* writerPtr, const nzslModule* modulePtr, const nzslGlslBindingMapping* bindingMapping, const nzslWriterStates* statesPtr);
-CNZSL_API nzslGlslOutput* nzslGlslWriterGenerateStage(nzslShaderStageType stage, nzslGlslWriter* writerPtr, const nzslModule* modulePtr, const nzslGlslBindingMapping* bindingMapping, const nzslWriterStates* statesPtr);
+CNZSL_API nzslGlslOutput* nzslGlslWriterGenerate(nzslGlslWriter* writerPtr, const nzslModule* modulePtr, const nzslGlslWriterParameters* parameterPtr, const nzslWriterStates* statesPtr);
/**
** Gets the last error message set by the last operation to this writer
diff --git a/include/NZSL/GlslWriter.hpp b/include/NZSL/GlslWriter.hpp
index 092a765..5855d4d 100644
--- a/include/NZSL/GlslWriter.hpp
+++ b/include/NZSL/GlslWriter.hpp
@@ -23,18 +23,17 @@ namespace nzsl
class NZSL_API GlslWriter : public ShaderWriter, public Ast::ExpressionVisitorExcept, public Ast::StatementVisitorExcept
{
public:
- using BindingMapping = std::unordered_map;
using ExtSupportCallback = std::function;
struct Environment;
struct Output;
+ struct Parameters;
inline GlslWriter();
GlslWriter(const GlslWriter&) = delete;
GlslWriter(GlslWriter&&) = delete;
~GlslWriter() = default;
- inline Output Generate(const Ast::Module& module, const BindingMapping& bindingMapping = {}, const States& states = {});
- Output Generate(std::optional shaderStage, const Ast::Module& module, const BindingMapping& bindingMapping = {}, const States& states = {});
+ Output Generate(const Ast::Module& module, const Parameters& parameters = {}, const States& states = {});
void SetEnv(Environment environment);
@@ -49,6 +48,13 @@ namespace nzsl
bool allowDrawParametersUniformsFallback = false;
};
+ struct Parameters
+ {
+ std::optional pushConstantBinding;
+ std::optional shaderStage;
+ std::unordered_map bindingMapping;
+ };
+
struct Output
{
std::string code;
diff --git a/include/NZSL/GlslWriter.inl b/include/NZSL/GlslWriter.inl
index 7d2dfa1..0675cc6 100644
--- a/include/NZSL/GlslWriter.inl
+++ b/include/NZSL/GlslWriter.inl
@@ -2,16 +2,10 @@
// This file is part of the "Nazara Shading Language" project
// For conditions of distribution and use, see copyright notice in Config.hpp
-
namespace nzsl
{
inline GlslWriter::GlslWriter() :
m_currentState(nullptr)
{
}
-
- inline auto GlslWriter::Generate(const Ast::Module& shader, const BindingMapping& bindingMapping, const States& states) -> Output
- {
- return Generate(std::nullopt, shader, bindingMapping, states);
- }
}
diff --git a/src/CNZSL/GlslWriter.cpp b/src/CNZSL/GlslWriter.cpp
index c43bd42..8fec132 100644
--- a/src/CNZSL/GlslWriter.cpp
+++ b/src/CNZSL/GlslWriter.cpp
@@ -3,7 +3,7 @@
// For conditions of distribution and use, see copyright notice in Config.hpp
#include
-#include
+#include
#include
#include
#include
@@ -14,68 +14,53 @@
extern "C"
{
- CNZSL_API nzslGlslBindingMapping* nzslGlslBindingMappingCreate(void)
+ CNZSL_API nzslGlslWriterParameters* nzslGlslWriterParametersCreate(void)
{
- return new nzslGlslBindingMapping;
+ return new nzslGlslWriterParameters;
}
- CNZSL_API void nzslGlslBindingMappingDestroy(nzslGlslBindingMapping* bindingMappingPtr)
+ CNZSL_API void nzslGlslWriterParametersDestroy(nzslGlslWriterParameters* parameterPtr)
{
- delete bindingMappingPtr;
+ delete parameterPtr;
}
- CNZSL_API void nzslGlslBindingMappingSetBinding(nzslGlslBindingMapping* bindingMappingPtr, uint32_t setIndex, uint32_t bindingIndex, unsigned int glBinding)
+ CNZSL_API void nzslGlslWriterParametersSetBindingMapping(nzslGlslWriterParameters* parameterPtr, uint32_t setIndex, uint32_t bindingIndex, unsigned int glBinding)
{
uint64_t setBinding = setIndex;
setBinding <<= 32;
setBinding |= bindingIndex;
- bindingMappingPtr->mappings[setBinding] = glBinding;
+ parameterPtr->parameters.bindingMapping[setBinding] = glBinding;
}
- CNZSL_API nzslGlslWriter* nzslGlslWriterCreate(void)
+ CNZSL_API void nzslGlslWriterParametersSetPushConstantBinding(nzslGlslWriterParameters* parameterPtr, unsigned int glBinding)
{
- return new nzslGlslWriter;
+ parameterPtr->parameters.pushConstantBinding = glBinding;
}
- CNZSL_API void nzslGlslWriterDestroy(nzslGlslWriter* writerPtr)
+ CNZSL_API void nzslGlslWriterParametersSetShaderStage(nzslGlslWriterParameters* parameterPtr, nzslShaderStageType stage)
{
- delete writerPtr;
+ constexpr std::array s_shaderStages = {
+ nzsl::ShaderStageType::Compute, // NZSL_STAGE_COMPUTE
+ nzsl::ShaderStageType::Fragment, // NZSL_STAGE_FRAGMENT
+ nzsl::ShaderStageType::Vertex // NZSL_STAGE_VERTEX
+ };
+
+ parameterPtr->parameters.shaderStage = s_shaderStages[stage];
}
- CNZSL_API nzslGlslOutput* nzslGlslWriterGenerate(nzslGlslWriter* writerPtr, const nzslModule* modulePtr, const nzslGlslBindingMapping* bindingMapping, const nzslWriterStates* statesPtr)
+ CNZSL_API nzslGlslWriter* nzslGlslWriterCreate(void)
{
- try
- {
- nzsl::GlslWriter::States states;
- if (statesPtr)
- states = static_cast(*statesPtr);
-
- std::unique_ptr output = std::make_unique();
- static_cast(*output) = writerPtr->writer.Generate(*modulePtr->module, bindingMapping->mappings, states);
-
- return output.release();
- }
- catch (std::exception& e)
- {
- writerPtr->lastError = fmt::format("nzslGlslWriterGenerate failed: {}", e.what());
- return nullptr;
- }
- catch (...)
- {
- writerPtr->lastError = "nzslGlslWriterGenerate failed with unknown error";
- return nullptr;
- }
+ return new nzslGlslWriter;
}
- CNZSL_API nzslGlslOutput* nzslGlslWriterGenerateStage(nzslShaderStageType stage, nzslGlslWriter* writerPtr, const nzslModule* modulePtr, const nzslGlslBindingMapping* bindingMapping, const nzslWriterStates* statesPtr)
+ CNZSL_API void nzslGlslWriterDestroy(nzslGlslWriter* writerPtr)
{
- constexpr std::array s_shaderStages = {
- nzsl::ShaderStageType::Compute, // NZSL_STAGE_COMPUTE
- nzsl::ShaderStageType::Fragment, // NZSL_STAGE_FRAGMENT
- nzsl::ShaderStageType::Vertex // NZSL_STAGE_VERTEX
- };
+ delete writerPtr;
+ }
+ CNZSL_API nzslGlslOutput* nzslGlslWriterGenerate(nzslGlslWriter* writerPtr, const nzslModule* modulePtr, const nzslGlslWriterParameters* parameters, const nzslWriterStates* statesPtr)
+ {
try
{
nzsl::GlslWriter::States states;
@@ -83,7 +68,7 @@ extern "C"
states = static_cast(*statesPtr);
std::unique_ptr output = std::make_unique();
- static_cast(*output) = writerPtr->writer.Generate(s_shaderStages[stage], *modulePtr->module, bindingMapping->mappings, states);
+ static_cast(*output) = writerPtr->writer.Generate(*modulePtr->module, parameters->parameters, states);
return output.release();
}
diff --git a/src/CNZSL/Structs/GlslBindingMapping.hpp b/src/CNZSL/Structs/GlslWriterParameters.hpp
similarity index 56%
rename from src/CNZSL/Structs/GlslBindingMapping.hpp
rename to src/CNZSL/Structs/GlslWriterParameters.hpp
index af1958d..dea3091 100644
--- a/src/CNZSL/Structs/GlslBindingMapping.hpp
+++ b/src/CNZSL/Structs/GlslWriterParameters.hpp
@@ -4,14 +4,14 @@
#pragma once
-#ifndef CNZSL_STRUCTS_GLSLBINDINGMAPPING_HPP
-#define CNZSL_STRUCTS_GLSLBINDINGMAPPING_HPP
+#ifndef CNZSL_STRUCTS_GLSLWRITERPARAMETERS_HPP
+#define CNZSL_STRUCTS_GLSLWRITERPARAMETERS_HPP
#include
-struct nzslGlslBindingMapping
+struct nzslGlslWriterParameters
{
- nzsl::GlslWriter::BindingMapping mappings;
+ nzsl::GlslWriter::Parameters parameters;
};
-#endif // CNZSL_STRUCTS_GLSLBINDINGMAPPING_HPP
+#endif // CNZSL_STRUCTS_GLSLWRITERPARAMETERS_HPP
diff --git a/src/NZSL/GlslWriter.cpp b/src/NZSL/GlslWriter.cpp
index b477296..c722c71 100644
--- a/src/NZSL/GlslWriter.cpp
+++ b/src/NZSL/GlslWriter.cpp
@@ -35,6 +35,7 @@ namespace nzsl
constexpr std::string_view s_glslWriterShaderDrawParametersBaseVertexName = "_nzslBaseVertex";
constexpr std::string_view s_glslWriterShaderDrawParametersDrawIndexName = "_nzslDrawID";
constexpr std::string_view s_glslWriterBlockBindingPrefix = "_nzslBinding";
+ constexpr std::string_view s_glslWriterPushConstantPrefix = "_nzslPushConstant";
constexpr std::string_view s_glslWriterVaryingPrefix = "_nzslVarying";
constexpr std::string_view s_glslWriterInputPrefix = "_nzslIn";
constexpr std::string_view s_glslWriterOutputPrefix = "_nzslOut";
@@ -318,8 +319,8 @@ namespace nzsl
struct GlslWriter::State
{
- State(const GlslWriter::BindingMapping& bindings) :
- bindingMapping(bindings)
+ State(const GlslWriter::Parameters& parameters) :
+ writerParameters(parameters)
{
}
@@ -346,7 +347,7 @@ namespace nzsl
std::unordered_map explicitUniformBlockBinding;
std::unordered_set reservedNames;
Nz::Bitset<> declaredFunctions;
- const GlslWriter::BindingMapping& bindingMapping;
+ const GlslWriter::Parameters& writerParameters;
GlslWriterPreVisitor previsitor;
ShaderStageType stage;
const States* states = nullptr;
@@ -361,9 +362,9 @@ namespace nzsl
unsigned int indentLevel = 0;
};
- auto GlslWriter::Generate(std::optional shaderStage, const Ast::Module& module, const BindingMapping& bindingMapping, const States& states) -> GlslWriter::Output
+ auto GlslWriter::Generate(const Ast::Module& module, const Parameters& parameters, const States& states) -> GlslWriter::Output
{
- State state(bindingMapping);
+ State state(parameters);
state.states = &states;
m_currentState = &state;
@@ -388,7 +389,7 @@ namespace nzsl
sanitizedModule = Ast::PropagateConstants(*targetModule);
Ast::DependencyCheckerVisitor::Config dependencyConfig;
- dependencyConfig.usedShaderStages = (shaderStage) ? *shaderStage : ShaderStageType_All; //< only one should exist anyway
+ dependencyConfig.usedShaderStages = (parameters.shaderStage) ? *parameters.shaderStage : ShaderStageType_All; //< only one should exist anyway
sanitizedModule = Ast::EliminateUnusedPass(*sanitizedModule, dependencyConfig);
@@ -414,7 +415,7 @@ namespace nzsl
}
}
- state.previsitor.selectedStage = shaderStage;
+ state.previsitor.selectedStage = parameters.shaderStage;
for (const auto& importedModule : targetModule->importedModules)
{
@@ -2257,7 +2258,7 @@ namespace nzsl
const Ast::ExpressionType& exprType = externalVar.type.GetResultingValue();
- bool isUniformOrStorageBuffer = IsStorageType(exprType) || IsUniformType(exprType);
+ bool isUniformOrStorageBuffer = IsPushConstantType(exprType) || IsStorageType(exprType) || IsUniformType(exprType);
const char* memoryLayout = nullptr;
if (isUniformOrStorageBuffer)
@@ -2324,38 +2325,51 @@ namespace nzsl
Append(") ");
};
- if (!m_currentState->bindingMapping.empty())
+ if (!IsPushConstantType(exprType))
{
- assert(externalVar.bindingIndex.HasValue());
+ if (!m_currentState->writerParameters.bindingMapping.empty())
+ {
+ assert(externalVar.bindingIndex.HasValue());
- std::uint64_t bindingIndex = externalVar.bindingIndex.GetResultingValue();
- std::uint64_t bindingSet;
- if (externalVar.bindingSet.HasValue())
- bindingSet = externalVar.bindingSet.GetResultingValue();
- else
- bindingSet = 0;
+ std::uint64_t bindingIndex = externalVar.bindingIndex.GetResultingValue();
+ std::uint64_t bindingSet;
+ if (externalVar.bindingSet.HasValue())
+ bindingSet = externalVar.bindingSet.GetResultingValue();
+ else
+ bindingSet = 0;
- auto bindingIt = m_currentState->bindingMapping.find(bindingSet << 32 | bindingIndex);
- if (bindingIt == m_currentState->bindingMapping.end())
- throw std::runtime_error("no binding found for (set=" + std::to_string(bindingSet) + ", binding=" + std::to_string(bindingIndex) + ")");
+ auto bindingIt = m_currentState->writerParameters.bindingMapping.find(bindingSet << 32 | bindingIndex);
+ if (bindingIt == m_currentState->writerParameters.bindingMapping.end())
+ throw std::runtime_error("no binding found for (set=" + std::to_string(bindingSet) + ", binding=" + std::to_string(bindingIndex) + ")");
- unsigned int glslBindingIndex = bindingIt->second;
+ unsigned int glslBindingIndex = bindingIt->second;
+
+ if (!m_currentState->requiresExplicitUniformBinding)
+ {
+ BeginLayout();
+ Append("binding = ", glslBindingIndex);
+ }
+ else
+ {
+ // Ensure name is unique
+ varName += std::to_string(glslBindingIndex);
+ if (IsSamplerType(exprType))
+ m_currentState->explicitTextureBinding.emplace(varName, glslBindingIndex);
+ else
+ m_currentState->explicitUniformBlockBinding.emplace(std::string(s_glslWriterBlockBindingPrefix) + varName, glslBindingIndex);
+ }
+ }
+ }
+ else if (m_currentState->writerParameters.pushConstantBinding.has_value())
+ {
if (!m_currentState->requiresExplicitUniformBinding)
{
BeginLayout();
- Append("binding = ", glslBindingIndex);
+ Append("binding = ", *m_currentState->writerParameters.pushConstantBinding);
}
else
- {
- // Ensure name is unique
- varName += std::to_string(glslBindingIndex);
-
- if (IsSamplerType(exprType))
- m_currentState->explicitTextureBinding.emplace(varName, glslBindingIndex);
- else
- m_currentState->explicitUniformBlockBinding.emplace(std::string(s_glslWriterBlockBindingPrefix) + varName, glslBindingIndex);
- }
+ m_currentState->explicitUniformBlockBinding.emplace(s_glslWriterPushConstantPrefix, *m_currentState->writerParameters.pushConstantBinding);
}
if (IsTextureType(exprType))
@@ -2395,8 +2409,13 @@ namespace nzsl
if (isUniformOrStorageBuffer)
{
- Append(s_glslWriterBlockBindingPrefix);
- AppendLine(varName);
+ if (IsPushConstantType(exprType))
+ AppendLine(s_glslWriterPushConstantPrefix);
+ else
+ {
+ Append(s_glslWriterBlockBindingPrefix);
+ AppendLine(varName);
+ }
EnterScope();
{
diff --git a/src/ShaderCompiler/Compiler.cpp b/src/ShaderCompiler/Compiler.cpp
index 6b038d6..3d1dd58 100644
--- a/src/ShaderCompiler/Compiler.cpp
+++ b/src/ShaderCompiler/Compiler.cpp
@@ -324,11 +324,11 @@ You can also specify -header as a suffix (ex: --compile=glsl-header) to generate
env.glMinorVersion = (version % 100) / 10;
}
- nzsl::GlslWriter::BindingMapping bindingMapping;
+ nzsl::GlslWriter::Parameters parameters;
if (m_options.count("gl-bindingmap") > 0)
{
unsigned int glslBinding = 0;
- nlohmann::json bindingArray;
+ nlohmann::ordered_json bindingArray;
nzsl::Ast::ReflectVisitor::Callbacks callbacks;
callbacks.onExternalDeclaration = [&](const nzsl::Ast::DeclareExternalStatement& extDecl)
@@ -344,6 +344,12 @@ You can also specify -header as a suffix (ex: --compile=glsl-header) to generate
for (auto& extVar : extDecl.externalVars)
{
+ if (IsPushConstantType(extVar.type.GetResultingValue()))
+ {
+ parameters.pushConstantBinding = glslBinding++;
+ continue;
+ }
+
std::uint64_t bindingSet = extSet;
if (extVar.bindingSet.HasValue())
{
@@ -360,9 +366,9 @@ You can also specify -header as a suffix (ex: --compile=glsl-header) to generate
bindingIndex = extVar.bindingIndex.GetResultingValue();
std::uint64_t binding = bindingSet << 32 | bindingIndex;
- bindingMapping.emplace(binding, glslBinding);
+ parameters.bindingMapping.emplace(binding, glslBinding);
- nlohmann::json& bindingDoc = bindingArray.emplace_back();
+ nlohmann::ordered_json& bindingDoc = bindingArray.emplace_back();
bindingDoc["set"] = bindingSet;
bindingDoc["binding"] = bindingIndex;
bindingDoc["glsl_binding"] = glslBinding;
@@ -376,14 +382,17 @@ You can also specify -header as a suffix (ex: --compile=glsl-header) to generate
if (!bindingArray.empty())
{
- nlohmann::json finalDoc;
+ nlohmann::ordered_json finalDoc;
finalDoc["bindings"] = std::move(bindingArray);
+ if (parameters.pushConstantBinding.has_value())
+ finalDoc["push_constant_binding"] = *parameters.pushConstantBinding;
+
std::string bindingStr = finalDoc.dump(4);
std::filesystem::path bindingOutputPath = outputPath;
bindingOutputPath.replace_extension("glsl.binding.json");
- OutputFile(std::move(bindingOutputPath), bindingStr.data(), bindingStr.size());
+ OutputFile(std::move(bindingOutputPath), bindingStr.data(), bindingStr.size(), true);
}
}
@@ -407,7 +416,9 @@ You can also specify -header as a suffix (ex: --compile=glsl-header) to generate
for (nzsl::ShaderStageType entryType : entryTypes)
{
- nzsl::GlslWriter::Output output = writer.Generate(entryType, module, bindingMapping, states);
+ parameters.shaderStage = entryType;
+
+ nzsl::GlslWriter::Output output = writer.Generate(module, parameters, states);
if (m_outputToStdout)
{
@@ -569,9 +580,9 @@ You can also specify -header as a suffix (ex: --compile=glsl-header) to generate
}
}
- void Compiler::OutputFile(std::filesystem::path filePath, const void* data, std::size_t size)
+ void Compiler::OutputFile(std::filesystem::path filePath, const void* data, std::size_t size, bool disallowHeader)
{
- if (m_outputHeader)
+ if (m_outputHeader && !disallowHeader)
{
std::string headerFile = ToHeader(data, size);
diff --git a/src/ShaderCompiler/Compiler.hpp b/src/ShaderCompiler/Compiler.hpp
index b5c934d..adabef6 100644
--- a/src/ShaderCompiler/Compiler.hpp
+++ b/src/ShaderCompiler/Compiler.hpp
@@ -55,7 +55,7 @@ namespace nzslc
void CompileToNZSLB(std::filesystem::path outputPath, const nzsl::Ast::Module& module);
void CompileToSPV(std::filesystem::path outputPath, const nzsl::Ast::Module& module, bool textual);
void PrintTime();
- void OutputFile(std::filesystem::path filePath, const void* data, std::size_t size);
+ void OutputFile(std::filesystem::path filePath, const void* data, std::size_t size, bool disallowHeader = false);
void OutputToStdout(std::string_view str);
void ReadInput();
void Sanitize();
diff --git a/tests/src/Tests/DebugInfoTests.cpp b/tests/src/Tests/DebugInfoTests.cpp
index 59ea9be..5bbb22e 100644
--- a/tests/src/Tests/DebugInfoTests.cpp
+++ b/tests/src/Tests/DebugInfoTests.cpp
@@ -63,6 +63,16 @@ struct Output_OutputStruct
vec4 color;
};
+struct PushConstants
+{
+ vec4 color;
+};
+
+layout(std140) uniform _nzslPushConstant
+{
+ vec4 color;
+} ExternalResources_constants;
+
layout(location = 0) out vec4 _nzslOutcolor;
void main()
@@ -70,7 +80,7 @@ void main()
Data_DataStruct data;
data.color = GetColor_Color();
Output_OutputStruct output_;
- output_.color = GetColorFromData_OutputStruct(data);
+ output_.color = (GetColorFromData_OutputStruct(data)) * ExternalResources_constants.color;
_nzslOutcolor = output_.color;
return;
@@ -79,13 +89,15 @@ void main()
ExpectSPIRV(*shaderModule, R"(
OpCapability Capability(Shader)
OpMemoryModel AddressingModel(Logical) MemoryModel(GLSL450)
- OpEntryPoint ExecutionModel(Fragment) %27 "main" %21
- OpExecutionMode %27 ExecutionMode(OriginUpperLeft)
+ OpEntryPoint ExecutionModel(Fragment) %30 "main" %24
+ OpExecutionMode %30 ExecutionMode(OriginUpperLeft)
OpDecorate %5 Decoration(Binding) 0
OpDecorate %5 Decoration(DescriptorSet) 0
- OpDecorate %21 Decoration(Location) 0
+ OpDecorate %24 Decoration(Location) 0
OpMemberDecorate %12 0 Decoration(Offset) 0
- OpMemberDecorate %22 0 Decoration(Offset) 0
+ OpDecorate %18 Decoration(Block)
+ OpMemberDecorate %18 0 Decoration(Offset) 0
+ OpMemberDecorate %25 0 Decoration(Offset) 0
%1 = OpTypeFloat 32
%2 = OpTypeImage %1 Dim(Dim2D) 0 0 0 1 ImageFormat(Unknown)
%3 = OpTypeSampledImage %2
@@ -102,50 +114,57 @@ void main()
%15 = OpConstant %1 f32(0.5)
%16 = OpConstant %1 f32(1)
%17 = OpConstantComposite %6 %15 %15 %15 %16
-%18 = OpTypeVoid
-%19 = OpTypeFunction %18
-%20 = OpTypePointer StorageClass(Output) %6
-%22 = OpTypeStruct %6
-%23 = OpTypePointer StorageClass(Function) %22
-%36 = OpTypePointer StorageClass(Function) %6
+%18 = OpTypeStruct %6
+%19 = OpTypePointer StorageClass(PushConstant) %18
+%21 = OpTypeVoid
+%22 = OpTypeFunction %21
+%23 = OpTypePointer StorageClass(Output) %6
+%25 = OpTypeStruct %6
+%26 = OpTypePointer StorageClass(Function) %25
+%39 = OpTypePointer StorageClass(Function) %6
+%51 = OpTypePointer StorageClass(PushConstant) %6
%5 = OpVariable %4 StorageClass(UniformConstant)
-%21 = OpVariable %20 StorageClass(Output)
-%24 = OpFunction %6 FunctionControl(0) %7
-%28 = OpLabel
-%29 = OpLoad %3 %5
-%30 = OpCompositeConstruct %11 %8 %8
-%31 = OpImageSampleImplicitLod %6 %29 %30
- OpReturnValue %31
- OpFunctionEnd
-%25 = OpFunction %6 FunctionControl(0) %7
-%32 = OpLabel
-%33 = OpFunctionCall %6 %24
- OpReturnValue %33
+%20 = OpVariable %19 StorageClass(PushConstant)
+%24 = OpVariable %23 StorageClass(Output)
+%27 = OpFunction %6 FunctionControl(0) %7
+%31 = OpLabel
+%32 = OpLoad %3 %5
+%33 = OpCompositeConstruct %11 %8 %8
+%34 = OpImageSampleImplicitLod %6 %32 %33
+ OpReturnValue %34
OpFunctionEnd
-%26 = OpFunction %6 FunctionControl(0) %14
-%34 = OpFunctionParameter %13
+%28 = OpFunction %6 FunctionControl(0) %7
%35 = OpLabel
-%37 = OpAccessChain %36 %34 %10
-%38 = OpLoad %6 %37
-%39 = OpFMul %6 %38 %17
- OpReturnValue %39
+%36 = OpFunctionCall %6 %27
+ OpReturnValue %36
+ OpFunctionEnd
+%29 = OpFunction %6 FunctionControl(0) %14
+%37 = OpFunctionParameter %13
+%38 = OpLabel
+%40 = OpAccessChain %39 %37 %10
+%41 = OpLoad %6 %40
+%42 = OpFMul %6 %41 %17
+ OpReturnValue %42
OpFunctionEnd
-%27 = OpFunction %18 FunctionControl(0) %19
-%40 = OpLabel
-%41 = OpVariable %13 StorageClass(Function)
-%42 = OpVariable %23 StorageClass(Function)
-%43 = OpVariable %13 StorageClass(Function)
-%44 = OpFunctionCall %6 %25
-%45 = OpAccessChain %36 %41 %10
- OpStore %45 %44
-%46 = OpLoad %12 %41
- OpStore %43 %46
-%47 = OpFunctionCall %6 %26 %43
-%48 = OpAccessChain %36 %42 %10
+%30 = OpFunction %21 FunctionControl(0) %22
+%43 = OpLabel
+%44 = OpVariable %13 StorageClass(Function)
+%45 = OpVariable %26 StorageClass(Function)
+%46 = OpVariable %13 StorageClass(Function)
+%47 = OpFunctionCall %6 %28
+%48 = OpAccessChain %39 %44 %10
OpStore %48 %47
-%49 = OpLoad %22 %42
-%50 = OpCompositeExtract %6 %49 0
- OpStore %21 %50
+%49 = OpLoad %12 %44
+ OpStore %46 %49
+%50 = OpFunctionCall %6 %29 %46
+%52 = OpAccessChain %51 %20 %10
+%53 = OpLoad %6 %52
+%54 = OpFMul %6 %50 %53
+%55 = OpAccessChain %39 %45 %10
+ OpStore %55 %54
+%56 = OpLoad %25 %45
+%57 = OpCompositeExtract %6 %56 0
+ OpStore %24 %57
OpReturn
OpFunctionEnd)", options, {}, true);
}
@@ -213,6 +232,16 @@ struct Output_OutputStruct
// Description: Test module
// License: MIT
+struct PushConstants
+{
+ vec4 color;
+};
+
+layout(std140) uniform _nzslPushConstant
+{
+ vec4 color;
+} ExternalResources_constants;
+
/*************** Outputs ***************/
layout(location = 0) out vec4 _nzslOutcolor;
@@ -221,33 +250,37 @@ void main()
Data_DataStruct data;
data.color = GetColor_Color();
Output_OutputStruct output_;
- output_.color = GetColorFromData_OutputStruct(data);
+ output_.color = (GetColorFromData_OutputStruct(data)) * ExternalResources_constants.color;
_nzslOutcolor = output_.color;
return;
})", options);
ExpectSPIRV(*shaderModule, R"(
- OpCapability Capability(Shader)
OpMemoryModel AddressingModel(Logical) MemoryModel(GLSL450)
- OpEntryPoint ExecutionModel(Fragment) %27 "main" %21
- OpExecutionMode %27 ExecutionMode(OriginUpperLeft)
+ OpEntryPoint ExecutionModel(Fragment) %30 "main" %24
+ OpExecutionMode %30 ExecutionMode(OriginUpperLeft)
OpSource SourceLanguage(NZSL) 100
OpName %12 "Data"
OpMemberName %12 0 "color"
- OpName %22 "Output"
- OpMemberName %22 0 "color"
+ OpName %18 "PushConstants"
+ OpMemberName %18 0 "color"
+ OpName %25 "Output"
+ OpMemberName %25 0 "color"
OpName %5 "tex1"
- OpName %21 "color"
- OpName %24 "GenerateColor"
- OpName %25 "GetColor"
- OpName %26 "GetColorFromData"
- OpName %27 "main"
+ OpName %20 "ExternalResources_constants"
+ OpName %24 "color"
+ OpName %27 "GenerateColor"
+ OpName %28 "GetColor"
+ OpName %29 "GetColorFromData"
+ OpName %30 "main"
OpDecorate %5 Decoration(Binding) 0
OpDecorate %5 Decoration(DescriptorSet) 0
- OpDecorate %21 Decoration(Location) 0
+ OpDecorate %24 Decoration(Location) 0
OpMemberDecorate %12 0 Decoration(Offset) 0
- OpMemberDecorate %22 0 Decoration(Offset) 0
+ OpDecorate %18 Decoration(Block)
+ OpMemberDecorate %18 0 Decoration(Offset) 0
+ OpMemberDecorate %25 0 Decoration(Offset) 0
%1 = OpTypeFloat 32
%2 = OpTypeImage %1 Dim(Dim2D) 0 0 0 1 ImageFormat(Unknown)
%3 = OpTypeSampledImage %2
@@ -264,50 +297,57 @@ void main()
%15 = OpConstant %1 f32(0.5)
%16 = OpConstant %1 f32(1)
%17 = OpConstantComposite %6 %15 %15 %15 %16
-%18 = OpTypeVoid
-%19 = OpTypeFunction %18
-%20 = OpTypePointer StorageClass(Output) %6
-%22 = OpTypeStruct %6
-%23 = OpTypePointer StorageClass(Function) %22
-%36 = OpTypePointer StorageClass(Function) %6
+%18 = OpTypeStruct %6
+%19 = OpTypePointer StorageClass(PushConstant) %18
+%21 = OpTypeVoid
+%22 = OpTypeFunction %21
+%23 = OpTypePointer StorageClass(Output) %6
+%25 = OpTypeStruct %6
+%26 = OpTypePointer StorageClass(Function) %25
+%39 = OpTypePointer StorageClass(Function) %6
+%51 = OpTypePointer StorageClass(PushConstant) %6
%5 = OpVariable %4 StorageClass(UniformConstant)
-%21 = OpVariable %20 StorageClass(Output)
-%24 = OpFunction %6 FunctionControl(0) %7
-%28 = OpLabel
-%29 = OpLoad %3 %5
-%30 = OpCompositeConstruct %11 %8 %8
-%31 = OpImageSampleImplicitLod %6 %29 %30
- OpReturnValue %31
- OpFunctionEnd
-%25 = OpFunction %6 FunctionControl(0) %7
-%32 = OpLabel
-%33 = OpFunctionCall %6 %24
- OpReturnValue %33
+%20 = OpVariable %19 StorageClass(PushConstant)
+%24 = OpVariable %23 StorageClass(Output)
+%27 = OpFunction %6 FunctionControl(0) %7
+%31 = OpLabel
+%32 = OpLoad %3 %5
+%33 = OpCompositeConstruct %11 %8 %8
+%34 = OpImageSampleImplicitLod %6 %32 %33
+ OpReturnValue %34
OpFunctionEnd
-%26 = OpFunction %6 FunctionControl(0) %14
-%34 = OpFunctionParameter %13
+%28 = OpFunction %6 FunctionControl(0) %7
%35 = OpLabel
-%37 = OpAccessChain %36 %34 %10
-%38 = OpLoad %6 %37
-%39 = OpFMul %6 %38 %17
- OpReturnValue %39
+%36 = OpFunctionCall %6 %27
+ OpReturnValue %36
+ OpFunctionEnd
+%29 = OpFunction %6 FunctionControl(0) %14
+%37 = OpFunctionParameter %13
+%38 = OpLabel
+%40 = OpAccessChain %39 %37 %10
+%41 = OpLoad %6 %40
+%42 = OpFMul %6 %41 %17
+ OpReturnValue %42
OpFunctionEnd
-%27 = OpFunction %18 FunctionControl(0) %19
-%40 = OpLabel
-%41 = OpVariable %13 StorageClass(Function)
-%42 = OpVariable %23 StorageClass(Function)
-%43 = OpVariable %13 StorageClass(Function)
-%44 = OpFunctionCall %6 %25
-%45 = OpAccessChain %36 %41 %10
- OpStore %45 %44
-%46 = OpLoad %12 %41
- OpStore %43 %46
-%47 = OpFunctionCall %6 %26 %43
-%48 = OpAccessChain %36 %42 %10
+%30 = OpFunction %21 FunctionControl(0) %22
+%43 = OpLabel
+%44 = OpVariable %13 StorageClass(Function)
+%45 = OpVariable %26 StorageClass(Function)
+%46 = OpVariable %13 StorageClass(Function)
+%47 = OpFunctionCall %6 %28
+%48 = OpAccessChain %39 %44 %10
OpStore %48 %47
-%49 = OpLoad %22 %42
-%50 = OpCompositeExtract %6 %49 0
- OpStore %21 %50
+%49 = OpLoad %12 %44
+ OpStore %46 %49
+%50 = OpFunctionCall %6 %29 %46
+%52 = OpAccessChain %51 %20 %10
+%53 = OpLoad %6 %52
+%54 = OpFMul %6 %50 %53
+%55 = OpAccessChain %39 %45 %10
+ OpStore %55 %54
+%56 = OpLoad %25 %45
+%57 = OpCompositeExtract %6 %56 0
+ OpStore %24 %57
OpReturn
OpFunctionEnd)", options, {}, true);
}
@@ -388,16 +428,28 @@ struct Output_OutputStruct
// Description: Test module
// License: MIT
+// @../resources/Shader.nzsl:12:1
+struct PushConstants
+{
+ vec4 color;
+};
+
+// @../resources/Shader.nzsl:17:1
+layout(std140) uniform _nzslPushConstant
+{
+ vec4 color;
+} ExternalResources_constants;
+
/*************** Outputs ***************/
layout(location = 0) out vec4 _nzslOutcolor;
-// @../resources/Shader.nzsl:12:1
+// @../resources/Shader.nzsl:23:1
void main()
{
Data_DataStruct data;
data.color = GetColor_Color();
Output_OutputStruct output_;
- output_.color = GetColorFromData_OutputStruct(data);
+ output_.color = (GetColorFromData_OutputStruct(data)) * ExternalResources_constants.color;
_nzslOutcolor = output_.color;
return;
@@ -406,40 +458,45 @@ void main()
ExpectSPIRV(*shaderModule, R"(
OpCapability Capability(Shader)
OpMemoryModel AddressingModel(Logical) MemoryModel(GLSL450)
- OpEntryPoint ExecutionModel(Fragment) %27 "main" %21
- OpExecutionMode %27 ExecutionMode(OriginUpperLeft)
-%28 = OpString "../resources/Shader.nzsl"
-%29 = OpString "../resources/modules/Color.nzsl"
-%30 = OpString "../resources/modules/Data/OutputStruct.nzsl"
- OpSource SourceLanguage(NZSL) 100 %28
+ OpEntryPoint ExecutionModel(Fragment) %30 "main" %24
+ OpExecutionMode %30 ExecutionMode(OriginUpperLeft)
+%31 = OpString "../resources/Shader.nzsl"
+%32 = OpString "../resources/modules/Color.nzsl"
+%33 = OpString "../resources/modules/Data/OutputStruct.nzsl"
+ OpSource SourceLanguage(NZSL) 100 %31
OpSourceExtension "ModuleName: Shader"
OpSourceExtension "Author: SirLynix"
OpSourceExtension "Description: Test module"
OpSourceExtension "License: MIT"
- OpSource SourceLanguage(NZSL) 100 %29
+ OpSource SourceLanguage(NZSL) 100 %32
OpSourceExtension "ModuleName: Color"
OpSourceExtension "Author: SirLynix"
OpSourceExtension "Description: Test color module"
OpSourceExtension "License: MIT"
OpSource SourceLanguage(NZSL) 100
OpSourceExtension "ModuleName: DataStruct"
- OpSource SourceLanguage(NZSL) 100 %30
+ OpSource SourceLanguage(NZSL) 100 %33
OpSourceExtension "ModuleName: OutputStruct"
OpName %12 "Data"
OpMemberName %12 0 "color"
- OpName %22 "Output"
- OpMemberName %22 0 "color"
+ OpName %18 "PushConstants"
+ OpMemberName %18 0 "color"
+ OpName %25 "Output"
+ OpMemberName %25 0 "color"
OpName %5 "tex1"
- OpName %21 "color"
- OpName %24 "GenerateColor"
- OpName %25 "GetColor"
- OpName %26 "GetColorFromData"
- OpName %27 "main"
+ OpName %20 "ExternalResources_constants"
+ OpName %24 "color"
+ OpName %27 "GenerateColor"
+ OpName %28 "GetColor"
+ OpName %29 "GetColorFromData"
+ OpName %30 "main"
OpDecorate %5 Decoration(Binding) 0
OpDecorate %5 Decoration(DescriptorSet) 0
- OpDecorate %21 Decoration(Location) 0
+ OpDecorate %24 Decoration(Location) 0
OpMemberDecorate %12 0 Decoration(Offset) 0
- OpMemberDecorate %22 0 Decoration(Offset) 0
+ OpDecorate %18 Decoration(Block)
+ OpMemberDecorate %18 0 Decoration(Offset) 0
+ OpMemberDecorate %25 0 Decoration(Offset) 0
%1 = OpTypeFloat 32
%2 = OpTypeImage %1 Dim(Dim2D) 0 0 0 1 ImageFormat(Unknown)
%3 = OpTypeSampledImage %2
@@ -456,75 +513,82 @@ void main()
%15 = OpConstant %1 f32(0.5)
%16 = OpConstant %1 f32(1)
%17 = OpConstantComposite %6 %15 %15 %15 %16
-%18 = OpTypeVoid
-%19 = OpTypeFunction %18
-%20 = OpTypePointer StorageClass(Output) %6
-%22 = OpTypeStruct %6
-%23 = OpTypePointer StorageClass(Function) %22
-%39 = OpTypePointer StorageClass(Function) %6
+%18 = OpTypeStruct %6
+%19 = OpTypePointer StorageClass(PushConstant) %18
+%21 = OpTypeVoid
+%22 = OpTypeFunction %21
+%23 = OpTypePointer StorageClass(Output) %6
+%25 = OpTypeStruct %6
+%26 = OpTypePointer StorageClass(Function) %25
+%42 = OpTypePointer StorageClass(Function) %6
+%54 = OpTypePointer StorageClass(PushConstant) %6
%5 = OpVariable %4 StorageClass(UniformConstant)
-%21 = OpVariable %20 StorageClass(Output)
- OpLine %29 13 1
-%24 = OpFunction %6 FunctionControl(0) %7
-%31 = OpLabel
+%20 = OpVariable %19 StorageClass(PushConstant)
+%24 = OpVariable %23 StorageClass(Output)
+ OpLine %32 13 1
+%27 = OpFunction %6 FunctionControl(0) %7
+%34 = OpLabel
OpNoLine
- OpLine %29 15 5
- OpLine %29 15 12
-%32 = OpLoad %3 %5
-%33 = OpCompositeConstruct %11 %8 %8
-%34 = OpImageSampleImplicitLod %6 %32 %33
- OpReturnValue %34
+ OpLine %32 15 5
+ OpLine %32 15 12
+%35 = OpLoad %3 %5
+%36 = OpCompositeConstruct %11 %8 %8
+%37 = OpImageSampleImplicitLod %6 %35 %36
+ OpReturnValue %37
OpFunctionEnd
- OpLine %29 32 1
-%25 = OpFunction %6 FunctionControl(0) %7
-%35 = OpLabel
+ OpLine %32 32 1
+%28 = OpFunction %6 FunctionControl(0) %7
+%38 = OpLabel
OpNoLine
- OpLine %29 34 5
- OpLine %29 34 12
-%36 = OpFunctionCall %6 %24
- OpReturnValue %36
+ OpLine %32 34 5
+ OpLine %32 34 12
+%39 = OpFunctionCall %6 %27
+ OpReturnValue %39
OpFunctionEnd
- OpLine %30 9 1
-%26 = OpFunction %6 FunctionControl(0) %14
- OpLine %30 9 21
-%37 = OpFunctionParameter %13
-%38 = OpLabel
+ OpLine %33 9 1
+%29 = OpFunction %6 FunctionControl(0) %14
+ OpLine %33 9 21
+%40 = OpFunctionParameter %13
+%41 = OpLabel
OpNoLine
- OpLine %30 11 5
- OpLine %30 11 12
-%40 = OpAccessChain %39 %37 %10
-%41 = OpLoad %6 %40
-%42 = OpFMul %6 %41 %17
- OpReturnValue %42
+ OpLine %33 11 5
+ OpLine %33 11 12
+%43 = OpAccessChain %42 %40 %10
+%44 = OpLoad %6 %43
+%45 = OpFMul %6 %44 %17
+ OpReturnValue %45
OpFunctionEnd
- OpLine %28 12 1
-%27 = OpFunction %18 FunctionControl(0) %19
-%43 = OpLabel
+ OpLine %31 23 1
+%30 = OpFunction %21 FunctionControl(0) %22
+%46 = OpLabel
OpNoLine
- OpLine %28 14 5
-%44 = OpVariable %13 StorageClass(Function)
- OpLine %28 17 5
-%45 = OpVariable %23 StorageClass(Function)
- OpLine %28 18 37
-%46 = OpVariable %13 StorageClass(Function)
- OpLine %28 15 18
-%47 = OpFunctionCall %6 %25
- OpLine %28 15 5
-%48 = OpAccessChain %39 %44 %10
- OpStore %48 %47
- OpLine %28 18 37
-%49 = OpLoad %12 %44
- OpStore %46 %49
- OpLine %28 18 20
-%50 = OpFunctionCall %6 %26 %46
- OpLine %28 18 5
-%51 = OpAccessChain %39 %45 %10
+ OpLine %31 25 5
+%47 = OpVariable %13 StorageClass(Function)
+ OpLine %31 28 5
+%48 = OpVariable %26 StorageClass(Function)
+ OpLine %31 29 37
+%49 = OpVariable %13 StorageClass(Function)
+ OpLine %31 26 18
+%50 = OpFunctionCall %6 %28
+ OpLine %31 26 5
+%51 = OpAccessChain %42 %47 %10
OpStore %51 %50
- OpLine %28 20 12
-%52 = OpLoad %22 %45
-%53 = OpCompositeExtract %6 %52 0
- OpStore %21 %53
- OpLine %28 20 5
+ OpLine %31 29 37
+%52 = OpLoad %12 %47
+ OpStore %49 %52
+ OpLine %31 29 20
+%53 = OpFunctionCall %6 %29 %49
+%55 = OpAccessChain %54 %20 %10
+%56 = OpLoad %6 %55
+%57 = OpFMul %6 %53 %56
+ OpLine %31 29 5
+%58 = OpAccessChain %42 %48 %10
+ OpStore %58 %57
+ OpLine %31 31 12
+%59 = OpLoad %25 %48
+%60 = OpCompositeExtract %6 %59 0
+ OpStore %24 %60
+ OpLine %31 31 5
OpReturn
OpFunctionEnd)", options, {}, true);
}
@@ -681,6 +745,17 @@ import GetColor as Color from Color;
import * from DataStruct;
import * from OutputStruct;
+[layout(std140)]
+struct PushConstants
+{
+ color: vec4[f32]
+}
+
+external ExternalResources
+{
+ constants: push_constant[PushConstants]
+}
+
[entry(frag)]
fn main() -> Output
{
@@ -688,7 +763,7 @@ fn main() -> Output
data.color = Color();
let output: Output;
- output.color = GetColorFromData(data);
+ output.color = GetColorFromData(data) * ExternalResources.constants.color;
return output;
}
@@ -699,16 +774,28 @@ fn main() -> Output
// Description: Test module
// License: MIT
+// @../resources/Shader.nzsl:12:1
+struct PushConstants
+{
+ vec4 color;
+};
+
+// @../resources/Shader.nzsl:17:1
+layout(std140) uniform _nzslPushConstant
+{
+ vec4 color;
+} ExternalResources_constants;
+
/*************** Outputs ***************/
layout(location = 0) out vec4 _nzslOutcolor;
-// @../resources/Shader.nzsl:12:1
+// @../resources/Shader.nzsl:23:1
void main()
{
Data_DataStruct data;
data.color = GetColor_Color();
Output_OutputStruct output_;
- output_.color = GetColorFromData_OutputStruct(data);
+ output_.color = (GetColorFromData_OutputStruct(data)) * ExternalResources_constants.color;
_nzslOutcolor = output_.color;
return;
@@ -717,12 +804,12 @@ void main()
ExpectSPIRV(*shaderModule, R"(
OpCapability Capability(Shader)
OpMemoryModel AddressingModel(Logical) MemoryModel(GLSL450)
- OpEntryPoint ExecutionModel(Fragment) %27 "main" %21
- OpExecutionMode %27 ExecutionMode(OriginUpperLeft)
-%28 = OpString "../resources/Shader.nzsl"
-%29 = OpString "../resources/modules/Color.nzsl"
-%30 = OpString "../resources/modules/Data/OutputStruct.nzsl"
- OpSource SourceLanguage(NZSL) 100 %28 "[nzsl_version("1.0")]
+ OpEntryPoint ExecutionModel(Fragment) %30 "main" %24
+ OpExecutionMode %30 ExecutionMode(OriginUpperLeft)
+%31 = OpString "../resources/Shader.nzsl"
+%32 = OpString "../resources/modules/Color.nzsl"
+%33 = OpString "../resources/modules/Data/OutputStruct.nzsl"
+ OpSource SourceLanguage(NZSL) 100 %31 "[nzsl_version("1.0")]
[author("SirLynix")]
[desc("Test module")]
[license("MIT")]
@@ -732,6 +819,17 @@ import GetColor as Color from Color;
import * from DataStruct;
import * from OutputStruct;
+[layout(std140)]
+struct PushConstants
+{
+ color: vec4[f32]
+}
+
+external ExternalResources
+{
+ constants: push_constant[PushConstants]
+}
+
[entry(frag)]
fn main() -> Output
{
@@ -739,7 +837,7 @@ fn main() -> Output
data.color = Color();
let output: Output;
- output.color = GetColorFromData(data);
+ output.color = GetColorFromData(data) * ExternalResources.constants.color;
return output;
}
@@ -748,7 +846,7 @@ fn main() -> Output
OpSourceExtension "Author: SirLynix"
OpSourceExtension "Description: Test module"
OpSourceExtension "License: MIT"
- OpSource SourceLanguage(NZSL) 100 %29 "[nzsl_version("1.0")]
+ OpSource SourceLanguage(NZSL) 100 %32 "[nzsl_version("1.0")]
[author("SirLynix")]
[desc("Test color module")]
[license("MIT")]
@@ -796,7 +894,7 @@ fn GetAnotherColor() -> vec4[f32]
OpSourceExtension "License: MIT"
OpSource SourceLanguage(NZSL) 100
OpSourceExtension "ModuleName: DataStruct"
- OpSource SourceLanguage(NZSL) 100 %30 "[nzsl_version("1.0")]
+ OpSource SourceLanguage(NZSL) 100 %33 "[nzsl_version("1.0")]
module OutputStruct;
import * from DataStruct;
@@ -818,19 +916,24 @@ struct Output
OpSourceExtension "ModuleName: OutputStruct"
OpName %12 "Data"
OpMemberName %12 0 "color"
- OpName %22 "Output"
- OpMemberName %22 0 "color"
+ OpName %18 "PushConstants"
+ OpMemberName %18 0 "color"
+ OpName %25 "Output"
+ OpMemberName %25 0 "color"
OpName %5 "tex1"
- OpName %21 "color"
- OpName %24 "GenerateColor"
- OpName %25 "GetColor"
- OpName %26 "GetColorFromData"
- OpName %27 "main"
+ OpName %20 "ExternalResources_constants"
+ OpName %24 "color"
+ OpName %27 "GenerateColor"
+ OpName %28 "GetColor"
+ OpName %29 "GetColorFromData"
+ OpName %30 "main"
OpDecorate %5 Decoration(Binding) 0
OpDecorate %5 Decoration(DescriptorSet) 0
- OpDecorate %21 Decoration(Location) 0
+ OpDecorate %24 Decoration(Location) 0
OpMemberDecorate %12 0 Decoration(Offset) 0
- OpMemberDecorate %22 0 Decoration(Offset) 0
+ OpDecorate %18 Decoration(Block)
+ OpMemberDecorate %18 0 Decoration(Offset) 0
+ OpMemberDecorate %25 0 Decoration(Offset) 0
%1 = OpTypeFloat 32
%2 = OpTypeImage %1 Dim(Dim2D) 0 0 0 1 ImageFormat(Unknown)
%3 = OpTypeSampledImage %2
@@ -847,75 +950,82 @@ struct Output
%15 = OpConstant %1 f32(0.5)
%16 = OpConstant %1 f32(1)
%17 = OpConstantComposite %6 %15 %15 %15 %16
-%18 = OpTypeVoid
-%19 = OpTypeFunction %18
-%20 = OpTypePointer StorageClass(Output) %6
-%22 = OpTypeStruct %6
-%23 = OpTypePointer StorageClass(Function) %22
-%39 = OpTypePointer StorageClass(Function) %6
+%18 = OpTypeStruct %6
+%19 = OpTypePointer StorageClass(PushConstant) %18
+%21 = OpTypeVoid
+%22 = OpTypeFunction %21
+%23 = OpTypePointer StorageClass(Output) %6
+%25 = OpTypeStruct %6
+%26 = OpTypePointer StorageClass(Function) %25
+%42 = OpTypePointer StorageClass(Function) %6
+%54 = OpTypePointer StorageClass(PushConstant) %6
%5 = OpVariable %4 StorageClass(UniformConstant)
-%21 = OpVariable %20 StorageClass(Output)
- OpLine %29 13 1
-%24 = OpFunction %6 FunctionControl(0) %7
-%31 = OpLabel
+%20 = OpVariable %19 StorageClass(PushConstant)
+%24 = OpVariable %23 StorageClass(Output)
+ OpLine %32 13 1
+%27 = OpFunction %6 FunctionControl(0) %7
+%34 = OpLabel
OpNoLine
- OpLine %29 15 5
- OpLine %29 15 12
-%32 = OpLoad %3 %5
-%33 = OpCompositeConstruct %11 %8 %8
-%34 = OpImageSampleImplicitLod %6 %32 %33
- OpReturnValue %34
+ OpLine %32 15 5
+ OpLine %32 15 12
+%35 = OpLoad %3 %5
+%36 = OpCompositeConstruct %11 %8 %8
+%37 = OpImageSampleImplicitLod %6 %35 %36
+ OpReturnValue %37
OpFunctionEnd
- OpLine %29 32 1
-%25 = OpFunction %6 FunctionControl(0) %7
-%35 = OpLabel
+ OpLine %32 32 1
+%28 = OpFunction %6 FunctionControl(0) %7
+%38 = OpLabel
OpNoLine
- OpLine %29 34 5
- OpLine %29 34 12
-%36 = OpFunctionCall %6 %24
- OpReturnValue %36
+ OpLine %32 34 5
+ OpLine %32 34 12
+%39 = OpFunctionCall %6 %27
+ OpReturnValue %39
OpFunctionEnd
- OpLine %30 9 1
-%26 = OpFunction %6 FunctionControl(0) %14
- OpLine %30 9 21
-%37 = OpFunctionParameter %13
-%38 = OpLabel
+ OpLine %33 9 1
+%29 = OpFunction %6 FunctionControl(0) %14
+ OpLine %33 9 21
+%40 = OpFunctionParameter %13
+%41 = OpLabel
OpNoLine
- OpLine %30 11 5
- OpLine %30 11 12
-%40 = OpAccessChain %39 %37 %10
-%41 = OpLoad %6 %40
-%42 = OpFMul %6 %41 %17
- OpReturnValue %42
+ OpLine %33 11 5
+ OpLine %33 11 12
+%43 = OpAccessChain %42 %40 %10
+%44 = OpLoad %6 %43
+%45 = OpFMul %6 %44 %17
+ OpReturnValue %45
OpFunctionEnd
- OpLine %28 12 1
-%27 = OpFunction %18 FunctionControl(0) %19
-%43 = OpLabel
+ OpLine %31 23 1
+%30 = OpFunction %21 FunctionControl(0) %22
+%46 = OpLabel
OpNoLine
- OpLine %28 14 5
-%44 = OpVariable %13 StorageClass(Function)
- OpLine %28 17 5
-%45 = OpVariable %23 StorageClass(Function)
- OpLine %28 18 37
-%46 = OpVariable %13 StorageClass(Function)
- OpLine %28 15 18
-%47 = OpFunctionCall %6 %25
- OpLine %28 15 5
-%48 = OpAccessChain %39 %44 %10
- OpStore %48 %47
- OpLine %28 18 37
-%49 = OpLoad %12 %44
- OpStore %46 %49
- OpLine %28 18 20
-%50 = OpFunctionCall %6 %26 %46
- OpLine %28 18 5
-%51 = OpAccessChain %39 %45 %10
+ OpLine %31 25 5
+%47 = OpVariable %13 StorageClass(Function)
+ OpLine %31 28 5
+%48 = OpVariable %26 StorageClass(Function)
+ OpLine %31 29 37
+%49 = OpVariable %13 StorageClass(Function)
+ OpLine %31 26 18
+%50 = OpFunctionCall %6 %28
+ OpLine %31 26 5
+%51 = OpAccessChain %42 %47 %10
OpStore %51 %50
- OpLine %28 20 12
-%52 = OpLoad %22 %45
-%53 = OpCompositeExtract %6 %52 0
- OpStore %21 %53
- OpLine %28 20 5
+ OpLine %31 29 37
+%52 = OpLoad %12 %47
+ OpStore %49 %52
+ OpLine %31 29 20
+%53 = OpFunctionCall %6 %29 %49
+%55 = OpAccessChain %54 %20 %10
+%56 = OpLoad %6 %55
+%57 = OpFMul %6 %53 %56
+ OpLine %31 29 5
+%58 = OpAccessChain %42 %48 %10
+ OpStore %58 %57
+ OpLine %31 31 12
+%59 = OpLoad %25 %48
+%60 = OpCompositeExtract %6 %59 0
+ OpStore %24 %60
+ OpLine %31 31 5
OpReturn
OpFunctionEnd)", options, {}, true);
}
diff --git a/tests/src/Tests/ExternalTests.cpp b/tests/src/Tests/ExternalTests.cpp
index ca9cdb7..40da320 100644
--- a/tests/src/Tests/ExternalTests.cpp
+++ b/tests/src/Tests/ExternalTests.cpp
@@ -958,6 +958,7 @@ fn main()
[nzsl_version("1.0")]
module;
+[layout(std140)]
struct Data
{
index: i32
@@ -978,12 +979,10 @@ fn main()
shaderModule = SanitizeModule(*shaderModule);
ExpectGLSL(*shaderModule, R"(
-struct Data
+layout(std140) uniform _nzslPushConstant
{
int index;
-};
-
-uniform Data data;
+} data;
void main()
{
diff --git a/tests/src/Tests/FilesystemResolverTests.cpp b/tests/src/Tests/FilesystemResolverTests.cpp
index f523fe7..08e2e2f 100644
--- a/tests/src/Tests/FilesystemResolverTests.cpp
+++ b/tests/src/Tests/FilesystemResolverTests.cpp
@@ -66,6 +66,16 @@ struct Output_OutputStruct
// Description: Test module
// License: MIT
+struct PushConstants
+{
+ vec4 color;
+};
+
+layout(std140) uniform _nzslPushConstant
+{
+ vec4 color;
+} ExternalResources_constants;
+
/*************** Outputs ***************/
layout(location = 0) out vec4 _nzslOutcolor;
@@ -74,7 +84,7 @@ void main()
Data_DataStruct data;
data.color = GetColor_Color();
Output_OutputStruct output_;
- output_.color = GetColorFromData_OutputStruct(data);
+ output_.color = (GetColorFromData_OutputStruct(data)) * ExternalResources_constants.color;
_nzslOutcolor = output_.color;
return;
@@ -145,54 +155,68 @@ alias GetColorFromData = _OutputStruct.GetColorFromData;
alias Output = _OutputStruct.Output;
+[layout(std140)]
+struct PushConstants
+{
+ color: vec4[f32]
+}
+
+external ExternalResources
+{
+ constants: push_constant[PushConstants]
+}
+
[entry(frag)]
fn main() -> Output
{
let data: Data;
data.color = Color();
let output: Output;
- output.color = GetColorFromData(data);
+ output.color = (GetColorFromData(data)) * ExternalResources.constants.color;
return output;
}
)");
ExpectSPIRV(*shaderModule, R"(
-%24 = OpFunction %6 FunctionControl(0) %7
-%28 = OpLabel
-%29 = OpLoad %3 %5
-%30 = OpCompositeConstruct %11 %8 %8
-%31 = OpImageSampleImplicitLod %6 %29 %30
- OpReturnValue %31
- OpFunctionEnd
-%25 = OpFunction %6 FunctionControl(0) %7
-%32 = OpLabel
-%33 = OpFunctionCall %6 %24
- OpReturnValue %33
+%27 = OpFunction %6 FunctionControl(0) %7
+%31 = OpLabel
+%32 = OpLoad %3 %5
+%33 = OpCompositeConstruct %11 %8 %8
+%34 = OpImageSampleImplicitLod %6 %32 %33
+ OpReturnValue %34
OpFunctionEnd
-%26 = OpFunction %6 FunctionControl(0) %14
-%34 = OpFunctionParameter %13
+%28 = OpFunction %6 FunctionControl(0) %7
%35 = OpLabel
-%37 = OpAccessChain %36 %34 %10
-%38 = OpLoad %6 %37
-%39 = OpFMul %6 %38 %17
- OpReturnValue %39
+%36 = OpFunctionCall %6 %27
+ OpReturnValue %36
+ OpFunctionEnd
+%29 = OpFunction %6 FunctionControl(0) %14
+%37 = OpFunctionParameter %13
+%38 = OpLabel
+%40 = OpAccessChain %39 %37 %10
+%41 = OpLoad %6 %40
+%42 = OpFMul %6 %41 %17
+ OpReturnValue %42
OpFunctionEnd
-%27 = OpFunction %18 FunctionControl(0) %19
-%40 = OpLabel
-%41 = OpVariable %13 StorageClass(Function)
-%42 = OpVariable %23 StorageClass(Function)
-%43 = OpVariable %13 StorageClass(Function)
-%44 = OpFunctionCall %6 %25
-%45 = OpAccessChain %36 %41 %10
- OpStore %45 %44
-%46 = OpLoad %12 %41
- OpStore %43 %46
-%47 = OpFunctionCall %6 %26 %43
-%48 = OpAccessChain %36 %42 %10
+%30 = OpFunction %21 FunctionControl(0) %22
+%43 = OpLabel
+%44 = OpVariable %13 StorageClass(Function)
+%45 = OpVariable %26 StorageClass(Function)
+%46 = OpVariable %13 StorageClass(Function)
+%47 = OpFunctionCall %6 %28
+%48 = OpAccessChain %39 %44 %10
OpStore %48 %47
-%49 = OpLoad %22 %42
-%50 = OpCompositeExtract %6 %49 0
- OpStore %21 %50
+%49 = OpLoad %12 %44
+ OpStore %46 %49
+%50 = OpFunctionCall %6 %29 %46
+%52 = OpAccessChain %51 %20 %10
+%53 = OpLoad %6 %52
+%54 = OpFMul %6 %50 %53
+%55 = OpAccessChain %39 %45 %10
+ OpStore %55 %54
+%56 = OpLoad %25 %45
+%57 = OpCompositeExtract %6 %56 0
+ OpStore %24 %57
OpReturn
OpFunctionEnd)", {}, {}, true);
}
diff --git a/tests/src/Tests/NzslcTests.cpp b/tests/src/Tests/NzslcTests.cpp
index 383ab51..c399a34 100644
--- a/tests/src/Tests/NzslcTests.cpp
+++ b/tests/src/Tests/NzslcTests.cpp
@@ -1,16 +1,9 @@
#include
-#include
#include
#include
#include
-#include
-#include
#include
-#include
#include
-#include
-#include
-#include
TEST_CASE("Standalone compiler", "[NZSLC]")
{
@@ -47,13 +40,14 @@ TEST_CASE("Standalone compiler", "[NZSLC]")
ExecuteCommand("./nzslc ../resources/modules/Data/DataStruct.nzslb"); //< validation
// Try to generate a full shader based on partial compilation result
- ExecuteCommand("./nzslc --compile=glsl,glsl-header,nzsl,nzsl-header,nzslb,nzslb-header,spv,spv-header,spv-txt --debug-level=regular -o test_files -m ../resources/modules/Color.nzslb -m ../resources/modules/Data/OutputStruct.nzslb -m ../resources/modules/Data/DataStruct.nzslb ../resources/Shader.nzslb");
+ ExecuteCommand("./nzslc --compile=glsl,glsl-header,nzsl,nzsl-header,nzslb,nzslb-header,spv,spv-header,spv-txt --gl-bindingmap --debug-level=regular -o test_files -m ../resources/modules/Color.nzslb -m ../resources/modules/Data/OutputStruct.nzslb -m ../resources/modules/Data/DataStruct.nzslb ../resources/Shader.nzslb");
// Validate generated files
ExecuteCommand("./nzslc test_files/Shader.nzsl");
ExecuteCommand("./nzslc test_files/Shader.nzslb");
ExecuteCommand("glslang -S frag test_files/Shader.frag.glsl");
ExecuteCommand("spirv-val test_files/Shader.spv");
+ CheckFileMatch("../resources/Shader.glsl.binding.json", "test_files/Shader.glsl.binding.json");
// Check that header version matches original files
CheckHeaderMatch("test_files/Shader.frag.glsl");
diff --git a/tests/src/Tests/ShaderUtils.cpp b/tests/src/Tests/ShaderUtils.cpp
index 4f2b10f..b8f599c 100644
--- a/tests/src/Tests/ShaderUtils.cpp
+++ b/tests/src/Tests/ShaderUtils.cpp
@@ -242,7 +242,10 @@ void ExpectGLSL(nzsl::ShaderStageType stageType, const nzsl::Ast::Module& shader
nzsl::GlslWriter writer;
writer.SetEnv(env);
- nzsl::GlslWriter::Output output = writer.Generate(stageType, targetModule, {}, options);
+ nzsl::GlslWriter::Parameters parameters;
+ parameters.shaderStage = stageType;
+
+ nzsl::GlslWriter::Output output = writer.Generate(targetModule, parameters, options);
SECTION("Validating expected code")
{
diff --git a/tests/src/Tests/ToolUtils.cpp b/tests/src/Tests/ToolUtils.cpp
index 09500a9..d895962 100644
--- a/tests/src/Tests/ToolUtils.cpp
+++ b/tests/src/Tests/ToolUtils.cpp
@@ -27,24 +27,49 @@ namespace NAZARA_ANONYMOUS_NAMESPACE
return str;
}
+
+ std::vector ReadFile(const std::filesystem::path& filepath)
+ {
+ std::ifstream originalFile(filepath, std::ios::in | std::ios::binary);
+ REQUIRE(originalFile);
+
+ originalFile.seekg(0, std::ios::end);
+
+ std::streamsize length = originalFile.tellg();
+ REQUIRE(length > 0);
+ if (length == 0)
+ return {}; //< ignore empty files
+
+ originalFile.seekg(0, std::ios::beg);
+
+ std::vector originalContent(Nz::SafeCast(length));
+ REQUIRE(originalFile.read(&originalContent[0], length));
+
+ return originalContent;
+ }
}
-void CheckHeaderMatch(const std::filesystem::path& originalFilepath)
+void CheckFileMatch(const std::filesystem::path& firstFile, const std::filesystem::path& secondFile)
{
- std::ifstream originalFile(originalFilepath, std::ios::in | std::ios::binary);
- REQUIRE(originalFile);
+ NAZARA_USE_ANONYMOUS_NAMESPACE
+
+ std::vector firstFileContent = ReadFile(firstFile);
+ std::vector secondFileContent = ReadFile(secondFile);
+
+ std::string firstFileStr(firstFileContent.begin(), firstFileContent.end());
+ ReplaceStr(firstFileStr, "\r\n", "\n");
- originalFile.seekg(0, std::ios::end);
+ std::string secondFileStr(secondFileContent.begin(), secondFileContent.end());
+ ReplaceStr(secondFileStr, "\r\n", "\n");
- std::streamsize length = originalFile.tellg();
- REQUIRE(length > 0);
- if (length == 0)
- return; //< ignore empty files
+ REQUIRE(firstFileStr == secondFileStr);
+}
- originalFile.seekg(0, std::ios::beg);
+void CheckHeaderMatch(const std::filesystem::path& originalFilepath)
+{
+ NAZARA_USE_ANONYMOUS_NAMESPACE
- std::vector originalContent(Nz::SafeCast(length));
- REQUIRE(originalFile.read(&originalContent[0], length));
+ std::vector originalContent = ReadFile(originalFilepath);
std::filesystem::path headerFilepath = originalFilepath;
headerFilepath.concat(".h");
diff --git a/tests/src/Tests/ToolUtils.hpp b/tests/src/Tests/ToolUtils.hpp
index 2739ed3..1493019 100644
--- a/tests/src/Tests/ToolUtils.hpp
+++ b/tests/src/Tests/ToolUtils.hpp
@@ -6,6 +6,7 @@
#include
#include
+void CheckFileMatch(const std::filesystem::path& firstFile, const std::filesystem::path& secondFile);
void CheckHeaderMatch(const std::filesystem::path& originalFilepath);
void ExecuteCommand(const std::string& command, const std::string& pattern = {}, std::string expectedOutput = {});