iris: Disable sRGB fast-clears for non-0/1 values

For texturing and draw calls, HW expects the clear color to be in two
different color spaces after sRGB fast-clears - sRGB in the former and
linear in the latter. Up until now, iris has stored the clear color in
the sRGB color space. Limit the allowable clear colors for sRGB
fast-clears to 0/1 so that both color space requirements are satisfied.

Makes iris pass the sRGB -> sRGB subtest of the fcc-write-after-clear
piglit test on gen9+.

v2:
* Drop iris_context::blend_enables. (Ken)
* Drop some more resolve-related blend-state-tracking code.

Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4972>
This commit is contained in:
Nanley Chery 2020-05-14 08:48:30 -07:00 committed by Marge Bot
parent 48a3f4c44b
commit f8961ea086
6 changed files with 20 additions and 41 deletions

View file

@ -328,8 +328,7 @@ iris_resource_blorp_write_aux_usage(struct iris_context *ice,
assert(render_format == res->surf.format);
return res->aux.usage;
} else {
return iris_resource_render_aux_usage(ice, res, render_format,
false, false);
return iris_resource_render_aux_usage(ice, res, render_format, false);
}
}

View file

@ -34,7 +34,6 @@
#include "iris_resource.h"
#include "iris_screen.h"
#include "intel/compiler/brw_compiler.h"
#include "util/format_srgb.h"
static bool
iris_is_color_fast_clear_compatible(struct iris_context *ice,
@ -87,6 +86,17 @@ can_fast_clear_color(struct iris_context *ice,
return false;
}
/* Disable sRGB fast-clears for non-0/1 color values. For texturing and
* draw calls, HW expects the clear color to be in two different color
* spaces after sRGB fast-clears - sRGB in the former and linear in the
* latter. By limiting the allowable values to 0/1, both color space
* requirements are satisfied.
*/
if (isl_format_is_srgb(render_format) &&
!isl_color_value_is_zero_one(color, render_format)) {
return false;
}
/* We store clear colors as floats or uints as needed. If there are
* texture views in play, the formats will not properly be respected
* during resolves because the resolve operations only know about the
@ -110,7 +120,6 @@ can_fast_clear_color(struct iris_context *ice,
static union isl_color_value
convert_fast_clear_color(struct iris_context *ice,
struct iris_resource *res,
enum isl_format render_format,
const union isl_color_value color)
{
union isl_color_value override_color = color;
@ -174,14 +183,6 @@ convert_fast_clear_color(struct iris_context *ice,
override_color.f32[3] = 1.0f;
}
/* Handle linear to SRGB conversion */
if (isl_format_is_srgb(render_format)) {
for (int i = 0; i < 3; i++) {
override_color.f32[i] =
util_format_linear_to_srgb_float(override_color.f32[i]);
}
}
return override_color;
}
@ -199,7 +200,7 @@ fast_clear_color(struct iris_context *ice,
const enum isl_aux_state aux_state =
iris_resource_get_aux_state(res, level, box->z);
color = convert_fast_clear_color(ice, res, format, color);
color = convert_fast_clear_color(ice, res, color);
bool color_changed = !!memcmp(&res->aux.clear_color, &color,
sizeof(color));
@ -309,11 +310,10 @@ fast_clear_color(struct iris_context *ice,
iris_blorp_surf_for_resource(&batch->screen->isl_dev, &surf,
p_res, res->aux.usage, level, true);
/* In newer gens (> 9), the hardware will do a linear -> sRGB conversion of
* the clear color during the fast clear, if the surface format is of sRGB
* type. We use the linear version of the surface format here to prevent
* that from happening, since we already do our own linear -> sRGB
* conversion in convert_fast_clear_color().
/* Use the linear version of the format to avoid using an invalid surface
* state on gen9. ISL_AUX_USAGE_CCS_E is not supported for sRGB formats on
* gen9 but iris may still assign that aux usage to resources with that
* format through the modifier interface.
*/
blorp_fast_clear(&blorp_batch, &surf, isl_format_srgb_to_linear(format),
ISL_SWIZZLE_IDENTITY,
@ -372,8 +372,7 @@ clear_color(struct iris_context *ice,
bool color_write_disable[4] = { false, false, false, false };
enum isl_aux_usage aux_usage =
iris_resource_render_aux_usage(ice, res, format,
false, false);
iris_resource_render_aux_usage(ice, res, format, false);
iris_resource_prepare_render(ice, batch, res, level,
box->z, box->depth, aux_usage);

View file

@ -670,9 +670,6 @@ struct iris_context {
enum gen_urb_deref_block_size urb_deref_block_size;
/** Bitfield of whether color blending is enabled for RT[i] */
uint8_t blend_enables;
/** Are depth writes enabled? (Depth buffer may or may not exist.) */
bool depth_writes_enabled;

View file

@ -229,8 +229,7 @@ iris_predraw_resolve_framebuffer(struct iris_context *ice,
}
}
if ((ice->state.dirty & IRIS_DIRTY_BLEND_STATE) ||
(ice->state.stage_dirty & IRIS_STAGE_DIRTY_BINDINGS_FS)) {
if (ice->state.stage_dirty & IRIS_STAGE_DIRTY_BINDINGS_FS) {
for (unsigned i = 0; i < cso_fb->nr_cbufs; i++) {
struct iris_surface *surf = (void *) cso_fb->cbufs[i];
if (!surf)
@ -240,7 +239,6 @@ iris_predraw_resolve_framebuffer(struct iris_context *ice,
enum isl_aux_usage aux_usage =
iris_resource_render_aux_usage(ice, res, surf->view.format,
ice->state.blend_enables & (1u << i),
draw_aux_buffer_disabled[i]);
if (ice->state.draw_aux_usage[i] != aux_usage) {
@ -310,8 +308,7 @@ iris_postdraw_update_resolve_tracking(struct iris_context *ice,
}
bool may_have_resolved_color =
(ice->state.dirty & IRIS_DIRTY_BLEND_STATE) ||
(ice->state.stage_dirty & IRIS_STAGE_DIRTY_BINDINGS_FS);
ice->state.stage_dirty & IRIS_STAGE_DIRTY_BINDINGS_FS;
for (unsigned i = 0; i < cso_fb->nr_cbufs; i++) {
struct iris_surface *surf = (void *) cso_fb->cbufs[i];
@ -1009,7 +1006,6 @@ enum isl_aux_usage
iris_resource_render_aux_usage(struct iris_context *ice,
struct iris_resource *res,
enum isl_format render_format,
bool blend_enabled,
bool draw_aux_disabled)
{
struct iris_screen *screen = (void *) ice->ctx.screen;
@ -1025,15 +1021,6 @@ iris_resource_render_aux_usage(struct iris_context *ice,
case ISL_AUX_USAGE_CCS_D:
case ISL_AUX_USAGE_CCS_E:
/* 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 (devinfo->gen >= 9 && blend_enabled &&
isl_format_is_srgb(render_format) &&
!isl_color_value_is_zero_one(res->aux.clear_color, render_format))
return ISL_AUX_USAGE_NONE;
/* Disable CCS for some cases of texture-view rendering. On gen12, HW
* may convert some subregions of shader output to fast-cleared blocks
* if CCS is enabled and the shader output matches the clear color.

View file

@ -500,7 +500,6 @@ bool iris_render_formats_color_compatible(enum isl_format a,
enum isl_aux_usage iris_resource_render_aux_usage(struct iris_context *ice,
struct iris_resource *res,
enum isl_format render_fmt,
bool blend_enabled,
bool draw_aux_disabled);
void iris_resource_prepare_render(struct iris_context *ice,
struct iris_batch *batch,

View file

@ -1280,11 +1280,9 @@ iris_bind_blend_state(struct pipe_context *ctx, void *state)
struct iris_blend_state *cso = state;
ice->state.cso_blend = cso;
ice->state.blend_enables = cso ? cso->blend_enables : 0;
ice->state.dirty |= IRIS_DIRTY_PS_BLEND;
ice->state.dirty |= IRIS_DIRTY_BLEND_STATE;
ice->state.dirty |= IRIS_DIRTY_RENDER_RESOLVES_AND_FLUSHES;
ice->state.stage_dirty |= ice->state.stage_dirty_for_nos[IRIS_NOS_BLEND];
if (GEN_GEN == 8)