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