intel_tex_image.c revision 4ad8a0adec588b4c2c5a8f93265ed46cee5d3ff6
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/texgetimage.h" 14#include "main/texobj.h" 15#include "main/teximage.h" 16#include "main/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_blit.h" 24#include "intel_fbo.h" 25#include "intel_span.h" 26 27#define FILE_DEBUG_FLAG DEBUG_TEXTURE 28 29/* Work back from the specified level of the image to the baselevel and create a 30 * miptree of that size. 31 */ 32struct intel_mipmap_tree * 33intel_miptree_create_for_teximage(struct intel_context *intel, 34 struct intel_texture_object *intelObj, 35 struct intel_texture_image *intelImage, 36 bool expect_accelerated_upload) 37{ 38 GLuint firstLevel; 39 GLuint lastLevel; 40 int width, height, depth; 41 GLuint i; 42 43 intel_miptree_get_dimensions_for_image(&intelImage->base.Base, 44 &width, &height, &depth); 45 46 DBG("%s\n", __FUNCTION__); 47 48 if (intelImage->base.Base.Level > intelObj->base.BaseLevel && 49 (width == 1 || 50 (intelObj->base.Target != GL_TEXTURE_1D && height == 1) || 51 (intelObj->base.Target == GL_TEXTURE_3D && depth == 1))) { 52 /* For this combination, we're at some lower mipmap level and 53 * some important dimension is 1. We can't extrapolate up to a 54 * likely base level width/height/depth for a full mipmap stack 55 * from this info, so just allocate this one level. 56 */ 57 firstLevel = intelImage->base.Base.Level; 58 lastLevel = intelImage->base.Base.Level; 59 } else { 60 /* If this image disrespects BaseLevel, allocate from level zero. 61 * Usually BaseLevel == 0, so it's unlikely to happen. 62 */ 63 if (intelImage->base.Base.Level < intelObj->base.BaseLevel) 64 firstLevel = 0; 65 else 66 firstLevel = intelObj->base.BaseLevel; 67 68 /* Figure out image dimensions at start level. */ 69 for (i = intelImage->base.Base.Level; i > firstLevel; i--) { 70 width <<= 1; 71 if (height != 1) 72 height <<= 1; 73 if (depth != 1) 74 depth <<= 1; 75 } 76 77 /* Guess a reasonable value for lastLevel. This is probably going 78 * to be wrong fairly often and might mean that we have to look at 79 * resizable buffers, or require that buffers implement lazy 80 * pagetable arrangements. 81 */ 82 if ((intelObj->base.Sampler.MinFilter == GL_NEAREST || 83 intelObj->base.Sampler.MinFilter == GL_LINEAR) && 84 intelImage->base.Base.Level == firstLevel && 85 (intel->gen < 4 || firstLevel == 0)) { 86 lastLevel = firstLevel; 87 } else { 88 lastLevel = firstLevel + _mesa_logbase2(MAX2(MAX2(width, height), depth)); 89 } 90 } 91 92 return intel_miptree_create(intel, 93 intelObj->base.Target, 94 intelImage->base.Base.TexFormat, 95 firstLevel, 96 lastLevel, 97 width, 98 height, 99 depth, 100 expect_accelerated_upload); 101} 102 103/* There are actually quite a few combinations this will work for, 104 * more than what I've listed here. 105 */ 106static bool 107check_pbo_format(GLenum format, GLenum type, 108 gl_format mesa_format) 109{ 110 switch (mesa_format) { 111 case MESA_FORMAT_ARGB8888: 112 return (format == GL_BGRA && (type == GL_UNSIGNED_BYTE || 113 type == GL_UNSIGNED_INT_8_8_8_8_REV)); 114 case MESA_FORMAT_RGB565: 115 return (format == GL_RGB && type == GL_UNSIGNED_SHORT_5_6_5); 116 case MESA_FORMAT_L8: 117 return (format == GL_LUMINANCE && type == GL_UNSIGNED_BYTE); 118 case MESA_FORMAT_YCBCR: 119 return (type == GL_UNSIGNED_SHORT_8_8_MESA || type == GL_UNSIGNED_BYTE); 120 default: 121 return false; 122 } 123} 124 125 126/* XXX: Do this for TexSubImage also: 127 */ 128static bool 129try_pbo_upload(struct gl_context *ctx, 130 struct gl_texture_image *image, 131 const struct gl_pixelstore_attrib *unpack, 132 GLenum format, GLenum type, 133 GLint width, GLint height, const void *pixels) 134{ 135 struct intel_texture_image *intelImage = intel_texture_image(image); 136 struct intel_context *intel = intel_context(ctx); 137 struct intel_buffer_object *pbo = intel_buffer_object(unpack->BufferObj); 138 GLuint src_offset, src_stride; 139 GLuint dst_x, dst_y, dst_stride; 140 drm_intel_bo *dst_buffer, *src_buffer; 141 142 if (!_mesa_is_bufferobj(unpack->BufferObj)) 143 return false; 144 145 DBG("trying pbo upload\n"); 146 147 if (intel->ctx._ImageTransferState || 148 unpack->SkipPixels || unpack->SkipRows) { 149 DBG("%s: image transfer\n", __FUNCTION__); 150 return false; 151 } 152 153 if (!check_pbo_format(format, type, intelImage->base.Base.TexFormat)) { 154 DBG("%s: format mismatch (upload to %s with format 0x%x, type 0x%x)\n", 155 __FUNCTION__, _mesa_get_format_name(intelImage->base.Base.TexFormat), 156 format, type); 157 return false; 158 } 159 160 ctx->Driver.AllocTextureImageBuffer(ctx, image, image->TexFormat, 161 width, height, 1); 162 163 if (!intelImage->mt) { 164 DBG("%s: no miptree\n", __FUNCTION__); 165 return false; 166 } 167 168 dst_buffer = intelImage->mt->region->bo; 169 src_buffer = intel_bufferobj_source(intel, pbo, 64, &src_offset); 170 /* note: potential 64-bit ptr to 32-bit int cast */ 171 src_offset += (GLuint) (unsigned long) pixels; 172 173 if (unpack->RowLength > 0) 174 src_stride = unpack->RowLength; 175 else 176 src_stride = width; 177 178 intel_miptree_get_image_offset(intelImage->mt, intelImage->base.Base.Level, 179 intelImage->base.Base.Face, 0, 180 &dst_x, &dst_y); 181 182 dst_stride = intelImage->mt->region->pitch; 183 184 if (!intelEmitCopyBlit(intel, 185 intelImage->mt->cpp, 186 src_stride, src_buffer, 187 src_offset, false, 188 dst_stride, dst_buffer, 0, 189 intelImage->mt->region->tiling, 190 0, 0, dst_x, dst_y, width, height, 191 GL_COPY)) { 192 DBG("%s: blit failed\n", __FUNCTION__); 193 return false; 194 } 195 196 DBG("%s: success\n", __FUNCTION__); 197 return true; 198} 199 200/** 201 * \param scatter Scatter if true. Gather if false. 202 * 203 * \see intel_tex_image_x8z24_scatter 204 * \see intel_tex_image_x8z24_gather 205 */ 206static void 207intel_tex_image_s8z24_scattergather(struct intel_context *intel, 208 struct intel_texture_image *intel_image, 209 bool scatter) 210{ 211 struct gl_context *ctx = &intel->ctx; 212 struct gl_renderbuffer *depth_rb = intel_image->depth_rb; 213 struct gl_renderbuffer *stencil_rb = intel_image->stencil_rb; 214 int w, h, d; 215 216 intel_miptree_get_dimensions_for_image(&intel_image->base.Base, &w, &h, &d); 217 assert(d == 1); /* FINISHME */ 218 219 uint32_t depth_row[w]; 220 uint8_t stencil_row[w]; 221 222 intel_renderbuffer_map(intel, depth_rb); 223 intel_renderbuffer_map(intel, stencil_rb); 224 225 if (scatter) { 226 for (int y = 0; y < h; ++y) { 227 depth_rb->GetRow(ctx, depth_rb, w, 0, y, depth_row); 228 for (int x = 0; x < w; ++x) { 229 stencil_row[x] = depth_row[x] >> 24; 230 } 231 stencil_rb->PutRow(ctx, stencil_rb, w, 0, y, stencil_row, NULL); 232 } 233 } else { /* gather */ 234 for (int y = 0; y < h; ++y) { 235 depth_rb->GetRow(ctx, depth_rb, w, 0, y, depth_row); 236 stencil_rb->GetRow(ctx, stencil_rb, w, 0, y, stencil_row); 237 for (int x = 0; x < w; ++x) { 238 uint32_t s8_x24 = stencil_row[x] << 24; 239 uint32_t x8_z24 = depth_row[x] & 0x00ffffff; 240 depth_row[x] = s8_x24 | x8_z24; 241 } 242 depth_rb->PutRow(ctx, depth_rb, w, 0, y, depth_row, NULL); 243 } 244 } 245 246 intel_renderbuffer_unmap(intel, depth_rb); 247 intel_renderbuffer_unmap(intel, stencil_rb); 248} 249 250/** 251 * Copy the x8 bits from intel_image->depth_rb to intel_image->stencil_rb. 252 */ 253void 254intel_tex_image_s8z24_scatter(struct intel_context *intel, 255 struct intel_texture_image *intel_image) 256{ 257 intel_tex_image_s8z24_scattergather(intel, intel_image, true); 258} 259 260/** 261 * Copy the data in intel_image->stencil_rb to the x8 bits in 262 * intel_image->depth_rb. 263 */ 264void 265intel_tex_image_s8z24_gather(struct intel_context *intel, 266 struct intel_texture_image *intel_image) 267{ 268 intel_tex_image_s8z24_scattergather(intel, intel_image, false); 269} 270 271bool 272intel_tex_image_s8z24_create_renderbuffers(struct intel_context *intel, 273 struct intel_texture_image *image) 274{ 275 struct gl_context *ctx = &intel->ctx; 276 bool ok = true; 277 int width, height, depth; 278 struct gl_renderbuffer *drb; 279 struct gl_renderbuffer *srb; 280 struct intel_renderbuffer *idrb; 281 struct intel_renderbuffer *isrb; 282 283 intel_miptree_get_dimensions_for_image(&image->base.Base, 284 &width, &height, &depth); 285 assert(depth == 1); /* FINISHME */ 286 287 assert(intel->has_separate_stencil); 288 assert(image->base.Base.TexFormat == MESA_FORMAT_S8_Z24); 289 assert(image->mt != NULL); 290 291 drb = intel_create_wrapped_renderbuffer(ctx, width, height, 292 MESA_FORMAT_X8_Z24); 293 srb = intel_create_wrapped_renderbuffer(ctx, width, height, 294 MESA_FORMAT_S8); 295 296 if (!drb || !srb) { 297 if (drb) { 298 drb->Delete(drb); 299 } 300 if (srb) { 301 srb->Delete(srb); 302 } 303 return false; 304 } 305 306 idrb = intel_renderbuffer(drb); 307 isrb = intel_renderbuffer(srb); 308 309 intel_region_reference(&idrb->region, image->mt->region); 310 ok = intel_alloc_renderbuffer_storage(ctx, srb, GL_STENCIL_INDEX8, 311 width, height); 312 313 if (!ok) { 314 drb->Delete(drb); 315 srb->Delete(srb); 316 return false; 317 } 318 319 intel_renderbuffer_set_draw_offset(idrb, image, 0); 320 intel_renderbuffer_set_draw_offset(isrb, image, 0); 321 322 _mesa_reference_renderbuffer(&image->depth_rb, drb); 323 _mesa_reference_renderbuffer(&image->stencil_rb, srb); 324 325 return true; 326} 327 328static void 329intelTexImage(struct gl_context * ctx, 330 GLint dims, 331 GLenum target, GLint level, 332 GLint internalFormat, 333 GLint width, GLint height, GLint depth, 334 GLenum format, GLenum type, const void *pixels, 335 const struct gl_pixelstore_attrib *unpack, 336 struct gl_texture_object *texObj, 337 struct gl_texture_image *texImage, GLsizei imageSize) 338{ 339 DBG("%s target %s level %d %dx%dx%d\n", __FUNCTION__, 340 _mesa_lookup_enum_by_nr(target), level, width, height, depth); 341 342 /* Attempt to use the blitter for PBO image uploads. 343 */ 344 if (dims <= 2 && 345 try_pbo_upload(ctx, texImage, unpack, format, type, 346 width, height, pixels)) { 347 return; 348 } 349 350 DBG("%s: upload image %dx%dx%d pixels %p\n", 351 __FUNCTION__, width, height, depth, pixels); 352 353 _mesa_store_teximage3d(ctx, target, level, internalFormat, 354 width, height, depth, 0, 355 format, type, pixels, 356 unpack, texObj, texImage); 357} 358 359 360static void 361intelTexImage3D(struct gl_context * ctx, 362 GLenum target, GLint level, 363 GLint internalFormat, 364 GLint width, GLint height, GLint depth, 365 GLint border, 366 GLenum format, GLenum type, const void *pixels, 367 const struct gl_pixelstore_attrib *unpack, 368 struct gl_texture_object *texObj, 369 struct gl_texture_image *texImage) 370{ 371 intelTexImage(ctx, 3, target, level, 372 internalFormat, width, height, depth, 373 format, type, pixels, unpack, texObj, texImage, 0); 374} 375 376 377static void 378intelTexImage2D(struct gl_context * ctx, 379 GLenum target, GLint level, 380 GLint internalFormat, 381 GLint width, GLint height, GLint border, 382 GLenum format, GLenum type, const void *pixels, 383 const struct gl_pixelstore_attrib *unpack, 384 struct gl_texture_object *texObj, 385 struct gl_texture_image *texImage) 386{ 387 intelTexImage(ctx, 2, target, level, 388 internalFormat, width, height, 1, 389 format, type, pixels, unpack, texObj, texImage, 0); 390} 391 392 393static void 394intelTexImage1D(struct gl_context * ctx, 395 GLenum target, GLint level, 396 GLint internalFormat, 397 GLint width, GLint border, 398 GLenum format, GLenum type, const void *pixels, 399 const struct gl_pixelstore_attrib *unpack, 400 struct gl_texture_object *texObj, 401 struct gl_texture_image *texImage) 402{ 403 intelTexImage(ctx, 1, target, level, 404 internalFormat, width, 1, 1, 405 format, type, pixels, unpack, texObj, texImage, 0); 406} 407 408 409/** 410 * Binds a region to a texture image, like it was uploaded by glTexImage2D(). 411 * 412 * Used for GLX_EXT_texture_from_pixmap and EGL image extensions, 413 */ 414static void 415intel_set_texture_image_region(struct gl_context *ctx, 416 struct gl_texture_image *image, 417 struct intel_region *region, 418 GLenum target, 419 GLenum internalFormat, 420 gl_format format) 421{ 422 struct intel_context *intel = intel_context(ctx); 423 struct intel_texture_image *intel_image = intel_texture_image(image); 424 425 _mesa_init_teximage_fields(&intel->ctx, target, image, 426 region->width, region->height, 1, 427 0, internalFormat, format); 428 429 ctx->Driver.FreeTextureImageBuffer(ctx, image); 430 431 intel_image->mt = intel_miptree_create_for_region(intel, target, 432 image->TexFormat, 433 region); 434 if (intel_image->mt == NULL) 435 return; 436 437 intel_image->base.RowStride = region->pitch; 438} 439 440void 441intelSetTexBuffer2(__DRIcontext *pDRICtx, GLint target, 442 GLint texture_format, 443 __DRIdrawable *dPriv) 444{ 445 struct gl_framebuffer *fb = dPriv->driverPrivate; 446 struct intel_context *intel = pDRICtx->driverPrivate; 447 struct gl_context *ctx = &intel->ctx; 448 struct intel_texture_object *intelObj; 449 struct intel_renderbuffer *rb; 450 struct gl_texture_object *texObj; 451 struct gl_texture_image *texImage; 452 int level = 0, internalFormat; 453 gl_format texFormat; 454 455 texObj = _mesa_get_current_tex_object(ctx, target); 456 intelObj = intel_texture_object(texObj); 457 458 if (!intelObj) 459 return; 460 461 if (dPriv->lastStamp != dPriv->dri2.stamp || 462 !pDRICtx->driScreenPriv->dri2.useInvalidate) 463 intel_update_renderbuffers(pDRICtx, dPriv); 464 465 rb = intel_get_renderbuffer(fb, BUFFER_FRONT_LEFT); 466 /* If the region isn't set, then intel_update_renderbuffers was unable 467 * to get the buffers for the drawable. 468 */ 469 if (rb->region == NULL) 470 return; 471 472 if (texture_format == __DRI_TEXTURE_FORMAT_RGB) { 473 internalFormat = GL_RGB; 474 texFormat = MESA_FORMAT_XRGB8888; 475 } 476 else { 477 internalFormat = GL_RGBA; 478 texFormat = MESA_FORMAT_ARGB8888; 479 } 480 481 _mesa_lock_texture(&intel->ctx, texObj); 482 texImage = _mesa_get_tex_image(ctx, texObj, target, level); 483 intel_set_texture_image_region(ctx, texImage, rb->region, target, 484 internalFormat, texFormat); 485 _mesa_unlock_texture(&intel->ctx, texObj); 486} 487 488void 489intelSetTexBuffer(__DRIcontext *pDRICtx, GLint target, __DRIdrawable *dPriv) 490{ 491 /* The old interface didn't have the format argument, so copy our 492 * implementation's behavior at the time. 493 */ 494 intelSetTexBuffer2(pDRICtx, target, __DRI_TEXTURE_FORMAT_RGBA, dPriv); 495} 496 497#if FEATURE_OES_EGL_image 498static void 499intel_image_target_texture_2d(struct gl_context *ctx, GLenum target, 500 struct gl_texture_object *texObj, 501 struct gl_texture_image *texImage, 502 GLeglImageOES image_handle) 503{ 504 struct intel_context *intel = intel_context(ctx); 505 __DRIscreen *screen; 506 __DRIimage *image; 507 508 screen = intel->intelScreen->driScrnPriv; 509 image = screen->dri2.image->lookupEGLImage(screen, image_handle, 510 screen->loaderPrivate); 511 if (image == NULL) 512 return; 513 514 intel_set_texture_image_region(ctx, texImage, image->region, 515 target, image->internal_format, image->format); 516} 517#endif 518 519void 520intelInitTextureImageFuncs(struct dd_function_table *functions) 521{ 522 functions->TexImage1D = intelTexImage1D; 523 functions->TexImage2D = intelTexImage2D; 524 functions->TexImage3D = intelTexImage3D; 525 526#if FEATURE_OES_EGL_image 527 functions->EGLImageTargetTexture2D = intel_image_target_texture_2d; 528#endif 529} 530