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