Tizen 2.1 base
[sdk/emulator/qemu.git] / gl / mesa / src / mesa / drivers / dri / intel / intel_fbo.c
1 /**************************************************************************
2  * 
3  * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas.
4  * All Rights Reserved.
5  * 
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the
8  * "Software"), to deal in the Software without restriction, including
9  * without limitation the rights to use, copy, modify, merge, publish,
10  * distribute, sub license, and/or sell copies of the Software, and to
11  * permit persons to whom the Software is furnished to do so, subject to
12  * the following conditions:
13  * 
14  * The above copyright notice and this permission notice (including the
15  * next paragraph) shall be included in all copies or substantial portions
16  * of the Software.
17  * 
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21  * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25  * 
26  **************************************************************************/
27
28
29 #include "main/enums.h"
30 #include "main/imports.h"
31 #include "main/macros.h"
32 #include "main/mfeatures.h"
33 #include "main/mtypes.h"
34 #include "main/fbobject.h"
35 #include "main/framebuffer.h"
36 #include "main/renderbuffer.h"
37 #include "main/context.h"
38 #include "main/teximage.h"
39 #include "main/image.h"
40
41 #include "swrast/swrast.h"
42 #include "drivers/common/meta.h"
43
44 #include "intel_context.h"
45 #include "intel_batchbuffer.h"
46 #include "intel_buffers.h"
47 #include "intel_blit.h"
48 #include "intel_fbo.h"
49 #include "intel_mipmap_tree.h"
50 #include "intel_regions.h"
51 #include "intel_tex.h"
52 #include "intel_span.h"
53 #ifndef I915
54 #include "brw_context.h"
55 #endif
56
57 #define FILE_DEBUG_FLAG DEBUG_FBO
58
59 static struct gl_renderbuffer *
60 intel_new_renderbuffer(struct gl_context * ctx, GLuint name);
61
62 bool
63 intel_framebuffer_has_hiz(struct gl_framebuffer *fb)
64 {
65    struct intel_renderbuffer *rb = NULL;
66    if (fb)
67       rb = intel_get_renderbuffer(fb, BUFFER_DEPTH);
68    return rb && rb->mt && rb->mt->hiz_mt;
69 }
70
71 struct intel_region*
72 intel_get_rb_region(struct gl_framebuffer *fb, GLuint attIndex)
73 {
74    struct intel_renderbuffer *irb = intel_get_renderbuffer(fb, attIndex);
75    if (irb && irb->mt) {
76       if (attIndex == BUFFER_STENCIL && irb->mt->stencil_mt)
77          return irb->mt->stencil_mt->region;
78       else
79          return irb->mt->region;
80    } else
81       return NULL;
82 }
83
84 /**
85  * Create a new framebuffer object.
86  */
87 static struct gl_framebuffer *
88 intel_new_framebuffer(struct gl_context * ctx, GLuint name)
89 {
90    /* Only drawable state in intel_framebuffer at this time, just use Mesa's
91     * class
92     */
93    return _mesa_new_framebuffer(ctx, name);
94 }
95
96
97 /** Called by gl_renderbuffer::Delete() */
98 static void
99 intel_delete_renderbuffer(struct gl_renderbuffer *rb)
100 {
101    struct intel_renderbuffer *irb = intel_renderbuffer(rb);
102
103    ASSERT(irb);
104
105    intel_miptree_release(&irb->mt);
106
107    free(irb);
108 }
109
110 /**
111  * \see dd_function_table::MapRenderbuffer
112  */
113 static void
114 intel_map_renderbuffer(struct gl_context *ctx,
115                        struct gl_renderbuffer *rb,
116                        GLuint x, GLuint y, GLuint w, GLuint h,
117                        GLbitfield mode,
118                        GLubyte **out_map,
119                        GLint *out_stride)
120 {
121    struct intel_context *intel = intel_context(ctx);
122    struct swrast_renderbuffer *srb = (struct swrast_renderbuffer *)rb;
123    struct intel_renderbuffer *irb = intel_renderbuffer(rb);
124    void *map;
125    int stride;
126
127    if (srb->Buffer) {
128       /* this is a malloc'd renderbuffer (accum buffer), not an irb */
129       GLint bpp = _mesa_get_format_bytes(rb->Format);
130       GLint rowStride = srb->RowStride;
131       *out_map = (GLubyte *) srb->Buffer + y * rowStride + x * bpp;
132       *out_stride = rowStride;
133       return;
134    }
135
136    /* We sometimes get called with this by our intel_span.c usage. */
137    if (!irb->mt) {
138       *out_map = NULL;
139       *out_stride = 0;
140       return;
141    }
142
143    /* For a window-system renderbuffer, we need to flip the mapping we receive
144     * upside-down.  So we need to ask for a rectangle on flipped vertically, and
145     * we then return a pointer to the bottom of it with a negative stride.
146     */
147    if (rb->Name == 0) {
148       y = rb->Height - y - h;
149    }
150
151    intel_miptree_map(intel, irb->mt, irb->mt_level, irb->mt_layer,
152                      x, y, w, h, mode, &map, &stride);
153
154    if (rb->Name == 0) {
155       map += (h - 1) * stride;
156       stride = -stride;
157    }
158
159    DBG("%s: rb %d (%s) mt mapped: (%d, %d) (%dx%d) -> %p/%d\n",
160        __FUNCTION__, rb->Name, _mesa_get_format_name(rb->Format),
161        x, y, w, h, map, stride);
162
163    *out_map = map;
164    *out_stride = stride;
165 }
166
167 /**
168  * \see dd_function_table::UnmapRenderbuffer
169  */
170 static void
171 intel_unmap_renderbuffer(struct gl_context *ctx,
172                          struct gl_renderbuffer *rb)
173 {
174    struct intel_context *intel = intel_context(ctx);
175    struct swrast_renderbuffer *srb = (struct swrast_renderbuffer *)rb;
176    struct intel_renderbuffer *irb = intel_renderbuffer(rb);
177
178    DBG("%s: rb %d (%s)\n", __FUNCTION__,
179        rb->Name, _mesa_get_format_name(rb->Format));
180
181    if (srb->Buffer) {
182       /* this is a malloc'd renderbuffer (accum buffer) */
183       /* nothing to do */
184       return;
185    }
186
187    intel_miptree_unmap(intel, irb->mt, irb->mt_level, irb->mt_layer);
188 }
189
190
191 /**
192  * Called via glRenderbufferStorageEXT() to set the format and allocate
193  * storage for a user-created renderbuffer.
194  */
195 GLboolean
196 intel_alloc_renderbuffer_storage(struct gl_context * ctx, struct gl_renderbuffer *rb,
197                                  GLenum internalFormat,
198                                  GLuint width, GLuint height)
199 {
200    struct intel_context *intel = intel_context(ctx);
201    struct intel_renderbuffer *irb = intel_renderbuffer(rb);
202
203    ASSERT(rb->Name != 0);
204
205    switch (internalFormat) {
206    default:
207       /* Use the same format-choice logic as for textures.
208        * Renderbuffers aren't any different from textures for us,
209        * except they're less useful because you can't texture with
210        * them.
211        */
212       rb->Format = intel->ctx.Driver.ChooseTextureFormat(ctx, internalFormat,
213                                                          GL_NONE, GL_NONE);
214       break;
215    case GL_STENCIL_INDEX:
216    case GL_STENCIL_INDEX1_EXT:
217    case GL_STENCIL_INDEX4_EXT:
218    case GL_STENCIL_INDEX8_EXT:
219    case GL_STENCIL_INDEX16_EXT:
220       /* These aren't actual texture formats, so force them here. */
221       if (intel->has_separate_stencil) {
222          rb->Format = MESA_FORMAT_S8;
223       } else {
224          assert(!intel->must_use_separate_stencil);
225          rb->Format = MESA_FORMAT_S8_Z24;
226       }
227       break;
228    }
229
230    rb->Width = width;
231    rb->Height = height;
232    rb->_BaseFormat = _mesa_base_fbo_format(ctx, internalFormat);
233
234    intel_miptree_release(&irb->mt);
235
236    DBG("%s: %s: %s (%dx%d)\n", __FUNCTION__,
237        _mesa_lookup_enum_by_nr(internalFormat),
238        _mesa_get_format_name(rb->Format), width, height);
239
240    if (width == 0 || height == 0)
241       return true;
242
243    irb->mt = intel_miptree_create_for_renderbuffer(intel, rb->Format,
244                                                    width, height);
245    if (!irb->mt)
246       return false;
247
248    if (intel->vtbl.is_hiz_depth_format(intel, rb->Format)) {
249       bool ok = intel_miptree_alloc_hiz(intel, irb->mt);
250       if (!ok) {
251          intel_miptree_release(&irb->mt);
252          return false;
253       }
254    }
255
256    return true;
257 }
258
259
260 #if FEATURE_OES_EGL_image
261 static void
262 intel_image_target_renderbuffer_storage(struct gl_context *ctx,
263                                         struct gl_renderbuffer *rb,
264                                         void *image_handle)
265 {
266    struct intel_context *intel = intel_context(ctx);
267    struct intel_renderbuffer *irb;
268    __DRIscreen *screen;
269    __DRIimage *image;
270
271    screen = intel->intelScreen->driScrnPriv;
272    image = screen->dri2.image->lookupEGLImage(screen, image_handle,
273                                               screen->loaderPrivate);
274    if (image == NULL)
275       return;
276
277    /* __DRIimage is opaque to the core so it has to be checked here */
278    switch (image->format) {
279    case MESA_FORMAT_RGBA8888_REV:
280       _mesa_error(&intel->ctx, GL_INVALID_OPERATION,
281             "glEGLImageTargetRenderbufferStorage(unsupported image format");
282       return;
283       break;
284    default:
285       break;
286    }
287
288    irb = intel_renderbuffer(rb);
289    intel_miptree_release(&irb->mt);
290    irb->mt = intel_miptree_create_for_region(intel,
291                                              GL_TEXTURE_2D,
292                                              image->format,
293                                              image->region);
294    if (!irb->mt)
295       return;
296
297    rb->InternalFormat = image->internal_format;
298    rb->Width = image->region->width;
299    rb->Height = image->region->height;
300    rb->Format = image->format;
301    rb->_BaseFormat = _mesa_base_fbo_format(&intel->ctx,
302                                            image->internal_format);
303 }
304 #endif
305
306 /**
307  * Called for each hardware renderbuffer when a _window_ is resized.
308  * Just update fields.
309  * Not used for user-created renderbuffers!
310  */
311 static GLboolean
312 intel_alloc_window_storage(struct gl_context * ctx, struct gl_renderbuffer *rb,
313                            GLenum internalFormat, GLuint width, GLuint height)
314 {
315    ASSERT(rb->Name == 0);
316    rb->Width = width;
317    rb->Height = height;
318    rb->InternalFormat = internalFormat;
319
320    return true;
321 }
322
323
324 static void
325 intel_resize_buffers(struct gl_context *ctx, struct gl_framebuffer *fb,
326                      GLuint width, GLuint height)
327 {
328    int i;
329
330    _mesa_resize_framebuffer(ctx, fb, width, height);
331
332    fb->Initialized = true; /* XXX remove someday */
333
334    if (fb->Name != 0) {
335       return;
336    }
337
338
339    /* Make sure all window system renderbuffers are up to date */
340    for (i = BUFFER_FRONT_LEFT; i <= BUFFER_BACK_RIGHT; i++) {
341       struct gl_renderbuffer *rb = fb->Attachment[i].Renderbuffer;
342
343       /* only resize if size is changing */
344       if (rb && (rb->Width != width || rb->Height != height)) {
345          rb->AllocStorage(ctx, rb, rb->InternalFormat, width, height);
346       }
347    }
348 }
349
350
351 /** Dummy function for gl_renderbuffer::AllocStorage() */
352 static GLboolean
353 intel_nop_alloc_storage(struct gl_context * ctx, struct gl_renderbuffer *rb,
354                         GLenum internalFormat, GLuint width, GLuint height)
355 {
356    _mesa_problem(ctx, "intel_op_alloc_storage should never be called.");
357    return false;
358 }
359
360 /**
361  * Create a new intel_renderbuffer which corresponds to an on-screen window,
362  * not a user-created renderbuffer.
363  */
364 struct intel_renderbuffer *
365 intel_create_renderbuffer(gl_format format)
366 {
367    struct intel_renderbuffer *irb;
368    struct gl_renderbuffer *rb;
369
370    GET_CURRENT_CONTEXT(ctx);
371
372    irb = CALLOC_STRUCT(intel_renderbuffer);
373    if (!irb) {
374       _mesa_error(ctx, GL_OUT_OF_MEMORY, "creating renderbuffer");
375       return NULL;
376    }
377
378    rb = &irb->Base.Base;
379
380    _mesa_init_renderbuffer(rb, 0);
381    rb->ClassID = INTEL_RB_CLASS;
382    rb->_BaseFormat = _mesa_get_format_base_format(format);
383    rb->Format = format;
384    rb->InternalFormat = rb->_BaseFormat;
385
386    /* intel-specific methods */
387    rb->Delete = intel_delete_renderbuffer;
388    rb->AllocStorage = intel_alloc_window_storage;
389
390    return irb;
391 }
392
393 /**
394  * Create a new renderbuffer object.
395  * Typically called via glBindRenderbufferEXT().
396  */
397 static struct gl_renderbuffer *
398 intel_new_renderbuffer(struct gl_context * ctx, GLuint name)
399 {
400    /*struct intel_context *intel = intel_context(ctx); */
401    struct intel_renderbuffer *irb;
402    struct gl_renderbuffer *rb;
403
404    irb = CALLOC_STRUCT(intel_renderbuffer);
405    if (!irb) {
406       _mesa_error(ctx, GL_OUT_OF_MEMORY, "creating renderbuffer");
407       return NULL;
408    }
409
410    rb = &irb->Base.Base;
411
412    _mesa_init_renderbuffer(rb, name);
413    rb->ClassID = INTEL_RB_CLASS;
414
415    /* intel-specific methods */
416    rb->Delete = intel_delete_renderbuffer;
417    rb->AllocStorage = intel_alloc_renderbuffer_storage;
418    /* span routines set in alloc_storage function */
419
420    return rb;
421 }
422
423
424 /**
425  * Called via glBindFramebufferEXT().
426  */
427 static void
428 intel_bind_framebuffer(struct gl_context * ctx, GLenum target,
429                        struct gl_framebuffer *fb, struct gl_framebuffer *fbread)
430 {
431    if (target == GL_FRAMEBUFFER_EXT || target == GL_DRAW_FRAMEBUFFER_EXT) {
432       intel_draw_buffer(ctx);
433    }
434    else {
435       /* don't need to do anything if target == GL_READ_FRAMEBUFFER_EXT */
436    }
437 }
438
439
440 /**
441  * Called via glFramebufferRenderbufferEXT().
442  */
443 static void
444 intel_framebuffer_renderbuffer(struct gl_context * ctx,
445                                struct gl_framebuffer *fb,
446                                GLenum attachment, struct gl_renderbuffer *rb)
447 {
448    DBG("Intel FramebufferRenderbuffer %u %u\n", fb->Name, rb ? rb->Name : 0);
449
450    _mesa_framebuffer_renderbuffer(ctx, fb, attachment, rb);
451    intel_draw_buffer(ctx);
452 }
453
454 /**
455  * \par Special case for separate stencil
456  *
457  *     When wrapping a depthstencil texture that uses separate stencil, this
458  *     function is recursively called twice: once to create \c
459  *     irb->wrapped_depth and again to create \c irb->wrapped_stencil.  On the
460  *     call to create \c irb->wrapped_depth, the \c format and \c
461  *     internal_format parameters do not match \c mt->format. In that case, \c
462  *     mt->format is MESA_FORMAT_S8_Z24 and \c format is \c
463  *     MESA_FORMAT_X8_Z24.
464  *
465  * @return true on success
466  */
467
468 static bool
469 intel_renderbuffer_update_wrapper(struct intel_context *intel,
470                                   struct intel_renderbuffer *irb,
471                                   struct gl_texture_image *image,
472                                   uint32_t layer)
473 {
474    struct gl_renderbuffer *rb = &irb->Base.Base;
475    struct intel_texture_image *intel_image = intel_texture_image(image);
476    struct intel_mipmap_tree *mt = intel_image->mt;
477    int level = image->Level;
478
479    rb->Format = image->TexFormat;
480    rb->InternalFormat = image->InternalFormat;
481    rb->_BaseFormat = image->_BaseFormat;
482    rb->Width = mt->level[level].width;
483    rb->Height = mt->level[level].height;
484
485    rb->Delete = intel_delete_renderbuffer;
486    rb->AllocStorage = intel_nop_alloc_storage;
487
488    intel_miptree_check_level_layer(mt, level, layer);
489    irb->mt_level = level;
490    irb->mt_layer = layer;
491
492    intel_miptree_reference(&irb->mt, mt);
493
494    intel_renderbuffer_set_draw_offset(irb);
495
496    if (mt->hiz_mt == NULL &&
497        intel->vtbl.is_hiz_depth_format(intel, rb->Format)) {
498       intel_miptree_alloc_hiz(intel, mt);
499       if (!mt->hiz_mt)
500          return false;
501    }
502
503    return true;
504 }
505
506 void
507 intel_renderbuffer_set_draw_offset(struct intel_renderbuffer *irb)
508 {
509    unsigned int dst_x, dst_y;
510
511    /* compute offset of the particular 2D image within the texture region */
512    intel_miptree_get_image_offset(irb->mt,
513                                   irb->mt_level,
514                                   0, /* face, which we ignore */
515                                   irb->mt_layer,
516                                   &dst_x, &dst_y);
517
518    irb->draw_x = dst_x;
519    irb->draw_y = dst_y;
520 }
521
522 /**
523  * Rendering to tiled buffers requires that the base address of the
524  * buffer be aligned to a page boundary.  We generally render to
525  * textures by pointing the surface at the mipmap image level, which
526  * may not be aligned to a tile boundary.
527  *
528  * This function returns an appropriately-aligned base offset
529  * according to the tiling restrictions, plus any required x/y offset
530  * from there.
531  */
532 uint32_t
533 intel_renderbuffer_tile_offsets(struct intel_renderbuffer *irb,
534                                 uint32_t *tile_x,
535                                 uint32_t *tile_y)
536 {
537    struct intel_region *region = irb->mt->region;
538    int cpp = region->cpp;
539    uint32_t pitch = region->pitch * cpp;
540
541    if (region->tiling == I915_TILING_NONE) {
542       *tile_x = 0;
543       *tile_y = 0;
544       return irb->draw_x * cpp + irb->draw_y * pitch;
545    } else if (region->tiling == I915_TILING_X) {
546       *tile_x = irb->draw_x % (512 / cpp);
547       *tile_y = irb->draw_y % 8;
548       return ((irb->draw_y / 8) * (8 * pitch) +
549               (irb->draw_x - *tile_x) / (512 / cpp) * 4096);
550    } else {
551       assert(region->tiling == I915_TILING_Y);
552       *tile_x = irb->draw_x % (128 / cpp);
553       *tile_y = irb->draw_y % 32;
554       return ((irb->draw_y / 32) * (32 * pitch) +
555               (irb->draw_x - *tile_x) / (128 / cpp) * 4096);
556    }
557 }
558
559 /**
560  * Called by glFramebufferTexture[123]DEXT() (and other places) to
561  * prepare for rendering into texture memory.  This might be called
562  * many times to choose different texture levels, cube faces, etc
563  * before intel_finish_render_texture() is ever called.
564  */
565 static void
566 intel_render_texture(struct gl_context * ctx,
567                      struct gl_framebuffer *fb,
568                      struct gl_renderbuffer_attachment *att)
569 {
570    struct intel_context *intel = intel_context(ctx);
571    struct gl_texture_image *image = _mesa_get_attachment_teximage(att);
572    struct intel_renderbuffer *irb = intel_renderbuffer(att->Renderbuffer);
573    struct intel_texture_image *intel_image = intel_texture_image(image);
574    struct intel_mipmap_tree *mt = intel_image->mt;
575    int layer;
576
577    (void) fb;
578
579    if (att->CubeMapFace > 0) {
580       assert(att->Zoffset == 0);
581       layer = att->CubeMapFace;
582    } else {
583       layer = att->Zoffset;
584    }
585
586    if (!intel_image->mt) {
587       /* Fallback on drawing to a texture that doesn't have a miptree
588        * (has a border, width/height 0, etc.)
589        */
590       _mesa_reference_renderbuffer(&att->Renderbuffer, NULL);
591       _swrast_render_texture(ctx, fb, att);
592       return;
593    }
594    else if (!irb) {
595       intel_miptree_check_level_layer(mt, att->TextureLevel, layer);
596
597       irb = (struct intel_renderbuffer *)intel_new_renderbuffer(ctx, ~0);
598
599       if (irb) {
600          /* bind the wrapper to the attachment point */
601          _mesa_reference_renderbuffer(&att->Renderbuffer, &irb->Base.Base);
602       }
603       else {
604          /* fallback to software rendering */
605          _swrast_render_texture(ctx, fb, att);
606          return;
607       }
608    }
609
610    if (!intel_renderbuffer_update_wrapper(intel, irb, image, layer)) {
611        _mesa_reference_renderbuffer(&att->Renderbuffer, NULL);
612        _swrast_render_texture(ctx, fb, att);
613        return;
614    }
615
616    irb->tex_image = image;
617
618    DBG("Begin render %s texture tex=%u w=%d h=%d refcount=%d\n",
619        _mesa_get_format_name(image->TexFormat),
620        att->Texture->Name, image->Width, image->Height,
621        irb->Base.Base.RefCount);
622
623    /* update drawing region, etc */
624    intel_draw_buffer(ctx);
625 }
626
627
628 /**
629  * Called by Mesa when rendering to a texture is done.
630  */
631 static void
632 intel_finish_render_texture(struct gl_context * ctx,
633                             struct gl_renderbuffer_attachment *att)
634 {
635    struct intel_context *intel = intel_context(ctx);
636    struct gl_texture_object *tex_obj = att->Texture;
637    struct gl_texture_image *image =
638       tex_obj->Image[att->CubeMapFace][att->TextureLevel];
639    struct intel_renderbuffer *irb = intel_renderbuffer(att->Renderbuffer);
640
641    DBG("Finish render %s texture tex=%u\n",
642        _mesa_get_format_name(image->TexFormat), att->Texture->Name);
643
644    if (irb)
645       irb->tex_image = NULL;
646
647    /* Since we've (probably) rendered to the texture and will (likely) use
648     * it in the texture domain later on in this batchbuffer, flush the
649     * batch.  Once again, we wish for a domain tracker in libdrm to cover
650     * usage inside of a batchbuffer like GEM does in the kernel.
651     */
652    intel_batchbuffer_emit_mi_flush(intel);
653 }
654
655 /**
656  * Do additional "completeness" testing of a framebuffer object.
657  */
658 static void
659 intel_validate_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb)
660 {
661    struct intel_context *intel = intel_context(ctx);
662    const struct intel_renderbuffer *depthRb =
663       intel_get_renderbuffer(fb, BUFFER_DEPTH);
664    const struct intel_renderbuffer *stencilRb =
665       intel_get_renderbuffer(fb, BUFFER_STENCIL);
666    struct intel_mipmap_tree *depth_mt = NULL, *stencil_mt = NULL;
667    int i;
668
669    if (depthRb)
670       depth_mt = depthRb->mt;
671    if (stencilRb) {
672       stencil_mt = stencilRb->mt;
673       if (stencil_mt->stencil_mt)
674          stencil_mt = stencil_mt->stencil_mt;
675    }
676
677    if (depth_mt && stencil_mt) {
678       if (depth_mt == stencil_mt) {
679          /* For true packed depth/stencil (not faked on prefers-separate-stencil
680           * hardware) we need to be sure they're the same level/layer, since
681           * we'll be emitting a single packet describing the packed setup.
682           */
683          if (depthRb->mt_level != stencilRb->mt_level ||
684              depthRb->mt_layer != stencilRb->mt_layer) {
685             fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
686          }
687       } else {
688          if (!intel->has_separate_stencil)
689             fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
690          if (stencil_mt->format != MESA_FORMAT_S8)
691             fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
692          if (intel->gen < 7 && depth_mt->hiz_mt == NULL) {
693             /* Before Gen7, separate depth and stencil buffers can be used
694              * only if HiZ is enabled. From the Sandybridge PRM, Volume 2,
695              * Part 1, Bit 3DSTATE_DEPTH_BUFFER.SeparateStencilBufferEnable:
696              *     [DevSNB]: This field must be set to the same value (enabled
697              *     or disabled) as Hierarchical Depth Buffer Enable.
698              */
699             fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED;
700          }
701       }
702    }
703
704    for (i = 0; i < Elements(fb->Attachment); i++) {
705       struct gl_renderbuffer *rb;
706       struct intel_renderbuffer *irb;
707
708       if (fb->Attachment[i].Type == GL_NONE)
709          continue;
710
711       /* A supported attachment will have a Renderbuffer set either
712        * from being a Renderbuffer or being a texture that got the
713        * intel_wrap_texture() treatment.
714        */
715       rb = fb->Attachment[i].Renderbuffer;
716       if (rb == NULL) {
717          DBG("attachment without renderbuffer\n");
718          fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
719          continue;
720       }
721
722       if (fb->Attachment[i].Type == GL_TEXTURE) {
723          const struct gl_texture_image *img =
724             _mesa_get_attachment_teximage_const(&fb->Attachment[i]);
725
726          if (img->Border) {
727             DBG("texture with border\n");
728             fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
729             continue;
730          }
731       }
732
733       irb = intel_renderbuffer(rb);
734       if (irb == NULL) {
735          DBG("software rendering renderbuffer\n");
736          fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
737          continue;
738       }
739
740       if (!intel->vtbl.render_target_supported(intel, rb)) {
741          DBG("Unsupported HW texture/renderbuffer format attached: %s\n",
742              _mesa_get_format_name(intel_rb_format(irb)));
743          fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
744       }
745    }
746 }
747
748 /**
749  * Try to do a glBlitFramebuffer using glCopyTexSubImage2D
750  * We can do this when the dst renderbuffer is actually a texture and
751  * there is no scaling, mirroring or scissoring.
752  *
753  * \return new buffer mask indicating the buffers left to blit using the
754  *         normal path.
755  */
756 static GLbitfield
757 intel_blit_framebuffer_copy_tex_sub_image(struct gl_context *ctx,
758                                           GLint srcX0, GLint srcY0,
759                                           GLint srcX1, GLint srcY1,
760                                           GLint dstX0, GLint dstY0,
761                                           GLint dstX1, GLint dstY1,
762                                           GLbitfield mask, GLenum filter)
763 {
764    if (mask & GL_COLOR_BUFFER_BIT) {
765       const struct gl_framebuffer *drawFb = ctx->DrawBuffer;
766       const struct gl_framebuffer *readFb = ctx->ReadBuffer;
767       const struct gl_renderbuffer_attachment *drawAtt =
768          &drawFb->Attachment[drawFb->_ColorDrawBufferIndexes[0]];
769       struct intel_renderbuffer *srcRb = 
770          intel_renderbuffer(readFb->_ColorReadBuffer);
771
772       /* If the source and destination are the same size with no
773          mirroring, the rectangles are within the size of the
774          texture and there is no scissor then we can use
775          glCopyTexSubimage2D to implement the blit. This will end
776          up as a fast hardware blit on some drivers */
777       if (srcRb && drawAtt && drawAtt->Texture &&
778           srcX0 - srcX1 == dstX0 - dstX1 &&
779           srcY0 - srcY1 == dstY0 - dstY1 &&
780           srcX1 >= srcX0 &&
781           srcY1 >= srcY0 &&
782           srcX0 >= 0 && srcX1 <= readFb->Width &&
783           srcY0 >= 0 && srcY1 <= readFb->Height &&
784           dstX0 >= 0 && dstX1 <= drawFb->Width &&
785           dstY0 >= 0 && dstY1 <= drawFb->Height &&
786           !ctx->Scissor.Enabled) {
787          const struct gl_texture_object *texObj = drawAtt->Texture;
788          const GLuint dstLevel = drawAtt->TextureLevel;
789          const GLenum target = texObj->Target;
790
791          struct gl_texture_image *texImage =
792             _mesa_select_tex_image(ctx, texObj, target, dstLevel);
793
794          if (intel_copy_texsubimage(intel_context(ctx),
795                                     intel_texture_image(texImage),
796                                     dstX0, dstY0,
797                                     srcRb,
798                                     srcX0, srcY0,
799                                     srcX1 - srcX0, /* width */
800                                     srcY1 - srcY0))
801             mask &= ~GL_COLOR_BUFFER_BIT;
802       }
803    }
804
805    return mask;
806 }
807
808 static void
809 intel_blit_framebuffer(struct gl_context *ctx,
810                        GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
811                        GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
812                        GLbitfield mask, GLenum filter)
813 {
814    /* Try faster, glCopyTexSubImage2D approach first which uses the BLT. */
815    mask = intel_blit_framebuffer_copy_tex_sub_image(ctx,
816                                                     srcX0, srcY0, srcX1, srcY1,
817                                                     dstX0, dstY0, dstX1, dstY1,
818                                                     mask, filter);
819    if (mask == 0x0)
820       return;
821
822    _mesa_meta_BlitFramebuffer(ctx,
823                               srcX0, srcY0, srcX1, srcY1,
824                               dstX0, dstY0, dstX1, dstY1,
825                               mask, filter);
826 }
827
828 void
829 intel_renderbuffer_set_needs_hiz_resolve(struct intel_renderbuffer *irb)
830 {
831    if (irb->mt) {
832       intel_miptree_slice_set_needs_hiz_resolve(irb->mt,
833                                                 irb->mt_level,
834                                                 irb->mt_layer);
835    }
836 }
837
838 void
839 intel_renderbuffer_set_needs_depth_resolve(struct intel_renderbuffer *irb)
840 {
841    if (irb->mt) {
842       intel_miptree_slice_set_needs_depth_resolve(irb->mt,
843                                                   irb->mt_level,
844                                                   irb->mt_layer);
845    }
846 }
847
848 bool
849 intel_renderbuffer_resolve_hiz(struct intel_context *intel,
850                                struct intel_renderbuffer *irb)
851 {
852    if (irb->mt)
853       return intel_miptree_slice_resolve_hiz(intel,
854                                              irb->mt,
855                                              irb->mt_level,
856                                              irb->mt_layer);
857
858    return false;
859 }
860
861 bool
862 intel_renderbuffer_resolve_depth(struct intel_context *intel,
863                                  struct intel_renderbuffer *irb)
864 {
865    if (irb->mt)
866       return intel_miptree_slice_resolve_depth(intel,
867                                                irb->mt,
868                                                irb->mt_level,
869                                                irb->mt_layer);
870
871    return false;
872 }
873
874 /**
875  * Do one-time context initializations related to GL_EXT_framebuffer_object.
876  * Hook in device driver functions.
877  */
878 void
879 intel_fbo_init(struct intel_context *intel)
880 {
881    intel->ctx.Driver.NewFramebuffer = intel_new_framebuffer;
882    intel->ctx.Driver.NewRenderbuffer = intel_new_renderbuffer;
883    intel->ctx.Driver.MapRenderbuffer = intel_map_renderbuffer;
884    intel->ctx.Driver.UnmapRenderbuffer = intel_unmap_renderbuffer;
885    intel->ctx.Driver.BindFramebuffer = intel_bind_framebuffer;
886    intel->ctx.Driver.FramebufferRenderbuffer = intel_framebuffer_renderbuffer;
887    intel->ctx.Driver.RenderTexture = intel_render_texture;
888    intel->ctx.Driver.FinishRenderTexture = intel_finish_render_texture;
889    intel->ctx.Driver.ResizeBuffers = intel_resize_buffers;
890    intel->ctx.Driver.ValidateFramebuffer = intel_validate_framebuffer;
891    intel->ctx.Driver.BlitFramebuffer = intel_blit_framebuffer;
892
893 #if FEATURE_OES_EGL_image
894    intel->ctx.Driver.EGLImageTargetRenderbufferStorage =
895       intel_image_target_renderbuffer_storage;
896 #endif   
897 }