Rice GLES2 (from mupen64plus-ae) plugin. Compile but doesn't works well on the OpenPa...
[mupen64plus-pandora.git] / source / gles2rice / src / OGLCombinerNV.cpp
CommitLineData
292f9317 1/*
2Copyright (C) 2003 Rice1964
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program; if not, write to the Free Software
16Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17*/
18
19#include "OGLExtensions.h"
20
21#include "OGLCombinerNV.h"
22#include "OGLRender.h"
23#include "OGLGraphicsContext.h"
24
25//========================================================================
26#define MUX_E_F (MUX_PRIMLODFRAC+1)
27#define MUX_SPARE1 (MUX_E_F+1)
28#define MUX_SECONDARY_COLOR (MUX_SPARE1+1)
29#define MUX_NOT_USED MUX_ERR
30#define MUX_COMBINED_SIGNED (MUX_SECONDARY_COLOR+1) //Use only by Nvidia register combiner
31
32
33typedef struct {
34 GLenum input;
35 GLenum mapping;
36 GLenum componentUsage;
37}RGBMapType;
38
39RGBMapType RGBmap1[] =
40{
41 {GL_ZERO, GL_UNSIGNED_IDENTITY_NV, GL_RGB}, //MUX_0 = 0,
42 {GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_RGB}, //MUX_1, = ZERO NEG
43 {GL_SPARE0_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB}, //MUX_COMBINED,
44 {GL_TEXTURE0_ARB, GL_UNSIGNED_IDENTITY_NV, GL_RGB}, //MUX_TEXEL0,
45 {GL_TEXTURE1_ARB, GL_UNSIGNED_IDENTITY_NV, GL_RGB}, //MUX_TEXEL1,
46 {GL_CONSTANT_COLOR0_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB}, //MUX_PRIM,
47 {GL_PRIMARY_COLOR_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB}, //MUX_SHADE,
48 {GL_CONSTANT_COLOR1_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB}, //MUX_ENV,
49 {GL_SPARE0_NV, GL_UNSIGNED_IDENTITY_NV, GL_ALPHA}, //MUX_COMBALPHA,
50 {GL_TEXTURE0_ARB, GL_UNSIGNED_IDENTITY_NV, GL_ALPHA}, //MUX_T0_ALPHA,
51 {GL_TEXTURE1_ARB, GL_UNSIGNED_IDENTITY_NV, GL_ALPHA}, //MUX_T1_ALPHA,
52 {GL_CONSTANT_COLOR0_NV, GL_UNSIGNED_IDENTITY_NV, GL_ALPHA}, //MUX_PRIM_ALPHA,
53 {GL_PRIMARY_COLOR_NV, GL_UNSIGNED_IDENTITY_NV, GL_ALPHA}, //MUX_SHADE_ALPHA,
54 {GL_CONSTANT_COLOR1_NV, GL_UNSIGNED_IDENTITY_NV, GL_ALPHA}, //MUX_ENV_ALPHA,
55 {GL_CONSTANT_COLOR1_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB}, //MUX_LODFRAC,
56 {GL_CONSTANT_COLOR1_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB}, //MUX_PRIMLODFRAC,
57 {GL_E_TIMES_F_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB}, //MUX_E_F,
58 {GL_SPARE1_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB}, //MUX_SPARE1,
59 {GL_SECONDARY_COLOR_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB}, //MUX_SECONDARY_COLOR,
60 {GL_SPARE0_NV, GL_SIGNED_IDENTITY_NV, GL_RGB}, //MUX_COMBINED_SIGNED,
61};
62
63
64//========================================================================
65COGLColorCombinerNvidia::COGLColorCombinerNvidia(CRender *pRender) :
66 COGLColorCombiner4(pRender)
67{
68 m_bNVSupported = false;
69 delete m_pDecodedMux;
70 m_pDecodedMux = new COGLDecodedMux;
71 m_pDecodedMux->m_maxConstants=2;
72}
73
74COGLColorCombinerNvidia::~COGLColorCombinerNvidia()
75{
76 m_vCompiledSettings.clear();
77}
78
79
80bool COGLColorCombinerNvidia::Initialize(void)
81{
82 m_bNVSupported = false;
83
84 if( COGLColorCombiner4::Initialize() )
85 {
86 m_bSupportMultiTexture = true;
87
88 COGLGraphicsContext *pcontext = (COGLGraphicsContext *)(CGraphicsContext::g_pGraphicsContext);
89 if( pcontext->IsExtensionSupported("GL_NV_texture_env_combine4") || pcontext->IsExtensionSupported("GL_NV_register_combiners") )
90 {
91 m_bNVSupported = true;
92 glEnable(GL_REGISTER_COMBINERS_NV);
93 return true;
94 }
95 else
96 {
97 DebugMessage(M64MSG_ERROR, "Your video card does not support Nvidia OpenGL extension combiner");
98 glDisable(GL_REGISTER_COMBINERS_NV);
99 return false;
100 }
101 }
102
103 glDisable(GL_REGISTER_COMBINERS_NV);
104 return false;
105}
106
107void COGLColorCombinerNvidia::InitCombinerCycle12(void)
108{
109 if( !m_bNVSupported ) {COGLColorCombiner4::InitCombinerCycle12(); return;}
110
111 glEnable(GL_REGISTER_COMBINERS_NV);
112
113#ifdef DEBUGGER
114 if( debuggerDropCombiners )
115 {
116 m_vCompiledSettings.clear();
117 m_dwLastMux0 = m_dwLastMux1 = 0;
118 debuggerDropCombiners = false;
119 }
120#endif
121
122 m_pOGLRender->EnableMultiTexture();
123 bool combinerIsChanged = false;
124
125 if( m_pDecodedMux->m_dwMux0 != m_dwLastMux0 || m_pDecodedMux->m_dwMux1 != m_dwLastMux1 || m_lastIndex < 0 )
126 {
127 combinerIsChanged = true;
128 m_lastIndex = FindCompiledMux();
129 if( m_lastIndex < 0 ) // Can not found
130 {
131 NVRegisterCombinerParserType result;
132 ParseDecodedMux(result);
133 m_lastIndex= SaveParserResult(result);
134 }
135
136 m_dwLastMux0 = m_pDecodedMux->m_dwMux0;
137 m_dwLastMux1 = m_pDecodedMux->m_dwMux1;
138 GenerateNVRegisterCombinerSetting(m_lastIndex);
139 }
140
141 m_pOGLRender->SetAllTexelRepeatFlag();
142
143 if( m_bCycleChanged || combinerIsChanged || gRDP.texturesAreReloaded || gRDP.colorsAreReloaded )
144 {
145 gRDP.texturesAreReloaded = false;
146 if( m_bCycleChanged || combinerIsChanged )
147 {
148 GenerateNVRegisterCombinerSettingConstants(m_lastIndex);
149 GenerateNVRegisterCombinerSetting(m_lastIndex);
150 ApplyFogAtFinalStage();
151 }
152 else if( gRDP.colorsAreReloaded )
153 {
154 GenerateNVRegisterCombinerSettingConstants(m_lastIndex);
155 }
156
157 gRDP.colorsAreReloaded = false;
158 }
159}
160
161void COGLColorCombinerNvidia::ParseDecodedMux(NVRegisterCombinerParserType &result) // Compile the decodedMux into NV register combiner setting
162{
163 //int stagesForRGB=0;
164 //int stagesForAlpha=0;
165 //int stages=0;
166
167 COGLDecodedMux &mux = *(COGLDecodedMux*)m_pDecodedMux;
168 mux.To_AB_Add_CD_Format();
169
170 result.stagesUsed=0;
171
172 if( StagesNeedToUse(mux, N64Cycle0RGB) == 0 )
173 {
174 // Nothing to be done for RGB
175 ByPassGeneralStage(result.s1rgb);
176 ByPassGeneralStage(result.s2rgb);
177 ByPassFinalStage(result.finalrgb);
178 }
179 else if( StagesNeedToUse(mux, N64Cycle0RGB) == 1 )
180 {
181 result.stagesUsed = 1;
182 Parse1Mux(mux, N64Cycle0RGB, result.s1rgb);
183 if( StagesNeedToUse(mux, N64Cycle1RGB) == 0 )
184 {
185 ByPassGeneralStage(result.s2rgb);
186 ByPassFinalStage(result.finalrgb);
187 }
188 else
189 {
190 result.stagesUsed = 2;
191 Parse1MuxForStage2AndFinalStage(mux, N64Cycle1RGB, result.s2rgb, result.finalrgb);
192 }
193 }
194 else
195 {
196 result.stagesUsed = 2;
197 Parse1Mux2Stages(mux, N64Cycle0RGB, result.s1rgb, result.s2rgb);
198 Parse1MuxForFinalStage(mux, N64Cycle1RGB, result.finalrgb);
199 }
200
201 // Debug texel1
202 /*
203 if( m_pDecodedMux->m_bTexel0IsUsed && m_pDecodedMux->m_bTexel1IsUsed )
204 {
205 result.finalrgb.a = MUX_TEXEL0;
206 result.finalrgb.b = MUX_TEXEL1;
207 result.finalrgb.c = MUX_0;
208 result.finalrgb.d = MUX_0;
209 }
210 */
211
212 if( StagesNeedToUse(mux, N64Cycle0Alpha) == 0 )
213 {
214 // Nothing to be done for Alpha
215 ByPassGeneralStage(result.s1alpha);
216 ByPassGeneralStage(result.s2alpha);
217 ByPassFinalStage(result.finalalpha);
218 }
219 else if( Parse1Mux2Stages(mux, N64Cycle0Alpha, result.s1alpha, result.s2alpha) == 1 )
220 {
221 // Only 1 NV stage is used
222 if( result.stagesUsed == 0 ) result.stagesUsed = 1;
223 if( StagesNeedToUse(mux, N64Cycle1Alpha) == 0 )
224 {
225 ByPassGeneralStage(result.s2alpha);
226 }
227 else
228 {
229 Parse1Mux(mux, N64Cycle1Alpha, result.s2alpha);
230 result.stagesUsed = 2;
231 }
232 }
233 else
234 {
235 // The 1st is used 2 stages, skip the 2nd N64 alpha setting
236 result.stagesUsed = 2;
237 result.s2alpha.a=MUX_COMBINED;
238 result.s2alpha.b=MUX_1;
239 result.s2alpha.c=m_pDecodedMux->m_n64Combiners[N64Cycle0Alpha].d;
240 result.s2alpha.d=MUX_1;
241 }
242
243 // Parse Alpha setting, alpha does not have a final stage
244 ByPassFinalStage(result.finalalpha);
245 ParseDecodedMuxForConstant(result);
246}
247
248void COGLColorCombinerNvidia::ParseDecodedMuxForConstant(NVRegisterCombinerParserType &result)
249{
250 result.constant0 = MUX_0;
251 result.constant1 = MUX_0;
252 bool const0Used=false;
253 bool const1Used=false;
254 if( m_pDecodedMux->isUsed(MUX_PRIM) )
255 {
256 result.constant0 = MUX_PRIM;
257 const0Used = true;
258 }
259 if( m_pDecodedMux->isUsed(MUX_ENV) )
260 {
261 if( const0Used )
262 {
263 result.constant1 = MUX_ENV;
264 const1Used = true;
265 }
266 else
267 {
268 result.constant0 = MUX_ENV;
269 const0Used = true;
270 }
271 }
272 if( m_pDecodedMux->isUsed(MUX_LODFRAC) && !const1Used )
273 {
274 if( !const1Used )
275 {
276 result.constant1 = MUX_LODFRAC;
277 const1Used = true;
278 }
279 else if( !const0Used )
280 {
281 result.constant0 = MUX_LODFRAC;
282 const0Used = true;
283 }
284 }
285
286 if( m_pDecodedMux->isUsed(MUX_PRIMLODFRAC) && !const1Used )
287 {
288 if( !const1Used )
289 {
290 result.constant1 = MUX_PRIMLODFRAC;
291 const1Used = true;
292 }
293 else if( !const0Used )
294 {
295 result.constant0 = MUX_PRIMLODFRAC;
296 const0Used = true;
297 }
298 }
299}
300
301int COGLColorCombinerNvidia::StagesNeedToUse(COGLDecodedMux &mux, N64StageNumberType stage)
302{
303 N64CombinerType &m = mux.m_n64Combiners[stage];
304
305 switch(mux.splitType[stage])
306 {
307 case CM_FMT_TYPE_NOT_USED:
308 return 0;
309 case CM_FMT_TYPE_D: // = A ==> can be done in 1 NV stage
310 case CM_FMT_TYPE_A_ADD_D: // = A+D ==> can be done in 1 NV stage
311 case CM_FMT_TYPE_A_MOD_C: // = A*C ==> can be done in 1 NV stage
312 case CM_FMT_TYPE_A_SUB_B: // = A-B ==> can be done in 1 NV stage
313 case CM_FMT_TYPE_A_MOD_C_ADD_D: // = A*C+D ==> can be done in 1 NV stage
314 case CM_FMT_TYPE_A_LERP_B_C: // = (A-B)*C+B ==> can be done in 1 NV stage
315 case CM_FMT_TYPE_A_SUB_B_MOD_C: // = (A-B)*C ==> can be done in 1 NV stage
316 case CM_FMT_TYPE_AB_ADD_CD: // = AB+CD
317 case CM_FMT_TYPE_AB_SUB_CD: // = AB-CD
318 return 1;
319 case CM_FMT_TYPE_A_SUB_B_ADD_D: // = A-B+D ==> can not be done in 1 stage
320 if( m.a == m.d ) // = 2A-B, simply it to A-B, in fact,we can do 2A-B with NV register combiner
321 return 1;
322 else // Need two NV stages for this N64 combiner
323 return 2;
324 case CM_FMT_TYPE_A_B_C_D: // = (A-B)*C+D ==> can not be done in 1 stage
325 default:
326 //if( m.a == m.d ) // = (A-B)*C+A = A(C+1)-B*C = A-B*C
327 // return 1;
328 //else
329 if( m.d == m.c ) // = (A-B)*C+C = A*C+(1-B)*C
330 return 1;
331 else // = (A-B)*C+D, need two NV stages
332 return 2;
333 }
334}
335
336bool isTex(uint8 val)
337{
338 if( (val&MUX_MASK) == MUX_TEXEL0 || (val&MUX_MASK) == MUX_TEXEL1 )
339 return true;
340 else
341 return false;
342}
343int COGLColorCombinerNvidia::Parse1Mux(COGLDecodedMux &mux, N64StageNumberType stage, NVGeneralCombinerType &res) // Compile the decodedMux into NV register combiner setting
344{
345 // Parse 1 N64 combiner, generate result and return how many NV stage is needed.
346 // result will be put into only 1 NV stage, not the 2nd one even if 2nd one is needed.
347 // The caller of this function will handle the 2nd NV stage if it is needed
348
349
350 // Up to here, the m_pDecodedMux is already simplied, N64 stage 1 and stage 2 have been
351 // adjusted so stage1 is almost always complicated than stage 2
352
353 // The stage type in decodedMux is still in (A-B)*C+D format
354 // we need to parser and translate it to A*B+C*D format for NV register general combiner
355 // and to A*D+(1-A)*C+D format for the NV final combiner
356
357 // Remember that N64 has two stages, NV has two general combiner stages and 1 final combiner stage
358 // NV should be able to simulate exactly all possible N64 combiner settings
359/*
360 CM_FMT_TYPE1_D, // = A ==> can be done in 1 NV stage
361 CM_FMT_TYPE2_A_ADD_D, // = A+D ==> can be done in 1 NV stage
362 CM_FMT_TYPE3_A_MOD_C, // = A*C ==> can be done in 1 NV stage
363 CM_FMT_TYPE4_A_SUB_B, // = A-B ==> can be done in 1 NV stage
364 CM_FMT_TYPE5_A_MOD_C_ADD_D, // = A*C+D ==> can be done in 1 NV stage
365 CM_FMT_TYPE6_A_LERP_B_C, // = (A-B)*C+B ==> can be done in 1 NV stage
366 CM_FMT_TYPE8_A_SUB_B_MOD_C, // = (A-B)*C ==> can be done in 1 NV stage
367
368 CM_FMT_TYPE7_A_SUB_B_ADD_D, // = A-B+C ==> can not be done in 1 stage
369 CM_FMT_TYPE9_A_B_C_D, // = (A-B)*C+D ==> can not be done in 1 stage
370
371 the last two ones, since we can neither do it in the final stage, if the 1st N64 stage
372 happen to be one of the two types and have used the two NV general combiners, and if the 2nd N64
373 combiner happens to be one of the two types as well, then we have to simplify the N64 combiner so
374 to implement it. In such as case, the N64 combiners are too complicated, we just do what either as
375 we can to implement it.
376
377 Use UNSIGNED_INVERT of ZERO ==> ONE
378
379 // If the 1st N64 stage can not be done in 1 NV stage, then we will do 1st N64 stage
380 // by using 2 NV general combiner stages, and the 2nd N64 stage by using the NV final
381 // combiner stage.
382
383 // RGB channel and alpha channel is the same in the general combiner, but different in
384 // the final combiner. In fact, final combiner does not do anything for alpha channel
385 // so alpha channel setting of both N64 combiner must be implemented by the two NV general
386 // combiner
387
388 If we can not implement the two alpha setting in 2 NV combiner stages, we will do what either
389 as we can.
390
391 */
392 N64CombinerType &m = mux.m_n64Combiners[stage];
393
394 switch(mux.splitType[stage])
395 {
396 case CM_FMT_TYPE_NOT_USED:
397 res.a=MUX_0;
398 res.b=MUX_0;
399 res.c=MUX_0;
400 res.d=MUX_0;
401 return 0;
402 break;
403 case CM_FMT_TYPE_D: // = A ==> can be done in 1 NV stage
404 res.a=m.d;
405 res.b=MUX_1;
406 res.c=MUX_0;
407 res.d=MUX_0;
408 return 1;
409 break;
410 case CM_FMT_TYPE_A_ADD_D: // = A+D ==> can be done in 1 NV stage
411 res.a=m.a;
412 res.b=MUX_1;
413 res.c=m.d;
414 res.d=MUX_1;
415 return 1;
416 break;
417 case CM_FMT_TYPE_A_MOD_C: // = A*C ==> can be done in 1 NV stage
418 res.a=m.a;
419 res.b=m.c;
420 res.c=MUX_0;
421 res.d=MUX_0;
422 return 1;
423 break;
424 case CM_FMT_TYPE_A_SUB_B: // = A-B ==> can be done in 1 NV stage
425 res.a=m.a;
426 res.b=MUX_1;
427 res.c=m.b|MUX_NEG;
428 res.d=MUX_1;
429 return 1;
430 break;
431 case CM_FMT_TYPE_A_MOD_C_ADD_D: // = A*C+D ==> can be done in 1 NV stage
432 res.a=m.a;
433 res.b=m.c;
434 res.c=m.d;
435 res.d=MUX_1;
436 return 1;
437 break;
438 case CM_FMT_TYPE_A_LERP_B_C: // = (A-B)*C+B ==> can be done in 1 NV stage
439 // = AC+(1-C)B
440 res.a=m.a;
441 res.b=m.c;
442 res.c=m.c^MUX_COMPLEMENT;
443 res.d=m.b;
444 return 1;
445 break;
446 case CM_FMT_TYPE_A_SUB_B_MOD_C: // = (A-B)*C ==> can be done in 1 NV stage
447 res.a=m.a;
448 res.b=m.c;
449 res.c=m.b|MUX_NEG;
450 res.d=m.c;
451 return 1;
452 break;
453 case CM_FMT_TYPE_AB_ADD_CD: // = AB+CD
454 res.a = m.a;
455 res.b = m.b;
456 res.c = m.c;
457 res.d = m.d;
458 return 1;
459 break;
460 case CM_FMT_TYPE_AB_SUB_CD: // = AB-CD
461 res.a = m.a;
462 res.b = m.b;
463 res.c = m.c|MUX_NEG;
464 res.d = m.d;
465 return 1;
466 break;
467 case CM_FMT_TYPE_A_SUB_B_ADD_D: // = A-B+D ==> can not be done in 1 stage
468 if( m.a == m.d ) // = 2A-B, simply it to A-B, in fact,we can do 2A-B with NV register combiner
469 {
470 res.a=m.a;
471 res.b=MUX_1;
472 res.c=m.b|MUX_NEG;
473 res.d=MUX_1;
474 return 1;
475 }
476 else // Need two NV stages for this N64 combiner
477 {
478 // Stage 1: R1=A-B
479 res.a=m.a;
480 res.b=MUX_1;
481
482 if( isTex(res.b) || !isTex(res.d) )
483 {
484 res.c=m.b|MUX_NEG;
485 res.d=MUX_1;
486 }
487 else
488 {
489 res.c=m.d;
490 res.d=MUX_1;
491 }
492 return 2;
493 }
494 break;
495 case CM_FMT_TYPE_A_B_C_D: // = (A-B)*C+D ==> can not be done in 1 stage
496 default:
497 if( m.a == m.d ) // = (A-B)*C+A = A(C+1)-B*C = A-B*C
498 {
499 res.a=m.a;
500 res.b=m.c;
501 res.c=m.b|MUX_NEG;
502 res.d=m.c;
503 return 1;
504 }
505 else if( m.d == m.c ) // = (A-B)*C+C = A*C+(1-B)*C
506 {
507 res.a=m.a;
508 res.b=m.c;
509 res.c=m.b^MUX_COMPLEMENT;
510 res.d=m.c;
511 return 1;
512 }
513 else // = (A-B)*C+D, need two NV stages
514 {
515 // Stage 1: R1=(A-B)*C = AC-BC
516 if( isTex(m.d) )
517 {
518 // = A*C+D
519 res.a=m.a;
520 res.b=m.c;
521 res.c=m.d;
522 res.d=MUX_1;
523 }
524 else
525 {
526 // = (A-B)*C = A*C - B*C
527 res.a=m.a;
528 res.b=m.c;
529 res.c=m.b|MUX_NEG;
530 res.d=m.c;
531 }
532 return 2;
533 }
534 break;
535 }
536}
537
538int COGLColorCombinerNvidia::Parse1Mux2Stages(COGLDecodedMux &mux, N64StageNumberType stage, NVGeneralCombinerType &res, NVGeneralCombinerType &res2)
539{
540 N64CombinerType &m = mux.m_n64Combiners[stage];
541 switch(mux.splitType[stage])
542 {
543 case CM_FMT_TYPE_A_SUB_B_ADD_D: // = A-B+D ==> can not be done in 1 stage
544 if( m.a != m.d ) // = 2A-B, simply it to A-B, in fact,we can do 2A-B with NV register combiner
545 {
546 // Stage 1: R1=A-B
547 res.a=m.a;
548 res.b=MUX_1;
549 res.c=m.b|MUX_NEG;
550 res.d=MUX_1;
551
552 res2.a=MUX_COMBINED_SIGNED;
553 res2.b=MUX_1;
554 res2.c=m.d;
555 res2.d=MUX_1;
556
557 return 2;
558 }
559 break;
560 case CM_FMT_TYPE_A_B_C_D: // = (A-B)*C+D ==> can not be done in 1 stage
561 case CM_FMT_TYPE_A_B_C_A: // = (A-B)*C+D ==> can not be done in 1 stage
562 //if( m.a != m.d && m.d != m.c )
563 {
564 // Stage 1: R1=(A-B)*C = AC-BC
565 res.a=m.a;
566 res.b=m.c;
567 res.c=m.b|MUX_NEG;
568 res.d=m.c;
569
570 res2.a=MUX_COMBINED_SIGNED;
571 res2.b=MUX_1;
572 res2.c=m.d;
573 res2.d=MUX_1;
574
575 return 2;
576 }
577 break;
578 default:
579 break;
580 }
581 return Parse1Mux(mux, stage, res);
582}
583
584
585void COGLColorCombinerNvidia::Parse1MuxForFinalStage(COGLDecodedMux &mux, N64StageNumberType stage, NVFinalCombinerType &res)
586{
587 N64CombinerType &m = mux.m_n64Combiners[stage];
588
589 // Final stage equation is: AB+(1-A)C+D
590 switch(mux.splitType[stage])
591 {
592 case CM_FMT_TYPE_NOT_USED:
593 res.a=MUX_0;
594 res.b=MUX_0;
595 res.c=MUX_0;
596 res.d=MUX_0;
597 break;
598 case CM_FMT_TYPE_D: // = A ==> can be done in 1 NV stage
599 res.a=m.a;
600 res.b=MUX_1;
601 res.c=MUX_0;
602 res.d=MUX_0;
603 break;
604 case CM_FMT_TYPE_A_ADD_D: // = A+D ==> can be done in 1 NV stage
605 res.a=m.a;
606 res.b=MUX_1;
607 res.c=MUX_0;
608 res.d=m.d;
609 break;
610 case CM_FMT_TYPE_A_MOD_C: // = A*C ==> can be done in 1 NV stage
611 res.a=m.a;
612 res.b=m.c;
613 res.c=MUX_0;
614 res.d=MUX_0;
615 break;
616 case CM_FMT_TYPE_A_SUB_B: // = A-B ==> can be done in 1 NV stage
617 res.a=m.a;
618 res.b=MUX_1;
619 res.c=MUX_0;
620 res.d=m.b|MUX_NEG;
621 break;
622 case CM_FMT_TYPE_A_MOD_C_ADD_D: // = A*C+D ==> can be done in 1 NV stage
623 res.a=m.a;
624 res.b=m.c;
625 res.c=MUX_0;
626 res.d=m.d;
627 break;
628 case CM_FMT_TYPE_A_LERP_B_C: // = (A-B)*C+B ==> can be done in 1 NV stage
629 // = AC+(1-B)C
630 res.a = m.c;
631 res.b = MUX_0;
632 res.c = m.b;
633 res.d = MUX_E_F;
634 res.e = m.a;
635 res.f = m.c;
636 break;
637 case CM_FMT_TYPE_A_SUB_B_MOD_C: // = (A-B)*C ==> can be done in 1 NV stage
638 res.a=m.c;
639 res.b=m.a;
640 res.c=m.b;
641 res.d=m.b|MUX_NEG;
642 break;
643 case CM_FMT_TYPE_AB_ADD_CD: // = AB+CD
644 res.a = m.a;
645 res.b = m.b;
646 res.e = m.c;
647 res.f = m.d;
648 res.c = MUX_0;
649 res.d = MUX_E_F;
650 break;
651 case CM_FMT_TYPE_AB_SUB_CD: // = AB-CD
652 res.a = m.a;
653 res.b = m.b;
654 res.e = m.c|MUX_NEG;
655 res.f = m.d;
656 res.c = MUX_0;
657 res.d = MUX_E_F;
658 break;
659 case CM_FMT_TYPE_A_SUB_B_ADD_D: // = A-B+D ==> can not be done in 1 stage
660 if( m.a == m.d ) // = 2A-B, simply it to A-B, in fact,we can do 2A-B with NV register combiner
661 {
662 res.a=m.a;
663 res.b=MUX_1;
664 res.c=MUX_0;
665 res.d=m.b|MUX_NEG;
666 }
667 else // Need two NV stages for this N64 combiner
668 {
669 TRACE0("NV Combiner parse, check me, not fully support this combiner");
670 // final combiner can not fully support this combiner setting
671 // Stage 1: R1=A-B
672 res.a=m.a;
673 res.b=MUX_1;
674 res.c=MUX_0;
675 res.d=m.b|MUX_NEG;
676 }
677 break;
678 case CM_FMT_TYPE_A_B_C_D: // = (A-B)*C+D ==> can not be done in 1 stage
679 default:
680 if( m.a == m.d ) // = (A-B)*C+A = A(C+1)-B*C = A-B*C
681 {
682 /*
683 res.a=m.c;
684 res.b=m.b|MUX_NEG;
685 res.c=MUX_0;
686 res.d=m.a;
687 */
688 res.a=m.c;
689 res.b=m.a;
690 res.c=m.b;
691 res.d=MUX_0;
692 }
693 else if( m.d == m.c ) // = (A-B)*C+C = A*C+(1-B)*C
694 {
695 res.a=m.b;
696 res.b=MUX_0;
697 res.c=m.c;
698 res.d=MUX_E_F;
699 res.e=m.a;
700 res.f=m.c;
701 }
702 else // = (A-B)*C+D, need two NV stages
703 {
704 TRACE0("NV Combiner parse, check me, not fully support this combiner");
705 // final combiner can not fully support this combiner setting
706 // Stage 1: R1=(A-B)*C = AC-BC
707 res.a=m.c;
708 res.b=m.a;
709 res.c=m.b;
710 res.d=m.b|MUX_NEG;
711 }
712 break;
713 }
714 res.g=MUX_COMBINED;
715}
716
717int COGLColorCombinerNvidia::Parse1MuxForStage2AndFinalStage(COGLDecodedMux &mux, N64StageNumberType stage, NVGeneralCombinerType &res, NVFinalCombinerType &fres)
718{
719 if( Parse1Mux(mux, stage, res) == 1 )
720 {
721 ByPassFinalStage(fres);
722 return 1;
723 }
724 else
725 {
726 ByPassFinalStage(fres);
727 fres.a=MUX_COMBINED;
728 fres.b=MUX_1;
729 fres.d = mux.m_n64Combiners[stage].d;
730 fres.g=MUX_COMBINED;
731 return 2;
732 }
733}
734
735void COGLColorCombinerNvidia::ByPassFinalStage(NVFinalCombinerType &fres)
736{
737 fres.a=MUX_0;
738 fres.b=MUX_0;
739 fres.c=MUX_0;
740 fres.d=MUX_COMBINED;
741 fres.e=MUX_0;
742 fres.f=MUX_0;
743 fres.g=MUX_COMBINED;
744}
745
746void COGLColorCombinerNvidia::ByPassGeneralStage(NVGeneralCombinerType &res)
747{
748 res.a=MUX_1;
749 res.b=MUX_COMBINED;
750 res.c=MUX_0;
751 res.d=MUX_0;
752}
753
754int COGLColorCombinerNvidia::FindCompiledMux(void)
755{
756 for( uint32 i=0; i<m_vCompiledSettings.size(); i++ )
757 {
758 if( m_vCompiledSettings[i].dwMux0 == m_pDecodedMux->m_dwMux0 && m_vCompiledSettings[i].dwMux1 == m_pDecodedMux->m_dwMux1 )
759 return i;
760 }
761
762 return -1;
763}
764void COGLColorCombinerNvidia::GenerateNVRegisterCombinerSettingConstants(int index)
765{
766 NVRegisterCombinerSettingType &info = m_vCompiledSettings[index];
767 uint8 consts[2] = {info.constant0,info.constant1};
768
769 float *pf;
770
771 for( int i=0; i<2; i++ )
772 {
773 switch( consts[i] )
774 {
775 case MUX_PRIM:
776 pf = GetPrimitiveColorfv();
777 pglCombinerParameterfvNV(GL_CONSTANT_COLOR0_NV+i,pf);
778 break;
779 case MUX_ENV:
780 pf = GetEnvColorfv();
781 pglCombinerParameterfvNV(GL_CONSTANT_COLOR0_NV+i,pf);
782 break;
783 case MUX_LODFRAC:
784 case MUX_PRIMLODFRAC:
785 {
786 float frac = gRDP.primLODFrac / 255.0f;
787 float tempf[4] = {frac,frac,frac,frac};
788 pglCombinerParameterfvNV(GL_CONSTANT_COLOR0_NV+i,tempf);
789 break;
790 }
791 }
792 }
793}
794
795void COGLColorCombinerNvidia::GenerateNVRegisterCombinerSetting(int index)
796{
797 if( index < 0 || index >= (int)m_vCompiledSettings.size() )
798 {
799 TRACE0("NV Register combiner, vector index out of range");
800 return;
801 }
802
803 NVRegisterCombinerSettingType &info = m_vCompiledSettings[index];
804
805 pglCombinerParameteriNV(GL_NUM_GENERAL_COMBINERS_NV,info.numOfStages);
806
807 uint32 i;
808
809 if( info.numOfStages > 0 )
810 {
811 for( i=0; i<4; i++ )
812 {
813 pglCombinerInputNV(GL_COMBINER0_NV, GL_RGB, info.stage1RGB[i].variable, info.stage1RGB[i].input,
814 info.stage1RGB[i].mapping, info.stage1RGB[i].componentUsage );
815 }
816
817 for( i=0; i<4; i++ )
818 {
819 pglCombinerInputNV(GL_COMBINER0_NV, GL_ALPHA, info.stage1Alpha[i].variable, info.stage1Alpha[i].input,
820 info.stage1Alpha[i].mapping, info.stage1Alpha[i].componentUsage );
821 }
822
823 pglCombinerOutputNV(GL_COMBINER0_NV, GL_RGB, info.stage1outputRGB.abOutput, info.stage1outputRGB.cdOutput,
824 info.stage1outputRGB.sumOutput, info.stage1outputRGB.scale, info.stage1outputRGB.bias, info.stage1outputRGB.abDotProduct,
825 info.stage1outputRGB.cdDotProduct, info.stage1outputRGB.muxSum);
826
827 pglCombinerOutputNV(GL_COMBINER0_NV, GL_ALPHA, info.stage2outputAlpha.abOutput, info.stage2outputAlpha.cdOutput,
828 info.stage2outputAlpha.sumOutput, info.stage2outputAlpha.scale, info.stage2outputAlpha.bias, info.stage2outputAlpha.abDotProduct,
829 info.stage2outputAlpha.cdDotProduct, info.stage2outputAlpha.muxSum);
830
831 if( info.numOfStages > 1 )
832 {
833 for( i=0; i<4; i++ )
834 {
835 pglCombinerInputNV(GL_COMBINER1_NV, GL_RGB, info.stage2RGB[i].variable,
836 info.stage2RGB[i].input, info.stage2RGB[i].mapping, info.stage2RGB[i].componentUsage );
837 }
838
839 for( i=0; i<4; i++ )
840 {
841 pglCombinerInputNV(GL_COMBINER1_NV, GL_ALPHA, info.stage2Alpha[i].variable, info.stage2Alpha[i].input,
842 info.stage2Alpha[i].mapping, info.stage2Alpha[i].componentUsage );
843 }
844
845 pglCombinerOutputNV(GL_COMBINER1_NV, GL_RGB, info.stage2outputRGB.abOutput, info.stage2outputRGB.cdOutput,
846 info.stage2outputRGB.sumOutput, info.stage2outputRGB.scale, info.stage2outputRGB.bias, info.stage2outputRGB.abDotProduct,
847 info.stage2outputRGB.cdDotProduct, info.stage2outputRGB.muxSum);
848
849 pglCombinerOutputNV(GL_COMBINER1_NV, GL_ALPHA, info.stage2outputAlpha.abOutput, info.stage2outputAlpha.cdOutput,
850 info.stage2outputAlpha.sumOutput, info.stage2outputAlpha.scale, info.stage2outputAlpha.bias, info.stage2outputAlpha.abDotProduct,
851 info.stage2outputAlpha.cdDotProduct, info.stage2outputAlpha.muxSum);
852 }
853 }
854
855 for( i=0; i<7; i++ )
856 {
857 pglFinalCombinerInputNV(info.finalStage[i].variable, info.finalStage[i].input,
858 info.finalStage[i].mapping, info.finalStage[i].componentUsage );
859 }
860}
861
862GLenum COGLColorCombinerNvidia::ConstMap(uint8 c)
863{
864 switch(c)
865 {
866 case MUX_0:
867 return GL_ZERO;
868 case MUX_1:
869 return GL_ZERO;
870 case MUX_COMBINED:
871 case MUX_TEXEL0:
872 case MUX_TEXEL1:
873 case MUX_PRIM:
874 case MUX_SHADE:
875 case MUX_ENV:
876 case MUX_COMBALPHA:
877 case MUX_T0_ALPHA:
878 case MUX_T1_ALPHA:
879 case MUX_PRIM_ALPHA:
880 case MUX_SHADE_ALPHA:
881 case MUX_ENV_ALPHA:
882 case MUX_LODFRAC:
883 case MUX_PRIMLODFRAC:
884 break;
885 }
886 return GL_ZERO;
887
888}
889
890void Set1Variable(GLenum variable, uint8 val, NVCombinerInputType &record, const NVRegisterCombinerParserType &result, bool forRGB=true)
891{
892 record.variable = variable;
893 record.componentUsage = RGBmap1[val&MUX_MASK].componentUsage;
894 record.input = RGBmap1[val&MUX_MASK].input;
895 record.mapping = RGBmap1[val&MUX_MASK].mapping;
896
897 switch( val&MUX_MASK )
898 {
899 case MUX_PRIM:
900 case MUX_ENV:
901 case MUX_PRIMLODFRAC:
902 case MUX_LODFRAC:
903 if( (val&MUX_MASK) == result.constant0 )
904 {
905 record.input = GL_CONSTANT_COLOR0_NV;
906 }
907 else if( (val&MUX_MASK) == result.constant1 )
908 {
909 record.input = GL_CONSTANT_COLOR1_NV;
910 }
911 else
912 {
913 record.input = GL_ZERO;
914 }
915 break;
916 }
917
918 if( val&MUX_NEG )
919 {
920 record.mapping = GL_SIGNED_NEGATE_NV;
921 }
922 else if( val == MUX_1 )
923 {
924 record.mapping = GL_UNSIGNED_INVERT_NV;
925 }
926 else if( val & MUX_COMPLEMENT )
927 {
928 record.mapping = GL_UNSIGNED_INVERT_NV;
929 }
930
931 if( val & MUX_ALPHAREPLICATE || !forRGB )
932 {
933 record.componentUsage = GL_ALPHA;
934 }
935}
936
937int COGLColorCombinerNvidia::SaveParserResult(const NVRegisterCombinerParserType &result)
938{
939 NVRegisterCombinerSettingType save;
940
941 // Stage 1 RGB
942 Set1Variable(GL_VARIABLE_A_NV, result.s1rgb.a, save.stage1RGB[0], result);
943 Set1Variable(GL_VARIABLE_B_NV, result.s1rgb.b, save.stage1RGB[1], result);
944 Set1Variable(GL_VARIABLE_C_NV, result.s1rgb.c, save.stage1RGB[2], result);
945 Set1Variable(GL_VARIABLE_D_NV, result.s1rgb.d, save.stage1RGB[3], result);
946
947 // Stage 1 Alpha
948 Set1Variable(GL_VARIABLE_A_NV, result.s1alpha.a, save.stage1Alpha[0], result, false);
949 Set1Variable(GL_VARIABLE_B_NV, result.s1alpha.b, save.stage1Alpha[1], result, false);
950 Set1Variable(GL_VARIABLE_C_NV, result.s1alpha.c, save.stage1Alpha[2], result, false);
951 Set1Variable(GL_VARIABLE_D_NV, result.s1alpha.d, save.stage1Alpha[3], result, false);
952
953 // Stage 2 RGB
954 Set1Variable(GL_VARIABLE_A_NV, result.s2rgb.a, save.stage2RGB[0], result);
955 Set1Variable(GL_VARIABLE_B_NV, result.s2rgb.b, save.stage2RGB[1], result);
956 Set1Variable(GL_VARIABLE_C_NV, result.s2rgb.c, save.stage2RGB[2], result);
957 Set1Variable(GL_VARIABLE_D_NV, result.s2rgb.d, save.stage2RGB[3], result);
958
959 // Stage 2 Alpha
960 Set1Variable(GL_VARIABLE_A_NV, result.s2alpha.a, save.stage2Alpha[0], result, false);
961 Set1Variable(GL_VARIABLE_B_NV, result.s2alpha.b, save.stage2Alpha[1], result, false);
962 Set1Variable(GL_VARIABLE_C_NV, result.s2alpha.c, save.stage2Alpha[2], result, false);
963 Set1Variable(GL_VARIABLE_D_NV, result.s2alpha.d, save.stage2Alpha[3], result, false);
964
965 // Final Stage RGB
966 Set1Variable(GL_VARIABLE_A_NV, result.finalrgb.a, save.finalStage[0], result);
967 Set1Variable(GL_VARIABLE_B_NV, result.finalrgb.b, save.finalStage[1], result);
968 Set1Variable(GL_VARIABLE_C_NV, result.finalrgb.c, save.finalStage[2], result);
969 Set1Variable(GL_VARIABLE_D_NV, result.finalrgb.d, save.finalStage[3], result);
970 Set1Variable(GL_VARIABLE_E_NV, result.finalrgb.e, save.finalStage[4], result);
971 //save.finalStage[4].componentUsage = GL_ALPHA;
972 Set1Variable(GL_VARIABLE_F_NV, result.finalrgb.f, save.finalStage[5], result);
973 //save.finalStage[5].componentUsage = GL_ALPHA;
974 Set1Variable(GL_VARIABLE_G_NV, result.finalrgb.g, save.finalStage[6], result);
975 save.finalStage[6].componentUsage = GL_ALPHA;
976
977 save.numOfStages = result.stagesUsed;
978 save.dwMux0 = m_pDecodedMux->m_dwMux0;
979 save.dwMux1 = m_pDecodedMux->m_dwMux1;
980
981 save.stage1outputRGB.scale = GL_NONE;
982 save.stage1outputRGB.sumOutput = GL_SPARE0_NV;
983 save.stage1outputRGB.abDotProduct = GL_FALSE;
984 save.stage1outputRGB.cdDotProduct = GL_FALSE;
985 save.stage1outputRGB.abOutput = GL_SPARE1_NV;
986 save.stage1outputRGB.cdOutput = GL_SECONDARY_COLOR_NV;
987 save.stage1outputRGB.bias = GL_NONE;
988 save.stage1outputRGB.muxSum = GL_FALSE;
989
990 save.stage1outputAlpha.scale = GL_NONE;
991 save.stage1outputAlpha.sumOutput = GL_SPARE0_NV;
992 save.stage1outputAlpha.abDotProduct = GL_FALSE;
993 save.stage1outputAlpha.cdDotProduct = GL_FALSE;
994 save.stage1outputAlpha.abOutput = GL_SPARE1_NV;
995 save.stage1outputAlpha.cdOutput = GL_SECONDARY_COLOR_NV;
996 save.stage1outputAlpha.bias = GL_NONE;
997 save.stage1outputAlpha.muxSum = GL_FALSE;
998
999 save.stage2outputRGB.scale = GL_NONE;
1000 save.stage2outputRGB.sumOutput = GL_SPARE0_NV;
1001 save.stage2outputRGB.abDotProduct = GL_FALSE;
1002 save.stage2outputRGB.cdDotProduct = GL_FALSE;
1003 save.stage2outputRGB.abOutput = GL_SPARE1_NV;
1004 save.stage2outputRGB.cdOutput = GL_SECONDARY_COLOR_NV;
1005 save.stage2outputRGB.bias = GL_NONE;
1006 save.stage2outputRGB.muxSum = GL_FALSE;
1007
1008 save.stage2outputAlpha.scale = GL_NONE;
1009 save.stage2outputAlpha.sumOutput = GL_SPARE0_NV;
1010 save.stage2outputAlpha.abDotProduct = GL_FALSE;
1011 save.stage2outputAlpha.cdDotProduct = GL_FALSE;
1012 save.stage2outputAlpha.abOutput = GL_SPARE1_NV;
1013 save.stage2outputAlpha.cdOutput = GL_SECONDARY_COLOR_NV;
1014 save.stage2outputAlpha.bias = GL_NONE;
1015 save.stage2outputAlpha.muxSum = GL_FALSE;
1016
1017 save.constant0 = result.constant0;
1018 save.constant1 = result.constant1;
1019
1020#ifdef DEBUGGER
1021 memcpy(&(save.parseResult),&result, sizeof(result));
1022 if( logCombiners )
1023 {
1024 TRACE0("\nNew Mux:\n");
1025 DisplayMuxString();
1026 COGLColorCombiner::DisplaySimpleMuxString();
1027 DisplayNVCombinerString(save);
1028 }
1029#endif
1030
1031 m_vCompiledSettings.push_back(save);
1032
1033 return m_vCompiledSettings.size()-1; // Return the index of the last element
1034}
1035
1036
1037void COGLColorCombinerNvidia::DisableCombiner(void)
1038{
1039 glDisable(GL_REGISTER_COMBINERS_NV);
1040 COGLColorCombiner4::DisableCombiner();
1041}
1042
1043void COGLColorCombinerNvidia::InitCombinerCycleCopy(void)
1044{
1045 glDisable(GL_REGISTER_COMBINERS_NV);
1046 COGLColorCombiner4::InitCombinerCycleCopy();
1047}
1048
1049void COGLColorCombinerNvidia::InitCombinerCycleFill(void)
1050{
1051 glDisable(GL_REGISTER_COMBINERS_NV);
1052 COGLColorCombiner4::InitCombinerCycleFill();
1053}
1054
1055void COGLColorCombinerNvidia::InitCombinerBlenderForSimpleTextureDraw(uint32 tile)
1056{
1057 glDisable(GL_REGISTER_COMBINERS_NV);
1058 COGLColorCombiner::InitCombinerBlenderForSimpleTextureDraw(tile);
1059}
1060
1061void COGLColorCombinerNvidia::ApplyFogAtFinalStage()
1062{
1063 // If we need to enable fog at final stage, the current flag stage setting
1064 // will be affect, which means correct combiner setting at final stage is lost
1065 // in order to use fog
1066 if( glIsEnabled(GL_FOG) )
1067 {
1068 // Use final stage as: cmb*fogfactor+fog*(1-fogfactor)
1069 pglFinalCombinerInputNV(GL_VARIABLE_A_NV, GL_FOG, GL_UNSIGNED_IDENTITY_NV, GL_ALPHA );
1070 pglFinalCombinerInputNV(GL_VARIABLE_B_NV, GL_SPARE0_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB );
1071 pglFinalCombinerInputNV(GL_VARIABLE_C_NV, GL_FOG, GL_UNSIGNED_IDENTITY_NV, GL_RGB );
1072 pglFinalCombinerInputNV(GL_VARIABLE_D_NV, GL_ZERO, GL_UNSIGNED_IDENTITY_NV, GL_RGB );
1073 }
1074}
1075
1076#ifdef DEBUGGER
1077extern const char *translatedCombTypes[];
1078void COGLColorCombinerNvidia::DisplaySimpleMuxString(void)
1079{
1080 COGLColorCombiner::DisplaySimpleMuxString();
1081 TRACE0("\nNV Combiner setting\n");
1082 uint32 index = FindCompiledMux();
1083 if( index >= 0 )
1084 {
1085 NVRegisterCombinerSettingType &record = m_vCompiledSettings[index];
1086 DisplayNVCombinerString(record);
1087 }
1088}
1089
1090char* FormatStrForFinalStage(uint8 val, char* buf)
1091{
1092 if( (val&MUX_MASK) == MUX_E_F )
1093 {
1094 strcpy(buf, "E_F");
1095 return buf;
1096 }
1097 else
1098 return DecodedMux::FormatStr(val, buf);
1099}
1100
1101void COGLColorCombinerNvidia::DisplayNVCombinerString(NVRegisterCombinerSettingType &record)
1102{
1103 NVRegisterCombinerParserType &result = record.parseResult;
1104
1105 char buf[2000];
1106 char buf0[30];
1107 char buf1[30];
1108 char buf2[30];
1109 char buf3[30];
1110 char buf4[30];
1111 char buf5[30];
1112 char buf6[30];
1113 buf[0]='\0';
1114
1115 TRACE0("\n\n");
1116 TRACE0("\nNvidia combiner stages:\n");
1117
1118 DebuggerAppendMsg("//aRGB0:\t%s * %s + %s * %s\n", DecodedMux::FormatStr(result.s1rgb.a, buf0),
1119 DecodedMux::FormatStr(result.s1rgb.b, buf1), DecodedMux::FormatStr(result.s1rgb.c, buf2),DecodedMux::FormatStr(result.s1rgb.d, buf3));
1120 DebuggerAppendMsg("//aA0:\t%s * %s + %s * %s\n", DecodedMux::FormatStr(result.s1alpha.a, buf0),
1121 DecodedMux::FormatStr(result.s1alpha.b, buf1), DecodedMux::FormatStr(result.s1alpha.c, buf2),DecodedMux::FormatStr(result.s1alpha.d, buf3));
1122 if( record.numOfStages == 2 )
1123 {
1124 DebuggerAppendMsg("//aRGB1:\t%s * %s + %s * %s\n", DecodedMux::FormatStr(result.s2rgb.a, buf0),
1125 DecodedMux::FormatStr(result.s2rgb.b, buf1), DecodedMux::FormatStr(result.s2rgb.c, buf2),DecodedMux::FormatStr(result.s2rgb.d, buf3));
1126 DebuggerAppendMsg("//aA1:\t%s * %s + %s * %s\n", DecodedMux::FormatStr(result.s2alpha.a, buf0),
1127 DecodedMux::FormatStr(result.s2alpha.b, buf1), DecodedMux::FormatStr(result.s2alpha.c, buf2),DecodedMux::FormatStr(result.s2alpha.d, buf3));
1128 }
1129 DebuggerAppendMsg("//Final:\t%s * %s + (1 - %s) * %s + %s\n\tE=%s, F=%s\n", FormatStrForFinalStage(result.finalrgb.a, buf0),
1130 FormatStrForFinalStage(result.finalrgb.b, buf1), FormatStrForFinalStage(result.finalrgb.a, buf2),
1131 FormatStrForFinalStage(result.finalrgb.c, buf3), FormatStrForFinalStage(result.finalrgb.d, buf4),
1132 FormatStrForFinalStage(result.finalrgb.e, buf5), FormatStrForFinalStage(result.finalrgb.f, buf6));
1133
1134 if( result.constant0 != MUX_0 )
1135 {
1136 DebuggerAppendMsg("//Constant 0:\t%s\n", DecodedMux::FormatStr(result.constant0, buf0));
1137 }
1138 if( result.constant1 != MUX_0 )
1139 {
1140 DebuggerAppendMsg("//Constant 1:\t%s\n", DecodedMux::FormatStr(result.constant1, buf0));
1141 }
1142 TRACE0("\n\n");
1143}
1144
1145#endif
1146