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