iris: Let blorp update the clear color for us.
authorRafael Antognolli <rafael.antognolli@intel.com>
Fri, 8 Mar 2019 18:58:41 +0000 (10:58 -0800)
committerRafael Antognolli <rafael.antognolli@intel.com>
Wed, 20 Mar 2019 23:46:26 +0000 (16:46 -0700)
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
src/gallium/drivers/iris/iris_blit.c
src/gallium/drivers/iris/iris_clear.c
src/gallium/drivers/iris/iris_resolve.c
src/gallium/drivers/iris/iris_resource.c
src/gallium/drivers/iris/iris_resource.h

index 057abc888e2a7bc469fba2b638353ba12a34ccef..c1f76ea006cecc23bdc5a8f6415dec65e16ffe5b 100644 (file)
@@ -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
index 89c7eb63d09f75c6cd4f6d92a309e40c3ba32637..9634b4ee3d1cb4eb04161714d16ce6faba5893e1 100644 (file)
@@ -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);
       }
    }
 
index 08d139fcdf7f11d5e6c84f0de70f0dc88509f73e..108a6e718d2e18da97d63d07ee503a9b4e3ca330 100644 (file)
@@ -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:
index 3e4b7e71c4aeebfe7f91faec65adf214ce2411f5..164647bc9d081c72e167ce50b5865aec9f68f616 100644 (file)
@@ -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;
    }
 
index 81715ed06f814043f656d1d724172e01866ae5bc..19c8c87c61eac3198f5d8006880c37731fef31d4 100644 (file)
@@ -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