From: Rafael Antognolli Date: Fri, 8 Mar 2019 18:58:41 +0000 (-0800) Subject: iris: Let blorp update the clear color for us. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=e7c840216380cbb0cb8a2eccf9bdf16aaf2a4554;p=mesa.git iris: Let blorp update the clear color for us. Reviewed-by: Kenneth Graunke --- diff --git a/src/gallium/drivers/iris/iris_blit.c b/src/gallium/drivers/iris/iris_blit.c index 057abc888e2..c1f76ea006c 100644 --- a/src/gallium/drivers/iris/iris_blit.c +++ b/src/gallium/drivers/iris/iris_blit.c @@ -255,6 +255,12 @@ iris_blorp_surf_for_resource(struct iris_vtable *vtbl, }; surf->clear_color = iris_resource_get_clear_color(res, NULL, NULL); + surf->clear_color_addr = (struct blorp_address) { + .buffer = res->aux.clear_color_bo, + .offset = res->aux.clear_color_offset, + .reloc_flags = 0, + .mocs = vtbl->mocs(res->aux.clear_color_bo), + }; } // XXX: ASTC diff --git a/src/gallium/drivers/iris/iris_clear.c b/src/gallium/drivers/iris/iris_clear.c index 89c7eb63d09..9634b4ee3d1 100644 --- a/src/gallium/drivers/iris/iris_clear.c +++ b/src/gallium/drivers/iris/iris_clear.c @@ -201,7 +201,10 @@ fast_clear_color(struct iris_context *ice, color = convert_fast_clear_color(ice, res, color, swizzle); - if (memcmp(&res->aux.clear_color, &color, sizeof(color)) != 0) { + bool color_changed = !!memcmp(&res->aux.clear_color, &color, + sizeof(color)); + + if (color_changed) { /* We decided that we are going to fast clear, and the color is * changing. But if we have a predicate bit set, the predication * affects whether we should clear or not, and if we shouldn't, we @@ -222,10 +225,10 @@ fast_clear_color(struct iris_context *ice, iris_resource_set_clear_color(ice, res, color); - /* If the buffer is already in ISL_AUX_STATE_CLEAR, the clear - * is redundant and can be skipped. + /* If the buffer is already in ISL_AUX_STATE_CLEAR, and the color hasn't + * changed, the clear is redundant and can be skipped. */ - if (aux_state == ISL_AUX_STATE_CLEAR) + if (!color_changed && aux_state == ISL_AUX_STATE_CLEAR) return; /* Ivybrigde PRM Vol 2, Part 1, "11.7 MCS Buffer for Render Target(s)": @@ -242,6 +245,11 @@ fast_clear_color(struct iris_context *ice, */ iris_emit_end_of_pipe_sync(batch, PIPE_CONTROL_RENDER_TARGET_FLUSH); + /* If we reach this point, we need to fast clear to change the state to + * ISL_AUX_STATE_CLEAR, or to update the fast clear color (or both). + */ + blorp_flags |= color_changed ? 0 : BLORP_BATCH_NO_UPDATE_CLEAR_COLOR; + struct blorp_batch blorp_batch; blorp_batch_init(&ice->blorp, &blorp_batch, batch, blorp_flags); @@ -276,7 +284,7 @@ clear_color(struct iris_context *ice, struct iris_batch *batch = &ice->batches[IRIS_BATCH_RENDER]; const struct gen_device_info *devinfo = &batch->screen->devinfo; - enum blorp_batch_flags blorp_flags = BLORP_BATCH_NO_UPDATE_CLEAR_COLOR; + enum blorp_batch_flags blorp_flags = 0; if (render_condition_enabled) { if (ice->state.predicate == IRIS_PREDICATE_STATE_DONT_RENDER) @@ -370,6 +378,8 @@ fast_clear_depth(struct iris_context *ice, depth = p_res->format == PIPE_FORMAT_Z32_FLOAT ? depth : (unsigned)(depth * depth_max) / (float)depth_max; + bool update_clear_depth = false; + /* If we're clearing to a new clear value, then we need to resolve any clear * flags out of the HiZ buffer into the real depth buffer. */ @@ -425,13 +435,14 @@ fast_clear_depth(struct iris_context *ice, * value so this shouldn't happen often. */ iris_hiz_exec(ice, batch, res, res_level, layer, 1, - ISL_AUX_OP_FULL_RESOLVE); + ISL_AUX_OP_FULL_RESOLVE, false); iris_resource_set_aux_state(ice, res, res_level, layer, 1, ISL_AUX_STATE_RESOLVED); } } const union isl_color_value clear_value = { .f32 = {depth, } }; iris_resource_set_clear_color(ice, res, clear_value); + update_clear_depth = true; } for (unsigned l = 0; l < box->depth; l++) { @@ -439,7 +450,8 @@ fast_clear_depth(struct iris_context *ice, iris_resource_get_aux_state(res, level, box->z + l); if (aux_state != ISL_AUX_STATE_CLEAR) { iris_hiz_exec(ice, batch, res, level, - box->z + l, 1, ISL_AUX_OP_FAST_CLEAR); + box->z + l, 1, ISL_AUX_OP_FAST_CLEAR, + update_clear_depth); } } diff --git a/src/gallium/drivers/iris/iris_resolve.c b/src/gallium/drivers/iris/iris_resolve.c index 08d139fcdf7..108a6e718d2 100644 --- a/src/gallium/drivers/iris/iris_resolve.c +++ b/src/gallium/drivers/iris/iris_resolve.c @@ -537,7 +537,8 @@ iris_hiz_exec(struct iris_context *ice, struct iris_batch *batch, struct iris_resource *res, unsigned int level, unsigned int start_layer, - unsigned int num_layers, enum isl_aux_op op) + unsigned int num_layers, enum isl_aux_op op, + bool update_clear_depth) { assert(iris_resource_level_has_hiz(res, level)); assert(op != ISL_AUX_OP_NONE); @@ -600,8 +601,9 @@ iris_hiz_exec(struct iris_context *ice, ISL_AUX_USAGE_HIZ, level, true); struct blorp_batch blorp_batch; - blorp_batch_init(&ice->blorp, &blorp_batch, batch, - BLORP_BATCH_NO_UPDATE_CLEAR_COLOR); + enum blorp_batch_flags flags = 0; + flags |= update_clear_depth ? 0 : BLORP_BATCH_NO_UPDATE_CLEAR_COLOR; + blorp_batch_init(&ice->blorp, &blorp_batch, batch, flags); blorp_hiz_op(&blorp_batch, &surf, level, start_layer, num_layers, op); blorp_batch_finish(&blorp_batch); @@ -997,7 +999,7 @@ iris_resource_prepare_hiz_access(struct iris_context *ice, } if (hiz_op != ISL_AUX_OP_NONE) { - iris_hiz_exec(ice, batch, res, level, layer, 1, hiz_op); + iris_hiz_exec(ice, batch, res, level, layer, 1, hiz_op, false); switch (hiz_op) { case ISL_AUX_OP_FULL_RESOLVE: diff --git a/src/gallium/drivers/iris/iris_resource.c b/src/gallium/drivers/iris/iris_resource.c index 3e4b7e71c4a..164647bc9d0 100644 --- a/src/gallium/drivers/iris/iris_resource.c +++ b/src/gallium/drivers/iris/iris_resource.c @@ -1401,29 +1401,6 @@ iris_resource_set_clear_color(struct iris_context *ice, { if (memcmp(&res->aux.clear_color, &color, sizeof(color)) != 0) { res->aux.clear_color = color; - struct iris_batch *batch = &ice->batches[IRIS_BATCH_RENDER]; - /* We can't update the clear color while the hardware is still using - * the previous one for a resolve or sampling from it. Make sure that - * there are no pending commands at this point. - */ - /* TODO: Make these pipe controls gen-specific? - * - * We don't really need them on gen <= 9 where we are reading the - * clear color from the surface state and clear_params, so they - * shouldn't be needed. On gen11, the clear color is read from this - * buffer, but the clear depth is still read from CLEAR_PARAMS, so we - * could probably skip it in the HiZ case as well. - * - * Need to also check that for i965. - */ - iris_emit_pipe_control_flush(batch, PIPE_CONTROL_CS_STALL); - for (int i = 0; i < 4; i++) { - ice->vtbl.store_data_imm32(batch, res->aux.clear_color_bo, - res->aux.clear_color_offset + i * 4, - color.u32[i]); - } - iris_emit_pipe_control_flush(batch, - PIPE_CONTROL_STATE_CACHE_INVALIDATE); return true; } diff --git a/src/gallium/drivers/iris/iris_resource.h b/src/gallium/drivers/iris/iris_resource.h index 81715ed06f8..19c8c87c61e 100644 --- a/src/gallium/drivers/iris/iris_resource.h +++ b/src/gallium/drivers/iris/iris_resource.h @@ -249,7 +249,8 @@ iris_hiz_exec(struct iris_context *ice, struct iris_batch *batch, struct iris_resource *res, unsigned int level, unsigned int start_layer, - unsigned int num_layers, enum isl_aux_op op); + unsigned int num_layers, enum isl_aux_op op, + bool update_clear_depth); /** * Prepare a miptree for access