Tizen 2.0 Release
[profile/ivi/osmesa.git] / src / mesa / drivers / dri / radeon / radeon_fbo.c
1 /**************************************************************************
2  * 
3  * Copyright 2008 Red Hat Inc.
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/enums.h"
34 #include "main/fbobject.h"
35 #include "main/framebuffer.h"
36 #include "main/renderbuffer.h"
37 #include "main/context.h"
38 #include "swrast/swrast.h"
39 #include "drivers/common/meta.h"
40
41 #include "radeon_common.h"
42 #include "radeon_mipmap_tree.h"
43
44 #define FILE_DEBUG_FLAG RADEON_TEXTURE
45 #define DBG(...) do {                                           \
46         if (RADEON_DEBUG & FILE_DEBUG_FLAG)                      \
47                 printf(__VA_ARGS__);                      \
48 } while(0)
49
50 static struct gl_framebuffer *
51 radeon_new_framebuffer(struct gl_context *ctx, GLuint name)
52 {
53   return _mesa_new_framebuffer(ctx, name);
54 }
55
56 static void
57 radeon_delete_renderbuffer(struct gl_renderbuffer *rb)
58 {
59   struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb);
60
61   radeon_print(RADEON_TEXTURE, RADEON_TRACE,
62                 "%s(rb %p, rrb %p) \n",
63                 __func__, rb, rrb);
64
65   ASSERT(rrb);
66
67   if (rrb && rrb->bo) {
68     radeon_bo_unref(rrb->bo);
69   }
70   free(rrb);
71 }
72
73 static void *
74 radeon_get_pointer(struct gl_context *ctx, struct gl_renderbuffer *rb,
75                    GLint x, GLint y)
76 {
77   radeon_print(RADEON_TEXTURE, RADEON_TRACE,
78                 "%s(%p, rb %p) \n",
79                 __func__, ctx, rb);
80
81   return NULL;
82 }
83
84 /**
85  * Called via glRenderbufferStorageEXT() to set the format and allocate
86  * storage for a user-created renderbuffer.
87  */
88 static GLboolean
89 radeon_alloc_renderbuffer_storage(struct gl_context * ctx, struct gl_renderbuffer *rb,
90                                  GLenum internalFormat,
91                                  GLuint width, GLuint height)
92 {
93   struct radeon_context *radeon = RADEON_CONTEXT(ctx);
94   struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb);
95   GLboolean software_buffer = GL_FALSE;
96   int cpp;
97
98   radeon_print(RADEON_TEXTURE, RADEON_TRACE,
99                 "%s(%p, rb %p) \n",
100                 __func__, ctx, rb);
101
102    ASSERT(rb->Name != 0);
103   switch (internalFormat) {
104    case GL_R3_G3_B2:
105    case GL_RGB4:
106    case GL_RGB5:
107       rb->Format = _dri_texformat_rgb565;
108       rb->DataType = GL_UNSIGNED_BYTE;
109       cpp = 2;
110       break;
111    case GL_RGB:
112    case GL_RGB8:
113    case GL_RGB10:
114    case GL_RGB12:
115    case GL_RGB16:
116       rb->Format = _dri_texformat_argb8888;
117       rb->DataType = GL_UNSIGNED_BYTE;
118       cpp = 4;
119       break;
120    case GL_RGBA:
121    case GL_RGBA2:
122    case GL_RGBA4:
123    case GL_RGB5_A1:
124    case GL_RGBA8:
125    case GL_RGB10_A2:
126    case GL_RGBA12:
127    case GL_RGBA16:
128       rb->Format = _dri_texformat_argb8888;
129       rb->DataType = GL_UNSIGNED_BYTE;
130       cpp = 4;
131       break;
132    case GL_STENCIL_INDEX:
133    case GL_STENCIL_INDEX1_EXT:
134    case GL_STENCIL_INDEX4_EXT:
135    case GL_STENCIL_INDEX8_EXT:
136    case GL_STENCIL_INDEX16_EXT:
137       /* alloc a depth+stencil buffer */
138       rb->Format = MESA_FORMAT_S8_Z24;
139       rb->DataType = GL_UNSIGNED_INT_24_8_EXT;
140       cpp = 4;
141       break;
142    case GL_DEPTH_COMPONENT16:
143       rb->Format = MESA_FORMAT_Z16;
144       rb->DataType = GL_UNSIGNED_SHORT;
145       cpp = 2;
146       break;
147    case GL_DEPTH_COMPONENT:
148    case GL_DEPTH_COMPONENT24:
149    case GL_DEPTH_COMPONENT32:
150       rb->Format = MESA_FORMAT_X8_Z24;
151       rb->DataType = GL_UNSIGNED_INT;
152       cpp = 4;
153       break;
154    case GL_DEPTH_STENCIL_EXT:
155    case GL_DEPTH24_STENCIL8_EXT:
156       rb->Format = MESA_FORMAT_S8_Z24;
157       rb->DataType = GL_UNSIGNED_INT_24_8_EXT;
158       cpp = 4;
159       break;
160    default:
161       _mesa_problem(ctx,
162                     "Unexpected format in radeon_alloc_renderbuffer_storage");
163       return GL_FALSE;
164    }
165
166   rb->_BaseFormat = _mesa_base_fbo_format(ctx, internalFormat);
167
168   if (ctx->Driver.Flush)
169           ctx->Driver.Flush(ctx); /* +r6/r7 */
170
171   if (rrb->bo)
172     radeon_bo_unref(rrb->bo);
173   
174     
175    if (software_buffer) {
176       return _mesa_soft_renderbuffer_storage(ctx, rb, internalFormat,
177                                              width, height);
178    }
179    else {
180      uint32_t size;
181      uint32_t pitch = ((cpp * width + 63) & ~63) / cpp;
182
183      if (RADEON_DEBUG & RADEON_MEMORY)
184              fprintf(stderr,"Allocating %d x %d radeon RBO (pitch %d)\n", width,
185                      height, pitch);
186
187      size = pitch * height * cpp;
188      rrb->pitch = pitch * cpp;
189      rrb->cpp = cpp;
190      rrb->bo = radeon_bo_open(radeon->radeonScreen->bom,
191                               0,
192                               size,
193                               0,
194                               RADEON_GEM_DOMAIN_VRAM,
195                               0);
196      rb->Width = width;
197      rb->Height = height;
198        return GL_TRUE;
199    }    
200    
201 }
202
203 #if FEATURE_OES_EGL_image
204 static void
205 radeon_image_target_renderbuffer_storage(struct gl_context *ctx,
206                                          struct gl_renderbuffer *rb,
207                                          void *image_handle)
208 {
209    radeonContextPtr radeon = RADEON_CONTEXT(ctx);
210    struct radeon_renderbuffer *rrb;
211    __DRIscreen *screen;
212    __DRIimage *image;
213
214    screen = radeon->radeonScreen->driScreen;
215    image = screen->dri2.image->lookupEGLImage(screen, image_handle,
216                                               screen->loaderPrivate);
217    if (image == NULL)
218       return;
219
220    rrb = radeon_renderbuffer(rb);
221
222    if (ctx->Driver.Flush)
223       ctx->Driver.Flush(ctx); /* +r6/r7 */
224
225    if (rrb->bo)
226       radeon_bo_unref(rrb->bo);
227    rrb->bo = image->bo;
228    radeon_bo_ref(rrb->bo);
229    fprintf(stderr, "image->bo: %p, name: %d, rbs: w %d -> p %d\n", image->bo, image->bo->handle,
230            image->width, image->pitch);
231
232    rrb->cpp = image->cpp;
233    rrb->pitch = image->pitch * image->cpp;
234
235    rb->Format = image->format;
236    rb->InternalFormat = image->internal_format;
237    rb->Width = image->width;
238    rb->Height = image->height;
239    rb->Format = image->format;
240    rb->DataType = image->data_type;
241    rb->_BaseFormat = _mesa_base_fbo_format(radeon->glCtx,
242                                            image->internal_format);
243 }
244 #endif
245
246 /**
247  * Called for each hardware renderbuffer when a _window_ is resized.
248  * Just update fields.
249  * Not used for user-created renderbuffers!
250  */
251 static GLboolean
252 radeon_alloc_window_storage(struct gl_context * ctx, struct gl_renderbuffer *rb,
253                            GLenum internalFormat, GLuint width, GLuint height)
254 {
255    ASSERT(rb->Name == 0);
256    rb->Width = width;
257    rb->Height = height;
258    rb->InternalFormat = internalFormat;
259   radeon_print(RADEON_TEXTURE, RADEON_TRACE,
260                 "%s(%p, rb %p) \n",
261                 __func__, ctx, rb);
262
263
264    return GL_TRUE;
265 }
266
267
268 static void
269 radeon_resize_buffers(struct gl_context *ctx, struct gl_framebuffer *fb,
270                      GLuint width, GLuint height)
271 {
272      struct radeon_framebuffer *radeon_fb = (struct radeon_framebuffer*)fb;
273    int i;
274
275   radeon_print(RADEON_TEXTURE, RADEON_TRACE,
276                 "%s(%p, fb %p) \n",
277                 __func__, ctx, fb);
278
279    _mesa_resize_framebuffer(ctx, fb, width, height);
280
281    fb->Initialized = GL_TRUE; /* XXX remove someday */
282
283    if (fb->Name != 0) {
284       return;
285    }
286
287    /* Make sure all window system renderbuffers are up to date */
288    for (i = 0; i < 2; i++) {
289       struct gl_renderbuffer *rb = &radeon_fb->color_rb[i]->base;
290
291       /* only resize if size is changing */
292       if (rb && (rb->Width != width || rb->Height != height)) {
293          rb->AllocStorage(ctx, rb, rb->InternalFormat, width, height);
294       }
295    }
296 }
297
298
299 /** Dummy function for gl_renderbuffer::AllocStorage() */
300 static GLboolean
301 radeon_nop_alloc_storage(struct gl_context * ctx, struct gl_renderbuffer *rb,
302                          GLenum internalFormat, GLuint width, GLuint height)
303 {
304    _mesa_problem(ctx, "radeon_op_alloc_storage should never be called.");
305    return GL_FALSE;
306 }
307
308
309 /**
310  * Create a renderbuffer for a window's color, depth and/or stencil buffer.
311  * Not used for user-created renderbuffers.
312  */
313 struct radeon_renderbuffer *
314 radeon_create_renderbuffer(gl_format format, __DRIdrawable *driDrawPriv)
315 {
316     struct radeon_renderbuffer *rrb;
317
318     rrb = CALLOC_STRUCT(radeon_renderbuffer);
319
320     radeon_print(RADEON_TEXTURE, RADEON_TRACE,
321                 "%s( rrb %p ) \n",
322                 __func__, rrb);
323
324     if (!rrb)
325         return NULL;
326
327     _mesa_init_renderbuffer(&rrb->base, 0);
328     rrb->base.ClassID = RADEON_RB_CLASS;
329
330     rrb->base.Format = format;
331
332     switch (format) {
333         case MESA_FORMAT_RGB565:
334             assert(_mesa_little_endian());
335             rrb->base.DataType = GL_UNSIGNED_BYTE;
336             rrb->base._BaseFormat = GL_RGB;
337             break;
338         case MESA_FORMAT_RGB565_REV:
339             assert(!_mesa_little_endian());
340             rrb->base.DataType = GL_UNSIGNED_BYTE;
341             rrb->base._BaseFormat = GL_RGB;
342             break;
343         case MESA_FORMAT_XRGB8888:
344             assert(_mesa_little_endian());
345             rrb->base.DataType = GL_UNSIGNED_BYTE;
346             rrb->base._BaseFormat = GL_RGB;
347             break;
348         case MESA_FORMAT_XRGB8888_REV:
349             assert(!_mesa_little_endian());
350             rrb->base.DataType = GL_UNSIGNED_BYTE;
351             rrb->base._BaseFormat = GL_RGB;
352             break;
353         case MESA_FORMAT_ARGB8888:
354             assert(_mesa_little_endian());
355             rrb->base.DataType = GL_UNSIGNED_BYTE;
356             rrb->base._BaseFormat = GL_RGBA;
357             break;
358         case MESA_FORMAT_ARGB8888_REV:
359             assert(!_mesa_little_endian());
360             rrb->base.DataType = GL_UNSIGNED_BYTE;
361             rrb->base._BaseFormat = GL_RGBA;
362             break;
363         case MESA_FORMAT_S8:
364             rrb->base.DataType = GL_UNSIGNED_BYTE;
365             rrb->base._BaseFormat = GL_STENCIL_INDEX;
366             break;
367         case MESA_FORMAT_Z16:
368             rrb->base.DataType = GL_UNSIGNED_SHORT;
369             rrb->base._BaseFormat = GL_DEPTH_COMPONENT;
370             break;
371         case MESA_FORMAT_X8_Z24:
372             rrb->base.DataType = GL_UNSIGNED_INT;
373             rrb->base._BaseFormat = GL_DEPTH_COMPONENT;
374             break;
375         case MESA_FORMAT_S8_Z24:
376             rrb->base.DataType = GL_UNSIGNED_INT_24_8_EXT;
377             rrb->base._BaseFormat = GL_DEPTH_STENCIL;
378             break;
379         default:
380             fprintf(stderr, "%s: Unknown format %s\n",
381                     __FUNCTION__, _mesa_get_format_name(format));
382             _mesa_delete_renderbuffer(&rrb->base);
383             return NULL;
384     }
385
386     rrb->dPriv = driDrawPriv;
387     rrb->base.InternalFormat = _mesa_get_format_base_format(format);
388
389     rrb->base.Delete = radeon_delete_renderbuffer;
390     rrb->base.AllocStorage = radeon_alloc_window_storage;
391     rrb->base.GetPointer = radeon_get_pointer;
392
393     rrb->bo = NULL;
394     return rrb;
395 }
396
397 static struct gl_renderbuffer *
398 radeon_new_renderbuffer(struct gl_context * ctx, GLuint name)
399 {
400   struct radeon_renderbuffer *rrb;
401
402   rrb = CALLOC_STRUCT(radeon_renderbuffer);
403
404   radeon_print(RADEON_TEXTURE, RADEON_TRACE,
405                 "%s(%p, rrb %p) \n",
406                 __func__, ctx, rrb);
407
408   if (!rrb)
409     return NULL;
410
411   _mesa_init_renderbuffer(&rrb->base, name);
412   rrb->base.ClassID = RADEON_RB_CLASS;
413
414   rrb->base.Delete = radeon_delete_renderbuffer;
415   rrb->base.AllocStorage = radeon_alloc_renderbuffer_storage;
416   rrb->base.GetPointer = radeon_get_pointer;
417
418   return &rrb->base;
419 }
420
421 static void
422 radeon_bind_framebuffer(struct gl_context * ctx, GLenum target,
423                        struct gl_framebuffer *fb, struct gl_framebuffer *fbread)
424 {
425   radeon_print(RADEON_TEXTURE, RADEON_TRACE,
426                 "%s(%p, fb %p, target %s) \n",
427                 __func__, ctx, fb,
428                 _mesa_lookup_enum_by_nr(target));
429
430    if (target == GL_FRAMEBUFFER_EXT || target == GL_DRAW_FRAMEBUFFER_EXT) {
431       radeon_draw_buffer(ctx, fb);
432    }
433    else {
434       /* don't need to do anything if target == GL_READ_FRAMEBUFFER_EXT */
435    }
436 }
437
438 static void
439 radeon_framebuffer_renderbuffer(struct gl_context * ctx,
440                                struct gl_framebuffer *fb,
441                                GLenum attachment, struct gl_renderbuffer *rb)
442 {
443
444         if (ctx->Driver.Flush)
445                 ctx->Driver.Flush(ctx); /* +r6/r7 */
446
447         radeon_print(RADEON_TEXTURE, RADEON_TRACE,
448                 "%s(%p, fb %p, rb %p) \n",
449                 __func__, ctx, fb, rb);
450
451    _mesa_framebuffer_renderbuffer(ctx, fb, attachment, rb);
452    radeon_draw_buffer(ctx, fb);
453 }
454
455 static GLboolean
456 radeon_update_wrapper(struct gl_context *ctx, struct radeon_renderbuffer *rrb, 
457                      struct gl_texture_image *texImage)
458 {
459         radeon_print(RADEON_TEXTURE, RADEON_TRACE,
460                 "%s(%p, rrb %p, texImage %p, texFormat %s) \n",
461                 __func__, ctx, rrb, texImage, _mesa_get_format_name(texImage->TexFormat));
462
463         switch (texImage->TexFormat) {
464                 case MESA_FORMAT_RGBA8888:
465                 case MESA_FORMAT_RGBA8888_REV:
466                 case MESA_FORMAT_ARGB8888:
467                 case MESA_FORMAT_ARGB8888_REV:
468                 case MESA_FORMAT_XRGB8888:
469                 case MESA_FORMAT_XRGB8888_REV:
470                 case MESA_FORMAT_RGB565:
471                 case MESA_FORMAT_RGB565_REV:
472                 case MESA_FORMAT_RGBA5551:
473                 case MESA_FORMAT_ARGB1555:
474                 case MESA_FORMAT_ARGB1555_REV:
475                 case MESA_FORMAT_ARGB4444:
476                 case MESA_FORMAT_ARGB4444_REV:
477                         rrb->base.DataType = GL_UNSIGNED_BYTE;
478                         break;
479                 case MESA_FORMAT_Z16:
480                         rrb->base.DataType = GL_UNSIGNED_SHORT;
481                         break;
482                 case MESA_FORMAT_X8_Z24:
483                         rrb->base.DataType = GL_UNSIGNED_INT;
484                         break;
485                 case MESA_FORMAT_S8_Z24:
486                         rrb->base.DataType = GL_UNSIGNED_INT_24_8_EXT;
487                         break;
488                 default:
489                         _mesa_problem(ctx, "Unexpected texture format in radeon_update_wrapper()");
490         }
491                 
492         rrb->cpp = _mesa_get_format_bytes(texImage->TexFormat);
493         rrb->pitch = texImage->Width * rrb->cpp;
494         rrb->base.Format = texImage->TexFormat;
495         rrb->base.InternalFormat = texImage->InternalFormat;
496         rrb->base._BaseFormat = _mesa_base_fbo_format(ctx, rrb->base.InternalFormat);
497         rrb->base.Width = texImage->Width;
498         rrb->base.Height = texImage->Height;
499         rrb->base.Delete = radeon_delete_renderbuffer;
500         rrb->base.AllocStorage = radeon_nop_alloc_storage;
501
502         return GL_TRUE;
503 }
504
505
506 static struct radeon_renderbuffer *
507 radeon_wrap_texture(struct gl_context * ctx, struct gl_texture_image *texImage)
508 {
509   const GLuint name = ~0;   /* not significant, but distinct for debugging */
510   struct radeon_renderbuffer *rrb;
511
512    /* make an radeon_renderbuffer to wrap the texture image */
513    rrb = CALLOC_STRUCT(radeon_renderbuffer);
514
515    radeon_print(RADEON_TEXTURE, RADEON_TRACE,
516                 "%s(%p, rrb %p, texImage %p) \n",
517                 __func__, ctx, rrb, texImage);
518
519    if (!rrb) {
520       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glFramebufferTexture");
521       return NULL;
522    }
523
524    _mesa_init_renderbuffer(&rrb->base, name);
525    rrb->base.ClassID = RADEON_RB_CLASS;
526
527    if (!radeon_update_wrapper(ctx, rrb, texImage)) {
528       free(rrb);
529       return NULL;
530    }
531
532    return rrb;
533   
534 }
535 static void
536 radeon_render_texture(struct gl_context * ctx,
537                      struct gl_framebuffer *fb,
538                      struct gl_renderbuffer_attachment *att)
539 {
540    struct gl_texture_image *newImage
541       = att->Texture->Image[att->CubeMapFace][att->TextureLevel];
542    struct radeon_renderbuffer *rrb = radeon_renderbuffer(att->Renderbuffer);
543    radeon_texture_image *radeon_image;
544    GLuint imageOffset;
545
546   radeon_print(RADEON_TEXTURE, RADEON_TRACE,
547                 "%s(%p, fb %p, rrb %p, att %p)\n",
548                 __func__, ctx, fb, rrb, att);
549
550    (void) fb;
551
552    ASSERT(newImage);
553
554    radeon_image = (radeon_texture_image *)newImage;
555
556    if (!radeon_image->mt || newImage->Border != 0) {
557       /* Fallback on drawing to a texture without a miptree.
558        */
559       _mesa_reference_renderbuffer(&att->Renderbuffer, NULL);
560       _swrast_render_texture(ctx, fb, att);
561       return;
562    }
563    else if (!rrb) {
564       rrb = radeon_wrap_texture(ctx, newImage);
565       if (rrb) {
566          /* bind the wrapper to the attachment point */
567          _mesa_reference_renderbuffer(&att->Renderbuffer, &rrb->base);
568       }
569       else {
570          /* fallback to software rendering */
571          _swrast_render_texture(ctx, fb, att);
572          return;
573       }
574    }
575
576    if (!radeon_update_wrapper(ctx, rrb, newImage)) {
577        _mesa_reference_renderbuffer(&att->Renderbuffer, NULL);
578        _swrast_render_texture(ctx, fb, att);
579        return;
580    }
581
582    DBG("Begin render texture tid %lx tex=%u w=%d h=%d refcount=%d\n",
583        _glthread_GetID(),
584        att->Texture->Name, newImage->Width, newImage->Height,
585        rrb->base.RefCount);
586
587    /* point the renderbufer's region to the texture image region */
588    if (rrb->bo != radeon_image->mt->bo) {
589       if (rrb->bo)
590         radeon_bo_unref(rrb->bo);
591       rrb->bo = radeon_image->mt->bo;
592       radeon_bo_ref(rrb->bo);
593    }
594
595    /* compute offset of the particular 2D image within the texture region */
596    imageOffset = radeon_miptree_image_offset(radeon_image->mt,
597                                             att->CubeMapFace,
598                                             att->TextureLevel);
599
600    if (att->Texture->Target == GL_TEXTURE_3D) {
601       imageOffset += radeon_image->mt->levels[att->TextureLevel].rowstride *
602                      radeon_image->mt->levels[att->TextureLevel].height *
603                      att->Zoffset;
604    }
605
606    /* store that offset in the region, along with the correct pitch for
607     * the image we are rendering to */
608    rrb->draw_offset = imageOffset;
609    rrb->pitch = radeon_image->mt->levels[att->TextureLevel].rowstride;
610
611    /* update drawing region, etc */
612    radeon_draw_buffer(ctx, fb);
613 }
614
615 static void
616 radeon_finish_render_texture(struct gl_context * ctx,
617                             struct gl_renderbuffer_attachment *att)
618 {
619
620 }
621 static void
622 radeon_validate_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb)
623 {
624         radeonContextPtr radeon = RADEON_CONTEXT(ctx);
625         gl_format mesa_format;
626         int i;
627
628         for (i = -2; i < (GLint) ctx->Const.MaxColorAttachments; i++) {
629                 struct gl_renderbuffer_attachment *att;
630                 if (i == -2) {
631                         att = &fb->Attachment[BUFFER_DEPTH];
632                 } else if (i == -1) {
633                         att = &fb->Attachment[BUFFER_STENCIL];
634                 } else {
635                         att = &fb->Attachment[BUFFER_COLOR0 + i];
636                 }
637
638                 if (att->Type == GL_TEXTURE) {
639                         mesa_format = att->Texture->Image[att->CubeMapFace][att->TextureLevel]->TexFormat;
640                 } else {
641                         /* All renderbuffer formats are renderable, but not sampable */
642                         continue;
643                 }
644
645                 if (!radeon->vtbl.is_format_renderable(mesa_format)){
646                         fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED;
647                         radeon_print(RADEON_TEXTURE, RADEON_TRACE,
648                                                 "%s: HW doesn't support format %s as output format of attachment %d\n",
649                                                 __FUNCTION__, _mesa_get_format_name(mesa_format), i);
650                         return;
651                 }
652         }
653 }
654
655 void radeon_fbo_init(struct radeon_context *radeon)
656 {
657 #if FEATURE_EXT_framebuffer_object
658   radeon->glCtx->Driver.NewFramebuffer = radeon_new_framebuffer;
659   radeon->glCtx->Driver.NewRenderbuffer = radeon_new_renderbuffer;
660   radeon->glCtx->Driver.BindFramebuffer = radeon_bind_framebuffer;
661   radeon->glCtx->Driver.FramebufferRenderbuffer = radeon_framebuffer_renderbuffer;
662   radeon->glCtx->Driver.RenderTexture = radeon_render_texture;
663   radeon->glCtx->Driver.FinishRenderTexture = radeon_finish_render_texture;
664   radeon->glCtx->Driver.ResizeBuffers = radeon_resize_buffers;
665   radeon->glCtx->Driver.ValidateFramebuffer = radeon_validate_framebuffer;
666 #endif
667 #if FEATURE_EXT_framebuffer_blit
668   radeon->glCtx->Driver.BlitFramebuffer = _mesa_meta_BlitFramebuffer;
669 #endif
670 #if FEATURE_OES_EGL_image
671   radeon->glCtx->Driver.EGLImageTargetRenderbufferStorage =
672           radeon_image_target_renderbuffer_storage;
673 #endif
674 }
675
676   
677 void radeon_renderbuffer_set_bo(struct radeon_renderbuffer *rb,
678                                 struct radeon_bo *bo)
679 {
680   struct radeon_bo *old;
681   old = rb->bo;
682   rb->bo = bo;
683   radeon_bo_ref(bo);
684   if (old)
685     radeon_bo_unref(old);
686 }