iris: handle new PIPE_CONTROL field
[mesa.git] / src / gallium / drivers / iris / iris_draw.c
index 0f7ca37561fbead15f716e0cbe05c6fb2b53179a..497ffc5ccd2ad0d766f8a835316212af3ad847bd 100644 (file)
@@ -63,6 +63,9 @@ static void
 iris_update_draw_info(struct iris_context *ice,
                       const struct pipe_draw_info *info)
 {
+   struct iris_screen *screen = (struct iris_screen *)ice->ctx.screen;
+   const struct brw_compiler *compiler = screen->compiler;
+
    if (ice->state.prim_mode != info->mode) {
       ice->state.prim_mode = info->mode;
       ice->state.dirty |= IRIS_DIRTY_VF_TOPOLOGY;
@@ -81,13 +84,17 @@ iris_update_draw_info(struct iris_context *ice,
       ice->state.vertices_per_patch = info->vertices_per_patch;
       ice->state.dirty |= IRIS_DIRTY_VF_TOPOLOGY;
 
+      /* 8_PATCH TCS needs this for key->input_vertices */
+      if (compiler->use_tcs_8_patch)
+         ice->state.dirty |= IRIS_DIRTY_UNCOMPILED_TCS;
+
       /* Flag constants dirty for gl_PatchVerticesIn if needed. */
       const struct shader_info *tcs_info =
          iris_get_shader_info(ice, MESA_SHADER_TESS_CTRL);
       if (tcs_info &&
           tcs_info->system_values_read & (1ull << SYSTEM_VALUE_VERTICES_IN)) {
          ice->state.dirty |= IRIS_DIRTY_CONSTANTS_TCS;
-         ice->state.shaders[MESA_SHADER_TESS_CTRL].cbuf0_needs_upload = true;
+         ice->state.shaders[MESA_SHADER_TESS_CTRL].sysvals_need_upload = true;
       }
    }
 
@@ -106,35 +113,56 @@ static void
 iris_update_draw_parameters(struct iris_context *ice,
                             const struct pipe_draw_info *info)
 {
-   if (info->indirect) {
-      pipe_resource_reference(&ice->draw.draw_params_res,
-                              info->indirect->buffer);
-      ice->draw.draw_params_offset = info->indirect->offset +
-                                     (info->index_size ? 12 : 8);
-      ice->draw.params.firstvertex = 0;
-      ice->draw.params.baseinstance = 0;
-      ice->state.dirty |= IRIS_DIRTY_VERTEX_BUFFERS |
-                          IRIS_DIRTY_VERTEX_ELEMENTS |
-                          IRIS_DIRTY_VF_SGVS;
-   } else if (ice->draw.is_indirect ||
-              ice->draw.params.firstvertex !=
-              (info->index_size ? info->index_bias : info->start) ||
-              (ice->draw.params.baseinstance != info->start_instance)) {
-      pipe_resource_reference(&ice->draw.draw_params_res, NULL);
-      ice->draw.draw_params_offset = 0;
-      ice->draw.params.firstvertex =
-         info->index_size ? info->index_bias : info->start;
-      ice->draw.params.baseinstance = info->start_instance;
-      ice->state.dirty |= IRIS_DIRTY_VERTEX_BUFFERS |
-                          IRIS_DIRTY_VERTEX_ELEMENTS |
-                          IRIS_DIRTY_VF_SGVS;
+   bool changed = false;
+
+   if (ice->state.vs_uses_draw_params) {
+      struct iris_state_ref *draw_params = &ice->draw.draw_params;
+
+      if (info->indirect) {
+         pipe_resource_reference(&draw_params->res, info->indirect->buffer);
+         draw_params->offset =
+            info->indirect->offset + (info->index_size ? 12 : 8);
+
+         changed = true;
+         ice->draw.params_valid = false;
+      } else {
+         int firstvertex = info->index_size ? info->index_bias : info->start;
+
+         if (!ice->draw.params_valid ||
+             ice->draw.params.firstvertex != firstvertex ||
+             ice->draw.params.baseinstance != info->start_instance) {
+
+            changed = true;
+            ice->draw.params.firstvertex = firstvertex;
+            ice->draw.params.baseinstance = info->start_instance;
+            ice->draw.params_valid = true;
+
+            u_upload_data(ice->ctx.stream_uploader, 0,
+                          sizeof(ice->draw.params), 4, &ice->draw.params,
+                          &draw_params->offset, &draw_params->res);
+         }
+      }
+   }
+
+   if (ice->state.vs_uses_derived_draw_params) {
+      struct iris_state_ref *derived_params = &ice->draw.derived_draw_params;
+      int is_indexed_draw = info->index_size ? -1 : 0;
+
+      if (ice->draw.derived_params.drawid != info->drawid ||
+          ice->draw.derived_params.is_indexed_draw != is_indexed_draw) {
+
+         changed = true;
+         ice->draw.derived_params.drawid = info->drawid;
+         ice->draw.derived_params.is_indexed_draw = is_indexed_draw;
+
+         u_upload_data(ice->ctx.stream_uploader, 0,
+                       sizeof(ice->draw.derived_params), 4,
+                       &ice->draw.derived_params,
+                       &derived_params->offset, &derived_params->res);
+      }
    }
-   ice->draw.is_indirect = info->indirect;
 
-   if (ice->draw.derived_params.drawid != info->drawid ||
-       ice->draw.derived_params.is_indexed_draw != (info->index_size ? ~0 : 0)) {
-      ice->draw.derived_params.drawid = info->drawid;
-      ice->draw.derived_params.is_indexed_draw = info->index_size ? ~0 : 0;
+   if (changed) {
       ice->state.dirty |= IRIS_DIRTY_VERTEX_BUFFERS |
                           IRIS_DIRTY_VERTEX_ELEMENTS |
                           IRIS_DIRTY_VF_SGVS;
@@ -150,8 +178,8 @@ iris_indirect_draw_vbo(struct iris_context *ice,
 
    if (info.indirect->indirect_draw_count &&
        ice->state.predicate == IRIS_PREDICATE_STATE_USE_BIT) {
-      /* Upload MI_PREDICATE_RESULT to GPR2.*/
-      ice->vtbl.load_register_reg64(batch, CS_GPR(2), MI_PREDICATE_RESULT);
+      /* Upload MI_PREDICATE_RESULT to GPR15.*/
+      ice->vtbl.load_register_reg64(batch, CS_GPR(15), MI_PREDICATE_RESULT);
    }
 
    uint64_t orig_dirty = ice->state.dirty;
@@ -173,7 +201,7 @@ iris_indirect_draw_vbo(struct iris_context *ice,
    if (info.indirect->indirect_draw_count &&
        ice->state.predicate == IRIS_PREDICATE_STATE_USE_BIT) {
       /* Restore MI_PREDICATE_RESULT. */
-      ice->vtbl.load_register_reg64(batch, MI_PREDICATE_RESULT, CS_GPR(2));
+      ice->vtbl.load_register_reg64(batch, MI_PREDICATE_RESULT, CS_GPR(15));
    }
 
    /* Put this back for post-draw resolves, we'll clear it again after. */
@@ -234,11 +262,15 @@ iris_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info)
 
    ice->vtbl.update_surface_base_address(batch, &ice->state.binder);
 
+   iris_handle_always_flush_cache(batch);
+
    if (info->indirect)
       iris_indirect_draw_vbo(ice, info);
    else
       iris_simple_draw_vbo(ice, info);
 
+   iris_handle_always_flush_cache(batch);
+
    iris_postdraw_update_resolve_tracking(ice, batch);
 
    ice->state.dirty &= ~IRIS_ALL_DIRTY_FOR_RENDER;
@@ -281,6 +313,8 @@ iris_update_grid_size_resource(struct iris_context *ice,
    if (!grid_needs_surface || state_ref->res)
       return;
 
+   struct iris_bo *grid_bo = iris_resource_bo(grid_ref->res);
+
    void *surf_map = NULL;
    u_upload_alloc(ice->state.surface_uploader, 0, isl_dev->ss.size,
                   isl_dev->ss.align, &state_ref->offset, &state_ref->res,
@@ -288,12 +322,11 @@ iris_update_grid_size_resource(struct iris_context *ice,
    state_ref->offset +=
       iris_bo_offset_from_base_address(iris_resource_bo(state_ref->res));
    isl_buffer_fill_state(&screen->isl_dev, surf_map,
-                         .address = grid_ref->offset +
-                            iris_resource_bo(grid_ref->res)->gtt_offset,
+                         .address = grid_ref->offset + grid_bo->gtt_offset,
                          .size_B = sizeof(grid->grid),
                          .format = ISL_FORMAT_RAW,
                          .stride_B = 1,
-                         .mocs = 4); // XXX: MOCS
+                         .mocs = ice->vtbl.mocs(grid_bo, isl_dev));
 
    ice->state.dirty |= IRIS_DIRTY_BINDINGS_CS;
 }
@@ -320,8 +353,7 @@ iris_launch_grid(struct pipe_context *ctx, const struct pipe_grid_info *grid)
 
    iris_batch_maybe_flush(batch, 1500);
 
-   if (ice->state.dirty & IRIS_DIRTY_UNCOMPILED_CS)
-      iris_update_compiled_compute_shader(ice);
+   iris_update_compiled_compute_shader(ice);
 
    iris_update_grid_size_resource(ice, grid);
 
@@ -334,8 +366,12 @@ iris_launch_grid(struct pipe_context *ctx, const struct pipe_grid_info *grid)
       ice->state.compute_predicate = NULL;
    }
 
+   iris_handle_always_flush_cache(batch);
+
    ice->vtbl.upload_compute_state(ice, batch, grid);
 
+   iris_handle_always_flush_cache(batch);
+
    ice->state.dirty &= ~IRIS_ALL_DIRTY_FOR_COMPUTE;
 
    /* Note: since compute shaders can't access the framebuffer, there's