2 * Copyright © 2012 Intel Corporation
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
24 #include "main/context.h"
25 #include "main/teximage.h"
26 #include "main/blend.h"
27 #include "main/fbobject.h"
28 #include "main/renderbuffer.h"
29 #include "main/glformats.h"
31 #include "brw_blorp.h"
32 #include "brw_context.h"
33 #include "brw_meta_util.h"
34 #include "brw_state.h"
35 #include "intel_fbo.h"
36 #include "intel_debug.h"
38 #define FILE_DEBUG_FLAG DEBUG_BLORP
41 brw_blorp_init(struct brw_context
*brw
)
43 blorp_init(&brw
->blorp
, brw
, &brw
->isl_dev
);
47 apply_gen6_stencil_hiz_offset(struct isl_surf
*surf
,
48 struct intel_mipmap_tree
*mt
,
52 assert(mt
->array_layout
== ALL_SLICES_AT_EACH_LOD
);
54 if (mt
->format
== MESA_FORMAT_S_UINT8
) {
55 /* Note: we can't compute the stencil offset using
56 * intel_miptree_get_aligned_offset(), because the miptree
57 * claims that the region is untiled even though it's W tiled.
59 *offset
= mt
->level
[lod
].level_y
* mt
->pitch
+
60 mt
->level
[lod
].level_x
* 64;
62 *offset
= intel_miptree_get_aligned_offset(mt
,
63 mt
->level
[lod
].level_x
,
64 mt
->level
[lod
].level_y
,
68 surf
->logical_level0_px
.width
= minify(surf
->logical_level0_px
.width
, lod
);
69 surf
->logical_level0_px
.height
= minify(surf
->logical_level0_px
.height
, lod
);
70 surf
->phys_level0_sa
.width
= minify(surf
->phys_level0_sa
.width
, lod
);
71 surf
->phys_level0_sa
.height
= minify(surf
->phys_level0_sa
.height
, lod
);
73 surf
->array_pitch_el_rows
=
74 ALIGN(surf
->phys_level0_sa
.height
, surf
->image_alignment_el
.height
);
78 brw_blorp_surf_for_miptree(struct brw_context
*brw
,
79 struct brw_blorp_surf
*surf
,
80 struct intel_mipmap_tree
*mt
,
81 bool is_render_target
,
83 struct isl_surf tmp_surfs
[2])
85 intel_miptree_get_isl_surf(brw
, mt
, &tmp_surfs
[0]);
86 surf
->surf
= &tmp_surfs
[0];
88 surf
->offset
= mt
->offset
;
90 if (brw
->gen
== 6 && mt
->format
== MESA_FORMAT_S_UINT8
&&
91 mt
->array_layout
== ALL_SLICES_AT_EACH_LOD
) {
92 /* Sandy bridge stencil and HiZ use this ALL_SLICES_AT_EACH_LOD hack in
93 * order to allow for layered rendering. The hack makes each LOD of the
94 * stencil or HiZ buffer a single tightly packed array surface at some
95 * offset into the surface. Since ISL doesn't know how to deal with the
96 * crazy ALL_SLICES_AT_EACH_LOD layout and since we have to do a manual
97 * offset of it anyway, we might as well do the offset here and keep the
98 * hacks inside the i965 driver.
100 * See also gen6_depth_stencil_state.c
103 apply_gen6_stencil_hiz_offset(&tmp_surfs
[0], mt
, *level
, &offset
);
104 surf
->offset
+= offset
;
108 struct isl_surf
*aux_surf
= &tmp_surfs
[1];
109 intel_miptree_get_aux_isl_surf(brw
, mt
, aux_surf
, &surf
->aux_usage
);
111 /* For textures that are in the RESOLVED state, we ignore the MCS */
112 if (mt
->mcs_mt
&& !is_render_target
&&
113 mt
->fast_clear_state
== INTEL_FAST_CLEAR_STATE_RESOLVED
)
114 surf
->aux_usage
= ISL_AUX_USAGE_NONE
;
116 if (surf
->aux_usage
!= ISL_AUX_USAGE_NONE
) {
117 /* We only really need a clear color if we also have an auxiliary
118 * surface. Without one, it does nothing.
120 surf
->clear_color
= intel_miptree_get_isl_clear_color(brw
, mt
);
122 surf
->aux_surf
= aux_surf
;
124 surf
->aux_bo
= mt
->mcs_mt
->bo
;
125 surf
->aux_offset
= mt
->mcs_mt
->offset
;
127 assert(surf
->aux_usage
== ISL_AUX_USAGE_HIZ
);
128 struct intel_mipmap_tree
*hiz_mt
= mt
->hiz_buf
->mt
;
130 surf
->aux_bo
= hiz_mt
->bo
;
132 hiz_mt
->array_layout
== ALL_SLICES_AT_EACH_LOD
) {
133 /* gen6 requires the HiZ buffer to be manually offset to the
134 * right location. We could fixup the surf but it doesn't
135 * matter since most of those fields don't matter.
137 apply_gen6_stencil_hiz_offset(aux_surf
, hiz_mt
, *level
,
140 surf
->aux_offset
= 0;
142 assert(hiz_mt
->pitch
== aux_surf
->row_pitch
);
144 surf
->aux_bo
= mt
->hiz_buf
->bo
;
145 surf
->aux_offset
= 0;
150 surf
->aux_offset
= 0;
151 memset(&surf
->clear_color
, 0, sizeof(surf
->clear_color
));
153 assert((surf
->aux_usage
== ISL_AUX_USAGE_NONE
) == (surf
->aux_bo
== NULL
));
156 static enum isl_format
157 brw_blorp_to_isl_format(struct brw_context
*brw
, mesa_format format
,
158 bool is_render_target
)
161 case MESA_FORMAT_NONE
:
162 return ISL_FORMAT_UNSUPPORTED
;
163 case MESA_FORMAT_S_UINT8
:
164 return ISL_FORMAT_R8_UINT
;
165 case MESA_FORMAT_Z24_UNORM_X8_UINT
:
166 return ISL_FORMAT_R24_UNORM_X8_TYPELESS
;
167 case MESA_FORMAT_Z_FLOAT32
:
168 return ISL_FORMAT_R32_FLOAT
;
169 case MESA_FORMAT_Z_UNORM16
:
170 return ISL_FORMAT_R16_UNORM
;
172 if (is_render_target
) {
173 assert(brw
->format_supported_as_render_target
[format
]);
174 return brw
->render_target_format
[format
];
176 return brw_format_for_mesa_format(format
);
184 * Note: if the src (or dst) is a 2D multisample array texture on Gen7+ using
185 * INTEL_MSAA_LAYOUT_UMS or INTEL_MSAA_LAYOUT_CMS, src_layer (dst_layer) is
186 * the physical layer holding sample 0. So, for example, if
187 * src_mt->num_samples == 4, then logical layer n corresponds to src_layer ==
191 brw_blorp_blit_miptrees(struct brw_context
*brw
,
192 struct intel_mipmap_tree
*src_mt
,
193 unsigned src_level
, unsigned src_layer
,
194 mesa_format src_format
, int src_swizzle
,
195 struct intel_mipmap_tree
*dst_mt
,
196 unsigned dst_level
, unsigned dst_layer
,
197 mesa_format dst_format
,
198 float src_x0
, float src_y0
,
199 float src_x1
, float src_y1
,
200 float dst_x0
, float dst_y0
,
201 float dst_x1
, float dst_y1
,
202 GLenum filter
, bool mirror_x
, bool mirror_y
,
203 bool decode_srgb
, bool encode_srgb
)
205 /* Get ready to blit. This includes depth resolving the src and dst
206 * buffers if necessary. Note: it's not necessary to do a color resolve on
207 * the destination buffer because we use the standard render path to render
208 * to destination color buffers, and the standard render path is
211 intel_miptree_resolve_color(brw
, src_mt
, INTEL_MIPTREE_IGNORE_CCS_E
);
212 intel_miptree_slice_resolve_depth(brw
, src_mt
, src_level
, src_layer
);
213 intel_miptree_slice_resolve_depth(brw
, dst_mt
, dst_level
, dst_layer
);
215 intel_miptree_prepare_mcs(brw
, dst_mt
);
217 DBG("%s from %dx %s mt %p %d %d (%f,%f) (%f,%f)"
218 "to %dx %s mt %p %d %d (%f,%f) (%f,%f) (flip %d,%d)\n",
220 src_mt
->num_samples
, _mesa_get_format_name(src_mt
->format
), src_mt
,
221 src_level
, src_layer
, src_x0
, src_y0
, src_x1
, src_y1
,
222 dst_mt
->num_samples
, _mesa_get_format_name(dst_mt
->format
), dst_mt
,
223 dst_level
, dst_layer
, dst_x0
, dst_y0
, dst_x1
, dst_y1
,
226 if (!decode_srgb
&& _mesa_get_format_color_encoding(src_format
) == GL_SRGB
)
227 src_format
= _mesa_get_srgb_format_linear(src_format
);
229 if (!encode_srgb
&& _mesa_get_format_color_encoding(dst_format
) == GL_SRGB
)
230 dst_format
= _mesa_get_srgb_format_linear(dst_format
);
232 /* When doing a multisample resolve of a GL_LUMINANCE32F or GL_INTENSITY32F
233 * texture, the above code configures the source format for L32_FLOAT or
234 * I32_FLOAT, and the destination format for R32_FLOAT. On Sandy Bridge,
235 * the SAMPLE message appears to handle multisampled L32_FLOAT and
236 * I32_FLOAT textures incorrectly, resulting in blocky artifacts. So work
237 * around the problem by using a source format of R32_FLOAT. This
238 * shouldn't affect rendering correctness, since the destination format is
239 * R32_FLOAT, so only the contents of the red channel matters.
242 src_mt
->num_samples
> 1 && dst_mt
->num_samples
<= 1 &&
243 src_mt
->format
== dst_mt
->format
&&
244 (dst_format
== MESA_FORMAT_L_FLOAT32
||
245 dst_format
== MESA_FORMAT_I_FLOAT32
)) {
246 src_format
= dst_format
= MESA_FORMAT_R_FLOAT32
;
249 intel_miptree_check_level_layer(src_mt
, src_level
, src_layer
);
250 intel_miptree_check_level_layer(dst_mt
, dst_level
, dst_layer
);
251 intel_miptree_used_for_rendering(dst_mt
);
253 struct isl_surf tmp_surfs
[4];
254 struct brw_blorp_surf src_surf
, dst_surf
;
255 brw_blorp_surf_for_miptree(brw
, &src_surf
, src_mt
, false,
256 &src_level
, &tmp_surfs
[0]);
257 brw_blorp_surf_for_miptree(brw
, &dst_surf
, dst_mt
, true,
258 &dst_level
, &tmp_surfs
[2]);
260 brw_blorp_blit(brw
, &src_surf
, src_level
, src_layer
,
261 brw_blorp_to_isl_format(brw
, src_format
, false), src_swizzle
,
262 &dst_surf
, dst_level
, dst_layer
,
263 brw_blorp_to_isl_format(brw
, dst_format
, true),
264 src_x0
, src_y0
, src_x1
, src_y1
,
265 dst_x0
, dst_y0
, dst_x1
, dst_y1
,
266 filter
, mirror_x
, mirror_y
);
268 intel_miptree_slice_set_needs_hiz_resolve(dst_mt
, dst_level
, dst_layer
);
270 if (intel_miptree_is_lossless_compressed(brw
, dst_mt
))
271 dst_mt
->fast_clear_state
= INTEL_FAST_CLEAR_STATE_UNRESOLVED
;
274 static struct intel_mipmap_tree
*
275 find_miptree(GLbitfield buffer_bit
, struct intel_renderbuffer
*irb
)
277 struct intel_mipmap_tree
*mt
= irb
->mt
;
278 if (buffer_bit
== GL_STENCIL_BUFFER_BIT
&& mt
->stencil_mt
)
284 blorp_get_texture_swizzle(const struct intel_renderbuffer
*irb
)
286 return irb
->Base
.Base
._BaseFormat
== GL_RGB
?
287 MAKE_SWIZZLE4(SWIZZLE_X
, SWIZZLE_Y
, SWIZZLE_Z
, SWIZZLE_ONE
) :
292 do_blorp_blit(struct brw_context
*brw
, GLbitfield buffer_bit
,
293 struct intel_renderbuffer
*src_irb
, mesa_format src_format
,
294 struct intel_renderbuffer
*dst_irb
, mesa_format dst_format
,
295 GLfloat srcX0
, GLfloat srcY0
, GLfloat srcX1
, GLfloat srcY1
,
296 GLfloat dstX0
, GLfloat dstY0
, GLfloat dstX1
, GLfloat dstY1
,
297 GLenum filter
, bool mirror_x
, bool mirror_y
)
299 const struct gl_context
*ctx
= &brw
->ctx
;
301 /* Find source/dst miptrees */
302 struct intel_mipmap_tree
*src_mt
= find_miptree(buffer_bit
, src_irb
);
303 struct intel_mipmap_tree
*dst_mt
= find_miptree(buffer_bit
, dst_irb
);
305 const bool do_srgb
= ctx
->Color
.sRGBEnabled
;
308 brw_blorp_blit_miptrees(brw
,
309 src_mt
, src_irb
->mt_level
, src_irb
->mt_layer
,
310 src_format
, blorp_get_texture_swizzle(src_irb
),
311 dst_mt
, dst_irb
->mt_level
, dst_irb
->mt_layer
,
313 srcX0
, srcY0
, srcX1
, srcY1
,
314 dstX0
, dstY0
, dstX1
, dstY1
,
315 filter
, mirror_x
, mirror_y
,
318 dst_irb
->need_downsample
= true;
322 try_blorp_blit(struct brw_context
*brw
,
323 const struct gl_framebuffer
*read_fb
,
324 const struct gl_framebuffer
*draw_fb
,
325 GLfloat srcX0
, GLfloat srcY0
, GLfloat srcX1
, GLfloat srcY1
,
326 GLfloat dstX0
, GLfloat dstY0
, GLfloat dstX1
, GLfloat dstY1
,
327 GLenum filter
, GLbitfield buffer_bit
)
329 struct gl_context
*ctx
= &brw
->ctx
;
331 /* Sync up the state of window system buffers. We need to do this before
332 * we go looking for the buffers.
334 intel_prepare_render(brw
);
336 bool mirror_x
, mirror_y
;
337 if (brw_meta_mirror_clip_and_scissor(ctx
, read_fb
, draw_fb
,
338 &srcX0
, &srcY0
, &srcX1
, &srcY1
,
339 &dstX0
, &dstY0
, &dstX1
, &dstY1
,
340 &mirror_x
, &mirror_y
))
344 struct intel_renderbuffer
*src_irb
;
345 struct intel_renderbuffer
*dst_irb
;
346 struct intel_mipmap_tree
*src_mt
;
347 struct intel_mipmap_tree
*dst_mt
;
348 switch (buffer_bit
) {
349 case GL_COLOR_BUFFER_BIT
:
350 src_irb
= intel_renderbuffer(read_fb
->_ColorReadBuffer
);
351 for (unsigned i
= 0; i
< draw_fb
->_NumColorDrawBuffers
; ++i
) {
352 dst_irb
= intel_renderbuffer(draw_fb
->_ColorDrawBuffers
[i
]);
354 do_blorp_blit(brw
, buffer_bit
,
355 src_irb
, src_irb
->Base
.Base
.Format
,
356 dst_irb
, dst_irb
->Base
.Base
.Format
,
357 srcX0
, srcY0
, srcX1
, srcY1
,
358 dstX0
, dstY0
, dstX1
, dstY1
,
359 filter
, mirror_x
, mirror_y
);
362 case GL_DEPTH_BUFFER_BIT
:
364 intel_renderbuffer(read_fb
->Attachment
[BUFFER_DEPTH
].Renderbuffer
);
366 intel_renderbuffer(draw_fb
->Attachment
[BUFFER_DEPTH
].Renderbuffer
);
367 src_mt
= find_miptree(buffer_bit
, src_irb
);
368 dst_mt
= find_miptree(buffer_bit
, dst_irb
);
370 /* We can't handle format conversions between Z24 and other formats
371 * since we have to lie about the surface format. See the comments in
372 * brw_blorp_surface_info::set().
374 if ((src_mt
->format
== MESA_FORMAT_Z24_UNORM_X8_UINT
) !=
375 (dst_mt
->format
== MESA_FORMAT_Z24_UNORM_X8_UINT
))
378 do_blorp_blit(brw
, buffer_bit
, src_irb
, MESA_FORMAT_NONE
,
379 dst_irb
, MESA_FORMAT_NONE
, srcX0
, srcY0
,
380 srcX1
, srcY1
, dstX0
, dstY0
, dstX1
, dstY1
,
381 filter
, mirror_x
, mirror_y
);
383 case GL_STENCIL_BUFFER_BIT
:
385 intel_renderbuffer(read_fb
->Attachment
[BUFFER_STENCIL
].Renderbuffer
);
387 intel_renderbuffer(draw_fb
->Attachment
[BUFFER_STENCIL
].Renderbuffer
);
388 do_blorp_blit(brw
, buffer_bit
, src_irb
, MESA_FORMAT_NONE
,
389 dst_irb
, MESA_FORMAT_NONE
, srcX0
, srcY0
,
390 srcX1
, srcY1
, dstX0
, dstY0
, dstX1
, dstY1
,
391 filter
, mirror_x
, mirror_y
);
394 unreachable("not reached");
401 brw_blorp_copytexsubimage(struct brw_context
*brw
,
402 struct gl_renderbuffer
*src_rb
,
403 struct gl_texture_image
*dst_image
,
405 int srcX0
, int srcY0
,
406 int dstX0
, int dstY0
,
407 int width
, int height
)
409 struct gl_context
*ctx
= &brw
->ctx
;
410 struct intel_renderbuffer
*src_irb
= intel_renderbuffer(src_rb
);
411 struct intel_texture_image
*intel_image
= intel_texture_image(dst_image
);
413 /* No pixel transfer operations (zoom, bias, mapping), just a blit */
414 if (brw
->ctx
._ImageTransferState
)
417 /* Sync up the state of window system buffers. We need to do this before
418 * we go looking at the src renderbuffer's miptree.
420 intel_prepare_render(brw
);
422 struct intel_mipmap_tree
*src_mt
= src_irb
->mt
;
423 struct intel_mipmap_tree
*dst_mt
= intel_image
->mt
;
425 /* There is support for only up to eight samples. */
426 if (src_mt
->num_samples
> 8 || dst_mt
->num_samples
> 8)
429 /* BLORP is only supported from Gen6 onwards. */
433 if (_mesa_get_format_base_format(src_rb
->Format
) !=
434 _mesa_get_format_base_format(dst_image
->TexFormat
)) {
438 /* We can't handle format conversions between Z24 and other formats since
439 * we have to lie about the surface format. See the comments in
440 * brw_blorp_surface_info::set().
442 if ((src_mt
->format
== MESA_FORMAT_Z24_UNORM_X8_UINT
) !=
443 (dst_mt
->format
== MESA_FORMAT_Z24_UNORM_X8_UINT
)) {
447 if (!brw
->format_supported_as_render_target
[dst_image
->TexFormat
])
450 /* Source clipping shouldn't be necessary, since copytexsubimage (in
451 * src/mesa/main/teximage.c) calls _mesa_clip_copytexsubimage() which
454 * Destination clipping shouldn't be necessary since the restrictions on
455 * glCopyTexSubImage prevent the user from specifying a destination rectangle
456 * that falls outside the bounds of the destination texture.
457 * See error_check_subtexture_dimensions().
460 int srcY1
= srcY0
+ height
;
461 int srcX1
= srcX0
+ width
;
462 int dstX1
= dstX0
+ width
;
463 int dstY1
= dstY0
+ height
;
465 /* Account for the fact that in the system framebuffer, the origin is at
468 bool mirror_y
= false;
469 if (_mesa_is_winsys_fbo(ctx
->ReadBuffer
)) {
470 GLint tmp
= src_rb
->Height
- srcY0
;
471 srcY0
= src_rb
->Height
- srcY1
;
476 /* Account for face selection and texture view MinLayer */
477 int dst_slice
= slice
+ dst_image
->TexObject
->MinLayer
+ dst_image
->Face
;
478 int dst_level
= dst_image
->Level
+ dst_image
->TexObject
->MinLevel
;
480 brw_blorp_blit_miptrees(brw
,
481 src_mt
, src_irb
->mt_level
, src_irb
->mt_layer
,
482 src_rb
->Format
, blorp_get_texture_swizzle(src_irb
),
483 dst_mt
, dst_level
, dst_slice
,
484 dst_image
->TexFormat
,
485 srcX0
, srcY0
, srcX1
, srcY1
,
486 dstX0
, dstY0
, dstX1
, dstY1
,
487 GL_NEAREST
, false, mirror_y
,
490 /* If we're copying to a packed depth stencil texture and the source
491 * framebuffer has separate stencil, we need to also copy the stencil data
494 src_rb
= ctx
->ReadBuffer
->Attachment
[BUFFER_STENCIL
].Renderbuffer
;
495 if (_mesa_get_format_bits(dst_image
->TexFormat
, GL_STENCIL_BITS
) > 0 &&
497 src_irb
= intel_renderbuffer(src_rb
);
498 src_mt
= src_irb
->mt
;
500 if (src_mt
->stencil_mt
)
501 src_mt
= src_mt
->stencil_mt
;
502 if (dst_mt
->stencil_mt
)
503 dst_mt
= dst_mt
->stencil_mt
;
505 if (src_mt
!= dst_mt
) {
506 brw_blorp_blit_miptrees(brw
,
507 src_mt
, src_irb
->mt_level
, src_irb
->mt_layer
,
509 blorp_get_texture_swizzle(src_irb
),
510 dst_mt
, dst_level
, dst_slice
,
512 srcX0
, srcY0
, srcX1
, srcY1
,
513 dstX0
, dstY0
, dstX1
, dstY1
,
514 GL_NEAREST
, false, mirror_y
,
524 brw_blorp_framebuffer(struct brw_context
*brw
,
525 struct gl_framebuffer
*readFb
,
526 struct gl_framebuffer
*drawFb
,
527 GLint srcX0
, GLint srcY0
, GLint srcX1
, GLint srcY1
,
528 GLint dstX0
, GLint dstY0
, GLint dstX1
, GLint dstY1
,
529 GLbitfield mask
, GLenum filter
)
531 /* BLORP is not supported before Gen6. */
535 static GLbitfield buffer_bits
[] = {
538 GL_STENCIL_BUFFER_BIT
,
541 for (unsigned int i
= 0; i
< ARRAY_SIZE(buffer_bits
); ++i
) {
542 if ((mask
& buffer_bits
[i
]) &&
543 try_blorp_blit(brw
, readFb
, drawFb
,
544 srcX0
, srcY0
, srcX1
, srcY1
,
545 dstX0
, dstY0
, dstX1
, dstY1
,
546 filter
, buffer_bits
[i
])) {
547 mask
&= ~buffer_bits
[i
];
555 set_write_disables(const struct intel_renderbuffer
*irb
,
556 const GLubyte
*color_mask
, bool *color_write_disable
)
558 /* Format information in the renderbuffer represents the requirements
559 * given by the client. There are cases where the backing miptree uses,
560 * for example, RGBA to represent RGBX. Since the client is only expecting
561 * RGB we can treat alpha as not used and write whatever we like into it.
563 const GLenum base_format
= irb
->Base
.Base
._BaseFormat
;
564 const int components
= _mesa_base_format_component_count(base_format
);
565 bool disables
= false;
567 assert(components
> 0);
569 for (int i
= 0; i
< components
; i
++) {
570 color_write_disable
[i
] = !color_mask
[i
];
571 disables
= disables
|| !color_mask
[i
];
578 do_single_blorp_clear(struct brw_context
*brw
, struct gl_framebuffer
*fb
,
579 struct gl_renderbuffer
*rb
, unsigned buf
,
580 bool partial_clear
, bool encode_srgb
, unsigned layer
)
582 struct gl_context
*ctx
= &brw
->ctx
;
583 struct intel_renderbuffer
*irb
= intel_renderbuffer(rb
);
584 mesa_format format
= irb
->mt
->format
;
585 uint32_t x0
, x1
, y0
, y1
;
587 if (!encode_srgb
&& _mesa_get_format_color_encoding(format
) == GL_SRGB
)
588 format
= _mesa_get_srgb_format_linear(format
);
596 y0
= rb
->Height
- fb
->_Ymax
;
597 y1
= rb
->Height
- fb
->_Ymin
;
600 /* If the clear region is empty, just return. */
601 if (x0
== x1
|| y0
== y1
)
604 bool can_fast_clear
= !partial_clear
;
606 bool color_write_disable
[4] = { false, false, false, false };
607 if (set_write_disables(irb
, ctx
->Color
.ColorMask
[buf
], color_write_disable
))
608 can_fast_clear
= false;
610 if (irb
->mt
->fast_clear_state
== INTEL_FAST_CLEAR_STATE_NO_MCS
||
611 !brw_is_color_fast_clear_compatible(brw
, irb
->mt
, &ctx
->Color
.ClearColor
))
612 can_fast_clear
= false;
614 if (can_fast_clear
) {
615 /* Record the clear color in the miptree so that it will be
616 * programmed in SURFACE_STATE by later rendering and resolve
619 const bool color_updated
= brw_meta_set_fast_clear_color(
620 brw
, irb
->mt
, &ctx
->Color
.ClearColor
);
622 /* If the buffer is already in INTEL_FAST_CLEAR_STATE_CLEAR, the clear
623 * is redundant and can be skipped.
625 if (!color_updated
&&
626 irb
->mt
->fast_clear_state
== INTEL_FAST_CLEAR_STATE_CLEAR
)
629 /* If the MCS buffer hasn't been allocated yet, we need to allocate
632 if (!irb
->mt
->mcs_mt
) {
633 if (!intel_miptree_alloc_non_msrt_mcs(brw
, irb
->mt
)) {
634 /* MCS allocation failed--probably this will only happen in
635 * out-of-memory conditions. But in any case, try to recover
636 * by falling back to a non-blorp clear technique.
643 intel_miptree_check_level_layer(irb
->mt
, irb
->mt_level
, layer
);
644 intel_miptree_used_for_rendering(irb
->mt
);
646 /* We can't setup the blorp_surf until we've allocated the MCS above */
647 struct isl_surf isl_tmp
[2];
648 struct brw_blorp_surf surf
;
649 unsigned level
= irb
->mt_level
;
650 brw_blorp_surf_for_miptree(brw
, &surf
, irb
->mt
, true, &level
, isl_tmp
);
652 if (can_fast_clear
) {
653 DBG("%s (fast) to mt %p level %d layer %d\n", __FUNCTION__
,
654 irb
->mt
, irb
->mt_level
, irb
->mt_layer
);
656 blorp_fast_clear(brw
, &surf
, level
, layer
, x0
, y0
, x1
, y1
);
658 /* Now that the fast clear has occurred, put the buffer in
659 * INTEL_FAST_CLEAR_STATE_CLEAR so that we won't waste time doing
662 irb
->mt
->fast_clear_state
= INTEL_FAST_CLEAR_STATE_CLEAR
;
664 DBG("%s (slow) to mt %p level %d layer %d\n", __FUNCTION__
,
665 irb
->mt
, irb
->mt_level
, irb
->mt_layer
);
667 union isl_color_value clear_color
;
668 memcpy(clear_color
.f32
, ctx
->Color
.ClearColor
.f
, sizeof(float) * 4);
670 blorp_clear(brw
, &surf
, level
, layer
, x0
, y0
, x1
, y1
,
671 (enum isl_format
)brw
->render_target_format
[format
],
672 clear_color
, color_write_disable
);
674 if (intel_miptree_is_lossless_compressed(brw
, irb
->mt
)) {
675 /* Compressed buffers can be cleared also using normal rep-clear. In
676 * such case they bahave such as if they were drawn using normal 3D
677 * render pipeline, and we simply mark the mcs as dirty.
679 assert(partial_clear
);
680 irb
->mt
->fast_clear_state
= INTEL_FAST_CLEAR_STATE_UNRESOLVED
;
688 brw_blorp_clear_color(struct brw_context
*brw
, struct gl_framebuffer
*fb
,
689 GLbitfield mask
, bool partial_clear
, bool encode_srgb
)
691 for (unsigned buf
= 0; buf
< fb
->_NumColorDrawBuffers
; buf
++) {
692 struct gl_renderbuffer
*rb
= fb
->_ColorDrawBuffers
[buf
];
693 struct intel_renderbuffer
*irb
= intel_renderbuffer(rb
);
695 /* Only clear the buffers present in the provided mask */
696 if (((1 << fb
->_ColorDrawBufferIndexes
[buf
]) & mask
) == 0)
699 /* If this is an ES2 context or GL_ARB_ES2_compatibility is supported,
700 * the framebuffer can be complete with some attachments missing. In
701 * this case the _ColorDrawBuffers pointer will be NULL.
706 if (fb
->MaxNumLayers
> 0) {
707 unsigned layer_multiplier
=
708 (irb
->mt
->msaa_layout
== INTEL_MSAA_LAYOUT_UMS
||
709 irb
->mt
->msaa_layout
== INTEL_MSAA_LAYOUT_CMS
) ?
710 irb
->mt
->num_samples
: 1;
711 unsigned num_layers
= irb
->layer_count
;
712 for (unsigned layer
= 0; layer
< num_layers
; layer
++) {
713 if (!do_single_blorp_clear(
714 brw
, fb
, rb
, buf
, partial_clear
, encode_srgb
,
715 irb
->mt_layer
+ layer
* layer_multiplier
)) {
720 unsigned layer
= irb
->mt_layer
;
721 if (!do_single_blorp_clear(brw
, fb
, rb
, buf
, partial_clear
,
726 irb
->need_downsample
= true;
733 brw_blorp_resolve_color(struct brw_context
*brw
, struct intel_mipmap_tree
*mt
)
735 DBG("%s to mt %p\n", __FUNCTION__
, mt
);
737 const mesa_format format
= _mesa_get_srgb_format_linear(mt
->format
);
739 intel_miptree_check_level_layer(mt
, 0 /* level */, 0 /* layer */);
740 intel_miptree_used_for_rendering(mt
);
742 struct isl_surf isl_tmp
[2];
743 struct brw_blorp_surf surf
;
745 brw_blorp_surf_for_miptree(brw
, &surf
, mt
, true, &level
, isl_tmp
);
747 brw_blorp_ccs_resolve(brw
, &surf
, brw_blorp_to_isl_format(brw
, format
, true));
749 mt
->fast_clear_state
= INTEL_FAST_CLEAR_STATE_RESOLVED
;
753 gen6_blorp_hiz_exec(struct brw_context
*brw
, struct intel_mipmap_tree
*mt
,
754 unsigned int level
, unsigned int layer
, enum gen6_hiz_op op
)
756 intel_miptree_check_level_layer(mt
, level
, layer
);
757 intel_miptree_used_for_rendering(mt
);
759 assert(intel_miptree_level_has_hiz(mt
, level
));
761 struct isl_surf isl_tmp
[2];
762 struct brw_blorp_surf surf
;
763 brw_blorp_surf_for_miptree(brw
, &surf
, mt
, true, &level
, isl_tmp
);
765 blorp_gen6_hiz_op(brw
, &surf
, level
, layer
, op
);
769 * Perform a HiZ or depth resolve operation.
771 * For an overview of HiZ ops, see the following sections of the Sandy Bridge
772 * PRM, Volume 1, Part 2:
773 * - 7.5.3.1 Depth Buffer Clear
774 * - 7.5.3.2 Depth Buffer Resolve
775 * - 7.5.3.3 Hierarchical Depth Buffer Resolve
778 intel_hiz_exec(struct brw_context
*brw
, struct intel_mipmap_tree
*mt
,
779 unsigned int level
, unsigned int layer
, enum gen6_hiz_op op
)
781 const char *opname
= NULL
;
784 case GEN6_HIZ_OP_DEPTH_RESOLVE
:
785 opname
= "depth resolve";
787 case GEN6_HIZ_OP_HIZ_RESOLVE
:
788 opname
= "hiz ambiguate";
790 case GEN6_HIZ_OP_DEPTH_CLEAR
:
791 opname
= "depth clear";
793 case GEN6_HIZ_OP_NONE
:
798 DBG("%s %s to mt %p level %d layer %d\n",
799 __func__
, opname
, mt
, level
, layer
);
802 gen8_hiz_exec(brw
, mt
, level
, layer
, op
);
804 gen6_blorp_hiz_exec(brw
, mt
, level
, layer
, op
);