Add Roland Scheidegger's S3TC patch. This patch does not implement the
[mesa.git] / src / mesa / drivers / dri / i915 / intel_tex.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 "mtypes.h"
30 #include "imports.h"
31 #include "simple_list.h"
32 #include "enums.h"
33 #include "image.h"
34 #include "texstore.h"
35 #include "texformat.h"
36 #include "teximage.h"
37 #include "texmem.h"
38 #include "texobj.h"
39 #include "swrast/swrast.h"
40
41 #include "mm.h"
42
43 #include "intel_screen.h"
44 #include "intel_batchbuffer.h"
45 #include "intel_context.h"
46 #include "intel_tex.h"
47 #include "intel_ioctl.h"
48
49
50
51 static GLboolean
52 intelValidateClientStorage( intelContextPtr intel, GLenum target,
53 GLint internalFormat,
54 GLint srcWidth, GLint srcHeight,
55 GLenum format, GLenum type, const void *pixels,
56 const struct gl_pixelstore_attrib *packing,
57 struct gl_texture_object *texObj,
58 struct gl_texture_image *texImage)
59
60 {
61 GLcontext *ctx = &intel->ctx;
62 int texelBytes;
63
64 if (0)
65 fprintf(stderr, "intformat %s format %s type %s\n",
66 _mesa_lookup_enum_by_nr( internalFormat ),
67 _mesa_lookup_enum_by_nr( format ),
68 _mesa_lookup_enum_by_nr( type ));
69
70 if (!ctx->Unpack.ClientStorage)
71 return 0;
72
73 if (ctx->_ImageTransferState ||
74 texImage->IsCompressed ||
75 texObj->GenerateMipmap)
76 return 0;
77
78
79 /* This list is incomplete
80 */
81 switch ( internalFormat ) {
82 case GL_RGBA:
83 if ( format == GL_BGRA && type == GL_UNSIGNED_INT_8_8_8_8_REV ) {
84 texImage->TexFormat = &_mesa_texformat_argb8888;
85 texelBytes = 4;
86 }
87 else
88 return 0;
89 break;
90
91 case GL_RGB:
92 if ( format == GL_RGB && type == GL_UNSIGNED_SHORT_5_6_5 ) {
93 texImage->TexFormat = &_mesa_texformat_rgb565;
94 texelBytes = 2;
95 }
96 else
97 return 0;
98 break;
99
100 case GL_YCBCR_MESA:
101 if ( format == GL_YCBCR_MESA &&
102 type == GL_UNSIGNED_SHORT_8_8_REV_APPLE ) {
103 texImage->TexFormat = &_mesa_texformat_ycbcr_rev;
104 texelBytes = 2;
105 }
106 else if ( format == GL_YCBCR_MESA &&
107 (type == GL_UNSIGNED_SHORT_8_8_APPLE ||
108 type == GL_UNSIGNED_BYTE)) {
109 texImage->TexFormat = &_mesa_texformat_ycbcr;
110 texelBytes = 2;
111 }
112 else
113 return 0;
114 break;
115
116
117 default:
118 return 0;
119 }
120
121 /* Could deal with these packing issues, but currently don't:
122 */
123 if (packing->SkipPixels ||
124 packing->SkipRows ||
125 packing->SwapBytes ||
126 packing->LsbFirst) {
127 return 0;
128 }
129
130 {
131 GLint srcRowStride = _mesa_image_row_stride(packing, srcWidth,
132 format, type);
133
134
135 if (0)
136 fprintf(stderr, "%s: srcRowStride %d/%x\n",
137 __FUNCTION__, srcRowStride, srcRowStride);
138
139 /* Could check this later in upload, pitch restrictions could be
140 * relaxed, but would need to store the image pitch somewhere,
141 * as packing details might change before image is uploaded:
142 */
143 if (!intelIsAgpMemory( intel, pixels, srcHeight * srcRowStride ) ||
144 (srcRowStride & 63))
145 return 0;
146
147
148 /* Have validated that _mesa_transfer_teximage would be a straight
149 * memcpy at this point. NOTE: future calls to TexSubImage will
150 * overwrite the client data. This is explicitly mentioned in the
151 * extension spec.
152 */
153 texImage->Data = (void *)pixels;
154 texImage->IsClientData = GL_TRUE;
155 texImage->RowStride = srcRowStride / texelBytes;
156 return 1;
157 }
158 }
159
160
161
162 static void intelTexImage1D( GLcontext *ctx, GLenum target, GLint level,
163 GLint internalFormat,
164 GLint width, GLint border,
165 GLenum format, GLenum type, const GLvoid *pixels,
166 const struct gl_pixelstore_attrib *packing,
167 struct gl_texture_object *texObj,
168 struct gl_texture_image *texImage )
169 {
170 driTextureObject * t = (driTextureObject *) texObj->DriverData;
171
172 assert(t);
173 intelFlush( ctx );
174 driSwapOutTextureObject( t );
175
176 texImage->IsClientData = GL_FALSE;
177
178 _mesa_store_teximage1d( ctx, target, level, internalFormat,
179 width, border, format, type,
180 pixels, packing, texObj, texImage );
181
182 t->dirty_images[0] |= (1 << level);
183 }
184
185 static void intelTexSubImage1D( GLcontext *ctx,
186 GLenum target,
187 GLint level,
188 GLint xoffset,
189 GLsizei width,
190 GLenum format, GLenum type,
191 const GLvoid *pixels,
192 const struct gl_pixelstore_attrib *packing,
193 struct gl_texture_object *texObj,
194 struct gl_texture_image *texImage )
195 {
196 driTextureObject * t = (driTextureObject *) texObj->DriverData;
197
198 assert(t);
199 intelFlush( ctx );
200 driSwapOutTextureObject( t );
201
202 _mesa_store_texsubimage1d(ctx, target, level, xoffset, width,
203 format, type, pixels, packing, texObj,
204 texImage);
205 }
206
207
208 /* Handles 2D, CUBE, RECT:
209 */
210 static void intelTexImage2D( GLcontext *ctx, GLenum target, GLint level,
211 GLint internalFormat,
212 GLint width, GLint height, GLint border,
213 GLenum format, GLenum type, const GLvoid *pixels,
214 const struct gl_pixelstore_attrib *packing,
215 struct gl_texture_object *texObj,
216 struct gl_texture_image *texImage )
217 {
218 driTextureObject * t = (driTextureObject *) texObj->DriverData;
219 GLuint face;
220
221 /* which cube face or ordinary 2D image */
222 switch (target) {
223 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
224 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
225 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
226 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
227 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
228 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
229 face = (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X;
230 ASSERT(face < 6);
231 break;
232 default:
233 face = 0;
234 }
235
236 assert(t);
237 intelFlush( ctx );
238 driSwapOutTextureObject( t );
239 texImage->IsClientData = GL_FALSE;
240
241 if (intelValidateClientStorage( INTEL_CONTEXT(ctx), target,
242 internalFormat,
243 width, height,
244 format, type, pixels,
245 packing, texObj, texImage)) {
246 if (INTEL_DEBUG & DEBUG_TEXTURE)
247 fprintf(stderr, "%s: Using client storage\n", __FUNCTION__);
248 }
249 else {
250 _mesa_store_teximage2d( ctx, target, level, internalFormat,
251 width, height, border, format, type,
252 pixels, packing, texObj, texImage );
253
254 t->dirty_images[face] |= (1 << level);
255 }
256 }
257
258 static void intelTexSubImage2D( GLcontext *ctx,
259 GLenum target,
260 GLint level,
261 GLint xoffset, GLint yoffset,
262 GLsizei width, GLsizei height,
263 GLenum format, GLenum type,
264 const GLvoid *pixels,
265 const struct gl_pixelstore_attrib *packing,
266 struct gl_texture_object *texObj,
267 struct gl_texture_image *texImage )
268 {
269 driTextureObject * t = (driTextureObject *) texObj->DriverData;
270 GLuint face;
271
272 /* which cube face or ordinary 2D image */
273 switch (target) {
274 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
275 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
276 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
277 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
278 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
279 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
280 face = (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X;
281 ASSERT(face < 6);
282 break;
283 default:
284 face = 0;
285 }
286
287 if (texImage->IsClientData &&
288 (char *)pixels == (char *)texImage->Data +
289 ((xoffset + yoffset * texImage->RowStride) *
290 texImage->TexFormat->TexelBytes)) {
291
292 /* Notification only - no upload required */
293 }
294 else {
295 assert( t ); /* this _should_ be true */
296 intelFlush( ctx );
297 driSwapOutTextureObject( t );
298
299 _mesa_store_texsubimage2d(ctx, target, level, xoffset, yoffset, width,
300 height, format, type, pixels, packing, texObj,
301 texImage);
302
303 t->dirty_images[face] |= (1 << level);
304 }
305 }
306
307 static void intelCompressedTexImage2D( GLcontext *ctx, GLenum target, GLint level,
308 GLint internalFormat,
309 GLint width, GLint height, GLint border,
310 GLsizei imageSize, const GLvoid *data,
311 struct gl_texture_object *texObj,
312 struct gl_texture_image *texImage )
313 {
314 driTextureObject * t = (driTextureObject *) texObj->DriverData;
315 GLuint face;
316
317 /* which cube face or ordinary 2D image */
318 switch (target) {
319 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
320 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
321 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
322 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
323 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
324 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
325 face = (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X;
326 ASSERT(face < 6);
327 break;
328 default:
329 face = 0;
330 }
331
332 assert(t);
333 intelFlush( ctx );
334
335 driSwapOutTextureObject( t );
336 texImage->IsClientData = GL_FALSE;
337
338 if (INTEL_DEBUG & DEBUG_TEXTURE)
339 fprintf(stderr, "%s: Using normal storage\n", __FUNCTION__);
340
341 _mesa_store_compressed_teximage2d(ctx, target, level, internalFormat, width,
342 height, border, imageSize, data, texObj, texImage);
343
344 t->dirty_images[face] |= (1 << level);
345 }
346
347
348 static void intelCompressedTexSubImage2D( GLcontext *ctx, GLenum target, GLint level,
349 GLint xoffset, GLint yoffset,
350 GLsizei width, GLsizei height,
351 GLenum format,
352 GLsizei imageSize, const GLvoid *data,
353 struct gl_texture_object *texObj,
354 struct gl_texture_image *texImage )
355 {
356 driTextureObject * t = (driTextureObject *) texObj->DriverData;
357 GLuint face;
358
359
360 /* which cube face or ordinary 2D image */
361 switch (target) {
362 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
363 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
364 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
365 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
366 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
367 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
368 face = (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X;
369 ASSERT(face < 6);
370 break;
371 default:
372 face = 0;
373 }
374
375 assert( t ); /* this _should_ be true */
376 intelFlush( ctx );
377 driSwapOutTextureObject( t );
378
379 _mesa_store_compressed_texsubimage2d(ctx, target, level, xoffset, yoffset, width,
380 height, format, imageSize, data, texObj, texImage);
381
382 t->dirty_images[face] |= (1 << level);
383 }
384
385
386 static void intelTexImage3D( GLcontext *ctx, GLenum target, GLint level,
387 GLint internalFormat,
388 GLint width, GLint height, GLint depth,
389 GLint border,
390 GLenum format, GLenum type, const GLvoid *pixels,
391 const struct gl_pixelstore_attrib *packing,
392 struct gl_texture_object *texObj,
393 struct gl_texture_image *texImage )
394 {
395 driTextureObject * t = (driTextureObject *) texObj->DriverData;
396
397 assert(t);
398 driSwapOutTextureObject( t );
399 texImage->IsClientData = GL_FALSE;
400
401 _mesa_store_teximage3d(ctx, target, level, internalFormat,
402 width, height, depth, border,
403 format, type, pixels,
404 &ctx->Unpack, texObj, texImage);
405
406 t->dirty_images[0] |= (1 << level);
407 }
408
409
410 static void
411 intelTexSubImage3D( GLcontext *ctx, GLenum target, GLint level,
412 GLint xoffset, GLint yoffset, GLint zoffset,
413 GLsizei width, GLsizei height, GLsizei depth,
414 GLenum format, GLenum type,
415 const GLvoid *pixels,
416 const struct gl_pixelstore_attrib *packing,
417 struct gl_texture_object *texObj,
418 struct gl_texture_image *texImage )
419 {
420 driTextureObject * t = (driTextureObject *) texObj->DriverData;
421
422 assert( t ); /* this _should_ be true */
423 driSwapOutTextureObject( t );
424
425 _mesa_store_texsubimage3d(ctx, target, level, xoffset, yoffset, zoffset,
426 width, height, depth,
427 format, type, pixels, packing, texObj, texImage);
428
429 t->dirty_images[0] |= (1 << level);
430 }
431
432
433
434
435 static void intelDeleteTexture( GLcontext *ctx, struct gl_texture_object *tObj )
436 {
437 driTextureObject * t = (driTextureObject *) tObj->DriverData;
438
439 if ( t != NULL ) {
440 intelFlush( ctx );
441 driDestroyTextureObject( t );
442 }
443
444 /* Free mipmap images and the texture object itself */
445 _mesa_delete_texture_object(ctx, tObj);
446 }
447
448
449 static const struct gl_texture_format *
450 intelChooseTextureFormat( GLcontext *ctx, GLint internalFormat,
451 GLenum format, GLenum type )
452 {
453 intelContextPtr intel = INTEL_CONTEXT( ctx );
454 const GLboolean do32bpt = ( intel->intelScreen->cpp == 4 &&
455 intel->intelScreen->textureSize > 4*1024*1024);
456
457 switch ( internalFormat ) {
458 case 4:
459 case GL_RGBA:
460 case GL_COMPRESSED_RGBA:
461 if ( format == GL_BGRA ) {
462 if ( type == GL_UNSIGNED_INT_8_8_8_8_REV ) {
463 return &_mesa_texformat_argb8888;
464 }
465 else if ( type == GL_UNSIGNED_SHORT_4_4_4_4_REV ) {
466 return &_mesa_texformat_argb4444;
467 }
468 else if ( type == GL_UNSIGNED_SHORT_1_5_5_5_REV ) {
469 return &_mesa_texformat_argb1555;
470 }
471 }
472 return do32bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_argb4444;
473
474 case 3:
475 case GL_RGB:
476 case GL_COMPRESSED_RGB:
477 if ( format == GL_RGB && type == GL_UNSIGNED_SHORT_5_6_5 ) {
478 return &_mesa_texformat_rgb565;
479 }
480 return do32bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_rgb565;
481
482 case GL_RGBA8:
483 case GL_RGB10_A2:
484 case GL_RGBA12:
485 case GL_RGBA16:
486 return do32bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_argb4444;
487
488 case GL_RGBA4:
489 case GL_RGBA2:
490 return &_mesa_texformat_argb4444;
491
492 case GL_RGB5_A1:
493 return &_mesa_texformat_argb1555;
494
495 case GL_RGB8:
496 case GL_RGB10:
497 case GL_RGB12:
498 case GL_RGB16:
499 return do32bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_rgb565;
500
501 case GL_RGB5:
502 case GL_RGB4:
503 case GL_R3_G3_B2:
504 return &_mesa_texformat_rgb565;
505
506 case GL_ALPHA:
507 case GL_ALPHA4:
508 case GL_ALPHA8:
509 case GL_ALPHA12:
510 case GL_ALPHA16:
511 case GL_COMPRESSED_ALPHA:
512 /* if (1 || intel->intelScreen->deviceID == PCI_CHIP_I915_G) */
513 return &_mesa_texformat_a8;
514 /* else */
515 /* return &_mesa_texformat_al88; */
516
517 case 1:
518 case GL_LUMINANCE:
519 case GL_LUMINANCE4:
520 case GL_LUMINANCE8:
521 case GL_LUMINANCE12:
522 case GL_LUMINANCE16:
523 case GL_COMPRESSED_LUMINANCE:
524 return &_mesa_texformat_l8;
525
526 case 2:
527 case GL_LUMINANCE_ALPHA:
528 case GL_LUMINANCE4_ALPHA4:
529 case GL_LUMINANCE6_ALPHA2:
530 case GL_LUMINANCE8_ALPHA8:
531 case GL_LUMINANCE12_ALPHA4:
532 case GL_LUMINANCE12_ALPHA12:
533 case GL_LUMINANCE16_ALPHA16:
534 case GL_COMPRESSED_LUMINANCE_ALPHA:
535 return &_mesa_texformat_al88;
536
537 case GL_INTENSITY:
538 case GL_INTENSITY4:
539 case GL_INTENSITY8:
540 case GL_INTENSITY12:
541 case GL_INTENSITY16:
542 case GL_COMPRESSED_INTENSITY:
543 return &_mesa_texformat_i8;
544
545 case GL_YCBCR_MESA:
546 if (type == GL_UNSIGNED_SHORT_8_8_MESA ||
547 type == GL_UNSIGNED_BYTE)
548 return &_mesa_texformat_ycbcr;
549 else
550 return &_mesa_texformat_ycbcr_rev;
551
552 case GL_COMPRESSED_RGB_FXT1_3DFX:
553 return &_mesa_texformat_rgb_fxt1;
554 case GL_COMPRESSED_RGBA_FXT1_3DFX:
555 return &_mesa_texformat_rgba_fxt1;
556
557 case GL_RGB_S3TC:
558 case GL_RGB4_S3TC:
559 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
560 return &_mesa_texformat_rgb_dxt1;
561
562 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
563 return &_mesa_texformat_rgba_dxt1;
564
565 case GL_RGBA_S3TC:
566 case GL_RGBA4_S3TC:
567 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
568 return &_mesa_texformat_rgba_dxt3;
569
570 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
571 return &_mesa_texformat_rgba_dxt5;
572
573 default:
574 fprintf(stderr, "unexpected texture format in %s\n", __FUNCTION__);
575 return NULL;
576 }
577
578 return NULL; /* never get here */
579 }
580
581
582
583 void intelDestroyTexObj(intelContextPtr intel, intelTextureObjectPtr t)
584 {
585 unsigned i;
586
587 if ( intel == NULL )
588 return;
589
590 if ( t->age > intel->dirtyAge )
591 intel->dirtyAge = t->age;
592
593 for ( i = 0 ; i < MAX_TEXTURE_UNITS ; i++ ) {
594 if ( t == intel->CurrentTexObj[ i ] )
595 intel->CurrentTexObj[ i ] = NULL;
596 }
597 }
598
599
600
601 /* Upload an image from mesa's internal copy. Image may be 1D, 2D or
602 * 3D. Cubemaps are expanded elsewhere.
603 */
604 static void intelUploadTexImage( intelContextPtr intel,
605 intelTextureObjectPtr t,
606 const struct gl_texture_image *image,
607 const GLuint offset )
608 {
609
610 if (!image || !image->Data)
611 return;
612
613 if (image->Depth == 1 && image->IsClientData) {
614 if (INTEL_DEBUG & DEBUG_TEXTURE)
615 fprintf(stderr, "Blit uploading\n");
616
617 /* Do it with a blit.
618 */
619 intelEmitCopyBlitLocked( intel,
620 image->TexFormat->TexelBytes,
621 image->RowStride, /* ? */
622 intelGetMemoryOffsetMESA( NULL, 0, image->Data ),
623 t->Pitch / image->TexFormat->TexelBytes,
624 intelGetMemoryOffsetMESA( NULL, 0, t->BufAddr + offset ),
625 0, 0,
626 0, 0,
627 image->Width,
628 image->Height);
629 }
630 else if (image->IsCompressed) {
631 GLuint row_len = image->Width * 2;
632 GLubyte *dst = (GLubyte *)(t->BufAddr + offset);
633 GLubyte *src = (GLubyte *)image->Data;
634 GLuint j;
635
636 if (INTEL_DEBUG & DEBUG_TEXTURE)
637 fprintf(stderr,
638 "Upload image %dx%dx%d offset %xm row_len %x "
639 "pitch %x depth_pitch %x\n",
640 image->Width, image->Height, image->Depth, offset,
641 row_len, t->Pitch, t->depth_pitch);
642
643 switch(image->IntFormat)
644 {
645 case GL_COMPRESSED_RGB_FXT1_3DFX:
646 case GL_COMPRESSED_RGBA_FXT1_3DFX:
647 case GL_RGB_S3TC:
648 case GL_RGB4_S3TC:
649 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
650 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
651 for (j = 0 ; j < image->Height/4 ; j++, dst += (t->Pitch)) {
652 __memcpy(dst, src, row_len );
653 src += row_len;
654 }
655 break;
656 case GL_RGBA_S3TC:
657 case GL_RGBA4_S3TC:
658 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
659 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
660 for (j = 0 ; j < image->Height/4 ; j++, dst += (t->Pitch)) {
661 __memcpy(dst, src, (image->Width*4) );
662 src += image->Width*4;
663 }
664 break;
665 default:
666 fprintf(stderr,"Internal Compressed format not supported %d\n", image->IntFormat);
667 break;
668 }
669 }
670 else {
671 GLuint row_len = image->Width * image->TexFormat->TexelBytes;
672 GLubyte *dst = (GLubyte *)(t->BufAddr + offset);
673 GLubyte *src = (GLubyte *)image->Data;
674 GLuint d, j;
675
676 if (INTEL_DEBUG & DEBUG_TEXTURE)
677 fprintf(stderr,
678 "Upload image %dx%dx%d offset %xm row_len %x "
679 "pitch %x depth_pitch %x\n",
680 image->Width, image->Height, image->Depth, offset,
681 row_len, t->Pitch, t->depth_pitch);
682
683 if (row_len == t->Pitch) {
684 for (d = 0; d < image->Depth; d++) {
685 memcpy( dst, src, t->Pitch * image->Height );
686 dst += t->depth_pitch;
687 src += row_len * image->Height;
688 }
689 }
690 else {
691 for (d = 0 ; d < image->Depth ; d++) {
692 for (j = 0 ; j < image->Height ; j++) {
693 __memcpy(dst, src, row_len );
694 src += row_len;
695 dst += t->Pitch;
696 }
697
698 dst += t->depth_pitch - (t->Pitch * image->Height);
699 }
700 }
701 }
702 }
703
704
705
706 int intelUploadTexImages( intelContextPtr intel,
707 intelTextureObjectPtr t,
708 GLuint face)
709 {
710 const int numLevels = t->base.lastLevel - t->base.firstLevel + 1;
711 const struct gl_texture_image *firstImage = t->image[face][t->base.firstLevel].image;
712 int pitch = firstImage->RowStride * firstImage->TexFormat->TexelBytes;
713
714 /* Can we texture out of the existing client data? */
715 if ( numLevels == 1 &&
716 firstImage->IsClientData &&
717 (pitch & 3) == 0) {
718
719 if (INTEL_DEBUG & DEBUG_TEXTURE)
720 fprintf(stderr, "AGP texturing from client memory\n");
721
722 t->TextureOffset = intelAgpOffsetFromVirtual( intel, firstImage->Data );
723 t->BufAddr = 0;
724 t->dirty = ~0;
725 return GL_TRUE;
726 }
727 else {
728 if (INTEL_DEBUG & DEBUG_TEXTURE)
729 fprintf(stderr, "Uploading client data to agp\n");
730
731 INTEL_FIREVERTICES( intel );
732 LOCK_HARDWARE( intel );
733
734 if ( t->base.memBlock == NULL ) {
735 int heap;
736
737 heap = driAllocateTexture( intel->texture_heaps, intel->nr_heaps,
738 (driTextureObject *) t );
739 if ( heap == -1 ) {
740 UNLOCK_HARDWARE( intel );
741 return GL_FALSE;
742 }
743
744 /* Set the base offset of the texture image */
745 t->BufAddr = intel->intelScreen->tex.map + t->base.memBlock->ofs;
746 t->TextureOffset = intel->intelScreen->textureOffset + t->base.memBlock->ofs;
747 t->dirty = ~0;
748 }
749
750
751 /* Let the world know we've used this memory recently.
752 */
753 driUpdateTextureLRU( (driTextureObject *) t );
754
755
756 /* Upload any images that are new */
757 if (t->base.dirty_images[face]) {
758 int i;
759
760 intelWaitForIdle( intel );
761
762 for (i = 0 ; i < numLevels ; i++) {
763 int level = i + t->base.firstLevel;
764
765 if (t->base.dirty_images[face] & (1<<level)) {
766
767 const struct gl_texture_image *image = t->image[face][i].image;
768 GLuint offset = t->image[face][i].offset;
769
770 if (INTEL_DEBUG & DEBUG_TEXTURE)
771 fprintf(stderr, "upload level %d, offset %x\n",
772 level, offset);
773
774 intelUploadTexImage( intel, t, image, offset );
775 }
776 }
777 t->base.dirty_images[face] = 0;
778 intel->perf_boxes |= I830_BOX_TEXTURE_LOAD;
779 }
780
781 UNLOCK_HARDWARE( intel );
782 return GL_TRUE;
783 }
784 }
785
786 /**
787 * Allocate a new texture object.
788 * Called via ctx->Driver.NewTextureObject.
789 * Note: this function will be called during context creation to
790 * allocate the default texture objects.
791 * Note: we could use containment here to 'derive' the driver-specific
792 * texture object from the core mesa gl_texture_object. Not done at this time.
793 */
794 static struct gl_texture_object *
795 intelNewTextureObject( GLcontext *ctx, GLuint name, GLenum target )
796 {
797 struct gl_texture_object *obj = _mesa_new_texture_object(ctx, name, target);
798 INTEL_CONTEXT(ctx)->vtbl.alloc_tex_obj( obj );
799 return obj;
800 }
801
802
803 void intelInitTextureFuncs( struct dd_function_table *functions )
804 {
805 functions->NewTextureObject = intelNewTextureObject;
806 functions->ChooseTextureFormat = intelChooseTextureFormat;
807 functions->TexImage1D = intelTexImage1D;
808 functions->TexImage2D = intelTexImage2D;
809 functions->TexImage3D = intelTexImage3D;
810 functions->TexSubImage1D = intelTexSubImage1D;
811 functions->TexSubImage2D = intelTexSubImage2D;
812 functions->TexSubImage3D = intelTexSubImage3D;
813 functions->CopyTexImage1D = _swrast_copy_teximage1d;
814 functions->CopyTexImage2D = _swrast_copy_teximage2d;
815 functions->CopyTexSubImage1D = _swrast_copy_texsubimage1d;
816 functions->CopyTexSubImage2D = _swrast_copy_texsubimage2d;
817 functions->CopyTexSubImage3D = _swrast_copy_texsubimage3d;
818 functions->DeleteTexture = intelDeleteTexture;
819 functions->UpdateTexturePalette = NULL;
820 functions->IsTextureResident = driIsTextureResident;
821 functions->TestProxyTexImage = _mesa_test_proxy_teximage;
822 functions->DeleteTexture = intelDeleteTexture;
823 functions->CompressedTexImage2D = intelCompressedTexImage2D;
824 functions->CompressedTexSubImage2D = intelCompressedTexSubImage2D;
825 }