radeon_fbo.c revision f9e1542286a05e9773f8f31ee75887f6da969cdb
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 "main/texrender.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
50static struct gl_framebuffer *
51radeon_new_framebuffer(struct gl_context *ctx, GLuint name)
52{
53  return _mesa_new_framebuffer(ctx, name);
54}
55
56static void
57radeon_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
73static void *
74radeon_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 */
88static GLboolean
89radeon_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
204static void
205radeon_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 */
251static GLboolean
252radeon_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
268static void
269radeon_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() */
300static GLboolean
301radeon_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 */
313struct radeon_renderbuffer *
314radeon_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
397static struct gl_renderbuffer *
398radeon_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
421static void
422radeon_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
438static void
439radeon_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
455static GLboolean
456radeon_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
506static struct radeon_renderbuffer *
507radeon_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}
535static void
536radeon_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      _mesa_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         _mesa_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       _mesa_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
615static void
616radeon_finish_render_texture(struct gl_context * ctx,
617                            struct gl_renderbuffer_attachment *att)
618{
619
620}
621static void
622radeon_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
655void 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
677void 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}
687