mirror of
https://github.com/yuzu-mirror/yuzu.git
synced 2024-11-03 06:10:00 +00:00
Implemented a shader unique identifier.
This commit is contained in:
parent
f761e3ef86
commit
d5d77848e6
4 changed files with 57 additions and 0 deletions
|
@ -2,7 +2,9 @@
|
||||||
// Licensed under GPLv2 or any later version
|
// Licensed under GPLv2 or any later version
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#include <boost/functional/hash.hpp>
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
|
#include "common/hash.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
#include "core/memory.h"
|
#include "core/memory.h"
|
||||||
#include "video_core/engines/maxwell_3d.h"
|
#include "video_core/engines/maxwell_3d.h"
|
||||||
|
@ -66,14 +68,17 @@ CachedShader::CachedShader(VAddr addr, Maxwell::ShaderProgram program_type)
|
||||||
// stage here.
|
// stage here.
|
||||||
setup.SetProgramB(GetShaderCode(GetShaderAddress(Maxwell::ShaderProgram::VertexB)));
|
setup.SetProgramB(GetShaderCode(GetShaderAddress(Maxwell::ShaderProgram::VertexB)));
|
||||||
case Maxwell::ShaderProgram::VertexB:
|
case Maxwell::ShaderProgram::VertexB:
|
||||||
|
CalculateProperties();
|
||||||
program_result = GLShader::GenerateVertexShader(setup);
|
program_result = GLShader::GenerateVertexShader(setup);
|
||||||
gl_type = GL_VERTEX_SHADER;
|
gl_type = GL_VERTEX_SHADER;
|
||||||
break;
|
break;
|
||||||
case Maxwell::ShaderProgram::Geometry:
|
case Maxwell::ShaderProgram::Geometry:
|
||||||
|
CalculateProperties();
|
||||||
program_result = GLShader::GenerateGeometryShader(setup);
|
program_result = GLShader::GenerateGeometryShader(setup);
|
||||||
gl_type = GL_GEOMETRY_SHADER;
|
gl_type = GL_GEOMETRY_SHADER;
|
||||||
break;
|
break;
|
||||||
case Maxwell::ShaderProgram::Fragment:
|
case Maxwell::ShaderProgram::Fragment:
|
||||||
|
CalculateProperties();
|
||||||
program_result = GLShader::GenerateFragmentShader(setup);
|
program_result = GLShader::GenerateFragmentShader(setup);
|
||||||
gl_type = GL_FRAGMENT_SHADER;
|
gl_type = GL_FRAGMENT_SHADER;
|
||||||
break;
|
break;
|
||||||
|
@ -140,6 +145,46 @@ GLuint CachedShader::LazyGeometryProgram(OGLProgram& target_program,
|
||||||
return target_program.handle;
|
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} {}
|
ShaderCacheOpenGL::ShaderCacheOpenGL(RasterizerOpenGL& rasterizer) : RasterizerCache{rasterizer} {}
|
||||||
|
|
||||||
Shader ShaderCacheOpenGL::GetStageProgram(Maxwell::ShaderProgram program) {
|
Shader ShaderCacheOpenGL::GetStageProgram(Maxwell::ShaderProgram program) {
|
||||||
|
|
|
@ -81,6 +81,8 @@ private:
|
||||||
GLuint LazyGeometryProgram(OGLProgram& target_program, const std::string& glsl_topology,
|
GLuint LazyGeometryProgram(OGLProgram& target_program, const std::string& glsl_topology,
|
||||||
u32 max_vertices, const std::string& debug_name);
|
u32 max_vertices, const std::string& debug_name);
|
||||||
|
|
||||||
|
void CalculateProperties();
|
||||||
|
|
||||||
VAddr addr;
|
VAddr addr;
|
||||||
std::size_t shader_length;
|
std::size_t shader_length;
|
||||||
Maxwell::ShaderProgram program_type;
|
Maxwell::ShaderProgram program_type;
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
// Licensed under GPLv2 or any later version
|
// Licensed under GPLv2 or any later version
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#include <fmt/format.h>
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
#include "video_core/engines/maxwell_3d.h"
|
#include "video_core/engines/maxwell_3d.h"
|
||||||
#include "video_core/renderer_opengl/gl_shader_decompiler.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) {
|
ProgramResult GenerateVertexShader(const ShaderSetup& setup) {
|
||||||
std::string out = "#version 430 core\n";
|
std::string out = "#version 430 core\n";
|
||||||
out += "#extension GL_ARB_separate_shader_objects : enable\n\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 += Decompiler::GetCommonDeclarations();
|
||||||
|
|
||||||
out += R"(
|
out += R"(
|
||||||
|
@ -84,6 +87,8 @@ void main() {
|
||||||
ProgramResult GenerateGeometryShader(const ShaderSetup& setup) {
|
ProgramResult GenerateGeometryShader(const ShaderSetup& setup) {
|
||||||
// Version is intentionally skipped in shader generation, it's added by the lazy compilation.
|
// 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";
|
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 += Decompiler::GetCommonDeclarations();
|
||||||
out += "bool exec_geometry();\n";
|
out += "bool exec_geometry();\n";
|
||||||
|
|
||||||
|
@ -117,6 +122,8 @@ void main() {
|
||||||
ProgramResult GenerateFragmentShader(const ShaderSetup& setup) {
|
ProgramResult GenerateFragmentShader(const ShaderSetup& setup) {
|
||||||
std::string out = "#version 430 core\n";
|
std::string out = "#version 430 core\n";
|
||||||
out += "#extension GL_ARB_separate_shader_objects : enable\n\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 += Decompiler::GetCommonDeclarations();
|
||||||
out += "bool exec_fragment();\n";
|
out += "bool exec_fragment();\n";
|
||||||
|
|
||||||
|
|
|
@ -177,6 +177,9 @@ struct ShaderSetup {
|
||||||
struct {
|
struct {
|
||||||
ProgramCode code;
|
ProgramCode code;
|
||||||
ProgramCode code_b; // Used for dual vertex shaders
|
ProgramCode code_b; // Used for dual vertex shaders
|
||||||
|
u64 unique_identifier;
|
||||||
|
std::size_t real_size;
|
||||||
|
std::size_t real_size_b;
|
||||||
} program;
|
} program;
|
||||||
|
|
||||||
/// Used in scenarios where we have a dual vertex shaders
|
/// Used in scenarios where we have a dual vertex shaders
|
||||||
|
|
Loading…
Reference in a new issue