source: OGRE/trunk/ogrenew/RenderSystems/GL/src/nvparse/ps1.0_program.cpp @ 692

Revision 692, 32.1 KB checked in by mattausch, 19 years ago (diff)

adding ogre 1.2 and dependencies

Line 
1#include "ps1.0_program.h"
2
3#include "nvparse_errors.h"
4#include "nvparse_externs.h"
5
6#include <OgreGLPrerequisites.h>
7
8#include <string>
9#include <map>
10#include <algorithm>
11#include <string.h>
12#include <set>
13
14
15using namespace std;
16using namespace ps10;
17struct ltstr
18{
19        bool operator()(const char* s1, const char* s2) const
20        {
21                return strcmp(s1, s2) < 0;
22        }
23};
24
25#define DBG_MESG(msg, line)     errors.set(msg, line)
26//#define DBG_MESG(msg, line)
27namespace ps10
28{
29        std::map<int, std::pair<int,int> > constToStageAndConstMap;
30        std::vector<int> constToStageArray;
31        std::map<int, int> stageToConstMap; // to keep track of which constants have been used up for this stage.
32                // r-value of 0 means none, r-value of 1 means c0 used, and r-value of 2 means both used.
33        //std::map<int, int> constToStageMap;
34        std::map<int, GLenum> stageToTargetMap;
35        std::set<const char*, ltstr> alphaBlueRegisters; // Keeps track of whether the result of a register
36                // was a dp3, if a register is in this set, it means that if it is used a source for the alpha
37                // component the blue component should be used, and not the alpha component.
38        void SetFinalCombinerStage();
39}
40
41void RemoveFromAlphaBlue(std::string s)
42{
43        std::set<const char*, ltstr>::iterator iter =
44                ps10::alphaBlueRegisters.find(s.c_str());
45        if (iter != alphaBlueRegisters.end())
46                alphaBlueRegisters.erase(iter);
47}
48
49/*
50void AddToMap(string s, int stage)
51{
52        const char* cstr = s.c_str();
53        if (cstr[0] == 'c')
54        {
55                int constNum = atoi(&cstr[1]);
56                if (constNum < 0 || constNum > 7)
57                        return;
58                constToStageMap[constNum] = stage;
59        }
60}
61*/
62
63bool AddToMap(string s, int stage, GLenum& constVal)
64{
65        const char* cstr = s.c_str();
66        if (cstr[0] == 'c')
67        {
68                int constNum = atoi(&cstr[1]);
69                std::map<int, int>::iterator iter = stageToConstMap.find(stage);
70                if (iter == stageToConstMap.end())
71                {
72                        // no constants used for this stage.
73                        std::pair<int, int> temp;
74                        temp.first = stage;
75                        temp.second = 0;
76                        constToStageAndConstMap[constNum] = temp;
77                        stageToConstMap[stage] = 0;
78                        constVal = 0;
79                        constToStageArray.push_back(constNum);
80                        constToStageArray.push_back(stage);
81                        constToStageArray.push_back(constVal);
82                }
83                else
84                {
85                        int constUsed = (*iter).second;
86                        if (constUsed >= 1)
87                                return false;
88                        else // const0 has been used, so use const1 for this stage.
89                        {
90                                std::pair<int,int> temp;
91                                temp.first = stage;
92                                temp.second = 1;
93                                constToStageAndConstMap[constNum] = temp;
94                                stageToConstMap[stage] = 1;
95                                constVal = 1;
96                                constToStageArray.push_back(constNum);
97                                constToStageArray.push_back(stage);
98                                constToStageArray.push_back(constVal);
99                        }
100                       
101                }
102        }
103        constVal += GL_CONSTANT_COLOR0_NV;
104        return true;
105}
106
107bool IsLegalTarget(int target)
108{
109        if (target == GL_TEXTURE_CUBE_MAP_ARB)
110                return true;
111        if (target == GL_TEXTURE_3D)
112                return true;
113#if defined(GL_EXT_texture_rectangle)
114        if (target == GL_TEXTURE_RECTANGLE_EXT)
115                return true;
116#elif defined(GL_NV_texture_rectangle)
117        if (target == GL_TEXTURE_RECTANGLE_NV)
118                return true;
119#endif
120        if (target == GL_TEXTURE_2D)
121                return true;
122        if (target == GL_TEXTURE_1D)
123                return true;
124        return false;
125}
126
127bool ps10_set_map(const std::vector<int>& argv)
128{
129        if (argv.size() % 2 != 0)
130        {
131                errors.set("Odd number of arguments for texture target map.");
132                return false;
133        }
134        for (unsigned int i=0;i<argv.size();i=i+2)
135        {
136                int stage = argv[i];
137                int target = argv[i+1];
138                if (!IsLegalTarget(target))
139                {
140                        errors.set("Illegal target in texture target map.");
141                        return false;
142                }
143                ps10::stageToTargetMap[stage] = target;
144        }
145        return true;
146}
147
148int const_to_combiner_reg_mapping[32][3]; // each 3 tuple is: (constant#, stage #, reg #)
149int const_to_combiner_reg_mapping_count = 0;
150
151
152namespace
153{
154        struct set_constants
155        {
156                void operator() (constdef c)
157                {
158                        if(c.reg[0] != 'c' && c.reg.size() != 2)
159                                DBG_MESG("def line must use constant registers", 0);
160                        int reg = c.reg[1] - '0';
161                        GLenum stage = GL_COMBINER0_NV + (reg / 2);
162                        GLenum cclr  = GL_CONSTANT_COLOR0_NV + (reg % 2);
163
164                        GLfloat cval[4];
165                        cval[0] = c.r;
166                        cval[1] = c.g;
167                        cval[2] = c.b;
168                        cval[3] = c.a;
169                        glCombinerStageParameterfvNV(stage, cclr, cval);
170                }
171        };
172
173        GLenum get_tex_target(int stage)
174        {
175                std::map<int, GLenum>::iterator iter = stageToTargetMap.find(stage);
176                if (iter != stageToTargetMap.end())
177                        return (*iter).second;
178                // If no mapping set, use the current state. This will not work correctly, in general,
179                // if nvparse was invoked within a display list.
180                if(glIsEnabled(GL_TEXTURE_CUBE_MAP_ARB))
181                        return GL_TEXTURE_CUBE_MAP_ARB;
182                if(glIsEnabled(GL_TEXTURE_3D))
183                        return GL_TEXTURE_3D;
184#if defined(GL_EXT_texture_rectangle)
185                if(glIsEnabled(GL_TEXTURE_RECTANGLE_EXT))
186                        return GL_TEXTURE_RECTANGLE_EXT;
187#elif defined(GL_NV_texture_rectangle)
188                if(glIsEnabled(GL_TEXTURE_RECTANGLE_NV))
189                        return GL_TEXTURE_RECTANGLE_NV;
190#endif
191                if(glIsEnabled(GL_TEXTURE_2D))
192                        return GL_TEXTURE_2D;
193                if(glIsEnabled(GL_TEXTURE_1D))
194                        return GL_TEXTURE_1D;
195
196                //otherwise make the op none...
197                return GL_NONE;
198        }
199
200       
201
202        struct set_texture_shaders
203        {
204                set_texture_shaders(vector<constdef> * cdef)
205                {
206                        for(stage = 0; stage < 4; stage++)
207                        {
208                                glActiveTextureARB(GL_TEXTURE0_ARB + stage);
209                                glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_NONE);
210                        }
211                        stage = 0;
212                        c = cdef;
213                }
214
215                void operator() (vector<string> & instr)
216                {
217                        if(stage > 3)
218                                return;
219                        glActiveTextureARB(GL_TEXTURE0_ARB + stage);
220
221                        string op = instr[0];
222                        if(op == "tex")
223                        {
224                                if(instr.size() != 2)
225                                        fprintf(stderr,"incorrect \"tex\" instruction, stage %d...\n", stage);
226                                reg2stage[instr[1]] = stage;
227                                glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, get_tex_target(stage));
228                        }
229                        else if(op == "texbem")
230                        {
231                                if(instr.size() != 3 || stage == 0)
232                                        fprintf(stderr,"incorrect \"texbem\" instruction, stage %d...\n", stage);
233                                reg2stage[instr[1]] = stage;
234                                glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_OFFSET_TEXTURE_2D_NV);
235                                if(reg2stage.count(instr[2]) == 0)
236                                        fprintf(stderr,"incorrect \"texbem\" instruction, stage %d...\n", stage);
237                                glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + reg2stage[instr[2]]);
238                        }
239                        else if(op == "texbeml")
240                        {
241                                if(instr.size() != 3 || stage == 0)
242                                        fprintf(stderr,"incorrect \"texbeml\" instruction, stage %d...\n", stage);
243                                reg2stage[instr[1]] = stage;
244                                glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_OFFSET_TEXTURE_SCALE_NV);
245                                if(reg2stage.count(instr[2]) == 0)
246                                        fprintf(stderr,"incorrect \"texbeml\" instruction, stage %d...\n", stage);
247                                glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + reg2stage[instr[2]]);
248                        }
249                        else if(op == "texcoord")
250                        {
251                                if(instr.size() != 2)
252                                        fprintf(stderr,"incorrect \"texcoord\" instruction, stage %d...\n", stage);
253                                reg2stage[instr[1]] = stage;
254                                glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_PASS_THROUGH_NV);
255                        }
256                        else if(op == "texkill")
257                        {
258                                if(instr.size() != 2)
259                                        fprintf(stderr,"incorrect \"texkill\" instruction, stage %d...\n", stage);
260                                reg2stage[instr[1]] = stage;
261                                glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_CULL_FRAGMENT_NV);
262                        }
263                        else if(op == "texm3x2pad")
264                        {
265                                if(instr.size() != 3 || stage == 0)
266                                        fprintf(stderr,"incorrect \"texm3x2pad\" instruction, stage %d...\n", stage);
267                                reg2stage[instr[1]] = stage;
268                                glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_NV);
269                                if(instr[2].find("_bx2") != string::npos)
270                                {
271                                   instr[2].erase(instr[2].begin() + instr[2].find("_bx2"), instr[2].end());
272                                   glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV);
273                                }
274                                if(reg2stage.count(instr[2]) == 0)
275                                        fprintf(stderr,"incorrect \"texm3x2pad\" instruction, stage %d...\n", stage);
276                                glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + reg2stage[instr[2]]);
277                        }
278                        else if(op == "texm3x2tex")
279                        {
280                                if(instr.size() != 3 || stage == 0)
281                                        fprintf(stderr,"incorrect \"texm3x2tex\" instruction, stage %d...\n", stage);
282                                reg2stage[instr[1]] = stage;
283                                glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_TEXTURE_2D_NV);
284                                if(instr[2].find("_bx2") != string::npos)
285                                {
286                                   instr[2].erase(instr[2].begin() + instr[2].find("_bx2"), instr[2].end());
287                                   glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV);
288                                }
289                                if(reg2stage.count(instr[2]) == 0)
290                                        fprintf(stderr,"incorrect \"texm3x2tex\" instruction, stage %d...\n", stage);
291                                glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + reg2stage[instr[2]]);
292                        }
293                        else if(op == "texm3x3pad")
294                        {
295                                if(instr.size() != 3 || stage == 0)
296                                        fprintf(stderr,"incorrect \"texm3x3pad\" instruction, stage %d...\n", stage);
297                                reg2stage[instr[1]] = stage;
298                                glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_NV);
299                                if(instr[2].find("_bx2") != string::npos)
300                                {
301                                   instr[2].erase(instr[2].begin() + instr[2].find("_bx2"), instr[2].end());
302                                   glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV);
303                                }
304                                if(reg2stage.count(instr[2]) == 0)
305                                        fprintf(stderr,"incorrect \"texm3x3pad\" instruction, stage %d...\n", stage);
306                                glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + reg2stage[instr[2]]);
307                        }
308                        else if(op == "texm3x3tex")
309                        {
310                                if(instr.size() != 3 || stage == 0)
311                                        fprintf(stderr,"incorrect \"texm3x3tex\" instruction, stage %d...\n", stage);
312                                reg2stage[instr[1]] = stage;
313
314                                glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_TEXTURE_CUBE_MAP_NV);
315
316                                if(instr[2].find("_bx2") != string::npos)
317                                {
318                                   instr[2].erase(instr[2].begin() + instr[2].find("_bx2"), instr[2].end());
319                                   glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV);
320                                }
321                                if(reg2stage.count(instr[2]) == 0)
322                                        fprintf(stderr,"incorrect \"texm3x3tex\" instruction, stage %d...\n", stage);
323                                glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + reg2stage[instr[2]]);
324                        }
325                        else if(op == "texm3x3spec")
326                        {
327                                if(instr.size() != 4 || stage == 0)
328                                        fprintf(stderr,"incorrect \"texm3x3spec\" instruction, stage %d...\n", stage);
329                                reg2stage[instr[1]] = stage;
330
331                                if(! c)
332                                        return;
333                                constdef cd;
334                                for(int i = c->size()-1; i >= 0; i--)
335                                {
336                                        cd = (*c)[i];
337                                        if(cd.reg == "c0")
338                                                break;
339                                }
340
341                                if(cd.reg != "c0" || instr[3] != "c0")
342                                        return;
343                                GLfloat eye[4];
344                                eye[0] = cd.r;
345                                eye[1] = cd.g;
346                                eye[2] = cd.b;
347                                eye[3] = cd.a;
348
349                                glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_CONST_EYE_REFLECT_CUBE_MAP_NV);
350                                glTexEnvfv(GL_TEXTURE_SHADER_NV, GL_CONST_EYE_NV, eye);
351
352                                if(instr[2].find("_bx2") != string::npos)
353                                {
354                                   instr[2].erase(instr[2].begin() + instr[2].find("_bx2"), instr[2].end());
355                                   glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV);
356                                }
357                                if(reg2stage.count(instr[2]) == 0)
358                                        fprintf(stderr,"incorrect \"texm3x3tex\" instruction, stage %d...\n", stage);
359                                glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + reg2stage[instr[2]]);
360                        }
361                        else if(op == "texm3x3vspec")
362                        {
363                                if(instr.size() != 3 || stage == 0)
364                                        fprintf(stderr,"incorrect \"texm3x3vspec\" instruction, stage %d...\n", stage);
365                                reg2stage[instr[1]] = stage;
366
367                                glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_REFLECT_CUBE_MAP_NV);
368
369                                if(instr[2].find("_bx2") != string::npos)
370                                {
371                                   instr[2].erase(instr[2].begin() + instr[2].find("_bx2"), instr[2].end());
372                                   glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV);
373                                }
374                                if(reg2stage.count(instr[2]) == 0)
375                                        fprintf(stderr,"incorrect \"texm3x3tex\" instruction, stage %d...\n", stage);
376                                glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + reg2stage[instr[2]]);
377                        }
378                        else if(op == "texreg2ar")
379                        {
380                                if(instr.size() != 3 || stage == 0)
381                                        fprintf(stderr,"incorrect \"texreg2ar\" instruction, stage %d...\n", stage);
382                                reg2stage[instr[1]] = stage;
383                                glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DEPENDENT_AR_TEXTURE_2D_NV);
384                                if(reg2stage.count(instr[2]) == 0)
385                                        fprintf(stderr,"incorrect \"texreg2ar\" instruction, stage %d...\n", stage);
386                                glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + reg2stage[instr[2]]);
387                        }
388                        else if(op == "texreg2gb")
389                        {
390                                if(instr.size() != 3 || stage == 0)
391                                        fprintf(stderr,"incorrect \"texreg2gb\" instruction, stage %d...\n", stage);
392                                reg2stage[instr[1]] = stage;
393                                glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DEPENDENT_GB_TEXTURE_2D_NV);
394                                if(reg2stage.count(instr[2]) == 0)
395                                        fprintf(stderr,"incorrect \"texreg2gb\" instruction, stage %d...\n", stage);
396                                glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + reg2stage[instr[2]]);
397                        }
398                        stage++;
399                }
400
401                map<string, int> reg2stage;
402                int stage;
403                vector<constdef> * c;
404        };
405       
406        GLenum reg_enum(string s, int stage)
407        {
408                /*if(s == "c0")
409                        return GL_CONSTANT_COLOR0_NV;
410                else if(s == "c1")
411                        return GL_CONSTANT_COLOR1_NV;
412                else if(s == "c2")
413                        return GL_CONSTANT_COLOR0_NV;
414                else if(s == "c3")
415                        return GL_CONSTANT_COLOR1_NV;
416                else if(s == "c4")
417                        return GL_CONSTANT_COLOR0_NV;
418                else if(s == "c5")
419                        return GL_CONSTANT_COLOR1_NV;
420                else if(s == "c6")
421                        return GL_CONSTANT_COLOR0_NV;
422                else if(s == "c7")
423                        return GL_CONSTANT_COLOR1_NV;
424                        */
425                if (s == "c0" || s == "c1" || s == "c2" || s == "c3" ||
426                        s == "c4" || s == "c5" || s == "c6" || s == "c7")
427                {
428                        GLenum result;
429                        if (!AddToMap(s,stage,result))
430                                errors.set("Illegal constant usage.",line_number);
431                          // This is a pain, since the caller is a void and no check is made for errors. Sigh.
432                        return result;
433                }
434                else if(s == "t0")
435                        return GL_TEXTURE0_ARB;
436                else if(s == "t1")
437                        return GL_TEXTURE1_ARB;
438                else if(s == "t2")
439                        return GL_TEXTURE2_ARB;
440                else if(s == "t3")
441                        return GL_TEXTURE3_ARB;
442                else if(s == "v0")
443                        return GL_PRIMARY_COLOR_NV;
444                else if(s == "v1")
445                        return GL_SECONDARY_COLOR_NV;
446                else if(s == "r0")
447                        return GL_SPARE0_NV;
448                else if(s == "r1")
449                        return GL_SPARE1_NV;
450                else // ??
451                        return GL_DISCARD_NV;
452        }
453
454        struct src
455        {
456                src(string s, int stage, string *regname=NULL)
457                {
458                        init(s, stage, regname);
459                }
460
461
462                void init(string s, int stage, string *regname=NULL)
463                {
464                        arg = s;
465                        comp = GL_RGB;
466            alphaComp = GL_ALPHA;
467                        map = GL_SIGNED_IDENTITY_NV;
468
469                        unsigned int offset;
470                        if(
471                (offset = s.find(".a")) != string::npos ||
472                (offset = s.find(".w")) != string::npos
473              )
474                        {
475                                comp = GL_ALPHA;
476                                s.erase(offset, offset+2);
477                        }
478            else if ((offset = s.find(".b")) != string::npos ||
479                     (offset = s.find(".z")) != string::npos)
480            {
481                alphaComp = GL_BLUE;
482                s.erase(offset,offset+2);
483            }
484
485                        bool negate = false;
486
487                        if(s[0] == '1')
488                        {
489                                s.erase(0, 1);
490                                while(s[0] == ' ')
491                                        s.erase(0,1);
492                                if(s[0] == '-')
493                                        s.erase(0,1);
494                                while(s[0] == ' ')
495                                        s.erase(0,1);
496                                map = GL_UNSIGNED_INVERT_NV;
497                        }
498                        else if(s[0] == '-')
499                        {
500                                s.erase(0, 1);
501                                while(s[0] == ' ')
502                                        s.erase(0,1);
503                                negate = true;
504                                map = GL_UNSIGNED_INVERT_NV;
505                        }
506
507                        bool half_bias = false;
508                        bool expand = false;
509                        if(s.find("_bias") != string::npos)
510                        {
511                                s.erase(s.find("_bias"), 5);
512                                half_bias = true;
513                        }
514                        else if(s.find("_bx2") != string::npos)
515                        {
516                                s.erase(s.find("_bx2"), 4);
517                                expand = true;
518                        }
519                       
520                        if(expand)
521                        {
522                                if(negate)
523                                        map = GL_EXPAND_NEGATE_NV;
524                                else
525                                        map = GL_EXPAND_NORMAL_NV;
526                        }
527                        else if(half_bias)
528                        {
529                                if(negate)
530                                        map = GL_HALF_BIAS_NEGATE_NV;
531                                else
532                                        map = GL_HALF_BIAS_NORMAL_NV;
533                        }
534                        reg = reg_enum(s,stage);
535
536                        if (regname != NULL)
537                                *regname = s; // return the bare register name
538
539                       
540            //alphaComp = GL_ALPHA;
541                        std::set<const char*, ltstr>::iterator iter =
542                                ps10::alphaBlueRegisters.find(s.c_str());
543                        if (iter != ps10::alphaBlueRegisters.end())
544                                alphaComp = GL_BLUE;
545
546                }
547
548                string arg;
549                GLenum reg;
550                GLenum map;
551                GLenum comp;
552                GLenum alphaComp;
553        };
554
555
556        struct set_register_combiners
557        {
558                set_register_combiners()
559                {
560          // combiner = 0;
561          combiner = -1;
562                }
563
564                void operator() (vector<string> & instr)
565                {
566                        string op;
567                        GLenum scale = GL_NONE;
568                        bool op_sat = false;
569            bool paired_instr = false;
570            int instr_base = 0;
571            if (instr[0]=="+") {
572              paired_instr = true;
573              instr_base = 1;
574            }
575                        op = instr[instr_base];
576                        unsigned int offset;
577                        if((offset = op.find("_x2")) != string::npos)
578                        {
579                                scale = GL_SCALE_BY_TWO_NV;
580                                op.erase(op.begin()+offset, op.begin()+offset+3);
581                        }
582                        else if((offset = op.find("_x4")) != string::npos)
583                        {
584                                scale = GL_SCALE_BY_FOUR_NV;
585                                op.erase(op.begin()+offset, op.begin()+offset+3);
586                        }
587                        else if((offset = op.find("_d2")) != string::npos)
588                        {
589                                scale = GL_SCALE_BY_ONE_HALF_NV;
590                                op.erase(op.begin()+offset, op.begin()+offset+3);
591                        }
592
593                        if((offset = op.find("_sat")) != string::npos)
594                        {
595                                // need to actually use this...
596                                op_sat = true;
597                                op.erase(op.begin()+offset, op.begin()+offset+4);
598                        }
599                       
600                        string dst = instr[1+instr_base];
601                        int mask = GL_RGBA;
602                        if(
603                (offset = dst.find(".rgba")) != string::npos  ||
604                (offset = dst.find(".xyzw")) != string::npos
605                )
606                        {
607                                dst.erase(offset, offset + 5);
608                        }
609                        else if(
610                (offset = dst.find(".rgb")) != string::npos  ||
611                (offset = dst.find(".xyz")) != string::npos
612                )
613                        {
614                                dst.erase(offset, offset + 4);
615                                mask = GL_RGB;
616                        }
617                        else if(
618                (offset = dst.find(".a")) != string::npos  ||
619                (offset = dst.find(".w")) != string::npos
620                )
621                        {
622                                dst.erase(offset, offset + 2);
623                                mask = GL_ALPHA;
624                        }
625
626            if (!paired_instr)
627              combiner++;
628
629                        GLenum dreg = reg_enum(dst,combiner);
630                        GLenum C = GL_COMBINER0_NV + combiner;
631
632                        bool isAlphaBlue = false; // To keep track of whether the dst register's alpha was its blue value.
633
634                        if(op == "add" || op == "sub")
635                        {
636                                src a(instr[2+instr_base],combiner);
637                                src b(instr[3+instr_base],combiner);
638
639                                if(mask == GL_RGBA || mask == GL_RGB)
640                                {
641                                        glCombinerInputNV(C, GL_RGB, GL_VARIABLE_A_NV, a.reg, a.map, a.comp);
642                                        glCombinerInputNV(C, GL_RGB, GL_VARIABLE_B_NV, GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_RGB);
643                                        glCombinerInputNV(C, GL_RGB, GL_VARIABLE_C_NV, b.reg, b.map, b.comp);
644                                        if(op == "add")
645                                                glCombinerInputNV(C, GL_RGB, GL_VARIABLE_D_NV, GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_RGB);
646                                        else
647                                                glCombinerInputNV(C, GL_RGB, GL_VARIABLE_D_NV, GL_ZERO, GL_EXPAND_NORMAL_NV, GL_RGB);
648                                        glCombinerOutputNV(C, GL_RGB, GL_DISCARD_NV, GL_DISCARD_NV, dreg, scale, GL_NONE,
649                                                                           GL_FALSE, GL_FALSE, GL_FALSE);
650                                }
651                                else if (!paired_instr)
652                                {
653                                        glCombinerOutputNV(C, GL_RGB, GL_DISCARD_NV, GL_DISCARD_NV, GL_DISCARD_NV, GL_NONE, GL_NONE,
654                                                                           GL_FALSE, GL_FALSE, GL_FALSE);
655                                }
656
657                                if(mask == GL_RGBA || mask == GL_ALPHA)
658                                {
659                                        glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_A_NV, a.reg, a.map, a.alphaComp);
660                                        glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_B_NV, GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_ALPHA);
661                                        glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_C_NV, b.reg, b.map, b.alphaComp);
662                                        if(op == "add")
663                                                glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_D_NV, GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_ALPHA);
664                                        else
665                                                glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_D_NV, GL_ZERO, GL_EXPAND_NORMAL_NV, GL_ALPHA);
666                                        glCombinerOutputNV(C, GL_ALPHA, GL_DISCARD_NV, GL_DISCARD_NV, dreg, scale, GL_NONE,
667                                                                           GL_FALSE, GL_FALSE, GL_FALSE);
668                                }
669                                else if (!paired_instr)
670                                {
671                                        glCombinerOutputNV(C, GL_ALPHA, GL_DISCARD_NV, GL_DISCARD_NV, GL_DISCARD_NV, GL_NONE, GL_NONE,
672                                                                           GL_FALSE, GL_FALSE, GL_FALSE);
673                                }
674                        }
675                        else if(op == "cnd")
676                        {
677                                src a(instr[3+instr_base],combiner);
678                                src b(instr[4+instr_base],combiner);
679
680                                if(instr[2+instr_base] != "r0.a" && instr[2+instr_base] != "r0.w")
681                                {} // bad
682                                if(mask == GL_RGBA || mask == GL_RGB)
683                                {
684                                        glCombinerInputNV(C, GL_RGB, GL_VARIABLE_A_NV, a.reg, a.map, a.comp);
685                                        glCombinerInputNV(C, GL_RGB, GL_VARIABLE_B_NV, GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_RGB);
686                                        glCombinerInputNV(C, GL_RGB, GL_VARIABLE_C_NV, b.reg, b.map, b.comp);
687                                        glCombinerInputNV(C, GL_RGB, GL_VARIABLE_D_NV, GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_RGB);
688                                        glCombinerOutputNV(C, GL_RGB, GL_DISCARD_NV, GL_DISCARD_NV, dreg, scale, GL_NONE,
689                                                                           GL_FALSE, GL_FALSE, GL_TRUE);
690                                }
691                                else if (!paired_instr)
692                                {
693                                        glCombinerOutputNV(C, GL_RGB, GL_DISCARD_NV, GL_DISCARD_NV, GL_DISCARD_NV, GL_NONE, GL_NONE,
694                                                                           GL_FALSE, GL_FALSE, GL_FALSE);
695                                }
696
697                                if(mask == GL_RGBA || mask == GL_ALPHA)
698                                {
699                                        glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_A_NV, a.reg, a.map, a.alphaComp);
700                                        glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_B_NV, GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_ALPHA);
701                                        glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_C_NV, b.reg, b.map, b.alphaComp);
702                                        glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_D_NV, GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_ALPHA);
703                                        glCombinerOutputNV(C, GL_ALPHA, GL_DISCARD_NV, GL_DISCARD_NV, dreg, scale, GL_NONE,
704                                                                           GL_FALSE, GL_FALSE, GL_TRUE);
705                                }
706                                else if (!paired_instr)
707                                {
708                                        glCombinerOutputNV(C, GL_ALPHA, GL_DISCARD_NV, GL_DISCARD_NV, GL_DISCARD_NV, GL_NONE, GL_NONE,
709                                                                           GL_FALSE, GL_FALSE, GL_FALSE);
710                                }
711                        }
712                        else if(op == "dp3")
713                        {
714                                src a(instr[2+instr_base],combiner);
715                                src b(instr[3+instr_base],combiner);
716
717                                if(mask == GL_RGBA || mask == GL_RGB)
718                                {
719                                        glCombinerInputNV(C, GL_RGB, GL_VARIABLE_A_NV, a.reg, a.map, a.comp);
720                                        glCombinerInputNV(C, GL_RGB, GL_VARIABLE_B_NV, b.reg, b.map, b.comp);
721                                        glCombinerOutputNV(C, GL_RGB, dreg, GL_DISCARD_NV, GL_DISCARD_NV, scale, GL_NONE,
722                                                GL_TRUE, GL_FALSE, GL_FALSE);
723                                }
724                                else if (!paired_instr)
725                                {
726                                        // ooh.. what to do here?
727                                }
728
729                                if(mask == GL_RGBA || mask == GL_ALPHA)
730                                {
731                                        // todo -- make next ref to dst.a actually ref dst.b since combiners can't write dp3 to the alpha channel
732                                        // Done by Ashu: Put this register in the alphaBlueRegister set.
733                                        isAlphaBlue = true;
734                                        ps10::alphaBlueRegisters.insert(dst.c_str());
735                                }
736                                else if (!paired_instr)
737                                {
738                                        glCombinerOutputNV(C, GL_ALPHA, GL_DISCARD_NV, GL_DISCARD_NV, GL_DISCARD_NV, GL_NONE, GL_NONE,
739                                                                           GL_FALSE, GL_FALSE, GL_FALSE);
740                                }
741                        }
742                        else if(op == "lrp")
743                        {
744                                src a(instr[2+instr_base],combiner);
745                                src b(instr[3+instr_base],combiner);
746                                src c(instr[4+instr_base],combiner);
747
748                                if(mask == GL_RGBA || mask == GL_RGB)
749                                {
750                                        glCombinerInputNV(C, GL_RGB, GL_VARIABLE_A_NV, a.reg, GL_UNSIGNED_IDENTITY_NV, a.comp);
751                                        glCombinerInputNV(C, GL_RGB, GL_VARIABLE_B_NV, b.reg, b.map, b.comp);
752                                        glCombinerInputNV(C, GL_RGB, GL_VARIABLE_C_NV, a.reg, GL_UNSIGNED_INVERT_NV, a.comp);
753                                        glCombinerInputNV(C, GL_RGB, GL_VARIABLE_D_NV, c.reg, c.map, c.comp);
754                                        glCombinerOutputNV(C, GL_RGB, GL_DISCARD_NV, GL_DISCARD_NV, dreg, scale, GL_NONE,
755                                                                           GL_FALSE, GL_FALSE, GL_FALSE);
756                                }
757                                else if (!paired_instr)
758                                {
759                                        glCombinerOutputNV(C, GL_RGB, GL_DISCARD_NV, GL_DISCARD_NV, GL_DISCARD_NV, GL_NONE, GL_NONE,
760                                                                           GL_FALSE, GL_FALSE, GL_FALSE);
761                                }
762
763                                if(mask == GL_RGBA || mask == GL_ALPHA)
764                                {
765                                        glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_A_NV, a.reg, GL_UNSIGNED_IDENTITY_NV, a.alphaComp);
766                                        glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_B_NV, b.reg, b.map, b.alphaComp);
767                                        glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_C_NV, a.reg, GL_UNSIGNED_INVERT_NV, a.alphaComp);
768                                        glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_D_NV, c.reg, c.map, c.alphaComp);
769                                        glCombinerOutputNV(C, GL_ALPHA, GL_DISCARD_NV, GL_DISCARD_NV, dreg, scale, GL_NONE,
770                                                                           GL_FALSE, GL_FALSE, GL_FALSE);
771                                }
772                                else if (!paired_instr)
773                                {
774                                        glCombinerOutputNV(C, GL_ALPHA, GL_DISCARD_NV, GL_DISCARD_NV, GL_DISCARD_NV, GL_NONE, GL_NONE,
775                                                                           GL_FALSE, GL_FALSE, GL_FALSE);
776                                }
777                        }
778                        else if(op == "mad")
779                        {
780                                src a(instr[2+instr_base],combiner);
781                                src b(instr[3+instr_base],combiner);
782                                src c(instr[4+instr_base],combiner);
783
784                                if(mask == GL_RGBA || mask == GL_RGB)
785                                {
786                                        glCombinerInputNV(C, GL_RGB, GL_VARIABLE_A_NV, a.reg, a.map, a.comp);
787                                        glCombinerInputNV(C, GL_RGB, GL_VARIABLE_B_NV, b.reg, b.map, b.comp);                                   
788                                        glCombinerInputNV(C, GL_RGB, GL_VARIABLE_C_NV, GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_RGB);
789                                        glCombinerInputNV(C, GL_RGB, GL_VARIABLE_D_NV, c.reg, c.map, c.comp);
790                                        glCombinerOutputNV(C, GL_RGB, GL_DISCARD_NV, GL_DISCARD_NV, dreg, scale, GL_NONE,
791                                                                           GL_FALSE, GL_FALSE, GL_FALSE);
792                                }
793                                else if (!paired_instr)
794                                {
795                                        glCombinerOutputNV(C, GL_RGB, GL_DISCARD_NV, GL_DISCARD_NV, GL_DISCARD_NV, GL_NONE, GL_NONE,
796                                                                           GL_FALSE, GL_FALSE, GL_FALSE);
797                                }
798
799                                if(mask == GL_RGBA || mask == GL_ALPHA)
800                                {
801                                        glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_A_NV, a.reg, a.map, a.alphaComp);
802                                        glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_B_NV, b.reg, b.map, b.alphaComp);
803                                        glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_C_NV, GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_ALPHA);
804                                        glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_D_NV, c.reg, c.map, c.alphaComp);
805                                        glCombinerOutputNV(C, GL_ALPHA, GL_DISCARD_NV, GL_DISCARD_NV, dreg, scale, GL_NONE,
806                                                                           GL_FALSE, GL_FALSE, GL_FALSE);
807                                }
808                                else if (!paired_instr)
809                                {
810                                        glCombinerOutputNV(C, GL_ALPHA, GL_DISCARD_NV, GL_DISCARD_NV, GL_DISCARD_NV, GL_NONE, GL_NONE,
811                                                                           GL_FALSE, GL_FALSE, GL_FALSE);
812                                }
813                        }
814                        else if(op == "mov")
815                        {
816                                src a(instr[2+instr_base],combiner);
817
818                                if(mask == GL_RGBA || mask == GL_RGB)
819                                {
820                                        glCombinerInputNV(C, GL_RGB, GL_VARIABLE_A_NV, a.reg, a.map, a.comp);
821                                        glCombinerInputNV(C, GL_RGB, GL_VARIABLE_B_NV, GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_RGB);
822                                        glCombinerOutputNV(C, GL_RGB, dreg, GL_DISCARD_NV, GL_DISCARD_NV, scale, GL_NONE,
823                                                                           GL_FALSE, GL_FALSE, GL_FALSE);
824                                }
825                                else if (!paired_instr)
826                                {
827                                        glCombinerOutputNV(C, GL_RGB, GL_DISCARD_NV, GL_DISCARD_NV, GL_DISCARD_NV, GL_NONE, GL_NONE,
828                                                                           GL_FALSE, GL_FALSE, GL_FALSE);
829                                }
830
831                                if(mask == GL_RGBA || mask == GL_ALPHA)
832                                {
833                                        glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_A_NV, a.reg, a.map, a.alphaComp);
834                                        glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_B_NV, GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_ALPHA);
835                                        glCombinerOutputNV(C, GL_ALPHA, dreg, GL_DISCARD_NV, GL_DISCARD_NV, scale, GL_NONE,
836                                                                           GL_FALSE, GL_FALSE, GL_FALSE);
837                                }
838                                else if (!paired_instr)
839                                {
840                                        glCombinerOutputNV(C, GL_ALPHA, GL_DISCARD_NV, GL_DISCARD_NV, GL_DISCARD_NV, GL_NONE, GL_NONE,
841                                                                           GL_FALSE, GL_FALSE, GL_FALSE);
842                                }
843                        }
844                        else if(op == "mul")
845                        {
846                                src a(instr[2+instr_base],combiner);
847                                src b(instr[3+instr_base],combiner);
848
849                                if(mask == GL_RGBA || mask == GL_RGB)
850                                {
851                                        glCombinerInputNV(C, GL_RGB, GL_VARIABLE_A_NV, a.reg, a.map, a.comp);
852                                        glCombinerInputNV(C, GL_RGB, GL_VARIABLE_B_NV, b.reg, b.map, b.comp);
853                                        glCombinerOutputNV(C, GL_RGB, dreg, GL_DISCARD_NV, GL_DISCARD_NV, scale, GL_NONE,
854                                                                           GL_FALSE, GL_FALSE, GL_FALSE);
855                                }
856                                else if (!paired_instr)
857                                {
858                                        glCombinerOutputNV(C, GL_RGB, GL_DISCARD_NV, GL_DISCARD_NV, GL_DISCARD_NV, GL_NONE, GL_NONE,
859                                                                           GL_FALSE, GL_FALSE, GL_FALSE);
860                                }
861
862                                if(mask == GL_RGBA || mask == GL_ALPHA)
863                                {
864                                        glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_A_NV, a.reg, a.map, a.alphaComp);
865                                        glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_B_NV, b.reg, b.map, b.alphaComp);
866                                        glCombinerOutputNV(C, GL_ALPHA, dreg, GL_DISCARD_NV, GL_DISCARD_NV, scale, GL_NONE,
867                                                                           GL_FALSE, GL_FALSE, GL_FALSE);
868                                }
869                                else if (!paired_instr)
870                                {
871                                        glCombinerOutputNV(C, GL_ALPHA, GL_DISCARD_NV, GL_DISCARD_NV, GL_DISCARD_NV, GL_NONE, GL_NONE,
872                                                                           GL_FALSE, GL_FALSE, GL_FALSE);
873                                }
874                        }
875            // combiner++;
876                        if (!isAlphaBlue)
877                                RemoveFromAlphaBlue(dst);
878                }
879
880                int combiner;
881        };
882
883
884}
885
886void ps10::SetFinalCombinerStage()
887{
888        glFinalCombinerInputNV(GL_VARIABLE_A_NV,GL_FOG,GL_UNSIGNED_IDENTITY_NV,GL_ALPHA);
889        glFinalCombinerInputNV(GL_VARIABLE_B_NV,GL_SPARE0_NV,
890                        GL_UNSIGNED_IDENTITY_NV,GL_RGB);
891        glFinalCombinerInputNV(GL_VARIABLE_C_NV,GL_FOG,GL_UNSIGNED_IDENTITY_NV,GL_RGB);
892        glFinalCombinerInputNV(GL_VARIABLE_D_NV,GL_ZERO,GL_UNSIGNED_IDENTITY_NV,GL_RGB);
893        glFinalCombinerInputNV(GL_VARIABLE_E_NV,GL_ZERO,GL_UNSIGNED_IDENTITY_NV,GL_RGB);
894        glFinalCombinerInputNV(GL_VARIABLE_F_NV,GL_ZERO,GL_UNSIGNED_IDENTITY_NV,GL_RGB);
895        std::set<const char*, ltstr>::iterator iter = ps10::alphaBlueRegisters.find("r0");
896        GLenum alphaComp = GL_ALPHA;
897        if (iter != ps10::alphaBlueRegisters.end())
898                alphaComp = GL_BLUE;
899        glFinalCombinerInputNV(GL_VARIABLE_G_NV,GL_SPARE0_NV,GL_UNSIGNED_IDENTITY_NV,alphaComp);
900        // We can now clear alphaBlueRegisters for the next go around
901        alphaBlueRegisters.clear();
902}
903
904void ps10::invoke(vector<constdef> * c,
905                      list<vector<string> > * a,
906                                  list<vector<string> > * b)
907{
908        const_to_combiner_reg_mapping_count = 0; // Hansong
909
910
911        glEnable(GL_PER_STAGE_CONSTANTS_NV); // should we require apps to do this?
912        if(c)
913                for_each(c->begin(), c->end(), set_constants());
914        if(a)
915                for_each(a->begin(), a->end(), set_texture_shaders(c));
916        glActiveTextureARB( GL_TEXTURE0_ARB );
917    int numCombiners = 0;
918    list<vector<string> >::iterator it = b->begin();
919    for(; it!=b->end(); ++it) {
920      if ( (*it)[0] != "+" )
921        numCombiners++;
922    }
923    glCombinerParameteriNV(GL_NUM_GENERAL_COMBINERS_NV, numCombiners);
924        if(b)
925                for_each(b->begin(), b->end(), set_register_combiners());
926        SetFinalCombinerStage();
927        // We can clear the stageToTarget map now.
928        stageToTargetMap.clear();
929}
930
931// simple identification - just look for magic substring
932//  -- easy to break...
933bool is_ps10(const char * s)
934{
935        if(strstr(s, "ps.1.0"))
936                return true;
937        if(strstr(s, "Ps.1.0"))
938                return true;
939        if(strstr(s, "ps.1.1"))
940                return true;
941        if(strstr(s, "Ps.1.1"))
942                return true;
943        return false;
944}
945
946bool ps10::init_extensions()
947{
948        // register combiners   
949        static bool rcinit = false;
950        if(rcinit == false)
951        {
952      /*
953                if(! glh_init_extensions("GL_NV_register_combiners"))
954                {
955                        errors.set("unable to initialize GL_NV_register_combiners\n");
956                        return false;
957                }
958                else
959                {
960        */
961                        rcinit = true;
962            /*
963                }
964        */
965        }
966
967        // register combiners 2
968        static bool rc2init = false;
969        if(rc2init == false)
970        {
971      /*
972                if( ! glh_init_extensions("GL_NV_register_combiners2"))
973                {
974                        errors.set("unable to initialize GL_NV_register_combiners2\n");
975                        return false;
976                }
977                else
978                {
979        */
980                        rc2init = true;
981            /*
982                }
983        */
984        }
985       
986        static bool tsinit = 0;
987        if (tsinit == false )
988        {
989      /*
990                if(! glh_init_extensions( "GL_NV_texture_shader " "GL_ARB_multitexture " ))
991                {
992                        errors.set("unable to initialize GL_NV_texture_shader\n");
993                        return false;
994                }
995                else
996                {
997        */
998                        tsinit = true;
999            /*
1000                }
1001        */
1002        }
1003        constToStageAndConstMap.clear();
1004        constToStageArray.clear();
1005        stageToConstMap.clear();
1006        line_number = 1;
1007        return true;
1008}
1009
1010const int* ps10_get_info(int* pcount)
1011{
1012        if (pcount)
1013                *pcount = constToStageArray.size();
1014        return &(constToStageArray[0]);
1015}
Note: See TracBrowser for help on using the repository browser.