2 * (C) Copyright IBM Corporation 2004
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:
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
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.
26 * \file via_texcombine.c
27 * Calculate texture combine hardware state.
29 * \author Ian Romanick <idr@us.ibm.com>
34 #include "main/glheader.h"
35 #include "main/context.h"
36 #include "main/macros.h"
37 #include "main/colormac.h"
38 #include "main/enums.h"
40 #include "via_context.h"
42 #include "via_3d_reg.h"
45 #define VIA_USE_ALPHA (HC_XTC_Adif - HC_XTC_Dif)
47 #define INPUT_A_SHIFT 14
48 #define INPUT_B_SHIFT 7
49 #define INPUT_C_SHIFT 0
50 #define INPUT_CBias_SHIFT 14
52 #define CONST_ONE (HC_XTC_0 | HC_XTC_InvTOPC)
54 static const unsigned color_operand_modifier
[4] = {
58 VIA_USE_ALPHA
| HC_XTC_InvTOPC
,
61 static const unsigned alpha_operand_modifier
[2] = {
65 static const unsigned bias_alpha_operand_modifier
[2] = {
66 0, HC_HTXnTBLAbias_Inv
70 static const unsigned c_shift_table
[3] = {
71 HC_HTXnTBLCshift_No
, HC_HTXnTBLCshift_1
, HC_HTXnTBLCshift_2
74 static const unsigned a_shift_table
[3] = {
75 HC_HTXnTBLAshift_No
, HC_HTXnTBLAshift_1
, HC_HTXnTBLAshift_2
80 * Calculate the hardware state for the specified texture combine mode
83 * All forms of DOT3 bumpmapping are completely untested, and are most
84 * likely wrong. KW: Looks like it will never be quite right as the
85 * hardware seems to experience overflow in color calculation at the
86 * 4x shift levels, which need to be programed for DOT3. Maybe newer
87 * hardware fixes these issues.
90 * KW: needs attention to the case where texunit 1 is enabled but
94 viaTexCombineState( struct via_context
*vmesa
,
95 const struct gl_tex_env_combine_state
* combine
,
98 unsigned color_arg
[3];
99 unsigned alpha_arg
[3];
100 unsigned bias_alpha_arg
[3];
101 unsigned color
= HC_HTXnTBLCsat_MASK
;
102 unsigned alpha
= HC_HTXnTBLAsat_MASK
;
105 unsigned a_shift
= combine
->ScaleShiftA
;
106 unsigned c_shift
= combine
->ScaleShiftRGB
;
108 unsigned constant_color
[3];
109 unsigned ordered_constant_color
[4];
110 unsigned constant_alpha
[3];
111 unsigned bias_alpha
= 0;
112 unsigned abc_alpha
= 0;
113 const struct gl_texture_unit
* texUnit
=
114 &vmesa
->glCtx
->Texture
.Unit
[unit
];
115 unsigned env_color
[4];
117 /* It seems that the color clamping can be overwhelmed at the 4x
118 * scale settings, necessitating this fallback:
120 if (c_shift
== 2 || a_shift
== 2) {
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]);
129 (void) memset( constant_color
, 0, sizeof( constant_color
) );
130 (void) memset( ordered_constant_color
, 0, sizeof( ordered_constant_color
) );
131 (void) memset( constant_alpha
, 0, sizeof( constant_alpha
) );
133 for ( i
= 0 ; i
< combine
->_NumArgsRGB
; i
++ ) {
134 const GLint op
= combine
->OperandRGB
[i
] - GL_SRC_COLOR
;
136 switch ( combine
->SourceRGB
[i
] ) {
138 color_arg
[i
] = HC_XTC_Tex
;
139 color_arg
[i
] += color_operand_modifier
[op
];
142 color_arg
[i
] = HC_XTC_HTXnTBLRC
;
145 case 0: /* GL_SRC_COLOR */
146 constant_color
[i
] = ((env_color
[0] << 16) |
147 (env_color
[1] << 8) |
150 case 1: /* GL_ONE_MINUS_SRC_COLOR */
151 constant_color
[i
] = ~((env_color
[0] << 16) |
152 (env_color
[1] << 8) |
153 env_color
[2]) & 0x00ffffff;
155 case 2: /* GL_SRC_ALPHA */
156 constant_color
[i
] = ((env_color
[3] << 16) |
157 (env_color
[3] << 8) |
160 case 3: /* GL_ONE_MINUS_SRC_ALPHA */
161 constant_color
[i
] = ~((env_color
[3] << 16) |
162 (env_color
[3] << 8) |
163 env_color
[3]) & 0x00ffffff;
167 case GL_PRIMARY_COLOR
:
168 color_arg
[i
] = HC_XTC_Dif
;
169 color_arg
[i
] += color_operand_modifier
[op
];
172 color_arg
[i
] = (unit
== 0) ? HC_XTC_Dif
: HC_XTC_Cur
;
173 color_arg
[i
] += color_operand_modifier
[op
];
179 /* On the Unichrome, all combine operations take on some form of:
181 * (xA * (xB op xC) + xBias) << xShift
183 * 'op' can be selected as add, subtract, min, max, or mask. The min, max
184 * and mask modes are currently unused. With the exception of DOT3, all
185 * standard GL_COMBINE modes can be implemented simply by selecting the
186 * correct inputs for A, B, C, and Bias and the correct operation for op.
188 * NOTE: xBias (when read from the constant registers) is signed,
189 * and scaled to fit -255..255 in 8 bits, ie 0x1 == 2.
192 switch( combine
->ModeRGB
) {
193 /* Ca = 1.0, Cb = arg0, Cc = 0, Cbias = 0
196 color
|= ((CONST_ONE
<< INPUT_A_SHIFT
) |
197 (color_arg
[0] << INPUT_B_SHIFT
));
199 ordered_constant_color
[1] = constant_color
[0];
202 /* Ca = arg[0], Cb = arg[1], Cc = 0, Cbias = 0
205 color
|= ((color_arg
[0] << INPUT_A_SHIFT
) |
206 (color_arg
[1] << INPUT_B_SHIFT
));
208 ordered_constant_color
[0] = constant_color
[0];
209 ordered_constant_color
[1] = constant_color
[1];
212 /* Ca = 1.0, Cb = arg[0], Cc = arg[1], Cbias = 0
216 if ( combine
->ModeRGB
== GL_SUBTRACT
) {
217 op
|= HC_HTXnTBLCop_Sub
;
220 color
|= ((CONST_ONE
<< INPUT_A_SHIFT
) |
221 (color_arg
[0] << INPUT_B_SHIFT
) |
222 (color_arg
[1] << INPUT_C_SHIFT
));
224 ordered_constant_color
[1] = constant_color
[0];
225 ordered_constant_color
[2] = constant_color
[1];
228 /* Ca = 1.0, Cb = arg[0], Cc = arg[1], Cbias = -0.5
231 color
|= ((CONST_ONE
<< INPUT_A_SHIFT
) |
232 (color_arg
[0] << INPUT_B_SHIFT
) |
233 (color_arg
[1] << INPUT_C_SHIFT
));
235 bias
|= HC_HTXnTBLCbias_HTXnTBLRC
;
237 ordered_constant_color
[1] = constant_color
[0];
238 ordered_constant_color
[2] = constant_color
[1];
239 ordered_constant_color
[3] = 0x00bfbfbf; /* -.5 */
242 /* Ca = arg[2], Cb = arg[0], Cc = arg[1], Cbias = arg[1]
245 op
|= HC_HTXnTBLCop_Sub
;
247 color
|= ((color_arg
[2] << INPUT_A_SHIFT
) |
248 (color_arg
[0] << INPUT_B_SHIFT
) |
249 (color_arg
[1] << INPUT_C_SHIFT
));
251 bias
|= (color_arg
[1] << INPUT_CBias_SHIFT
);
253 ordered_constant_color
[0] = constant_color
[2];
254 ordered_constant_color
[1] = constant_color
[0];
255 ordered_constant_color
[2] = constant_color
[1];
256 ordered_constant_color
[3] = (constant_color
[1] >> 1) & 0x7f7f7f;
260 /* At this point this code is completely untested. It appears that the
261 * Unichrome has the same limitation as the Radeon R100. The only
262 * supported post-scale when doing DOT3 bumpmapping is 1x.
264 case GL_DOT3_RGB_EXT
:
265 case GL_DOT3_RGBA_EXT
:
270 color
|= ((color_arg
[0] << INPUT_A_SHIFT
) |
271 (color_arg
[1] << INPUT_B_SHIFT
));
272 op
|= HC_HTXnTBLDOT4
;
284 /* The alpha blend stage has the annoying quirk of not having a
285 * hard-wired 0 input, like the color stage. As a result, we have
286 * to program the constant register with 0 and use that as our
289 * (xA * (xB op xC) + xBias) << xShift
293 for ( i
= 0 ; i
< combine
->_NumArgsA
; i
++ ) {
294 const GLint op
= combine
->OperandA
[i
] - GL_SRC_ALPHA
;
296 switch ( combine
->SourceA
[i
] ) {
298 alpha_arg
[i
] = HC_XTA_Atex
;
299 alpha_arg
[i
] += alpha_operand_modifier
[op
];
300 bias_alpha_arg
[i
] = HC_HTXnTBLAbias_Atex
;
301 bias_alpha_arg
[i
] += bias_alpha_operand_modifier
[op
];
304 alpha_arg
[i
] = HC_XTA_HTXnTBLRA
;
305 bias_alpha_arg
[i
] = HC_HTXnTBLAbias_HTXnTBLRAbias
;
306 constant_alpha
[i
] = (op
== 0) ? env_color
[3] : (~env_color
[3] & 0xff);
308 case GL_PRIMARY_COLOR
:
309 alpha_arg
[i
] = HC_XTA_Adif
;
310 alpha_arg
[i
] += alpha_operand_modifier
[op
];
311 bias_alpha_arg
[i
] = HC_HTXnTBLAbias_Adif
;
312 bias_alpha_arg
[i
] += bias_alpha_operand_modifier
[op
];
315 alpha_arg
[i
] = (unit
== 0) ? HC_XTA_Adif
: HC_XTA_Acur
;
316 alpha_arg
[i
] += alpha_operand_modifier
[op
];
317 bias_alpha_arg
[i
] = (unit
== 0 ?
318 HC_HTXnTBLAbias_Adif
:
319 HC_HTXnTBLAbias_Acur
);
320 bias_alpha_arg
[i
] += bias_alpha_operand_modifier
[op
];
325 switch( combine
->ModeA
) {
326 /* Aa = 0, Ab = 0, Ac = 0, Abias = arg0
329 alpha
|= ((HC_XTA_HTXnTBLRA
<< INPUT_A_SHIFT
) |
330 (HC_XTA_HTXnTBLRA
<< INPUT_B_SHIFT
) |
331 (HC_XTA_HTXnTBLRA
<< INPUT_C_SHIFT
));
334 bias
|= bias_alpha_arg
[0];
335 bias_alpha
= constant_alpha
[0] >> 1;
338 /* Aa = arg[0], Ab = arg[1], Ac = 0, Abias = 0
341 alpha
|= ((alpha_arg
[1] << INPUT_A_SHIFT
) |
342 (alpha_arg
[0] << INPUT_B_SHIFT
) |
343 (HC_XTA_HTXnTBLRA
<< INPUT_C_SHIFT
));
345 abc_alpha
= ((constant_alpha
[1] << HC_HTXnTBLRAa_SHIFT
) |
346 (constant_alpha
[0] << HC_HTXnTBLRAb_SHIFT
) |
347 (0 << HC_HTXnTBLRAc_SHIFT
));
349 bias
|= HC_HTXnTBLAbias_HTXnTBLRAbias
;
353 /* Aa = 1.0, Ab = arg[0], Ac = arg[1], Abias = 0
357 if ( combine
->ModeA
== GL_SUBTRACT
) {
358 op
|= HC_HTXnTBLAop_Sub
;
361 alpha
|= ((HC_XTA_HTXnTBLRA
<< INPUT_A_SHIFT
) |
362 (alpha_arg
[0] << INPUT_B_SHIFT
) |
363 (alpha_arg
[1] << INPUT_C_SHIFT
));
365 abc_alpha
= ((0xff << HC_HTXnTBLRAa_SHIFT
) |
366 (constant_alpha
[0] << HC_HTXnTBLRAb_SHIFT
) |
367 (constant_alpha
[1] << HC_HTXnTBLRAc_SHIFT
));
369 bias
|= HC_HTXnTBLAbias_HTXnTBLRAbias
;
373 /* Aa = 1.0, Ab = arg[0], Ac = arg[1], Abias = -0.5
376 alpha
|= ((HC_XTA_HTXnTBLRA
<< INPUT_A_SHIFT
) |
377 (alpha_arg
[0] << INPUT_B_SHIFT
) |
378 (alpha_arg
[1] << INPUT_C_SHIFT
));
379 abc_alpha
= ((0xff << HC_HTXnTBLRAa_SHIFT
) |
380 (constant_alpha
[0] << HC_HTXnTBLRAb_SHIFT
) |
381 (constant_alpha
[1] << HC_HTXnTBLRAc_SHIFT
));
383 bias
|= HC_HTXnTBLAbias_HTXnTBLRAbias
;
387 /* Aa = arg[2], Ab = arg[0], Ac = arg[1], Abias = arg[1]
390 op
|= HC_HTXnTBLAop_Sub
;
392 alpha
|= ((alpha_arg
[2] << INPUT_A_SHIFT
) |
393 (alpha_arg
[0] << INPUT_B_SHIFT
) |
394 (alpha_arg
[1] << INPUT_C_SHIFT
));
395 abc_alpha
= ((constant_alpha
[2] << HC_HTXnTBLRAa_SHIFT
) |
396 (constant_alpha
[0] << HC_HTXnTBLRAb_SHIFT
) |
397 (constant_alpha
[1] << HC_HTXnTBLRAc_SHIFT
));
399 bias
|= bias_alpha_arg
[1];
400 bias_alpha
= constant_alpha
[1] >> 1;
405 op
|= c_shift_table
[ c_shift
] | a_shift_table
[ a_shift
];
408 vmesa
->regHTXnTBLMPfog
[unit
] = HC_HTXnTBLMPfog_Fog
;
410 vmesa
->regHTXnTBLCsat
[unit
] = color
;
411 vmesa
->regHTXnTBLAsat
[unit
] = alpha
;
412 vmesa
->regHTXnTBLCop
[unit
] = op
| bias
;
413 vmesa
->regHTXnTBLRAa
[unit
] = abc_alpha
;
414 vmesa
->regHTXnTBLRFog
[unit
] = bias_alpha
;
416 vmesa
->regHTXnTBLRCa
[unit
] = ordered_constant_color
[0];
417 vmesa
->regHTXnTBLRCb
[unit
] = ordered_constant_color
[1];
418 vmesa
->regHTXnTBLRCc
[unit
] = ordered_constant_color
[2];
419 vmesa
->regHTXnTBLRCbias
[unit
] = ordered_constant_color
[3];