summaryrefslogtreecommitdiff
path: root/src/video_core/shader/shader.cpp
diff options
context:
space:
mode:
authorGravatar Yuri Kunde Schlesner2016-12-17 01:21:16 -0800
committerGravatar Yuri Kunde Schlesner2017-01-25 18:53:24 -0800
commit114d6b2f97eb62c7d8c958ebb391b70b026130f9 (patch)
tree8600239b8ee804b78bc2c60fb6285a2e8cf2c4fa /src/video_core/shader/shader.cpp
parentVideoCore/Shader: Rename shader_jit_x64{ => _compiler}.{cpp,h} (diff)
downloadyuzu-114d6b2f97eb62c7d8c958ebb391b70b026130f9.tar.gz
yuzu-114d6b2f97eb62c7d8c958ebb391b70b026130f9.tar.xz
yuzu-114d6b2f97eb62c7d8c958ebb391b70b026130f9.zip
VideoCore/Shader: Split interpreter and JIT into separate ShaderEngines
Diffstat (limited to 'src/video_core/shader/shader.cpp')
-rw-r--r--src/video_core/shader/shader.cpp92
1 files changed, 13 insertions, 79 deletions
diff --git a/src/video_core/shader/shader.cpp b/src/video_core/shader/shader.cpp
index 97c6519d6..b30dae476 100644
--- a/src/video_core/shader/shader.cpp
+++ b/src/video_core/shader/shader.cpp
@@ -2,14 +2,8 @@
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 <atomic>
6#include <cmath> 5#include <cmath>
7#include <cstring> 6#include <cstring>
8#include <unordered_map>
9#include <utility>
10#include <boost/range/algorithm/fill.hpp>
11#include "common/bit_field.h"
12#include "common/hash.h"
13#include "common/logging/log.h" 7#include "common/logging/log.h"
14#include "common/microprofile.h" 8#include "common/microprofile.h"
15#include "video_core/pica.h" 9#include "video_core/pica.h"
@@ -17,7 +11,7 @@
17#include "video_core/shader/shader.h" 11#include "video_core/shader/shader.h"
18#include "video_core/shader/shader_interpreter.h" 12#include "video_core/shader/shader_interpreter.h"
19#ifdef ARCHITECTURE_x86_64 13#ifdef ARCHITECTURE_x86_64
20#include "video_core/shader/shader_jit_x64_compiler.h" 14#include "video_core/shader/shader_jit_x64.h"
21#endif // ARCHITECTURE_x86_64 15#endif // ARCHITECTURE_x86_64
22#include "video_core/video_core.h" 16#include "video_core/video_core.h"
23 17
@@ -87,93 +81,33 @@ void UnitState::LoadInputVertex(const InputVertex& input, int num_attributes) {
87 conditional_code[1] = false; 81 conditional_code[1] = false;
88} 82}
89 83
90class MergedShaderEngine : public ShaderEngine { 84MICROPROFILE_DEFINE(GPU_Shader, "GPU", "Shader", MP_RGB(50, 50, 240));
91public:
92 void SetupBatch(const ShaderSetup* setup) override;
93 void Run(UnitState& state, unsigned int entry_point) const override;
94 DebugData<true> ProduceDebugInfo(const InputVertex& input, int num_attributes,
95 unsigned int entry_point) const override;
96
97private:
98 const ShaderSetup* setup = nullptr;
99};
100
101#ifdef ARCHITECTURE_x86_64
102static std::unordered_map<u64, std::unique_ptr<JitShader>> shader_map;
103static const JitShader* jit_shader;
104#endif // ARCHITECTURE_x86_64
105 85
106void ClearCache() {
107#ifdef ARCHITECTURE_x86_64 86#ifdef ARCHITECTURE_x86_64
108 shader_map.clear(); 87static std::unique_ptr<JitX64Engine> jit_engine;
109#endif // ARCHITECTURE_x86_64 88#endif // ARCHITECTURE_x86_64
110} 89static InterpreterEngine interpreter_engine;
111
112void MergedShaderEngine::SetupBatch(const ShaderSetup* setup_) {
113 setup = setup_;
114 if (setup == nullptr)
115 return;
116 90
91ShaderEngine* GetEngine() {
117#ifdef ARCHITECTURE_x86_64 92#ifdef ARCHITECTURE_x86_64
93 // TODO(yuriks): Re-initialize on each change rather than being persistent
118 if (VideoCore::g_shader_jit_enabled) { 94 if (VideoCore::g_shader_jit_enabled) {
119 u64 code_hash = Common::ComputeHash64(&setup->program_code, sizeof(setup->program_code)); 95 if (jit_engine == nullptr) {
120 u64 swizzle_hash = Common::ComputeHash64(&setup->swizzle_data, sizeof(setup->swizzle_data)); 96 jit_engine = std::make_unique<JitX64Engine>();
121
122 u64 cache_key = code_hash ^ swizzle_hash;
123 auto iter = shader_map.find(cache_key);
124 if (iter != shader_map.end()) {
125 jit_shader = iter->second.get();
126 } else {
127 auto shader = std::make_unique<JitShader>();
128 shader->Compile();
129 jit_shader = shader.get();
130 shader_map[cache_key] = std::move(shader);
131 } 97 }
98 return jit_engine.get();
132 } 99 }
133#endif // ARCHITECTURE_x86_64 100#endif // ARCHITECTURE_x86_64
134}
135
136MICROPROFILE_DEFINE(GPU_Shader, "GPU", "Shader", MP_RGB(50, 50, 240));
137
138void MergedShaderEngine::Run(UnitState& state, unsigned int entry_point) const {
139 ASSERT(setup != nullptr);
140 ASSERT(entry_point < 1024);
141 101
142 MICROPROFILE_SCOPE(GPU_Shader); 102 return &interpreter_engine;
103}
143 104
105void Shutdown() {
144#ifdef ARCHITECTURE_x86_64 106#ifdef ARCHITECTURE_x86_64
145 if (VideoCore::g_shader_jit_enabled) { 107 jit_engine = nullptr;
146 jit_shader->Run(*setup, state, entry_point);
147 } else {
148 DebugData<false> dummy_debug_data;
149 RunInterpreter(*setup, state, dummy_debug_data, entry_point);
150 }
151#else
152 DebugData<false> dummy_debug_data;
153 RunInterpreter(*setup, state, dummy_debug_data, entry_point);
154#endif // ARCHITECTURE_x86_64 108#endif // ARCHITECTURE_x86_64
155} 109}
156 110
157DebugData<true> MergedShaderEngine::ProduceDebugInfo(const InputVertex& input, int num_attributes,
158 unsigned int entry_point) const {
159 ASSERT(setup != nullptr);
160 ASSERT(entry_point < 1024);
161
162 UnitState state;
163 DebugData<true> debug_data;
164
165 // Setup input register table
166 boost::fill(state.registers.input, Math::Vec4<float24>::AssignToAll(float24::Zero()));
167 state.LoadInputVertex(input, num_attributes);
168 RunInterpreter(*setup, state, debug_data, entry_point);
169 return debug_data;
170}
171
172ShaderEngine* GetEngine() {
173 static MergedShaderEngine merged_engine;
174 return &merged_engine;
175}
176
177} // namespace Shader 111} // namespace Shader
178 112
179} // namespace Pica 113} // namespace Pica