Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/libmupen64plus/mupen64plus-video-rice/src/OGLCombinerNV.cpp
2 views
1
/*
2
Copyright (C) 2003 Rice1964
3
4
This program is free software; you can redistribute it and/or
5
modify it under the terms of the GNU General Public License
6
as published by the Free Software Foundation; either version 2
7
of the License, or (at your option) any later version.
8
9
This program is distributed in the hope that it will be useful,
10
but WITHOUT ANY WARRANTY; without even the implied warranty of
11
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
GNU General Public License for more details.
13
14
You should have received a copy of the GNU General Public License
15
along with this program; if not, write to the Free Software
16
Foundation, 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
33
typedef struct {
34
GLenum input;
35
GLenum mapping;
36
GLenum componentUsage;
37
}RGBMapType;
38
39
RGBMapType 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
//========================================================================
65
COGLColorCombinerNvidia::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
74
COGLColorCombinerNvidia::~COGLColorCombinerNvidia()
75
{
76
m_vCompiledSettings.clear();
77
}
78
79
80
bool 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
107
void 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
161
void 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
248
void 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
301
int 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
336
bool 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
}
343
int 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
538
int 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
585
void 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
717
int 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
735
void 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
746
void 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
754
int 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
}
764
void 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
795
void 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
862
GLenum 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
890
void 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
937
int 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
1037
void COGLColorCombinerNvidia::DisableCombiner(void)
1038
{
1039
glDisable(GL_REGISTER_COMBINERS_NV);
1040
COGLColorCombiner4::DisableCombiner();
1041
}
1042
1043
void COGLColorCombinerNvidia::InitCombinerCycleCopy(void)
1044
{
1045
glDisable(GL_REGISTER_COMBINERS_NV);
1046
COGLColorCombiner4::InitCombinerCycleCopy();
1047
}
1048
1049
void COGLColorCombinerNvidia::InitCombinerCycleFill(void)
1050
{
1051
glDisable(GL_REGISTER_COMBINERS_NV);
1052
COGLColorCombiner4::InitCombinerCycleFill();
1053
}
1054
1055
void COGLColorCombinerNvidia::InitCombinerBlenderForSimpleTextureDraw(uint32 tile)
1056
{
1057
glDisable(GL_REGISTER_COMBINERS_NV);
1058
COGLColorCombiner::InitCombinerBlenderForSimpleTextureDraw(tile);
1059
}
1060
1061
void 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
1077
extern const char *translatedCombTypes[];
1078
void 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
1090
char* 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
1101
void 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
1147
1148