Просмотр исходного кода

ShaderCache/PipelineCache: Cache null shaders.

Fernando Sahmkow 6 лет назад
Родитель
Сommit
644588fd88

+ 13 - 4
src/video_core/renderer_opengl/gl_shader_cache.cpp

@@ -448,7 +448,7 @@ Shader ShaderCacheOpenGL::GetStageProgram(Maxwell::ShaderProgram program) {
 
 
     // Look up shader in the cache based on address
     // Look up shader in the cache based on address
     const auto cpu_addr{memory_manager.GpuToCpuAddress(address)};
     const auto cpu_addr{memory_manager.GpuToCpuAddress(address)};
-    Shader shader{cpu_addr ? TryGet(*cpu_addr) : nullptr};
+    Shader shader{cpu_addr ? TryGet(*cpu_addr) : null_shader};
     if (shader) {
     if (shader) {
         return last_shaders[static_cast<std::size_t>(program)] = shader;
         return last_shaders[static_cast<std::size_t>(program)] = shader;
     }
     }
@@ -477,7 +477,12 @@ Shader ShaderCacheOpenGL::GetStageProgram(Maxwell::ShaderProgram program) {
         const std::size_t size_in_bytes = code.size() * sizeof(u64);
         const std::size_t size_in_bytes = code.size() * sizeof(u64);
         shader = CachedShader::CreateFromCache(params, found->second, size_in_bytes);
         shader = CachedShader::CreateFromCache(params, found->second, size_in_bytes);
     }
     }
-    Register(shader);
+
+    if (cpu_addr) {
+        Register(shader);
+    } else {
+        null_shader = shader;
+    }
 
 
     return last_shaders[static_cast<std::size_t>(program)] = shader;
     return last_shaders[static_cast<std::size_t>(program)] = shader;
 }
 }
@@ -486,7 +491,7 @@ Shader ShaderCacheOpenGL::GetComputeKernel(GPUVAddr code_addr) {
     auto& memory_manager{system.GPU().MemoryManager()};
     auto& memory_manager{system.GPU().MemoryManager()};
     const auto cpu_addr{memory_manager.GpuToCpuAddress(code_addr)};
     const auto cpu_addr{memory_manager.GpuToCpuAddress(code_addr)};
 
 
-    auto kernel = cpu_addr ? TryGet(*cpu_addr) : nullptr;
+    auto kernel = cpu_addr ? TryGet(*cpu_addr) : null_kernel;
     if (kernel) {
     if (kernel) {
         return kernel;
         return kernel;
     }
     }
@@ -507,7 +512,11 @@ Shader ShaderCacheOpenGL::GetComputeKernel(GPUVAddr code_addr) {
         kernel = CachedShader::CreateFromCache(params, found->second, size_in_bytes);
         kernel = CachedShader::CreateFromCache(params, found->second, size_in_bytes);
     }
     }
 
 
-    Register(kernel);
+    if (cpu_addr) {
+        Register(kernel);
+    } else {
+        null_kernel = kernel;
+    }
     return kernel;
     return kernel;
 }
 }
 
 

+ 3 - 0
src/video_core/renderer_opengl/gl_shader_cache.h

@@ -125,6 +125,9 @@ private:
     ShaderDiskCacheOpenGL disk_cache;
     ShaderDiskCacheOpenGL disk_cache;
     std::unordered_map<u64, PrecompiledShader> runtime_cache;
     std::unordered_map<u64, PrecompiledShader> runtime_cache;
 
 
+    Shader null_shader{};
+    Shader null_kernel{};
+
     std::array<Shader, Maxwell::MaxShaderProgram> last_shaders;
     std::array<Shader, Maxwell::MaxShaderProgram> last_shaders;
 };
 };
 
 

+ 12 - 4
src/video_core/renderer_vulkan/vk_pipeline_cache.cpp

@@ -207,7 +207,7 @@ std::array<Shader, Maxwell::MaxShaderProgram> VKPipelineCache::GetShaders() {
         const GPUVAddr program_addr{GetShaderAddress(system, program)};
         const GPUVAddr program_addr{GetShaderAddress(system, program)};
         const std::optional cpu_addr = memory_manager.GpuToCpuAddress(program_addr);
         const std::optional cpu_addr = memory_manager.GpuToCpuAddress(program_addr);
         ASSERT(cpu_addr);
         ASSERT(cpu_addr);
-        auto shader = cpu_addr ? TryGet(*cpu_addr) : nullptr;
+        auto shader = cpu_addr ? TryGet(*cpu_addr) : null_shader;
         if (!shader) {
         if (!shader) {
             const auto host_ptr{memory_manager.GetPointer(program_addr)};
             const auto host_ptr{memory_manager.GetPointer(program_addr)};
 
 
@@ -218,7 +218,11 @@ std::array<Shader, Maxwell::MaxShaderProgram> VKPipelineCache::GetShaders() {
 
 
             shader = std::make_shared<CachedShader>(system, stage, program_addr, *cpu_addr,
             shader = std::make_shared<CachedShader>(system, stage, program_addr, *cpu_addr,
                                                     std::move(code), stage_offset);
                                                     std::move(code), stage_offset);
-            Register(shader);
+            if (cpu_addr) {
+                Register(shader);
+            } else {
+                null_shader = shader;
+            }
         }
         }
         shaders[index] = std::move(shader);
         shaders[index] = std::move(shader);
     }
     }
@@ -261,7 +265,7 @@ VKComputePipeline& VKPipelineCache::GetComputePipeline(const ComputePipelineCach
     const auto cpu_addr = memory_manager.GpuToCpuAddress(program_addr);
     const auto cpu_addr = memory_manager.GpuToCpuAddress(program_addr);
     ASSERT(cpu_addr);
     ASSERT(cpu_addr);
 
 
-    auto shader = cpu_addr ? TryGet(*cpu_addr) : nullptr;
+    auto shader = cpu_addr ? TryGet(*cpu_addr) : null_kernel;
     if (!shader) {
     if (!shader) {
         // No shader found - create a new one
         // No shader found - create a new one
         const auto host_ptr = memory_manager.GetPointer(program_addr);
         const auto host_ptr = memory_manager.GetPointer(program_addr);
@@ -271,7 +275,11 @@ VKComputePipeline& VKPipelineCache::GetComputePipeline(const ComputePipelineCach
         shader = std::make_shared<CachedShader>(system, Tegra::Engines::ShaderType::Compute,
         shader = std::make_shared<CachedShader>(system, Tegra::Engines::ShaderType::Compute,
                                                 program_addr, *cpu_addr, std::move(code),
                                                 program_addr, *cpu_addr, std::move(code),
                                                 kernel_main_offset);
                                                 kernel_main_offset);
-        Register(shader);
+        if (cpu_addr) {
+            Register(shader);
+        } else {
+            null_kernel = shader;
+        }
     }
     }
 
 
     Specialization specialization;
     Specialization specialization;

+ 3 - 0
src/video_core/renderer_vulkan/vk_pipeline_cache.h

@@ -182,6 +182,9 @@ private:
     VKUpdateDescriptorQueue& update_descriptor_queue;
     VKUpdateDescriptorQueue& update_descriptor_queue;
     VKRenderPassCache& renderpass_cache;
     VKRenderPassCache& renderpass_cache;
 
 
+    Shader null_shader{};
+    Shader null_kernel{};
+
     std::array<Shader, Maxwell::MaxShaderProgram> last_shaders;
     std::array<Shader, Maxwell::MaxShaderProgram> last_shaders;
 
 
     GraphicsPipelineCacheKey last_graphics_key;
     GraphicsPipelineCacheKey last_graphics_key;