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 <topi.pohjolainen@intel.com>
This commit is contained in:
parent
d4de403f91
commit
3e57e9494c
|
@ -317,7 +317,7 @@ brw_blorp_blit_miptrees(struct brw_context *brw,
|
||||||
src_aux_usage, src_clear_supported);
|
src_aux_usage, src_clear_supported);
|
||||||
|
|
||||||
enum isl_aux_usage dst_aux_usage =
|
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;
|
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,
|
intel_miptree_prepare_access(brw, dst_mt, dst_level, 1, dst_layer, 1,
|
||||||
dst_aux_usage, dst_clear_supported);
|
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);
|
irb->mt, irb->mt_level, irb->mt_layer, num_layers);
|
||||||
|
|
||||||
enum isl_aux_usage aux_usage =
|
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,
|
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 isl_surf isl_tmp[2];
|
||||||
struct blorp_surf surf;
|
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);
|
clear_color, color_write_disable);
|
||||||
blorp_batch_finish(&batch);
|
blorp_batch_finish(&batch);
|
||||||
|
|
||||||
intel_miptree_finish_render(brw, irb->mt, level,
|
intel_miptree_finish_render(brw, irb->mt, level, irb->mt_layer,
|
||||||
irb->mt_layer, num_layers, encode_srgb);
|
num_layers, encode_srgb, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -473,7 +473,8 @@ brw_predraw_resolve_framebuffer(struct brw_context *brw)
|
||||||
|
|
||||||
intel_miptree_prepare_render(brw, irb->mt, irb->mt_level,
|
intel_miptree_prepare_render(brw, irb->mt, irb->mt_level,
|
||||||
irb->mt_layer, irb->layer_count,
|
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);
|
brw_render_cache_set_add_bo(brw, irb->mt->bo);
|
||||||
intel_miptree_finish_render(brw, irb->mt, irb->mt_level,
|
intel_miptree_finish_render(brw, irb->mt, irb->mt_level,
|
||||||
irb->mt_layer, irb->layer_count,
|
irb->mt_layer, irb->layer_count,
|
||||||
ctx->Color.sRGBEnabled);
|
ctx->Color.sRGBEnabled,
|
||||||
|
ctx->Color.BlendEnabled & (1 << i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -292,17 +292,6 @@ brw_is_color_fast_clear_compatible(struct brw_context *brw,
|
||||||
brw->mesa_to_isl_render_format[mt->format])
|
brw->mesa_to_isl_render_format[mt->format])
|
||||||
return false;
|
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);
|
const mesa_format format = _mesa_get_render_format(ctx, mt->format);
|
||||||
if (_mesa_is_format_integer_color(format)) {
|
if (_mesa_is_format_integer_color(format)) {
|
||||||
if (brw->gen >= 8) {
|
if (brw->gen >= 8) {
|
||||||
|
|
|
@ -208,7 +208,7 @@ brw_emit_surface_state(struct brw_context *brw,
|
||||||
uint32_t
|
uint32_t
|
||||||
brw_update_renderbuffer_surface(struct brw_context *brw,
|
brw_update_renderbuffer_surface(struct brw_context *brw,
|
||||||
struct gl_renderbuffer *rb,
|
struct gl_renderbuffer *rb,
|
||||||
uint32_t flags, unsigned unit /* unused */,
|
uint32_t flags, unsigned unit,
|
||||||
uint32_t surf_index)
|
uint32_t surf_index)
|
||||||
{
|
{
|
||||||
struct gl_context *ctx = &brw->ctx;
|
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;
|
struct intel_mipmap_tree *mt = irb->mt;
|
||||||
|
|
||||||
enum isl_aux_usage aux_usage =
|
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) {
|
if (flags & INTEL_AUX_BUFFER_DISABLED) {
|
||||||
assert(brw->gen >= 9);
|
assert(brw->gen >= 9);
|
||||||
|
|
|
@ -201,13 +201,7 @@ intel_miptree_supports_ccs(struct brw_context *brw,
|
||||||
if (!brw->mesa_format_supports_render[mt->format])
|
if (!brw->mesa_format_supports_render[mt->format])
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (brw->gen >= 9) {
|
return true;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
|
@ -259,12 +253,13 @@ intel_miptree_supports_ccs_e(struct brw_context *brw,
|
||||||
if (!intel_miptree_supports_ccs(brw, mt))
|
if (!intel_miptree_supports_ccs(brw, mt))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/* Fast clear can be also used to clear srgb surfaces by using equivalent
|
/* Many window system buffers are sRGB even if they are never rendered as
|
||||||
* linear format. This trick, however, can't be extended to be used with
|
* sRGB. For those, we want CCS_E for when sRGBEncode is false. When the
|
||||||
* lossless compression and therefore a check is needed to see if the format
|
* surface is used as sRGB, we fall back to CCS_D.
|
||||||
* really is linear.
|
|
||||||
*/
|
*/
|
||||||
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
|
enum isl_aux_usage
|
||||||
intel_miptree_render_aux_usage(struct brw_context *brw,
|
intel_miptree_render_aux_usage(struct brw_context *brw,
|
||||||
struct intel_mipmap_tree *mt,
|
struct intel_mipmap_tree *mt,
|
||||||
bool srgb_enabled)
|
bool srgb_enabled, bool blend_enabled)
|
||||||
{
|
{
|
||||||
switch (mt->aux_usage) {
|
switch (mt->aux_usage) {
|
||||||
case ISL_AUX_USAGE_MCS:
|
case ISL_AUX_USAGE_MCS:
|
||||||
|
@ -2592,29 +2587,28 @@ intel_miptree_render_aux_usage(struct brw_context *brw,
|
||||||
return ISL_AUX_USAGE_MCS;
|
return ISL_AUX_USAGE_MCS;
|
||||||
|
|
||||||
case ISL_AUX_USAGE_CCS_D:
|
case ISL_AUX_USAGE_CCS_D:
|
||||||
/* If FRAMEBUFFER_SRGB is used on Gen9+ then we need to resolve any of
|
return mt->mcs_buf ? ISL_AUX_USAGE_CCS_D : ISL_AUX_USAGE_NONE;
|
||||||
* 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
case ISL_AUX_USAGE_CCS_E: {
|
case ISL_AUX_USAGE_CCS_E: {
|
||||||
/* Lossless compression is not supported for SRGB formats, it
|
mesa_format mesa_format =
|
||||||
* should be impossible to get here with such surfaces.
|
srgb_enabled ? mt->format :_mesa_get_srgb_format_linear(mt->format);
|
||||||
*/
|
enum isl_format isl_format = brw_isl_format_for_mesa_format(mesa_format);
|
||||||
assert(!srgb_enabled ||
|
|
||||||
_mesa_get_srgb_format_linear(mt->format) == mt->format);
|
|
||||||
|
|
||||||
return ISL_AUX_USAGE_CCS_E;
|
/* 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.
|
||||||
|
*/
|
||||||
|
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_D;
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -2626,10 +2620,10 @@ void
|
||||||
intel_miptree_prepare_render(struct brw_context *brw,
|
intel_miptree_prepare_render(struct brw_context *brw,
|
||||||
struct intel_mipmap_tree *mt, uint32_t level,
|
struct intel_mipmap_tree *mt, uint32_t level,
|
||||||
uint32_t start_layer, uint32_t layer_count,
|
uint32_t start_layer, uint32_t layer_count,
|
||||||
bool srgb_enabled)
|
bool srgb_enabled, bool blend_enabled)
|
||||||
{
|
{
|
||||||
enum isl_aux_usage aux_usage =
|
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,
|
intel_miptree_prepare_access(brw, mt, level, 1, start_layer, layer_count,
|
||||||
aux_usage, aux_usage != ISL_AUX_USAGE_NONE);
|
aux_usage, aux_usage != ISL_AUX_USAGE_NONE);
|
||||||
}
|
}
|
||||||
|
@ -2638,12 +2632,12 @@ void
|
||||||
intel_miptree_finish_render(struct brw_context *brw,
|
intel_miptree_finish_render(struct brw_context *brw,
|
||||||
struct intel_mipmap_tree *mt, uint32_t level,
|
struct intel_mipmap_tree *mt, uint32_t level,
|
||||||
uint32_t start_layer, uint32_t layer_count,
|
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));
|
assert(_mesa_is_format_color_format(mt->format));
|
||||||
|
|
||||||
enum isl_aux_usage aux_usage =
|
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,
|
intel_miptree_finish_write(brw, mt, level, start_layer, layer_count,
|
||||||
aux_usage);
|
aux_usage);
|
||||||
}
|
}
|
||||||
|
|
|
@ -630,17 +630,17 @@ intel_miptree_prepare_fb_fetch(struct brw_context *brw,
|
||||||
enum isl_aux_usage
|
enum isl_aux_usage
|
||||||
intel_miptree_render_aux_usage(struct brw_context *brw,
|
intel_miptree_render_aux_usage(struct brw_context *brw,
|
||||||
struct intel_mipmap_tree *mt,
|
struct intel_mipmap_tree *mt,
|
||||||
bool srgb_enabled);
|
bool srgb_enabled, bool blend_enabled);
|
||||||
void
|
void
|
||||||
intel_miptree_prepare_render(struct brw_context *brw,
|
intel_miptree_prepare_render(struct brw_context *brw,
|
||||||
struct intel_mipmap_tree *mt, uint32_t level,
|
struct intel_mipmap_tree *mt, uint32_t level,
|
||||||
uint32_t start_layer, uint32_t layer_count,
|
uint32_t start_layer, uint32_t layer_count,
|
||||||
bool srgb_enabled);
|
bool srgb_enabled, bool blend_enabled);
|
||||||
void
|
void
|
||||||
intel_miptree_finish_render(struct brw_context *brw,
|
intel_miptree_finish_render(struct brw_context *brw,
|
||||||
struct intel_mipmap_tree *mt, uint32_t level,
|
struct intel_mipmap_tree *mt, uint32_t level,
|
||||||
uint32_t start_layer, uint32_t layer_count,
|
uint32_t start_layer, uint32_t layer_count,
|
||||||
bool srgb_enabled);
|
bool srgb_enabled, bool blend_enabled);
|
||||||
void
|
void
|
||||||
intel_miptree_prepare_depth(struct brw_context *brw,
|
intel_miptree_prepare_depth(struct brw_context *brw,
|
||||||
struct intel_mipmap_tree *mt, uint32_t level,
|
struct intel_mipmap_tree *mt, uint32_t level,
|
||||||
|
|
Loading…
Reference in New Issue