return false;
/* MCS is only supported for color buffers */
- switch (_mesa_get_format_base_format(mt->format)) {
- case GL_DEPTH_COMPONENT:
- case GL_DEPTH_STENCIL:
- case GL_STENCIL_INDEX:
+ if (!_mesa_is_format_color_format(mt->format))
return false;
- }
if (mt->cpp != 4 && mt->cpp != 8 && mt->cpp != 16)
return false;
if (devinfo->gen < 8 && (mip_mapped || arrayed))
return false;
+ /* The PRM doesn't say this explicitly, but fast-clears don't appear to
+ * work for 3D textures until gen9 where the layout of 3D textures changes
+ * to match 2D array textures.
+ */
+ if (devinfo->gen <= 8 && mt->surf.dim != ISL_SURF_DIM_2D)
+ return false;
+
/* There's no point in using an MCS buffer if the surface isn't in a
* renderable format.
*/
if (!bo) {
mt->bo = brw_bo_alloc_tiled(brw->bufmgr, "isl-miptree",
mt->surf.size,
+ BRW_MEMZONE_OTHER,
isl_tiling_to_i915_tiling(
mt->surf.tiling),
mt->surf.row_pitch, alloc_flags);
mt->aux_buf->clear_color_bo =
brw_bo_alloc_tiled(brw->bufmgr, "clear_color_bo",
brw->isl_dev.ss.clear_color_state_size,
- I915_TILING_NONE, 0, BO_ALLOC_ZEROED);
+ BRW_MEMZONE_OTHER, I915_TILING_NONE, 0,
+ BO_ALLOC_ZEROED);
if (!mt->aux_buf->clear_color_bo) {
free(mt->aux_buf);
mt->aux_buf = NULL;
unsigned dst_level, unsigned dst_layer)
{
+ const struct gen_device_info *devinfo = &brw->screen->devinfo;
mesa_format format = src_mt->format;
unsigned width = minify(src_mt->surf.phys_level0_sa.width,
src_level - src_mt->first_level);
assert(_mesa_get_srgb_format_linear(src_mt->format) ==
_mesa_get_srgb_format_linear(dst_mt->format));
+ DBG("validate blit mt %s %p %d,%d -> mt %s %p %d,%d (%dx%d)\n",
+ _mesa_get_format_name(src_mt->format),
+ src_mt, src_level, src_layer,
+ _mesa_get_format_name(dst_mt->format),
+ dst_mt, dst_level, dst_layer,
+ width, height);
+
+ if (devinfo->gen >= 6) {
+ /* On gen6 and above, we just use blorp. It's faster than the blitter
+ * and can handle everything without software fallbacks.
+ */
+ brw_blorp_copy_miptrees(brw,
+ src_mt, src_level, src_layer,
+ dst_mt, dst_level, dst_layer,
+ 0, 0, 0, 0, width, height);
+
+ if (src_mt->stencil_mt) {
+ assert(dst_mt->stencil_mt);
+ brw_blorp_copy_miptrees(brw,
+ src_mt->stencil_mt, src_level, src_layer,
+ dst_mt->stencil_mt, dst_level, dst_layer,
+ 0, 0, 0, 0, width, height);
+ }
+ return;
+ }
+
if (dst_mt->compressed) {
unsigned int i, j;
_mesa_get_format_block_size(dst_mt->format, &i, &j);
width = ALIGN_NPOT(width, i) / i;
}
- /* If it's a packed depth/stencil buffer with separate stencil, the blit
- * below won't apply since we can't do the depth's Y tiling or the
- * stencil's W tiling in the blitter.
- */
- if (src_mt->stencil_mt) {
- intel_miptree_copy_slice_sw(brw,
- src_mt, src_level, src_layer,
- dst_mt, dst_level, dst_layer,
- width, height);
- return;
- }
+ /* Gen4-5 doesn't support separate stencil */
+ assert(!src_mt->stencil_mt);
uint32_t dst_x, dst_y, src_x, src_y;
intel_miptree_get_image_offset(dst_mt, dst_level, dst_layer,
* trying to recalculate based on different format block sizes.
*/
buf->bo = brw_bo_alloc_tiled(brw->bufmgr, "aux-miptree", size,
- I915_TILING_Y, aux_surf->row_pitch,
- alloc_flags);
+ BRW_MEMZONE_OTHER, I915_TILING_Y,
+ aux_surf->row_pitch, alloc_flags);
if (!buf->bo) {
free(buf);
return NULL;
enum isl_aux_state initial_state;
uint8_t memset_value;
struct isl_surf aux_surf;
- bool aux_surf_ok;
+ MAYBE_UNUSED bool aux_surf_ok;
switch (mt->aux_usage) {
case ISL_AUX_USAGE_NONE:
aux_surf_ok = true;
break;
case ISL_AUX_USAGE_HIZ:
- assert(!_mesa_is_format_color_format(mt->format));
-
initial_state = ISL_AUX_STATE_AUX_INVALID;
aux_surf_ok = isl_surf_get_hiz_surf(&brw->isl_dev, &mt->surf, &aux_surf);
- assert(aux_surf_ok);
break;
case ISL_AUX_USAGE_MCS:
- assert(_mesa_is_format_color_format(mt->format));
- assert(brw->screen->devinfo.gen >= 7); /* MCS only used on Gen7+ */
-
/* From the Ivy Bridge PRM, Vol 2 Part 1 p326:
*
* When MCS buffer is enabled and bound to MSRT, it is required that
initial_state = ISL_AUX_STATE_CLEAR;
memset_value = 0xFF;
aux_surf_ok = isl_surf_get_mcs_surf(&brw->isl_dev, &mt->surf, &aux_surf);
- assert(aux_surf_ok);
break;
case ISL_AUX_USAGE_CCS_D:
case ISL_AUX_USAGE_CCS_E:
- assert(_mesa_is_format_color_format(mt->format));
-
/* When CCS_E is used, we need to ensure that the CCS starts off in a
* valid state. From the Sky Lake PRM, "MCS Buffer for Render
* Target(s)":
break;
}
- /* Ensure we have a valid aux_surf. */
- if (aux_surf_ok == false)
- return false;
+ /* We should have a valid aux_surf. */
+ assert(aux_surf_ok);
/* No work is needed for a zero-sized auxiliary buffer. */
if (aux_surf.size == 0)
{
if (memcmp(&mt->fast_clear_color, &clear_color, sizeof(clear_color)) != 0) {
mt->fast_clear_color = clear_color;
- brw->ctx.NewDriverState |= BRW_NEW_AUX_STATE;
- return true;
- }
- return false;
-}
-
-bool
-intel_miptree_set_depth_clear_value(struct brw_context *brw,
- struct intel_mipmap_tree *mt,
- float clear_value)
-{
- if (mt->fast_clear_color.f32[0] != clear_value) {
- mt->fast_clear_color.f32[0] = clear_value;
+ if (mt->aux_buf->clear_color_bo) {
+ /* We can't update the clear color while the hardware is still using
+ * the previous one for a resolve or sampling from it. Make sure that
+ * there are no pending commands at this point.
+ */
+ brw_emit_pipe_control_flush(brw, PIPE_CONTROL_CS_STALL);
+ for (int i = 0; i < 4; i++) {
+ brw_store_data_imm32(brw, mt->aux_buf->clear_color_bo,
+ mt->aux_buf->clear_color_offset + i * 4,
+ mt->fast_clear_color.u32[i]);
+ }
+ brw_emit_pipe_control_flush(brw, PIPE_CONTROL_STATE_CACHE_INVALIDATE);
+ }
brw->ctx.NewDriverState |= BRW_NEW_AUX_STATE;
return true;
}