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