intel_fbo.c revision db3ada6055814a4bd5aa95fc9505fc101864391d
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/imports.h"
30#include "main/macros.h"
31#include "main/mfeatures.h"
32#include "main/mtypes.h"
33#include "main/fbobject.h"
34#include "main/framebuffer.h"
35#include "main/renderbuffer.h"
36#include "main/context.h"
37#include "main/teximage.h"
38#include "swrast/swrast.h"
39#include "drivers/common/meta.h"
40
41#include "intel_context.h"
42#include "intel_batchbuffer.h"
43#include "intel_buffers.h"
44#include "intel_fbo.h"
45#include "intel_mipmap_tree.h"
46#include "intel_regions.h"
47#include "intel_tex.h"
48#include "intel_span.h"
49#ifndef I915
50#include "brw_context.h"
51#endif
52
53#define FILE_DEBUG_FLAG DEBUG_FBO
54
55
56/**
57 * Create a new framebuffer object.
58 */
59static struct gl_framebuffer *
60intel_new_framebuffer(struct gl_context * ctx, GLuint name)
61{
62   /* Only drawable state in intel_framebuffer at this time, just use Mesa's
63    * class
64    */
65   return _mesa_new_framebuffer(ctx, name);
66}
67
68
69/** Called by gl_renderbuffer::Delete() */
70static void
71intel_delete_renderbuffer(struct gl_renderbuffer *rb)
72{
73   struct intel_renderbuffer *irb = intel_renderbuffer(rb);
74
75   ASSERT(irb);
76
77   intel_region_release(&irb->region);
78   intel_region_release(&irb->hiz_region);
79
80   _mesa_reference_renderbuffer(&irb->wrapped_depth, NULL);
81   _mesa_reference_renderbuffer(&irb->wrapped_stencil, NULL);
82
83   free(irb);
84}
85
86
87/**
88 * Return a pointer to a specific pixel in a renderbuffer.
89 */
90static void *
91intel_get_pointer(struct gl_context * ctx, struct gl_renderbuffer *rb,
92                  GLint x, GLint y)
93{
94   /* By returning NULL we force all software rendering to go through
95    * the span routines.
96    */
97   return NULL;
98}
99
100
101/**
102 * Called via glRenderbufferStorageEXT() to set the format and allocate
103 * storage for a user-created renderbuffer.
104 */
105GLboolean
106intel_alloc_renderbuffer_storage(struct gl_context * ctx, struct gl_renderbuffer *rb,
107                                 GLenum internalFormat,
108                                 GLuint width, GLuint height)
109{
110   struct intel_context *intel = intel_context(ctx);
111   struct intel_renderbuffer *irb = intel_renderbuffer(rb);
112   int cpp, tiling;
113
114   ASSERT(rb->Name != 0);
115
116   switch (internalFormat) {
117   default:
118      /* Use the same format-choice logic as for textures.
119       * Renderbuffers aren't any different from textures for us,
120       * except they're less useful because you can't texture with
121       * them.
122       */
123      rb->Format = intel->ctx.Driver.ChooseTextureFormat(ctx, internalFormat,
124							 GL_NONE, GL_NONE);
125      break;
126   case GL_STENCIL_INDEX:
127   case GL_STENCIL_INDEX1_EXT:
128   case GL_STENCIL_INDEX4_EXT:
129   case GL_STENCIL_INDEX8_EXT:
130   case GL_STENCIL_INDEX16_EXT:
131      /* These aren't actual texture formats, so force them here. */
132      if (intel->has_separate_stencil) {
133	 rb->Format = MESA_FORMAT_S8;
134      } else {
135	 assert(!intel->must_use_separate_stencil);
136	 rb->Format = MESA_FORMAT_S8_Z24;
137      }
138      break;
139   }
140
141   rb->Width = width;
142   rb->Height = height;
143   rb->_BaseFormat = _mesa_base_fbo_format(ctx, internalFormat);
144   rb->DataType = intel_mesa_format_to_rb_datatype(rb->Format);
145   cpp = _mesa_get_format_bytes(rb->Format);
146
147   intel_flush(ctx);
148
149   /* free old region */
150   if (irb->region) {
151      intel_region_release(&irb->region);
152   }
153   if (irb->hiz_region) {
154      intel_region_release(&irb->hiz_region);
155   }
156
157   /* allocate new memory region/renderbuffer */
158
159   /* alloc hardware renderbuffer */
160   DBG("Allocating %d x %d Intel RBO\n", width, height);
161
162   tiling = I915_TILING_NONE;
163   if (intel->use_texture_tiling) {
164      GLenum base_format = _mesa_get_format_base_format(rb->Format);
165
166      if (intel->gen >= 4 && (base_format == GL_DEPTH_COMPONENT ||
167			      base_format == GL_STENCIL_INDEX ||
168			      base_format == GL_DEPTH_STENCIL))
169	 tiling = I915_TILING_Y;
170      else
171	 tiling = I915_TILING_X;
172   }
173
174   if (irb->Base.Format == MESA_FORMAT_S8) {
175      /*
176       * The stencil buffer is W tiled. However, we request from the kernel a
177       * non-tiled buffer because the GTT is incapable of W fencing.
178       *
179       * The stencil buffer has quirky pitch requirements.  From Vol 2a,
180       * 11.5.6.2.1 3DSTATE_STENCIL_BUFFER, field "Surface Pitch":
181       *    The pitch must be set to 2x the value computed based on width, as
182       *    the stencil buffer is stored with two rows interleaved.
183       * To accomplish this, we resort to the nasty hack of doubling the drm
184       * region's cpp and halving its height.
185       *
186       * If we neglect to double the pitch, then render corruption occurs.
187       */
188      irb->region = intel_region_alloc(intel->intelScreen,
189				       I915_TILING_NONE,
190				       cpp * 2,
191				       ALIGN(width, 64),
192				       ALIGN((height + 1) / 2, 64),
193				       GL_TRUE);
194      if (!irb->region)
195	return false;
196
197   } else if (irb->Base.Format == MESA_FORMAT_S8_Z24
198	      && intel->must_use_separate_stencil) {
199
200      bool ok = true;
201      struct gl_renderbuffer *depth_rb;
202      struct gl_renderbuffer *stencil_rb;
203
204      depth_rb = intel_create_wrapped_renderbuffer(ctx, width, height,
205						   MESA_FORMAT_X8_Z24);
206      stencil_rb = intel_create_wrapped_renderbuffer(ctx, width, height,
207						     MESA_FORMAT_S8);
208      ok = depth_rb && stencil_rb;
209      ok = ok && intel_alloc_renderbuffer_storage(ctx, depth_rb,
210						  depth_rb->InternalFormat,
211						  width, height);
212      ok = ok && intel_alloc_renderbuffer_storage(ctx, stencil_rb,
213						  stencil_rb->InternalFormat,
214						  width, height);
215
216      if (!ok) {
217	 if (depth_rb) {
218	    intel_delete_renderbuffer(depth_rb);
219	 }
220	 if (stencil_rb) {
221	    intel_delete_renderbuffer(stencil_rb);
222	 }
223	 return false;
224      }
225
226      depth_rb->Wrapped = rb;
227      stencil_rb->Wrapped = rb;
228      _mesa_reference_renderbuffer(&irb->wrapped_depth, depth_rb);
229      _mesa_reference_renderbuffer(&irb->wrapped_stencil, stencil_rb);
230
231   } else {
232      irb->region = intel_region_alloc(intel->intelScreen, tiling, cpp,
233				       width, height, GL_TRUE);
234      if (!irb->region)
235	 return false;
236
237      if (intel->vtbl.is_hiz_depth_format(intel, rb->Format)) {
238	 irb->hiz_region = intel_region_alloc(intel->intelScreen,
239					      I915_TILING_Y,
240					      irb->region->cpp,
241					      irb->region->width,
242					      irb->region->height,
243					      GL_TRUE);
244	 if (!irb->hiz_region) {
245	    intel_region_release(&irb->region);
246	    return false;
247	 }
248      }
249   }
250
251   return GL_TRUE;
252}
253
254
255#if FEATURE_OES_EGL_image
256static void
257intel_image_target_renderbuffer_storage(struct gl_context *ctx,
258					struct gl_renderbuffer *rb,
259					void *image_handle)
260{
261   struct intel_context *intel = intel_context(ctx);
262   struct intel_renderbuffer *irb;
263   __DRIscreen *screen;
264   __DRIimage *image;
265
266   screen = intel->intelScreen->driScrnPriv;
267   image = screen->dri2.image->lookupEGLImage(screen, image_handle,
268					      screen->loaderPrivate);
269   if (image == NULL)
270      return;
271
272   /* __DRIimage is opaque to the core so it has to be checked here */
273   switch (image->format) {
274   case MESA_FORMAT_RGBA8888_REV:
275      _mesa_error(&intel->ctx, GL_INVALID_OPERATION,
276            "glEGLImageTargetRenderbufferStorage(unsupported image format");
277      return;
278      break;
279   default:
280      break;
281   }
282
283   irb = intel_renderbuffer(rb);
284   intel_region_reference(&irb->region, image->region);
285
286   rb->InternalFormat = image->internal_format;
287   rb->Width = image->region->width;
288   rb->Height = image->region->height;
289   rb->Format = image->format;
290   rb->DataType = image->data_type;
291   rb->_BaseFormat = _mesa_base_fbo_format(&intel->ctx,
292					   image->internal_format);
293}
294#endif
295
296/**
297 * Called for each hardware renderbuffer when a _window_ is resized.
298 * Just update fields.
299 * Not used for user-created renderbuffers!
300 */
301static GLboolean
302intel_alloc_window_storage(struct gl_context * ctx, struct gl_renderbuffer *rb,
303                           GLenum internalFormat, GLuint width, GLuint height)
304{
305   ASSERT(rb->Name == 0);
306   rb->Width = width;
307   rb->Height = height;
308   rb->InternalFormat = internalFormat;
309
310   return GL_TRUE;
311}
312
313
314static void
315intel_resize_buffers(struct gl_context *ctx, struct gl_framebuffer *fb,
316		     GLuint width, GLuint height)
317{
318   int i;
319
320   _mesa_resize_framebuffer(ctx, fb, width, height);
321
322   fb->Initialized = GL_TRUE; /* XXX remove someday */
323
324   if (fb->Name != 0) {
325      return;
326   }
327
328
329   /* Make sure all window system renderbuffers are up to date */
330   for (i = BUFFER_FRONT_LEFT; i <= BUFFER_BACK_RIGHT; i++) {
331      struct gl_renderbuffer *rb = fb->Attachment[i].Renderbuffer;
332
333      /* only resize if size is changing */
334      if (rb && (rb->Width != width || rb->Height != height)) {
335	 rb->AllocStorage(ctx, rb, rb->InternalFormat, width, height);
336      }
337   }
338}
339
340
341/** Dummy function for gl_renderbuffer::AllocStorage() */
342static GLboolean
343intel_nop_alloc_storage(struct gl_context * ctx, struct gl_renderbuffer *rb,
344                        GLenum internalFormat, GLuint width, GLuint height)
345{
346   _mesa_problem(ctx, "intel_op_alloc_storage should never be called.");
347   return GL_FALSE;
348}
349
350/**
351 * Create a new intel_renderbuffer which corresponds to an on-screen window,
352 * not a user-created renderbuffer.
353 */
354struct intel_renderbuffer *
355intel_create_renderbuffer(gl_format format)
356{
357   GET_CURRENT_CONTEXT(ctx);
358
359   struct intel_renderbuffer *irb;
360
361   irb = CALLOC_STRUCT(intel_renderbuffer);
362   if (!irb) {
363      _mesa_error(ctx, GL_OUT_OF_MEMORY, "creating renderbuffer");
364      return NULL;
365   }
366
367   _mesa_init_renderbuffer(&irb->Base, 0);
368   irb->Base.ClassID = INTEL_RB_CLASS;
369   irb->Base._BaseFormat = _mesa_get_format_base_format(format);
370   irb->Base.Format = format;
371   irb->Base.InternalFormat = irb->Base._BaseFormat;
372   irb->Base.DataType = intel_mesa_format_to_rb_datatype(format);
373
374   /* intel-specific methods */
375   irb->Base.Delete = intel_delete_renderbuffer;
376   irb->Base.AllocStorage = intel_alloc_window_storage;
377   irb->Base.GetPointer = intel_get_pointer;
378
379   return irb;
380}
381
382
383struct gl_renderbuffer*
384intel_create_wrapped_renderbuffer(struct gl_context * ctx,
385				  int width, int height,
386				  gl_format format)
387{
388   /*
389    * The name here is irrelevant, as long as its nonzero, because the
390    * renderbuffer never gets entered into Mesa's renderbuffer hash table.
391    */
392   GLuint name = ~0;
393
394   struct intel_renderbuffer *irb = CALLOC_STRUCT(intel_renderbuffer);
395   if (!irb) {
396      _mesa_error(ctx, GL_OUT_OF_MEMORY, "creating renderbuffer");
397      return NULL;
398   }
399
400   struct gl_renderbuffer *rb = &irb->Base;
401   _mesa_init_renderbuffer(rb, name);
402   rb->ClassID = INTEL_RB_CLASS;
403   rb->_BaseFormat = _mesa_get_format_base_format(format);
404   rb->Format = format;
405   rb->InternalFormat = rb->_BaseFormat;
406   rb->DataType = intel_mesa_format_to_rb_datatype(format);
407   rb->Width = width;
408   rb->Height = height;
409
410   return rb;
411}
412
413
414/**
415 * Create a new renderbuffer object.
416 * Typically called via glBindRenderbufferEXT().
417 */
418static struct gl_renderbuffer *
419intel_new_renderbuffer(struct gl_context * ctx, GLuint name)
420{
421   /*struct intel_context *intel = intel_context(ctx); */
422   struct intel_renderbuffer *irb;
423
424   irb = CALLOC_STRUCT(intel_renderbuffer);
425   if (!irb) {
426      _mesa_error(ctx, GL_OUT_OF_MEMORY, "creating renderbuffer");
427      return NULL;
428   }
429
430   _mesa_init_renderbuffer(&irb->Base, name);
431   irb->Base.ClassID = INTEL_RB_CLASS;
432
433   /* intel-specific methods */
434   irb->Base.Delete = intel_delete_renderbuffer;
435   irb->Base.AllocStorage = intel_alloc_renderbuffer_storage;
436   irb->Base.GetPointer = intel_get_pointer;
437   /* span routines set in alloc_storage function */
438
439   return &irb->Base;
440}
441
442
443/**
444 * Called via glBindFramebufferEXT().
445 */
446static void
447intel_bind_framebuffer(struct gl_context * ctx, GLenum target,
448                       struct gl_framebuffer *fb, struct gl_framebuffer *fbread)
449{
450   if (target == GL_FRAMEBUFFER_EXT || target == GL_DRAW_FRAMEBUFFER_EXT) {
451      intel_draw_buffer(ctx);
452   }
453   else {
454      /* don't need to do anything if target == GL_READ_FRAMEBUFFER_EXT */
455   }
456}
457
458
459/**
460 * Called via glFramebufferRenderbufferEXT().
461 */
462static void
463intel_framebuffer_renderbuffer(struct gl_context * ctx,
464                               struct gl_framebuffer *fb,
465                               GLenum attachment, struct gl_renderbuffer *rb)
466{
467   DBG("Intel FramebufferRenderbuffer %u %u\n", fb->Name, rb ? rb->Name : 0);
468
469   intel_flush(ctx);
470
471   _mesa_framebuffer_renderbuffer(ctx, fb, attachment, rb);
472   intel_draw_buffer(ctx);
473}
474
475static bool
476intel_update_tex_wrapper_regions(struct intel_context *intel,
477				 struct intel_renderbuffer *irb,
478				 struct intel_texture_image *intel_image);
479
480static GLboolean
481intel_update_wrapper(struct gl_context *ctx, struct intel_renderbuffer *irb,
482		     struct gl_texture_image *texImage)
483{
484   struct intel_context *intel = intel_context(ctx);
485   struct intel_texture_image *intel_image = intel_texture_image(texImage);
486
487   if (!intel_span_supports_format(texImage->TexFormat)) {
488      DBG("Render to texture BAD FORMAT %s\n",
489	  _mesa_get_format_name(texImage->TexFormat));
490      return GL_FALSE;
491   } else {
492      DBG("Render to texture %s\n", _mesa_get_format_name(texImage->TexFormat));
493   }
494
495   irb->Base.Format = texImage->TexFormat;
496   irb->Base.DataType = intel_mesa_format_to_rb_datatype(texImage->TexFormat);
497   irb->Base.InternalFormat = texImage->InternalFormat;
498   irb->Base._BaseFormat = _mesa_base_tex_format(ctx, irb->Base.InternalFormat);
499   irb->Base.Width = texImage->Width;
500   irb->Base.Height = texImage->Height;
501
502   irb->Base.Delete = intel_delete_renderbuffer;
503   irb->Base.AllocStorage = intel_nop_alloc_storage;
504
505   if (intel_image->stencil_rb) {
506      /*  The tex image has packed depth/stencil format, but is using separate
507       * stencil. */
508
509      bool ok;
510      struct intel_renderbuffer *depth_irb =
511	 intel_renderbuffer(intel_image->depth_rb);
512
513      /* Update the hiz region if necessary. */
514      ok =  intel_update_tex_wrapper_regions(intel, depth_irb, intel_image);
515      if (!ok) {
516	 return false;
517      }
518
519      /* The tex image shares its embedded depth and stencil renderbuffers with
520       * the renderbuffer wrapper. */
521      _mesa_reference_renderbuffer(&irb->wrapped_depth,
522				   intel_image->depth_rb);
523      _mesa_reference_renderbuffer(&irb->wrapped_stencil,
524				   intel_image->stencil_rb);
525
526      return true;
527   } else {
528      return intel_update_tex_wrapper_regions(intel, irb, intel_image);
529   }
530}
531
532/**
533 * FIXME: The handling of the hiz region is broken for mipmapped depth textures
534 * FIXME: because intel_finalize_mipmap_tree is unaware of it.
535 */
536static bool
537intel_update_tex_wrapper_regions(struct intel_context *intel,
538				 struct intel_renderbuffer *irb,
539				 struct intel_texture_image *intel_image)
540{
541   struct gl_renderbuffer *rb = &irb->Base;
542
543   /* Point the renderbuffer's region to the texture's region. */
544   if (irb->region != intel_image->mt->region) {
545      intel_region_reference(&irb->region, intel_image->mt->region);
546   }
547
548   /* Allocate the texture's hiz region if necessary. */
549   if (intel->vtbl.is_hiz_depth_format(intel, rb->Format)
550       && !intel_image->mt->hiz_region) {
551      intel_image->mt->hiz_region =
552         intel_region_alloc(intel->intelScreen,
553                            I915_TILING_Y,
554                            _mesa_get_format_bytes(rb->Format),
555                            rb->Width,
556                            rb->Height,
557                            GL_TRUE);
558      if (!intel_image->mt->hiz_region)
559         return GL_FALSE;
560   }
561
562   /* Point the renderbuffer's hiz region to the texture's hiz region. */
563   if (irb->hiz_region != intel_image->mt->hiz_region) {
564      intel_region_reference(&irb->hiz_region, intel_image->mt->hiz_region);
565   }
566
567   return GL_TRUE;
568}
569
570
571/**
572 * When glFramebufferTexture[123]D is called this function sets up the
573 * gl_renderbuffer wrapper around the texture image.
574 * This will have the region info needed for hardware rendering.
575 */
576static struct intel_renderbuffer *
577intel_wrap_texture(struct gl_context * ctx, struct gl_texture_image *texImage)
578{
579   const GLuint name = ~0;   /* not significant, but distinct for debugging */
580   struct intel_renderbuffer *irb;
581
582   /* make an intel_renderbuffer to wrap the texture image */
583   irb = CALLOC_STRUCT(intel_renderbuffer);
584   if (!irb) {
585      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glFramebufferTexture");
586      return NULL;
587   }
588
589   _mesa_init_renderbuffer(&irb->Base, name);
590   irb->Base.ClassID = INTEL_RB_CLASS;
591
592   if (!intel_update_wrapper(ctx, irb, texImage)) {
593      free(irb);
594      return NULL;
595   }
596
597   return irb;
598}
599
600void
601intel_renderbuffer_set_draw_offset(struct intel_renderbuffer *irb,
602				   struct intel_texture_image *intel_image,
603				   int zoffset)
604{
605   unsigned int dst_x, dst_y;
606
607   /* compute offset of the particular 2D image within the texture region */
608   intel_miptree_get_image_offset(intel_image->mt,
609				  intel_image->base.Base.Level,
610				  intel_image->base.Base.Face,
611				  zoffset,
612				  &dst_x, &dst_y);
613
614   irb->draw_x = dst_x;
615   irb->draw_y = dst_y;
616}
617
618/**
619 * Rendering to tiled buffers requires that the base address of the
620 * buffer be aligned to a page boundary.  We generally render to
621 * textures by pointing the surface at the mipmap image level, which
622 * may not be aligned to a tile boundary.
623 *
624 * This function returns an appropriately-aligned base offset
625 * according to the tiling restrictions, plus any required x/y offset
626 * from there.
627 */
628uint32_t
629intel_renderbuffer_tile_offsets(struct intel_renderbuffer *irb,
630				uint32_t *tile_x,
631				uint32_t *tile_y)
632{
633   int cpp = irb->region->cpp;
634   uint32_t pitch = irb->region->pitch * cpp;
635
636   if (irb->region->tiling == I915_TILING_NONE) {
637      *tile_x = 0;
638      *tile_y = 0;
639      return irb->draw_x * cpp + irb->draw_y * pitch;
640   } else if (irb->region->tiling == I915_TILING_X) {
641      *tile_x = irb->draw_x % (512 / cpp);
642      *tile_y = irb->draw_y % 8;
643      return ((irb->draw_y / 8) * (8 * pitch) +
644	      (irb->draw_x - *tile_x) / (512 / cpp) * 4096);
645   } else {
646      assert(irb->region->tiling == I915_TILING_Y);
647      *tile_x = irb->draw_x % (128 / cpp);
648      *tile_y = irb->draw_y % 32;
649      return ((irb->draw_y / 32) * (32 * pitch) +
650	      (irb->draw_x - *tile_x) / (128 / cpp) * 4096);
651   }
652}
653
654#ifndef I915
655static bool
656need_tile_offset_workaround(struct brw_context *brw,
657			    struct intel_renderbuffer *irb)
658{
659   uint32_t tile_x, tile_y;
660
661   if (brw->has_surface_tile_offset)
662      return false;
663
664   intel_renderbuffer_tile_offsets(irb, &tile_x, &tile_y);
665
666   return tile_x != 0 || tile_y != 0;
667}
668#endif
669
670/**
671 * Called by glFramebufferTexture[123]DEXT() (and other places) to
672 * prepare for rendering into texture memory.  This might be called
673 * many times to choose different texture levels, cube faces, etc
674 * before intel_finish_render_texture() is ever called.
675 */
676static void
677intel_render_texture(struct gl_context * ctx,
678                     struct gl_framebuffer *fb,
679                     struct gl_renderbuffer_attachment *att)
680{
681   struct gl_texture_image *image = _mesa_get_attachment_teximage(att);
682   struct intel_renderbuffer *irb = intel_renderbuffer(att->Renderbuffer);
683   struct intel_texture_image *intel_image = intel_texture_image(image);
684
685   (void) fb;
686
687   if (!intel_image->mt) {
688      /* Fallback on drawing to a texture that doesn't have a miptree
689       * (has a border, width/height 0, etc.)
690       */
691      _mesa_reference_renderbuffer(&att->Renderbuffer, NULL);
692      _swrast_render_texture(ctx, fb, att);
693      return;
694   }
695   else if (!irb) {
696      irb = intel_wrap_texture(ctx, image);
697      if (irb) {
698         /* bind the wrapper to the attachment point */
699         _mesa_reference_renderbuffer(&att->Renderbuffer, &irb->Base);
700      }
701      else {
702         /* fallback to software rendering */
703         _swrast_render_texture(ctx, fb, att);
704         return;
705      }
706   }
707
708   if (!intel_update_wrapper(ctx, irb, image)) {
709       _mesa_reference_renderbuffer(&att->Renderbuffer, NULL);
710       _swrast_render_texture(ctx, fb, att);
711       return;
712   }
713
714   DBG("Begin render texture tid %lx tex=%u w=%d h=%d refcount=%d\n",
715       _glthread_GetID(),
716       att->Texture->Name, image->Width, image->Height,
717       irb->Base.RefCount);
718
719   intel_renderbuffer_set_draw_offset(irb, intel_image, att->Zoffset);
720   intel_image->used_as_render_target = GL_TRUE;
721
722#ifndef I915
723   if (need_tile_offset_workaround(brw_context(ctx), irb)) {
724      /* Original gen4 hardware couldn't draw to a non-tile-aligned
725       * destination in a miptree unless you actually setup your
726       * renderbuffer as a miptree and used the fragile
727       * lod/array_index/etc. controls to select the image.  So,
728       * instead, we just make a new single-level miptree and render
729       * into that.
730       */
731      struct intel_context *intel = intel_context(ctx);
732      struct intel_mipmap_tree *old_mt = intel_image->mt;
733      struct intel_mipmap_tree *new_mt;
734
735      new_mt = intel_miptree_create(intel, image->TexObject->Target,
736				    intel_image->base.Base.TexFormat,
737				    intel_image->base.Base.Level,
738				    intel_image->base.Base.Level,
739				    intel_image->base.Base.Width,
740				    intel_image->base.Base.Height,
741				    intel_image->base.Base.Depth,
742				    GL_TRUE);
743
744      intel_miptree_image_copy(intel,
745                               new_mt,
746			       intel_image->base.Base.Face,
747			       intel_image->base.Base.Level,
748			       old_mt);
749
750      intel_miptree_release(&intel_image->mt);
751      intel_image->mt = new_mt;
752      intel_renderbuffer_set_draw_offset(irb, intel_image, att->Zoffset);
753
754      intel_region_reference(&irb->region, intel_image->mt->region);
755   }
756#endif
757   /* update drawing region, etc */
758   intel_draw_buffer(ctx);
759}
760
761
762/**
763 * Called by Mesa when rendering to a texture is done.
764 */
765static void
766intel_finish_render_texture(struct gl_context * ctx,
767                            struct gl_renderbuffer_attachment *att)
768{
769   struct intel_context *intel = intel_context(ctx);
770   struct gl_texture_object *tex_obj = att->Texture;
771   struct gl_texture_image *image =
772      tex_obj->Image[att->CubeMapFace][att->TextureLevel];
773   struct intel_texture_image *intel_image = intel_texture_image(image);
774
775   DBG("Finish render texture tid %lx tex=%u\n",
776       _glthread_GetID(), att->Texture->Name);
777
778   /* Flag that this image may now be validated into the object's miptree. */
779   if (intel_image)
780      intel_image->used_as_render_target = GL_FALSE;
781
782   /* Since we've (probably) rendered to the texture and will (likely) use
783    * it in the texture domain later on in this batchbuffer, flush the
784    * batch.  Once again, we wish for a domain tracker in libdrm to cover
785    * usage inside of a batchbuffer like GEM does in the kernel.
786    */
787   intel_batchbuffer_emit_mi_flush(intel);
788}
789
790/**
791 * Do additional "completeness" testing of a framebuffer object.
792 */
793static void
794intel_validate_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb)
795{
796   struct intel_context *intel = intel_context(ctx);
797   const struct intel_renderbuffer *depthRb =
798      intel_get_renderbuffer(fb, BUFFER_DEPTH);
799   const struct intel_renderbuffer *stencilRb =
800      intel_get_renderbuffer(fb, BUFFER_STENCIL);
801   int i;
802
803   /*
804    * The depth and stencil renderbuffers are the same renderbuffer or wrap
805    * the same texture.
806    */
807   if (depthRb && stencilRb) {
808      bool depth_stencil_are_same;
809      if (depthRb == stencilRb)
810	 depth_stencil_are_same = true;
811      else if ((fb->Attachment[BUFFER_DEPTH].Type == GL_TEXTURE) &&
812	       (fb->Attachment[BUFFER_STENCIL].Type == GL_TEXTURE) &&
813	       (fb->Attachment[BUFFER_DEPTH].Texture->Name ==
814		fb->Attachment[BUFFER_STENCIL].Texture->Name))
815	 depth_stencil_are_same = true;
816      else
817	 depth_stencil_are_same = false;
818
819      if (!intel->has_separate_stencil && !depth_stencil_are_same) {
820	 fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
821      }
822   }
823
824   for (i = 0; i < Elements(fb->Attachment); i++) {
825      struct gl_renderbuffer *rb;
826      struct intel_renderbuffer *irb;
827
828      if (fb->Attachment[i].Type == GL_NONE)
829	 continue;
830
831      /* A supported attachment will have a Renderbuffer set either
832       * from being a Renderbuffer or being a texture that got the
833       * intel_wrap_texture() treatment.
834       */
835      rb = fb->Attachment[i].Renderbuffer;
836      if (rb == NULL) {
837	 DBG("attachment without renderbuffer\n");
838	 fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
839	 continue;
840      }
841
842      irb = intel_renderbuffer(rb);
843      if (irb == NULL) {
844	 DBG("software rendering renderbuffer\n");
845	 fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
846	 continue;
847      }
848
849      if (!intel_span_supports_format(irb->Base.Format) ||
850	  !intel->vtbl.render_target_supported(irb->Base.Format)) {
851	 DBG("Unsupported texture/renderbuffer format attached: %s\n",
852	     _mesa_get_format_name(irb->Base.Format));
853	 fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
854      }
855   }
856}
857
858/**
859 * Try to do a glBlitFramebuffer using glCopyTexSubImage2D
860 * We can do this when the dst renderbuffer is actually a texture and
861 * there is no scaling, mirroring or scissoring.
862 *
863 * \return new buffer mask indicating the buffers left to blit using the
864 *         normal path.
865 */
866static GLbitfield
867intel_blit_framebuffer_copy_tex_sub_image(struct gl_context *ctx,
868                                          GLint srcX0, GLint srcY0,
869                                          GLint srcX1, GLint srcY1,
870                                          GLint dstX0, GLint dstY0,
871                                          GLint dstX1, GLint dstY1,
872                                          GLbitfield mask, GLenum filter)
873{
874   if (mask & GL_COLOR_BUFFER_BIT) {
875      const struct gl_framebuffer *drawFb = ctx->DrawBuffer;
876      const struct gl_framebuffer *readFb = ctx->ReadBuffer;
877      const struct gl_renderbuffer_attachment *drawAtt =
878         &drawFb->Attachment[drawFb->_ColorDrawBufferIndexes[0]];
879
880      /* If the source and destination are the same size with no
881         mirroring, the rectangles are within the size of the
882         texture and there is no scissor then we can use
883         glCopyTexSubimage2D to implement the blit. This will end
884         up as a fast hardware blit on some drivers */
885      if (drawAtt && drawAtt->Texture &&
886          srcX0 - srcX1 == dstX0 - dstX1 &&
887          srcY0 - srcY1 == dstY0 - dstY1 &&
888          srcX1 >= srcX0 &&
889          srcY1 >= srcY0 &&
890          srcX0 >= 0 && srcX1 <= readFb->Width &&
891          srcY0 >= 0 && srcY1 <= readFb->Height &&
892          dstX0 >= 0 && dstX1 <= drawFb->Width &&
893          dstY0 >= 0 && dstY1 <= drawFb->Height &&
894          !ctx->Scissor.Enabled) {
895         const struct gl_texture_object *texObj = drawAtt->Texture;
896         const GLuint dstLevel = drawAtt->TextureLevel;
897         const GLenum target = texObj->Target;
898
899         struct gl_texture_image *texImage =
900            _mesa_select_tex_image(ctx, texObj, target, dstLevel);
901
902         if (intel_copy_texsubimage(intel_context(ctx),
903                                    intel_texture_image(texImage),
904                                    dstX0, dstY0,
905                                    srcX0, srcY0,
906                                    srcX1 - srcX0, /* width */
907                                    srcY1 - srcY0))
908            mask &= ~GL_COLOR_BUFFER_BIT;
909      }
910   }
911
912   return mask;
913}
914
915static void
916intel_blit_framebuffer(struct gl_context *ctx,
917                       GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
918                       GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
919                       GLbitfield mask, GLenum filter)
920{
921   /* Try faster, glCopyTexSubImage2D approach first which uses the BLT. */
922   mask = intel_blit_framebuffer_copy_tex_sub_image(ctx,
923                                                    srcX0, srcY0, srcX1, srcY1,
924                                                    dstX0, dstY0, dstX1, dstY1,
925                                                    mask, filter);
926   if (mask == 0x0)
927      return;
928
929   _mesa_meta_BlitFramebuffer(ctx,
930                              srcX0, srcY0, srcX1, srcY1,
931                              dstX0, dstY0, dstX1, dstY1,
932                              mask, filter);
933}
934
935/**
936 * Do one-time context initializations related to GL_EXT_framebuffer_object.
937 * Hook in device driver functions.
938 */
939void
940intel_fbo_init(struct intel_context *intel)
941{
942   intel->ctx.Driver.NewFramebuffer = intel_new_framebuffer;
943   intel->ctx.Driver.NewRenderbuffer = intel_new_renderbuffer;
944   intel->ctx.Driver.BindFramebuffer = intel_bind_framebuffer;
945   intel->ctx.Driver.FramebufferRenderbuffer = intel_framebuffer_renderbuffer;
946   intel->ctx.Driver.RenderTexture = intel_render_texture;
947   intel->ctx.Driver.FinishRenderTexture = intel_finish_render_texture;
948   intel->ctx.Driver.ResizeBuffers = intel_resize_buffers;
949   intel->ctx.Driver.ValidateFramebuffer = intel_validate_framebuffer;
950   intel->ctx.Driver.BlitFramebuffer = intel_blit_framebuffer;
951
952#if FEATURE_OES_EGL_image
953   intel->ctx.Driver.EGLImageTargetRenderbufferStorage =
954      intel_image_target_renderbuffer_storage;
955#endif
956}
957