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
61 intel_framebuffer_has_hiz(struct gl_framebuffer
*fb
)
63 struct intel_renderbuffer
*rb
= NULL
;
65 rb
= intel_get_renderbuffer(fb
, BUFFER_DEPTH
);
66 return rb
&& rb
->mt
&& rb
->mt
->hiz_mt
;
70 intel_get_rb_region(struct gl_framebuffer
*fb
, GLuint attIndex
)
72 struct intel_renderbuffer
*irb
= intel_get_renderbuffer(fb
, attIndex
);
74 return irb
->mt
->region
;
80 * Create a new framebuffer object.
82 static struct gl_framebuffer
*
83 intel_new_framebuffer(struct gl_context
* ctx
, GLuint name
)
85 /* Only drawable state in intel_framebuffer at this time, just use Mesa's
88 return _mesa_new_framebuffer(ctx
, name
);
92 /** Called by gl_renderbuffer::Delete() */
94 intel_delete_renderbuffer(struct gl_renderbuffer
*rb
)
96 struct intel_renderbuffer
*irb
= intel_renderbuffer(rb
);
100 intel_miptree_release(&irb
->mt
);
102 _mesa_reference_renderbuffer(&irb
->wrapped_depth
, NULL
);
103 _mesa_reference_renderbuffer(&irb
->wrapped_stencil
, NULL
);
109 * \brief Map a renderbuffer through the GTT.
111 * \see intel_map_renderbuffer()
114 intel_map_renderbuffer_gtt(struct gl_context
*ctx
,
115 struct gl_renderbuffer
*rb
,
116 GLuint x
, GLuint y
, GLuint w
, GLuint h
,
121 struct intel_context
*intel
= intel_context(ctx
);
122 struct intel_renderbuffer
*irb
= intel_renderbuffer(rb
);
124 int stride
, flip_stride
;
128 intel_renderbuffer_resolve_depth(intel
, irb
);
129 if (mode
& GL_MAP_WRITE_BIT
) {
130 intel_renderbuffer_set_needs_hiz_resolve(irb
);
133 irb
->map_mode
= mode
;
139 stride
= irb
->mt
->region
->pitch
* irb
->mt
->region
->cpp
;
142 y
= irb
->mt
->region
->height
- 1 - y
;
143 flip_stride
= -stride
;
147 flip_stride
= stride
;
150 if (drm_intel_bo_references(intel
->batch
.bo
, irb
->mt
->region
->bo
)) {
151 intel_batchbuffer_flush(intel
);
154 drm_intel_gem_bo_map_gtt(irb
->mt
->region
->bo
);
156 map
= irb
->mt
->region
->bo
->virtual;
157 map
+= x
* irb
->mt
->region
->cpp
;
158 map
+= (int)y
* stride
;
161 *out_stride
= flip_stride
;
163 DBG("%s: rb %d (%s) gtt mapped: (%d, %d) (%dx%d) -> %p/%d\n",
164 __FUNCTION__
, rb
->Name
, _mesa_get_format_name(rb
->Format
),
165 x
, y
, w
, h
, *out_map
, *out_stride
);
169 * \brief Map a renderbuffer by blitting it to a temporary gem buffer.
171 * On gen6+, we have LLC sharing, which means we can get high-performance
172 * access to linear-mapped buffers.
174 * This function allocates a temporary gem buffer at
175 * intel_renderbuffer::map_bo, then blits the renderbuffer into it, and
176 * returns a map of that. (Note: Only X tiled buffers can be blitted).
178 * \see intel_renderbuffer::map_bo
179 * \see intel_map_renderbuffer()
182 intel_map_renderbuffer_blit(struct gl_context
*ctx
,
183 struct gl_renderbuffer
*rb
,
184 GLuint x
, GLuint y
, GLuint w
, GLuint h
,
189 struct intel_context
*intel
= intel_context(ctx
);
190 struct intel_renderbuffer
*irb
= intel_renderbuffer(rb
);
195 assert(irb
->mt
->region
);
196 assert(intel
->gen
>= 6);
197 assert(!(mode
& GL_MAP_WRITE_BIT
));
198 assert(irb
->mt
->region
->tiling
== I915_TILING_X
);
200 irb
->map_mode
= mode
;
206 dst_stride
= ALIGN(w
* irb
->mt
->region
->cpp
, 4);
209 src_x
= x
+ irb
->draw_x
;
210 src_y
= y
+ irb
->draw_y
;
213 src_y
= irb
->mt
->region
->height
- y
- h
;
216 irb
->map_bo
= drm_intel_bo_alloc(intel
->bufmgr
, "MapRenderbuffer() temp",
217 dst_stride
* h
, 4096);
219 /* We don't do the flip in the blit, because it's always so tricky to get
223 intelEmitCopyBlit(intel
,
224 irb
->mt
->region
->cpp
,
225 irb
->mt
->region
->pitch
, irb
->mt
->region
->bo
,
226 0, irb
->mt
->region
->tiling
,
227 dst_stride
/ irb
->mt
->region
->cpp
, irb
->map_bo
,
233 intel_batchbuffer_flush(intel
);
234 drm_intel_bo_map(irb
->map_bo
, false);
237 *out_map
= irb
->map_bo
->virtual;
238 *out_stride
= dst_stride
;
240 *out_map
= irb
->map_bo
->virtual + (h
- 1) * dst_stride
;
241 *out_stride
= -dst_stride
;
244 DBG("%s: rb %d (%s) blit mapped: (%d, %d) (%dx%d) -> %p/%d\n",
245 __FUNCTION__
, rb
->Name
, _mesa_get_format_name(rb
->Format
),
246 src_x
, src_y
, w
, h
, *out_map
, *out_stride
);
248 /* Fallback to GTT mapping. */
249 drm_intel_bo_unreference(irb
->map_bo
);
251 intel_map_renderbuffer_gtt(ctx
, rb
,
254 out_map
, out_stride
);
259 * \brief Map a stencil renderbuffer.
261 * Stencil buffers are W-tiled. Since the GTT has no W fence, we must detile
262 * the buffer in software.
264 * This function allocates a temporary malloc'd buffer at
265 * intel_renderbuffer::map_buffer, detiles the stencil buffer into it, then
266 * returns the temporary buffer as the map.
268 * \see intel_renderbuffer::map_buffer
269 * \see intel_map_renderbuffer()
270 * \see intel_unmap_renderbuffer_s8()
273 intel_map_renderbuffer_s8(struct gl_context
*ctx
,
274 struct gl_renderbuffer
*rb
,
275 GLuint x
, GLuint y
, GLuint w
, GLuint h
,
280 struct intel_context
*intel
= intel_context(ctx
);
281 struct intel_renderbuffer
*irb
= intel_renderbuffer(rb
);
282 uint8_t *tiled_s8_map
;
283 uint8_t *untiled_s8_map
;
285 assert(rb
->Format
== MESA_FORMAT_S8
);
288 irb
->map_mode
= mode
;
294 /* Flip the Y axis for the default framebuffer. */
295 int y_flip
= (rb
->Name
== 0) ? -1 : 1;
296 int y_bias
= (rb
->Name
== 0) ? (rb
->Height
- 1) : 0;
298 irb
->map_buffer
= malloc(w
* h
);
299 untiled_s8_map
= irb
->map_buffer
;
300 tiled_s8_map
= intel_region_map(intel
, irb
->mt
->region
, mode
);
302 for (uint32_t pix_y
= 0; pix_y
< h
; pix_y
++) {
303 for (uint32_t pix_x
= 0; pix_x
< w
; pix_x
++) {
304 uint32_t flipped_y
= y_flip
* (int32_t)(y
+ pix_y
) + y_bias
;
305 ptrdiff_t offset
= intel_offset_S8(irb
->mt
->region
->pitch
,
308 untiled_s8_map
[pix_y
* w
+ pix_x
] = tiled_s8_map
[offset
];
312 *out_map
= untiled_s8_map
;
315 DBG("%s: rb %d (%s) s8 detiled mapped: (%d, %d) (%dx%d) -> %p/%d\n",
316 __FUNCTION__
, rb
->Name
, _mesa_get_format_name(rb
->Format
),
317 x
, y
, w
, h
, *out_map
, *out_stride
);
321 * \brief Map a depthstencil buffer with separate stencil.
323 * A depthstencil renderbuffer, if using separate stencil, consists of a depth
324 * renderbuffer and a hidden stencil renderbuffer. This function maps the
325 * depth buffer, whose format is MESA_FORMAT_X8_Z24, through the GTT and
326 * returns that as the mapped pointer. The caller need not be aware of the
327 * hidden stencil buffer and may safely assume that the mapped pointer points
328 * to a MESA_FORMAT_S8_Z24 buffer
330 * The consistency between the depth buffer's S8 bits and the hidden stencil
331 * buffer is managed within intel_map_renderbuffer() and
332 * intel_unmap_renderbuffer() by scattering or gathering the stencil bits
333 * according to the map mode.
335 * \see intel_map_renderbuffer()
336 * \see intel_unmap_renderbuffer_separate_s8z24()
339 intel_map_renderbuffer_separate_s8z24(struct gl_context
*ctx
,
340 struct gl_renderbuffer
*rb
,
341 GLuint x
, GLuint y
, GLuint w
, GLuint h
,
346 struct intel_context
*intel
= intel_context(ctx
);
347 struct intel_renderbuffer
*irb
= intel_renderbuffer(rb
);
350 int32_t s8z24_stride
;
352 struct intel_renderbuffer
*s8_irb
;
355 assert(rb
->Name
!= 0);
356 assert(rb
->Format
== MESA_FORMAT_S8_Z24
);
357 assert(irb
->wrapped_depth
!= NULL
);
358 assert(irb
->wrapped_stencil
!= NULL
);
360 irb
->map_mode
= mode
;
366 /* Map with write mode for the gather below. */
367 intel_map_renderbuffer_gtt(ctx
, irb
->wrapped_depth
,
368 x
, y
, w
, h
, mode
| GL_MAP_WRITE_BIT
,
369 &s8z24_map
, &s8z24_stride
);
371 s8_irb
= intel_renderbuffer(irb
->wrapped_stencil
);
372 s8_map
= intel_region_map(intel
, s8_irb
->mt
->region
, GL_MAP_READ_BIT
);
374 /* Gather the stencil buffer into the depth buffer. */
375 for (uint32_t pix_y
= 0; pix_y
< h
; ++pix_y
) {
376 for (uint32_t pix_x
= 0; pix_x
< w
; ++pix_x
) {
377 ptrdiff_t s8_offset
= intel_offset_S8(s8_irb
->mt
->region
->pitch
,
380 ptrdiff_t s8z24_offset
= pix_y
* s8z24_stride
383 s8z24_map
[s8z24_offset
] = s8_map
[s8_offset
];
387 intel_region_unmap(intel
, s8_irb
->mt
->region
);
389 *out_map
= s8z24_map
;
390 *out_stride
= s8z24_stride
;
394 * \see dd_function_table::MapRenderbuffer
397 intel_map_renderbuffer(struct gl_context
*ctx
,
398 struct gl_renderbuffer
*rb
,
399 GLuint x
, GLuint y
, GLuint w
, GLuint h
,
404 struct intel_context
*intel
= intel_context(ctx
);
405 struct intel_renderbuffer
*irb
= intel_renderbuffer(rb
);
407 /* We sometimes get called with this by our intel_span.c usage. */
408 if (!irb
->mt
&& !irb
->wrapped_depth
) {
414 if (rb
->Format
== MESA_FORMAT_S8
) {
415 intel_map_renderbuffer_s8(ctx
, rb
, x
, y
, w
, h
, mode
,
416 out_map
, out_stride
);
417 } else if (irb
->wrapped_depth
) {
418 intel_map_renderbuffer_separate_s8z24(ctx
, rb
, x
, y
, w
, h
, mode
,
419 out_map
, out_stride
);
420 } else if (intel
->gen
>= 6 &&
421 !(mode
& GL_MAP_WRITE_BIT
) &&
422 irb
->mt
->region
->tiling
== I915_TILING_X
) {
423 intel_map_renderbuffer_blit(ctx
, rb
, x
, y
, w
, h
, mode
,
424 out_map
, out_stride
);
426 intel_map_renderbuffer_gtt(ctx
, rb
, x
, y
, w
, h
, mode
,
427 out_map
, out_stride
);
432 * \see intel_map_renderbuffer_s8()
435 intel_unmap_renderbuffer_s8(struct gl_context
*ctx
,
436 struct gl_renderbuffer
*rb
)
438 struct intel_context
*intel
= intel_context(ctx
);
439 struct intel_renderbuffer
*irb
= intel_renderbuffer(rb
);
441 DBG("%s: rb %d (%s)\n", __FUNCTION__
,
442 rb
->Name
, _mesa_get_format_name(rb
->Format
));
444 assert(rb
->Format
== MESA_FORMAT_S8
);
446 if (!irb
->map_buffer
)
449 if (irb
->map_mode
& GL_MAP_WRITE_BIT
) {
450 /* The temporary buffer was written to, so we must copy its pixels into
453 uint8_t *untiled_s8_map
= irb
->map_buffer
;
454 uint8_t *tiled_s8_map
= irb
->mt
->region
->bo
->virtual;
456 /* Flip the Y axis for the default framebuffer. */
457 int y_flip
= (rb
->Name
== 0) ? -1 : 1;
458 int y_bias
= (rb
->Name
== 0) ? (rb
->Height
- 1) : 0;
460 for (uint32_t pix_y
= 0; pix_y
< irb
->map_h
; pix_y
++) {
461 for (uint32_t pix_x
= 0; pix_x
< irb
->map_w
; pix_x
++) {
462 uint32_t flipped_y
= y_flip
* (int32_t)(pix_y
+ irb
->map_y
) + y_bias
;
463 ptrdiff_t offset
= intel_offset_S8(irb
->mt
->region
->pitch
,
466 tiled_s8_map
[offset
] =
467 untiled_s8_map
[pix_y
* irb
->map_w
+ pix_x
];
472 intel_region_unmap(intel
, irb
->mt
->region
);
473 free(irb
->map_buffer
);
474 irb
->map_buffer
= NULL
;
478 * \brief Unmap a depthstencil renderbuffer with separate stencil.
480 * \see intel_map_renderbuffer_separate_s8z24()
481 * \see intel_unmap_renderbuffer()
484 intel_unmap_renderbuffer_separate_s8z24(struct gl_context
*ctx
,
485 struct gl_renderbuffer
*rb
)
487 struct intel_context
*intel
= intel_context(ctx
);
488 struct intel_renderbuffer
*irb
= intel_renderbuffer(rb
);
489 struct intel_renderbuffer
*s8z24_irb
;
491 assert(rb
->Name
!= 0);
492 assert(rb
->Format
== MESA_FORMAT_S8_Z24
);
493 assert(irb
->wrapped_depth
!= NULL
);
494 assert(irb
->wrapped_stencil
!= NULL
);
496 s8z24_irb
= intel_renderbuffer(irb
->wrapped_depth
);
498 if (irb
->map_mode
& GL_MAP_WRITE_BIT
) {
499 /* Copy the stencil bits from the depth buffer into the stencil buffer.
501 uint32_t map_x
= irb
->map_x
;
502 uint32_t map_y
= irb
->map_y
;
503 uint32_t map_w
= irb
->map_w
;
504 uint32_t map_h
= irb
->map_h
;
506 struct intel_renderbuffer
*s8_irb
;
509 s8_irb
= intel_renderbuffer(irb
->wrapped_stencil
);
510 s8_map
= intel_region_map(intel
, s8_irb
->mt
->region
, GL_MAP_WRITE_BIT
);
512 int32_t s8z24_stride
= 4 * s8z24_irb
->mt
->region
->pitch
;
513 uint8_t *s8z24_map
= s8z24_irb
->mt
->region
->bo
->virtual
514 + map_y
* s8z24_stride
517 for (uint32_t pix_y
= 0; pix_y
< map_h
; ++pix_y
) {
518 for (uint32_t pix_x
= 0; pix_x
< map_w
; ++pix_x
) {
519 ptrdiff_t s8_offset
= intel_offset_S8(s8_irb
->mt
->region
->pitch
,
522 ptrdiff_t s8z24_offset
= pix_y
* s8z24_stride
525 s8_map
[s8_offset
] = s8z24_map
[s8z24_offset
];
529 intel_region_unmap(intel
, s8_irb
->mt
->region
);
532 drm_intel_gem_bo_unmap_gtt(s8z24_irb
->mt
->region
->bo
);
536 * \see dd_function_table::UnmapRenderbuffer
539 intel_unmap_renderbuffer(struct gl_context
*ctx
,
540 struct gl_renderbuffer
*rb
)
542 struct intel_renderbuffer
*irb
= intel_renderbuffer(rb
);
544 DBG("%s: rb %d (%s)\n", __FUNCTION__
,
545 rb
->Name
, _mesa_get_format_name(rb
->Format
));
547 if (rb
->Format
== MESA_FORMAT_S8
) {
548 intel_unmap_renderbuffer_s8(ctx
, rb
);
549 } else if (irb
->wrapped_depth
) {
550 intel_unmap_renderbuffer_separate_s8z24(ctx
, rb
);
551 } else if (irb
->map_bo
) {
552 /* Paired with intel_map_renderbuffer_blit(). */
553 drm_intel_bo_unmap(irb
->map_bo
);
554 drm_intel_bo_unreference(irb
->map_bo
);
557 /* Paired with intel_map_renderbuffer_gtt(). */
559 /* The miptree may be null when intel_map_renderbuffer() is
560 * called from intel_span.c.
562 drm_intel_gem_bo_unmap_gtt(irb
->mt
->region
->bo
);
568 * Return a pointer to a specific pixel in a renderbuffer.
571 intel_get_pointer(struct gl_context
* ctx
, struct gl_renderbuffer
*rb
,
574 /* By returning NULL we force all software rendering to go through
582 * Called via glRenderbufferStorageEXT() to set the format and allocate
583 * storage for a user-created renderbuffer.
586 intel_alloc_renderbuffer_storage(struct gl_context
* ctx
, struct gl_renderbuffer
*rb
,
587 GLenum internalFormat
,
588 GLuint width
, GLuint height
)
590 struct intel_context
*intel
= intel_context(ctx
);
591 struct intel_renderbuffer
*irb
= intel_renderbuffer(rb
);
594 ASSERT(rb
->Name
!= 0);
596 switch (internalFormat
) {
598 /* Use the same format-choice logic as for textures.
599 * Renderbuffers aren't any different from textures for us,
600 * except they're less useful because you can't texture with
603 rb
->Format
= intel
->ctx
.Driver
.ChooseTextureFormat(ctx
, internalFormat
,
606 case GL_STENCIL_INDEX
:
607 case GL_STENCIL_INDEX1_EXT
:
608 case GL_STENCIL_INDEX4_EXT
:
609 case GL_STENCIL_INDEX8_EXT
:
610 case GL_STENCIL_INDEX16_EXT
:
611 /* These aren't actual texture formats, so force them here. */
612 if (intel
->has_separate_stencil
) {
613 rb
->Format
= MESA_FORMAT_S8
;
615 assert(!intel
->must_use_separate_stencil
);
616 rb
->Format
= MESA_FORMAT_S8_Z24
;
623 rb
->_BaseFormat
= _mesa_base_fbo_format(ctx
, internalFormat
);
624 rb
->DataType
= intel_mesa_format_to_rb_datatype(rb
->Format
);
625 cpp
= _mesa_get_format_bytes(rb
->Format
);
629 intel_miptree_release(&irb
->mt
);
631 DBG("%s: %s: %s (%dx%d)\n", __FUNCTION__
,
632 _mesa_lookup_enum_by_nr(internalFormat
),
633 _mesa_get_format_name(rb
->Format
), width
, height
);
635 tiling
= I915_TILING_NONE
;
636 if (intel
->use_texture_tiling
) {
637 GLenum base_format
= _mesa_get_format_base_format(rb
->Format
);
639 if (intel
->gen
>= 4 && (base_format
== GL_DEPTH_COMPONENT
||
640 base_format
== GL_STENCIL_INDEX
||
641 base_format
== GL_DEPTH_STENCIL
))
642 tiling
= I915_TILING_Y
;
644 tiling
= I915_TILING_X
;
647 if (irb
->Base
.Format
== MESA_FORMAT_S8
) {
649 * The stencil buffer is W tiled. However, we request from the kernel a
650 * non-tiled buffer because the GTT is incapable of W fencing.
652 * The stencil buffer has quirky pitch requirements. From Vol 2a,
653 * 11.5.6.2.1 3DSTATE_STENCIL_BUFFER, field "Surface Pitch":
654 * The pitch must be set to 2x the value computed based on width, as
655 * the stencil buffer is stored with two rows interleaved.
656 * To accomplish this, we resort to the nasty hack of doubling the drm
657 * region's cpp and halving its height.
659 * If we neglect to double the pitch, then render corruption occurs.
661 irb
->mt
= intel_miptree_create_for_renderbuffer(
667 ALIGN((height
+ 1) / 2, 64));
671 } else if (irb
->Base
.Format
== MESA_FORMAT_S8_Z24
672 && intel
->has_separate_stencil
) {
675 struct gl_renderbuffer
*depth_rb
;
676 struct gl_renderbuffer
*stencil_rb
;
678 depth_rb
= intel_create_wrapped_renderbuffer(ctx
, width
, height
,
680 stencil_rb
= intel_create_wrapped_renderbuffer(ctx
, width
, height
,
682 ok
= depth_rb
&& stencil_rb
;
683 ok
= ok
&& intel_alloc_renderbuffer_storage(ctx
, depth_rb
,
684 depth_rb
->InternalFormat
,
686 ok
= ok
&& intel_alloc_renderbuffer_storage(ctx
, stencil_rb
,
687 stencil_rb
->InternalFormat
,
692 intel_delete_renderbuffer(depth_rb
);
695 intel_delete_renderbuffer(stencil_rb
);
700 depth_rb
->Wrapped
= rb
;
701 stencil_rb
->Wrapped
= rb
;
702 _mesa_reference_renderbuffer(&irb
->wrapped_depth
, depth_rb
);
703 _mesa_reference_renderbuffer(&irb
->wrapped_stencil
, stencil_rb
);
706 irb
->mt
= intel_miptree_create_for_renderbuffer(intel
, rb
->Format
,
712 if (intel
->vtbl
.is_hiz_depth_format(intel
, rb
->Format
)) {
713 bool ok
= intel_miptree_alloc_hiz(intel
, irb
->mt
);
715 intel_miptree_release(&irb
->mt
);
725 #if FEATURE_OES_EGL_image
727 intel_image_target_renderbuffer_storage(struct gl_context
*ctx
,
728 struct gl_renderbuffer
*rb
,
731 struct intel_context
*intel
= intel_context(ctx
);
732 struct intel_renderbuffer
*irb
;
736 screen
= intel
->intelScreen
->driScrnPriv
;
737 image
= screen
->dri2
.image
->lookupEGLImage(screen
, image_handle
,
738 screen
->loaderPrivate
);
742 /* __DRIimage is opaque to the core so it has to be checked here */
743 switch (image
->format
) {
744 case MESA_FORMAT_RGBA8888_REV
:
745 _mesa_error(&intel
->ctx
, GL_INVALID_OPERATION
,
746 "glEGLImageTargetRenderbufferStorage(unsupported image format");
753 irb
= intel_renderbuffer(rb
);
754 intel_miptree_release(&irb
->mt
);
755 irb
->mt
= intel_miptree_create_for_region(intel
,
762 rb
->InternalFormat
= image
->internal_format
;
763 rb
->Width
= image
->region
->width
;
764 rb
->Height
= image
->region
->height
;
765 rb
->Format
= image
->format
;
766 rb
->DataType
= image
->data_type
;
767 rb
->_BaseFormat
= _mesa_base_fbo_format(&intel
->ctx
,
768 image
->internal_format
);
773 * Called for each hardware renderbuffer when a _window_ is resized.
774 * Just update fields.
775 * Not used for user-created renderbuffers!
778 intel_alloc_window_storage(struct gl_context
* ctx
, struct gl_renderbuffer
*rb
,
779 GLenum internalFormat
, GLuint width
, GLuint height
)
781 ASSERT(rb
->Name
== 0);
784 rb
->InternalFormat
= internalFormat
;
791 intel_resize_buffers(struct gl_context
*ctx
, struct gl_framebuffer
*fb
,
792 GLuint width
, GLuint height
)
796 _mesa_resize_framebuffer(ctx
, fb
, width
, height
);
798 fb
->Initialized
= true; /* XXX remove someday */
805 /* Make sure all window system renderbuffers are up to date */
806 for (i
= BUFFER_FRONT_LEFT
; i
<= BUFFER_BACK_RIGHT
; i
++) {
807 struct gl_renderbuffer
*rb
= fb
->Attachment
[i
].Renderbuffer
;
809 /* only resize if size is changing */
810 if (rb
&& (rb
->Width
!= width
|| rb
->Height
!= height
)) {
811 rb
->AllocStorage(ctx
, rb
, rb
->InternalFormat
, width
, height
);
817 /** Dummy function for gl_renderbuffer::AllocStorage() */
819 intel_nop_alloc_storage(struct gl_context
* ctx
, struct gl_renderbuffer
*rb
,
820 GLenum internalFormat
, GLuint width
, GLuint height
)
822 _mesa_problem(ctx
, "intel_op_alloc_storage should never be called.");
827 * Create a new intel_renderbuffer which corresponds to an on-screen window,
828 * not a user-created renderbuffer.
830 struct intel_renderbuffer
*
831 intel_create_renderbuffer(gl_format format
)
833 GET_CURRENT_CONTEXT(ctx
);
835 struct intel_renderbuffer
*irb
;
837 irb
= CALLOC_STRUCT(intel_renderbuffer
);
839 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "creating renderbuffer");
843 _mesa_init_renderbuffer(&irb
->Base
, 0);
844 irb
->Base
.ClassID
= INTEL_RB_CLASS
;
845 irb
->Base
._BaseFormat
= _mesa_get_format_base_format(format
);
846 irb
->Base
.Format
= format
;
847 irb
->Base
.InternalFormat
= irb
->Base
._BaseFormat
;
848 irb
->Base
.DataType
= intel_mesa_format_to_rb_datatype(format
);
850 /* intel-specific methods */
851 irb
->Base
.Delete
= intel_delete_renderbuffer
;
852 irb
->Base
.AllocStorage
= intel_alloc_window_storage
;
853 irb
->Base
.GetPointer
= intel_get_pointer
;
859 struct gl_renderbuffer
*
860 intel_create_wrapped_renderbuffer(struct gl_context
* ctx
,
861 int width
, int height
,
865 * The name here is irrelevant, as long as its nonzero, because the
866 * renderbuffer never gets entered into Mesa's renderbuffer hash table.
870 struct intel_renderbuffer
*irb
= CALLOC_STRUCT(intel_renderbuffer
);
872 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "creating renderbuffer");
876 struct gl_renderbuffer
*rb
= &irb
->Base
;
877 _mesa_init_renderbuffer(rb
, name
);
878 rb
->ClassID
= INTEL_RB_CLASS
;
879 rb
->_BaseFormat
= _mesa_get_format_base_format(format
);
881 rb
->InternalFormat
= rb
->_BaseFormat
;
882 rb
->DataType
= intel_mesa_format_to_rb_datatype(format
);
891 * Create a new renderbuffer object.
892 * Typically called via glBindRenderbufferEXT().
894 static struct gl_renderbuffer
*
895 intel_new_renderbuffer(struct gl_context
* ctx
, GLuint name
)
897 /*struct intel_context *intel = intel_context(ctx); */
898 struct intel_renderbuffer
*irb
;
900 irb
= CALLOC_STRUCT(intel_renderbuffer
);
902 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "creating renderbuffer");
906 _mesa_init_renderbuffer(&irb
->Base
, name
);
907 irb
->Base
.ClassID
= INTEL_RB_CLASS
;
909 /* intel-specific methods */
910 irb
->Base
.Delete
= intel_delete_renderbuffer
;
911 irb
->Base
.AllocStorage
= intel_alloc_renderbuffer_storage
;
912 irb
->Base
.GetPointer
= intel_get_pointer
;
913 /* span routines set in alloc_storage function */
920 * Called via glBindFramebufferEXT().
923 intel_bind_framebuffer(struct gl_context
* ctx
, GLenum target
,
924 struct gl_framebuffer
*fb
, struct gl_framebuffer
*fbread
)
926 if (target
== GL_FRAMEBUFFER_EXT
|| target
== GL_DRAW_FRAMEBUFFER_EXT
) {
927 intel_draw_buffer(ctx
);
930 /* don't need to do anything if target == GL_READ_FRAMEBUFFER_EXT */
936 * Called via glFramebufferRenderbufferEXT().
939 intel_framebuffer_renderbuffer(struct gl_context
* ctx
,
940 struct gl_framebuffer
*fb
,
941 GLenum attachment
, struct gl_renderbuffer
*rb
)
943 DBG("Intel FramebufferRenderbuffer %u %u\n", fb
->Name
, rb
? rb
->Name
: 0);
947 _mesa_framebuffer_renderbuffer(ctx
, fb
, attachment
, rb
);
948 intel_draw_buffer(ctx
);
951 static struct intel_renderbuffer
*
952 intel_renderbuffer_wrap_miptree(struct intel_context
*intel
,
953 struct intel_mipmap_tree
*mt
,
957 GLenum internal_format
);
960 * \par Special case for separate stencil
962 * When wrapping a depthstencil texture that uses separate stencil, this
963 * function is recursively called twice: once to create \c
964 * irb->wrapped_depth and again to create \c irb->wrapped_stencil. On the
965 * call to create \c irb->wrapped_depth, the \c format and \c
966 * internal_format parameters do not match \c mt->format. In that case, \c
967 * mt->format is MESA_FORMAT_S8_Z24 and \c format is \c
968 * MESA_FORMAT_X8_Z24.
970 * @return true on success
973 intel_renderbuffer_update_wrapper(struct intel_context
*intel
,
974 struct intel_renderbuffer
*irb
,
975 struct intel_mipmap_tree
*mt
,
979 GLenum internal_format
)
981 struct gl_renderbuffer
*rb
= &irb
->Base
;
984 rb
->InternalFormat
= internal_format
;
985 rb
->DataType
= intel_mesa_format_to_rb_datatype(rb
->Format
);
986 rb
->_BaseFormat
= _mesa_get_format_base_format(rb
->Format
);
987 rb
->Width
= mt
->level
[level
].width
;
988 rb
->Height
= mt
->level
[level
].height
;
990 irb
->Base
.Delete
= intel_delete_renderbuffer
;
991 irb
->Base
.AllocStorage
= intel_nop_alloc_storage
;
993 intel_miptree_check_level_layer(mt
, level
, layer
);
994 irb
->mt_level
= level
;
995 irb
->mt_layer
= layer
;
997 if (mt
->stencil_mt
&& _mesa_is_depthstencil_format(rb
->InternalFormat
)) {
998 assert((irb
->wrapped_depth
== NULL
) == (irb
->wrapped_stencil
== NULL
));
1000 struct intel_renderbuffer
*depth_irb
;
1001 struct intel_renderbuffer
*stencil_irb
;
1003 if (!irb
->wrapped_depth
) {
1004 depth_irb
= intel_renderbuffer_wrap_miptree(intel
,
1007 GL_DEPTH_COMPONENT24
);
1008 stencil_irb
= intel_renderbuffer_wrap_miptree(intel
,
1013 _mesa_reference_renderbuffer(&irb
->wrapped_depth
, &depth_irb
->Base
);
1014 _mesa_reference_renderbuffer(&irb
->wrapped_stencil
, &stencil_irb
->Base
);
1016 if (!irb
->wrapped_depth
|| !irb
->wrapped_stencil
)
1021 depth_irb
= intel_renderbuffer(irb
->wrapped_depth
);
1022 stencil_irb
= intel_renderbuffer(irb
->wrapped_stencil
);
1024 ok
&= intel_renderbuffer_update_wrapper(intel
,
1029 GL_DEPTH_COMPONENT24
);
1030 ok
&= intel_renderbuffer_update_wrapper(intel
,
1040 intel_miptree_reference(&irb
->mt
, mt
);
1041 intel_renderbuffer_set_draw_offset(irb
);
1043 if (mt
->hiz_mt
== NULL
&&
1044 intel
->vtbl
.is_hiz_depth_format(intel
, rb
->Format
)) {
1045 intel_miptree_alloc_hiz(intel
, mt
);
1055 * \brief Wrap a renderbuffer around a single slice of a miptree.
1057 * Called by glFramebufferTexture*(). This just allocates a
1058 * ``struct intel_renderbuffer`` then calls
1059 * intel_renderbuffer_update_wrapper() to do the real work.
1061 * \see intel_renderbuffer_update_wrapper()
1063 static struct intel_renderbuffer
*
1064 intel_renderbuffer_wrap_miptree(struct intel_context
*intel
,
1065 struct intel_mipmap_tree
*mt
,
1069 GLenum internal_format
)
1072 const GLuint name
= ~0; /* not significant, but distinct for debugging */
1073 struct gl_context
*ctx
= &intel
->ctx
;
1074 struct intel_renderbuffer
*irb
;
1076 intel_miptree_check_level_layer(mt
, level
, layer
);
1078 irb
= CALLOC_STRUCT(intel_renderbuffer
);
1080 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glFramebufferTexture");
1084 _mesa_init_renderbuffer(&irb
->Base
, name
);
1085 irb
->Base
.ClassID
= INTEL_RB_CLASS
;
1087 if (!intel_renderbuffer_update_wrapper(intel
, irb
,
1089 format
, internal_format
)) {
1098 intel_renderbuffer_set_draw_offset(struct intel_renderbuffer
*irb
)
1100 unsigned int dst_x
, dst_y
;
1102 /* compute offset of the particular 2D image within the texture region */
1103 intel_miptree_get_image_offset(irb
->mt
,
1105 0, /* face, which we ignore */
1109 irb
->draw_x
= dst_x
;
1110 irb
->draw_y
= dst_y
;
1114 * Rendering to tiled buffers requires that the base address of the
1115 * buffer be aligned to a page boundary. We generally render to
1116 * textures by pointing the surface at the mipmap image level, which
1117 * may not be aligned to a tile boundary.
1119 * This function returns an appropriately-aligned base offset
1120 * according to the tiling restrictions, plus any required x/y offset
1124 intel_renderbuffer_tile_offsets(struct intel_renderbuffer
*irb
,
1128 struct intel_region
*region
= irb
->mt
->region
;
1129 int cpp
= region
->cpp
;
1130 uint32_t pitch
= region
->pitch
* cpp
;
1132 if (region
->tiling
== I915_TILING_NONE
) {
1135 return irb
->draw_x
* cpp
+ irb
->draw_y
* pitch
;
1136 } else if (region
->tiling
== I915_TILING_X
) {
1137 *tile_x
= irb
->draw_x
% (512 / cpp
);
1138 *tile_y
= irb
->draw_y
% 8;
1139 return ((irb
->draw_y
/ 8) * (8 * pitch
) +
1140 (irb
->draw_x
- *tile_x
) / (512 / cpp
) * 4096);
1142 assert(region
->tiling
== I915_TILING_Y
);
1143 *tile_x
= irb
->draw_x
% (128 / cpp
);
1144 *tile_y
= irb
->draw_y
% 32;
1145 return ((irb
->draw_y
/ 32) * (32 * pitch
) +
1146 (irb
->draw_x
- *tile_x
) / (128 / cpp
) * 4096);
1152 need_tile_offset_workaround(struct brw_context
*brw
,
1153 struct intel_renderbuffer
*irb
)
1155 uint32_t tile_x
, tile_y
;
1157 if (brw
->has_surface_tile_offset
)
1160 intel_renderbuffer_tile_offsets(irb
, &tile_x
, &tile_y
);
1162 return tile_x
!= 0 || tile_y
!= 0;
1167 * Called by glFramebufferTexture[123]DEXT() (and other places) to
1168 * prepare for rendering into texture memory. This might be called
1169 * many times to choose different texture levels, cube faces, etc
1170 * before intel_finish_render_texture() is ever called.
1173 intel_render_texture(struct gl_context
* ctx
,
1174 struct gl_framebuffer
*fb
,
1175 struct gl_renderbuffer_attachment
*att
)
1177 struct intel_context
*intel
= intel_context(ctx
);
1178 struct gl_texture_image
*image
= _mesa_get_attachment_teximage(att
);
1179 struct intel_renderbuffer
*irb
= intel_renderbuffer(att
->Renderbuffer
);
1180 struct intel_texture_image
*intel_image
= intel_texture_image(image
);
1181 struct intel_mipmap_tree
*mt
= intel_image
->mt
;
1186 if (att
->CubeMapFace
> 0) {
1187 assert(att
->Zoffset
== 0);
1188 layer
= att
->CubeMapFace
;
1190 layer
= att
->Zoffset
;
1193 if (!intel_image
->mt
) {
1194 /* Fallback on drawing to a texture that doesn't have a miptree
1195 * (has a border, width/height 0, etc.)
1197 _mesa_reference_renderbuffer(&att
->Renderbuffer
, NULL
);
1198 _swrast_render_texture(ctx
, fb
, att
);
1202 irb
= intel_renderbuffer_wrap_miptree(intel
,
1207 image
->InternalFormat
);
1210 /* bind the wrapper to the attachment point */
1211 _mesa_reference_renderbuffer(&att
->Renderbuffer
, &irb
->Base
);
1214 /* fallback to software rendering */
1215 _swrast_render_texture(ctx
, fb
, att
);
1220 if (!intel_renderbuffer_update_wrapper(intel
, irb
,
1221 mt
, att
->TextureLevel
, layer
,
1223 image
->InternalFormat
)) {
1224 _mesa_reference_renderbuffer(&att
->Renderbuffer
, NULL
);
1225 _swrast_render_texture(ctx
, fb
, att
);
1229 DBG("Begin render %s texture tex=%u w=%d h=%d refcount=%d\n",
1230 _mesa_get_format_name(image
->TexFormat
),
1231 att
->Texture
->Name
, image
->Width
, image
->Height
,
1232 irb
->Base
.RefCount
);
1234 intel_image
->used_as_render_target
= true;
1237 if (need_tile_offset_workaround(brw_context(ctx
), irb
)) {
1238 /* Original gen4 hardware couldn't draw to a non-tile-aligned
1239 * destination in a miptree unless you actually setup your
1240 * renderbuffer as a miptree and used the fragile
1241 * lod/array_index/etc. controls to select the image. So,
1242 * instead, we just make a new single-level miptree and render
1245 struct intel_context
*intel
= intel_context(ctx
);
1246 struct intel_mipmap_tree
*new_mt
;
1247 int width
, height
, depth
;
1249 intel_miptree_get_dimensions_for_image(image
, &width
, &height
, &depth
);
1251 new_mt
= intel_miptree_create(intel
, image
->TexObject
->Target
,
1252 intel_image
->base
.Base
.TexFormat
,
1253 intel_image
->base
.Base
.Level
,
1254 intel_image
->base
.Base
.Level
,
1255 width
, height
, depth
,
1258 intel_miptree_copy_teximage(intel
, intel_image
, new_mt
);
1259 intel_renderbuffer_set_draw_offset(irb
);
1261 intel_miptree_reference(&irb
->mt
, intel_image
->mt
);
1262 intel_miptree_release(&new_mt
);
1265 /* update drawing region, etc */
1266 intel_draw_buffer(ctx
);
1271 * Called by Mesa when rendering to a texture is done.
1274 intel_finish_render_texture(struct gl_context
* ctx
,
1275 struct gl_renderbuffer_attachment
*att
)
1277 struct intel_context
*intel
= intel_context(ctx
);
1278 struct gl_texture_object
*tex_obj
= att
->Texture
;
1279 struct gl_texture_image
*image
=
1280 tex_obj
->Image
[att
->CubeMapFace
][att
->TextureLevel
];
1281 struct intel_texture_image
*intel_image
= intel_texture_image(image
);
1283 DBG("Finish render %s texture tex=%u\n",
1284 _mesa_get_format_name(image
->TexFormat
), att
->Texture
->Name
);
1286 /* Flag that this image may now be validated into the object's miptree. */
1288 intel_image
->used_as_render_target
= false;
1290 /* Since we've (probably) rendered to the texture and will (likely) use
1291 * it in the texture domain later on in this batchbuffer, flush the
1292 * batch. Once again, we wish for a domain tracker in libdrm to cover
1293 * usage inside of a batchbuffer like GEM does in the kernel.
1295 intel_batchbuffer_emit_mi_flush(intel
);
1299 * Do additional "completeness" testing of a framebuffer object.
1302 intel_validate_framebuffer(struct gl_context
*ctx
, struct gl_framebuffer
*fb
)
1304 struct intel_context
*intel
= intel_context(ctx
);
1305 const struct intel_renderbuffer
*depthRb
=
1306 intel_get_renderbuffer(fb
, BUFFER_DEPTH
);
1307 const struct intel_renderbuffer
*stencilRb
=
1308 intel_get_renderbuffer(fb
, BUFFER_STENCIL
);
1312 * The depth and stencil renderbuffers are the same renderbuffer or wrap
1315 if (depthRb
&& stencilRb
) {
1316 bool depth_stencil_are_same
;
1317 if (depthRb
== stencilRb
)
1318 depth_stencil_are_same
= true;
1319 else if ((fb
->Attachment
[BUFFER_DEPTH
].Type
== GL_TEXTURE
) &&
1320 (fb
->Attachment
[BUFFER_STENCIL
].Type
== GL_TEXTURE
) &&
1321 (fb
->Attachment
[BUFFER_DEPTH
].Texture
->Name
==
1322 fb
->Attachment
[BUFFER_STENCIL
].Texture
->Name
))
1323 depth_stencil_are_same
= true;
1325 depth_stencil_are_same
= false;
1327 if (!intel
->has_separate_stencil
&& !depth_stencil_are_same
) {
1328 fb
->_Status
= GL_FRAMEBUFFER_UNSUPPORTED_EXT
;
1332 for (i
= 0; i
< Elements(fb
->Attachment
); i
++) {
1333 struct gl_renderbuffer
*rb
;
1334 struct intel_renderbuffer
*irb
;
1336 if (fb
->Attachment
[i
].Type
== GL_NONE
)
1339 /* A supported attachment will have a Renderbuffer set either
1340 * from being a Renderbuffer or being a texture that got the
1341 * intel_wrap_texture() treatment.
1343 rb
= fb
->Attachment
[i
].Renderbuffer
;
1345 DBG("attachment without renderbuffer\n");
1346 fb
->_Status
= GL_FRAMEBUFFER_UNSUPPORTED_EXT
;
1350 irb
= intel_renderbuffer(rb
);
1352 DBG("software rendering renderbuffer\n");
1353 fb
->_Status
= GL_FRAMEBUFFER_UNSUPPORTED_EXT
;
1357 if (!intel
->vtbl
.render_target_supported(intel
, irb
->Base
.Format
)) {
1358 DBG("Unsupported HW texture/renderbuffer format attached: %s\n",
1359 _mesa_get_format_name(irb
->Base
.Format
));
1360 fb
->_Status
= GL_FRAMEBUFFER_UNSUPPORTED_EXT
;
1364 if (!intel_span_supports_format(irb
->Base
.Format
)) {
1365 DBG("Unsupported swrast texture/renderbuffer format attached: %s\n",
1366 _mesa_get_format_name(irb
->Base
.Format
));
1367 fb
->_Status
= GL_FRAMEBUFFER_UNSUPPORTED_EXT
;
1374 * Try to do a glBlitFramebuffer using glCopyTexSubImage2D
1375 * We can do this when the dst renderbuffer is actually a texture and
1376 * there is no scaling, mirroring or scissoring.
1378 * \return new buffer mask indicating the buffers left to blit using the
1382 intel_blit_framebuffer_copy_tex_sub_image(struct gl_context
*ctx
,
1383 GLint srcX0
, GLint srcY0
,
1384 GLint srcX1
, GLint srcY1
,
1385 GLint dstX0
, GLint dstY0
,
1386 GLint dstX1
, GLint dstY1
,
1387 GLbitfield mask
, GLenum filter
)
1389 if (mask
& GL_COLOR_BUFFER_BIT
) {
1390 const struct gl_framebuffer
*drawFb
= ctx
->DrawBuffer
;
1391 const struct gl_framebuffer
*readFb
= ctx
->ReadBuffer
;
1392 const struct gl_renderbuffer_attachment
*drawAtt
=
1393 &drawFb
->Attachment
[drawFb
->_ColorDrawBufferIndexes
[0]];
1395 /* If the source and destination are the same size with no
1396 mirroring, the rectangles are within the size of the
1397 texture and there is no scissor then we can use
1398 glCopyTexSubimage2D to implement the blit. This will end
1399 up as a fast hardware blit on some drivers */
1400 if (drawAtt
&& drawAtt
->Texture
&&
1401 srcX0
- srcX1
== dstX0
- dstX1
&&
1402 srcY0
- srcY1
== dstY0
- dstY1
&&
1405 srcX0
>= 0 && srcX1
<= readFb
->Width
&&
1406 srcY0
>= 0 && srcY1
<= readFb
->Height
&&
1407 dstX0
>= 0 && dstX1
<= drawFb
->Width
&&
1408 dstY0
>= 0 && dstY1
<= drawFb
->Height
&&
1409 !ctx
->Scissor
.Enabled
) {
1410 const struct gl_texture_object
*texObj
= drawAtt
->Texture
;
1411 const GLuint dstLevel
= drawAtt
->TextureLevel
;
1412 const GLenum target
= texObj
->Target
;
1414 struct gl_texture_image
*texImage
=
1415 _mesa_select_tex_image(ctx
, texObj
, target
, dstLevel
);
1417 if (intel_copy_texsubimage(intel_context(ctx
),
1418 intel_texture_image(texImage
),
1421 srcX1
- srcX0
, /* width */
1423 mask
&= ~GL_COLOR_BUFFER_BIT
;
1431 intel_blit_framebuffer(struct gl_context
*ctx
,
1432 GLint srcX0
, GLint srcY0
, GLint srcX1
, GLint srcY1
,
1433 GLint dstX0
, GLint dstY0
, GLint dstX1
, GLint dstY1
,
1434 GLbitfield mask
, GLenum filter
)
1436 /* Try faster, glCopyTexSubImage2D approach first which uses the BLT. */
1437 mask
= intel_blit_framebuffer_copy_tex_sub_image(ctx
,
1438 srcX0
, srcY0
, srcX1
, srcY1
,
1439 dstX0
, dstY0
, dstX1
, dstY1
,
1444 _mesa_meta_BlitFramebuffer(ctx
,
1445 srcX0
, srcY0
, srcX1
, srcY1
,
1446 dstX0
, dstY0
, dstX1
, dstY1
,
1451 intel_renderbuffer_set_needs_hiz_resolve(struct intel_renderbuffer
*irb
)
1454 intel_miptree_slice_set_needs_hiz_resolve(irb
->mt
,
1457 } else if (irb
->wrapped_depth
) {
1458 intel_renderbuffer_set_needs_hiz_resolve(
1459 intel_renderbuffer(irb
->wrapped_depth
));
1466 intel_renderbuffer_set_needs_depth_resolve(struct intel_renderbuffer
*irb
)
1469 intel_miptree_slice_set_needs_depth_resolve(irb
->mt
,
1472 } else if (irb
->wrapped_depth
) {
1473 intel_renderbuffer_set_needs_depth_resolve(
1474 intel_renderbuffer(irb
->wrapped_depth
));
1481 intel_renderbuffer_resolve_hiz(struct intel_context
*intel
,
1482 struct intel_renderbuffer
*irb
)
1485 return intel_miptree_slice_resolve_hiz(intel
,
1489 if (irb
->wrapped_depth
)
1490 return intel_renderbuffer_resolve_hiz(intel
,
1491 intel_renderbuffer(irb
->wrapped_depth
));
1497 intel_renderbuffer_resolve_depth(struct intel_context
*intel
,
1498 struct intel_renderbuffer
*irb
)
1501 return intel_miptree_slice_resolve_depth(intel
,
1506 if (irb
->wrapped_depth
)
1507 return intel_renderbuffer_resolve_depth(intel
,
1508 intel_renderbuffer(irb
->wrapped_depth
));
1514 * Do one-time context initializations related to GL_EXT_framebuffer_object.
1515 * Hook in device driver functions.
1518 intel_fbo_init(struct intel_context
*intel
)
1520 intel
->ctx
.Driver
.NewFramebuffer
= intel_new_framebuffer
;
1521 intel
->ctx
.Driver
.NewRenderbuffer
= intel_new_renderbuffer
;
1522 intel
->ctx
.Driver
.MapRenderbuffer
= intel_map_renderbuffer
;
1523 intel
->ctx
.Driver
.UnmapRenderbuffer
= intel_unmap_renderbuffer
;
1524 intel
->ctx
.Driver
.BindFramebuffer
= intel_bind_framebuffer
;
1525 intel
->ctx
.Driver
.FramebufferRenderbuffer
= intel_framebuffer_renderbuffer
;
1526 intel
->ctx
.Driver
.RenderTexture
= intel_render_texture
;
1527 intel
->ctx
.Driver
.FinishRenderTexture
= intel_finish_render_texture
;
1528 intel
->ctx
.Driver
.ResizeBuffers
= intel_resize_buffers
;
1529 intel
->ctx
.Driver
.ValidateFramebuffer
= intel_validate_framebuffer
;
1530 intel
->ctx
.Driver
.BlitFramebuffer
= intel_blit_framebuffer
;
1532 #if FEATURE_OES_EGL_image
1533 intel
->ctx
.Driver
.EGLImageTargetRenderbufferStorage
=
1534 intel_image_target_renderbuffer_storage
;