intel_fbo.c revision f73caddd3339d284556036d031ab30ce8057a510
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   irb = intel_renderbuffer(rb);
273   intel_region_reference(&irb->region, image->region);
274
275   rb->InternalFormat = image->internal_format;
276   rb->Width = image->region->width;
277   rb->Height = image->region->height;
278   rb->Format = image->format;
279   rb->DataType = image->data_type;
280   rb->_BaseFormat = _mesa_base_fbo_format(&intel->ctx,
281					   image->internal_format);
282}
283#endif
284
285/**
286 * Called for each hardware renderbuffer when a _window_ is resized.
287 * Just update fields.
288 * Not used for user-created renderbuffers!
289 */
290static GLboolean
291intel_alloc_window_storage(struct gl_context * ctx, struct gl_renderbuffer *rb,
292                           GLenum internalFormat, GLuint width, GLuint height)
293{
294   ASSERT(rb->Name == 0);
295   rb->Width = width;
296   rb->Height = height;
297   rb->InternalFormat = internalFormat;
298
299   return GL_TRUE;
300}
301
302
303static void
304intel_resize_buffers(struct gl_context *ctx, struct gl_framebuffer *fb,
305		     GLuint width, GLuint height)
306{
307   int i;
308
309   _mesa_resize_framebuffer(ctx, fb, width, height);
310
311   fb->Initialized = GL_TRUE; /* XXX remove someday */
312
313   if (fb->Name != 0) {
314      return;
315   }
316
317
318   /* Make sure all window system renderbuffers are up to date */
319   for (i = BUFFER_FRONT_LEFT; i <= BUFFER_BACK_RIGHT; i++) {
320      struct gl_renderbuffer *rb = fb->Attachment[i].Renderbuffer;
321
322      /* only resize if size is changing */
323      if (rb && (rb->Width != width || rb->Height != height)) {
324	 rb->AllocStorage(ctx, rb, rb->InternalFormat, width, height);
325      }
326   }
327}
328
329
330/** Dummy function for gl_renderbuffer::AllocStorage() */
331static GLboolean
332intel_nop_alloc_storage(struct gl_context * ctx, struct gl_renderbuffer *rb,
333                        GLenum internalFormat, GLuint width, GLuint height)
334{
335   _mesa_problem(ctx, "intel_op_alloc_storage should never be called.");
336   return GL_FALSE;
337}
338
339/**
340 * Create a new intel_renderbuffer which corresponds to an on-screen window,
341 * not a user-created renderbuffer.
342 */
343struct intel_renderbuffer *
344intel_create_renderbuffer(gl_format format)
345{
346   GET_CURRENT_CONTEXT(ctx);
347
348   struct intel_renderbuffer *irb;
349
350   irb = CALLOC_STRUCT(intel_renderbuffer);
351   if (!irb) {
352      _mesa_error(ctx, GL_OUT_OF_MEMORY, "creating renderbuffer");
353      return NULL;
354   }
355
356   _mesa_init_renderbuffer(&irb->Base, 0);
357   irb->Base.ClassID = INTEL_RB_CLASS;
358   irb->Base._BaseFormat = _mesa_get_format_base_format(format);
359   irb->Base.Format = format;
360   irb->Base.InternalFormat = irb->Base._BaseFormat;
361   irb->Base.DataType = intel_mesa_format_to_rb_datatype(format);
362
363   /* intel-specific methods */
364   irb->Base.Delete = intel_delete_renderbuffer;
365   irb->Base.AllocStorage = intel_alloc_window_storage;
366   irb->Base.GetPointer = intel_get_pointer;
367
368   return irb;
369}
370
371
372struct gl_renderbuffer*
373intel_create_wrapped_renderbuffer(struct gl_context * ctx,
374				  int width, int height,
375				  gl_format format)
376{
377   /*
378    * The name here is irrelevant, as long as its nonzero, because the
379    * renderbuffer never gets entered into Mesa's renderbuffer hash table.
380    */
381   GLuint name = ~0;
382
383   struct intel_renderbuffer *irb = CALLOC_STRUCT(intel_renderbuffer);
384   if (!irb) {
385      _mesa_error(ctx, GL_OUT_OF_MEMORY, "creating renderbuffer");
386      return NULL;
387   }
388
389   struct gl_renderbuffer *rb = &irb->Base;
390   _mesa_init_renderbuffer(rb, name);
391   rb->ClassID = INTEL_RB_CLASS;
392   rb->_BaseFormat = _mesa_get_format_base_format(format);
393   rb->Format = format;
394   rb->InternalFormat = rb->_BaseFormat;
395   rb->DataType = intel_mesa_format_to_rb_datatype(format);
396   rb->Width = width;
397   rb->Height = height;
398
399   return rb;
400}
401
402
403/**
404 * Create a new renderbuffer object.
405 * Typically called via glBindRenderbufferEXT().
406 */
407static struct gl_renderbuffer *
408intel_new_renderbuffer(struct gl_context * ctx, GLuint name)
409{
410   /*struct intel_context *intel = intel_context(ctx); */
411   struct intel_renderbuffer *irb;
412
413   irb = CALLOC_STRUCT(intel_renderbuffer);
414   if (!irb) {
415      _mesa_error(ctx, GL_OUT_OF_MEMORY, "creating renderbuffer");
416      return NULL;
417   }
418
419   _mesa_init_renderbuffer(&irb->Base, name);
420   irb->Base.ClassID = INTEL_RB_CLASS;
421
422   /* intel-specific methods */
423   irb->Base.Delete = intel_delete_renderbuffer;
424   irb->Base.AllocStorage = intel_alloc_renderbuffer_storage;
425   irb->Base.GetPointer = intel_get_pointer;
426   /* span routines set in alloc_storage function */
427
428   return &irb->Base;
429}
430
431
432/**
433 * Called via glBindFramebufferEXT().
434 */
435static void
436intel_bind_framebuffer(struct gl_context * ctx, GLenum target,
437                       struct gl_framebuffer *fb, struct gl_framebuffer *fbread)
438{
439   if (target == GL_FRAMEBUFFER_EXT || target == GL_DRAW_FRAMEBUFFER_EXT) {
440      intel_draw_buffer(ctx, fb);
441   }
442   else {
443      /* don't need to do anything if target == GL_READ_FRAMEBUFFER_EXT */
444   }
445}
446
447
448/**
449 * Called via glFramebufferRenderbufferEXT().
450 */
451static void
452intel_framebuffer_renderbuffer(struct gl_context * ctx,
453                               struct gl_framebuffer *fb,
454                               GLenum attachment, struct gl_renderbuffer *rb)
455{
456   DBG("Intel FramebufferRenderbuffer %u %u\n", fb->Name, rb ? rb->Name : 0);
457
458   intel_flush(ctx);
459
460   _mesa_framebuffer_renderbuffer(ctx, fb, attachment, rb);
461   intel_draw_buffer(ctx, fb);
462}
463
464static bool
465intel_update_tex_wrapper_regions(struct intel_context *intel,
466				 struct intel_renderbuffer *irb,
467				 struct intel_texture_image *intel_image);
468
469static GLboolean
470intel_update_wrapper(struct gl_context *ctx, struct intel_renderbuffer *irb,
471		     struct gl_texture_image *texImage)
472{
473   struct intel_context *intel = intel_context(ctx);
474   struct intel_texture_image *intel_image = intel_texture_image(texImage);
475
476   if (!intel_span_supports_format(texImage->TexFormat)) {
477      DBG("Render to texture BAD FORMAT %s\n",
478	  _mesa_get_format_name(texImage->TexFormat));
479      return GL_FALSE;
480   } else {
481      DBG("Render to texture %s\n", _mesa_get_format_name(texImage->TexFormat));
482   }
483
484   irb->Base.Format = texImage->TexFormat;
485   irb->Base.DataType = intel_mesa_format_to_rb_datatype(texImage->TexFormat);
486   irb->Base.InternalFormat = texImage->InternalFormat;
487   irb->Base._BaseFormat = _mesa_base_tex_format(ctx, irb->Base.InternalFormat);
488   irb->Base.Width = texImage->Width;
489   irb->Base.Height = texImage->Height;
490
491   irb->Base.Delete = intel_delete_renderbuffer;
492   irb->Base.AllocStorage = intel_nop_alloc_storage;
493
494   if (intel_image->stencil_rb) {
495      /*  The tex image has packed depth/stencil format, but is using separate
496       * stencil. */
497
498      bool ok;
499      struct intel_renderbuffer *depth_irb =
500	 intel_renderbuffer(intel_image->depth_rb);
501
502      /* Update the hiz region if necessary. */
503      ok =  intel_update_tex_wrapper_regions(intel, depth_irb, intel_image);
504      if (!ok) {
505	 return false;
506      }
507
508      /* The tex image shares its embedded depth and stencil renderbuffers with
509       * the renderbuffer wrapper. */
510      if (irb->wrapped_depth != intel_image->depth_rb) {
511	 _mesa_reference_renderbuffer(&irb->wrapped_depth,
512				      intel_image->depth_rb);
513      }
514      if (irb->wrapped_stencil != intel_image->stencil_rb) {
515	 _mesa_reference_renderbuffer(&irb->wrapped_stencil,
516				      intel_image->stencil_rb);
517      }
518
519      return true;
520
521   } else {
522      return intel_update_tex_wrapper_regions(intel, irb, intel_image);
523   }
524}
525
526/**
527 * FIXME: The handling of the hiz region is broken for mipmapped depth textures
528 * FIXME: because intel_finalize_mipmap_tree is unaware of it.
529 */
530static bool
531intel_update_tex_wrapper_regions(struct intel_context *intel,
532				 struct intel_renderbuffer *irb,
533				 struct intel_texture_image *intel_image)
534{
535   struct gl_renderbuffer *rb = &irb->Base;
536
537   /* Point the renderbuffer's region to the texture's region. */
538   if (irb->region != intel_image->mt->region) {
539      intel_region_reference(&irb->region, intel_image->mt->region);
540   }
541
542   /* Allocate the texture's hiz region if necessary. */
543   if (intel->vtbl.is_hiz_depth_format(intel, rb->Format)
544       && !intel_image->mt->hiz_region) {
545      intel_image->mt->hiz_region =
546         intel_region_alloc(intel->intelScreen,
547                            I915_TILING_Y,
548                            _mesa_get_format_bytes(rb->Format),
549                            rb->Width,
550                            rb->Height,
551                            GL_TRUE);
552      if (!intel_image->mt->hiz_region)
553         return GL_FALSE;
554   }
555
556   /* Point the renderbuffer's hiz region to the texture's hiz region. */
557   if (irb->hiz_region != intel_image->mt->hiz_region) {
558      intel_region_reference(&irb->hiz_region, intel_image->mt->hiz_region);
559   }
560
561   return GL_TRUE;
562}
563
564
565/**
566 * When glFramebufferTexture[123]D is called this function sets up the
567 * gl_renderbuffer wrapper around the texture image.
568 * This will have the region info needed for hardware rendering.
569 */
570static struct intel_renderbuffer *
571intel_wrap_texture(struct gl_context * ctx, struct gl_texture_image *texImage)
572{
573   const GLuint name = ~0;   /* not significant, but distinct for debugging */
574   struct intel_renderbuffer *irb;
575
576   /* make an intel_renderbuffer to wrap the texture image */
577   irb = CALLOC_STRUCT(intel_renderbuffer);
578   if (!irb) {
579      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glFramebufferTexture");
580      return NULL;
581   }
582
583   _mesa_init_renderbuffer(&irb->Base, name);
584   irb->Base.ClassID = INTEL_RB_CLASS;
585
586   if (!intel_update_wrapper(ctx, irb, texImage)) {
587      free(irb);
588      return NULL;
589   }
590
591   return irb;
592}
593
594void
595intel_renderbuffer_set_draw_offset(struct intel_renderbuffer *irb,
596				   struct intel_texture_image *intel_image,
597				   int zoffset)
598{
599   struct intel_mipmap_tree *mt = intel_image->mt;
600   unsigned int dst_x, dst_y;
601
602   /* compute offset of the particular 2D image within the texture region */
603   intel_miptree_get_image_offset(intel_image->mt,
604				  intel_image->level,
605				  intel_image->face,
606				  zoffset,
607				  &dst_x, &dst_y);
608
609   irb->draw_x = dst_x;
610   irb->draw_y = dst_y;
611}
612
613/**
614 * Rendering to tiled buffers requires that the base address of the
615 * buffer be aligned to a page boundary.  We generally render to
616 * textures by pointing the surface at the mipmap image level, which
617 * may not be aligned to a tile boundary.
618 *
619 * This function returns an appropriately-aligned base offset
620 * according to the tiling restrictions, plus any required x/y offset
621 * from there.
622 */
623uint32_t
624intel_renderbuffer_tile_offsets(struct intel_renderbuffer *irb,
625				uint32_t *tile_x,
626				uint32_t *tile_y)
627{
628   int cpp = irb->region->cpp;
629   uint32_t pitch = irb->region->pitch * cpp;
630
631   if (irb->region->tiling == I915_TILING_NONE) {
632      *tile_x = 0;
633      *tile_y = 0;
634      return irb->draw_x * cpp + irb->draw_y * pitch;
635   } else if (irb->region->tiling == I915_TILING_X) {
636      *tile_x = irb->draw_x % (512 / cpp);
637      *tile_y = irb->draw_y % 8;
638      return ((irb->draw_y / 8) * (8 * pitch) +
639	      (irb->draw_x - *tile_x) / (512 / cpp) * 4096);
640   } else {
641      assert(irb->region->tiling == I915_TILING_Y);
642      *tile_x = irb->draw_x % (128 / cpp);
643      *tile_y = irb->draw_y % 32;
644      return ((irb->draw_y / 32) * (32 * pitch) +
645	      (irb->draw_x - *tile_x) / (128 / cpp) * 4096);
646   }
647}
648
649#ifndef I915
650static bool
651need_tile_offset_workaround(struct brw_context *brw,
652			    struct intel_renderbuffer *irb)
653{
654   uint32_t tile_x, tile_y;
655
656   if (brw->has_surface_tile_offset)
657      return false;
658
659   intel_renderbuffer_tile_offsets(irb, &tile_x, &tile_y);
660
661   return tile_x != 0 || tile_y != 0;
662}
663#endif
664
665/**
666 * Called by glFramebufferTexture[123]DEXT() (and other places) to
667 * prepare for rendering into texture memory.  This might be called
668 * many times to choose different texture levels, cube faces, etc
669 * before intel_finish_render_texture() is ever called.
670 */
671static void
672intel_render_texture(struct gl_context * ctx,
673                     struct gl_framebuffer *fb,
674                     struct gl_renderbuffer_attachment *att)
675{
676   struct gl_texture_image *image = _mesa_get_attachment_teximage(att);
677   struct intel_renderbuffer *irb = intel_renderbuffer(att->Renderbuffer);
678   struct intel_texture_image *intel_image = intel_texture_image(image);
679
680   (void) fb;
681
682   if (!intel_image->mt) {
683      /* Fallback on drawing to a texture that doesn't have a miptree
684       * (has a border, width/height 0, etc.)
685       */
686      _mesa_reference_renderbuffer(&att->Renderbuffer, NULL);
687      _swrast_render_texture(ctx, fb, att);
688      return;
689   }
690   else if (!irb) {
691      irb = intel_wrap_texture(ctx, image);
692      if (irb) {
693         /* bind the wrapper to the attachment point */
694         _mesa_reference_renderbuffer(&att->Renderbuffer, &irb->Base);
695      }
696      else {
697         /* fallback to software rendering */
698         _swrast_render_texture(ctx, fb, att);
699         return;
700      }
701   }
702
703   if (!intel_update_wrapper(ctx, irb, image)) {
704       _mesa_reference_renderbuffer(&att->Renderbuffer, NULL);
705       _swrast_render_texture(ctx, fb, att);
706       return;
707   }
708
709   DBG("Begin render texture tid %lx tex=%u w=%d h=%d refcount=%d\n",
710       _glthread_GetID(),
711       att->Texture->Name, image->Width, image->Height,
712       irb->Base.RefCount);
713
714   intel_renderbuffer_set_draw_offset(irb, intel_image, att->Zoffset);
715   intel_image->used_as_render_target = GL_TRUE;
716
717#ifndef I915
718   if (need_tile_offset_workaround(brw_context(ctx), irb)) {
719      /* Original gen4 hardware couldn't draw to a non-tile-aligned
720       * destination in a miptree unless you actually setup your
721       * renderbuffer as a miptree and used the fragile
722       * lod/array_index/etc. controls to select the image.  So,
723       * instead, we just make a new single-level miptree and render
724       * into that.
725       */
726      struct intel_context *intel = intel_context(ctx);
727      struct intel_mipmap_tree *old_mt = intel_image->mt;
728      struct intel_mipmap_tree *new_mt;
729
730      new_mt = intel_miptree_create(intel, image->TexObject->Target,
731				    intel_image->base.TexFormat,
732				    intel_image->level,
733				    intel_image->level,
734				    intel_image->base.Width,
735				    intel_image->base.Height,
736				    intel_image->base.Depth,
737				    GL_TRUE);
738
739      intel_miptree_image_copy(intel,
740                               new_mt,
741                               intel_image->face,
742			       intel_image->level,
743			       old_mt);
744
745      intel_miptree_release(intel, &intel_image->mt);
746      intel_image->mt = new_mt;
747      intel_renderbuffer_set_draw_offset(irb, intel_image, att->Zoffset);
748
749      intel_region_reference(&irb->region, intel_image->mt->region);
750   }
751#endif
752   /* update drawing region, etc */
753   intel_draw_buffer(ctx, fb);
754}
755
756
757/**
758 * Called by Mesa when rendering to a texture is done.
759 */
760static void
761intel_finish_render_texture(struct gl_context * ctx,
762                            struct gl_renderbuffer_attachment *att)
763{
764   struct intel_context *intel = intel_context(ctx);
765   struct gl_texture_object *tex_obj = att->Texture;
766   struct gl_texture_image *image =
767      tex_obj->Image[att->CubeMapFace][att->TextureLevel];
768   struct intel_texture_image *intel_image = intel_texture_image(image);
769
770   DBG("Finish render texture tid %lx tex=%u\n",
771       _glthread_GetID(), att->Texture->Name);
772
773   /* Flag that this image may now be validated into the object's miptree. */
774   if (intel_image)
775      intel_image->used_as_render_target = GL_FALSE;
776
777   /* Since we've (probably) rendered to the texture and will (likely) use
778    * it in the texture domain later on in this batchbuffer, flush the
779    * batch.  Once again, we wish for a domain tracker in libdrm to cover
780    * usage inside of a batchbuffer like GEM does in the kernel.
781    */
782   intel_batchbuffer_emit_mi_flush(intel);
783}
784
785/**
786 * Do additional "completeness" testing of a framebuffer object.
787 */
788static void
789intel_validate_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb)
790{
791   struct intel_context *intel = intel_context(ctx);
792   const struct intel_renderbuffer *depthRb =
793      intel_get_renderbuffer(fb, BUFFER_DEPTH);
794   const struct intel_renderbuffer *stencilRb =
795      intel_get_renderbuffer(fb, BUFFER_STENCIL);
796   int i;
797
798   /*
799    * The depth and stencil renderbuffers are the same renderbuffer or wrap
800    * the same texture.
801    */
802   if (depthRb && stencilRb) {
803      bool depth_stencil_are_same;
804      if (depthRb == stencilRb)
805	 depth_stencil_are_same = true;
806      else if ((fb->Attachment[BUFFER_DEPTH].Type == GL_TEXTURE) &&
807	       (fb->Attachment[BUFFER_STENCIL].Type == GL_TEXTURE) &&
808	       (fb->Attachment[BUFFER_DEPTH].Texture->Name ==
809		fb->Attachment[BUFFER_STENCIL].Texture->Name))
810	 depth_stencil_are_same = true;
811      else
812	 depth_stencil_are_same = false;
813
814      if (!intel->has_separate_stencil && !depth_stencil_are_same) {
815	 fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
816      }
817   }
818
819   for (i = 0; i < Elements(fb->Attachment); i++) {
820      struct gl_renderbuffer *rb;
821      struct intel_renderbuffer *irb;
822
823      if (fb->Attachment[i].Type == GL_NONE)
824	 continue;
825
826      /* A supported attachment will have a Renderbuffer set either
827       * from being a Renderbuffer or being a texture that got the
828       * intel_wrap_texture() treatment.
829       */
830      rb = fb->Attachment[i].Renderbuffer;
831      if (rb == NULL) {
832	 DBG("attachment without renderbuffer\n");
833	 fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
834	 continue;
835      }
836
837      irb = intel_renderbuffer(rb);
838      if (irb == NULL) {
839	 DBG("software rendering renderbuffer\n");
840	 fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
841	 continue;
842      }
843
844      if (!intel_span_supports_format(irb->Base.Format) ||
845	  !intel->vtbl.render_target_supported(irb->Base.Format)) {
846	 DBG("Unsupported texture/renderbuffer format attached: %s\n",
847	     _mesa_get_format_name(irb->Base.Format));
848	 fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
849      }
850   }
851}
852
853/**
854 * Try to do a glBlitFramebuffer using glCopyTexSubImage2D
855 * We can do this when the dst renderbuffer is actually a texture and
856 * there is no scaling, mirroring or scissoring.
857 *
858 * \return new buffer mask indicating the buffers left to blit using the
859 *         normal path.
860 */
861static GLbitfield
862intel_blit_framebuffer_copy_tex_sub_image(struct gl_context *ctx,
863                                          GLint srcX0, GLint srcY0,
864                                          GLint srcX1, GLint srcY1,
865                                          GLint dstX0, GLint dstY0,
866                                          GLint dstX1, GLint dstY1,
867                                          GLbitfield mask, GLenum filter)
868{
869   if (mask & GL_COLOR_BUFFER_BIT) {
870      const struct gl_framebuffer *drawFb = ctx->DrawBuffer;
871      const struct gl_framebuffer *readFb = ctx->ReadBuffer;
872      const struct gl_renderbuffer_attachment *drawAtt =
873         &drawFb->Attachment[drawFb->_ColorDrawBufferIndexes[0]];
874
875      /* If the source and destination are the same size with no
876         mirroring, the rectangles are within the size of the
877         texture and there is no scissor then we can use
878         glCopyTexSubimage2D to implement the blit. This will end
879         up as a fast hardware blit on some drivers */
880      if (drawAtt && drawAtt->Texture &&
881          srcX0 - srcX1 == dstX0 - dstX1 &&
882          srcY0 - srcY1 == dstY0 - dstY1 &&
883          srcX1 >= srcX0 &&
884          srcY1 >= srcY0 &&
885          srcX0 >= 0 && srcX1 <= readFb->Width &&
886          srcY0 >= 0 && srcY1 <= readFb->Height &&
887          dstX0 >= 0 && dstX1 <= drawFb->Width &&
888          dstY0 >= 0 && dstY1 <= drawFb->Height &&
889          !ctx->Scissor.Enabled) {
890         const struct gl_texture_object *texObj = drawAtt->Texture;
891         const GLuint dstLevel = drawAtt->TextureLevel;
892         const GLenum target = texObj->Target;
893
894         struct gl_texture_image *texImage =
895            _mesa_select_tex_image(ctx, texObj, target, dstLevel);
896         GLenum internalFormat = texImage->InternalFormat;
897
898         if (intel_copy_texsubimage(intel_context(ctx), target,
899                                    intel_texture_image(texImage),
900                                    internalFormat,
901                                    dstX0, dstY0,
902                                    srcX0, srcY0,
903                                    srcX1 - srcX0, /* width */
904                                    srcY1 - srcY0))
905            mask &= ~GL_COLOR_BUFFER_BIT;
906      }
907   }
908
909   return mask;
910}
911
912static void
913intel_blit_framebuffer(struct gl_context *ctx,
914                       GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
915                       GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
916                       GLbitfield mask, GLenum filter)
917{
918   /* Try faster, glCopyTexSubImage2D approach first which uses the BLT. */
919   mask = intel_blit_framebuffer_copy_tex_sub_image(ctx,
920                                                    srcX0, srcY0, srcX1, srcY1,
921                                                    dstX0, dstY0, dstX1, dstY1,
922                                                    mask, filter);
923   if (mask == 0x0)
924      return;
925
926   _mesa_meta_BlitFramebuffer(ctx,
927                              srcX0, srcY0, srcX1, srcY1,
928                              dstX0, dstY0, dstX1, dstY1,
929                              mask, filter);
930}
931
932/**
933 * Do one-time context initializations related to GL_EXT_framebuffer_object.
934 * Hook in device driver functions.
935 */
936void
937intel_fbo_init(struct intel_context *intel)
938{
939   intel->ctx.Driver.NewFramebuffer = intel_new_framebuffer;
940   intel->ctx.Driver.NewRenderbuffer = intel_new_renderbuffer;
941   intel->ctx.Driver.BindFramebuffer = intel_bind_framebuffer;
942   intel->ctx.Driver.FramebufferRenderbuffer = intel_framebuffer_renderbuffer;
943   intel->ctx.Driver.RenderTexture = intel_render_texture;
944   intel->ctx.Driver.FinishRenderTexture = intel_finish_render_texture;
945   intel->ctx.Driver.ResizeBuffers = intel_resize_buffers;
946   intel->ctx.Driver.ValidateFramebuffer = intel_validate_framebuffer;
947   intel->ctx.Driver.BlitFramebuffer = intel_blit_framebuffer;
948
949#if FEATURE_OES_EGL_image
950   intel->ctx.Driver.EGLImageTargetRenderbufferStorage =
951      intel_image_target_renderbuffer_storage;
952#endif
953}
954