summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Fernando Sahmkow2018-12-09 17:33:10 -0400
committerGravatar FernandoS272018-12-09 17:33:33 -0400
commitd5d77848e68ff9571797dd7df6242f0ab25f6fd3 (patch)
treee818fbe21b23f97907bde07e491bdbb41f8b7137 /src
parentMerge pull request #1868 from lioncash/config (diff)
downloadyuzu-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.cpp45
-rw-r--r--src/video_core/renderer_opengl/gl_shader_cache.h2
-rw-r--r--src/video_core/renderer_opengl/gl_shader_gen.cpp7
-rw-r--r--src/video_core/renderer_opengl/gl_shader_gen.h3
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
148static 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
155static 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
172void 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
143ShaderCacheOpenGL::ShaderCacheOpenGL(RasterizerOpenGL& rasterizer) : RasterizerCache{rasterizer} {} 188ShaderCacheOpenGL::ShaderCacheOpenGL(RasterizerOpenGL& rasterizer) : RasterizerCache{rasterizer} {}
144 189
145Shader ShaderCacheOpenGL::GetStageProgram(Maxwell::ShaderProgram program) { 190Shader 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};
16ProgramResult GenerateVertexShader(const ShaderSetup& setup) { 17ProgramResult 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() {
84ProgramResult GenerateGeometryShader(const ShaderSetup& setup) { 87ProgramResult 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() {
117ProgramResult GenerateFragmentShader(const ShaderSetup& setup) { 122ProgramResult 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