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