intel_fbo.c revision 1383e56bd916f9fc4357a6224aac4e8c691303cb
1/**************************************************************************
2 *
3 * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
16 * of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 **************************************************************************/
27
28
29#include "main/enums.h"
30#include "main/imports.h"
31#include "main/macros.h"
32#include "main/mfeatures.h"
33#include "main/mtypes.h"
34#include "main/fbobject.h"
35#include "main/framebuffer.h"
36#include "main/renderbuffer.h"
37#include "main/context.h"
38#include "main/teximage.h"
39#include "main/image.h"
40
41#include "swrast/swrast.h"
42#include "drivers/common/meta.h"
43
44#include "intel_context.h"
45#include "intel_batchbuffer.h"
46#include "intel_buffers.h"
47#include "intel_blit.h"
48#include "intel_fbo.h"
49#include "intel_mipmap_tree.h"
50#include "intel_regions.h"
51#include "intel_tex.h"
52#include "intel_span.h"
53#ifndef I915
54#include "brw_context.h"
55#endif
56
57#define FILE_DEBUG_FLAG DEBUG_FBO
58
59
60bool
61intel_framebuffer_has_hiz(struct gl_framebuffer *fb)
62{
63   struct intel_renderbuffer *rb = NULL;
64   if (fb)
65      rb = intel_get_renderbuffer(fb, BUFFER_DEPTH);
66   return rb && rb->mt && rb->mt->hiz_mt;
67}
68
69struct intel_region*
70intel_get_rb_region(struct gl_framebuffer *fb, GLuint attIndex)
71{
72   struct intel_renderbuffer *irb = intel_get_renderbuffer(fb, attIndex);
73   if (irb && irb->mt)
74      return irb->mt->region;
75   else
76      return NULL;
77}
78
79/**
80 * Create a new framebuffer object.
81 */
82static struct gl_framebuffer *
83intel_new_framebuffer(struct gl_context * ctx, GLuint name)
84{
85   /* Only drawable state in intel_framebuffer at this time, just use Mesa's
86    * class
87    */
88   return _mesa_new_framebuffer(ctx, name);
89}
90
91
92/** Called by gl_renderbuffer::Delete() */
93static void
94intel_delete_renderbuffer(struct gl_renderbuffer *rb)
95{
96   struct intel_renderbuffer *irb = intel_renderbuffer(rb);
97
98   ASSERT(irb);
99
100   intel_miptree_release(&irb->mt);
101
102   _mesa_reference_renderbuffer(&irb->wrapped_depth, NULL);
103   _mesa_reference_renderbuffer(&irb->wrapped_stencil, NULL);
104
105   free(irb);
106}
107
108/**
109 * \brief Map a renderbuffer through the GTT.
110 *
111 * \see intel_map_renderbuffer()
112 */
113static void
114intel_map_renderbuffer_gtt(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 intel_renderbuffer *irb = intel_renderbuffer(rb);
123   GLubyte *map;
124   int stride, flip_stride;
125
126   assert(irb->mt);
127
128   irb->map_mode = mode;
129   irb->map_x = x;
130   irb->map_y = y;
131   irb->map_w = w;
132   irb->map_h = h;
133
134   stride = irb->mt->region->pitch * irb->mt->region->cpp;
135
136   if (rb->Name == 0) {
137      y = irb->mt->region->height - 1 - y;
138      flip_stride = -stride;
139   } else {
140      x += irb->draw_x;
141      y += irb->draw_y;
142      flip_stride = stride;
143   }
144
145   if (drm_intel_bo_references(intel->batch.bo, irb->mt->region->bo)) {
146      intel_batchbuffer_flush(intel);
147   }
148
149   drm_intel_gem_bo_map_gtt(irb->mt->region->bo);
150
151   map = irb->mt->region->bo->virtual;
152   map += x * irb->mt->region->cpp;
153   map += (int)y * stride;
154
155   *out_map = map;
156   *out_stride = flip_stride;
157
158   DBG("%s: rb %d (%s) gtt mapped: (%d, %d) (%dx%d) -> %p/%d\n",
159       __FUNCTION__, rb->Name, _mesa_get_format_name(rb->Format),
160       x, y, w, h, *out_map, *out_stride);
161}
162
163/**
164 * \brief Map a renderbuffer by blitting it to a temporary gem buffer.
165 *
166 * On gen6+, we have LLC sharing, which means we can get high-performance
167 * access to linear-mapped buffers.
168 *
169 * This function allocates a temporary gem buffer at
170 * intel_renderbuffer::map_bo, then blits the renderbuffer into it, and
171 * returns a map of that. (Note: Only X tiled buffers can be blitted).
172 *
173 * \see intel_renderbuffer::map_bo
174 * \see intel_map_renderbuffer()
175 */
176static void
177intel_map_renderbuffer_blit(struct gl_context *ctx,
178			    struct gl_renderbuffer *rb,
179			    GLuint x, GLuint y, GLuint w, GLuint h,
180			    GLbitfield mode,
181			    GLubyte **out_map,
182			    GLint *out_stride)
183{
184   struct intel_context *intel = intel_context(ctx);
185   struct intel_renderbuffer *irb = intel_renderbuffer(rb);
186
187   int src_x, src_y;
188   int dst_stride;
189
190   assert(irb->mt->region);
191   assert(intel->gen >= 6);
192   assert(!(mode & GL_MAP_WRITE_BIT));
193   assert(irb->mt->region->tiling == I915_TILING_X);
194
195   irb->map_mode = mode;
196   irb->map_x = x;
197   irb->map_y = y;
198   irb->map_w = w;
199   irb->map_h = h;
200
201   dst_stride = ALIGN(w * irb->mt->region->cpp, 4);
202
203   if (rb->Name) {
204      src_x = x + irb->draw_x;
205      src_y = y + irb->draw_y;
206   } else {
207      src_x = x;
208      src_y = irb->mt->region->height - y - h;
209   }
210
211   irb->map_bo = drm_intel_bo_alloc(intel->bufmgr, "MapRenderbuffer() temp",
212				    dst_stride * h, 4096);
213
214   /* We don't do the flip in the blit, because it's always so tricky to get
215    * right.
216    */
217   if (irb->map_bo &&
218       intelEmitCopyBlit(intel,
219			 irb->mt->region->cpp,
220			 irb->mt->region->pitch, irb->mt->region->bo,
221			 0, irb->mt->region->tiling,
222			 dst_stride / irb->mt->region->cpp, irb->map_bo,
223			 0, I915_TILING_NONE,
224			 src_x, src_y,
225			 0, 0,
226			 w, h,
227			 GL_COPY)) {
228      intel_batchbuffer_flush(intel);
229      drm_intel_bo_map(irb->map_bo, false);
230
231      if (rb->Name) {
232	 *out_map = irb->map_bo->virtual;
233	 *out_stride = dst_stride;
234      } else {
235	 *out_map = irb->map_bo->virtual + (h - 1) * dst_stride;
236	 *out_stride = -dst_stride;
237      }
238
239      DBG("%s: rb %d (%s) blit mapped: (%d, %d) (%dx%d) -> %p/%d\n",
240	  __FUNCTION__, rb->Name, _mesa_get_format_name(rb->Format),
241	  src_x, src_y, w, h, *out_map, *out_stride);
242   } else {
243      /* Fallback to GTT mapping. */
244      drm_intel_bo_unreference(irb->map_bo);
245      irb->map_bo = NULL;
246      intel_map_renderbuffer_gtt(ctx, rb,
247				 x, y, w, h,
248				 mode,
249				 out_map, out_stride);
250   }
251}
252
253/**
254 * \brief Map a stencil renderbuffer.
255 *
256 * Stencil buffers are W-tiled. Since the GTT has no W fence, we must detile
257 * the buffer in software.
258 *
259 * This function allocates a temporary malloc'd buffer at
260 * intel_renderbuffer::map_buffer, detiles the stencil buffer into it, then
261 * returns the temporary buffer as the map.
262 *
263 * \see intel_renderbuffer::map_buffer
264 * \see intel_map_renderbuffer()
265 * \see intel_unmap_renderbuffer_s8()
266 */
267static void
268intel_map_renderbuffer_s8(struct gl_context *ctx,
269			  struct gl_renderbuffer *rb,
270			  GLuint x, GLuint y, GLuint w, GLuint h,
271			  GLbitfield mode,
272			  GLubyte **out_map,
273			  GLint *out_stride)
274{
275   struct intel_context *intel = intel_context(ctx);
276   struct intel_renderbuffer *irb = intel_renderbuffer(rb);
277   uint8_t *tiled_s8_map;
278   uint8_t *untiled_s8_map;
279
280   assert(rb->Format == MESA_FORMAT_S8);
281   assert(irb->mt);
282
283   irb->map_mode = mode;
284   irb->map_x = x;
285   irb->map_y = y;
286   irb->map_w = w;
287   irb->map_h = h;
288
289   /* Flip the Y axis for the default framebuffer. */
290   int y_flip = (rb->Name == 0) ? -1 : 1;
291   int y_bias = (rb->Name == 0) ? (rb->Height - 1) : 0;
292
293   irb->map_buffer = malloc(w * h);
294   untiled_s8_map = irb->map_buffer;
295   tiled_s8_map = intel_region_map(intel, irb->mt->region, mode);
296
297   for (uint32_t pix_y = 0; pix_y < h; pix_y++) {
298      for (uint32_t pix_x = 0; pix_x < w; pix_x++) {
299	 uint32_t flipped_y = y_flip * (int32_t)(y + pix_y) + y_bias;
300	 ptrdiff_t offset = intel_offset_S8(irb->mt->region->pitch,
301	                                    x + pix_x,
302	                                    flipped_y);
303	 untiled_s8_map[pix_y * w + pix_x] = tiled_s8_map[offset];
304      }
305   }
306
307   *out_map = untiled_s8_map;
308   *out_stride = w;
309
310   DBG("%s: rb %d (%s) s8 detiled mapped: (%d, %d) (%dx%d) -> %p/%d\n",
311       __FUNCTION__, rb->Name, _mesa_get_format_name(rb->Format),
312       x, y, w, h, *out_map, *out_stride);
313}
314
315/**
316 * \brief Map a depthstencil buffer with separate stencil.
317 *
318 * A depthstencil renderbuffer, if using separate stencil, consists of a depth
319 * renderbuffer and a hidden stencil renderbuffer.  This function maps the
320 * depth buffer, whose format is MESA_FORMAT_X8_Z24, through the GTT and
321 * returns that as the mapped pointer. The caller need not be aware of the
322 * hidden stencil buffer and may safely assume that the mapped pointer points
323 * to a MESA_FORMAT_S8_Z24 buffer
324 *
325 * The consistency between the depth buffer's S8 bits and the hidden stencil
326 * buffer is managed within intel_map_renderbuffer() and
327 * intel_unmap_renderbuffer() by scattering or gathering the stencil bits
328 * according to the map mode.
329 *
330 * \see intel_map_renderbuffer()
331 * \see intel_unmap_renderbuffer_separate_s8z24()
332 */
333static void
334intel_map_renderbuffer_separate_s8z24(struct gl_context *ctx,
335				      struct gl_renderbuffer *rb,
336				      GLuint x, GLuint y, GLuint w, GLuint h,
337				      GLbitfield mode,
338				      GLubyte **out_map,
339				      GLint *out_stride)
340{
341   struct intel_context *intel = intel_context(ctx);
342   struct intel_renderbuffer *irb = intel_renderbuffer(rb);
343
344   uint8_t *s8z24_map;
345   int32_t s8z24_stride;
346
347   struct intel_renderbuffer *s8_irb;
348   uint8_t *s8_map;
349
350   assert(rb->Name != 0);
351   assert(rb->Format == MESA_FORMAT_S8_Z24);
352   assert(irb->wrapped_depth != NULL);
353   assert(irb->wrapped_stencil != NULL);
354
355   irb->map_mode = mode;
356   irb->map_x = x;
357   irb->map_y = y;
358   irb->map_w = w;
359   irb->map_h = h;
360
361   /* Map with write mode for the gather below. */
362   intel_map_renderbuffer_gtt(ctx, irb->wrapped_depth,
363			       x, y, w, h, mode | GL_MAP_WRITE_BIT,
364			       &s8z24_map, &s8z24_stride);
365
366   s8_irb = intel_renderbuffer(irb->wrapped_stencil);
367   s8_map = intel_region_map(intel, s8_irb->mt->region, GL_MAP_READ_BIT);
368
369   /* Gather the stencil buffer into the depth buffer. */
370   for (uint32_t pix_y = 0; pix_y < h; ++pix_y) {
371      for (uint32_t pix_x = 0; pix_x < w; ++pix_x) {
372	 ptrdiff_t s8_offset = intel_offset_S8(s8_irb->mt->region->pitch,
373					       x + pix_x,
374					       y + pix_y);
375	 ptrdiff_t s8z24_offset = pix_y * s8z24_stride
376				+ pix_x * 4
377				+ 3;
378	 s8z24_map[s8z24_offset] = s8_map[s8_offset];
379      }
380   }
381
382   intel_region_unmap(intel, s8_irb->mt->region);
383
384   *out_map = s8z24_map;
385   *out_stride = s8z24_stride;
386}
387
388/**
389 * \see dd_function_table::MapRenderbuffer
390 */
391static void
392intel_map_renderbuffer(struct gl_context *ctx,
393		       struct gl_renderbuffer *rb,
394		       GLuint x, GLuint y, GLuint w, GLuint h,
395		       GLbitfield mode,
396		       GLubyte **out_map,
397		       GLint *out_stride)
398{
399   struct intel_context *intel = intel_context(ctx);
400   struct intel_renderbuffer *irb = intel_renderbuffer(rb);
401
402   /* We sometimes get called with this by our intel_span.c usage. */
403   if (!irb->mt && !irb->wrapped_depth) {
404      *out_map = NULL;
405      *out_stride = 0;
406      return;
407   }
408
409   if (rb->Format == MESA_FORMAT_S8) {
410      intel_map_renderbuffer_s8(ctx, rb, x, y, w, h, mode,
411			        out_map, out_stride);
412   } else if (irb->wrapped_depth) {
413      intel_map_renderbuffer_separate_s8z24(ctx, rb, x, y, w, h, mode,
414					    out_map, out_stride);
415   } else if (intel->gen >= 6 &&
416	      !(mode & GL_MAP_WRITE_BIT) &&
417	      irb->mt->region->tiling == I915_TILING_X) {
418      intel_map_renderbuffer_blit(ctx, rb, x, y, w, h, mode,
419				  out_map, out_stride);
420   } else {
421      intel_map_renderbuffer_gtt(ctx, rb, x, y, w, h, mode,
422				 out_map, out_stride);
423   }
424}
425
426/**
427 * \see intel_map_renderbuffer_s8()
428 */
429static void
430intel_unmap_renderbuffer_s8(struct gl_context *ctx,
431			    struct gl_renderbuffer *rb)
432{
433   struct intel_context *intel = intel_context(ctx);
434   struct intel_renderbuffer *irb = intel_renderbuffer(rb);
435
436   DBG("%s: rb %d (%s)\n", __FUNCTION__,
437       rb->Name, _mesa_get_format_name(rb->Format));
438
439   assert(rb->Format == MESA_FORMAT_S8);
440
441   if (!irb->map_buffer)
442      return;
443
444   if (irb->map_mode & GL_MAP_WRITE_BIT) {
445      /* The temporary buffer was written to, so we must copy its pixels into
446       * the real buffer.
447       */
448      uint8_t *untiled_s8_map = irb->map_buffer;
449      uint8_t *tiled_s8_map = irb->mt->region->bo->virtual;
450
451      /* Flip the Y axis for the default framebuffer. */
452      int y_flip = (rb->Name == 0) ? -1 : 1;
453      int y_bias = (rb->Name == 0) ? (rb->Height - 1) : 0;
454
455      for (uint32_t pix_y = 0; pix_y < irb->map_h; pix_y++) {
456	 for (uint32_t pix_x = 0; pix_x < irb->map_w; pix_x++) {
457	    uint32_t flipped_y = y_flip * (int32_t)(pix_y + irb->map_y) + y_bias;
458	    ptrdiff_t offset = intel_offset_S8(irb->mt->region->pitch,
459	                                       pix_x + irb->map_x,
460	                                       flipped_y);
461	    tiled_s8_map[offset] =
462	       untiled_s8_map[pix_y * irb->map_w + pix_x];
463	 }
464      }
465   }
466
467   intel_region_unmap(intel, irb->mt->region);
468   free(irb->map_buffer);
469   irb->map_buffer = NULL;
470}
471
472/**
473 * \brief Unmap a depthstencil renderbuffer with separate stencil.
474 *
475 * \see intel_map_renderbuffer_separate_s8z24()
476 * \see intel_unmap_renderbuffer()
477 */
478static void
479intel_unmap_renderbuffer_separate_s8z24(struct gl_context *ctx,
480				        struct gl_renderbuffer *rb)
481{
482   struct intel_context *intel = intel_context(ctx);
483   struct intel_renderbuffer *irb = intel_renderbuffer(rb);
484   struct intel_renderbuffer *s8z24_irb;
485
486   assert(rb->Name != 0);
487   assert(rb->Format == MESA_FORMAT_S8_Z24);
488   assert(irb->wrapped_depth != NULL);
489   assert(irb->wrapped_stencil != NULL);
490
491   s8z24_irb = intel_renderbuffer(irb->wrapped_depth);
492
493   if (irb->map_mode & GL_MAP_WRITE_BIT) {
494      /* Copy the stencil bits from the depth buffer into the stencil buffer.
495       */
496      uint32_t map_x = irb->map_x;
497      uint32_t map_y = irb->map_y;
498      uint32_t map_w = irb->map_w;
499      uint32_t map_h = irb->map_h;
500
501      struct intel_renderbuffer *s8_irb;
502      uint8_t *s8_map;
503
504      s8_irb = intel_renderbuffer(irb->wrapped_stencil);
505      s8_map = intel_region_map(intel, s8_irb->mt->region, GL_MAP_WRITE_BIT);
506
507      int32_t s8z24_stride = 4 * s8z24_irb->mt->region->pitch;
508      uint8_t *s8z24_map = s8z24_irb->mt->region->bo->virtual
509			 + map_y * s8z24_stride
510			 + map_x * 4;
511
512      for (uint32_t pix_y = 0; pix_y < map_h; ++pix_y) {
513	 for (uint32_t pix_x = 0; pix_x < map_w; ++pix_x) {
514	    ptrdiff_t s8_offset = intel_offset_S8(s8_irb->mt->region->pitch,
515						  map_x + pix_x,
516						  map_y + pix_y);
517	    ptrdiff_t s8z24_offset = pix_y * s8z24_stride
518				   + pix_x * 4
519				   + 3;
520	    s8_map[s8_offset] = s8z24_map[s8z24_offset];
521	 }
522      }
523
524      intel_region_unmap(intel, s8_irb->mt->region);
525   }
526
527   drm_intel_gem_bo_unmap_gtt(s8z24_irb->mt->region->bo);
528}
529
530/**
531 * \see dd_function_table::UnmapRenderbuffer
532 */
533static void
534intel_unmap_renderbuffer(struct gl_context *ctx,
535			 struct gl_renderbuffer *rb)
536{
537   struct intel_renderbuffer *irb = intel_renderbuffer(rb);
538
539   DBG("%s: rb %d (%s)\n", __FUNCTION__,
540       rb->Name, _mesa_get_format_name(rb->Format));
541
542   if (rb->Format == MESA_FORMAT_S8) {
543      intel_unmap_renderbuffer_s8(ctx, rb);
544   } else if (irb->wrapped_depth) {
545      intel_unmap_renderbuffer_separate_s8z24(ctx, rb);
546   } else if (irb->map_bo) {
547      /* Paired with intel_map_renderbuffer_blit(). */
548      drm_intel_bo_unmap(irb->map_bo);
549      drm_intel_bo_unreference(irb->map_bo);
550      irb->map_bo = 0;
551   } else {
552      /* Paired with intel_map_renderbuffer_gtt(). */
553      if (irb->mt) {
554	 /* The miptree may be null when intel_map_renderbuffer() is
555	  * called from intel_span.c.
556	  */
557	 drm_intel_gem_bo_unmap_gtt(irb->mt->region->bo);
558      }
559   }
560}
561
562/**
563 * Return a pointer to a specific pixel in a renderbuffer.
564 */
565static void *
566intel_get_pointer(struct gl_context * ctx, struct gl_renderbuffer *rb,
567                  GLint x, GLint y)
568{
569   /* By returning NULL we force all software rendering to go through
570    * the span routines.
571    */
572   return NULL;
573}
574
575
576/**
577 * Called via glRenderbufferStorageEXT() to set the format and allocate
578 * storage for a user-created renderbuffer.
579 */
580GLboolean
581intel_alloc_renderbuffer_storage(struct gl_context * ctx, struct gl_renderbuffer *rb,
582                                 GLenum internalFormat,
583                                 GLuint width, GLuint height)
584{
585   struct intel_context *intel = intel_context(ctx);
586   struct intel_renderbuffer *irb = intel_renderbuffer(rb);
587   int cpp, tiling;
588
589   ASSERT(rb->Name != 0);
590
591   switch (internalFormat) {
592   default:
593      /* Use the same format-choice logic as for textures.
594       * Renderbuffers aren't any different from textures for us,
595       * except they're less useful because you can't texture with
596       * them.
597       */
598      rb->Format = intel->ctx.Driver.ChooseTextureFormat(ctx, internalFormat,
599							 GL_NONE, GL_NONE);
600      break;
601   case GL_STENCIL_INDEX:
602   case GL_STENCIL_INDEX1_EXT:
603   case GL_STENCIL_INDEX4_EXT:
604   case GL_STENCIL_INDEX8_EXT:
605   case GL_STENCIL_INDEX16_EXT:
606      /* These aren't actual texture formats, so force them here. */
607      if (intel->has_separate_stencil) {
608	 rb->Format = MESA_FORMAT_S8;
609      } else {
610	 assert(!intel->must_use_separate_stencil);
611	 rb->Format = MESA_FORMAT_S8_Z24;
612      }
613      break;
614   }
615
616   rb->Width = width;
617   rb->Height = height;
618   rb->_BaseFormat = _mesa_base_fbo_format(ctx, internalFormat);
619   rb->DataType = intel_mesa_format_to_rb_datatype(rb->Format);
620   cpp = _mesa_get_format_bytes(rb->Format);
621
622   intel_flush(ctx);
623
624   intel_miptree_release(&irb->mt);
625
626   DBG("%s: %s: %s (%dx%d)\n", __FUNCTION__,
627       _mesa_lookup_enum_by_nr(internalFormat),
628       _mesa_get_format_name(rb->Format), width, height);
629
630   tiling = I915_TILING_NONE;
631   if (intel->use_texture_tiling) {
632      GLenum base_format = _mesa_get_format_base_format(rb->Format);
633
634      if (intel->gen >= 4 && (base_format == GL_DEPTH_COMPONENT ||
635			      base_format == GL_STENCIL_INDEX ||
636			      base_format == GL_DEPTH_STENCIL))
637	 tiling = I915_TILING_Y;
638      else
639	 tiling = I915_TILING_X;
640   }
641
642   if (irb->Base.Format == MESA_FORMAT_S8) {
643      /*
644       * The stencil buffer is W tiled. However, we request from the kernel a
645       * non-tiled buffer because the GTT is incapable of W fencing.
646       *
647       * The stencil buffer has quirky pitch requirements.  From Vol 2a,
648       * 11.5.6.2.1 3DSTATE_STENCIL_BUFFER, field "Surface Pitch":
649       *    The pitch must be set to 2x the value computed based on width, as
650       *    the stencil buffer is stored with two rows interleaved.
651       * To accomplish this, we resort to the nasty hack of doubling the drm
652       * region's cpp and halving its height.
653       *
654       * If we neglect to double the pitch, then render corruption occurs.
655       */
656      irb->mt = intel_miptree_create_for_renderbuffer(
657		  intel,
658		  rb->Format,
659		  I915_TILING_NONE,
660		  cpp * 2,
661		  ALIGN(width, 64),
662		  ALIGN((height + 1) / 2, 64));
663      if (!irb->mt)
664	 return false;
665
666   } else if (irb->Base.Format == MESA_FORMAT_S8_Z24
667	      && intel->must_use_separate_stencil) {
668
669      bool ok = true;
670      struct gl_renderbuffer *depth_rb;
671      struct gl_renderbuffer *stencil_rb;
672
673      depth_rb = intel_create_wrapped_renderbuffer(ctx, width, height,
674						   MESA_FORMAT_X8_Z24);
675      stencil_rb = intel_create_wrapped_renderbuffer(ctx, width, height,
676						     MESA_FORMAT_S8);
677      ok = depth_rb && stencil_rb;
678      ok = ok && intel_alloc_renderbuffer_storage(ctx, depth_rb,
679						  depth_rb->InternalFormat,
680						  width, height);
681      ok = ok && intel_alloc_renderbuffer_storage(ctx, stencil_rb,
682						  stencil_rb->InternalFormat,
683						  width, height);
684
685      if (!ok) {
686	 if (depth_rb) {
687	    intel_delete_renderbuffer(depth_rb);
688	 }
689	 if (stencil_rb) {
690	    intel_delete_renderbuffer(stencil_rb);
691	 }
692	 return false;
693      }
694
695      depth_rb->Wrapped = rb;
696      stencil_rb->Wrapped = rb;
697      _mesa_reference_renderbuffer(&irb->wrapped_depth, depth_rb);
698      _mesa_reference_renderbuffer(&irb->wrapped_stencil, stencil_rb);
699
700   } else {
701      irb->mt = intel_miptree_create_for_renderbuffer(intel, rb->Format,
702                                                      tiling, cpp,
703                                                      width, height);
704      if (!irb->mt)
705	 return false;
706
707      if (intel->vtbl.is_hiz_depth_format(intel, rb->Format)) {
708	 bool ok = intel_miptree_alloc_hiz(intel, irb->mt);
709	 if (!ok) {
710	    intel_miptree_release(&irb->mt);
711	    return false;
712	 }
713      }
714   }
715
716   return true;
717}
718
719
720#if FEATURE_OES_EGL_image
721static void
722intel_image_target_renderbuffer_storage(struct gl_context *ctx,
723					struct gl_renderbuffer *rb,
724					void *image_handle)
725{
726   struct intel_context *intel = intel_context(ctx);
727   struct intel_renderbuffer *irb;
728   __DRIscreen *screen;
729   __DRIimage *image;
730
731   screen = intel->intelScreen->driScrnPriv;
732   image = screen->dri2.image->lookupEGLImage(screen, image_handle,
733					      screen->loaderPrivate);
734   if (image == NULL)
735      return;
736
737   /* __DRIimage is opaque to the core so it has to be checked here */
738   switch (image->format) {
739   case MESA_FORMAT_RGBA8888_REV:
740      _mesa_error(&intel->ctx, GL_INVALID_OPERATION,
741            "glEGLImageTargetRenderbufferStorage(unsupported image format");
742      return;
743      break;
744   default:
745      break;
746   }
747
748   irb = intel_renderbuffer(rb);
749   intel_miptree_release(&irb->mt);
750   irb->mt = intel_miptree_create_for_region(intel,
751                                             GL_TEXTURE_2D,
752                                             image->format,
753                                             image->region);
754   if (!irb->mt)
755      return;
756
757   rb->InternalFormat = image->internal_format;
758   rb->Width = image->region->width;
759   rb->Height = image->region->height;
760   rb->Format = image->format;
761   rb->DataType = image->data_type;
762   rb->_BaseFormat = _mesa_base_fbo_format(&intel->ctx,
763					   image->internal_format);
764}
765#endif
766
767/**
768 * Called for each hardware renderbuffer when a _window_ is resized.
769 * Just update fields.
770 * Not used for user-created renderbuffers!
771 */
772static GLboolean
773intel_alloc_window_storage(struct gl_context * ctx, struct gl_renderbuffer *rb,
774                           GLenum internalFormat, GLuint width, GLuint height)
775{
776   ASSERT(rb->Name == 0);
777   rb->Width = width;
778   rb->Height = height;
779   rb->InternalFormat = internalFormat;
780
781   return true;
782}
783
784
785static void
786intel_resize_buffers(struct gl_context *ctx, struct gl_framebuffer *fb,
787		     GLuint width, GLuint height)
788{
789   int i;
790
791   _mesa_resize_framebuffer(ctx, fb, width, height);
792
793   fb->Initialized = true; /* XXX remove someday */
794
795   if (fb->Name != 0) {
796      return;
797   }
798
799
800   /* Make sure all window system renderbuffers are up to date */
801   for (i = BUFFER_FRONT_LEFT; i <= BUFFER_BACK_RIGHT; i++) {
802      struct gl_renderbuffer *rb = fb->Attachment[i].Renderbuffer;
803
804      /* only resize if size is changing */
805      if (rb && (rb->Width != width || rb->Height != height)) {
806	 rb->AllocStorage(ctx, rb, rb->InternalFormat, width, height);
807      }
808   }
809}
810
811
812/** Dummy function for gl_renderbuffer::AllocStorage() */
813static GLboolean
814intel_nop_alloc_storage(struct gl_context * ctx, struct gl_renderbuffer *rb,
815                        GLenum internalFormat, GLuint width, GLuint height)
816{
817   _mesa_problem(ctx, "intel_op_alloc_storage should never be called.");
818   return false;
819}
820
821/**
822 * Create a new intel_renderbuffer which corresponds to an on-screen window,
823 * not a user-created renderbuffer.
824 */
825struct intel_renderbuffer *
826intel_create_renderbuffer(gl_format format)
827{
828   GET_CURRENT_CONTEXT(ctx);
829
830   struct intel_renderbuffer *irb;
831
832   irb = CALLOC_STRUCT(intel_renderbuffer);
833   if (!irb) {
834      _mesa_error(ctx, GL_OUT_OF_MEMORY, "creating renderbuffer");
835      return NULL;
836   }
837
838   _mesa_init_renderbuffer(&irb->Base, 0);
839   irb->Base.ClassID = INTEL_RB_CLASS;
840   irb->Base._BaseFormat = _mesa_get_format_base_format(format);
841   irb->Base.Format = format;
842   irb->Base.InternalFormat = irb->Base._BaseFormat;
843   irb->Base.DataType = intel_mesa_format_to_rb_datatype(format);
844
845   /* intel-specific methods */
846   irb->Base.Delete = intel_delete_renderbuffer;
847   irb->Base.AllocStorage = intel_alloc_window_storage;
848   irb->Base.GetPointer = intel_get_pointer;
849
850   return irb;
851}
852
853
854struct gl_renderbuffer*
855intel_create_wrapped_renderbuffer(struct gl_context * ctx,
856				  int width, int height,
857				  gl_format format)
858{
859   /*
860    * The name here is irrelevant, as long as its nonzero, because the
861    * renderbuffer never gets entered into Mesa's renderbuffer hash table.
862    */
863   GLuint name = ~0;
864
865   struct intel_renderbuffer *irb = CALLOC_STRUCT(intel_renderbuffer);
866   if (!irb) {
867      _mesa_error(ctx, GL_OUT_OF_MEMORY, "creating renderbuffer");
868      return NULL;
869   }
870
871   struct gl_renderbuffer *rb = &irb->Base;
872   _mesa_init_renderbuffer(rb, name);
873   rb->ClassID = INTEL_RB_CLASS;
874   rb->_BaseFormat = _mesa_get_format_base_format(format);
875   rb->Format = format;
876   rb->InternalFormat = rb->_BaseFormat;
877   rb->DataType = intel_mesa_format_to_rb_datatype(format);
878   rb->Width = width;
879   rb->Height = height;
880
881   return rb;
882}
883
884
885/**
886 * Create a new renderbuffer object.
887 * Typically called via glBindRenderbufferEXT().
888 */
889static struct gl_renderbuffer *
890intel_new_renderbuffer(struct gl_context * ctx, GLuint name)
891{
892   /*struct intel_context *intel = intel_context(ctx); */
893   struct intel_renderbuffer *irb;
894
895   irb = CALLOC_STRUCT(intel_renderbuffer);
896   if (!irb) {
897      _mesa_error(ctx, GL_OUT_OF_MEMORY, "creating renderbuffer");
898      return NULL;
899   }
900
901   _mesa_init_renderbuffer(&irb->Base, name);
902   irb->Base.ClassID = INTEL_RB_CLASS;
903
904   /* intel-specific methods */
905   irb->Base.Delete = intel_delete_renderbuffer;
906   irb->Base.AllocStorage = intel_alloc_renderbuffer_storage;
907   irb->Base.GetPointer = intel_get_pointer;
908   /* span routines set in alloc_storage function */
909
910   return &irb->Base;
911}
912
913
914/**
915 * Called via glBindFramebufferEXT().
916 */
917static void
918intel_bind_framebuffer(struct gl_context * ctx, GLenum target,
919                       struct gl_framebuffer *fb, struct gl_framebuffer *fbread)
920{
921   if (target == GL_FRAMEBUFFER_EXT || target == GL_DRAW_FRAMEBUFFER_EXT) {
922      intel_draw_buffer(ctx);
923   }
924   else {
925      /* don't need to do anything if target == GL_READ_FRAMEBUFFER_EXT */
926   }
927}
928
929
930/**
931 * Called via glFramebufferRenderbufferEXT().
932 */
933static void
934intel_framebuffer_renderbuffer(struct gl_context * ctx,
935                               struct gl_framebuffer *fb,
936                               GLenum attachment, struct gl_renderbuffer *rb)
937{
938   DBG("Intel FramebufferRenderbuffer %u %u\n", fb->Name, rb ? rb->Name : 0);
939
940   intel_flush(ctx);
941
942   _mesa_framebuffer_renderbuffer(ctx, fb, attachment, rb);
943   intel_draw_buffer(ctx);
944}
945
946static struct intel_renderbuffer*
947intel_renderbuffer_wrap_miptree(struct intel_context *intel,
948                                struct intel_mipmap_tree *mt,
949                                uint32_t level,
950                                uint32_t layer,
951                                gl_format format,
952                                GLenum internal_format);
953
954/**
955 * \par Special case for separate stencil
956 *
957 *     When wrapping a depthstencil texture that uses separate stencil, this
958 *     function is recursively called twice: once to create \c
959 *     irb->wrapped_depth and again to create \c irb->wrapped_stencil.  On the
960 *     call to create \c irb->wrapped_depth, the \c format and \c
961 *     internal_format parameters do not match \c mt->format. In that case, \c
962 *     mt->format is MESA_FORMAT_S8_Z24 and \c format is \c
963 *     MESA_FORMAT_X8_Z24.
964 *
965 * @return true on success
966 */
967static bool
968intel_renderbuffer_update_wrapper(struct intel_context *intel,
969                                  struct intel_renderbuffer *irb,
970                                  struct intel_mipmap_tree *mt,
971                                  uint32_t level,
972                                  uint32_t layer,
973                                  gl_format format,
974                                  GLenum internal_format)
975{
976   struct gl_renderbuffer *rb = &irb->Base;
977
978   rb->Format = format;
979   if (!intel_span_supports_format(rb->Format)) {
980      DBG("Render to texture BAD FORMAT %s\n",
981	  _mesa_get_format_name(rb->Format));
982      return false;
983   } else {
984      DBG("Render to texture %s\n", _mesa_get_format_name(rb->Format));
985   }
986
987   rb->InternalFormat = internal_format;
988   rb->DataType = intel_mesa_format_to_rb_datatype(rb->Format);
989   rb->_BaseFormat = _mesa_get_format_base_format(rb->Format);
990   rb->Width = mt->level[level].width;
991   rb->Height = mt->level[level].height;
992
993   irb->Base.Delete = intel_delete_renderbuffer;
994   irb->Base.AllocStorage = intel_nop_alloc_storage;
995
996   intel_miptree_check_level_layer(mt, level, layer);
997   irb->mt_level = level;
998   irb->mt_layer = layer;
999
1000   if (mt->stencil_mt && _mesa_is_depthstencil_format(rb->InternalFormat)) {
1001      assert((irb->wrapped_depth == NULL) == (irb->wrapped_stencil == NULL));
1002
1003      struct intel_renderbuffer *depth_irb;
1004      struct intel_renderbuffer *stencil_irb;
1005
1006      if (!irb->wrapped_depth) {
1007	 depth_irb = intel_renderbuffer_wrap_miptree(intel,
1008	                                             mt, level, layer,
1009	                                             MESA_FORMAT_X8_Z24,
1010	                                             GL_DEPTH_COMPONENT24);
1011	 stencil_irb = intel_renderbuffer_wrap_miptree(intel,
1012	                                               mt->stencil_mt,
1013	                                               level, layer,
1014	                                               MESA_FORMAT_S8,
1015	                                               GL_STENCIL_INDEX8);
1016	 _mesa_reference_renderbuffer(&irb->wrapped_depth, &depth_irb->Base);
1017	 _mesa_reference_renderbuffer(&irb->wrapped_stencil, &stencil_irb->Base);
1018
1019	 if (!irb->wrapped_depth || !irb->wrapped_stencil)
1020	    return false;
1021      } else {
1022	 bool ok = true;
1023
1024	 depth_irb = intel_renderbuffer(irb->wrapped_depth);
1025	 stencil_irb = intel_renderbuffer(irb->wrapped_stencil);
1026
1027	 ok &= intel_renderbuffer_update_wrapper(intel,
1028	                                         depth_irb,
1029	                                         mt,
1030	                                         level, layer,
1031	                                         MESA_FORMAT_X8_Z24,
1032	                                         GL_DEPTH_COMPONENT24);
1033	 ok &= intel_renderbuffer_update_wrapper(intel,
1034	                                         stencil_irb,
1035	                                         mt->stencil_mt,
1036	                                         level, layer,
1037	                                         MESA_FORMAT_S8,
1038	                                         GL_STENCIL_INDEX8);
1039	 if (!ok)
1040	    return false;
1041      }
1042   } else {
1043      intel_miptree_reference(&irb->mt, mt);
1044      intel_renderbuffer_set_draw_offset(irb);
1045   }
1046
1047   return true;
1048}
1049
1050/**
1051 * \brief Wrap a renderbuffer around a single slice of a miptree.
1052 *
1053 * Called by glFramebufferTexture*(). This just allocates a
1054 * ``struct intel_renderbuffer`` then calls
1055 * intel_renderbuffer_update_wrapper() to do the real work.
1056 *
1057 * \see intel_renderbuffer_update_wrapper()
1058 */
1059static struct intel_renderbuffer*
1060intel_renderbuffer_wrap_miptree(struct intel_context *intel,
1061                                struct intel_mipmap_tree *mt,
1062                                uint32_t level,
1063                                uint32_t layer,
1064                                gl_format format,
1065                                GLenum internal_format)
1066
1067{
1068   const GLuint name = ~0;   /* not significant, but distinct for debugging */
1069   struct gl_context *ctx = &intel->ctx;
1070   struct intel_renderbuffer *irb;
1071
1072   intel_miptree_check_level_layer(mt, level, layer);
1073
1074   irb = CALLOC_STRUCT(intel_renderbuffer);
1075   if (!irb) {
1076      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glFramebufferTexture");
1077      return NULL;
1078   }
1079
1080   _mesa_init_renderbuffer(&irb->Base, name);
1081   irb->Base.ClassID = INTEL_RB_CLASS;
1082
1083   if (!intel_renderbuffer_update_wrapper(intel, irb,
1084                                          mt, level, layer,
1085                                          format, internal_format)) {
1086      free(irb);
1087      return NULL;
1088   }
1089
1090   return irb;
1091}
1092
1093void
1094intel_renderbuffer_set_draw_offset(struct intel_renderbuffer *irb)
1095{
1096   unsigned int dst_x, dst_y;
1097
1098   /* compute offset of the particular 2D image within the texture region */
1099   intel_miptree_get_image_offset(irb->mt,
1100				  irb->mt_level,
1101				  0, /* face, which we ignore */
1102				  irb->mt_layer,
1103				  &dst_x, &dst_y);
1104
1105   irb->draw_x = dst_x;
1106   irb->draw_y = dst_y;
1107}
1108
1109/**
1110 * Rendering to tiled buffers requires that the base address of the
1111 * buffer be aligned to a page boundary.  We generally render to
1112 * textures by pointing the surface at the mipmap image level, which
1113 * may not be aligned to a tile boundary.
1114 *
1115 * This function returns an appropriately-aligned base offset
1116 * according to the tiling restrictions, plus any required x/y offset
1117 * from there.
1118 */
1119uint32_t
1120intel_renderbuffer_tile_offsets(struct intel_renderbuffer *irb,
1121				uint32_t *tile_x,
1122				uint32_t *tile_y)
1123{
1124   struct intel_region *region = irb->mt->region;
1125   int cpp = region->cpp;
1126   uint32_t pitch = region->pitch * cpp;
1127
1128   if (region->tiling == I915_TILING_NONE) {
1129      *tile_x = 0;
1130      *tile_y = 0;
1131      return irb->draw_x * cpp + irb->draw_y * pitch;
1132   } else if (region->tiling == I915_TILING_X) {
1133      *tile_x = irb->draw_x % (512 / cpp);
1134      *tile_y = irb->draw_y % 8;
1135      return ((irb->draw_y / 8) * (8 * pitch) +
1136	      (irb->draw_x - *tile_x) / (512 / cpp) * 4096);
1137   } else {
1138      assert(region->tiling == I915_TILING_Y);
1139      *tile_x = irb->draw_x % (128 / cpp);
1140      *tile_y = irb->draw_y % 32;
1141      return ((irb->draw_y / 32) * (32 * pitch) +
1142	      (irb->draw_x - *tile_x) / (128 / cpp) * 4096);
1143   }
1144}
1145
1146#ifndef I915
1147static bool
1148need_tile_offset_workaround(struct brw_context *brw,
1149			    struct intel_renderbuffer *irb)
1150{
1151   uint32_t tile_x, tile_y;
1152
1153   if (brw->has_surface_tile_offset)
1154      return false;
1155
1156   intel_renderbuffer_tile_offsets(irb, &tile_x, &tile_y);
1157
1158   return tile_x != 0 || tile_y != 0;
1159}
1160#endif
1161
1162/**
1163 * Called by glFramebufferTexture[123]DEXT() (and other places) to
1164 * prepare for rendering into texture memory.  This might be called
1165 * many times to choose different texture levels, cube faces, etc
1166 * before intel_finish_render_texture() is ever called.
1167 */
1168static void
1169intel_render_texture(struct gl_context * ctx,
1170                     struct gl_framebuffer *fb,
1171                     struct gl_renderbuffer_attachment *att)
1172{
1173   struct intel_context *intel = intel_context(ctx);
1174   struct gl_texture_image *image = _mesa_get_attachment_teximage(att);
1175   struct intel_renderbuffer *irb = intel_renderbuffer(att->Renderbuffer);
1176   struct intel_texture_image *intel_image = intel_texture_image(image);
1177   struct intel_mipmap_tree *mt = intel_image->mt;
1178
1179   (void) fb;
1180
1181   int layer;
1182   if (att->CubeMapFace > 0) {
1183      assert(att->Zoffset == 0);
1184      layer = att->CubeMapFace;
1185   } else {
1186      layer = att->Zoffset;
1187   }
1188
1189   if (!intel_image->mt) {
1190      /* Fallback on drawing to a texture that doesn't have a miptree
1191       * (has a border, width/height 0, etc.)
1192       */
1193      _mesa_reference_renderbuffer(&att->Renderbuffer, NULL);
1194      _swrast_render_texture(ctx, fb, att);
1195      return;
1196   }
1197   else if (!irb) {
1198      irb = intel_renderbuffer_wrap_miptree(intel,
1199                                            mt,
1200                                            att->TextureLevel,
1201                                            layer,
1202                                            image->TexFormat,
1203                                            image->InternalFormat);
1204
1205      if (irb) {
1206         /* bind the wrapper to the attachment point */
1207         _mesa_reference_renderbuffer(&att->Renderbuffer, &irb->Base);
1208      }
1209      else {
1210         /* fallback to software rendering */
1211         _swrast_render_texture(ctx, fb, att);
1212         return;
1213      }
1214   }
1215
1216   if (!intel_renderbuffer_update_wrapper(intel, irb,
1217                                          mt, att->TextureLevel, layer,
1218                                          image->TexFormat,
1219                                          image->InternalFormat)) {
1220       _mesa_reference_renderbuffer(&att->Renderbuffer, NULL);
1221       _swrast_render_texture(ctx, fb, att);
1222       return;
1223   }
1224
1225   DBG("Begin render texture tid %lx tex=%u w=%d h=%d refcount=%d\n",
1226       _glthread_GetID(),
1227       att->Texture->Name, image->Width, image->Height,
1228       irb->Base.RefCount);
1229
1230   intel_image->used_as_render_target = true;
1231
1232#ifndef I915
1233   if (need_tile_offset_workaround(brw_context(ctx), irb)) {
1234      /* Original gen4 hardware couldn't draw to a non-tile-aligned
1235       * destination in a miptree unless you actually setup your
1236       * renderbuffer as a miptree and used the fragile
1237       * lod/array_index/etc. controls to select the image.  So,
1238       * instead, we just make a new single-level miptree and render
1239       * into that.
1240       */
1241      struct intel_context *intel = intel_context(ctx);
1242      struct intel_mipmap_tree *new_mt;
1243      int width, height, depth;
1244
1245      intel_miptree_get_dimensions_for_image(image, &width, &height, &depth);
1246
1247      new_mt = intel_miptree_create(intel, image->TexObject->Target,
1248				    intel_image->base.Base.TexFormat,
1249				    intel_image->base.Base.Level,
1250				    intel_image->base.Base.Level,
1251                                    width, height, depth,
1252				    true);
1253
1254      intel_miptree_copy_teximage(intel, intel_image, new_mt);
1255      intel_renderbuffer_set_draw_offset(irb);
1256
1257      intel_miptree_reference(&irb->mt, intel_image->mt);
1258      intel_miptree_release(&new_mt);
1259   }
1260#endif
1261   /* update drawing region, etc */
1262   intel_draw_buffer(ctx);
1263}
1264
1265
1266/**
1267 * Called by Mesa when rendering to a texture is done.
1268 */
1269static void
1270intel_finish_render_texture(struct gl_context * ctx,
1271                            struct gl_renderbuffer_attachment *att)
1272{
1273   struct intel_context *intel = intel_context(ctx);
1274   struct gl_texture_object *tex_obj = att->Texture;
1275   struct gl_texture_image *image =
1276      tex_obj->Image[att->CubeMapFace][att->TextureLevel];
1277   struct intel_texture_image *intel_image = intel_texture_image(image);
1278
1279   DBG("Finish render texture tid %lx tex=%u\n",
1280       _glthread_GetID(), att->Texture->Name);
1281
1282   /* Flag that this image may now be validated into the object's miptree. */
1283   if (intel_image)
1284      intel_image->used_as_render_target = false;
1285
1286   /* Since we've (probably) rendered to the texture and will (likely) use
1287    * it in the texture domain later on in this batchbuffer, flush the
1288    * batch.  Once again, we wish for a domain tracker in libdrm to cover
1289    * usage inside of a batchbuffer like GEM does in the kernel.
1290    */
1291   intel_batchbuffer_emit_mi_flush(intel);
1292}
1293
1294/**
1295 * Do additional "completeness" testing of a framebuffer object.
1296 */
1297static void
1298intel_validate_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb)
1299{
1300   struct intel_context *intel = intel_context(ctx);
1301   const struct intel_renderbuffer *depthRb =
1302      intel_get_renderbuffer(fb, BUFFER_DEPTH);
1303   const struct intel_renderbuffer *stencilRb =
1304      intel_get_renderbuffer(fb, BUFFER_STENCIL);
1305   int i;
1306
1307   /*
1308    * The depth and stencil renderbuffers are the same renderbuffer or wrap
1309    * the same texture.
1310    */
1311   if (depthRb && stencilRb) {
1312      bool depth_stencil_are_same;
1313      if (depthRb == stencilRb)
1314	 depth_stencil_are_same = true;
1315      else if ((fb->Attachment[BUFFER_DEPTH].Type == GL_TEXTURE) &&
1316	       (fb->Attachment[BUFFER_STENCIL].Type == GL_TEXTURE) &&
1317	       (fb->Attachment[BUFFER_DEPTH].Texture->Name ==
1318		fb->Attachment[BUFFER_STENCIL].Texture->Name))
1319	 depth_stencil_are_same = true;
1320      else
1321	 depth_stencil_are_same = false;
1322
1323      if (!intel->has_separate_stencil && !depth_stencil_are_same) {
1324	 fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
1325      }
1326   }
1327
1328   for (i = 0; i < Elements(fb->Attachment); i++) {
1329      struct gl_renderbuffer *rb;
1330      struct intel_renderbuffer *irb;
1331
1332      if (fb->Attachment[i].Type == GL_NONE)
1333	 continue;
1334
1335      /* A supported attachment will have a Renderbuffer set either
1336       * from being a Renderbuffer or being a texture that got the
1337       * intel_wrap_texture() treatment.
1338       */
1339      rb = fb->Attachment[i].Renderbuffer;
1340      if (rb == NULL) {
1341	 DBG("attachment without renderbuffer\n");
1342	 fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
1343	 continue;
1344      }
1345
1346      irb = intel_renderbuffer(rb);
1347      if (irb == NULL) {
1348	 DBG("software rendering renderbuffer\n");
1349	 fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
1350	 continue;
1351      }
1352
1353      if (!intel_span_supports_format(irb->Base.Format) ||
1354	  !intel->vtbl.render_target_supported(irb->Base.Format)) {
1355	 DBG("Unsupported texture/renderbuffer format attached: %s\n",
1356	     _mesa_get_format_name(irb->Base.Format));
1357	 fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
1358      }
1359   }
1360}
1361
1362/**
1363 * Try to do a glBlitFramebuffer using glCopyTexSubImage2D
1364 * We can do this when the dst renderbuffer is actually a texture and
1365 * there is no scaling, mirroring or scissoring.
1366 *
1367 * \return new buffer mask indicating the buffers left to blit using the
1368 *         normal path.
1369 */
1370static GLbitfield
1371intel_blit_framebuffer_copy_tex_sub_image(struct gl_context *ctx,
1372                                          GLint srcX0, GLint srcY0,
1373                                          GLint srcX1, GLint srcY1,
1374                                          GLint dstX0, GLint dstY0,
1375                                          GLint dstX1, GLint dstY1,
1376                                          GLbitfield mask, GLenum filter)
1377{
1378   if (mask & GL_COLOR_BUFFER_BIT) {
1379      const struct gl_framebuffer *drawFb = ctx->DrawBuffer;
1380      const struct gl_framebuffer *readFb = ctx->ReadBuffer;
1381      const struct gl_renderbuffer_attachment *drawAtt =
1382         &drawFb->Attachment[drawFb->_ColorDrawBufferIndexes[0]];
1383
1384      /* If the source and destination are the same size with no
1385         mirroring, the rectangles are within the size of the
1386         texture and there is no scissor then we can use
1387         glCopyTexSubimage2D to implement the blit. This will end
1388         up as a fast hardware blit on some drivers */
1389      if (drawAtt && drawAtt->Texture &&
1390          srcX0 - srcX1 == dstX0 - dstX1 &&
1391          srcY0 - srcY1 == dstY0 - dstY1 &&
1392          srcX1 >= srcX0 &&
1393          srcY1 >= srcY0 &&
1394          srcX0 >= 0 && srcX1 <= readFb->Width &&
1395          srcY0 >= 0 && srcY1 <= readFb->Height &&
1396          dstX0 >= 0 && dstX1 <= drawFb->Width &&
1397          dstY0 >= 0 && dstY1 <= drawFb->Height &&
1398          !ctx->Scissor.Enabled) {
1399         const struct gl_texture_object *texObj = drawAtt->Texture;
1400         const GLuint dstLevel = drawAtt->TextureLevel;
1401         const GLenum target = texObj->Target;
1402
1403         struct gl_texture_image *texImage =
1404            _mesa_select_tex_image(ctx, texObj, target, dstLevel);
1405
1406         if (intel_copy_texsubimage(intel_context(ctx),
1407                                    intel_texture_image(texImage),
1408                                    dstX0, dstY0,
1409                                    srcX0, srcY0,
1410                                    srcX1 - srcX0, /* width */
1411                                    srcY1 - srcY0))
1412            mask &= ~GL_COLOR_BUFFER_BIT;
1413      }
1414   }
1415
1416   return mask;
1417}
1418
1419static void
1420intel_blit_framebuffer(struct gl_context *ctx,
1421                       GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
1422                       GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
1423                       GLbitfield mask, GLenum filter)
1424{
1425   /* Try faster, glCopyTexSubImage2D approach first which uses the BLT. */
1426   mask = intel_blit_framebuffer_copy_tex_sub_image(ctx,
1427                                                    srcX0, srcY0, srcX1, srcY1,
1428                                                    dstX0, dstY0, dstX1, dstY1,
1429                                                    mask, filter);
1430   if (mask == 0x0)
1431      return;
1432
1433   _mesa_meta_BlitFramebuffer(ctx,
1434                              srcX0, srcY0, srcX1, srcY1,
1435                              dstX0, dstY0, dstX1, dstY1,
1436                              mask, filter);
1437}
1438
1439void
1440intel_renderbuffer_set_needs_hiz_resolve(struct intel_renderbuffer *irb)
1441{
1442   if (irb->mt) {
1443      intel_miptree_slice_set_needs_hiz_resolve(irb->mt,
1444                                                irb->mt_level,
1445                                                irb->mt_layer);
1446   } else if (irb->wrapped_depth) {
1447      intel_renderbuffer_set_needs_hiz_resolve(
1448	    intel_renderbuffer(irb->wrapped_depth));
1449   } else {
1450      return;
1451   }
1452}
1453
1454void
1455intel_renderbuffer_set_needs_depth_resolve(struct intel_renderbuffer *irb)
1456{
1457   if (irb->mt) {
1458      intel_miptree_slice_set_needs_depth_resolve(irb->mt,
1459                                                  irb->mt_level,
1460                                                  irb->mt_layer);
1461   } else if (irb->wrapped_depth) {
1462      intel_renderbuffer_set_needs_depth_resolve(
1463	    intel_renderbuffer(irb->wrapped_depth));
1464   } else {
1465      return;
1466   }
1467}
1468
1469bool
1470intel_renderbuffer_resolve_hiz(struct intel_context *intel,
1471			       struct intel_renderbuffer *irb)
1472{
1473   if (irb->mt)
1474      return intel_miptree_slice_resolve_hiz(intel,
1475                                             irb->mt,
1476                                             irb->mt_level,
1477                                             irb->mt_layer);
1478   if (irb->wrapped_depth)
1479      return intel_renderbuffer_resolve_hiz(intel,
1480					    intel_renderbuffer(irb->wrapped_depth));
1481
1482   return false;
1483}
1484
1485bool
1486intel_renderbuffer_resolve_depth(struct intel_context *intel,
1487				 struct intel_renderbuffer *irb)
1488{
1489   if (irb->mt)
1490      return intel_miptree_slice_resolve_depth(intel,
1491                                               irb->mt,
1492                                               irb->mt_level,
1493                                               irb->mt_layer);
1494
1495   if (irb->wrapped_depth)
1496      return intel_renderbuffer_resolve_depth(intel,
1497                                              intel_renderbuffer(irb->wrapped_depth));
1498
1499   return false;
1500}
1501
1502/**
1503 * Do one-time context initializations related to GL_EXT_framebuffer_object.
1504 * Hook in device driver functions.
1505 */
1506void
1507intel_fbo_init(struct intel_context *intel)
1508{
1509   intel->ctx.Driver.NewFramebuffer = intel_new_framebuffer;
1510   intel->ctx.Driver.NewRenderbuffer = intel_new_renderbuffer;
1511   intel->ctx.Driver.MapRenderbuffer = intel_map_renderbuffer;
1512   intel->ctx.Driver.UnmapRenderbuffer = intel_unmap_renderbuffer;
1513   intel->ctx.Driver.BindFramebuffer = intel_bind_framebuffer;
1514   intel->ctx.Driver.FramebufferRenderbuffer = intel_framebuffer_renderbuffer;
1515   intel->ctx.Driver.RenderTexture = intel_render_texture;
1516   intel->ctx.Driver.FinishRenderTexture = intel_finish_render_texture;
1517   intel->ctx.Driver.ResizeBuffers = intel_resize_buffers;
1518   intel->ctx.Driver.ValidateFramebuffer = intel_validate_framebuffer;
1519   intel->ctx.Driver.BlitFramebuffer = intel_blit_framebuffer;
1520
1521#if FEATURE_OES_EGL_image
1522   intel->ctx.Driver.EGLImageTargetRenderbufferStorage =
1523      intel_image_target_renderbuffer_storage;
1524#endif
1525}
1526