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>
42 #include "via_context.h"
43 #include "via_state.h"
47 #include "via_ioctl.h"
49 #include "swrast/swrast.h"
50 #include "array_cache/acache.h"
52 #include "swrast_setup/swrast_setup.h"
54 #include "tnl/t_pipeline.h"
56 #define VIA_USE_ALPHA (HC_XTC_Adif - HC_XTC_Dif)
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
64 #define CONST_ONE (HC_XTC_0 | HC_XTC_InvTOPC)
66 static const unsigned color_operand_modifier
[4] = {
70 VIA_USE_ALPHA
| HC_XTC_InvTOPC
,
73 static const unsigned alpha_operand_modifier
[2] = {
77 static const unsigned c_shift_table
[3] = {
78 HC_HTXnTBLCshift_No
, HC_HTXnTBLCshift_1
, HC_HTXnTBLCshift_2
81 static const unsigned a_shift_table
[3] = {
82 HC_HTXnTBLAshift_No
, HC_HTXnTBLAshift_1
, HC_HTXnTBLAshift_2
87 * Calculate the hardware state for the specified texture combine mode
90 * For the alpha combine, \c GL_CONSTANT is still probably wrong.
93 * All forms of DOT3 bumpmapping are completely untested, and are most
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.
103 viaTexCombineState( viaContextPtr vmesa
,
104 const struct gl_tex_env_combine_state
* combine
,
107 unsigned color_arg
[3];
108 unsigned alpha_arg
[3];
113 unsigned a_shift
= combine
->ScaleShiftA
;
114 unsigned c_shift
= combine
->ScaleShiftRGB
;
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];
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
) );
132 for ( i
= 0 ; i
< combine
->_NumArgsRGB
; i
++ ) {
133 const GLint op
= combine
->OperandRGB
[i
] - GL_SRC_COLOR
;
135 switch ( combine
->SourceRGB
[i
] ) {
137 color_arg
[i
] = HC_XTC_Tex
;
138 color_arg
[i
] += color_operand_modifier
[op
];
141 color_arg
[i
] = HC_XTC_HTXnTBLRC
;
145 constant_color
[i
] = ((env_color
[0] << 16)
146 | (env_color
[1] << 8)
150 constant_color
[i
] = ~((env_color
[0] << 16)
151 | (env_color
[1] << 8)
152 | env_color
[2]) & 0x00ffffff;
155 constant_color
[i
] = ((env_color
[3] << 16)
156 | (env_color
[3] << 8)
160 constant_color
[i
] = ~((env_color
[3] << 16)
161 | (env_color
[3] << 8)
162 | env_color
[3]) & 0x00ffffff;
166 case GL_PRIMARY_COLOR
:
167 color_arg
[i
] = HC_XTC_Dif
;
168 color_arg
[i
] += color_operand_modifier
[op
];
171 color_arg
[i
] = (unit
== 0) ? HC_XTC_Dif
: HC_XTC_Cur
;
172 color_arg
[i
] += color_operand_modifier
[op
];
177 for ( i
= 0 ; i
< combine
->_NumArgsA
; i
++ ) {
178 const GLint op
= combine
->OperandA
[i
] - GL_SRC_ALPHA
;
180 switch ( combine
->SourceA
[i
] ) {
182 alpha_arg
[i
] = HC_XTA_Atex
;
183 alpha_arg
[i
] += alpha_operand_modifier
[op
];
186 alpha_arg
[i
] = HC_XTA_HTXnTBLRA
;
187 constant_alpha
= (op
== 0)
188 ? env_color
[3] : ~(env_color
[3]) & 0x000000ff;
190 case GL_PRIMARY_COLOR
:
191 alpha_arg
[i
] = HC_XTA_Adif
;
192 alpha_arg
[i
] += alpha_operand_modifier
[op
];
195 alpha_arg
[i
] = (unit
== 0) ? HC_XTA_Adif
: HC_XTA_Acur
;
196 alpha_arg
[i
] += alpha_operand_modifier
[op
];
202 /* On the Unichrome, all combine operations take on some form of:
204 * A * (B op Bias) + C
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.
212 color
= HC_HTXnTBLCsat_MASK
;
213 alpha
= HC_HTXnTBLAsat_MASK
;
215 switch( combine
->ModeRGB
) {
216 /* A = 0, B = 0, C = arg0, Bias = 0
219 bias
|= (color_arg
[0] << INPUT_BiasC_SHIFT
);
220 ordered_constant_color
[3] = constant_color
[0];
223 /* A = arg[0], B = arg[1], C = 0, Bias = 0
226 color
|= (color_arg
[0] << INPUT_A_SHIFT
)
227 | (color_arg
[1] << INPUT_B_SHIFT
);
229 ordered_constant_color
[0] = constant_color
[0];
230 ordered_constant_color
[1] = constant_color
[1];
233 /* A = 1.0, B = arg[0], C = 0, Bias = arg[1]
237 if ( combine
->ModeRGB
== GL_SUBTRACT
) {
238 op
|= HC_HTXnTBLCop_Sub
;
241 color
|= (color_arg
[0] << INPUT_B_SHIFT
)
242 | (CONST_ONE
<< INPUT_A_SHIFT
);
244 bias
|= (color_arg
[1] << INPUT_BiasC_SHIFT
);
245 ordered_constant_color
[1] = constant_color
[0];
246 ordered_constant_color
[3] = constant_color
[1];
249 /* A = 0, B = arg[0], C = arg[1], Bias = 0.5
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
;
257 ordered_constant_color
[1] = constant_color
[0];
258 ordered_constant_color
[2] = constant_color
[1];
259 ordered_constant_color
[3] = 0x00808080;
262 /* A = arg[2], B = arg[0], C = arg[1], Bias = arg[1]
265 op
|= HC_HTXnTBLCop_Sub
;
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
);
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];
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.
282 case GL_DOT3_RGB_EXT
:
283 case GL_DOT3_RGBA_EXT
:
288 color
|= (color_arg
[0] << INPUT_A_SHIFT
) |
289 (color_arg
[1] << INPUT_B_SHIFT
);
290 op
|= HC_HTXnTBLDOT4
;
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
301 switch( combine
->ModeA
) {
302 /* A = 0, B = 0, C = 0, Bias = arg0
305 bias
|= (alpha_arg
[0] << INPUT_BiasA_SHIFT
);
307 alpha
|= (HC_XTA_HTXnTBLRA
<< INPUT_A_SHIFT
) |
308 (HC_XTA_HTXnTBLRA
<< INPUT_B_SHIFT
) |
309 (HC_XTA_HTXnTBLRA
<< INPUT_C_SHIFT
);
312 /* A = arg[0], B = arg[1], C = 0, Bias = 0
315 alpha
|= (alpha_arg
[1] << INPUT_A_SHIFT
)
316 | (alpha_arg
[0] << INPUT_B_SHIFT
)
317 | (HC_XTA_HTXnTBLRA
<< INPUT_C_SHIFT
);
319 bias
|= (HC_XTA_HTXnTBLRA
<< INPUT_BiasA_SHIFT
);
322 /* A = 0, B = arg[0], C = 0, Bias = arg[1]
326 if ( combine
->ModeA
== GL_SUBTRACT
) {
327 op
|= HC_HTXnTBLAop_Sub
;
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
);
336 /* A = 0, B = arg[0], C = arg[1], Bias = 0.5
339 op
|= HC_HTXnTBLAop_Sub
;
341 alpha
|= (alpha_arg
[0] << INPUT_B_SHIFT
)
342 | (alpha_arg
[1] << INPUT_C_SHIFT
);
343 bias
|= (HC_XTA_HTXnTBLRA
<< INPUT_BiasA_SHIFT
);
345 bias_alpha
= 0x00000080;
348 /* A = arg[2], B = arg[0], C = arg[1], Bias = arg[1]
351 op
|= HC_HTXnTBLAop_Sub
;
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
);
361 op
|= c_shift_table
[ c_shift
] | a_shift_table
[ a_shift
];
365 vmesa
->regHTXnTBLMPfog_0
= HC_HTXnTBLMPfog_Fog
;
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);
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];
378 vmesa
->regHTXnTBLMPfog_1
= HC_HTXnTBLMPfog_Fog
;
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);