The alpha post-scale and the RGB post-scale were mistakenly reversed.
[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_vb.h"
46 #include "via_tris.h"
47 #include "via_ioctl.h"
48
49 #include "swrast/swrast.h"
50 #include "array_cache/acache.h"
51 #include "tnl/tnl.h"
52 #include "swrast_setup/swrast_setup.h"
53
54 #include "tnl/t_pipeline.h"
55
56 #define VIA_USE_ALPHA (HC_XTC_Adif - HC_XTC_Dif)
57
58 #define INPUT_A_SHIFT 14
59 #define INPUT_B_SHIFT 7
60 #define INPUT_C_SHIFT 0
61 #define INPUT_BiasC_SHIFT 14
62 #define INPUT_BiasA_SHIFT 3
63
64 #define CONST_ONE (HC_XTC_0 | HC_XTC_InvTOPC)
65
66 static const unsigned color_operand_modifier[4] = {
67 0,
68 HC_XTC_InvTOPC,
69 VIA_USE_ALPHA,
70 VIA_USE_ALPHA | HC_XTC_InvTOPC,
71 };
72
73 static const unsigned alpha_operand_modifier[2] = {
74 0, HC_XTA_InvTOPA
75 };
76
77 static const unsigned c_shift_table[3] = {
78 HC_HTXnTBLCshift_No, HC_HTXnTBLCshift_1, HC_HTXnTBLCshift_2
79 };
80
81 static const unsigned a_shift_table[3] = {
82 HC_HTXnTBLAshift_No, HC_HTXnTBLAshift_1, HC_HTXnTBLAshift_2
83 };
84
85
86 /**
87 * Calculate the hardware state for the specified texture combine mode
88 *
89 * \bug
90 * For the alpha combine, \c GL_CONSTANT is still probably wrong.
91 *
92 * \bug
93 * All forms of DOT3 bumpmapping are completely untested, and are most
94 * likely wrong.
95 *
96 * \bug
97 * This code still fails progs/demos/texenv for all modes with \c GL_ALPHA
98 * textures. This was also the case with the code that Via supplied. It
99 * also fails for \c GL_REPLACE with \c GL_RGBA textures. Everything else
100 * that texenv tests looks good.
101 */
102 void
103 viaTexCombineState( viaContextPtr vmesa,
104 const struct gl_tex_env_combine_state * combine,
105 unsigned unit )
106 {
107 unsigned color_arg[3];
108 unsigned alpha_arg[3];
109 unsigned color = 0;
110 unsigned alpha = 0;
111 unsigned bias = 0;
112 unsigned op = 0;
113 unsigned a_shift = combine->ScaleShiftA;
114 unsigned c_shift = combine->ScaleShiftRGB;
115 unsigned i;
116 unsigned constant_color[3];
117 unsigned ordered_constant_color[4];
118 unsigned constant_alpha = 0;
119 unsigned bias_alpha = 0;
120 const struct gl_texture_unit const * texUnit = & vmesa->glCtx->Texture.Unit[unit];
121 unsigned env_color[4];
122
123
124 CLAMPED_FLOAT_TO_UBYTE(env_color[0], texUnit->EnvColor[0]);
125 CLAMPED_FLOAT_TO_UBYTE(env_color[1], texUnit->EnvColor[1]);
126 CLAMPED_FLOAT_TO_UBYTE(env_color[2], texUnit->EnvColor[2]);
127 CLAMPED_FLOAT_TO_UBYTE(env_color[3], texUnit->EnvColor[3]);
128
129 (void) memset( constant_color, 0, sizeof( constant_color ) );
130 (void) memset( ordered_constant_color, 0, sizeof( ordered_constant_color ) );
131
132 for ( i = 0 ; i < combine->_NumArgsRGB ; i++ ) {
133 const GLint op = combine->OperandRGB[i] - GL_SRC_COLOR;
134
135 switch ( combine->SourceRGB[i] ) {
136 case GL_TEXTURE:
137 color_arg[i] = HC_XTC_Tex;
138 color_arg[i] += color_operand_modifier[op];
139 break;
140 case GL_CONSTANT:
141 color_arg[i] = HC_XTC_HTXnTBLRC;
142
143 switch( op ) {
144 case 0:
145 constant_color[i] = ((env_color[0] << 16)
146 | (env_color[1] << 8)
147 | env_color[2]);
148 break;
149 case 1:
150 constant_color[i] = ~((env_color[0] << 16)
151 | (env_color[1] << 8)
152 | env_color[2]) & 0x00ffffff;
153 break;
154 case 2:
155 constant_color[i] = ((env_color[3] << 16)
156 | (env_color[3] << 8)
157 | env_color[3]);
158 break;
159 case 3:
160 constant_color[i] = ~((env_color[3] << 16)
161 | (env_color[3] << 8)
162 | env_color[3]) & 0x00ffffff;
163 break;
164 }
165 break;
166 case GL_PRIMARY_COLOR:
167 color_arg[i] = HC_XTC_Dif;
168 color_arg[i] += color_operand_modifier[op];
169 break;
170 case GL_PREVIOUS:
171 color_arg[i] = (unit == 0) ? HC_XTC_Dif : HC_XTC_Cur;
172 color_arg[i] += color_operand_modifier[op];
173 break;
174 }
175 }
176
177 for ( i = 0 ; i < combine->_NumArgsA ; i++ ) {
178 const GLint op = combine->OperandA[i] - GL_SRC_ALPHA;
179
180 switch ( combine->SourceA[i] ) {
181 case GL_TEXTURE:
182 alpha_arg[i] = HC_XTA_Atex;
183 alpha_arg[i] += alpha_operand_modifier[op];
184 break;
185 case GL_CONSTANT:
186 alpha_arg[i] = HC_XTA_HTXnTBLRA;
187 constant_alpha = (op == 0)
188 ? env_color[3] : ~(env_color[3]) & 0x000000ff;
189 break;
190 case GL_PRIMARY_COLOR:
191 alpha_arg[i] = HC_XTA_Adif;
192 alpha_arg[i] += alpha_operand_modifier[op];
193 break;
194 case GL_PREVIOUS:
195 alpha_arg[i] = (unit == 0) ? HC_XTA_Adif : HC_XTA_Acur;
196 alpha_arg[i] += alpha_operand_modifier[op];
197 break;
198 }
199 }
200
201
202 /* On the Unichrome, all combine operations take on some form of:
203 *
204 * A * (B op Bias) + C
205 *
206 * 'op' can be selected as add, subtract, min, max, or mask. The min, max
207 * and mask modes are currently unused. With the exception of DOT3, all
208 * standard GL_COMBINE modes can be implemented simply by selecting the
209 * correct inputs for A, B, C, and Bias and the correct operation for op.
210 */
211
212 color = HC_HTXnTBLCsat_MASK;
213 alpha = HC_HTXnTBLAsat_MASK;
214
215 switch( combine->ModeRGB ) {
216 /* A = 0, B = 0, C = arg0, Bias = 0
217 */
218 case GL_REPLACE:
219 bias |= (color_arg[0] << INPUT_BiasC_SHIFT);
220 ordered_constant_color[3] = constant_color[0];
221 break;
222
223 /* A = arg[0], B = arg[1], C = 0, Bias = 0
224 */
225 case GL_MODULATE:
226 color |= (color_arg[0] << INPUT_A_SHIFT)
227 | (color_arg[1] << INPUT_B_SHIFT);
228
229 ordered_constant_color[0] = constant_color[0];
230 ordered_constant_color[1] = constant_color[1];
231 break;
232
233 /* A = 1.0, B = arg[0], C = 0, Bias = arg[1]
234 */
235 case GL_ADD:
236 case GL_SUBTRACT:
237 if ( combine->ModeRGB == GL_SUBTRACT ) {
238 op |= HC_HTXnTBLCop_Sub;
239 }
240
241 color |= (color_arg[0] << INPUT_B_SHIFT)
242 | (CONST_ONE << INPUT_A_SHIFT);
243
244 bias |= (color_arg[1] << INPUT_BiasC_SHIFT);
245 ordered_constant_color[1] = constant_color[0];
246 ordered_constant_color[3] = constant_color[1];
247 break;
248
249 /* A = 0, B = arg[0], C = arg[1], Bias = 0.5
250 */
251 case GL_ADD_SIGNED:
252 color |= (color_arg[0] << INPUT_B_SHIFT)
253 | (color_arg[1] << INPUT_C_SHIFT);
254 bias |= HC_HTXnTBLCbias_HTXnTBLRC;
255 op |= HC_HTXnTBLCop_Sub;
256
257 ordered_constant_color[1] = constant_color[0];
258 ordered_constant_color[2] = constant_color[1];
259 ordered_constant_color[3] = 0x00808080;
260 break;
261
262 /* A = arg[2], B = arg[0], C = arg[1], Bias = arg[1]
263 */
264 case GL_INTERPOLATE:
265 op |= HC_HTXnTBLCop_Sub;
266
267 color |= (color_arg[2] << INPUT_A_SHIFT) |
268 (color_arg[0] << INPUT_B_SHIFT) |
269 (color_arg[1] << INPUT_C_SHIFT);
270 bias |= (color_arg[1] << INPUT_BiasC_SHIFT);
271
272 ordered_constant_color[0] = constant_color[2];
273 ordered_constant_color[1] = constant_color[0];
274 ordered_constant_color[2] = constant_color[1];
275 ordered_constant_color[3] = constant_color[1];
276 break;
277
278 /* At this point this code is completely untested. It appears that the
279 * Unichrome has the same limitation as the Radeon R100. The only
280 * supported post-scale when doing DOT3 bumpmapping is 1x.
281 */
282 case GL_DOT3_RGB_EXT:
283 case GL_DOT3_RGBA_EXT:
284 case GL_DOT3_RGB:
285 case GL_DOT3_RGBA:
286 c_shift = 2;
287 a_shift = 2;
288 color |= (color_arg[0] << INPUT_A_SHIFT) |
289 (color_arg[1] << INPUT_B_SHIFT);
290 op |= HC_HTXnTBLDOT4;
291 break;
292 }
293
294
295 /* The alpha blend stage has the annoying quirk of not having a
296 * hard-wired 0 input, like the color stage. As a result, we have
297 * to program the constant register with 0 and use that as our
298 * 0 input.
299 */
300
301 switch( combine->ModeA ) {
302 /* A = 0, B = 0, C = 0, Bias = arg0
303 */
304 case GL_REPLACE:
305 bias |= (alpha_arg[0] << INPUT_BiasA_SHIFT);
306
307 alpha |= (HC_XTA_HTXnTBLRA << INPUT_A_SHIFT) |
308 (HC_XTA_HTXnTBLRA << INPUT_B_SHIFT) |
309 (HC_XTA_HTXnTBLRA << INPUT_C_SHIFT);
310 break;
311
312 /* A = arg[0], B = arg[1], C = 0, Bias = 0
313 */
314 case GL_MODULATE:
315 alpha |= (alpha_arg[1] << INPUT_A_SHIFT)
316 | (alpha_arg[0] << INPUT_B_SHIFT)
317 | (HC_XTA_HTXnTBLRA << INPUT_C_SHIFT);
318
319 bias |= (HC_XTA_HTXnTBLRA << INPUT_BiasA_SHIFT);
320 break;
321
322 /* A = 0, B = arg[0], C = 0, Bias = arg[1]
323 */
324 case GL_ADD:
325 case GL_SUBTRACT:
326 if ( combine->ModeA == GL_SUBTRACT ) {
327 op |= HC_HTXnTBLAop_Sub;
328 }
329
330 alpha |= (HC_XTA_HTXnTBLRA << INPUT_A_SHIFT) |
331 (alpha_arg[0] << INPUT_B_SHIFT) |
332 (HC_XTA_HTXnTBLRA << INPUT_C_SHIFT);
333 bias |= (alpha_arg[1] << INPUT_BiasA_SHIFT);
334 break;
335
336 /* A = 0, B = arg[0], C = arg[1], Bias = 0.5
337 */
338 case GL_ADD_SIGNED:
339 op |= HC_HTXnTBLAop_Sub;
340
341 alpha |= (alpha_arg[0] << INPUT_B_SHIFT)
342 | (alpha_arg[1] << INPUT_C_SHIFT);
343 bias |= (HC_XTA_HTXnTBLRA << INPUT_BiasA_SHIFT);
344
345 bias_alpha = 0x00000080;
346 break;
347
348 /* A = arg[2], B = arg[0], C = arg[1], Bias = arg[1]
349 */
350 case GL_INTERPOLATE:
351 op |= HC_HTXnTBLAop_Sub;
352
353 alpha |= (alpha_arg[2] << INPUT_A_SHIFT) |
354 (alpha_arg[0] << INPUT_B_SHIFT) |
355 (alpha_arg[1] << INPUT_C_SHIFT);
356 bias |= (alpha_arg[1] << INPUT_BiasA_SHIFT);
357 break;
358 }
359
360
361 op |= c_shift_table[ c_shift ] | a_shift_table[ a_shift ];
362
363
364 if ( unit == 0 ) {
365 vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
366
367 vmesa->regHTXnTBLCsat_0 = color;
368 vmesa->regHTXnTBLAsat_0 = alpha;
369 vmesa->regHTXnTBLCop_0 = op | bias;
370 vmesa->regHTXnTBLRAa_0 = bias_alpha | (constant_alpha << 16);
371
372 vmesa->regHTXnTBLRCa_0 = ordered_constant_color[0];
373 vmesa->regHTXnTBLRCb_0 = ordered_constant_color[1];
374 vmesa->regHTXnTBLRCc_0 = ordered_constant_color[2];
375 vmesa->regHTXnTBLRCbias_0 = ordered_constant_color[3];
376 }
377 else {
378 vmesa->regHTXnTBLMPfog_1 = HC_HTXnTBLMPfog_Fog;
379
380 vmesa->regHTXnTBLCsat_1 = color;
381 vmesa->regHTXnTBLAsat_1 = alpha;
382 vmesa->regHTXnTBLCop_1 = op | bias;
383 vmesa->regHTXnTBLRAa_1 = bias_alpha | (constant_alpha << 16);
384 }
385 }
386