summaryrefslogtreecommitdiff
path: root/src/video_core
diff options
context:
space:
mode:
authorGravatar Yuri Kunde Schlesner2016-12-16 23:21:26 -0800
committerGravatar Yuri Kunde Schlesner2017-01-25 18:53:23 -0800
commitdd4a1672a77830a53de61cf0554b34e9e17a2905 (patch)
tree63b1b64e3858aca34c0828dbd9fec6f5ebc1f887 /src/video_core
parentVideoCore/Shader: Add constness to methods (diff)
downloadyuzu-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.cpp13
-rw-r--r--src/video_core/shader/shader.cpp44
-rw-r--r--src/video_core/shader/shader.h17
-rw-r--r--src/video_core/shader/shader_interpreter.h1
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
90class MergedShaderEngine : public ShaderEngine {
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
90#ifdef ARCHITECTURE_x86_64 101#ifdef ARCHITECTURE_x86_64
91static std::unordered_map<u64, std::unique_ptr<JitShader>> shader_map; 102static std::unordered_map<u64, std::unique_ptr<JitShader>> shader_map;
92static const JitShader* jit_shader; 103static const JitShader* jit_shader;
@@ -98,13 +109,17 @@ void ClearCache() {
98#endif // ARCHITECTURE_x86_64 109#endif // ARCHITECTURE_x86_64
99} 110}
100 111
101void ShaderSetup::Setup() { 112void 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
121MICROPROFILE_DEFINE(GPU_Shader, "GPU", "Shader", MP_RGB(50, 50, 240)); 136MICROPROFILE_DEFINE(GPU_Shader, "GPU", "Shader", MP_RGB(50, 50, 240));
122 137
123void ShaderSetup::Run(UnitState& state, unsigned int entry_point) const { 138void 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
141DebugData<true> ShaderSetup::ProduceDebugInfo(const InputVertex& input, int num_attributes, 157DebugData<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
172ShaderEngine* 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 {
156void ClearCache(); 156void ClearCache();
157 157
158struct ShaderSetup { 158struct 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
184class ShaderEngine {
185public:
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
212ShaderEngine* 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
9namespace Shader { 9namespace Shader {
10 10
11struct ShaderSetup;
11struct UnitState; 12struct UnitState;
12 13
13template <bool Debug> 14template <bool Debug>