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