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