diff options
Diffstat (limited to 'src/video_core')
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_cache.cpp | 45 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_cache.h | 2 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_gen.cpp | 7 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_gen.h | 3 | 
4 files changed, 57 insertions, 0 deletions
| diff --git a/src/video_core/renderer_opengl/gl_shader_cache.cpp b/src/video_core/renderer_opengl/gl_shader_cache.cpp index 038b25c75..a4265f498 100644 --- a/src/video_core/renderer_opengl/gl_shader_cache.cpp +++ b/src/video_core/renderer_opengl/gl_shader_cache.cpp @@ -2,7 +2,9 @@  // Licensed under GPLv2 or any later version  // Refer to the license.txt file included. +#include <boost/functional/hash.hpp>  #include "common/assert.h" +#include "common/hash.h"  #include "core/core.h"  #include "core/memory.h"  #include "video_core/engines/maxwell_3d.h" @@ -66,14 +68,17 @@ CachedShader::CachedShader(VAddr addr, Maxwell::ShaderProgram program_type)          // stage here.          setup.SetProgramB(GetShaderCode(GetShaderAddress(Maxwell::ShaderProgram::VertexB)));      case Maxwell::ShaderProgram::VertexB: +        CalculateProperties();          program_result = GLShader::GenerateVertexShader(setup);          gl_type = GL_VERTEX_SHADER;          break;      case Maxwell::ShaderProgram::Geometry: +        CalculateProperties();          program_result = GLShader::GenerateGeometryShader(setup);          gl_type = GL_GEOMETRY_SHADER;          break;      case Maxwell::ShaderProgram::Fragment: +        CalculateProperties();          program_result = GLShader::GenerateFragmentShader(setup);          gl_type = GL_FRAGMENT_SHADER;          break; @@ -140,6 +145,46 @@ GLuint CachedShader::LazyGeometryProgram(OGLProgram& target_program,      return target_program.handle;  }; +static bool IsSchedInstruction(u32 offset, u32 main_offset) { +    // sched instructions appear once every 4 instructions. +    static constexpr std::size_t SchedPeriod = 4; +    const std::size_t absolute_offset = offset - main_offset; +    return (absolute_offset % SchedPeriod) == 0; +} + +static std::size_t CalculateProgramSize(const GLShader::ProgramCode& program) { +    const std::size_t start_offset = 10; +    std::size_t offset = start_offset; +    std::size_t size = start_offset * sizeof(u64); +    while (offset < program.size()) { +        const u64 inst = program[offset]; +        if (!IsSchedInstruction(offset, start_offset)) { +            if (inst == 0 || (inst >> 52) == 0x50b) { +                break; +            } +        } +        size += 8; +        offset++; +    } +    return size; +} + +void CachedShader::CalculateProperties() { +    setup.program.real_size = CalculateProgramSize(setup.program.code); +    setup.program.real_size_b = 0; +    setup.program.unique_identifier = Common::CityHash64( +        reinterpret_cast<const char*>(setup.program.code.data()), setup.program.real_size); +    if (program_type == Maxwell::ShaderProgram::VertexA) { +        std::size_t seed = 0; +        boost::hash_combine(seed, setup.program.unique_identifier); +        setup.program.real_size_b = CalculateProgramSize(setup.program.code_b); +        const u64 identifier_b = Common::CityHash64( +            reinterpret_cast<const char*>(setup.program.code_b.data()), setup.program.real_size_b); +        boost::hash_combine(seed, identifier_b); +        setup.program.unique_identifier = static_cast<u64>(seed); +    } +} +  ShaderCacheOpenGL::ShaderCacheOpenGL(RasterizerOpenGL& rasterizer) : RasterizerCache{rasterizer} {}  Shader ShaderCacheOpenGL::GetStageProgram(Maxwell::ShaderProgram program) { diff --git a/src/video_core/renderer_opengl/gl_shader_cache.h b/src/video_core/renderer_opengl/gl_shader_cache.h index 08f470de3..b4ef6030d 100644 --- a/src/video_core/renderer_opengl/gl_shader_cache.h +++ b/src/video_core/renderer_opengl/gl_shader_cache.h @@ -81,6 +81,8 @@ private:      GLuint LazyGeometryProgram(OGLProgram& target_program, const std::string& glsl_topology,                                 u32 max_vertices, const std::string& debug_name); +    void CalculateProperties(); +      VAddr addr;      std::size_t shader_length;      Maxwell::ShaderProgram program_type; diff --git a/src/video_core/renderer_opengl/gl_shader_gen.cpp b/src/video_core/renderer_opengl/gl_shader_gen.cpp index 23ed91e27..5d0819dc5 100644 --- a/src/video_core/renderer_opengl/gl_shader_gen.cpp +++ b/src/video_core/renderer_opengl/gl_shader_gen.cpp @@ -2,6 +2,7 @@  // Licensed under GPLv2 or any later version  // Refer to the license.txt file included. +#include <fmt/format.h>  #include "common/assert.h"  #include "video_core/engines/maxwell_3d.h"  #include "video_core/renderer_opengl/gl_shader_decompiler.h" @@ -16,6 +17,8 @@ static constexpr u32 PROGRAM_OFFSET{10};  ProgramResult GenerateVertexShader(const ShaderSetup& setup) {      std::string out = "#version 430 core\n";      out += "#extension GL_ARB_separate_shader_objects : enable\n\n"; +    const std::string id = fmt::format("{:016x}", setup.program.unique_identifier); +    out += "// Shader Unique Id: VS" + id + "\n\n";      out += Decompiler::GetCommonDeclarations();      out += R"( @@ -84,6 +87,8 @@ void main() {  ProgramResult GenerateGeometryShader(const ShaderSetup& setup) {      // Version is intentionally skipped in shader generation, it's added by the lazy compilation.      std::string out = "#extension GL_ARB_separate_shader_objects : enable\n\n"; +    const std::string id = fmt::format("{:016x}", setup.program.unique_identifier); +    out += "// Shader Unique Id: GS" + id + "\n\n";      out += Decompiler::GetCommonDeclarations();      out += "bool exec_geometry();\n"; @@ -117,6 +122,8 @@ void main() {  ProgramResult GenerateFragmentShader(const ShaderSetup& setup) {      std::string out = "#version 430 core\n";      out += "#extension GL_ARB_separate_shader_objects : enable\n\n"; +    const std::string id = fmt::format("{:016x}", setup.program.unique_identifier); +    out += "// Shader Unique Id: FS" + id + "\n\n";      out += Decompiler::GetCommonDeclarations();      out += "bool exec_fragment();\n"; diff --git a/src/video_core/renderer_opengl/gl_shader_gen.h b/src/video_core/renderer_opengl/gl_shader_gen.h index 4fa6d7612..fcc20d3b4 100644 --- a/src/video_core/renderer_opengl/gl_shader_gen.h +++ b/src/video_core/renderer_opengl/gl_shader_gen.h @@ -177,6 +177,9 @@ struct ShaderSetup {      struct {          ProgramCode code;          ProgramCode code_b; // Used for dual vertex shaders +        u64 unique_identifier; +        std::size_t real_size; +        std::size_t real_size_b;      } program;      /// Used in scenarios where we have a dual vertex shaders | 
