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