From 54c41af0aa92333579a72830254ac3aaa9f4aea1 Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Wed, 16 Aug 2017 16:04:22 -0700 Subject: [PATCH] i965: Make a BRW_NEW_FAST_CLEAR_COLOR dirty bit. When changing fast clear colors, we need to emit new SURFACE_STATE with the updated color at the next draw call. Most things work today because the atoms that handle SURFACE_STATE for images (mutable images, textures, render targets) also listen to BRW_NEW_BLORP, causing us to re-emit these on every BLORP operation. However, this is overkill - most BLORP operations don't require us to re-emit SURFACE_STATE. One case where this is broken today is a fast clear to a different color followed by a non-coherent framebuffer fetch. The renderbuffer read atom doesn't listen to BRW_NEW_BLORP, and would not get the new fast clear color. Cc: mesa-stable@lists.freedesktop.org Reviewed-by: Jason Ekstrand --- src/mesa/drivers/dri/i965/brw_blorp.c | 13 ++++++++++--- src/mesa/drivers/dri/i965/brw_context.h | 2 ++ src/mesa/drivers/dri/i965/brw_gs_surface_state.c | 1 + src/mesa/drivers/dri/i965/brw_state_upload.c | 1 + src/mesa/drivers/dri/i965/brw_tcs_surface_state.c | 1 + src/mesa/drivers/dri/i965/brw_tes_surface_state.c | 1 + src/mesa/drivers/dri/i965/brw_vs_surface_state.c | 1 + src/mesa/drivers/dri/i965/brw_wm_surface_state.c | 10 ++++++++-- 8 files changed, 25 insertions(+), 5 deletions(-) diff --git a/src/mesa/drivers/dri/i965/brw_blorp.c b/src/mesa/drivers/dri/i965/brw_blorp.c index d8e48064e3a..3ea396d726e 100644 --- a/src/mesa/drivers/dri/i965/brw_blorp.c +++ b/src/mesa/drivers/dri/i965/brw_blorp.c @@ -819,16 +819,23 @@ do_single_blorp_clear(struct brw_context *brw, struct gl_framebuffer *fb, brw_meta_convert_fast_clear_color(brw, irb->mt, &ctx->Color.ClearColor); + bool same_clear_color = memcmp(&irb->mt->fast_clear_color, + &clear_color, sizeof(clear_color)) == 0; + /* If the buffer is already in INTEL_FAST_CLEAR_STATE_CLEAR, the clear * is redundant and can be skipped. */ - if (aux_state == ISL_AUX_STATE_CLEAR && - memcmp(&irb->mt->fast_clear_color, - &clear_color, sizeof(clear_color)) == 0) + if (aux_state == ISL_AUX_STATE_CLEAR && same_clear_color) return; irb->mt->fast_clear_color = clear_color; + /* If the clear color has changed, we need to emit a new SURFACE_STATE + * on the next draw call. + */ + if (!same_clear_color) + ctx->NewDriverState |= BRW_NEW_FAST_CLEAR_COLOR; + DBG("%s (fast) to mt %p level %d layers %d+%d\n", __FUNCTION__, irb->mt, irb->mt_level, irb->mt_layer, num_layers); diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h index a227a61f654..932240bfc50 100644 --- a/src/mesa/drivers/dri/i965/brw_context.h +++ b/src/mesa/drivers/dri/i965/brw_context.h @@ -215,6 +215,7 @@ enum brw_state_id { BRW_STATE_VIEWPORT_COUNT, BRW_STATE_CONSERVATIVE_RASTERIZATION, BRW_STATE_DRAW_CALL, + BRW_STATE_FAST_CLEAR_COLOR, BRW_NUM_STATE_BITS }; @@ -306,6 +307,7 @@ enum brw_state_id { #define BRW_NEW_BLORP (1ull << BRW_STATE_BLORP) #define BRW_NEW_CONSERVATIVE_RASTERIZATION (1ull << BRW_STATE_CONSERVATIVE_RASTERIZATION) #define BRW_NEW_DRAW_CALL (1ull << BRW_STATE_DRAW_CALL) +#define BRW_NEW_FAST_CLEAR_COLOR (1ull << BRW_STATE_FAST_CLEAR_COLOR) struct brw_state_flags { /** State update flags signalled by mesa internals */ diff --git a/src/mesa/drivers/dri/i965/brw_gs_surface_state.c b/src/mesa/drivers/dri/i965/brw_gs_surface_state.c index d5a106d6bec..bcf39a88522 100644 --- a/src/mesa/drivers/dri/i965/brw_gs_surface_state.c +++ b/src/mesa/drivers/dri/i965/brw_gs_surface_state.c @@ -133,6 +133,7 @@ const struct brw_tracked_state brw_gs_image_surfaces = { .mesa = _NEW_TEXTURE, .brw = BRW_NEW_BATCH | BRW_NEW_BLORP | + BRW_NEW_FAST_CLEAR_COLOR | BRW_NEW_GEOMETRY_PROGRAM | BRW_NEW_GS_PROG_DATA | BRW_NEW_IMAGE_UNITS, diff --git a/src/mesa/drivers/dri/i965/brw_state_upload.c b/src/mesa/drivers/dri/i965/brw_state_upload.c index 1ae45ba2ac1..9add4515b92 100644 --- a/src/mesa/drivers/dri/i965/brw_state_upload.c +++ b/src/mesa/drivers/dri/i965/brw_state_upload.c @@ -350,6 +350,7 @@ static struct dirty_bit_map brw_bits[] = { DEFINE_BIT(BRW_NEW_VIEWPORT_COUNT), DEFINE_BIT(BRW_NEW_CONSERVATIVE_RASTERIZATION), DEFINE_BIT(BRW_NEW_DRAW_CALL), + DEFINE_BIT(BRW_NEW_FAST_CLEAR_COLOR), {0, 0, 0} }; diff --git a/src/mesa/drivers/dri/i965/brw_tcs_surface_state.c b/src/mesa/drivers/dri/i965/brw_tcs_surface_state.c index 5c500d0f8d3..02f3f0e0356 100644 --- a/src/mesa/drivers/dri/i965/brw_tcs_surface_state.c +++ b/src/mesa/drivers/dri/i965/brw_tcs_surface_state.c @@ -133,6 +133,7 @@ const struct brw_tracked_state brw_tcs_image_surfaces = { .dirty = { .brw = BRW_NEW_BATCH | BRW_NEW_BLORP | + BRW_NEW_FAST_CLEAR_COLOR | BRW_NEW_IMAGE_UNITS | BRW_NEW_TCS_PROG_DATA | BRW_NEW_TESS_PROGRAMS, diff --git a/src/mesa/drivers/dri/i965/brw_tes_surface_state.c b/src/mesa/drivers/dri/i965/brw_tes_surface_state.c index 1982955be8f..2750487b811 100644 --- a/src/mesa/drivers/dri/i965/brw_tes_surface_state.c +++ b/src/mesa/drivers/dri/i965/brw_tes_surface_state.c @@ -133,6 +133,7 @@ const struct brw_tracked_state brw_tes_image_surfaces = { .dirty = { .brw = BRW_NEW_BATCH | BRW_NEW_BLORP | + BRW_NEW_FAST_CLEAR_COLOR | BRW_NEW_IMAGE_UNITS | BRW_NEW_TESS_PROGRAMS | BRW_NEW_TES_PROG_DATA, diff --git a/src/mesa/drivers/dri/i965/brw_vs_surface_state.c b/src/mesa/drivers/dri/i965/brw_vs_surface_state.c index 016da7456af..9c2184cc485 100644 --- a/src/mesa/drivers/dri/i965/brw_vs_surface_state.c +++ b/src/mesa/drivers/dri/i965/brw_vs_surface_state.c @@ -198,6 +198,7 @@ const struct brw_tracked_state brw_vs_image_surfaces = { .mesa = _NEW_TEXTURE, .brw = BRW_NEW_BATCH | BRW_NEW_BLORP | + BRW_NEW_FAST_CLEAR_COLOR | BRW_NEW_IMAGE_UNITS | BRW_NEW_VERTEX_PROGRAM | BRW_NEW_VS_PROG_DATA, 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 ab55eee1ce4..7ae982d7711 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c +++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c @@ -1065,7 +1065,8 @@ const struct brw_tracked_state gen6_renderbuffer_surfaces = { .dirty = { .mesa = _NEW_BUFFERS, .brw = BRW_NEW_BATCH | - BRW_NEW_BLORP, + BRW_NEW_BLORP | + BRW_NEW_FAST_CLEAR_COLOR, }, .emit = update_renderbuffer_surfaces, }; @@ -1150,6 +1151,7 @@ const struct brw_tracked_state brw_renderbuffer_read_surfaces = { .dirty = { .mesa = _NEW_BUFFERS, .brw = BRW_NEW_BATCH | + BRW_NEW_FAST_CLEAR_COLOR | BRW_NEW_FRAGMENT_PROGRAM | BRW_NEW_FS_PROG_DATA, }, @@ -1246,6 +1248,7 @@ const struct brw_tracked_state brw_texture_surfaces = { .mesa = _NEW_TEXTURE, .brw = BRW_NEW_BATCH | BRW_NEW_BLORP | + BRW_NEW_FAST_CLEAR_COLOR | BRW_NEW_FRAGMENT_PROGRAM | BRW_NEW_FS_PROG_DATA | BRW_NEW_GEOMETRY_PROGRAM | @@ -1286,7 +1289,8 @@ const struct brw_tracked_state brw_cs_texture_surfaces = { .mesa = _NEW_TEXTURE, .brw = BRW_NEW_BATCH | BRW_NEW_BLORP | - BRW_NEW_COMPUTE_PROGRAM, + BRW_NEW_COMPUTE_PROGRAM | + BRW_NEW_FAST_CLEAR_COLOR, }, .emit = brw_update_cs_texture_surfaces, }; @@ -1499,6 +1503,7 @@ const struct brw_tracked_state brw_cs_image_surfaces = { .brw = BRW_NEW_BATCH | BRW_NEW_BLORP | BRW_NEW_CS_PROG_DATA | + BRW_NEW_FAST_CLEAR_COLOR | BRW_NEW_IMAGE_UNITS }, .emit = brw_upload_cs_image_surfaces, @@ -1683,6 +1688,7 @@ const struct brw_tracked_state brw_wm_image_surfaces = { .mesa = _NEW_TEXTURE, .brw = BRW_NEW_BATCH | BRW_NEW_BLORP | + BRW_NEW_FAST_CLEAR_COLOR | BRW_NEW_FRAGMENT_PROGRAM | BRW_NEW_FS_PROG_DATA | BRW_NEW_IMAGE_UNITS -- 2.30.2