diff options
Diffstat (limited to 'src/video_core')
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_disk_cache.cpp | 43 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_disk_cache.h | 14 | 
2 files changed, 57 insertions, 0 deletions
| diff --git a/src/video_core/renderer_opengl/gl_shader_disk_cache.cpp b/src/video_core/renderer_opengl/gl_shader_disk_cache.cpp index eb9854b9f..0c42e3d8a 100644 --- a/src/video_core/renderer_opengl/gl_shader_disk_cache.cpp +++ b/src/video_core/renderer_opengl/gl_shader_disk_cache.cpp @@ -27,6 +27,9 @@ enum class EntryKind : u32 {  constexpr u32 NativeVersion = 1; +// TODO(Rodrigo): Hash files +constexpr u64 PrecompiledHash = 0xdeadbeefdeadbeef; +  // Making sure sizes doesn't change by accident  static_assert(sizeof(BaseBindings) == 12);  static_assert(sizeof(ShaderDiskCacheUsage) == 24); @@ -153,6 +156,26 @@ void ShaderDiskCacheOpenGL::SaveUsage(const ShaderDiskCacheUsage& usage) {      file.WriteObject(usage);  } +void ShaderDiskCacheOpenGL::SavePrecompiled(const ShaderDiskCacheUsage& usage, GLuint program) { +    FileUtil::IOFile file = AppendPrecompiledFile(); +    if (!file.IsOpen()) { +        return; +    } + +    file.WriteObject(usage); + +    GLint binary_length{}; +    glGetProgramiv(program, GL_PROGRAM_BINARY_LENGTH, &binary_length); + +    GLenum binary_format{}; +    std::vector<u8> binary(binary_length); +    glGetProgramBinary(program, binary_length, nullptr, &binary_format, binary.data()); + +    file.WriteObject(static_cast<u32>(binary_format)); +    file.WriteObject(static_cast<u32>(binary_length)); +    file.WriteArray(binary.data(), binary.size()); +} +  FileUtil::IOFile ShaderDiskCacheOpenGL::AppendTransferableFile() const {      if (!EnsureDirectories()) {          return {}; @@ -173,6 +196,26 @@ FileUtil::IOFile ShaderDiskCacheOpenGL::AppendTransferableFile() const {      return file;  } +FileUtil::IOFile ShaderDiskCacheOpenGL::AppendPrecompiledFile() const { +    if (!EnsureDirectories()) { +        return {}; +    } + +    const auto precompiled_path{GetPrecompiledPath()}; +    const bool existed = FileUtil::Exists(precompiled_path); + +    FileUtil::IOFile file(precompiled_path, "ab"); +    if (!file.IsOpen()) { +        LOG_ERROR(Render_OpenGL, "Failed to open precompiled cache in path={}", precompiled_path); +        return {}; +    } + +    if (!existed || file.GetSize() == 0) { +        file.WriteObject(PrecompiledHash); +    } +    return file; +} +  bool ShaderDiskCacheOpenGL::EnsureDirectories() const {      const auto CreateDir = [](const std::string& dir) {          if (!FileUtil::CreateDir(dir)) { diff --git a/src/video_core/renderer_opengl/gl_shader_disk_cache.h b/src/video_core/renderer_opengl/gl_shader_disk_cache.h index 46d762b64..fdb29caa5 100644 --- a/src/video_core/renderer_opengl/gl_shader_disk_cache.h +++ b/src/video_core/renderer_opengl/gl_shader_disk_cache.h @@ -130,6 +130,14 @@ public:      }  }; +struct ShaderDiskCachePrecompiledEntry { +    ShaderDiskCacheUsage usage; +    GLenum binary_format; +    std::vector<u8> binary; +    std::string code; +    GLShader::ShaderEntries entries; +}; +  class ShaderDiskCacheOpenGL {  public:      /// Loads transferable cache. If file has a old version, it deletes it. Returns true on success. @@ -142,10 +150,16 @@ public:      /// Saves shader usage to the transferable file. Does not check for collisions.      void SaveUsage(const ShaderDiskCacheUsage& usage); +    /// Saves a precompiled shader entry. Does not check for collisions. +    void SavePrecompiled(const ShaderDiskCacheUsage& usage, GLuint program); +  private:      /// Opens current game's transferable file and write it's header if it doesn't exist      FileUtil::IOFile AppendTransferableFile() const; +    /// Opens current game's precompiled file and write it's header if it doesn't exist +    FileUtil::IOFile AppendPrecompiledFile() const; +      /// Create shader disk cache directories. Returns true on success.      bool EnsureDirectories() const; | 
