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/enums.h"
30 #include "main/imports.h"
31 #include "main/macros.h"
32 #include "main/mfeatures.h"
33 #include "main/mtypes.h"
34 #include "main/fbobject.h"
35 #include "main/framebuffer.h"
36 #include "main/renderbuffer.h"
37 #include "main/context.h"
38 #include "main/teximage.h"
39 #include "main/image.h"
41 #include "swrast/swrast.h"
42 #include "drivers/common/meta.h"
44 #include "intel_context.h"
45 #include "intel_batchbuffer.h"
46 #include "intel_buffers.h"
47 #include "intel_blit.h"
48 #include "intel_fbo.h"
49 #include "intel_mipmap_tree.h"
50 #include "intel_regions.h"
51 #include "intel_tex.h"
52 #include "intel_span.h"
54 #include "brw_context.h"
57 #define FILE_DEBUG_FLAG DEBUG_FBO
59 static struct gl_renderbuffer
*
60 intel_new_renderbuffer(struct gl_context
* ctx
, GLuint name
);
63 intel_get_rb_region(struct gl_framebuffer
*fb
, GLuint attIndex
)
65 struct intel_renderbuffer
*irb
= intel_get_renderbuffer(fb
, attIndex
);
67 if (attIndex
== BUFFER_STENCIL
&& irb
->mt
->stencil_mt
)
68 return irb
->mt
->stencil_mt
->region
;
70 return irb
->mt
->region
;
76 * Create a new framebuffer object.
78 static struct gl_framebuffer
*
79 intel_new_framebuffer(struct gl_context
* ctx
, GLuint name
)
81 /* Only drawable state in intel_framebuffer at this time, just use Mesa's
84 return _mesa_new_framebuffer(ctx
, name
);
88 /** Called by gl_renderbuffer::Delete() */
90 intel_delete_renderbuffer(struct gl_renderbuffer
*rb
)
92 struct intel_renderbuffer
*irb
= intel_renderbuffer(rb
);
96 intel_miptree_release(&irb
->mt
);
102 * \see dd_function_table::MapRenderbuffer
105 intel_map_renderbuffer(struct gl_context
*ctx
,
106 struct gl_renderbuffer
*rb
,
107 GLuint x
, GLuint y
, GLuint w
, GLuint h
,
112 struct intel_context
*intel
= intel_context(ctx
);
113 struct swrast_renderbuffer
*srb
= (struct swrast_renderbuffer
*)rb
;
114 struct intel_renderbuffer
*irb
= intel_renderbuffer(rb
);
119 /* this is a malloc'd renderbuffer (accum buffer), not an irb */
120 GLint bpp
= _mesa_get_format_bytes(rb
->Format
);
121 GLint rowStride
= srb
->RowStride
;
122 *out_map
= (GLubyte
*) srb
->Buffer
+ y
* rowStride
+ x
* bpp
;
123 *out_stride
= rowStride
;
127 /* We sometimes get called with this by our intel_span.c usage. */
134 /* For a window-system renderbuffer, we need to flip the mapping we receive
135 * upside-down. So we need to ask for a rectangle on flipped vertically, and
136 * we then return a pointer to the bottom of it with a negative stride.
139 y
= rb
->Height
- y
- h
;
142 intel_miptree_map(intel
, irb
->mt
, irb
->mt_level
, irb
->mt_layer
,
143 x
, y
, w
, h
, mode
, &map
, &stride
);
146 map
+= (h
- 1) * stride
;
150 DBG("%s: rb %d (%s) mt mapped: (%d, %d) (%dx%d) -> %p/%d\n",
151 __FUNCTION__
, rb
->Name
, _mesa_get_format_name(rb
->Format
),
152 x
, y
, w
, h
, map
, stride
);
155 *out_stride
= stride
;
159 * \see dd_function_table::UnmapRenderbuffer
162 intel_unmap_renderbuffer(struct gl_context
*ctx
,
163 struct gl_renderbuffer
*rb
)
165 struct intel_context
*intel
= intel_context(ctx
);
166 struct swrast_renderbuffer
*srb
= (struct swrast_renderbuffer
*)rb
;
167 struct intel_renderbuffer
*irb
= intel_renderbuffer(rb
);
169 DBG("%s: rb %d (%s)\n", __FUNCTION__
,
170 rb
->Name
, _mesa_get_format_name(rb
->Format
));
173 /* this is a malloc'd renderbuffer (accum buffer) */
178 intel_miptree_unmap(intel
, irb
->mt
, irb
->mt_level
, irb
->mt_layer
);
183 * Round up the requested multisample count to the next supported sample size.
186 quantize_num_samples(struct intel_context
*intel
, unsigned num_samples
)
188 switch (intel
->gen
) {
190 /* Gen6 supports only 4x multisampling. */
196 /* Gen7 supports 4x and 8x multisampling. */
199 else if (num_samples
> 0)
205 /* MSAA unsupported */
212 * Called via glRenderbufferStorageEXT() to set the format and allocate
213 * storage for a user-created renderbuffer.
216 intel_alloc_renderbuffer_storage(struct gl_context
* ctx
, struct gl_renderbuffer
*rb
,
217 GLenum internalFormat
,
218 GLuint width
, GLuint height
)
220 struct intel_context
*intel
= intel_context(ctx
);
221 struct intel_renderbuffer
*irb
= intel_renderbuffer(rb
);
222 rb
->NumSamples
= quantize_num_samples(intel
, rb
->NumSamples
);
224 switch (internalFormat
) {
226 /* Use the same format-choice logic as for textures.
227 * Renderbuffers aren't any different from textures for us,
228 * except they're less useful because you can't texture with
231 rb
->Format
= intel
->ctx
.Driver
.ChooseTextureFormat(ctx
, internalFormat
,
234 case GL_STENCIL_INDEX
:
235 case GL_STENCIL_INDEX1_EXT
:
236 case GL_STENCIL_INDEX4_EXT
:
237 case GL_STENCIL_INDEX8_EXT
:
238 case GL_STENCIL_INDEX16_EXT
:
239 /* These aren't actual texture formats, so force them here. */
240 if (intel
->has_separate_stencil
) {
241 rb
->Format
= MESA_FORMAT_S8
;
243 assert(!intel
->must_use_separate_stencil
);
244 rb
->Format
= MESA_FORMAT_S8_Z24
;
251 rb
->_BaseFormat
= _mesa_base_fbo_format(ctx
, internalFormat
);
253 intel_miptree_release(&irb
->mt
);
255 DBG("%s: %s: %s (%dx%d)\n", __FUNCTION__
,
256 _mesa_lookup_enum_by_nr(internalFormat
),
257 _mesa_get_format_name(rb
->Format
), width
, height
);
259 if (width
== 0 || height
== 0)
262 irb
->mt
= intel_miptree_create_for_renderbuffer(intel
, rb
->Format
,
268 if (intel
->vtbl
.is_hiz_depth_format(intel
, rb
->Format
)) {
269 bool ok
= intel_miptree_alloc_hiz(intel
, irb
->mt
, rb
->NumSamples
);
271 intel_miptree_release(&irb
->mt
);
276 if (irb
->mt
->msaa_layout
== INTEL_MSAA_LAYOUT_CMS
) {
277 bool ok
= intel_miptree_alloc_mcs(intel
, irb
->mt
, rb
->NumSamples
);
279 intel_miptree_release(&irb
->mt
);
288 #if FEATURE_OES_EGL_image
290 intel_image_target_renderbuffer_storage(struct gl_context
*ctx
,
291 struct gl_renderbuffer
*rb
,
294 struct intel_context
*intel
= intel_context(ctx
);
295 struct intel_renderbuffer
*irb
;
299 screen
= intel
->intelScreen
->driScrnPriv
;
300 image
= screen
->dri2
.image
->lookupEGLImage(screen
, image_handle
,
301 screen
->loaderPrivate
);
305 /* __DRIimage is opaque to the core so it has to be checked here */
306 switch (image
->format
) {
307 case MESA_FORMAT_RGBA8888_REV
:
308 _mesa_error(&intel
->ctx
, GL_INVALID_OPERATION
,
309 "glEGLImageTargetRenderbufferStorage(unsupported image format");
316 irb
= intel_renderbuffer(rb
);
317 intel_miptree_release(&irb
->mt
);
318 irb
->mt
= intel_miptree_create_for_region(intel
,
325 rb
->InternalFormat
= image
->internal_format
;
326 rb
->Width
= image
->region
->width
;
327 rb
->Height
= image
->region
->height
;
328 rb
->Format
= image
->format
;
329 rb
->_BaseFormat
= _mesa_base_fbo_format(&intel
->ctx
,
330 image
->internal_format
);
335 * Called for each hardware renderbuffer when a _window_ is resized.
336 * Just update fields.
337 * Not used for user-created renderbuffers!
340 intel_alloc_window_storage(struct gl_context
* ctx
, struct gl_renderbuffer
*rb
,
341 GLenum internalFormat
, GLuint width
, GLuint height
)
343 ASSERT(rb
->Name
== 0);
346 rb
->InternalFormat
= internalFormat
;
353 intel_resize_buffers(struct gl_context
*ctx
, struct gl_framebuffer
*fb
,
354 GLuint width
, GLuint height
)
358 _mesa_resize_framebuffer(ctx
, fb
, width
, height
);
360 fb
->Initialized
= true; /* XXX remove someday */
362 if (_mesa_is_user_fbo(fb
)) {
367 /* Make sure all window system renderbuffers are up to date */
368 for (i
= BUFFER_FRONT_LEFT
; i
<= BUFFER_BACK_RIGHT
; i
++) {
369 struct gl_renderbuffer
*rb
= fb
->Attachment
[i
].Renderbuffer
;
371 /* only resize if size is changing */
372 if (rb
&& (rb
->Width
!= width
|| rb
->Height
!= height
)) {
373 rb
->AllocStorage(ctx
, rb
, rb
->InternalFormat
, width
, height
);
379 /** Dummy function for gl_renderbuffer::AllocStorage() */
381 intel_nop_alloc_storage(struct gl_context
* ctx
, struct gl_renderbuffer
*rb
,
382 GLenum internalFormat
, GLuint width
, GLuint height
)
384 _mesa_problem(ctx
, "intel_op_alloc_storage should never be called.");
389 * Create a new intel_renderbuffer which corresponds to an on-screen window,
390 * not a user-created renderbuffer.
392 struct intel_renderbuffer
*
393 intel_create_renderbuffer(gl_format format
)
395 struct intel_renderbuffer
*irb
;
396 struct gl_renderbuffer
*rb
;
398 GET_CURRENT_CONTEXT(ctx
);
400 irb
= CALLOC_STRUCT(intel_renderbuffer
);
402 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "creating renderbuffer");
406 rb
= &irb
->Base
.Base
;
408 _mesa_init_renderbuffer(rb
, 0);
409 rb
->ClassID
= INTEL_RB_CLASS
;
410 rb
->_BaseFormat
= _mesa_get_format_base_format(format
);
412 rb
->InternalFormat
= rb
->_BaseFormat
;
414 /* intel-specific methods */
415 rb
->Delete
= intel_delete_renderbuffer
;
416 rb
->AllocStorage
= intel_alloc_window_storage
;
422 * Private window-system buffers (as opposed to ones shared with the display
423 * server created with intel_create_renderbuffer()) are most similar in their
424 * handling to user-created renderbuffers, but they have a resize handler that
425 * may be called at intel_update_renderbuffers() time.
427 struct intel_renderbuffer
*
428 intel_create_private_renderbuffer(gl_format format
)
430 struct intel_renderbuffer
*irb
;
432 irb
= intel_create_renderbuffer(format
);
433 irb
->Base
.Base
.AllocStorage
= intel_alloc_renderbuffer_storage
;
439 * Create a new renderbuffer object.
440 * Typically called via glBindRenderbufferEXT().
442 static struct gl_renderbuffer
*
443 intel_new_renderbuffer(struct gl_context
* ctx
, GLuint name
)
445 /*struct intel_context *intel = intel_context(ctx); */
446 struct intel_renderbuffer
*irb
;
447 struct gl_renderbuffer
*rb
;
449 irb
= CALLOC_STRUCT(intel_renderbuffer
);
451 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "creating renderbuffer");
455 rb
= &irb
->Base
.Base
;
457 _mesa_init_renderbuffer(rb
, name
);
458 rb
->ClassID
= INTEL_RB_CLASS
;
460 /* intel-specific methods */
461 rb
->Delete
= intel_delete_renderbuffer
;
462 rb
->AllocStorage
= intel_alloc_renderbuffer_storage
;
463 /* span routines set in alloc_storage function */
470 * Called via glBindFramebufferEXT().
473 intel_bind_framebuffer(struct gl_context
* ctx
, GLenum target
,
474 struct gl_framebuffer
*fb
, struct gl_framebuffer
*fbread
)
476 if (target
== GL_FRAMEBUFFER_EXT
|| target
== GL_DRAW_FRAMEBUFFER_EXT
) {
477 intel_draw_buffer(ctx
);
480 /* don't need to do anything if target == GL_READ_FRAMEBUFFER_EXT */
486 * Called via glFramebufferRenderbufferEXT().
489 intel_framebuffer_renderbuffer(struct gl_context
* ctx
,
490 struct gl_framebuffer
*fb
,
491 GLenum attachment
, struct gl_renderbuffer
*rb
)
493 DBG("Intel FramebufferRenderbuffer %u %u\n", fb
->Name
, rb
? rb
->Name
: 0);
495 _mesa_framebuffer_renderbuffer(ctx
, fb
, attachment
, rb
);
496 intel_draw_buffer(ctx
);
500 * \par Special case for separate stencil
502 * When wrapping a depthstencil texture that uses separate stencil, this
503 * function is recursively called twice: once to create \c
504 * irb->wrapped_depth and again to create \c irb->wrapped_stencil. On the
505 * call to create \c irb->wrapped_depth, the \c format and \c
506 * internal_format parameters do not match \c mt->format. In that case, \c
507 * mt->format is MESA_FORMAT_S8_Z24 and \c format is \c
508 * MESA_FORMAT_X8_Z24.
510 * @return true on success
514 intel_renderbuffer_update_wrapper(struct intel_context
*intel
,
515 struct intel_renderbuffer
*irb
,
516 struct gl_texture_image
*image
,
519 struct gl_renderbuffer
*rb
= &irb
->Base
.Base
;
520 struct intel_texture_image
*intel_image
= intel_texture_image(image
);
521 struct intel_mipmap_tree
*mt
= intel_image
->mt
;
522 int level
= image
->Level
;
524 rb
->Format
= image
->TexFormat
;
525 rb
->InternalFormat
= image
->InternalFormat
;
526 rb
->_BaseFormat
= image
->_BaseFormat
;
527 rb
->Width
= mt
->level
[level
].width
;
528 rb
->Height
= mt
->level
[level
].height
;
530 rb
->Delete
= intel_delete_renderbuffer
;
531 rb
->AllocStorage
= intel_nop_alloc_storage
;
533 intel_miptree_check_level_layer(mt
, level
, layer
);
534 irb
->mt_level
= level
;
535 irb
->mt_layer
= layer
;
537 intel_miptree_reference(&irb
->mt
, mt
);
539 intel_renderbuffer_set_draw_offset(irb
);
541 if (mt
->hiz_mt
== NULL
&&
542 intel
->vtbl
.is_hiz_depth_format(intel
, rb
->Format
)) {
543 intel_miptree_alloc_hiz(intel
, mt
, 0 /* num_samples */);
552 intel_renderbuffer_set_draw_offset(struct intel_renderbuffer
*irb
)
554 unsigned int dst_x
, dst_y
;
556 /* compute offset of the particular 2D image within the texture region */
557 intel_miptree_get_image_offset(irb
->mt
,
559 0, /* face, which we ignore */
568 * Rendering to tiled buffers requires that the base address of the
569 * buffer be aligned to a page boundary. We generally render to
570 * textures by pointing the surface at the mipmap image level, which
571 * may not be aligned to a tile boundary.
573 * This function returns an appropriately-aligned base offset
574 * according to the tiling restrictions, plus any required x/y offset
578 intel_renderbuffer_tile_offsets(struct intel_renderbuffer
*irb
,
582 struct intel_region
*region
= irb
->mt
->region
;
583 uint32_t mask_x
, mask_y
;
585 intel_region_get_tile_masks(region
, &mask_x
, &mask_y
);
587 *tile_x
= irb
->draw_x
& mask_x
;
588 *tile_y
= irb
->draw_y
& mask_y
;
589 return intel_region_get_aligned_offset(region
, irb
->draw_x
& ~mask_x
,
590 irb
->draw_y
& ~mask_y
);
594 * Called by glFramebufferTexture[123]DEXT() (and other places) to
595 * prepare for rendering into texture memory. This might be called
596 * many times to choose different texture levels, cube faces, etc
597 * before intel_finish_render_texture() is ever called.
600 intel_render_texture(struct gl_context
* ctx
,
601 struct gl_framebuffer
*fb
,
602 struct gl_renderbuffer_attachment
*att
)
604 struct intel_context
*intel
= intel_context(ctx
);
605 struct gl_texture_image
*image
= _mesa_get_attachment_teximage(att
);
606 struct intel_renderbuffer
*irb
= intel_renderbuffer(att
->Renderbuffer
);
607 struct intel_texture_image
*intel_image
= intel_texture_image(image
);
608 struct intel_mipmap_tree
*mt
= intel_image
->mt
;
613 if (att
->CubeMapFace
> 0) {
614 assert(att
->Zoffset
== 0);
615 layer
= att
->CubeMapFace
;
617 layer
= att
->Zoffset
;
620 if (!intel_image
->mt
) {
621 /* Fallback on drawing to a texture that doesn't have a miptree
622 * (has a border, width/height 0, etc.)
624 _mesa_reference_renderbuffer(&att
->Renderbuffer
, NULL
);
625 _swrast_render_texture(ctx
, fb
, att
);
629 intel_miptree_check_level_layer(mt
, att
->TextureLevel
, layer
);
631 irb
= (struct intel_renderbuffer
*)intel_new_renderbuffer(ctx
, ~0);
634 /* bind the wrapper to the attachment point */
635 _mesa_reference_renderbuffer(&att
->Renderbuffer
, &irb
->Base
.Base
);
638 /* fallback to software rendering */
639 _swrast_render_texture(ctx
, fb
, att
);
644 if (!intel_renderbuffer_update_wrapper(intel
, irb
, image
, layer
)) {
645 _mesa_reference_renderbuffer(&att
->Renderbuffer
, NULL
);
646 _swrast_render_texture(ctx
, fb
, att
);
650 irb
->tex_image
= image
;
652 DBG("Begin render %s texture tex=%u w=%d h=%d refcount=%d\n",
653 _mesa_get_format_name(image
->TexFormat
),
654 att
->Texture
->Name
, image
->Width
, image
->Height
,
655 irb
->Base
.Base
.RefCount
);
657 /* update drawing region, etc */
658 intel_draw_buffer(ctx
);
663 * Called by Mesa when rendering to a texture is done.
666 intel_finish_render_texture(struct gl_context
* ctx
,
667 struct gl_renderbuffer_attachment
*att
)
669 struct intel_context
*intel
= intel_context(ctx
);
670 struct gl_texture_object
*tex_obj
= att
->Texture
;
671 struct gl_texture_image
*image
=
672 tex_obj
->Image
[att
->CubeMapFace
][att
->TextureLevel
];
673 struct intel_renderbuffer
*irb
= intel_renderbuffer(att
->Renderbuffer
);
675 DBG("Finish render %s texture tex=%u\n",
676 _mesa_get_format_name(image
->TexFormat
), att
->Texture
->Name
);
679 irb
->tex_image
= NULL
;
681 /* Since we've (probably) rendered to the texture and will (likely) use
682 * it in the texture domain later on in this batchbuffer, flush the
683 * batch. Once again, we wish for a domain tracker in libdrm to cover
684 * usage inside of a batchbuffer like GEM does in the kernel.
686 intel_batchbuffer_emit_mi_flush(intel
);
690 * Do additional "completeness" testing of a framebuffer object.
693 intel_validate_framebuffer(struct gl_context
*ctx
, struct gl_framebuffer
*fb
)
695 struct intel_context
*intel
= intel_context(ctx
);
696 const struct intel_renderbuffer
*depthRb
=
697 intel_get_renderbuffer(fb
, BUFFER_DEPTH
);
698 const struct intel_renderbuffer
*stencilRb
=
699 intel_get_renderbuffer(fb
, BUFFER_STENCIL
);
700 struct intel_mipmap_tree
*depth_mt
= NULL
, *stencil_mt
= NULL
;
703 DBG("%s() on fb %p (%s)\n", __FUNCTION__
,
704 fb
, (fb
== ctx
->DrawBuffer
? "drawbuffer" :
705 (fb
== ctx
->ReadBuffer
? "readbuffer" : "other buffer")));
708 depth_mt
= depthRb
->mt
;
710 stencil_mt
= stencilRb
->mt
;
711 if (stencil_mt
->stencil_mt
)
712 stencil_mt
= stencil_mt
->stencil_mt
;
715 if (depth_mt
&& stencil_mt
) {
716 if (depth_mt
== stencil_mt
) {
717 /* For true packed depth/stencil (not faked on prefers-separate-stencil
718 * hardware) we need to be sure they're the same level/layer, since
719 * we'll be emitting a single packet describing the packed setup.
721 if (depthRb
->mt_level
!= stencilRb
->mt_level
||
722 depthRb
->mt_layer
!= stencilRb
->mt_layer
) {
723 DBG("depth image level/layer %d/%d != stencil image %d/%d\n",
727 stencilRb
->mt_layer
);
728 fb
->_Status
= GL_FRAMEBUFFER_UNSUPPORTED_EXT
;
731 if (!intel
->has_separate_stencil
) {
732 DBG("separate stencil unsupported\n");
733 fb
->_Status
= GL_FRAMEBUFFER_UNSUPPORTED_EXT
;
735 if (stencil_mt
->format
!= MESA_FORMAT_S8
) {
736 DBG("separate stencil is %s instead of S8\n",
737 _mesa_get_format_name(stencil_mt
->format
));
738 fb
->_Status
= GL_FRAMEBUFFER_UNSUPPORTED_EXT
;
740 if (intel
->gen
< 7 && depth_mt
->hiz_mt
== NULL
) {
741 /* Before Gen7, separate depth and stencil buffers can be used
742 * only if HiZ is enabled. From the Sandybridge PRM, Volume 2,
743 * Part 1, Bit 3DSTATE_DEPTH_BUFFER.SeparateStencilBufferEnable:
744 * [DevSNB]: This field must be set to the same value (enabled
745 * or disabled) as Hierarchical Depth Buffer Enable.
747 DBG("separate stencil without HiZ\n");
748 fb
->_Status
= GL_FRAMEBUFFER_UNSUPPORTED
;
753 for (i
= 0; i
< Elements(fb
->Attachment
); i
++) {
754 struct gl_renderbuffer
*rb
;
755 struct intel_renderbuffer
*irb
;
757 if (fb
->Attachment
[i
].Type
== GL_NONE
)
760 /* A supported attachment will have a Renderbuffer set either
761 * from being a Renderbuffer or being a texture that got the
762 * intel_wrap_texture() treatment.
764 rb
= fb
->Attachment
[i
].Renderbuffer
;
766 DBG("attachment without renderbuffer\n");
767 fb
->_Status
= GL_FRAMEBUFFER_UNSUPPORTED_EXT
;
771 if (fb
->Attachment
[i
].Type
== GL_TEXTURE
) {
772 const struct gl_texture_image
*img
=
773 _mesa_get_attachment_teximage_const(&fb
->Attachment
[i
]);
776 DBG("texture with border\n");
777 fb
->_Status
= GL_FRAMEBUFFER_UNSUPPORTED_EXT
;
782 irb
= intel_renderbuffer(rb
);
784 DBG("software rendering renderbuffer\n");
785 fb
->_Status
= GL_FRAMEBUFFER_UNSUPPORTED_EXT
;
789 if (!intel
->vtbl
.render_target_supported(intel
, rb
)) {
790 DBG("Unsupported HW texture/renderbuffer format attached: %s\n",
791 _mesa_get_format_name(intel_rb_format(irb
)));
792 fb
->_Status
= GL_FRAMEBUFFER_UNSUPPORTED_EXT
;
798 * Try to do a glBlitFramebuffer using glCopyTexSubImage2D
799 * We can do this when the dst renderbuffer is actually a texture and
800 * there is no scaling, mirroring or scissoring.
802 * \return new buffer mask indicating the buffers left to blit using the
806 intel_blit_framebuffer_copy_tex_sub_image(struct gl_context
*ctx
,
807 GLint srcX0
, GLint srcY0
,
808 GLint srcX1
, GLint srcY1
,
809 GLint dstX0
, GLint dstY0
,
810 GLint dstX1
, GLint dstY1
,
811 GLbitfield mask
, GLenum filter
)
813 if (mask
& GL_COLOR_BUFFER_BIT
) {
814 const struct gl_framebuffer
*drawFb
= ctx
->DrawBuffer
;
815 const struct gl_framebuffer
*readFb
= ctx
->ReadBuffer
;
816 const struct gl_renderbuffer_attachment
*drawAtt
=
817 &drawFb
->Attachment
[drawFb
->_ColorDrawBufferIndexes
[0]];
818 struct intel_renderbuffer
*srcRb
=
819 intel_renderbuffer(readFb
->_ColorReadBuffer
);
821 /* If the source and destination are the same size with no
822 mirroring, the rectangles are within the size of the
823 texture and there is no scissor then we can use
824 glCopyTexSubimage2D to implement the blit. This will end
825 up as a fast hardware blit on some drivers */
826 if (srcRb
&& drawAtt
&& drawAtt
->Texture
&&
827 srcX0
- srcX1
== dstX0
- dstX1
&&
828 srcY0
- srcY1
== dstY0
- dstY1
&&
831 srcX0
>= 0 && srcX1
<= readFb
->Width
&&
832 srcY0
>= 0 && srcY1
<= readFb
->Height
&&
833 dstX0
>= 0 && dstX1
<= drawFb
->Width
&&
834 dstY0
>= 0 && dstY1
<= drawFb
->Height
&&
835 !ctx
->Scissor
.Enabled
) {
836 const struct gl_texture_object
*texObj
= drawAtt
->Texture
;
837 const GLuint dstLevel
= drawAtt
->TextureLevel
;
838 const GLenum target
= texObj
->Target
;
840 struct gl_texture_image
*texImage
=
841 _mesa_select_tex_image(ctx
, texObj
, target
, dstLevel
);
843 if (intel_copy_texsubimage(intel_context(ctx
),
844 intel_texture_image(texImage
),
848 srcX1
- srcX0
, /* width */
850 mask
&= ~GL_COLOR_BUFFER_BIT
;
858 intel_blit_framebuffer(struct gl_context
*ctx
,
859 GLint srcX0
, GLint srcY0
, GLint srcX1
, GLint srcY1
,
860 GLint dstX0
, GLint dstY0
, GLint dstX1
, GLint dstY1
,
861 GLbitfield mask
, GLenum filter
)
863 /* Try faster, glCopyTexSubImage2D approach first which uses the BLT. */
864 mask
= intel_blit_framebuffer_copy_tex_sub_image(ctx
,
865 srcX0
, srcY0
, srcX1
, srcY1
,
866 dstX0
, dstY0
, dstX1
, dstY1
,
872 mask
= brw_blorp_framebuffer(intel_context(ctx
),
873 srcX0
, srcY0
, srcX1
, srcY1
,
874 dstX0
, dstY0
, dstX1
, dstY1
,
880 _mesa_meta_BlitFramebuffer(ctx
,
881 srcX0
, srcY0
, srcX1
, srcY1
,
882 dstX0
, dstY0
, dstX1
, dstY1
,
887 intel_renderbuffer_set_needs_hiz_resolve(struct intel_renderbuffer
*irb
)
890 intel_miptree_slice_set_needs_hiz_resolve(irb
->mt
,
897 intel_renderbuffer_set_needs_depth_resolve(struct intel_renderbuffer
*irb
)
900 intel_miptree_slice_set_needs_depth_resolve(irb
->mt
,
907 intel_renderbuffer_resolve_hiz(struct intel_context
*intel
,
908 struct intel_renderbuffer
*irb
)
911 return intel_miptree_slice_resolve_hiz(intel
,
920 intel_renderbuffer_resolve_depth(struct intel_context
*intel
,
921 struct intel_renderbuffer
*irb
)
924 return intel_miptree_slice_resolve_depth(intel
,
933 * Do one-time context initializations related to GL_EXT_framebuffer_object.
934 * Hook in device driver functions.
937 intel_fbo_init(struct intel_context
*intel
)
939 intel
->ctx
.Driver
.NewFramebuffer
= intel_new_framebuffer
;
940 intel
->ctx
.Driver
.NewRenderbuffer
= intel_new_renderbuffer
;
941 intel
->ctx
.Driver
.MapRenderbuffer
= intel_map_renderbuffer
;
942 intel
->ctx
.Driver
.UnmapRenderbuffer
= intel_unmap_renderbuffer
;
943 intel
->ctx
.Driver
.BindFramebuffer
= intel_bind_framebuffer
;
944 intel
->ctx
.Driver
.FramebufferRenderbuffer
= intel_framebuffer_renderbuffer
;
945 intel
->ctx
.Driver
.RenderTexture
= intel_render_texture
;
946 intel
->ctx
.Driver
.FinishRenderTexture
= intel_finish_render_texture
;
947 intel
->ctx
.Driver
.ResizeBuffers
= intel_resize_buffers
;
948 intel
->ctx
.Driver
.ValidateFramebuffer
= intel_validate_framebuffer
;
949 intel
->ctx
.Driver
.BlitFramebuffer
= intel_blit_framebuffer
;
951 #if FEATURE_OES_EGL_image
952 intel
->ctx
.Driver
.EGLImageTargetRenderbufferStorage
=
953 intel_image_target_renderbuffer_storage
;