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 i915LayoutTextureImages( i915ContextPtr i915
,
64 struct gl_texture_object
*tObj
)
66 const struct gl_texture_image
*baseImage
= tObj
->Image
[0][tObj
->BaseLevel
];
67 i915TextureObjectPtr t
= (i915TextureObjectPtr
) tObj
->DriverData
;
68 GLint firstLevel
, lastLevel
, numLevels
;
69 GLint i
, total_height
, pitch
;
71 /* Compute which mipmap levels we really want to send to the hardware.
73 driCalculateTextureFirstLastLevel( (driTextureObject
*) t
);
75 /* Figure out the amount of memory required to hold all the mipmap
76 * levels. Choose the smallest pitch to accomodate the largest
79 firstLevel
= t
->intel
.base
.firstLevel
;
80 lastLevel
= t
->intel
.base
.lastLevel
;
81 numLevels
= lastLevel
- firstLevel
+ 1;
85 /* All images must be loaded at this pitch. Count the number of
88 switch (tObj
->Target
) {
89 case GL_TEXTURE_CUBE_MAP
: {
90 const GLuint dim
= tObj
->Image
[0][firstLevel
]->Width
;
93 pitch
= dim
* t
->intel
.texelBytes
;
94 pitch
*= 2; /* double pitch for cube layouts */
95 pitch
= (pitch
+ 3) & ~3;
97 total_height
= dim
* 4;
99 for ( face
= 0 ; face
< 6 ; face
++) {
100 GLuint x
= initial_offsets
[face
][0] * dim
;
101 GLuint y
= initial_offsets
[face
][1] * dim
;
104 t
->intel
.base
.dirty_images
[face
] = ~0;
106 assert(tObj
->Image
[face
][firstLevel
]->Width
== dim
);
107 assert(tObj
->Image
[face
][firstLevel
]->Height
== dim
);
109 for (i
= 0; i
< numLevels
; i
++) {
110 t
->intel
.image
[face
][i
].image
= tObj
->Image
[face
][firstLevel
+ i
];
111 if (!t
->intel
.image
[face
][i
].image
) {
112 fprintf(stderr
, "no image %d %d\n", face
, i
);
113 break; /* can't happen */
116 t
->intel
.image
[face
][i
].offset
=
117 y
* pitch
+ x
* t
->intel
.texelBytes
;
118 t
->intel
.image
[face
][i
].internalFormat
= baseImage
->_BaseFormat
;
121 x
+= step_offsets
[face
][0] * d
;
122 y
+= step_offsets
[face
][1] * d
;
127 case GL_TEXTURE_3D
: {
128 GLuint virtual_height
;
129 GLuint tmp_numLevels
= numLevels
;
130 pitch
= tObj
->Image
[0][firstLevel
]->Width
* t
->intel
.texelBytes
;
131 pitch
= (pitch
+ 3) & ~3;
132 t
->intel
.base
.dirty_images
[0] = ~0;
134 /* Calculate the size of a single slice. Hardware demands a
135 * minimum of 8 mipmaps, some of which might ultimately not be
138 if (tmp_numLevels
< 9)
141 virtual_height
= tObj
->Image
[0][firstLevel
]->Height
;
143 for ( total_height
= i
= 0 ; i
< tmp_numLevels
; i
++ ) {
144 t
->intel
.image
[0][i
].image
= tObj
->Image
[0][firstLevel
+ i
];
145 if (t
->intel
.image
[0][i
].image
) {
146 t
->intel
.image
[0][i
].offset
= total_height
* pitch
;
147 t
->intel
.image
[0][i
].internalFormat
= baseImage
->_BaseFormat
;
150 total_height
+= MAX2(2, virtual_height
);
151 virtual_height
>>= 1;
154 t
->intel
.depth_pitch
= total_height
* pitch
;
156 /* Multiply slice size by texture depth for total size. It's
157 * remarkable how wasteful of memory all the i8x0 texture
160 total_height
*= t
->intel
.image
[0][0].image
->Depth
;
164 pitch
= tObj
->Image
[0][firstLevel
]->Width
* t
->intel
.texelBytes
;
165 pitch
= (pitch
+ 3) & ~3;
166 t
->intel
.base
.dirty_images
[0] = ~0;
168 for ( total_height
= i
= 0 ; i
< numLevels
; i
++ ) {
169 t
->intel
.image
[0][i
].image
= tObj
->Image
[0][firstLevel
+ i
];
170 if (!t
->intel
.image
[0][i
].image
)
173 t
->intel
.image
[0][i
].offset
= total_height
* pitch
;
174 t
->intel
.image
[0][i
].internalFormat
= baseImage
->_BaseFormat
;
175 if (t
->intel
.image
[0][i
].image
->IsCompressed
)
177 if (t
->intel
.image
[0][i
].image
->Height
> 4)
178 total_height
+= t
->intel
.image
[0][i
].image
->Height
/4;
183 total_height
+= MAX2(2, t
->intel
.image
[0][i
].image
->Height
);
188 t
->intel
.Pitch
= pitch
;
189 t
->intel
.base
.totalSize
= total_height
*pitch
;
190 t
->intel
.max_level
= numLevels
-1;
194 static void i945LayoutTextureImages( i915ContextPtr i915
,
195 struct gl_texture_object
*tObj
)
197 const struct gl_texture_image
*baseImage
= tObj
->Image
[0][tObj
->BaseLevel
];
198 i915TextureObjectPtr t
= (i915TextureObjectPtr
) tObj
->DriverData
;
199 GLint firstLevel
, lastLevel
, numLevels
;
200 GLint i
, total_height
, pitch
, sz
, max_offset
= 0, offset
;
203 /* Compute which mipmap levels we really want to send to the hardware.
205 driCalculateTextureFirstLastLevel( (driTextureObject
*) t
);
207 /* Figure out the amount of memory required to hold all the mipmap
208 * levels. Choose the smallest pitch to accomodate the largest
211 firstLevel
= t
->intel
.base
.firstLevel
;
212 lastLevel
= t
->intel
.base
.lastLevel
;
213 numLevels
= lastLevel
- firstLevel
+ 1;
217 /* All images must be loaded at this pitch. Count the number of
220 switch (tObj
->Target
) {
221 case GL_TEXTURE_CUBE_MAP
: {
222 const GLuint dim
= tObj
->Image
[0][firstLevel
]->Width
;
225 /* Depending on the size of the largest images, pitch can be
226 * determined either by the old-style packing of cubemap faces,
227 * or the final row of 4x4, 2x2 and 1x1 faces below this.
230 pitch
= dim
* t
->intel
.texelBytes
;
231 pitch
*= 2; /* double pitch for cube layouts */
232 pitch
= (pitch
+ 3) & ~3;
235 pitch
= 14 * 8 * t
->intel
.texelBytes
; /* determined by row of
240 total_height
= dim
* 4 + 4;
242 for ( face
= 0 ; face
< 6 ; face
++) {
243 GLuint x
= initial_offsets
[face
][0] * dim
;
244 GLuint y
= initial_offsets
[face
][1] * dim
;
247 if (dim
== 4 && face
>= 4) {
248 y
= total_height
- 4;
252 y
= total_height
- 4;
256 t
->intel
.base
.dirty_images
[face
] = ~0;
258 assert(tObj
->Image
[face
][firstLevel
]->Width
== dim
);
259 assert(tObj
->Image
[face
][firstLevel
]->Height
== dim
);
261 for (i
= 0; i
< numLevels
; i
++) {
264 t
->intel
.image
[face
][i
].image
= tObj
->Image
[face
][firstLevel
+ i
];
265 assert(t
->intel
.image
[face
][i
].image
);
267 t
->intel
.image
[face
][i
].offset
=
268 y
* pitch
+ x
* t
->intel
.texelBytes
;
269 t
->intel
.image
[face
][i
].internalFormat
= baseImage
->_BaseFormat
;
278 x
+= step_offsets
[face
][0] * d
;
279 y
+= step_offsets
[face
][1] * d
;
288 y
= total_height
- 4;
294 y
= total_height
- 4;
303 x
+= step_offsets
[face
][0] * d
;
304 y
+= step_offsets
[face
][1] * d
;
309 max_offset
= total_height
* pitch
;
312 case GL_TEXTURE_3D
: {
313 GLuint depth_packing
= 0, depth_pack_pitch
;
314 GLuint tmp_numLevels
= numLevels
;
315 pitch
= tObj
->Image
[0][firstLevel
]->Width
* t
->intel
.texelBytes
;
316 pitch
= (pitch
+ 3) & ~3;
317 depth_pack_pitch
= pitch
;
319 t
->intel
.base
.dirty_images
[0] = ~0;
322 for ( total_height
= i
= 0 ; i
< tmp_numLevels
; i
++ ) {
323 t
->intel
.image
[0][i
].image
= tObj
->Image
[0][firstLevel
+ i
];
324 if (!t
->intel
.image
[0][i
].image
)
328 t
->intel
.image
[0][i
].offset
= total_height
* pitch
;
329 t
->intel
.image
[0][i
].internalFormat
= baseImage
->_BaseFormat
;
333 total_height
+= MAX2(2, t
->intel
.image
[0][i
].image
->Height
) *
334 MAX2((t
->intel
.image
[0][i
].image
->Depth
>> depth_packing
), 1);
336 /* When alignment dominates, can't increase depth packing?
337 * Or does pitch grow??? What are the alignment constraints,
340 if (depth_pack_pitch
> 4) {
342 depth_pack_pitch
<<= 2;
346 max_offset
= total_height
* pitch
;
350 pitch
= tObj
->Image
[0][firstLevel
]->Width
* t
->intel
.texelBytes
;
351 pitch
= (pitch
+ 3) & ~3;
352 t
->intel
.base
.dirty_images
[0] = ~0;
355 for ( offset
= i
= 0 ; i
< numLevels
; i
++ ) {
356 t
->intel
.image
[0][i
].image
= tObj
->Image
[0][firstLevel
+ i
];
357 if (!t
->intel
.image
[0][i
].image
)
360 t
->intel
.image
[0][i
].offset
= offset
;
361 t
->intel
.image
[0][i
].internalFormat
= baseImage
->_BaseFormat
;
363 if (t
->intel
.image
[0][i
].image
->IsCompressed
)
364 sz
= MAX2(1, t
->intel
.image
[0][i
].image
->Height
/4) * pitch
;
366 sz
= MAX2(2, t
->intel
.image
[0][i
].image
->Height
) * pitch
;
368 /* Because the images are packed better, the final offset
369 * might not be the maximal one:
371 max_offset
= MAX2(max_offset
, offset
+ sz
);
373 /* LPT change: step right after second mipmap.
384 t
->intel
.Pitch
= pitch
;
385 t
->intel
.base
.totalSize
= max_offset
;
386 t
->intel
.max_level
= numLevels
-1;
392 static void i915SetTexImages( i915ContextPtr i915
,
393 struct gl_texture_object
*tObj
)
395 GLuint textureFormat
;
396 i915TextureObjectPtr t
= (i915TextureObjectPtr
) tObj
->DriverData
;
397 const struct gl_texture_image
*baseImage
= tObj
->Image
[0][tObj
->BaseLevel
];
400 switch( baseImage
->TexFormat
->MesaFormat
) {
402 t
->intel
.texelBytes
= 1;
403 textureFormat
= MAPSURF_8BIT
| MT_8BIT_L8
;
407 t
->intel
.texelBytes
= 1;
408 textureFormat
= MAPSURF_8BIT
| MT_8BIT_I8
;
412 t
->intel
.texelBytes
= 1;
413 textureFormat
= MAPSURF_8BIT
| MT_8BIT_A8
;
416 case MESA_FORMAT_AL88
:
417 t
->intel
.texelBytes
= 2;
418 textureFormat
= MAPSURF_16BIT
| MT_16BIT_AY88
;
421 case MESA_FORMAT_RGB565
:
422 t
->intel
.texelBytes
= 2;
423 textureFormat
= MAPSURF_16BIT
| MT_16BIT_RGB565
;
426 case MESA_FORMAT_ARGB1555
:
427 t
->intel
.texelBytes
= 2;
428 textureFormat
= MAPSURF_16BIT
| MT_16BIT_ARGB1555
;
431 case MESA_FORMAT_ARGB4444
:
432 t
->intel
.texelBytes
= 2;
433 textureFormat
= MAPSURF_16BIT
| MT_16BIT_ARGB4444
;
436 case MESA_FORMAT_ARGB8888
:
437 t
->intel
.texelBytes
= 4;
438 textureFormat
= MAPSURF_32BIT
| MT_32BIT_ARGB8888
;
441 case MESA_FORMAT_YCBCR_REV
:
442 t
->intel
.texelBytes
= 2;
443 textureFormat
= (MAPSURF_422
| MT_422_YCRCB_NORMAL
);
444 ss2
|= SS2_COLORSPACE_CONVERSION
;
447 case MESA_FORMAT_YCBCR
:
448 t
->intel
.texelBytes
= 2;
449 textureFormat
= (MAPSURF_422
| MT_422_YCRCB_SWAPY
);
450 ss2
|= SS2_COLORSPACE_CONVERSION
;
453 case MESA_FORMAT_RGB_FXT1
:
454 case MESA_FORMAT_RGBA_FXT1
:
455 t
->intel
.texelBytes
= 2;
456 textureFormat
= (MAPSURF_COMPRESSED
| MT_COMPRESS_FXT1
);
459 case MESA_FORMAT_DEPTH_COMPONENT16
:
460 t
->intel
.texelBytes
= 2;
461 textureFormat
= (MAPSURF_16BIT
| MT_16BIT_L16
);
464 case MESA_FORMAT_RGBA_DXT1
:
465 case MESA_FORMAT_RGB_DXT1
:
467 * DXTn pitches are Width/4 * blocksize in bytes
468 * for DXT1: blocksize=8 so Width/4*8 = Width * 2
469 * for DXT3/5: blocksize=16 so Width/4*16 = Width * 4
471 t
->intel
.texelBytes
= 2;
472 textureFormat
= (MAPSURF_COMPRESSED
| MT_COMPRESS_DXT1
);
475 case MESA_FORMAT_RGBA_DXT3
:
476 t
->intel
.texelBytes
= 4;
477 textureFormat
= (MAPSURF_COMPRESSED
| MT_COMPRESS_DXT2_3
);
480 case MESA_FORMAT_RGBA_DXT5
:
481 t
->intel
.texelBytes
= 4;
482 textureFormat
= (MAPSURF_COMPRESSED
| MT_COMPRESS_DXT4_5
);
486 case MESA_FORMAT_DEPTH_COMPONENT_X8Z24
:
487 t
->intel
.texelBytes
= 4;
488 textureFormat
= (MAPSURF_32BIT
| MT_32BIT_xL824
);
493 fprintf(stderr
, "%s: bad image format %x\n", __FUNCTION__
,
494 baseImage
->TexFormat
->MesaFormat
);
499 if (i915
->intel
.intelScreen
->deviceID
== PCI_CHIP_I945_G
)
500 i945LayoutTextureImages( i915
, tObj
);
502 i915LayoutTextureImages( i915
, tObj
);
504 t
->Setup
[I915_TEXREG_MS3
] =
505 (((tObj
->Image
[0][t
->intel
.base
.firstLevel
]->Height
- 1) << MS3_HEIGHT_SHIFT
) |
506 ((tObj
->Image
[0][t
->intel
.base
.firstLevel
]->Width
- 1) << MS3_WIDTH_SHIFT
) |
510 t
->Setup
[I915_TEXREG_MS4
] =
511 ((((t
->intel
.Pitch
/ 4) - 1) << MS4_PITCH_SHIFT
) |
512 MS4_CUBE_FACE_ENA_MASK
|
513 (((t
->intel
.max_level
* 4)) << MS4_MAX_LOD_SHIFT
) |
514 ((tObj
->Image
[0][t
->intel
.base
.firstLevel
]->Depth
- 1) << MS4_VOLUME_DEPTH_SHIFT
));
516 t
->Setup
[I915_TEXREG_SS2
] &= ~(SS2_COLORSPACE_CONVERSION
);
517 t
->Setup
[I915_TEXREG_SS2
] |= ss2
;
519 t
->intel
.dirty
= I915_UPLOAD_TEX_ALL
;
524 /* The i915 (and related graphics cores) do not support GL_CLAMP. The
525 * Intel drivers for "other operating systems" implement GL_CLAMP as
526 * GL_CLAMP_TO_EDGE, so the same is done here.
528 static GLuint
translate_wrap_mode( GLenum wrap
)
531 case GL_REPEAT
: return TEXCOORDMODE_WRAP
;
532 case GL_CLAMP
: return TEXCOORDMODE_CLAMP_EDGE
; /* not quite correct */
533 case GL_CLAMP_TO_EDGE
: return TEXCOORDMODE_CLAMP_EDGE
;
534 case GL_CLAMP_TO_BORDER
: return TEXCOORDMODE_CLAMP_BORDER
;
535 case GL_MIRRORED_REPEAT
: return TEXCOORDMODE_MIRROR
;
536 default: return TEXCOORDMODE_WRAP
;
543 static void i915ImportTexObjState( struct gl_texture_object
*texObj
)
545 i915TextureObjectPtr t
= (i915TextureObjectPtr
)texObj
->DriverData
;
546 int minFilt
= 0, mipFilt
= 0, magFilt
= 0, shadow
= 0;
548 if(INTEL_DEBUG
&DEBUG_DRI
)
549 fprintf(stderr
, "%s\n", __FUNCTION__
);
551 switch (texObj
->MinFilter
) {
553 minFilt
= FILTER_NEAREST
;
554 mipFilt
= MIPFILTER_NONE
;
557 minFilt
= FILTER_LINEAR
;
558 mipFilt
= MIPFILTER_NONE
;
560 case GL_NEAREST_MIPMAP_NEAREST
:
561 minFilt
= FILTER_NEAREST
;
562 mipFilt
= MIPFILTER_NEAREST
;
564 case GL_LINEAR_MIPMAP_NEAREST
:
565 minFilt
= FILTER_LINEAR
;
566 mipFilt
= MIPFILTER_NEAREST
;
568 case GL_NEAREST_MIPMAP_LINEAR
:
569 minFilt
= FILTER_NEAREST
;
570 mipFilt
= MIPFILTER_LINEAR
;
572 case GL_LINEAR_MIPMAP_LINEAR
:
573 minFilt
= FILTER_LINEAR
;
574 mipFilt
= MIPFILTER_LINEAR
;
580 if ( texObj
->MaxAnisotropy
> 1.0 ) {
581 minFilt
= FILTER_ANISOTROPIC
;
582 magFilt
= FILTER_ANISOTROPIC
;
585 switch (texObj
->MagFilter
) {
587 magFilt
= FILTER_NEAREST
;
590 magFilt
= FILTER_LINEAR
;
597 if (texObj
->CompareMode
== GL_COMPARE_R_TO_TEXTURE_ARB
&&
598 texObj
->Target
!= GL_TEXTURE_3D
) {
600 shadow
= SS2_SHADOW_ENABLE
;
601 shadow
|= intel_translate_compare_func( texObj
->CompareFunc
);
603 minFilt
= FILTER_4X4_FLAT
;
604 magFilt
= FILTER_4X4_FLAT
;
608 t
->Setup
[I915_TEXREG_SS2
] &= ~(SS2_MIN_FILTER_MASK
|
609 SS2_MIP_FILTER_MASK
|
610 SS2_MAG_FILTER_MASK
|
612 SS2_SHADOW_FUNC_MASK
);
613 t
->Setup
[I915_TEXREG_SS2
] |= ((minFilt
<< SS2_MIN_FILTER_SHIFT
) |
614 (mipFilt
<< SS2_MIP_FILTER_SHIFT
) |
615 (magFilt
<< SS2_MAG_FILTER_SHIFT
) |
619 GLuint ss3
= t
->Setup
[I915_TEXREG_SS3
] & ~(SS3_TCX_ADDR_MODE_MASK
|
620 SS3_TCY_ADDR_MODE_MASK
|
621 SS3_TCZ_ADDR_MODE_MASK
);
622 GLenum ws
= texObj
->WrapS
;
623 GLenum wt
= texObj
->WrapT
;
624 GLenum wr
= texObj
->WrapR
;
626 t
->refs_border_color
= 0;
628 if (texObj
->Target
== GL_TEXTURE_3D
&&
629 (texObj
->MinFilter
!= GL_NEAREST
||
630 texObj
->MagFilter
!= GL_NEAREST
)) {
632 /* Try to mimic GL_CLAMP functionality a little better -
633 * switch to CLAMP_TO_BORDER whenever a non-NEAREST filter is
634 * in use. Only do this for 3D textures at the moment --
635 * doing it universally would fix the conform texbc.c
638 if (ws
== GL_CLAMP
) ws
= GL_CLAMP_TO_BORDER
;
639 if (wt
== GL_CLAMP
) wt
= GL_CLAMP_TO_BORDER
;
640 if (wr
== GL_CLAMP
) wr
= GL_CLAMP_TO_BORDER
;
642 /* 3D textures don't seem to respect the border color.
643 * Fallback if there's ever a danger that they might refer to
646 if (ws
== GL_CLAMP_TO_BORDER
) t
->refs_border_color
= 1;
647 if (wt
== GL_CLAMP_TO_BORDER
) t
->refs_border_color
= 1;
648 if (wr
== GL_CLAMP_TO_BORDER
) t
->refs_border_color
= 1;
651 ss3
|= translate_wrap_mode(ws
) << SS3_TCX_ADDR_MODE_SHIFT
;
652 ss3
|= translate_wrap_mode(wt
) << SS3_TCY_ADDR_MODE_SHIFT
;
653 ss3
|= translate_wrap_mode(wr
) << SS3_TCZ_ADDR_MODE_SHIFT
;
655 if (ss3
!= t
->Setup
[I915_TEXREG_SS3
]) {
656 t
->intel
.dirty
= I915_UPLOAD_TEX_ALL
;
657 t
->Setup
[I915_TEXREG_SS3
] = ss3
;
662 const GLubyte
*color
= texObj
->_BorderChan
;
664 t
->Setup
[I915_TEXREG_SS4
] = INTEL_PACKCOLOR8888(color
[0],color
[1],
671 static void i915_import_tex_unit( i915ContextPtr i915
,
672 i915TextureObjectPtr t
,
675 GLuint state
[I915_TEX_SETUP_SIZE
];
677 if(INTEL_DEBUG
&DEBUG_TEXTURE
)
678 fprintf(stderr
, "%s unit(%d)\n", __FUNCTION__
, unit
);
680 if (i915
->intel
.CurrentTexObj
[unit
])
681 i915
->intel
.CurrentTexObj
[unit
]->base
.bound
&= ~(1U << unit
);
683 i915
->intel
.CurrentTexObj
[unit
] = (intelTextureObjectPtr
)t
;
684 t
->intel
.base
.bound
|= (1 << unit
);
686 if (t
->intel
.dirty
& I915_UPLOAD_TEX(unit
)) {
687 i915ImportTexObjState( t
->intel
.base
.tObj
);
688 t
->intel
.dirty
&= ~I915_UPLOAD_TEX(unit
);
691 state
[I915_TEXREG_MS2
] = t
->intel
.TextureOffset
;
692 state
[I915_TEXREG_MS3
] = t
->Setup
[I915_TEXREG_MS3
];
693 state
[I915_TEXREG_MS4
] = t
->Setup
[I915_TEXREG_MS4
];
695 state
[I915_TEXREG_SS2
] = (i915
->state
.Tex
[unit
][I915_TEXREG_SS2
] &
697 state
[I915_TEXREG_SS2
] |= (t
->Setup
[I915_TEXREG_SS2
] & ~SS2_LOD_BIAS_MASK
);
699 state
[I915_TEXREG_SS3
] = (i915
->state
.Tex
[unit
][I915_TEXREG_SS3
] &
700 SS3_NORMALIZED_COORDS
);
701 state
[I915_TEXREG_SS3
] |= (t
->Setup
[I915_TEXREG_SS3
] &
702 ~(SS3_NORMALIZED_COORDS
|
703 SS3_TEXTUREMAP_INDEX_MASK
));
705 state
[I915_TEXREG_SS3
] |= (unit
<<SS3_TEXTUREMAP_INDEX_SHIFT
);
707 state
[I915_TEXREG_SS4
] = t
->Setup
[I915_TEXREG_SS4
];
710 if (memcmp(state
, i915
->state
.Tex
[unit
], sizeof(state
)) != 0) {
711 I915_STATECHANGE( i915
, I915_UPLOAD_TEX(unit
) );
712 memcpy(i915
->state
.Tex
[unit
], state
, sizeof(state
));
718 static GLboolean
enable_tex_common( GLcontext
*ctx
, GLuint unit
)
720 i915ContextPtr i915
= I915_CONTEXT(ctx
);
721 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
722 struct gl_texture_object
*tObj
= texUnit
->_Current
;
723 i915TextureObjectPtr t
= (i915TextureObjectPtr
)tObj
->DriverData
;
725 if (0) fprintf(stderr
, "%s %d\n", __FUNCTION__
, unit
);
727 if (!(i915
->state
.active
& I915_UPLOAD_TEX(unit
))) {
728 I915_ACTIVESTATE(i915
, I915_UPLOAD_TEX(unit
), GL_TRUE
);
731 /* Fallback if there's a texture border */
732 if ( tObj
->Image
[0][tObj
->BaseLevel
]->Border
> 0 ) {
737 /* Update state if this is a different texture object to last
740 if (i915
->intel
.CurrentTexObj
[unit
] != &t
->intel
||
741 (t
->intel
.dirty
& I915_UPLOAD_TEX(unit
))) {
742 i915_import_tex_unit( i915
, t
, unit
);
743 i915
->tex_program
.translated
= 0;
749 static GLboolean
enable_tex_rect( GLcontext
*ctx
, GLuint unit
)
751 i915ContextPtr i915
= I915_CONTEXT(ctx
);
752 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
753 struct gl_texture_object
*tObj
= texUnit
->_Current
;
754 i915TextureObjectPtr t
= (i915TextureObjectPtr
)tObj
->DriverData
;
755 GLuint ss3
= i915
->state
.Tex
[unit
][I915_TEXREG_SS3
];
757 ss3
&= ~SS3_NORMALIZED_COORDS
;
759 if (ss3
!= i915
->state
.Tex
[unit
][I915_TEXREG_SS3
]) {
760 I915_STATECHANGE(i915
, I915_UPLOAD_TEX(unit
));
761 i915
->state
.Tex
[unit
][I915_TEXREG_SS3
] = ss3
;
764 /* Upload teximages (not pipelined)
766 if (t
->intel
.base
.dirty_images
[0]) {
767 i915SetTexImages( i915
, tObj
);
768 if (!intelUploadTexImages( &i915
->intel
, &t
->intel
, 0 )) {
777 static GLboolean
enable_tex_2d( GLcontext
*ctx
, GLuint unit
)
779 i915ContextPtr i915
= I915_CONTEXT(ctx
);
780 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
781 struct gl_texture_object
*tObj
= texUnit
->_Current
;
782 i915TextureObjectPtr t
= (i915TextureObjectPtr
)tObj
->DriverData
;
783 GLuint ss3
= i915
->state
.Tex
[unit
][I915_TEXREG_SS3
];
785 ss3
|= SS3_NORMALIZED_COORDS
;
787 if (ss3
!= i915
->state
.Tex
[unit
][I915_TEXREG_SS3
]) {
788 I915_STATECHANGE(i915
, I915_UPLOAD_TEX(unit
));
789 i915
->state
.Tex
[unit
][I915_TEXREG_SS3
] = ss3
;
792 /* Upload teximages (not pipelined)
794 if (t
->intel
.base
.dirty_images
[0]) {
795 i915SetTexImages( i915
, tObj
);
796 if (!intelUploadTexImages( &i915
->intel
, &t
->intel
, 0 )) {
804 static GLboolean
enable_tex_cube( GLcontext
*ctx
, GLuint unit
)
806 i915ContextPtr i915
= I915_CONTEXT(ctx
);
807 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
808 struct gl_texture_object
*tObj
= texUnit
->_Current
;
809 i915TextureObjectPtr t
= (i915TextureObjectPtr
)tObj
->DriverData
;
810 GLuint ss3
= i915
->state
.Tex
[unit
][I915_TEXREG_SS3
];
813 ss3
|= SS3_NORMALIZED_COORDS
;
815 if (ss3
!= i915
->state
.Tex
[unit
][I915_TEXREG_SS3
]) {
816 I915_STATECHANGE(i915
, I915_UPLOAD_TEX(unit
));
817 i915
->state
.Tex
[unit
][I915_TEXREG_SS3
] = ss3
;
820 /* Upload teximages (not pipelined)
822 if ( t
->intel
.base
.dirty_images
[0] || t
->intel
.base
.dirty_images
[1] ||
823 t
->intel
.base
.dirty_images
[2] || t
->intel
.base
.dirty_images
[3] ||
824 t
->intel
.base
.dirty_images
[4] || t
->intel
.base
.dirty_images
[5] ) {
825 i915SetTexImages( i915
, tObj
);
828 /* upload (per face) */
829 for (face
= 0; face
< 6; face
++) {
830 if (t
->intel
.base
.dirty_images
[face
]) {
831 if (!intelUploadTexImages( &i915
->intel
, &t
->intel
, face
)) {
841 static GLboolean
enable_tex_3d( GLcontext
*ctx
, GLuint unit
)
843 struct gl_texture_object
*tObj
= ctx
->Texture
.Unit
[unit
]._Current
;
844 i915TextureObjectPtr t
= (i915TextureObjectPtr
)tObj
->DriverData
;
846 /* 3D textures on I915 seem to get bogus border colors, hence this
849 if (t
->refs_border_color
)
858 static GLboolean
disable_tex( GLcontext
*ctx
, GLuint unit
)
860 i915ContextPtr i915
= I915_CONTEXT(ctx
);
862 if (i915
->state
.active
& I915_UPLOAD_TEX(unit
)) {
863 I915_ACTIVESTATE(i915
, I915_UPLOAD_TEX(unit
), GL_FALSE
);
866 /* The old texture is no longer bound to this texture unit.
869 if ( i915
->intel
.CurrentTexObj
[unit
] != NULL
) {
870 i915
->intel
.CurrentTexObj
[unit
]->base
.bound
&= ~(1U << 0);
871 i915
->intel
.CurrentTexObj
[unit
] = NULL
;
877 static GLboolean
i915UpdateTexUnit( GLcontext
*ctx
, GLuint unit
)
879 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
881 if (texUnit
->_ReallyEnabled
&&
882 INTEL_CONTEXT(ctx
)->intelScreen
->tex
.size
< 2048 * 1024)
885 switch (texUnit
->_ReallyEnabled
) {
888 return (enable_tex_2d( ctx
, unit
) &&
889 enable_tex_common( ctx
, unit
));
890 case TEXTURE_RECT_BIT
:
891 return (enable_tex_rect( ctx
, unit
) &&
892 enable_tex_common( ctx
, unit
));
893 case TEXTURE_CUBE_BIT
:
894 return (enable_tex_cube( ctx
, unit
) &&
895 enable_tex_common( ctx
, unit
));
897 return (enable_tex_2d( ctx
, unit
) &&
898 enable_tex_common( ctx
, unit
) &&
899 enable_tex_3d( ctx
, unit
));
901 return disable_tex( ctx
, unit
);
908 void i915UpdateTextureState( intelContextPtr intel
)
910 GLcontext
*ctx
= &intel
->ctx
;
911 GLboolean ok
= GL_TRUE
;
914 for (i
= 0 ; i
< I915_TEX_UNITS
&& ok
; i
++) {
915 ok
= i915UpdateTexUnit( ctx
, i
);
918 FALLBACK( intel
, I915_FALLBACK_TEXTURE
, !ok
);