| 
									
										
										
										
											2016-08-13 22:57:50 +10:00
										 |  |  | // Copyright 2016 Dolphin Emulator Project
 | 
					
						
							|  |  |  | // Licensed under GPLv2+
 | 
					
						
							|  |  |  | // Refer to the license.txt file included.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #pragma once
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <array>
 | 
					
						
							| 
									
										
										
										
											2016-09-30 23:07:50 -04:00
										 |  |  | #include <cstddef>
 | 
					
						
							| 
									
										
										
										
											2016-08-13 22:57:50 +10:00
										 |  |  | #include <map>
 | 
					
						
							|  |  |  | #include <memory>
 | 
					
						
							|  |  |  | #include <string>
 | 
					
						
							|  |  |  | #include <unordered_map>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-30 23:07:50 -04:00
										 |  |  | #include "Common/CommonTypes.h"
 | 
					
						
							| 
									
										
										
										
											2016-08-13 22:57:50 +10:00
										 |  |  | #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(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-13 15:24:55 +10:00
										 |  |  |   // Descriptor set layout accessor. Used for allocating descriptor sets.
 | 
					
						
							|  |  |  |   VkDescriptorSetLayout GetDescriptorSetLayout(DESCRIPTOR_SET_LAYOUT layout) const | 
					
						
							| 
									
										
										
										
											2016-08-13 22:57:50 +10:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2016-11-13 15:24:55 +10:00
										 |  |  |     return m_descriptor_set_layouts[layout]; | 
					
						
							| 
									
										
										
										
											2016-08-13 22:57:50 +10:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2016-11-13 15:24:55 +10:00
										 |  |  |   // Pipeline layout accessor. Used to fill in required field in PipelineInfo.
 | 
					
						
							|  |  |  |   VkPipelineLayout GetPipelineLayout(PIPELINE_LAYOUT layout) const | 
					
						
							| 
									
										
										
										
											2016-11-13 15:38:32 +10:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2016-11-13 15:24:55 +10:00
										 |  |  |     return m_pipeline_layouts[layout]; | 
					
						
							| 
									
										
										
										
											2016-11-13 15:38:32 +10:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2016-08-13 22:57:50 +10:00
										 |  |  |   // 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); | 
					
						
							| 
									
										
										
										
											2016-09-28 22:31:39 +02:00
										 |  |  |   VkShaderModule GetPixelShaderForUid(const PixelShaderUid& uid); | 
					
						
							| 
									
										
										
										
											2016-08-13 22:57:50 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // 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(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-13 18:39:06 +10:00
										 |  |  |   // Creates a pipeline for the specified description. The resulting pipeline, if successful
 | 
					
						
							|  |  |  |   // is not stored anywhere, this is left up to the caller.
 | 
					
						
							|  |  |  |   VkPipeline CreatePipeline(const PipelineInfo& info); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Find a pipeline by the specified description, if not found, attempts to create it.
 | 
					
						
							| 
									
										
										
										
											2016-08-13 22:57:50 +10:00
										 |  |  |   VkPipeline GetPipeline(const PipelineInfo& info); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-13 18:39:06 +10:00
										 |  |  |   // Find a pipeline by the specified description, if not found, attempts to create it. If this
 | 
					
						
							|  |  |  |   // resulted in a pipeline being created, the second field of the return value will be false,
 | 
					
						
							|  |  |  |   // otherwise for a cache hit it will be true.
 | 
					
						
							|  |  |  |   std::pair<VkPipeline, bool> GetPipelineWithCacheResult(const PipelineInfo& info); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-13 22:57:50 +10:00
										 |  |  |   // 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; } | 
					
						
							| 
									
										
										
										
											2016-11-13 18:39:06 +10:00
										 |  |  |   // Gets the filename of the specified type of cache object (e.g. vertex shader, pipeline).
 | 
					
						
							|  |  |  |   std::string GetDiskCacheFileName(const char* type); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-13 22:57:50 +10:00
										 |  |  | private: | 
					
						
							|  |  |  |   bool CreatePipelineCache(bool load_from_disk); | 
					
						
							| 
									
										
										
										
											2016-11-13 18:50:10 +10:00
										 |  |  |   bool ValidatePipelineCache(const u8* data, size_t data_length); | 
					
						
							| 
									
										
										
										
											2016-08-13 22:57:50 +10:00
										 |  |  |   void DestroyPipelineCache(); | 
					
						
							|  |  |  |   void LoadShaderCaches(); | 
					
						
							|  |  |  |   void DestroyShaderCaches(); | 
					
						
							|  |  |  |   bool CreateDescriptorSetLayouts(); | 
					
						
							|  |  |  |   void DestroyDescriptorSetLayouts(); | 
					
						
							|  |  |  |   bool CreatePipelineLayouts(); | 
					
						
							|  |  |  |   void DestroyPipelineLayouts(); | 
					
						
							|  |  |  |   bool CreateUtilityShaderVertexFormat(); | 
					
						
							|  |  |  |   bool CreateStaticSamplers(); | 
					
						
							|  |  |  |   bool CompileSharedShaders(); | 
					
						
							|  |  |  |   void DestroySharedShaders(); | 
					
						
							|  |  |  |   void DestroySamplers(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-13 15:38:32 +10:00
										 |  |  |   std::array<VkDescriptorSetLayout, NUM_DESCRIPTOR_SET_LAYOUTS> m_descriptor_set_layouts = {}; | 
					
						
							| 
									
										
										
										
											2016-11-13 15:24:55 +10:00
										 |  |  |   std::array<VkPipelineLayout, NUM_PIPELINE_LAYOUTS> m_pipeline_layouts = {}; | 
					
						
							| 
									
										
										
										
											2016-08-13 22:57:50 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  |   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
 |