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