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