Merge remote branch 'upstream/gallium-0.1' into nouveau-gallium-0.1
[mesa.git] / src / mesa / state_tracker / st_cb_texture.c
1 /**************************************************************************
2 *
3 * Copyright 2007 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 "main/imports.h"
29 #include "main/convolve.h"
30 #include "main/enums.h"
31 #include "main/image.h"
32 #include "main/macros.h"
33 #include "main/mipmap.h"
34 #include "main/texcompress.h"
35 #include "main/texformat.h"
36 #include "main/teximage.h"
37 #include "main/texobj.h"
38 #include "main/texstore.h"
39
40 #include "state_tracker/st_context.h"
41 #include "state_tracker/st_cb_fbo.h"
42 #include "state_tracker/st_cb_texture.h"
43 #include "state_tracker/st_format.h"
44 #include "state_tracker/st_texture.h"
45 #include "state_tracker/st_gen_mipmap.h"
46
47 #include "pipe/p_context.h"
48 #include "pipe/p_defines.h"
49 #include "pipe/p_inlines.h"
50 #include "util/p_tile.h"
51
52
53 #define DBG if (0) printf
54
55
56 static INLINE struct st_texture_image *
57 st_texture_image(struct gl_texture_image *img)
58 {
59 return (struct st_texture_image *) img;
60 }
61
62
63 static enum pipe_texture_target
64 gl_target_to_pipe(GLenum target)
65 {
66 switch (target) {
67 case GL_TEXTURE_1D:
68 return PIPE_TEXTURE_1D;
69
70 case GL_TEXTURE_2D:
71 case GL_TEXTURE_RECTANGLE_NV:
72 return PIPE_TEXTURE_2D;
73
74 case GL_TEXTURE_3D:
75 return PIPE_TEXTURE_3D;
76
77 case GL_TEXTURE_CUBE_MAP_ARB:
78 return PIPE_TEXTURE_CUBE;
79
80 default:
81 assert(0);
82 return 0;
83 }
84 }
85
86
87 /**
88 * Return nominal bytes per texel for a compressed format, 0 for non-compressed
89 * format.
90 */
91 static int
92 compressed_num_bytes(GLuint mesaFormat)
93 {
94 switch(mesaFormat) {
95 case MESA_FORMAT_RGB_FXT1:
96 case MESA_FORMAT_RGBA_FXT1:
97 case MESA_FORMAT_RGB_DXT1:
98 case MESA_FORMAT_RGBA_DXT1:
99 return 2;
100 case MESA_FORMAT_RGBA_DXT3:
101 case MESA_FORMAT_RGBA_DXT5:
102 return 4;
103 default:
104 return 0;
105 }
106 }
107
108
109 static GLboolean
110 st_IsTextureResident(GLcontext * ctx, struct gl_texture_object *texObj)
111 {
112 #if 0
113 struct intel_context *intel = intel_context(ctx);
114 struct st_texture_object *stObj = st_texture_object(texObj);
115
116 return
117 stObj->pt &&
118 stObj->pt->region &&
119 intel_is_region_resident(intel, stObj->pt->region);
120 #endif
121 return 1;
122 }
123
124
125 static struct gl_texture_image *
126 st_NewTextureImage(GLcontext * ctx)
127 {
128 DBG("%s\n", __FUNCTION__);
129 (void) ctx;
130 return (struct gl_texture_image *) CALLOC_STRUCT(st_texture_image);
131 }
132
133
134 static struct gl_texture_object *
135 st_NewTextureObject(GLcontext * ctx, GLuint name, GLenum target)
136 {
137 struct st_texture_object *obj = CALLOC_STRUCT(st_texture_object);
138
139 DBG("%s\n", __FUNCTION__);
140 _mesa_initialize_texture_object(&obj->base, name, target);
141
142 return &obj->base;
143 }
144
145 static void
146 st_DeleteTextureObject(GLcontext *ctx,
147 struct gl_texture_object *texObj)
148 {
149 struct st_texture_object *stObj = st_texture_object(texObj);
150 if (stObj->pt)
151 pipe_texture_release(&stObj->pt);
152
153 _mesa_delete_texture_object(ctx, texObj);
154 }
155
156
157 static void
158 st_FreeTextureImageData(GLcontext * ctx, struct gl_texture_image *texImage)
159 {
160 struct st_texture_image *stImage = st_texture_image(texImage);
161
162 DBG("%s\n", __FUNCTION__);
163
164 if (stImage->pt) {
165 pipe_texture_release(&stImage->pt);
166 }
167
168 if (texImage->Data) {
169 free(texImage->Data);
170 texImage->Data = NULL;
171 }
172 }
173
174
175 /* ================================================================
176 * From linux kernel i386 header files, copes with odd sizes better
177 * than COPY_DWORDS would:
178 * XXX Put this in src/mesa/main/imports.h ???
179 */
180 #if defined(i386) || defined(__i386__)
181 static INLINE void *
182 __memcpy(void *to, const void *from, size_t n)
183 {
184 int d0, d1, d2;
185 __asm__ __volatile__("rep ; movsl\n\t"
186 "testb $2,%b4\n\t"
187 "je 1f\n\t"
188 "movsw\n"
189 "1:\ttestb $1,%b4\n\t"
190 "je 2f\n\t"
191 "movsb\n" "2:":"=&c"(d0), "=&D"(d1), "=&S"(d2)
192 :"0"(n / 4), "q"(n), "1"((long) to), "2"((long) from)
193 :"memory");
194 return (to);
195 }
196 #else
197 #define __memcpy(a,b,c) memcpy(a,b,c)
198 #endif
199
200
201 /* The system memcpy (at least on ubuntu 5.10) has problems copying
202 * to agp (writecombined) memory from a source which isn't 64-byte
203 * aligned - there is a 4x performance falloff.
204 *
205 * The x86 __memcpy is immune to this but is slightly slower
206 * (10%-ish) than the system memcpy.
207 *
208 * The sse_memcpy seems to have a slight cliff at 64/32 bytes, but
209 * isn't much faster than x86_memcpy for agp copies.
210 *
211 * TODO: switch dynamically.
212 */
213 static void *
214 do_memcpy(void *dest, const void *src, size_t n)
215 {
216 if ((((unsigned) src) & 63) || (((unsigned) dest) & 63)) {
217 return __memcpy(dest, src, n);
218 }
219 else
220 return memcpy(dest, src, n);
221 }
222
223
224 /* Functions to store texture images. Where possible, textures
225 * will be created or further instantiated with image data, otherwise
226 * images will be stored in malloc'd memory. A validation step is
227 * required to pull those images into a texture, or otherwise
228 * decide a fallback is required.
229 */
230
231
232 static int
233 logbase2(int n)
234 {
235 GLint i = 1;
236 GLint log2 = 0;
237
238 while (n > i) {
239 i *= 2;
240 log2++;
241 }
242
243 return log2;
244 }
245
246
247 /**
248 * Allocate a pipe_texture object for the given st_texture_object using
249 * the given st_texture_image to guess the mipmap size/levels.
250 *
251 * [comments...]
252 * Otherwise, store it in memory if (Border != 0) or (any dimension ==
253 * 1).
254 *
255 * Otherwise, if max_level >= level >= min_level, create texture with
256 * space for images from min_level down to max_level.
257 *
258 * Otherwise, create texture with space for images from (level 0)..(1x1).
259 * Consider pruning this texture at a validation if the saving is worth it.
260 */
261 static void
262 guess_and_alloc_texture(struct st_context *st,
263 struct st_texture_object *stObj,
264 const struct st_texture_image *stImage)
265 {
266 GLuint firstLevel;
267 GLuint lastLevel;
268 GLuint width = stImage->base.Width;
269 GLuint height = stImage->base.Height;
270 GLuint depth = stImage->base.Depth;
271 GLuint i, comp_byte = 0;
272
273 DBG("%s\n", __FUNCTION__);
274
275 assert(!stObj->pt);
276
277 if (stImage->base.Border)
278 return;
279
280 if (stImage->level > stObj->base.BaseLevel &&
281 (stImage->base.Width == 1 ||
282 (stObj->base.Target != GL_TEXTURE_1D &&
283 stImage->base.Height == 1) ||
284 (stObj->base.Target == GL_TEXTURE_3D &&
285 stImage->base.Depth == 1)))
286 return;
287
288 /* If this image disrespects BaseLevel, allocate from level zero.
289 * Usually BaseLevel == 0, so it's unlikely to happen.
290 */
291 if (stImage->level < stObj->base.BaseLevel)
292 firstLevel = 0;
293 else
294 firstLevel = stObj->base.BaseLevel;
295
296
297 /* Figure out image dimensions at start level.
298 */
299 for (i = stImage->level; i > firstLevel; i--) {
300 width <<= 1;
301 if (height != 1)
302 height <<= 1;
303 if (depth != 1)
304 depth <<= 1;
305 }
306
307 /* Guess a reasonable value for lastLevel. This is probably going
308 * to be wrong fairly often and might mean that we have to look at
309 * resizable buffers, or require that buffers implement lazy
310 * pagetable arrangements.
311 */
312 if ((stObj->base.MinFilter == GL_NEAREST ||
313 stObj->base.MinFilter == GL_LINEAR) &&
314 stImage->level == firstLevel) {
315 lastLevel = firstLevel;
316 }
317 else {
318 GLuint l2width = logbase2(width);
319 GLuint l2height = logbase2(height);
320 GLuint l2depth = logbase2(depth);
321 lastLevel = firstLevel + MAX2(MAX2(l2width, l2height), l2depth);
322 }
323
324 if (stImage->base.IsCompressed)
325 comp_byte = compressed_num_bytes(stImage->base.TexFormat->MesaFormat);
326
327 stObj->pt = st_texture_create(st,
328 gl_target_to_pipe(stObj->base.Target),
329 st_mesa_format_to_pipe_format(stImage->base.TexFormat->MesaFormat),
330 lastLevel,
331 width,
332 height,
333 depth,
334 comp_byte);
335
336 DBG("%s - success\n", __FUNCTION__);
337 }
338
339
340 /* There are actually quite a few combinations this will work for,
341 * more than what I've listed here.
342 */
343 static GLboolean
344 check_pbo_format(GLint internalFormat,
345 GLenum format, GLenum type,
346 const struct gl_texture_format *mesa_format)
347 {
348 switch (internalFormat) {
349 case 4:
350 case GL_RGBA:
351 return (format == GL_BGRA &&
352 (type == GL_UNSIGNED_BYTE ||
353 type == GL_UNSIGNED_INT_8_8_8_8_REV) &&
354 mesa_format == &_mesa_texformat_argb8888);
355 case 3:
356 case GL_RGB:
357 return (format == GL_RGB &&
358 type == GL_UNSIGNED_SHORT_5_6_5 &&
359 mesa_format == &_mesa_texformat_rgb565);
360 case GL_YCBCR_MESA:
361 return (type == GL_UNSIGNED_SHORT_8_8_MESA || type == GL_UNSIGNED_BYTE);
362 default:
363 return GL_FALSE;
364 }
365 }
366
367
368 /* XXX: Do this for TexSubImage also:
369 */
370 static GLboolean
371 try_pbo_upload(GLcontext *ctx,
372 struct st_texture_image *stImage,
373 const struct gl_pixelstore_attrib *unpack,
374 GLint internalFormat,
375 GLint width, GLint height,
376 GLenum format, GLenum type, const void *pixels)
377 {
378 return GL_FALSE; /* XXX fix flushing/locking/blitting below */
379 #if 000
380 struct intel_context *intel = intel_context(ctx);
381 struct intel_buffer_object *pbo = intel_buffer_object(unpack->BufferObj);
382 GLuint src_offset, src_stride;
383 GLuint dst_offset, dst_stride;
384
385 if (!pbo ||
386 ctx._ImageTransferState ||
387 unpack->SkipPixels || unpack->SkipRows) {
388 _mesa_printf("%s: failure 1\n", __FUNCTION__);
389 return GL_FALSE;
390 }
391
392 src_offset = (GLuint) pixels;
393
394 if (unpack->RowLength > 0)
395 src_stride = unpack->RowLength;
396 else
397 src_stride = width;
398
399 dst_offset = st_texture_image_offset(stImage->pt,
400 stImage->face,
401 stImage->level);
402
403 dst_stride = stImage->pt->pitch;
404
405 {
406 struct _DriBufferObject *src_buffer =
407 intel_bufferobj_buffer(intel, pbo, INTEL_READ);
408
409 /* Temporary hack: cast to _DriBufferObject:
410 */
411 struct _DriBufferObject *dst_buffer =
412 (struct _DriBufferObject *)stImage->pt->region->buffer;
413
414
415 intelEmitCopyBlit(intel,
416 stImage->pt->cpp,
417 src_stride, src_buffer, src_offset,
418 dst_stride, dst_buffer, dst_offset,
419 0, 0, 0, 0, width, height,
420 GL_COPY);
421 }
422
423 return GL_TRUE;
424 #endif
425 }
426
427
428 /**
429 * Adjust pixel unpack params and image dimensions to strip off the
430 * texture border.
431 * Gallium doesn't support texture borders. They've seldem been used
432 * and seldom been implemented correctly anyway.
433 * \param unpackNew returns the new pixel unpack parameters
434 */
435 static void
436 strip_texture_border(GLint border,
437 GLint *width, GLint *height, GLint *depth,
438 const struct gl_pixelstore_attrib *unpack,
439 struct gl_pixelstore_attrib *unpackNew)
440 {
441 assert(border > 0); /* sanity check */
442
443 *unpackNew = *unpack;
444
445 if (unpackNew->RowLength == 0)
446 unpackNew->RowLength = *width;
447
448 if (depth && unpackNew->ImageHeight == 0)
449 unpackNew->ImageHeight = *height;
450
451 unpackNew->SkipPixels += border;
452 if (height)
453 unpackNew->SkipRows += border;
454 if (depth)
455 unpackNew->SkipImages += border;
456
457 assert(*width >= 3);
458 *width = *width - 2 * border;
459 if (height && *height >= 3)
460 *height = *height - 2 * border;
461 if (depth && *depth >= 3)
462 *depth = *depth - 2 * border;
463 }
464
465
466 static void
467 st_TexImage(GLcontext * ctx,
468 GLint dims,
469 GLenum target, GLint level,
470 GLint internalFormat,
471 GLint width, GLint height, GLint depth,
472 GLint border,
473 GLenum format, GLenum type, const void *pixels,
474 const struct gl_pixelstore_attrib *unpack,
475 struct gl_texture_object *texObj,
476 struct gl_texture_image *texImage,
477 GLsizei imageSize, int compressed)
478 {
479 struct pipe_context *pipe = ctx->st->pipe;
480 struct st_texture_object *stObj = st_texture_object(texObj);
481 struct st_texture_image *stImage = st_texture_image(texImage);
482 GLint postConvWidth, postConvHeight;
483 GLint texelBytes, sizeInBytes;
484 GLuint dstRowStride;
485 struct gl_pixelstore_attrib unpackNB;
486
487 DBG("%s target %s level %d %dx%dx%d border %d\n", __FUNCTION__,
488 _mesa_lookup_enum_by_nr(target), level, width, height, depth, border);
489
490 /* gallium does not support texture borders, strip it off */
491 if (border) {
492 strip_texture_border(border, &width, &height, &depth,
493 unpack, &unpackNB);
494 unpack = &unpackNB;
495 border = 0;
496 }
497
498 postConvWidth = width;
499 postConvHeight = height;
500
501 stImage->face = _mesa_tex_target_to_face(target);
502 stImage->level = level;
503
504 if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) {
505 _mesa_adjust_image_for_convolution(ctx, dims, &postConvWidth,
506 &postConvHeight);
507 }
508
509 /* choose the texture format */
510 texImage->TexFormat = st_ChooseTextureFormat(ctx, internalFormat,
511 format, type);
512
513 _mesa_set_fetch_functions(texImage, dims);
514
515 if (texImage->TexFormat->TexelBytes == 0) {
516 /* must be a compressed format */
517 texelBytes = 0;
518 texImage->IsCompressed = GL_TRUE;
519 texImage->CompressedSize =
520 ctx->Driver.CompressedTextureSize(ctx, texImage->Width,
521 texImage->Height, texImage->Depth,
522 texImage->TexFormat->MesaFormat);
523 }
524 else {
525 texelBytes = texImage->TexFormat->TexelBytes;
526
527 /* Minimum pitch of 32 bytes */
528 if (postConvWidth * texelBytes < 32) {
529 postConvWidth = 32 / texelBytes;
530 texImage->RowStride = postConvWidth;
531 }
532
533 /* we'll set RowStride elsewhere when the texture is a "mapped" state */
534 /*assert(texImage->RowStride == postConvWidth);*/
535 }
536
537 /* Release the reference to a potentially orphaned buffer.
538 * Release any old malloced memory.
539 */
540 if (stImage->pt) {
541 pipe_texture_release(&stImage->pt);
542 assert(!texImage->Data);
543 }
544 else if (texImage->Data) {
545 _mesa_align_free(texImage->Data);
546 }
547
548 /* If this is the only mipmap level in the texture, could call
549 * bmBufferData with NULL data to free the old block and avoid
550 * waiting on any outstanding fences.
551 */
552 if (stObj->pt &&
553 /*stObj->pt->first_level == level &&*/
554 stObj->pt->last_level == level &&
555 stObj->pt->target != PIPE_TEXTURE_CUBE &&
556 !st_texture_match_image(stObj->pt, &stImage->base,
557 stImage->face, stImage->level)) {
558
559 DBG("release it\n");
560 pipe_texture_release(&stObj->pt);
561 assert(!stObj->pt);
562 }
563
564 if (!stObj->pt) {
565 guess_and_alloc_texture(ctx->st, stObj, stImage);
566 if (!stObj->pt) {
567 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
568 return;
569 }
570 }
571
572 assert(!stImage->pt);
573
574 if (stObj->pt &&
575 st_texture_match_image(stObj->pt, &stImage->base,
576 stImage->face, stImage->level)) {
577
578 pipe_texture_reference(&stImage->pt, stObj->pt);
579 assert(stImage->pt);
580 }
581
582 if (!stImage->pt)
583 DBG("XXX: Image did not fit into texture - storing in local memory!\n");
584
585 #if 0 /* XXX FIX when st_buffer_objects are in place */
586 /* PBO fastpaths:
587 */
588 if (dims <= 2 &&
589 stImage->pt &&
590 intel_buffer_object(unpack->BufferObj) &&
591 check_pbo_format(internalFormat, format,
592 type, texImage->TexFormat)) {
593
594 DBG("trying pbo upload\n");
595
596
597
598 /* Otherwise, attempt to use the blitter for PBO image uploads.
599 */
600 if (try_pbo_upload(intel, stImage, unpack,
601 internalFormat,
602 width, height, format, type, pixels)) {
603 DBG("pbo upload succeeded\n");
604 return;
605 }
606
607 DBG("pbo upload failed\n");
608 }
609 #else
610 (void) try_pbo_upload;
611 (void) check_pbo_format;
612 #endif
613
614
615 /* st_CopyTexImage calls this function with pixels == NULL, with
616 * the expectation that the texture will be set up but nothing
617 * more will be done. This is where those calls return:
618 */
619 if (compressed) {
620 pixels = _mesa_validate_pbo_compressed_teximage(ctx, imageSize, pixels,
621 unpack,
622 "glCompressedTexImage");
623 } else {
624 pixels = _mesa_validate_pbo_teximage(ctx, dims, width, height, 1,
625 format, type,
626 pixels, unpack, "glTexImage");
627 }
628 if (!pixels)
629 return;
630
631 if (stImage->pt) {
632 texImage->Data = st_texture_image_map(ctx->st, stImage, 0);
633 dstRowStride = stImage->surface->pitch * stImage->surface->cpp;
634 }
635 else {
636 /* Allocate regular memory and store the image there temporarily. */
637 if (texImage->IsCompressed) {
638 sizeInBytes = texImage->CompressedSize;
639 dstRowStride =
640 _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat, width);
641 assert(dims != 3);
642 }
643 else {
644 dstRowStride = postConvWidth * texelBytes;
645 sizeInBytes = depth * dstRowStride * postConvHeight;
646 }
647
648 texImage->Data = malloc(sizeInBytes);
649 }
650
651 DBG("Upload image %dx%dx%d row_len %x pitch %x\n",
652 width, height, depth, width * texelBytes, dstRowStride);
653
654 /* Copy data. Would like to know when it's ok for us to eg. use
655 * the blitter to copy. Or, use the hardware to do the format
656 * conversion and copy:
657 */
658 if (compressed) {
659 memcpy(texImage->Data, pixels, imageSize);
660 }
661 else {
662 GLuint srcImageStride = _mesa_image_image_stride(unpack, width, height,
663 format, type);
664 int i;
665 const GLubyte *src = (const GLubyte *) pixels;
666
667 for (i = 0; i++ < depth;) {
668 if (!texImage->TexFormat->StoreImage(ctx, dims,
669 texImage->_BaseFormat,
670 texImage->TexFormat,
671 texImage->Data,
672 0, 0, 0, /* dstX/Y/Zoffset */
673 dstRowStride,
674 texImage->ImageOffsets,
675 width, height, 1,
676 format, type, src, unpack)) {
677 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
678 }
679
680 if (stImage->pt && i < depth) {
681 st_texture_image_unmap(stImage);
682 texImage->Data = st_texture_image_map(ctx->st, stImage, i);
683 src += srcImageStride;
684 }
685 }
686 }
687
688 _mesa_unmap_teximage_pbo(ctx, unpack);
689
690 if (stImage->pt) {
691 st_texture_image_unmap(stImage);
692 texImage->Data = NULL;
693 }
694
695 if (stObj->pt)
696 pipe->texture_update(pipe, stObj->pt, stImage->face, (1 << level));
697
698 if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
699 ctx->Driver.GenerateMipmap(ctx, target, texObj);
700 }
701 }
702
703
704 static void
705 st_TexImage3D(GLcontext * ctx,
706 GLenum target, GLint level,
707 GLint internalFormat,
708 GLint width, GLint height, GLint depth,
709 GLint border,
710 GLenum format, GLenum type, const void *pixels,
711 const struct gl_pixelstore_attrib *unpack,
712 struct gl_texture_object *texObj,
713 struct gl_texture_image *texImage)
714 {
715 st_TexImage(ctx, 3, target, level,
716 internalFormat, width, height, depth, border,
717 format, type, pixels, unpack, texObj, texImage, 0, 0);
718 }
719
720
721 static void
722 st_TexImage2D(GLcontext * ctx,
723 GLenum target, GLint level,
724 GLint internalFormat,
725 GLint width, GLint height, GLint border,
726 GLenum format, GLenum type, const void *pixels,
727 const struct gl_pixelstore_attrib *unpack,
728 struct gl_texture_object *texObj,
729 struct gl_texture_image *texImage)
730 {
731 st_TexImage(ctx, 2, target, level,
732 internalFormat, width, height, 1, border,
733 format, type, pixels, unpack, texObj, texImage, 0, 0);
734 }
735
736
737 static void
738 st_TexImage1D(GLcontext * ctx,
739 GLenum target, GLint level,
740 GLint internalFormat,
741 GLint width, GLint border,
742 GLenum format, GLenum type, const void *pixels,
743 const struct gl_pixelstore_attrib *unpack,
744 struct gl_texture_object *texObj,
745 struct gl_texture_image *texImage)
746 {
747 st_TexImage(ctx, 1, target, level,
748 internalFormat, width, 1, 1, border,
749 format, type, pixels, unpack, texObj, texImage, 0, 0);
750 }
751
752
753 static void
754 st_CompressedTexImage2D( GLcontext *ctx, GLenum target, GLint level,
755 GLint internalFormat,
756 GLint width, GLint height, GLint border,
757 GLsizei imageSize, const GLvoid *data,
758 struct gl_texture_object *texObj,
759 struct gl_texture_image *texImage )
760 {
761 st_TexImage(ctx, 2, target, level,
762 internalFormat, width, height, 1, border,
763 0, 0, data, &ctx->Unpack, texObj, texImage, imageSize, 1);
764 }
765
766
767 /**
768 * Need to map texture image into memory before copying image data,
769 * then unmap it.
770 */
771 static void
772 st_get_tex_image(GLcontext * ctx, GLenum target, GLint level,
773 GLenum format, GLenum type, GLvoid * pixels,
774 struct gl_texture_object *texObj,
775 struct gl_texture_image *texImage, int compressed)
776 {
777 struct st_texture_image *stImage = st_texture_image(texImage);
778 GLuint dstImageStride = _mesa_image_image_stride(&ctx->Pack, texImage->Width,
779 texImage->Height, format,
780 type);
781 GLuint depth;
782 int i;
783 GLubyte *dest;
784
785 /* Map */
786 if (stImage->pt) {
787 /* Image is stored in hardware format in a buffer managed by the
788 * kernel. Need to explicitly map and unmap it.
789 */
790 texImage->Data = st_texture_image_map(ctx->st, stImage, 0);
791 texImage->RowStride = stImage->surface->pitch;
792 }
793 else {
794 /* Otherwise, the image should actually be stored in
795 * texImage->Data. This is pretty confusing for
796 * everybody, I'd much prefer to separate the two functions of
797 * texImage->Data - storage for texture images in main memory
798 * and access (ie mappings) of images. In other words, we'd
799 * create a new texImage->Map field and leave Data simply for
800 * storage.
801 */
802 assert(texImage->Data);
803 }
804
805 depth = texImage->Depth;
806 texImage->Depth = 1;
807
808 dest = (GLubyte *) pixels;
809
810 for (i = 0; i++ < depth;) {
811 if (compressed) {
812 _mesa_get_compressed_teximage(ctx, target, level, dest,
813 texObj, texImage);
814 } else {
815 _mesa_get_teximage(ctx, target, level, format, type, dest,
816 texObj, texImage);
817 }
818
819 if (stImage->pt && i < depth) {
820 st_texture_image_unmap(stImage);
821 texImage->Data = st_texture_image_map(ctx->st, stImage, i);
822 dest += dstImageStride;
823 }
824 }
825
826 texImage->Depth = depth;
827
828 /* Unmap */
829 if (stImage->pt) {
830 st_texture_image_unmap(stImage);
831 texImage->Data = NULL;
832 }
833 }
834
835
836 static void
837 st_GetTexImage(GLcontext * ctx, GLenum target, GLint level,
838 GLenum format, GLenum type, GLvoid * pixels,
839 struct gl_texture_object *texObj,
840 struct gl_texture_image *texImage)
841 {
842 st_get_tex_image(ctx, target, level, format, type, pixels,
843 texObj, texImage, 0);
844 }
845
846
847 static void
848 st_GetCompressedTexImage(GLcontext *ctx, GLenum target, GLint level,
849 GLvoid *pixels,
850 const struct gl_texture_object *texObj,
851 const struct gl_texture_image *texImage)
852 {
853 st_get_tex_image(ctx, target, level, 0, 0, pixels,
854 (struct gl_texture_object *) texObj,
855 (struct gl_texture_image *) texImage, 1);
856 }
857
858
859
860 static void
861 st_TexSubimage(GLcontext * ctx,
862 GLint dims,
863 GLenum target, GLint level,
864 GLint xoffset, GLint yoffset, GLint zoffset,
865 GLint width, GLint height, GLint depth,
866 GLenum format, GLenum type, const void *pixels,
867 const struct gl_pixelstore_attrib *packing,
868 struct gl_texture_object *texObj,
869 struct gl_texture_image *texImage)
870 {
871 struct pipe_context *pipe = ctx->st->pipe;
872 struct st_texture_object *stObj = st_texture_object(texObj);
873 struct st_texture_image *stImage = st_texture_image(texImage);
874 GLuint dstRowStride;
875 GLuint srcImageStride = _mesa_image_image_stride(packing, width, height,
876 format, type);
877 int i;
878 const GLubyte *src;
879
880 DBG("%s target %s level %d offset %d,%d %dx%d\n", __FUNCTION__,
881 _mesa_lookup_enum_by_nr(target),
882 level, xoffset, yoffset, width, height);
883
884 pixels =
885 _mesa_validate_pbo_teximage(ctx, dims, width, height, depth, format,
886 type, pixels, packing, "glTexSubImage2D");
887 if (!pixels)
888 return;
889
890 /* Map buffer if necessary. Need to lock to prevent other contexts
891 * from uploading the buffer under us.
892 */
893 if (stImage->pt) {
894 texImage->Data = st_texture_image_map(ctx->st, stImage, zoffset);
895 dstRowStride = stImage->surface->pitch * stImage->surface->cpp;
896 }
897
898 src = (const GLubyte *) pixels;
899
900 for (i = 0; i++ < depth;) {
901 if (!texImage->TexFormat->StoreImage(ctx, dims, texImage->_BaseFormat,
902 texImage->TexFormat,
903 texImage->Data,
904 xoffset, yoffset, 0,
905 dstRowStride,
906 texImage->ImageOffsets,
907 width, height, 1,
908 format, type, src, packing)) {
909 _mesa_error(ctx, GL_OUT_OF_MEMORY, "st_TexSubImage");
910 }
911
912 if (stImage->pt && i < depth) {
913 st_texture_image_unmap(stImage);
914 texImage->Data = st_texture_image_map(ctx->st, stImage, zoffset + i);
915 src += srcImageStride;
916 }
917 }
918
919 if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
920 ctx->Driver.GenerateMipmap(ctx, target, texObj);
921 }
922
923 _mesa_unmap_teximage_pbo(ctx, packing);
924
925 if (stImage->pt) {
926 st_texture_image_unmap(stImage);
927 texImage->Data = NULL;
928 }
929
930 pipe->texture_update(pipe, stObj->pt, stImage->face, (1 << level));
931 }
932
933
934
935 static void
936 st_TexSubImage3D(GLcontext * ctx,
937 GLenum target,
938 GLint level,
939 GLint xoffset, GLint yoffset, GLint zoffset,
940 GLsizei width, GLsizei height, GLsizei depth,
941 GLenum format, GLenum type,
942 const GLvoid * pixels,
943 const struct gl_pixelstore_attrib *packing,
944 struct gl_texture_object *texObj,
945 struct gl_texture_image *texImage)
946 {
947 st_TexSubimage(ctx, 3, target, level,
948 xoffset, yoffset, zoffset,
949 width, height, depth,
950 format, type, pixels, packing, texObj, texImage);
951 }
952
953
954
955 static void
956 st_TexSubImage2D(GLcontext * ctx,
957 GLenum target,
958 GLint level,
959 GLint xoffset, GLint yoffset,
960 GLsizei width, GLsizei height,
961 GLenum format, GLenum type,
962 const GLvoid * pixels,
963 const struct gl_pixelstore_attrib *packing,
964 struct gl_texture_object *texObj,
965 struct gl_texture_image *texImage)
966 {
967 st_TexSubimage(ctx, 2, target, level,
968 xoffset, yoffset, 0,
969 width, height, 1,
970 format, type, pixels, packing, texObj, texImage);
971 }
972
973
974 static void
975 st_TexSubImage1D(GLcontext * ctx,
976 GLenum target,
977 GLint level,
978 GLint xoffset,
979 GLsizei width,
980 GLenum format, GLenum type,
981 const GLvoid * pixels,
982 const struct gl_pixelstore_attrib *packing,
983 struct gl_texture_object *texObj,
984 struct gl_texture_image *texImage)
985 {
986 st_TexSubimage(ctx, 1, target, level,
987 xoffset, 0, 0,
988 width, 1, 1,
989 format, type, pixels, packing, texObj, texImage);
990 }
991
992
993
994 /**
995 * Return 0 for GL_TEXTURE_CUBE_MAP_POSITIVE_X,
996 * 1 for GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
997 * etc.
998 * XXX duplicated from main/teximage.c
999 */
1000 static uint
1001 texture_face(GLenum target)
1002 {
1003 if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
1004 target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB)
1005 return (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X;
1006 else
1007 return 0;
1008 }
1009
1010
1011
1012 /**
1013 * Do a CopyTexSubImage operation by mapping the source surface and
1014 * dest surface and using get_tile()/put_tile() to access the pixels/texels.
1015 *
1016 * Note: srcY=0=TOP of renderbuffer
1017 */
1018 static void
1019 fallback_copy_texsubimage(GLcontext *ctx,
1020 GLenum target,
1021 GLint level,
1022 struct st_renderbuffer *strb,
1023 struct st_texture_image *stImage,
1024 GLenum baseFormat,
1025 GLint destX, GLint destY, GLint destZ,
1026 GLint srcX, GLint srcY,
1027 GLsizei width, GLsizei height)
1028 {
1029 struct pipe_context *pipe = ctx->st->pipe;
1030 struct pipe_screen *screen = pipe->screen;
1031 const uint face = texture_face(target);
1032 struct pipe_texture *pt = stImage->pt;
1033 struct pipe_surface *src_surf, *dest_surf;
1034 GLfloat *data;
1035 GLint row, yStep;
1036
1037 /* determine bottom-to-top vs. top-to-bottom order */
1038 if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) {
1039 destY = height - 1 - destY;
1040 yStep = -1;
1041 }
1042 else {
1043 yStep = 1;
1044 }
1045
1046 src_surf = strb->surface;
1047
1048 dest_surf = screen->get_tex_surface(screen, pt, face, level, destZ);
1049
1050 /* buffer for one row */
1051 data = (GLfloat *) malloc(width * 4 * sizeof(GLfloat));
1052
1053 /* do copy row by row */
1054 for (row = 0; row < height; row++) {
1055 pipe_get_tile_rgba(pipe, src_surf, srcX, srcY + row, width, 1, data);
1056
1057 /* XXX we're ignoring convolution for now */
1058 if (ctx->_ImageTransferState) {
1059 _mesa_apply_rgba_transfer_ops(ctx,
1060 ctx->_ImageTransferState & ~IMAGE_CONVOLUTION_BIT,
1061 width, (GLfloat (*)[4])data);
1062 }
1063
1064 pipe_put_tile_rgba(pipe, dest_surf, destX, destY, width, 1, data);
1065 destY += yStep;
1066 }
1067
1068 free(data);
1069 }
1070
1071
1072
1073
1074 /**
1075 * Do a CopyTex[Sub]Image using an optimized hardware (blit) path.
1076 * Note that the region to copy has already been clip tested.
1077 *
1078 * Note: srcY=0=Bottom of renderbuffer
1079 *
1080 * \return GL_TRUE if success, GL_FALSE if failure (use a fallback)
1081 */
1082 static void
1083 do_copy_texsubimage(GLcontext *ctx,
1084 GLenum target, GLint level,
1085 GLint destX, GLint destY, GLint destZ,
1086 GLint srcX, GLint srcY,
1087 GLsizei width, GLsizei height)
1088 {
1089 struct gl_texture_unit *texUnit =
1090 &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
1091 struct gl_texture_object *texObj =
1092 _mesa_select_tex_object(ctx, texUnit, target);
1093 struct gl_texture_image *texImage =
1094 _mesa_select_tex_image(ctx, texObj, target, level);
1095 struct st_texture_image *stImage = st_texture_image(texImage);
1096 struct st_texture_object *stObj = st_texture_object(texObj);
1097 GLenum baseFormat = texImage->InternalFormat;
1098 struct gl_framebuffer *fb = ctx->ReadBuffer;
1099 struct st_renderbuffer *strb;
1100 struct pipe_context *pipe = ctx->st->pipe;
1101 struct pipe_screen *screen = pipe->screen;
1102 struct pipe_surface *dest_surface;
1103 uint dest_format, src_format;
1104 uint do_flip = FALSE;
1105
1106 (void) texImage;
1107
1108 /* determine if copying depth or color data */
1109 if (baseFormat == GL_DEPTH_COMPONENT) {
1110 strb = st_renderbuffer(fb->_DepthBuffer);
1111 }
1112 else if (baseFormat == GL_DEPTH_STENCIL_EXT) {
1113 strb = st_renderbuffer(fb->_StencilBuffer);
1114 }
1115 else {
1116 /* baseFormat == GL_RGB, GL_RGBA, GL_ALPHA, etc */
1117 strb = st_renderbuffer(fb->_ColorReadBuffer);
1118 }
1119
1120 assert(strb);
1121 assert(strb->surface);
1122 assert(stImage->pt);
1123
1124 if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) {
1125 srcY = strb->Base.Height - srcY - height;
1126 do_flip = TRUE;
1127 }
1128
1129 src_format = strb->surface->format;
1130 dest_format = stImage->pt->format;
1131
1132 dest_surface = screen->get_tex_surface(screen, stImage->pt, stImage->face,
1133 stImage->level, destZ);
1134
1135 if (src_format == dest_format &&
1136 ctx->_ImageTransferState == 0x0 &&
1137 strb->surface->buffer &&
1138 dest_surface->buffer &&
1139 strb->surface->cpp == stImage->pt->cpp) {
1140 /* do blit-style copy */
1141
1142 /* XXX may need to invert image depending on window
1143 * vs. user-created FBO
1144 */
1145
1146 #if 0
1147 /* A bit of fiddling to get the blitter to work with -ve
1148 * pitches. But we get a nice inverted blit this way, so it's
1149 * worth it:
1150 */
1151 intelEmitCopyBlit(intel,
1152 stImage->pt->cpp,
1153 -src->pitch,
1154 src->buffer,
1155 src->height * src->pitch * src->cpp,
1156 stImage->pt->pitch,
1157 stImage->pt->region->buffer,
1158 dest_offset,
1159 x, y + height, dstx, dsty, width, height,
1160 GL_COPY); /* ? */
1161 #else
1162
1163 pipe->surface_copy(pipe,
1164 do_flip,
1165 /* dest */
1166 dest_surface,
1167 destX, destY,
1168 /* src */
1169 strb->surface,
1170 srcX, srcY,
1171 /* size */
1172 width, height);
1173 #endif
1174 }
1175 else {
1176 fallback_copy_texsubimage(ctx, target, level,
1177 strb, stImage, baseFormat,
1178 destX, destY, destZ,
1179 srcX, srcY, width, height);
1180 }
1181
1182 pipe_surface_reference(&dest_surface, NULL);
1183
1184 pipe->texture_update(pipe, stObj->pt, stImage->face, (1 << level));
1185
1186 if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
1187 ctx->Driver.GenerateMipmap(ctx, target, texObj);
1188 }
1189 }
1190
1191
1192
1193 static void
1194 st_CopyTexImage1D(GLcontext * ctx, GLenum target, GLint level,
1195 GLenum internalFormat,
1196 GLint x, GLint y, GLsizei width, GLint border)
1197 {
1198 struct gl_texture_unit *texUnit =
1199 &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
1200 struct gl_texture_object *texObj =
1201 _mesa_select_tex_object(ctx, texUnit, target);
1202 struct gl_texture_image *texImage =
1203 _mesa_select_tex_image(ctx, texObj, target, level);
1204
1205 #if 0
1206 if (border)
1207 goto fail;
1208 #endif
1209
1210 /* Setup or redefine the texture object, texture and texture
1211 * image. Don't populate yet.
1212 */
1213 ctx->Driver.TexImage1D(ctx, target, level, internalFormat,
1214 width, border,
1215 GL_RGBA, CHAN_TYPE, NULL,
1216 &ctx->DefaultPacking, texObj, texImage);
1217
1218 do_copy_texsubimage(ctx, target, level,
1219 0, 0, 0,
1220 x, y, width, 1);
1221 }
1222
1223
1224 static void
1225 st_CopyTexImage2D(GLcontext * ctx, GLenum target, GLint level,
1226 GLenum internalFormat,
1227 GLint x, GLint y, GLsizei width, GLsizei height,
1228 GLint border)
1229 {
1230 struct gl_texture_unit *texUnit =
1231 &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
1232 struct gl_texture_object *texObj =
1233 _mesa_select_tex_object(ctx, texUnit, target);
1234 struct gl_texture_image *texImage =
1235 _mesa_select_tex_image(ctx, texObj, target, level);
1236
1237 #if 0
1238 if (border)
1239 goto fail;
1240 #endif
1241
1242 /* Setup or redefine the texture object, texture and texture
1243 * image. Don't populate yet.
1244 */
1245 ctx->Driver.TexImage2D(ctx, target, level, internalFormat,
1246 width, height, border,
1247 GL_RGBA, CHAN_TYPE, NULL,
1248 &ctx->DefaultPacking, texObj, texImage);
1249
1250
1251 do_copy_texsubimage(ctx, target, level,
1252 0, 0, 0,
1253 x, y, width, height);
1254 }
1255
1256
1257 static void
1258 st_CopyTexSubImage1D(GLcontext * ctx, GLenum target, GLint level,
1259 GLint xoffset, GLint x, GLint y, GLsizei width)
1260 {
1261 const GLint yoffset = 0, zoffset = 0;
1262 const GLsizei height = 1;
1263 do_copy_texsubimage(ctx, target, level,
1264 xoffset, yoffset, zoffset,
1265 x, y, width, height);
1266 }
1267
1268
1269 static void
1270 st_CopyTexSubImage2D(GLcontext * ctx, GLenum target, GLint level,
1271 GLint xoffset, GLint yoffset,
1272 GLint x, GLint y, GLsizei width, GLsizei height)
1273 {
1274 const GLint zoffset = 0;
1275 do_copy_texsubimage(ctx, target, level,
1276 xoffset, yoffset, zoffset,
1277 x, y, width, height);
1278 }
1279
1280
1281 static void
1282 st_CopyTexSubImage3D(GLcontext * ctx, GLenum target, GLint level,
1283 GLint xoffset, GLint yoffset, GLint zoffset,
1284 GLint x, GLint y, GLsizei width, GLsizei height)
1285 {
1286 do_copy_texsubimage(ctx, target, level,
1287 xoffset, yoffset, zoffset,
1288 x, y, width, height);
1289 }
1290
1291
1292
1293
1294 /**
1295 * Compute which mipmap levels that really need to be sent to the hardware.
1296 * This depends on the base image size, GL_TEXTURE_MIN_LOD,
1297 * GL_TEXTURE_MAX_LOD, GL_TEXTURE_BASE_LEVEL, and GL_TEXTURE_MAX_LEVEL.
1298 */
1299 static void
1300 calculate_first_last_level(struct st_texture_object *stObj)
1301 {
1302 struct gl_texture_object *tObj = &stObj->base;
1303 const struct gl_texture_image *const baseImage =
1304 tObj->Image[0][tObj->BaseLevel];
1305
1306 /* These must be signed values. MinLod and MaxLod can be negative numbers,
1307 * and having firstLevel and lastLevel as signed prevents the need for
1308 * extra sign checks.
1309 */
1310 int firstLevel;
1311 int lastLevel;
1312
1313 /* Yes, this looks overly complicated, but it's all needed.
1314 */
1315 switch (tObj->Target) {
1316 case GL_TEXTURE_1D:
1317 case GL_TEXTURE_2D:
1318 case GL_TEXTURE_3D:
1319 case GL_TEXTURE_CUBE_MAP:
1320 if (tObj->MinFilter == GL_NEAREST || tObj->MinFilter == GL_LINEAR) {
1321 /* GL_NEAREST and GL_LINEAR only care about GL_TEXTURE_BASE_LEVEL.
1322 */
1323 firstLevel = lastLevel = tObj->BaseLevel;
1324 }
1325 else {
1326 firstLevel = 0;
1327 lastLevel = MIN2(tObj->MaxLevel - tObj->BaseLevel, baseImage->MaxLog2);
1328 }
1329 break;
1330 case GL_TEXTURE_RECTANGLE_NV:
1331 case GL_TEXTURE_4D_SGIS:
1332 firstLevel = lastLevel = 0;
1333 break;
1334 default:
1335 return;
1336 }
1337
1338 stObj->lastLevel = lastLevel;
1339 }
1340
1341
1342 static void
1343 copy_image_data_to_texture(struct st_context *st,
1344 struct st_texture_object *stObj,
1345 GLuint dstLevel,
1346 struct st_texture_image *stImage)
1347 {
1348 if (stImage->pt) {
1349 /* Copy potentially with the blitter:
1350 */
1351 st_texture_image_copy(st->pipe,
1352 stObj->pt, dstLevel, /* dest texture, level */
1353 stImage->pt, /* src texture */
1354 stImage->face
1355 );
1356
1357 pipe_texture_release(&stImage->pt);
1358 }
1359 else {
1360 assert(stImage->base.Data != NULL);
1361
1362 /* More straightforward upload.
1363 */
1364 st_texture_image_data(st->pipe,
1365 stObj->pt,
1366 stImage->face,
1367 stImage->level,
1368 stImage->base.Data,
1369 stImage->base.RowStride,
1370 stImage->base.RowStride *
1371 stImage->base.Height);
1372 _mesa_align_free(stImage->base.Data);
1373 stImage->base.Data = NULL;
1374 }
1375
1376 pipe_texture_reference(&stImage->pt, stObj->pt);
1377 }
1378
1379
1380 /**
1381 * Called during state validation. When this function is finished,
1382 * the texture object should be ready for rendering.
1383 * \return GL_TRUE for success, GL_FALSE for failure (out of mem)
1384 */
1385 GLboolean
1386 st_finalize_texture(GLcontext *ctx,
1387 struct pipe_context *pipe,
1388 struct gl_texture_object *tObj,
1389 GLboolean *needFlush)
1390 {
1391 struct st_texture_object *stObj = st_texture_object(tObj);
1392 const GLuint nr_faces = (stObj->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1;
1393 int comp_byte = 0;
1394 int cpp;
1395 GLuint face;
1396 struct st_texture_image *firstImage;
1397
1398 *needFlush = GL_FALSE;
1399
1400 /* We know/require this is true by now:
1401 */
1402 assert(stObj->base._Complete);
1403
1404 /* What levels must the texture include at a minimum?
1405 */
1406 calculate_first_last_level(stObj);
1407 firstImage = st_texture_image(stObj->base.Image[0][stObj->base.BaseLevel]);
1408
1409 #if 0
1410 /* Fallback case:
1411 */
1412 if (firstImage->base.Border) {
1413 if (stObj->pt) {
1414 pipe_texture_release(&stObj->pt);
1415 }
1416 return GL_FALSE;
1417 }
1418 #endif
1419
1420 /* If both firstImage and stObj point to a texture which can contain
1421 * all active images, favour firstImage. Note that because of the
1422 * completeness requirement, we know that the image dimensions
1423 * will match.
1424 */
1425 if (firstImage->pt &&
1426 firstImage->pt != stObj->pt &&
1427 firstImage->pt->last_level >= stObj->lastLevel) {
1428
1429 if (stObj->pt)
1430 pipe_texture_release(&stObj->pt);
1431
1432 pipe_texture_reference(&stObj->pt, firstImage->pt);
1433 }
1434
1435 if (firstImage->base.IsCompressed) {
1436 comp_byte = compressed_num_bytes(firstImage->base.TexFormat->MesaFormat);
1437 cpp = comp_byte;
1438 }
1439 else {
1440 cpp = firstImage->base.TexFormat->TexelBytes;
1441 }
1442
1443 /* Check texture can hold all active levels. Check texture matches
1444 * target, imageFormat, etc.
1445 */
1446 if (stObj->pt &&
1447 (stObj->pt->target != gl_target_to_pipe(stObj->base.Target) ||
1448 stObj->pt->format !=
1449 st_mesa_format_to_pipe_format(firstImage->base.TexFormat->MesaFormat) ||
1450 stObj->pt->last_level != stObj->lastLevel ||
1451 stObj->pt->width[0] != firstImage->base.Width ||
1452 stObj->pt->height[0] != firstImage->base.Height ||
1453 stObj->pt->depth[0] != firstImage->base.Depth ||
1454 stObj->pt->cpp != cpp ||
1455 stObj->pt->compressed != firstImage->base.IsCompressed)) {
1456 pipe_texture_release(&stObj->pt);
1457 }
1458
1459
1460 /* May need to create a new texture:
1461 */
1462 if (!stObj->pt) {
1463 stObj->pt = st_texture_create(ctx->st,
1464 gl_target_to_pipe(stObj->base.Target),
1465 st_mesa_format_to_pipe_format(firstImage->base.TexFormat->MesaFormat),
1466 stObj->lastLevel,
1467 firstImage->base.Width,
1468 firstImage->base.Height,
1469 firstImage->base.Depth,
1470 comp_byte);
1471 if (!stObj->pt) {
1472 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
1473 return GL_FALSE;
1474 }
1475 }
1476
1477 /* Pull in any images not in the object's texture:
1478 */
1479 for (face = 0; face < nr_faces; face++) {
1480 GLuint level;
1481 for (level = 0; level <= stObj->lastLevel; level++) {
1482 struct st_texture_image *stImage =
1483 st_texture_image(stObj->base.Image[face][stObj->base.BaseLevel + level]);
1484
1485 /* Need to import images in main memory or held in other textures.
1486 */
1487 if (stImage && stObj->pt != stImage->pt) {
1488 copy_image_data_to_texture(ctx->st, stObj, level, stImage);
1489 *needFlush = GL_TRUE;
1490 pipe->texture_update(pipe, stObj->pt, face, (1 << level));
1491 }
1492 }
1493 }
1494
1495 return GL_TRUE;
1496 }
1497
1498
1499
1500
1501 void
1502 st_init_texture_functions(struct dd_function_table *functions)
1503 {
1504 functions->ChooseTextureFormat = st_ChooseTextureFormat;
1505 functions->TexImage1D = st_TexImage1D;
1506 functions->TexImage2D = st_TexImage2D;
1507 functions->TexImage3D = st_TexImage3D;
1508 functions->TexSubImage1D = st_TexSubImage1D;
1509 functions->TexSubImage2D = st_TexSubImage2D;
1510 functions->TexSubImage3D = st_TexSubImage3D;
1511 functions->CopyTexImage1D = st_CopyTexImage1D;
1512 functions->CopyTexImage2D = st_CopyTexImage2D;
1513 functions->CopyTexSubImage1D = st_CopyTexSubImage1D;
1514 functions->CopyTexSubImage2D = st_CopyTexSubImage2D;
1515 functions->CopyTexSubImage3D = st_CopyTexSubImage3D;
1516 functions->GenerateMipmap = st_generate_mipmap;
1517
1518 functions->GetTexImage = st_GetTexImage;
1519
1520 /* compressed texture functions */
1521 functions->CompressedTexImage2D = st_CompressedTexImage2D;
1522 functions->GetCompressedTexImage = st_GetCompressedTexImage;
1523
1524 functions->NewTextureObject = st_NewTextureObject;
1525 functions->NewTextureImage = st_NewTextureImage;
1526 functions->DeleteTexture = st_DeleteTextureObject;
1527 functions->FreeTexImageData = st_FreeTextureImageData;
1528 functions->UpdateTexturePalette = 0;
1529 functions->IsTextureResident = st_IsTextureResident;
1530
1531 functions->TextureMemCpy = do_memcpy;
1532
1533 /* XXX Temporary until we can query pipe's texture sizes */
1534 functions->TestProxyTexImage = _mesa_test_proxy_teximage;
1535 }