iris: Fix resource tracking for CS thread ID buffer
authorKenneth Graunke <kenneth@whitecape.org>
Thu, 27 Jun 2019 06:38:59 +0000 (23:38 -0700)
committerKenneth Graunke <kenneth@whitecape.org>
Thu, 27 Jun 2019 15:12:22 +0000 (08:12 -0700)
Today, we stream the compute shader thread IDs simply because they're
(annoyingly) relative to dynamic state base address.  We could upload
them once at compile time, but we'd need a separate non-streaming
uploader for IRIS_MEMZONE_DYNAMIC, and I'm not sure it's worth it.

stream_state pins the buffer for use in the current batch, but also
returns a reference to the pipe_resource.  We dropped this reference
on the floor, leaking a reference basically every time we dispatched
a compute shader after switching to a new one.

The reason it returns a reference is so that we can hold on to it and
re-pin it in iris_restore_compute_saved_bos, which we were also failing
to do.  So if we actually filled up a batch with repeated dispatches to
the same compute shader, and flushed, then continued dispatching, we
would fail to pin it and likely GPU hang.

src/gallium/drivers/iris/iris_context.h
src/gallium/drivers/iris/iris_state.c

index e34ea930eae6046ef7b18bd92a6810b11e34057b..21877173b3f71a1b0b0cc5d134f6d8ad065eb8bc 100644 (file)
@@ -712,6 +712,7 @@ struct iris_context {
          struct pipe_resource *scissor;
          struct pipe_resource *blend;
          struct pipe_resource *index_buffer;
+         struct pipe_resource *cs_thread_ids;
       } last_res;
 
       /** Records the size of variable-length state for INTEL_DEBUG=bat */
index 385d99bdb4f6ad97946267199a8030e0bc93a4b0..5de994893e0baca3e319ad9a7b59e9331bfe002c 100644 (file)
@@ -4369,6 +4369,10 @@ iris_restore_compute_saved_bos(struct iris_context *ice,
          struct iris_bo *bo = iris_resource_bo(shader->assembly.res);
          iris_use_pinned_bo(batch, bo, false);
 
+         struct iris_bo *curbe_bo =
+            iris_resource_bo(ice->state.last_res.cs_thread_ids);
+         iris_use_pinned_bo(batch, curbe_bo, false);
+
          struct brw_stage_prog_data *prog_data = shader->prog_data;
 
          if (prog_data->total_scratch > 0) {
@@ -5507,9 +5511,9 @@ iris_upload_compute_state(struct iris_context *ice,
       assert(cs_prog_data->push.cross_thread.dwords == 0 &&
              cs_prog_data->push.per_thread.dwords == 1 &&
              cs_prog_data->base.param[0] == BRW_PARAM_BUILTIN_SUBGROUP_ID);
-      struct pipe_resource *curbe_data_res = NULL;
       uint32_t *curbe_data_map =
-         stream_state(batch, ice->state.dynamic_uploader, &curbe_data_res,
+         stream_state(batch, ice->state.dynamic_uploader,
+                      &ice->state.last_res.cs_thread_ids,
                       ALIGN(cs_prog_data->push.total.size, 64), 64,
                       &curbe_data_offset);
       assert(curbe_data_map);
@@ -5653,6 +5657,7 @@ iris_destroy_state(struct iris_context *ice)
    pipe_resource_reference(&ice->state.last_res.scissor, NULL);
    pipe_resource_reference(&ice->state.last_res.blend, NULL);
    pipe_resource_reference(&ice->state.last_res.index_buffer, NULL);
+   pipe_resource_reference(&ice->state.last_res.cs_thread_ids, NULL);
 }
 
 /* ------------------------------------------------------------------- */