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