2
// Copyright ļæ½ 1997 - 2001, Paul C. Gregory
4
// Contact: pgregory@aqsis.com
6
// This library is free software; you can redistribute it and/or
7
// modify it under the terms of the GNU General Public
8
// License as published by the Free Software Foundation; either
9
// version 2 of the License, or (at your option) any later version.
11
// This library is distributed in the hope that it will be useful,
12
// but WITHOUT ANY WARRANTY; without even the implied warranty of
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
// General Public License for more details.
16
// You should have received a copy of the GNU General Public
17
// License along with this library; if not, write to the Free Software
18
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22
\brief Implements functions for the shader virtual machine.
23
\author Paul C. Gregory (pgregory@aqsis.com)
35
START_NAMESPACE( Aqsis )
37
void CqShaderVM::SO_nop()
40
void CqShaderVM::SO_dup()
45
void CqShaderVM::SO_drop()
50
void CqShaderVM::SO_debug_break()
53
void CqShaderVM::SO_pushif()
56
RESULT(type_float, class_uniform);
57
pResult->SetFloat( ReadNext().m_FloatVal );
61
void CqShaderVM::SO_puship()
64
TqFloat f = ReadNext().m_FloatVal;
65
TqFloat f2 = ReadNext().m_FloatVal;
66
TqFloat f3 = ReadNext().m_FloatVal;
67
RESULT(type_point, class_uniform);
68
CqVector3D v(f,f2,f3);
73
void CqShaderVM::SO_pushis()
76
RESULT(type_string, class_uniform);
77
CqString * ps = ReadNext().m_pString;
78
pResult->SetValue( *ps );
82
void CqShaderVM::SO_pushv()
84
PushV( GetVar( ReadNext().m_iVariable ) );
87
void CqShaderVM::SO_ipushv()
91
IqShaderData* pVar = GetVar( ReadNext().m_iVariable );
92
if ( pVar->ArrayLength() == 0 )
95
std::cerr << critical << "Attempt to index a non array variable" << std::endl;
98
//If either the value or the index is varying, so must the result be.
99
RESULT(pVar->Type(), (pVar->Size()>1 || A->Size()>1)?class_varying:class_uniform);
100
TqInt ext = m_pEnv->GridSize();
101
TqBool fVarying = ext > 1;
103
CqBitVector& RS = m_pEnv->RunningState();
104
for ( i = 0; i < ext; i++ )
106
if(!fVarying || RS.Value( i ))
109
A->GetFloat( _aq_A, i );
110
pResult->SetValueFromVariable( pVar->ArrayEntry( static_cast<unsigned int>( _aq_A ) ), i );
117
void CqShaderVM::SO_pop()
120
IqShaderData* pV = GetVar( ReadNext().m_iVariable );
122
TqUint ext = MAX( m_pEnv->GridSize(), pV->Size() );
123
TqBool fVarying = ext > 1;
125
CqBitVector& RS = m_pEnv->RunningState();
126
for ( i = 0; i < ext; i++ )
128
if(!fVarying || RS.Value( i ))
129
pV->SetValueFromVariable( Val, i );
134
void CqShaderVM::SO_ipop()
137
UsProgramElement& el = ReadNext();
138
IqShaderData* pV = GetVar( el.m_iVariable );
139
CqShaderVariableArray* pVA = static_cast<CqShaderVariableArray*>( pV );
140
if ( pV->ArrayLength() == 0 )
143
std::cerr << critical << "Attempt to index a non array variable" << std::endl;
148
//TqInt ext=__fVarying?m_pEnv->GridSize():1;
149
TqUint ext = MAX( m_pEnv->GridSize(), pV->Size() );
150
TqBool fVarying = ext > 1;
152
CqBitVector& RS = m_pEnv->RunningState();
153
for ( i = 0; i < ext; i++ )
155
if ( !fVarying || RS.Value( i ) )
158
A->GetFloat( fIndex, i );
159
TqInt index = static_cast<unsigned int>( fIndex );
160
( *pVA ) [ index ] ->SetValueFromVariable( Val, i );
167
void CqShaderVM::SO_mergef()
169
// Get the current state from the current stack entry
171
POPV( A ); // Relational result
172
POPV( F ); // False statement
173
POPV( T ); // True statement
174
RESULT(type_float, class_varying);
176
TqInt ext = m_pEnv->GridSize();
177
for ( i = 0; i < ext; i++ )
180
TqFloat _aq_T, _aq_F;
181
A->GetBool( _aq_A, i );
182
T->GetFloat( _aq_T, i );
183
F->GetFloat( _aq_F, i );
184
if ( _aq_A ) pResult->SetValue( _aq_T, i );
185
else pResult->SetValue( _aq_F, i );
193
void CqShaderVM::SO_merges()
195
// Get the current state from the current stack entry
197
POPV( A ); // Relational result
198
POPV( F ); // False statement
199
POPV( T ); // True statement
200
RESULT(type_string, class_varying);
202
TqInt ext = m_pEnv->GridSize();
203
for ( i = 0; i < ext; i++ )
206
CqString _aq_T, _aq_F;
207
A->GetBool( _aq_A, i );
208
T->GetString( _aq_T, i );
209
F->GetString( _aq_F, i );
210
if ( _aq_A ) pResult->SetValue( _aq_T, i );
211
else pResult->SetValue( _aq_F, i );
219
void CqShaderVM::SO_mergep()
221
// Get the current state from the current stack entry
223
POPV( A ); // Relational result
224
POPV( F ); // False statement
225
POPV( T ); // True statement
226
RESULT(type_point, class_varying);
228
TqInt ext = m_pEnv->GridSize();
229
for ( i = 0; i < ext; i++ )
232
CqVector3D _aq_T, _aq_F;
233
A->GetBool( _aq_A, i );
234
T->GetPoint( _aq_T, i );
235
F->GetPoint( _aq_F, i );
236
if ( _aq_A ) pResult->SetValue( _aq_T, i );
237
else pResult->SetValue( _aq_F, i );
245
void CqShaderVM::SO_mergec()
247
// Get the current state from the current stack entry
249
POPV( A ); // Relational result
250
POPV( F ); // False statement
251
POPV( T ); // True statement
252
RESULT(type_color, class_varying);
254
TqInt ext = m_pEnv->GridSize();
255
for ( i = 0; i < ext; i++ )
258
CqColor _aq_T, _aq_F;
259
A->GetBool( _aq_A, i );
260
T->GetColor( _aq_T, i );
261
F->GetColor( _aq_F, i );
262
if ( _aq_A ) pResult->SetValue( _aq_T, i );
263
else pResult->SetValue( _aq_F, i );
271
void CqShaderVM::SO_setfc()
275
RESULT(type_color, __fVarying?class_varying:class_uniform);
276
OpCAST_FC( A, pResult, m_pEnv->RunningState() );
281
void CqShaderVM::SO_setfp()
285
RESULT(type_point, __fVarying?class_varying:class_uniform);
286
OpCAST_FP( A, pResult, m_pEnv->RunningState() );
292
void CqShaderVM::SO_setfm()
296
RESULT(type_matrix, __fVarying?class_varying:class_uniform);
297
OpCAST_FM( A, pResult, m_pEnv->RunningState() );
302
void CqShaderVM::SO_settc()
308
RESULT(type_color, __fVarying?class_varying:class_uniform);
309
OpTRIPLE_C( pResult, A, B, C, m_pEnv->RunningState() );
316
void CqShaderVM::SO_settp()
322
RESULT(type_point, __fVarying?class_varying:class_uniform);
323
OpTRIPLE_P( pResult, A, B, C, m_pEnv->RunningState() );
330
void CqShaderVM::SO_setpc()
334
RESULT(type_color, __fVarying?class_varying:class_uniform);
335
OpCAST_PC( A, pResult, m_pEnv->RunningState() );
340
void CqShaderVM::SO_setcp()
344
RESULT(type_point, __fVarying?class_varying:class_uniform);
345
OpCAST_CP( A, pResult, m_pEnv->RunningState() );
350
void CqShaderVM::SO_setwm()
369
RESULT(type_matrix, __fVarying?class_varying:class_uniform);
370
OpHEXTUPLE_M( pResult, P, O, N, M, L, K, J, I, H, G, F, E, D, C, B, A, m_pEnv->RunningState() );
390
void CqShaderVM::SO_RS_PUSH()
395
void CqShaderVM::SO_RS_POP()
400
void CqShaderVM::SO_RS_GET()
402
m_pEnv->GetCurrentState();
405
void CqShaderVM::SO_RS_INVERSE()
407
m_pEnv->InvertRunningState();
410
void CqShaderVM::SO_S_CLEAR()
412
m_pEnv->ClearCurrentState();
415
void CqShaderVM::SO_S_GET()
417
// Get the current state from the current stack entry
421
CqBitVector& RS = m_pEnv->RunningState();
422
TqInt ext = m_pEnv->GridSize();
423
for ( i = 0; i < ext; i++ )
428
A->GetBool( _aq_A, i );
429
m_pEnv->CurrentState().SetValue( i, _aq_A );
435
void CqShaderVM::SO_RS_JZ()
437
SqLabel lab = ReadNext().m_Label;
438
if ( m_pEnv->RunningState().Count() == 0 )
441
m_PC = lab.m_pAddress;
445
void CqShaderVM::SO_RS_JNZ()
447
SqLabel lab = ReadNext().m_Label;
448
if ( m_pEnv->RunningState().Count() == m_pEnv->RunningState().Size() )
451
m_PC = lab.m_pAddress;
455
void CqShaderVM::SO_S_JZ()
457
SqLabel lab = ReadNext().m_Label;
458
if ( m_pEnv->CurrentState().Count() == 0 )
461
m_PC = lab.m_pAddress;
465
void CqShaderVM::SO_S_JNZ()
467
SqLabel lab = ReadNext().m_Label;
468
if ( m_pEnv->CurrentState().Count() == m_pEnv->RunningState().Size() )
471
m_PC = lab.m_pAddress;
475
void CqShaderVM::SO_jnz()
477
SqLabel lab = ReadNext().m_Label;
479
IqShaderData* f = POP.m_Data;
483
if ( !__fVarying || m_pEnv->RunningState().Value( __iGrid ) )
486
f->GetBool( _f, __iGrid );
490
while ( ++__iGrid < m_pEnv->GridSize() );
492
m_PC = lab.m_pAddress;
495
void CqShaderVM::SO_jz()
497
SqLabel lab = ReadNext().m_Label;
499
IqShaderData* f = POP.m_Data;
503
if ( !__fVarying || m_pEnv->RunningState().Value( __iGrid ) )
506
f->GetBool( _f, __iGrid );
510
while ( ++__iGrid < m_pEnv->GridSize() );
512
m_PC = lab.m_pAddress;
515
void CqShaderVM::SO_jmp()
517
SqLabel lab = ReadNext().m_Label;
519
m_PC = lab.m_pAddress;
522
void CqShaderVM::SO_lsff()
527
RESULT(type_float, __fVarying?class_varying:class_uniform);
528
OpLSS_FF( A, B, pResult, m_pEnv->RunningState() );
534
void CqShaderVM::SO_lspp()
539
RESULT(type_float, __fVarying?class_varying:class_uniform);
540
OpLSS_PP( A, B, pResult, m_pEnv->RunningState() );
546
void CqShaderVM::SO_lscc()
551
RESULT(type_float, __fVarying?class_varying:class_uniform);
552
OpLSS_CC( A, B, pResult, m_pEnv->RunningState() );
558
void CqShaderVM::SO_gtff()
563
RESULT(type_float, __fVarying?class_varying:class_uniform);
564
OpGRT_FF( A, B, pResult, m_pEnv->RunningState() );
570
void CqShaderVM::SO_gtpp()
575
RESULT(type_float, __fVarying?class_varying:class_uniform);
576
OpGRT_PP( A, B, pResult, m_pEnv->RunningState() );
582
void CqShaderVM::SO_gtcc()
587
RESULT(type_float, __fVarying?class_varying:class_uniform);
588
OpGRT_CC( A, B, pResult, m_pEnv->RunningState() );
594
void CqShaderVM::SO_geff()
599
RESULT(type_float, __fVarying?class_varying:class_uniform);
600
OpGE_FF( A, B, pResult, m_pEnv->RunningState() );
606
void CqShaderVM::SO_gepp()
611
RESULT(type_float, __fVarying?class_varying:class_uniform);
612
OpGE_PP( A, B, pResult, m_pEnv->RunningState() );
618
void CqShaderVM::SO_gecc()
623
RESULT(type_float, __fVarying?class_varying:class_uniform);
624
OpGE_CC( A, B, pResult, m_pEnv->RunningState() );
630
void CqShaderVM::SO_leff()
635
RESULT(type_float, __fVarying?class_varying:class_uniform);
636
OpLE_FF( A, B, pResult, m_pEnv->RunningState() );
642
void CqShaderVM::SO_lepp()
647
RESULT(type_float, __fVarying?class_varying:class_uniform);
648
OpLE_PP( A, B, pResult, m_pEnv->RunningState() );
654
void CqShaderVM::SO_lecc()
659
RESULT(type_float, __fVarying?class_varying:class_uniform);
660
OpLE_CC( A, B, pResult, m_pEnv->RunningState() );
666
void CqShaderVM::SO_eqff()
671
RESULT(type_float, __fVarying?class_varying:class_uniform);
672
OpEQ_FF( A, B, pResult, m_pEnv->RunningState() );
678
void CqShaderVM::SO_eqpp()
683
RESULT(type_float, __fVarying?class_varying:class_uniform);
684
OpEQ_PP( A, B, pResult, m_pEnv->RunningState() );
690
void CqShaderVM::SO_eqcc()
695
RESULT(type_float, __fVarying?class_varying:class_uniform);
696
OpEQ_CC( A, B, pResult, m_pEnv->RunningState() );
702
void CqShaderVM::SO_eqss()
707
RESULT(type_float, __fVarying?class_varying:class_uniform);
708
OpEQ_SS( A, B, pResult, m_pEnv->RunningState() );
714
void CqShaderVM::SO_neff()
719
RESULT(type_float, __fVarying?class_varying:class_uniform);
720
OpNE_FF( A, B, pResult, m_pEnv->RunningState() );
726
void CqShaderVM::SO_nepp()
731
RESULT(type_float, __fVarying?class_varying:class_uniform);
732
OpNE_PP( A, B, pResult, m_pEnv->RunningState() );
738
void CqShaderVM::SO_necc()
743
RESULT(type_float, __fVarying?class_varying:class_uniform);
744
OpNE_CC( A, B, pResult, m_pEnv->RunningState() );
750
void CqShaderVM::SO_ness()
755
RESULT(type_float, __fVarying?class_varying:class_uniform);
756
OpNE_SS( A, B, pResult, m_pEnv->RunningState() );
762
void CqShaderVM::SO_mulff()
767
RESULT(type_float, __fVarying?class_varying:class_uniform);
768
OpMUL_FF( A, B, pResult, m_pEnv->RunningState() );
774
void CqShaderVM::SO_divff()
779
RESULT(type_float, __fVarying?class_varying:class_uniform);
780
OpDIV_FF( A, B, pResult, m_pEnv->RunningState() );
786
void CqShaderVM::SO_addff()
791
RESULT(type_float, __fVarying?class_varying:class_uniform);
792
OpADD_FF( A, B, pResult, m_pEnv->RunningState() );
798
void CqShaderVM::SO_subff()
803
RESULT(type_float, __fVarying?class_varying:class_uniform);
804
OpSUB_FF( A, B, pResult, m_pEnv->RunningState() );
810
void CqShaderVM::SO_negf()
814
RESULT(type_float, __fVarying?class_varying:class_uniform);
815
OpNEG_F( A, pResult, m_pEnv->RunningState() );
820
void CqShaderVM::SO_mulpp()
825
RESULT(type_point, __fVarying?class_varying:class_uniform);
826
OpMULV( A, B, pResult, m_pEnv->RunningState() );
832
void CqShaderVM::SO_divpp()
837
RESULT(type_point, __fVarying?class_varying:class_uniform);
838
OpDIV_PP( A, B, pResult, m_pEnv->RunningState() );
844
void CqShaderVM::SO_addpp()
849
RESULT(type_point, __fVarying?class_varying:class_uniform);
850
OpADD_PP( A, B, pResult, m_pEnv->RunningState() );
856
void CqShaderVM::SO_subpp()
861
RESULT(type_point, __fVarying?class_varying:class_uniform);
862
OpSUB_PP( A, B, pResult, m_pEnv->RunningState() );
868
void CqShaderVM::SO_crspp()
873
RESULT(type_point, __fVarying?class_varying:class_uniform);
874
OpCRS_PP( A, B, pResult, m_pEnv->RunningState() );
880
void CqShaderVM::SO_dotpp()
885
RESULT(type_float, __fVarying?class_varying:class_uniform);
886
OpDOT_PP( A, B, pResult, m_pEnv->RunningState() );
892
void CqShaderVM::SO_negp()
896
RESULT(type_point, __fVarying?class_varying:class_uniform);
897
OpNEG_P( A, pResult, m_pEnv->RunningState() );
902
void CqShaderVM::SO_mulcc()
907
RESULT(type_color, __fVarying?class_varying:class_uniform);
908
OpMUL_CC( A, B, pResult, m_pEnv->RunningState() );
914
void CqShaderVM::SO_divcc()
919
RESULT(type_color, __fVarying?class_varying:class_uniform);
920
OpDIV_CC( A, B, pResult, m_pEnv->RunningState() );
926
void CqShaderVM::SO_addcc()
931
RESULT(type_color, __fVarying?class_varying:class_uniform);
932
OpADD_CC( A, B, pResult, m_pEnv->RunningState() );
938
void CqShaderVM::SO_subcc()
943
RESULT(type_color, __fVarying?class_varying:class_uniform);
944
OpSUB_CC( A, B, pResult, m_pEnv->RunningState() );
950
void CqShaderVM::SO_crscc()
955
RESULT(type_color, __fVarying?class_varying:class_uniform);
956
OpCRS_CC( A, B, pResult, m_pEnv->RunningState() );
962
void CqShaderVM::SO_dotcc()
967
RESULT(type_float, __fVarying?class_varying:class_uniform);
968
OpDOT_CC( A, B, pResult, m_pEnv->RunningState() );
974
void CqShaderVM::SO_negc()
978
RESULT(type_color, __fVarying?class_varying:class_uniform);
979
OpNEG_C( A, pResult, m_pEnv->RunningState() );
984
void CqShaderVM::SO_mulfp()
989
RESULT(type_point, __fVarying?class_varying:class_uniform);
990
OpMUL_FP( A, B, pResult, m_pEnv->RunningState() );
996
void CqShaderVM::SO_divfp()
1001
RESULT(type_point, __fVarying?class_varying:class_uniform);
1002
OpDIV_FP( A, B, pResult, m_pEnv->RunningState() );
1008
void CqShaderVM::SO_addfp()
1013
RESULT(type_point, __fVarying?class_varying:class_uniform);
1014
OpADD_FP( A, B, pResult, m_pEnv->RunningState() );
1020
void CqShaderVM::SO_subfp()
1025
RESULT(type_point, __fVarying?class_varying:class_uniform);
1026
OpSUB_FP( A, B, pResult, m_pEnv->RunningState() );
1032
void CqShaderVM::SO_mulfc()
1037
RESULT(type_color, __fVarying?class_varying:class_uniform);
1038
OpMUL_FC( A, B, pResult, m_pEnv->RunningState() );
1044
void CqShaderVM::SO_divfc()
1049
RESULT(type_color, __fVarying?class_varying:class_uniform);
1050
OpDIV_FC( A, B, pResult, m_pEnv->RunningState() );
1056
void CqShaderVM::SO_addfc()
1061
RESULT(type_color, __fVarying?class_varying:class_uniform);
1062
OpADD_FC( A, B, pResult, m_pEnv->RunningState() );
1068
void CqShaderVM::SO_subfc()
1073
RESULT(type_color, __fVarying?class_varying:class_uniform);
1074
OpSUB_FC( A, B, pResult, m_pEnv->RunningState() );
1080
void CqShaderVM::SO_mulmm()
1083
RESULT(type_float, class_uniform);
1084
pResult->SetFloat( 0.0f );
1085
Push( pResult ); /* TODO: Implement matrices in the VM*/
1088
void CqShaderVM::SO_divmm()
1091
RESULT(type_float, class_uniform);
1092
pResult->SetFloat( 0.0f );
1093
Push( pResult ); /* TODO: Implement matrices in the VM*/
1096
void CqShaderVM::SO_land()
1101
RESULT(type_float, __fVarying?class_varying:class_uniform);
1102
OpLAND_B( A, B, pResult, m_pEnv->RunningState() );
1108
void CqShaderVM::SO_lor()
1113
RESULT(type_float, __fVarying?class_varying:class_uniform);
1114
OpLOR_B( A, B, pResult, m_pEnv->RunningState() );
1120
void CqShaderVM::SO_radians()
1123
FUNC1( type_float, m_pEnv->SO_radians );
1126
void CqShaderVM::SO_degrees()
1129
FUNC1( type_float, m_pEnv->SO_degrees );
1132
void CqShaderVM::SO_sin()
1135
FUNC1( type_float, m_pEnv->SO_sin );
1138
void CqShaderVM::SO_asin()
1141
FUNC1( type_float, m_pEnv->SO_asin );
1144
void CqShaderVM::SO_cos()
1147
FUNC1( type_float, m_pEnv->SO_cos );
1150
void CqShaderVM::SO_acos()
1153
FUNC1( type_float, m_pEnv->SO_acos );
1156
void CqShaderVM::SO_tan()
1159
FUNC1( type_float, m_pEnv->SO_tan );
1162
void CqShaderVM::SO_atan()
1165
FUNC1( type_float, m_pEnv->SO_atan );
1168
void CqShaderVM::SO_atan2()
1171
FUNC2( type_float, m_pEnv->SO_atan );
1174
void CqShaderVM::SO_pow()
1177
FUNC2( type_float, m_pEnv->SO_pow );
1180
END_NAMESPACE( Aqsis )
1181
//---------------------------------------------------------------------