radeon/r200/r300: cleanup some of the renderbuffer code
[mesa.git] / src / mesa / drivers / dri / intel / intel_tex_image.c
1
2 #include <stdlib.h>
3 #include <stdio.h>
4
5 #include "main/glheader.h"
6 #include "main/macros.h"
7 #include "main/mtypes.h"
8 #include "main/enums.h"
9 #include "main/colortab.h"
10 #include "main/convolve.h"
11 #include "main/context.h"
12 #include "main/simple_list.h"
13 #include "main/texcompress.h"
14 #include "main/texformat.h"
15 #include "main/texobj.h"
16 #include "main/texstore.h"
17 #include "main/teximage.h"
18
19 #include "intel_context.h"
20 #include "intel_mipmap_tree.h"
21 #include "intel_buffer_objects.h"
22 #include "intel_batchbuffer.h"
23 #include "intel_tex.h"
24 #include "intel_blit.h"
25 #include "intel_fbo.h"
26
27 #define FILE_DEBUG_FLAG DEBUG_TEXTURE
28
29 /* Functions to store texture images. Where possible, mipmap_tree's
30 * will be created or further instantiated with image data, otherwise
31 * images will be stored in malloc'd memory. A validation step is
32 * required to pull those images into a mipmap tree, or otherwise
33 * decide a fallback is required.
34 */
35
36
37 static int
38 logbase2(int n)
39 {
40 GLint i = 1;
41 GLint log2 = 0;
42
43 while (n > i) {
44 i *= 2;
45 log2++;
46 }
47
48 return log2;
49 }
50
51
52 /* Otherwise, store it in memory if (Border != 0) or (any dimension ==
53 * 1).
54 *
55 * Otherwise, if max_level >= level >= min_level, create tree with
56 * space for textures from min_level down to max_level.
57 *
58 * Otherwise, create tree with space for textures from (level
59 * 0)..(1x1). Consider pruning this tree at a validation if the
60 * saving is worth it.
61 */
62 static void
63 guess_and_alloc_mipmap_tree(struct intel_context *intel,
64 struct intel_texture_object *intelObj,
65 struct intel_texture_image *intelImage)
66 {
67 GLuint firstLevel;
68 GLuint lastLevel;
69 GLuint width = intelImage->base.Width;
70 GLuint height = intelImage->base.Height;
71 GLuint depth = intelImage->base.Depth;
72 GLuint l2width, l2height, l2depth;
73 GLuint i, comp_byte = 0;
74
75 DBG("%s\n", __FUNCTION__);
76
77 if (intelImage->base.Border ||
78 ((intelImage->base._BaseFormat == GL_DEPTH_COMPONENT) &&
79 ((intelObj->base.WrapS == GL_CLAMP_TO_BORDER) ||
80 (intelObj->base.WrapT == GL_CLAMP_TO_BORDER))))
81 return;
82
83 if (intelImage->level > intelObj->base.BaseLevel &&
84 (intelImage->base.Width == 1 ||
85 (intelObj->base.Target != GL_TEXTURE_1D &&
86 intelImage->base.Height == 1) ||
87 (intelObj->base.Target == GL_TEXTURE_3D &&
88 intelImage->base.Depth == 1)))
89 return;
90
91 /* If this image disrespects BaseLevel, allocate from level zero.
92 * Usually BaseLevel == 0, so it's unlikely to happen.
93 */
94 if (intelImage->level < intelObj->base.BaseLevel)
95 firstLevel = 0;
96 else
97 firstLevel = intelObj->base.BaseLevel;
98
99
100 /* Figure out image dimensions at start level.
101 */
102 for (i = intelImage->level; i > firstLevel; i--) {
103 width <<= 1;
104 if (height != 1)
105 height <<= 1;
106 if (depth != 1)
107 depth <<= 1;
108 }
109
110 /* Guess a reasonable value for lastLevel. This is probably going
111 * to be wrong fairly often and might mean that we have to look at
112 * resizable buffers, or require that buffers implement lazy
113 * pagetable arrangements.
114 */
115 if ((intelObj->base.MinFilter == GL_NEAREST ||
116 intelObj->base.MinFilter == GL_LINEAR) &&
117 intelImage->level == firstLevel) {
118 lastLevel = firstLevel;
119 }
120 else {
121 l2width = logbase2(width);
122 l2height = logbase2(height);
123 l2depth = logbase2(depth);
124 lastLevel = firstLevel + MAX2(MAX2(l2width, l2height), l2depth);
125 }
126
127 assert(!intelObj->mt);
128 if (intelImage->base.IsCompressed)
129 comp_byte = intel_compressed_num_bytes(intelImage->base.TexFormat->MesaFormat);
130 intelObj->mt = intel_miptree_create(intel,
131 intelObj->base.Target,
132 intelImage->base.InternalFormat,
133 firstLevel,
134 lastLevel,
135 width,
136 height,
137 depth,
138 intelImage->base.TexFormat->TexelBytes,
139 comp_byte);
140
141 DBG("%s - success\n", __FUNCTION__);
142 }
143
144
145
146
147 static GLuint
148 target_to_face(GLenum target)
149 {
150 switch (target) {
151 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
152 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
153 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
154 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
155 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
156 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
157 return ((GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X);
158 default:
159 return 0;
160 }
161 }
162
163 /* There are actually quite a few combinations this will work for,
164 * more than what I've listed here.
165 */
166 static GLboolean
167 check_pbo_format(GLint internalFormat,
168 GLenum format, GLenum type,
169 const struct gl_texture_format *mesa_format)
170 {
171 switch (internalFormat) {
172 case 4:
173 case GL_RGBA:
174 return (format == GL_BGRA &&
175 (type == GL_UNSIGNED_BYTE ||
176 type == GL_UNSIGNED_INT_8_8_8_8_REV) &&
177 mesa_format == &_mesa_texformat_argb8888);
178 case 3:
179 case GL_RGB:
180 return (format == GL_RGB &&
181 type == GL_UNSIGNED_SHORT_5_6_5 &&
182 mesa_format == &_mesa_texformat_rgb565);
183 case GL_YCBCR_MESA:
184 return (type == GL_UNSIGNED_SHORT_8_8_MESA || type == GL_UNSIGNED_BYTE);
185 default:
186 return GL_FALSE;
187 }
188 }
189
190
191 /* XXX: Do this for TexSubImage also:
192 */
193 static GLboolean
194 try_pbo_upload(struct intel_context *intel,
195 struct intel_texture_image *intelImage,
196 const struct gl_pixelstore_attrib *unpack,
197 GLint internalFormat,
198 GLint width, GLint height,
199 GLenum format, GLenum type, const void *pixels)
200 {
201 struct intel_buffer_object *pbo = intel_buffer_object(unpack->BufferObj);
202 GLuint src_offset, src_stride;
203 GLuint dst_offset, dst_stride;
204
205 if (!pbo ||
206 intel->ctx._ImageTransferState ||
207 unpack->SkipPixels || unpack->SkipRows) {
208 _mesa_printf("%s: failure 1\n", __FUNCTION__);
209 return GL_FALSE;
210 }
211
212 /* note: potential 64-bit ptr to 32-bit int cast */
213 src_offset = (GLuint) (unsigned long) pixels;
214
215 if (unpack->RowLength > 0)
216 src_stride = unpack->RowLength;
217 else
218 src_stride = width;
219
220 dst_offset = intel_miptree_image_offset(intelImage->mt,
221 intelImage->face,
222 intelImage->level);
223
224 dst_stride = intelImage->mt->pitch;
225
226 intelFlush(&intel->ctx);
227 LOCK_HARDWARE(intel);
228 {
229 dri_bo *src_buffer = intel_bufferobj_buffer(intel, pbo, INTEL_READ);
230 dri_bo *dst_buffer = intel_region_buffer(intel,
231 intelImage->mt->region,
232 INTEL_WRITE_FULL);
233
234
235 intelEmitCopyBlit(intel,
236 intelImage->mt->cpp,
237 src_stride, src_buffer, src_offset, GL_FALSE,
238 dst_stride, dst_buffer, dst_offset, GL_FALSE,
239 0, 0, 0, 0, width, height,
240 GL_COPY);
241 }
242 UNLOCK_HARDWARE(intel);
243
244 return GL_TRUE;
245 }
246
247
248
249 static GLboolean
250 try_pbo_zcopy(struct intel_context *intel,
251 struct intel_texture_image *intelImage,
252 const struct gl_pixelstore_attrib *unpack,
253 GLint internalFormat,
254 GLint width, GLint height,
255 GLenum format, GLenum type, const void *pixels)
256 {
257 struct intel_buffer_object *pbo = intel_buffer_object(unpack->BufferObj);
258 GLuint src_offset, src_stride;
259 GLuint dst_offset, dst_stride;
260
261 if (!pbo ||
262 intel->ctx._ImageTransferState ||
263 unpack->SkipPixels || unpack->SkipRows) {
264 _mesa_printf("%s: failure 1\n", __FUNCTION__);
265 return GL_FALSE;
266 }
267
268 /* note: potential 64-bit ptr to 32-bit int cast */
269 src_offset = (GLuint) (unsigned long) pixels;
270
271 if (unpack->RowLength > 0)
272 src_stride = unpack->RowLength;
273 else
274 src_stride = width;
275
276 dst_offset = intel_miptree_image_offset(intelImage->mt,
277 intelImage->face,
278 intelImage->level);
279
280 dst_stride = intelImage->mt->pitch;
281
282 if (src_stride != dst_stride || dst_offset != 0 || src_offset != 0) {
283 _mesa_printf("%s: failure 2\n", __FUNCTION__);
284 return GL_FALSE;
285 }
286
287 intel_region_attach_pbo(intel, intelImage->mt->region, pbo);
288
289 return GL_TRUE;
290 }
291
292
293
294
295
296
297 static void
298 intelTexImage(GLcontext * ctx,
299 GLint dims,
300 GLenum target, GLint level,
301 GLint internalFormat,
302 GLint width, GLint height, GLint depth,
303 GLint border,
304 GLenum format, GLenum type, const void *pixels,
305 const struct gl_pixelstore_attrib *unpack,
306 struct gl_texture_object *texObj,
307 struct gl_texture_image *texImage, GLsizei imageSize, int compressed)
308 {
309 struct intel_context *intel = intel_context(ctx);
310 struct intel_texture_object *intelObj = intel_texture_object(texObj);
311 struct intel_texture_image *intelImage = intel_texture_image(texImage);
312 GLint postConvWidth = width;
313 GLint postConvHeight = height;
314 GLint texelBytes, sizeInBytes;
315 GLuint dstRowStride, srcRowStride = texImage->RowStride;
316
317
318 DBG("%s target %s level %d %dx%dx%d border %d\n", __FUNCTION__,
319 _mesa_lookup_enum_by_nr(target), level, width, height, depth, border);
320
321 intelFlush(ctx);
322
323 intelImage->face = target_to_face(target);
324 intelImage->level = level;
325
326 if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) {
327 _mesa_adjust_image_for_convolution(ctx, dims, &postConvWidth,
328 &postConvHeight);
329 }
330
331 /* choose the texture format */
332 texImage->TexFormat = intelChooseTextureFormat(ctx, internalFormat,
333 format, type);
334
335 _mesa_set_fetch_functions(texImage, dims);
336
337 if (texImage->TexFormat->TexelBytes == 0) {
338 /* must be a compressed format */
339 texelBytes = 0;
340 texImage->IsCompressed = GL_TRUE;
341 texImage->CompressedSize =
342 ctx->Driver.CompressedTextureSize(ctx, texImage->Width,
343 texImage->Height, texImage->Depth,
344 texImage->TexFormat->MesaFormat);
345 } else {
346 texelBytes = texImage->TexFormat->TexelBytes;
347
348 /* Minimum pitch of 32 bytes */
349 if (postConvWidth * texelBytes < 32) {
350 postConvWidth = 32 / texelBytes;
351 texImage->RowStride = postConvWidth;
352 }
353
354 if (!intelImage->mt) {
355 assert(texImage->RowStride == postConvWidth);
356 }
357 }
358
359 /* Release the reference to a potentially orphaned buffer.
360 * Release any old malloced memory.
361 */
362 if (intelImage->mt) {
363 intel_miptree_release(intel, &intelImage->mt);
364 assert(!texImage->Data);
365 }
366 else if (texImage->Data) {
367 _mesa_free_texmemory(texImage->Data);
368 texImage->Data = NULL;
369 }
370
371 /* If this is the only texture image in the tree, could call
372 * bmBufferData with NULL data to free the old block and avoid
373 * waiting on any outstanding fences.
374 */
375 if (intelObj->mt &&
376 intelObj->mt->first_level == level &&
377 intelObj->mt->last_level == level &&
378 intelObj->mt->target != GL_TEXTURE_CUBE_MAP_ARB &&
379 !intel_miptree_match_image(intelObj->mt, &intelImage->base,
380 intelImage->face, intelImage->level)) {
381
382 DBG("release it\n");
383 intel_miptree_release(intel, &intelObj->mt);
384 assert(!intelObj->mt);
385 }
386
387 if (!intelObj->mt) {
388 guess_and_alloc_mipmap_tree(intel, intelObj, intelImage);
389 if (!intelObj->mt) {
390 DBG("guess_and_alloc_mipmap_tree: failed\n");
391 }
392 }
393
394 assert(!intelImage->mt);
395
396 if (intelObj->mt &&
397 intel_miptree_match_image(intelObj->mt, &intelImage->base,
398 intelImage->face, intelImage->level)) {
399
400 intel_miptree_reference(&intelImage->mt, intelObj->mt);
401 assert(intelImage->mt);
402 } else if (intelImage->base.Border == 0) {
403 int comp_byte = 0;
404
405 if (intelImage->base.IsCompressed) {
406 comp_byte =
407 intel_compressed_num_bytes(intelImage->base.TexFormat->MesaFormat);
408 }
409
410 /* Didn't fit in the object miptree, but it's suitable for inclusion in
411 * a miptree, so create one just for our level and store it in the image.
412 * It'll get moved into the object miptree at validate time.
413 */
414 intelImage->mt = intel_miptree_create(intel, target, internalFormat,
415 level, level,
416 width, height, depth,
417 intelImage->base.TexFormat->TexelBytes,
418 comp_byte);
419
420 }
421
422 /* PBO fastpaths:
423 */
424 if (dims <= 2 &&
425 intelImage->mt &&
426 intel_buffer_object(unpack->BufferObj) &&
427 check_pbo_format(internalFormat, format,
428 type, intelImage->base.TexFormat)) {
429
430 DBG("trying pbo upload\n");
431
432 /* Attempt to texture directly from PBO data (zero copy upload).
433 *
434 * Currently disable as it can lead to worse as well as better
435 * performance (in particular when intel_region_cow() is
436 * required).
437 */
438 if (intelObj->mt == intelImage->mt &&
439 intelObj->mt->first_level == level &&
440 intelObj->mt->last_level == level) {
441
442 if (try_pbo_zcopy(intel, intelImage, unpack,
443 internalFormat,
444 width, height, format, type, pixels)) {
445
446 DBG("pbo zcopy upload succeeded\n");
447 return;
448 }
449 }
450
451
452 /* Otherwise, attempt to use the blitter for PBO image uploads.
453 */
454 if (try_pbo_upload(intel, intelImage, unpack,
455 internalFormat,
456 width, height, format, type, pixels)) {
457 DBG("pbo upload succeeded\n");
458 return;
459 }
460
461 DBG("pbo upload failed\n");
462 }
463
464
465
466 /* intelCopyTexImage calls this function with pixels == NULL, with
467 * the expectation that the mipmap tree will be set up but nothing
468 * more will be done. This is where those calls return:
469 */
470 if (compressed) {
471 pixels = _mesa_validate_pbo_compressed_teximage(ctx, imageSize, pixels,
472 unpack,
473 "glCompressedTexImage");
474 } else {
475 pixels = _mesa_validate_pbo_teximage(ctx, dims, width, height, 1,
476 format, type,
477 pixels, unpack, "glTexImage");
478 }
479
480 LOCK_HARDWARE(intel);
481
482 if (intelImage->mt) {
483 texImage->Data = intel_miptree_image_map(intel,
484 intelImage->mt,
485 intelImage->face,
486 intelImage->level,
487 &dstRowStride,
488 intelImage->base.ImageOffsets);
489 texImage->RowStride = dstRowStride / intelImage->mt->cpp;
490 }
491 else {
492 /* Allocate regular memory and store the image there temporarily. */
493 if (texImage->IsCompressed) {
494 sizeInBytes = texImage->CompressedSize;
495 dstRowStride =
496 _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat, width);
497 assert(dims != 3);
498 }
499 else {
500 dstRowStride = postConvWidth * texelBytes;
501 sizeInBytes = depth * dstRowStride * postConvHeight;
502 }
503
504 texImage->Data = _mesa_alloc_texmemory(sizeInBytes);
505 }
506
507 DBG("Upload image %dx%dx%d row_len %d "
508 "pitch %d\n",
509 width, height, depth, width * texelBytes, dstRowStride);
510
511 /* Copy data. Would like to know when it's ok for us to eg. use
512 * the blitter to copy. Or, use the hardware to do the format
513 * conversion and copy:
514 */
515 if (pixels) {
516 if (compressed) {
517 if (intelImage->mt) {
518 struct intel_region *dst = intelImage->mt->region;
519 _mesa_copy_rect(texImage->Data, dst->cpp, dst->pitch,
520 0, 0,
521 intelImage->mt->level[level].width,
522 intelImage->mt->level[level].height/4,
523 pixels,
524 srcRowStride,
525 0, 0);
526 } else
527 memcpy(texImage->Data, pixels, imageSize);
528 } else if (!texImage->TexFormat->StoreImage(ctx, dims,
529 texImage->_BaseFormat,
530 texImage->TexFormat,
531 texImage->Data, 0, 0, 0, /* dstX/Y/Zoffset */
532 dstRowStride,
533 texImage->ImageOffsets,
534 width, height, depth,
535 format, type, pixels, unpack)) {
536 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
537 }
538 }
539
540 /* GL_SGIS_generate_mipmap */
541 if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
542 intel_generate_mipmap(ctx, target, texObj);
543 }
544
545 _mesa_unmap_teximage_pbo(ctx, unpack);
546
547 if (intelImage->mt) {
548 intel_miptree_image_unmap(intel, intelImage->mt);
549 texImage->Data = NULL;
550 }
551
552 UNLOCK_HARDWARE(intel);
553 }
554
555 void
556 intelTexImage3D(GLcontext * ctx,
557 GLenum target, GLint level,
558 GLint internalFormat,
559 GLint width, GLint height, GLint depth,
560 GLint border,
561 GLenum format, GLenum type, const void *pixels,
562 const struct gl_pixelstore_attrib *unpack,
563 struct gl_texture_object *texObj,
564 struct gl_texture_image *texImage)
565 {
566 intelTexImage(ctx, 3, target, level,
567 internalFormat, width, height, depth, border,
568 format, type, pixels, unpack, texObj, texImage, 0, 0);
569 }
570
571
572 void
573 intelTexImage2D(GLcontext * ctx,
574 GLenum target, GLint level,
575 GLint internalFormat,
576 GLint width, GLint height, GLint border,
577 GLenum format, GLenum type, const void *pixels,
578 const struct gl_pixelstore_attrib *unpack,
579 struct gl_texture_object *texObj,
580 struct gl_texture_image *texImage)
581 {
582 intelTexImage(ctx, 2, target, level,
583 internalFormat, width, height, 1, border,
584 format, type, pixels, unpack, texObj, texImage, 0, 0);
585 }
586
587 void
588 intelTexImage1D(GLcontext * ctx,
589 GLenum target, GLint level,
590 GLint internalFormat,
591 GLint width, GLint border,
592 GLenum format, GLenum type, const void *pixels,
593 const struct gl_pixelstore_attrib *unpack,
594 struct gl_texture_object *texObj,
595 struct gl_texture_image *texImage)
596 {
597 intelTexImage(ctx, 1, target, level,
598 internalFormat, width, 1, 1, border,
599 format, type, pixels, unpack, texObj, texImage, 0, 0);
600 }
601
602 void intelCompressedTexImage2D( GLcontext *ctx, GLenum target, GLint level,
603 GLint internalFormat,
604 GLint width, GLint height, GLint border,
605 GLsizei imageSize, const GLvoid *data,
606 struct gl_texture_object *texObj,
607 struct gl_texture_image *texImage )
608 {
609 intelTexImage(ctx, 2, target, level,
610 internalFormat, width, height, 1, border,
611 0, 0, data, &ctx->Unpack, texObj, texImage, imageSize, 1);
612 }
613
614 /**
615 * Need to map texture image into memory before copying image data,
616 * then unmap it.
617 */
618 static void
619 intel_get_tex_image(GLcontext * ctx, GLenum target, GLint level,
620 GLenum format, GLenum type, GLvoid * pixels,
621 struct gl_texture_object *texObj,
622 struct gl_texture_image *texImage, int compressed)
623 {
624 struct intel_context *intel = intel_context(ctx);
625 struct intel_texture_image *intelImage = intel_texture_image(texImage);
626
627 /* Map */
628 if (intelImage->mt) {
629 /* Image is stored in hardware format in a buffer managed by the
630 * kernel. Need to explicitly map and unmap it.
631 */
632 intelImage->base.Data =
633 intel_miptree_image_map(intel,
634 intelImage->mt,
635 intelImage->face,
636 intelImage->level,
637 &intelImage->base.RowStride,
638 intelImage->base.ImageOffsets);
639 intelImage->base.RowStride /= intelImage->mt->cpp;
640 }
641 else {
642 /* Otherwise, the image should actually be stored in
643 * intelImage->base.Data. This is pretty confusing for
644 * everybody, I'd much prefer to separate the two functions of
645 * texImage->Data - storage for texture images in main memory
646 * and access (ie mappings) of images. In other words, we'd
647 * create a new texImage->Map field and leave Data simply for
648 * storage.
649 */
650 assert(intelImage->base.Data);
651 }
652
653
654 if (compressed) {
655 _mesa_get_compressed_teximage(ctx, target, level, pixels,
656 texObj, texImage);
657 } else {
658 _mesa_get_teximage(ctx, target, level, format, type, pixels,
659 texObj, texImage);
660 }
661
662
663 /* Unmap */
664 if (intelImage->mt) {
665 intel_miptree_image_unmap(intel, intelImage->mt);
666 intelImage->base.Data = NULL;
667 }
668 }
669
670 void
671 intelGetTexImage(GLcontext * ctx, GLenum target, GLint level,
672 GLenum format, GLenum type, GLvoid * pixels,
673 struct gl_texture_object *texObj,
674 struct gl_texture_image *texImage)
675 {
676 intel_get_tex_image(ctx, target, level, format, type, pixels,
677 texObj, texImage, 0);
678
679
680 }
681
682 void
683 intelGetCompressedTexImage(GLcontext *ctx, GLenum target, GLint level,
684 GLvoid *pixels,
685 struct gl_texture_object *texObj,
686 struct gl_texture_image *texImage)
687 {
688 intel_get_tex_image(ctx, target, level, 0, 0, pixels,
689 texObj, texImage, 1);
690 }
691
692 void
693 intelSetTexOffset(__DRIcontext *pDRICtx, GLint texname,
694 unsigned long long offset, GLint depth, GLuint pitch)
695 {
696 struct intel_context *intel = pDRICtx->driverPrivate;
697 struct gl_texture_object *tObj = _mesa_lookup_texture(&intel->ctx, texname);
698 struct intel_texture_object *intelObj = intel_texture_object(tObj);
699
700 if (!intelObj)
701 return;
702
703 if (intelObj->mt)
704 intel_miptree_release(intel, &intelObj->mt);
705
706 intelObj->imageOverride = GL_TRUE;
707 intelObj->depthOverride = depth;
708 intelObj->pitchOverride = pitch;
709
710 if (offset)
711 intelObj->textureOffset = offset;
712 }
713
714 void
715 intelSetTexBuffer(__DRIcontext *pDRICtx, GLint target, __DRIdrawable *dPriv)
716 {
717 struct intel_framebuffer *intel_fb = dPriv->driverPrivate;
718 struct intel_context *intel = pDRICtx->driverPrivate;
719 struct intel_texture_object *intelObj;
720 struct intel_texture_image *intelImage;
721 struct intel_mipmap_tree *mt;
722 struct intel_renderbuffer *rb;
723 struct gl_texture_unit *texUnit;
724 struct gl_texture_object *texObj;
725 struct gl_texture_image *texImage;
726 int level = 0, type, format, internalFormat;
727
728 texUnit = &intel->ctx.Texture.Unit[intel->ctx.Texture.CurrentUnit];
729 texObj = _mesa_select_tex_object(&intel->ctx, texUnit, target);
730 intelObj = intel_texture_object(texObj);
731
732 if (!intelObj)
733 return;
734
735 intel_update_renderbuffers(pDRICtx, dPriv);
736
737 rb = intel_fb->color_rb[0];
738 /* If the region isn't set, then intel_update_renderbuffers was unable
739 * to get the buffers for the drawable.
740 */
741 if (rb->region == NULL)
742 return;
743
744 type = GL_BGRA;
745 format = GL_UNSIGNED_BYTE;
746 internalFormat = (rb->region->cpp == 3 ? 3 : 4);
747
748 mt = intel_miptree_create_for_region(intel, target,
749 internalFormat,
750 0, 0, rb->region, 1, 0);
751 if (mt == NULL)
752 return;
753
754 _mesa_lock_texture(&intel->ctx, texObj);
755
756 if (intelObj->mt)
757 intel_miptree_release(intel, &intelObj->mt);
758
759 intelObj->mt = mt;
760 texImage = _mesa_get_tex_image(&intel->ctx, texObj, target, level);
761 _mesa_init_teximage_fields(&intel->ctx, target, texImage,
762 rb->region->width, rb->region->height, 1,
763 0, internalFormat);
764
765 intelImage = intel_texture_image(texImage);
766 intelImage->face = target_to_face(target);
767 intelImage->level = level;
768 texImage->TexFormat = intelChooseTextureFormat(&intel->ctx, internalFormat,
769 type, format);
770 _mesa_set_fetch_functions(texImage, 2);
771 texImage->RowStride = rb->region->pitch;
772 intel_miptree_reference(&intelImage->mt, intelObj->mt);
773
774 if (!intel_miptree_match_image(intelObj->mt, &intelImage->base,
775 intelImage->face, intelImage->level)) {
776 fprintf(stderr, "miptree doesn't match image\n");
777 }
778
779 _mesa_unlock_texture(&intel->ctx, texObj);
780 }