summaryrefslogtreecommitdiff
path: root/Source/Core/VideoBackends/Vulkan/ObjectCache.h
diff options
context:
space:
mode:
authorMat M <mathew1800@gmail.com>2016-09-30 19:15:50 -0400
committerGitHub <noreply@github.com>2016-09-30 19:15:50 -0400
commit46b9383280a623753686ab6df6c479e784e416ae (patch)
tree9ffb2cbdba6d39a29d6fed9df4db03166755a20d /Source/Core/VideoBackends/Vulkan/ObjectCache.h
parentf3cdc6433cba253fa4485cd7e27025c31410ed0c (diff)
parenta8194cff3ca8f9b85a779da6b8214b58ba3fa7d0 (diff)
Merge pull request #3935 from stenzek/vulkan-pr
Vulkan Backend
Diffstat (limited to 'Source/Core/VideoBackends/Vulkan/ObjectCache.h')
-rw-r--r--Source/Core/VideoBackends/Vulkan/ObjectCache.h189
1 files changed, 189 insertions, 0 deletions
diff --git a/Source/Core/VideoBackends/Vulkan/ObjectCache.h b/Source/Core/VideoBackends/Vulkan/ObjectCache.h
new file mode 100644
index 0000000000..f2ae25142a
--- /dev/null
+++ b/Source/Core/VideoBackends/Vulkan/ObjectCache.h
@@ -0,0 +1,189 @@
+// Copyright 2016 Dolphin Emulator Project
+// Licensed under GPLv2+
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include <array>
+#include <map>
+#include <memory>
+#include <string>
+#include <unordered_map>
+
+#include "Common/LinearDiskCache.h"
+
+#include "VideoBackends/Vulkan/Constants.h"
+
+#include "VideoCommon/GeometryShaderGen.h"
+#include "VideoCommon/PixelShaderGen.h"
+#include "VideoCommon/VertexShaderGen.h"
+
+namespace Vulkan
+{
+class CommandBufferManager;
+class VertexFormat;
+class StreamBuffer;
+
+struct PipelineInfo
+{
+ // These are packed in descending order of size, to avoid any padding so that the structure
+ // can be copied/compared as a single block of memory. 64-bit pointer size is assumed.
+ const VertexFormat* vertex_format;
+ VkPipelineLayout pipeline_layout;
+ VkShaderModule vs;
+ VkShaderModule gs;
+ VkShaderModule ps;
+ VkRenderPass render_pass;
+ BlendState blend_state;
+ RasterizationState rasterization_state;
+ DepthStencilState depth_stencil_state;
+ VkPrimitiveTopology primitive_topology;
+};
+
+struct PipelineInfoHash
+{
+ std::size_t operator()(const PipelineInfo& key) const;
+};
+
+bool operator==(const PipelineInfo& lhs, const PipelineInfo& rhs);
+bool operator!=(const PipelineInfo& lhs, const PipelineInfo& rhs);
+bool operator<(const PipelineInfo& lhs, const PipelineInfo& rhs);
+bool operator>(const PipelineInfo& lhs, const PipelineInfo& rhs);
+bool operator==(const SamplerState& lhs, const SamplerState& rhs);
+bool operator!=(const SamplerState& lhs, const SamplerState& rhs);
+bool operator>(const SamplerState& lhs, const SamplerState& rhs);
+bool operator<(const SamplerState& lhs, const SamplerState& rhs);
+
+class ObjectCache
+{
+public:
+ ObjectCache();
+ ~ObjectCache();
+
+ // We have four shared pipeline layouts:
+ // - Standard
+ // - Per-stage UBO (VS/GS/PS, VS constants accessible from PS)
+ // - 8 combined image samplers (accessible from PS)
+ // - BBox Enabled
+ // - Same as standard, plus a single SSBO accessible from PS
+ // - Push Constant
+ // - Same as standard, plus 128 bytes of push constants, accessible from all stages.
+ //
+ // All three pipeline layouts use the same descriptor set layouts, but the final descriptor set
+ // (SSBO) is only required when using the BBox Enabled pipeline layout.
+ //
+ VkDescriptorSetLayout GetDescriptorSetLayout(DESCRIPTOR_SET set) const
+ {
+ return m_descriptor_set_layouts[set];
+ }
+ VkPipelineLayout GetStandardPipelineLayout() const { return m_standard_pipeline_layout; }
+ VkPipelineLayout GetBBoxPipelineLayout() const { return m_bbox_pipeline_layout; }
+ VkPipelineLayout GetPushConstantPipelineLayout() const { return m_push_constant_pipeline_layout; }
+ // Shared utility shader resources
+ VertexFormat* GetUtilityShaderVertexFormat() const
+ {
+ return m_utility_shader_vertex_format.get();
+ }
+ StreamBuffer* GetUtilityShaderVertexBuffer() const
+ {
+ return m_utility_shader_vertex_buffer.get();
+ }
+ StreamBuffer* GetUtilityShaderUniformBuffer() const
+ {
+ return m_utility_shader_uniform_buffer.get();
+ }
+
+ // Get utility shader header based on current config.
+ std::string GetUtilityShaderHeader() const;
+
+ // Accesses ShaderGen shader caches
+ VkShaderModule GetVertexShaderForUid(const VertexShaderUid& uid);
+ VkShaderModule GetGeometryShaderForUid(const GeometryShaderUid& uid);
+ VkShaderModule GetPixelShaderForUid(const PixelShaderUid& uid, DSTALPHA_MODE dstalpha_mode);
+
+ // Static samplers
+ VkSampler GetPointSampler() const { return m_point_sampler; }
+ VkSampler GetLinearSampler() const { return m_linear_sampler; }
+ VkSampler GetSampler(const SamplerState& info);
+
+ // Perform at startup, create descriptor layouts, compiles all static shaders.
+ bool Initialize();
+
+ // Find a pipeline by the specified description, if not found, attempts to create it
+ VkPipeline GetPipeline(const PipelineInfo& info);
+
+ // Wipes out the pipeline cache, use when MSAA modes change, for example
+ // Also destroys the data that would be stored in the disk cache.
+ void ClearPipelineCache();
+
+ // Saves the pipeline cache to disk. Call when shutting down.
+ void SavePipelineCache();
+
+ // Clear sampler cache, use when anisotropy mode changes
+ // WARNING: Ensure none of the objects from here are in use when calling
+ void ClearSamplerCache();
+
+ // Recompile shared shaders, call when stereo mode changes.
+ void RecompileSharedShaders();
+
+ // Shared shader accessors
+ VkShaderModule GetScreenQuadVertexShader() const { return m_screen_quad_vertex_shader; }
+ VkShaderModule GetPassthroughVertexShader() const { return m_passthrough_vertex_shader; }
+ VkShaderModule GetScreenQuadGeometryShader() const { return m_screen_quad_geometry_shader; }
+ VkShaderModule GetPassthroughGeometryShader() const { return m_passthrough_geometry_shader; }
+private:
+ bool CreatePipelineCache(bool load_from_disk);
+ void DestroyPipelineCache();
+ void LoadShaderCaches();
+ void DestroyShaderCaches();
+ bool CreateDescriptorSetLayouts();
+ void DestroyDescriptorSetLayouts();
+ bool CreatePipelineLayouts();
+ void DestroyPipelineLayouts();
+ bool CreateUtilityShaderVertexFormat();
+ bool CreateStaticSamplers();
+ bool CompileSharedShaders();
+ void DestroySharedShaders();
+ void DestroySamplers();
+
+ std::string GetDiskCacheFileName(const char* type);
+
+ std::array<VkDescriptorSetLayout, NUM_DESCRIPTOR_SETS> m_descriptor_set_layouts = {};
+
+ VkPipelineLayout m_standard_pipeline_layout = VK_NULL_HANDLE;
+ VkPipelineLayout m_bbox_pipeline_layout = VK_NULL_HANDLE;
+ VkPipelineLayout m_push_constant_pipeline_layout = VK_NULL_HANDLE;
+
+ std::unique_ptr<VertexFormat> m_utility_shader_vertex_format;
+ std::unique_ptr<StreamBuffer> m_utility_shader_vertex_buffer;
+ std::unique_ptr<StreamBuffer> m_utility_shader_uniform_buffer;
+
+ template <typename Uid>
+ struct ShaderCache
+ {
+ std::map<Uid, VkShaderModule> shader_map;
+ LinearDiskCache<Uid, u32> disk_cache;
+ };
+ ShaderCache<VertexShaderUid> m_vs_cache;
+ ShaderCache<GeometryShaderUid> m_gs_cache;
+ ShaderCache<PixelShaderUid> m_ps_cache;
+
+ std::unordered_map<PipelineInfo, VkPipeline, PipelineInfoHash> m_pipeline_objects;
+ VkPipelineCache m_pipeline_cache = VK_NULL_HANDLE;
+ std::string m_pipeline_cache_filename;
+
+ VkSampler m_point_sampler = VK_NULL_HANDLE;
+ VkSampler m_linear_sampler = VK_NULL_HANDLE;
+
+ std::map<SamplerState, VkSampler> m_sampler_cache;
+
+ // Utility/shared shaders
+ VkShaderModule m_screen_quad_vertex_shader = VK_NULL_HANDLE;
+ VkShaderModule m_passthrough_vertex_shader = VK_NULL_HANDLE;
+ VkShaderModule m_screen_quad_geometry_shader = VK_NULL_HANDLE;
+ VkShaderModule m_passthrough_geometry_shader = VK_NULL_HANDLE;
+};
+
+extern std::unique_ptr<ObjectCache> g_object_cache;
+
+} // namespace Vulkan