add missing license texts
[mesa.git] / src / mesa / drivers / dri / i915 / i915_texstate.c
1 /**************************************************************************
2 *
3 * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
16 * of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 **************************************************************************/
27
28 #include "glheader.h"
29 #include "macros.h"
30 #include "mtypes.h"
31 #include "simple_list.h"
32 #include "enums.h"
33 #include "texformat.h"
34 #include "texstore.h"
35
36 #include "mm.h"
37
38 #include "intel_screen.h"
39 #include "intel_ioctl.h"
40 #include "intel_tex.h"
41
42 #include "i915_context.h"
43 #include "i915_reg.h"
44
45 static GLint initial_offsets[6][2] = { {0,0},
46 {0,2},
47 {1,0},
48 {1,2},
49 {1,1},
50 {1,3} };
51
52
53 static GLint step_offsets[6][2] = { {0,2},
54 {0,2},
55 {-1,2},
56 {-1,2},
57 {-1,1},
58 {-1,1} };
59
60
61 #define I915_TEX_UNIT_ENABLED(unit) (1<<unit)
62
63 static void i915SetTexImages( i915ContextPtr i915,
64 struct gl_texture_object *tObj )
65 {
66 GLuint total_height, pitch, i, textureFormat;
67 i915TextureObjectPtr t = (i915TextureObjectPtr) tObj->DriverData;
68 const struct gl_texture_image *baseImage = tObj->Image[0][tObj->BaseLevel];
69 GLint firstLevel, lastLevel, numLevels;
70 GLint ss2 = 0;
71
72 switch( baseImage->TexFormat->MesaFormat ) {
73 case MESA_FORMAT_L8:
74 t->intel.texelBytes = 1;
75 textureFormat = MAPSURF_8BIT | MT_8BIT_L8;
76 break;
77
78 case MESA_FORMAT_I8:
79 t->intel.texelBytes = 1;
80 textureFormat = MAPSURF_8BIT | MT_8BIT_I8;
81 break;
82
83 case MESA_FORMAT_A8:
84 t->intel.texelBytes = 1;
85 textureFormat = MAPSURF_8BIT | MT_8BIT_A8;
86 break;
87
88 case MESA_FORMAT_AL88:
89 t->intel.texelBytes = 2;
90 textureFormat = MAPSURF_16BIT | MT_16BIT_AY88;
91 break;
92
93 case MESA_FORMAT_RGB565:
94 t->intel.texelBytes = 2;
95 textureFormat = MAPSURF_16BIT | MT_16BIT_RGB565;
96 break;
97
98 case MESA_FORMAT_ARGB1555:
99 t->intel.texelBytes = 2;
100 textureFormat = MAPSURF_16BIT | MT_16BIT_ARGB1555;
101 break;
102
103 case MESA_FORMAT_ARGB4444:
104 t->intel.texelBytes = 2;
105 textureFormat = MAPSURF_16BIT | MT_16BIT_ARGB4444;
106 break;
107
108 case MESA_FORMAT_ARGB8888:
109 t->intel.texelBytes = 4;
110 textureFormat = MAPSURF_32BIT | MT_32BIT_ARGB8888;
111 break;
112
113 case MESA_FORMAT_YCBCR_REV:
114 t->intel.texelBytes = 2;
115 textureFormat = (MAPSURF_422 | MT_422_YCRCB_NORMAL);
116 ss2 |= SS2_COLORSPACE_CONVERSION;
117 break;
118
119 case MESA_FORMAT_YCBCR:
120 t->intel.texelBytes = 2;
121 textureFormat = (MAPSURF_422 | MT_422_YCRCB_SWAPY);
122 ss2 |= SS2_COLORSPACE_CONVERSION;
123 break;
124
125 default:
126 fprintf(stderr, "%s: bad image format\n", __FUNCTION__);
127 abort();
128 }
129
130 /* Compute which mipmap levels we really want to send to the hardware.
131 */
132 driCalculateTextureFirstLastLevel( (driTextureObject *) t );
133
134
135 /* Figure out the amount of memory required to hold all the mipmap
136 * levels. Choose the smallest pitch to accomodate the largest
137 * mipmap:
138 */
139 firstLevel = t->intel.base.firstLevel;
140 lastLevel = t->intel.base.lastLevel;
141 numLevels = lastLevel - firstLevel + 1;
142
143
144
145 /* All images must be loaded at this pitch. Count the number of
146 * lines required:
147 */
148 switch (tObj->Target) {
149 case GL_TEXTURE_CUBE_MAP: {
150 const GLuint dim = tObj->Image[0][firstLevel]->Width;
151 GLuint face;
152
153 pitch = dim * t->intel.texelBytes;
154 pitch *= 2; /* double pitch for cube layouts */
155 pitch = (pitch + 3) & ~3;
156
157 total_height = dim * 4;
158
159 for ( face = 0 ; face < 6 ; face++) {
160 GLuint x = initial_offsets[face][0] * dim;
161 GLuint y = initial_offsets[face][1] * dim;
162 GLuint d = dim;
163
164 t->intel.base.dirty_images[face] = ~0;
165
166 assert(tObj->Image[face][firstLevel]->Width == dim);
167 assert(tObj->Image[face][firstLevel]->Height == dim);
168
169 for (i = 0; i < numLevels; i++) {
170 t->intel.image[face][i].image = tObj->Image[face][firstLevel + i];
171 if (!t->intel.image[face][i].image) {
172 fprintf(stderr, "no image %d %d\n", face, i);
173 break; /* can't happen */
174 }
175
176 t->intel.image[face][i].offset =
177 y * pitch + x * t->intel.texelBytes;
178 t->intel.image[face][i].internalFormat = baseImage->Format;
179
180 d >>= 1;
181 x += step_offsets[face][0] * d;
182 y += step_offsets[face][1] * d;
183 }
184 }
185 break;
186 }
187 case GL_TEXTURE_3D: {
188 GLuint virtual_height;
189 GLuint tmp_numLevels = numLevels;
190 pitch = tObj->Image[0][firstLevel]->Width * t->intel.texelBytes;
191 pitch = (pitch + 3) & ~3;
192 t->intel.base.dirty_images[0] = ~0;
193
194 /* Calculate the size of a single slice. Hardware demands a
195 * minimum of 8 mipmaps, some of which might ultimately not be
196 * used:
197 */
198 if (tmp_numLevels < 9)
199 tmp_numLevels = 9;
200
201 virtual_height = tObj->Image[0][firstLevel]->Height;
202
203 for ( total_height = i = 0 ; i < tmp_numLevels ; i++ ) {
204 t->intel.image[0][i].image = tObj->Image[0][firstLevel + i];
205 if (t->intel.image[0][i].image) {
206 t->intel.image[0][i].offset = total_height * pitch;
207 t->intel.image[0][i].internalFormat = baseImage->Format;
208 }
209
210 total_height += MAX2(2, virtual_height);
211 virtual_height >>= 1;
212 }
213
214 t->intel.depth_pitch = total_height * pitch;
215
216 /* Multiply slice size by texture depth for total size. It's
217 * remarkable how wasteful of memory all the i8x0 texture
218 * layouts are.
219 */
220 total_height *= t->intel.image[0][0].image->Depth;
221 break;
222 }
223 default:
224 pitch = tObj->Image[0][firstLevel]->Width * t->intel.texelBytes;
225 pitch = (pitch + 3) & ~3;
226 t->intel.base.dirty_images[0] = ~0;
227
228 for ( total_height = i = 0 ; i < numLevels ; i++ ) {
229 t->intel.image[0][i].image = tObj->Image[0][firstLevel + i];
230 if (!t->intel.image[0][i].image)
231 break;
232
233 t->intel.image[0][i].offset = total_height * pitch;
234 t->intel.image[0][i].internalFormat = baseImage->Format;
235 total_height += MAX2(2, t->intel.image[0][i].image->Height);
236 }
237 break;
238 }
239
240 t->intel.Pitch = pitch;
241 t->intel.base.totalSize = total_height*pitch;
242 t->intel.max_level = numLevels-1;
243 t->Setup[I915_TEXREG_MS3] =
244 (((tObj->Image[0][firstLevel]->Height - 1) << MS3_HEIGHT_SHIFT) |
245 ((tObj->Image[0][firstLevel]->Width - 1) << MS3_WIDTH_SHIFT) |
246 textureFormat |
247 MS3_USE_FENCE_REGS);
248 t->Setup[I915_TEXREG_MS4] =
249 ((((pitch / 4) - 1) << MS4_PITCH_SHIFT) |
250 MS4_CUBE_FACE_ENA_MASK |
251 (((t->intel.max_level * 4)) << MS4_MAX_LOD_SHIFT) |
252 ((tObj->Image[0][firstLevel]->Depth - 1) << MS4_VOLUME_DEPTH_SHIFT));
253
254 t->Setup[I915_TEXREG_SS2] &= ~SS2_COLORSPACE_CONVERSION;
255 t->Setup[I915_TEXREG_SS2] |= ss2;
256
257 t->intel.dirty = I915_UPLOAD_TEX_ALL;
258 }
259
260
261 /* The i915 (and related graphics cores) do not support GL_CLAMP. The
262 * Intel drivers for "other operating systems" implement GL_CLAMP as
263 * GL_CLAMP_TO_EDGE, so the same is done here.
264 */
265 static GLuint translate_wrap_mode( GLenum wrap )
266 {
267 switch( wrap ) {
268 case GL_REPEAT: return TEXCOORDMODE_WRAP;
269 case GL_CLAMP: return TEXCOORDMODE_CLAMP_EDGE; /* not quite correct */
270 case GL_CLAMP_TO_EDGE: return TEXCOORDMODE_CLAMP_EDGE;
271 case GL_CLAMP_TO_BORDER: return TEXCOORDMODE_CLAMP_BORDER;
272 case GL_MIRRORED_REPEAT: return TEXCOORDMODE_MIRROR;
273 default: return TEXCOORDMODE_WRAP;
274 }
275 }
276
277
278 /**
279 */
280 static void i915ImportTexObjState( struct gl_texture_object *texObj )
281 {
282 i915TextureObjectPtr t = (i915TextureObjectPtr)texObj->DriverData;
283 int minFilt = 0, mipFilt = 0, magFilt = 0;
284
285 if(INTEL_DEBUG&DEBUG_DRI)
286 fprintf(stderr, "%s\n", __FUNCTION__);
287
288 switch (texObj->MinFilter) {
289 case GL_NEAREST:
290 minFilt = FILTER_NEAREST;
291 mipFilt = MIPFILTER_NONE;
292 break;
293 case GL_LINEAR:
294 minFilt = FILTER_LINEAR;
295 mipFilt = MIPFILTER_NONE;
296 break;
297 case GL_NEAREST_MIPMAP_NEAREST:
298 minFilt = FILTER_NEAREST;
299 mipFilt = MIPFILTER_NEAREST;
300 break;
301 case GL_LINEAR_MIPMAP_NEAREST:
302 minFilt = FILTER_LINEAR;
303 mipFilt = MIPFILTER_NEAREST;
304 break;
305 case GL_NEAREST_MIPMAP_LINEAR:
306 minFilt = FILTER_NEAREST;
307 mipFilt = MIPFILTER_LINEAR;
308 break;
309 case GL_LINEAR_MIPMAP_LINEAR:
310 minFilt = FILTER_LINEAR;
311 mipFilt = MIPFILTER_LINEAR;
312 break;
313 default:
314 break;
315 }
316
317 if ( texObj->MaxAnisotropy > 1.0 ) {
318 minFilt = FILTER_ANISOTROPIC;
319 magFilt = FILTER_ANISOTROPIC;
320 }
321 else {
322 switch (texObj->MagFilter) {
323 case GL_NEAREST:
324 magFilt = FILTER_NEAREST;
325 break;
326 case GL_LINEAR:
327 magFilt = FILTER_LINEAR;
328 break;
329 default:
330 break;
331 }
332 }
333
334 t->Setup[I915_TEXREG_SS2] &= ~SS2_MIN_FILTER_MASK;
335 t->Setup[I915_TEXREG_SS2] &= ~SS2_MIP_FILTER_MASK;
336 t->Setup[I915_TEXREG_SS2] &= ~SS2_MAG_FILTER_MASK;
337 t->Setup[I915_TEXREG_SS2] |= ((minFilt << SS2_MIN_FILTER_SHIFT) |
338 (mipFilt << SS2_MIP_FILTER_SHIFT) |
339 (magFilt << SS2_MAG_FILTER_SHIFT));
340
341 {
342 GLuint ss3 = t->Setup[I915_TEXREG_SS3] & ~(SS3_TCX_ADDR_MODE_MASK |
343 SS3_TCY_ADDR_MODE_MASK |
344 SS3_TCZ_ADDR_MODE_MASK);
345 GLenum ws = texObj->WrapS;
346 GLenum wt = texObj->WrapT;
347 GLenum wr = texObj->WrapR;
348
349 t->refs_border_color = 0;
350
351 if (texObj->Target == GL_TEXTURE_3D &&
352 (texObj->MinFilter != GL_NEAREST ||
353 texObj->MagFilter != GL_NEAREST)) {
354
355 /* Try to mimic GL_CLAMP functionality a little better -
356 * switch to CLAMP_TO_BORDER whenever a non-NEAREST filter is
357 * in use. Only do this for 3D textures at the moment --
358 * doing it universally would fix the conform texbc.c
359 * failure, though.
360 */
361 if (ws == GL_CLAMP) ws = GL_CLAMP_TO_BORDER;
362 if (wt == GL_CLAMP) wt = GL_CLAMP_TO_BORDER;
363 if (wr == GL_CLAMP) wr = GL_CLAMP_TO_BORDER;
364
365 /* 3D textures don't seem to respect the border color.
366 * Fallback if there's ever a danger that they might refer to
367 * it.
368 */
369 if (ws == GL_CLAMP_TO_BORDER) t->refs_border_color = 1;
370 if (wt == GL_CLAMP_TO_BORDER) t->refs_border_color = 1;
371 if (wr == GL_CLAMP_TO_BORDER) t->refs_border_color = 1;
372 }
373
374 ss3 |= translate_wrap_mode(ws) << SS3_TCX_ADDR_MODE_SHIFT;
375 ss3 |= translate_wrap_mode(wt) << SS3_TCY_ADDR_MODE_SHIFT;
376 ss3 |= translate_wrap_mode(wr) << SS3_TCZ_ADDR_MODE_SHIFT;
377
378 if (ss3 != t->Setup[I915_TEXREG_SS3]) {
379 t->intel.dirty = I915_UPLOAD_TEX_ALL;
380 t->Setup[I915_TEXREG_SS3] = ss3;
381 }
382 }
383
384 {
385 const GLubyte *color = texObj->_BorderChan;
386
387 t->Setup[I915_TEXREG_SS4] = INTEL_PACKCOLOR8888(color[0],color[1],
388 color[2],color[3]);
389 }
390 }
391
392
393
394 static void i915_import_tex_unit( i915ContextPtr i915,
395 i915TextureObjectPtr t,
396 GLuint unit )
397 {
398 GLuint state[I915_TEX_SETUP_SIZE];
399
400 if(INTEL_DEBUG&DEBUG_TEXTURE)
401 fprintf(stderr, "%s unit(%d)\n", __FUNCTION__, unit);
402
403 if (i915->intel.CurrentTexObj[unit])
404 i915->intel.CurrentTexObj[unit]->base.bound &= ~(1U << unit);
405
406 i915->intel.CurrentTexObj[unit] = (intelTextureObjectPtr)t;
407 t->intel.base.bound |= (1 << unit);
408
409 if (t->intel.dirty & I915_UPLOAD_TEX(unit)) {
410 i915ImportTexObjState( t->intel.base.tObj );
411 t->intel.dirty &= ~I915_UPLOAD_TEX(unit);
412 }
413
414 state[I915_TEXREG_MS2] = t->intel.TextureOffset;
415 state[I915_TEXREG_MS3] = t->Setup[I915_TEXREG_MS3];
416 state[I915_TEXREG_MS4] = t->Setup[I915_TEXREG_MS4];
417
418 state[I915_TEXREG_SS2] = (i915->state.Tex[unit][I915_TEXREG_SS2] &
419 SS2_LOD_BIAS_MASK);
420 state[I915_TEXREG_SS2] |= (t->Setup[I915_TEXREG_SS2] & ~SS2_LOD_BIAS_MASK);
421
422 state[I915_TEXREG_SS3] = (i915->state.Tex[unit][I915_TEXREG_SS3] &
423 SS3_NORMALIZED_COORDS);
424 state[I915_TEXREG_SS3] |= (t->Setup[I915_TEXREG_SS3] &
425 ~(SS3_NORMALIZED_COORDS|
426 SS3_TEXTUREMAP_INDEX_MASK));
427
428 state[I915_TEXREG_SS3] |= (unit<<SS3_TEXTUREMAP_INDEX_SHIFT);
429
430 state[I915_TEXREG_SS4] = t->Setup[I915_TEXREG_SS4];
431
432
433 if (memcmp(state, i915->state.Tex[unit], sizeof(state)) != 0) {
434 I915_STATECHANGE( i915, I915_UPLOAD_TEX(unit) );
435 memcpy(i915->state.Tex[unit], state, sizeof(state));
436 }
437 }
438
439
440
441 static GLboolean enable_tex_common( GLcontext *ctx, GLuint unit )
442 {
443 i915ContextPtr i915 = I915_CONTEXT(ctx);
444 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
445 struct gl_texture_object *tObj = texUnit->_Current;
446 i915TextureObjectPtr t = (i915TextureObjectPtr)tObj->DriverData;
447
448 if (0) fprintf(stderr, "%s %d\n", __FUNCTION__, unit);
449
450 if (!(i915->state.active & I915_UPLOAD_TEX(unit))) {
451 I915_ACTIVESTATE(i915, I915_UPLOAD_TEX(unit), GL_TRUE);
452 }
453
454 /* Fallback if there's a texture border */
455 if ( tObj->Image[0][tObj->BaseLevel]->Border > 0 ) {
456 return GL_FALSE;
457 }
458
459
460 /* Update state if this is a different texture object to last
461 * time.
462 */
463 if (i915->intel.CurrentTexObj[unit] != &t->intel ||
464 (t->intel.dirty & I915_UPLOAD_TEX(unit))) {
465 i915_import_tex_unit( i915, t, unit);
466 i915->tex_program.translated = 0;
467 }
468
469 return GL_TRUE;
470 }
471
472 static GLboolean enable_tex_rect( GLcontext *ctx, GLuint unit )
473 {
474 i915ContextPtr i915 = I915_CONTEXT(ctx);
475 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
476 struct gl_texture_object *tObj = texUnit->_Current;
477 i915TextureObjectPtr t = (i915TextureObjectPtr)tObj->DriverData;
478 GLuint ss3 = i915->state.Tex[unit][I915_TEXREG_SS3];
479
480 ss3 &= ~SS3_NORMALIZED_COORDS;
481
482 if (ss3 != i915->state.Tex[unit][I915_TEXREG_SS3]) {
483 I915_STATECHANGE(i915, I915_UPLOAD_TEX(unit));
484 i915->state.Tex[unit][I915_TEXREG_SS3] = ss3;
485 }
486
487 /* Upload teximages (not pipelined)
488 */
489 if (t->intel.base.dirty_images[0]) {
490 i915SetTexImages( i915, tObj );
491 if (!intelUploadTexImages( &i915->intel, &t->intel, 0 )) {
492 return GL_FALSE;
493 }
494 }
495
496 return GL_TRUE;
497 }
498
499
500 static GLboolean enable_tex_2d( GLcontext *ctx, GLuint unit )
501 {
502 i915ContextPtr i915 = I915_CONTEXT(ctx);
503 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
504 struct gl_texture_object *tObj = texUnit->_Current;
505 i915TextureObjectPtr t = (i915TextureObjectPtr)tObj->DriverData;
506 GLuint ss3 = i915->state.Tex[unit][I915_TEXREG_SS3];
507
508 ss3 |= SS3_NORMALIZED_COORDS;
509
510 if (ss3 != i915->state.Tex[unit][I915_TEXREG_SS3]) {
511 I915_STATECHANGE(i915, I915_UPLOAD_TEX(unit));
512 i915->state.Tex[unit][I915_TEXREG_SS3] = ss3;
513 }
514
515 /* Upload teximages (not pipelined)
516 */
517 if (t->intel.base.dirty_images[0]) {
518 i915SetTexImages( i915, tObj );
519 if (!intelUploadTexImages( &i915->intel, &t->intel, 0 )) {
520 return GL_FALSE;
521 }
522 }
523
524 return GL_TRUE;
525 }
526
527 static GLboolean enable_tex_cube( GLcontext *ctx, GLuint unit )
528 {
529 i915ContextPtr i915 = I915_CONTEXT(ctx);
530 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
531 struct gl_texture_object *tObj = texUnit->_Current;
532 i915TextureObjectPtr t = (i915TextureObjectPtr)tObj->DriverData;
533 GLuint ss3 = i915->state.Tex[unit][I915_TEXREG_SS3];
534 GLuint face;
535
536 ss3 |= SS3_NORMALIZED_COORDS;
537
538 if (ss3 != i915->state.Tex[unit][I915_TEXREG_SS3]) {
539 I915_STATECHANGE(i915, I915_UPLOAD_TEX(unit));
540 i915->state.Tex[unit][I915_TEXREG_SS3] = ss3;
541 }
542
543 /* Upload teximages (not pipelined)
544 */
545 if ( t->intel.base.dirty_images[0] || t->intel.base.dirty_images[1] ||
546 t->intel.base.dirty_images[2] || t->intel.base.dirty_images[3] ||
547 t->intel.base.dirty_images[4] || t->intel.base.dirty_images[5] ) {
548 i915SetTexImages( i915, tObj );
549 }
550
551 /* upload (per face) */
552 for (face = 0; face < 6; face++) {
553 if (t->intel.base.dirty_images[face]) {
554 if (!intelUploadTexImages( &i915->intel, &t->intel, face )) {
555 return GL_FALSE;
556 }
557 }
558 }
559
560
561 return GL_TRUE;
562 }
563
564 static GLboolean enable_tex_3d( GLcontext *ctx, GLuint unit )
565 {
566 struct gl_texture_object *tObj = ctx->Texture.Unit[unit]._Current;
567 i915TextureObjectPtr t = (i915TextureObjectPtr)tObj->DriverData;
568
569 /* 3D textures on I915 seem to get bogus border colors, hence this
570 * fallback:
571 */
572 if (t->refs_border_color)
573 return GL_FALSE;
574
575 return GL_TRUE;
576 }
577
578
579
580
581 static GLboolean disable_tex( GLcontext *ctx, GLuint unit )
582 {
583 i915ContextPtr i915 = I915_CONTEXT(ctx);
584
585 if (i915->state.active & I915_UPLOAD_TEX(unit)) {
586 I915_ACTIVESTATE(i915, I915_UPLOAD_TEX(unit), GL_FALSE);
587 }
588
589 /* The old texture is no longer bound to this texture unit.
590 * Mark it as such.
591 */
592 if ( i915->intel.CurrentTexObj[unit] != NULL ) {
593 i915->intel.CurrentTexObj[unit]->base.bound &= ~(1U << 0);
594 i915->intel.CurrentTexObj[unit] = NULL;
595 }
596
597 return GL_TRUE;
598 }
599
600 static GLboolean i915UpdateTexUnit( GLcontext *ctx, GLuint unit )
601 {
602 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
603
604 if (texUnit->_ReallyEnabled &&
605 INTEL_CONTEXT(ctx)->intelScreen->textureSize < 2048 * 1024)
606 return GL_FALSE;
607
608 switch (texUnit->_ReallyEnabled) {
609 case TEXTURE_1D_BIT:
610 case TEXTURE_2D_BIT:
611 return (enable_tex_2d( ctx, unit ) &&
612 enable_tex_common( ctx, unit ));
613 case TEXTURE_RECT_BIT:
614 return (enable_tex_rect( ctx, unit ) &&
615 enable_tex_common( ctx, unit ));
616 case TEXTURE_CUBE_BIT:
617 return (enable_tex_cube( ctx, unit ) &&
618 enable_tex_common( ctx, unit ));
619 case TEXTURE_3D_BIT:
620 return (enable_tex_2d( ctx, unit ) &&
621 enable_tex_common( ctx, unit ) &&
622 enable_tex_3d( ctx, unit));
623 case 0:
624 return disable_tex( ctx, unit );
625 default:
626 return GL_FALSE;
627 }
628 }
629
630
631 void i915UpdateTextureState( intelContextPtr intel )
632 {
633 GLcontext *ctx = &intel->ctx;
634 GLboolean ok = GL_TRUE;
635 GLuint i;
636
637 for (i = 0 ; i < I915_TEX_UNITS && ok ; i++) {
638 ok = i915UpdateTexUnit( ctx, i );
639 }
640
641 FALLBACK( intel, I915_FALLBACK_TEXTURE, !ok );
642 }
643
644
645