OSDN Git Service

bee8be1fd270c7ab3c587a430f47f468defc8594
[android-x86/external-mesa.git] / src / mesa / drivers / dri / i965 / intel_tex_image.c
1
2 #include "main/macros.h"
3 #include "main/mtypes.h"
4 #include "main/enums.h"
5 #include "main/bufferobj.h"
6 #include "main/context.h"
7 #include "main/formats.h"
8 #include "main/image.h"
9 #include "main/pbo.h"
10 #include "main/renderbuffer.h"
11 #include "main/texcompress.h"
12 #include "main/texgetimage.h"
13 #include "main/texobj.h"
14 #include "main/teximage.h"
15 #include "main/texstore.h"
16
17 #include "drivers/common/meta.h"
18
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_image.h"
26 #include "intel_tiled_memcpy.h"
27 #include "brw_context.h"
28
29 #define FILE_DEBUG_FLAG DEBUG_TEXTURE
30
31 /* Work back from the specified level of the image to the baselevel and create a
32  * miptree of that size.
33  */
34 struct intel_mipmap_tree *
35 intel_miptree_create_for_teximage(struct brw_context *brw,
36                                   struct intel_texture_object *intelObj,
37                                   struct intel_texture_image *intelImage,
38                                   uint32_t layout_flags)
39 {
40    GLuint lastLevel;
41    int width, height, depth;
42    GLuint i;
43
44    intel_get_image_dims(&intelImage->base.Base, &width, &height, &depth);
45
46    DBG("%s\n", __func__);
47
48    /* Figure out image dimensions at start level. */
49    for (i = intelImage->base.Base.Level; i > 0; i--) {
50       width <<= 1;
51       if (height != 1)
52          height <<= 1;
53       if (intelObj->base.Target == GL_TEXTURE_3D)
54          depth <<= 1;
55    }
56
57    /* Guess a reasonable value for lastLevel.  This is probably going
58     * to be wrong fairly often and might mean that we have to look at
59     * resizable buffers, or require that buffers implement lazy
60     * pagetable arrangements.
61     */
62    if ((intelObj->base.Sampler.MinFilter == GL_NEAREST ||
63         intelObj->base.Sampler.MinFilter == GL_LINEAR) &&
64        intelImage->base.Base.Level == 0 &&
65        !intelObj->base.GenerateMipmap) {
66       lastLevel = 0;
67    } else {
68       lastLevel = _mesa_get_tex_max_num_levels(intelObj->base.Target,
69                                                width, height, depth) - 1;
70    }
71
72    return intel_miptree_create(brw,
73                                intelObj->base.Target,
74                                intelImage->base.Base.TexFormat,
75                                0,
76                                lastLevel,
77                                width,
78                                height,
79                                depth,
80                                intelImage->base.Base.NumSamples,
81                                layout_flags | MIPTREE_LAYOUT_TILING_ANY);
82 }
83
84 static void
85 intelTexImage(struct gl_context * ctx,
86               GLuint dims,
87               struct gl_texture_image *texImage,
88               GLenum format, GLenum type, const void *pixels,
89               const struct gl_pixelstore_attrib *unpack)
90 {
91    struct intel_texture_image *intelImage = intel_texture_image(texImage);
92    bool ok;
93
94    bool tex_busy = intelImage->mt && drm_intel_bo_busy(intelImage->mt->bo);
95
96    DBG("%s mesa_format %s target %s format %s type %s level %d %dx%dx%d\n",
97        __func__, _mesa_get_format_name(texImage->TexFormat),
98        _mesa_enum_to_string(texImage->TexObject->Target),
99        _mesa_enum_to_string(format), _mesa_enum_to_string(type),
100        texImage->Level, texImage->Width, texImage->Height, texImage->Depth);
101
102    /* Allocate storage for texture data. */
103    if (!ctx->Driver.AllocTextureImageBuffer(ctx, texImage)) {
104       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage%uD", dims);
105       return;
106    }
107
108    assert(intelImage->mt);
109
110    ok = _mesa_meta_pbo_TexSubImage(ctx, dims, texImage, 0, 0, 0,
111                                    texImage->Width, texImage->Height,
112                                    texImage->Depth,
113                                    format, type, pixels,
114                                    tex_busy, unpack);
115    if (ok)
116       return;
117
118    ok = intel_texsubimage_tiled_memcpy(ctx, dims, texImage,
119                                        0, 0, 0, /*x,y,z offsets*/
120                                        texImage->Width,
121                                        texImage->Height,
122                                        texImage->Depth,
123                                        format, type, pixels, unpack,
124                                        false /*allocate_storage*/);
125    if (ok)
126       return;
127
128    DBG("%s: upload image %dx%dx%d pixels %p\n",
129        __func__, texImage->Width, texImage->Height, texImage->Depth,
130        pixels);
131
132    _mesa_store_teximage(ctx, dims, texImage,
133                         format, type, pixels, unpack);
134 }
135
136
137 /**
138  * Binds a BO to a texture image, as if it was uploaded by glTexImage2D().
139  *
140  * Used for GLX_EXT_texture_from_pixmap and EGL image extensions,
141  */
142 static void
143 intel_set_texture_image_bo(struct gl_context *ctx,
144                            struct gl_texture_image *image,
145                            drm_intel_bo *bo,
146                            GLenum target,
147                            GLenum internalFormat,
148                            mesa_format format,
149                            uint32_t offset,
150                            GLuint width, GLuint height,
151                            GLuint pitch,
152                            GLuint tile_x, GLuint tile_y,
153                            uint32_t layout_flags)
154 {
155    struct brw_context *brw = brw_context(ctx);
156    struct intel_texture_image *intel_image = intel_texture_image(image);
157    struct gl_texture_object *texobj = image->TexObject;
158    struct intel_texture_object *intel_texobj = intel_texture_object(texobj);
159    uint32_t draw_x, draw_y;
160
161    _mesa_init_teximage_fields(&brw->ctx, image,
162                               width, height, 1,
163                               0, internalFormat, format);
164
165    ctx->Driver.FreeTextureImageBuffer(ctx, image);
166
167    intel_image->mt = intel_miptree_create_for_bo(brw, bo, image->TexFormat,
168                                                  0, width, height, 1, pitch,
169                                                  layout_flags);
170    if (intel_image->mt == NULL)
171        return;
172    intel_image->mt->target = target;
173    intel_image->mt->total_width = width;
174    intel_image->mt->total_height = height;
175    intel_image->mt->level[0].slice[0].x_offset = tile_x;
176    intel_image->mt->level[0].slice[0].y_offset = tile_y;
177
178    intel_miptree_get_tile_offsets(intel_image->mt, 0, 0, &draw_x, &draw_y);
179
180    /* From "OES_EGL_image" error reporting. We report GL_INVALID_OPERATION
181     * for EGL images from non-tile aligned sufaces in gen4 hw and earlier which has
182     * trouble resolving back to destination image due to alignment issues.
183     */
184    if (!brw->has_surface_tile_offset &&
185        (draw_x != 0 || draw_y != 0)) {
186       _mesa_error(ctx, GL_INVALID_OPERATION, __func__);
187       intel_miptree_release(&intel_image->mt);
188       return;
189    }
190
191    intel_texobj->needs_validate = true;
192
193    intel_image->mt->offset = offset;
194    assert(pitch % intel_image->mt->cpp == 0);
195    intel_image->base.RowStride = pitch / intel_image->mt->cpp;
196
197    /* Immediately validate the image to the object. */
198    intel_miptree_reference(&intel_texobj->mt, intel_image->mt);
199 }
200
201 void
202 intelSetTexBuffer2(__DRIcontext *pDRICtx, GLint target,
203                    GLint texture_format,
204                    __DRIdrawable *dPriv)
205 {
206    struct gl_framebuffer *fb = dPriv->driverPrivate;
207    struct brw_context *brw = pDRICtx->driverPrivate;
208    struct gl_context *ctx = &brw->ctx;
209    struct intel_renderbuffer *rb;
210    struct gl_texture_object *texObj;
211    struct gl_texture_image *texImage;
212    int level = 0, internalFormat = 0;
213    mesa_format texFormat = MESA_FORMAT_NONE;
214
215    texObj = _mesa_get_current_tex_object(ctx, target);
216
217    if (!texObj)
218       return;
219
220    if (dPriv->lastStamp != dPriv->dri2.stamp ||
221        !pDRICtx->driScreenPriv->dri2.useInvalidate)
222       intel_update_renderbuffers(pDRICtx, dPriv);
223
224    rb = intel_get_renderbuffer(fb, BUFFER_FRONT_LEFT);
225    /* If the miptree isn't set, then intel_update_renderbuffers was unable
226     * to get the BO for the drawable from the window system.
227     */
228    if (!rb || !rb->mt)
229       return;
230
231    if (rb->mt->cpp == 4) {
232       if (texture_format == __DRI_TEXTURE_FORMAT_RGB) {
233          internalFormat = GL_RGB;
234          texFormat = MESA_FORMAT_B8G8R8X8_UNORM;
235       }
236       else {
237          internalFormat = GL_RGBA;
238          texFormat = MESA_FORMAT_B8G8R8A8_UNORM;
239       }
240    } else if (rb->mt->cpp == 2) {
241       internalFormat = GL_RGB;
242       texFormat = MESA_FORMAT_B5G6R5_UNORM;
243    }
244
245    _mesa_lock_texture(&brw->ctx, texObj);
246    texImage = _mesa_get_tex_image(ctx, texObj, target, level);
247    intel_miptree_make_shareable(brw, rb->mt);
248    intel_set_texture_image_bo(ctx, texImage, rb->mt->bo, target,
249                               internalFormat, texFormat, 0,
250                               rb->Base.Base.Width,
251                               rb->Base.Base.Height,
252                               rb->mt->pitch,
253                               0, 0, 0);
254    _mesa_unlock_texture(&brw->ctx, texObj);
255 }
256
257 static GLboolean
258 intel_bind_renderbuffer_tex_image(struct gl_context *ctx,
259                                   struct gl_renderbuffer *rb,
260                                   struct gl_texture_image *image)
261 {
262    struct intel_renderbuffer *irb = intel_renderbuffer(rb);
263    struct intel_texture_image *intel_image = intel_texture_image(image);
264    struct gl_texture_object *texobj = image->TexObject;
265    struct intel_texture_object *intel_texobj = intel_texture_object(texobj);
266
267    /* We can only handle RB allocated with AllocRenderbufferStorage, or
268     * window-system renderbuffers.
269     */
270    assert(!rb->TexImage);
271
272    if (!irb->mt)
273       return false;
274
275    _mesa_lock_texture(ctx, texobj);
276    _mesa_init_teximage_fields(ctx, image,
277                               rb->Width, rb->Height, 1,
278                               0, rb->InternalFormat, rb->Format);
279    image->NumSamples = rb->NumSamples;
280
281    intel_miptree_reference(&intel_image->mt, irb->mt);
282
283    /* Immediately validate the image to the object. */
284    intel_miptree_reference(&intel_texobj->mt, intel_image->mt);
285
286    intel_texobj->needs_validate = true;
287    _mesa_unlock_texture(ctx, texobj);
288
289    return true;
290 }
291
292 void
293 intelSetTexBuffer(__DRIcontext *pDRICtx, GLint target, __DRIdrawable *dPriv)
294 {
295    /* The old interface didn't have the format argument, so copy our
296     * implementation's behavior at the time.
297     */
298    intelSetTexBuffer2(pDRICtx, target, __DRI_TEXTURE_FORMAT_RGBA, dPriv);
299 }
300
301 static void
302 intel_image_target_texture_2d(struct gl_context *ctx, GLenum target,
303                               struct gl_texture_object *texObj,
304                               struct gl_texture_image *texImage,
305                               GLeglImageOES image_handle)
306 {
307    struct brw_context *brw = brw_context(ctx);
308    __DRIscreen *screen;
309    __DRIimage *image;
310
311    screen = brw->intelScreen->driScrnPriv;
312    image = screen->dri2.image->lookupEGLImage(screen, image_handle,
313                                               screen->loaderPrivate);
314    if (image == NULL)
315       return;
316
317    /* We support external textures only for EGLImages created with
318     * EGL_EXT_image_dma_buf_import. We may lift that restriction in the future.
319     */
320    if (target == GL_TEXTURE_EXTERNAL_OES && !image->dma_buf_imported) {
321       _mesa_error(ctx, GL_INVALID_OPERATION,
322             "glEGLImageTargetTexture2DOES(external target is enabled only "
323                "for images created with EGL_EXT_image_dma_buf_import");
324       return;
325    }
326
327    /* Disallow depth/stencil textures: we don't have a way to pass the
328     * separate stencil miptree of a GL_DEPTH_STENCIL texture through.
329     */
330    if (image->has_depthstencil) {
331       _mesa_error(ctx, GL_INVALID_OPERATION, __func__);
332       return;
333    }
334
335    /* Disable creation of the texture's aux buffers because the driver exposes
336     * no EGL API to manage them. That is, there is no API for resolving the aux
337     * buffer's content to the main buffer nor for invalidating the aux buffer's
338     * content.
339     */
340    intel_set_texture_image_bo(ctx, texImage, image->bo,
341                               target, image->internal_format,
342                               image->format, image->offset,
343                               image->width,  image->height,
344                               image->pitch,
345                               image->tile_x, image->tile_y,
346                               MIPTREE_LAYOUT_DISABLE_AUX);
347 }
348
349 /**
350  * \brief A fast path for glGetTexImage.
351  *
352  * \see intel_readpixels_tiled_memcpy()
353  */
354 bool
355 intel_gettexsubimage_tiled_memcpy(struct gl_context *ctx,
356                                   struct gl_texture_image *texImage,
357                                   GLint xoffset, GLint yoffset,
358                                   GLsizei width, GLsizei height,
359                                   GLenum format, GLenum type,
360                                   GLvoid *pixels,
361                                   const struct gl_pixelstore_attrib *packing)
362 {
363    struct brw_context *brw = brw_context(ctx);
364    struct intel_texture_image *image = intel_texture_image(texImage);
365    int dst_pitch;
366
367    /* The miptree's buffer. */
368    drm_intel_bo *bo;
369
370    int error = 0;
371
372    uint32_t cpp;
373    mem_copy_fn mem_copy = NULL;
374
375    /* This fastpath is restricted to specific texture types:
376     * a 2D BGRA, RGBA, L8 or A8 texture. It could be generalized to support
377     * more types.
378     *
379     * FINISHME: The restrictions below on packing alignment and packing row
380     * length are likely unneeded now because we calculate the destination stride
381     * with _mesa_image_row_stride. However, before removing the restrictions
382     * we need tests.
383     */
384    if (!brw->has_llc ||
385        !(type == GL_UNSIGNED_BYTE || type == GL_UNSIGNED_INT_8_8_8_8_REV) ||
386        !(texImage->TexObject->Target == GL_TEXTURE_2D ||
387          texImage->TexObject->Target == GL_TEXTURE_RECTANGLE) ||
388        pixels == NULL ||
389        _mesa_is_bufferobj(packing->BufferObj) ||
390        packing->Alignment > 4 ||
391        packing->SkipPixels > 0 ||
392        packing->SkipRows > 0 ||
393        (packing->RowLength != 0 && packing->RowLength != width) ||
394        packing->SwapBytes ||
395        packing->LsbFirst ||
396        packing->Invert)
397       return false;
398
399    /* We can't handle copying from RGBX or BGRX because the tiled_memcpy
400     * function doesn't set the last channel to 1. Note this checks BaseFormat
401     * rather than TexFormat in case the RGBX format is being simulated with an
402     * RGBA format.
403     */
404    if (texImage->_BaseFormat == GL_RGB)
405       return false;
406
407    if (!intel_get_memcpy(texImage->TexFormat, format, type, &mem_copy, &cpp))
408       return false;
409
410    /* If this is a nontrivial texture view, let another path handle it instead. */
411    if (texImage->TexObject->MinLayer)
412       return false;
413
414    if (!image->mt ||
415        (image->mt->tiling != I915_TILING_X &&
416        image->mt->tiling != I915_TILING_Y)) {
417       /* The algorithm is written only for X- or Y-tiled memory. */
418       return false;
419    }
420
421    /* Since we are going to write raw data to the miptree, we need to resolve
422     * any pending fast color clears before we start.
423     */
424    intel_miptree_resolve_color(brw, image->mt, 0);
425
426    bo = image->mt->bo;
427
428    if (drm_intel_bo_references(brw->batch.bo, bo)) {
429       perf_debug("Flushing before mapping a referenced bo.\n");
430       intel_batchbuffer_flush(brw);
431    }
432
433    error = brw_bo_map(brw, bo, false /* write enable */, "miptree");
434    if (error) {
435       DBG("%s: failed to map bo\n", __func__);
436       return false;
437    }
438
439    dst_pitch = _mesa_image_row_stride(packing, width, format, type);
440
441    DBG("%s: level=%d x,y=(%d,%d) (w,h)=(%d,%d) format=0x%x type=0x%x "
442        "mesa_format=0x%x tiling=%d "
443        "packing=(alignment=%d row_length=%d skip_pixels=%d skip_rows=%d)\n",
444        __func__, texImage->Level, xoffset, yoffset, width, height,
445        format, type, texImage->TexFormat, image->mt->tiling,
446        packing->Alignment, packing->RowLength, packing->SkipPixels,
447        packing->SkipRows);
448
449    int level = texImage->Level + texImage->TexObject->MinLevel;
450
451    /* Adjust x and y offset based on miplevel */
452    xoffset += image->mt->level[level].level_x;
453    yoffset += image->mt->level[level].level_y;
454
455    tiled_to_linear(
456       xoffset * cpp, (xoffset + width) * cpp,
457       yoffset, yoffset + height,
458       pixels - (ptrdiff_t) yoffset * dst_pitch - (ptrdiff_t) xoffset * cpp,
459       bo->virtual,
460       dst_pitch, image->mt->pitch,
461       brw->has_swizzling,
462       image->mt->tiling,
463       mem_copy
464    );
465
466    drm_intel_bo_unmap(bo);
467    return true;
468 }
469
470 static void
471 intel_get_tex_sub_image(struct gl_context *ctx,
472                         GLint xoffset, GLint yoffset, GLint zoffset,
473                         GLsizei width, GLsizei height, GLint depth,
474                         GLenum format, GLenum type, GLvoid *pixels,
475                         struct gl_texture_image *texImage)
476 {
477    struct brw_context *brw = brw_context(ctx);
478    bool ok;
479
480    DBG("%s\n", __func__);
481
482    if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
483       if (_mesa_meta_pbo_GetTexSubImage(ctx, 3, texImage,
484                                         xoffset, yoffset, zoffset,
485                                         width, height, depth, format, type,
486                                         pixels, &ctx->Pack)) {
487          /* Flush to guarantee coherency between the render cache and other
488           * caches the PBO could potentially be bound to after this point.
489           * See the related comment in intelReadPixels() for a more detailed
490           * explanation.
491           */
492          brw_emit_mi_flush(brw);
493          return;
494       }
495
496       perf_debug("%s: fallback to CPU mapping in PBO case\n", __func__);
497    }
498
499    ok = intel_gettexsubimage_tiled_memcpy(ctx, texImage, xoffset, yoffset,
500                                           width, height,
501                                           format, type, pixels, &ctx->Pack);
502
503    if(ok)
504       return;
505
506    _mesa_meta_GetTexSubImage(ctx, xoffset, yoffset, zoffset,
507                              width, height, depth,
508                              format, type, pixels, texImage);
509
510    DBG("%s - DONE\n", __func__);
511 }
512
513 void
514 intelInitTextureImageFuncs(struct dd_function_table *functions)
515 {
516    functions->TexImage = intelTexImage;
517    functions->EGLImageTargetTexture2D = intel_image_target_texture_2d;
518    functions->BindRenderbufferTexImage = intel_bind_renderbuffer_tex_image;
519    functions->GetTexSubImage = intel_get_tex_sub_image;
520 }