intel_fbo.c revision e2dce7f7ee3e7da9cbb0bb33307ecd79e824426d
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
59static struct gl_renderbuffer *
60intel_new_renderbuffer(struct gl_context * ctx, GLuint name);
61
62bool
63intel_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
71struct intel_region*
72intel_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 */
87static struct gl_framebuffer *
88intel_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() */
98static void
99intel_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 */
113static void
114intel_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 */
170static void
171intel_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 */
195GLboolean
196intel_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   irb->mt = intel_miptree_create_for_renderbuffer(intel, rb->Format,
241						   width, height);
242   if (!irb->mt)
243      return false;
244
245   if (intel->vtbl.is_hiz_depth_format(intel, rb->Format)) {
246      bool ok = intel_miptree_alloc_hiz(intel, irb->mt);
247      if (!ok) {
248	 intel_miptree_release(&irb->mt);
249	 return false;
250      }
251   }
252
253   return true;
254}
255
256
257#if FEATURE_OES_EGL_image
258static void
259intel_image_target_renderbuffer_storage(struct gl_context *ctx,
260					struct gl_renderbuffer *rb,
261					void *image_handle)
262{
263   struct intel_context *intel = intel_context(ctx);
264   struct intel_renderbuffer *irb;
265   __DRIscreen *screen;
266   __DRIimage *image;
267
268   screen = intel->intelScreen->driScrnPriv;
269   image = screen->dri2.image->lookupEGLImage(screen, image_handle,
270					      screen->loaderPrivate);
271   if (image == NULL)
272      return;
273
274   /* __DRIimage is opaque to the core so it has to be checked here */
275   switch (image->format) {
276   case MESA_FORMAT_RGBA8888_REV:
277      _mesa_error(&intel->ctx, GL_INVALID_OPERATION,
278            "glEGLImageTargetRenderbufferStorage(unsupported image format");
279      return;
280      break;
281   default:
282      break;
283   }
284
285   irb = intel_renderbuffer(rb);
286   intel_miptree_release(&irb->mt);
287   irb->mt = intel_miptree_create_for_region(intel,
288                                             GL_TEXTURE_2D,
289                                             image->format,
290                                             image->region);
291   if (!irb->mt)
292      return;
293
294   rb->InternalFormat = image->internal_format;
295   rb->Width = image->region->width;
296   rb->Height = image->region->height;
297   rb->Format = image->format;
298   rb->_BaseFormat = _mesa_base_fbo_format(&intel->ctx,
299					   image->internal_format);
300}
301#endif
302
303/**
304 * Called for each hardware renderbuffer when a _window_ is resized.
305 * Just update fields.
306 * Not used for user-created renderbuffers!
307 */
308static GLboolean
309intel_alloc_window_storage(struct gl_context * ctx, struct gl_renderbuffer *rb,
310                           GLenum internalFormat, GLuint width, GLuint height)
311{
312   ASSERT(rb->Name == 0);
313   rb->Width = width;
314   rb->Height = height;
315   rb->InternalFormat = internalFormat;
316
317   return true;
318}
319
320
321static void
322intel_resize_buffers(struct gl_context *ctx, struct gl_framebuffer *fb,
323		     GLuint width, GLuint height)
324{
325   int i;
326
327   _mesa_resize_framebuffer(ctx, fb, width, height);
328
329   fb->Initialized = true; /* XXX remove someday */
330
331   if (fb->Name != 0) {
332      return;
333   }
334
335
336   /* Make sure all window system renderbuffers are up to date */
337   for (i = BUFFER_FRONT_LEFT; i <= BUFFER_BACK_RIGHT; i++) {
338      struct gl_renderbuffer *rb = fb->Attachment[i].Renderbuffer;
339
340      /* only resize if size is changing */
341      if (rb && (rb->Width != width || rb->Height != height)) {
342	 rb->AllocStorage(ctx, rb, rb->InternalFormat, width, height);
343      }
344   }
345}
346
347
348/** Dummy function for gl_renderbuffer::AllocStorage() */
349static GLboolean
350intel_nop_alloc_storage(struct gl_context * ctx, struct gl_renderbuffer *rb,
351                        GLenum internalFormat, GLuint width, GLuint height)
352{
353   _mesa_problem(ctx, "intel_op_alloc_storage should never be called.");
354   return false;
355}
356
357/**
358 * Create a new intel_renderbuffer which corresponds to an on-screen window,
359 * not a user-created renderbuffer.
360 */
361struct intel_renderbuffer *
362intel_create_renderbuffer(gl_format format)
363{
364   struct intel_renderbuffer *irb;
365   struct gl_renderbuffer *rb;
366
367   GET_CURRENT_CONTEXT(ctx);
368
369   irb = CALLOC_STRUCT(intel_renderbuffer);
370   if (!irb) {
371      _mesa_error(ctx, GL_OUT_OF_MEMORY, "creating renderbuffer");
372      return NULL;
373   }
374
375   rb = &irb->Base.Base;
376
377   _mesa_init_renderbuffer(rb, 0);
378   rb->ClassID = INTEL_RB_CLASS;
379   rb->_BaseFormat = _mesa_get_format_base_format(format);
380   rb->Format = format;
381   rb->InternalFormat = rb->_BaseFormat;
382
383   /* intel-specific methods */
384   rb->Delete = intel_delete_renderbuffer;
385   rb->AllocStorage = intel_alloc_window_storage;
386
387   return irb;
388}
389
390/**
391 * Create a new renderbuffer object.
392 * Typically called via glBindRenderbufferEXT().
393 */
394static struct gl_renderbuffer *
395intel_new_renderbuffer(struct gl_context * ctx, GLuint name)
396{
397   /*struct intel_context *intel = intel_context(ctx); */
398   struct intel_renderbuffer *irb;
399   struct gl_renderbuffer *rb;
400
401   irb = CALLOC_STRUCT(intel_renderbuffer);
402   if (!irb) {
403      _mesa_error(ctx, GL_OUT_OF_MEMORY, "creating renderbuffer");
404      return NULL;
405   }
406
407   rb = &irb->Base.Base;
408
409   _mesa_init_renderbuffer(rb, name);
410   rb->ClassID = INTEL_RB_CLASS;
411
412   /* intel-specific methods */
413   rb->Delete = intel_delete_renderbuffer;
414   rb->AllocStorage = intel_alloc_renderbuffer_storage;
415   /* span routines set in alloc_storage function */
416
417   return rb;
418}
419
420
421/**
422 * Called via glBindFramebufferEXT().
423 */
424static void
425intel_bind_framebuffer(struct gl_context * ctx, GLenum target,
426                       struct gl_framebuffer *fb, struct gl_framebuffer *fbread)
427{
428   if (target == GL_FRAMEBUFFER_EXT || target == GL_DRAW_FRAMEBUFFER_EXT) {
429      intel_draw_buffer(ctx);
430   }
431   else {
432      /* don't need to do anything if target == GL_READ_FRAMEBUFFER_EXT */
433   }
434}
435
436
437/**
438 * Called via glFramebufferRenderbufferEXT().
439 */
440static void
441intel_framebuffer_renderbuffer(struct gl_context * ctx,
442                               struct gl_framebuffer *fb,
443                               GLenum attachment, struct gl_renderbuffer *rb)
444{
445   DBG("Intel FramebufferRenderbuffer %u %u\n", fb->Name, rb ? rb->Name : 0);
446
447   _mesa_framebuffer_renderbuffer(ctx, fb, attachment, rb);
448   intel_draw_buffer(ctx);
449}
450
451/**
452 * \par Special case for separate stencil
453 *
454 *     When wrapping a depthstencil texture that uses separate stencil, this
455 *     function is recursively called twice: once to create \c
456 *     irb->wrapped_depth and again to create \c irb->wrapped_stencil.  On the
457 *     call to create \c irb->wrapped_depth, the \c format and \c
458 *     internal_format parameters do not match \c mt->format. In that case, \c
459 *     mt->format is MESA_FORMAT_S8_Z24 and \c format is \c
460 *     MESA_FORMAT_X8_Z24.
461 *
462 * @return true on success
463 */
464
465static bool
466intel_renderbuffer_update_wrapper(struct intel_context *intel,
467                                  struct intel_renderbuffer *irb,
468				  struct gl_texture_image *image,
469                                  uint32_t layer)
470{
471   struct gl_renderbuffer *rb = &irb->Base.Base;
472   struct intel_texture_image *intel_image = intel_texture_image(image);
473   struct intel_mipmap_tree *mt = intel_image->mt;
474   int level = image->Level;
475
476   rb->Format = image->TexFormat;
477   rb->InternalFormat = image->InternalFormat;
478   rb->_BaseFormat = image->_BaseFormat;
479   rb->Width = mt->level[level].width;
480   rb->Height = mt->level[level].height;
481
482   rb->Delete = intel_delete_renderbuffer;
483   rb->AllocStorage = intel_nop_alloc_storage;
484
485   intel_miptree_check_level_layer(mt, level, layer);
486   irb->mt_level = level;
487   irb->mt_layer = layer;
488
489   intel_miptree_reference(&irb->mt, mt);
490
491   intel_renderbuffer_set_draw_offset(irb);
492
493   if (mt->hiz_mt == NULL &&
494       intel->vtbl.is_hiz_depth_format(intel, rb->Format)) {
495      intel_miptree_alloc_hiz(intel, mt);
496      if (!mt->hiz_mt)
497	 return false;
498   }
499
500   return true;
501}
502
503void
504intel_renderbuffer_set_draw_offset(struct intel_renderbuffer *irb)
505{
506   unsigned int dst_x, dst_y;
507
508   /* compute offset of the particular 2D image within the texture region */
509   intel_miptree_get_image_offset(irb->mt,
510				  irb->mt_level,
511				  0, /* face, which we ignore */
512				  irb->mt_layer,
513				  &dst_x, &dst_y);
514
515   irb->draw_x = dst_x;
516   irb->draw_y = dst_y;
517}
518
519/**
520 * Rendering to tiled buffers requires that the base address of the
521 * buffer be aligned to a page boundary.  We generally render to
522 * textures by pointing the surface at the mipmap image level, which
523 * may not be aligned to a tile boundary.
524 *
525 * This function returns an appropriately-aligned base offset
526 * according to the tiling restrictions, plus any required x/y offset
527 * from there.
528 */
529uint32_t
530intel_renderbuffer_tile_offsets(struct intel_renderbuffer *irb,
531				uint32_t *tile_x,
532				uint32_t *tile_y)
533{
534   struct intel_region *region = irb->mt->region;
535   int cpp = region->cpp;
536   uint32_t pitch = region->pitch * cpp;
537
538   if (region->tiling == I915_TILING_NONE) {
539      *tile_x = 0;
540      *tile_y = 0;
541      return irb->draw_x * cpp + irb->draw_y * pitch;
542   } else if (region->tiling == I915_TILING_X) {
543      *tile_x = irb->draw_x % (512 / cpp);
544      *tile_y = irb->draw_y % 8;
545      return ((irb->draw_y / 8) * (8 * pitch) +
546	      (irb->draw_x - *tile_x) / (512 / cpp) * 4096);
547   } else {
548      assert(region->tiling == I915_TILING_Y);
549      *tile_x = irb->draw_x % (128 / cpp);
550      *tile_y = irb->draw_y % 32;
551      return ((irb->draw_y / 32) * (32 * pitch) +
552	      (irb->draw_x - *tile_x) / (128 / cpp) * 4096);
553   }
554}
555
556/**
557 * Called by glFramebufferTexture[123]DEXT() (and other places) to
558 * prepare for rendering into texture memory.  This might be called
559 * many times to choose different texture levels, cube faces, etc
560 * before intel_finish_render_texture() is ever called.
561 */
562static void
563intel_render_texture(struct gl_context * ctx,
564                     struct gl_framebuffer *fb,
565                     struct gl_renderbuffer_attachment *att)
566{
567   struct intel_context *intel = intel_context(ctx);
568   struct gl_texture_image *image = _mesa_get_attachment_teximage(att);
569   struct intel_renderbuffer *irb = intel_renderbuffer(att->Renderbuffer);
570   struct intel_texture_image *intel_image = intel_texture_image(image);
571   struct intel_mipmap_tree *mt = intel_image->mt;
572   int layer;
573
574   (void) fb;
575
576   if (att->CubeMapFace > 0) {
577      assert(att->Zoffset == 0);
578      layer = att->CubeMapFace;
579   } else {
580      layer = att->Zoffset;
581   }
582
583   if (!intel_image->mt) {
584      /* Fallback on drawing to a texture that doesn't have a miptree
585       * (has a border, width/height 0, etc.)
586       */
587      _mesa_reference_renderbuffer(&att->Renderbuffer, NULL);
588      _swrast_render_texture(ctx, fb, att);
589      return;
590   }
591   else if (!irb) {
592      intel_miptree_check_level_layer(mt, att->TextureLevel, layer);
593
594      irb = (struct intel_renderbuffer *)intel_new_renderbuffer(ctx, ~0);
595
596      if (irb) {
597         /* bind the wrapper to the attachment point */
598         _mesa_reference_renderbuffer(&att->Renderbuffer, &irb->Base.Base);
599      }
600      else {
601         /* fallback to software rendering */
602         _swrast_render_texture(ctx, fb, att);
603         return;
604      }
605   }
606
607   if (!intel_renderbuffer_update_wrapper(intel, irb, image, layer)) {
608       _mesa_reference_renderbuffer(&att->Renderbuffer, NULL);
609       _swrast_render_texture(ctx, fb, att);
610       return;
611   }
612
613   irb->tex_image = image;
614
615   DBG("Begin render %s texture tex=%u w=%d h=%d refcount=%d\n",
616       _mesa_get_format_name(image->TexFormat),
617       att->Texture->Name, image->Width, image->Height,
618       irb->Base.Base.RefCount);
619
620   /* update drawing region, etc */
621   intel_draw_buffer(ctx);
622}
623
624
625/**
626 * Called by Mesa when rendering to a texture is done.
627 */
628static void
629intel_finish_render_texture(struct gl_context * ctx,
630                            struct gl_renderbuffer_attachment *att)
631{
632   struct intel_context *intel = intel_context(ctx);
633   struct gl_texture_object *tex_obj = att->Texture;
634   struct gl_texture_image *image =
635      tex_obj->Image[att->CubeMapFace][att->TextureLevel];
636   struct intel_renderbuffer *irb = intel_renderbuffer(att->Renderbuffer);
637
638   DBG("Finish render %s texture tex=%u\n",
639       _mesa_get_format_name(image->TexFormat), att->Texture->Name);
640
641   if (irb)
642      irb->tex_image = NULL;
643
644   /* Since we've (probably) rendered to the texture and will (likely) use
645    * it in the texture domain later on in this batchbuffer, flush the
646    * batch.  Once again, we wish for a domain tracker in libdrm to cover
647    * usage inside of a batchbuffer like GEM does in the kernel.
648    */
649   intel_batchbuffer_emit_mi_flush(intel);
650}
651
652/**
653 * Do additional "completeness" testing of a framebuffer object.
654 */
655static void
656intel_validate_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb)
657{
658   struct intel_context *intel = intel_context(ctx);
659   const struct intel_renderbuffer *depthRb =
660      intel_get_renderbuffer(fb, BUFFER_DEPTH);
661   const struct intel_renderbuffer *stencilRb =
662      intel_get_renderbuffer(fb, BUFFER_STENCIL);
663   struct intel_mipmap_tree *depth_mt = NULL, *stencil_mt = NULL;
664   int i;
665
666   DBG("%s() on fb %p (%s)\n", __FUNCTION__,
667       fb, (fb == ctx->DrawBuffer ? "drawbuffer" :
668	    (fb == ctx->ReadBuffer ? "readbuffer" : "other buffer")));
669
670   if (depthRb)
671      depth_mt = depthRb->mt;
672   if (stencilRb) {
673      stencil_mt = stencilRb->mt;
674      if (stencil_mt->stencil_mt)
675	 stencil_mt = stencil_mt->stencil_mt;
676   }
677
678   if (depth_mt && stencil_mt) {
679      if (depth_mt == stencil_mt) {
680	 /* For true packed depth/stencil (not faked on prefers-separate-stencil
681	  * hardware) we need to be sure they're the same level/layer, since
682	  * we'll be emitting a single packet describing the packed setup.
683	  */
684	 if (depthRb->mt_level != stencilRb->mt_level ||
685	     depthRb->mt_layer != stencilRb->mt_layer) {
686	    DBG("depth image level/layer %d/%d != stencil image %d/%d\n",
687		depthRb->mt_level,
688		depthRb->mt_layer,
689		stencilRb->mt_level,
690		stencilRb->mt_layer);
691	    fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
692	 }
693      } else {
694	 if (!intel->has_separate_stencil) {
695	    DBG("separate stencil unsupported\n");
696	    fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
697	 }
698	 if (stencil_mt->format != MESA_FORMAT_S8) {
699	    DBG("separate stencil is %s instead of S8\n",
700		_mesa_get_format_name(stencil_mt->format));
701	    fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
702	 }
703	 if (intel->gen < 7 && depth_mt->hiz_mt == NULL) {
704	    /* Before Gen7, separate depth and stencil buffers can be used
705	     * only if HiZ is enabled. From the Sandybridge PRM, Volume 2,
706	     * Part 1, Bit 3DSTATE_DEPTH_BUFFER.SeparateStencilBufferEnable:
707	     *     [DevSNB]: This field must be set to the same value (enabled
708	     *     or disabled) as Hierarchical Depth Buffer Enable.
709	     */
710	    DBG("separate stencil without HiZ\n");
711	    fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED;
712	 }
713      }
714   }
715
716   for (i = 0; i < Elements(fb->Attachment); i++) {
717      struct gl_renderbuffer *rb;
718      struct intel_renderbuffer *irb;
719
720      if (fb->Attachment[i].Type == GL_NONE)
721	 continue;
722
723      /* A supported attachment will have a Renderbuffer set either
724       * from being a Renderbuffer or being a texture that got the
725       * intel_wrap_texture() treatment.
726       */
727      rb = fb->Attachment[i].Renderbuffer;
728      if (rb == NULL) {
729	 DBG("attachment without renderbuffer\n");
730	 fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
731	 continue;
732      }
733
734      if (fb->Attachment[i].Type == GL_TEXTURE) {
735	 const struct gl_texture_image *img =
736	    _mesa_get_attachment_teximage_const(&fb->Attachment[i]);
737
738	 if (img->Border) {
739	    DBG("texture with border\n");
740	    fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
741	    continue;
742	 }
743      }
744
745      irb = intel_renderbuffer(rb);
746      if (irb == NULL) {
747	 DBG("software rendering renderbuffer\n");
748	 fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
749	 continue;
750      }
751
752      if (!intel->vtbl.render_target_supported(intel, rb)) {
753	 DBG("Unsupported HW texture/renderbuffer format attached: %s\n",
754	     _mesa_get_format_name(intel_rb_format(irb)));
755	 fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
756      }
757   }
758}
759
760/**
761 * Try to do a glBlitFramebuffer using glCopyTexSubImage2D
762 * We can do this when the dst renderbuffer is actually a texture and
763 * there is no scaling, mirroring or scissoring.
764 *
765 * \return new buffer mask indicating the buffers left to blit using the
766 *         normal path.
767 */
768static GLbitfield
769intel_blit_framebuffer_copy_tex_sub_image(struct gl_context *ctx,
770                                          GLint srcX0, GLint srcY0,
771                                          GLint srcX1, GLint srcY1,
772                                          GLint dstX0, GLint dstY0,
773                                          GLint dstX1, GLint dstY1,
774                                          GLbitfield mask, GLenum filter)
775{
776   if (mask & GL_COLOR_BUFFER_BIT) {
777      const struct gl_framebuffer *drawFb = ctx->DrawBuffer;
778      const struct gl_framebuffer *readFb = ctx->ReadBuffer;
779      const struct gl_renderbuffer_attachment *drawAtt =
780         &drawFb->Attachment[drawFb->_ColorDrawBufferIndexes[0]];
781      struct intel_renderbuffer *srcRb =
782         intel_renderbuffer(readFb->_ColorReadBuffer);
783
784      /* If the source and destination are the same size with no
785         mirroring, the rectangles are within the size of the
786         texture and there is no scissor then we can use
787         glCopyTexSubimage2D to implement the blit. This will end
788         up as a fast hardware blit on some drivers */
789      if (srcRb && drawAtt && drawAtt->Texture &&
790          srcX0 - srcX1 == dstX0 - dstX1 &&
791          srcY0 - srcY1 == dstY0 - dstY1 &&
792          srcX1 >= srcX0 &&
793          srcY1 >= srcY0 &&
794          srcX0 >= 0 && srcX1 <= readFb->Width &&
795          srcY0 >= 0 && srcY1 <= readFb->Height &&
796          dstX0 >= 0 && dstX1 <= drawFb->Width &&
797          dstY0 >= 0 && dstY1 <= drawFb->Height &&
798          !ctx->Scissor.Enabled) {
799         const struct gl_texture_object *texObj = drawAtt->Texture;
800         const GLuint dstLevel = drawAtt->TextureLevel;
801         const GLenum target = texObj->Target;
802
803         struct gl_texture_image *texImage =
804            _mesa_select_tex_image(ctx, texObj, target, dstLevel);
805
806         if (intel_copy_texsubimage(intel_context(ctx),
807                                    intel_texture_image(texImage),
808                                    dstX0, dstY0,
809                                    srcRb,
810                                    srcX0, srcY0,
811                                    srcX1 - srcX0, /* width */
812                                    srcY1 - srcY0))
813            mask &= ~GL_COLOR_BUFFER_BIT;
814      }
815   }
816
817   return mask;
818}
819
820static void
821intel_blit_framebuffer(struct gl_context *ctx,
822                       GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
823                       GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
824                       GLbitfield mask, GLenum filter)
825{
826   /* Try faster, glCopyTexSubImage2D approach first which uses the BLT. */
827   mask = intel_blit_framebuffer_copy_tex_sub_image(ctx,
828                                                    srcX0, srcY0, srcX1, srcY1,
829                                                    dstX0, dstY0, dstX1, dstY1,
830                                                    mask, filter);
831   if (mask == 0x0)
832      return;
833
834   _mesa_meta_BlitFramebuffer(ctx,
835                              srcX0, srcY0, srcX1, srcY1,
836                              dstX0, dstY0, dstX1, dstY1,
837                              mask, filter);
838}
839
840void
841intel_renderbuffer_set_needs_hiz_resolve(struct intel_renderbuffer *irb)
842{
843   if (irb->mt) {
844      intel_miptree_slice_set_needs_hiz_resolve(irb->mt,
845                                                irb->mt_level,
846                                                irb->mt_layer);
847   }
848}
849
850void
851intel_renderbuffer_set_needs_depth_resolve(struct intel_renderbuffer *irb)
852{
853   if (irb->mt) {
854      intel_miptree_slice_set_needs_depth_resolve(irb->mt,
855                                                  irb->mt_level,
856                                                  irb->mt_layer);
857   }
858}
859
860bool
861intel_renderbuffer_resolve_hiz(struct intel_context *intel,
862			       struct intel_renderbuffer *irb)
863{
864   if (irb->mt)
865      return intel_miptree_slice_resolve_hiz(intel,
866                                             irb->mt,
867                                             irb->mt_level,
868                                             irb->mt_layer);
869
870   return false;
871}
872
873bool
874intel_renderbuffer_resolve_depth(struct intel_context *intel,
875				 struct intel_renderbuffer *irb)
876{
877   if (irb->mt)
878      return intel_miptree_slice_resolve_depth(intel,
879                                               irb->mt,
880                                               irb->mt_level,
881                                               irb->mt_layer);
882
883   return false;
884}
885
886/**
887 * Do one-time context initializations related to GL_EXT_framebuffer_object.
888 * Hook in device driver functions.
889 */
890void
891intel_fbo_init(struct intel_context *intel)
892{
893   intel->ctx.Driver.NewFramebuffer = intel_new_framebuffer;
894   intel->ctx.Driver.NewRenderbuffer = intel_new_renderbuffer;
895   intel->ctx.Driver.MapRenderbuffer = intel_map_renderbuffer;
896   intel->ctx.Driver.UnmapRenderbuffer = intel_unmap_renderbuffer;
897   intel->ctx.Driver.BindFramebuffer = intel_bind_framebuffer;
898   intel->ctx.Driver.FramebufferRenderbuffer = intel_framebuffer_renderbuffer;
899   intel->ctx.Driver.RenderTexture = intel_render_texture;
900   intel->ctx.Driver.FinishRenderTexture = intel_finish_render_texture;
901   intel->ctx.Driver.ResizeBuffers = intel_resize_buffers;
902   intel->ctx.Driver.ValidateFramebuffer = intel_validate_framebuffer;
903   intel->ctx.Driver.BlitFramebuffer = intel_blit_framebuffer;
904
905#if FEATURE_OES_EGL_image
906   intel->ctx.Driver.EGLImageTargetRenderbufferStorage =
907      intel_image_target_renderbuffer_storage;
908#endif
909}
910