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