[Mesa-dev] [PATCH 32/32] i965: Enable regular fast-clears (CCS_D) on gen9+
Jason Ekstrand
jason at jlekstrand.net
Wed Jul 19 21:01:58 UTC 2017
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.
---
src/mesa/drivers/dri/i965/brw_blorp.c | 10 ++--
src/mesa/drivers/dri/i965/brw_draw.c | 6 ++-
src/mesa/drivers/dri/i965/brw_meta_util.c | 11 ----
src/mesa/drivers/dri/i965/brw_wm_surface_state.c | 5 +-
src/mesa/drivers/dri/i965/intel_mipmap_tree.c | 66 +++++++++++-------------
src/mesa/drivers/dri/i965/intel_mipmap_tree.h | 6 +--
6 files changed, 45 insertions(+), 59 deletions(-)
diff --git a/src/mesa/drivers/dri/i965/brw_blorp.c b/src/mesa/drivers/dri/i965/brw_blorp.c
index 43745d2..b799972 100644
--- a/src/mesa/drivers/dri/i965/brw_blorp.c
+++ b/src/mesa/drivers/dri/i965/brw_blorp.c
@@ -324,7 +324,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);
@@ -885,9 +885,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;
@@ -907,8 +907,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 01b618c..8e0a4ae 100644
--- a/src/mesa/drivers/dri/i965/brw_draw.c
+++ b/src/mesa/drivers/dri/i965/brw_draw.c
@@ -474,7 +474,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));
}
}
@@ -542,7 +543,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 f9fd350..7ce1fd1 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->num_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 2fefba5..0d32945 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
@@ -200,7 +200,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;
@@ -208,7 +208,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 ebc414c..1cba7e7 100644
--- a/src/mesa/drivers/dri/i965/intel_mipmap_tree.c
+++ b/src/mesa/drivers/dri/i965/intel_mipmap_tree.c
@@ -242,13 +242,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
@@ -299,12 +293,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);
}
/**
@@ -2839,7 +2834,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:
@@ -2847,29 +2842,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:
@@ -2881,10 +2875,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);
}
@@ -2893,12 +2887,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 df413b1..48d488e 100644
--- a/src/mesa/drivers/dri/i965/intel_mipmap_tree.h
+++ b/src/mesa/drivers/dri/i965/intel_mipmap_tree.h
@@ -943,17 +943,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,
--
2.5.0.400.gff86faf
More information about the mesa-dev
mailing list