Typo
[mesa.git] / src / mesa / drivers / dri / unichrome / via_texcombine.c
1 /*
2 * (C) Copyright IBM Corporation 2004
3 * All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * on the rights to use, copy, modify, merge, publish, distribute, sub
9 * license, and/or sell copies of the Software, and to permit persons to whom
10 * the Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
14 * Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
19 * IBM AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
20 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
21 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
22 * USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25 /**
26 * \file via_texcombine.c
27 * Calculate texture combine hardware state.
28 *
29 * \author Ian Romanick <idr@us.ibm.com>
30 */
31
32 #include <stdio.h>
33
34 #include "glheader.h"
35 #include "context.h"
36 #include "macros.h"
37 #include "colormac.h"
38 #include "enums.h"
39 #include "dd.h"
40
41 #include "mm.h"
42 #include "via_context.h"
43 #include "via_state.h"
44 #include "via_tex.h"
45 #include "via_tris.h"
46 #include "via_ioctl.h"
47
48 #include "swrast/swrast.h"
49 #include "array_cache/acache.h"
50 #include "tnl/tnl.h"
51 #include "swrast_setup/swrast_setup.h"
52
53 #include "tnl/t_pipeline.h"
54
55 #define VIA_USE_ALPHA (HC_XTC_Adif - HC_XTC_Dif)
56
57 #define INPUT_A_SHIFT 14
58 #define INPUT_B_SHIFT 7
59 #define INPUT_C_SHIFT 0
60 #define INPUT_CBias_SHIFT 14
61 #define INPUT_ABias_SHIFT 3
62
63 #define CONST_ONE (HC_XTC_0 | HC_XTC_InvTOPC)
64
65 static const unsigned color_operand_modifier[4] = {
66 0,
67 HC_XTC_InvTOPC,
68 VIA_USE_ALPHA,
69 VIA_USE_ALPHA | HC_XTC_InvTOPC,
70 };
71
72 static const unsigned alpha_operand_modifier[2] = {
73 0, HC_XTA_InvTOPA
74 };
75
76 static const unsigned c_shift_table[3] = {
77 HC_HTXnTBLCshift_No, HC_HTXnTBLCshift_1, HC_HTXnTBLCshift_2
78 };
79
80 static const unsigned a_shift_table[3] = {
81 HC_HTXnTBLAshift_No, HC_HTXnTBLAshift_1, HC_HTXnTBLAshift_2
82 };
83
84
85 /**
86 * Calculate the hardware state for the specified texture combine mode
87 *
88 * \bug
89 * For the alpha combine, \c GL_CONSTANT is still probably wrong.
90 *
91 * \bug
92 * All forms of DOT3 bumpmapping are completely untested, and are most
93 * likely wrong.
94 *
95 * \bug
96 * This code still fails progs/demos/texenv for all modes with \c GL_ALPHA
97 * textures. This was also the case with the code that Via supplied. It
98 * also fails for \c GL_REPLACE with \c GL_RGBA textures. Everything else
99 * that texenv tests looks good.
100 *
101 * \bug
102 * KW: needs attention to the case where texunit 1 is enabled but
103 * texunit 0 is not.
104 */
105 void
106 viaTexCombineState( viaContextPtr vmesa,
107 const struct gl_tex_env_combine_state * combine,
108 unsigned unit )
109 {
110 unsigned color_arg[3];
111 unsigned alpha_arg[3];
112 unsigned color = 0;
113 unsigned alpha = 0;
114 unsigned bias = 0;
115 unsigned op = 0;
116 unsigned a_shift = combine->ScaleShiftA;
117 unsigned c_shift = combine->ScaleShiftRGB;
118 unsigned i;
119 unsigned constant_color[3];
120 unsigned ordered_constant_color[4];
121 unsigned constant_alpha = 0;
122 unsigned bias_alpha = 0;
123 const struct gl_texture_unit const * texUnit = & vmesa->glCtx->Texture.Unit[unit];
124 unsigned env_color[4];
125
126
127 CLAMPED_FLOAT_TO_UBYTE(env_color[0], texUnit->EnvColor[0]);
128 CLAMPED_FLOAT_TO_UBYTE(env_color[1], texUnit->EnvColor[1]);
129 CLAMPED_FLOAT_TO_UBYTE(env_color[2], texUnit->EnvColor[2]);
130 CLAMPED_FLOAT_TO_UBYTE(env_color[3], texUnit->EnvColor[3]);
131
132 (void) memset( constant_color, 0, sizeof( constant_color ) );
133 (void) memset( ordered_constant_color, 0, sizeof( ordered_constant_color ) );
134
135 for ( i = 0 ; i < combine->_NumArgsRGB ; i++ ) {
136 const GLint op = combine->OperandRGB[i] - GL_SRC_COLOR;
137
138 switch ( combine->SourceRGB[i] ) {
139 case GL_TEXTURE:
140 color_arg[i] = HC_XTC_Tex;
141 color_arg[i] += color_operand_modifier[op];
142 break;
143 case GL_CONSTANT:
144 color_arg[i] = HC_XTC_HTXnTBLRC;
145
146 switch( op ) {
147 case 0: /* GL_SRC_COLOR */
148 constant_color[i] = ((env_color[0] << 16) |
149 (env_color[1] << 8) |
150 env_color[2]);
151 break;
152 case 1: /* GL_ONE_MINUS_SRC_COLOR */
153 constant_color[i] = ~((env_color[0] << 16) |
154 (env_color[1] << 8) |
155 env_color[2]) & 0x00ffffff;
156 break;
157 case 2: /* GL_SRC_ALPHA */
158 constant_color[i] = ((env_color[3] << 16) |
159 (env_color[3] << 8) |
160 env_color[3]);
161 break;
162 case 3: /* GL_ONE_MINUS_SRC_ALPHA */
163 constant_color[i] = ~((env_color[3] << 16) |
164 (env_color[3] << 8) |
165 env_color[3]) & 0x00ffffff;
166 break;
167 }
168 break;
169 case GL_PRIMARY_COLOR:
170 color_arg[i] = HC_XTC_Dif;
171 color_arg[i] += color_operand_modifier[op];
172 break;
173 case GL_PREVIOUS:
174 color_arg[i] = (unit == 0) ? HC_XTC_Dif : HC_XTC_Cur;
175 color_arg[i] += color_operand_modifier[op];
176 break;
177 }
178 }
179
180 for ( i = 0 ; i < combine->_NumArgsA ; i++ ) {
181 const GLint op = combine->OperandA[i] - GL_SRC_ALPHA;
182
183 switch ( combine->SourceA[i] ) {
184 case GL_TEXTURE:
185 alpha_arg[i] = HC_XTA_Atex;
186 alpha_arg[i] += alpha_operand_modifier[op];
187 break;
188 case GL_CONSTANT:
189 alpha_arg[i] = HC_XTA_HTXnTBLRA;
190 constant_alpha = (op == 0)
191 ? env_color[3] : ~(env_color[3]) & 0x000000ff;
192 break;
193 case GL_PRIMARY_COLOR:
194 alpha_arg[i] = HC_XTA_Adif;
195 alpha_arg[i] += alpha_operand_modifier[op];
196 break;
197 case GL_PREVIOUS:
198 alpha_arg[i] = (unit == 0) ? HC_XTA_Adif : HC_XTA_Acur;
199 alpha_arg[i] += alpha_operand_modifier[op];
200 break;
201 }
202 }
203
204
205 /* On the Unichrome, all combine operations take on some form of:
206 *
207 * (xA * (xB op xC) + xBias) << xShift
208 *
209 * 'op' can be selected as add, subtract, min, max, or mask. The min, max
210 * and mask modes are currently unused. With the exception of DOT3, all
211 * standard GL_COMBINE modes can be implemented simply by selecting the
212 * correct inputs for A, B, C, and Bias and the correct operation for op.
213 */
214
215 color = HC_HTXnTBLCsat_MASK;
216 alpha = HC_HTXnTBLAsat_MASK;
217
218 switch( combine->ModeRGB ) {
219 /* Ca = 0, Cb = 0, Cc = 0, Cbias = arg0
220 */
221 case GL_REPLACE:
222 bias |= (color_arg[0] << INPUT_CBias_SHIFT);
223 ordered_constant_color[3] = constant_color[0];
224 break;
225
226 /* Ca = arg[0], Cb = arg[1], Cc = 0, Cbias = 0
227 */
228 case GL_MODULATE:
229 color |= (color_arg[0] << INPUT_A_SHIFT)
230 | (color_arg[1] << INPUT_B_SHIFT);
231
232 ordered_constant_color[0] = constant_color[0];
233 ordered_constant_color[1] = constant_color[1];
234 break;
235
236 /* Ca = 1.0, Cb = arg[0], Cc = 0, Cbias = arg[1]
237 */
238 case GL_ADD:
239 case GL_SUBTRACT:
240 if ( combine->ModeRGB == GL_SUBTRACT ) {
241 op |= HC_HTXnTBLCop_Sub;
242 }
243
244 color |= (color_arg[0] << INPUT_B_SHIFT)
245 | (CONST_ONE << INPUT_A_SHIFT);
246
247 bias |= (color_arg[1] << INPUT_CBias_SHIFT);
248 ordered_constant_color[1] = constant_color[0];
249 ordered_constant_color[3] = constant_color[1];
250 break;
251
252 /* Ca = 0, Cb = arg[0], Cc = arg[1], Cbias = 0.5
253 */
254 case GL_ADD_SIGNED:
255 color |= (color_arg[0] << INPUT_B_SHIFT)
256 | (color_arg[1] << INPUT_C_SHIFT);
257 bias |= HC_HTXnTBLCbias_HTXnTBLRC;
258 op |= HC_HTXnTBLCop_Sub;
259
260 ordered_constant_color[1] = constant_color[0];
261 ordered_constant_color[2] = constant_color[1];
262 ordered_constant_color[3] = 0x00808080;
263 break;
264
265 /* Ca = arg[2], Cb = arg[0], Cc = arg[1], Cbias = arg[1]
266 */
267 case GL_INTERPOLATE:
268 op |= HC_HTXnTBLCop_Sub;
269
270 color |= (color_arg[2] << INPUT_A_SHIFT) |
271 (color_arg[0] << INPUT_B_SHIFT) |
272 (color_arg[1] << INPUT_C_SHIFT);
273 bias |= (color_arg[1] << INPUT_CBias_SHIFT);
274
275 ordered_constant_color[0] = constant_color[2];
276 ordered_constant_color[1] = constant_color[0];
277 ordered_constant_color[2] = constant_color[1];
278 ordered_constant_color[3] = constant_color[1];
279 break;
280
281 /* At this point this code is completely untested. It appears that the
282 * Unichrome has the same limitation as the Radeon R100. The only
283 * supported post-scale when doing DOT3 bumpmapping is 1x.
284 */
285 case GL_DOT3_RGB_EXT:
286 case GL_DOT3_RGBA_EXT:
287 case GL_DOT3_RGB:
288 case GL_DOT3_RGBA:
289 c_shift = 2;
290 a_shift = 2;
291 color |= (color_arg[0] << INPUT_A_SHIFT) |
292 (color_arg[1] << INPUT_B_SHIFT);
293 op |= HC_HTXnTBLDOT4;
294 break;
295 }
296
297
298 /* The alpha blend stage has the annoying quirk of not having a
299 * hard-wired 0 input, like the color stage. As a result, we have
300 * to program the constant register with 0 and use that as our
301 * 0 input.
302 */
303
304 switch( combine->ModeA ) {
305 /* Aa = 0, Ab = 0, Ac = 0, Abias = arg0
306 */
307 case GL_REPLACE:
308 bias |= (alpha_arg[0] << INPUT_ABias_SHIFT);
309
310 alpha |= (HC_XTA_HTXnTBLRA << INPUT_A_SHIFT) |
311 (HC_XTA_HTXnTBLRA << INPUT_B_SHIFT) |
312 (HC_XTA_HTXnTBLRA << INPUT_C_SHIFT);
313 break;
314
315 /* Aa = arg[0], Ab = arg[1], Ac = 0, Abias = 0
316 */
317 case GL_MODULATE:
318 alpha |= (alpha_arg[1] << INPUT_A_SHIFT)
319 | (alpha_arg[0] << INPUT_B_SHIFT)
320 | (HC_XTA_HTXnTBLRA << INPUT_C_SHIFT);
321
322 bias |= (HC_XTA_HTXnTBLRA << INPUT_ABias_SHIFT);
323 break;
324
325 /* Aa = 0, Ab = arg[0], Ac = 0, Abias = arg[1]
326 */
327 case GL_ADD:
328 case GL_SUBTRACT:
329 if ( combine->ModeA == GL_SUBTRACT ) {
330 op |= HC_HTXnTBLAop_Sub;
331 }
332
333 alpha |= (HC_XTA_HTXnTBLRA << INPUT_A_SHIFT) |
334 (alpha_arg[0] << INPUT_B_SHIFT) |
335 (HC_XTA_HTXnTBLRA << INPUT_C_SHIFT);
336 bias |= (alpha_arg[1] << INPUT_ABias_SHIFT);
337 break;
338
339 /* Aa = 0, Ab = arg[0], Ac = arg[1], Abias = 0.5
340 */
341 case GL_ADD_SIGNED:
342 op |= HC_HTXnTBLAop_Sub;
343
344 alpha |= (alpha_arg[0] << INPUT_B_SHIFT)
345 | (alpha_arg[1] << INPUT_C_SHIFT);
346 bias |= (HC_XTA_HTXnTBLRA << INPUT_ABias_SHIFT);
347
348 bias_alpha = 0x00000080;
349 break;
350
351 /* Aa = arg[2], Ab = arg[0], Ac = arg[1], Abias = arg[1]
352 */
353 case GL_INTERPOLATE:
354 op |= HC_HTXnTBLAop_Sub;
355
356 alpha |= (alpha_arg[2] << INPUT_A_SHIFT) |
357 (alpha_arg[0] << INPUT_B_SHIFT) |
358 (alpha_arg[1] << INPUT_C_SHIFT);
359 bias |= (alpha_arg[1] << INPUT_ABias_SHIFT);
360 break;
361 }
362
363
364 op |= c_shift_table[ c_shift ] | a_shift_table[ a_shift ];
365
366
367 if ( unit == 0 ) {
368 vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
369
370 vmesa->regHTXnTBLCsat_0 = color;
371 vmesa->regHTXnTBLAsat_0 = alpha;
372 vmesa->regHTXnTBLCop_0 = op | bias;
373 vmesa->regHTXnTBLRAa_0 = bias_alpha | (constant_alpha << 16);
374
375 vmesa->regHTXnTBLRCa_0 = ordered_constant_color[0];
376 vmesa->regHTXnTBLRCb_0 = ordered_constant_color[1];
377 vmesa->regHTXnTBLRCc_0 = ordered_constant_color[2];
378 vmesa->regHTXnTBLRCbias_0 = ordered_constant_color[3];
379 }
380 else {
381 vmesa->regHTXnTBLMPfog_1 = HC_HTXnTBLMPfog_Fog;
382
383 vmesa->regHTXnTBLCsat_1 = color;
384 vmesa->regHTXnTBLAsat_1 = alpha;
385 vmesa->regHTXnTBLCop_1 = op | bias;
386 vmesa->regHTXnTBLRAa_1 = bias_alpha | (constant_alpha << 16);
387
388 vmesa->regHTXnTBLRCa_1 = ordered_constant_color[0];
389 vmesa->regHTXnTBLRCb_1 = ordered_constant_color[1];
390 vmesa->regHTXnTBLRCc_1 = ordered_constant_color[2];
391 vmesa->regHTXnTBLRCbias_1 = ordered_constant_color[3];
392 }
393 }
394