]> git.tdb.fi Git - libs/gl.git/blobdiff - source/backends/vulkan/pipelinecache.cpp
Support compute shaders and compute operations
[libs/gl.git] / source / backends / vulkan / pipelinecache.cpp
index 646d79324b6b65692f7bd7a43ddab33892c062be..0ec5fcc78fbd12f7e8a2a693ae07fd6bbadf64b5 100644 (file)
@@ -1,8 +1,7 @@
-#include <msp/core/hash.h>
 #include "device.h"
-#include "framebuffer.h"
 #include "pipelinecache.h"
 #include "pipelinestate.h"
+#include "renderpass.h"
 #include "vulkan.h"
 
 using namespace std;
@@ -24,85 +23,21 @@ PipelineCache::~PipelineCache()
                vk.DestroyPipeline(kvp.second);
 }
 
-VkRenderPass PipelineCache::get_render_pass(const FrameFormat &format, bool clear, bool discard, bool to_present)
+VkRenderPass PipelineCache::get_render_pass(const RenderPass &rp)
 {
-       const VulkanFunctions &vk = device.get_functions();
-
-       uint64_t key = hash<64>(static_cast<uint8_t>(clear | (discard*2) | (to_present*4)));
-       for(FrameAttachment a: format)
-               key = hash_update<64>(key, a);
-
-       auto j = render_passes.find(key);
-       if(j!=render_passes.end())
-               return j->second;
-
-       VkAttachmentDescription attachments[FrameFormat::MAX_ATTACHMENTS] = { };
-       VkAttachmentReference color_refs[FrameFormat::MAX_ATTACHMENTS] = { };
-       VkAttachmentReference depth_stencil_ref = { };
-       depth_stencil_ref.attachment = VK_ATTACHMENT_UNUSED;
-
-       VkSampleCountFlagBits vk_samples = static_cast<VkSampleCountFlagBits>(get_vulkan_samples(format.get_samples()));
+       uint64_t key = rp.compute_hash();
+       auto i = render_passes.find(key);
+       if(i!=render_passes.end())
+               return i->second;
 
-       unsigned i = 0;
-       unsigned color_count = 0;
-       for(FrameAttachment a: format)
-       {
-               VkImageLayout subpass_layout = static_cast<VkImageLayout>(get_vulkan_attachment_layout(get_components(get_attachment_pixelformat(a))));
-               VkImageLayout external_layout = (to_present ? VK_IMAGE_LAYOUT_PRESENT_SRC_KHR : subpass_layout);
-
-               attachments[i].format = static_cast<VkFormat>(get_vulkan_pixelformat(get_attachment_pixelformat(a)));
-               attachments[i].samples = vk_samples;
-               attachments[i].loadOp = (clear ? discard ? VK_ATTACHMENT_LOAD_OP_DONT_CARE : VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_LOAD);
-               attachments[i].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
-               attachments[i].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
-               attachments[i].stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE;
-               attachments[i].initialLayout = ((clear && discard) ? VK_IMAGE_LAYOUT_UNDEFINED : external_layout);
-               attachments[i].finalLayout = external_layout;
-
-               if(subpass_layout==VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)
-               {
-                       color_refs[color_count].attachment = i;
-                       color_refs[color_count].layout = subpass_layout;
-                       ++color_count;
-               }
-               else
-               {
-                       depth_stencil_ref.attachment = i;
-                       depth_stencil_ref.layout = subpass_layout;
-               }
-
-               ++i;
-       }
+       const VulkanFunctions &vk = device.get_functions();
 
-       VkSubpassDescription subpass = { };
-       subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
-       subpass.colorAttachmentCount = color_count;
-       subpass.pColorAttachments = color_refs;
-       subpass.pDepthStencilAttachment = &depth_stencil_ref;
-
-       VkSubpassDependency dependency = { };
-       VkRenderPassCreateInfo render_pass_info = { };
-       render_pass_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
-       render_pass_info.attachmentCount = format.size();
-       render_pass_info.pAttachments = attachments;
-       render_pass_info.subpassCount = 1;
-       render_pass_info.pSubpasses = &subpass;
-
-       if(to_present)
-       {
-               dependency.srcSubpass = 0;
-               dependency.dstSubpass = VK_SUBPASS_EXTERNAL;
-               dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
-               dependency.srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT;
-               dependency.dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
-               dependency.dstAccessMask = 0;
-
-               render_pass_info.dependencyCount = 1;
-               render_pass_info.pDependencies = &dependency;
-       }
+       vector<char> buffer;
+       rp.fill_creation_info(buffer);
+       const VkRenderPassCreateInfo *creation_info = reinterpret_cast<const VkRenderPassCreateInfo *>(buffer.data());
 
        VkRenderPass render_pass;
-       vk.CreateRenderPass(render_pass_info, render_pass);
+       vk.CreateRenderPass(*creation_info, render_pass);
 
        render_passes.insert(make_pair(key, render_pass));
 
@@ -120,10 +55,19 @@ VkPipeline PipelineCache::get_pipeline(const PipelineState &ps)
 
        vector<char> buffer;
        ps.fill_creation_info(buffer);
-       const VkGraphicsPipelineCreateInfo *creation_info = reinterpret_cast<const VkGraphicsPipelineCreateInfo *>(buffer.data());
 
+       VkStructureType type = *reinterpret_cast<const VkStructureType *>(buffer.data());
        VkPipeline pipeline;
-       vk.CreateGraphicsPipelines(0, 1, creation_info, &pipeline);
+       if(type==VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO)
+       {
+               const VkComputePipelineCreateInfo *creation_info = reinterpret_cast<const VkComputePipelineCreateInfo *>(buffer.data());
+               vk.CreateComputePipelines(0, 1, creation_info, &pipeline);
+       }
+       else
+       {
+               const VkGraphicsPipelineCreateInfo *creation_info = reinterpret_cast<const VkGraphicsPipelineCreateInfo *>(buffer.data());
+               vk.CreateGraphicsPipelines(0, 1, creation_info, &pipeline);
+       }
 
        pipelines.insert(make_pair(key, pipeline));