1 /**************************************************************************
3 * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas.
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:
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
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.
26 **************************************************************************/
29 #include "main/imports.h"
30 #include "main/macros.h"
31 #include "main/mfeatures.h"
32 #include "main/mtypes.h"
33 #include "main/fbobject.h"
34 #include "main/framebuffer.h"
35 #include "main/renderbuffer.h"
36 #include "main/context.h"
37 #include "main/teximage.h"
38 #include "swrast/swrast.h"
39 #include "drivers/common/meta.h"
41 #include "intel_context.h"
42 #include "intel_batchbuffer.h"
43 #include "intel_buffers.h"
44 #include "intel_fbo.h"
45 #include "intel_mipmap_tree.h"
46 #include "intel_regions.h"
47 #include "intel_tex.h"
48 #include "intel_span.h"
50 #include "brw_context.h"
53 #define FILE_DEBUG_FLAG DEBUG_FBO
57 * Create a new framebuffer object.
59 static struct gl_framebuffer *
60 intel_new_framebuffer(struct gl_context * ctx, GLuint name)
62 /* Only drawable state in intel_framebuffer at this time, just use Mesa's
65 return _mesa_new_framebuffer(ctx, name);
69 /** Called by gl_renderbuffer::Delete() */
71 intel_delete_renderbuffer(struct gl_renderbuffer *rb)
73 struct intel_renderbuffer *irb = intel_renderbuffer(rb);
77 intel_region_release(&irb->region);
78 intel_region_release(&irb->hiz_region);
80 _mesa_reference_renderbuffer(&irb->wrapped_depth, NULL);
81 _mesa_reference_renderbuffer(&irb->wrapped_stencil, NULL);
88 * Return a pointer to a specific pixel in a renderbuffer.
91 intel_get_pointer(struct gl_context * ctx, struct gl_renderbuffer *rb,
94 /* By returning NULL we force all software rendering to go through
102 * Called via glRenderbufferStorageEXT() to set the format and allocate
103 * storage for a user-created renderbuffer.
106 intel_alloc_renderbuffer_storage(struct gl_context * ctx, struct gl_renderbuffer *rb,
107 GLenum internalFormat,
108 GLuint width, GLuint height)
110 struct intel_context *intel = intel_context(ctx);
111 struct intel_renderbuffer *irb = intel_renderbuffer(rb);
114 ASSERT(rb->Name != 0);
116 switch (internalFormat) {
118 /* Use the same format-choice logic as for textures.
119 * Renderbuffers aren't any different from textures for us,
120 * except they're less useful because you can't texture with
123 rb->Format = intel->ctx.Driver.ChooseTextureFormat(ctx, internalFormat,
126 case GL_STENCIL_INDEX:
127 case GL_STENCIL_INDEX1_EXT:
128 case GL_STENCIL_INDEX4_EXT:
129 case GL_STENCIL_INDEX8_EXT:
130 case GL_STENCIL_INDEX16_EXT:
131 /* These aren't actual texture formats, so force them here. */
132 if (intel->has_separate_stencil) {
133 rb->Format = MESA_FORMAT_S8;
135 assert(!intel->must_use_separate_stencil);
136 rb->Format = MESA_FORMAT_S8_Z24;
143 rb->_BaseFormat = _mesa_base_fbo_format(ctx, internalFormat);
144 rb->DataType = intel_mesa_format_to_rb_datatype(rb->Format);
145 cpp = _mesa_get_format_bytes(rb->Format);
149 /* free old region */
151 intel_region_release(&irb->region);
153 if (irb->hiz_region) {
154 intel_region_release(&irb->hiz_region);
157 /* allocate new memory region/renderbuffer */
159 /* alloc hardware renderbuffer */
160 DBG("Allocating %d x %d Intel RBO\n", width, height);
162 tiling = I915_TILING_NONE;
163 if (intel->use_texture_tiling) {
164 GLenum base_format = _mesa_get_format_base_format(rb->Format);
166 if (intel->gen >= 4 && (base_format == GL_DEPTH_COMPONENT ||
167 base_format == GL_STENCIL_INDEX ||
168 base_format == GL_DEPTH_STENCIL))
169 tiling = I915_TILING_Y;
171 tiling = I915_TILING_X;
174 if (irb->Base.Format == MESA_FORMAT_S8) {
176 * The stencil buffer is W tiled. However, we request from the kernel a
177 * non-tiled buffer because the GTT is incapable of W fencing.
179 * The stencil buffer has quirky pitch requirements. From Vol 2a,
180 * 11.5.6.2.1 3DSTATE_STENCIL_BUFFER, field "Surface Pitch":
181 * The pitch must be set to 2x the value computed based on width, as
182 * the stencil buffer is stored with two rows interleaved.
183 * To accomplish this, we resort to the nasty hack of doubling the drm
184 * region's cpp and halving its height.
186 * If we neglect to double the pitch, then render corruption occurs.
188 irb->region = intel_region_alloc(intel->intelScreen,
192 ALIGN((height + 1) / 2, 64),
197 } else if (irb->Base.Format == MESA_FORMAT_S8_Z24
198 && intel->must_use_separate_stencil) {
201 struct gl_renderbuffer *depth_rb;
202 struct gl_renderbuffer *stencil_rb;
204 depth_rb = intel_create_wrapped_renderbuffer(ctx, width, height,
206 stencil_rb = intel_create_wrapped_renderbuffer(ctx, width, height,
208 ok = depth_rb && stencil_rb;
209 ok = ok && intel_alloc_renderbuffer_storage(ctx, depth_rb,
210 depth_rb->InternalFormat,
212 ok = ok && intel_alloc_renderbuffer_storage(ctx, stencil_rb,
213 stencil_rb->InternalFormat,
218 intel_delete_renderbuffer(depth_rb);
221 intel_delete_renderbuffer(stencil_rb);
226 depth_rb->Wrapped = rb;
227 stencil_rb->Wrapped = rb;
228 _mesa_reference_renderbuffer(&irb->wrapped_depth, depth_rb);
229 _mesa_reference_renderbuffer(&irb->wrapped_stencil, stencil_rb);
232 irb->region = intel_region_alloc(intel->intelScreen, tiling, cpp,
233 width, height, GL_TRUE);
237 if (intel->vtbl.is_hiz_depth_format(intel, rb->Format)) {
238 irb->hiz_region = intel_region_alloc(intel->intelScreen,
244 if (!irb->hiz_region) {
245 intel_region_release(&irb->region);
255 #if FEATURE_OES_EGL_image
257 intel_image_target_renderbuffer_storage(struct gl_context *ctx,
258 struct gl_renderbuffer *rb,
261 struct intel_context *intel = intel_context(ctx);
262 struct intel_renderbuffer *irb;
266 screen = intel->intelScreen->driScrnPriv;
267 image = screen->dri2.image->lookupEGLImage(screen, image_handle,
268 screen->loaderPrivate);
272 irb = intel_renderbuffer(rb);
274 intel_region_release(&irb->region);
275 intel_region_reference(&irb->region, image->region);
277 rb->InternalFormat = image->internal_format;
278 rb->Width = image->region->width;
279 rb->Height = image->region->height;
280 rb->Format = image->format;
281 rb->DataType = image->data_type;
282 rb->_BaseFormat = _mesa_base_fbo_format(&intel->ctx,
283 image->internal_format);
288 * Called for each hardware renderbuffer when a _window_ is resized.
289 * Just update fields.
290 * Not used for user-created renderbuffers!
293 intel_alloc_window_storage(struct gl_context * ctx, struct gl_renderbuffer *rb,
294 GLenum internalFormat, GLuint width, GLuint height)
296 ASSERT(rb->Name == 0);
299 rb->InternalFormat = internalFormat;
306 intel_resize_buffers(struct gl_context *ctx, struct gl_framebuffer *fb,
307 GLuint width, GLuint height)
311 _mesa_resize_framebuffer(ctx, fb, width, height);
313 fb->Initialized = GL_TRUE; /* XXX remove someday */
320 /* Make sure all window system renderbuffers are up to date */
321 for (i = BUFFER_FRONT_LEFT; i <= BUFFER_BACK_RIGHT; i++) {
322 struct gl_renderbuffer *rb = fb->Attachment[i].Renderbuffer;
324 /* only resize if size is changing */
325 if (rb && (rb->Width != width || rb->Height != height)) {
326 rb->AllocStorage(ctx, rb, rb->InternalFormat, width, height);
332 /** Dummy function for gl_renderbuffer::AllocStorage() */
334 intel_nop_alloc_storage(struct gl_context * ctx, struct gl_renderbuffer *rb,
335 GLenum internalFormat, GLuint width, GLuint height)
337 _mesa_problem(ctx, "intel_op_alloc_storage should never be called.");
343 intel_renderbuffer_set_region(struct intel_context *intel,
344 struct intel_renderbuffer *rb,
345 struct intel_region *region)
347 struct intel_region *old;
351 intel_region_reference(&rb->region, region);
352 intel_region_release(&old);
357 intel_renderbuffer_set_hiz_region(struct intel_context *intel,
358 struct intel_renderbuffer *rb,
359 struct intel_region *region)
361 struct intel_region *old = rb->hiz_region;
362 rb->hiz_region = NULL;
363 intel_region_reference(&rb->hiz_region, region);
364 intel_region_release(&old);
369 * Create a new intel_renderbuffer which corresponds to an on-screen window,
370 * not a user-created renderbuffer.
372 struct intel_renderbuffer *
373 intel_create_renderbuffer(gl_format format)
375 GET_CURRENT_CONTEXT(ctx);
377 struct intel_renderbuffer *irb;
379 irb = CALLOC_STRUCT(intel_renderbuffer);
381 _mesa_error(ctx, GL_OUT_OF_MEMORY, "creating renderbuffer");
385 _mesa_init_renderbuffer(&irb->Base, 0);
386 irb->Base.ClassID = INTEL_RB_CLASS;
387 irb->Base._BaseFormat = _mesa_get_format_base_format(format);
388 irb->Base.Format = format;
389 irb->Base.InternalFormat = irb->Base._BaseFormat;
390 irb->Base.DataType = intel_mesa_format_to_rb_datatype(format);
392 /* intel-specific methods */
393 irb->Base.Delete = intel_delete_renderbuffer;
394 irb->Base.AllocStorage = intel_alloc_window_storage;
395 irb->Base.GetPointer = intel_get_pointer;
401 struct gl_renderbuffer*
402 intel_create_wrapped_renderbuffer(struct gl_context * ctx,
403 int width, int height,
407 * The name here is irrelevant, as long as its nonzero, because the
408 * renderbuffer never gets entered into Mesa's renderbuffer hash table.
412 struct intel_renderbuffer *irb = CALLOC_STRUCT(intel_renderbuffer);
414 _mesa_error(ctx, GL_OUT_OF_MEMORY, "creating renderbuffer");
418 struct gl_renderbuffer *rb = &irb->Base;
419 _mesa_init_renderbuffer(rb, name);
420 rb->ClassID = INTEL_RB_CLASS;
421 rb->_BaseFormat = _mesa_get_format_base_format(format);
423 rb->InternalFormat = rb->_BaseFormat;
424 rb->DataType = intel_mesa_format_to_rb_datatype(format);
433 * Create a new renderbuffer object.
434 * Typically called via glBindRenderbufferEXT().
436 static struct gl_renderbuffer *
437 intel_new_renderbuffer(struct gl_context * ctx, GLuint name)
439 /*struct intel_context *intel = intel_context(ctx); */
440 struct intel_renderbuffer *irb;
442 irb = CALLOC_STRUCT(intel_renderbuffer);
444 _mesa_error(ctx, GL_OUT_OF_MEMORY, "creating renderbuffer");
448 _mesa_init_renderbuffer(&irb->Base, name);
449 irb->Base.ClassID = INTEL_RB_CLASS;
451 /* intel-specific methods */
452 irb->Base.Delete = intel_delete_renderbuffer;
453 irb->Base.AllocStorage = intel_alloc_renderbuffer_storage;
454 irb->Base.GetPointer = intel_get_pointer;
455 /* span routines set in alloc_storage function */
462 * Called via glBindFramebufferEXT().
465 intel_bind_framebuffer(struct gl_context * ctx, GLenum target,
466 struct gl_framebuffer *fb, struct gl_framebuffer *fbread)
468 if (target == GL_FRAMEBUFFER_EXT || target == GL_DRAW_FRAMEBUFFER_EXT) {
469 intel_draw_buffer(ctx, fb);
472 /* don't need to do anything if target == GL_READ_FRAMEBUFFER_EXT */
478 * Called via glFramebufferRenderbufferEXT().
481 intel_framebuffer_renderbuffer(struct gl_context * ctx,
482 struct gl_framebuffer *fb,
483 GLenum attachment, struct gl_renderbuffer *rb)
485 DBG("Intel FramebufferRenderbuffer %u %u\n", fb->Name, rb ? rb->Name : 0);
489 _mesa_framebuffer_renderbuffer(ctx, fb, attachment, rb);
490 intel_draw_buffer(ctx, fb);
494 intel_update_tex_wrapper_regions(struct intel_context *intel,
495 struct intel_renderbuffer *irb,
496 struct intel_texture_image *intel_image);
499 intel_update_wrapper(struct gl_context *ctx, struct intel_renderbuffer *irb,
500 struct gl_texture_image *texImage)
502 struct intel_context *intel = intel_context(ctx);
503 struct intel_texture_image *intel_image = intel_texture_image(texImage);
505 if (!intel_span_supports_format(texImage->TexFormat)) {
506 DBG("Render to texture BAD FORMAT %s\n",
507 _mesa_get_format_name(texImage->TexFormat));
510 DBG("Render to texture %s\n", _mesa_get_format_name(texImage->TexFormat));
513 irb->Base.Format = texImage->TexFormat;
514 irb->Base.DataType = intel_mesa_format_to_rb_datatype(texImage->TexFormat);
515 irb->Base.InternalFormat = texImage->InternalFormat;
516 irb->Base._BaseFormat = _mesa_base_tex_format(ctx, irb->Base.InternalFormat);
517 irb->Base.Width = texImage->Width;
518 irb->Base.Height = texImage->Height;
520 irb->Base.Delete = intel_delete_renderbuffer;
521 irb->Base.AllocStorage = intel_nop_alloc_storage;
523 if (intel_image->stencil_rb) {
524 /* The tex image has packed depth/stencil format, but is using separate
528 struct intel_renderbuffer *depth_irb =
529 intel_renderbuffer(intel_image->depth_rb);
531 /* Update the hiz region if necessary. */
532 ok = intel_update_tex_wrapper_regions(intel, depth_irb, intel_image);
537 /* The tex image shares its embedded depth and stencil renderbuffers with
538 * the renderbuffer wrapper. */
539 if (irb->wrapped_depth != intel_image->depth_rb) {
540 _mesa_reference_renderbuffer(&irb->wrapped_depth,
541 intel_image->depth_rb);
543 if (irb->wrapped_stencil != intel_image->stencil_rb) {
544 _mesa_reference_renderbuffer(&irb->wrapped_stencil,
545 intel_image->stencil_rb);
551 return intel_update_tex_wrapper_regions(intel, irb, intel_image);
556 * FIXME: The handling of the hiz region is broken for mipmapped depth textures
557 * FIXME: because intel_finalize_mipmap_tree is unaware of it.
560 intel_update_tex_wrapper_regions(struct intel_context *intel,
561 struct intel_renderbuffer *irb,
562 struct intel_texture_image *intel_image)
564 struct gl_renderbuffer *rb = &irb->Base;
566 /* Point the renderbuffer's region to the texture's region. */
567 if (irb->region != intel_image->mt->region) {
568 intel_region_release(&irb->region);
569 intel_region_reference(&irb->region, intel_image->mt->region);
572 /* Allocate the texture's hiz region if necessary. */
573 if (intel->vtbl.is_hiz_depth_format(intel, rb->Format)
574 && !intel_image->mt->hiz_region) {
575 intel_image->mt->hiz_region =
576 intel_region_alloc(intel->intelScreen,
578 _mesa_get_format_bytes(rb->Format),
582 if (!intel_image->mt->hiz_region)
586 /* Point the renderbuffer's hiz region to the texture's hiz region. */
587 if (irb->hiz_region != intel_image->mt->hiz_region) {
588 intel_region_release(&irb->hiz_region);
589 intel_region_reference(&irb->hiz_region, intel_image->mt->hiz_region);
597 * When glFramebufferTexture[123]D is called this function sets up the
598 * gl_renderbuffer wrapper around the texture image.
599 * This will have the region info needed for hardware rendering.
601 static struct intel_renderbuffer *
602 intel_wrap_texture(struct gl_context * ctx, struct gl_texture_image *texImage)
604 const GLuint name = ~0; /* not significant, but distinct for debugging */
605 struct intel_renderbuffer *irb;
607 /* make an intel_renderbuffer to wrap the texture image */
608 irb = CALLOC_STRUCT(intel_renderbuffer);
610 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glFramebufferTexture");
614 _mesa_init_renderbuffer(&irb->Base, name);
615 irb->Base.ClassID = INTEL_RB_CLASS;
617 if (!intel_update_wrapper(ctx, irb, texImage)) {
626 intel_renderbuffer_set_draw_offset(struct intel_renderbuffer *irb,
627 struct intel_texture_image *intel_image,
630 struct intel_mipmap_tree *mt = intel_image->mt;
631 unsigned int dst_x, dst_y;
633 /* compute offset of the particular 2D image within the texture region */
634 intel_miptree_get_image_offset(intel_image->mt,
645 * Rendering to tiled buffers requires that the base address of the
646 * buffer be aligned to a page boundary. We generally render to
647 * textures by pointing the surface at the mipmap image level, which
648 * may not be aligned to a tile boundary.
650 * This function returns an appropriately-aligned base offset
651 * according to the tiling restrictions, plus any required x/y offset
655 intel_renderbuffer_tile_offsets(struct intel_renderbuffer *irb,
659 int cpp = irb->region->cpp;
660 uint32_t pitch = irb->region->pitch * cpp;
662 if (irb->region->tiling == I915_TILING_NONE) {
665 return irb->draw_x * cpp + irb->draw_y * pitch;
666 } else if (irb->region->tiling == I915_TILING_X) {
667 *tile_x = irb->draw_x % (512 / cpp);
668 *tile_y = irb->draw_y % 8;
669 return ((irb->draw_y / 8) * (8 * pitch) +
670 (irb->draw_x - *tile_x) / (512 / cpp) * 4096);
672 assert(irb->region->tiling == I915_TILING_Y);
673 *tile_x = irb->draw_x % (128 / cpp);
674 *tile_y = irb->draw_y % 32;
675 return ((irb->draw_y / 32) * (32 * pitch) +
676 (irb->draw_x - *tile_x) / (128 / cpp) * 4096);
682 need_tile_offset_workaround(struct brw_context *brw,
683 struct intel_renderbuffer *irb)
685 uint32_t tile_x, tile_y;
687 if (brw->has_surface_tile_offset)
690 intel_renderbuffer_tile_offsets(irb, &tile_x, &tile_y);
692 return tile_x != 0 || tile_y != 0;
697 * Called by glFramebufferTexture[123]DEXT() (and other places) to
698 * prepare for rendering into texture memory. This might be called
699 * many times to choose different texture levels, cube faces, etc
700 * before intel_finish_render_texture() is ever called.
703 intel_render_texture(struct gl_context * ctx,
704 struct gl_framebuffer *fb,
705 struct gl_renderbuffer_attachment *att)
707 struct gl_texture_image *image = _mesa_get_attachment_teximage(att);
708 struct intel_renderbuffer *irb = intel_renderbuffer(att->Renderbuffer);
709 struct intel_texture_image *intel_image = intel_texture_image(image);
713 if (!intel_image->mt) {
714 /* Fallback on drawing to a texture that doesn't have a miptree
715 * (has a border, width/height 0, etc.)
717 _mesa_reference_renderbuffer(&att->Renderbuffer, NULL);
718 _swrast_render_texture(ctx, fb, att);
722 irb = intel_wrap_texture(ctx, image);
724 /* bind the wrapper to the attachment point */
725 _mesa_reference_renderbuffer(&att->Renderbuffer, &irb->Base);
728 /* fallback to software rendering */
729 _swrast_render_texture(ctx, fb, att);
734 if (!intel_update_wrapper(ctx, irb, image)) {
735 _mesa_reference_renderbuffer(&att->Renderbuffer, NULL);
736 _swrast_render_texture(ctx, fb, att);
740 DBG("Begin render texture tid %lx tex=%u w=%d h=%d refcount=%d\n",
742 att->Texture->Name, image->Width, image->Height,
745 intel_renderbuffer_set_draw_offset(irb, intel_image, att->Zoffset);
746 intel_image->used_as_render_target = GL_TRUE;
749 if (need_tile_offset_workaround(brw_context(ctx), irb)) {
750 /* Original gen4 hardware couldn't draw to a non-tile-aligned
751 * destination in a miptree unless you actually setup your
752 * renderbuffer as a miptree and used the fragile
753 * lod/array_index/etc. controls to select the image. So,
754 * instead, we just make a new single-level miptree and render
757 struct intel_context *intel = intel_context(ctx);
758 struct intel_mipmap_tree *old_mt = intel_image->mt;
759 struct intel_mipmap_tree *new_mt;
761 new_mt = intel_miptree_create(intel, image->TexObject->Target,
762 intel_image->base.TexFormat,
765 intel_image->base.Width,
766 intel_image->base.Height,
767 intel_image->base.Depth,
770 intel_miptree_image_copy(intel,
776 intel_miptree_release(intel, &intel_image->mt);
777 intel_image->mt = new_mt;
778 intel_renderbuffer_set_draw_offset(irb, intel_image, att->Zoffset);
780 intel_region_release(&irb->region);
781 intel_region_reference(&irb->region, intel_image->mt->region);
784 /* update drawing region, etc */
785 intel_draw_buffer(ctx, fb);
790 * Called by Mesa when rendering to a texture is done.
793 intel_finish_render_texture(struct gl_context * ctx,
794 struct gl_renderbuffer_attachment *att)
796 struct intel_context *intel = intel_context(ctx);
797 struct gl_texture_object *tex_obj = att->Texture;
798 struct gl_texture_image *image =
799 tex_obj->Image[att->CubeMapFace][att->TextureLevel];
800 struct intel_texture_image *intel_image = intel_texture_image(image);
802 DBG("Finish render texture tid %lx tex=%u\n",
803 _glthread_GetID(), att->Texture->Name);
805 /* Flag that this image may now be validated into the object's miptree. */
807 intel_image->used_as_render_target = GL_FALSE;
809 /* Since we've (probably) rendered to the texture and will (likely) use
810 * it in the texture domain later on in this batchbuffer, flush the
811 * batch. Once again, we wish for a domain tracker in libdrm to cover
812 * usage inside of a batchbuffer like GEM does in the kernel.
814 intel_batchbuffer_emit_mi_flush(intel);
818 * Do additional "completeness" testing of a framebuffer object.
821 intel_validate_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb)
823 struct intel_context *intel = intel_context(ctx);
824 const struct intel_renderbuffer *depthRb =
825 intel_get_renderbuffer(fb, BUFFER_DEPTH);
826 const struct intel_renderbuffer *stencilRb =
827 intel_get_renderbuffer(fb, BUFFER_STENCIL);
831 * The depth and stencil renderbuffers are the same renderbuffer or wrap
834 bool depth_stencil_are_same;
835 if (depthRb && stencilRb && depthRb == stencilRb)
836 depth_stencil_are_same = true;
837 else if (depthRb && stencilRb && depthRb != stencilRb
838 && (fb->Attachment[BUFFER_DEPTH].Type == GL_TEXTURE)
839 && (fb->Attachment[BUFFER_STENCIL].Type == GL_TEXTURE)
840 && (fb->Attachment[BUFFER_DEPTH].Texture->Name
841 == fb->Attachment[BUFFER_STENCIL].Texture->Name))
842 depth_stencil_are_same = true;
844 depth_stencil_are_same = false;
846 if (!intel->has_separate_stencil
847 && depthRb && stencilRb
848 && !depth_stencil_are_same) {
849 fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
852 for (i = 0; i < Elements(fb->Attachment); i++) {
853 struct gl_renderbuffer *rb;
854 struct intel_renderbuffer *irb;
856 if (fb->Attachment[i].Type == GL_NONE)
859 /* A supported attachment will have a Renderbuffer set either
860 * from being a Renderbuffer or being a texture that got the
861 * intel_wrap_texture() treatment.
863 rb = fb->Attachment[i].Renderbuffer;
865 DBG("attachment without renderbuffer\n");
866 fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
870 irb = intel_renderbuffer(rb);
872 DBG("software rendering renderbuffer\n");
873 fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
877 if (!intel_span_supports_format(irb->Base.Format) ||
878 !intel->vtbl.render_target_supported(irb->Base.Format)) {
879 DBG("Unsupported texture/renderbuffer format attached: %s\n",
880 _mesa_get_format_name(irb->Base.Format));
881 fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
887 * Try to do a glBlitFramebuffer using glCopyTexSubImage2D
888 * We can do this when the dst renderbuffer is actually a texture and
889 * there is no scaling, mirroring or scissoring.
891 * \return new buffer mask indicating the buffers left to blit using the
895 intel_blit_framebuffer_copy_tex_sub_image(struct gl_context *ctx,
896 GLint srcX0, GLint srcY0,
897 GLint srcX1, GLint srcY1,
898 GLint dstX0, GLint dstY0,
899 GLint dstX1, GLint dstY1,
900 GLbitfield mask, GLenum filter)
902 if (mask & GL_COLOR_BUFFER_BIT) {
903 const struct gl_framebuffer *drawFb = ctx->DrawBuffer;
904 const struct gl_framebuffer *readFb = ctx->ReadBuffer;
905 const struct gl_renderbuffer_attachment *drawAtt =
906 &drawFb->Attachment[drawFb->_ColorDrawBufferIndexes[0]];
908 /* If the source and destination are the same size with no
909 mirroring, the rectangles are within the size of the
910 texture and there is no scissor then we can use
911 glCopyTexSubimage2D to implement the blit. This will end
912 up as a fast hardware blit on some drivers */
913 if (drawAtt && drawAtt->Texture &&
914 srcX0 - srcX1 == dstX0 - dstX1 &&
915 srcY0 - srcY1 == dstY0 - dstY1 &&
918 srcX0 >= 0 && srcX1 <= readFb->Width &&
919 srcY0 >= 0 && srcY1 <= readFb->Height &&
920 dstX0 >= 0 && dstX1 <= drawFb->Width &&
921 dstY0 >= 0 && dstY1 <= drawFb->Height &&
922 !ctx->Scissor.Enabled) {
923 const struct gl_texture_object *texObj = drawAtt->Texture;
924 const GLuint dstLevel = drawAtt->TextureLevel;
925 const GLenum target = texObj->Target;
927 struct gl_texture_image *texImage =
928 _mesa_select_tex_image(ctx, texObj, target, dstLevel);
929 GLenum internalFormat = texImage->InternalFormat;
931 if (intel_copy_texsubimage(intel_context(ctx), target,
932 intel_texture_image(texImage),
936 srcX1 - srcX0, /* width */
938 mask &= ~GL_COLOR_BUFFER_BIT;
946 intel_blit_framebuffer(struct gl_context *ctx,
947 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
948 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
949 GLbitfield mask, GLenum filter)
951 /* Try faster, glCopyTexSubImage2D approach first which uses the BLT. */
952 mask = intel_blit_framebuffer_copy_tex_sub_image(ctx,
953 srcX0, srcY0, srcX1, srcY1,
954 dstX0, dstY0, dstX1, dstY1,
959 _mesa_meta_BlitFramebuffer(ctx,
960 srcX0, srcY0, srcX1, srcY1,
961 dstX0, dstY0, dstX1, dstY1,
966 * Do one-time context initializations related to GL_EXT_framebuffer_object.
967 * Hook in device driver functions.
970 intel_fbo_init(struct intel_context *intel)
972 intel->ctx.Driver.NewFramebuffer = intel_new_framebuffer;
973 intel->ctx.Driver.NewRenderbuffer = intel_new_renderbuffer;
974 intel->ctx.Driver.BindFramebuffer = intel_bind_framebuffer;
975 intel->ctx.Driver.FramebufferRenderbuffer = intel_framebuffer_renderbuffer;
976 intel->ctx.Driver.RenderTexture = intel_render_texture;
977 intel->ctx.Driver.FinishRenderTexture = intel_finish_render_texture;
978 intel->ctx.Driver.ResizeBuffers = intel_resize_buffers;
979 intel->ctx.Driver.ValidateFramebuffer = intel_validate_framebuffer;
980 intel->ctx.Driver.BlitFramebuffer = intel_blit_framebuffer;
982 #if FEATURE_OES_EGL_image
983 intel->ctx.Driver.EGLImageTargetRenderbufferStorage =
984 intel_image_target_renderbuffer_storage;