#
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)
llvm_target_machine.get(),
file->data(),
file->size(),
- next_module_id++);
+ next_module_id++,
+ spirv::Execution_model::vertex,
+ "main");
}
catch(spirv::Parser_error &e)
{
return reinterpret_cast<std::uintptr_t>(symbol);
},
nullptr);
- for(auto &entry_point : converted_module.entry_points)
- {
- auto function = reinterpret_cast<void *>(
- 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<void *>(
+ 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
{
return get_symbol<T>(get(), symbol_name);
}
};
+
+template <typename T>
+struct Create_llvm_type
+{
+ static_assert(!std::is_same<T, T>::value, "Create_llvm_type not implemented for type T");
+ ::LLVMTypeRef operator()(::LLVMContextRef context) const = delete;
+};
+
+template <typename T>
+struct Create_llvm_type<const T> : public Create_llvm_type<T>
+{
+};
+
+template <>
+struct Create_llvm_type<void>
+{
+ ::LLVMTypeRef operator()(::LLVMContextRef context) const
+ {
+ return ::LLVMVoidTypeInContext(context);
+ }
+};
+
+template <>
+struct Create_llvm_type<bool>
+{
+ ::LLVMTypeRef operator()(::LLVMContextRef context) const
+ {
+ return ::LLVMIntTypeInContext(context,
+ std::numeric_limits<unsigned char>::digits * sizeof(bool));
+ }
+};
+
+template <>
+struct Create_llvm_type<char>
+{
+ ::LLVMTypeRef operator()(::LLVMContextRef context) const
+ {
+ return ::LLVMIntTypeInContext(context, std::numeric_limits<unsigned char>::digits);
+ }
+};
+
+template <>
+struct Create_llvm_type<unsigned char>
+{
+ ::LLVMTypeRef operator()(::LLVMContextRef context) const
+ {
+ return ::LLVMIntTypeInContext(context, std::numeric_limits<unsigned char>::digits);
+ }
+};
+
+template <>
+struct Create_llvm_type<signed char>
+{
+ ::LLVMTypeRef operator()(::LLVMContextRef context) const
+ {
+ return ::LLVMIntTypeInContext(context, std::numeric_limits<unsigned char>::digits);
+ }
+};
+
+template <>
+struct Create_llvm_type<short>
+{
+ ::LLVMTypeRef operator()(::LLVMContextRef context) const
+ {
+ return ::LLVMIntTypeInContext(context, std::numeric_limits<unsigned short>::digits);
+ }
+};
+
+template <>
+struct Create_llvm_type<unsigned short>
+{
+ ::LLVMTypeRef operator()(::LLVMContextRef context) const
+ {
+ return ::LLVMIntTypeInContext(context, std::numeric_limits<unsigned short>::digits);
+ }
+};
+
+template <>
+struct Create_llvm_type<int>
+{
+ ::LLVMTypeRef operator()(::LLVMContextRef context) const
+ {
+ return ::LLVMIntTypeInContext(context, std::numeric_limits<unsigned>::digits);
+ }
+};
+
+template <>
+struct Create_llvm_type<unsigned>
+{
+ ::LLVMTypeRef operator()(::LLVMContextRef context) const
+ {
+ return ::LLVMIntTypeInContext(context, std::numeric_limits<unsigned>::digits);
+ }
+};
+
+template <>
+struct Create_llvm_type<long>
+{
+ ::LLVMTypeRef operator()(::LLVMContextRef context) const
+ {
+ return ::LLVMIntTypeInContext(context, std::numeric_limits<unsigned long>::digits);
+ }
+};
+
+template <>
+struct Create_llvm_type<unsigned long>
+{
+ ::LLVMTypeRef operator()(::LLVMContextRef context) const
+ {
+ return ::LLVMIntTypeInContext(context, std::numeric_limits<unsigned long>::digits);
+ }
+};
+
+template <>
+struct Create_llvm_type<long long>
+{
+ ::LLVMTypeRef operator()(::LLVMContextRef context) const
+ {
+ return ::LLVMIntTypeInContext(context, std::numeric_limits<unsigned long long>::digits);
+ }
+};
+
+template <>
+struct Create_llvm_type<unsigned long long>
+{
+ ::LLVMTypeRef operator()(::LLVMContextRef context) const
+ {
+ return ::LLVMIntTypeInContext(context, std::numeric_limits<unsigned long long>::digits);
+ }
+};
+
+template <typename T>
+struct Create_llvm_type<T *>
+{
+ ::LLVMTypeRef operator()(::LLVMContextRef context) const
+ {
+ constexpr unsigned default_address_space = 0;
+ return ::LLVMPointerType(Create_llvm_type<T>()(context), default_address_space);
+ }
+};
+
+template <>
+struct Create_llvm_type<void *> : public Create_llvm_type<unsigned char *>
+{
+};
+
+template <>
+struct Create_llvm_type<const void *> : public Create_llvm_type<const unsigned char *>
+{
+};
+
+template <typename T, std::size_t N>
+struct Create_llvm_type<T[N]>
+{
+ ::LLVMTypeRef operator()(::LLVMContextRef context) const
+ {
+ return ::LLVMArrayType(Create_llvm_type<T>()(context), N);
+ }
+};
+
+template <typename Return_type, typename ...Args>
+struct Create_llvm_type<Return_type (*)(Args...)>
+{
+ ::LLVMTypeRef operator()(::LLVMContextRef context) const
+ {
+ ::LLVMTypeRef arguments[] = {Create_llvm_type<Args>()(context)...};
+ constexpr bool is_var_arg = false;
+ return ::LLVMFunctionType(
+ Create_llvm_type<Return_type>()(context), arguments, sizeof...(Args), is_var_arg);
+ }
+};
}
}
--- /dev/null
+# 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)
--- /dev/null
+/*
+ * 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"
--- /dev/null
+/*
+ * 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 <memory>
+#include <cstdint>
+#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<Pipeline> move_from_handle(Handle pipeline) noexcept
+ {
+ return std::unique_ptr<Pipeline>(from_handle(pipeline));
+ }
+ static Pipeline *from_handle(Handle pipeline) noexcept
+ {
+ return reinterpret_cast<Pipeline *>(pipeline);
+ }
+};
+
+inline Pipeline::Handle to_handle(Pipeline *pipeline) noexcept
+{
+ return reinterpret_cast<Pipeline::Handle>(pipeline);
+}
+
+inline Pipeline::Handle move_to_handle(std::unique_ptr<Pipeline> 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<Graphics_pipeline> make();
+ static std::unique_ptr<Graphics_pipeline> move_from_handle(Handle pipeline) noexcept
+ {
+ return std::unique_ptr<Graphics_pipeline>(from_handle(pipeline));
+ }
+ static Graphics_pipeline *from_handle(Handle pipeline) noexcept
+ {
+ auto *retval = reinterpret_cast<Pipeline *>(pipeline);
+ assert(!retval || dynamic_cast<Graphics_pipeline *>(retval));
+ return static_cast<Graphics_pipeline *>(retval);
+ }
+
+private:
+ Graphics_pipeline(std::shared_ptr<void> state,
+ Vertex_shader_function vertex_shader_function) noexcept
+ : state(std::move(state)),
+ vertex_shader_function(vertex_shader_function)
+ {
+ }
+
+private:
+ std::shared_ptr<void> state;
+ Vertex_shader_function vertex_shader_function;
+};
+
+inline Pipeline::Handle to_handle(Graphics_pipeline *pipeline) noexcept
+{
+ return to_handle(static_cast<Pipeline *>(pipeline));
+}
+
+inline Pipeline::Handle move_to_handle(std::unique_ptr<Graphics_pipeline> pipeline) noexcept
+{
+ return to_handle(pipeline.release());
+}
+}
+}
+
+#endif // PIPELINE_PIPELINE_H_
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)
#include "util/optional.h"
#include "util/variant.h"
#include "util/enum.h"
+#include "pipeline/pipeline.h"
#include <functional>
#include <list>
#include <iostream>
llvm_wrapper::Builder builder;
util::optional<Last_merge_instruction> last_merge_instruction;
std::list<std::function<void()>> function_entry_block_handlers;
+ spirv::Execution_model execution_model;
+ util::string_view entry_point_name;
private:
Id_state &get_id_state(Id id)
{
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())
{
// 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())
{
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;
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;
std::make_shared<Struct_type_descriptor>(std::vector<Decoration_with_parameters>{},
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, "");
std::make_shared<Struct_type_descriptor>(std::vector<Decoration_with_parameters>{},
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<Struct_type_descriptor>(std::vector<Decoration_with_parameters>{},
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<Vertex_shader_function,
+ pipeline::Graphics_pipeline::Vertex_shader_function>::value,
+ "vertex shader function signature mismatch");
+ auto function_type = llvm_wrapper::Create_llvm_type<Vertex_shader_function>()(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<void>(arg_vertex_start_index);
+ static_cast<void>(arg_vertex_count);
+ static_cast<void>(arg_instance_id);
+ static_cast<void>(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;
#warning finish Spirv_to_llvm::run
stage = Stage::generate_code;
spirv::parse(*this, shader_words, shader_size);
- std::vector<Converted_module::Entry_point> entry_points;
+ std::string entry_function_name;
for(auto &id_state : id_states)
{
for(auto &entry_point : id_state.op_entry_points)
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,
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;
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);
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);
}
}
}
std::shared_ptr<Type_descriptor> return_type,
std::vector<std::shared_ptr<Type_descriptor>> 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)),
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_point> entry_points;
+ std::string entry_function_name;
std::shared_ptr<Struct_type_descriptor> io_struct;
std::size_t inputs_member;
std::shared_ptr<Struct_type_descriptor> inputs_struct;
std::size_t outputs_member;
std::shared_ptr<Struct_type_descriptor> outputs_struct;
- Converted_module() : module(), entry_points()
- {
- }
+ Converted_module() = default;
explicit Converted_module(llvm_wrapper::Module module,
- std::vector<Entry_point> entry_points,
+ std::string entry_function_name,
std::shared_ptr<Struct_type_descriptor> io_struct,
std::size_t inputs_member,
std::shared_ptr<Struct_type_descriptor> inputs_struct,
std::size_t outputs_member,
std::shared_ptr<Struct_type_descriptor> 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)),
::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);
}
}