From 2b04d910fdd12f9fda20ff54eb49aef7a2b816e9 Mon Sep 17 00:00:00 2001 From: Jacob Lifshay Date: Thu, 17 Aug 2017 01:19:36 -0700 Subject: [PATCH] vertex shader runs --- src/demo/CMakeLists.txt | 2 +- src/demo/demo.cpp | 182 +++++++++++++++++++-------- src/pipeline/pipeline.cpp | 159 +++++++++++++++++++++++- src/pipeline/pipeline.h | 184 +++++++++++++++++++--------- src/spirv_to_llvm/spirv_to_llvm.cpp | 3 +- src/spirv_to_llvm/spirv_to_llvm.h | 22 +++- src/vulkan/util.h | 55 +++++++++ 7 files changed, 490 insertions(+), 117 deletions(-) create mode 100644 src/vulkan/util.h diff --git a/src/demo/CMakeLists.txt b/src/demo/CMakeLists.txt index 5b6bfcf..01ff840 100644 --- a/src/demo/CMakeLists.txt +++ b/src/demo/CMakeLists.txt @@ -21,4 +21,4 @@ cmake_minimum_required(VERSION 3.1 FATAL_ERROR) set(sources demo.cpp) add_executable(demo ${sources}) -target_link_libraries(demo vulkan_cpu_spirv vulkan_cpu_util vulkan_cpu_spirv_to_llvm) +target_link_libraries(demo vulkan_cpu_spirv vulkan_cpu_util vulkan_cpu_pipeline vulkan_cpu_vulkan) diff --git a/src/demo/demo.cpp b/src/demo/demo.cpp index 5c40345..3a9ccc9 100644 --- a/src/demo/demo.cpp +++ b/src/demo/demo.cpp @@ -31,8 +31,8 @@ #include "spirv/parser.h" #include "util/optional.h" #include "util/string_view.h" -#include "spirv_to_llvm/spirv_to_llvm.h" -#include "llvm_wrapper/llvm_wrapper.h" +#include "pipeline/pipeline.h" +#include "vulkan/vulkan.h" namespace vulkan_cpu { @@ -219,61 +219,141 @@ int test_main(int argc, char **argv) auto file = load_file(filename); if(file) { - { - dump_words(*file); - std::cerr << std::endl; - spirv::Dump_callbacks dump_callbacks; - try - { - spirv::parse(dump_callbacks, file->data(), file->size()); - } - catch(spirv::Parser_error &e) - { - std::cerr << dump_callbacks.ss.str() << std::endl; - std::cerr << "error: " << e.what(); - return 1; - } - std::cerr << dump_callbacks.ss.str() << std::endl; - } - auto llvm_target_machine = llvm_wrapper::Target_machine::create_native_target_machine(); - auto llvm_context = llvm_wrapper::Context::create(); - std::uint64_t next_module_id = 1; - spirv_to_llvm::Converted_module converted_module; + dump_words(*file); + std::cerr << std::endl; try { - converted_module = spirv_to_llvm::spirv_to_llvm(llvm_context.get(), - llvm_target_machine.get(), - file->data(), - file->size(), - next_module_id++, - spirv::Execution_model::vertex, - "main"); + VkShaderModuleCreateInfo shader_module_create_info = { + .sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO, + .pNext = nullptr, + .flags = 0, + .codeSize = file->size() * sizeof(spirv::Word), + .pCode = file->data(), + }; + auto shader_module = pipeline::Shader_module_handle::make(shader_module_create_info); + VkPipelineLayoutCreateInfo pipeline_layout_create_info = { + .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, + .pNext = nullptr, + .flags = 0, + .setLayoutCount = 0, + .pSetLayouts = nullptr, + .pushConstantRangeCount = 0, + .pPushConstantRanges = nullptr, + }; + auto pipeline_layout = + pipeline::Pipeline_layout_handle::make(pipeline_layout_create_info); + constexpr std::size_t subpass_count = 1; + VkSubpassDescription subpass_descriptions[subpass_count] = { + { + .flags = 0, + .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS, + .inputAttachmentCount = 0, + .pInputAttachments = nullptr, + .colorAttachmentCount = 0, + .pColorAttachments = nullptr, + .pResolveAttachments = nullptr, + .pDepthStencilAttachment = nullptr, + .preserveAttachmentCount = 0, + .pPreserveAttachments = nullptr, + }, + }; + VkRenderPassCreateInfo render_pass_create_info = { + .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, + .pNext = nullptr, + .flags = 0, + .attachmentCount = 0, + .pAttachments = nullptr, + .subpassCount = subpass_count, + .pSubpasses = subpass_descriptions, + .dependencyCount = 0, + .pDependencies = nullptr, + }; + auto render_pass = pipeline::Render_pass_handle::make(render_pass_create_info); + constexpr std::size_t stage_count = 1; + VkPipelineShaderStageCreateInfo stages[stage_count] = { + { + .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, + .pNext = nullptr, + .flags = 0, + .stage = VK_SHADER_STAGE_VERTEX_BIT, + .module = pipeline::to_handle(shader_module.get()), + .pName = "main", + .pSpecializationInfo = nullptr, + }, + }; + VkPipelineVertexInputStateCreateInfo pipeline_vertex_input_state_create_info = { + .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, + .pNext = nullptr, + .flags = 0, + .vertexBindingDescriptionCount = 0, + .pVertexBindingDescriptions = nullptr, + .vertexAttributeDescriptionCount = 0, + .pVertexAttributeDescriptions = nullptr, + }; + VkPipelineInputAssemblyStateCreateInfo pipeline_input_assembly_state_create_info = { + .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, + .pNext = nullptr, + .flags = 0, + .topology = VK_PRIMITIVE_TOPOLOGY_POINT_LIST, + .primitiveRestartEnable = false, + }; + VkPipelineRasterizationStateCreateInfo pipeline_rasterization_state_create_info = { + .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, + .pNext = nullptr, + .flags = 0, + .depthClampEnable = false, + .rasterizerDiscardEnable = true, + .polygonMode = VK_POLYGON_MODE_FILL, + .cullMode = VK_CULL_MODE_BACK_BIT, + .frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE, + .depthBiasEnable = false, + .depthBiasConstantFactor = 0, + .depthBiasClamp = 0, + .depthBiasSlopeFactor = 0, + .lineWidth = 1, + }; + VkGraphicsPipelineCreateInfo graphics_pipeline_create_info = { + .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, + .pNext = nullptr, + .flags = 0, + .stageCount = stage_count, + .pStages = stages, + .pVertexInputState = &pipeline_vertex_input_state_create_info, + .pInputAssemblyState = &pipeline_input_assembly_state_create_info, + .pTessellationState = nullptr, + .pViewportState = nullptr, + .pRasterizationState = &pipeline_rasterization_state_create_info, + .pMultisampleState = nullptr, + .pDepthStencilState = nullptr, + .pColorBlendState = nullptr, + .pDynamicState = nullptr, + .layout = pipeline::to_handle(pipeline_layout.get()), + .renderPass = pipeline::to_handle(render_pass.get()), + .subpass = 0, + .basePipelineHandle = VK_NULL_HANDLE, + .basePipelineIndex = -1, + }; + auto graphics_pipeline = + pipeline::Graphics_pipeline::make(nullptr, graphics_pipeline_create_info); + std::cerr << "vertex_shader_output_struct_size: " + << graphics_pipeline->get_vertex_shader_output_struct_size() << std::endl; + constexpr std::uint32_t vertex_start_index = 0; + constexpr std::uint32_t vertex_end_index = 3; + constexpr std::uint32_t instance_id = 0; + constexpr std::size_t vertex_count = vertex_end_index - vertex_start_index; + std::unique_ptr output_buffer( + new unsigned char[graphics_pipeline->get_vertex_shader_output_struct_size() + * vertex_count]); + auto vertex_shader_function = graphics_pipeline->get_vertex_shader_function(); + vertex_shader_function( + vertex_start_index, vertex_end_index, instance_id, output_buffer.get()); + std::cerr << "shader completed" << std::endl; } - catch(spirv::Parser_error &e) + catch(std::runtime_error &e) { - std::cerr << "error: " << e.what(); + std::cerr << "error: " << e.what() << std::endl; return 1; } - std::cerr << "Translation to LLVM succeeded." << std::endl; - ::LLVMDumpModule(converted_module.module.get()); - bool failed = - ::LLVMVerifyModule(converted_module.module.get(), ::LLVMPrintMessageAction, nullptr); - if(failed) - return 1; - auto orc_jit_stack = llvm_wrapper::Orc_jit_stack::create(std::move(llvm_target_machine)); - orc_jit_stack.add_eagerly_compiled_ir( - std::move(converted_module.module), - [](const char *symbol_name, [[gnu::unused]] void *user_data) noexcept->std::uint64_t - { - std::cerr << "resolving symbol: " << symbol_name << std::endl; - void *symbol = nullptr; - return reinterpret_cast(symbol); - }, - nullptr); - 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 << ": " << reinterpret_cast(function) - << std::endl; } else { diff --git a/src/pipeline/pipeline.cpp b/src/pipeline/pipeline.cpp index 11d7ce5..20544e4 100644 --- a/src/pipeline/pipeline.cpp +++ b/src/pipeline/pipeline.cpp @@ -21,17 +21,174 @@ * */ #include "pipeline.h" +#include "spirv_to_llvm/spirv_to_llvm.h" +#include "llvm_wrapper/llvm_wrapper.h" +#include "vulkan/util.h" #include +#include +#include +#include namespace vulkan_cpu { namespace pipeline { +class Pipeline_cache +{ +}; + +void Api_object_deleter::operator()(Pipeline_cache *pipeline_cache) const noexcept +{ + delete pipeline_cache; +} + +class Render_pass +{ +}; + +void Api_object_deleter::operator()(Render_pass *render_pass) const noexcept +{ + delete render_pass; +} + +template <> +Render_pass_handle Render_pass_handle::make(const VkRenderPassCreateInfo &render_pass_create_info) +{ +#warning finish implementing Render_pass_handle::make + return Render_pass_handle(new Render_pass()); +} + +class Pipeline_layout +{ +}; + +void Api_object_deleter::operator()(Pipeline_layout *pipeline_layout) const + noexcept +{ + delete pipeline_layout; +} + +template <> +Pipeline_layout_handle Pipeline_layout_handle::make( + const VkPipelineLayoutCreateInfo &pipeline_layout_create_info) +{ +#warning finish implementing Pipeline_layout_handle::make + return Pipeline_layout_handle(new Pipeline_layout()); +} + +struct Graphics_pipeline::Implementation +{ + spirv_to_llvm::Jit_symbol_resolver jit_symbol_resolver; + llvm_wrapper::Orc_jit_stack jit_stack; + llvm_wrapper::Context llvm_context = llvm_wrapper::Context::create(); + std::uint64_t next_module_id = 1; + std::uint64_t make_module_id() noexcept + { + return next_module_id++; + } +}; + std::unique_ptr Graphics_pipeline::make( Pipeline_cache *pipeline_cache, const VkGraphicsPipelineCreateInfo &create_info) { + assert(create_info.sType == VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO); + auto *render_pass = Render_pass_handle::from_handle(create_info.renderPass); + assert(render_pass); + auto *pipeline_layout = Pipeline_layout_handle::from_handle(create_info.layout); + assert(pipeline_layout); + if(create_info.flags & VK_PIPELINE_CREATE_DERIVATIVE_BIT) + { +#warning implement creating derived pipelines + throw std::runtime_error("creating derived pipelines is not implemented"); + } + auto implementation = std::make_shared(); + auto llvm_target_machine = llvm_wrapper::Target_machine::create_native_target_machine(); + std::vector compiled_shaders; + compiled_shaders.reserve(create_info.stageCount); + for(std::size_t i = 0; i < create_info.stageCount; i++) + { + auto &stage_info = create_info.pStages[i]; + auto execution_models = + vulkan::get_execution_models_from_shader_stage_flags(stage_info.stage); + assert(execution_models.size() == 1); + auto execution_model = *execution_models.begin(); + auto *shader_module = Shader_module_handle::from_handle(stage_info.module); + assert(shader_module); + { + spirv::Dump_callbacks dump_callbacks; + try + { + spirv::parse(dump_callbacks, shader_module->words(), shader_module->word_count()); + } + catch(spirv::Parser_error &e) + { + std::cerr << dump_callbacks.ss.str() << std::endl; + throw; + } + std::cerr << dump_callbacks.ss.str() << std::endl; + } + auto compiled_shader = spirv_to_llvm::spirv_to_llvm(implementation->llvm_context.get(), + llvm_target_machine.get(), + shader_module->words(), + shader_module->word_count(), + implementation->make_module_id(), + execution_model, + stage_info.pName); + std::cerr << "Translation to LLVM succeeded." << std::endl; + ::LLVMDumpModule(compiled_shader.module.get()); + bool failed = + ::LLVMVerifyModule(compiled_shader.module.get(), ::LLVMPrintMessageAction, nullptr); + if(failed) + throw std::runtime_error("LLVM module verification failed"); + compiled_shaders.push_back(std::move(compiled_shader)); + } + auto data_layout = llvm_target_machine.create_target_data_layout(); + implementation->jit_stack = llvm_wrapper::Orc_jit_stack::create(std::move(llvm_target_machine)); + Vertex_shader_function vertex_shader_function = nullptr; + std::size_t vertex_shader_output_struct_size = 0; + for(auto &compiled_shader : compiled_shaders) + { + vertex_shader_output_struct_size = implementation->jit_stack.add_eagerly_compiled_ir( + std::move(compiled_shader.module), + &spirv_to_llvm::Jit_symbol_resolver::resolve, + static_cast(&implementation->jit_symbol_resolver)); + auto shader_entry_point_address = implementation->jit_stack.get_symbol_address( + compiled_shader.entry_function_name.c_str()); + std::cerr << "shader entry: " << compiled_shader.entry_function_name << ": " + << reinterpret_cast(shader_entry_point_address) << std::endl; + assert(shader_entry_point_address); + switch(compiled_shader.execution_model) + { + case spirv::Execution_model::fragment: +#warning finish implementing Graphics_pipeline::make + throw std::runtime_error("creating fragment shaders is not implemented"); + case spirv::Execution_model::geometry: +#warning finish implementing Graphics_pipeline::make + throw std::runtime_error("creating geometry shaders is not implemented"); + case spirv::Execution_model::gl_compute: + case spirv::Execution_model::kernel: + throw std::runtime_error("can't create compute shaders from Graphics_pipeline::make"); + case spirv::Execution_model::tessellation_control: + case spirv::Execution_model::tessellation_evaluation: +#warning finish implementing Graphics_pipeline::make + throw std::runtime_error("creating tessellation shaders is not implemented"); + case spirv::Execution_model::vertex: + { + vertex_shader_function = + reinterpret_cast(shader_entry_point_address); + vertex_shader_output_struct_size = ::LLVMABISizeOfType( + data_layout.get(), compiled_shader.outputs_struct->get_or_make_type().type); +#warning finish implementing Graphics_pipeline::make + continue; + } + } + throw std::runtime_error("unknown shader kind"); + } #warning finish implementing Graphics_pipeline::make - throw std::runtime_error("Graphics_pipeline::make is not implemented"); + if(!vertex_shader_function) + throw std::runtime_error("graphics pipeline doesn't have vertex shader"); + return std::unique_ptr(new Graphics_pipeline( + std::move(implementation), vertex_shader_function, vertex_shader_output_struct_size)); } } } diff --git a/src/pipeline/pipeline.h b/src/pipeline/pipeline.h index 54b4e57..6060044 100644 --- a/src/pipeline/pipeline.h +++ b/src/pipeline/pipeline.h @@ -27,86 +27,138 @@ #include #include #include +#include #include "llvm_wrapper/llvm_wrapper.h" #include "vulkan/vulkan.h" +#include "spirv/spirv.h" namespace vulkan_cpu { namespace pipeline { -class Pipeline_cache; - -class Pipeline_cache_handle +template +struct Api_object_deleter { -private: - static void destroy(Pipeline_cache *value) noexcept; + void operator()(T *) const noexcept = delete; + typedef void Vulkan_handle; + typedef void Create_info; +}; -public: - explicit Pipeline_cache_handle(Pipeline_cache *value) noexcept : value(value) - { - } - constexpr Pipeline_cache_handle() noexcept : value(nullptr) - { - } - Pipeline_cache_handle(Pipeline_cache_handle &&rt) noexcept : value(rt.value) - { - rt.value = nullptr; - } - Pipeline_cache_handle &operator=(Pipeline_cache_handle rt) noexcept - { - swap(rt); - return *this; - } - ~Pipeline_cache_handle() noexcept - { - if(value) - destroy(value); - } - void swap(Pipeline_cache_handle &rt) noexcept - { - using std::swap; - swap(value, rt.value); - } - static Pipeline_cache *from_handle(VkPipelineCache pipeline_cache) noexcept +template +struct Api_object_handle : public std::unique_ptr> +{ + typedef typename Api_object_deleter::Vulkan_handle Vulkan_handle; + typedef typename Api_object_deleter::Create_info Create_info; + typedef Object_ Object; + using std::unique_ptr>::unique_ptr; + static Object *from_handle(Vulkan_handle vulkan_handle) noexcept { - return reinterpret_cast(pipeline_cache); + return reinterpret_cast(vulkan_handle); } - static Pipeline_cache_handle move_from_handle(VkPipelineCache pipeline_cache) noexcept + static Api_object_handle move_from_handle(Vulkan_handle vulkan_handle) noexcept { - return Pipeline_cache_handle(from_handle(pipeline_cache)); + return Api_object_handle(from_handle(vulkan_handle)); } - Pipeline_cache *get() const noexcept + static Api_object_handle make(const Create_info &create_info); +}; + +template +inline typename Api_object_deleter::Vulkan_handle to_handle(Object *object) noexcept +{ + static_assert(!std::is_void::Vulkan_handle>::value, ""); + return reinterpret_cast::Vulkan_handle>(object); +} + +template +inline typename Api_object_deleter::Vulkan_handle move_to_handle( + Api_object_handle object) noexcept +{ + return to_handle(object.release()); +} + +class Pipeline_cache; + +template <> +struct Api_object_deleter +{ + void operator()(Pipeline_cache *pipeline_cache) const noexcept; + typedef VkPipelineCache Vulkan_handle; + typedef VkPipelineCacheCreateInfo Create_info; +}; + +typedef Api_object_handle Pipeline_cache_handle; + +class Render_pass; + +template <> +struct Api_object_deleter +{ + void operator()(Render_pass *render_pass) const noexcept; + typedef VkRenderPass Vulkan_handle; + typedef VkRenderPassCreateInfo Create_info; +}; + +typedef Api_object_handle Render_pass_handle; + +class Pipeline_layout; + +template <> +struct Api_object_deleter +{ + void operator()(Pipeline_layout *pipeline_layout) const noexcept; + typedef VkPipelineLayout Vulkan_handle; + typedef VkPipelineLayoutCreateInfo Create_info; +}; + +typedef Api_object_handle Pipeline_layout_handle; + +struct Shader_module +{ + std::shared_ptr bytes; + std::size_t byte_count; + Shader_module(std::shared_ptr bytes, std::size_t byte_count) noexcept + : bytes(std::move(bytes)), + byte_count(byte_count) { - return value; } - Pipeline_cache *release() noexcept + const spirv::Word *words() const noexcept { - auto retval = value; - value = nullptr; - return retval; + return reinterpret_cast(bytes.get()); } - Pipeline_cache *operator->() const noexcept + std::size_t word_count() const noexcept { - assert(value); - return value; + assert(byte_count % sizeof(spirv::Word) == 0); + return byte_count / sizeof(spirv::Word); } - Pipeline_cache &operator*() const noexcept +}; + +template <> +struct Api_object_deleter +{ + void operator()(Shader_module *shader_module) const noexcept { - return *operator->(); + delete shader_module; } - -private: - Pipeline_cache *value; + typedef VkShaderModule Vulkan_handle; + typedef VkShaderModuleCreateInfo Create_info; }; -inline VkPipelineCache to_handle(Pipeline_cache *pipeline_cache) noexcept -{ - return reinterpret_cast(pipeline_cache); -} +typedef Api_object_handle Shader_module_handle; -inline VkPipelineCache move_to_handle(Pipeline_cache_handle pipeline_cache) noexcept +template <> +inline Shader_module_handle Shader_module_handle::make(const VkShaderModuleCreateInfo &create_info) { - return to_handle(pipeline_cache.release()); + struct Code_deleter + { + void operator()(unsigned char *bytes) const noexcept + { + delete[] bytes; + } + }; + auto bytes = + std::shared_ptr(new unsigned char[create_info.codeSize], Code_deleter{}); + std::memcpy(bytes.get(), create_info.pCode, create_info.codeSize); + return Shader_module_handle(new Shader_module(std::move(bytes), create_info.codeSize)); } class Pipeline @@ -141,6 +193,9 @@ inline VkPipeline move_to_handle(std::unique_ptr pipeline) noexcept class Graphics_pipeline final : public Pipeline { +private: + struct Implementation; + public: #warning finish adding draw function parameters typedef void (*Vertex_shader_function)(std::uint32_t vertex_start_index, @@ -149,10 +204,14 @@ public: void *output_buffer); public: - const Vertex_shader_function get_vertex_shader_function() const noexcept + Vertex_shader_function get_vertex_shader_function() const noexcept { return vertex_shader_function; } + std::size_t get_vertex_shader_output_struct_size() const noexcept + { + return vertex_shader_output_struct_size; + } static std::unique_ptr make(Pipeline_cache *pipeline_cache, const VkGraphicsPipelineCreateInfo &create_info); static std::unique_ptr move_from_handle(VkPipeline pipeline) noexcept @@ -167,16 +226,19 @@ public: } private: - Graphics_pipeline(std::shared_ptr state, - Vertex_shader_function vertex_shader_function) noexcept - : state(std::move(state)), - vertex_shader_function(vertex_shader_function) + Graphics_pipeline(std::shared_ptr implementation, + Vertex_shader_function vertex_shader_function, + std::size_t vertex_shader_output_struct_size) noexcept + : implementation(std::move(implementation)), + vertex_shader_function(vertex_shader_function), + vertex_shader_output_struct_size(vertex_shader_output_struct_size) { } private: - std::shared_ptr state; + std::shared_ptr implementation; Vertex_shader_function vertex_shader_function; + std::size_t vertex_shader_output_struct_size; }; inline VkPipeline to_handle(Graphics_pipeline *pipeline) noexcept diff --git a/src/spirv_to_llvm/spirv_to_llvm.cpp b/src/spirv_to_llvm/spirv_to_llvm.cpp index 423507c..9e7eadc 100644 --- a/src/spirv_to_llvm/spirv_to_llvm.cpp +++ b/src/spirv_to_llvm/spirv_to_llvm.cpp @@ -1590,7 +1590,8 @@ public: return Converted_module(std::move(module), std::move(entry_function_name), std::move(inputs_struct), - std::move(outputs_struct)); + std::move(outputs_struct), + execution_model); } virtual void handle_header(unsigned version_number_major, unsigned version_number_minor, diff --git a/src/spirv_to_llvm/spirv_to_llvm.h b/src/spirv_to_llvm/spirv_to_llvm.h index 42ed3f4..1291233 100644 --- a/src/spirv_to_llvm/spirv_to_llvm.h +++ b/src/spirv_to_llvm/spirv_to_llvm.h @@ -570,19 +570,37 @@ struct Converted_module std::string entry_function_name; std::shared_ptr inputs_struct; std::shared_ptr outputs_struct; + spirv::Execution_model execution_model; Converted_module() = default; explicit Converted_module(llvm_wrapper::Module module, std::string entry_function_name, std::shared_ptr inputs_struct, - std::shared_ptr outputs_struct) noexcept + std::shared_ptr outputs_struct, + spirv::Execution_model execution_model) noexcept : module(std::move(module)), entry_function_name(std::move(entry_function_name)), inputs_struct(std::move(inputs_struct)), - outputs_struct(std::move(outputs_struct)) + outputs_struct(std::move(outputs_struct)), + execution_model(execution_model) { } }; +struct Jit_symbol_resolver +{ + typedef void (*Resolved_symbol)(); + Resolved_symbol resolve(const char *name) + { +#warning finish implementing + return nullptr; + } + static std::uint64_t resolve(const char *name, void *user_data) noexcept + { + return reinterpret_cast( + static_cast(user_data)->resolve(name)); + } +}; + class Spirv_to_llvm; Converted_module spirv_to_llvm(::LLVMContextRef context, diff --git a/src/vulkan/util.h b/src/vulkan/util.h new file mode 100644 index 0000000..98edf17 --- /dev/null +++ b/src/vulkan/util.h @@ -0,0 +1,55 @@ +/* + * 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 VULKAN_UTIL_H_ +#define VULKAN_UTIL_H_ + +#include "vulkan/vulkan.h" +#include "spirv/spirv.h" +#include "util/enum.h" + +namespace vulkan_cpu +{ +namespace vulkan +{ +constexpr util::Enum_set get_execution_models_from_shader_stage_flags( + VkShaderStageFlags stages) noexcept +{ + util::Enum_set retval; + if(stages & VK_SHADER_STAGE_COMPUTE_BIT) + retval.insert(spirv::Execution_model::gl_compute); + if(stages & VK_SHADER_STAGE_FRAGMENT_BIT) + retval.insert(spirv::Execution_model::fragment); + if(stages & VK_SHADER_STAGE_GEOMETRY_BIT) + retval.insert(spirv::Execution_model::geometry); + if(stages & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) + retval.insert(spirv::Execution_model::tessellation_control); + if(stages & VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) + retval.insert(spirv::Execution_model::tessellation_evaluation); + if(stages & VK_SHADER_STAGE_VERTEX_BIT) + retval.insert(spirv::Execution_model::vertex); + return retval; +} +} +} + +#endif // VULKAN_UTIL_H_ -- 2.30.2