intel_fbo.c revision 638342858894293246400d95a90d153c7f66719a
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/mtypes.h"
32#include "main/fbobject.h"
33#include "main/framebuffer.h"
34#include "main/renderbuffer.h"
35#include "main/context.h"
36#include "main/texrender.h"
37#include "drivers/common/meta.h"
38
39#include "intel_context.h"
40#include "intel_batchbuffer.h"
41#include "intel_buffers.h"
42#include "intel_fbo.h"
43#include "intel_mipmap_tree.h"
44#include "intel_regions.h"
45#ifndef I915
46#include "brw_state.h"
47#endif
48
49#define FILE_DEBUG_FLAG DEBUG_FBO
50
51
52/**
53 * Create a new framebuffer object.
54 */
55static struct gl_framebuffer *
56intel_new_framebuffer(GLcontext * ctx, GLuint name)
57{
58   /* Only drawable state in intel_framebuffer at this time, just use Mesa's
59    * class
60    */
61   return _mesa_new_framebuffer(ctx, name);
62}
63
64
65/** Called by gl_renderbuffer::Delete() */
66static void
67intel_delete_renderbuffer(struct gl_renderbuffer *rb)
68{
69   GET_CURRENT_CONTEXT(ctx);
70   struct intel_context *intel = intel_context(ctx);
71   struct intel_renderbuffer *irb = intel_renderbuffer(rb);
72
73   ASSERT(irb);
74
75   if (intel && irb->region) {
76      intel_region_release(&irb->region);
77   }
78
79   free(irb);
80}
81
82
83/**
84 * Return a pointer to a specific pixel in a renderbuffer.
85 */
86static void *
87intel_get_pointer(GLcontext * ctx, struct gl_renderbuffer *rb,
88                  GLint x, GLint y)
89{
90   /* By returning NULL we force all software rendering to go through
91    * the span routines.
92    */
93   return NULL;
94}
95
96
97/**
98 * Called via glRenderbufferStorageEXT() to set the format and allocate
99 * storage for a user-created renderbuffer.
100 */
101static GLboolean
102intel_alloc_renderbuffer_storage(GLcontext * ctx, struct gl_renderbuffer *rb,
103                                 GLenum internalFormat,
104                                 GLuint width, GLuint height)
105{
106   struct intel_context *intel = intel_context(ctx);
107   struct intel_renderbuffer *irb = intel_renderbuffer(rb);
108   int cpp;
109
110   ASSERT(rb->Name != 0);
111
112   switch (internalFormat) {
113   case GL_R3_G3_B2:
114   case GL_RGB4:
115   case GL_RGB5:
116      rb->Format = MESA_FORMAT_RGB565;
117      rb->DataType = GL_UNSIGNED_BYTE;
118      break;
119   case GL_RGB:
120   case GL_RGB8:
121   case GL_RGB10:
122   case GL_RGB12:
123   case GL_RGB16:
124      rb->Format = MESA_FORMAT_XRGB8888;
125      rb->DataType = GL_UNSIGNED_BYTE;
126      break;
127   case GL_RGBA:
128   case GL_RGBA2:
129   case GL_RGBA4:
130   case GL_RGB5_A1:
131   case GL_RGBA8:
132   case GL_RGB10_A2:
133   case GL_RGBA12:
134   case GL_RGBA16:
135      rb->Format = MESA_FORMAT_ARGB8888;
136      rb->DataType = GL_UNSIGNED_BYTE;
137      break;
138   case GL_ALPHA:
139   case GL_ALPHA8:
140      rb->Format = MESA_FORMAT_A8;
141      rb->DataType = GL_UNSIGNED_BYTE;
142      break;
143   case GL_STENCIL_INDEX:
144   case GL_STENCIL_INDEX1_EXT:
145   case GL_STENCIL_INDEX4_EXT:
146   case GL_STENCIL_INDEX8_EXT:
147   case GL_STENCIL_INDEX16_EXT:
148      /* alloc a depth+stencil buffer */
149      rb->Format = MESA_FORMAT_S8_Z24;
150      rb->DataType = GL_UNSIGNED_INT_24_8_EXT;
151      break;
152   case GL_DEPTH_COMPONENT16:
153      rb->Format = MESA_FORMAT_Z16;
154      rb->DataType = GL_UNSIGNED_SHORT;
155      break;
156   case GL_DEPTH_COMPONENT:
157   case GL_DEPTH_COMPONENT24:
158   case GL_DEPTH_COMPONENT32:
159      rb->Format = MESA_FORMAT_S8_Z24;
160      rb->DataType = GL_UNSIGNED_INT_24_8_EXT;
161      break;
162   case GL_DEPTH_STENCIL_EXT:
163   case GL_DEPTH24_STENCIL8_EXT:
164      rb->Format = MESA_FORMAT_S8_Z24;
165      rb->DataType = GL_UNSIGNED_INT_24_8_EXT;
166      break;
167   default:
168      _mesa_problem(ctx,
169                    "Unexpected format in intel_alloc_renderbuffer_storage");
170      return GL_FALSE;
171   }
172
173   rb->_BaseFormat = _mesa_base_fbo_format(ctx, internalFormat);
174   cpp = _mesa_get_format_bytes(rb->Format);
175
176   intel_flush(ctx);
177
178   /* free old region */
179   if (irb->region) {
180      intel_region_release(&irb->region);
181   }
182
183   /* allocate new memory region/renderbuffer */
184
185   /* alloc hardware renderbuffer */
186   DBG("Allocating %d x %d Intel RBO\n", width, height);
187
188   irb->region = intel_region_alloc(intel, I915_TILING_NONE, cpp,
189				    width, height, GL_TRUE);
190   if (!irb->region)
191      return GL_FALSE;       /* out of memory? */
192
193   ASSERT(irb->region->buffer);
194
195   rb->Width = width;
196   rb->Height = height;
197
198   return GL_TRUE;
199}
200
201
202#if FEATURE_OES_EGL_image
203static void
204intel_image_target_renderbuffer_storage(GLcontext *ctx,
205					struct gl_renderbuffer *rb,
206					void *image_handle)
207{
208   struct intel_context *intel = intel_context(ctx);
209   struct intel_renderbuffer *irb;
210   __DRIscreen *screen;
211   __DRIimage *image;
212
213   screen = intel->intelScreen->driScrnPriv;
214   image = screen->dri2.image->lookupEGLImage(intel->driContext, image_handle,
215					      intel->driContext->loaderPrivate);
216   if (image == NULL)
217      return;
218
219   irb = intel_renderbuffer(rb);
220   if (irb->region)
221      intel_region_release(&irb->region);
222   intel_region_reference(&irb->region, image->region);
223
224   rb->InternalFormat = image->internal_format;
225   rb->Width = image->region->width;
226   rb->Height = image->region->height;
227   rb->Format = image->format;
228   rb->DataType = image->data_type;
229   rb->_BaseFormat = _mesa_base_fbo_format(&intel->ctx,
230					   image->internal_format);
231}
232#endif
233
234/**
235 * Called for each hardware renderbuffer when a _window_ is resized.
236 * Just update fields.
237 * Not used for user-created renderbuffers!
238 */
239static GLboolean
240intel_alloc_window_storage(GLcontext * ctx, struct gl_renderbuffer *rb,
241                           GLenum internalFormat, GLuint width, GLuint height)
242{
243   ASSERT(rb->Name == 0);
244   rb->Width = width;
245   rb->Height = height;
246   rb->InternalFormat = internalFormat;
247
248   return GL_TRUE;
249}
250
251
252static void
253intel_resize_buffers(GLcontext *ctx, struct gl_framebuffer *fb,
254		     GLuint width, GLuint height)
255{
256   int i;
257
258   _mesa_resize_framebuffer(ctx, fb, width, height);
259
260   fb->Initialized = GL_TRUE; /* XXX remove someday */
261
262   if (fb->Name != 0) {
263      return;
264   }
265
266
267   /* Make sure all window system renderbuffers are up to date */
268   for (i = BUFFER_FRONT_LEFT; i <= BUFFER_BACK_RIGHT; i++) {
269      struct gl_renderbuffer *rb = fb->Attachment[i].Renderbuffer;
270
271      /* only resize if size is changing */
272      if (rb && (rb->Width != width || rb->Height != height)) {
273	 rb->AllocStorage(ctx, rb, rb->InternalFormat, width, height);
274      }
275   }
276}
277
278
279/** Dummy function for gl_renderbuffer::AllocStorage() */
280static GLboolean
281intel_nop_alloc_storage(GLcontext * ctx, struct gl_renderbuffer *rb,
282                        GLenum internalFormat, GLuint width, GLuint height)
283{
284   _mesa_problem(ctx, "intel_op_alloc_storage should never be called.");
285   return GL_FALSE;
286}
287
288
289void
290intel_renderbuffer_set_region(struct intel_context *intel,
291			      struct intel_renderbuffer *rb,
292			      struct intel_region *region)
293{
294   struct intel_region *old;
295
296   old = rb->region;
297   rb->region = NULL;
298   intel_region_reference(&rb->region, region);
299#ifndef I915
300   if (old) {
301      brw_state_cache_bo_delete(&brw_context(&intel->ctx)->surface_cache,
302				old->buffer);
303   }
304#endif
305   intel_region_release(&old);
306}
307
308
309/**
310 * Create a new intel_renderbuffer which corresponds to an on-screen window,
311 * not a user-created renderbuffer.
312 */
313struct intel_renderbuffer *
314intel_create_renderbuffer(gl_format format)
315{
316   GET_CURRENT_CONTEXT(ctx);
317
318   struct intel_renderbuffer *irb;
319
320   irb = CALLOC_STRUCT(intel_renderbuffer);
321   if (!irb) {
322      _mesa_error(ctx, GL_OUT_OF_MEMORY, "creating renderbuffer");
323      return NULL;
324   }
325
326   _mesa_init_renderbuffer(&irb->Base, 0);
327   irb->Base.ClassID = INTEL_RB_CLASS;
328
329   switch (format) {
330   case MESA_FORMAT_RGB565:
331      irb->Base._BaseFormat = GL_RGB;
332      irb->Base.DataType = GL_UNSIGNED_BYTE;
333      break;
334   case MESA_FORMAT_XRGB8888:
335      irb->Base._BaseFormat = GL_RGB;
336      irb->Base.DataType = GL_UNSIGNED_BYTE;
337      break;
338   case MESA_FORMAT_ARGB8888:
339      irb->Base._BaseFormat = GL_RGBA;
340      irb->Base.DataType = GL_UNSIGNED_BYTE;
341      break;
342   case MESA_FORMAT_Z16:
343      irb->Base._BaseFormat = GL_DEPTH_COMPONENT;
344      irb->Base.DataType = GL_UNSIGNED_SHORT;
345      break;
346   case MESA_FORMAT_X8_Z24:
347      irb->Base._BaseFormat = GL_DEPTH_COMPONENT;
348      irb->Base.DataType = GL_UNSIGNED_INT;
349      break;
350   case MESA_FORMAT_S8_Z24:
351      irb->Base._BaseFormat = GL_DEPTH_STENCIL;
352      irb->Base.DataType = GL_UNSIGNED_INT_24_8_EXT;
353      break;
354   case MESA_FORMAT_A8:
355      irb->Base._BaseFormat = GL_ALPHA;
356      irb->Base.DataType = GL_UNSIGNED_BYTE;
357      break;
358   default:
359      _mesa_problem(NULL,
360                    "Unexpected intFormat in intel_create_renderbuffer");
361      free(irb);
362      return NULL;
363   }
364
365   irb->Base.Format = format;
366   irb->Base.InternalFormat = irb->Base._BaseFormat;
367
368   /* intel-specific methods */
369   irb->Base.Delete = intel_delete_renderbuffer;
370   irb->Base.AllocStorage = intel_alloc_window_storage;
371   irb->Base.GetPointer = intel_get_pointer;
372
373   return irb;
374}
375
376
377/**
378 * Create a new renderbuffer object.
379 * Typically called via glBindRenderbufferEXT().
380 */
381static struct gl_renderbuffer *
382intel_new_renderbuffer(GLcontext * ctx, GLuint name)
383{
384   /*struct intel_context *intel = intel_context(ctx); */
385   struct intel_renderbuffer *irb;
386
387   irb = CALLOC_STRUCT(intel_renderbuffer);
388   if (!irb) {
389      _mesa_error(ctx, GL_OUT_OF_MEMORY, "creating renderbuffer");
390      return NULL;
391   }
392
393   _mesa_init_renderbuffer(&irb->Base, name);
394   irb->Base.ClassID = INTEL_RB_CLASS;
395
396   /* intel-specific methods */
397   irb->Base.Delete = intel_delete_renderbuffer;
398   irb->Base.AllocStorage = intel_alloc_renderbuffer_storage;
399   irb->Base.GetPointer = intel_get_pointer;
400   /* span routines set in alloc_storage function */
401
402   return &irb->Base;
403}
404
405
406/**
407 * Called via glBindFramebufferEXT().
408 */
409static void
410intel_bind_framebuffer(GLcontext * ctx, GLenum target,
411                       struct gl_framebuffer *fb, struct gl_framebuffer *fbread)
412{
413   if (target == GL_FRAMEBUFFER_EXT || target == GL_DRAW_FRAMEBUFFER_EXT) {
414      intel_draw_buffer(ctx, fb);
415   }
416   else {
417      /* don't need to do anything if target == GL_READ_FRAMEBUFFER_EXT */
418   }
419}
420
421
422/**
423 * Called via glFramebufferRenderbufferEXT().
424 */
425static void
426intel_framebuffer_renderbuffer(GLcontext * ctx,
427                               struct gl_framebuffer *fb,
428                               GLenum attachment, struct gl_renderbuffer *rb)
429{
430   DBG("Intel FramebufferRenderbuffer %u %u\n", fb->Name, rb ? rb->Name : 0);
431
432   intel_flush(ctx);
433
434   _mesa_framebuffer_renderbuffer(ctx, fb, attachment, rb);
435   intel_draw_buffer(ctx, fb);
436}
437
438
439static GLboolean
440intel_update_wrapper(GLcontext *ctx, struct intel_renderbuffer *irb,
441		     struct gl_texture_image *texImage)
442{
443   if (texImage->TexFormat == MESA_FORMAT_ARGB8888) {
444      irb->Base.DataType = GL_UNSIGNED_BYTE;
445      DBG("Render to RGBA8 texture OK\n");
446   }
447   else if (texImage->TexFormat == MESA_FORMAT_XRGB8888) {
448      irb->Base.DataType = GL_UNSIGNED_BYTE;
449      DBG("Render to XGBA8 texture OK\n");
450   }
451   else if (texImage->TexFormat == MESA_FORMAT_RGB565) {
452      irb->Base.DataType = GL_UNSIGNED_BYTE;
453      DBG("Render to RGB5 texture OK\n");
454   }
455   else if (texImage->TexFormat == MESA_FORMAT_ARGB1555) {
456      irb->Base.DataType = GL_UNSIGNED_BYTE;
457      DBG("Render to ARGB1555 texture OK\n");
458   }
459   else if (texImage->TexFormat == MESA_FORMAT_ARGB4444) {
460      irb->Base.DataType = GL_UNSIGNED_BYTE;
461      DBG("Render to ARGB4444 texture OK\n");
462   }
463   else if (texImage->TexFormat == MESA_FORMAT_A8) {
464      irb->Base.DataType = GL_UNSIGNED_BYTE;
465      DBG("Render to A8 texture OK\n");
466   }
467   else if (texImage->TexFormat == MESA_FORMAT_Z16) {
468      irb->Base.DataType = GL_UNSIGNED_SHORT;
469      DBG("Render to DEPTH16 texture OK\n");
470   }
471   else if (texImage->TexFormat == MESA_FORMAT_S8_Z24) {
472      irb->Base.DataType = GL_UNSIGNED_INT_24_8_EXT;
473      DBG("Render to DEPTH_STENCIL texture OK\n");
474   }
475   else {
476      DBG("Render to texture BAD FORMAT %s\n",
477	  _mesa_get_format_name(texImage->TexFormat));
478      return GL_FALSE;
479   }
480
481   irb->Base.Format = texImage->TexFormat;
482
483   irb->Base.InternalFormat = texImage->InternalFormat;
484   irb->Base._BaseFormat = _mesa_base_fbo_format(ctx, irb->Base.InternalFormat);
485   irb->Base.Width = texImage->Width;
486   irb->Base.Height = texImage->Height;
487
488   irb->Base.Delete = intel_delete_renderbuffer;
489   irb->Base.AllocStorage = intel_nop_alloc_storage;
490
491   return GL_TRUE;
492}
493
494
495/**
496 * When glFramebufferTexture[123]D is called this function sets up the
497 * gl_renderbuffer wrapper around the texture image.
498 * This will have the region info needed for hardware rendering.
499 */
500static struct intel_renderbuffer *
501intel_wrap_texture(GLcontext * ctx, struct gl_texture_image *texImage)
502{
503   const GLuint name = ~0;   /* not significant, but distinct for debugging */
504   struct intel_renderbuffer *irb;
505
506   /* make an intel_renderbuffer to wrap the texture image */
507   irb = CALLOC_STRUCT(intel_renderbuffer);
508   if (!irb) {
509      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glFramebufferTexture");
510      return NULL;
511   }
512
513   _mesa_init_renderbuffer(&irb->Base, name);
514   irb->Base.ClassID = INTEL_RB_CLASS;
515
516   if (!intel_update_wrapper(ctx, irb, texImage)) {
517      free(irb);
518      return NULL;
519   }
520
521   return irb;
522}
523
524
525/**
526 * Called by glFramebufferTexture[123]DEXT() (and other places) to
527 * prepare for rendering into texture memory.  This might be called
528 * many times to choose different texture levels, cube faces, etc
529 * before intel_finish_render_texture() is ever called.
530 */
531static void
532intel_render_texture(GLcontext * ctx,
533                     struct gl_framebuffer *fb,
534                     struct gl_renderbuffer_attachment *att)
535{
536   struct gl_texture_image *newImage
537      = att->Texture->Image[att->CubeMapFace][att->TextureLevel];
538   struct intel_renderbuffer *irb = intel_renderbuffer(att->Renderbuffer);
539   struct intel_texture_image *intel_image;
540   GLuint dst_x, dst_y;
541
542   (void) fb;
543
544   ASSERT(newImage);
545
546   intel_image = intel_texture_image(newImage);
547   if (!intel_image->mt) {
548      /* Fallback on drawing to a texture that doesn't have a miptree
549       * (has a border, width/height 0, etc.)
550       */
551      _mesa_reference_renderbuffer(&att->Renderbuffer, NULL);
552      _mesa_render_texture(ctx, fb, att);
553      return;
554   }
555   else if (!irb) {
556      irb = intel_wrap_texture(ctx, newImage);
557      if (irb) {
558         /* bind the wrapper to the attachment point */
559         _mesa_reference_renderbuffer(&att->Renderbuffer, &irb->Base);
560      }
561      else {
562         /* fallback to software rendering */
563         _mesa_render_texture(ctx, fb, att);
564         return;
565      }
566   }
567
568   if (!intel_update_wrapper(ctx, irb, newImage)) {
569       _mesa_reference_renderbuffer(&att->Renderbuffer, NULL);
570       _mesa_render_texture(ctx, fb, att);
571       return;
572   }
573
574   DBG("Begin render texture tid %lx tex=%u w=%d h=%d refcount=%d\n",
575       _glthread_GetID(),
576       att->Texture->Name, newImage->Width, newImage->Height,
577       irb->Base.RefCount);
578
579   /* point the renderbufer's region to the texture image region */
580   if (irb->region != intel_image->mt->region) {
581      if (irb->region)
582	 intel_region_release(&irb->region);
583      intel_region_reference(&irb->region, intel_image->mt->region);
584   }
585
586   /* compute offset of the particular 2D image within the texture region */
587   intel_miptree_get_image_offset(intel_image->mt,
588				  att->TextureLevel,
589				  att->CubeMapFace,
590				  att->Zoffset,
591				  &dst_x, &dst_y);
592
593   intel_image->mt->region->draw_offset = (dst_y * intel_image->mt->region->pitch +
594					   dst_x) * intel_image->mt->cpp;
595   intel_image->mt->region->draw_x = dst_x;
596   intel_image->mt->region->draw_y = dst_y;
597   intel_image->used_as_render_target = GL_TRUE;
598
599   /* update drawing region, etc */
600   intel_draw_buffer(ctx, fb);
601}
602
603
604/**
605 * Called by Mesa when rendering to a texture is done.
606 */
607static void
608intel_finish_render_texture(GLcontext * ctx,
609                            struct gl_renderbuffer_attachment *att)
610{
611   struct intel_context *intel = intel_context(ctx);
612   struct gl_texture_object *tex_obj = att->Texture;
613   struct gl_texture_image *image =
614      tex_obj->Image[att->CubeMapFace][att->TextureLevel];
615   struct intel_texture_image *intel_image = intel_texture_image(image);
616
617   /* Flag that this image may now be validated into the object's miptree. */
618   intel_image->used_as_render_target = GL_FALSE;
619
620   /* Since we've (probably) rendered to the texture and will (likely) use
621    * it in the texture domain later on in this batchbuffer, flush the
622    * batch.  Once again, we wish for a domain tracker in libdrm to cover
623    * usage inside of a batchbuffer like GEM does in the kernel.
624    */
625   intel_batchbuffer_emit_mi_flush(intel->batch);
626}
627
628/**
629 * Do additional "completeness" testing of a framebuffer object.
630 */
631static void
632intel_validate_framebuffer(GLcontext *ctx, struct gl_framebuffer *fb)
633{
634   const struct intel_renderbuffer *depthRb =
635      intel_get_renderbuffer(fb, BUFFER_DEPTH);
636   const struct intel_renderbuffer *stencilRb =
637      intel_get_renderbuffer(fb, BUFFER_STENCIL);
638   int i;
639
640   if (depthRb && stencilRb && stencilRb != depthRb) {
641      if (ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Type == GL_TEXTURE &&
642	  ctx->DrawBuffer->Attachment[BUFFER_STENCIL].Type == GL_TEXTURE &&
643	  (ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Texture->Name ==
644	   ctx->DrawBuffer->Attachment[BUFFER_STENCIL].Texture->Name)) {
645	 /* OK */
646      } else {
647	 /* we only support combined depth/stencil buffers, not separate
648	  * stencil buffers.
649	  */
650	 DBG("Only supports combined depth/stencil (found %s, %s)\n",
651	     depthRb ? _mesa_get_format_name(depthRb->Base.Format): "NULL",
652	     stencilRb ? _mesa_get_format_name(stencilRb->Base.Format): "NULL");
653	 fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
654      }
655   }
656
657   for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) {
658      struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[i];
659      struct intel_renderbuffer *irb = intel_renderbuffer(rb);
660
661      if (rb == NULL)
662	 continue;
663
664      if (irb == NULL) {
665	 DBG("software rendering renderbuffer\n");
666	 fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
667	 continue;
668      }
669
670      switch (irb->Base.Format) {
671      case MESA_FORMAT_ARGB8888:
672      case MESA_FORMAT_XRGB8888:
673      case MESA_FORMAT_RGB565:
674      case MESA_FORMAT_ARGB1555:
675      case MESA_FORMAT_ARGB4444:
676      case MESA_FORMAT_A8:
677	 break;
678      default:
679	 fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
680      }
681   }
682}
683
684
685/**
686 * Do one-time context initializations related to GL_EXT_framebuffer_object.
687 * Hook in device driver functions.
688 */
689void
690intel_fbo_init(struct intel_context *intel)
691{
692   intel->ctx.Driver.NewFramebuffer = intel_new_framebuffer;
693   intel->ctx.Driver.NewRenderbuffer = intel_new_renderbuffer;
694   intel->ctx.Driver.BindFramebuffer = intel_bind_framebuffer;
695   intel->ctx.Driver.FramebufferRenderbuffer = intel_framebuffer_renderbuffer;
696   intel->ctx.Driver.RenderTexture = intel_render_texture;
697   intel->ctx.Driver.FinishRenderTexture = intel_finish_render_texture;
698   intel->ctx.Driver.ResizeBuffers = intel_resize_buffers;
699   intel->ctx.Driver.ValidateFramebuffer = intel_validate_framebuffer;
700   intel->ctx.Driver.BlitFramebuffer = _mesa_meta_BlitFramebuffer;
701
702#if FEATURE_OES_EGL_image
703   intel->ctx.Driver.EGLImageTargetRenderbufferStorage =
704      intel_image_target_renderbuffer_storage;
705#endif
706}
707