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