Adapt for winsys interface changes.
[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 * textures will be copied to this texture 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 /* st_CopyTexImage 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 const GLubyte *src = (const GLubyte *) pixels;
710
711 for (i = 0; i++ < depth;) {
712 if (!texImage->TexFormat->StoreImage(ctx, dims,
713 texImage->_BaseFormat,
714 texImage->TexFormat,
715 texImage->Data,
716 0, 0, 0, /* dstX/Y/Zoffset */
717 dstRowStride,
718 texImage->ImageOffsets,
719 width, height, 1,
720 format, type, src, unpack)) {
721 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
722 }
723
724 if (stImage->pt && i < depth) {
725 st_texture_image_unmap(stImage);
726 texImage->Data = st_texture_image_map(ctx->st, stImage, i);
727 src += srcImageStride;
728 }
729 }
730 }
731
732 _mesa_unmap_teximage_pbo(ctx, unpack);
733
734 if (stImage->pt) {
735 st_texture_image_unmap(stImage);
736 texImage->Data = NULL;
737 }
738
739 #if 0
740 /* GL_SGIS_generate_mipmap -- this can be accelerated now.
741 */
742 if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
743 intel_generate_mipmap(ctx, target,
744 &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
745 texObj);
746 }
747 #endif
748 }
749
750
751 static void
752 st_TexImage3D(GLcontext * ctx,
753 GLenum target, GLint level,
754 GLint internalFormat,
755 GLint width, GLint height, GLint depth,
756 GLint border,
757 GLenum format, GLenum type, const void *pixels,
758 const struct gl_pixelstore_attrib *unpack,
759 struct gl_texture_object *texObj,
760 struct gl_texture_image *texImage)
761 {
762 st_TexImage(ctx, 3, target, level,
763 internalFormat, width, height, depth, border,
764 format, type, pixels, unpack, texObj, texImage, 0, 0);
765 }
766
767
768 static void
769 st_TexImage2D(GLcontext * ctx,
770 GLenum target, GLint level,
771 GLint internalFormat,
772 GLint width, GLint height, GLint border,
773 GLenum format, GLenum type, const void *pixels,
774 const struct gl_pixelstore_attrib *unpack,
775 struct gl_texture_object *texObj,
776 struct gl_texture_image *texImage)
777 {
778 st_TexImage(ctx, 2, target, level,
779 internalFormat, width, height, 1, border,
780 format, type, pixels, unpack, texObj, texImage, 0, 0);
781 }
782
783
784 static void
785 st_TexImage1D(GLcontext * ctx,
786 GLenum target, GLint level,
787 GLint internalFormat,
788 GLint width, GLint border,
789 GLenum format, GLenum type, const void *pixels,
790 const struct gl_pixelstore_attrib *unpack,
791 struct gl_texture_object *texObj,
792 struct gl_texture_image *texImage)
793 {
794 st_TexImage(ctx, 1, target, level,
795 internalFormat, width, 1, 1, border,
796 format, type, pixels, unpack, texObj, texImage, 0, 0);
797 }
798
799
800 static void
801 st_CompressedTexImage2D( GLcontext *ctx, GLenum target, GLint level,
802 GLint internalFormat,
803 GLint width, GLint height, GLint border,
804 GLsizei imageSize, const GLvoid *data,
805 struct gl_texture_object *texObj,
806 struct gl_texture_image *texImage )
807 {
808 st_TexImage(ctx, 2, target, level,
809 internalFormat, width, height, 1, border,
810 0, 0, data, &ctx->Unpack, texObj, texImage, imageSize, 1);
811 }
812
813
814 /**
815 * Need to map texture image into memory before copying image data,
816 * then unmap it.
817 */
818 static void
819 st_get_tex_image(GLcontext * ctx, GLenum target, GLint level,
820 GLenum format, GLenum type, GLvoid * pixels,
821 struct gl_texture_object *texObj,
822 struct gl_texture_image *texImage, int compressed)
823 {
824 struct st_texture_image *stImage = st_texture_image(texImage);
825 GLuint dstImageStride = _mesa_image_image_stride(&ctx->Pack, texImage->Width,
826 texImage->Height, format,
827 type);
828 GLuint depth;
829 int i;
830 GLubyte *dest;
831
832 /* Map */
833 if (stImage->pt) {
834 /* Image is stored in hardware format in a buffer managed by the
835 * kernel. Need to explicitly map and unmap it.
836 */
837 texImage->Data = st_texture_image_map(ctx->st, stImage, 0);
838 texImage->RowStride = stImage->surface->pitch;
839 }
840 else {
841 /* Otherwise, the image should actually be stored in
842 * texImage->Data. This is pretty confusing for
843 * everybody, I'd much prefer to separate the two functions of
844 * texImage->Data - storage for texture images in main memory
845 * and access (ie mappings) of images. In other words, we'd
846 * create a new texImage->Map field and leave Data simply for
847 * storage.
848 */
849 assert(texImage->Data);
850 }
851
852 depth = texImage->Depth;
853 texImage->Depth = 1;
854
855 dest = (GLubyte *) pixels;
856
857 for (i = 0; i++ < depth;) {
858 if (compressed) {
859 _mesa_get_compressed_teximage(ctx, target, level, dest,
860 texObj, texImage);
861 } else {
862 _mesa_get_teximage(ctx, target, level, format, type, dest,
863 texObj, texImage);
864 }
865
866 if (stImage->pt && i < depth) {
867 st_texture_image_unmap(stImage);
868 texImage->Data = st_texture_image_map(ctx->st, stImage, i);
869 dest += dstImageStride;
870 }
871 }
872
873 texImage->Depth = depth;
874
875 /* Unmap */
876 if (stImage->pt) {
877 st_texture_image_unmap(stImage);
878 texImage->Data = NULL;
879 }
880 }
881
882
883 static void
884 st_GetTexImage(GLcontext * ctx, GLenum target, GLint level,
885 GLenum format, GLenum type, GLvoid * pixels,
886 struct gl_texture_object *texObj,
887 struct gl_texture_image *texImage)
888 {
889 st_get_tex_image(ctx, target, level, format, type, pixels,
890 texObj, texImage, 0);
891 }
892
893
894 static void
895 st_GetCompressedTexImage(GLcontext *ctx, GLenum target, GLint level,
896 GLvoid *pixels,
897 const struct gl_texture_object *texObj,
898 const struct gl_texture_image *texImage)
899 {
900 st_get_tex_image(ctx, target, level, 0, 0, pixels,
901 (struct gl_texture_object *) texObj,
902 (struct gl_texture_image *) texImage, 1);
903 }
904
905
906
907 static void
908 st_TexSubimage(GLcontext * ctx,
909 GLint dims,
910 GLenum target, GLint level,
911 GLint xoffset, GLint yoffset, GLint zoffset,
912 GLint width, GLint height, GLint depth,
913 GLenum format, GLenum type, const void *pixels,
914 const struct gl_pixelstore_attrib *packing,
915 struct gl_texture_object *texObj,
916 struct gl_texture_image *texImage)
917 {
918 struct st_texture_image *stImage = st_texture_image(texImage);
919 GLuint dstRowStride;
920 GLuint srcImageStride = _mesa_image_image_stride(packing, width, height,
921 format, type);
922 int i;
923 const GLubyte *src;
924
925 DBG("%s target %s level %d offset %d,%d %dx%d\n", __FUNCTION__,
926 _mesa_lookup_enum_by_nr(target),
927 level, xoffset, yoffset, width, height);
928
929 pixels =
930 _mesa_validate_pbo_teximage(ctx, dims, width, height, depth, format,
931 type, pixels, packing, "glTexSubImage2D");
932 if (!pixels)
933 return;
934
935 /* Map buffer if necessary. Need to lock to prevent other contexts
936 * from uploading the buffer under us.
937 */
938 if (stImage->pt) {
939 texImage->Data = st_texture_image_map(ctx->st, stImage, zoffset);
940 dstRowStride = stImage->surface->pitch * stImage->surface->cpp;
941 }
942
943 src = (const GLubyte *) pixels;
944
945 for (i = 0; i++ < depth;) {
946 if (!texImage->TexFormat->StoreImage(ctx, dims, texImage->_BaseFormat,
947 texImage->TexFormat,
948 texImage->Data,
949 xoffset, yoffset, 0,
950 dstRowStride,
951 texImage->ImageOffsets,
952 width, height, 1,
953 format, type, src, packing)) {
954 _mesa_error(ctx, GL_OUT_OF_MEMORY, "st_TexSubImage");
955 }
956
957 if (stImage->pt && i < depth) {
958 st_texture_image_unmap(stImage);
959 texImage->Data = st_texture_image_map(ctx->st, stImage, zoffset + i);
960 src += srcImageStride;
961 }
962 }
963
964 #if 0
965 /* GL_SGIS_generate_mipmap */
966 if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
967 _mesa_generate_mipmap(ctx, target,
968 &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
969 texObj);
970 }
971 #endif
972
973 _mesa_unmap_teximage_pbo(ctx, packing);
974
975 if (stImage->pt) {
976 st_texture_image_unmap(stImage);
977 texImage->Data = NULL;
978 }
979 }
980
981
982
983 static void
984 st_TexSubImage3D(GLcontext * ctx,
985 GLenum target,
986 GLint level,
987 GLint xoffset, GLint yoffset, GLint zoffset,
988 GLsizei width, GLsizei height, GLsizei depth,
989 GLenum format, GLenum type,
990 const GLvoid * pixels,
991 const struct gl_pixelstore_attrib *packing,
992 struct gl_texture_object *texObj,
993 struct gl_texture_image *texImage)
994 {
995 st_TexSubimage(ctx, 3, target, level,
996 xoffset, yoffset, zoffset,
997 width, height, depth,
998 format, type, pixels, packing, texObj, texImage);
999 }
1000
1001
1002
1003 static void
1004 st_TexSubImage2D(GLcontext * ctx,
1005 GLenum target,
1006 GLint level,
1007 GLint xoffset, GLint yoffset,
1008 GLsizei width, GLsizei height,
1009 GLenum format, GLenum type,
1010 const GLvoid * pixels,
1011 const struct gl_pixelstore_attrib *packing,
1012 struct gl_texture_object *texObj,
1013 struct gl_texture_image *texImage)
1014 {
1015 st_TexSubimage(ctx, 2, target, level,
1016 xoffset, yoffset, 0,
1017 width, height, 1,
1018 format, type, pixels, packing, texObj, texImage);
1019 }
1020
1021
1022 static void
1023 st_TexSubImage1D(GLcontext * ctx,
1024 GLenum target,
1025 GLint level,
1026 GLint xoffset,
1027 GLsizei width,
1028 GLenum format, GLenum type,
1029 const GLvoid * pixels,
1030 const struct gl_pixelstore_attrib *packing,
1031 struct gl_texture_object *texObj,
1032 struct gl_texture_image *texImage)
1033 {
1034 st_TexSubimage(ctx, 1, target, level,
1035 xoffset, 0, 0,
1036 width, 1, 1,
1037 format, type, pixels, packing, texObj, texImage);
1038 }
1039
1040
1041
1042 /**
1043 * Return 0 for GL_TEXTURE_CUBE_MAP_POSITIVE_X,
1044 * 1 for GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
1045 * etc.
1046 * XXX duplicated from main/teximage.c
1047 */
1048 static uint
1049 texture_face(GLenum target)
1050 {
1051 if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
1052 target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB)
1053 return (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X;
1054 else
1055 return 0;
1056 }
1057
1058
1059
1060 /**
1061 * Do a CopyTexSubImage operation by mapping the source surface and
1062 * dest surface and using get_tile()/put_tile() to access the pixels/texels.
1063 *
1064 * Note: srcY=0=TOP of renderbuffer
1065 */
1066 static void
1067 fallback_copy_texsubimage(GLcontext *ctx,
1068 GLenum target,
1069 GLint level,
1070 struct st_renderbuffer *strb,
1071 struct st_texture_image *stImage,
1072 GLenum baseFormat,
1073 GLint destX, GLint destY, GLint destZ,
1074 GLint srcX, GLint srcY,
1075 GLsizei width, GLsizei height)
1076 {
1077 struct pipe_context *pipe = ctx->st->pipe;
1078 const uint face = texture_face(target);
1079 struct pipe_texture *pt = stImage->pt;
1080 struct pipe_surface *src_surf, *dest_surf;
1081 GLfloat *data;
1082 GLint row, yStep;
1083
1084 /* determine bottom-to-top vs. top-to-bottom order */
1085 if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) {
1086 destY = height - 1 - destY;
1087 yStep = -1;
1088 }
1089 else {
1090 yStep = 1;
1091 }
1092
1093 src_surf = strb->surface;
1094
1095 dest_surf = pipe->get_tex_surface(pipe, pt,
1096 face, level, destZ);
1097
1098 (void) pipe_surface_map(dest_surf);
1099 (void) pipe_surface_map(src_surf);
1100
1101 /* buffer for one row */
1102 data = (GLfloat *) malloc(width * 4 * sizeof(GLfloat));
1103
1104 /* do copy row by row */
1105 for (row = 0; row < height; row++) {
1106 pipe->get_tile_rgba(pipe, src_surf, srcX, srcY + row, width, 1, data);
1107
1108 /* XXX we're ignoring convolution for now */
1109 if (ctx->_ImageTransferState) {
1110 _mesa_apply_rgba_transfer_ops(ctx,
1111 ctx->_ImageTransferState & ~IMAGE_CONVOLUTION_BIT,
1112 width, (GLfloat (*)[4])data);
1113 }
1114
1115 pipe->put_tile_rgba(pipe, dest_surf, destX, destY, width, 1, data);
1116 destY += yStep;
1117 }
1118
1119
1120 (void) pipe_surface_unmap(dest_surf);
1121 (void) pipe_surface_unmap(src_surf);
1122
1123 free(data);
1124 }
1125
1126
1127
1128
1129 /**
1130 * Do a CopyTex[Sub]Image using an optimized hardware (blit) path.
1131 * Note that the region to copy has already been clip tested.
1132 *
1133 * Note: srcY=0=Bottom of renderbuffer
1134 *
1135 * \return GL_TRUE if success, GL_FALSE if failure (use a fallback)
1136 */
1137 static void
1138 do_copy_texsubimage(GLcontext *ctx,
1139 GLenum target, GLint level,
1140 GLint destX, GLint destY, GLint destZ,
1141 GLint srcX, GLint srcY,
1142 GLsizei width, GLsizei height)
1143 {
1144 struct gl_texture_unit *texUnit =
1145 &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
1146 struct gl_texture_object *texObj =
1147 _mesa_select_tex_object(ctx, texUnit, target);
1148 struct gl_texture_image *texImage =
1149 _mesa_select_tex_image(ctx, texObj, target, level);
1150 struct st_texture_image *stImage = st_texture_image(texImage);
1151 GLenum baseFormat = texImage->InternalFormat;
1152 struct gl_framebuffer *fb = ctx->ReadBuffer;
1153 struct st_renderbuffer *strb;
1154 struct pipe_context *pipe = ctx->st->pipe;
1155 struct pipe_surface *dest_surface;
1156 uint dest_format, src_format;
1157
1158 (void) texImage;
1159
1160 /* determine if copying depth or color data */
1161 if (baseFormat == GL_DEPTH_COMPONENT) {
1162 strb = st_renderbuffer(fb->_DepthBuffer);
1163 }
1164 else if (baseFormat == GL_DEPTH_STENCIL_EXT) {
1165 strb = st_renderbuffer(fb->_StencilBuffer);
1166 }
1167 else {
1168 /* baseFormat == GL_RGB, GL_RGBA, GL_ALPHA, etc */
1169 strb = st_renderbuffer(fb->_ColorReadBuffer);
1170 }
1171
1172 assert(strb);
1173 assert(strb->surface);
1174 assert(stImage->pt);
1175
1176 if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) {
1177 srcY = strb->Base.Height - srcY - height;
1178 }
1179
1180 src_format = strb->surface->format;
1181 dest_format = stImage->pt->format;
1182
1183 dest_surface = pipe->get_tex_surface(pipe, stImage->pt, stImage->face,
1184 stImage->level, destZ);
1185
1186 if (src_format == dest_format &&
1187 ctx->_ImageTransferState == 0x0 &&
1188 strb->surface->buffer &&
1189 dest_surface->buffer &&
1190 strb->surface->cpp == stImage->pt->cpp) {
1191 /* do blit-style copy */
1192
1193 /* XXX may need to invert image depending on window
1194 * vs. user-created FBO
1195 */
1196
1197 #if 0
1198 /* A bit of fiddling to get the blitter to work with -ve
1199 * pitches. But we get a nice inverted blit this way, so it's
1200 * worth it:
1201 */
1202 intelEmitCopyBlit(intel,
1203 stImage->pt->cpp,
1204 -src->pitch,
1205 src->buffer,
1206 src->height * src->pitch * src->cpp,
1207 stImage->pt->pitch,
1208 stImage->pt->region->buffer,
1209 dest_offset,
1210 x, y + height, dstx, dsty, width, height,
1211 GL_COPY); /* ? */
1212 #else
1213
1214 pipe->surface_copy(pipe,
1215 /* dest */
1216 dest_surface,
1217 destX, destY,
1218 /* src */
1219 strb->surface,
1220 srcX, srcY,
1221 /* size */
1222 width, height);
1223 #endif
1224 }
1225 else {
1226 fallback_copy_texsubimage(ctx, target, level,
1227 strb, stImage, baseFormat,
1228 destX, destY, destZ,
1229 srcX, srcY, width, height);
1230 }
1231
1232 pipe_surface_reference(&dest_surface, NULL);
1233
1234 #if 0
1235 /* GL_SGIS_generate_mipmap -- this can be accelerated now.
1236 * XXX Add a ctx->Driver.GenerateMipmaps() function?
1237 */
1238 if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
1239 intel_generate_mipmap(ctx, target,
1240 &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
1241 texObj);
1242 }
1243 #endif
1244
1245 }
1246
1247
1248
1249 static void
1250 st_CopyTexImage1D(GLcontext * ctx, GLenum target, GLint level,
1251 GLenum internalFormat,
1252 GLint x, GLint y, GLsizei width, GLint border)
1253 {
1254 struct gl_texture_unit *texUnit =
1255 &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
1256 struct gl_texture_object *texObj =
1257 _mesa_select_tex_object(ctx, texUnit, target);
1258 struct gl_texture_image *texImage =
1259 _mesa_select_tex_image(ctx, texObj, target, level);
1260
1261 #if 0
1262 if (border)
1263 goto fail;
1264 #endif
1265
1266 /* Setup or redefine the texture object, texture and texture
1267 * image. Don't populate yet.
1268 */
1269 ctx->Driver.TexImage1D(ctx, target, level, internalFormat,
1270 width, border,
1271 GL_RGBA, CHAN_TYPE, NULL,
1272 &ctx->DefaultPacking, texObj, texImage);
1273
1274 do_copy_texsubimage(ctx, target, level,
1275 0, 0, 0,
1276 x, y, width, 1);
1277 }
1278
1279
1280 static void
1281 st_CopyTexImage2D(GLcontext * ctx, GLenum target, GLint level,
1282 GLenum internalFormat,
1283 GLint x, GLint y, GLsizei width, GLsizei height,
1284 GLint border)
1285 {
1286 struct gl_texture_unit *texUnit =
1287 &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
1288 struct gl_texture_object *texObj =
1289 _mesa_select_tex_object(ctx, texUnit, target);
1290 struct gl_texture_image *texImage =
1291 _mesa_select_tex_image(ctx, texObj, target, level);
1292
1293 #if 0
1294 if (border)
1295 goto fail;
1296 #endif
1297
1298 /* Setup or redefine the texture object, texture and texture
1299 * image. Don't populate yet.
1300 */
1301 ctx->Driver.TexImage2D(ctx, target, level, internalFormat,
1302 width, height, border,
1303 GL_RGBA, CHAN_TYPE, NULL,
1304 &ctx->DefaultPacking, texObj, texImage);
1305
1306
1307 do_copy_texsubimage(ctx, target, level,
1308 0, 0, 0,
1309 x, y, width, height);
1310 }
1311
1312
1313 static void
1314 st_CopyTexSubImage1D(GLcontext * ctx, GLenum target, GLint level,
1315 GLint xoffset, GLint x, GLint y, GLsizei width)
1316 {
1317 const GLint yoffset = 0, zoffset = 0;
1318 const GLsizei height = 1;
1319 do_copy_texsubimage(ctx, target, level,
1320 xoffset, yoffset, zoffset,
1321 x, y, width, height);
1322 }
1323
1324
1325 static void
1326 st_CopyTexSubImage2D(GLcontext * ctx, GLenum target, GLint level,
1327 GLint xoffset, GLint yoffset,
1328 GLint x, GLint y, GLsizei width, GLsizei height)
1329 {
1330 const GLint zoffset = 0;
1331 do_copy_texsubimage(ctx, target, level,
1332 xoffset, yoffset, zoffset,
1333 x, y, width, height);
1334 }
1335
1336
1337 static void
1338 st_CopyTexSubImage3D(GLcontext * ctx, GLenum target, GLint level,
1339 GLint xoffset, GLint yoffset, GLint zoffset,
1340 GLint x, GLint y, GLsizei width, GLsizei height)
1341 {
1342 do_copy_texsubimage(ctx, target, level,
1343 xoffset, yoffset, zoffset,
1344 x, y, width, height);
1345 }
1346
1347
1348
1349
1350 /**
1351 * Compute which mipmap levels that really need to be sent to the hardware.
1352 * This depends on the base image size, GL_TEXTURE_MIN_LOD,
1353 * GL_TEXTURE_MAX_LOD, GL_TEXTURE_BASE_LEVEL, and GL_TEXTURE_MAX_LEVEL.
1354 */
1355 static void
1356 calculate_first_last_level(struct st_texture_object *stObj)
1357 {
1358 struct gl_texture_object *tObj = &stObj->base;
1359 const struct gl_texture_image *const baseImage =
1360 tObj->Image[0][tObj->BaseLevel];
1361
1362 /* These must be signed values. MinLod and MaxLod can be negative numbers,
1363 * and having firstLevel and lastLevel as signed prevents the need for
1364 * extra sign checks.
1365 */
1366 int firstLevel;
1367 int lastLevel;
1368
1369 /* Yes, this looks overly complicated, but it's all needed.
1370 */
1371 switch (tObj->Target) {
1372 case GL_TEXTURE_1D:
1373 case GL_TEXTURE_2D:
1374 case GL_TEXTURE_3D:
1375 case GL_TEXTURE_CUBE_MAP:
1376 if (tObj->MinFilter == GL_NEAREST || tObj->MinFilter == GL_LINEAR) {
1377 /* GL_NEAREST and GL_LINEAR only care about GL_TEXTURE_BASE_LEVEL.
1378 */
1379 firstLevel = lastLevel = tObj->BaseLevel;
1380 }
1381 else {
1382 firstLevel = tObj->BaseLevel + (GLint) (tObj->MinLod + 0.5);
1383 firstLevel = MAX2(firstLevel, tObj->BaseLevel);
1384 lastLevel = tObj->BaseLevel + (GLint) (tObj->MaxLod + 0.5);
1385 lastLevel = MAX2(lastLevel, tObj->BaseLevel);
1386 lastLevel = MIN2(lastLevel, tObj->BaseLevel + baseImage->MaxLog2);
1387 lastLevel = MIN2(lastLevel, tObj->MaxLevel);
1388 lastLevel = MAX2(firstLevel, lastLevel); /* need at least one level */
1389 }
1390 break;
1391 case GL_TEXTURE_RECTANGLE_NV:
1392 case GL_TEXTURE_4D_SGIS:
1393 firstLevel = lastLevel = 0;
1394 break;
1395 default:
1396 return;
1397 }
1398
1399 /* save these values */
1400 stObj->firstLevel = firstLevel;
1401 stObj->lastLevel = lastLevel;
1402 }
1403
1404
1405 static void
1406 copy_image_data_to_texture(struct st_context *st,
1407 struct st_texture_object *stObj,
1408 struct st_texture_image *stImage)
1409 {
1410 if (stImage->pt) {
1411 /* Copy potentially with the blitter:
1412 */
1413 st_texture_image_copy(st->pipe,
1414 stObj->pt, /* dest texture */
1415 stImage->face, stImage->level,
1416 stImage->pt /* src texture */
1417 );
1418
1419 st->pipe->texture_release(st->pipe, &stImage->pt);
1420 }
1421 else {
1422 assert(stImage->base.Data != NULL);
1423
1424 /* More straightforward upload.
1425 */
1426 st_texture_image_data(st->pipe,
1427 stObj->pt,
1428 stImage->face,
1429 stImage->level,
1430 stImage->base.Data,
1431 stImage->base.RowStride,
1432 stImage->base.RowStride *
1433 stImage->base.Height);
1434 _mesa_align_free(stImage->base.Data);
1435 stImage->base.Data = NULL;
1436 }
1437
1438 pipe_texture_reference(st->pipe, &stImage->pt, stObj->pt);
1439 }
1440
1441
1442 /*
1443 */
1444 GLboolean
1445 st_finalize_texture(GLcontext *ctx,
1446 struct pipe_context *pipe, GLuint unit,
1447 GLboolean *needFlush)
1448 {
1449 struct gl_texture_object *tObj = ctx->Texture.Unit[unit]._Current;
1450 struct st_texture_object *stObj = st_texture_object(tObj);
1451 int comp_byte = 0;
1452 int cpp;
1453
1454 GLuint face, i;
1455 GLuint nr_faces = 0;
1456 struct st_texture_image *firstImage;
1457
1458 *needFlush = GL_FALSE;
1459
1460 /* We know/require this is true by now:
1461 */
1462 assert(stObj->base._Complete);
1463
1464 /* What levels must the texture include at a minimum?
1465 */
1466 calculate_first_last_level(stObj);
1467 firstImage =
1468 st_texture_image(stObj->base.Image[0][stObj->firstLevel]);
1469
1470 /* Fallback case:
1471 */
1472 if (firstImage->base.Border) {
1473 if (stObj->pt) {
1474 ctx->st->pipe->texture_release(ctx->st->pipe, &stObj->pt);
1475 }
1476 return GL_FALSE;
1477 }
1478
1479
1480 /* If both firstImage and stObj point to a texture which can contain
1481 * all active images, favour firstImage. Note that because of the
1482 * completeness requirement, we know that the image dimensions
1483 * will match.
1484 */
1485 if (firstImage->pt &&
1486 firstImage->pt != stObj->pt &&
1487 firstImage->pt->first_level <= stObj->firstLevel &&
1488 firstImage->pt->last_level >= stObj->lastLevel) {
1489
1490 if (stObj->pt)
1491 ctx->st->pipe->texture_release(ctx->st->pipe, &stObj->pt);
1492
1493 pipe_texture_reference(ctx->st->pipe, &stObj->pt, firstImage->pt);
1494 }
1495
1496 if (firstImage->base.IsCompressed) {
1497 comp_byte = compressed_num_bytes(firstImage->base.TexFormat->MesaFormat);
1498 cpp = comp_byte;
1499 }
1500 else {
1501 cpp = firstImage->base.TexFormat->TexelBytes;
1502 }
1503
1504 /* Check texture can hold all active levels. Check texture matches
1505 * target, imageFormat, etc.
1506 *
1507 * XXX: For some layouts (eg i945?), the test might have to be
1508 * first_level == firstLevel, as the texture isn't valid except at the
1509 * original start level. Hope to get around this by
1510 * programming minLod, maxLod, baseLevel into the hardware and
1511 * leaving the texture alone.
1512 */
1513 if (stObj->pt &&
1514 (stObj->pt->target != gl_target_to_pipe(stObj->base.Target) ||
1515 stObj->pt->internal_format != firstImage->base.InternalFormat ||
1516 stObj->pt->first_level != stObj->firstLevel ||
1517 stObj->pt->last_level != stObj->lastLevel ||
1518 stObj->pt->width[0] != firstImage->base.Width ||
1519 stObj->pt->height[0] != firstImage->base.Height ||
1520 stObj->pt->depth[0] != firstImage->base.Depth ||
1521 stObj->pt->cpp != cpp ||
1522 stObj->pt->compressed != firstImage->base.IsCompressed)) {
1523 ctx->st->pipe->texture_release(ctx->st->pipe, &stObj->pt);
1524 }
1525
1526
1527 /* May need to create a new texture:
1528 */
1529 if (!stObj->pt) {
1530 stObj->pt = st_texture_create(ctx->st,
1531 gl_target_to_pipe(stObj->base.Target),
1532 st_mesa_format_to_pipe_format(firstImage->base.TexFormat->MesaFormat),
1533 firstImage->base.InternalFormat,
1534 stObj->firstLevel,
1535 stObj->lastLevel,
1536 firstImage->base.Width,
1537 firstImage->base.Height,
1538 firstImage->base.Depth,
1539 comp_byte);
1540 }
1541
1542 /* Pull in any images not in the object's texture:
1543 */
1544 nr_faces = (stObj->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1;
1545 for (face = 0; face < nr_faces; face++) {
1546 for (i = stObj->firstLevel; i <= stObj->lastLevel; i++) {
1547 struct st_texture_image *stImage =
1548 st_texture_image(stObj->base.Image[face][i]);
1549
1550 /* Need to import images in main memory or held in other textures.
1551 */
1552 if (stObj->pt != stImage->pt) {
1553 copy_image_data_to_texture(ctx->st, stObj, stImage);
1554 *needFlush = GL_TRUE;
1555 }
1556 }
1557 }
1558
1559
1560 return GL_TRUE;
1561 }
1562
1563
1564
1565
1566 void
1567 st_init_texture_functions(struct dd_function_table *functions)
1568 {
1569 functions->ChooseTextureFormat = st_ChooseTextureFormat;
1570 functions->TexImage1D = st_TexImage1D;
1571 functions->TexImage2D = st_TexImage2D;
1572 functions->TexImage3D = st_TexImage3D;
1573 functions->TexSubImage1D = st_TexSubImage1D;
1574 functions->TexSubImage2D = st_TexSubImage2D;
1575 functions->TexSubImage3D = st_TexSubImage3D;
1576 functions->CopyTexImage1D = st_CopyTexImage1D;
1577 functions->CopyTexImage2D = st_CopyTexImage2D;
1578 functions->CopyTexSubImage1D = st_CopyTexSubImage1D;
1579 functions->CopyTexSubImage2D = st_CopyTexSubImage2D;
1580 functions->CopyTexSubImage3D = st_CopyTexSubImage3D;
1581
1582 functions->GetTexImage = st_GetTexImage;
1583
1584 /* compressed texture functions */
1585 functions->CompressedTexImage2D = st_CompressedTexImage2D;
1586 functions->GetCompressedTexImage = st_GetCompressedTexImage;
1587
1588 functions->NewTextureObject = st_NewTextureObject;
1589 functions->NewTextureImage = st_NewTextureImage;
1590 functions->DeleteTexture = st_DeleteTextureObject;
1591 functions->FreeTexImageData = st_FreeTextureImageData;
1592 functions->UpdateTexturePalette = 0;
1593 functions->IsTextureResident = st_IsTextureResident;
1594
1595 functions->TextureMemCpy = do_memcpy;
1596
1597 /* XXX Temporary until we can query pipe's texture sizes */
1598 functions->TestProxyTexImage = _mesa_test_proxy_teximage;
1599 }