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