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