From 37a0eecec8f6cd74d4048371fbc50a07c085026d Mon Sep 17 00:00:00 2001 From: Jacob Lifshay Date: Fri, 11 Aug 2017 17:34:28 -0700 Subject: [PATCH] start adding graphics pipeline --- src/CMakeLists.txt | 7 +- src/demo/demo.cpp | 15 ++- src/llvm_wrapper/llvm_wrapper.h | 171 ++++++++++++++++++++++++++++ src/pipeline/CMakeLists.txt | 25 ++++ src/pipeline/pipeline.cpp | 23 ++++ src/pipeline/pipeline.h | 119 +++++++++++++++++++ src/spirv_to_llvm/CMakeLists.txt | 2 +- src/spirv_to_llvm/spirv_to_llvm.cpp | 144 +++++++++++++++++++---- src/spirv_to_llvm/spirv_to_llvm.h | 27 ++--- 9 files changed, 480 insertions(+), 53 deletions(-) create mode 100644 src/pipeline/CMakeLists.txt create mode 100644 src/pipeline/pipeline.cpp create mode 100644 src/pipeline/pipeline.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 70d3010..5b8ffa1 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -20,10 +20,11 @@ # cmake_minimum_required(VERSION 3.1 FATAL_ERROR) include_directories(${CMAKE_CURRENT_SOURCE_DIR}) -add_subdirectory(spirv) add_subdirectory(demo) -add_subdirectory(json) -add_subdirectory(util) add_subdirectory(generate_spirv_parser) +add_subdirectory(json) add_subdirectory(llvm_wrapper) +add_subdirectory(pipeline) +add_subdirectory(spirv) add_subdirectory(spirv_to_llvm) +add_subdirectory(util) diff --git a/src/demo/demo.cpp b/src/demo/demo.cpp index 0e50f95..e5e2b48 100644 --- a/src/demo/demo.cpp +++ b/src/demo/demo.cpp @@ -245,7 +245,9 @@ int test_main(int argc, char **argv) llvm_target_machine.get(), file->data(), file->size(), - next_module_id++); + next_module_id++, + spirv::Execution_model::vertex, + "main"); } catch(spirv::Parser_error &e) { @@ -268,13 +270,10 @@ int test_main(int argc, char **argv) return reinterpret_cast(symbol); }, nullptr); - for(auto &entry_point : converted_module.entry_points) - { - auto function = reinterpret_cast( - orc_jit_stack.get_symbol_address(entry_point.entry_function_name.c_str())); - std::cerr << "entry point \"" << entry_point.name << "\": &" - << entry_point.entry_function_name << " == " << function << std::endl; - } + auto function = reinterpret_cast( + orc_jit_stack.get_symbol_address(converted_module.entry_function_name.c_str())); + std::cerr << "entry point: " << converted_module.entry_function_name << ": " << function + << std::endl; } else { diff --git a/src/llvm_wrapper/llvm_wrapper.h b/src/llvm_wrapper/llvm_wrapper.h index ce81b9e..4f2b206 100644 --- a/src/llvm_wrapper/llvm_wrapper.h +++ b/src/llvm_wrapper/llvm_wrapper.h @@ -489,6 +489,177 @@ struct Orc_jit_stack : public Wrapper<::LLVMOrcJITStackRef, Orc_jit_stack_delete return get_symbol(get(), symbol_name); } }; + +template +struct Create_llvm_type +{ + static_assert(!std::is_same::value, "Create_llvm_type not implemented for type T"); + ::LLVMTypeRef operator()(::LLVMContextRef context) const = delete; +}; + +template +struct Create_llvm_type : public Create_llvm_type +{ +}; + +template <> +struct Create_llvm_type +{ + ::LLVMTypeRef operator()(::LLVMContextRef context) const + { + return ::LLVMVoidTypeInContext(context); + } +}; + +template <> +struct Create_llvm_type +{ + ::LLVMTypeRef operator()(::LLVMContextRef context) const + { + return ::LLVMIntTypeInContext(context, + std::numeric_limits::digits * sizeof(bool)); + } +}; + +template <> +struct Create_llvm_type +{ + ::LLVMTypeRef operator()(::LLVMContextRef context) const + { + return ::LLVMIntTypeInContext(context, std::numeric_limits::digits); + } +}; + +template <> +struct Create_llvm_type +{ + ::LLVMTypeRef operator()(::LLVMContextRef context) const + { + return ::LLVMIntTypeInContext(context, std::numeric_limits::digits); + } +}; + +template <> +struct Create_llvm_type +{ + ::LLVMTypeRef operator()(::LLVMContextRef context) const + { + return ::LLVMIntTypeInContext(context, std::numeric_limits::digits); + } +}; + +template <> +struct Create_llvm_type +{ + ::LLVMTypeRef operator()(::LLVMContextRef context) const + { + return ::LLVMIntTypeInContext(context, std::numeric_limits::digits); + } +}; + +template <> +struct Create_llvm_type +{ + ::LLVMTypeRef operator()(::LLVMContextRef context) const + { + return ::LLVMIntTypeInContext(context, std::numeric_limits::digits); + } +}; + +template <> +struct Create_llvm_type +{ + ::LLVMTypeRef operator()(::LLVMContextRef context) const + { + return ::LLVMIntTypeInContext(context, std::numeric_limits::digits); + } +}; + +template <> +struct Create_llvm_type +{ + ::LLVMTypeRef operator()(::LLVMContextRef context) const + { + return ::LLVMIntTypeInContext(context, std::numeric_limits::digits); + } +}; + +template <> +struct Create_llvm_type +{ + ::LLVMTypeRef operator()(::LLVMContextRef context) const + { + return ::LLVMIntTypeInContext(context, std::numeric_limits::digits); + } +}; + +template <> +struct Create_llvm_type +{ + ::LLVMTypeRef operator()(::LLVMContextRef context) const + { + return ::LLVMIntTypeInContext(context, std::numeric_limits::digits); + } +}; + +template <> +struct Create_llvm_type +{ + ::LLVMTypeRef operator()(::LLVMContextRef context) const + { + return ::LLVMIntTypeInContext(context, std::numeric_limits::digits); + } +}; + +template <> +struct Create_llvm_type +{ + ::LLVMTypeRef operator()(::LLVMContextRef context) const + { + return ::LLVMIntTypeInContext(context, std::numeric_limits::digits); + } +}; + +template +struct Create_llvm_type +{ + ::LLVMTypeRef operator()(::LLVMContextRef context) const + { + constexpr unsigned default_address_space = 0; + return ::LLVMPointerType(Create_llvm_type()(context), default_address_space); + } +}; + +template <> +struct Create_llvm_type : public Create_llvm_type +{ +}; + +template <> +struct Create_llvm_type : public Create_llvm_type +{ +}; + +template +struct Create_llvm_type +{ + ::LLVMTypeRef operator()(::LLVMContextRef context) const + { + return ::LLVMArrayType(Create_llvm_type()(context), N); + } +}; + +template +struct Create_llvm_type +{ + ::LLVMTypeRef operator()(::LLVMContextRef context) const + { + ::LLVMTypeRef arguments[] = {Create_llvm_type()(context)...}; + constexpr bool is_var_arg = false; + return ::LLVMFunctionType( + Create_llvm_type()(context), arguments, sizeof...(Args), is_var_arg); + } +}; } } diff --git a/src/pipeline/CMakeLists.txt b/src/pipeline/CMakeLists.txt new file mode 100644 index 0000000..e4dc438 --- /dev/null +++ b/src/pipeline/CMakeLists.txt @@ -0,0 +1,25 @@ +# Copyright 2017 Jacob Lifshay +# +# 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. +# +cmake_minimum_required(VERSION 3.1 FATAL_ERROR) + +set(sources pipeline.cpp) +add_library(vulkan_cpu_pipeline STATIC ${sources}) +target_link_libraries(vulkan_cpu_pipeline vulkan_cpu_spirv_to_llvm vulkan_cpu_util vulkan_cpu_spirv vulkan_cpu_llvm_wrapper) diff --git a/src/pipeline/pipeline.cpp b/src/pipeline/pipeline.cpp new file mode 100644 index 0000000..fccfeb3 --- /dev/null +++ b/src/pipeline/pipeline.cpp @@ -0,0 +1,23 @@ +/* + * Copyright 2017 Jacob Lifshay + * + * 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. + * + */ +#include "pipeline.h" diff --git a/src/pipeline/pipeline.h b/src/pipeline/pipeline.h new file mode 100644 index 0000000..c31a8dd --- /dev/null +++ b/src/pipeline/pipeline.h @@ -0,0 +1,119 @@ +/* + * Copyright 2017 Jacob Lifshay + * + * 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. + * + */ +#ifndef PIPELINE_PIPELINE_H_ +#define PIPELINE_PIPELINE_H_ + +#include +#include +#include "llvm_wrapper/llvm_wrapper.h" + +namespace vulkan_cpu +{ +namespace pipeline +{ +class Pipeline +{ + Pipeline(const Pipeline &) = delete; + Pipeline &operator=(const Pipeline &) = delete; + +public: + typedef std::uintptr_t Handle; + +public: + constexpr Pipeline() noexcept + { + } + virtual ~Pipeline() = default; + static std::unique_ptr move_from_handle(Handle pipeline) noexcept + { + return std::unique_ptr(from_handle(pipeline)); + } + static Pipeline *from_handle(Handle pipeline) noexcept + { + return reinterpret_cast(pipeline); + } +}; + +inline Pipeline::Handle to_handle(Pipeline *pipeline) noexcept +{ + return reinterpret_cast(pipeline); +} + +inline Pipeline::Handle move_to_handle(std::unique_ptr pipeline) noexcept +{ + return to_handle(pipeline.release()); +} + +class Graphics_pipeline final : public Pipeline +{ +public: +#warning finish adding draw function parameters + typedef void (*Vertex_shader_function)(std::uint32_t vertex_start_index, + std::uint32_t vertex_count, + std::uint32_t instance_id, + void *output_buffer); + +public: + const Vertex_shader_function get_vertex_shader_function() const noexcept + { + return vertex_shader_function; + } +#warning finish implementing Graphics_pipeline::make + static std::unique_ptr make(); + static std::unique_ptr move_from_handle(Handle pipeline) noexcept + { + return std::unique_ptr(from_handle(pipeline)); + } + static Graphics_pipeline *from_handle(Handle pipeline) noexcept + { + auto *retval = reinterpret_cast(pipeline); + assert(!retval || dynamic_cast(retval)); + return static_cast(retval); + } + +private: + Graphics_pipeline(std::shared_ptr state, + Vertex_shader_function vertex_shader_function) noexcept + : state(std::move(state)), + vertex_shader_function(vertex_shader_function) + { + } + +private: + std::shared_ptr state; + Vertex_shader_function vertex_shader_function; +}; + +inline Pipeline::Handle to_handle(Graphics_pipeline *pipeline) noexcept +{ + return to_handle(static_cast(pipeline)); +} + +inline Pipeline::Handle move_to_handle(std::unique_ptr pipeline) noexcept +{ + return to_handle(pipeline.release()); +} +} +} + +#endif // PIPELINE_PIPELINE_H_ diff --git a/src/spirv_to_llvm/CMakeLists.txt b/src/spirv_to_llvm/CMakeLists.txt index 64eb3cf..631cb15 100644 --- a/src/spirv_to_llvm/CMakeLists.txt +++ b/src/spirv_to_llvm/CMakeLists.txt @@ -22,4 +22,4 @@ cmake_minimum_required(VERSION 3.1 FATAL_ERROR) set(sources spirv_to_llvm.cpp) add_library(vulkan_cpu_spirv_to_llvm STATIC ${sources}) -target_link_libraries(vulkan_cpu_spirv_to_llvm vulkan_cpu_util vulkan_cpu_spirv vulkan_cpu_llvm_wrapper) +target_link_libraries(vulkan_cpu_spirv_to_llvm vulkan_cpu_util vulkan_cpu_spirv vulkan_cpu_llvm_wrapper vulkan_cpu_pipeline) diff --git a/src/spirv_to_llvm/spirv_to_llvm.cpp b/src/spirv_to_llvm/spirv_to_llvm.cpp index 560ed8a..09ea92e 100644 --- a/src/spirv_to_llvm/spirv_to_llvm.cpp +++ b/src/spirv_to_llvm/spirv_to_llvm.cpp @@ -24,6 +24,7 @@ #include "util/optional.h" #include "util/variant.h" #include "util/enum.h" +#include "pipeline/pipeline.h" #include #include #include @@ -637,6 +638,8 @@ private: llvm_wrapper::Builder builder; util::optional last_merge_instruction; std::list> function_entry_block_handlers; + spirv::Execution_model execution_model; + util::string_view entry_point_name; private: Id_state &get_id_state(Id id) @@ -712,11 +715,11 @@ private: { auto &function = get_id_state(current_function_id).function.value(); state.label = Label_state(::LLVMAppendBasicBlockInContext( - context, function.function, get_prefixed_name(get_name(id)).c_str())); + context, function.function, get_prefixed_name(get_name(id), false).c_str())); } return state.label->basic_block; } - std::string get_prefixed_name(std::string name) const + std::string get_prefixed_name(std::string name, bool is_builtin_name) const { if(!name.empty()) { @@ -727,11 +730,13 @@ private: // ensure name doesn't conflict with names generated by get_or_make_prefixed_name name.insert(0, "_"); } + if(!is_builtin_name) + name.insert(0, "_"); // ensure user names don't conflict with builtin names return name_prefix_string + std::move(name); } return name; } - std::string get_or_make_prefixed_name(std::string name) + std::string get_or_make_prefixed_name(std::string name, bool is_builtin_name) { if(name.empty()) { @@ -739,14 +744,21 @@ private: ss << name_prefix_string << next_name_index++; return ss.str(); } - return get_prefixed_name(std::move(name)); + return get_prefixed_name(std::move(name), is_builtin_name); } public: explicit Spirv_to_llvm(::LLVMContextRef context, ::LLVMTargetMachineRef target_machine, - std::uint64_t shader_id) - : context(context), target_machine(target_machine), shader_id(shader_id), stage() + std::uint64_t shader_id, + spirv::Execution_model execution_model, + util::string_view entry_point_name) + : context(context), + target_machine(target_machine), + shader_id(shader_id), + stage(), + execution_model(execution_model), + entry_point_name(entry_point_name) { { std::ostringstream ss; @@ -754,7 +766,7 @@ public: name_prefix_string = ss.str(); } module = llvm_wrapper::Module::create_with_target_machine( - get_prefixed_name("module").c_str(), context, target_machine); + get_prefixed_name("module", true).c_str(), context, target_machine); target_data = ::LLVMGetModuleDataLayout(module.get()); builder = llvm_wrapper::Builder::create(context); constexpr std::size_t no_instruction_index = 0; @@ -762,7 +774,7 @@ public: std::make_shared(std::vector{}, context, target_data, - get_prefixed_name("Io_struct").c_str(), + get_prefixed_name("Io_struct", true).c_str(), no_instruction_index); assert(implicit_function_arguments.size() == 1); static_assert(io_struct_argument_index == 0, ""); @@ -775,17 +787,86 @@ public: std::make_shared(std::vector{}, context, target_data, - get_prefixed_name("Inputs").c_str(), + get_prefixed_name("Inputs", true).c_str(), no_instruction_index); inputs_member = io_struct->add_member(Struct_type_descriptor::Member({}, inputs_struct)); outputs_struct = std::make_shared(std::vector{}, context, target_data, - get_prefixed_name("Outputs").c_str(), + get_prefixed_name("Outputs", true).c_str(), no_instruction_index); outputs_member = io_struct->add_member(Struct_type_descriptor::Member({}, outputs_struct)); } + std::string generate_entry_function(Op_entry_point_state &entry_point) + { + ::LLVMValueRef function = nullptr; + switch(execution_model) + { + case spirv::Execution_model::vertex: + { + typedef void (*Vertex_shader_function)(std::uint32_t vertex_start_index, + std::uint32_t vertex_count, + std::uint32_t instance_id, + void *output_buffer); + constexpr std::size_t arg_vertex_start_index = 0; + constexpr std::size_t arg_vertex_count = 1; + constexpr std::size_t arg_instance_id = 2; + constexpr std::size_t arg_output_buffer = 3; + static_assert(std::is_same::value, + "vertex shader function signature mismatch"); + auto function_type = llvm_wrapper::Create_llvm_type()(context); + function = ::LLVMAddFunction( + module.get(), get_prefixed_name("vertex_entry_point", true).c_str(), function_type); + llvm_wrapper::Module::set_function_target_machine(function, target_machine); + static_cast(arg_vertex_start_index); + static_cast(arg_vertex_count); + static_cast(arg_instance_id); + static_cast(arg_output_buffer); +#warning finish implementing vertex execution model + break; + } + case spirv::Execution_model::tessellation_control: +#warning implement execution model + throw Parser_error(entry_point.instruction_start_index, + entry_point.instruction_start_index, + "unimplemented execution model: " + + std::string(spirv::get_enumerant_name(execution_model))); + case spirv::Execution_model::tessellation_evaluation: +#warning implement execution model + throw Parser_error(entry_point.instruction_start_index, + entry_point.instruction_start_index, + "unimplemented execution model: " + + std::string(spirv::get_enumerant_name(execution_model))); + case spirv::Execution_model::geometry: +#warning implement execution model + throw Parser_error(entry_point.instruction_start_index, + entry_point.instruction_start_index, + "unimplemented execution model: " + + std::string(spirv::get_enumerant_name(execution_model))); + case spirv::Execution_model::fragment: +#warning implement execution model + throw Parser_error(entry_point.instruction_start_index, + entry_point.instruction_start_index, + "unimplemented execution model: " + + std::string(spirv::get_enumerant_name(execution_model))); + case spirv::Execution_model::gl_compute: +#warning implement execution model + throw Parser_error(entry_point.instruction_start_index, + entry_point.instruction_start_index, + "unimplemented execution model: " + + std::string(spirv::get_enumerant_name(execution_model))); + case spirv::Execution_model::kernel: + // TODO: implement execution model as extension + throw Parser_error(entry_point.instruction_start_index, + entry_point.instruction_start_index, + "unimplemented execution model: " + + std::string(spirv::get_enumerant_name(execution_model))); + } + assert(function); + return ::LLVMGetValueName(function); + } Converted_module run(const Word *shader_words, std::size_t shader_size) { stage = Stage::calculate_types; @@ -798,7 +879,7 @@ public: #warning finish Spirv_to_llvm::run stage = Stage::generate_code; spirv::parse(*this, shader_words, shader_size); - std::vector entry_points; + std::string entry_function_name; for(auto &id_state : id_states) { for(auto &entry_point : id_state.op_entry_points) @@ -807,19 +888,35 @@ public: throw Parser_error(entry_point.instruction_start_index, entry_point.instruction_start_index, "No definition for function referenced in OpEntryPoint"); - entry_points.push_back( - Converted_module::Entry_point(std::string(entry_point.entry_point.name), - id_state.function->output_function_name)); + if(entry_point.entry_point.name != entry_point_name + || entry_point.entry_point.execution_model != execution_model) + continue; + if(!entry_function_name.empty()) + throw Parser_error(entry_point.instruction_start_index, + entry_point.instruction_start_index, + "duplicate entry point: " + + std::string(spirv::get_enumerant_name(execution_model)) + + " \"" + + std::string(entry_point_name) + + "\""); + entry_function_name = generate_entry_function(entry_point); } } - Converted_module retval(std::move(module), - std::move(entry_points), + if(entry_function_name.empty()) + throw Parser_error(0, + 0, + "can't find entry point: " + + std::string(spirv::get_enumerant_name(execution_model)) + + " \"" + + std::string(entry_point_name) + + "\""); + return Converted_module(std::move(module), + std::move(entry_function_name), std::move(io_struct), inputs_member, std::move(inputs_struct), outputs_member, std::move(outputs_struct)); - return retval; } virtual void handle_header(unsigned version_number_major, unsigned version_number_minor, @@ -2430,7 +2527,7 @@ void Spirv_to_llvm::handle_instruction_op_type_struct(Op_type_struct instruction state.decorations, context, ::LLVMGetModuleDataLayout(module.get()), - get_prefixed_name(get_name(instruction.result)).c_str(), + get_prefixed_name(get_name(instruction.result), false).c_str(), instruction_start_index, std::move(members)); break; @@ -2852,7 +2949,7 @@ void Spirv_to_llvm::handle_instruction_op_function(Op_function instruction, auto function_name = get_name(current_function_id); if(function_name.empty() && state.op_entry_points.size() == 1) function_name = std::string(state.op_entry_points[0].entry_point.name); - function_name = get_or_make_prefixed_name(std::move(function_name)); + function_name = get_or_make_prefixed_name(std::move(function_name), false); auto function = ::LLVMAddFunction( module.get(), function_name.c_str(), function_type->get_or_make_type().type); llvm_wrapper::Module::set_function_target_machine(function, target_machine); @@ -8810,11 +8907,14 @@ void Spirv_to_llvm::handle_instruction_glsl_std_450_op_n_clamp(Glsl_std_450_op_n Converted_module spirv_to_llvm(::LLVMContextRef context, ::LLVMTargetMachineRef target_machine, - const Word *shader_words, + const spirv::Word *shader_words, std::size_t shader_size, - std::uint64_t shader_id) + std::uint64_t shader_id, + spirv::Execution_model execution_model, + util::string_view entry_point_name) { - return Spirv_to_llvm(context, target_machine, shader_id).run(shader_words, shader_size); + return Spirv_to_llvm(context, target_machine, shader_id, execution_model, entry_point_name) + .run(shader_words, shader_size); } } } diff --git a/src/spirv_to_llvm/spirv_to_llvm.h b/src/spirv_to_llvm/spirv_to_llvm.h index cd01c09..602ed09 100644 --- a/src/spirv_to_llvm/spirv_to_llvm.h +++ b/src/spirv_to_llvm/spirv_to_llvm.h @@ -406,7 +406,7 @@ public: std::shared_ptr return_type, std::vector> args, std::size_t instruction_start_index, - ::LLVMTargetDataRef target_data, + ::LLVMTargetDataRef target_data, bool is_var_arg = false) noexcept : Type_descriptor(std::move(decorations)), return_type(std::move(return_type)), @@ -559,36 +559,23 @@ public: struct Converted_module { - struct Entry_point - { - std::string name; - std::string entry_function_name; -#warning finish filling in Entry_point - explicit Entry_point(std::string name, std::string entry_function_name) noexcept - : name(std::move(name)), - entry_function_name(std::move(entry_function_name)) - { - } - }; llvm_wrapper::Module module; - std::vector entry_points; + std::string entry_function_name; std::shared_ptr io_struct; std::size_t inputs_member; std::shared_ptr inputs_struct; std::size_t outputs_member; std::shared_ptr outputs_struct; - Converted_module() : module(), entry_points() - { - } + Converted_module() = default; explicit Converted_module(llvm_wrapper::Module module, - std::vector entry_points, + std::string entry_function_name, std::shared_ptr io_struct, std::size_t inputs_member, std::shared_ptr inputs_struct, std::size_t outputs_member, std::shared_ptr outputs_struct) noexcept : module(std::move(module)), - entry_points(std::move(entry_points)), + entry_function_name(std::move(entry_function_name)), io_struct(std::move(io_struct)), inputs_member(inputs_member), inputs_struct(std::move(inputs_struct)), @@ -604,7 +591,9 @@ Converted_module spirv_to_llvm(::LLVMContextRef context, ::LLVMTargetMachineRef target_machine, const spirv::Word *shader_words, std::size_t shader_size, - std::uint64_t shader_id); + std::uint64_t shader_id, + spirv::Execution_model execution_model, + util::string_view entry_point_name); } } -- 2.30.2