From 4b1c1d1e38f28492589bf4196843c13f6128942b Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Mon, 11 Mar 2019 04:17:29 -0300 Subject: [PATCH] Add ellipsis overloads for instructions ending in vectors --- include/sirit/sirit.h | 102 +++++++++++++++++++++++++++++---- src/instructions/extension.cpp | 6 +- tests/main.cpp | 47 ++++++++------- 3 files changed, 122 insertions(+), 33 deletions(-) diff --git a/include/sirit/sirit.h b/include/sirit/sirit.h index aac6fdb..ecef394 100644 --- a/include/sirit/sirit.h +++ b/include/sirit/sirit.h @@ -9,8 +9,8 @@ #include #include #include -#include #include +#include #include #include #include @@ -52,10 +52,23 @@ public: void AddEntryPoint(spv::ExecutionModel execution_model, Id entry_point, const std::string& name, const std::vector& interfaces = {}); + /// Adds an entry point. + template + void AddEntryPoint(spv::ExecutionModel execution_model, Id entry_point, const std::string& name, + Ts&&... interfaces) { + AddEntryPoint(execution_model, entry_point, name, {interfaces...}); + } + /// Declare an execution mode for an entry point. void AddExecutionMode(Id entry_point, spv::ExecutionMode mode, const std::vector& literals = {}); + /// Declare an execution mode for an entry point. + template + void AddExecutionMode(Id entry_point, spv::ExecutionMode mode, Ts&&... literals) { + AddExecutionMode(entry_point, mode, {literals...}); + } + /** * Adds an instruction to module's code * @param op Instruction to insert into code. Types and constants must not @@ -111,6 +124,12 @@ public: /// Returns type struct. Id OpTypeStruct(const std::vector& members = {}); + /// Returns type struct. + template + Id OpTypeStruct(Ts&&... members) { + return OpTypeStruct({members...}); + } + /// Returns type opaque. Id OpTypeOpaque(const std::string& name); @@ -120,6 +139,12 @@ public: /// Returns type function. Id OpTypeFunction(Id return_type, const std::vector& arguments = {}); + /// Returns type function. + template + Id OpTypeFunction(Id return_type, Ts&&... arguments) { + return OpTypeFunction(return_type, {arguments...}); + } + /// Returns type event. Id OpTypeEvent(); @@ -149,6 +174,12 @@ public: /// Returns a numeric scalar constant. Id ConstantComposite(Id result_type, const std::vector& constituents); + /// Returns a numeric scalar constant. + template + Id ConstantComposite(Id result_type, Ts&&... constituents) { + return ConstantComposite(result_type, {constituents...}); + } + /// Returns a sampler constant. Id ConstantSampler(Id result_type, spv::SamplerAddressingMode addressing_mode, bool normalized, spv::SamplerFilterMode filter_mode); @@ -167,12 +198,25 @@ public: /// Call a function. Id OpFunctionCall(Id result_type, Id function, const std::vector& arguments = {}); + /// Call a function. + template + Id OpFunctionCall(Id result_type, Id function, Ts&&... arguments) { + return OpFunctionCall(result_type, function, {arguments...}); + } + // Flow /// Declare a structured loop. Id OpLoopMerge(Id merge_block, Id continue_target, spv::LoopControlMask loop_control, const std::vector& literals = {}); + /// Declare a structured loop. + template + Id OpLoopMerge(Id merge_block, Id continue_target, spv::LoopControlMask loop_control, + Ts&&... literals) { + return OpLoopMerge(merge_block, continue_target, loop_control, {literals...}); + } + /// Declare a structured selection. Id OpSelectionMerge(Id merge_block, spv::SelectionControlMask selection_control); @@ -232,29 +276,63 @@ public: /// Store through a pointer. Id OpStore(Id pointer, Id object, std::optional memory_access = {}); - /// Create a pointer into a composite object that can be used with OpLoad - /// and OpStore. + /// Create a pointer into a composite object that can be used with OpLoad and OpStore. Id OpAccessChain(Id result_type, Id base, const std::vector& indexes = {}); + /// Create a pointer into a composite object that can be used with OpLoad and OpStore. + template + Id OpAccessChain(Id result_type, Id base, Ts&&... indexes) { + return OpAccessChain(result_type, base, {indexes...}); + } + /// Make a copy of a composite object, while modifying one part of it. Id OpCompositeInsert(Id result_type, Id object, Id composite, const std::vector& indexes = {}); + /// Make a copy of a composite object, while modifying one part of it. + template + Id OpCompositeInsert(Id result_type, Id object, Id composite, Ts&&... indexes) { + return OpCompositeInsert(result_type, object, composite, {indexes...}); + } + /// Extract a part of a composite object. Id OpCompositeExtract(Id result_type, Id composite, const std::vector& indexes = {}); - /// Construct a new composite object from a set of constituent objects that - /// will fully form it. + /// Extract a part of a composite object. + template + Id OpCompositeExtract(Id result_type, Id composite, Ts&&... indexes) { + return OpCompositeExtract(result_type, composite, {indexes...}); + } + + /// Construct a new composite object from a set of constituent objects that will fully form it. Id OpCompositeConstruct(Id result_type, const std::vector& ids); + /// Construct a new composite object from a set of constituent objects that will fully form it. + template + Id OpCompositeConstruct(Id result_type, Ts&&... ids) { + return OpCompositeConstruct(result_type, {ids...}); + } + // Annotation /// Add a decoration to target. Id Decorate(Id target, spv::Decoration decoration, const std::vector& literals = {}); + /// Add a decoration to target. + template + Id Decorate(Id target, spv::Decoration decoration, Ts&&... literals) { + return Decorate(target, decoration, {literals...}); + } + Id MemberDecorate(Id structure_type, Literal member, spv::Decoration decoration, const std::vector& literals = {}); + template + Id MemberDecorate(Id structure_type, Literal member, spv::Decoration decoration, + Ts&&... literals) { + return MemberDecorate(structure_type, member, decoration, {literals...}); + } + // Misc /// Make an intermediate object whose value is undefined. @@ -437,6 +515,11 @@ public: Id OpExtInst(Id result_type, Id set, std::uint32_t instruction, const std::vector& operands); + template + Id OpExtInst(Id result_type, Id set, std::uint32_t instruction, Ts&&... operands) { + return OpExtInst(result_type, set, instruction, {operands...}); + } + /// Result is x if x >= 0; otherwise result is -x. Id OpFAbs(Id result_type, Id x); @@ -595,14 +678,13 @@ private: Id GetGLSLstd450(); - const std::uint32_t version; - + std::uint32_t version{}; std::uint32_t bound{1}; - std::set extensions; - std::set capabilities; + std::unordered_set extensions; + std::unordered_set capabilities; + std::unordered_set> ext_inst_import; std::unique_ptr glsl_std_450; - std::set> ext_inst_import; spv::AddressingModel addressing_model{spv::AddressingModel::Logical}; spv::MemoryModel memory_model{spv::MemoryModel::GLSL450}; diff --git a/src/instructions/extension.cpp b/src/instructions/extension.cpp index 56d417b..07cc37e 100644 --- a/src/instructions/extension.cpp +++ b/src/instructions/extension.cpp @@ -22,17 +22,17 @@ Id Module::OpExtInst(Id result_type, Id set, u32 instruction, const std::vector< #define DEFINE_UNARY(funcname, opcode) \ Id Module::funcname(Id result_type, Id operand) { \ - return OpExtInst(result_type, GetGLSLstd450(), opcode, {operand}); \ + return OpExtInst(result_type, GetGLSLstd450(), opcode, operand); \ } #define DEFINE_BINARY(funcname, opcode) \ Id Module::funcname(Id result_type, Id operand_1, Id operand_2) { \ - return OpExtInst(result_type, GetGLSLstd450(), opcode, {operand_1, operand_2}); \ + return OpExtInst(result_type, GetGLSLstd450(), opcode, operand_1, operand_2); \ } #define DEFINE_TRINARY(funcname, opcode) \ Id Module::funcname(Id result_type, Id operand_1, Id operand_2, Id operand_3) { \ - return OpExtInst(result_type, GetGLSLstd450(), opcode, {operand_1, operand_2, operand_3}); \ + return OpExtInst(result_type, GetGLSLstd450(), opcode, operand_1, operand_2, operand_3); \ } DEFINE_UNARY(OpFAbs, GLSLstd450FAbs) diff --git a/tests/main.cpp b/tests/main.cpp index afa1514..e8c164f 100644 --- a/tests/main.cpp +++ b/tests/main.cpp @@ -4,9 +4,9 @@ * Lesser General Public License version 3 or any later version. */ -#include #include #include +#include using u32 = uint32_t; @@ -18,7 +18,7 @@ public: void Generate() { AddCapability(spv::Capability::Shader); SetMemoryModel(spv::AddressingModel::Logical, spv::MemoryModel::GLSL450); - + const auto t_void = Name(OpTypeVoid(), "void"); const auto t_uint = Name(OpTypeInt(32, false), "uint"); const auto t_float = Name(OpTypeFloat(32), "float"); @@ -26,45 +26,52 @@ public: const auto float4 = Name(OpTypeVector(t_float, 4), "float4"); const auto in_float = Name(OpTypePointer(spv::StorageClass::Input, t_float), "in_float"); const auto in_float4 = Name(OpTypePointer(spv::StorageClass::Input, float4), "in_float4"); - const auto out_float4 = Name(OpTypePointer(spv::StorageClass::Output, float4), "out_float4"); + const auto out_float4 = + Name(OpTypePointer(spv::StorageClass::Output, float4), "out_float4"); + + const auto gl_per_vertex = Name(OpTypeStruct(float4), "gl_PerVertex"); + const auto gl_per_vertex_ptr = + Name(OpTypePointer(spv::StorageClass::Output, gl_per_vertex), "out_gl_PerVertex"); - const auto gl_per_vertex = Name(OpTypeStruct({float4}), "gl_PerVertex"); - const auto gl_per_vertex_ptr = Name(OpTypePointer(spv::StorageClass::Output, gl_per_vertex), "out_gl_PerVertex"); - const auto in_pos = Name(OpVariable(in_float4, spv::StorageClass::Input), "in_pos"); - const auto per_vertex = Name(OpVariable(gl_per_vertex_ptr, spv::StorageClass::Output), "per_vertex"); + const auto per_vertex = + Name(OpVariable(gl_per_vertex_ptr, spv::StorageClass::Output), "per_vertex"); - Decorate(in_pos, spv::Decoration::Location, {0}); + Decorate(in_pos, spv::Decoration::Location, 0); Decorate(gl_per_vertex, spv::Decoration::Block); Decorate(gl_per_vertex, spv::Decoration::Block); - MemberDecorate(gl_per_vertex, 0, spv::Decoration::BuiltIn, {static_cast(spv::BuiltIn::Position)}); - + MemberDecorate(gl_per_vertex, 0, spv::Decoration::BuiltIn, + static_cast(spv::BuiltIn::Position)); + AddGlobalVariable(in_pos); AddGlobalVariable(per_vertex); - const auto main_func = Emit(Name(OpFunction(t_void, spv::FunctionControlMask::MaskNone, OpTypeFunction(t_void)), "main")); + const auto main_func = Emit( + Name(OpFunction(t_void, spv::FunctionControlMask::MaskNone, OpTypeFunction(t_void)), + "main")); Emit(OpLabel()); - const auto ptr_pos_x = Emit(OpAccessChain(in_float, in_pos, {Constant(t_uint, 0u)})); - const auto ptr_pos_y = Emit(OpAccessChain(in_float, in_pos, {Constant(t_uint, 1u)})); + const auto ptr_pos_x = Emit(OpAccessChain(in_float, in_pos, Constant(t_uint, 0u))); + const auto ptr_pos_y = Emit(OpAccessChain(in_float, in_pos, Constant(t_uint, 1u))); const auto pos_x = Emit(OpLoad(t_float, ptr_pos_x)); const auto pos_y = Emit(OpLoad(t_float, ptr_pos_y)); auto tmp_position = Emit(OpUndef(float4)); - Decorate(tmp_position, spv::Decoration::FPRoundingMode, {static_cast(spv::FPRoundingMode::RTE)}); - tmp_position = Emit(OpCompositeInsert(float4, pos_x, tmp_position, {0})); - tmp_position = Emit(OpCompositeInsert(float4, pos_y, tmp_position, {1})); - tmp_position = Emit(OpCompositeInsert(float4, Constant(t_float, 0.f), tmp_position, {2})); - tmp_position = Emit(OpCompositeInsert(float4, Constant(t_float, 1.f), tmp_position, {3})); + Decorate(tmp_position, spv::Decoration::FPRoundingMode, + static_cast(spv::FPRoundingMode::RTE)); + tmp_position = Emit(OpCompositeInsert(float4, pos_x, tmp_position, 0)); + tmp_position = Emit(OpCompositeInsert(float4, pos_y, tmp_position, 1)); + tmp_position = Emit(OpCompositeInsert(float4, Constant(t_float, 0.f), tmp_position, 2)); + tmp_position = Emit(OpCompositeInsert(float4, Constant(t_float, 1.f), tmp_position, 3)); - const auto gl_position = Emit(OpAccessChain(out_float4, per_vertex, {Constant(t_uint, 0u)})); + const auto gl_position = Emit(OpAccessChain(out_float4, per_vertex, Constant(t_uint, 0u))); Emit(OpStore(gl_position, tmp_position)); Emit(OpReturn()); Emit(OpFunctionEnd()); - AddEntryPoint(spv::ExecutionModel::Vertex, main_func, "main", {in_pos, per_vertex}); + AddEntryPoint(spv::ExecutionModel::Vertex, main_func, "main", in_pos, per_vertex); } };