diff options
| author | 2016-12-17 16:06:04 -0800 | |
|---|---|---|
| committer | 2017-01-25 18:53:25 -0800 | |
| commit | 0f642741451e3f75c2f1d64ae9beccaf1437f12c (patch) | |
| tree | f964da57def5be6b8d5bc41176db97668bd01125 /src | |
| parent | Shader: Remove OutputRegisters struct (diff) | |
| download | yuzu-0f642741451e3f75c2f1d64ae9beccaf1437f12c.tar.gz yuzu-0f642741451e3f75c2f1d64ae9beccaf1437f12c.tar.xz yuzu-0f642741451e3f75c2f1d64ae9beccaf1437f12c.zip | |
VideoCore/Shader: Move per-batch ShaderEngine state into ShaderSetup
Diffstat (limited to 'src')
| -rw-r--r-- | src/citra_qt/debugger/graphics/graphics_vertex_shader.cpp | 5 | ||||
| -rw-r--r-- | src/video_core/command_processor.cpp | 8 | ||||
| -rw-r--r-- | src/video_core/shader/shader.h | 17 | ||||
| -rw-r--r-- | src/video_core/shader/shader_interpreter.cpp | 16 | ||||
| -rw-r--r-- | src/video_core/shader/shader_interpreter.h | 11 | ||||
| -rw-r--r-- | src/video_core/shader/shader_jit_x64.cpp | 25 | ||||
| -rw-r--r-- | src/video_core/shader/shader_jit_x64.h | 7 |
7 files changed, 43 insertions, 46 deletions
diff --git a/src/citra_qt/debugger/graphics/graphics_vertex_shader.cpp b/src/citra_qt/debugger/graphics/graphics_vertex_shader.cpp index c6f807eb3..616b34d56 100644 --- a/src/citra_qt/debugger/graphics/graphics_vertex_shader.cpp +++ b/src/citra_qt/debugger/graphics/graphics_vertex_shader.cpp | |||
| @@ -521,8 +521,9 @@ void GraphicsVertexShaderWidget::Reload(bool replace_vertex_data, void* vertex_d | |||
| 521 | 521 | ||
| 522 | // Generate debug information | 522 | // Generate debug information |
| 523 | Pica::Shader::InterpreterEngine shader_engine; | 523 | Pica::Shader::InterpreterEngine shader_engine; |
| 524 | shader_engine.SetupBatch(&shader_setup); | 524 | shader_engine.SetupBatch(shader_setup); |
| 525 | debug_data = shader_engine.ProduceDebugInfo(input_vertex, num_attributes, entry_point); | 525 | debug_data = |
| 526 | shader_engine.ProduceDebugInfo(shader_setup, input_vertex, num_attributes, entry_point); | ||
| 526 | 527 | ||
| 527 | // Reload widget state | 528 | // Reload widget state |
| 528 | for (int attr = 0; attr < num_attributes; ++attr) { | 529 | for (int attr = 0; attr < num_attributes; ++attr) { |
diff --git a/src/video_core/command_processor.cpp b/src/video_core/command_processor.cpp index 66d19cba0..c3872d06c 100644 --- a/src/video_core/command_processor.cpp +++ b/src/video_core/command_processor.cpp | |||
| @@ -143,7 +143,7 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) { | |||
| 143 | immediate_attribute_id = 0; | 143 | immediate_attribute_id = 0; |
| 144 | 144 | ||
| 145 | auto* shader_engine = Shader::GetEngine(); | 145 | auto* shader_engine = Shader::GetEngine(); |
| 146 | shader_engine->SetupBatch(&g_state.vs); | 146 | shader_engine->SetupBatch(g_state.vs); |
| 147 | 147 | ||
| 148 | // Send to vertex shader | 148 | // Send to vertex shader |
| 149 | if (g_debug_context) | 149 | if (g_debug_context) |
| @@ -151,7 +151,7 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) { | |||
| 151 | static_cast<void*>(&immediate_input)); | 151 | static_cast<void*>(&immediate_input)); |
| 152 | Shader::UnitState shader_unit; | 152 | Shader::UnitState shader_unit; |
| 153 | shader_unit.LoadInputVertex(immediate_input, regs.vs.num_input_attributes + 1); | 153 | shader_unit.LoadInputVertex(immediate_input, regs.vs.num_input_attributes + 1); |
| 154 | shader_engine->Run(shader_unit, regs.vs.main_offset); | 154 | shader_engine->Run(g_state.vs, shader_unit, regs.vs.main_offset); |
| 155 | auto output_vertex = Shader::OutputVertex::FromRegisters( | 155 | auto output_vertex = Shader::OutputVertex::FromRegisters( |
| 156 | shader_unit.registers.output, regs, regs.vs.output_mask); | 156 | shader_unit.registers.output, regs, regs.vs.output_mask); |
| 157 | 157 | ||
| @@ -248,7 +248,7 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) { | |||
| 248 | auto* shader_engine = Shader::GetEngine(); | 248 | auto* shader_engine = Shader::GetEngine(); |
| 249 | Shader::UnitState shader_unit; | 249 | Shader::UnitState shader_unit; |
| 250 | 250 | ||
| 251 | shader_engine->SetupBatch(&g_state.vs); | 251 | shader_engine->SetupBatch(g_state.vs); |
| 252 | 252 | ||
| 253 | for (unsigned int index = 0; index < regs.num_vertices; ++index) { | 253 | for (unsigned int index = 0; index < regs.num_vertices; ++index) { |
| 254 | // Indexed rendering doesn't use the start offset | 254 | // Indexed rendering doesn't use the start offset |
| @@ -288,7 +288,7 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) { | |||
| 288 | g_debug_context->OnEvent(DebugContext::Event::VertexShaderInvocation, | 288 | g_debug_context->OnEvent(DebugContext::Event::VertexShaderInvocation, |
| 289 | (void*)&input); | 289 | (void*)&input); |
| 290 | shader_unit.LoadInputVertex(input, loader.GetNumTotalAttributes()); | 290 | shader_unit.LoadInputVertex(input, loader.GetNumTotalAttributes()); |
| 291 | shader_engine->Run(shader_unit, regs.vs.main_offset); | 291 | shader_engine->Run(g_state.vs, shader_unit, regs.vs.main_offset); |
| 292 | 292 | ||
| 293 | // Retrieve vertex from register data | 293 | // Retrieve vertex from register data |
| 294 | output_vertex = Shader::OutputVertex::FromRegisters(shader_unit.registers.output, | 294 | output_vertex = Shader::OutputVertex::FromRegisters(shader_unit.registers.output, |
diff --git a/src/video_core/shader/shader.h b/src/video_core/shader/shader.h index 7d51d0044..f26d2ba4f 100644 --- a/src/video_core/shader/shader.h +++ b/src/video_core/shader/shader.h | |||
| @@ -167,6 +167,12 @@ struct ShaderSetup { | |||
| 167 | 167 | ||
| 168 | std::array<u32, 1024> program_code; | 168 | std::array<u32, 1024> program_code; |
| 169 | std::array<u32, 1024> swizzle_data; | 169 | std::array<u32, 1024> swizzle_data; |
| 170 | |||
| 171 | /// Data private to ShaderEngines | ||
| 172 | struct EngineData { | ||
| 173 | /// Used by the JIT, points to a compiled shader object. | ||
| 174 | const void* cached_shader = nullptr; | ||
| 175 | } engine_data; | ||
| 170 | }; | 176 | }; |
| 171 | 177 | ||
| 172 | class ShaderEngine { | 178 | class ShaderEngine { |
| @@ -177,13 +183,16 @@ public: | |||
| 177 | * Performs any shader unit setup that only needs to happen once per shader (as opposed to once | 183 | * Performs any shader unit setup that only needs to happen once per shader (as opposed to once |
| 178 | * per vertex, which would happen within the `Run` function). | 184 | * per vertex, which would happen within the `Run` function). |
| 179 | */ | 185 | */ |
| 180 | virtual void SetupBatch(const ShaderSetup* setup) = 0; | 186 | virtual void SetupBatch(ShaderSetup& setup) = 0; |
| 181 | 187 | ||
| 182 | /** | 188 | /** |
| 183 | * Runs the currently setup shader | 189 | * Runs the currently setup shader. |
| 184 | * @param state Shader unit state, must be setup per shader and per shader unit | 190 | * |
| 191 | * @param setup Shader engine state, must be setup with SetupBatch on each shader change. | ||
| 192 | * @param state Shader unit state, must be setup with input data before each shader invocation. | ||
| 185 | */ | 193 | */ |
| 186 | virtual void Run(UnitState& state, unsigned int entry_point) const = 0; | 194 | virtual void Run(const ShaderSetup& setup, UnitState& state, |
| 195 | unsigned int entry_point) const = 0; | ||
| 187 | }; | 196 | }; |
| 188 | 197 | ||
| 189 | // TODO(yuriks): Remove and make it non-global state somewhere | 198 | // TODO(yuriks): Remove and make it non-global state somewhere |
diff --git a/src/video_core/shader/shader_interpreter.cpp b/src/video_core/shader/shader_interpreter.cpp index a6197c10a..e44abbf1d 100644 --- a/src/video_core/shader/shader_interpreter.cpp +++ b/src/video_core/shader/shader_interpreter.cpp | |||
| @@ -652,25 +652,23 @@ static void RunInterpreter(const ShaderSetup& setup, UnitState& state, DebugData | |||
| 652 | } | 652 | } |
| 653 | } | 653 | } |
| 654 | 654 | ||
| 655 | void InterpreterEngine::SetupBatch(const ShaderSetup* setup_) { | 655 | void InterpreterEngine::SetupBatch(ShaderSetup& setup) {} |
| 656 | setup = setup_; | ||
| 657 | } | ||
| 658 | 656 | ||
| 659 | MICROPROFILE_DECLARE(GPU_Shader); | 657 | MICROPROFILE_DECLARE(GPU_Shader); |
| 660 | 658 | ||
| 661 | void InterpreterEngine::Run(UnitState& state, unsigned int entry_point) const { | 659 | void InterpreterEngine::Run(const ShaderSetup& setup, UnitState& state, |
| 662 | ASSERT(setup != nullptr); | 660 | unsigned int entry_point) const { |
| 663 | ASSERT(entry_point < 1024); | 661 | ASSERT(entry_point < 1024); |
| 664 | 662 | ||
| 665 | MICROPROFILE_SCOPE(GPU_Shader); | 663 | MICROPROFILE_SCOPE(GPU_Shader); |
| 666 | 664 | ||
| 667 | DebugData<false> dummy_debug_data; | 665 | DebugData<false> dummy_debug_data; |
| 668 | RunInterpreter(*setup, state, dummy_debug_data, entry_point); | 666 | RunInterpreter(setup, state, dummy_debug_data, entry_point); |
| 669 | } | 667 | } |
| 670 | 668 | ||
| 671 | DebugData<true> InterpreterEngine::ProduceDebugInfo(const InputVertex& input, int num_attributes, | 669 | DebugData<true> InterpreterEngine::ProduceDebugInfo(const ShaderSetup& setup, |
| 670 | const InputVertex& input, int num_attributes, | ||
| 672 | unsigned int entry_point) const { | 671 | unsigned int entry_point) const { |
| 673 | ASSERT(setup != nullptr); | ||
| 674 | ASSERT(entry_point < 1024); | 672 | ASSERT(entry_point < 1024); |
| 675 | 673 | ||
| 676 | UnitState state; | 674 | UnitState state; |
| @@ -679,7 +677,7 @@ DebugData<true> InterpreterEngine::ProduceDebugInfo(const InputVertex& input, in | |||
| 679 | // Setup input register table | 677 | // Setup input register table |
| 680 | boost::fill(state.registers.input, Math::Vec4<float24>::AssignToAll(float24::Zero())); | 678 | boost::fill(state.registers.input, Math::Vec4<float24>::AssignToAll(float24::Zero())); |
| 681 | state.LoadInputVertex(input, num_attributes); | 679 | state.LoadInputVertex(input, num_attributes); |
| 682 | RunInterpreter(*setup, state, debug_data, entry_point); | 680 | RunInterpreter(setup, state, debug_data, entry_point); |
| 683 | return debug_data; | 681 | return debug_data; |
| 684 | } | 682 | } |
| 685 | 683 | ||
diff --git a/src/video_core/shader/shader_interpreter.h b/src/video_core/shader/shader_interpreter.h index c3691da70..7f94d405f 100644 --- a/src/video_core/shader/shader_interpreter.h +++ b/src/video_core/shader/shader_interpreter.h | |||
| @@ -13,8 +13,8 @@ namespace Shader { | |||
| 13 | 13 | ||
| 14 | class InterpreterEngine final : public ShaderEngine { | 14 | class InterpreterEngine final : public ShaderEngine { |
| 15 | public: | 15 | public: |
| 16 | void SetupBatch(const ShaderSetup* setup) override; | 16 | void SetupBatch(ShaderSetup& setup) override; |
| 17 | void Run(UnitState& state, unsigned int entry_point) const override; | 17 | void Run(const ShaderSetup& setup, UnitState& state, unsigned int entry_point) const override; |
| 18 | 18 | ||
| 19 | /** | 19 | /** |
| 20 | * Produce debug information based on the given shader and input vertex | 20 | * Produce debug information based on the given shader and input vertex |
| @@ -23,11 +23,8 @@ public: | |||
| 23 | * @param config Configuration object for the shader pipeline | 23 | * @param config Configuration object for the shader pipeline |
| 24 | * @return Debug information for this shader with regards to the given vertex | 24 | * @return Debug information for this shader with regards to the given vertex |
| 25 | */ | 25 | */ |
| 26 | DebugData<true> ProduceDebugInfo(const InputVertex& input, int num_attributes, | 26 | DebugData<true> ProduceDebugInfo(const ShaderSetup& setup, const InputVertex& input, |
| 27 | unsigned int entry_point) const; | 27 | int num_attributes, unsigned int entry_point) const; |
| 28 | |||
| 29 | private: | ||
| 30 | const ShaderSetup* setup = nullptr; | ||
| 31 | }; | 28 | }; |
| 32 | 29 | ||
| 33 | } // namespace | 30 | } // namespace |
diff --git a/src/video_core/shader/shader_jit_x64.cpp b/src/video_core/shader/shader_jit_x64.cpp index 755ae119f..15c1d60b5 100644 --- a/src/video_core/shader/shader_jit_x64.cpp +++ b/src/video_core/shader/shader_jit_x64.cpp | |||
| @@ -14,37 +14,32 @@ namespace Shader { | |||
| 14 | JitX64Engine::JitX64Engine() = default; | 14 | JitX64Engine::JitX64Engine() = default; |
| 15 | JitX64Engine::~JitX64Engine() = default; | 15 | JitX64Engine::~JitX64Engine() = default; |
| 16 | 16 | ||
| 17 | void JitX64Engine::SetupBatch(const ShaderSetup* setup_) { | 17 | void JitX64Engine::SetupBatch(ShaderSetup& setup) { |
| 18 | cached_shader = nullptr; | 18 | u64 code_hash = Common::ComputeHash64(&setup.program_code, sizeof(setup.program_code)); |
| 19 | setup = setup_; | 19 | u64 swizzle_hash = Common::ComputeHash64(&setup.swizzle_data, sizeof(setup.swizzle_data)); |
| 20 | if (setup == nullptr) | ||
| 21 | return; | ||
| 22 | |||
| 23 | u64 code_hash = Common::ComputeHash64(&setup->program_code, sizeof(setup->program_code)); | ||
| 24 | u64 swizzle_hash = Common::ComputeHash64(&setup->swizzle_data, sizeof(setup->swizzle_data)); | ||
| 25 | 20 | ||
| 26 | u64 cache_key = code_hash ^ swizzle_hash; | 21 | u64 cache_key = code_hash ^ swizzle_hash; |
| 27 | auto iter = cache.find(cache_key); | 22 | auto iter = cache.find(cache_key); |
| 28 | if (iter != cache.end()) { | 23 | if (iter != cache.end()) { |
| 29 | cached_shader = iter->second.get(); | 24 | setup.engine_data.cached_shader = iter->second.get(); |
| 30 | } else { | 25 | } else { |
| 31 | auto shader = std::make_unique<JitShader>(); | 26 | auto shader = std::make_unique<JitShader>(); |
| 32 | shader->Compile(&setup->program_code, &setup->swizzle_data); | 27 | shader->Compile(&setup.program_code, &setup.swizzle_data); |
| 33 | cached_shader = shader.get(); | 28 | setup.engine_data.cached_shader = shader.get(); |
| 34 | cache.emplace_hint(iter, cache_key, std::move(shader)); | 29 | cache.emplace_hint(iter, cache_key, std::move(shader)); |
| 35 | } | 30 | } |
| 36 | } | 31 | } |
| 37 | 32 | ||
| 38 | MICROPROFILE_DECLARE(GPU_Shader); | 33 | MICROPROFILE_DECLARE(GPU_Shader); |
| 39 | 34 | ||
| 40 | void JitX64Engine::Run(UnitState& state, unsigned int entry_point) const { | 35 | void JitX64Engine::Run(const ShaderSetup& setup, UnitState& state, unsigned int entry_point) const { |
| 41 | ASSERT(setup != nullptr); | 36 | ASSERT(setup.engine_data.cached_shader != nullptr); |
| 42 | ASSERT(cached_shader != nullptr); | ||
| 43 | ASSERT(entry_point < 1024); | 37 | ASSERT(entry_point < 1024); |
| 44 | 38 | ||
| 45 | MICROPROFILE_SCOPE(GPU_Shader); | 39 | MICROPROFILE_SCOPE(GPU_Shader); |
| 46 | 40 | ||
| 47 | cached_shader->Run(*setup, state, entry_point); | 41 | const JitShader* shader = static_cast<const JitShader*>(setup.engine_data.cached_shader); |
| 42 | shader->Run(setup, state, entry_point); | ||
| 48 | } | 43 | } |
| 49 | 44 | ||
| 50 | } // namespace Shader | 45 | } // namespace Shader |
diff --git a/src/video_core/shader/shader_jit_x64.h b/src/video_core/shader/shader_jit_x64.h index b26044477..bd30f51e2 100644 --- a/src/video_core/shader/shader_jit_x64.h +++ b/src/video_core/shader/shader_jit_x64.h | |||
| @@ -19,14 +19,11 @@ public: | |||
| 19 | JitX64Engine(); | 19 | JitX64Engine(); |
| 20 | ~JitX64Engine() override; | 20 | ~JitX64Engine() override; |
| 21 | 21 | ||
| 22 | void SetupBatch(const ShaderSetup* setup) override; | 22 | void SetupBatch(ShaderSetup& setup) override; |
| 23 | void Run(UnitState& state, unsigned int entry_point) const override; | 23 | void Run(const ShaderSetup& setup, UnitState& state, unsigned int entry_point) const override; |
| 24 | 24 | ||
| 25 | private: | 25 | private: |
| 26 | const ShaderSetup* setup = nullptr; | ||
| 27 | |||
| 28 | std::unordered_map<u64, std::unique_ptr<JitShader>> cache; | 26 | std::unordered_map<u64, std::unique_ptr<JitShader>> cache; |
| 29 | const JitShader* cached_shader = nullptr; | ||
| 30 | }; | 27 | }; |
| 31 | 28 | ||
| 32 | } // namespace Shader | 29 | } // namespace Shader |