intel_tex_image.c revision 66681b4c8cb1ef16f42c1591298cb30c83bca09b
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#include "main/texstore.h"
18
19#include "intel_context.h"
20#include "intel_mipmap_tree.h"
21#include "intel_buffer_objects.h"
22#include "intel_batchbuffer.h"
23#include "intel_tex.h"
24#include "intel_blit.h"
25#include "intel_fbo.h"
26#include "intel_span.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
38
39/* Otherwise, store it in memory if (Border != 0) or (any dimension ==
40 * 1).
41 *
42 * Otherwise, if max_level >= level >= min_level, create tree with
43 * space for textures from min_level down to max_level.
44 *
45 * Otherwise, create tree with space for textures from (level
46 * 0)..(1x1).  Consider pruning this tree at a validation if the
47 * saving is worth it.
48 */
49struct intel_mipmap_tree *
50intel_miptree_create_for_teximage(struct intel_context *intel,
51				  struct intel_texture_object *intelObj,
52				  struct intel_texture_image *intelImage,
53				  bool expect_accelerated_upload)
54{
55   GLuint firstLevel;
56   GLuint lastLevel;
57   int width, height, depth;
58   GLuint i;
59
60   intel_miptree_get_dimensions_for_image(&intelImage->base.Base,
61                                          &width, &height, &depth);
62
63   DBG("%s\n", __FUNCTION__);
64
65   if (intelImage->base.Base.Border)
66      return NULL;
67
68   if (intelImage->base.Base.Level > intelObj->base.BaseLevel &&
69       (width == 1 ||
70        (intelObj->base.Target != GL_TEXTURE_1D && height == 1) ||
71        (intelObj->base.Target == GL_TEXTURE_3D && 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 gl_context *ctx,
150               struct gl_texture_image *image,
151               const struct gl_pixelstore_attrib *unpack,
152	       GLenum format, GLenum type,
153               GLint width, GLint height, const void *pixels)
154{
155   struct intel_texture_image *intelImage = intel_texture_image(image);
156   struct intel_context *intel = intel_context(ctx);
157   struct intel_buffer_object *pbo = intel_buffer_object(unpack->BufferObj);
158   GLuint src_offset, src_stride;
159   GLuint dst_x, dst_y, dst_stride;
160   drm_intel_bo *dst_buffer, *src_buffer;
161
162   if (!_mesa_is_bufferobj(unpack->BufferObj))
163      return false;
164
165   DBG("trying pbo upload\n");
166
167   if (intel->ctx._ImageTransferState ||
168       unpack->SkipPixels || unpack->SkipRows) {
169      DBG("%s: image transfer\n", __FUNCTION__);
170      return false;
171   }
172
173   if (!check_pbo_format(format, type, intelImage->base.Base.TexFormat)) {
174      DBG("%s: format mismatch (upload to %s with format 0x%x, type 0x%x)\n",
175	  __FUNCTION__, _mesa_get_format_name(intelImage->base.Base.TexFormat),
176	  format, type);
177      return false;
178   }
179
180   ctx->Driver.AllocTextureImageBuffer(ctx, image, image->TexFormat,
181                                       width, height, 1);
182
183   if (!intelImage->mt) {
184      DBG("%s: no miptree\n", __FUNCTION__);
185      return false;
186   }
187
188   dst_buffer = intelImage->mt->region->bo;
189   src_buffer = intel_bufferobj_source(intel, pbo, 64, &src_offset);
190   /* note: potential 64-bit ptr to 32-bit int cast */
191   src_offset += (GLuint) (unsigned long) pixels;
192
193   if (unpack->RowLength > 0)
194      src_stride = unpack->RowLength;
195   else
196      src_stride = width;
197
198   intel_miptree_get_image_offset(intelImage->mt, intelImage->base.Base.Level,
199				  intelImage->base.Base.Face, 0,
200				  &dst_x, &dst_y);
201
202   dst_stride = intelImage->mt->region->pitch;
203
204   if (!intelEmitCopyBlit(intel,
205			  intelImage->mt->cpp,
206			  src_stride, src_buffer,
207			  src_offset, false,
208			  dst_stride, dst_buffer, 0,
209			  intelImage->mt->region->tiling,
210			  0, 0, dst_x, dst_y, width, height,
211			  GL_COPY)) {
212      DBG("%s: blit failed\n", __FUNCTION__);
213      return false;
214   }
215
216   DBG("%s: success\n", __FUNCTION__);
217   return true;
218}
219
220/**
221 * \param scatter Scatter if true. Gather if false.
222 *
223 * \see intel_tex_image_x8z24_scatter
224 * \see intel_tex_image_x8z24_gather
225 */
226static void
227intel_tex_image_s8z24_scattergather(struct intel_context *intel,
228				    struct intel_texture_image *intel_image,
229				    bool scatter)
230{
231   struct gl_context *ctx = &intel->ctx;
232   struct gl_renderbuffer *depth_rb = intel_image->depth_rb;
233   struct gl_renderbuffer *stencil_rb = intel_image->stencil_rb;
234   int w, h, d;
235
236   intel_miptree_get_dimensions_for_image(&intel_image->base.Base, &w, &h, &d);
237   assert(d == 1); /* FINISHME */
238
239   uint32_t depth_row[w];
240   uint8_t stencil_row[w];
241
242   intel_renderbuffer_map(intel, depth_rb);
243   intel_renderbuffer_map(intel, stencil_rb);
244
245   if (scatter) {
246      for (int y = 0; y < h; ++y) {
247	 depth_rb->GetRow(ctx, depth_rb, w, 0, y, depth_row);
248	 for (int x = 0; x < w; ++x) {
249	    stencil_row[x] = depth_row[x] >> 24;
250	 }
251	 stencil_rb->PutRow(ctx, stencil_rb, w, 0, y, stencil_row, NULL);
252      }
253   } else { /* gather */
254      for (int y = 0; y < h; ++y) {
255	 depth_rb->GetRow(ctx, depth_rb, w, 0, y, depth_row);
256	 stencil_rb->GetRow(ctx, stencil_rb, w, 0, y, stencil_row);
257	 for (int x = 0; x < w; ++x) {
258	    uint32_t s8_x24 = stencil_row[x] << 24;
259	    uint32_t x8_z24 = depth_row[x] & 0x00ffffff;
260	    depth_row[x] = s8_x24 | x8_z24;
261	 }
262	 depth_rb->PutRow(ctx, depth_rb, w, 0, y, depth_row, NULL);
263      }
264   }
265
266   intel_renderbuffer_unmap(intel, depth_rb);
267   intel_renderbuffer_unmap(intel, stencil_rb);
268}
269
270/**
271 * Copy the x8 bits from intel_image->depth_rb to intel_image->stencil_rb.
272 */
273void
274intel_tex_image_s8z24_scatter(struct intel_context *intel,
275			      struct intel_texture_image *intel_image)
276{
277   intel_tex_image_s8z24_scattergather(intel, intel_image, true);
278}
279
280/**
281 * Copy the data in intel_image->stencil_rb to the x8 bits in
282 * intel_image->depth_rb.
283 */
284void
285intel_tex_image_s8z24_gather(struct intel_context *intel,
286			     struct intel_texture_image *intel_image)
287{
288   intel_tex_image_s8z24_scattergather(intel, intel_image, false);
289}
290
291bool
292intel_tex_image_s8z24_create_renderbuffers(struct intel_context *intel,
293					   struct intel_texture_image *image)
294{
295   struct gl_context *ctx = &intel->ctx;
296   bool ok = true;
297   int width, height, depth;
298   struct gl_renderbuffer *drb;
299   struct gl_renderbuffer *srb;
300   struct intel_renderbuffer *idrb;
301   struct intel_renderbuffer *isrb;
302
303   intel_miptree_get_dimensions_for_image(&image->base.Base,
304                                          &width, &height, &depth);
305   assert(depth == 1); /* FINISHME */
306
307   assert(intel->has_separate_stencil);
308   assert(image->base.Base.TexFormat == MESA_FORMAT_S8_Z24);
309   assert(image->mt != NULL);
310
311   drb = intel_create_wrapped_renderbuffer(ctx, width, height,
312					   MESA_FORMAT_X8_Z24);
313   srb = intel_create_wrapped_renderbuffer(ctx, width, height,
314					   MESA_FORMAT_S8);
315
316   if (!drb || !srb) {
317      if (drb) {
318	 drb->Delete(drb);
319      }
320      if (srb) {
321	 srb->Delete(srb);
322      }
323      return false;
324   }
325
326   idrb = intel_renderbuffer(drb);
327   isrb = intel_renderbuffer(srb);
328
329   intel_region_reference(&idrb->region, image->mt->region);
330   ok = intel_alloc_renderbuffer_storage(ctx, srb, GL_STENCIL_INDEX8,
331					 width, height);
332
333   if (!ok) {
334      drb->Delete(drb);
335      srb->Delete(srb);
336      return false;
337   }
338
339   intel_renderbuffer_set_draw_offset(idrb, image, 0);
340   intel_renderbuffer_set_draw_offset(isrb, image, 0);
341
342   _mesa_reference_renderbuffer(&image->depth_rb, drb);
343   _mesa_reference_renderbuffer(&image->stencil_rb, srb);
344
345   return true;
346}
347
348static void
349intelTexImage(struct gl_context * ctx,
350              GLint dims,
351              GLenum target, GLint level,
352              GLint internalFormat,
353              GLint width, GLint height, GLint depth,
354              GLint border,
355              GLenum format, GLenum type, const void *pixels,
356              const struct gl_pixelstore_attrib *unpack,
357              struct gl_texture_object *texObj,
358              struct gl_texture_image *texImage, GLsizei imageSize)
359{
360   DBG("%s target %s level %d %dx%dx%d border %d\n", __FUNCTION__,
361       _mesa_lookup_enum_by_nr(target), level, width, height, depth, border);
362
363   /* Attempt to use the blitter for PBO image uploads.
364    */
365   if (dims <= 2 &&
366       try_pbo_upload(ctx, texImage, unpack, format, type,
367		      width, height, pixels)) {
368      return;
369   }
370
371   DBG("%s: upload image %dx%dx%d pixels %p\n",
372       __FUNCTION__, width, height, depth, pixels);
373
374   _mesa_store_teximage3d(ctx, target, level, internalFormat,
375			  width, height, depth, border,
376			  format, type, pixels,
377			  unpack, texObj, texImage);
378}
379
380
381static void
382intelTexImage3D(struct gl_context * ctx,
383                GLenum target, GLint level,
384                GLint internalFormat,
385                GLint width, GLint height, GLint depth,
386                GLint border,
387                GLenum format, GLenum type, const void *pixels,
388                const struct gl_pixelstore_attrib *unpack,
389                struct gl_texture_object *texObj,
390                struct gl_texture_image *texImage)
391{
392   intelTexImage(ctx, 3, target, level,
393                 internalFormat, width, height, depth, border,
394                 format, type, pixels, unpack, texObj, texImage, 0);
395}
396
397
398static void
399intelTexImage2D(struct gl_context * ctx,
400                GLenum target, GLint level,
401                GLint internalFormat,
402                GLint width, GLint height, GLint border,
403                GLenum format, GLenum type, const void *pixels,
404                const struct gl_pixelstore_attrib *unpack,
405                struct gl_texture_object *texObj,
406                struct gl_texture_image *texImage)
407{
408   intelTexImage(ctx, 2, target, level,
409                 internalFormat, width, height, 1, border,
410                 format, type, pixels, unpack, texObj, texImage, 0);
411}
412
413
414static void
415intelTexImage1D(struct gl_context * ctx,
416                GLenum target, GLint level,
417                GLint internalFormat,
418                GLint width, GLint border,
419                GLenum format, GLenum type, const void *pixels,
420                const struct gl_pixelstore_attrib *unpack,
421                struct gl_texture_object *texObj,
422                struct gl_texture_image *texImage)
423{
424   intelTexImage(ctx, 1, target, level,
425                 internalFormat, width, 1, 1, border,
426                 format, type, pixels, unpack, texObj, texImage, 0);
427}
428
429
430/**
431 * Binds a region to a texture image, like it was uploaded by glTexImage2D().
432 *
433 * Used for GLX_EXT_texture_from_pixmap and EGL image extensions,
434 */
435static void
436intel_set_texture_image_region(struct gl_context *ctx,
437			       struct gl_texture_image *image,
438			       struct intel_region *region,
439			       GLenum target,
440			       GLenum internalFormat,
441			       gl_format format)
442{
443   struct intel_context *intel = intel_context(ctx);
444   struct intel_texture_image *intel_image = intel_texture_image(image);
445
446   _mesa_init_teximage_fields(&intel->ctx, target, image,
447			      region->width, region->height, 1,
448			      0, internalFormat, format);
449
450   ctx->Driver.FreeTextureImageBuffer(ctx, image);
451
452   intel_image->mt = intel_miptree_create_for_region(intel, target,
453						     image->TexFormat,
454						     region);
455   if (intel_image->mt == NULL)
456       return;
457
458   intel_image->base.RowStride = region->pitch;
459}
460
461void
462intelSetTexBuffer2(__DRIcontext *pDRICtx, GLint target,
463		   GLint texture_format,
464		   __DRIdrawable *dPriv)
465{
466   struct gl_framebuffer *fb = dPriv->driverPrivate;
467   struct intel_context *intel = pDRICtx->driverPrivate;
468   struct gl_context *ctx = &intel->ctx;
469   struct intel_texture_object *intelObj;
470   struct intel_renderbuffer *rb;
471   struct gl_texture_object *texObj;
472   struct gl_texture_image *texImage;
473   int level = 0, internalFormat;
474   gl_format texFormat;
475
476   texObj = _mesa_get_current_tex_object(ctx, target);
477   intelObj = intel_texture_object(texObj);
478
479   if (!intelObj)
480      return;
481
482   if (dPriv->lastStamp != dPriv->dri2.stamp ||
483       !pDRICtx->driScreenPriv->dri2.useInvalidate)
484      intel_update_renderbuffers(pDRICtx, dPriv);
485
486   rb = intel_get_renderbuffer(fb, BUFFER_FRONT_LEFT);
487   /* If the region isn't set, then intel_update_renderbuffers was unable
488    * to get the buffers for the drawable.
489    */
490   if (rb->region == NULL)
491      return;
492
493   if (texture_format == __DRI_TEXTURE_FORMAT_RGB) {
494      internalFormat = GL_RGB;
495      texFormat = MESA_FORMAT_XRGB8888;
496   }
497   else {
498      internalFormat = GL_RGBA;
499      texFormat = MESA_FORMAT_ARGB8888;
500   }
501
502   _mesa_lock_texture(&intel->ctx, texObj);
503   texImage = _mesa_get_tex_image(ctx, texObj, target, level);
504   intel_set_texture_image_region(ctx, texImage, rb->region, target,
505				  internalFormat, texFormat);
506   _mesa_unlock_texture(&intel->ctx, texObj);
507}
508
509void
510intelSetTexBuffer(__DRIcontext *pDRICtx, GLint target, __DRIdrawable *dPriv)
511{
512   /* The old interface didn't have the format argument, so copy our
513    * implementation's behavior at the time.
514    */
515   intelSetTexBuffer2(pDRICtx, target, __DRI_TEXTURE_FORMAT_RGBA, dPriv);
516}
517
518#if FEATURE_OES_EGL_image
519static void
520intel_image_target_texture_2d(struct gl_context *ctx, GLenum target,
521			      struct gl_texture_object *texObj,
522			      struct gl_texture_image *texImage,
523			      GLeglImageOES image_handle)
524{
525   struct intel_context *intel = intel_context(ctx);
526   __DRIscreen *screen;
527   __DRIimage *image;
528
529   screen = intel->intelScreen->driScrnPriv;
530   image = screen->dri2.image->lookupEGLImage(screen, image_handle,
531					      screen->loaderPrivate);
532   if (image == NULL)
533      return;
534
535   intel_set_texture_image_region(ctx, texImage, image->region,
536				  target, image->internal_format, image->format);
537}
538#endif
539
540void
541intelInitTextureImageFuncs(struct dd_function_table *functions)
542{
543   functions->TexImage1D = intelTexImage1D;
544   functions->TexImage2D = intelTexImage2D;
545   functions->TexImage3D = intelTexImage3D;
546
547#if FEATURE_OES_EGL_image
548   functions->EGLImageTargetTexture2D = intel_image_target_texture_2d;
549#endif
550}
551