1 // Copyright 2018 Dolphin Emulator Project 2 // Licensed under GPLv2+ 3 // Refer to the license.txt file included. 4 5 #pragma once 6 7 #include <array> 8 #include <cstddef> 9 #include <cstring> 10 #include <map> 11 #include <memory> 12 #include <optional> 13 #include <string> 14 #include <unordered_map> 15 #include <utility> 16 17 #include "Common/CommonTypes.h" 18 #include "Common/File.h" 19 #include "Common/LinearDiskCache.h" 20 21 #include "VideoCommon/AbstractPipeline.h" 22 #include "VideoCommon/AbstractShader.h" 23 #include "VideoCommon/AsyncShaderCompiler.h" 24 #include "VideoCommon/GXPipelineTypes.h" 25 #include "VideoCommon/GeometryShaderGen.h" 26 #include "VideoCommon/PixelShaderGen.h" 27 #include "VideoCommon/RenderState.h" 28 #include "VideoCommon/TextureCacheBase.h" 29 #include "VideoCommon/TextureConversionShader.h" 30 #include "VideoCommon/TextureConverterShaderGen.h" 31 #include "VideoCommon/UberShaderPixel.h" 32 #include "VideoCommon/UberShaderVertex.h" 33 #include "VideoCommon/VertexShaderGen.h" 34 35 class NativeVertexFormat; 36 enum class AbstractTextureFormat : u32; 37 enum class APIType; 38 enum class TextureFormat; 39 enum class TLUTFormat; 40 41 namespace VideoCommon 42 { 43 class ShaderCache final 44 { 45 public: 46 ShaderCache(); 47 ~ShaderCache(); 48 49 // Perform at startup, create descriptor layouts, compiles all static shaders. 50 bool Initialize(); 51 void Shutdown(); 52 53 // Compiles/loads cached shaders. 54 void InitializeShaderCache(); 55 56 // Changes the shader host config. Shaders should be reloaded afterwards. SetHostConfig(const ShaderHostConfig & host_config)57 void SetHostConfig(const ShaderHostConfig& host_config) { m_host_config = host_config; } 58 59 // Reloads/recreates all shaders and pipelines. 60 void Reload(); 61 62 // Retrieves all pending shaders/pipelines from the async compiler. 63 void RetrieveAsyncShaders(); 64 65 // Accesses ShaderGen shader caches 66 const AbstractPipeline* GetPipelineForUid(const GXPipelineUid& uid); 67 const AbstractPipeline* GetUberPipelineForUid(const GXUberPipelineUid& uid); 68 69 // Accesses ShaderGen shader caches asynchronously. 70 // The optional will be empty if this pipeline is now background compiling. 71 std::optional<const AbstractPipeline*> GetPipelineForUidAsync(const GXPipelineUid& uid); 72 73 // Shared shaders GetScreenQuadVertexShader()74 const AbstractShader* GetScreenQuadVertexShader() const 75 { 76 return m_screen_quad_vertex_shader.get(); 77 } GetTextureCopyVertexShader()78 const AbstractShader* GetTextureCopyVertexShader() const 79 { 80 return m_texture_copy_vertex_shader.get(); 81 } GetEFBCopyVertexShader()82 const AbstractShader* GetEFBCopyVertexShader() const { return m_efb_copy_vertex_shader.get(); } GetTexcoordGeometryShader()83 const AbstractShader* GetTexcoordGeometryShader() const 84 { 85 return m_texcoord_geometry_shader.get(); 86 } GetTextureCopyPixelShader()87 const AbstractShader* GetTextureCopyPixelShader() const 88 { 89 return m_texture_copy_pixel_shader.get(); 90 } GetColorGeometryShader()91 const AbstractShader* GetColorGeometryShader() const { return m_color_geometry_shader.get(); } GetColorPixelShader()92 const AbstractShader* GetColorPixelShader() const { return m_color_pixel_shader.get(); } 93 94 // EFB copy to RAM/VRAM pipelines 95 const AbstractPipeline* 96 GetEFBCopyToVRAMPipeline(const TextureConversionShaderGen::TCShaderUid& uid); 97 const AbstractPipeline* GetEFBCopyToRAMPipeline(const EFBCopyParams& uid); 98 99 // RGBA8 framebuffer copy pipelines GetRGBA8CopyPipeline()100 const AbstractPipeline* GetRGBA8CopyPipeline() const { return m_copy_rgba8_pipeline.get(); } GetRGBA8StereoCopyPipeline()101 const AbstractPipeline* GetRGBA8StereoCopyPipeline() const 102 { 103 return m_rgba8_stereo_copy_pipeline.get(); 104 } 105 106 // Palette texture conversion pipelines 107 const AbstractPipeline* GetPaletteConversionPipeline(TLUTFormat format); 108 109 // Texture reinterpret pipelines 110 const AbstractPipeline* GetTextureReinterpretPipeline(TextureFormat from_format, 111 TextureFormat to_format); 112 113 // Texture decoding compute shaders 114 const AbstractShader* GetTextureDecodingShader(TextureFormat format, TLUTFormat palette_format); 115 116 private: 117 static constexpr size_t NUM_PALETTE_CONVERSION_SHADERS = 3; 118 119 void WaitForAsyncCompiler(); 120 void LoadCaches(); 121 void ClearCaches(); 122 void LoadPipelineUIDCache(); 123 void ClosePipelineUIDCache(); 124 void CompileMissingPipelines(); 125 void QueueUberShaderPipelines(); 126 bool CompileSharedPipelines(); 127 128 // GX shader compiler methods 129 std::unique_ptr<AbstractShader> CompileVertexShader(const VertexShaderUid& uid) const; 130 std::unique_ptr<AbstractShader> 131 CompileVertexUberShader(const UberShader::VertexShaderUid& uid) const; 132 std::unique_ptr<AbstractShader> CompilePixelShader(const PixelShaderUid& uid) const; 133 std::unique_ptr<AbstractShader> 134 CompilePixelUberShader(const UberShader::PixelShaderUid& uid) const; 135 const AbstractShader* InsertVertexShader(const VertexShaderUid& uid, 136 std::unique_ptr<AbstractShader> shader); 137 const AbstractShader* InsertVertexUberShader(const UberShader::VertexShaderUid& uid, 138 std::unique_ptr<AbstractShader> shader); 139 const AbstractShader* InsertPixelShader(const PixelShaderUid& uid, 140 std::unique_ptr<AbstractShader> shader); 141 const AbstractShader* InsertPixelUberShader(const UberShader::PixelShaderUid& uid, 142 std::unique_ptr<AbstractShader> shader); 143 const AbstractShader* CreateGeometryShader(const GeometryShaderUid& uid); 144 bool NeedsGeometryShader(const GeometryShaderUid& uid) const; 145 146 // Should we use geometry shaders for EFB copies? 147 bool UseGeometryShaderForEFBCopies() const; 148 149 // GX pipeline compiler methods 150 AbstractPipelineConfig 151 GetGXPipelineConfig(const NativeVertexFormat* vertex_format, const AbstractShader* vertex_shader, 152 const AbstractShader* geometry_shader, const AbstractShader* pixel_shader, 153 const RasterizationState& rasterization_state, const DepthState& depth_state, 154 const BlendingState& blending_state); 155 std::optional<AbstractPipelineConfig> GetGXPipelineConfig(const GXPipelineUid& uid); 156 std::optional<AbstractPipelineConfig> GetGXPipelineConfig(const GXUberPipelineUid& uid); 157 const AbstractPipeline* InsertGXPipeline(const GXPipelineUid& config, 158 std::unique_ptr<AbstractPipeline> pipeline); 159 const AbstractPipeline* InsertGXUberPipeline(const GXUberPipelineUid& config, 160 std::unique_ptr<AbstractPipeline> pipeline); 161 void AddSerializedGXPipelineUID(const SerializedGXPipelineUid& uid); 162 void AppendGXPipelineUID(const GXPipelineUid& config); 163 164 // ASync Compiler Methods 165 void QueueVertexShaderCompile(const VertexShaderUid& uid, u32 priority); 166 void QueueVertexUberShaderCompile(const UberShader::VertexShaderUid& uid, u32 priority); 167 void QueuePixelShaderCompile(const PixelShaderUid& uid, u32 priority); 168 void QueuePixelUberShaderCompile(const UberShader::PixelShaderUid& uid, u32 priority); 169 void QueuePipelineCompile(const GXPipelineUid& uid, u32 priority); 170 void QueueUberPipelineCompile(const GXUberPipelineUid& uid, u32 priority); 171 172 // Populating various caches. 173 template <ShaderStage stage, typename K, typename T> 174 void LoadShaderCache(T& cache, APIType api_type, const char* type, bool include_gameid); 175 template <typename T> 176 void ClearShaderCache(T& cache); 177 template <typename KeyType, typename DiskKeyType, typename T> 178 void LoadPipelineCache(T& cache, LinearDiskCache<DiskKeyType, u8>& disk_cache, APIType api_type, 179 const char* type, bool include_gameid); 180 template <typename T, typename Y> 181 void ClearPipelineCache(T& cache, Y& disk_cache); 182 183 // Priorities for compiling. The lower the value, the sooner the pipeline is compiled. 184 // The shader cache is compiled last, as it is the least likely to be required. On demand 185 // shaders are always compiled before pending ubershaders, as we want to use the ubershader 186 // for as few frames as possible, otherwise we risk framerate drops. 187 enum : u32 188 { 189 COMPILE_PRIORITY_ONDEMAND_PIPELINE = 100, 190 COMPILE_PRIORITY_UBERSHADER_PIPELINE = 200, 191 COMPILE_PRIORITY_SHADERCACHE_PIPELINE = 300 192 }; 193 194 // Configuration bits. 195 APIType m_api_type; 196 ShaderHostConfig m_host_config = {}; 197 std::unique_ptr<AsyncShaderCompiler> m_async_shader_compiler; 198 199 // Shared shaders 200 std::unique_ptr<AbstractShader> m_screen_quad_vertex_shader; 201 std::unique_ptr<AbstractShader> m_texture_copy_vertex_shader; 202 std::unique_ptr<AbstractShader> m_efb_copy_vertex_shader; 203 std::unique_ptr<AbstractShader> m_texcoord_geometry_shader; 204 std::unique_ptr<AbstractShader> m_color_geometry_shader; 205 std::unique_ptr<AbstractShader> m_texture_copy_pixel_shader; 206 std::unique_ptr<AbstractShader> m_color_pixel_shader; 207 208 // GX Shader Caches 209 template <typename Uid> 210 struct ShaderModuleCache 211 { 212 struct Shader 213 { 214 std::unique_ptr<AbstractShader> shader; 215 bool pending; 216 }; 217 std::map<Uid, Shader> shader_map; 218 LinearDiskCache<Uid, u8> disk_cache; 219 }; 220 ShaderModuleCache<VertexShaderUid> m_vs_cache; 221 ShaderModuleCache<GeometryShaderUid> m_gs_cache; 222 ShaderModuleCache<PixelShaderUid> m_ps_cache; 223 ShaderModuleCache<UberShader::VertexShaderUid> m_uber_vs_cache; 224 ShaderModuleCache<UberShader::PixelShaderUid> m_uber_ps_cache; 225 226 // GX Pipeline Caches - .first - pipeline, .second - pending 227 std::map<GXPipelineUid, std::pair<std::unique_ptr<AbstractPipeline>, bool>> m_gx_pipeline_cache; 228 std::map<GXUberPipelineUid, std::pair<std::unique_ptr<AbstractPipeline>, bool>> 229 m_gx_uber_pipeline_cache; 230 File::IOFile m_gx_pipeline_uid_cache_file; 231 LinearDiskCache<SerializedGXPipelineUid, u8> m_gx_pipeline_disk_cache; 232 LinearDiskCache<SerializedGXUberPipelineUid, u8> m_gx_uber_pipeline_disk_cache; 233 234 // EFB copy to VRAM/RAM pipelines 235 std::map<TextureConversionShaderGen::TCShaderUid, std::unique_ptr<AbstractPipeline>> 236 m_efb_copy_to_vram_pipelines; 237 std::map<EFBCopyParams, std::unique_ptr<AbstractPipeline>> m_efb_copy_to_ram_pipelines; 238 239 // Copy pipeline for RGBA8 textures 240 std::unique_ptr<AbstractPipeline> m_copy_rgba8_pipeline; 241 std::unique_ptr<AbstractPipeline> m_rgba8_stereo_copy_pipeline; 242 243 // Palette conversion pipelines 244 std::array<std::unique_ptr<AbstractPipeline>, NUM_PALETTE_CONVERSION_SHADERS> 245 m_palette_conversion_pipelines; 246 247 // Texture reinterpreting pipeline 248 std::map<std::pair<TextureFormat, TextureFormat>, std::unique_ptr<AbstractPipeline>> 249 m_texture_reinterpret_pipelines; 250 251 // Texture decoding shaders 252 std::map<std::pair<u32, u32>, std::unique_ptr<AbstractShader>> m_texture_decoding_shaders; 253 }; 254 255 } // namespace VideoCommon 256 257 extern std::unique_ptr<VideoCommon::ShaderCache> g_shader_cache; 258