[Mesa-dev] [RFC] gallium/u_queue: add barrier function

Rob Clark robdclark at gmail.com
Mon Jul 18 23:57:11 UTC 2016


possibly.. although sprinkling queue_barrier() calls (which is at
least useful for debugging, although I think I won't use it in the end
after debugging) hasn't found the issue yet.  I did at least find an
issue w/ fence handling (I was grabbing the fence # potentially before
the batch was flushed), but that also doesn't seem to be the issue I
am seeing.

The idea of having a ring of N fences (where N is given by
max_jobs-1), rather than embedding the fence in the refcnt'd batch, is
interesting, and sounds like it might solve some problems.  I may end
up doing that..

BR,
-R

On Mon, Jul 18, 2016 at 7:34 PM, Marek Olšák <maraeo at gmail.com> wrote:
> I think your issue is that you have self-releasing jobs with the
> cleanup callback and you automatically lose fences that way, so there
> is no way to wait for completion.
>
> Since you have only 1 thread with N jobs at most, I suggest you keep
> N+1 fences around (a ring of fences) that you reuse for new jobs and
> keep a pointer to the most-recently-used fence. That way you know
> which fence you need to wait on to make the whole queue idle.
>
> Marek
>
> On Mon, Jul 18, 2016 at 10:25 PM, Rob Clark <robdclark at gmail.com> wrote:
>> Helper to block until all previous jobs are complete.
>> ---
>> So I think this might end up being useful to me in some cases.. but
>> the implementation only works for a single threaded queue (which is
>> all I need).  I could also just put a helper in my driver code.
>>
>> Opinions?
>>
>>  src/gallium/auxiliary/util/u_queue.c | 12 ++++++++++++
>>  src/gallium/auxiliary/util/u_queue.h |  2 ++
>>  2 files changed, 14 insertions(+)
>>
>> diff --git a/src/gallium/auxiliary/util/u_queue.c b/src/gallium/auxiliary/util/u_queue.c
>> index 838464f..861faca 100644
>> --- a/src/gallium/auxiliary/util/u_queue.c
>> +++ b/src/gallium/auxiliary/util/u_queue.c
>> @@ -242,3 +242,15 @@ util_queue_add_job(struct util_queue *queue,
>>     pipe_condvar_signal(queue->has_queued_cond);
>>     pipe_mutex_unlock(queue->lock);
>>  }
>> +
>> +static void dummy_execute(void *job, int thread_index) {}
>> +
>> +/* blocks until all previously queued jobs complete: */
>> +void util_queue_barrier(struct util_queue *queue)
>> +{
>> +   struct util_queue_fence fence;
>> +   util_queue_fence_init(&fence);
>> +   util_queue_add_job(queue, &fence /*dummy*/, &fence, dummy_execute, NULL);
>> +   util_queue_job_wait(&fence);
>> +   util_queue_fence_destroy(&fence);
>> +}
>> diff --git a/src/gallium/auxiliary/util/u_queue.h b/src/gallium/auxiliary/util/u_queue.h
>> index 59646cc..8a22ee0 100644
>> --- a/src/gallium/auxiliary/util/u_queue.h
>> +++ b/src/gallium/auxiliary/util/u_queue.h
>> @@ -85,6 +85,8 @@ void util_queue_add_job(struct util_queue *queue,
>>
>>  void util_queue_job_wait(struct util_queue_fence *fence);
>>
>> +void util_queue_barrier(struct util_queue *queue);
>> +
>>  /* util_queue needs to be cleared to zeroes for this to work */
>>  static inline bool
>>  util_queue_is_initialized(struct util_queue *queue)
>> --
>> 2.7.4
>>


More information about the mesa-dev mailing list