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