summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Fernando Sahmkow2019-06-25 07:57:32 -0400
committerGravatar FernandoS272019-07-09 08:14:37 -0400
commit459fce3a8f26241ff2a68c323e75fb70e7e1ba79 (patch)
tree4b653d7dd8fd7e6d325ca69cdd1384187cbd73ac /src
parentshader_ir: Implement BRX & BRA.CC (diff)
downloadyuzu-459fce3a8f26241ff2a68c323e75fb70e7e1ba79.tar.gz
yuzu-459fce3a8f26241ff2a68c323e75fb70e7e1ba79.tar.xz
yuzu-459fce3a8f26241ff2a68c323e75fb70e7e1ba79.zip
shader_ir: propagate shader size to the IR
Diffstat (limited to 'src')
-rw-r--r--src/video_core/renderer_opengl/gl_shader_cache.cpp22
-rw-r--r--src/video_core/renderer_opengl/gl_shader_gen.cpp8
-rw-r--r--src/video_core/renderer_opengl/gl_shader_gen.h2
-rw-r--r--src/video_core/shader/decode.cpp6
-rw-r--r--src/video_core/shader/shader_ir.cpp4
-rw-r--r--src/video_core/shader/shader_ir.h3
6 files changed, 28 insertions, 17 deletions
diff --git a/src/video_core/renderer_opengl/gl_shader_cache.cpp b/src/video_core/renderer_opengl/gl_shader_cache.cpp
index f9b2b03a0..5d76ee12d 100644
--- a/src/video_core/renderer_opengl/gl_shader_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_cache.cpp
@@ -129,9 +129,11 @@ std::size_t CalculateProgramSize(const GLShader::ProgramCode& program) {
129 129
130/// Hashes one (or two) program streams 130/// Hashes one (or two) program streams
131u64 GetUniqueIdentifier(Maxwell::ShaderProgram program_type, const ProgramCode& code, 131u64 GetUniqueIdentifier(Maxwell::ShaderProgram program_type, const ProgramCode& code,
132 const ProgramCode& code_b) { 132 const ProgramCode& code_b, std::size_t size_a = 0, std::size_t size_b = 0) {
133 u64 unique_identifier = 133 if (size_a == 0) {
134 Common::CityHash64(reinterpret_cast<const char*>(code.data()), CalculateProgramSize(code)); 134 size_a = CalculateProgramSize(code);
135 }
136 u64 unique_identifier = Common::CityHash64(reinterpret_cast<const char*>(code.data()), size_a);
135 if (program_type != Maxwell::ShaderProgram::VertexA) { 137 if (program_type != Maxwell::ShaderProgram::VertexA) {
136 return unique_identifier; 138 return unique_identifier;
137 } 139 }
@@ -140,8 +142,11 @@ u64 GetUniqueIdentifier(Maxwell::ShaderProgram program_type, const ProgramCode&
140 std::size_t seed = 0; 142 std::size_t seed = 0;
141 boost::hash_combine(seed, unique_identifier); 143 boost::hash_combine(seed, unique_identifier);
142 144
143 const u64 identifier_b = Common::CityHash64(reinterpret_cast<const char*>(code_b.data()), 145 if (size_b == 0) {
144 CalculateProgramSize(code_b)); 146 size_b = CalculateProgramSize(code_b);
147 }
148 const u64 identifier_b =
149 Common::CityHash64(reinterpret_cast<const char*>(code_b.data()), size_b);
145 boost::hash_combine(seed, identifier_b); 150 boost::hash_combine(seed, identifier_b);
146 return static_cast<u64>(seed); 151 return static_cast<u64>(seed);
147} 152}
@@ -150,14 +155,17 @@ u64 GetUniqueIdentifier(Maxwell::ShaderProgram program_type, const ProgramCode&
150GLShader::ProgramResult CreateProgram(const Device& device, Maxwell::ShaderProgram program_type, 155GLShader::ProgramResult CreateProgram(const Device& device, Maxwell::ShaderProgram program_type,
151 ProgramCode program_code, ProgramCode program_code_b) { 156 ProgramCode program_code, ProgramCode program_code_b) {
152 GLShader::ShaderSetup setup(program_code); 157 GLShader::ShaderSetup setup(program_code);
158 setup.program.size_a = CalculateProgramSize(program_code);
159 setup.program.size_b = 0;
153 if (program_type == Maxwell::ShaderProgram::VertexA) { 160 if (program_type == Maxwell::ShaderProgram::VertexA) {
154 // VertexB is always enabled, so when VertexA is enabled, we have two vertex shaders. 161 // VertexB is always enabled, so when VertexA is enabled, we have two vertex shaders.
155 // Conventional HW does not support this, so we combine VertexA and VertexB into one 162 // Conventional HW does not support this, so we combine VertexA and VertexB into one
156 // stage here. 163 // stage here.
157 setup.SetProgramB(program_code_b); 164 setup.SetProgramB(program_code_b);
165 setup.program.size_b = CalculateProgramSize(program_code_b);
158 } 166 }
159 setup.program.unique_identifier = 167 setup.program.unique_identifier = GetUniqueIdentifier(
160 GetUniqueIdentifier(program_type, program_code, program_code_b); 168 program_type, program_code, program_code_b, setup.program.size_a, setup.program.size_b);
161 169
162 switch (program_type) { 170 switch (program_type) {
163 case Maxwell::ShaderProgram::VertexA: 171 case Maxwell::ShaderProgram::VertexA:
diff --git a/src/video_core/renderer_opengl/gl_shader_gen.cpp b/src/video_core/renderer_opengl/gl_shader_gen.cpp
index 9148629ec..f9ee8429e 100644
--- a/src/video_core/renderer_opengl/gl_shader_gen.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_gen.cpp
@@ -29,14 +29,14 @@ layout (std140, binding = EMULATION_UBO_BINDING) uniform vs_config {
29}; 29};
30 30
31)"; 31)";
32 const ShaderIR program_ir(setup.program.code, PROGRAM_OFFSET); 32 const ShaderIR program_ir(setup.program.code, PROGRAM_OFFSET, setup.program.size_a);
33 ProgramResult program = 33 ProgramResult program =
34 Decompile(device, program_ir, Maxwell3D::Regs::ShaderStage::Vertex, "vertex"); 34 Decompile(device, program_ir, Maxwell3D::Regs::ShaderStage::Vertex, "vertex");
35 35
36 out += program.first; 36 out += program.first;
37 37
38 if (setup.IsDualProgram()) { 38 if (setup.IsDualProgram()) {
39 const ShaderIR program_ir_b(setup.program.code_b, PROGRAM_OFFSET); 39 const ShaderIR program_ir_b(setup.program.code_b, PROGRAM_OFFSET, setup.program.size_b);
40 ProgramResult program_b = 40 ProgramResult program_b =
41 Decompile(device, program_ir_b, Maxwell3D::Regs::ShaderStage::Vertex, "vertex_b"); 41 Decompile(device, program_ir_b, Maxwell3D::Regs::ShaderStage::Vertex, "vertex_b");
42 42
@@ -80,7 +80,7 @@ layout (std140, binding = EMULATION_UBO_BINDING) uniform gs_config {
80}; 80};
81 81
82)"; 82)";
83 const ShaderIR program_ir(setup.program.code, PROGRAM_OFFSET); 83 const ShaderIR program_ir(setup.program.code, PROGRAM_OFFSET, setup.program.size_a);
84 ProgramResult program = 84 ProgramResult program =
85 Decompile(device, program_ir, Maxwell3D::Regs::ShaderStage::Geometry, "geometry"); 85 Decompile(device, program_ir, Maxwell3D::Regs::ShaderStage::Geometry, "geometry");
86 out += program.first; 86 out += program.first;
@@ -115,7 +115,7 @@ layout (std140, binding = EMULATION_UBO_BINDING) uniform fs_config {
115}; 115};
116 116
117)"; 117)";
118 const ShaderIR program_ir(setup.program.code, PROGRAM_OFFSET); 118 const ShaderIR program_ir(setup.program.code, PROGRAM_OFFSET, setup.program.size_a);
119 ProgramResult program = 119 ProgramResult program =
120 Decompile(device, program_ir, Maxwell3D::Regs::ShaderStage::Fragment, "fragment"); 120 Decompile(device, program_ir, Maxwell3D::Regs::ShaderStage::Fragment, "fragment");
121 121
diff --git a/src/video_core/renderer_opengl/gl_shader_gen.h b/src/video_core/renderer_opengl/gl_shader_gen.h
index 0536c8a03..7cbc590f8 100644
--- a/src/video_core/renderer_opengl/gl_shader_gen.h
+++ b/src/video_core/renderer_opengl/gl_shader_gen.h
@@ -27,6 +27,8 @@ struct ShaderSetup {
27 ProgramCode code; 27 ProgramCode code;
28 ProgramCode code_b; // Used for dual vertex shaders 28 ProgramCode code_b; // Used for dual vertex shaders
29 u64 unique_identifier; 29 u64 unique_identifier;
30 std::size_t size_a;
31 std::size_t size_b;
30 } program; 32 } program;
31 33
32 /// Used in scenarios where we have a dual vertex shaders 34 /// Used in scenarios where we have a dual vertex shaders
diff --git a/src/video_core/shader/decode.cpp b/src/video_core/shader/decode.cpp
index 65029d35e..09f55bd21 100644
--- a/src/video_core/shader/decode.cpp
+++ b/src/video_core/shader/decode.cpp
@@ -39,7 +39,7 @@ void ShaderIR::Decode() {
39 std::memcpy(&header, program_code.data(), sizeof(Tegra::Shader::Header)); 39 std::memcpy(&header, program_code.data(), sizeof(Tegra::Shader::Header));
40 40
41 ShaderCharacteristics shader_info{}; 41 ShaderCharacteristics shader_info{};
42 bool can_proceed = ScanFlow(program_code, MAX_PROGRAM_LENGTH, main_offset, shader_info); 42 bool can_proceed = ScanFlow(program_code, program_code.size(), main_offset, shader_info);
43 if (can_proceed) { 43 if (can_proceed) {
44 coverage_begin = shader_info.start; 44 coverage_begin = shader_info.start;
45 coverage_end = shader_info.end; 45 coverage_end = shader_info.end;
@@ -52,12 +52,12 @@ void ShaderIR::Decode() {
52 } 52 }
53 return; 53 return;
54 } 54 }
55 LOG_CRITICAL(HW_GPU, "Flow Analysis failed, falling back to brute force compiling"); 55 LOG_WARNING(HW_GPU, "Flow Analysis failed, falling back to brute force compiling");
56 56
57 // Now we need to deal with an undecompilable shader. We need to brute force 57 // Now we need to deal with an undecompilable shader. We need to brute force
58 // a shader that captures every position. 58 // a shader that captures every position.
59 coverage_begin = shader_info.start; 59 coverage_begin = shader_info.start;
60 const u32 shader_end = static_cast<u32>(MAX_PROGRAM_LENGTH); 60 const u32 shader_end = static_cast<u32>(program_size / sizeof(u64));
61 coverage_end = shader_end; 61 coverage_end = shader_end;
62 for (u32 label = main_offset; label < shader_end; label++) { 62 for (u32 label = main_offset; label < shader_end; label++) {
63 basic_blocks.insert({label, DecodeRange(label, label + 1)}); 63 basic_blocks.insert({label, DecodeRange(label, label + 1)});
diff --git a/src/video_core/shader/shader_ir.cpp b/src/video_core/shader/shader_ir.cpp
index 11b545cca..5994bfc4e 100644
--- a/src/video_core/shader/shader_ir.cpp
+++ b/src/video_core/shader/shader_ir.cpp
@@ -22,8 +22,8 @@ using Tegra::Shader::PredCondition;
22using Tegra::Shader::PredOperation; 22using Tegra::Shader::PredOperation;
23using Tegra::Shader::Register; 23using Tegra::Shader::Register;
24 24
25ShaderIR::ShaderIR(const ProgramCode& program_code, u32 main_offset) 25ShaderIR::ShaderIR(const ProgramCode& program_code, u32 main_offset, const std::size_t size)
26 : program_code{program_code}, main_offset{main_offset} { 26 : program_code{program_code}, main_offset{main_offset}, program_size{size} {
27 Decode(); 27 Decode();
28} 28}
29 29
diff --git a/src/video_core/shader/shader_ir.h b/src/video_core/shader/shader_ir.h
index e71462e02..a67d4f390 100644
--- a/src/video_core/shader/shader_ir.h
+++ b/src/video_core/shader/shader_ir.h
@@ -65,7 +65,7 @@ struct GlobalMemoryUsage {
65 65
66class ShaderIR final { 66class ShaderIR final {
67public: 67public:
68 explicit ShaderIR(const ProgramCode& program_code, u32 main_offset); 68 explicit ShaderIR(const ProgramCode& program_code, u32 main_offset, std::size_t size);
69 ~ShaderIR(); 69 ~ShaderIR();
70 70
71 const std::map<u32, NodeBlock>& GetBasicBlocks() const { 71 const std::map<u32, NodeBlock>& GetBasicBlocks() const {
@@ -316,6 +316,7 @@ private:
316 316
317 const ProgramCode& program_code; 317 const ProgramCode& program_code;
318 const u32 main_offset; 318 const u32 main_offset;
319 const std::size_t program_size;
319 320
320 u32 coverage_begin{}; 321 u32 coverage_begin{};
321 u32 coverage_end{}; 322 u32 coverage_end{};