radeon: make compile again.
[mesa.git] / src / mesa / drivers / dri / radeon / radeon_texstate.c
1 /**************************************************************************
2
3 Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
4 VA Linux Systems Inc., Fremont, California.
5
6 All Rights Reserved.
7
8 Permission is hereby granted, free of charge, to any person obtaining
9 a copy of this software and associated documentation files (the
10 "Software"), to deal in the Software without restriction, including
11 without limitation the rights to use, copy, modify, merge, publish,
12 distribute, sublicense, and/or sell copies of the Software, and to
13 permit persons to whom the Software is furnished to do so, subject to
14 the following conditions:
15
16 The above copyright notice and this permission notice (including the
17 next paragraph) shall be included in all copies or substantial
18 portions of the Software.
19
20 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
23 IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
24 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27
28 **************************************************************************/
29
30 /*
31 * Authors:
32 * Kevin E. Martin <martin@valinux.com>
33 * Gareth Hughes <gareth@valinux.com>
34 */
35
36 #include "main/glheader.h"
37 #include "main/imports.h"
38 #include "main/colormac.h"
39 #include "main/context.h"
40 #include "main/macros.h"
41 #include "main/texformat.h"
42 #include "main/texobj.h"
43 #include "main/enums.h"
44
45 #include "radeon_context.h"
46 #include "radeon_mipmap_tree.h"
47 #include "radeon_state.h"
48 #include "radeon_ioctl.h"
49 #include "radeon_swtcl.h"
50 #include "radeon_tex.h"
51 #include "radeon_tcl.h"
52
53
54 #define RADEON_TXFORMAT_A8 RADEON_TXFORMAT_I8
55 #define RADEON_TXFORMAT_L8 RADEON_TXFORMAT_I8
56 #define RADEON_TXFORMAT_AL88 RADEON_TXFORMAT_AI88
57 #define RADEON_TXFORMAT_YCBCR RADEON_TXFORMAT_YVYU422
58 #define RADEON_TXFORMAT_YCBCR_REV RADEON_TXFORMAT_VYUY422
59 #define RADEON_TXFORMAT_RGB_DXT1 RADEON_TXFORMAT_DXT1
60 #define RADEON_TXFORMAT_RGBA_DXT1 RADEON_TXFORMAT_DXT1
61 #define RADEON_TXFORMAT_RGBA_DXT3 RADEON_TXFORMAT_DXT23
62 #define RADEON_TXFORMAT_RGBA_DXT5 RADEON_TXFORMAT_DXT45
63
64 #define _COLOR(f) \
65 [ MESA_FORMAT_ ## f ] = { RADEON_TXFORMAT_ ## f, 0 }
66 #define _COLOR_REV(f) \
67 [ MESA_FORMAT_ ## f ## _REV ] = { RADEON_TXFORMAT_ ## f, 0 }
68 #define _ALPHA(f) \
69 [ MESA_FORMAT_ ## f ] = { RADEON_TXFORMAT_ ## f | RADEON_TXFORMAT_ALPHA_IN_MAP, 0 }
70 #define _ALPHA_REV(f) \
71 [ MESA_FORMAT_ ## f ## _REV ] = { RADEON_TXFORMAT_ ## f | RADEON_TXFORMAT_ALPHA_IN_MAP, 0 }
72 #define _YUV(f) \
73 [ MESA_FORMAT_ ## f ] = { RADEON_TXFORMAT_ ## f, RADEON_YUV_TO_RGB }
74 #define _INVALID(f) \
75 [ MESA_FORMAT_ ## f ] = { 0xffffffff, 0 }
76 #define VALID_FORMAT(f) ( ((f) <= MESA_FORMAT_RGBA_DXT5) \
77 && (tx_table[f].format != 0xffffffff) )
78
79 struct tx_table {
80 GLuint format, filter;
81 };
82
83 static const struct tx_table tx_table[] =
84 {
85 _ALPHA(RGBA8888),
86 _ALPHA_REV(RGBA8888),
87 _ALPHA(ARGB8888),
88 _ALPHA_REV(ARGB8888),
89 [ MESA_FORMAT_RGB888 ] = { RADEON_TXFORMAT_ARGB8888, 0 },
90 _COLOR(RGB565),
91 _COLOR_REV(RGB565),
92 _ALPHA(ARGB4444),
93 _ALPHA_REV(ARGB4444),
94 _ALPHA(ARGB1555),
95 _ALPHA_REV(ARGB1555),
96 _ALPHA(AL88),
97 _ALPHA_REV(AL88),
98 _ALPHA(A8),
99 _COLOR(L8),
100 _ALPHA(I8),
101 _INVALID(CI8),
102 _YUV(YCBCR),
103 _YUV(YCBCR_REV),
104 _INVALID(RGB_FXT1),
105 _INVALID(RGBA_FXT1),
106 _COLOR(RGB_DXT1),
107 _ALPHA(RGBA_DXT1),
108 _ALPHA(RGBA_DXT3),
109 _ALPHA(RGBA_DXT5),
110 };
111
112 #undef _COLOR
113 #undef _ALPHA
114 #undef _INVALID
115
116 /**
117 * This function computes the number of bytes of storage needed for
118 * the given texture object (all mipmap levels, all cube faces).
119 * The \c image[face][level].x/y/width/height parameters for upload/blitting
120 * are computed here. \c pp_txfilter, \c pp_txformat, etc. will be set here
121 * too.
122 *
123 * \param rmesa Context pointer
124 * \param tObj GL texture object whose images are to be posted to
125 * hardware state.
126 */
127 #if 0
128 static void radeonSetTexImages( r100ContextPtr rmesa,
129 struct gl_texture_object *tObj )
130 {
131 radeonTexObjPtr t = (radeonTexObjPtr)tObj->DriverData;
132 const struct gl_texture_image *baseImage = tObj->Image[0][tObj->BaseLevel];
133 GLint curOffset, blitWidth;
134 GLint i, texelBytes;
135 GLint numLevels;
136 GLint log2Width, log2Height, log2Depth;
137
138 /* Set the hardware texture format
139 */
140 if ( !t->image_override ) {
141 t->pp_txformat &= ~(RADEON_TXFORMAT_FORMAT_MASK |
142 RADEON_TXFORMAT_ALPHA_IN_MAP);
143 t->pp_txfilter &= ~RADEON_YUV_TO_RGB;
144
145 if ( VALID_FORMAT( baseImage->TexFormat->MesaFormat ) ) {
146 t->pp_txformat |= tx_table[ baseImage->TexFormat->MesaFormat ].format;
147 t->pp_txfilter |= tx_table[ baseImage->TexFormat->MesaFormat ].filter;
148 }
149 else {
150 _mesa_problem(NULL, "unexpected texture format in %s", __FUNCTION__);
151 return;
152 }
153 }
154
155 texelBytes = baseImage->TexFormat->TexelBytes;
156
157 /* Compute which mipmap levels we really want to send to the hardware.
158 */
159
160 if (tObj->Target != GL_TEXTURE_CUBE_MAP)
161 driCalculateTextureFirstLastLevel( (driTextureObject *) t );
162 else {
163 /* r100 can't handle mipmaps for cube/3d textures, so don't waste
164 memory for them */
165 t->base.firstLevel = t->base.lastLevel = tObj->BaseLevel;
166 }
167 log2Width = tObj->Image[0][t->base.firstLevel]->WidthLog2;
168 log2Height = tObj->Image[0][t->base.firstLevel]->HeightLog2;
169 log2Depth = tObj->Image[0][t->base.firstLevel]->DepthLog2;
170
171 numLevels = t->base.lastLevel - t->base.firstLevel + 1;
172
173 assert(numLevels <= RADEON_MAX_TEXTURE_LEVELS);
174
175 /* Calculate mipmap offsets and dimensions for blitting (uploading)
176 * The idea is that we lay out the mipmap levels within a block of
177 * memory organized as a rectangle of width BLIT_WIDTH_BYTES.
178 */
179 curOffset = 0;
180 blitWidth = BLIT_WIDTH_BYTES;
181 t->tile_bits = 0;
182
183 /* figure out if this texture is suitable for tiling. */
184 if (texelBytes && (tObj->Target != GL_TEXTURE_RECTANGLE_NV)) {
185 if (rmesa->texmicrotile && (baseImage->Height > 1)) {
186 /* allow 32 (bytes) x 1 mip (which will use two times the space
187 the non-tiled version would use) max if base texture is large enough */
188 if ((numLevels == 1) ||
189 (((baseImage->Width * texelBytes / baseImage->Height) <= 32) &&
190 (baseImage->Width * texelBytes > 64)) ||
191 ((baseImage->Width * texelBytes / baseImage->Height) <= 16)) {
192 /* R100 has two microtile bits (only the txoffset reg, not the blitter)
193 weird: X2 + OPT: 32bit correct, 16bit completely hosed
194 X2: 32bit correct, 16bit correct
195 OPT: 32bit large mips correct, small mips hosed, 16bit completely hosed */
196 t->tile_bits |= RADEON_TXO_MICRO_TILE_X2 /*| RADEON_TXO_MICRO_TILE_OPT*/;
197 }
198 }
199 if ((baseImage->Width * texelBytes >= 256) && (baseImage->Height >= 16)) {
200 /* R100 disables macro tiling only if mip width is smaller than 256 bytes, and not
201 in the case if height is smaller than 16 (not 100% sure), as does the r200,
202 so need to disable macro tiling in that case */
203 if ((numLevels == 1) || ((baseImage->Width * texelBytes / baseImage->Height) <= 4)) {
204 t->tile_bits |= RADEON_TXO_MACRO_TILE;
205 }
206 }
207 }
208
209 for (i = 0; i < numLevels; i++) {
210 const struct gl_texture_image *texImage;
211 GLuint size;
212
213 texImage = tObj->Image[0][i + t->base.firstLevel];
214 if ( !texImage )
215 break;
216
217 /* find image size in bytes */
218 if (texImage->IsCompressed) {
219 /* need to calculate the size AFTER padding even though the texture is
220 submitted without padding.
221 Only handle pot textures currently - don't know if npot is even possible,
222 size calculation would certainly need (trivial) adjustments.
223 Align (and later pad) to 32byte, not sure what that 64byte blit width is
224 good for? */
225 if ((t->pp_txformat & RADEON_TXFORMAT_FORMAT_MASK) == RADEON_TXFORMAT_DXT1) {
226 /* RGB_DXT1/RGBA_DXT1, 8 bytes per block */
227 if ((texImage->Width + 3) < 8) /* width one block */
228 size = texImage->CompressedSize * 4;
229 else if ((texImage->Width + 3) < 16)
230 size = texImage->CompressedSize * 2;
231 else size = texImage->CompressedSize;
232 }
233 else /* DXT3/5, 16 bytes per block */
234 if ((texImage->Width + 3) < 8)
235 size = texImage->CompressedSize * 2;
236 else size = texImage->CompressedSize;
237 }
238 else if (tObj->Target == GL_TEXTURE_RECTANGLE_NV) {
239 size = ((texImage->Width * texelBytes + 63) & ~63) * texImage->Height;
240 }
241 else if (t->tile_bits & RADEON_TXO_MICRO_TILE_X2) {
242 /* tile pattern is 16 bytes x2. mipmaps stay 32 byte aligned,
243 though the actual offset may be different (if texture is less than
244 32 bytes width) to the untiled case */
245 int w = (texImage->Width * texelBytes * 2 + 31) & ~31;
246 size = (w * ((texImage->Height + 1) / 2)) * texImage->Depth;
247 blitWidth = MAX2(texImage->Width, 64 / texelBytes);
248 }
249 else {
250 int w = (texImage->Width * texelBytes + 31) & ~31;
251 size = w * texImage->Height * texImage->Depth;
252 blitWidth = MAX2(texImage->Width, 64 / texelBytes);
253 }
254 assert(size > 0);
255
256 /* Align to 32-byte offset. It is faster to do this unconditionally
257 * (no branch penalty).
258 */
259
260 curOffset = (curOffset + 0x1f) & ~0x1f;
261
262 if (texelBytes) {
263 t->image[0][i].x = curOffset; /* fix x and y coords up later together with offset */
264 t->image[0][i].y = 0;
265 t->image[0][i].width = MIN2(size / texelBytes, blitWidth);
266 t->image[0][i].height = (size / texelBytes) / t->image[0][i].width;
267 }
268 else {
269 t->image[0][i].x = curOffset % BLIT_WIDTH_BYTES;
270 t->image[0][i].y = curOffset / BLIT_WIDTH_BYTES;
271 t->image[0][i].width = MIN2(size, BLIT_WIDTH_BYTES);
272 t->image[0][i].height = size / t->image[0][i].width;
273 }
274
275 #if 0
276 /* for debugging only and only applicable to non-rectangle targets */
277 assert(size % t->image[0][i].width == 0);
278 assert(t->image[0][i].x == 0
279 || (size < BLIT_WIDTH_BYTES && t->image[0][i].height == 1));
280 #endif
281
282 if (0)
283 fprintf(stderr,
284 "level %d: %dx%d x=%d y=%d w=%d h=%d size=%d at %d\n",
285 i, texImage->Width, texImage->Height,
286 t->image[0][i].x, t->image[0][i].y,
287 t->image[0][i].width, t->image[0][i].height, size, curOffset);
288
289 curOffset += size;
290
291 }
292
293 /* Align the total size of texture memory block.
294 */
295 t->base.totalSize = (curOffset + RADEON_OFFSET_MASK) & ~RADEON_OFFSET_MASK;
296
297 /* Setup remaining cube face blits, if needed */
298 if (tObj->Target == GL_TEXTURE_CUBE_MAP) {
299 const GLuint faceSize = t->base.totalSize;
300 GLuint face;
301 /* reuse face 0 x/y/width/height - just update the offset when uploading */
302 for (face = 1; face < 6; face++) {
303 for (i = 0; i < numLevels; i++) {
304 t->image[face][i].x = t->image[0][i].x;
305 t->image[face][i].y = t->image[0][i].y;
306 t->image[face][i].width = t->image[0][i].width;
307 t->image[face][i].height = t->image[0][i].height;
308 }
309 }
310 t->base.totalSize = 6 * faceSize; /* total texmem needed */
311 }
312
313 /* Hardware state:
314 */
315 t->pp_txfilter &= ~RADEON_MAX_MIP_LEVEL_MASK;
316 t->pp_txfilter |= (numLevels - 1) << RADEON_MAX_MIP_LEVEL_SHIFT;
317
318 t->pp_txformat &= ~(RADEON_TXFORMAT_WIDTH_MASK |
319 RADEON_TXFORMAT_HEIGHT_MASK |
320 RADEON_TXFORMAT_CUBIC_MAP_ENABLE |
321 RADEON_TXFORMAT_F5_WIDTH_MASK |
322 RADEON_TXFORMAT_F5_HEIGHT_MASK);
323 t->pp_txformat |= ((log2Width << RADEON_TXFORMAT_WIDTH_SHIFT) |
324 (log2Height << RADEON_TXFORMAT_HEIGHT_SHIFT));
325
326 if (tObj->Target == GL_TEXTURE_CUBE_MAP) {
327 assert(log2Width == log2Height);
328 t->pp_txformat |= ((log2Width << RADEON_TXFORMAT_F5_WIDTH_SHIFT) |
329 (log2Height << RADEON_TXFORMAT_F5_HEIGHT_SHIFT) |
330 (RADEON_TXFORMAT_CUBIC_MAP_ENABLE));
331 t->pp_cubic_faces = ((log2Width << RADEON_FACE_WIDTH_1_SHIFT) |
332 (log2Height << RADEON_FACE_HEIGHT_1_SHIFT) |
333 (log2Width << RADEON_FACE_WIDTH_2_SHIFT) |
334 (log2Height << RADEON_FACE_HEIGHT_2_SHIFT) |
335 (log2Width << RADEON_FACE_WIDTH_3_SHIFT) |
336 (log2Height << RADEON_FACE_HEIGHT_3_SHIFT) |
337 (log2Width << RADEON_FACE_WIDTH_4_SHIFT) |
338 (log2Height << RADEON_FACE_HEIGHT_4_SHIFT));
339 }
340
341 t->pp_txsize = (((tObj->Image[0][t->base.firstLevel]->Width - 1) << 0) |
342 ((tObj->Image[0][t->base.firstLevel]->Height - 1) << 16));
343
344 /* Only need to round to nearest 32 for textures, but the blitter
345 * requires 64-byte aligned pitches, and we may/may not need the
346 * blitter. NPOT only!
347 */
348 if ( !t->image_override ) {
349 if (baseImage->IsCompressed)
350 t->pp_txpitch = (tObj->Image[0][t->base.firstLevel]->Width + 63) & ~(63);
351 else
352 t->pp_txpitch = ((tObj->Image[0][t->base.firstLevel]->Width * texelBytes) + 63) & ~(63);
353 t->pp_txpitch -= 32;
354 }
355
356 t->dirty_state = R100_TEX_ALL;
357
358 /* FYI: radeonUploadTexImages( rmesa, t ); used to be called here */
359 }
360 #endif
361
362
363 /* ================================================================
364 * Texture combine functions
365 */
366
367 /* GL_ARB_texture_env_combine support
368 */
369
370 /* The color tables have combine functions for GL_SRC_COLOR,
371 * GL_ONE_MINUS_SRC_COLOR, GL_SRC_ALPHA and GL_ONE_MINUS_SRC_ALPHA.
372 */
373 static GLuint radeon_texture_color[][RADEON_MAX_TEXTURE_UNITS] =
374 {
375 {
376 RADEON_COLOR_ARG_A_T0_COLOR,
377 RADEON_COLOR_ARG_A_T1_COLOR,
378 RADEON_COLOR_ARG_A_T2_COLOR
379 },
380 {
381 RADEON_COLOR_ARG_A_T0_COLOR | RADEON_COMP_ARG_A,
382 RADEON_COLOR_ARG_A_T1_COLOR | RADEON_COMP_ARG_A,
383 RADEON_COLOR_ARG_A_T2_COLOR | RADEON_COMP_ARG_A
384 },
385 {
386 RADEON_COLOR_ARG_A_T0_ALPHA,
387 RADEON_COLOR_ARG_A_T1_ALPHA,
388 RADEON_COLOR_ARG_A_T2_ALPHA
389 },
390 {
391 RADEON_COLOR_ARG_A_T0_ALPHA | RADEON_COMP_ARG_A,
392 RADEON_COLOR_ARG_A_T1_ALPHA | RADEON_COMP_ARG_A,
393 RADEON_COLOR_ARG_A_T2_ALPHA | RADEON_COMP_ARG_A
394 },
395 };
396
397 static GLuint radeon_tfactor_color[] =
398 {
399 RADEON_COLOR_ARG_A_TFACTOR_COLOR,
400 RADEON_COLOR_ARG_A_TFACTOR_COLOR | RADEON_COMP_ARG_A,
401 RADEON_COLOR_ARG_A_TFACTOR_ALPHA,
402 RADEON_COLOR_ARG_A_TFACTOR_ALPHA | RADEON_COMP_ARG_A
403 };
404
405 static GLuint radeon_primary_color[] =
406 {
407 RADEON_COLOR_ARG_A_DIFFUSE_COLOR,
408 RADEON_COLOR_ARG_A_DIFFUSE_COLOR | RADEON_COMP_ARG_A,
409 RADEON_COLOR_ARG_A_DIFFUSE_ALPHA,
410 RADEON_COLOR_ARG_A_DIFFUSE_ALPHA | RADEON_COMP_ARG_A
411 };
412
413 static GLuint radeon_previous_color[] =
414 {
415 RADEON_COLOR_ARG_A_CURRENT_COLOR,
416 RADEON_COLOR_ARG_A_CURRENT_COLOR | RADEON_COMP_ARG_A,
417 RADEON_COLOR_ARG_A_CURRENT_ALPHA,
418 RADEON_COLOR_ARG_A_CURRENT_ALPHA | RADEON_COMP_ARG_A
419 };
420
421 /* GL_ZERO table - indices 0-3
422 * GL_ONE table - indices 1-4
423 */
424 static GLuint radeon_zero_color[] =
425 {
426 RADEON_COLOR_ARG_A_ZERO,
427 RADEON_COLOR_ARG_A_ZERO | RADEON_COMP_ARG_A,
428 RADEON_COLOR_ARG_A_ZERO,
429 RADEON_COLOR_ARG_A_ZERO | RADEON_COMP_ARG_A,
430 RADEON_COLOR_ARG_A_ZERO
431 };
432
433
434 /* The alpha tables only have GL_SRC_ALPHA and GL_ONE_MINUS_SRC_ALPHA.
435 */
436 static GLuint radeon_texture_alpha[][RADEON_MAX_TEXTURE_UNITS] =
437 {
438 {
439 RADEON_ALPHA_ARG_A_T0_ALPHA,
440 RADEON_ALPHA_ARG_A_T1_ALPHA,
441 RADEON_ALPHA_ARG_A_T2_ALPHA
442 },
443 {
444 RADEON_ALPHA_ARG_A_T0_ALPHA | RADEON_COMP_ARG_A,
445 RADEON_ALPHA_ARG_A_T1_ALPHA | RADEON_COMP_ARG_A,
446 RADEON_ALPHA_ARG_A_T2_ALPHA | RADEON_COMP_ARG_A
447 },
448 };
449
450 static GLuint radeon_tfactor_alpha[] =
451 {
452 RADEON_ALPHA_ARG_A_TFACTOR_ALPHA,
453 RADEON_ALPHA_ARG_A_TFACTOR_ALPHA | RADEON_COMP_ARG_A
454 };
455
456 static GLuint radeon_primary_alpha[] =
457 {
458 RADEON_ALPHA_ARG_A_DIFFUSE_ALPHA,
459 RADEON_ALPHA_ARG_A_DIFFUSE_ALPHA | RADEON_COMP_ARG_A
460 };
461
462 static GLuint radeon_previous_alpha[] =
463 {
464 RADEON_ALPHA_ARG_A_CURRENT_ALPHA,
465 RADEON_ALPHA_ARG_A_CURRENT_ALPHA | RADEON_COMP_ARG_A
466 };
467
468 /* GL_ZERO table - indices 0-1
469 * GL_ONE table - indices 1-2
470 */
471 static GLuint radeon_zero_alpha[] =
472 {
473 RADEON_ALPHA_ARG_A_ZERO,
474 RADEON_ALPHA_ARG_A_ZERO | RADEON_COMP_ARG_A,
475 RADEON_ALPHA_ARG_A_ZERO
476 };
477
478
479 /* Extract the arg from slot A, shift it into the correct argument slot
480 * and set the corresponding complement bit.
481 */
482 #define RADEON_COLOR_ARG( n, arg ) \
483 do { \
484 color_combine |= \
485 ((color_arg[n] & RADEON_COLOR_ARG_MASK) \
486 << RADEON_COLOR_ARG_##arg##_SHIFT); \
487 color_combine |= \
488 ((color_arg[n] >> RADEON_COMP_ARG_SHIFT) \
489 << RADEON_COMP_ARG_##arg##_SHIFT); \
490 } while (0)
491
492 #define RADEON_ALPHA_ARG( n, arg ) \
493 do { \
494 alpha_combine |= \
495 ((alpha_arg[n] & RADEON_ALPHA_ARG_MASK) \
496 << RADEON_ALPHA_ARG_##arg##_SHIFT); \
497 alpha_combine |= \
498 ((alpha_arg[n] >> RADEON_COMP_ARG_SHIFT) \
499 << RADEON_COMP_ARG_##arg##_SHIFT); \
500 } while (0)
501
502
503 /* ================================================================
504 * Texture unit state management
505 */
506
507 static GLboolean radeonUpdateTextureEnv( GLcontext *ctx, int unit )
508 {
509 r100ContextPtr rmesa = R100_CONTEXT(ctx);
510 const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
511 GLuint color_combine, alpha_combine;
512 const GLuint color_combine0 = RADEON_COLOR_ARG_A_ZERO | RADEON_COLOR_ARG_B_ZERO
513 | RADEON_COLOR_ARG_C_CURRENT_COLOR | RADEON_BLEND_CTL_ADD
514 | RADEON_SCALE_1X | RADEON_CLAMP_TX;
515 const GLuint alpha_combine0 = RADEON_ALPHA_ARG_A_ZERO | RADEON_ALPHA_ARG_B_ZERO
516 | RADEON_ALPHA_ARG_C_CURRENT_ALPHA | RADEON_BLEND_CTL_ADD
517 | RADEON_SCALE_1X | RADEON_CLAMP_TX;
518
519
520 /* texUnit->_Current can be NULL if and only if the texture unit is
521 * not actually enabled.
522 */
523 assert( (texUnit->_ReallyEnabled == 0)
524 || (texUnit->_Current != NULL) );
525
526 if ( RADEON_DEBUG & DEBUG_TEXTURE ) {
527 fprintf( stderr, "%s( %p, %d )\n", __FUNCTION__, (void *)ctx, unit );
528 }
529
530 /* Set the texture environment state. Isn't this nice and clean?
531 * The chip will automagically set the texture alpha to 0xff when
532 * the texture format does not include an alpha component. This
533 * reduces the amount of special-casing we have to do, alpha-only
534 * textures being a notable exception. Doesn't work for luminance
535 * textures realized with I8 and ALPHA_IN_MAP not set neither (on r100).
536 */
537 /* Don't cache these results.
538 */
539 rmesa->state.texture.unit[unit].format = 0;
540 rmesa->state.texture.unit[unit].envMode = 0;
541
542 if ( !texUnit->_ReallyEnabled ) {
543 color_combine = color_combine0;
544 alpha_combine = alpha_combine0;
545 }
546 else {
547 GLuint color_arg[3], alpha_arg[3];
548 GLuint i;
549 const GLuint numColorArgs = texUnit->_CurrentCombine->_NumArgsRGB;
550 const GLuint numAlphaArgs = texUnit->_CurrentCombine->_NumArgsA;
551 GLuint RGBshift = texUnit->_CurrentCombine->ScaleShiftRGB;
552 GLuint Ashift = texUnit->_CurrentCombine->ScaleShiftA;
553
554
555 /* Step 1:
556 * Extract the color and alpha combine function arguments.
557 */
558 for ( i = 0 ; i < numColorArgs ; i++ ) {
559 const GLint op = texUnit->_CurrentCombine->OperandRGB[i] - GL_SRC_COLOR;
560 const GLuint srcRGBi = texUnit->_CurrentCombine->SourceRGB[i];
561 assert(op >= 0);
562 assert(op <= 3);
563 switch ( srcRGBi ) {
564 case GL_TEXTURE:
565 if (texUnit->_Current->Image[0][0]->_BaseFormat == GL_ALPHA)
566 color_arg[i] = radeon_zero_color[op];
567 else
568 color_arg[i] = radeon_texture_color[op][unit];
569 break;
570 case GL_CONSTANT:
571 color_arg[i] = radeon_tfactor_color[op];
572 break;
573 case GL_PRIMARY_COLOR:
574 color_arg[i] = radeon_primary_color[op];
575 break;
576 case GL_PREVIOUS:
577 color_arg[i] = radeon_previous_color[op];
578 break;
579 case GL_ZERO:
580 color_arg[i] = radeon_zero_color[op];
581 break;
582 case GL_ONE:
583 color_arg[i] = radeon_zero_color[op+1];
584 break;
585 case GL_TEXTURE0:
586 case GL_TEXTURE1:
587 case GL_TEXTURE2: {
588 GLuint txunit = srcRGBi - GL_TEXTURE0;
589 if (ctx->Texture.Unit[txunit]._Current->Image[0][0]->_BaseFormat == GL_ALPHA)
590 color_arg[i] = radeon_zero_color[op];
591 else
592 /* implement ogl 1.4/1.5 core spec here, not specification of
593 * GL_ARB_texture_env_crossbar (which would require disabling blending
594 * instead of undefined results when referencing not enabled texunit) */
595 color_arg[i] = radeon_texture_color[op][txunit];
596 }
597 break;
598 default:
599 return GL_FALSE;
600 }
601 }
602
603 for ( i = 0 ; i < numAlphaArgs ; i++ ) {
604 const GLint op = texUnit->_CurrentCombine->OperandA[i] - GL_SRC_ALPHA;
605 const GLuint srcAi = texUnit->_CurrentCombine->SourceA[i];
606 assert(op >= 0);
607 assert(op <= 1);
608 switch ( srcAi ) {
609 case GL_TEXTURE:
610 if (texUnit->_Current->Image[0][0]->_BaseFormat == GL_LUMINANCE)
611 alpha_arg[i] = radeon_zero_alpha[op+1];
612 else
613 alpha_arg[i] = radeon_texture_alpha[op][unit];
614 break;
615 case GL_CONSTANT:
616 alpha_arg[i] = radeon_tfactor_alpha[op];
617 break;
618 case GL_PRIMARY_COLOR:
619 alpha_arg[i] = radeon_primary_alpha[op];
620 break;
621 case GL_PREVIOUS:
622 alpha_arg[i] = radeon_previous_alpha[op];
623 break;
624 case GL_ZERO:
625 alpha_arg[i] = radeon_zero_alpha[op];
626 break;
627 case GL_ONE:
628 alpha_arg[i] = radeon_zero_alpha[op+1];
629 break;
630 case GL_TEXTURE0:
631 case GL_TEXTURE1:
632 case GL_TEXTURE2: {
633 GLuint txunit = srcAi - GL_TEXTURE0;
634 if (ctx->Texture.Unit[txunit]._Current->Image[0][0]->_BaseFormat == GL_LUMINANCE)
635 alpha_arg[i] = radeon_zero_alpha[op+1];
636 else
637 alpha_arg[i] = radeon_texture_alpha[op][txunit];
638 }
639 break;
640 default:
641 return GL_FALSE;
642 }
643 }
644
645 /* Step 2:
646 * Build up the color and alpha combine functions.
647 */
648 switch ( texUnit->_CurrentCombine->ModeRGB ) {
649 case GL_REPLACE:
650 color_combine = (RADEON_COLOR_ARG_A_ZERO |
651 RADEON_COLOR_ARG_B_ZERO |
652 RADEON_BLEND_CTL_ADD |
653 RADEON_CLAMP_TX);
654 RADEON_COLOR_ARG( 0, C );
655 break;
656 case GL_MODULATE:
657 color_combine = (RADEON_COLOR_ARG_C_ZERO |
658 RADEON_BLEND_CTL_ADD |
659 RADEON_CLAMP_TX);
660 RADEON_COLOR_ARG( 0, A );
661 RADEON_COLOR_ARG( 1, B );
662 break;
663 case GL_ADD:
664 color_combine = (RADEON_COLOR_ARG_B_ZERO |
665 RADEON_COMP_ARG_B |
666 RADEON_BLEND_CTL_ADD |
667 RADEON_CLAMP_TX);
668 RADEON_COLOR_ARG( 0, A );
669 RADEON_COLOR_ARG( 1, C );
670 break;
671 case GL_ADD_SIGNED:
672 color_combine = (RADEON_COLOR_ARG_B_ZERO |
673 RADEON_COMP_ARG_B |
674 RADEON_BLEND_CTL_ADDSIGNED |
675 RADEON_CLAMP_TX);
676 RADEON_COLOR_ARG( 0, A );
677 RADEON_COLOR_ARG( 1, C );
678 break;
679 case GL_SUBTRACT:
680 color_combine = (RADEON_COLOR_ARG_B_ZERO |
681 RADEON_COMP_ARG_B |
682 RADEON_BLEND_CTL_SUBTRACT |
683 RADEON_CLAMP_TX);
684 RADEON_COLOR_ARG( 0, A );
685 RADEON_COLOR_ARG( 1, C );
686 break;
687 case GL_INTERPOLATE:
688 color_combine = (RADEON_BLEND_CTL_BLEND |
689 RADEON_CLAMP_TX);
690 RADEON_COLOR_ARG( 0, B );
691 RADEON_COLOR_ARG( 1, A );
692 RADEON_COLOR_ARG( 2, C );
693 break;
694
695 case GL_DOT3_RGB_EXT:
696 case GL_DOT3_RGBA_EXT:
697 /* The EXT version of the DOT3 extension does not support the
698 * scale factor, but the ARB version (and the version in OpenGL
699 * 1.3) does.
700 */
701 RGBshift = 0;
702 /* FALLTHROUGH */
703
704 case GL_DOT3_RGB:
705 case GL_DOT3_RGBA:
706 /* The R100 / RV200 only support a 1X multiplier in hardware
707 * w/the ARB version.
708 */
709 if ( RGBshift != (RADEON_SCALE_1X >> RADEON_SCALE_SHIFT) ) {
710 return GL_FALSE;
711 }
712
713 RGBshift += 2;
714 if ( (texUnit->_CurrentCombine->ModeRGB == GL_DOT3_RGBA_EXT)
715 || (texUnit->_CurrentCombine->ModeRGB == GL_DOT3_RGBA) ) {
716 /* is it necessary to set this or will it be ignored anyway? */
717 Ashift = RGBshift;
718 }
719
720 color_combine = (RADEON_COLOR_ARG_C_ZERO |
721 RADEON_BLEND_CTL_DOT3 |
722 RADEON_CLAMP_TX);
723 RADEON_COLOR_ARG( 0, A );
724 RADEON_COLOR_ARG( 1, B );
725 break;
726
727 case GL_MODULATE_ADD_ATI:
728 color_combine = (RADEON_BLEND_CTL_ADD |
729 RADEON_CLAMP_TX);
730 RADEON_COLOR_ARG( 0, A );
731 RADEON_COLOR_ARG( 1, C );
732 RADEON_COLOR_ARG( 2, B );
733 break;
734 case GL_MODULATE_SIGNED_ADD_ATI:
735 color_combine = (RADEON_BLEND_CTL_ADDSIGNED |
736 RADEON_CLAMP_TX);
737 RADEON_COLOR_ARG( 0, A );
738 RADEON_COLOR_ARG( 1, C );
739 RADEON_COLOR_ARG( 2, B );
740 break;
741 case GL_MODULATE_SUBTRACT_ATI:
742 color_combine = (RADEON_BLEND_CTL_SUBTRACT |
743 RADEON_CLAMP_TX);
744 RADEON_COLOR_ARG( 0, A );
745 RADEON_COLOR_ARG( 1, C );
746 RADEON_COLOR_ARG( 2, B );
747 break;
748 default:
749 return GL_FALSE;
750 }
751
752 switch ( texUnit->_CurrentCombine->ModeA ) {
753 case GL_REPLACE:
754 alpha_combine = (RADEON_ALPHA_ARG_A_ZERO |
755 RADEON_ALPHA_ARG_B_ZERO |
756 RADEON_BLEND_CTL_ADD |
757 RADEON_CLAMP_TX);
758 RADEON_ALPHA_ARG( 0, C );
759 break;
760 case GL_MODULATE:
761 alpha_combine = (RADEON_ALPHA_ARG_C_ZERO |
762 RADEON_BLEND_CTL_ADD |
763 RADEON_CLAMP_TX);
764 RADEON_ALPHA_ARG( 0, A );
765 RADEON_ALPHA_ARG( 1, B );
766 break;
767 case GL_ADD:
768 alpha_combine = (RADEON_ALPHA_ARG_B_ZERO |
769 RADEON_COMP_ARG_B |
770 RADEON_BLEND_CTL_ADD |
771 RADEON_CLAMP_TX);
772 RADEON_ALPHA_ARG( 0, A );
773 RADEON_ALPHA_ARG( 1, C );
774 break;
775 case GL_ADD_SIGNED:
776 alpha_combine = (RADEON_ALPHA_ARG_B_ZERO |
777 RADEON_COMP_ARG_B |
778 RADEON_BLEND_CTL_ADDSIGNED |
779 RADEON_CLAMP_TX);
780 RADEON_ALPHA_ARG( 0, A );
781 RADEON_ALPHA_ARG( 1, C );
782 break;
783 case GL_SUBTRACT:
784 alpha_combine = (RADEON_COLOR_ARG_B_ZERO |
785 RADEON_COMP_ARG_B |
786 RADEON_BLEND_CTL_SUBTRACT |
787 RADEON_CLAMP_TX);
788 RADEON_ALPHA_ARG( 0, A );
789 RADEON_ALPHA_ARG( 1, C );
790 break;
791 case GL_INTERPOLATE:
792 alpha_combine = (RADEON_BLEND_CTL_BLEND |
793 RADEON_CLAMP_TX);
794 RADEON_ALPHA_ARG( 0, B );
795 RADEON_ALPHA_ARG( 1, A );
796 RADEON_ALPHA_ARG( 2, C );
797 break;
798
799 case GL_MODULATE_ADD_ATI:
800 alpha_combine = (RADEON_BLEND_CTL_ADD |
801 RADEON_CLAMP_TX);
802 RADEON_ALPHA_ARG( 0, A );
803 RADEON_ALPHA_ARG( 1, C );
804 RADEON_ALPHA_ARG( 2, B );
805 break;
806 case GL_MODULATE_SIGNED_ADD_ATI:
807 alpha_combine = (RADEON_BLEND_CTL_ADDSIGNED |
808 RADEON_CLAMP_TX);
809 RADEON_ALPHA_ARG( 0, A );
810 RADEON_ALPHA_ARG( 1, C );
811 RADEON_ALPHA_ARG( 2, B );
812 break;
813 case GL_MODULATE_SUBTRACT_ATI:
814 alpha_combine = (RADEON_BLEND_CTL_SUBTRACT |
815 RADEON_CLAMP_TX);
816 RADEON_ALPHA_ARG( 0, A );
817 RADEON_ALPHA_ARG( 1, C );
818 RADEON_ALPHA_ARG( 2, B );
819 break;
820 default:
821 return GL_FALSE;
822 }
823
824 if ( (texUnit->_CurrentCombine->ModeRGB == GL_DOT3_RGB_EXT)
825 || (texUnit->_CurrentCombine->ModeRGB == GL_DOT3_RGB) ) {
826 alpha_combine |= RADEON_DOT_ALPHA_DONT_REPLICATE;
827 }
828
829 /* Step 3:
830 * Apply the scale factor.
831 */
832 color_combine |= (RGBshift << RADEON_SCALE_SHIFT);
833 alpha_combine |= (Ashift << RADEON_SCALE_SHIFT);
834
835 /* All done!
836 */
837 }
838
839 if ( rmesa->hw.tex[unit].cmd[TEX_PP_TXCBLEND] != color_combine ||
840 rmesa->hw.tex[unit].cmd[TEX_PP_TXABLEND] != alpha_combine ) {
841 RADEON_STATECHANGE( rmesa, tex[unit] );
842 rmesa->hw.tex[unit].cmd[TEX_PP_TXCBLEND] = color_combine;
843 rmesa->hw.tex[unit].cmd[TEX_PP_TXABLEND] = alpha_combine;
844 }
845
846 return GL_TRUE;
847 }
848
849 void radeonSetTexOffset(__DRIcontext * pDRICtx, GLint texname,
850 unsigned long long offset, GLint depth, GLuint pitch)
851 {
852 r100ContextPtr rmesa = pDRICtx->driverPrivate;
853 struct gl_texture_object *tObj =
854 _mesa_lookup_texture(rmesa->radeon.glCtx, texname);
855 radeonTexObjPtr t;
856
857 if (tObj == NULL)
858 return;
859
860 t = (radeonTexObjPtr) tObj->DriverData;
861
862 t->image_override = GL_TRUE;
863
864 if (!offset)
865 return;
866
867 t->pp_txoffset = offset;
868 t->pp_txpitch = pitch - 32;
869
870 switch (depth) {
871 case 32:
872 t->pp_txformat = tx_table[MESA_FORMAT_ARGB8888].format;
873 t->pp_txfilter |= tx_table[MESA_FORMAT_ARGB8888].filter;
874 break;
875 case 24:
876 default:
877 t->pp_txformat = tx_table[MESA_FORMAT_RGB888].format;
878 t->pp_txfilter |= tx_table[MESA_FORMAT_RGB888].filter;
879 break;
880 case 16:
881 t->pp_txformat = tx_table[MESA_FORMAT_RGB565].format;
882 t->pp_txfilter |= tx_table[MESA_FORMAT_RGB565].filter;
883 break;
884 }
885 }
886
887 #define TEXOBJ_TXFILTER_MASK (RADEON_MAX_MIP_LEVEL_MASK | \
888 RADEON_MIN_FILTER_MASK | \
889 RADEON_MAG_FILTER_MASK | \
890 RADEON_MAX_ANISO_MASK | \
891 RADEON_YUV_TO_RGB | \
892 RADEON_YUV_TEMPERATURE_MASK | \
893 RADEON_CLAMP_S_MASK | \
894 RADEON_CLAMP_T_MASK | \
895 RADEON_BORDER_MODE_D3D )
896
897 #define TEXOBJ_TXFORMAT_MASK (RADEON_TXFORMAT_WIDTH_MASK | \
898 RADEON_TXFORMAT_HEIGHT_MASK | \
899 RADEON_TXFORMAT_FORMAT_MASK | \
900 RADEON_TXFORMAT_F5_WIDTH_MASK | \
901 RADEON_TXFORMAT_F5_HEIGHT_MASK | \
902 RADEON_TXFORMAT_ALPHA_IN_MAP | \
903 RADEON_TXFORMAT_CUBIC_MAP_ENABLE | \
904 RADEON_TXFORMAT_NON_POWER2)
905
906 #if 0
907 static void import_tex_obj_state( r100ContextPtr rmesa,
908 int unit,
909 radeonTexObjPtr texobj )
910 {
911 /* do not use RADEON_DB_STATE to avoid stale texture caches */
912 uint32_t *cmd = &rmesa->hw.tex[unit].cmd[TEX_CMD_0];
913 GLuint se_coord_fmt = rmesa->hw.set.cmd[SET_SE_COORDFMT];
914
915 RADEON_STATECHANGE( rmesa, tex[unit] );
916
917 cmd[TEX_PP_TXFILTER] &= ~TEXOBJ_TXFILTER_MASK;
918 cmd[TEX_PP_TXFILTER] |= texobj->pp_txfilter & TEXOBJ_TXFILTER_MASK;
919 cmd[TEX_PP_TXFORMAT] &= ~TEXOBJ_TXFORMAT_MASK;
920 cmd[TEX_PP_TXFORMAT] |= texobj->pp_txformat & TEXOBJ_TXFORMAT_MASK;
921 cmd[TEX_PP_TXOFFSET] = texobj->pp_txoffset;
922 cmd[TEX_PP_BORDER_COLOR] = texobj->pp_border_color;
923
924 if (texobj->base.tObj->Target == GL_TEXTURE_RECTANGLE_NV) {
925 GLuint *txr_cmd = RADEON_DB_STATE( txr[unit] );
926 txr_cmd[TXR_PP_TEX_SIZE] = texobj->pp_txsize; /* NPOT only! */
927 txr_cmd[TXR_PP_TEX_PITCH] = texobj->pp_txpitch; /* NPOT only! */
928 RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.txr[unit] );
929 se_coord_fmt |= RADEON_VTX_ST0_NONPARAMETRIC << unit;
930 }
931 else {
932 se_coord_fmt &= ~(RADEON_VTX_ST0_NONPARAMETRIC << unit);
933
934 if (texobj->base.tObj->Target == GL_TEXTURE_CUBE_MAP) {
935 int *cube_cmd = &rmesa->hw.cube[unit].cmd[CUBE_CMD_0];
936 GLuint bytesPerFace = texobj->base.totalSize / 6;
937 ASSERT(texobj->base.totalSize % 6 == 0);
938
939 RADEON_STATECHANGE( rmesa, cube[unit] );
940 cube_cmd[CUBE_PP_CUBIC_FACES] = texobj->pp_cubic_faces;
941 /* dont know if this setup conforms to OpenGL..
942 * at least it matches the behavior of mesa software renderer
943 */
944 cube_cmd[CUBE_PP_CUBIC_OFFSET_0] = texobj->pp_txoffset; /* right */
945 cube_cmd[CUBE_PP_CUBIC_OFFSET_1] = texobj->pp_txoffset + 1 * bytesPerFace; /* left */
946 cube_cmd[CUBE_PP_CUBIC_OFFSET_2] = texobj->pp_txoffset + 2 * bytesPerFace; /* top */
947 cube_cmd[CUBE_PP_CUBIC_OFFSET_3] = texobj->pp_txoffset + 3 * bytesPerFace; /* bottom */
948 cube_cmd[CUBE_PP_CUBIC_OFFSET_4] = texobj->pp_txoffset + 4 * bytesPerFace; /* front */
949 cmd[TEX_PP_TXOFFSET] = texobj->pp_txoffset + 5 * bytesPerFace; /* back */
950 }
951 }
952
953 if (se_coord_fmt != rmesa->hw.set.cmd[SET_SE_COORDFMT]) {
954 RADEON_STATECHANGE( rmesa, set );
955 rmesa->hw.set.cmd[SET_SE_COORDFMT] = se_coord_fmt;
956 }
957
958 texobj->dirty_state &= ~(1<<unit);
959 }
960 #endif
961
962
963
964 static void set_texgen_matrix( r100ContextPtr rmesa,
965 GLuint unit,
966 const GLfloat *s_plane,
967 const GLfloat *t_plane,
968 const GLfloat *r_plane,
969 const GLfloat *q_plane )
970 {
971 rmesa->TexGenMatrix[unit].m[0] = s_plane[0];
972 rmesa->TexGenMatrix[unit].m[4] = s_plane[1];
973 rmesa->TexGenMatrix[unit].m[8] = s_plane[2];
974 rmesa->TexGenMatrix[unit].m[12] = s_plane[3];
975
976 rmesa->TexGenMatrix[unit].m[1] = t_plane[0];
977 rmesa->TexGenMatrix[unit].m[5] = t_plane[1];
978 rmesa->TexGenMatrix[unit].m[9] = t_plane[2];
979 rmesa->TexGenMatrix[unit].m[13] = t_plane[3];
980
981 rmesa->TexGenMatrix[unit].m[2] = r_plane[0];
982 rmesa->TexGenMatrix[unit].m[6] = r_plane[1];
983 rmesa->TexGenMatrix[unit].m[10] = r_plane[2];
984 rmesa->TexGenMatrix[unit].m[14] = r_plane[3];
985
986 rmesa->TexGenMatrix[unit].m[3] = q_plane[0];
987 rmesa->TexGenMatrix[unit].m[7] = q_plane[1];
988 rmesa->TexGenMatrix[unit].m[11] = q_plane[2];
989 rmesa->TexGenMatrix[unit].m[15] = q_plane[3];
990
991 rmesa->TexGenEnabled |= RADEON_TEXMAT_0_ENABLE << unit;
992 rmesa->radeon.NewGLState |= _NEW_TEXTURE_MATRIX;
993 }
994
995 /* Returns GL_FALSE if fallback required.
996 */
997 static GLboolean radeon_validate_texgen( GLcontext *ctx, GLuint unit )
998 {
999 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1000 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
1001 GLuint inputshift = RADEON_TEXGEN_0_INPUT_SHIFT + unit*4;
1002 GLuint tmp = rmesa->TexGenEnabled;
1003 static const GLfloat reflect[16] = {
1004 -1, 0, 0, 0,
1005 0, -1, 0, 0,
1006 0, 0, -1, 0,
1007 0, 0, 0, 1 };
1008
1009 rmesa->TexGenEnabled &= ~(RADEON_TEXGEN_TEXMAT_0_ENABLE << unit);
1010 rmesa->TexGenEnabled &= ~(RADEON_TEXMAT_0_ENABLE << unit);
1011 rmesa->TexGenEnabled &= ~(RADEON_TEXGEN_INPUT_MASK << inputshift);
1012 rmesa->TexGenNeedNormals[unit] = 0;
1013
1014 if ((texUnit->TexGenEnabled & (S_BIT|T_BIT|R_BIT|Q_BIT)) == 0) {
1015 /* Disabled, no fallback:
1016 */
1017 rmesa->TexGenEnabled |=
1018 (RADEON_TEXGEN_INPUT_TEXCOORD_0 + unit) << inputshift;
1019 return GL_TRUE;
1020 }
1021 /* the r100 cannot do texgen for some coords and not for others
1022 * we do not detect such cases (certainly can't do it here) and just
1023 * ASSUME that when S and T are texgen enabled we do not need other
1024 * non-texgen enabled coords, no matter if the R and Q bits are texgen
1025 * enabled. Still check for mixed mode texgen for all coords.
1026 */
1027 else if ( (texUnit->TexGenEnabled & S_BIT) &&
1028 (texUnit->TexGenEnabled & T_BIT) &&
1029 (texUnit->GenModeS == texUnit->GenModeT) ) {
1030 if ( ((texUnit->TexGenEnabled & R_BIT) &&
1031 (texUnit->GenModeS != texUnit->GenModeR)) ||
1032 ((texUnit->TexGenEnabled & Q_BIT) &&
1033 (texUnit->GenModeS != texUnit->GenModeQ)) ) {
1034 /* Mixed modes, fallback:
1035 */
1036 if (RADEON_DEBUG & DEBUG_FALLBACKS)
1037 fprintf(stderr, "fallback mixed texgen\n");
1038 return GL_FALSE;
1039 }
1040 rmesa->TexGenEnabled |= RADEON_TEXGEN_TEXMAT_0_ENABLE << unit;
1041 }
1042 else {
1043 /* some texgen mode not including both S and T bits */
1044 if (RADEON_DEBUG & DEBUG_FALLBACKS)
1045 fprintf(stderr, "fallback mixed texgen/nontexgen\n");
1046 return GL_FALSE;
1047 }
1048
1049 if ((texUnit->TexGenEnabled & (R_BIT | Q_BIT)) != 0) {
1050 /* need this here for vtxfmt presumably. Argh we need to set
1051 this from way too many places, would be much easier if we could leave
1052 tcl q coord always enabled as on r200) */
1053 RADEON_STATECHANGE( rmesa, tcl );
1054 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_Q_BIT(unit);
1055 }
1056
1057 switch (texUnit->GenModeS) {
1058 case GL_OBJECT_LINEAR:
1059 rmesa->TexGenEnabled |= RADEON_TEXGEN_INPUT_OBJ << inputshift;
1060 set_texgen_matrix( rmesa, unit,
1061 texUnit->ObjectPlaneS,
1062 texUnit->ObjectPlaneT,
1063 texUnit->ObjectPlaneR,
1064 texUnit->ObjectPlaneQ);
1065 break;
1066
1067 case GL_EYE_LINEAR:
1068 rmesa->TexGenEnabled |= RADEON_TEXGEN_INPUT_EYE << inputshift;
1069 set_texgen_matrix( rmesa, unit,
1070 texUnit->EyePlaneS,
1071 texUnit->EyePlaneT,
1072 texUnit->EyePlaneR,
1073 texUnit->EyePlaneQ);
1074 break;
1075
1076 case GL_REFLECTION_MAP_NV:
1077 rmesa->TexGenNeedNormals[unit] = GL_TRUE;
1078 rmesa->TexGenEnabled |= RADEON_TEXGEN_INPUT_EYE_REFLECT << inputshift;
1079 /* TODO: unknown if this is needed/correct */
1080 set_texgen_matrix( rmesa, unit, reflect, reflect + 4,
1081 reflect + 8, reflect + 12 );
1082 break;
1083
1084 case GL_NORMAL_MAP_NV:
1085 rmesa->TexGenNeedNormals[unit] = GL_TRUE;
1086 rmesa->TexGenEnabled |= RADEON_TEXGEN_INPUT_EYE_NORMAL << inputshift;
1087 break;
1088
1089 case GL_SPHERE_MAP:
1090 /* the mode which everyone uses :-( */
1091 default:
1092 /* Unsupported mode, fallback:
1093 */
1094 if (RADEON_DEBUG & DEBUG_FALLBACKS)
1095 fprintf(stderr, "fallback GL_SPHERE_MAP\n");
1096 return GL_FALSE;
1097 }
1098
1099 if (tmp != rmesa->TexGenEnabled) {
1100 rmesa->radeon.NewGLState |= _NEW_TEXTURE_MATRIX;
1101 }
1102
1103 return GL_TRUE;
1104 }
1105
1106 #if 0
1107 static void disable_tex( GLcontext *ctx, int unit )
1108 {
1109 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1110
1111 if (rmesa->hw.ctx.cmd[CTX_PP_CNTL] & (RADEON_TEX_0_ENABLE<<unit)) {
1112 /* Texture unit disabled */
1113 if ( rmesa->state.texture.unit[unit].texobj != NULL ) {
1114 /* The old texture is no longer bound to this texture unit.
1115 * Mark it as such.
1116 */
1117
1118 rmesa->state.texture.unit[unit].texobj->base.bound &= ~(1UL << unit);
1119 rmesa->state.texture.unit[unit].texobj = NULL;
1120 }
1121
1122 RADEON_STATECHANGE( rmesa, ctx );
1123 rmesa->hw.ctx.cmd[CTX_PP_CNTL] &=
1124 ~((RADEON_TEX_0_ENABLE | RADEON_TEX_BLEND_0_ENABLE) << unit);
1125
1126 RADEON_STATECHANGE( rmesa, tcl );
1127 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] &= ~(RADEON_ST_BIT(unit) |
1128 RADEON_Q_BIT(unit));
1129
1130 if (rmesa->radeon.TclFallback & (RADEON_TCL_FALLBACK_TEXGEN_0<<unit)) {
1131 TCL_FALLBACK( ctx, (RADEON_TCL_FALLBACK_TEXGEN_0<<unit), GL_FALSE);
1132 rmesa->recheck_texgen[unit] = GL_TRUE;
1133 }
1134
1135 if (rmesa->hw.tex[unit].cmd[TEX_PP_TXFORMAT] & RADEON_TXFORMAT_CUBIC_MAP_ENABLE) {
1136 /* this seems to be a genuine (r100 only?) hw bug. Need to remove the
1137 cubic_map bit on unit 2 when the unit is disabled, otherwise every
1138 2nd (2d) mipmap on unit 0 will be broken (may not be needed for other
1139 units, better be safe than sorry though).*/
1140 RADEON_STATECHANGE( rmesa, tex[unit] );
1141 rmesa->hw.tex[unit].cmd[TEX_PP_TXFORMAT] &= ~RADEON_TXFORMAT_CUBIC_MAP_ENABLE;
1142 }
1143
1144 {
1145 GLuint inputshift = RADEON_TEXGEN_0_INPUT_SHIFT + unit*4;
1146 GLuint tmp = rmesa->TexGenEnabled;
1147
1148 rmesa->TexGenEnabled &= ~(RADEON_TEXGEN_TEXMAT_0_ENABLE<<unit);
1149 rmesa->TexGenEnabled &= ~(RADEON_TEXMAT_0_ENABLE<<unit);
1150 rmesa->TexGenEnabled &= ~(RADEON_TEXGEN_INPUT_MASK<<inputshift);
1151 rmesa->TexGenNeedNormals[unit] = 0;
1152 rmesa->TexGenEnabled |=
1153 (RADEON_TEXGEN_INPUT_TEXCOORD_0+unit) << inputshift;
1154
1155 if (tmp != rmesa->TexGenEnabled) {
1156 rmesa->recheck_texgen[unit] = GL_TRUE;
1157 rmesa->radeon.NewGLState |= _NEW_TEXTURE_MATRIX;
1158 }
1159 }
1160 }
1161 }
1162
1163 static GLboolean enable_tex_2d( GLcontext *ctx, int unit )
1164 {
1165 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1166 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
1167 struct gl_texture_object *tObj = texUnit->_Current;
1168 radeonTexObjPtr t = (radeonTexObjPtr) tObj->DriverData;
1169
1170 /* Need to load the 2d images associated with this unit.
1171 */
1172 if (t->pp_txformat & RADEON_TXFORMAT_NON_POWER2) {
1173 t->pp_txformat &= ~RADEON_TXFORMAT_NON_POWER2;
1174 t->base.dirty_images[0] = ~0;
1175 }
1176
1177 ASSERT(tObj->Target == GL_TEXTURE_2D || tObj->Target == GL_TEXTURE_1D);
1178
1179 if ( t->base.dirty_images[0] ) {
1180 RADEON_FIREVERTICES( rmesa );
1181 radeonSetTexImages( rmesa, tObj );
1182 radeonUploadTexImages( rmesa, (radeonTexObjPtr) tObj->DriverData, 0 );
1183 if ( !t->base.memBlock && !t->image_override )
1184 return GL_FALSE;
1185 }
1186
1187 return GL_TRUE;
1188 }
1189
1190 static GLboolean enable_tex_cube( GLcontext *ctx, int unit )
1191 {
1192 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1193 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
1194 struct gl_texture_object *tObj = texUnit->_Current;
1195 radeonTexObjPtr t = (radeonTexObjPtr) tObj->DriverData;
1196 GLuint face;
1197
1198 /* Need to load the 2d images associated with this unit.
1199 */
1200 if (t->pp_txformat & RADEON_TXFORMAT_NON_POWER2) {
1201 t->pp_txformat &= ~RADEON_TXFORMAT_NON_POWER2;
1202 for (face = 0; face < 6; face++)
1203 t->base.dirty_images[face] = ~0;
1204 }
1205
1206 ASSERT(tObj->Target == GL_TEXTURE_CUBE_MAP);
1207
1208 if ( t->base.dirty_images[0] || t->base.dirty_images[1] ||
1209 t->base.dirty_images[2] || t->base.dirty_images[3] ||
1210 t->base.dirty_images[4] || t->base.dirty_images[5] ) {
1211 /* flush */
1212 RADEON_FIREVERTICES( rmesa );
1213 /* layout memory space, once for all faces */
1214 radeonSetTexImages( rmesa, tObj );
1215 }
1216
1217 /* upload (per face) */
1218 for (face = 0; face < 6; face++) {
1219 if (t->base.dirty_images[face]) {
1220 radeonUploadTexImages( rmesa, (radeonTexObjPtr) tObj->DriverData, face );
1221 }
1222 }
1223
1224 if ( !t->base.memBlock ) {
1225 /* texmem alloc failed, use s/w fallback */
1226 return GL_FALSE;
1227 }
1228
1229 return GL_TRUE;
1230 }
1231
1232 static GLboolean enable_tex_rect( GLcontext *ctx, int unit )
1233 {
1234 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1235 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
1236 struct gl_texture_object *tObj = texUnit->_Current;
1237 radeonTexObjPtr t = (radeonTexObjPtr) tObj->DriverData;
1238
1239 if (!(t->pp_txformat & RADEON_TXFORMAT_NON_POWER2)) {
1240 t->pp_txformat |= RADEON_TXFORMAT_NON_POWER2;
1241 t->base.dirty_images[0] = ~0;
1242 }
1243
1244 ASSERT(tObj->Target == GL_TEXTURE_RECTANGLE_NV);
1245
1246 if ( t->base.dirty_images[0] ) {
1247 RADEON_FIREVERTICES( rmesa );
1248 radeonSetTexImages( rmesa, tObj );
1249 radeonUploadTexImages( rmesa, (radeonTexObjPtr) tObj->DriverData, 0 );
1250 if ( !t->base.memBlock &&
1251 !t->image_override /* && !rmesa->prefer_gart_client_texturing FIXME */ ) {
1252 fprintf(stderr, "%s: upload failed\n", __FUNCTION__);
1253 return GL_FALSE;
1254 }
1255 }
1256
1257 return GL_TRUE;
1258 }
1259
1260
1261 static GLboolean update_tex_common( GLcontext *ctx, int unit )
1262 {
1263 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1264 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
1265 struct gl_texture_object *tObj = texUnit->_Current;
1266 radeonTexObjPtr t = (radeonTexObjPtr) tObj->DriverData;
1267 GLenum format;
1268
1269 /* Fallback if there's a texture border */
1270 if ( tObj->Image[0][tObj->BaseLevel]->Border > 0 ) {
1271 fprintf(stderr, "%s: border\n", __FUNCTION__);
1272 return GL_FALSE;
1273 }
1274 /* yuv conversion only works in first unit */
1275 if (unit != 0 && (t->pp_txfilter & RADEON_YUV_TO_RGB))
1276 return GL_FALSE;
1277
1278 /* Update state if this is a different texture object to last
1279 * time.
1280 */
1281 if ( rmesa->state.texture.unit[unit].texobj != t ) {
1282 if ( rmesa->state.texture.unit[unit].texobj != NULL ) {
1283 /* The old texture is no longer bound to this texture unit.
1284 * Mark it as such.
1285 */
1286
1287 rmesa->state.texture.unit[unit].texobj->base.bound &=
1288 ~(1UL << unit);
1289 }
1290
1291 rmesa->state.texture.unit[unit].texobj = t;
1292 t->base.bound |= (1UL << unit);
1293 t->dirty_state |= 1<<unit;
1294 driUpdateTextureLRU( (driTextureObject *) t ); /* XXX: should be locked! */
1295 }
1296
1297
1298 /* Newly enabled?
1299 */
1300 if ( !(rmesa->hw.ctx.cmd[CTX_PP_CNTL] & (RADEON_TEX_0_ENABLE<<unit))) {
1301 RADEON_STATECHANGE( rmesa, ctx );
1302 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |=
1303 (RADEON_TEX_0_ENABLE | RADEON_TEX_BLEND_0_ENABLE) << unit;
1304
1305 RADEON_STATECHANGE( rmesa, tcl );
1306
1307 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_ST_BIT(unit);
1308
1309 rmesa->recheck_texgen[unit] = GL_TRUE;
1310 }
1311
1312 if (t->dirty_state & (1<<unit)) {
1313 import_tex_obj_state( rmesa, unit, t );
1314 /* may need to update texture matrix (for texrect adjustments) */
1315 rmesa->radeon.NewGLState |= _NEW_TEXTURE_MATRIX;
1316 }
1317
1318 if (rmesa->recheck_texgen[unit]) {
1319 GLboolean fallback = !radeon_validate_texgen( ctx, unit );
1320 TCL_FALLBACK( ctx, (RADEON_TCL_FALLBACK_TEXGEN_0<<unit), fallback);
1321 rmesa->recheck_texgen[unit] = 0;
1322 rmesa->radeon.NewGLState |= _NEW_TEXTURE_MATRIX;
1323 }
1324
1325 format = tObj->Image[0][tObj->BaseLevel]->_BaseFormat;
1326 if ( rmesa->state.texture.unit[unit].format != format ||
1327 rmesa->state.texture.unit[unit].envMode != texUnit->EnvMode ) {
1328 rmesa->state.texture.unit[unit].format = format;
1329 rmesa->state.texture.unit[unit].envMode = texUnit->EnvMode;
1330 if ( ! radeonUpdateTextureEnv( ctx, unit ) ) {
1331 return GL_FALSE;
1332 }
1333 }
1334
1335 FALLBACK( rmesa, RADEON_FALLBACK_BORDER_MODE, t->border_fallback );
1336 return !t->border_fallback;
1337 }
1338 #endif
1339
1340 /**
1341 * Compute the cached hardware register values for the given texture object.
1342 *
1343 * \param rmesa Context pointer
1344 * \param t the r300 texture object
1345 */
1346 static void setup_hardware_state(r100ContextPtr rmesa, radeonTexObj *t)
1347 {
1348 const struct gl_texture_image *firstImage =
1349 t->base.Image[0][t->mt->firstLevel];
1350 GLint log2Width, log2Height, log2Depth, texelBytes;
1351
1352 log2Width = firstImage->WidthLog2;
1353 log2Height = firstImage->HeightLog2;
1354 log2Depth = firstImage->DepthLog2;
1355 texelBytes = firstImage->TexFormat->TexelBytes;
1356
1357 if (!t->image_override) {
1358 if (VALID_FORMAT(firstImage->TexFormat->MesaFormat)) {
1359 const struct tx_table *table = tx_table;
1360
1361 t->pp_txformat &= ~(RADEON_TXFORMAT_FORMAT_MASK |
1362 RADEON_TXFORMAT_ALPHA_IN_MAP);
1363 t->pp_txfilter &= ~RADEON_YUV_TO_RGB;
1364
1365 // t->pp_txformat |= table[ firstImage->TexFormat->MesaFormat ].format;
1366 // t->pp_txfilter |= table[ firstImage->TexFormat->MesaFormat ].filter;
1367 } else {
1368 _mesa_problem(NULL, "unexpected texture format in %s",
1369 __FUNCTION__);
1370 return;
1371 }
1372 }
1373
1374 t->pp_txfilter &= ~RADEON_MAX_MIP_LEVEL_MASK;
1375 t->pp_txfilter |= (t->mt->lastLevel - t->mt->firstLevel) << RADEON_MAX_MIP_LEVEL_SHIFT;
1376
1377 t->pp_txformat &= ~(RADEON_TXFORMAT_WIDTH_MASK |
1378 RADEON_TXFORMAT_HEIGHT_MASK |
1379 RADEON_TXFORMAT_CUBIC_MAP_ENABLE |
1380 RADEON_TXFORMAT_F5_WIDTH_MASK |
1381 RADEON_TXFORMAT_F5_HEIGHT_MASK);
1382 t->pp_txformat |= ((log2Width << RADEON_TXFORMAT_WIDTH_SHIFT) |
1383 (log2Height << RADEON_TXFORMAT_HEIGHT_SHIFT));
1384
1385 t->tile_bits = 0;
1386
1387 if (t->base.Target == GL_TEXTURE_CUBE_MAP) {
1388 ASSERT(log2Width == log2Height);
1389 t->pp_txformat |= ((log2Width << RADEON_TXFORMAT_F5_WIDTH_SHIFT) |
1390 (log2Height << RADEON_TXFORMAT_F5_HEIGHT_SHIFT) |
1391 /* don't think we need this bit, if it exists at all - fglrx does not set it */
1392 (RADEON_TXFORMAT_CUBIC_MAP_ENABLE));
1393 t->pp_cubic_faces = ((log2Width << RADEON_FACE_WIDTH_1_SHIFT) |
1394 (log2Height << RADEON_FACE_HEIGHT_1_SHIFT) |
1395 (log2Width << RADEON_FACE_WIDTH_2_SHIFT) |
1396 (log2Height << RADEON_FACE_HEIGHT_2_SHIFT) |
1397 (log2Width << RADEON_FACE_WIDTH_3_SHIFT) |
1398 (log2Height << RADEON_FACE_HEIGHT_3_SHIFT) |
1399 (log2Width << RADEON_FACE_WIDTH_4_SHIFT) |
1400 (log2Height << RADEON_FACE_HEIGHT_4_SHIFT));
1401 }
1402
1403 t->pp_txsize = (((firstImage->Width - 1) << RADEON_TEX_USIZE_SHIFT)
1404 | ((firstImage->Height - 1) << RADEON_TEX_VSIZE_SHIFT));
1405
1406 if ( !t->image_override ) {
1407 if (firstImage->IsCompressed)
1408 t->pp_txpitch = (firstImage->Width + 63) & ~(63);
1409 else
1410 t->pp_txpitch = ((firstImage->Width * texelBytes) + 63) & ~(63);
1411 t->pp_txpitch -= 32;
1412 }
1413
1414 if (t->base.Target == GL_TEXTURE_RECTANGLE_NV) {
1415 t->pp_txformat |= RADEON_TXFORMAT_NON_POWER2;
1416 }
1417
1418 }
1419 #if 0
1420 static GLboolean radeonUpdateTextureUnit( GLcontext *ctx, int unit )
1421 {
1422 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
1423
1424 if ( texUnit->_ReallyEnabled & (TEXTURE_RECT_BIT) ) {
1425 return (enable_tex_rect( ctx, unit ) &&
1426 update_tex_common( ctx, unit ));
1427 }
1428 else if ( texUnit->_ReallyEnabled & (TEXTURE_1D_BIT | TEXTURE_2D_BIT) ) {
1429 return (enable_tex_2d( ctx, unit ) &&
1430 update_tex_common( ctx, unit ));
1431 }
1432 else if ( texUnit->_ReallyEnabled & (TEXTURE_CUBE_BIT) ) {
1433 return (enable_tex_cube( ctx, unit ) &&
1434 update_tex_common( ctx, unit ));
1435 }
1436 else if ( texUnit->_ReallyEnabled ) {
1437 return GL_FALSE;
1438 }
1439 else {
1440 disable_tex( ctx, unit );
1441 return GL_TRUE;
1442 }
1443 }
1444 #endif
1445
1446 static GLboolean radeonUpdateTextureUnit( GLcontext *ctx, int unit )
1447 {
1448 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
1449
1450 }
1451
1452 void radeonUpdateTextureState( GLcontext *ctx )
1453 {
1454 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1455 GLboolean ok;
1456
1457 ok = (radeonUpdateTextureUnit( ctx, 0 ) &&
1458 radeonUpdateTextureUnit( ctx, 1 ) &&
1459 radeonUpdateTextureUnit( ctx, 2 ));
1460
1461 FALLBACK( rmesa, RADEON_FALLBACK_TEXTURE, !ok );
1462
1463 if (rmesa->radeon.TclFallback)
1464 radeonChooseVertexState( ctx );
1465 }