mesa: move texrender.c to swrast
[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/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/s_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
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 }