glsl2: Add pass for supporting variable vector indexing in rvalues.
[mesa.git] / src / mesa / shader / ir_to_mesa.cpp
1 /*
2 * Copyright (C) 2005-2007 Brian Paul All Rights Reserved.
3 * Copyright (C) 2008 VMware, Inc. All Rights Reserved.
4 * Copyright © 2010 Intel Corporation
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice (including the next
14 * paragraph) shall be included in all copies or substantial portions of the
15 * Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23 * DEALINGS IN THE SOFTWARE.
24 */
25
26 /**
27 * \file ir_to_mesa.cpp
28 *
29 * Translates the IR to ARB_fragment_program text if possible,
30 * printing the result
31 */
32
33 #include <stdio.h>
34 #include "ir.h"
35 #include "ir_visitor.h"
36 #include "ir_print_visitor.h"
37 #include "ir_expression_flattening.h"
38 #include "glsl_types.h"
39 #include "glsl_parser_extras.h"
40 #include "../glsl/program.h"
41 #include "ir_optimization.h"
42 #include "ast.h"
43
44 extern "C" {
45 #include "main/mtypes.h"
46 #include "shader/prog_instruction.h"
47 #include "shader/prog_optimize.h"
48 #include "shader/prog_print.h"
49 #include "shader/program.h"
50 #include "shader/prog_uniform.h"
51 #include "shader/prog_parameter.h"
52 #include "shader/shader_api.h"
53 }
54
55 /**
56 * This struct is a corresponding struct to Mesa prog_src_register, with
57 * wider fields.
58 */
59 typedef struct ir_to_mesa_src_reg {
60 int file; /**< PROGRAM_* from Mesa */
61 int index; /**< temporary index, VERT_ATTRIB_*, FRAG_ATTRIB_*, etc. */
62 GLuint swizzle; /**< SWIZZLE_XYZWONEZERO swizzles from Mesa. */
63 int negate; /**< NEGATE_XYZW mask from mesa */
64 bool reladdr; /**< Register index should be offset by address reg. */
65 } ir_to_mesa_src_reg;
66
67 typedef struct ir_to_mesa_dst_reg {
68 int file; /**< PROGRAM_* from Mesa */
69 int index; /**< temporary index, VERT_ATTRIB_*, FRAG_ATTRIB_*, etc. */
70 int writemask; /**< Bitfield of WRITEMASK_[XYZW] */
71 GLuint cond_mask:4;
72 } ir_to_mesa_dst_reg;
73
74 extern ir_to_mesa_src_reg ir_to_mesa_undef;
75
76 class ir_to_mesa_instruction : public exec_node {
77 public:
78 enum prog_opcode op;
79 ir_to_mesa_dst_reg dst_reg;
80 ir_to_mesa_src_reg src_reg[3];
81 /** Pointer to the ir source this tree came from for debugging */
82 ir_instruction *ir;
83 GLboolean cond_update;
84 int sampler; /**< sampler index */
85 int tex_target; /**< One of TEXTURE_*_INDEX */
86 GLboolean tex_shadow;
87 };
88
89 class temp_entry : public exec_node {
90 public:
91 temp_entry(ir_variable *var, int file, int index)
92 : file(file), index(index), var(var)
93 {
94 /* empty */
95 }
96
97 int file;
98 int index;
99 ir_variable *var; /* variable that maps to this, if any */
100 };
101
102 class ir_to_mesa_visitor : public ir_visitor {
103 public:
104 ir_to_mesa_visitor();
105
106 GLcontext *ctx;
107 struct gl_program *prog;
108
109 int next_temp;
110
111 temp_entry *find_variable_storage(ir_variable *var);
112
113 ir_to_mesa_src_reg get_temp(const glsl_type *type);
114
115 struct ir_to_mesa_src_reg src_reg_for_float(float val);
116
117 /**
118 * \name Visit methods
119 *
120 * As typical for the visitor pattern, there must be one \c visit method for
121 * each concrete subclass of \c ir_instruction. Virtual base classes within
122 * the hierarchy should not have \c visit methods.
123 */
124 /*@{*/
125 virtual void visit(ir_variable *);
126 virtual void visit(ir_loop *);
127 virtual void visit(ir_loop_jump *);
128 virtual void visit(ir_function_signature *);
129 virtual void visit(ir_function *);
130 virtual void visit(ir_expression *);
131 virtual void visit(ir_swizzle *);
132 virtual void visit(ir_dereference_variable *);
133 virtual void visit(ir_dereference_array *);
134 virtual void visit(ir_dereference_record *);
135 virtual void visit(ir_assignment *);
136 virtual void visit(ir_constant *);
137 virtual void visit(ir_call *);
138 virtual void visit(ir_return *);
139 virtual void visit(ir_discard *);
140 virtual void visit(ir_texture *);
141 virtual void visit(ir_if *);
142 /*@}*/
143
144 struct ir_to_mesa_src_reg result;
145
146 /** List of temp_entry */
147 exec_list variable_storage;
148
149 /** List of ir_to_mesa_instruction */
150 exec_list instructions;
151
152 ir_to_mesa_instruction *ir_to_mesa_emit_op1(ir_instruction *ir,
153 enum prog_opcode op,
154 ir_to_mesa_dst_reg dst,
155 ir_to_mesa_src_reg src0);
156
157 ir_to_mesa_instruction *ir_to_mesa_emit_op2(ir_instruction *ir,
158 enum prog_opcode op,
159 ir_to_mesa_dst_reg dst,
160 ir_to_mesa_src_reg src0,
161 ir_to_mesa_src_reg src1);
162
163 ir_to_mesa_instruction *ir_to_mesa_emit_op3(ir_instruction *ir,
164 enum prog_opcode op,
165 ir_to_mesa_dst_reg dst,
166 ir_to_mesa_src_reg src0,
167 ir_to_mesa_src_reg src1,
168 ir_to_mesa_src_reg src2);
169
170 void ir_to_mesa_emit_scalar_op1(ir_instruction *ir,
171 enum prog_opcode op,
172 ir_to_mesa_dst_reg dst,
173 ir_to_mesa_src_reg src0);
174
175 void ir_to_mesa_emit_scalar_op2(ir_instruction *ir,
176 enum prog_opcode op,
177 ir_to_mesa_dst_reg dst,
178 ir_to_mesa_src_reg src0,
179 ir_to_mesa_src_reg src1);
180
181 int *sampler_map;
182 int sampler_map_size;
183
184 void map_sampler(int location, int sampler);
185 int get_sampler_number(int location);
186
187 void *mem_ctx;
188 };
189
190 ir_to_mesa_src_reg ir_to_mesa_undef = {
191 PROGRAM_UNDEFINED, 0, SWIZZLE_NOOP, NEGATE_NONE, false,
192 };
193
194 ir_to_mesa_dst_reg ir_to_mesa_undef_dst = {
195 PROGRAM_UNDEFINED, 0, SWIZZLE_NOOP
196 };
197
198 ir_to_mesa_dst_reg ir_to_mesa_address_reg = {
199 PROGRAM_ADDRESS, 0, WRITEMASK_X
200 };
201
202 static int swizzle_for_size(int size)
203 {
204 int size_swizzles[4] = {
205 MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X),
206 MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y),
207 MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_Z),
208 MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W),
209 };
210
211 return size_swizzles[size - 1];
212 }
213
214 ir_to_mesa_instruction *
215 ir_to_mesa_visitor::ir_to_mesa_emit_op3(ir_instruction *ir,
216 enum prog_opcode op,
217 ir_to_mesa_dst_reg dst,
218 ir_to_mesa_src_reg src0,
219 ir_to_mesa_src_reg src1,
220 ir_to_mesa_src_reg src2)
221 {
222 ir_to_mesa_instruction *inst = new(mem_ctx) ir_to_mesa_instruction();
223
224 inst->op = op;
225 inst->dst_reg = dst;
226 inst->src_reg[0] = src0;
227 inst->src_reg[1] = src1;
228 inst->src_reg[2] = src2;
229 inst->ir = ir;
230
231 this->instructions.push_tail(inst);
232
233 return inst;
234 }
235
236
237 ir_to_mesa_instruction *
238 ir_to_mesa_visitor::ir_to_mesa_emit_op2(ir_instruction *ir,
239 enum prog_opcode op,
240 ir_to_mesa_dst_reg dst,
241 ir_to_mesa_src_reg src0,
242 ir_to_mesa_src_reg src1)
243 {
244 return ir_to_mesa_emit_op3(ir, op, dst, src0, src1, ir_to_mesa_undef);
245 }
246
247 ir_to_mesa_instruction *
248 ir_to_mesa_visitor::ir_to_mesa_emit_op1(ir_instruction *ir,
249 enum prog_opcode op,
250 ir_to_mesa_dst_reg dst,
251 ir_to_mesa_src_reg src0)
252 {
253 return ir_to_mesa_emit_op3(ir, op, dst,
254 src0, ir_to_mesa_undef, ir_to_mesa_undef);
255 }
256
257 void
258 ir_to_mesa_visitor::map_sampler(int location, int sampler)
259 {
260 if (this->sampler_map_size <= location) {
261 this->sampler_map = talloc_realloc(this->mem_ctx, this->sampler_map,
262 int, location + 1);
263 this->sampler_map_size = location + 1;
264 }
265
266 this->sampler_map[location] = sampler;
267 }
268
269 int
270 ir_to_mesa_visitor::get_sampler_number(int location)
271 {
272 assert(location < this->sampler_map_size);
273 return this->sampler_map[location];
274 }
275
276 inline ir_to_mesa_dst_reg
277 ir_to_mesa_dst_reg_from_src(ir_to_mesa_src_reg reg)
278 {
279 ir_to_mesa_dst_reg dst_reg;
280
281 dst_reg.file = reg.file;
282 dst_reg.index = reg.index;
283 dst_reg.writemask = WRITEMASK_XYZW;
284 dst_reg.cond_mask = COND_TR;
285
286 return dst_reg;
287 }
288
289 inline ir_to_mesa_src_reg
290 ir_to_mesa_src_reg_from_dst(ir_to_mesa_dst_reg reg)
291 {
292 ir_to_mesa_src_reg src_reg;
293
294 src_reg.file = reg.file;
295 src_reg.index = reg.index;
296 src_reg.swizzle = SWIZZLE_XYZW;
297 src_reg.negate = 0;
298 src_reg.reladdr = 0;
299
300 return src_reg;
301 }
302
303 /**
304 * Emits Mesa scalar opcodes to produce unique answers across channels.
305 *
306 * Some Mesa opcodes are scalar-only, like ARB_fp/vp. The src X
307 * channel determines the result across all channels. So to do a vec4
308 * of this operation, we want to emit a scalar per source channel used
309 * to produce dest channels.
310 */
311 void
312 ir_to_mesa_visitor::ir_to_mesa_emit_scalar_op2(ir_instruction *ir,
313 enum prog_opcode op,
314 ir_to_mesa_dst_reg dst,
315 ir_to_mesa_src_reg orig_src0,
316 ir_to_mesa_src_reg orig_src1)
317 {
318 int i, j;
319 int done_mask = ~dst.writemask;
320
321 /* Mesa RCP is a scalar operation splatting results to all channels,
322 * like ARB_fp/vp. So emit as many RCPs as necessary to cover our
323 * dst channels.
324 */
325 for (i = 0; i < 4; i++) {
326 GLuint this_mask = (1 << i);
327 ir_to_mesa_instruction *inst;
328 ir_to_mesa_src_reg src0 = orig_src0;
329 ir_to_mesa_src_reg src1 = orig_src1;
330
331 if (done_mask & this_mask)
332 continue;
333
334 GLuint src0_swiz = GET_SWZ(src0.swizzle, i);
335 GLuint src1_swiz = GET_SWZ(src1.swizzle, i);
336 for (j = i + 1; j < 4; j++) {
337 if (!(done_mask & (1 << j)) &&
338 GET_SWZ(src0.swizzle, j) == src0_swiz &&
339 GET_SWZ(src1.swizzle, j) == src1_swiz) {
340 this_mask |= (1 << j);
341 }
342 }
343 src0.swizzle = MAKE_SWIZZLE4(src0_swiz, src0_swiz,
344 src0_swiz, src0_swiz);
345 src1.swizzle = MAKE_SWIZZLE4(src1_swiz, src1_swiz,
346 src1_swiz, src1_swiz);
347
348 inst = ir_to_mesa_emit_op2(ir, op,
349 dst,
350 src0,
351 src1);
352 inst->dst_reg.writemask = this_mask;
353 done_mask |= this_mask;
354 }
355 }
356
357 void
358 ir_to_mesa_visitor::ir_to_mesa_emit_scalar_op1(ir_instruction *ir,
359 enum prog_opcode op,
360 ir_to_mesa_dst_reg dst,
361 ir_to_mesa_src_reg src0)
362 {
363 ir_to_mesa_src_reg undef = ir_to_mesa_undef;
364
365 undef.swizzle = SWIZZLE_XXXX;
366
367 ir_to_mesa_emit_scalar_op2(ir, op, dst, src0, undef);
368 }
369
370 struct ir_to_mesa_src_reg
371 ir_to_mesa_visitor::src_reg_for_float(float val)
372 {
373 ir_to_mesa_src_reg src_reg;
374
375 src_reg.file = PROGRAM_CONSTANT;
376 src_reg.index = _mesa_add_unnamed_constant(this->prog->Parameters,
377 &val, 1, &src_reg.swizzle);
378
379 return src_reg;
380 }
381
382 static int
383 type_size(const struct glsl_type *type)
384 {
385 unsigned int i;
386 int size;
387
388 switch (type->base_type) {
389 case GLSL_TYPE_UINT:
390 case GLSL_TYPE_INT:
391 case GLSL_TYPE_FLOAT:
392 case GLSL_TYPE_BOOL:
393 if (type->is_matrix()) {
394 return 4; /* FINISHME: Not all matrices are 4x4. */
395 } else {
396 /* Regardless of size of vector, it gets a vec4. This is bad
397 * packing for things like floats, but otherwise arrays become a
398 * mess. Hopefully a later pass over the code can pack scalars
399 * down if appropriate.
400 */
401 return 1;
402 }
403 case GLSL_TYPE_ARRAY:
404 return type_size(type->fields.array) * type->length;
405 case GLSL_TYPE_STRUCT:
406 size = 0;
407 for (i = 0; i < type->length; i++) {
408 size += type_size(type->fields.structure[i].type);
409 }
410 return size;
411 default:
412 assert(0);
413 }
414 }
415
416 /**
417 * In the initial pass of codegen, we assign temporary numbers to
418 * intermediate results. (not SSA -- variable assignments will reuse
419 * storage). Actual register allocation for the Mesa VM occurs in a
420 * pass over the Mesa IR later.
421 */
422 ir_to_mesa_src_reg
423 ir_to_mesa_visitor::get_temp(const glsl_type *type)
424 {
425 ir_to_mesa_src_reg src_reg;
426 int swizzle[4];
427 int i;
428
429 assert(!type->is_array());
430
431 src_reg.file = PROGRAM_TEMPORARY;
432 src_reg.index = next_temp;
433 src_reg.reladdr = false;
434 next_temp += type_size(type);
435
436 for (i = 0; i < type->vector_elements; i++)
437 swizzle[i] = i;
438 for (; i < 4; i++)
439 swizzle[i] = type->vector_elements - 1;
440 src_reg.swizzle = MAKE_SWIZZLE4(swizzle[0], swizzle[1],
441 swizzle[2], swizzle[3]);
442 src_reg.negate = 0;
443
444 return src_reg;
445 }
446
447 temp_entry *
448 ir_to_mesa_visitor::find_variable_storage(ir_variable *var)
449 {
450
451 temp_entry *entry;
452
453 foreach_iter(exec_list_iterator, iter, this->variable_storage) {
454 entry = (temp_entry *)iter.get();
455
456 if (entry->var == var)
457 return entry;
458 }
459
460 return NULL;
461 }
462
463 void
464 ir_to_mesa_visitor::visit(ir_variable *ir)
465 {
466 (void)ir;
467 }
468
469 void
470 ir_to_mesa_visitor::visit(ir_loop *ir)
471 {
472 assert(!ir->from);
473 assert(!ir->to);
474 assert(!ir->increment);
475 assert(!ir->counter);
476
477 ir_to_mesa_emit_op1(NULL, OPCODE_BGNLOOP,
478 ir_to_mesa_undef_dst, ir_to_mesa_undef);
479
480 visit_exec_list(&ir->body_instructions, this);
481
482 ir_to_mesa_emit_op1(NULL, OPCODE_ENDLOOP,
483 ir_to_mesa_undef_dst, ir_to_mesa_undef);
484 }
485
486 void
487 ir_to_mesa_visitor::visit(ir_loop_jump *ir)
488 {
489 switch (ir->mode) {
490 case ir_loop_jump::jump_break:
491 ir_to_mesa_emit_op1(NULL, OPCODE_BRK,
492 ir_to_mesa_undef_dst, ir_to_mesa_undef);
493 break;
494 case ir_loop_jump::jump_continue:
495 ir_to_mesa_emit_op1(NULL, OPCODE_CONT,
496 ir_to_mesa_undef_dst, ir_to_mesa_undef);
497 break;
498 }
499 }
500
501
502 void
503 ir_to_mesa_visitor::visit(ir_function_signature *ir)
504 {
505 assert(0);
506 (void)ir;
507 }
508
509 void
510 ir_to_mesa_visitor::visit(ir_function *ir)
511 {
512 /* Ignore function bodies other than main() -- we shouldn't see calls to
513 * them since they should all be inlined before we get to ir_to_mesa.
514 */
515 if (strcmp(ir->name, "main") == 0) {
516 const ir_function_signature *sig;
517 exec_list empty;
518
519 sig = ir->matching_signature(&empty);
520
521 assert(sig);
522
523 foreach_iter(exec_list_iterator, iter, sig->body) {
524 ir_instruction *ir = (ir_instruction *)iter.get();
525
526 ir->accept(this);
527 }
528 }
529 }
530
531 void
532 ir_to_mesa_visitor::visit(ir_expression *ir)
533 {
534 unsigned int operand;
535 struct ir_to_mesa_src_reg op[2];
536 struct ir_to_mesa_src_reg result_src;
537 struct ir_to_mesa_dst_reg result_dst;
538 const glsl_type *vec4_type = glsl_type::get_instance(GLSL_TYPE_FLOAT, 4, 1);
539 const glsl_type *vec3_type = glsl_type::get_instance(GLSL_TYPE_FLOAT, 3, 1);
540 const glsl_type *vec2_type = glsl_type::get_instance(GLSL_TYPE_FLOAT, 2, 1);
541
542 for (operand = 0; operand < ir->get_num_operands(); operand++) {
543 this->result.file = PROGRAM_UNDEFINED;
544 ir->operands[operand]->accept(this);
545 if (this->result.file == PROGRAM_UNDEFINED) {
546 ir_print_visitor v;
547 printf("Failed to get tree for expression operand:\n");
548 ir->operands[operand]->accept(&v);
549 exit(1);
550 }
551 op[operand] = this->result;
552
553 /* Only expression implemented for matrices yet */
554 assert(!ir->operands[operand]->type->is_matrix() ||
555 ir->operation == ir_binop_mul);
556 }
557
558 this->result.file = PROGRAM_UNDEFINED;
559
560 /* Storage for our result. Ideally for an assignment we'd be using
561 * the actual storage for the result here, instead.
562 */
563 result_src = get_temp(ir->type);
564 /* convenience for the emit functions below. */
565 result_dst = ir_to_mesa_dst_reg_from_src(result_src);
566 /* Limit writes to the channels that will be used by result_src later.
567 * This does limit this temp's use as a temporary for multi-instruction
568 * sequences.
569 */
570 result_dst.writemask = (1 << ir->type->vector_elements) - 1;
571
572 switch (ir->operation) {
573 case ir_unop_logic_not:
574 ir_to_mesa_emit_op2(ir, OPCODE_SEQ, result_dst,
575 op[0], src_reg_for_float(0.0));
576 break;
577 case ir_unop_neg:
578 op[0].negate = ~op[0].negate;
579 result_src = op[0];
580 break;
581 case ir_unop_abs:
582 ir_to_mesa_emit_op1(ir, OPCODE_ABS, result_dst, op[0]);
583 break;
584 case ir_unop_sign:
585 ir_to_mesa_emit_op1(ir, OPCODE_SSG, result_dst, op[0]);
586 break;
587 case ir_unop_rcp:
588 ir_to_mesa_emit_scalar_op1(ir, OPCODE_RCP, result_dst, op[0]);
589 break;
590
591 case ir_unop_exp:
592 ir_to_mesa_emit_scalar_op2(ir, OPCODE_POW, result_dst,
593 src_reg_for_float(M_E), op[0]);
594 break;
595 case ir_unop_exp2:
596 ir_to_mesa_emit_scalar_op1(ir, OPCODE_EX2, result_dst, op[0]);
597 break;
598 case ir_unop_log:
599 ir_to_mesa_emit_scalar_op1(ir, OPCODE_LOG, result_dst, op[0]);
600 break;
601 case ir_unop_log2:
602 ir_to_mesa_emit_scalar_op1(ir, OPCODE_LG2, result_dst, op[0]);
603 break;
604 case ir_unop_sin:
605 ir_to_mesa_emit_scalar_op1(ir, OPCODE_SIN, result_dst, op[0]);
606 break;
607 case ir_unop_cos:
608 ir_to_mesa_emit_scalar_op1(ir, OPCODE_COS, result_dst, op[0]);
609 break;
610
611 case ir_unop_dFdx:
612 ir_to_mesa_emit_op1(ir, OPCODE_DDX, result_dst, op[0]);
613 break;
614 case ir_unop_dFdy:
615 ir_to_mesa_emit_op1(ir, OPCODE_DDY, result_dst, op[0]);
616 break;
617
618 case ir_binop_add:
619 ir_to_mesa_emit_op2(ir, OPCODE_ADD, result_dst, op[0], op[1]);
620 break;
621 case ir_binop_sub:
622 ir_to_mesa_emit_op2(ir, OPCODE_SUB, result_dst, op[0], op[1]);
623 break;
624 case ir_binop_mul:
625 if (ir->operands[0]->type->is_matrix() &&
626 !ir->operands[1]->type->is_matrix()) {
627 if (ir->operands[1]->type->is_scalar()) {
628 ir_to_mesa_dst_reg dst_column = result_dst;
629 ir_to_mesa_src_reg src_column = op[0];
630 for (int i = 0; i < ir->operands[0]->type->matrix_columns; i++) {
631 ir_to_mesa_emit_op2(ir, OPCODE_MUL,
632 dst_column, src_column, op[1]);
633 dst_column.index++;
634 src_column.index++;
635 }
636 } else {
637 ir_to_mesa_src_reg src_column = op[0];
638 ir_to_mesa_src_reg src_chan = op[1];
639 assert(!ir->operands[1]->type->is_matrix() ||
640 !"FINISHME: matrix * matrix");
641 for (int i = 0; i < ir->operands[0]->type->matrix_columns; i++) {
642 src_chan.swizzle = MAKE_SWIZZLE4(i, i, i, i);
643 if (i == 0) {
644 ir_to_mesa_emit_op2(ir, OPCODE_MUL,
645 result_dst, src_column, src_chan);
646 } else {
647 ir_to_mesa_emit_op3(ir, OPCODE_MAD,
648 result_dst, src_column, src_chan,
649 result_src);
650 }
651 src_column.index++;
652 }
653 }
654 } else if (ir->operands[1]->type->is_matrix()) {
655 if (ir->operands[0]->type->is_scalar()) {
656 ir_to_mesa_dst_reg dst_column = result_dst;
657 ir_to_mesa_src_reg src_column = op[1];
658 for (int i = 0; i < ir->operands[1]->type->matrix_columns; i++) {
659 ir_to_mesa_emit_op2(ir, OPCODE_MUL,
660 dst_column, src_column, op[0]);
661 dst_column.index++;
662 src_column.index++;
663 }
664 } else {
665 ir_to_mesa_src_reg src_column = op[1];
666 ir_to_mesa_dst_reg dst_chan = result_dst;
667
668 /* FINISHME here and above: non-square matrices */
669 assert(ir->operands[1]->type->vector_elements ==
670 ir->operands[1]->type->matrix_columns);
671
672 for (int i = 0; i < ir->operands[0]->type->vector_elements; i++) {
673 dst_chan.writemask = (1 << i);
674 switch (ir->operands[0]->type->vector_elements) {
675 case 2:
676 ir_to_mesa_emit_op2(ir, OPCODE_DP2, dst_chan, op[0], src_column);
677 break;
678 case 3:
679 ir_to_mesa_emit_op2(ir, OPCODE_DP3, dst_chan, op[0], src_column);
680 break;
681 case 4:
682 ir_to_mesa_emit_op2(ir, OPCODE_DP4, dst_chan, op[0], src_column);
683 break;
684 default:
685 assert(0);
686 }
687 src_column.index++;
688 }
689 }
690 } else {
691 assert(!ir->operands[0]->type->is_matrix());
692 assert(!ir->operands[1]->type->is_matrix());
693 ir_to_mesa_emit_op2(ir, OPCODE_MUL, result_dst, op[0], op[1]);
694 }
695 break;
696 case ir_binop_div:
697 assert(!"not reached: should be handled by ir_div_to_mul_rcp");
698 case ir_binop_mod:
699 assert(!"ir_binop_mod should have been converted to b * fract(a/b)");
700 break;
701
702 case ir_binop_less:
703 ir_to_mesa_emit_op2(ir, OPCODE_SLT, result_dst, op[0], op[1]);
704 break;
705 case ir_binop_greater:
706 ir_to_mesa_emit_op2(ir, OPCODE_SGT, result_dst, op[0], op[1]);
707 break;
708 case ir_binop_lequal:
709 ir_to_mesa_emit_op2(ir, OPCODE_SLE, result_dst, op[0], op[1]);
710 break;
711 case ir_binop_gequal:
712 ir_to_mesa_emit_op2(ir, OPCODE_SGE, result_dst, op[0], op[1]);
713 break;
714 case ir_binop_equal:
715 ir_to_mesa_emit_op2(ir, OPCODE_SEQ, result_dst, op[0], op[1]);
716 break;
717 case ir_binop_logic_xor:
718 case ir_binop_nequal:
719 ir_to_mesa_emit_op2(ir, OPCODE_SNE, result_dst, op[0], op[1]);
720 break;
721
722 case ir_binop_logic_or:
723 /* This could be a saturated add and skip the SNE. */
724 ir_to_mesa_emit_op2(ir, OPCODE_ADD,
725 result_dst,
726 op[0], op[1]);
727
728 ir_to_mesa_emit_op2(ir, OPCODE_SNE,
729 result_dst,
730 result_src, src_reg_for_float(0.0));
731 break;
732
733 case ir_binop_logic_and:
734 /* the bool args are stored as float 0.0 or 1.0, so "mul" gives us "and". */
735 ir_to_mesa_emit_op2(ir, OPCODE_MUL,
736 result_dst,
737 op[0], op[1]);
738 break;
739
740 case ir_binop_dot:
741 if (ir->operands[0]->type == vec4_type) {
742 assert(ir->operands[1]->type == vec4_type);
743 ir_to_mesa_emit_op2(ir, OPCODE_DP4,
744 result_dst,
745 op[0], op[1]);
746 } else if (ir->operands[0]->type == vec3_type) {
747 assert(ir->operands[1]->type == vec3_type);
748 ir_to_mesa_emit_op2(ir, OPCODE_DP3,
749 result_dst,
750 op[0], op[1]);
751 } else if (ir->operands[0]->type == vec2_type) {
752 assert(ir->operands[1]->type == vec2_type);
753 ir_to_mesa_emit_op2(ir, OPCODE_DP2,
754 result_dst,
755 op[0], op[1]);
756 }
757 break;
758 case ir_unop_sqrt:
759 ir_to_mesa_emit_scalar_op1(ir, OPCODE_RSQ, result_dst, op[0]);
760 ir_to_mesa_emit_scalar_op1(ir, OPCODE_RCP, result_dst, result_src);
761 /* For incoming channels < 0, set the result to 0. */
762 ir_to_mesa_emit_op3(ir, OPCODE_CMP, result_dst,
763 op[0], src_reg_for_float(0.0), result_src);
764 break;
765 case ir_unop_rsq:
766 ir_to_mesa_emit_scalar_op1(ir, OPCODE_RSQ, result_dst, op[0]);
767 break;
768 case ir_unop_i2f:
769 case ir_unop_b2f:
770 case ir_unop_b2i:
771 /* Mesa IR lacks types, ints are stored as truncated floats. */
772 result_src = op[0];
773 break;
774 case ir_unop_f2i:
775 ir_to_mesa_emit_op1(ir, OPCODE_TRUNC, result_dst, op[0]);
776 break;
777 case ir_unop_f2b:
778 case ir_unop_i2b:
779 ir_to_mesa_emit_op2(ir, OPCODE_SNE, result_dst,
780 result_src, src_reg_for_float(0.0));
781 break;
782 case ir_unop_trunc:
783 ir_to_mesa_emit_op1(ir, OPCODE_TRUNC, result_dst, op[0]);
784 break;
785 case ir_unop_ceil:
786 op[0].negate = ~op[0].negate;
787 ir_to_mesa_emit_op1(ir, OPCODE_FLR, result_dst, op[0]);
788 result_src.negate = ~result_src.negate;
789 break;
790 case ir_unop_floor:
791 ir_to_mesa_emit_op1(ir, OPCODE_FLR, result_dst, op[0]);
792 break;
793 case ir_unop_fract:
794 ir_to_mesa_emit_op1(ir, OPCODE_FRC, result_dst, op[0]);
795 break;
796
797 case ir_binop_min:
798 ir_to_mesa_emit_op2(ir, OPCODE_MIN, result_dst, op[0], op[1]);
799 break;
800 case ir_binop_max:
801 ir_to_mesa_emit_op2(ir, OPCODE_MAX, result_dst, op[0], op[1]);
802 break;
803 case ir_binop_pow:
804 ir_to_mesa_emit_scalar_op2(ir, OPCODE_POW, result_dst, op[0], op[1]);
805 break;
806
807 case ir_unop_bit_not:
808 case ir_unop_u2f:
809 case ir_binop_lshift:
810 case ir_binop_rshift:
811 case ir_binop_bit_and:
812 case ir_binop_bit_xor:
813 case ir_binop_bit_or:
814 assert(!"GLSL 1.30 features unsupported");
815 break;
816 }
817
818 this->result = result_src;
819 }
820
821
822 void
823 ir_to_mesa_visitor::visit(ir_swizzle *ir)
824 {
825 ir_to_mesa_src_reg src_reg;
826 int i;
827 int swizzle[4];
828
829 /* Note that this is only swizzles in expressions, not those on the left
830 * hand side of an assignment, which do write masking. See ir_assignment
831 * for that.
832 */
833
834 ir->val->accept(this);
835 src_reg = this->result;
836 assert(src_reg.file != PROGRAM_UNDEFINED);
837
838 for (i = 0; i < 4; i++) {
839 if (i < ir->type->vector_elements) {
840 switch (i) {
841 case 0:
842 swizzle[i] = GET_SWZ(src_reg.swizzle, ir->mask.x);
843 break;
844 case 1:
845 swizzle[i] = GET_SWZ(src_reg.swizzle, ir->mask.y);
846 break;
847 case 2:
848 swizzle[i] = GET_SWZ(src_reg.swizzle, ir->mask.z);
849 break;
850 case 3:
851 swizzle[i] = GET_SWZ(src_reg.swizzle, ir->mask.w);
852 break;
853 }
854 } else {
855 /* If the type is smaller than a vec4, replicate the last
856 * channel out.
857 */
858 swizzle[i] = swizzle[ir->type->vector_elements - 1];
859 }
860 }
861
862 src_reg.swizzle = MAKE_SWIZZLE4(swizzle[0],
863 swizzle[1],
864 swizzle[2],
865 swizzle[3]);
866
867 this->result = src_reg;
868 }
869
870 static temp_entry *
871 get_builtin_matrix_ref(void *mem_ctx, struct gl_program *prog, ir_variable *var)
872 {
873 /*
874 * NOTE: The ARB_vertex_program extension specified that matrices get
875 * loaded in registers in row-major order. With GLSL, we want column-
876 * major order. So, we need to transpose all matrices here...
877 */
878 static const struct {
879 const char *name;
880 int matrix;
881 int modifier;
882 } matrices[] = {
883 { "gl_ModelViewMatrix", STATE_MODELVIEW_MATRIX, STATE_MATRIX_TRANSPOSE },
884 { "gl_ModelViewMatrixInverse", STATE_MODELVIEW_MATRIX, STATE_MATRIX_INVTRANS },
885 { "gl_ModelViewMatrixTranspose", STATE_MODELVIEW_MATRIX, 0 },
886 { "gl_ModelViewMatrixInverseTranspose", STATE_MODELVIEW_MATRIX, STATE_MATRIX_INVERSE },
887
888 { "gl_ProjectionMatrix", STATE_PROJECTION_MATRIX, STATE_MATRIX_TRANSPOSE },
889 { "gl_ProjectionMatrixInverse", STATE_PROJECTION_MATRIX, STATE_MATRIX_INVTRANS },
890 { "gl_ProjectionMatrixTranspose", STATE_PROJECTION_MATRIX, 0 },
891 { "gl_ProjectionMatrixInverseTranspose", STATE_PROJECTION_MATRIX, STATE_MATRIX_INVERSE },
892
893 { "gl_ModelViewProjectionMatrix", STATE_MVP_MATRIX, STATE_MATRIX_TRANSPOSE },
894 { "gl_ModelViewProjectionMatrixInverse", STATE_MVP_MATRIX, STATE_MATRIX_INVTRANS },
895 { "gl_ModelViewProjectionMatrixTranspose", STATE_MVP_MATRIX, 0 },
896 { "gl_ModelViewProjectionMatrixInverseTranspose", STATE_MVP_MATRIX, STATE_MATRIX_INVERSE },
897
898 { "gl_TextureMatrix", STATE_TEXTURE_MATRIX, STATE_MATRIX_TRANSPOSE },
899 { "gl_TextureMatrixInverse", STATE_TEXTURE_MATRIX, STATE_MATRIX_INVTRANS },
900 { "gl_TextureMatrixTranspose", STATE_TEXTURE_MATRIX, 0 },
901 { "gl_TextureMatrixInverseTranspose", STATE_TEXTURE_MATRIX, STATE_MATRIX_INVERSE },
902
903 { "gl_NormalMatrix", STATE_MODELVIEW_MATRIX, STATE_MATRIX_INVERSE },
904
905 };
906 unsigned int i;
907 temp_entry *entry;
908
909 /* C++ gets angry when we try to use an int as a gl_state_index, so we use
910 * ints for gl_state_index. Make sure they're compatible.
911 */
912 assert(sizeof(gl_state_index) == sizeof(int));
913
914 for (i = 0; i < Elements(matrices); i++) {
915 if (strcmp(var->name, matrices[i].name) == 0) {
916 int j;
917 int last_pos = -1, base_pos = -1;
918 int tokens[STATE_LENGTH];
919
920 tokens[0] = matrices[i].matrix;
921 tokens[1] = 0; /* array index! */
922 tokens[4] = matrices[i].modifier;
923
924 /* Add a ref for each column. It looks like the reason we do
925 * it this way is that _mesa_add_state_reference doesn't work
926 * for things that aren't vec4s, so the tokens[2]/tokens[3]
927 * range has to be equal.
928 */
929 for (j = 0; j < 4; j++) {
930 tokens[2] = j;
931 tokens[3] = j;
932 int pos = _mesa_add_state_reference(prog->Parameters,
933 (gl_state_index *)tokens);
934 assert(last_pos == -1 || last_pos == base_pos + j);
935 if (base_pos == -1)
936 base_pos = pos;
937 }
938
939 entry = new(mem_ctx) temp_entry(var,
940 PROGRAM_STATE_VAR,
941 base_pos);
942
943 return entry;
944 }
945 }
946
947 return NULL;
948 }
949
950 void
951 ir_to_mesa_visitor::visit(ir_dereference_variable *ir)
952 {
953 ir_to_mesa_src_reg src_reg;
954 temp_entry *entry = find_variable_storage(ir->var);
955 unsigned int loc;
956
957 if (!entry) {
958 switch (ir->var->mode) {
959 case ir_var_uniform:
960 entry = get_builtin_matrix_ref(this->mem_ctx, this->prog, ir->var);
961 if (entry)
962 break;
963
964 /* FINISHME: Fix up uniform name for arrays and things */
965 if (ir->var->type->base_type == GLSL_TYPE_SAMPLER) {
966 /* FINISHME: we whack the location of the var here, which
967 * is probably not expected. But we need to communicate
968 * mesa's sampler number to the tex instruction.
969 */
970 int sampler = _mesa_add_sampler(this->prog->Parameters,
971 ir->var->name,
972 ir->var->type->gl_type);
973 map_sampler(ir->var->location, sampler);
974
975 entry = new(mem_ctx) temp_entry(ir->var, PROGRAM_SAMPLER, sampler);
976 this->variable_storage.push_tail(entry);
977 break;
978 }
979
980 assert(ir->var->type->gl_type != 0 &&
981 ir->var->type->gl_type != GL_INVALID_ENUM);
982 loc = _mesa_add_uniform(this->prog->Parameters,
983 ir->var->name,
984 type_size(ir->var->type) * 4,
985 ir->var->type->gl_type,
986 NULL);
987
988 /* Always mark the uniform used at this point. If it isn't
989 * used, dead code elimination should have nuked the decl already.
990 */
991 this->prog->Parameters->Parameters[loc].Used = GL_TRUE;
992
993 entry = new(mem_ctx) temp_entry(ir->var, PROGRAM_UNIFORM, loc);
994 this->variable_storage.push_tail(entry);
995 break;
996 case ir_var_in:
997 case ir_var_out:
998 case ir_var_inout:
999 /* The linker assigns locations for varyings and attributes,
1000 * including deprecated builtins (like gl_Color), user-assign
1001 * generic attributes (glBindVertexLocation), and
1002 * user-defined varyings.
1003 *
1004 * FINISHME: We would hit this path for function arguments. Fix!
1005 */
1006 assert(ir->var->location != -1);
1007 if (ir->var->mode == ir_var_in ||
1008 ir->var->mode == ir_var_inout) {
1009 entry = new(mem_ctx) temp_entry(ir->var,
1010 PROGRAM_INPUT,
1011 ir->var->location);
1012
1013 if (this->prog->Target == GL_VERTEX_PROGRAM_ARB &&
1014 ir->var->location >= VERT_ATTRIB_GENERIC0) {
1015 _mesa_add_attribute(prog->Attributes,
1016 ir->var->name,
1017 type_size(ir->var->type) * 4,
1018 ir->var->type->gl_type,
1019 ir->var->location - VERT_ATTRIB_GENERIC0);
1020 }
1021 } else {
1022 entry = new(mem_ctx) temp_entry(ir->var,
1023 PROGRAM_OUTPUT,
1024 ir->var->location);
1025 }
1026
1027 break;
1028 case ir_var_auto:
1029 entry = new(mem_ctx) temp_entry(ir->var, PROGRAM_TEMPORARY,
1030 this->next_temp);
1031 this->variable_storage.push_tail(entry);
1032
1033 next_temp += type_size(ir->var->type);
1034 break;
1035 }
1036
1037 if (!entry) {
1038 printf("Failed to make storage for %s\n", ir->var->name);
1039 exit(1);
1040 }
1041 }
1042
1043 src_reg.file = entry->file;
1044 src_reg.index = entry->index;
1045 /* If the type is smaller than a vec4, replicate the last channel out. */
1046 src_reg.swizzle = swizzle_for_size(ir->var->type->vector_elements);
1047 src_reg.reladdr = false;
1048 src_reg.negate = 0;
1049
1050 this->result = src_reg;
1051 }
1052
1053 void
1054 ir_to_mesa_visitor::visit(ir_dereference_array *ir)
1055 {
1056 ir_constant *index;
1057 ir_to_mesa_src_reg src_reg;
1058
1059 index = ir->array_index->constant_expression_value();
1060
1061 /* By the time we make it to this stage, matrices should be broken down
1062 * to vectors.
1063 */
1064 assert(!ir->type->is_matrix());
1065
1066 ir->array->accept(this);
1067 src_reg = this->result;
1068
1069 if (src_reg.file == PROGRAM_INPUT ||
1070 src_reg.file == PROGRAM_OUTPUT) {
1071 assert(index); /* FINISHME: Handle variable indexing of builtins. */
1072
1073 src_reg.index += index->value.i[0];
1074 } else {
1075 if (index) {
1076 src_reg.index += index->value.i[0];
1077 } else {
1078 ir_to_mesa_src_reg array_base = this->result;
1079 /* Variable index array dereference. It eats the "vec4" of the
1080 * base of the array and an index that offsets the Mesa register
1081 * index.
1082 */
1083 ir->array_index->accept(this);
1084
1085 /* FINISHME: This doesn't work when we're trying to do the LHS
1086 * of an assignment.
1087 */
1088 src_reg.reladdr = true;
1089 ir_to_mesa_emit_op1(ir, OPCODE_ARL, ir_to_mesa_address_reg,
1090 this->result);
1091
1092 this->result = get_temp(ir->type);
1093 ir_to_mesa_emit_op1(ir, OPCODE_MOV,
1094 ir_to_mesa_dst_reg_from_src(this->result),
1095 src_reg);
1096 }
1097 }
1098
1099 /* If the type is smaller than a vec4, replicate the last channel out. */
1100 src_reg.swizzle = swizzle_for_size(ir->type->vector_elements);
1101
1102 this->result = src_reg;
1103 }
1104
1105 void
1106 ir_to_mesa_visitor::visit(ir_dereference_record *ir)
1107 {
1108 unsigned int i;
1109 const glsl_type *struct_type = ir->record->type;
1110 int offset = 0;
1111
1112 ir->record->accept(this);
1113
1114 for (i = 0; i < struct_type->length; i++) {
1115 if (strcmp(struct_type->fields.structure[i].name, ir->field) == 0)
1116 break;
1117 offset += type_size(struct_type->fields.structure[i].type);
1118 }
1119 this->result.index += offset;
1120 }
1121
1122 /**
1123 * We want to be careful in assignment setup to hit the actual storage
1124 * instead of potentially using a temporary like we might with the
1125 * ir_dereference handler.
1126 *
1127 * Thanks to ir_swizzle_swizzle, and ir_vec_index_to_swizzle, we
1128 * should only see potentially one variable array index of a vector,
1129 * and one swizzle, before getting to actual vec4 storage. So handle
1130 * those, then go use ir_dereference to handle the rest.
1131 */
1132 static struct ir_to_mesa_dst_reg
1133 get_assignment_lhs(ir_instruction *ir, ir_to_mesa_visitor *v)
1134 {
1135 struct ir_to_mesa_dst_reg dst_reg;
1136 ir_dereference *deref;
1137 ir_swizzle *swiz;
1138
1139 /* Use the rvalue deref handler for the most part. We'll ignore
1140 * swizzles in it and write swizzles using writemask, though.
1141 */
1142 ir->accept(v);
1143 dst_reg = ir_to_mesa_dst_reg_from_src(v->result);
1144
1145 if ((deref = ir->as_dereference())) {
1146 ir_dereference_array *deref_array = ir->as_dereference_array();
1147 assert(!deref_array || deref_array->array->type->is_array());
1148
1149 ir->accept(v);
1150 } else if ((swiz = ir->as_swizzle())) {
1151 dst_reg.writemask = 0;
1152 if (swiz->mask.num_components >= 1)
1153 dst_reg.writemask |= (1 << swiz->mask.x);
1154 if (swiz->mask.num_components >= 2)
1155 dst_reg.writemask |= (1 << swiz->mask.y);
1156 if (swiz->mask.num_components >= 3)
1157 dst_reg.writemask |= (1 << swiz->mask.z);
1158 if (swiz->mask.num_components >= 4)
1159 dst_reg.writemask |= (1 << swiz->mask.w);
1160 }
1161
1162 return dst_reg;
1163 }
1164
1165 static GLuint
1166 reswizzle_for_writemask(GLuint writemask, GLuint swizzle)
1167 {
1168 int new_swizzle[4], pos = 0;
1169 int i;
1170
1171 /* reswizzle the rhs so the components are in place for the
1172 * components we'll assign to the lhs.
1173 */
1174 for (i = 0; i < 4; i++) {
1175 if (writemask & (1 << i)) {
1176 new_swizzle[i] = GET_SWZ(swizzle, pos++);
1177 } else {
1178 new_swizzle[i] = GET_SWZ(swizzle, 0);
1179 }
1180 }
1181
1182 return MAKE_SWIZZLE4(new_swizzle[0],
1183 new_swizzle[1],
1184 new_swizzle[2],
1185 new_swizzle[3]);
1186 }
1187
1188 void
1189 ir_to_mesa_visitor::visit(ir_assignment *ir)
1190 {
1191 struct ir_to_mesa_dst_reg l;
1192 struct ir_to_mesa_src_reg r;
1193
1194 assert(!ir->lhs->type->is_matrix());
1195 assert(!ir->lhs->type->is_array());
1196 assert(ir->lhs->type->base_type != GLSL_TYPE_STRUCT);
1197
1198 l = get_assignment_lhs(ir->lhs, this);
1199
1200 ir->rhs->accept(this);
1201 r = this->result;
1202
1203 r.swizzle = reswizzle_for_writemask(l.writemask, r.swizzle);
1204
1205 assert(l.file != PROGRAM_UNDEFINED);
1206 assert(r.file != PROGRAM_UNDEFINED);
1207
1208 if (ir->condition) {
1209 ir_to_mesa_src_reg condition;
1210
1211 ir->condition->accept(this);
1212 condition = this->result;
1213
1214 /* We use the OPCODE_CMP (a < 0 ? b : c) for conditional moves,
1215 * and the condition we produced is 0.0 or 1.0. By flipping the
1216 * sign, we can choose which value OPCODE_CMP produces without
1217 * an extra computing the condition.
1218 */
1219 condition.negate = ~condition.negate;
1220 ir_to_mesa_emit_op3(ir, OPCODE_CMP, l,
1221 condition, r, ir_to_mesa_src_reg_from_dst(l));
1222 } else {
1223 ir_to_mesa_emit_op1(ir, OPCODE_MOV, l, r);
1224 }
1225 }
1226
1227
1228 void
1229 ir_to_mesa_visitor::visit(ir_constant *ir)
1230 {
1231 ir_to_mesa_src_reg src_reg;
1232 GLfloat stack_vals[4];
1233 GLfloat *values = stack_vals;
1234 unsigned int i;
1235
1236 if (ir->type->is_matrix() || ir->type->is_array()) {
1237 assert(!"FINISHME: array/matrix constants");
1238 }
1239
1240 src_reg.file = PROGRAM_CONSTANT;
1241 switch (ir->type->base_type) {
1242 case GLSL_TYPE_FLOAT:
1243 values = &ir->value.f[0];
1244 break;
1245 case GLSL_TYPE_UINT:
1246 for (i = 0; i < ir->type->vector_elements; i++) {
1247 values[i] = ir->value.u[i];
1248 }
1249 break;
1250 case GLSL_TYPE_INT:
1251 for (i = 0; i < ir->type->vector_elements; i++) {
1252 values[i] = ir->value.i[i];
1253 }
1254 break;
1255 case GLSL_TYPE_BOOL:
1256 for (i = 0; i < ir->type->vector_elements; i++) {
1257 values[i] = ir->value.b[i];
1258 }
1259 break;
1260 default:
1261 assert(!"Non-float/uint/int/bool constant");
1262 }
1263
1264 src_reg.index = _mesa_add_unnamed_constant(this->prog->Parameters,
1265 values, ir->type->vector_elements,
1266 &src_reg.swizzle);
1267 src_reg.reladdr = false;
1268 src_reg.negate = 0;
1269
1270 this->result = src_reg;
1271 }
1272
1273
1274 void
1275 ir_to_mesa_visitor::visit(ir_call *ir)
1276 {
1277 printf("Can't support call to %s\n", ir->callee_name());
1278 exit(1);
1279 }
1280
1281
1282 void
1283 ir_to_mesa_visitor::visit(ir_texture *ir)
1284 {
1285 ir_to_mesa_src_reg result_src, coord, lod_info, projector;
1286 ir_to_mesa_dst_reg result_dst, coord_dst;
1287 ir_to_mesa_instruction *inst = NULL;
1288 prog_opcode opcode = OPCODE_NOP;
1289
1290 ir->coordinate->accept(this);
1291
1292 /* Put our coords in a temp. We'll need to modify them for shadow,
1293 * projection, or LOD, so the only case we'd use it as is is if
1294 * we're doing plain old texturing. Mesa IR optimization should
1295 * handle cleaning up our mess in that case.
1296 */
1297 coord = get_temp(glsl_type::vec4_type);
1298 coord_dst = ir_to_mesa_dst_reg_from_src(coord);
1299 ir_to_mesa_emit_op1(ir, OPCODE_MOV, coord_dst,
1300 this->result);
1301
1302 if (ir->projector) {
1303 ir->projector->accept(this);
1304 projector = this->result;
1305 }
1306
1307 /* Storage for our result. Ideally for an assignment we'd be using
1308 * the actual storage for the result here, instead.
1309 */
1310 result_src = get_temp(glsl_type::vec4_type);
1311 result_dst = ir_to_mesa_dst_reg_from_src(result_src);
1312
1313 switch (ir->op) {
1314 case ir_tex:
1315 opcode = OPCODE_TEX;
1316 break;
1317 case ir_txb:
1318 opcode = OPCODE_TXB;
1319 ir->lod_info.bias->accept(this);
1320 lod_info = this->result;
1321 break;
1322 case ir_txl:
1323 opcode = OPCODE_TXL;
1324 ir->lod_info.lod->accept(this);
1325 lod_info = this->result;
1326 break;
1327 case ir_txd:
1328 case ir_txf:
1329 assert(!"GLSL 1.30 features unsupported");
1330 break;
1331 }
1332
1333 if (ir->projector) {
1334 if (opcode == OPCODE_TEX) {
1335 /* Slot the projector in as the last component of the coord. */
1336 coord_dst.writemask = WRITEMASK_W;
1337 ir_to_mesa_emit_op1(ir, OPCODE_MOV, coord_dst, projector);
1338 coord_dst.writemask = WRITEMASK_XYZW;
1339 opcode = OPCODE_TXP;
1340 } else {
1341 ir_to_mesa_src_reg coord_w = coord;
1342 coord_w.swizzle = SWIZZLE_WWWW;
1343
1344 /* For the other TEX opcodes there's no projective version
1345 * since the last slot is taken up by lod info. Do the
1346 * projective divide now.
1347 */
1348 coord_dst.writemask = WRITEMASK_W;
1349 ir_to_mesa_emit_op1(ir, OPCODE_RCP, coord_dst, projector);
1350
1351 coord_dst.writemask = WRITEMASK_XYZ;
1352 ir_to_mesa_emit_op2(ir, OPCODE_MUL, coord_dst, coord, coord_w);
1353
1354 coord_dst.writemask = WRITEMASK_XYZW;
1355 coord.swizzle = SWIZZLE_XYZW;
1356 }
1357 }
1358
1359 if (ir->shadow_comparitor) {
1360 /* Slot the shadow value in as the second to last component of the
1361 * coord.
1362 */
1363 ir->shadow_comparitor->accept(this);
1364 coord_dst.writemask = WRITEMASK_Z;
1365 ir_to_mesa_emit_op1(ir, OPCODE_MOV, coord_dst, this->result);
1366 coord_dst.writemask = WRITEMASK_XYZW;
1367 }
1368
1369 if (opcode == OPCODE_TXL || opcode == OPCODE_TXB) {
1370 /* Mesa IR stores lod or lod bias in the last channel of the coords. */
1371 coord_dst.writemask = WRITEMASK_W;
1372 ir_to_mesa_emit_op1(ir, OPCODE_MOV, coord_dst, lod_info);
1373 coord_dst.writemask = WRITEMASK_XYZW;
1374 }
1375
1376 inst = ir_to_mesa_emit_op1(ir, opcode, result_dst, coord);
1377
1378 if (ir->shadow_comparitor)
1379 inst->tex_shadow = GL_TRUE;
1380
1381 ir_dereference_variable *sampler = ir->sampler->as_dereference_variable();
1382 assert(sampler); /* FINISHME: sampler arrays */
1383 /* generate the mapping, remove when we generate storage at
1384 * declaration time
1385 */
1386 sampler->accept(this);
1387
1388 inst->sampler = get_sampler_number(sampler->var->location);
1389
1390 switch (sampler->type->sampler_dimensionality) {
1391 case GLSL_SAMPLER_DIM_1D:
1392 inst->tex_target = TEXTURE_1D_INDEX;
1393 break;
1394 case GLSL_SAMPLER_DIM_2D:
1395 inst->tex_target = TEXTURE_2D_INDEX;
1396 break;
1397 case GLSL_SAMPLER_DIM_3D:
1398 inst->tex_target = TEXTURE_3D_INDEX;
1399 break;
1400 case GLSL_SAMPLER_DIM_CUBE:
1401 inst->tex_target = TEXTURE_CUBE_INDEX;
1402 break;
1403 default:
1404 assert(!"FINISHME: other texture targets");
1405 }
1406
1407 this->result = result_src;
1408 }
1409
1410 void
1411 ir_to_mesa_visitor::visit(ir_return *ir)
1412 {
1413 assert(0);
1414
1415 ir->get_value()->accept(this);
1416 }
1417
1418 void
1419 ir_to_mesa_visitor::visit(ir_discard *ir)
1420 {
1421 assert(ir->condition == NULL); /* FINISHME */
1422
1423 ir_to_mesa_emit_op1(ir, OPCODE_KIL_NV,
1424 ir_to_mesa_undef_dst, ir_to_mesa_undef);
1425 }
1426
1427 void
1428 ir_to_mesa_visitor::visit(ir_if *ir)
1429 {
1430 ir_to_mesa_instruction *cond_inst, *if_inst, *else_inst = NULL;
1431 ir_to_mesa_instruction *prev_inst;
1432
1433 prev_inst = (ir_to_mesa_instruction *)this->instructions.get_tail();
1434
1435 ir->condition->accept(this);
1436 assert(this->result.file != PROGRAM_UNDEFINED);
1437
1438 if (ctx->Shader.EmitCondCodes) {
1439 cond_inst = (ir_to_mesa_instruction *)this->instructions.get_tail();
1440
1441 /* See if we actually generated any instruction for generating
1442 * the condition. If not, then cook up a move to a temp so we
1443 * have something to set cond_update on.
1444 */
1445 if (cond_inst == prev_inst) {
1446 ir_to_mesa_src_reg temp = get_temp(glsl_type::bool_type);
1447 cond_inst = ir_to_mesa_emit_op1(ir->condition, OPCODE_MOV,
1448 ir_to_mesa_dst_reg_from_src(temp),
1449 result);
1450 }
1451 cond_inst->cond_update = GL_TRUE;
1452
1453 if_inst = ir_to_mesa_emit_op1(ir->condition,
1454 OPCODE_IF, ir_to_mesa_undef_dst,
1455 ir_to_mesa_undef);
1456 if_inst->dst_reg.cond_mask = COND_NE;
1457 } else {
1458 if_inst = ir_to_mesa_emit_op1(ir->condition,
1459 OPCODE_IF, ir_to_mesa_undef_dst,
1460 this->result);
1461 }
1462
1463 this->instructions.push_tail(if_inst);
1464
1465 visit_exec_list(&ir->then_instructions, this);
1466
1467 if (!ir->else_instructions.is_empty()) {
1468 else_inst = ir_to_mesa_emit_op1(ir->condition, OPCODE_ELSE,
1469 ir_to_mesa_undef_dst,
1470 ir_to_mesa_undef);
1471 visit_exec_list(&ir->else_instructions, this);
1472 }
1473
1474 if_inst = ir_to_mesa_emit_op1(ir->condition, OPCODE_ENDIF,
1475 ir_to_mesa_undef_dst, ir_to_mesa_undef);
1476 }
1477
1478 ir_to_mesa_visitor::ir_to_mesa_visitor()
1479 {
1480 result.file = PROGRAM_UNDEFINED;
1481 next_temp = 1;
1482 sampler_map = NULL;
1483 sampler_map_size = 0;
1484 }
1485
1486 static struct prog_src_register
1487 mesa_src_reg_from_ir_src_reg(ir_to_mesa_src_reg reg)
1488 {
1489 struct prog_src_register mesa_reg;
1490
1491 mesa_reg.File = reg.file;
1492 assert(reg.index < (1 << INST_INDEX_BITS) - 1);
1493 mesa_reg.Index = reg.index;
1494 mesa_reg.Swizzle = reg.swizzle;
1495 mesa_reg.RelAddr = reg.reladdr;
1496 mesa_reg.Negate = reg.negate;
1497 mesa_reg.Abs = 0;
1498
1499 return mesa_reg;
1500 }
1501
1502 static void
1503 set_branchtargets(struct prog_instruction *mesa_instructions,
1504 int num_instructions)
1505 {
1506 int if_count = 0, loop_count = 0;
1507 int *if_stack, *loop_stack;
1508 int if_stack_pos = 0, loop_stack_pos = 0;
1509 int i, j;
1510
1511 for (i = 0; i < num_instructions; i++) {
1512 switch (mesa_instructions[i].Opcode) {
1513 case OPCODE_IF:
1514 if_count++;
1515 break;
1516 case OPCODE_BGNLOOP:
1517 loop_count++;
1518 break;
1519 case OPCODE_BRK:
1520 case OPCODE_CONT:
1521 mesa_instructions[i].BranchTarget = -1;
1522 break;
1523 default:
1524 break;
1525 }
1526 }
1527
1528 if_stack = (int *)calloc(if_count, sizeof(*if_stack));
1529 loop_stack = (int *)calloc(loop_count, sizeof(*loop_stack));
1530
1531 for (i = 0; i < num_instructions; i++) {
1532 switch (mesa_instructions[i].Opcode) {
1533 case OPCODE_IF:
1534 if_stack[if_stack_pos] = i;
1535 if_stack_pos++;
1536 break;
1537 case OPCODE_ELSE:
1538 mesa_instructions[if_stack[if_stack_pos - 1]].BranchTarget = i;
1539 if_stack[if_stack_pos - 1] = i;
1540 break;
1541 case OPCODE_ENDIF:
1542 mesa_instructions[if_stack[if_stack_pos - 1]].BranchTarget = i;
1543 if_stack_pos--;
1544 break;
1545 case OPCODE_BGNLOOP:
1546 loop_stack[loop_stack_pos] = i;
1547 loop_stack_pos++;
1548 break;
1549 case OPCODE_ENDLOOP:
1550 loop_stack_pos--;
1551 /* Rewrite any breaks/conts at this nesting level (haven't
1552 * already had a BranchTarget assigned) to point to the end
1553 * of the loop.
1554 */
1555 for (j = loop_stack[loop_stack_pos]; j < i; j++) {
1556 if (mesa_instructions[j].Opcode == OPCODE_BRK ||
1557 mesa_instructions[j].Opcode == OPCODE_CONT) {
1558 if (mesa_instructions[j].BranchTarget == -1) {
1559 mesa_instructions[j].BranchTarget = i;
1560 }
1561 }
1562 }
1563 /* The loop ends point at each other. */
1564 mesa_instructions[i].BranchTarget = loop_stack[loop_stack_pos];
1565 mesa_instructions[loop_stack[loop_stack_pos]].BranchTarget = i;
1566 default:
1567 break;
1568 }
1569 }
1570
1571 free(if_stack);
1572 }
1573
1574 static void
1575 print_program(struct prog_instruction *mesa_instructions,
1576 ir_instruction **mesa_instruction_annotation,
1577 int num_instructions)
1578 {
1579 ir_instruction *last_ir = NULL;
1580 int i;
1581
1582 for (i = 0; i < num_instructions; i++) {
1583 struct prog_instruction *mesa_inst = mesa_instructions + i;
1584 ir_instruction *ir = mesa_instruction_annotation[i];
1585
1586 if (last_ir != ir && ir) {
1587 ir_print_visitor print;
1588 ir->accept(&print);
1589 printf("\n");
1590 last_ir = ir;
1591 }
1592
1593 _mesa_print_instruction(mesa_inst);
1594 }
1595 }
1596
1597 static void
1598 count_resources(struct gl_program *prog)
1599 {
1600 unsigned int i;
1601
1602 prog->InputsRead = 0;
1603 prog->OutputsWritten = 0;
1604 prog->SamplersUsed = 0;
1605
1606 for (i = 0; i < prog->NumInstructions; i++) {
1607 struct prog_instruction *inst = &prog->Instructions[i];
1608 unsigned int reg;
1609
1610 switch (inst->DstReg.File) {
1611 case PROGRAM_OUTPUT:
1612 prog->OutputsWritten |= BITFIELD64_BIT(inst->DstReg.Index);
1613 break;
1614 case PROGRAM_INPUT:
1615 prog->InputsRead |= BITFIELD64_BIT(inst->DstReg.Index);
1616 break;
1617 default:
1618 break;
1619 }
1620
1621 for (reg = 0; reg < _mesa_num_inst_src_regs(inst->Opcode); reg++) {
1622 switch (inst->SrcReg[reg].File) {
1623 case PROGRAM_OUTPUT:
1624 prog->OutputsWritten |= BITFIELD64_BIT(inst->SrcReg[reg].Index);
1625 break;
1626 case PROGRAM_INPUT:
1627 prog->InputsRead |= BITFIELD64_BIT(inst->SrcReg[reg].Index);
1628 break;
1629 default:
1630 break;
1631 }
1632 }
1633
1634 /* Instead of just using the uniform's value to map to a
1635 * sampler, Mesa first allocates a separate number for the
1636 * sampler (_mesa_add_sampler), then we reindex it down to a
1637 * small integer (sampler_map[], SamplersUsed), then that gets
1638 * mapped to the uniform's value, and we get an actual sampler.
1639 */
1640 if (_mesa_is_tex_instruction(inst->Opcode)) {
1641 prog->SamplerTargets[inst->TexSrcUnit] =
1642 (gl_texture_index)inst->TexSrcTarget;
1643 prog->SamplersUsed |= 1 << inst->TexSrcUnit;
1644 if (inst->TexShadow) {
1645 prog->ShadowSamplers |= 1 << inst->TexSrcUnit;
1646 }
1647 }
1648 }
1649
1650 _mesa_update_shader_textures_used(prog);
1651 }
1652
1653 /* Each stage has some uniforms in its Parameters list. The Uniforms
1654 * list for the linked shader program has a pointer to these uniforms
1655 * in each of the stage's Parameters list, so that their values can be
1656 * updated when a uniform is set.
1657 */
1658 static void
1659 link_uniforms_to_shared_uniform_list(struct gl_uniform_list *uniforms,
1660 struct gl_program *prog)
1661 {
1662 unsigned int i;
1663
1664 for (i = 0; i < prog->Parameters->NumParameters; i++) {
1665 const struct gl_program_parameter *p = prog->Parameters->Parameters + i;
1666
1667 if (p->Type == PROGRAM_UNIFORM || p->Type == PROGRAM_SAMPLER) {
1668 struct gl_uniform *uniform =
1669 _mesa_append_uniform(uniforms, p->Name, prog->Target, i);
1670 if (uniform)
1671 uniform->Initialized = p->Initialized;
1672 }
1673 }
1674 }
1675
1676 struct gl_program *
1677 get_mesa_program(GLcontext *ctx, void *mem_ctx, struct gl_shader *shader)
1678 {
1679 ir_to_mesa_visitor v;
1680 struct prog_instruction *mesa_instructions, *mesa_inst;
1681 ir_instruction **mesa_instruction_annotation;
1682 int i;
1683 struct gl_program *prog;
1684 GLenum target;
1685
1686 switch (shader->Type) {
1687 case GL_VERTEX_SHADER: target = GL_VERTEX_PROGRAM_ARB; break;
1688 case GL_FRAGMENT_SHADER: target = GL_FRAGMENT_PROGRAM_ARB; break;
1689 default: assert(!"should not be reached"); break;
1690 }
1691
1692 prog = ctx->Driver.NewProgram(ctx, target, 1);
1693 if (!prog)
1694 return NULL;
1695 prog->Parameters = _mesa_new_parameter_list();
1696 prog->Varying = _mesa_new_parameter_list();
1697 prog->Attributes = _mesa_new_parameter_list();
1698 v.ctx = ctx;
1699 v.prog = prog;
1700
1701 v.mem_ctx = talloc_new(NULL);
1702 visit_exec_list(shader->ir, &v);
1703 v.ir_to_mesa_emit_op1(NULL, OPCODE_END,
1704 ir_to_mesa_undef_dst, ir_to_mesa_undef);
1705
1706 prog->NumTemporaries = v.next_temp;
1707
1708 int num_instructions = 0;
1709 foreach_iter(exec_list_iterator, iter, v.instructions) {
1710 num_instructions++;
1711 }
1712
1713 mesa_instructions =
1714 (struct prog_instruction *)calloc(num_instructions,
1715 sizeof(*mesa_instructions));
1716 mesa_instruction_annotation = talloc_array(mem_ctx, ir_instruction *,
1717 num_instructions);
1718
1719 mesa_inst = mesa_instructions;
1720 i = 0;
1721 foreach_iter(exec_list_iterator, iter, v.instructions) {
1722 ir_to_mesa_instruction *inst = (ir_to_mesa_instruction *)iter.get();
1723
1724 mesa_inst->Opcode = inst->op;
1725 mesa_inst->CondUpdate = inst->cond_update;
1726 mesa_inst->DstReg.File = inst->dst_reg.file;
1727 mesa_inst->DstReg.Index = inst->dst_reg.index;
1728 mesa_inst->DstReg.CondMask = inst->dst_reg.cond_mask;
1729 mesa_inst->DstReg.WriteMask = inst->dst_reg.writemask;
1730 mesa_inst->SrcReg[0] = mesa_src_reg_from_ir_src_reg(inst->src_reg[0]);
1731 mesa_inst->SrcReg[1] = mesa_src_reg_from_ir_src_reg(inst->src_reg[1]);
1732 mesa_inst->SrcReg[2] = mesa_src_reg_from_ir_src_reg(inst->src_reg[2]);
1733 mesa_inst->TexSrcUnit = inst->sampler;
1734 mesa_inst->TexSrcTarget = inst->tex_target;
1735 mesa_inst->TexShadow = inst->tex_shadow;
1736 mesa_instruction_annotation[i] = inst->ir;
1737
1738 mesa_inst++;
1739 i++;
1740 }
1741
1742 set_branchtargets(mesa_instructions, num_instructions);
1743 if (0) {
1744 print_program(mesa_instructions, mesa_instruction_annotation,
1745 num_instructions);
1746 }
1747
1748 prog->Instructions = mesa_instructions;
1749 prog->NumInstructions = num_instructions;
1750
1751 _mesa_reference_program(ctx, &shader->Program, prog);
1752
1753 if ((ctx->Shader.Flags & GLSL_NO_OPT) == 0) {
1754 _mesa_optimize_program(ctx, prog);
1755 }
1756
1757 return prog;
1758 }
1759
1760 extern "C" {
1761
1762 static void
1763 steal_memory(ir_instruction *ir, void *new_ctx)
1764 {
1765 talloc_steal(new_ctx, ir);
1766 }
1767
1768 void
1769 _mesa_glsl_compile_shader(GLcontext *ctx, struct gl_shader *shader)
1770 {
1771 struct _mesa_glsl_parse_state *state;
1772
1773 state = talloc_zero(shader, struct _mesa_glsl_parse_state);
1774 switch (shader->Type) {
1775 case GL_VERTEX_SHADER: state->target = vertex_shader; break;
1776 case GL_FRAGMENT_SHADER: state->target = fragment_shader; break;
1777 case GL_GEOMETRY_SHADER: state->target = geometry_shader; break;
1778 }
1779
1780 state->scanner = NULL;
1781 state->translation_unit.make_empty();
1782 state->symbols = new(shader) glsl_symbol_table;
1783 state->info_log = talloc_strdup(shader, "");
1784 state->error = false;
1785 state->temp_index = 0;
1786 state->loop_or_switch_nesting = NULL;
1787 state->ARB_texture_rectangle_enable = true;
1788
1789 state->extensions = &ctx->Extensions;
1790 state->Const.MaxDrawBuffers = ctx->Const.MaxDrawBuffers;
1791 state->Const.MaxTextureCoords = ctx->Const.MaxTextureCoordUnits;
1792
1793 const char *source = shader->Source;
1794 state->error = preprocess(state, &source, &state->info_log,
1795 &ctx->Extensions);
1796
1797 if (!state->error) {
1798 _mesa_glsl_lexer_ctor(state, source);
1799 _mesa_glsl_parse(state);
1800 _mesa_glsl_lexer_dtor(state);
1801 }
1802
1803 shader->ir = new(shader) exec_list;
1804 if (!state->error && !state->translation_unit.is_empty())
1805 _mesa_ast_to_hir(shader->ir, state);
1806
1807 /* Lowering */
1808 do_mod_to_fract(shader->ir);
1809 do_div_to_mul_rcp(shader->ir);
1810
1811 /* Optimization passes */
1812 if (!state->error && !shader->ir->is_empty()) {
1813 bool progress;
1814 do {
1815 progress = false;
1816
1817 progress = do_function_inlining(shader->ir) || progress;
1818 progress = do_if_simplification(shader->ir) || progress;
1819 progress = do_copy_propagation(shader->ir) || progress;
1820 progress = do_dead_code_local(shader->ir) || progress;
1821 progress = do_dead_code_unlinked(state, shader->ir) || progress;
1822 progress = do_constant_variable_unlinked(shader->ir) || progress;
1823 progress = do_constant_folding(shader->ir) || progress;
1824
1825 progress = do_vec_index_to_swizzle(shader->ir) || progress;
1826 /* Do this one after the previous to let the easier pass handle
1827 * constant vector indexing.
1828 */
1829 progress = do_vec_index_to_cond_assign(shader->ir) || progress;
1830
1831 progress = do_swizzle_swizzle(shader->ir) || progress;
1832 } while (progress);
1833 }
1834
1835 shader->symbols = state->symbols;
1836
1837 shader->CompileStatus = !state->error;
1838 shader->InfoLog = state->info_log;
1839
1840 /* Retain any live IR, but trash the rest. */
1841 foreach_list(node, shader->ir) {
1842 visit_tree((ir_instruction *) node, steal_memory, shader);
1843 }
1844
1845 talloc_free(state);
1846 }
1847
1848 void
1849 _mesa_glsl_link_shader(GLcontext *ctx, struct gl_shader_program *prog)
1850 {
1851 unsigned int i;
1852
1853 _mesa_clear_shader_program_data(ctx, prog);
1854
1855 prog->LinkStatus = GL_TRUE;
1856
1857 for (i = 0; i < prog->NumShaders; i++) {
1858 if (!prog->Shaders[i]->CompileStatus) {
1859 prog->InfoLog =
1860 talloc_asprintf_append(prog->InfoLog,
1861 "linking with uncompiled shader");
1862 prog->LinkStatus = GL_FALSE;
1863 }
1864 }
1865
1866 prog->Varying = _mesa_new_parameter_list();
1867 _mesa_reference_vertprog(ctx, &prog->VertexProgram, NULL);
1868 _mesa_reference_fragprog(ctx, &prog->FragmentProgram, NULL);
1869
1870 if (prog->LinkStatus) {
1871 link_shaders(prog);
1872
1873 /* We don't use the linker's uniforms list, and cook up our own at
1874 * generate time.
1875 */
1876 free(prog->Uniforms);
1877 prog->Uniforms = _mesa_new_uniform_list();
1878 }
1879
1880 prog->LinkStatus = prog->LinkStatus;
1881
1882 /* FINISHME: This should use the linker-generated code */
1883 if (prog->LinkStatus) {
1884 for (i = 0; i < prog->NumShaders; i++) {
1885 struct gl_program *linked_prog;
1886
1887 linked_prog = get_mesa_program(ctx, prog,
1888 prog->Shaders[i]);
1889 count_resources(linked_prog);
1890
1891 link_uniforms_to_shared_uniform_list(prog->Uniforms, linked_prog);
1892
1893 switch (prog->Shaders[i]->Type) {
1894 case GL_VERTEX_SHADER:
1895 _mesa_reference_vertprog(ctx, &prog->VertexProgram,
1896 (struct gl_vertex_program *)linked_prog);
1897 ctx->Driver.ProgramStringNotify(ctx, GL_VERTEX_PROGRAM_ARB,
1898 linked_prog);
1899 break;
1900 case GL_FRAGMENT_SHADER:
1901 _mesa_reference_fragprog(ctx, &prog->FragmentProgram,
1902 (struct gl_fragment_program *)linked_prog);
1903 ctx->Driver.ProgramStringNotify(ctx, GL_FRAGMENT_PROGRAM_ARB,
1904 linked_prog);
1905 break;
1906 }
1907 }
1908 }
1909 }
1910
1911 } /* extern "C" */