From f8961ea08654ed762608535f331e169f7afde182 Mon Sep 17 00:00:00 2001 From: Nanley Chery Date: Thu, 14 May 2020 08:48:30 -0700 Subject: [PATCH] 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 Part-of: --- src/gallium/drivers/iris/iris_blit.c | 3 +- src/gallium/drivers/iris/iris_clear.c | 35 ++++++++++++------------ src/gallium/drivers/iris/iris_context.h | 3 -- src/gallium/drivers/iris/iris_resolve.c | 17 ++---------- src/gallium/drivers/iris/iris_resource.h | 1 - src/gallium/drivers/iris/iris_state.c | 2 -- 6 files changed, 20 insertions(+), 41 deletions(-) diff --git a/src/gallium/drivers/iris/iris_blit.c b/src/gallium/drivers/iris/iris_blit.c index 40e1dcac9e7..15bbea616bf 100644 --- a/src/gallium/drivers/iris/iris_blit.c +++ b/src/gallium/drivers/iris/iris_blit.c @@ -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); } } diff --git a/src/gallium/drivers/iris/iris_clear.c b/src/gallium/drivers/iris/iris_clear.c index a1e2218674a..f11dabc575f 100644 --- a/src/gallium/drivers/iris/iris_clear.c +++ b/src/gallium/drivers/iris/iris_clear.c @@ -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); diff --git a/src/gallium/drivers/iris/iris_context.h b/src/gallium/drivers/iris/iris_context.h index 94a7a916727..730df63b958 100644 --- a/src/gallium/drivers/iris/iris_context.h +++ b/src/gallium/drivers/iris/iris_context.h @@ -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; diff --git a/src/gallium/drivers/iris/iris_resolve.c b/src/gallium/drivers/iris/iris_resolve.c index 937dee11553..a02dd7bfd9e 100644 --- a/src/gallium/drivers/iris/iris_resolve.c +++ b/src/gallium/drivers/iris/iris_resolve.c @@ -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. diff --git a/src/gallium/drivers/iris/iris_resource.h b/src/gallium/drivers/iris/iris_resource.h index 3323b132dae..2d062ec3af4 100644 --- a/src/gallium/drivers/iris/iris_resource.h +++ b/src/gallium/drivers/iris/iris_resource.h @@ -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, diff --git a/src/gallium/drivers/iris/iris_state.c b/src/gallium/drivers/iris/iris_state.c index 9d824507ad8..4ef149f7060 100644 --- a/src/gallium/drivers/iris/iris_state.c +++ b/src/gallium/drivers/iris/iris_state.c @@ -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) -- 2.30.2