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