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
;
126 fprintf(stderr
, "%s: bad image format\n", __FUNCTION__
);
130 /* Compute which mipmap levels we really want to send to the hardware.
132 driCalculateTextureFirstLastLevel( (driTextureObject
*) t
);
135 /* Figure out the amount of memory required to hold all the mipmap
136 * levels. Choose the smallest pitch to accomodate the largest
139 firstLevel
= t
->intel
.base
.firstLevel
;
140 lastLevel
= t
->intel
.base
.lastLevel
;
141 numLevels
= lastLevel
- firstLevel
+ 1;
145 /* All images must be loaded at this pitch. Count the number of
148 switch (tObj
->Target
) {
149 case GL_TEXTURE_CUBE_MAP
: {
150 const GLuint dim
= tObj
->Image
[0][firstLevel
]->Width
;
153 pitch
= dim
* t
->intel
.texelBytes
;
154 pitch
*= 2; /* double pitch for cube layouts */
155 pitch
= (pitch
+ 3) & ~3;
157 total_height
= dim
* 4;
159 for ( face
= 0 ; face
< 6 ; face
++) {
160 GLuint x
= initial_offsets
[face
][0] * dim
;
161 GLuint y
= initial_offsets
[face
][1] * dim
;
164 t
->intel
.base
.dirty_images
[face
] = ~0;
166 assert(tObj
->Image
[face
][firstLevel
]->Width
== dim
);
167 assert(tObj
->Image
[face
][firstLevel
]->Height
== dim
);
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 */
176 t
->intel
.image
[face
][i
].offset
=
177 y
* pitch
+ x
* t
->intel
.texelBytes
;
178 t
->intel
.image
[face
][i
].internalFormat
= baseImage
->Format
;
181 x
+= step_offsets
[face
][0] * d
;
182 y
+= step_offsets
[face
][1] * d
;
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;
194 /* Calculate the size of a single slice. Hardware demands a
195 * minimum of 8 mipmaps, some of which might ultimately not be
198 if (tmp_numLevels
< 9)
201 virtual_height
= tObj
->Image
[0][firstLevel
]->Height
;
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
;
210 total_height
+= MAX2(2, virtual_height
);
211 virtual_height
>>= 1;
214 t
->intel
.depth_pitch
= total_height
* pitch
;
216 /* Multiply slice size by texture depth for total size. It's
217 * remarkable how wasteful of memory all the i8x0 texture
220 total_height
*= t
->intel
.image
[0][0].image
->Depth
;
224 pitch
= tObj
->Image
[0][firstLevel
]->Width
* t
->intel
.texelBytes
;
225 pitch
= (pitch
+ 3) & ~3;
226 t
->intel
.base
.dirty_images
[0] = ~0;
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
)
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
);
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
) |
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
));
254 t
->Setup
[I915_TEXREG_SS2
] &= ~SS2_COLORSPACE_CONVERSION
;
255 t
->Setup
[I915_TEXREG_SS2
] |= ss2
;
257 t
->intel
.dirty
= I915_UPLOAD_TEX_ALL
;
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.
265 static GLuint
translate_wrap_mode( GLenum 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
;
280 static void i915ImportTexObjState( struct gl_texture_object
*texObj
)
282 i915TextureObjectPtr t
= (i915TextureObjectPtr
)texObj
->DriverData
;
283 int minFilt
= 0, mipFilt
= 0, magFilt
= 0;
285 if(INTEL_DEBUG
&DEBUG_DRI
)
286 fprintf(stderr
, "%s\n", __FUNCTION__
);
288 switch (texObj
->MinFilter
) {
290 minFilt
= FILTER_NEAREST
;
291 mipFilt
= MIPFILTER_NONE
;
294 minFilt
= FILTER_LINEAR
;
295 mipFilt
= MIPFILTER_NONE
;
297 case GL_NEAREST_MIPMAP_NEAREST
:
298 minFilt
= FILTER_NEAREST
;
299 mipFilt
= MIPFILTER_NEAREST
;
301 case GL_LINEAR_MIPMAP_NEAREST
:
302 minFilt
= FILTER_LINEAR
;
303 mipFilt
= MIPFILTER_NEAREST
;
305 case GL_NEAREST_MIPMAP_LINEAR
:
306 minFilt
= FILTER_NEAREST
;
307 mipFilt
= MIPFILTER_LINEAR
;
309 case GL_LINEAR_MIPMAP_LINEAR
:
310 minFilt
= FILTER_LINEAR
;
311 mipFilt
= MIPFILTER_LINEAR
;
317 if ( texObj
->MaxAnisotropy
> 1.0 ) {
318 minFilt
= FILTER_ANISOTROPIC
;
319 magFilt
= FILTER_ANISOTROPIC
;
322 switch (texObj
->MagFilter
) {
324 magFilt
= FILTER_NEAREST
;
327 magFilt
= FILTER_LINEAR
;
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
));
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
;
349 t
->refs_border_color
= 0;
351 if (texObj
->Target
== GL_TEXTURE_3D
&&
352 (texObj
->MinFilter
!= GL_NEAREST
||
353 texObj
->MagFilter
!= GL_NEAREST
)) {
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
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
;
365 /* 3D textures don't seem to respect the border color.
366 * Fallback if there's ever a danger that they might refer to
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;
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
;
378 if (ss3
!= t
->Setup
[I915_TEXREG_SS3
]) {
379 t
->intel
.dirty
= I915_UPLOAD_TEX_ALL
;
380 t
->Setup
[I915_TEXREG_SS3
] = ss3
;
385 const GLubyte
*color
= texObj
->_BorderChan
;
387 t
->Setup
[I915_TEXREG_SS4
] = INTEL_PACKCOLOR8888(color
[0],color
[1],
394 static void i915_import_tex_unit( i915ContextPtr i915
,
395 i915TextureObjectPtr t
,
398 GLuint state
[I915_TEX_SETUP_SIZE
];
400 if(INTEL_DEBUG
&DEBUG_TEXTURE
)
401 fprintf(stderr
, "%s unit(%d)\n", __FUNCTION__
, unit
);
403 if (i915
->intel
.CurrentTexObj
[unit
])
404 i915
->intel
.CurrentTexObj
[unit
]->base
.bound
&= ~(1U << unit
);
406 i915
->intel
.CurrentTexObj
[unit
] = (intelTextureObjectPtr
)t
;
407 t
->intel
.base
.bound
|= (1 << unit
);
409 if (t
->intel
.dirty
& I915_UPLOAD_TEX(unit
)) {
410 i915ImportTexObjState( t
->intel
.base
.tObj
);
411 t
->intel
.dirty
&= ~I915_UPLOAD_TEX(unit
);
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
];
418 state
[I915_TEXREG_SS2
] = (i915
->state
.Tex
[unit
][I915_TEXREG_SS2
] &
420 state
[I915_TEXREG_SS2
] |= (t
->Setup
[I915_TEXREG_SS2
] & ~SS2_LOD_BIAS_MASK
);
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
));
428 state
[I915_TEXREG_SS3
] |= (unit
<<SS3_TEXTUREMAP_INDEX_SHIFT
);
430 state
[I915_TEXREG_SS4
] = t
->Setup
[I915_TEXREG_SS4
];
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
));
441 static GLboolean
enable_tex_common( GLcontext
*ctx
, GLuint unit
)
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
;
448 if (0) fprintf(stderr
, "%s %d\n", __FUNCTION__
, unit
);
450 if (!(i915
->state
.active
& I915_UPLOAD_TEX(unit
))) {
451 I915_ACTIVESTATE(i915
, I915_UPLOAD_TEX(unit
), GL_TRUE
);
454 /* Fallback if there's a texture border */
455 if ( tObj
->Image
[0][tObj
->BaseLevel
]->Border
> 0 ) {
460 /* Update state if this is a different texture object to last
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;
472 static GLboolean
enable_tex_rect( GLcontext
*ctx
, GLuint unit
)
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
];
480 ss3
&= ~SS3_NORMALIZED_COORDS
;
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
;
487 /* Upload teximages (not pipelined)
489 if (t
->intel
.base
.dirty_images
[0]) {
490 i915SetTexImages( i915
, tObj
);
491 if (!intelUploadTexImages( &i915
->intel
, &t
->intel
, 0 )) {
500 static GLboolean
enable_tex_2d( GLcontext
*ctx
, GLuint unit
)
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
];
508 ss3
|= SS3_NORMALIZED_COORDS
;
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
;
515 /* Upload teximages (not pipelined)
517 if (t
->intel
.base
.dirty_images
[0]) {
518 i915SetTexImages( i915
, tObj
);
519 if (!intelUploadTexImages( &i915
->intel
, &t
->intel
, 0 )) {
527 static GLboolean
enable_tex_cube( GLcontext
*ctx
, GLuint unit
)
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
];
536 ss3
|= SS3_NORMALIZED_COORDS
;
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
;
543 /* Upload teximages (not pipelined)
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
);
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
)) {
564 static GLboolean
enable_tex_3d( GLcontext
*ctx
, GLuint unit
)
566 struct gl_texture_object
*tObj
= ctx
->Texture
.Unit
[unit
]._Current
;
567 i915TextureObjectPtr t
= (i915TextureObjectPtr
)tObj
->DriverData
;
569 /* 3D textures on I915 seem to get bogus border colors, hence this
572 if (t
->refs_border_color
)
581 static GLboolean
disable_tex( GLcontext
*ctx
, GLuint unit
)
583 i915ContextPtr i915
= I915_CONTEXT(ctx
);
585 if (i915
->state
.active
& I915_UPLOAD_TEX(unit
)) {
586 I915_ACTIVESTATE(i915
, I915_UPLOAD_TEX(unit
), GL_FALSE
);
589 /* The old texture is no longer bound to this texture unit.
592 if ( i915
->intel
.CurrentTexObj
[unit
] != NULL
) {
593 i915
->intel
.CurrentTexObj
[unit
]->base
.bound
&= ~(1U << 0);
594 i915
->intel
.CurrentTexObj
[unit
] = NULL
;
600 static GLboolean
i915UpdateTexUnit( GLcontext
*ctx
, GLuint unit
)
602 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
604 if (texUnit
->_ReallyEnabled
&&
605 INTEL_CONTEXT(ctx
)->intelScreen
->textureSize
< 2048 * 1024)
608 switch (texUnit
->_ReallyEnabled
) {
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
));
620 return (enable_tex_2d( ctx
, unit
) &&
621 enable_tex_common( ctx
, unit
) &&
622 enable_tex_3d( ctx
, unit
));
624 return disable_tex( ctx
, unit
);
631 void i915UpdateTextureState( intelContextPtr intel
)
633 GLcontext
*ctx
= &intel
->ctx
;
634 GLboolean ok
= GL_TRUE
;
637 for (i
= 0 ; i
< I915_TEX_UNITS
&& ok
; i
++) {
638 ok
= i915UpdateTexUnit( ctx
, i
);
641 FALLBACK( intel
, I915_FALLBACK_TEXTURE
, !ok
);