1 /**************************************************************************
3 * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
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:
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
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.
26 **************************************************************************/
31 #include "simple_list.h"
33 #include "texformat.h"
38 #include "intel_screen.h"
39 #include "intel_ioctl.h"
40 #include "intel_tex.h"
42 #include "i915_context.h"
45 static GLint initial_offsets
[6][2] = { {0,0},
53 static GLint step_offsets
[6][2] = { {0,2},
61 #define I915_TEX_UNIT_ENABLED(unit) (1<<unit)
63 static void i915SetTexImages( i915ContextPtr i915
,
64 struct gl_texture_object
*tObj
)
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
;
72 switch( baseImage
->TexFormat
->MesaFormat
) {
74 t
->intel
.texelBytes
= 1;
75 textureFormat
= MAPSURF_8BIT
| MT_8BIT_L8
;
79 t
->intel
.texelBytes
= 1;
80 textureFormat
= MAPSURF_8BIT
| MT_8BIT_I8
;
84 t
->intel
.texelBytes
= 1;
85 textureFormat
= MAPSURF_8BIT
| MT_8BIT_A8
;
88 case MESA_FORMAT_AL88
:
89 t
->intel
.texelBytes
= 2;
90 textureFormat
= MAPSURF_16BIT
| MT_16BIT_AY88
;
93 case MESA_FORMAT_RGB565
:
94 t
->intel
.texelBytes
= 2;
95 textureFormat
= MAPSURF_16BIT
| MT_16BIT_RGB565
;
98 case MESA_FORMAT_ARGB1555
:
99 t
->intel
.texelBytes
= 2;
100 textureFormat
= MAPSURF_16BIT
| MT_16BIT_ARGB1555
;
103 case MESA_FORMAT_ARGB4444
:
104 t
->intel
.texelBytes
= 2;
105 textureFormat
= MAPSURF_16BIT
| MT_16BIT_ARGB4444
;
108 case MESA_FORMAT_ARGB8888
:
109 t
->intel
.texelBytes
= 4;
110 textureFormat
= MAPSURF_32BIT
| MT_32BIT_ARGB8888
;
113 case MESA_FORMAT_YCBCR_REV
:
114 t
->intel
.texelBytes
= 2;
115 textureFormat
= (MAPSURF_422
| MT_422_YCRCB_NORMAL
);
116 ss2
|= SS2_COLORSPACE_CONVERSION
;
119 case MESA_FORMAT_YCBCR
:
120 t
->intel
.texelBytes
= 2;
121 textureFormat
= (MAPSURF_422
| MT_422_YCRCB_SWAPY
);
122 ss2
|= SS2_COLORSPACE_CONVERSION
;
125 case MESA_FORMAT_RGB_FXT1
:
126 case MESA_FORMAT_RGBA_FXT1
:
127 t
->intel
.texelBytes
= 2;
128 textureFormat
= (MAPSURF_COMPRESSED
| MT_COMPRESS_FXT1
);
130 case MESA_FORMAT_RGBA_DXT1
:
131 case MESA_FORMAT_RGB_DXT1
:
133 * DXTn pitches are Width/4 * blocksize in bytes
134 * for DXT1: blocksize=8 so Width/4*8 = Width * 2
135 * for DXT3/5: blocksize=16 so Width/4*16 = Width * 4
137 t
->intel
.texelBytes
= 2;
138 textureFormat
= (MAPSURF_COMPRESSED
| MT_COMPRESS_DXT1
);
140 case MESA_FORMAT_RGBA_DXT3
:
141 t
->intel
.texelBytes
= 4;
142 textureFormat
= (MAPSURF_COMPRESSED
| MT_COMPRESS_DXT2_3
);
144 case MESA_FORMAT_RGBA_DXT5
:
145 t
->intel
.texelBytes
= 4;
146 textureFormat
= (MAPSURF_COMPRESSED
| MT_COMPRESS_DXT4_5
);
150 fprintf(stderr
, "%s: bad image format\n", __FUNCTION__
);
154 /* Compute which mipmap levels we really want to send to the hardware.
156 driCalculateTextureFirstLastLevel( (driTextureObject
*) t
);
159 /* Figure out the amount of memory required to hold all the mipmap
160 * levels. Choose the smallest pitch to accomodate the largest
163 firstLevel
= t
->intel
.base
.firstLevel
;
164 lastLevel
= t
->intel
.base
.lastLevel
;
165 numLevels
= lastLevel
- firstLevel
+ 1;
169 /* All images must be loaded at this pitch. Count the number of
172 switch (tObj
->Target
) {
173 case GL_TEXTURE_CUBE_MAP
: {
174 const GLuint dim
= tObj
->Image
[0][firstLevel
]->Width
;
177 pitch
= dim
* t
->intel
.texelBytes
;
178 pitch
*= 2; /* double pitch for cube layouts */
179 pitch
= (pitch
+ 3) & ~3;
181 total_height
= dim
* 4;
183 for ( face
= 0 ; face
< 6 ; face
++) {
184 GLuint x
= initial_offsets
[face
][0] * dim
;
185 GLuint y
= initial_offsets
[face
][1] * dim
;
188 t
->intel
.base
.dirty_images
[face
] = ~0;
190 assert(tObj
->Image
[face
][firstLevel
]->Width
== dim
);
191 assert(tObj
->Image
[face
][firstLevel
]->Height
== dim
);
193 for (i
= 0; i
< numLevels
; i
++) {
194 t
->intel
.image
[face
][i
].image
= tObj
->Image
[face
][firstLevel
+ i
];
195 if (!t
->intel
.image
[face
][i
].image
) {
196 fprintf(stderr
, "no image %d %d\n", face
, i
);
197 break; /* can't happen */
200 t
->intel
.image
[face
][i
].offset
=
201 y
* pitch
+ x
* t
->intel
.texelBytes
;
202 t
->intel
.image
[face
][i
].internalFormat
= baseImage
->Format
;
205 x
+= step_offsets
[face
][0] * d
;
206 y
+= step_offsets
[face
][1] * d
;
211 case GL_TEXTURE_3D
: {
212 GLuint virtual_height
;
213 GLuint tmp_numLevels
= numLevels
;
214 pitch
= tObj
->Image
[0][firstLevel
]->Width
* t
->intel
.texelBytes
;
215 pitch
= (pitch
+ 3) & ~3;
216 t
->intel
.base
.dirty_images
[0] = ~0;
218 /* Calculate the size of a single slice. Hardware demands a
219 * minimum of 8 mipmaps, some of which might ultimately not be
222 if (tmp_numLevels
< 9)
225 virtual_height
= tObj
->Image
[0][firstLevel
]->Height
;
227 for ( total_height
= i
= 0 ; i
< tmp_numLevels
; i
++ ) {
228 t
->intel
.image
[0][i
].image
= tObj
->Image
[0][firstLevel
+ i
];
229 if (t
->intel
.image
[0][i
].image
) {
230 t
->intel
.image
[0][i
].offset
= total_height
* pitch
;
231 t
->intel
.image
[0][i
].internalFormat
= baseImage
->Format
;
234 total_height
+= MAX2(2, virtual_height
);
235 virtual_height
>>= 1;
238 t
->intel
.depth_pitch
= total_height
* pitch
;
240 /* Multiply slice size by texture depth for total size. It's
241 * remarkable how wasteful of memory all the i8x0 texture
244 total_height
*= t
->intel
.image
[0][0].image
->Depth
;
248 pitch
= tObj
->Image
[0][firstLevel
]->Width
* t
->intel
.texelBytes
;
249 pitch
= (pitch
+ 3) & ~3;
250 t
->intel
.base
.dirty_images
[0] = ~0;
252 for ( total_height
= i
= 0 ; i
< numLevels
; i
++ ) {
253 t
->intel
.image
[0][i
].image
= tObj
->Image
[0][firstLevel
+ i
];
254 if (!t
->intel
.image
[0][i
].image
)
257 t
->intel
.image
[0][i
].offset
= total_height
* pitch
;
258 t
->intel
.image
[0][i
].internalFormat
= baseImage
->Format
;
259 if (t
->intel
.image
[0][i
].image
->IsCompressed
)
261 if (t
->intel
.image
[0][i
].image
->Height
> 4)
262 total_height
+= t
->intel
.image
[0][i
].image
->Height
/4;
267 total_height
+= MAX2(2, t
->intel
.image
[0][i
].image
->Height
);
272 t
->intel
.Pitch
= pitch
;
273 t
->intel
.base
.totalSize
= total_height
*pitch
;
274 t
->intel
.max_level
= numLevels
-1;
275 t
->Setup
[I915_TEXREG_MS3
] =
276 (((tObj
->Image
[0][firstLevel
]->Height
- 1) << MS3_HEIGHT_SHIFT
) |
277 ((tObj
->Image
[0][firstLevel
]->Width
- 1) << MS3_WIDTH_SHIFT
) |
280 t
->Setup
[I915_TEXREG_MS4
] =
281 ((((pitch
/ 4) - 1) << MS4_PITCH_SHIFT
) |
282 MS4_CUBE_FACE_ENA_MASK
|
283 (((t
->intel
.max_level
* 4)) << MS4_MAX_LOD_SHIFT
) |
284 ((tObj
->Image
[0][firstLevel
]->Depth
- 1) << MS4_VOLUME_DEPTH_SHIFT
));
286 t
->Setup
[I915_TEXREG_SS2
] &= ~SS2_COLORSPACE_CONVERSION
;
287 t
->Setup
[I915_TEXREG_SS2
] |= ss2
;
289 t
->intel
.dirty
= I915_UPLOAD_TEX_ALL
;
293 /* The i915 (and related graphics cores) do not support GL_CLAMP. The
294 * Intel drivers for "other operating systems" implement GL_CLAMP as
295 * GL_CLAMP_TO_EDGE, so the same is done here.
297 static GLuint
translate_wrap_mode( GLenum wrap
)
300 case GL_REPEAT
: return TEXCOORDMODE_WRAP
;
301 case GL_CLAMP
: return TEXCOORDMODE_CLAMP_EDGE
; /* not quite correct */
302 case GL_CLAMP_TO_EDGE
: return TEXCOORDMODE_CLAMP_EDGE
;
303 case GL_CLAMP_TO_BORDER
: return TEXCOORDMODE_CLAMP_BORDER
;
304 case GL_MIRRORED_REPEAT
: return TEXCOORDMODE_MIRROR
;
305 default: return TEXCOORDMODE_WRAP
;
312 static void i915ImportTexObjState( struct gl_texture_object
*texObj
)
314 i915TextureObjectPtr t
= (i915TextureObjectPtr
)texObj
->DriverData
;
315 int minFilt
= 0, mipFilt
= 0, magFilt
= 0;
317 if(INTEL_DEBUG
&DEBUG_DRI
)
318 fprintf(stderr
, "%s\n", __FUNCTION__
);
320 switch (texObj
->MinFilter
) {
322 minFilt
= FILTER_NEAREST
;
323 mipFilt
= MIPFILTER_NONE
;
326 minFilt
= FILTER_LINEAR
;
327 mipFilt
= MIPFILTER_NONE
;
329 case GL_NEAREST_MIPMAP_NEAREST
:
330 minFilt
= FILTER_NEAREST
;
331 mipFilt
= MIPFILTER_NEAREST
;
333 case GL_LINEAR_MIPMAP_NEAREST
:
334 minFilt
= FILTER_LINEAR
;
335 mipFilt
= MIPFILTER_NEAREST
;
337 case GL_NEAREST_MIPMAP_LINEAR
:
338 minFilt
= FILTER_NEAREST
;
339 mipFilt
= MIPFILTER_LINEAR
;
341 case GL_LINEAR_MIPMAP_LINEAR
:
342 minFilt
= FILTER_LINEAR
;
343 mipFilt
= MIPFILTER_LINEAR
;
349 if ( texObj
->MaxAnisotropy
> 1.0 ) {
350 minFilt
= FILTER_ANISOTROPIC
;
351 magFilt
= FILTER_ANISOTROPIC
;
354 switch (texObj
->MagFilter
) {
356 magFilt
= FILTER_NEAREST
;
359 magFilt
= FILTER_LINEAR
;
366 t
->Setup
[I915_TEXREG_SS2
] &= ~SS2_MIN_FILTER_MASK
;
367 t
->Setup
[I915_TEXREG_SS2
] &= ~SS2_MIP_FILTER_MASK
;
368 t
->Setup
[I915_TEXREG_SS2
] &= ~SS2_MAG_FILTER_MASK
;
369 t
->Setup
[I915_TEXREG_SS2
] |= ((minFilt
<< SS2_MIN_FILTER_SHIFT
) |
370 (mipFilt
<< SS2_MIP_FILTER_SHIFT
) |
371 (magFilt
<< SS2_MAG_FILTER_SHIFT
));
374 GLuint ss3
= t
->Setup
[I915_TEXREG_SS3
] & ~(SS3_TCX_ADDR_MODE_MASK
|
375 SS3_TCY_ADDR_MODE_MASK
|
376 SS3_TCZ_ADDR_MODE_MASK
);
377 GLenum ws
= texObj
->WrapS
;
378 GLenum wt
= texObj
->WrapT
;
379 GLenum wr
= texObj
->WrapR
;
381 t
->refs_border_color
= 0;
383 if (texObj
->Target
== GL_TEXTURE_3D
&&
384 (texObj
->MinFilter
!= GL_NEAREST
||
385 texObj
->MagFilter
!= GL_NEAREST
)) {
387 /* Try to mimic GL_CLAMP functionality a little better -
388 * switch to CLAMP_TO_BORDER whenever a non-NEAREST filter is
389 * in use. Only do this for 3D textures at the moment --
390 * doing it universally would fix the conform texbc.c
393 if (ws
== GL_CLAMP
) ws
= GL_CLAMP_TO_BORDER
;
394 if (wt
== GL_CLAMP
) wt
= GL_CLAMP_TO_BORDER
;
395 if (wr
== GL_CLAMP
) wr
= GL_CLAMP_TO_BORDER
;
397 /* 3D textures don't seem to respect the border color.
398 * Fallback if there's ever a danger that they might refer to
401 if (ws
== GL_CLAMP_TO_BORDER
) t
->refs_border_color
= 1;
402 if (wt
== GL_CLAMP_TO_BORDER
) t
->refs_border_color
= 1;
403 if (wr
== GL_CLAMP_TO_BORDER
) t
->refs_border_color
= 1;
406 ss3
|= translate_wrap_mode(ws
) << SS3_TCX_ADDR_MODE_SHIFT
;
407 ss3
|= translate_wrap_mode(wt
) << SS3_TCY_ADDR_MODE_SHIFT
;
408 ss3
|= translate_wrap_mode(wr
) << SS3_TCZ_ADDR_MODE_SHIFT
;
410 if (ss3
!= t
->Setup
[I915_TEXREG_SS3
]) {
411 t
->intel
.dirty
= I915_UPLOAD_TEX_ALL
;
412 t
->Setup
[I915_TEXREG_SS3
] = ss3
;
417 const GLubyte
*color
= texObj
->_BorderChan
;
419 t
->Setup
[I915_TEXREG_SS4
] = INTEL_PACKCOLOR8888(color
[0],color
[1],
426 static void i915_import_tex_unit( i915ContextPtr i915
,
427 i915TextureObjectPtr t
,
430 GLuint state
[I915_TEX_SETUP_SIZE
];
432 if(INTEL_DEBUG
&DEBUG_TEXTURE
)
433 fprintf(stderr
, "%s unit(%d)\n", __FUNCTION__
, unit
);
435 if (i915
->intel
.CurrentTexObj
[unit
])
436 i915
->intel
.CurrentTexObj
[unit
]->base
.bound
&= ~(1U << unit
);
438 i915
->intel
.CurrentTexObj
[unit
] = (intelTextureObjectPtr
)t
;
439 t
->intel
.base
.bound
|= (1 << unit
);
441 if (t
->intel
.dirty
& I915_UPLOAD_TEX(unit
)) {
442 i915ImportTexObjState( t
->intel
.base
.tObj
);
443 t
->intel
.dirty
&= ~I915_UPLOAD_TEX(unit
);
446 state
[I915_TEXREG_MS2
] = t
->intel
.TextureOffset
;
447 state
[I915_TEXREG_MS3
] = t
->Setup
[I915_TEXREG_MS3
];
448 state
[I915_TEXREG_MS4
] = t
->Setup
[I915_TEXREG_MS4
];
450 state
[I915_TEXREG_SS2
] = (i915
->state
.Tex
[unit
][I915_TEXREG_SS2
] &
452 state
[I915_TEXREG_SS2
] |= (t
->Setup
[I915_TEXREG_SS2
] & ~SS2_LOD_BIAS_MASK
);
454 state
[I915_TEXREG_SS3
] = (i915
->state
.Tex
[unit
][I915_TEXREG_SS3
] &
455 SS3_NORMALIZED_COORDS
);
456 state
[I915_TEXREG_SS3
] |= (t
->Setup
[I915_TEXREG_SS3
] &
457 ~(SS3_NORMALIZED_COORDS
|
458 SS3_TEXTUREMAP_INDEX_MASK
));
460 state
[I915_TEXREG_SS3
] |= (unit
<<SS3_TEXTUREMAP_INDEX_SHIFT
);
462 state
[I915_TEXREG_SS4
] = t
->Setup
[I915_TEXREG_SS4
];
465 if (memcmp(state
, i915
->state
.Tex
[unit
], sizeof(state
)) != 0) {
466 I915_STATECHANGE( i915
, I915_UPLOAD_TEX(unit
) );
467 memcpy(i915
->state
.Tex
[unit
], state
, sizeof(state
));
473 static GLboolean
enable_tex_common( GLcontext
*ctx
, GLuint unit
)
475 i915ContextPtr i915
= I915_CONTEXT(ctx
);
476 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
477 struct gl_texture_object
*tObj
= texUnit
->_Current
;
478 i915TextureObjectPtr t
= (i915TextureObjectPtr
)tObj
->DriverData
;
480 if (0) fprintf(stderr
, "%s %d\n", __FUNCTION__
, unit
);
482 if (!(i915
->state
.active
& I915_UPLOAD_TEX(unit
))) {
483 I915_ACTIVESTATE(i915
, I915_UPLOAD_TEX(unit
), GL_TRUE
);
486 /* Fallback if there's a texture border */
487 if ( tObj
->Image
[0][tObj
->BaseLevel
]->Border
> 0 ) {
492 /* Update state if this is a different texture object to last
495 if (i915
->intel
.CurrentTexObj
[unit
] != &t
->intel
||
496 (t
->intel
.dirty
& I915_UPLOAD_TEX(unit
))) {
497 i915_import_tex_unit( i915
, t
, unit
);
498 i915
->tex_program
.translated
= 0;
504 static GLboolean
enable_tex_rect( GLcontext
*ctx
, GLuint unit
)
506 i915ContextPtr i915
= I915_CONTEXT(ctx
);
507 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
508 struct gl_texture_object
*tObj
= texUnit
->_Current
;
509 i915TextureObjectPtr t
= (i915TextureObjectPtr
)tObj
->DriverData
;
510 GLuint ss3
= i915
->state
.Tex
[unit
][I915_TEXREG_SS3
];
512 ss3
&= ~SS3_NORMALIZED_COORDS
;
514 if (ss3
!= i915
->state
.Tex
[unit
][I915_TEXREG_SS3
]) {
515 I915_STATECHANGE(i915
, I915_UPLOAD_TEX(unit
));
516 i915
->state
.Tex
[unit
][I915_TEXREG_SS3
] = ss3
;
519 /* Upload teximages (not pipelined)
521 if (t
->intel
.base
.dirty_images
[0]) {
522 i915SetTexImages( i915
, tObj
);
523 if (!intelUploadTexImages( &i915
->intel
, &t
->intel
, 0 )) {
532 static GLboolean
enable_tex_2d( GLcontext
*ctx
, GLuint unit
)
534 i915ContextPtr i915
= I915_CONTEXT(ctx
);
535 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
536 struct gl_texture_object
*tObj
= texUnit
->_Current
;
537 i915TextureObjectPtr t
= (i915TextureObjectPtr
)tObj
->DriverData
;
538 GLuint ss3
= i915
->state
.Tex
[unit
][I915_TEXREG_SS3
];
540 ss3
|= SS3_NORMALIZED_COORDS
;
542 if (ss3
!= i915
->state
.Tex
[unit
][I915_TEXREG_SS3
]) {
543 I915_STATECHANGE(i915
, I915_UPLOAD_TEX(unit
));
544 i915
->state
.Tex
[unit
][I915_TEXREG_SS3
] = ss3
;
547 /* Upload teximages (not pipelined)
549 if (t
->intel
.base
.dirty_images
[0]) {
550 i915SetTexImages( i915
, tObj
);
551 if (!intelUploadTexImages( &i915
->intel
, &t
->intel
, 0 )) {
559 static GLboolean
enable_tex_cube( GLcontext
*ctx
, GLuint unit
)
561 i915ContextPtr i915
= I915_CONTEXT(ctx
);
562 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
563 struct gl_texture_object
*tObj
= texUnit
->_Current
;
564 i915TextureObjectPtr t
= (i915TextureObjectPtr
)tObj
->DriverData
;
565 GLuint ss3
= i915
->state
.Tex
[unit
][I915_TEXREG_SS3
];
568 ss3
|= SS3_NORMALIZED_COORDS
;
570 if (ss3
!= i915
->state
.Tex
[unit
][I915_TEXREG_SS3
]) {
571 I915_STATECHANGE(i915
, I915_UPLOAD_TEX(unit
));
572 i915
->state
.Tex
[unit
][I915_TEXREG_SS3
] = ss3
;
575 /* Upload teximages (not pipelined)
577 if ( t
->intel
.base
.dirty_images
[0] || t
->intel
.base
.dirty_images
[1] ||
578 t
->intel
.base
.dirty_images
[2] || t
->intel
.base
.dirty_images
[3] ||
579 t
->intel
.base
.dirty_images
[4] || t
->intel
.base
.dirty_images
[5] ) {
580 i915SetTexImages( i915
, tObj
);
583 /* upload (per face) */
584 for (face
= 0; face
< 6; face
++) {
585 if (t
->intel
.base
.dirty_images
[face
]) {
586 if (!intelUploadTexImages( &i915
->intel
, &t
->intel
, face
)) {
596 static GLboolean
enable_tex_3d( GLcontext
*ctx
, GLuint unit
)
598 struct gl_texture_object
*tObj
= ctx
->Texture
.Unit
[unit
]._Current
;
599 i915TextureObjectPtr t
= (i915TextureObjectPtr
)tObj
->DriverData
;
601 /* 3D textures on I915 seem to get bogus border colors, hence this
604 if (t
->refs_border_color
)
613 static GLboolean
disable_tex( GLcontext
*ctx
, GLuint unit
)
615 i915ContextPtr i915
= I915_CONTEXT(ctx
);
617 if (i915
->state
.active
& I915_UPLOAD_TEX(unit
)) {
618 I915_ACTIVESTATE(i915
, I915_UPLOAD_TEX(unit
), GL_FALSE
);
621 /* The old texture is no longer bound to this texture unit.
624 if ( i915
->intel
.CurrentTexObj
[unit
] != NULL
) {
625 i915
->intel
.CurrentTexObj
[unit
]->base
.bound
&= ~(1U << 0);
626 i915
->intel
.CurrentTexObj
[unit
] = NULL
;
632 static GLboolean
i915UpdateTexUnit( GLcontext
*ctx
, GLuint unit
)
634 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
636 if (texUnit
->_ReallyEnabled
&&
637 INTEL_CONTEXT(ctx
)->intelScreen
->textureSize
< 2048 * 1024)
640 switch (texUnit
->_ReallyEnabled
) {
643 return (enable_tex_2d( ctx
, unit
) &&
644 enable_tex_common( ctx
, unit
));
645 case TEXTURE_RECT_BIT
:
646 return (enable_tex_rect( ctx
, unit
) &&
647 enable_tex_common( ctx
, unit
));
648 case TEXTURE_CUBE_BIT
:
649 return (enable_tex_cube( ctx
, unit
) &&
650 enable_tex_common( ctx
, unit
));
652 return (enable_tex_2d( ctx
, unit
) &&
653 enable_tex_common( ctx
, unit
) &&
654 enable_tex_3d( ctx
, unit
));
656 return disable_tex( ctx
, unit
);
663 void i915UpdateTextureState( intelContextPtr intel
)
665 GLcontext
*ctx
= &intel
->ctx
;
666 GLboolean ok
= GL_TRUE
;
669 for (i
= 0 ; i
< I915_TEX_UNITS
&& ok
; i
++) {
670 ok
= i915UpdateTexUnit( ctx
, i
);
673 FALLBACK( intel
, I915_FALLBACK_TEXTURE
, !ok
);