summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar bunnei2015-10-06 18:01:53 -0400
committerGravatar bunnei2015-10-21 21:53:16 -0400
commita74774257eafd37f2efae5b745930c3950a3aa04 (patch)
tree9229e0c816b3fa25cbcdfa9e07f788aac544b086 /src
parentrenderer_opengl: Refactor shader generation/caching to be more organized + va... (diff)
downloadyuzu-a74774257eafd37f2efae5b745930c3950a3aa04.tar.gz
yuzu-a74774257eafd37f2efae5b745930c3950a3aa04.tar.xz
yuzu-a74774257eafd37f2efae5b745930c3950a3aa04.zip
gl_shader_gen: Various cleanups + moved TEV stage generation to its own function.
Diffstat (limited to 'src')
-rw-r--r--src/video_core/renderer_opengl/gl_shader_gen.cpp331
1 files changed, 170 insertions, 161 deletions
diff --git a/src/video_core/renderer_opengl/gl_shader_gen.cpp b/src/video_core/renderer_opengl/gl_shader_gen.cpp
index 059f127af..4854c347e 100644
--- a/src/video_core/renderer_opengl/gl_shader_gen.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_gen.cpp
@@ -6,268 +6,313 @@
6#include "video_core/renderer_opengl/gl_rasterizer.h" 6#include "video_core/renderer_opengl/gl_rasterizer.h"
7#include "video_core/renderer_opengl/gl_shader_gen.h" 7#include "video_core/renderer_opengl/gl_shader_gen.h"
8 8
9using Pica::Regs;
10using TevStageConfig = Regs::TevStageConfig;
11
9namespace GLShader { 12namespace GLShader {
10 13
11static bool IsPassThroughTevStage(const Pica::Regs::TevStageConfig& stage) { 14static bool IsPassThroughTevStage(const TevStageConfig& stage) {
12 return (stage.color_op == Pica::Regs::TevStageConfig::Operation::Replace && 15 return (stage.color_op == TevStageConfig::Operation::Replace &&
13 stage.alpha_op == Pica::Regs::TevStageConfig::Operation::Replace && 16 stage.alpha_op == TevStageConfig::Operation::Replace &&
14 stage.color_source1 == Pica::Regs::TevStageConfig::Source::Previous && 17 stage.color_source1 == TevStageConfig::Source::Previous &&
15 stage.alpha_source1 == Pica::Regs::TevStageConfig::Source::Previous && 18 stage.alpha_source1 == TevStageConfig::Source::Previous &&
16 stage.color_modifier1 == Pica::Regs::TevStageConfig::ColorModifier::SourceColor && 19 stage.color_modifier1 == TevStageConfig::ColorModifier::SourceColor &&
17 stage.alpha_modifier1 == Pica::Regs::TevStageConfig::AlphaModifier::SourceAlpha && 20 stage.alpha_modifier1 == TevStageConfig::AlphaModifier::SourceAlpha &&
18 stage.GetColorMultiplier() == 1 && 21 stage.GetColorMultiplier() == 1 &&
19 stage.GetAlphaMultiplier() == 1); 22 stage.GetAlphaMultiplier() == 1);
20} 23}
21 24
22static void AppendSource(std::string& shader, Pica::Regs::TevStageConfig::Source source, const std::string& index_name) { 25static void AppendSource(std::string& out, TevStageConfig::Source source,
23 using Source = Pica::Regs::TevStageConfig::Source; 26 const std::string& index_name) {
27 using Source = TevStageConfig::Source;
24 switch (source) { 28 switch (source) {
25 case Source::PrimaryColor: 29 case Source::PrimaryColor:
26 shader += "o[2]"; 30 out += "o[2]";
27 break; 31 break;
28 case Source::PrimaryFragmentColor: 32 case Source::PrimaryFragmentColor:
29 // HACK: Until we implement fragment lighting, use primary_color 33 // HACK: Until we implement fragment lighting, use primary_color
30 shader += "o[2]"; 34 out += "o[2]";
31 break; 35 break;
32 case Source::SecondaryFragmentColor: 36 case Source::SecondaryFragmentColor:
33 // HACK: Until we implement fragment lighting, use zero 37 // HACK: Until we implement fragment lighting, use zero
34 shader += "vec4(0.0, 0.0, 0.0, 0.0)"; 38 out += "vec4(0.0, 0.0, 0.0, 0.0)";
35 break; 39 break;
36 case Source::Texture0: 40 case Source::Texture0:
37 shader += "texture(tex[0], o[3].xy)"; 41 out += "texture(tex[0], o[3].xy)";
38 break; 42 break;
39 case Source::Texture1: 43 case Source::Texture1:
40 shader += "texture(tex[1], o[3].zw)"; 44 out += "texture(tex[1], o[3].zw)";
41 break; 45 break;
42 case Source::Texture2: // TODO: Unverified 46 case Source::Texture2: // TODO: Unverified
43 shader += "texture(tex[2], o[5].zw)"; 47 out += "texture(tex[2], o[5].zw)";
44 break; 48 break;
45 case Source::PreviousBuffer: 49 case Source::PreviousBuffer:
46 shader += "g_combiner_buffer"; 50 out += "g_combiner_buffer";
47 break; 51 break;
48 case Source::Constant: 52 case Source::Constant:
49 shader += "const_color[" + index_name + "]"; 53 out += "const_color[" + index_name + "]";
50 break; 54 break;
51 case Source::Previous: 55 case Source::Previous:
52 shader += "g_last_tex_env_out"; 56 out += "g_last_tex_env_out";
53 break; 57 break;
54 default: 58 default:
55 shader += "vec4(0.0)"; 59 out += "vec4(0.0)";
56 LOG_CRITICAL(Render_OpenGL, "Unknown source op %u", source); 60 LOG_CRITICAL(Render_OpenGL, "Unknown source op %u", source);
57 break; 61 break;
58 } 62 }
59} 63}
60 64
61static void AppendColorModifier(std::string& shader, Pica::Regs::TevStageConfig::ColorModifier modifier, 65static void AppendColorModifier(std::string& out, TevStageConfig::ColorModifier modifier,
62 Pica::Regs::TevStageConfig::Source source, const std::string& index_name) { 66 TevStageConfig::Source source, const std::string& index_name) {
63 using ColorModifier = Pica::Regs::TevStageConfig::ColorModifier; 67 using ColorModifier = TevStageConfig::ColorModifier;
64 switch (modifier) { 68 switch (modifier) {
65 case ColorModifier::SourceColor: 69 case ColorModifier::SourceColor:
66 AppendSource(shader, source, index_name); 70 AppendSource(out, source, index_name);
67 shader += ".rgb"; 71 out += ".rgb";
68 break; 72 break;
69 case ColorModifier::OneMinusSourceColor: 73 case ColorModifier::OneMinusSourceColor:
70 shader += "vec3(1.0) - "; 74 out += "vec3(1.0) - ";
71 AppendSource(shader, source, index_name); 75 AppendSource(out, source, index_name);
72 shader += ".rgb"; 76 out += ".rgb";
73 break; 77 break;
74 case ColorModifier::SourceAlpha: 78 case ColorModifier::SourceAlpha:
75 AppendSource(shader, source, index_name); 79 AppendSource(out, source, index_name);
76 shader += ".aaa"; 80 out += ".aaa";
77 break; 81 break;
78 case ColorModifier::OneMinusSourceAlpha: 82 case ColorModifier::OneMinusSourceAlpha:
79 shader += "vec3(1.0) - "; 83 out += "vec3(1.0) - ";
80 AppendSource(shader, source, index_name); 84 AppendSource(out, source, index_name);
81 shader += ".aaa"; 85 out += ".aaa";
82 break; 86 break;
83 case ColorModifier::SourceRed: 87 case ColorModifier::SourceRed:
84 AppendSource(shader, source, index_name); 88 AppendSource(out, source, index_name);
85 shader += ".rrr"; 89 out += ".rrr";
86 break; 90 break;
87 case ColorModifier::OneMinusSourceRed: 91 case ColorModifier::OneMinusSourceRed:
88 shader += "vec3(1.0) - "; 92 out += "vec3(1.0) - ";
89 AppendSource(shader, source, index_name); 93 AppendSource(out, source, index_name);
90 shader += ".rrr"; 94 out += ".rrr";
91 break; 95 break;
92 case ColorModifier::SourceGreen: 96 case ColorModifier::SourceGreen:
93 AppendSource(shader, source, index_name); 97 AppendSource(out, source, index_name);
94 shader += ".ggg"; 98 out += ".ggg";
95 break; 99 break;
96 case ColorModifier::OneMinusSourceGreen: 100 case ColorModifier::OneMinusSourceGreen:
97 shader += "vec3(1.0) - "; 101 out += "vec3(1.0) - ";
98 AppendSource(shader, source, index_name); 102 AppendSource(out, source, index_name);
99 shader += ".ggg"; 103 out += ".ggg";
100 break; 104 break;
101 case ColorModifier::SourceBlue: 105 case ColorModifier::SourceBlue:
102 AppendSource(shader, source, index_name); 106 AppendSource(out, source, index_name);
103 shader += ".bbb"; 107 out += ".bbb";
104 break; 108 break;
105 case ColorModifier::OneMinusSourceBlue: 109 case ColorModifier::OneMinusSourceBlue:
106 shader += "vec3(1.0) - "; 110 out += "vec3(1.0) - ";
107 AppendSource(shader, source, index_name); 111 AppendSource(out, source, index_name);
108 shader += ".bbb"; 112 out += ".bbb";
109 break; 113 break;
110 default: 114 default:
111 shader += "vec3(0.0)"; 115 out += "vec3(0.0)";
112 LOG_CRITICAL(Render_OpenGL, "Unknown color modifier op %u", modifier); 116 LOG_CRITICAL(Render_OpenGL, "Unknown color modifier op %u", modifier);
113 break; 117 break;
114 } 118 }
115} 119}
116 120
117static void AppendAlphaModifier(std::string& shader, Pica::Regs::TevStageConfig::AlphaModifier modifier, 121static void AppendAlphaModifier(std::string& out, TevStageConfig::AlphaModifier modifier,
118 Pica::Regs::TevStageConfig::Source source, const std::string& index_name) { 122 TevStageConfig::Source source, const std::string& index_name) {
119 using AlphaModifier = Pica::Regs::TevStageConfig::AlphaModifier; 123 using AlphaModifier = TevStageConfig::AlphaModifier;
120 switch (modifier) { 124 switch (modifier) {
121 case AlphaModifier::SourceAlpha: 125 case AlphaModifier::SourceAlpha:
122 AppendSource(shader, source, index_name); 126 AppendSource(out, source, index_name);
123 shader += ".a"; 127 out += ".a";
124 break; 128 break;
125 case AlphaModifier::OneMinusSourceAlpha: 129 case AlphaModifier::OneMinusSourceAlpha:
126 shader += "1.0 - "; 130 out += "1.0 - ";
127 AppendSource(shader, source, index_name); 131 AppendSource(out, source, index_name);
128 shader += ".a"; 132 out += ".a";
129 break; 133 break;
130 case AlphaModifier::SourceRed: 134 case AlphaModifier::SourceRed:
131 AppendSource(shader, source, index_name); 135 AppendSource(out, source, index_name);
132 shader += ".r"; 136 out += ".r";
133 break; 137 break;
134 case AlphaModifier::OneMinusSourceRed: 138 case AlphaModifier::OneMinusSourceRed:
135 shader += "1.0 - "; 139 out += "1.0 - ";
136 AppendSource(shader, source, index_name); 140 AppendSource(out, source, index_name);
137 shader += ".r"; 141 out += ".r";
138 break; 142 break;
139 case AlphaModifier::SourceGreen: 143 case AlphaModifier::SourceGreen:
140 AppendSource(shader, source, index_name); 144 AppendSource(out, source, index_name);
141 shader += ".g"; 145 out += ".g";
142 break; 146 break;
143 case AlphaModifier::OneMinusSourceGreen: 147 case AlphaModifier::OneMinusSourceGreen:
144 shader += "1.0 - "; 148 out += "1.0 - ";
145 AppendSource(shader, source, index_name); 149 AppendSource(out, source, index_name);
146 shader += ".g"; 150 out += ".g";
147 break; 151 break;
148 case AlphaModifier::SourceBlue: 152 case AlphaModifier::SourceBlue:
149 AppendSource(shader, source, index_name); 153 AppendSource(out, source, index_name);
150 shader += ".b"; 154 out += ".b";
151 break; 155 break;
152 case AlphaModifier::OneMinusSourceBlue: 156 case AlphaModifier::OneMinusSourceBlue:
153 shader += "1.0 - "; 157 out += "1.0 - ";
154 AppendSource(shader, source, index_name); 158 AppendSource(out, source, index_name);
155 shader += ".b"; 159 out += ".b";
156 break; 160 break;
157 default: 161 default:
158 shader += "vec3(0.0)"; 162 out += "vec3(0.0)";
159 LOG_CRITICAL(Render_OpenGL, "Unknown alpha modifier op %u", modifier); 163 LOG_CRITICAL(Render_OpenGL, "Unknown alpha modifier op %u", modifier);
160 break; 164 break;
161 } 165 }
162} 166}
163 167
164static void AppendColorCombiner(std::string& shader, Pica::Regs::TevStageConfig::Operation operation, 168static void AppendColorCombiner(std::string& out, TevStageConfig::Operation operation,
165 const std::string& variable_name) { 169 const std::string& variable_name) {
166 using Operation = Pica::Regs::TevStageConfig::Operation; 170 using Operation = TevStageConfig::Operation;
167 171
168 switch (operation) { 172 switch (operation) {
169 case Operation::Replace: 173 case Operation::Replace:
170 shader += variable_name + "[0]"; 174 out += variable_name + "[0]";
171 break; 175 break;
172 case Operation::Modulate: 176 case Operation::Modulate:
173 shader += variable_name + "[0] * " + variable_name + "[1]"; 177 out += variable_name + "[0] * " + variable_name + "[1]";
174 break; 178 break;
175 case Operation::Add: 179 case Operation::Add:
176 shader += "min(" + variable_name + "[0] + " + variable_name + "[1], vec3(1.0))"; 180 out += "min(" + variable_name + "[0] + " + variable_name + "[1], vec3(1.0))";
177 break; 181 break;
178 case Operation::AddSigned: 182 case Operation::AddSigned:
179 shader += "clamp(" + variable_name + "[0] + " + variable_name + "[1] - vec3(0.5), vec3(0.0), vec3(1.0))"; 183 out += "clamp(" + variable_name + "[0] + " + variable_name + "[1] - vec3(0.5), vec3(0.0), vec3(1.0))";
180 break; 184 break;
181 case Operation::Lerp: 185 case Operation::Lerp:
182 shader += variable_name + "[0] * " + variable_name + "[2] + " + variable_name + "[1] * (vec3(1.0) - " + variable_name + "[2])"; 186 out += variable_name + "[0] * " + variable_name + "[2] + " + variable_name + "[1] * (vec3(1.0) - " + variable_name + "[2])";
183 break; 187 break;
184 case Operation::Subtract: 188 case Operation::Subtract:
185 shader += "max(" + variable_name + "[0] - " + variable_name + "[1], vec3(0.0))"; 189 out += "max(" + variable_name + "[0] - " + variable_name + "[1], vec3(0.0))";
186 break; 190 break;
187 case Operation::MultiplyThenAdd: 191 case Operation::MultiplyThenAdd:
188 shader += "min(" + variable_name + "[0] * " + variable_name + "[1] + " + variable_name + "[2], vec3(1.0))"; 192 out += "min(" + variable_name + "[0] * " + variable_name + "[1] + " + variable_name + "[2], vec3(1.0))";
189 break; 193 break;
190 case Operation::AddThenMultiply: 194 case Operation::AddThenMultiply:
191 shader += "min(" + variable_name + "[0] + " + variable_name + "[1], vec3(1.0)) * " + variable_name + "[2]"; 195 out += "min(" + variable_name + "[0] + " + variable_name + "[1], vec3(1.0)) * " + variable_name + "[2]";
192 break; 196 break;
193 default: 197 default:
194 shader += "vec3(0.0)"; 198 out += "vec3(0.0)";
195 LOG_CRITICAL(Render_OpenGL, "Unknown color comb op %u", operation); 199 LOG_CRITICAL(Render_OpenGL, "Unknown color combiner operation: %u", operation);
196 break; 200 break;
197 } 201 }
198} 202}
199 203
200static void AppendAlphaCombiner(std::string& shader, Pica::Regs::TevStageConfig::Operation operation, 204static void AppendAlphaCombiner(std::string& out, TevStageConfig::Operation operation,
201 const std::string& variable_name) { 205 const std::string& variable_name) {
202 using Operation = Pica::Regs::TevStageConfig::Operation; 206 using Operation = TevStageConfig::Operation;
203 switch (operation) { 207 switch (operation) {
204 case Operation::Replace: 208 case Operation::Replace:
205 shader += variable_name + "[0]"; 209 out += variable_name + "[0]";
206 break; 210 break;
207 case Operation::Modulate: 211 case Operation::Modulate:
208 shader += variable_name + "[0] * " + variable_name + "[1]"; 212 out += variable_name + "[0] * " + variable_name + "[1]";
209 break; 213 break;
210 case Operation::Add: 214 case Operation::Add:
211 shader += "min(" + variable_name + "[0] + " + variable_name + "[1], 1.0)"; 215 out += "min(" + variable_name + "[0] + " + variable_name + "[1], 1.0)";
212 break; 216 break;
213 case Operation::AddSigned: 217 case Operation::AddSigned:
214 shader += "clamp(" + variable_name + "[0] + " + variable_name + "[1] - 0.5, 0.0, 1.0)"; 218 out += "clamp(" + variable_name + "[0] + " + variable_name + "[1] - 0.5, 0.0, 1.0)";
215 break; 219 break;
216 case Operation::Lerp: 220 case Operation::Lerp:
217 shader += variable_name + "[0] * " + variable_name + "[2] + " + variable_name + "[1] * (1.0 - " + variable_name + "[2])"; 221 out += variable_name + "[0] * " + variable_name + "[2] + " + variable_name + "[1] * (1.0 - " + variable_name + "[2])";
218 break; 222 break;
219 case Operation::Subtract: 223 case Operation::Subtract:
220 shader += "max(" + variable_name + "[0] - " + variable_name + "[1], 0.0)"; 224 out += "max(" + variable_name + "[0] - " + variable_name + "[1], 0.0)";
221 break; 225 break;
222 case Operation::MultiplyThenAdd: 226 case Operation::MultiplyThenAdd:
223 shader += "min(" + variable_name + "[0] * " + variable_name + "[1] + " + variable_name + "[2], 1.0)"; 227 out += "min(" + variable_name + "[0] * " + variable_name + "[1] + " + variable_name + "[2], 1.0)";
224 break; 228 break;
225 case Operation::AddThenMultiply: 229 case Operation::AddThenMultiply:
226 shader += "min(" + variable_name + "[0] + " + variable_name + "[1], 1.0) * " + variable_name + "[2]"; 230 out += "min(" + variable_name + "[0] + " + variable_name + "[1], 1.0) * " + variable_name + "[2]";
227 break; 231 break;
228 default: 232 default:
229 shader += "0.0"; 233 out += "0.0";
230 LOG_CRITICAL(Render_OpenGL, "Unknown alpha combiner op %u", operation); 234 LOG_CRITICAL(Render_OpenGL, "Unknown alpha combiner operation: %u", operation);
231 break; 235 break;
232 } 236 }
233} 237}
234 238
235static void AppendAlphaTestCondition(std::string& shader, Pica::Regs::CompareFunc func) { 239static void AppendAlphaTestCondition(std::string& out, Regs::CompareFunc func) {
236 using CompareFunc = Pica::Regs::CompareFunc; 240 using CompareFunc = Regs::CompareFunc;
237 switch (func) { 241 switch (func) {
238 case CompareFunc::Never: 242 case CompareFunc::Never:
239 shader += "true"; 243 out += "true";
240 break; 244 break;
241 case CompareFunc::Always: 245 case CompareFunc::Always:
242 shader += "false"; 246 out += "false";
243 break; 247 break;
244 case CompareFunc::Equal: 248 case CompareFunc::Equal:
245 shader += "int(g_last_tex_env_out.a * 255.0f) != alphatest_ref"; 249 out += "int(g_last_tex_env_out.a * 255.0f) != alphatest_ref";
246 break; 250 break;
247 case CompareFunc::NotEqual: 251 case CompareFunc::NotEqual:
248 shader += "int(g_last_tex_env_out.a * 255.0f) == alphatest_ref"; 252 out += "int(g_last_tex_env_out.a * 255.0f) == alphatest_ref";
249 break; 253 break;
250 case CompareFunc::LessThan: 254 case CompareFunc::LessThan:
251 shader += "int(g_last_tex_env_out.a * 255.0f) >= alphatest_ref"; 255 out += "int(g_last_tex_env_out.a * 255.0f) >= alphatest_ref";
252 break; 256 break;
253 case CompareFunc::LessThanOrEqual: 257 case CompareFunc::LessThanOrEqual:
254 shader += "int(g_last_tex_env_out.a * 255.0f) > alphatest_ref"; 258 out += "int(g_last_tex_env_out.a * 255.0f) > alphatest_ref";
255 break; 259 break;
256 case CompareFunc::GreaterThan: 260 case CompareFunc::GreaterThan:
257 shader += "int(g_last_tex_env_out.a * 255.0f) <= alphatest_ref"; 261 out += "int(g_last_tex_env_out.a * 255.0f) <= alphatest_ref";
258 break; 262 break;
259 case CompareFunc::GreaterThanOrEqual: 263 case CompareFunc::GreaterThanOrEqual:
260 shader += "int(g_last_tex_env_out.a * 255.0f) < alphatest_ref"; 264 out += "int(g_last_tex_env_out.a * 255.0f) < alphatest_ref";
261 break; 265 break;
262 default: 266 default:
263 shader += "false"; 267 out += "false";
264 LOG_CRITICAL(Render_OpenGL, "Unknown alpha test condition %u", func); 268 LOG_CRITICAL(Render_OpenGL, "Unknown alpha test condition %u", func);
265 break; 269 break;
266 } 270 }
267} 271}
268 272
273static void WriteTevStage(std::string& out, const ShaderCacheKey& config, unsigned index) {
274 auto& stage = config.tev_stages[index];
275 if (!IsPassThroughTevStage(stage)) {
276 std::string index_name = std::to_string(index);
277
278 out += "vec3 color_results_" + index_name + "[3] = vec3[3](";
279 AppendColorModifier(out, stage.color_modifier1, stage.color_source1, index_name);
280 out += ", ";
281 AppendColorModifier(out, stage.color_modifier2, stage.color_source2, index_name);
282 out += ", ";
283 AppendColorModifier(out, stage.color_modifier3, stage.color_source3, index_name);
284 out += ");\n";
285
286 out += "vec3 color_output_" + index_name + " = ";
287 AppendColorCombiner(out, stage.color_op, "color_results_" + index_name);
288 out += ";\n";
289
290 out += "float alpha_results_" + index_name + "[3] = float[3](";
291 AppendAlphaModifier(out, stage.alpha_modifier1, stage.alpha_source1, index_name);
292 out += ", ";
293 AppendAlphaModifier(out, stage.alpha_modifier2, stage.alpha_source2, index_name);
294 out += ", ";
295 AppendAlphaModifier(out, stage.alpha_modifier3, stage.alpha_source3, index_name);
296 out += ");\n";
297
298 out += "float alpha_output_" + index_name + " = ";
299 AppendAlphaCombiner(out, stage.alpha_op, "alpha_results_" + index_name);
300 out += ";\n";
301
302 out += "g_last_tex_env_out = vec4(min(color_output_" + index_name + " * " +
303 std::to_string(stage.GetColorMultiplier()) + ".0, 1.0), min(alpha_output_" + index_name + " * " +
304 std::to_string(stage.GetAlphaMultiplier()) + ".0, 1.0));\n";
305 }
306
307 if (config.TevStageUpdatesCombinerBufferColor(index))
308 out += "g_combiner_buffer.rgb = g_last_tex_env_out.rgb;\n";
309
310 if (config.TevStageUpdatesCombinerBufferAlpha(index))
311 out += "g_combiner_buffer.a = g_last_tex_env_out.a;\n";
312}
313
269std::string GenerateFragmentShader(const ShaderCacheKey& config) { 314std::string GenerateFragmentShader(const ShaderCacheKey& config) {
270 std::string shader = R"( 315 std::string out = R"(
271#version 150 core 316#version 150 core
272 317
273#define NUM_VTX_ATTR 7 318#define NUM_VTX_ATTR 7
@@ -288,63 +333,27 @@ vec4 g_last_tex_env_out = vec4(0.0, 0.0, 0.0, 0.0);
288)"; 333)";
289 334
290 // Do not do any sort of processing if it's obvious we're not going to pass the alpha test 335 // Do not do any sort of processing if it's obvious we're not going to pass the alpha test
291 if (config.alpha_test_func == Pica::Regs::CompareFunc::Never) { 336 if (config.alpha_test_func == Regs::CompareFunc::Never) {
292 shader += "discard;"; 337 out += "discard;";
293 return shader; 338 return out;
294 } 339 }
295 340
296 auto& tev_stages = config.tev_stages; 341 for (std::size_t index = 0; index < config.tev_stages.size(); ++index)
297 for (unsigned tev_stage_index = 0; tev_stage_index < tev_stages.size(); ++tev_stage_index) { 342 WriteTevStage(out, config, (unsigned)index);
298 auto& tev_stage = tev_stages[tev_stage_index];
299 if (!IsPassThroughTevStage(tev_stage)) {
300 std::string index_name = std::to_string(tev_stage_index);
301
302 shader += "vec3 color_results_" + index_name + "[3] = vec3[3](";
303 AppendColorModifier(shader, tev_stage.color_modifier1, tev_stage.color_source1, index_name);
304 shader += ", ";
305 AppendColorModifier(shader, tev_stage.color_modifier2, tev_stage.color_source2, index_name);
306 shader += ", ";
307 AppendColorModifier(shader, tev_stage.color_modifier3, tev_stage.color_source3, index_name);
308 shader += ");\n";
309
310 shader += "vec3 color_output_" + index_name + " = ";
311 AppendColorCombiner(shader, tev_stage.color_op, "color_results_" + index_name);
312 shader += ";\n";
313
314 shader += "float alpha_results_" + index_name + "[3] = float[3](";
315 AppendAlphaModifier(shader, tev_stage.alpha_modifier1, tev_stage.alpha_source1, index_name);
316 shader += ", ";
317 AppendAlphaModifier(shader, tev_stage.alpha_modifier2, tev_stage.alpha_source2, index_name);
318 shader += ", ";
319 AppendAlphaModifier(shader, tev_stage.alpha_modifier3, tev_stage.alpha_source3, index_name);
320 shader += ");\n";
321
322 shader += "float alpha_output_" + index_name + " = ";
323 AppendAlphaCombiner(shader, tev_stage.alpha_op, "alpha_results_" + index_name);
324 shader += ";\n";
325
326 shader += "g_last_tex_env_out = vec4(min(color_output_" + index_name + " * " + std::to_string(tev_stage.GetColorMultiplier()) + ".0, 1.0), min(alpha_output_" + index_name + " * " + std::to_string(tev_stage.GetAlphaMultiplier()) + ".0, 1.0));\n";
327 }
328
329 if (config.TevStageUpdatesCombinerBufferColor(tev_stage_index))
330 shader += "g_combiner_buffer.rgb = g_last_tex_env_out.rgb;\n";
331
332 if (config.TevStageUpdatesCombinerBufferAlpha(tev_stage_index))
333 shader += "g_combiner_buffer.a = g_last_tex_env_out.a;\n";
334 }
335 343
336 if (config.alpha_test_func != Pica::Regs::CompareFunc::Always) { 344 if (config.alpha_test_func != Regs::CompareFunc::Always) {
337 shader += "if ("; 345 out += "if (";
338 AppendAlphaTestCondition(shader, config.alpha_test_func); 346 AppendAlphaTestCondition(out, config.alpha_test_func);
339 shader += ") {\n discard;\n }\n"; 347 out += ") {\n discard;\n }\n";
340 } 348 }
341 349
342 shader += "color = g_last_tex_env_out;\n}"; 350 out += "color = g_last_tex_env_out;\n}";
343 return shader; 351
352 return out;
344} 353}
345 354
346std::string GenerateVertexShader() { 355std::string GenerateVertexShader() {
347 static const std::string shader_str = R"( 356 static const std::string out = R"(
348#version 150 core 357#version 150 core
349 358
350#define NUM_VTX_ATTR 7 359#define NUM_VTX_ATTR 7
@@ -365,7 +374,7 @@ void main() {
365 gl_Position = vec4(vert_position.x, -vert_position.y, -vert_position.z, vert_position.w); 374 gl_Position = vec4(vert_position.x, -vert_position.y, -vert_position.z, vert_position.w);
366} 375}
367)"; 376)";
368 return shader_str; 377 return out;
369} 378}
370 379
371} // namespace GLShaderGen 380} // namespace GLShader