#ifndef EMULATOR_INCLUDE_EMULATOR_GRAPHICS_SHADER_RECOMPILER_SPIRVBUILDER_H_ #define EMULATOR_INCLUDE_EMULATOR_GRAPHICS_SHADER_RECOMPILER_SPIRVBUILDER_H_ #include "common/common.h" #include #include #include #include #include namespace Libs::Graphics::ShaderRecompiler::Spirv { struct TypeAnnotation { uint32_t opcode = 0; std::vector operands; }; struct DeferredPhi { size_t word_offset = 0; size_t incoming_count = 0; }; class Builder { public: explicit Builder(uint32_t version = 0x00010300u); ~Builder() = default; KYTY_CLASS_DEFAULT_COPY(Builder); uint32_t AllocateId(); void RequireVersion(uint32_t version); void RequireCapability(uint32_t capability); void RequireExtension(const char* name); uint32_t Import(const char* name); uint32_t Type(uint32_t opcode, std::initializer_list operands = {}); uint32_t Type(uint32_t opcode, const std::vector& operands); uint32_t DecoratedType(uint32_t opcode, std::initializer_list operands, std::initializer_list annotations); uint32_t Constant(uint32_t opcode, uint32_t type, std::initializer_list operands = {}); uint32_t Constant(uint32_t opcode, uint32_t type, const std::vector& operands); uint32_t DefineGlobalVariable(uint32_t pointer_type, uint32_t storage_class); void DefineGlobalVariable(uint32_t id, uint32_t pointer_type, uint32_t storage_class); void AddMemoryModel(std::initializer_list operands); void AddEntryPoint(uint32_t execution_model, uint32_t entry_point, const char* name, const std::vector& interfaces); void AddExecutionMode(std::initializer_list operands); void AddName(uint32_t target, const char* name); void AddAnnotation(std::initializer_list words); void AddFunction(std::initializer_list words); void AddFunction(const std::vector& words); DeferredPhi AddDeferredPhi(uint32_t type, uint32_t result, size_t incoming_count); void PatchDeferredPhi(DeferredPhi phi, size_t incoming, uint32_t value, uint32_t parent); [[nodiscard]] std::vector Build() const; private: static void AppendInstruction(std::vector& section, uint32_t opcode, const std::vector& operands); static void AppendInstruction(std::vector& section, uint32_t opcode, std::initializer_list operands); static void AppendString(std::vector& words, const char* text); void AddCapability(std::initializer_list operands); void AddExtension(const char* name); void AddExtInstImport(uint32_t id, const char* name); void AddType(std::initializer_list words); uint32_t m_next_id = 1; uint32_t m_version = 0; std::vector m_capabilities; std::vector m_extensions; std::vector m_ext_inst_imports; std::vector m_memory_model; std::vector m_entry_points; std::vector m_execution_modes; std::vector m_debug; std::vector m_annotations; std::vector m_declarations; std::vector m_functions; std::set m_required_capabilities; std::set m_required_extensions; std::map m_import_ids; std::map, uint32_t> m_declaration_ids; size_t m_unpatched_phi_incomings = 0; }; } // namespace Libs::Graphics::ShaderRecompiler::Spirv #endif /* EMULATOR_INCLUDE_EMULATOR_GRAPHICS_SHADER_RECOMPILER_SPIRVBUILDER_H_ */