winsys/amdgpu: extend amdgpu_add_fence to allow adding multiple fences
authorNicolai Hähnle <nicolai.haehnle@amd.com>
Tue, 7 Feb 2017 16:53:49 +0000 (17:53 +0100)
committerNicolai Hähnle <nicolai.haehnle@amd.com>
Wed, 5 Apr 2017 08:37:18 +0000 (10:37 +0200)
Reviewed-by: Marek Olšák <marek.olsak@amd.com>
src/gallium/winsys/amdgpu/drm/amdgpu_cs.c
src/gallium/winsys/amdgpu/drm/amdgpu_cs.h

index e2d3a45e6e6acbaa6ffa6755be1cf99ed6e231ba..bffa725427e61ddf660259230f0856d0164cfe4d 100644 (file)
@@ -952,31 +952,44 @@ static void amdgpu_add_fence_dependency(struct amdgpu_cs *acs,
    bo->num_fences = new_num_fences;
 }
 
-static void amdgpu_add_fence(struct amdgpu_winsys_bo *bo,
-                             struct pipe_fence_handle *fence)
+/* Add the given list of fences to the buffer's fence list.
+ *
+ * Must be called with the winsys bo_fence_lock held.
+ */
+void amdgpu_add_fences(struct amdgpu_winsys_bo *bo,
+                       unsigned num_fences,
+                       struct pipe_fence_handle **fences)
 {
-   if (bo->num_fences >= bo->max_fences) {
-      unsigned new_max_fences = MAX2(1, bo->max_fences * 2);
+   if (bo->num_fences + num_fences > bo->max_fences) {
+      unsigned new_max_fences = MAX2(bo->num_fences + num_fences, bo->max_fences * 2);
       struct pipe_fence_handle **new_fences =
          REALLOC(bo->fences,
                  bo->num_fences * sizeof(*new_fences),
                  new_max_fences * sizeof(*new_fences));
-      if (new_fences) {
+      if (likely(new_fences)) {
          bo->fences = new_fences;
          bo->max_fences = new_max_fences;
       } else {
-         fprintf(stderr, "amdgpu_add_fence: allocation failure, dropping fence\n");
+         unsigned drop;
+
+         fprintf(stderr, "amdgpu_add_fences: allocation failure, dropping fence(s)\n");
          if (!bo->num_fences)
             return;
 
-         bo->num_fences--; /* prefer to keep a more recent fence if possible */
+         bo->num_fences--; /* prefer to keep the most recent fence if possible */
          amdgpu_fence_reference(&bo->fences[bo->num_fences], NULL);
+
+         drop = bo->num_fences + num_fences - bo->max_fences;
+         num_fences -= drop;
+         fences += drop;
       }
    }
 
-   bo->fences[bo->num_fences] = NULL;
-   amdgpu_fence_reference(&bo->fences[bo->num_fences], fence);
-   bo->num_fences++;
+   for (unsigned i = 0; i < num_fences; ++i) {
+      bo->fences[bo->num_fences] = NULL;
+      amdgpu_fence_reference(&bo->fences[bo->num_fences], fences[i]);
+      bo->num_fences++;
+   }
 }
 
 static void amdgpu_add_fence_dependencies_list(struct amdgpu_cs *acs,
@@ -990,7 +1003,7 @@ static void amdgpu_add_fence_dependencies_list(struct amdgpu_cs *acs,
 
       amdgpu_add_fence_dependency(acs, buffer);
       p_atomic_inc(&bo->num_active_ioctls);
-      amdgpu_add_fence(bo, fence);
+      amdgpu_add_fences(bo, 1, &fence);
    }
 }
 
index bdf7cb2b8ebefd15533804628bb041e2057e256b..242410f08210a3a7328d3b546b291b678f808775 100644 (file)
@@ -240,6 +240,9 @@ amdgpu_bo_is_referenced_by_any_cs(struct amdgpu_winsys_bo *bo)
 
 bool amdgpu_fence_wait(struct pipe_fence_handle *fence, uint64_t timeout,
                        bool absolute);
+void amdgpu_add_fences(struct amdgpu_winsys_bo *bo,
+                       unsigned num_fences,
+                       struct pipe_fence_handle **fences);
 void amdgpu_cs_sync_flush(struct radeon_winsys_cs *rcs);
 void amdgpu_cs_init_functions(struct amdgpu_winsys *ws);
 void amdgpu_cs_submit_ib(void *job, int thread_index);