diff options
| author | ameerj <52414509+ameerj@users.noreply.github.com> | 2023-01-29 21:04:46 -0500 | 
|---|---|---|
| committer | ameerj <52414509+ameerj@users.noreply.github.com> | 2023-01-29 21:32:12 -0500 | 
| commit | 720ff380978e4e353ec878953c261b3a1b6451d7 (patch) | |
| tree | 02a7fe6182ec18f933ede578a4602e0cc757b6d0 | |
| parent | 01eeda74a65611b833de871a188db30a12f51fa3 (diff) | |
gl_compute_pipeline: Force context flush when loading shader cache
4 files changed, 37 insertions, 7 deletions
| diff --git a/src/video_core/renderer_opengl/gl_compute_pipeline.cpp b/src/video_core/renderer_opengl/gl_compute_pipeline.cpp index 26d066004..1a0cea9b7 100644 --- a/src/video_core/renderer_opengl/gl_compute_pipeline.cpp +++ b/src/video_core/renderer_opengl/gl_compute_pipeline.cpp @@ -30,7 +30,7 @@ bool ComputePipelineKey::operator==(const ComputePipelineKey& rhs) const noexcep  ComputePipeline::ComputePipeline(const Device& device, TextureCache& texture_cache_,                                   BufferCache& buffer_cache_, ProgramManager& program_manager_,                                   const Shader::Info& info_, std::string code, -                                 std::vector<u32> code_v) +                                 std::vector<u32> code_v, bool force_context_flush)      : texture_cache{texture_cache_}, buffer_cache{buffer_cache_},        program_manager{program_manager_}, info{info_} {      switch (device.GetShaderBackend()) { @@ -63,6 +63,15 @@ ComputePipeline::ComputePipeline(const Device& device, TextureCache& texture_cac      writes_global_memory = !use_storage_buffers &&                             std::ranges::any_of(info.storage_buffers_descriptors,                                                 [](const auto& desc) { return desc.is_written; }); +    if (force_context_flush) { +        std::scoped_lock lock{built_mutex}; +        built_fence.Create(); +        // Flush this context to ensure compilation commands and fence are in the GPU pipe. +        glFlush(); +        built_condvar.notify_one(); +    } else { +        is_built = true; +    }  }  void ComputePipeline::Configure() { @@ -142,6 +151,9 @@ void ComputePipeline::Configure() {      }      texture_cache.FillComputeImageViews(std::span(views.data(), views.size())); +    if (!is_built) { +        WaitForBuild(); +    }      if (assembly_program.handle != 0) {          program_manager.BindComputeAssemblyProgram(assembly_program.handle);      } else { @@ -223,4 +235,13 @@ void ComputePipeline::Configure() {      }  } +void ComputePipeline::WaitForBuild() { +    if (built_fence.handle == 0) { +        std::unique_lock lock{built_mutex}; +        built_condvar.wait(lock, [this] { return built_fence.handle != 0; }); +    } +    ASSERT(glClientWaitSync(built_fence.handle, 0, GL_TIMEOUT_IGNORED) != GL_WAIT_FAILED); +    is_built = true; +} +  } // namespace OpenGL diff --git a/src/video_core/renderer_opengl/gl_compute_pipeline.h b/src/video_core/renderer_opengl/gl_compute_pipeline.h index 6534dec32..9bcc72b59 100644 --- a/src/video_core/renderer_opengl/gl_compute_pipeline.h +++ b/src/video_core/renderer_opengl/gl_compute_pipeline.h @@ -50,7 +50,8 @@ class ComputePipeline {  public:      explicit ComputePipeline(const Device& device, TextureCache& texture_cache_,                               BufferCache& buffer_cache_, ProgramManager& program_manager_, -                             const Shader::Info& info_, std::string code, std::vector<u32> code_v); +                             const Shader::Info& info_, std::string code, std::vector<u32> code_v, +                             bool force_context_flush = false);      void Configure(); @@ -65,6 +66,8 @@ public:      }  private: +    void WaitForBuild(); +      TextureCache& texture_cache;      BufferCache& buffer_cache;      Tegra::MemoryManager* gpu_memory; @@ -81,6 +84,11 @@ private:      bool use_storage_buffers{};      bool writes_global_memory{}; + +    std::mutex built_mutex; +    std::condition_variable built_condvar; +    OGLSync built_fence{}; +    bool is_built{false};  };  } // namespace OpenGL diff --git a/src/video_core/renderer_opengl/gl_shader_cache.cpp b/src/video_core/renderer_opengl/gl_shader_cache.cpp index 15812b678..626ea7dcb 100644 --- a/src/video_core/renderer_opengl/gl_shader_cache.cpp +++ b/src/video_core/renderer_opengl/gl_shader_cache.cpp @@ -286,7 +286,7 @@ void ShaderCache::LoadDiskResources(u64 title_id, std::stop_token stop_loading,          file.read(reinterpret_cast<char*>(&key), sizeof(key));          queue_work([this, key, env = std::move(env), &state, &callback](Context* ctx) mutable {              ctx->pools.ReleaseContents(); -            auto pipeline{CreateComputePipeline(ctx->pools, key, env)}; +            auto pipeline{CreateComputePipeline(ctx->pools, key, env, true)};              std::scoped_lock lock{state.mutex};              if (pipeline) {                  compute_cache.emplace(key, std::move(pipeline)); @@ -560,8 +560,8 @@ std::unique_ptr<ComputePipeline> ShaderCache::CreateComputePipeline(  }  std::unique_ptr<ComputePipeline> ShaderCache::CreateComputePipeline( -    ShaderContext::ShaderPools& pools, const ComputePipelineKey& key, -    Shader::Environment& env) try { +    ShaderContext::ShaderPools& pools, const ComputePipelineKey& key, Shader::Environment& env, +    bool force_context_flush) try {      LOG_INFO(Render_OpenGL, "0x{:016x}", key.Hash());      Shader::Maxwell::Flow::CFG cfg{env, pools.flow_block, env.StartAddress()}; @@ -590,7 +590,7 @@ std::unique_ptr<ComputePipeline> ShaderCache::CreateComputePipeline(      }      return std::make_unique<ComputePipeline>(device, texture_cache, buffer_cache, program_manager, -                                             program.info, code, code_spirv); +                                             program.info, code, code_spirv, force_context_flush);  } catch (Shader::Exception& exception) {      LOG_ERROR(Render_OpenGL, "{}", exception.what());      return nullptr; diff --git a/src/video_core/renderer_opengl/gl_shader_cache.h b/src/video_core/renderer_opengl/gl_shader_cache.h index 50f610cd0..6b9732fca 100644 --- a/src/video_core/renderer_opengl/gl_shader_cache.h +++ b/src/video_core/renderer_opengl/gl_shader_cache.h @@ -58,7 +58,8 @@ private:      std::unique_ptr<ComputePipeline> CreateComputePipeline(ShaderContext::ShaderPools& pools,                                                             const ComputePipelineKey& key, -                                                           Shader::Environment& env); +                                                           Shader::Environment& env, +                                                           bool force_context_flush = false);      std::unique_ptr<ShaderWorker> CreateWorkers() const; | 
