diff options
| author | 2018-12-09 17:33:10 -0400 | |
|---|---|---|
| committer | 2018-12-09 17:33:33 -0400 | |
| commit | d5d77848e68ff9571797dd7df6242f0ab25f6fd3 (patch) | |
| tree | e818fbe21b23f97907bde07e491bdbb41f8b7137 /src | |
| parent | Merge pull request #1868 from lioncash/config (diff) | |
| download | yuzu-d5d77848e68ff9571797dd7df6242f0ab25f6fd3.tar.gz yuzu-d5d77848e68ff9571797dd7df6242f0ab25f6fd3.tar.xz yuzu-d5d77848e68ff9571797dd7df6242f0ab25f6fd3.zip | |
Implemented a shader unique identifier.
Diffstat (limited to 'src')
| -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 @@ | |||
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include <boost/functional/hash.hpp> | ||
| 5 | #include "common/assert.h" | 6 | #include "common/assert.h" |
| 7 | #include "common/hash.h" | ||
| 6 | #include "core/core.h" | 8 | #include "core/core.h" |
| 7 | #include "core/memory.h" | 9 | #include "core/memory.h" |
| 8 | #include "video_core/engines/maxwell_3d.h" | 10 | #include "video_core/engines/maxwell_3d.h" |
| @@ -66,14 +68,17 @@ CachedShader::CachedShader(VAddr addr, Maxwell::ShaderProgram program_type) | |||
| 66 | // stage here. | 68 | // stage here. |
| 67 | setup.SetProgramB(GetShaderCode(GetShaderAddress(Maxwell::ShaderProgram::VertexB))); | 69 | setup.SetProgramB(GetShaderCode(GetShaderAddress(Maxwell::ShaderProgram::VertexB))); |
| 68 | case Maxwell::ShaderProgram::VertexB: | 70 | case Maxwell::ShaderProgram::VertexB: |
| 71 | CalculateProperties(); | ||
| 69 | program_result = GLShader::GenerateVertexShader(setup); | 72 | program_result = GLShader::GenerateVertexShader(setup); |
| 70 | gl_type = GL_VERTEX_SHADER; | 73 | gl_type = GL_VERTEX_SHADER; |
| 71 | break; | 74 | break; |
| 72 | case Maxwell::ShaderProgram::Geometry: | 75 | case Maxwell::ShaderProgram::Geometry: |
| 76 | CalculateProperties(); | ||
| 73 | program_result = GLShader::GenerateGeometryShader(setup); | 77 | program_result = GLShader::GenerateGeometryShader(setup); |
| 74 | gl_type = GL_GEOMETRY_SHADER; | 78 | gl_type = GL_GEOMETRY_SHADER; |
| 75 | break; | 79 | break; |
| 76 | case Maxwell::ShaderProgram::Fragment: | 80 | case Maxwell::ShaderProgram::Fragment: |
| 81 | CalculateProperties(); | ||
| 77 | program_result = GLShader::GenerateFragmentShader(setup); | 82 | program_result = GLShader::GenerateFragmentShader(setup); |
| 78 | gl_type = GL_FRAGMENT_SHADER; | 83 | gl_type = GL_FRAGMENT_SHADER; |
| 79 | break; | 84 | break; |
| @@ -140,6 +145,46 @@ GLuint CachedShader::LazyGeometryProgram(OGLProgram& target_program, | |||
| 140 | return target_program.handle; | 145 | return target_program.handle; |
| 141 | }; | 146 | }; |
| 142 | 147 | ||
| 148 | static bool IsSchedInstruction(u32 offset, u32 main_offset) { | ||
| 149 | // sched instructions appear once every 4 instructions. | ||
| 150 | static constexpr std::size_t SchedPeriod = 4; | ||
| 151 | const std::size_t absolute_offset = offset - main_offset; | ||
| 152 | return (absolute_offset % SchedPeriod) == 0; | ||
| 153 | } | ||
| 154 | |||
| 155 | static std::size_t CalculateProgramSize(const GLShader::ProgramCode& program) { | ||
| 156 | const std::size_t start_offset = 10; | ||
| 157 | std::size_t offset = start_offset; | ||
| 158 | std::size_t size = start_offset * sizeof(u64); | ||
| 159 | while (offset < program.size()) { | ||
| 160 | const u64 inst = program[offset]; | ||
| 161 | if (!IsSchedInstruction(offset, start_offset)) { | ||
| 162 | if (inst == 0 || (inst >> 52) == 0x50b) { | ||
| 163 | break; | ||
| 164 | } | ||
| 165 | } | ||
| 166 | size += 8; | ||
| 167 | offset++; | ||
| 168 | } | ||
| 169 | return size; | ||
| 170 | } | ||
| 171 | |||
| 172 | void CachedShader::CalculateProperties() { | ||
| 173 | setup.program.real_size = CalculateProgramSize(setup.program.code); | ||
| 174 | setup.program.real_size_b = 0; | ||
| 175 | setup.program.unique_identifier = Common::CityHash64( | ||
| 176 | reinterpret_cast<const char*>(setup.program.code.data()), setup.program.real_size); | ||
| 177 | if (program_type == Maxwell::ShaderProgram::VertexA) { | ||
| 178 | std::size_t seed = 0; | ||
| 179 | boost::hash_combine(seed, setup.program.unique_identifier); | ||
| 180 | setup.program.real_size_b = CalculateProgramSize(setup.program.code_b); | ||
| 181 | const u64 identifier_b = Common::CityHash64( | ||
| 182 | reinterpret_cast<const char*>(setup.program.code_b.data()), setup.program.real_size_b); | ||
| 183 | boost::hash_combine(seed, identifier_b); | ||
| 184 | setup.program.unique_identifier = static_cast<u64>(seed); | ||
| 185 | } | ||
| 186 | } | ||
| 187 | |||
| 143 | ShaderCacheOpenGL::ShaderCacheOpenGL(RasterizerOpenGL& rasterizer) : RasterizerCache{rasterizer} {} | 188 | ShaderCacheOpenGL::ShaderCacheOpenGL(RasterizerOpenGL& rasterizer) : RasterizerCache{rasterizer} {} |
| 144 | 189 | ||
| 145 | Shader ShaderCacheOpenGL::GetStageProgram(Maxwell::ShaderProgram program) { | 190 | 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: | |||
| 81 | GLuint LazyGeometryProgram(OGLProgram& target_program, const std::string& glsl_topology, | 81 | GLuint LazyGeometryProgram(OGLProgram& target_program, const std::string& glsl_topology, |
| 82 | u32 max_vertices, const std::string& debug_name); | 82 | u32 max_vertices, const std::string& debug_name); |
| 83 | 83 | ||
| 84 | void CalculateProperties(); | ||
| 85 | |||
| 84 | VAddr addr; | 86 | VAddr addr; |
| 85 | std::size_t shader_length; | 87 | std::size_t shader_length; |
| 86 | Maxwell::ShaderProgram program_type; | 88 | 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 @@ | |||
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include <fmt/format.h> | ||
| 5 | #include "common/assert.h" | 6 | #include "common/assert.h" |
| 6 | #include "video_core/engines/maxwell_3d.h" | 7 | #include "video_core/engines/maxwell_3d.h" |
| 7 | #include "video_core/renderer_opengl/gl_shader_decompiler.h" | 8 | #include "video_core/renderer_opengl/gl_shader_decompiler.h" |
| @@ -16,6 +17,8 @@ static constexpr u32 PROGRAM_OFFSET{10}; | |||
| 16 | ProgramResult GenerateVertexShader(const ShaderSetup& setup) { | 17 | ProgramResult GenerateVertexShader(const ShaderSetup& setup) { |
| 17 | std::string out = "#version 430 core\n"; | 18 | std::string out = "#version 430 core\n"; |
| 18 | out += "#extension GL_ARB_separate_shader_objects : enable\n\n"; | 19 | out += "#extension GL_ARB_separate_shader_objects : enable\n\n"; |
| 20 | const std::string id = fmt::format("{:016x}", setup.program.unique_identifier); | ||
| 21 | out += "// Shader Unique Id: VS" + id + "\n\n"; | ||
| 19 | out += Decompiler::GetCommonDeclarations(); | 22 | out += Decompiler::GetCommonDeclarations(); |
| 20 | 23 | ||
| 21 | out += R"( | 24 | out += R"( |
| @@ -84,6 +87,8 @@ void main() { | |||
| 84 | ProgramResult GenerateGeometryShader(const ShaderSetup& setup) { | 87 | ProgramResult GenerateGeometryShader(const ShaderSetup& setup) { |
| 85 | // Version is intentionally skipped in shader generation, it's added by the lazy compilation. | 88 | // Version is intentionally skipped in shader generation, it's added by the lazy compilation. |
| 86 | std::string out = "#extension GL_ARB_separate_shader_objects : enable\n\n"; | 89 | std::string out = "#extension GL_ARB_separate_shader_objects : enable\n\n"; |
| 90 | const std::string id = fmt::format("{:016x}", setup.program.unique_identifier); | ||
| 91 | out += "// Shader Unique Id: GS" + id + "\n\n"; | ||
| 87 | out += Decompiler::GetCommonDeclarations(); | 92 | out += Decompiler::GetCommonDeclarations(); |
| 88 | out += "bool exec_geometry();\n"; | 93 | out += "bool exec_geometry();\n"; |
| 89 | 94 | ||
| @@ -117,6 +122,8 @@ void main() { | |||
| 117 | ProgramResult GenerateFragmentShader(const ShaderSetup& setup) { | 122 | ProgramResult GenerateFragmentShader(const ShaderSetup& setup) { |
| 118 | std::string out = "#version 430 core\n"; | 123 | std::string out = "#version 430 core\n"; |
| 119 | out += "#extension GL_ARB_separate_shader_objects : enable\n\n"; | 124 | out += "#extension GL_ARB_separate_shader_objects : enable\n\n"; |
| 125 | const std::string id = fmt::format("{:016x}", setup.program.unique_identifier); | ||
| 126 | out += "// Shader Unique Id: FS" + id + "\n\n"; | ||
| 120 | out += Decompiler::GetCommonDeclarations(); | 127 | out += Decompiler::GetCommonDeclarations(); |
| 121 | out += "bool exec_fragment();\n"; | 128 | out += "bool exec_fragment();\n"; |
| 122 | 129 | ||
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 { | |||
| 177 | struct { | 177 | struct { |
| 178 | ProgramCode code; | 178 | ProgramCode code; |
| 179 | ProgramCode code_b; // Used for dual vertex shaders | 179 | ProgramCode code_b; // Used for dual vertex shaders |
| 180 | u64 unique_identifier; | ||
| 181 | std::size_t real_size; | ||
| 182 | std::size_t real_size_b; | ||
| 180 | } program; | 183 | } program; |
| 181 | 184 | ||
| 182 | /// Used in scenarios where we have a dual vertex shaders | 185 | /// Used in scenarios where we have a dual vertex shaders |