diff options
| author | 2016-12-16 23:21:26 -0800 | |
|---|---|---|
| committer | 2017-01-25 18:53:23 -0800 | |
| commit | dd4a1672a77830a53de61cf0554b34e9e17a2905 (patch) | |
| tree | 63b1b64e3858aca34c0828dbd9fec6f5ebc1f887 /src/video_core | |
| parent | VideoCore/Shader: Add constness to methods (diff) | |
| download | yuzu-dd4a1672a77830a53de61cf0554b34e9e17a2905.tar.gz yuzu-dd4a1672a77830a53de61cf0554b34e9e17a2905.tar.xz yuzu-dd4a1672a77830a53de61cf0554b34e9e17a2905.zip | |
VideoCore/Shader: Split shader uniform state and shader engine
Currently there's only a single dummy implementation, which will be
split in a following commit.
Diffstat (limited to 'src/video_core')
| -rw-r--r-- | src/video_core/command_processor.cpp | 13 | ||||
| -rw-r--r-- | src/video_core/shader/shader.cpp | 44 | ||||
| -rw-r--r-- | src/video_core/shader/shader.h | 17 | ||||
| -rw-r--r-- | src/video_core/shader/shader_interpreter.h | 1 |
4 files changed, 54 insertions, 21 deletions
diff --git a/src/video_core/command_processor.cpp b/src/video_core/command_processor.cpp index fc224c6f2..694c9f169 100644 --- a/src/video_core/command_processor.cpp +++ b/src/video_core/command_processor.cpp | |||
| @@ -142,15 +142,16 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) { | |||
| 142 | MICROPROFILE_SCOPE(GPU_Drawing); | 142 | MICROPROFILE_SCOPE(GPU_Drawing); |
| 143 | immediate_attribute_id = 0; | 143 | immediate_attribute_id = 0; |
| 144 | 144 | ||
| 145 | Shader::UnitState shader_unit; | 145 | auto* shader_engine = Shader::GetEngine(); |
| 146 | g_state.vs.Setup(); | 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) |
| 150 | g_debug_context->OnEvent(DebugContext::Event::VertexShaderInvocation, | 150 | g_debug_context->OnEvent(DebugContext::Event::VertexShaderInvocation, |
| 151 | static_cast<void*>(&immediate_input)); | 151 | static_cast<void*>(&immediate_input)); |
| 152 | Shader::UnitState shader_unit; | ||
| 152 | shader_unit.LoadInputVertex(immediate_input, regs.vs.num_input_attributes + 1); | 153 | shader_unit.LoadInputVertex(immediate_input, regs.vs.num_input_attributes + 1); |
| 153 | g_state.vs.Run(shader_unit, regs.vs.main_offset); | 154 | shader_engine->Run(shader_unit, regs.vs.main_offset); |
| 154 | Shader::OutputVertex output_vertex = | 155 | Shader::OutputVertex output_vertex = |
| 155 | shader_unit.output_registers.ToVertex(regs.vs); | 156 | shader_unit.output_registers.ToVertex(regs.vs); |
| 156 | 157 | ||
| @@ -244,8 +245,10 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) { | |||
| 244 | unsigned int vertex_cache_pos = 0; | 245 | unsigned int vertex_cache_pos = 0; |
| 245 | vertex_cache_ids.fill(-1); | 246 | vertex_cache_ids.fill(-1); |
| 246 | 247 | ||
| 248 | auto* shader_engine = Shader::GetEngine(); | ||
| 247 | Shader::UnitState shader_unit; | 249 | Shader::UnitState shader_unit; |
| 248 | g_state.vs.Setup(); | 250 | |
| 251 | shader_engine->SetupBatch(&g_state.vs); | ||
| 249 | 252 | ||
| 250 | for (unsigned int index = 0; index < regs.num_vertices; ++index) { | 253 | for (unsigned int index = 0; index < regs.num_vertices; ++index) { |
| 251 | // Indexed rendering doesn't use the start offset | 254 | // Indexed rendering doesn't use the start offset |
| @@ -285,7 +288,7 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) { | |||
| 285 | g_debug_context->OnEvent(DebugContext::Event::VertexShaderInvocation, | 288 | g_debug_context->OnEvent(DebugContext::Event::VertexShaderInvocation, |
| 286 | (void*)&input); | 289 | (void*)&input); |
| 287 | shader_unit.LoadInputVertex(input, loader.GetNumTotalAttributes()); | 290 | shader_unit.LoadInputVertex(input, loader.GetNumTotalAttributes()); |
| 288 | g_state.vs.Run(shader_unit, regs.vs.main_offset); | 291 | shader_engine->Run(shader_unit, regs.vs.main_offset); |
| 289 | 292 | ||
| 290 | // Retrieve vertex from register data | 293 | // Retrieve vertex from register data |
| 291 | output_vertex = shader_unit.output_registers.ToVertex(regs.vs); | 294 | output_vertex = shader_unit.output_registers.ToVertex(regs.vs); |
diff --git a/src/video_core/shader/shader.cpp b/src/video_core/shader/shader.cpp index ae696533f..d276a1221 100644 --- a/src/video_core/shader/shader.cpp +++ b/src/video_core/shader/shader.cpp | |||
| @@ -87,6 +87,17 @@ void UnitState::LoadInputVertex(const InputVertex& input, int num_attributes) { | |||
| 87 | conditional_code[1] = false; | 87 | conditional_code[1] = false; |
| 88 | } | 88 | } |
| 89 | 89 | ||
| 90 | class MergedShaderEngine : public ShaderEngine { | ||
| 91 | public: | ||
| 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 | |||
| 97 | private: | ||
| 98 | const ShaderSetup* setup = nullptr; | ||
| 99 | }; | ||
| 100 | |||
| 90 | #ifdef ARCHITECTURE_x86_64 | 101 | #ifdef ARCHITECTURE_x86_64 |
| 91 | static std::unordered_map<u64, std::unique_ptr<JitShader>> shader_map; | 102 | static std::unordered_map<u64, std::unique_ptr<JitShader>> shader_map; |
| 92 | static const JitShader* jit_shader; | 103 | static const JitShader* jit_shader; |
| @@ -98,13 +109,17 @@ void ClearCache() { | |||
| 98 | #endif // ARCHITECTURE_x86_64 | 109 | #endif // ARCHITECTURE_x86_64 |
| 99 | } | 110 | } |
| 100 | 111 | ||
| 101 | void ShaderSetup::Setup() { | 112 | void MergedShaderEngine::SetupBatch(const ShaderSetup* setup_) { |
| 113 | setup = setup_; | ||
| 114 | if (setup == nullptr) | ||
| 115 | return; | ||
| 116 | |||
| 102 | #ifdef ARCHITECTURE_x86_64 | 117 | #ifdef ARCHITECTURE_x86_64 |
| 103 | if (VideoCore::g_shader_jit_enabled) { | 118 | if (VideoCore::g_shader_jit_enabled) { |
| 104 | u64 cache_key = | 119 | u64 code_hash = Common::ComputeHash64(&setup->program_code, sizeof(setup->program_code)); |
| 105 | Common::ComputeHash64(&program_code, sizeof(program_code)) ^ | 120 | u64 swizzle_hash = Common::ComputeHash64(&setup->swizzle_data, sizeof(setup->swizzle_data)); |
| 106 | Common::ComputeHash64(&swizzle_data, sizeof(swizzle_data)); | ||
| 107 | 121 | ||
| 122 | u64 cache_key = code_hash ^ swizzle_hash; | ||
| 108 | auto iter = shader_map.find(cache_key); | 123 | auto iter = shader_map.find(cache_key); |
| 109 | if (iter != shader_map.end()) { | 124 | if (iter != shader_map.end()) { |
| 110 | jit_shader = iter->second.get(); | 125 | jit_shader = iter->second.get(); |
| @@ -120,26 +135,28 @@ void ShaderSetup::Setup() { | |||
| 120 | 135 | ||
| 121 | MICROPROFILE_DEFINE(GPU_Shader, "GPU", "Shader", MP_RGB(50, 50, 240)); | 136 | MICROPROFILE_DEFINE(GPU_Shader, "GPU", "Shader", MP_RGB(50, 50, 240)); |
| 122 | 137 | ||
| 123 | void ShaderSetup::Run(UnitState& state, unsigned int entry_point) const { | 138 | void MergedShaderEngine::Run(UnitState& state, unsigned int entry_point) const { |
| 139 | ASSERT(setup != nullptr); | ||
| 124 | ASSERT(entry_point < 1024); | 140 | ASSERT(entry_point < 1024); |
| 125 | 141 | ||
| 126 | MICROPROFILE_SCOPE(GPU_Shader); | 142 | MICROPROFILE_SCOPE(GPU_Shader); |
| 127 | 143 | ||
| 128 | #ifdef ARCHITECTURE_x86_64 | 144 | #ifdef ARCHITECTURE_x86_64 |
| 129 | if (VideoCore::g_shader_jit_enabled) { | 145 | if (VideoCore::g_shader_jit_enabled) { |
| 130 | jit_shader->Run(*this, state, entry_point); | 146 | jit_shader->Run(*setup, state, entry_point); |
| 131 | } else { | 147 | } else { |
| 132 | DebugData<false> dummy_debug_data; | 148 | DebugData<false> dummy_debug_data; |
| 133 | RunInterpreter(*this, state, dummy_debug_data, entry_point); | 149 | RunInterpreter(*setup, state, dummy_debug_data, entry_point); |
| 134 | } | 150 | } |
| 135 | #else | 151 | #else |
| 136 | DebugData<false> dummy_debug_data; | 152 | DebugData<false> dummy_debug_data; |
| 137 | RunInterpreter(*this, state, dummy_debug_data, entry_point); | 153 | RunInterpreter(*setup, state, dummy_debug_data, entry_point); |
| 138 | #endif // ARCHITECTURE_x86_64 | 154 | #endif // ARCHITECTURE_x86_64 |
| 139 | } | 155 | } |
| 140 | 156 | ||
| 141 | DebugData<true> ShaderSetup::ProduceDebugInfo(const InputVertex& input, int num_attributes, | 157 | DebugData<true> MergedShaderEngine::ProduceDebugInfo(const InputVertex& input, int num_attributes, |
| 142 | unsigned int entry_point) const { | 158 | unsigned int entry_point) const { |
| 159 | ASSERT(setup != nullptr); | ||
| 143 | ASSERT(entry_point < 1024); | 160 | ASSERT(entry_point < 1024); |
| 144 | 161 | ||
| 145 | UnitState state; | 162 | UnitState state; |
| @@ -148,10 +165,15 @@ DebugData<true> ShaderSetup::ProduceDebugInfo(const InputVertex& input, int num_ | |||
| 148 | // Setup input register table | 165 | // Setup input register table |
| 149 | boost::fill(state.registers.input, Math::Vec4<float24>::AssignToAll(float24::Zero())); | 166 | boost::fill(state.registers.input, Math::Vec4<float24>::AssignToAll(float24::Zero())); |
| 150 | state.LoadInputVertex(input, num_attributes); | 167 | state.LoadInputVertex(input, num_attributes); |
| 151 | RunInterpreter(*this, state, debug_data, entry_point); | 168 | RunInterpreter(*setup, state, debug_data, entry_point); |
| 152 | return debug_data; | 169 | return debug_data; |
| 153 | } | 170 | } |
| 154 | 171 | ||
| 172 | ShaderEngine* GetEngine() { | ||
| 173 | static MergedShaderEngine merged_engine; | ||
| 174 | return &merged_engine; | ||
| 175 | } | ||
| 176 | |||
| 155 | } // namespace Shader | 177 | } // namespace Shader |
| 156 | 178 | ||
| 157 | } // namespace Pica | 179 | } // namespace Pica |
diff --git a/src/video_core/shader/shader.h b/src/video_core/shader/shader.h index 44b9861e9..899fb2607 100644 --- a/src/video_core/shader/shader.h +++ b/src/video_core/shader/shader.h | |||
| @@ -156,7 +156,6 @@ struct UnitState { | |||
| 156 | void ClearCache(); | 156 | void ClearCache(); |
| 157 | 157 | ||
| 158 | struct ShaderSetup { | 158 | struct ShaderSetup { |
| 159 | |||
| 160 | struct { | 159 | struct { |
| 161 | // The float uniforms are accessed by the shader JIT using SSE instructions, and are | 160 | // The float uniforms are accessed by the shader JIT using SSE instructions, and are |
| 162 | // therefore required to be 16-byte aligned. | 161 | // therefore required to be 16-byte aligned. |
| @@ -180,18 +179,23 @@ struct ShaderSetup { | |||
| 180 | 179 | ||
| 181 | std::array<u32, 1024> program_code; | 180 | std::array<u32, 1024> program_code; |
| 182 | std::array<u32, 1024> swizzle_data; | 181 | std::array<u32, 1024> swizzle_data; |
| 182 | }; | ||
| 183 | |||
| 184 | class ShaderEngine { | ||
| 185 | public: | ||
| 186 | virtual ~ShaderEngine() = default; | ||
| 183 | 187 | ||
| 184 | /** | 188 | /** |
| 185 | * Performs any shader unit setup that only needs to happen once per shader (as opposed to once | 189 | * Performs any shader unit setup that only needs to happen once per shader (as opposed to once |
| 186 | * per vertex, which would happen within the `Run` function). | 190 | * per vertex, which would happen within the `Run` function). |
| 187 | */ | 191 | */ |
| 188 | void Setup(); | 192 | virtual void SetupBatch(const ShaderSetup* setup) = 0; |
| 189 | 193 | ||
| 190 | /** | 194 | /** |
| 191 | * Runs the currently setup shader | 195 | * Runs the currently setup shader |
| 192 | * @param state Shader unit state, must be setup per shader and per shader unit | 196 | * @param state Shader unit state, must be setup per shader and per shader unit |
| 193 | */ | 197 | */ |
| 194 | void Run(UnitState& state, unsigned int entry_point) const; | 198 | virtual void Run(UnitState& state, unsigned int entry_point) const = 0; |
| 195 | 199 | ||
| 196 | /** | 200 | /** |
| 197 | * Produce debug information based on the given shader and input vertex | 201 | * Produce debug information based on the given shader and input vertex |
| @@ -200,10 +204,13 @@ struct ShaderSetup { | |||
| 200 | * @param config Configuration object for the shader pipeline | 204 | * @param config Configuration object for the shader pipeline |
| 201 | * @return Debug information for this shader with regards to the given vertex | 205 | * @return Debug information for this shader with regards to the given vertex |
| 202 | */ | 206 | */ |
| 203 | DebugData<true> ProduceDebugInfo(const InputVertex& input, int num_attributes, | 207 | virtual DebugData<true> ProduceDebugInfo(const InputVertex& input, int num_attributes, |
| 204 | unsigned int entry_point) const; | 208 | unsigned int entry_point) const = 0; |
| 205 | }; | 209 | }; |
| 206 | 210 | ||
| 211 | // TODO(yuriks): Remove and make it non-global state somewhere | ||
| 212 | ShaderEngine* GetEngine(); | ||
| 213 | |||
| 207 | } // namespace Shader | 214 | } // namespace Shader |
| 208 | 215 | ||
| 209 | } // namespace Pica | 216 | } // namespace Pica |
diff --git a/src/video_core/shader/shader_interpreter.h b/src/video_core/shader/shader_interpreter.h index d31dcd7a6..3237b50b3 100644 --- a/src/video_core/shader/shader_interpreter.h +++ b/src/video_core/shader/shader_interpreter.h | |||
| @@ -8,6 +8,7 @@ namespace Pica { | |||
| 8 | 8 | ||
| 9 | namespace Shader { | 9 | namespace Shader { |
| 10 | 10 | ||
| 11 | struct ShaderSetup; | ||
| 11 | struct UnitState; | 12 | struct UnitState; |
| 12 | 13 | ||
| 13 | template <bool Debug> | 14 | template <bool Debug> |