implement creating graphics pipelines through vulkan api
authorJacob Lifshay <programmerjake@gmail.com>
Fri, 22 Sep 2017 03:58:49 +0000 (20:58 -0700)
committerJacob Lifshay <programmerjake@gmail.com>
Fri, 22 Sep 2017 03:58:49 +0000 (20:58 -0700)
src/pipeline/pipeline.h
src/vulkan/api_objects.cpp
src/vulkan/api_objects.h
src/vulkan_icd/vulkan_icd.cpp

index 04a37a962664c711eda083c2399bc4f17dcd041c..637f363147eecf05239f7667c393832fe1f9589c 100644 (file)
@@ -196,6 +196,9 @@ private:
     VkViewport viewport;
     VkRect2D scissor_rect;
 };
+
+using vulkan::move_to_handle;
+using vulkan::to_handle;
 }
 }
 
index 11f02d8017636a0e77a0d8632b8c5bbdb7b0be99..693a754f76fdc29c4046fcc7b9c125e03d91bdb4 100644 (file)
@@ -568,11 +568,33 @@ std::unique_ptr<Vulkan_descriptor_set_layout> Vulkan_descriptor_set_layout::crea
     assert(create_info.bindingCount == 0 || create_info.pBindings);
     std::vector<Binding> bindings;
     bindings.reserve(create_info.bindingCount);
-    for(std::uint32_t i = 0; i<create_info.bindingCount;i++)
+    for(std::uint32_t i = 0; i < create_info.bindingCount; i++)
         bindings.emplace_back(create_info.pBindings[i]);
     return std::make_unique<Vulkan_descriptor_set_layout>(std::move(bindings));
 }
 
+std::unique_ptr<Vulkan_pipeline_layout> Vulkan_pipeline_layout::create(
+    Vulkan_device &device, const VkPipelineLayoutCreateInfo &create_info)
+{
+    assert(create_info.sType == VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO);
+    assert(create_info.setLayoutCount == 0 || create_info.pSetLayouts);
+    assert(create_info.pushConstantRangeCount == 0 || create_info.pPushConstantRanges);
+    std::vector<Vulkan_descriptor_set_layout *> descriptor_set_layouts;
+    descriptor_set_layouts.reserve(create_info.setLayoutCount);
+    for(std::uint32_t i = 0; i < create_info.setLayoutCount; i++)
+    {
+        auto *descriptor_set_layout =
+            Vulkan_descriptor_set_layout::from_handle(create_info.pSetLayouts[i]);
+        assert(descriptor_set_layout);
+        descriptor_set_layouts.push_back(descriptor_set_layout);
+    }
+    std::vector<VkPushConstantRange> push_constant_ranges(
+        create_info.pPushConstantRanges,
+        create_info.pPushConstantRanges + create_info.pushConstantRangeCount);
+    return std::make_unique<Vulkan_pipeline_layout>(std::move(descriptor_set_layouts),
+                                                    std::move(push_constant_ranges));
+}
+
 std::unique_ptr<Vulkan_render_pass> Vulkan_render_pass::create(
     Vulkan_device &device, const VkRenderPassCreateInfo &create_info)
 {
@@ -680,7 +702,7 @@ std::unique_ptr<Vulkan_render_pass> Vulkan_render_pass::create(
     {
         static std::atomic_bool wrote_warning{false};
         if(!wrote_warning.exchange(true, std::memory_order::memory_order_relaxed))
-            std::cerr << "depth stencil attachments not supported" << std::endl;
+            std::cerr << "depth stencil attachments not implemented" << std::endl;
     }
     return std::make_unique<Vulkan_render_pass>(
         std::move(attachments), *color_attachment_index, depth_stencil_attachment_index);
index 2b697e472523dcd3bfa8fd52ef56f71374da33e6..df8b6a5a33b5677dd460408560a404dc772d9966 100644 (file)
@@ -1490,15 +1490,15 @@ struct Vulkan_nondispatchable_object
 
 template <typename Object_type>
 typename std::
-    enable_if<std::is_base_of<Vulkan_dispatchable_object<Object_type,
+    enable_if<std::is_base_of<Vulkan_dispatchable_object<typename Object_type::Object,
                                                          typename Object_type::Vulkan_handle>,
                               Object_type>::value,
               typename Object_type::Vulkan_handle>::type
     to_handle(Object_type *object) noexcept
 {
     return reinterpret_cast<typename Object_type::Vulkan_handle>(
-        static_cast<Vulkan_dispatchable_object<Object_type, typename Object_type::Vulkan_handle> *>(
-            object));
+        static_cast<Vulkan_dispatchable_object<typename Object_type::Object,
+                                               typename Object_type::Vulkan_handle> *>(object));
 }
 
 template <typename Object_type>
@@ -1510,15 +1510,15 @@ decltype(to_handle(static_cast<Object_type *>(nullptr))) move_to_handle(
 
 template <typename Object_type, typename = void>
 typename std::
-    enable_if<std::is_base_of<Vulkan_nondispatchable_object<Object_type,
+    enable_if<std::is_base_of<Vulkan_nondispatchable_object<typename Object_type::Object,
                                                             typename Object_type::Vulkan_handle>,
                               Object_type>::value,
               typename Object_type::Vulkan_handle>::type
     to_handle(Object_type *object) noexcept
 {
     return reinterpret_cast<typename Object_type::Vulkan_handle>(
-        static_cast<Vulkan_nondispatchable_object<Object_type, typename Object_type::Vulkan_handle>
-                        *>(object));
+        static_cast<Vulkan_nondispatchable_object<typename Object_type::Object,
+                                                  typename Object_type::Vulkan_handle> *>(object));
 }
 
 struct Vulkan_device;
@@ -2486,6 +2486,21 @@ struct Vulkan_descriptor_set_layout
         Vulkan_device &device, const VkDescriptorSetLayoutCreateInfo &create_info);
 };
 
