struct ati_fragment_shader was not defined anywhere, define it to get r300_vertexprog...
[profile/ivi/mesa.git] / src / mesa / drivers / dri / r300 / r300_vertexprog.c
1 #include "glheader.h"
2 #include "macros.h"
3 #include "enums.h"
4
5 #include "program.h"
6 #include "r300_context.h"
7 #include "nvvertprog.h"
8
9 #define SCALAR_FLAG (1<<31)
10 #define FLAG_MASK (1<<31)
11 #define OPN(operator, ip, op) {#operator, VP_OPCODE_##operator, ip, op}
12
13 #warning "This is just a hack to get everything to compile"
14 struct ati_fragment_shader {};
15
16 struct{
17         char *name;
18         int opcode;
19         unsigned long ip; /* number of input operands and flags */
20         unsigned long op;
21 }op_names[]={
22         OPN(ABS, 1, 1),
23         OPN(ADD, 2, 1),
24         OPN(ARL, 1, 1|SCALAR_FLAG),
25         OPN(DP3, 2, 3|SCALAR_FLAG),
26         OPN(DP4, 2, 3|SCALAR_FLAG),
27         OPN(DPH, 2, 3|SCALAR_FLAG),
28         OPN(DST, 2, 1),
29         OPN(EX2, 1|SCALAR_FLAG, 4|SCALAR_FLAG),
30         OPN(EXP, 1|SCALAR_FLAG, 1),
31         OPN(FLR, 1, 1),
32         OPN(FRC, 1, 1),
33         OPN(LG2, 1|SCALAR_FLAG, 4|SCALAR_FLAG),
34         OPN(LIT, 1, 1),
35         OPN(LOG, 1|SCALAR_FLAG, 1),
36         OPN(MAD, 3, 1),
37         OPN(MAX, 2, 1),
38         OPN(MIN, 2, 1),
39         OPN(MOV, 1, 1),
40         OPN(MUL, 2, 1),
41         OPN(POW, 2|SCALAR_FLAG, 4|SCALAR_FLAG),
42         OPN(RCP, 1|SCALAR_FLAG, 4|SCALAR_FLAG),
43         OPN(RSQ, 1|SCALAR_FLAG, 4|SCALAR_FLAG),
44         OPN(SGE, 2, 1),
45         OPN(SLT, 2, 1),
46         OPN(SUB, 2, 1),
47         OPN(SWZ, 1, 1),
48         OPN(XPD, 2, 1),
49         OPN(RCC, 0, 0), //extra
50         OPN(PRINT, 0, 0),
51         OPN(END, 0, 0),
52 };
53 #undef OPN
54 #define OPN(rf) {#rf, PROGRAM_##rf}
55
56 struct{
57         char *name;
58         int id;
59 }register_file_names[]={
60         OPN(TEMPORARY),
61         OPN(INPUT),
62         OPN(OUTPUT),
63         OPN(LOCAL_PARAM),
64         OPN(ENV_PARAM),
65         OPN(NAMED_PARAM),
66         OPN(STATE_VAR),
67         OPN(WRITE_ONLY),
68         OPN(ADDRESS),
69 };
70         
71 char *dst_mask_names[4]={ "X", "Y", "Z", "W" };
72
73 /* from vertex program spec:
74       Instruction    Inputs  Output   Description
75       -----------    ------  ------   --------------------------------
76       ABS            v       v        absolute value
77       ADD            v,v     v        add
78       ARL            v       a        address register load
79       DP3            v,v     ssss     3-component dot product
80       DP4            v,v     ssss     4-component dot product
81       DPH            v,v     ssss     homogeneous dot product
82       DST            v,v     v        distance vector
83       EX2            s       ssss     exponential base 2
84       EXP            s       v        exponential base 2 (approximate)
85       FLR            v       v        floor
86       FRC            v       v        fraction
87       LG2            s       ssss     logarithm base 2
88       LIT            v       v        compute light coefficients
89       LOG            s       v        logarithm base 2 (approximate)
90       MAD            v,v,v   v        multiply and add
91       MAX            v,v     v        maximum
92       MIN            v,v     v        minimum
93       MOV            v       v        move
94       MUL            v,v     v        multiply
95       POW            s,s     ssss     exponentiate
96       RCP            s       ssss     reciprocal
97       RSQ            s       ssss     reciprocal square root
98       SGE            v,v     v        set on greater than or equal
99       SLT            v,v     v        set on less than
100       SUB            v,v     v        subtract
101       SWZ            v       v        extended swizzle
102       XPD            v,v     v        cross product
103 */
104
105 void dump_program_params(struct vertex_program *vp)
106 {
107         int i;
108         int pi;
109
110         fprintf(stderr, "NumInstructions=%d\n", vp->Base.NumInstructions);
111         fprintf(stderr, "NumTemporaries=%d\n", vp->Base.NumTemporaries);
112         fprintf(stderr, "NumParameters=%d\n", vp->Base.NumParameters);
113         fprintf(stderr, "NumAttributes=%d\n", vp->Base.NumAttributes);
114         fprintf(stderr, "NumAddressRegs=%d\n", vp->Base.NumAddressRegs);
115         
116 #if 0   
117         for(pi=0; pi < vp->Base.NumParameters; pi++){
118                 fprintf(stderr, "{ ");
119                 for(i=0; i < 4; i++)
120                         fprintf(stderr, "%f ", vp->Base.LocalParams[pi][i]);
121                 fprintf(stderr, "}\n");
122         }
123 #endif  
124         for(pi=0; pi < vp->Parameters->NumParameters; pi++){
125                 fprintf(stderr, "param %02d:", pi);
126                 
127                 switch(vp->Parameters->Parameters[pi].Type){
128                         
129                 case NAMED_PARAMETER:
130                         fprintf(stderr, "%s", vp->Parameters->Parameters[pi].Name);
131                         fprintf(stderr, "(NAMED_PARAMETER)");
132                 break;
133                 
134                 case CONSTANT:
135                         fprintf(stderr, "(CONSTANT)");
136                 break;
137                 
138                 case STATE:
139                         fprintf(stderr, "(STATE)\n");
140                         /* fetch state info */
141                         continue;
142                 break;
143
144                 }
145                 
146                 fprintf(stderr, "{ ");
147                 for(i=0; i < 4; i++)
148                         fprintf(stderr, "%f ", vp->Parameters->Parameters[pi].Values[i]);
149                 fprintf(stderr, "}\n");
150                 
151         }
152 }
153
154 static void debug_vp(struct vertex_program *vp)
155 {
156         struct vp_instruction *vpi;
157         int i, operand_index;
158         int operator_index;
159         
160         dump_program_params(vp);
161
162         vpi=vp->Instructions;
163         
164         for(;; vpi++){
165                 if(vpi->Opcode == VP_OPCODE_END)
166                         break;
167                 
168                 for(i=0; i < sizeof(op_names) / sizeof(*op_names); i++){
169                         if(vpi->Opcode == op_names[i].opcode){
170                                 fprintf(stderr, "%s ", op_names[i].name);
171                                 break;
172                         }
173                 }
174                 operator_index=i;
175                 
176                 for(i=0; i < sizeof(register_file_names) / sizeof(*register_file_names); i++){
177                         if(vpi->DstReg.File == register_file_names[i].id){
178                                 fprintf(stderr, "%s ", register_file_names[i].name);
179                                 break;
180                         }
181                 }
182                 
183                 fprintf(stderr, "%d.", vpi->DstReg.Index);
184                 
185                 for(i=0; i < 4; i++)
186                         if(vpi->DstReg.WriteMask[i])
187                                 fprintf(stderr, "%s", dst_mask_names[i]);
188                 fprintf(stderr, " ");
189                 
190                 for(operand_index=0; operand_index < (op_names[operator_index].ip & (~FLAG_MASK));
191                         operand_index++){
192                                 
193                         if(vpi->SrcReg[operand_index].Negate)
194                                 fprintf(stderr, "-");
195                         
196                         for(i=0; i < sizeof(register_file_names) / sizeof(*register_file_names); i++){
197                                 if(vpi->SrcReg[operand_index].File == register_file_names[i].id){
198                                         fprintf(stderr, "%s ", register_file_names[i].name);
199                                         break;
200                                 }
201                         }
202                         fprintf(stderr, "%d.", vpi->SrcReg[operand_index].Index);
203                         
204                         for(i=0; i < 4; i++)
205                                 fprintf(stderr, "%s", dst_mask_names[vpi->SrcReg[operand_index].Swizzle[i]]);
206                         
207                         if(operand_index+1 < (op_names[operator_index].ip & (~FLAG_MASK)) )
208                                 fprintf(stderr, ",");
209                 }
210                 fprintf(stderr, "\n");
211         }
212         
213 }
214
215 void update_params(struct r300_vertex_program *vp)
216 {
217         int pi;
218         struct vertex_program *mesa_vp=(void *)vp;
219         
220         vp->params.length=0;
221         
222         /* Temporary solution */
223         
224         for(pi=0; pi < mesa_vp->Parameters->NumParameters; pi++){
225                 switch(mesa_vp->Parameters->Parameters[pi].Type){
226                         
227                 case NAMED_PARAMETER:
228                         //fprintf(stderr, "%s", vp->Parameters->Parameters[pi].Name);
229                 case CONSTANT:
230                         vp->params.body.f[pi*4+0]=mesa_vp->Parameters->Parameters[pi].Values[0];
231                         vp->params.body.f[pi*4+1]=mesa_vp->Parameters->Parameters[pi].Values[1];
232                         vp->params.body.f[pi*4+2]=mesa_vp->Parameters->Parameters[pi].Values[2];
233                         vp->params.body.f[pi*4+3]=mesa_vp->Parameters->Parameters[pi].Values[3];
234                         vp->params.length+=4;
235                 break;
236
237                 case STATE:
238                         fprintf(stderr, "State found! bailing out.\n");
239                         exit(0);
240                         /* fetch state info */
241                         continue;
242                 break;
243                 default: _mesa_problem(NULL, "Bad param type in %s", __FUNCTION__);
244                 }
245         
246         }
247         
248 }
249                 
250 unsigned long translate_dst_mask(GLboolean *mask)
251 {
252         unsigned long flags=0;
253         
254         if(mask[0]) flags |= VSF_FLAG_X;
255         if(mask[1]) flags |= VSF_FLAG_Y;
256         if(mask[2]) flags |= VSF_FLAG_Z;
257         if(mask[3]) flags |= VSF_FLAG_W;
258         
259         return flags;
260 }
261
262 unsigned long translate_dst_class(enum register_file file)
263 {
264         
265         switch(file){
266                 case PROGRAM_TEMPORARY:
267                         return R300_VPI_OUT_REG_CLASS_TEMPORARY;
268                 case PROGRAM_OUTPUT:
269                         return R300_VPI_OUT_REG_CLASS_RESULT;
270                 /*      
271                 case PROGRAM_INPUT:
272                 case PROGRAM_LOCAL_PARAM:
273                 case PROGRAM_ENV_PARAM:
274                 case PROGRAM_NAMED_PARAM:
275                 case PROGRAM_STATE_VAR:
276                 case PROGRAM_WRITE_ONLY:
277                 case PROGRAM_ADDRESS:
278                 */
279                 default:
280                         fprintf(stderr, "problem in %s", __FUNCTION__);
281                         exit(0);
282         }
283 }
284
285 unsigned long translate_src_class(enum register_file file)
286 {
287         
288         switch(file){
289                 case PROGRAM_TEMPORARY:
290                         return R300_VPI_IN_REG_CLASS_TEMPORARY;
291                         
292                         
293                 case PROGRAM_INPUT:
294                 case PROGRAM_LOCAL_PARAM:
295                 case PROGRAM_ENV_PARAM:
296                 case PROGRAM_NAMED_PARAM:
297                 case PROGRAM_STATE_VAR:
298                         return R300_VPI_IN_REG_CLASS_PARAMETER;
299                 /*      
300                 case PROGRAM_OUTPUT:
301                 case PROGRAM_WRITE_ONLY:
302                 case PROGRAM_ADDRESS:
303                 */
304                 default:
305                         fprintf(stderr, "problem in %s", __FUNCTION__);
306                         exit(0);
307         }
308 }
309
310 unsigned long translate_swizzle(GLubyte swizzle)
311 {
312         switch(swizzle){
313                 case 0: return VSF_IN_COMPONENT_X;
314                 case 1: return VSF_IN_COMPONENT_Y;
315                 case 2: return VSF_IN_COMPONENT_Z;
316                 case 3: return VSF_IN_COMPONENT_W;
317                 
318                 case SWIZZLE_ZERO:
319                 case SWIZZLE_ONE:
320                 default:
321                         fprintf(stderr, "problem in %s", __FUNCTION__);
322                         exit(0);
323         }
324 }
325
326 unsigned long translate_src(struct vp_src_register *src)
327 {
328         return MAKE_VSF_SOURCE(src->Index,
329                                 translate_swizzle(src->Swizzle[0]),
330                                 translate_swizzle(src->Swizzle[1]),
331                                 translate_swizzle(src->Swizzle[2]),
332                                 translate_swizzle(src->Swizzle[3]),
333                                 translate_src_class(src->File),
334                                 src->Negate ? VSF_FLAG_ALL : VSF_FLAG_NONE);
335 }
336
337 unsigned long translate_opcode(enum vp_opcode opcode)
338 {
339
340         switch(opcode){
341                 case VP_OPCODE_ADD: return R300_VPI_OUT_OP_ADD;
342                 case VP_OPCODE_DST: return R300_VPI_OUT_OP_DST;
343                 case VP_OPCODE_EX2: return R300_VPI_OUT_OP_EX2;
344                 case VP_OPCODE_EXP: return R300_VPI_OUT_OP_EXP;
345                 case VP_OPCODE_FRC: return R300_VPI_OUT_OP_FRC;
346                 case VP_OPCODE_LG2: return R300_VPI_OUT_OP_LG2;
347                 case VP_OPCODE_LIT: return R300_VPI_OUT_OP_LIT;
348                 case VP_OPCODE_LOG: return R300_VPI_OUT_OP_LOG;
349                 case VP_OPCODE_MAD: return R300_VPI_OUT_OP_MAD;
350                 case VP_OPCODE_MAX: return R300_VPI_OUT_OP_MAX;
351                 case VP_OPCODE_MIN: return R300_VPI_OUT_OP_MIN;
352                 case VP_OPCODE_MUL: return R300_VPI_OUT_OP_MUL;
353                 case VP_OPCODE_POW: return R300_VPI_OUT_OP_POW;
354                 case VP_OPCODE_RCP: return R300_VPI_OUT_OP_RCP;
355                 case VP_OPCODE_RSQ: return R300_VPI_OUT_OP_RSQ;
356                 case VP_OPCODE_SGE: return R300_VPI_OUT_OP_SGE;
357                 case VP_OPCODE_SLT: return R300_VPI_OUT_OP_SLT;
358                 /* these ops need special handling */
359                 case VP_OPCODE_ABS: 
360                 case VP_OPCODE_ARL:
361                 case VP_OPCODE_DP3:
362                 case VP_OPCODE_DP4:
363                 case VP_OPCODE_DPH:
364                 case VP_OPCODE_FLR:
365                 case VP_OPCODE_MOV:
366                 case VP_OPCODE_SUB:
367                 case VP_OPCODE_SWZ:
368                 case VP_OPCODE_XPD:
369                 case VP_OPCODE_RCC:
370                 case VP_OPCODE_PRINT:
371                 case VP_OPCODE_END:
372                         fprintf(stderr, "%s should not be called with opcode %d", __FUNCTION__, opcode);
373                 break;
374                 default: 
375                         fprintf(stderr, "%s unknown opcode %d", __FUNCTION__, opcode);
376         }
377         exit(-1);
378         return 0;
379 }
380                 
381 static void translate_program(struct r300_vertex_program *vp)
382 {
383         struct vertex_program *mesa_vp=(void *)vp;
384         struct vp_instruction *vpi;
385         int inst_index=0;
386         int operand_index, i;
387         int op_found;   
388         update_params(vp);
389         
390         vp->program.length=0;
391         
392         for(vpi=mesa_vp->Instructions; vpi->Opcode != VP_OPCODE_END; vpi++, inst_index++){
393                 switch(vpi->Opcode){
394                 case VP_OPCODE_ABS: 
395                 case VP_OPCODE_ARL:
396                 case VP_OPCODE_DP3:
397                 case VP_OPCODE_DP4:
398                 case VP_OPCODE_DPH:
399                 case VP_OPCODE_DST:
400                 case VP_OPCODE_FLR:
401                 case VP_OPCODE_MOV:
402                 case VP_OPCODE_SUB:
403                 case VP_OPCODE_SWZ:
404                 case VP_OPCODE_XPD:
405                 case VP_OPCODE_RCC:
406                 case VP_OPCODE_PRINT:
407                         fprintf(stderr, "Dont know how to handle op %d yet\n", vpi->Opcode);
408                         exit(-1);
409                 break;
410                 case VP_OPCODE_END:
411                         break;
412                 default:
413                         break;
414                 }
415                 vp->program.body.i[inst_index].op=MAKE_VSF_OP(translate_opcode(vpi->Opcode), vpi->DstReg.Index,
416                                 translate_dst_mask(vpi->DstReg.WriteMask), translate_dst_class(vpi->DstReg.File));
417                 
418                 op_found=0;
419                 for(i=0; i < sizeof(op_names) / sizeof(*op_names); i++)
420                         if(op_names[i].opcode == vpi->Opcode){
421                                 op_found=1;
422                                 break;
423                         }
424                 if(!op_found){
425                         fprintf(stderr, "op %d not found in op_names\n", vpi->Opcode);
426                         exit(-1);
427                 }
428                         
429                 switch(op_names[i].ip){
430                         case 1:
431                                 vp->program.body.i[inst_index].src1=translate_src(&vpi->SrcReg[0]);
432                                 vp->program.body.i[inst_index].src2=0;
433                                 vp->program.body.i[inst_index].src3=0;
434                         break;
435                         
436                         case 2:
437                                 vp->program.body.i[inst_index].src1=translate_src(&vpi->SrcReg[0]);
438                                 vp->program.body.i[inst_index].src2=translate_src(&vpi->SrcReg[1]);
439                                 vp->program.body.i[inst_index].src3=0;
440                         break;
441                         
442                         case 3:
443                                 vp->program.body.i[inst_index].src1=translate_src(&vpi->SrcReg[0]);
444                                 vp->program.body.i[inst_index].src2=translate_src(&vpi->SrcReg[1]);
445                                 vp->program.body.i[inst_index].src3=translate_src(&vpi->SrcReg[2]);
446                         break;
447                         
448                         default:
449                                 fprintf(stderr, "scalars and op RCC not handled yet");
450                                 exit(-1);
451                         break;
452                 }
453         }
454         vp->program.length=inst_index*4;
455
456 }
457
458 static void r300BindProgram(GLcontext *ctx, GLenum target, struct program *prog)
459 {
460         fprintf(stderr, "r300BindProgram\n");
461 }
462
463 /* Mesa doesnt seem to have prototype for this */
464 struct program *
465 _mesa_init_ati_fragment_shader( GLcontext *ctx, struct ati_fragment_shader *prog,
466                            GLenum target, GLuint id);
467
468 static struct program *r300NewProgram(GLcontext *ctx, GLenum target, GLuint id)
469 {
470         r300ContextPtr rmesa = R300_CONTEXT(ctx);
471         struct r300_vertex_program *vp;
472         struct fragment_program *fp;
473         struct ati_fragment_shader *afs;
474
475         fprintf(stderr, "r300NewProgram, target=%d, id=%d\n", target, id);
476
477         switch(target){
478                 case GL_VERTEX_PROGRAM_ARB:
479                         fprintf(stderr, "vertex prog\n");
480                         vp=CALLOC_STRUCT(r300_vertex_program);
481                 
482                 /* note that vp points to mesa_program since its first on the struct
483                 */
484                 return _mesa_init_vertex_program(ctx, &vp->mesa_program, target, id);
485                 
486                 case GL_FRAGMENT_PROGRAM_ARB:
487                         fprintf(stderr, "fragment prog\n");
488                         fp=CALLOC_STRUCT(fragment_program);
489                 return _mesa_init_fragment_program(ctx, fp, target, id);
490                 
491                 case GL_FRAGMENT_PROGRAM_NV:
492                         fprintf(stderr, "nv fragment prog\n");
493                         fp=CALLOC_STRUCT(fragment_program);
494                 return _mesa_init_fragment_program(ctx, fp, target, id);
495                 
496                 case GL_FRAGMENT_SHADER_ATI:
497                         fprintf(stderr, "ati fragment prog\n");
498                         afs=CALLOC_STRUCT(ati_fragment_shader);
499                 return _mesa_init_ati_fragment_shader(ctx, afs, target, id);
500         }
501         
502         return NULL;    
503 }
504
505
506 static void r300DeleteProgram(GLcontext *ctx, struct program *prog)
507 {
508         fprintf(stderr, "r300DeleteProgram\n");
509         
510         /* check that not active */
511         _mesa_delete_program(ctx, prog);
512 }
513      
514 static GLboolean r300IsProgramNative(GLcontext *ctx, GLenum target,
515                                 struct program *prog);
516
517 static void r300ProgramStringNotify(GLcontext *ctx, GLenum target, 
518                                 struct program *prog)
519 {
520         struct r300_vertex_program *vp=(void *)prog;
521         
522         fprintf(stderr, "r300ProgramStringNotify\n");
523         /* XXX: There is still something wrong as mesa doesnt call r300IsProgramNative at all */
524         (void)r300IsProgramNative(ctx, target, prog);
525
526         switch(target) {
527         case GL_VERTEX_PROGRAM_ARB:
528                 vp->translated=GL_FALSE;
529                 break;
530         }
531         
532 }
533
534 static GLboolean r300IsProgramNative(GLcontext *ctx, GLenum target,
535                                 struct program *prog)
536 {
537         
538         fprintf(stderr, "r300IsProgramNative\n");
539         //exit(0);
540         debug_vp((struct vertex_program *)prog);
541         
542         return 1;
543 }
544
545 /* This is misnamed and shouldnt be here since fragment programs use these functions too */             
546 void r300InitVertexProgFuncs(struct dd_function_table *functions)
547 {
548 #if 1
549         functions->NewProgram=r300NewProgram;
550         functions->BindProgram=r300BindProgram;
551         functions->DeleteProgram=r300DeleteProgram;
552         functions->ProgramStringNotify=r300ProgramStringNotify;
553         functions->IsProgramNative=r300IsProgramNative;
554 #endif  
555 }