From: Jason Ekstrand Date: Thu, 22 Jun 2017 04:35:07 +0000 (-0700) Subject: i965: Enable regular fast-clears (CCS_D) on gen9+ X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=3e57e9494c227;p=mesa.git i965: Enable regular fast-clears (CCS_D) on gen9+ The set of formats which supports CCS_E is actually fairly small on gen9. However, everything that supports fast-clears on gen8 also supports fast-clears on gen9+. The one very annoying exception is that blending is broken for non-0/1 clear colors with sRGB formats. In order to solve that problem, we do a resolve to get rid of the clear color. Another option would be to just not fast-clear with non-0/1 clear colors however non-0/1 + blending + sRGB is uncommon enough that this shouldn't be a significant performance problem. This appears to help gl_manhattan31_off by about 2%. Reviewed-by: Topi Pohjolainen --- diff --git a/src/mesa/drivers/dri/i965/brw_blorp.c b/src/mesa/drivers/dri/i965/brw_blorp.c index 36962687c2e..36f7ed2a39d 100644 --- a/src/mesa/drivers/dri/i965/brw_blorp.c +++ b/src/mesa/drivers/dri/i965/brw_blorp.c @@ -317,7 +317,7 @@ brw_blorp_blit_miptrees(struct brw_context *brw, src_aux_usage, src_clear_supported); enum isl_aux_usage dst_aux_usage = - intel_miptree_render_aux_usage(brw, dst_mt, encode_srgb); + intel_miptree_render_aux_usage(brw, dst_mt, encode_srgb, false); const bool dst_clear_supported = dst_aux_usage != ISL_AUX_USAGE_NONE; intel_miptree_prepare_access(brw, dst_mt, dst_level, 1, dst_layer, 1, dst_aux_usage, dst_clear_supported); @@ -876,9 +876,9 @@ do_single_blorp_clear(struct brw_context *brw, struct gl_framebuffer *fb, irb->mt, irb->mt_level, irb->mt_layer, num_layers); enum isl_aux_usage aux_usage = - intel_miptree_render_aux_usage(brw, irb->mt, encode_srgb); + intel_miptree_render_aux_usage(brw, irb->mt, encode_srgb, false); intel_miptree_prepare_render(brw, irb->mt, level, irb->mt_layer, - num_layers, encode_srgb); + num_layers, encode_srgb, false); struct isl_surf isl_tmp[2]; struct blorp_surf surf; @@ -898,8 +898,8 @@ do_single_blorp_clear(struct brw_context *brw, struct gl_framebuffer *fb, clear_color, color_write_disable); blorp_batch_finish(&batch); - intel_miptree_finish_render(brw, irb->mt, level, - irb->mt_layer, num_layers, encode_srgb); + intel_miptree_finish_render(brw, irb->mt, level, irb->mt_layer, + num_layers, encode_srgb, false); } return; diff --git a/src/mesa/drivers/dri/i965/brw_draw.c b/src/mesa/drivers/dri/i965/brw_draw.c index 20ff99fff9d..d73a3dc827a 100644 --- a/src/mesa/drivers/dri/i965/brw_draw.c +++ b/src/mesa/drivers/dri/i965/brw_draw.c @@ -473,7 +473,8 @@ brw_predraw_resolve_framebuffer(struct brw_context *brw) intel_miptree_prepare_render(brw, irb->mt, irb->mt_level, irb->mt_layer, irb->layer_count, - ctx->Color.sRGBEnabled); + ctx->Color.sRGBEnabled, + ctx->Color.BlendEnabled & (1 << i)); } } @@ -541,7 +542,8 @@ brw_postdraw_set_buffers_need_resolve(struct brw_context *brw) brw_render_cache_set_add_bo(brw, irb->mt->bo); intel_miptree_finish_render(brw, irb->mt, irb->mt_level, irb->mt_layer, irb->layer_count, - ctx->Color.sRGBEnabled); + ctx->Color.sRGBEnabled, + ctx->Color.BlendEnabled & (1 << i)); } } diff --git a/src/mesa/drivers/dri/i965/brw_meta_util.c b/src/mesa/drivers/dri/i965/brw_meta_util.c index ea14f44790f..7ce1fd137f7 100644 --- a/src/mesa/drivers/dri/i965/brw_meta_util.c +++ b/src/mesa/drivers/dri/i965/brw_meta_util.c @@ -292,17 +292,6 @@ brw_is_color_fast_clear_compatible(struct brw_context *brw, brw->mesa_to_isl_render_format[mt->format]) return false; - /* Gen9 doesn't support fast clear on single-sampled SRGB buffers. When - * GL_FRAMEBUFFER_SRGB is enabled any color renderbuffers will be - * resolved in intel_update_state. In that case it's pointless to do a - * fast clear because it's very likely to be immediately resolved. - */ - if (brw->gen >= 9 && - mt->surf.samples == 1 && - ctx->Color.sRGBEnabled && - _mesa_get_srgb_format_linear(mt->format) != mt->format) - return false; - const mesa_format format = _mesa_get_render_format(ctx, mt->format); if (_mesa_is_format_integer_color(format)) { if (brw->gen >= 8) { diff --git a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c index 5121b98e1a8..250806d28e4 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c +++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c @@ -208,7 +208,7 @@ brw_emit_surface_state(struct brw_context *brw, uint32_t brw_update_renderbuffer_surface(struct brw_context *brw, struct gl_renderbuffer *rb, - uint32_t flags, unsigned unit /* unused */, + uint32_t flags, unsigned unit, uint32_t surf_index) { struct gl_context *ctx = &brw->ctx; @@ -216,7 +216,8 @@ brw_update_renderbuffer_surface(struct brw_context *brw, struct intel_mipmap_tree *mt = irb->mt; enum isl_aux_usage aux_usage = - intel_miptree_render_aux_usage(brw, mt, ctx->Color.sRGBEnabled); + intel_miptree_render_aux_usage(brw, mt, ctx->Color.sRGBEnabled, + ctx->Color.BlendEnabled & (1 << unit)); if (flags & INTEL_AUX_BUFFER_DISABLED) { assert(brw->gen >= 9); diff --git a/src/mesa/drivers/dri/i965/intel_mipmap_tree.c b/src/mesa/drivers/dri/i965/intel_mipmap_tree.c index 548a081fe22..ed7cb8e2152 100644 --- a/src/mesa/drivers/dri/i965/intel_mipmap_tree.c +++ b/src/mesa/drivers/dri/i965/intel_mipmap_tree.c @@ -201,13 +201,7 @@ intel_miptree_supports_ccs(struct brw_context *brw, if (!brw->mesa_format_supports_render[mt->format]) return false; - if (brw->gen >= 9) { - mesa_format linear_format = _mesa_get_srgb_format_linear(mt->format); - const enum isl_format isl_format = - brw_isl_format_for_mesa_format(linear_format); - return isl_format_supports_ccs_e(&brw->screen->devinfo, isl_format); - } else - return true; + return true; } static bool @@ -259,12 +253,13 @@ intel_miptree_supports_ccs_e(struct brw_context *brw, if (!intel_miptree_supports_ccs(brw, mt)) return false; - /* Fast clear can be also used to clear srgb surfaces by using equivalent - * linear format. This trick, however, can't be extended to be used with - * lossless compression and therefore a check is needed to see if the format - * really is linear. + /* Many window system buffers are sRGB even if they are never rendered as + * sRGB. For those, we want CCS_E for when sRGBEncode is false. When the + * surface is used as sRGB, we fall back to CCS_D. */ - return _mesa_get_srgb_format_linear(mt->format) == mt->format; + mesa_format linear_format = _mesa_get_srgb_format_linear(mt->format); + enum isl_format isl_format = brw_isl_format_for_mesa_format(linear_format); + return isl_format_supports_ccs_e(&brw->screen->devinfo, isl_format); } /** @@ -2584,7 +2579,7 @@ intel_miptree_prepare_fb_fetch(struct brw_context *brw, enum isl_aux_usage intel_miptree_render_aux_usage(struct brw_context *brw, struct intel_mipmap_tree *mt, - bool srgb_enabled) + bool srgb_enabled, bool blend_enabled) { switch (mt->aux_usage) { case ISL_AUX_USAGE_MCS: @@ -2592,29 +2587,28 @@ intel_miptree_render_aux_usage(struct brw_context *brw, return ISL_AUX_USAGE_MCS; case ISL_AUX_USAGE_CCS_D: - /* If FRAMEBUFFER_SRGB is used on Gen9+ then we need to resolve any of - * the single-sampled color renderbuffers because the CCS buffer isn't - * supported for SRGB formats. This only matters if FRAMEBUFFER_SRGB is - * enabled because otherwise the surface state will be programmed with - * the linear equivalent format anyway. - */ - if (srgb_enabled && - _mesa_get_srgb_format_linear(mt->format) != mt->format) { - return ISL_AUX_USAGE_NONE; - } else if (!mt->mcs_buf) { - return ISL_AUX_USAGE_NONE; - } else { - return ISL_AUX_USAGE_CCS_D; - } + return mt->mcs_buf ? ISL_AUX_USAGE_CCS_D : ISL_AUX_USAGE_NONE; case ISL_AUX_USAGE_CCS_E: { - /* Lossless compression is not supported for SRGB formats, it - * should be impossible to get here with such surfaces. + mesa_format mesa_format = + srgb_enabled ? mt->format :_mesa_get_srgb_format_linear(mt->format); + enum isl_format isl_format = brw_isl_format_for_mesa_format(mesa_format); + + /* If the format supports CCS_E, then we can just use it */ + if (isl_format_supports_ccs_e(&brw->screen->devinfo, isl_format)) + return ISL_AUX_USAGE_CCS_E; + + /* Otherwise, we have to fall back to CCS_D */ + + /* gen9 hardware technically supports non-0/1 clear colors with sRGB + * formats. However, there are issues with blending where it doesn't + * properly apply the sRGB curve to the clear color when blending. */ - assert(!srgb_enabled || - _mesa_get_srgb_format_linear(mt->format) == mt->format); + if (blend_enabled && isl_format_is_srgb(isl_format) && + !isl_color_value_is_zero_one(mt->fast_clear_color, isl_format)) + return ISL_AUX_USAGE_NONE; - return ISL_AUX_USAGE_CCS_E; + return ISL_AUX_USAGE_CCS_D; } default: @@ -2626,10 +2620,10 @@ void intel_miptree_prepare_render(struct brw_context *brw, struct intel_mipmap_tree *mt, uint32_t level, uint32_t start_layer, uint32_t layer_count, - bool srgb_enabled) + bool srgb_enabled, bool blend_enabled) { enum isl_aux_usage aux_usage = - intel_miptree_render_aux_usage(brw, mt, srgb_enabled); + intel_miptree_render_aux_usage(brw, mt, srgb_enabled, blend_enabled); intel_miptree_prepare_access(brw, mt, level, 1, start_layer, layer_count, aux_usage, aux_usage != ISL_AUX_USAGE_NONE); } @@ -2638,12 +2632,12 @@ void intel_miptree_finish_render(struct brw_context *brw, struct intel_mipmap_tree *mt, uint32_t level, uint32_t start_layer, uint32_t layer_count, - bool srgb_enabled) + bool srgb_enabled, bool blend_enabled) { assert(_mesa_is_format_color_format(mt->format)); enum isl_aux_usage aux_usage = - intel_miptree_render_aux_usage(brw, mt, srgb_enabled); + intel_miptree_render_aux_usage(brw, mt, srgb_enabled, blend_enabled); intel_miptree_finish_write(brw, mt, level, start_layer, layer_count, aux_usage); } diff --git a/src/mesa/drivers/dri/i965/intel_mipmap_tree.h b/src/mesa/drivers/dri/i965/intel_mipmap_tree.h index bc49b6bb071..3628345c4e9 100644 --- a/src/mesa/drivers/dri/i965/intel_mipmap_tree.h +++ b/src/mesa/drivers/dri/i965/intel_mipmap_tree.h @@ -630,17 +630,17 @@ intel_miptree_prepare_fb_fetch(struct brw_context *brw, enum isl_aux_usage intel_miptree_render_aux_usage(struct brw_context *brw, struct intel_mipmap_tree *mt, - bool srgb_enabled); + bool srgb_enabled, bool blend_enabled); void intel_miptree_prepare_render(struct brw_context *brw, struct intel_mipmap_tree *mt, uint32_t level, uint32_t start_layer, uint32_t layer_count, - bool srgb_enabled); + bool srgb_enabled, bool blend_enabled); void intel_miptree_finish_render(struct brw_context *brw, struct intel_mipmap_tree *mt, uint32_t level, uint32_t start_layer, uint32_t layer_count, - bool srgb_enabled); + bool srgb_enabled, bool blend_enabled); void intel_miptree_prepare_depth(struct brw_context *brw, struct intel_mipmap_tree *mt, uint32_t level,