diff --git a/include/sirit/sirit.h b/include/sirit/sirit.h index c7f3e2b..065496f 100644 --- a/include/sirit/sirit.h +++ b/include/sirit/sirit.h @@ -1347,8 +1347,13 @@ public: /// 3) store the New Value back through Pointer. Id OpAtomicXor(Id result_type, Id pointer, Id memory, Id semantics, Id value); + // Print a message for vulkan layers to use, e.g. renderdoc + // Usage is like C printf + Id OpDebugPrintf(Id fmt, std::span fmt_args); + private: Id GetGLSLstd450(); + Id GetNonSemanticDebugPrintf(); std::uint32_t version{}; std::uint32_t bound{}; @@ -1356,6 +1361,7 @@ private: std::unordered_set extensions; std::unordered_set capabilities; std::optional glsl_std_450; + std::optional non_semantic_debug_printf; spv::AddressingModel addressing_model{spv::AddressingModel::Logical}; spv::MemoryModel memory_model{spv::MemoryModel::GLSL450}; @@ -1364,6 +1370,7 @@ private: std::unique_ptr entry_points; std::unique_ptr execution_modes; std::unique_ptr debug; + std::unique_ptr debug_name; std::unique_ptr annotations; std::unique_ptr declarations; std::unique_ptr global_variables; diff --git a/src/instructions/debug.cpp b/src/instructions/debug.cpp index 1ca3462..2907e66 100644 --- a/src/instructions/debug.cpp +++ b/src/instructions/debug.cpp @@ -12,14 +12,14 @@ namespace Sirit { Id Module::Name(Id target, std::string_view name) { - debug->Reserve(3 + WordsInString(name)); - *debug << spv::Op::OpName << target << name << EndOp{}; + debug_name->Reserve(3 + WordsInString(name)); + *debug_name << spv::Op::OpName << target << name << EndOp{}; return target; } Id Module::MemberName(Id type, u32 member, std::string_view name) { - debug->Reserve(4 + WordsInString(name)); - *debug << spv::Op::OpMemberName << type << member << name << EndOp{}; + debug_name->Reserve(4 + WordsInString(name)); + *debug_name << spv::Op::OpMemberName << type << member << name << EndOp{}; return type; } diff --git a/src/instructions/extension.cpp b/src/instructions/extension.cpp index 44dc691..501b515 100644 --- a/src/instructions/extension.cpp +++ b/src/instructions/extension.cpp @@ -4,7 +4,9 @@ * 3-Clause BSD License */ +#include #include +#include #include "sirit/sirit.h" @@ -80,4 +82,12 @@ DEFINE_BINARY(OpCross, GLSLstd450Cross) DEFINE_UNARY(OpLength, GLSLstd450Length) DEFINE_TRINARY(OpFMix, GLSLstd450FMix) +Id Module::OpDebugPrintf(Id fmt, std::span fmt_args) { + std::vector operands; + operands.push_back(fmt); + std::copy(fmt_args.begin(), fmt_args.end(), std::back_inserter(operands)); + return OpExtInst(TypeVoid(), GetNonSemanticDebugPrintf(), NonSemanticDebugPrintfDebugPrintf, + operands); +} + } // namespace Sirit diff --git a/src/sirit.cpp b/src/sirit.cpp index 7075f23..48a5f61 100644 --- a/src/sirit.cpp +++ b/src/sirit.cpp @@ -21,8 +21,8 @@ Module::Module(u32 version_) : version{version_}, ext_inst_imports{std::make_unique(&bound)}, entry_points{std::make_unique(&bound)}, execution_modes{std::make_unique(&bound)}, debug{std::make_unique(&bound)}, - annotations{std::make_unique(&bound)}, declarations{std::make_unique( - &bound)}, + debug_name{std::make_unique(&bound)}, annotations{std::make_unique(&bound)}, + declarations{std::make_unique(&bound)}, global_variables{std::make_unique(&bound)}, code{std::make_unique(&bound)} {} Module::~Module() = default; @@ -60,6 +60,7 @@ std::vector Module::Assemble() const { insert(entry_points->Words()); insert(execution_modes->Words()); insert(debug->Words()); + insert(debug_name->Words()); insert(annotations->Words()); insert(declarations->Words()); insert(global_variables->Words()); @@ -131,12 +132,24 @@ Id Module::AddGlobalVariable(Id result_type, spv::StorageClass storage_class, } Id Module::GetGLSLstd450() { + const char* extname = "GLSL.std.450"; + size_t len = WordsInString(extname); if (!glsl_std_450) { - ext_inst_imports->Reserve(3 + 4); - glsl_std_450 = *ext_inst_imports << OpId{spv::Op::OpExtInstImport} << "GLSL.std.450" - << EndOp{}; + ext_inst_imports->Reserve(3 + len); + glsl_std_450 = *ext_inst_imports << OpId{spv::Op::OpExtInstImport} << extname << EndOp{}; } return *glsl_std_450; } +Id Module::GetNonSemanticDebugPrintf() { + const char* extname = "NonSemantic.DebugPrintf"; + size_t len = WordsInString(extname); + if (!non_semantic_debug_printf) { + ext_inst_imports->Reserve(3 + len); + non_semantic_debug_printf = *ext_inst_imports << OpId{spv::Op::OpExtInstImport} << extname + << EndOp{}; + } + return *non_semantic_debug_printf; +} + } // namespace Sirit