+struct Vulkan_pipeline_layout
+    : public Vulkan_nondispatchable_object<Vulkan_pipeline_layout, VkPipelineLayout>
+{
+    std::vector<Vulkan_descriptor_set_layout *> descriptor_set_layouts;
+    std::vector<VkPushConstantRange> push_constant_ranges;
+    Vulkan_pipeline_layout(std::vector<Vulkan_descriptor_set_layout *> descriptor_set_layouts,
+                           std::vector<VkPushConstantRange> push_constant_ranges) noexcept
+        : descriptor_set_layouts(std::move(descriptor_set_layouts)),
+          push_constant_ranges(std::move(push_constant_ranges))
+    {
+    }
+    static std::unique_ptr<Vulkan_pipeline_layout> create(
+        Vulkan_device &device, const VkPipelineLayoutCreateInfo &create_info);
+};
+
 struct Vulkan_render_pass : public Vulkan_nondispatchable_object<Vulkan_render_pass, VkRenderPass>
 {
 #warning finish implementing Vulkan_render_pass
index 4d9d616fe2df092b4570bc01cafad0b0a6e43b90..17bcc61af4f26123156831a491fe2a84a13d2ea4 100644 (file)
@@ -798,22 +798,31 @@ extern "C" VKAPI_ATTR void VKAPI_CALL vkDestroyImageView(VkDevice device,
 
 extern "C" VKAPI_ATTR VkResult VKAPI_CALL
     vkCreateShaderModule(VkDevice device,
-                         const VkShaderModuleCreateInfo *pCreateInfo,
+                         const VkShaderModuleCreateInfo *create_info,
                          const VkAllocationCallbacks *allocator,
-                         VkShaderModule *pShaderModule)
+                         VkShaderModule *shader_module)
 {
     validate_allocator(allocator);
-#warning finish implementing vkCreateShaderModule
-    assert(!"vkCreateShaderModule is not implemented");
+    assert(device);
+    assert(create_info);
+    assert(shader_module);
+    return vulkan_icd::catch_exceptions_and_return_result(
+        [&]()
+        {
+            auto create_result = pipeline::Shader_module::create(
+                *vulkan::Vulkan_device::from_handle(device), *create_info);
+            *shader_module = move_to_handle(std::move(create_result));
+            return VK_SUCCESS;
+        });
 }
 
 extern "C" VKAPI_ATTR void VKAPI_CALL vkDestroyShaderModule(VkDevice device,
-                                                            VkShaderModule shaderModule,
+                                                            VkShaderModule shader_module,
                                                             const VkAllocationCallbacks *allocator)
 {
     validate_allocator(allocator);
-#warning finish implementing vkDestroyShaderModule
-    assert(!"vkDestroyShaderModule is not implemented");
+    assert(device);
+    pipeline::Shader_module::move_from_handle(shader_module).reset();
 }
 
 extern "C" VKAPI_ATTR VkResult VKAPI_CALL
@@ -865,15 +874,32 @@ extern "C" VKAPI_ATTR VkResult VKAPI_CALL vkMergePipelineCaches(VkDevice device,
 
 extern "C" VKAPI_ATTR VkResult VKAPI_CALL
     vkCreateGraphicsPipelines(VkDevice device,
-                              VkPipelineCache pipelineCache,
-                              uint32_t createInfoCount,
-                              const VkGraphicsPipelineCreateInfo *pCreateInfos,
+                              VkPipelineCache pipeline_cache,
+                              uint32_t create_info_count,
+                              const VkGraphicsPipelineCreateInfo *create_infos,
                               const VkAllocationCallbacks *allocator,
-                              VkPipeline *pPipelines)
+                              VkPipeline *pipelines)
 {
     validate_allocator(allocator);
-#warning finish implementing vkCreateGraphicsPipelines
-    assert(!"vkCreateGraphicsPipelines is not implemented");
+    assert(device);
+    assert(create_info_count != 0);
+    assert(create_infos);
+    assert(pipelines);
+    return vulkan_icd::catch_exceptions_and_return_result(
+        [&]()
+        {
+            std::vector<std::unique_ptr<pipeline::Pipeline>> pipeline_vector;
+            pipeline_vector.resize(create_info_count);
+            for(std::uint32_t i = 0; i < create_info_count; i++)
+                pipeline_vector[i] = pipeline::Graphics_pipeline::create(
+                    *vulkan::Vulkan_device::from_handle(device),
+                    pipeline::Pipeline_cache::from_handle(pipeline_cache),
+                    create_infos[i]);
+            // only copy to pipelines after we're sure nothing will throw
+            for(std::uint32_t i = 0; i < create_info_count; i++)
+                pipelines[i] = move_to_handle(std::move(pipeline_vector[i]));
+            return VK_SUCCESS;
+        });
 }
 
 extern "C" VKAPI_ATTR VkResult VKAPI_CALL
@@ -894,27 +920,36 @@ extern "C" VKAPI_ATTR void VKAPI_CALL vkDestroyPipeline(VkDevice device,
                                                         const VkAllocationCallbacks *allocator)
 {
     validate_allocator(allocator);
-#warning finish implementing vkDestroyPipeline
-    assert(!"vkDestroyPipeline is not implemented");
+    assert(device);
+    pipeline::Pipeline::move_from_handle(pipeline).reset();
 }
 
 extern "C" VKAPI_ATTR VkResult VKAPI_CALL
     vkCreatePipelineLayout(VkDevice device,
-                           const VkPipelineLayoutCreateInfo *pCreateInfo,
+                           const VkPipelineLayoutCreateInfo *create_info,
                            const VkAllocationCallbacks *allocator,
-                           VkPipelineLayout *pPipelineLayout)
+                           VkPipelineLayout *pipeline_layout)
 {
     validate_allocator(allocator);
-#warning finish implementing vkCreatePipelineLayout
-    assert(!"vkCreatePipelineLayout is not implemented");
+    assert(device);
+    assert(create_info);
+    assert(pipeline_layout);
+    return vulkan_icd::catch_exceptions_and_return_result(
+        [&]()
+        {
+            auto create_result = vulkan::Vulkan_pipeline_layout::create(
+                *vulkan::Vulkan_device::from_handle(device), *create_info);
+            *pipeline_layout = move_to_handle(std::move(create_result));
+            return VK_SUCCESS;
+        });
 }
 
 extern "C" VKAPI_ATTR void VKAPI_CALL vkDestroyPipelineLayout(
-    VkDevice device, VkPipelineLayout pipelineLayout, const VkAllocationCallbacks *allocator)
+    VkDevice device, VkPipelineLayout pipeline_layout, const VkAllocationCallbacks *allocator)
 {
     validate_allocator(allocator);
-#warning finish implementing vkDestroyPipelineLayout
-    assert(!"vkDestroyPipelineLayout is not implemented");
+    assert(device);
+    vulkan::Vulkan_pipeline_layout::move_from_handle(pipeline_layout).reset();
 }
 
 extern "C" VKAPI_ATTR VkResult VKAPI_CALL vkCreateSampler(VkDevice device,
@@ -932,8 +967,8 @@ extern "C" VKAPI_ATTR void VKAPI_CALL vkDestroySampler(VkDevice device,
                                                        const VkAllocationCallbacks *allocator)
 {
     validate_allocator(allocator);
-#warning finish implementing vkDestroySampler
-    assert(!"vkDestroySampler is not implemented");
+    assert(device);
+    vulkan::Vulkan_sampler::move_from_handle(sampler).reset();
 }
 
 extern "C" VKAPI_ATTR VkResult VKAPI_CALL