drm/amdgpu: add optional dependencies to the CS IOCTL v2
authorChristian König <christian.koenig@amd.com>
Fri, 19 Jun 2015 15:31:29 +0000 (17:31 +0200)
committerAlex Deucher <alexander.deucher@amd.com>
Mon, 29 Jun 2015 19:52:49 +0000 (15:52 -0400)
v2: remove unrelated whitespace change, fix C comment

Signed-off-by: Christian König <christian.koenig@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
include/uapi/drm/amdgpu_drm.h

index 84ba1d1bf3270e20e810d8d290e9764a028a0257..d63135bf29c0c258f72025fa6f41f34677576ec4 100644 (file)
@@ -226,6 +226,9 @@ int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data)
                        }
                        break;
 
+               case AMDGPU_CHUNK_ID_DEPENDENCIES:
+                       break;
+
                default:
                        r = -EINVAL;
                        goto out;
@@ -663,6 +666,55 @@ static int amdgpu_cs_ib_fill(struct amdgpu_device *adev,
        return 0;
 }
 
+static int amdgpu_cs_dependencies(struct amdgpu_device *adev,
+                                 struct amdgpu_cs_parser *p)
+{
+       struct amdgpu_ib *ib;
+       int i, j, r;
+
+       if (!p->num_ibs)
+               return 0;
+
+       /* Add dependencies to first IB */
+       ib = &p->ibs[0];
+       for (i = 0; i < p->nchunks; ++i) {
+               struct drm_amdgpu_cs_chunk_dep *deps;
+               struct amdgpu_cs_chunk *chunk;
+               unsigned num_deps;
+
+               chunk = &p->chunks[i];
+
+               if (chunk->chunk_id != AMDGPU_CHUNK_ID_DEPENDENCIES)
+                       continue;
+
+               deps = (struct drm_amdgpu_cs_chunk_dep *)chunk->kdata;
+               num_deps = chunk->length_dw * 4 /
+                       sizeof(struct drm_amdgpu_cs_chunk_dep);
+
+               for (j = 0; j < num_deps; ++j) {
+                       struct amdgpu_fence *fence;
+                       struct amdgpu_ring *ring;
+
+                       r = amdgpu_cs_get_ring(adev, deps[j].ip_type,
+                                              deps[j].ip_instance,
+                                              deps[j].ring, &ring);
+                       if (r)
+                               return r;
+
+                       r = amdgpu_fence_recreate(ring, p->filp,
+                                                 deps[j].handle,
+                                                 &fence);
+                       if (r)
+                               return r;
+
+                       amdgpu_sync_fence(&ib->sync, fence);
+                       amdgpu_fence_unref(&fence);
+               }
+       }
+
+       return 0;
+}
+
 int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
 {
        struct amdgpu_device *adev = dev->dev_private;
@@ -697,11 +749,16 @@ int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
                        else
                                DRM_ERROR("Failed to process the buffer list %d!\n", r);
                }
-       } else {
+       }
+
+       if (!r) {
                reserved_buffers = true;
                r = amdgpu_cs_ib_fill(adev, &parser);
        }
 
+       if (!r)
+               r = amdgpu_cs_dependencies(adev, &parser);
+
        if (r) {
                amdgpu_cs_parser_fini(&parser, r, reserved_buffers);
                up_read(&adev->exclusive_lock);
index d3f4832db289b5da2787427360e7b933677d9fd5..8edf1042036167c55d8b00f16c0b320ac0680a20 100644 (file)
@@ -348,6 +348,7 @@ struct drm_amdgpu_gem_va {
 
 #define AMDGPU_CHUNK_ID_IB             0x01
 #define AMDGPU_CHUNK_ID_FENCE          0x02
+#define AMDGPU_CHUNK_ID_DEPENDENCIES   0x03
 
 struct drm_amdgpu_cs_chunk {
        uint32_t                chunk_id;
@@ -399,6 +400,14 @@ struct drm_amdgpu_cs_chunk_ib {
        uint32_t ring;
 };
 
+struct drm_amdgpu_cs_chunk_dep {
+       uint32_t ip_type;
+       uint32_t ip_instance;
+       uint32_t ring;
+       uint32_t ctx_id;
+       uint64_t handle;
+};
+
 struct drm_amdgpu_cs_chunk_fence {
        uint32_t handle;
        uint32_t offset;