New driver for i915 as well as older i830/i845/i865 chipsets.
[mesa.git] / src / mesa / drivers / dri / i915 / i830_texblend.c
1 /**************************************************************************
2 *
3 * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
4 * All Rights Reserved.
5 *
6 **************************************************************************/
7
8 #include "glheader.h"
9 #include "macros.h"
10 #include "mtypes.h"
11 #include "simple_list.h"
12 #include "enums.h"
13 #include "texformat.h"
14 #include "texstore.h"
15
16 #include "mm.h"
17
18 #include "intel_screen.h"
19 #include "intel_ioctl.h"
20 #include "intel_tex.h"
21
22 #include "i830_context.h"
23 #include "i830_reg.h"
24
25
26 /* ================================================================
27 * Texture combine functions
28 */
29 static GLuint pass_through( GLuint *state, GLuint blendUnit )
30 {
31 state[0] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) |
32 TEXPIPE_COLOR |
33 ENABLE_TEXOUTPUT_WRT_SEL |
34 TEXOP_OUTPUT_CURRENT |
35 DISABLE_TEX_CNTRL_STAGE |
36 TEXOP_SCALE_1X |
37 TEXOP_MODIFY_PARMS |
38 TEXBLENDOP_ARG1);
39 state[1] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) |
40 TEXPIPE_ALPHA |
41 ENABLE_TEXOUTPUT_WRT_SEL |
42 TEXOP_OUTPUT_CURRENT |
43 TEXOP_SCALE_1X |
44 TEXOP_MODIFY_PARMS |
45 TEXBLENDOP_ARG1);
46 state[2] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) |
47 TEXPIPE_COLOR |
48 TEXBLEND_ARG1 |
49 TEXBLENDARG_MODIFY_PARMS |
50 TEXBLENDARG_CURRENT);
51 state[3] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) |
52 TEXPIPE_ALPHA |
53 TEXBLEND_ARG1 |
54 TEXBLENDARG_MODIFY_PARMS |
55 TEXBLENDARG_CURRENT);
56
57 return 4;
58 }
59
60 static GLuint emit_factor( GLuint blendUnit, GLuint *state, GLuint count,
61 const GLfloat *factor )
62 {
63 GLubyte r, g, b, a;
64 GLuint col;
65
66 if (0)
67 fprintf(stderr, "emit constant %d: %.2f %.2f %.2f %.2f\n",
68 blendUnit, factor[0], factor[1], factor[2], factor[3]);
69
70 UNCLAMPED_FLOAT_TO_UBYTE(r, factor[0]);
71 UNCLAMPED_FLOAT_TO_UBYTE(g, factor[1]);
72 UNCLAMPED_FLOAT_TO_UBYTE(b, factor[2]);
73 UNCLAMPED_FLOAT_TO_UBYTE(a, factor[3]);
74
75 col = ((a << 24) | (r << 16) | (g << 8) | b);
76
77 state[count++] = _3DSTATE_COLOR_FACTOR_N_CMD(blendUnit);
78 state[count++] = col;
79
80 return count;
81 }
82
83
84 static __inline__ GLuint GetTexelOp(GLint unit)
85 {
86 switch(unit) {
87 case 0: return TEXBLENDARG_TEXEL0;
88 case 1: return TEXBLENDARG_TEXEL1;
89 case 2: return TEXBLENDARG_TEXEL2;
90 case 3: return TEXBLENDARG_TEXEL3;
91 default: return TEXBLENDARG_TEXEL0;
92 }
93 }
94
95
96 GLuint i830SetBlend_GL1_2(i830ContextPtr i830, int blendUnit,
97 GLenum envMode, GLenum format, GLuint texel_op,
98 GLuint *state, const GLfloat *factor)
99 {
100 if(INTEL_DEBUG&DEBUG_TEXTURE)
101 fprintf(stderr, "%s %s %s texel_op(0x%x)\n",
102 __FUNCTION__,
103 _mesa_lookup_enum_by_nr(format),
104 _mesa_lookup_enum_by_nr(envMode),
105 texel_op);
106
107 switch(envMode) {
108 case GL_REPLACE:
109 switch(format) {
110 case GL_ALPHA:
111 state[0] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) |
112 TEXPIPE_COLOR |
113 ENABLE_TEXOUTPUT_WRT_SEL |
114 TEXOP_OUTPUT_CURRENT |
115 DISABLE_TEX_CNTRL_STAGE |
116 TEXOP_SCALE_1X |
117 TEXOP_MODIFY_PARMS |
118 TEXBLENDOP_ARG1);
119 state[1] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) |
120 TEXPIPE_ALPHA |
121 ENABLE_TEXOUTPUT_WRT_SEL |
122 TEXOP_OUTPUT_CURRENT |
123 TEXOP_SCALE_1X |
124 TEXOP_MODIFY_PARMS |
125 TEXBLENDOP_ARG1);
126 state[2] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) |
127 TEXPIPE_COLOR |
128 TEXBLEND_ARG1 |
129 TEXBLENDARG_MODIFY_PARMS |
130 TEXBLENDARG_CURRENT);
131 state[3] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) |
132 TEXPIPE_ALPHA |
133 TEXBLEND_ARG1 |
134 TEXBLENDARG_MODIFY_PARMS |
135 texel_op);
136 return 4;
137
138 case GL_LUMINANCE:
139 case GL_RGB:
140 case GL_YCBCR_MESA:
141 state[0] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) |
142 TEXPIPE_COLOR |
143 ENABLE_TEXOUTPUT_WRT_SEL |
144 TEXOP_OUTPUT_CURRENT |
145 DISABLE_TEX_CNTRL_STAGE |
146 TEXOP_SCALE_1X |
147 TEXOP_MODIFY_PARMS |
148 TEXBLENDOP_ARG1);
149 state[1] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) |
150 TEXPIPE_ALPHA |
151 ENABLE_TEXOUTPUT_WRT_SEL |
152 TEXOP_OUTPUT_CURRENT |
153 TEXOP_SCALE_1X |
154 TEXOP_MODIFY_PARMS |
155 TEXBLENDOP_ARG1);
156 state[2] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) |
157 TEXPIPE_COLOR |
158 TEXBLEND_ARG1 |
159 TEXBLENDARG_MODIFY_PARMS |
160 texel_op);
161 state[3] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) |
162 TEXPIPE_ALPHA |
163 TEXBLEND_ARG1 |
164 TEXBLENDARG_MODIFY_PARMS |
165 TEXBLENDARG_CURRENT);
166 return 4;
167
168 case GL_INTENSITY:
169 case GL_LUMINANCE_ALPHA:
170 case GL_RGBA:
171 state[0] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) |
172 TEXPIPE_COLOR |
173 ENABLE_TEXOUTPUT_WRT_SEL |
174 TEXOP_OUTPUT_CURRENT |
175 DISABLE_TEX_CNTRL_STAGE |
176 TEXOP_SCALE_1X |
177 TEXOP_MODIFY_PARMS |
178 TEXBLENDOP_ARG1);
179 state[1] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) |
180 TEXPIPE_ALPHA |
181 ENABLE_TEXOUTPUT_WRT_SEL |
182 TEXOP_OUTPUT_CURRENT |
183 TEXOP_SCALE_1X |
184 TEXOP_MODIFY_PARMS |
185 TEXBLENDOP_ARG1);
186 state[2] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) |
187 TEXPIPE_COLOR |
188 TEXBLEND_ARG1 |
189 TEXBLENDARG_MODIFY_PARMS |
190 texel_op);
191 state[3] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) |
192 TEXPIPE_ALPHA |
193 TEXBLEND_ARG1 |
194 TEXBLENDARG_MODIFY_PARMS |
195 texel_op);
196 return 4;
197
198 default:
199 /* Always set to passthru if something is funny */
200 return pass_through( state, blendUnit );
201 }
202
203 case GL_MODULATE:
204 switch(format) {
205 case GL_ALPHA:
206 state[0] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) |
207 TEXPIPE_COLOR |
208 ENABLE_TEXOUTPUT_WRT_SEL |
209 TEXOP_OUTPUT_CURRENT |
210 DISABLE_TEX_CNTRL_STAGE |
211 TEXOP_SCALE_1X |
212 TEXOP_MODIFY_PARMS |
213 TEXBLENDOP_ARG1);
214 state[1] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) |
215 TEXPIPE_ALPHA |
216 ENABLE_TEXOUTPUT_WRT_SEL |
217 TEXOP_OUTPUT_CURRENT |
218 TEXOP_SCALE_1X |
219 TEXOP_MODIFY_PARMS |
220 TEXBLENDOP_MODULATE);
221 state[2] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) |
222 TEXPIPE_COLOR |
223 TEXBLEND_ARG1 |
224 TEXBLENDARG_MODIFY_PARMS |
225 TEXBLENDARG_CURRENT);
226 state[3] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) |
227 TEXPIPE_ALPHA |
228 TEXBLEND_ARG1 |
229 TEXBLENDARG_MODIFY_PARMS |
230 texel_op);
231 state[4] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) |
232 TEXPIPE_ALPHA |
233 TEXBLEND_ARG2 |
234 TEXBLENDARG_MODIFY_PARMS |
235 TEXBLENDARG_CURRENT);
236 return 5;
237
238 case GL_LUMINANCE:
239 case GL_RGB:
240 case GL_YCBCR_MESA:
241 state[0] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) |
242 TEXPIPE_COLOR |
243 ENABLE_TEXOUTPUT_WRT_SEL |
244 TEXOP_OUTPUT_CURRENT |
245 DISABLE_TEX_CNTRL_STAGE |
246 TEXOP_SCALE_1X |
247 TEXOP_MODIFY_PARMS |
248 TEXBLENDOP_MODULATE);
249 state[1] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) |
250 TEXPIPE_ALPHA |
251 ENABLE_TEXOUTPUT_WRT_SEL |
252 TEXOP_OUTPUT_CURRENT |
253 TEXOP_SCALE_1X |
254 TEXOP_MODIFY_PARMS |
255 TEXBLENDOP_ARG1);
256 state[2] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) |
257 TEXPIPE_COLOR |
258 TEXBLEND_ARG1 |
259 TEXBLENDARG_MODIFY_PARMS |
260 texel_op);
261 state[3] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) |
262 TEXPIPE_COLOR |
263 TEXBLEND_ARG2 |
264 TEXBLENDARG_MODIFY_PARMS |
265 TEXBLENDARG_CURRENT);
266 state[4] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) |
267 TEXPIPE_ALPHA |
268 TEXBLEND_ARG1 |
269 TEXBLENDARG_MODIFY_PARMS |
270 TEXBLENDARG_CURRENT);
271 return 5;
272
273 case GL_INTENSITY:
274 case GL_LUMINANCE_ALPHA:
275 case GL_RGBA:
276 state[0] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) |
277 TEXPIPE_COLOR |
278 ENABLE_TEXOUTPUT_WRT_SEL |
279 TEXOP_OUTPUT_CURRENT |
280 DISABLE_TEX_CNTRL_STAGE |
281 TEXOP_SCALE_1X |
282 TEXOP_MODIFY_PARMS |
283 TEXBLENDOP_MODULATE);
284 state[1] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) |
285 TEXPIPE_ALPHA |
286 ENABLE_TEXOUTPUT_WRT_SEL |
287 TEXOP_OUTPUT_CURRENT |
288 TEXOP_SCALE_1X |
289 TEXOP_MODIFY_PARMS |
290 TEXBLENDOP_MODULATE);
291 state[2] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) |
292 TEXPIPE_COLOR |
293 TEXBLEND_ARG1 |
294 TEXBLENDARG_MODIFY_PARMS |
295 texel_op);
296 state[3] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) |
297 TEXPIPE_COLOR |
298 TEXBLEND_ARG2 |
299 TEXBLENDARG_MODIFY_PARMS |
300 TEXBLENDARG_CURRENT);
301 state[4] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) |
302 TEXPIPE_ALPHA |
303 TEXBLEND_ARG1 |
304 TEXBLENDARG_MODIFY_PARMS |
305 texel_op);
306 state[5] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) |
307 TEXPIPE_ALPHA |
308 TEXBLEND_ARG2 |
309 TEXBLENDARG_MODIFY_PARMS |
310 TEXBLENDARG_CURRENT);
311 return 6;
312
313 default:
314 /* Always set to passthru if something is funny */
315 return pass_through( state, blendUnit );
316 }
317
318 case GL_DECAL:
319 switch(format) {
320 case GL_RGB:
321 case GL_YCBCR_MESA:
322 state[0] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) |
323 TEXPIPE_COLOR |
324 ENABLE_TEXOUTPUT_WRT_SEL |
325 TEXOP_OUTPUT_CURRENT |
326 DISABLE_TEX_CNTRL_STAGE |
327 TEXOP_SCALE_1X |
328 TEXOP_MODIFY_PARMS |
329 TEXBLENDOP_ARG1);
330 state[1] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) |
331 TEXPIPE_ALPHA |
332 ENABLE_TEXOUTPUT_WRT_SEL |
333 TEXOP_OUTPUT_CURRENT |
334 TEXOP_SCALE_1X |
335 TEXOP_MODIFY_PARMS |
336 TEXBLENDOP_ARG1);
337 state[2] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) |
338 TEXPIPE_COLOR |
339 TEXBLEND_ARG1 |
340 TEXBLENDARG_MODIFY_PARMS |
341 texel_op);
342 state[3] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) |
343 TEXPIPE_ALPHA |
344 TEXBLEND_ARG1 |
345 TEXBLENDARG_MODIFY_PARMS |
346 TEXBLENDARG_CURRENT);
347 return 4;
348
349 case GL_RGBA:
350 state[0] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) |
351 TEXPIPE_COLOR |
352 ENABLE_TEXOUTPUT_WRT_SEL |
353 TEXOP_OUTPUT_CURRENT |
354 DISABLE_TEX_CNTRL_STAGE |
355 TEXOP_SCALE_1X |
356 TEXOP_MODIFY_PARMS |
357 TEXBLENDOP_BLEND);
358 state[1] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) |
359 TEXPIPE_ALPHA |
360 ENABLE_TEXOUTPUT_WRT_SEL |
361 TEXOP_OUTPUT_CURRENT |
362 TEXOP_SCALE_1X |
363 TEXOP_MODIFY_PARMS |
364 TEXBLENDOP_ARG1);
365 state[2] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) |
366 TEXPIPE_COLOR |
367 TEXBLEND_ARG0 |
368 TEXBLENDARG_MODIFY_PARMS |
369 TEXBLENDARG_REPLICATE_ALPHA |
370 texel_op);
371 state[3] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) |
372 TEXPIPE_COLOR |
373 TEXBLEND_ARG1 |
374 TEXBLENDARG_MODIFY_PARMS |
375 texel_op);
376 state[4] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) |
377 TEXPIPE_COLOR |
378 TEXBLEND_ARG2 |
379 TEXBLENDARG_MODIFY_PARMS |
380 TEXBLENDARG_CURRENT);
381 state[5] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) |
382 TEXPIPE_ALPHA |
383 TEXBLEND_ARG1 |
384 TEXBLENDARG_MODIFY_PARMS |
385 TEXBLENDARG_CURRENT);
386 return 6;
387 default:
388 /* Always set to passthru if something is funny */
389 return pass_through( state, blendUnit );
390 }
391
392 case GL_BLEND:
393 switch(format) {
394 case GL_ALPHA:
395 state[0] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) |
396 TEXPIPE_COLOR |
397 ENABLE_TEXOUTPUT_WRT_SEL |
398 TEXOP_OUTPUT_CURRENT |
399 DISABLE_TEX_CNTRL_STAGE |
400 TEXOP_SCALE_1X |
401 TEXOP_MODIFY_PARMS |
402 TEXBLENDOP_ARG1);
403 state[1] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) |
404 TEXPIPE_ALPHA |
405 ENABLE_TEXOUTPUT_WRT_SEL |
406 TEXOP_OUTPUT_CURRENT |
407 TEXOP_SCALE_1X |
408 TEXOP_MODIFY_PARMS |
409 TEXBLENDOP_MODULATE);
410 state[2] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) |
411 TEXPIPE_COLOR |
412 TEXBLEND_ARG1 |
413 TEXBLENDARG_MODIFY_PARMS |
414 TEXBLENDARG_CURRENT);
415 state[3] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) |
416 TEXPIPE_ALPHA |
417 TEXBLEND_ARG1 |
418 TEXBLENDARG_MODIFY_PARMS |
419 texel_op);
420 state[4] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) |
421 TEXPIPE_ALPHA |
422 TEXBLEND_ARG2 |
423 TEXBLENDARG_MODIFY_PARMS |
424 TEXBLENDARG_CURRENT);
425 return 5;
426
427 case GL_LUMINANCE:
428 case GL_RGB:
429 case GL_YCBCR_MESA:
430 state[0] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) |
431 TEXPIPE_COLOR |
432 ENABLE_TEXOUTPUT_WRT_SEL |
433 TEXOP_OUTPUT_CURRENT |
434 DISABLE_TEX_CNTRL_STAGE |
435 TEXOP_SCALE_1X |
436 TEXOP_MODIFY_PARMS |
437 TEXBLENDOP_BLEND);
438 state[1] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) |
439 TEXPIPE_ALPHA |
440 ENABLE_TEXOUTPUT_WRT_SEL |
441 TEXOP_OUTPUT_CURRENT |
442 TEXOP_SCALE_1X |
443 TEXOP_MODIFY_PARMS |
444 TEXBLENDOP_ARG1);
445 state[2] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) |
446 TEXPIPE_COLOR |
447 TEXBLEND_ARG0 |
448 TEXBLENDARG_MODIFY_PARMS |
449 texel_op);
450 state[3] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) |
451 TEXPIPE_COLOR |
452 TEXBLEND_ARG1 |
453 TEXBLENDARG_MODIFY_PARMS |
454 TEXBLENDARG_FACTOR_N);
455 state[4] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) |
456 TEXPIPE_COLOR |
457 TEXBLEND_ARG2 |
458 TEXBLENDARG_MODIFY_PARMS |
459 TEXBLENDARG_CURRENT);
460 state[5] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) |
461 TEXPIPE_ALPHA |
462 TEXBLEND_ARG1 |
463 TEXBLENDARG_MODIFY_PARMS |
464 TEXBLENDARG_CURRENT);
465 return emit_factor( blendUnit, state, 6, factor );
466
467 case GL_INTENSITY:
468 state[0] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) |
469 TEXPIPE_COLOR |
470 ENABLE_TEXOUTPUT_WRT_SEL |
471 TEXOP_OUTPUT_CURRENT |
472 DISABLE_TEX_CNTRL_STAGE |
473 TEXOP_SCALE_1X |
474 TEXOP_MODIFY_PARMS |
475 TEXBLENDOP_BLEND);
476 state[1] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) |
477 TEXPIPE_ALPHA |
478 ENABLE_TEXOUTPUT_WRT_SEL |
479 TEXOP_OUTPUT_CURRENT |
480 TEXOP_SCALE_1X |
481 TEXOP_MODIFY_PARMS |
482 TEXBLENDOP_BLEND);
483 state[2] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) |
484 TEXPIPE_COLOR |
485 TEXBLEND_ARG0 |
486 TEXBLENDARG_MODIFY_PARMS |
487 texel_op);
488 state[3] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) |
489 TEXPIPE_COLOR |
490 TEXBLEND_ARG1 |
491 TEXBLENDARG_MODIFY_PARMS |
492 TEXBLENDARG_FACTOR_N);
493 state[4] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) |
494 TEXPIPE_COLOR |
495 TEXBLEND_ARG2 |
496 TEXBLENDARG_MODIFY_PARMS |
497 TEXBLENDARG_CURRENT);
498 state[5] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) |
499 TEXPIPE_ALPHA |
500 TEXBLEND_ARG0 |
501 TEXBLENDARG_MODIFY_PARMS |
502 texel_op);
503 state[6] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) |
504 TEXPIPE_ALPHA |
505 TEXBLEND_ARG1 |
506 TEXBLENDARG_MODIFY_PARMS |
507 TEXBLENDARG_FACTOR_N);
508 state[7] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) |
509 TEXPIPE_ALPHA |
510 TEXBLEND_ARG2 |
511 TEXBLENDARG_MODIFY_PARMS |
512 TEXBLENDARG_CURRENT);
513 return emit_factor( blendUnit, state, 8, factor );
514
515
516 case GL_LUMINANCE_ALPHA:
517 case GL_RGBA:
518 state[0] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) |
519 TEXPIPE_COLOR |
520 ENABLE_TEXOUTPUT_WRT_SEL |
521 TEXOP_OUTPUT_CURRENT |
522 DISABLE_TEX_CNTRL_STAGE |
523 TEXOP_SCALE_1X |
524 TEXOP_MODIFY_PARMS |
525 TEXBLENDOP_BLEND);
526 state[1] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) |
527 TEXPIPE_ALPHA |
528 ENABLE_TEXOUTPUT_WRT_SEL |
529 TEXOP_OUTPUT_CURRENT |
530 TEXOP_SCALE_1X |
531 TEXOP_MODIFY_PARMS |
532 TEXBLENDOP_MODULATE);
533 state[2] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) |
534 TEXPIPE_COLOR |
535 TEXBLEND_ARG0 |
536 TEXBLENDARG_MODIFY_PARMS |
537 texel_op);
538 state[3] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) |
539 TEXPIPE_COLOR |
540 TEXBLEND_ARG1 |
541 TEXBLENDARG_MODIFY_PARMS |
542 TEXBLENDARG_FACTOR_N);
543 state[4] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) |
544 TEXPIPE_COLOR |
545 TEXBLEND_ARG2 |
546 TEXBLENDARG_MODIFY_PARMS |
547 TEXBLENDARG_CURRENT);
548 state[5] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) |
549 TEXPIPE_ALPHA |
550 TEXBLEND_ARG1 |
551 TEXBLENDARG_MODIFY_PARMS |
552 texel_op);
553 state[6] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) |
554 TEXPIPE_ALPHA |
555 TEXBLEND_ARG2 |
556 TEXBLENDARG_MODIFY_PARMS |
557 TEXBLENDARG_CURRENT);
558 return emit_factor( blendUnit, state, 7, factor );
559
560 default:
561 /* Always set to passthru if something is funny */
562 return pass_through( state, blendUnit );
563 }
564
565 case GL_ADD:
566 switch(format) {
567 case GL_ALPHA:
568 state[0] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) |
569 TEXPIPE_COLOR |
570 ENABLE_TEXOUTPUT_WRT_SEL |
571 TEXOP_OUTPUT_CURRENT |
572 DISABLE_TEX_CNTRL_STAGE |
573 TEXOP_SCALE_1X |
574 TEXOP_MODIFY_PARMS |
575 TEXBLENDOP_ARG1);
576 state[1] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) |
577 TEXPIPE_ALPHA |
578 ENABLE_TEXOUTPUT_WRT_SEL |
579 TEXOP_OUTPUT_CURRENT |
580 TEXOP_SCALE_1X |
581 TEXOP_MODIFY_PARMS |
582 TEXBLENDOP_MODULATE);
583 state[2] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) |
584 TEXPIPE_COLOR |
585 TEXBLEND_ARG1 |
586 TEXBLENDARG_MODIFY_PARMS |
587 TEXBLENDARG_CURRENT);
588 state[3] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) |
589 TEXPIPE_ALPHA |
590 TEXBLEND_ARG1 |
591 TEXBLENDARG_MODIFY_PARMS |
592 texel_op);
593 state[4] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) |
594 TEXPIPE_ALPHA |
595 TEXBLEND_ARG2 |
596 TEXBLENDARG_MODIFY_PARMS |
597 TEXBLENDARG_CURRENT);
598 return 5;
599
600 case GL_LUMINANCE:
601 case GL_RGB:
602 case GL_YCBCR_MESA:
603 state[0] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) |
604 TEXPIPE_COLOR |
605 ENABLE_TEXOUTPUT_WRT_SEL |
606 TEXOP_OUTPUT_CURRENT |
607 DISABLE_TEX_CNTRL_STAGE |
608 TEXOP_SCALE_1X |
609 TEXOP_MODIFY_PARMS |
610 TEXBLENDOP_ADD);
611 state[1] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) |
612 TEXPIPE_ALPHA |
613 ENABLE_TEXOUTPUT_WRT_SEL |
614 TEXOP_OUTPUT_CURRENT |
615 TEXOP_SCALE_1X |
616 TEXOP_MODIFY_PARMS |
617 TEXBLENDOP_ARG1);
618 state[2] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) |
619 TEXPIPE_COLOR |
620 TEXBLEND_ARG1 |
621 TEXBLENDARG_MODIFY_PARMS |
622 texel_op);
623 state[3] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) |
624 TEXPIPE_COLOR |
625 TEXBLEND_ARG2 |
626 TEXBLENDARG_MODIFY_PARMS |
627 TEXBLENDARG_CURRENT);
628 state[4] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) |
629 TEXPIPE_ALPHA |
630 TEXBLEND_ARG1 |
631 TEXBLENDARG_MODIFY_PARMS |
632 TEXBLENDARG_CURRENT);
633 return 5;
634
635 case GL_INTENSITY:
636 state[0] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) |
637 TEXPIPE_COLOR |
638 ENABLE_TEXOUTPUT_WRT_SEL |
639 TEXOP_OUTPUT_CURRENT |
640 DISABLE_TEX_CNTRL_STAGE |
641 TEXOP_SCALE_1X |
642 TEXOP_MODIFY_PARMS |
643 TEXBLENDOP_ADD);
644 state[1] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) |
645 TEXPIPE_ALPHA |
646 ENABLE_TEXOUTPUT_WRT_SEL |
647 TEXOP_OUTPUT_CURRENT |
648 TEXOP_SCALE_1X |
649 TEXOP_MODIFY_PARMS |
650 TEXBLENDOP_ADD);
651 state[2] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) |
652 TEXPIPE_COLOR |
653 TEXBLEND_ARG1 |
654 TEXBLENDARG_MODIFY_PARMS |
655 texel_op);
656 state[3] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) |
657 TEXPIPE_COLOR |
658 TEXBLEND_ARG2 |
659 TEXBLENDARG_MODIFY_PARMS |
660 TEXBLENDARG_CURRENT);
661 state[4] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) |
662 TEXPIPE_ALPHA |
663 TEXBLEND_ARG1 |
664 TEXBLENDARG_MODIFY_PARMS |
665 texel_op);
666 state[5] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) |
667 TEXPIPE_ALPHA |
668 TEXBLEND_ARG2 |
669 TEXBLENDARG_MODIFY_PARMS |
670 TEXBLENDARG_CURRENT);
671 return 6;
672
673 case GL_LUMINANCE_ALPHA:
674 case GL_RGBA:
675 state[0] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) |
676 TEXPIPE_COLOR |
677 ENABLE_TEXOUTPUT_WRT_SEL |
678 TEXOP_OUTPUT_CURRENT |
679 DISABLE_TEX_CNTRL_STAGE |
680 TEXOP_SCALE_1X |
681 TEXOP_MODIFY_PARMS |
682 TEXBLENDOP_ADD);
683 state[1] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) |
684 TEXPIPE_ALPHA |
685 ENABLE_TEXOUTPUT_WRT_SEL |
686 TEXOP_OUTPUT_CURRENT |
687 TEXOP_SCALE_1X |
688 TEXOP_MODIFY_PARMS |
689 TEXBLENDOP_MODULATE);
690 state[2] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) |
691 TEXPIPE_COLOR |
692 TEXBLEND_ARG1 |
693 TEXBLENDARG_MODIFY_PARMS |
694 texel_op);
695 state[3] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) |
696 TEXPIPE_COLOR |
697 TEXBLEND_ARG2 |
698 TEXBLENDARG_MODIFY_PARMS |
699 TEXBLENDARG_CURRENT);
700 state[4] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) |
701 TEXPIPE_ALPHA |
702 TEXBLEND_ARG1 |
703 TEXBLENDARG_MODIFY_PARMS |
704 texel_op);
705 state[5] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) |
706 TEXPIPE_ALPHA |
707 TEXBLEND_ARG2 |
708 TEXBLENDARG_MODIFY_PARMS |
709 TEXBLENDARG_CURRENT);
710 return 6;
711
712 default:
713 /* Always set to passthru if something is funny */
714 return pass_through( state, blendUnit );
715 }
716
717 default:
718 /* Always set to passthru if something is funny */
719 return pass_through( state, blendUnit );
720 }
721 }
722
723 static GLuint i830SetTexEnvCombine(i830ContextPtr i830,
724 const struct gl_texture_unit *texUnit,
725 GLint blendUnit,
726 GLuint texel_op,
727 GLuint *state,
728 const GLfloat *factor )
729 {
730 GLuint blendop;
731 GLuint ablendop;
732 GLuint args_RGB[3];
733 GLuint args_A[3];
734 GLuint rgb_shift;
735 GLuint alpha_shift;
736 GLboolean need_factor = 0;
737 int i;
738
739 if(INTEL_DEBUG&DEBUG_TEXTURE)
740 fprintf(stderr, "%s\n", __FUNCTION__);
741
742
743 /* The EXT version of the DOT3 extension does not support the
744 * scale factor, but the ARB version (and the version in OpenGL
745 * 1.3) does.
746 */
747 switch (texUnit->Combine.ModeRGB) {
748 case GL_DOT3_RGB_EXT:
749 alpha_shift = texUnit->Combine.ScaleShiftA;
750 rgb_shift = 0;
751 break;
752
753 case GL_DOT3_RGBA_EXT:
754 alpha_shift = 0;
755 rgb_shift = 0;
756 break;
757
758 default:
759 rgb_shift = texUnit->Combine.ScaleShiftRGB;
760 alpha_shift = texUnit->Combine.ScaleShiftA;
761 break;
762 }
763
764
765 switch(texUnit->Combine.ModeRGB) {
766 case GL_REPLACE:
767 blendop = TEXBLENDOP_ARG1;
768 break;
769 case GL_MODULATE:
770 blendop = TEXBLENDOP_MODULATE;
771 break;
772 case GL_ADD:
773 blendop = TEXBLENDOP_ADD;
774 break;
775 case GL_ADD_SIGNED:
776 blendop = TEXBLENDOP_ADDSIGNED;
777 break;
778 case GL_INTERPOLATE:
779 blendop = TEXBLENDOP_BLEND;
780 break;
781 case GL_SUBTRACT:
782 blendop = TEXBLENDOP_SUBTRACT;
783 break;
784 case GL_DOT3_RGB_EXT:
785 case GL_DOT3_RGB:
786 blendop = TEXBLENDOP_DOT3;
787 break;
788 case GL_DOT3_RGBA_EXT:
789 case GL_DOT3_RGBA:
790 blendop = TEXBLENDOP_DOT3;
791 break;
792 default:
793 return pass_through( state, blendUnit );
794 }
795
796 blendop |= (rgb_shift << TEXOP_SCALE_SHIFT);
797
798
799 /* Handle RGB args */
800 for(i = 0; i < 3; i++) {
801 switch(texUnit->Combine.SourceRGB[i]) {
802 case GL_TEXTURE:
803 args_RGB[i] = texel_op;
804 break;
805 case GL_CONSTANT:
806 args_RGB[i] = TEXBLENDARG_FACTOR_N;
807 need_factor = 1;
808 break;
809 case GL_PRIMARY_COLOR:
810 args_RGB[i] = TEXBLENDARG_DIFFUSE;
811 break;
812 case GL_PREVIOUS:
813 args_RGB[i] = TEXBLENDARG_CURRENT;
814 break;
815 default:
816 return pass_through( state, blendUnit );
817 }
818
819 switch(texUnit->Combine.OperandRGB[i]) {
820 case GL_SRC_COLOR:
821 args_RGB[i] |= 0;
822 break;
823 case GL_ONE_MINUS_SRC_COLOR:
824 args_RGB[i] |= TEXBLENDARG_INV_ARG;
825 break;
826 case GL_SRC_ALPHA:
827 args_RGB[i] |= TEXBLENDARG_REPLICATE_ALPHA;
828 break;
829 case GL_ONE_MINUS_SRC_ALPHA:
830 args_RGB[i] |= (TEXBLENDARG_REPLICATE_ALPHA |
831 TEXBLENDARG_INV_ARG);
832 break;
833 default:
834 return pass_through( state, blendUnit );
835 }
836 }
837
838
839 /* Need to knobble the alpha calculations of TEXBLENDOP_DOT4 to
840 * match the spec. Can't use DOT3 as it won't propogate values
841 * into alpha as required:
842 *
843 * Note - the global factor is set up with alpha == .5, so
844 * the alpha part of the DOT4 calculation should be zero.
845 */
846 if ( texUnit->Combine.ModeRGB == GL_DOT3_RGBA_EXT ||
847 texUnit->Combine.ModeRGB == GL_DOT3_RGBA ) {
848 ablendop = TEXBLENDOP_DOT4;
849 args_A[0] = TEXBLENDARG_FACTOR; /* the global factor */
850 args_A[1] = TEXBLENDARG_FACTOR;
851 args_A[2] = TEXBLENDARG_FACTOR;
852 }
853 else {
854 switch(texUnit->Combine.ModeA) {
855 case GL_REPLACE:
856 ablendop = TEXBLENDOP_ARG1;
857 break;
858 case GL_MODULATE:
859 ablendop = TEXBLENDOP_MODULATE;
860 break;
861 case GL_ADD:
862 ablendop = TEXBLENDOP_ADD;
863 break;
864 case GL_ADD_SIGNED:
865 ablendop = TEXBLENDOP_ADDSIGNED;
866 break;
867 case GL_INTERPOLATE:
868 ablendop = TEXBLENDOP_BLEND;
869 break;
870 case GL_SUBTRACT:
871 ablendop = TEXBLENDOP_SUBTRACT;
872 break;
873 default:
874 return pass_through( state, blendUnit );
875 }
876
877
878 ablendop |= (alpha_shift << TEXOP_SCALE_SHIFT);
879
880 /* Handle A args */
881 for(i = 0; i < 3; i++) {
882 switch(texUnit->Combine.SourceA[i]) {
883 case GL_TEXTURE:
884 args_A[i] = texel_op;
885 break;
886 case GL_CONSTANT:
887 args_A[i] = TEXBLENDARG_FACTOR_N;
888 need_factor = 1;
889 break;
890 case GL_PRIMARY_COLOR:
891 args_A[i] = TEXBLENDARG_DIFFUSE;
892 break;
893 case GL_PREVIOUS:
894 args_A[i] = TEXBLENDARG_CURRENT;
895 break;
896 default:
897 return pass_through( state, blendUnit );
898 }
899
900 switch(texUnit->Combine.OperandA[i]) {
901 case GL_SRC_ALPHA:
902 args_A[i] |= 0;
903 break;
904 case GL_ONE_MINUS_SRC_ALPHA:
905 args_A[i] |= TEXBLENDARG_INV_ARG;
906 break;
907 default:
908 return pass_through( state, blendUnit );
909 }
910 }
911 }
912
913
914
915 /* Native Arg1 == Arg0 in GL_EXT_texture_env_combine spec */
916 /* Native Arg2 == Arg1 in GL_EXT_texture_env_combine spec */
917 /* Native Arg0 == Arg2 in GL_EXT_texture_env_combine spec */
918
919 /* When we render we need to figure out which is the last really enabled
920 * tex unit, and put last stage on it
921 */
922
923
924 /* Build color pipeline */
925
926 state[0] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) |
927 TEXPIPE_COLOR |
928 ENABLE_TEXOUTPUT_WRT_SEL |
929 TEXOP_OUTPUT_CURRENT |
930 DISABLE_TEX_CNTRL_STAGE |
931 TEXOP_MODIFY_PARMS |
932 blendop);
933 state[1] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) |
934 TEXPIPE_COLOR |
935 TEXBLEND_ARG1 |
936 TEXBLENDARG_MODIFY_PARMS |
937 args_RGB[0]);
938 state[2] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) |
939 TEXPIPE_COLOR |
940 TEXBLEND_ARG2 |
941 TEXBLENDARG_MODIFY_PARMS |
942 args_RGB[1]);
943 state[3] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) |
944 TEXPIPE_COLOR |
945 TEXBLEND_ARG0 |
946 TEXBLENDARG_MODIFY_PARMS |
947 args_RGB[2]);
948
949 /* Build Alpha pipeline */
950 state[4] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) |
951 TEXPIPE_ALPHA |
952 ENABLE_TEXOUTPUT_WRT_SEL |
953 TEXOP_OUTPUT_CURRENT |
954 TEXOP_MODIFY_PARMS |
955 ablendop);
956 state[5] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) |
957 TEXPIPE_ALPHA |
958 TEXBLEND_ARG1 |
959 TEXBLENDARG_MODIFY_PARMS |
960 args_A[0]);
961 state[6] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) |
962 TEXPIPE_ALPHA |
963 TEXBLEND_ARG2 |
964 TEXBLENDARG_MODIFY_PARMS |
965 args_A[1]);
966 state[7] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) |
967 TEXPIPE_ALPHA |
968 TEXBLEND_ARG0 |
969 TEXBLENDARG_MODIFY_PARMS |
970 args_A[2]);
971
972
973 if (need_factor)
974 return emit_factor( blendUnit, state, 8, factor );
975 else
976 return 8;
977 }
978
979
980 static void emit_texblend( i830ContextPtr i830, GLuint unit, GLuint blendUnit,
981 GLboolean last_stage )
982 {
983 struct gl_texture_unit *texUnit = &i830->intel.ctx.Texture.Unit[unit];
984 struct gl_texture_object *tObj = texUnit->_Current;
985 i830TextureObjectPtr t = (i830TextureObjectPtr)tObj->DriverData;
986 GLuint tmp[I830_TEXBLEND_SIZE], tmp_sz;
987
988
989 if (0) fprintf(stderr, "%s unit %d\n", __FUNCTION__, unit);
990
991 /* Update i830->state.TexBlend
992 */
993 if (texUnit->EnvMode == GL_COMBINE) {
994 tmp_sz = i830SetTexEnvCombine(i830, texUnit, blendUnit,
995 GetTexelOp(unit), tmp,
996 texUnit->EnvColor );
997 }
998 else {
999 tmp_sz = i830SetBlend_GL1_2(i830, blendUnit, texUnit->EnvMode,
1000 t->intel.image[0][0].internalFormat,
1001 GetTexelOp(unit), tmp,
1002 texUnit->EnvColor );
1003 }
1004
1005 if (last_stage)
1006 tmp[0] |= TEXOP_LAST_STAGE;
1007
1008 if (tmp_sz != i830->state.TexBlendWordsUsed[blendUnit] ||
1009 memcmp( tmp, i830->state.TexBlend[blendUnit], tmp_sz * sizeof(GLuint))) {
1010
1011 I830_STATECHANGE( i830, I830_UPLOAD_TEXBLEND(blendUnit) );
1012 memcpy( i830->state.TexBlend[blendUnit], tmp, tmp_sz * sizeof(GLuint));
1013 i830->state.TexBlendWordsUsed[blendUnit] = tmp_sz;
1014 }
1015
1016 I830_ACTIVESTATE(i830, I830_UPLOAD_TEXBLEND(blendUnit), GL_TRUE);
1017 }
1018
1019 static void emit_passthrough( i830ContextPtr i830 )
1020 {
1021 GLuint tmp[I830_TEXBLEND_SIZE], tmp_sz;
1022 GLuint unit = 0;
1023
1024 tmp_sz = pass_through( tmp, unit );
1025 tmp[0] |= TEXOP_LAST_STAGE;
1026
1027 if (tmp_sz != i830->state.TexBlendWordsUsed[unit] ||
1028 memcmp( tmp, i830->state.TexBlend[unit], tmp_sz * sizeof(GLuint))) {
1029
1030 I830_STATECHANGE( i830, I830_UPLOAD_TEXBLEND(unit) );
1031 memcpy( i830->state.TexBlend[unit], tmp, tmp_sz * sizeof(GLuint));
1032 i830->state.TexBlendWordsUsed[unit] = tmp_sz;
1033 }
1034
1035 I830_ACTIVESTATE(i830, I830_UPLOAD_TEXBLEND(unit), GL_TRUE);
1036 }
1037
1038 void i830EmitTextureBlend( i830ContextPtr i830 )
1039 {
1040 GLcontext *ctx = &i830->intel.ctx;
1041 GLuint unit, last_stage = 0, blendunit = 0;
1042
1043 I830_ACTIVESTATE(i830, I830_UPLOAD_TEXBLEND_ALL, GL_FALSE);
1044
1045 if (ctx->Texture._EnabledUnits) {
1046 for (unit = 0 ; unit < ctx->Const.MaxTextureUnits ; unit++)
1047 if (ctx->Texture.Unit[unit]._ReallyEnabled)
1048 last_stage = unit;
1049
1050 for (unit = 0 ; unit < ctx->Const.MaxTextureUnits ; unit++)
1051 if (ctx->Texture.Unit[unit]._ReallyEnabled)
1052 emit_texblend( i830, unit, blendunit++, last_stage == unit );
1053 }
1054 else {
1055 emit_passthrough( i830 );
1056 }
1057 }
1058