From: Christian König <christian.koe...@amd.com>

The driver falls back to explicit synchronization as soon as
buffers move between clients or are moved by TTM.

Signed-off-by: Christian König <christian.koenig at amd.com>
---
 drivers/gpu/drm/radeon/radeon.h    |  1 +
 drivers/gpu/drm/radeon/radeon_cs.c | 24 +++++++++++++++++++++++-
 include/uapi/drm/radeon_drm.h      |  7 ++++---
 3 files changed, 28 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index b9fde1d..1529afb 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -1101,6 +1101,7 @@ struct radeon_cs_parser {
        struct radeon_cs_chunk  *chunk_relocs;
        struct radeon_cs_chunk  *chunk_flags;
        struct radeon_cs_chunk  *chunk_const_ib;
+       struct radeon_cs_chunk  *chunk_wait_for;
        struct radeon_ib        ib;
        struct radeon_ib        const_ib;
        void                    *track;
diff --git a/drivers/gpu/drm/radeon/radeon_cs.c 
b/drivers/gpu/drm/radeon/radeon_cs.c
index c0fc8d8..a73f9da 100644
--- a/drivers/gpu/drm/radeon/radeon_cs.c
+++ b/drivers/gpu/drm/radeon/radeon_cs.c
@@ -165,7 +165,8 @@ static int radeon_cs_parser_relocs(struct radeon_cs_parser 
*p)
                }

                p->relocs[i].tv.bo = &p->relocs[i].robj->tbo;
-               p->relocs[i].tv.shared = !r->write_domain;
+               p->relocs[i].tv.shared = !r->write_domain ||
+                                        !!p->chunk_wait_for;

                radeon_cs_buckets_add(&buckets, &p->relocs[i].tv.head,
                                      priority);
@@ -235,6 +236,23 @@ static int radeon_cs_sync_rings(struct radeon_cs_parser *p)
        struct radeon_bo_list *reloc;
        int r;

+       if (p->chunk_wait_for) {
+               struct radeon_fpriv *fpriv = p->filp->driver_priv;
+               unsigned i;
+
+               for (i = 0; i < p->chunk_wait_for->length_dw; i += 2) {
+                       struct radeon_fence *fence;
+                       uint64_t *id;
+
+                       id = (uint64_t *)&p->chunk_wait_for->kdata[i];
+
+                       mutex_lock(&fpriv->seq_lock);
+                       fence = radeon_seq_query(fpriv->seq, *id);
+                       radeon_sync_fence(&p->ib.sync, fence);
+                       mutex_unlock(&fpriv->seq_lock);
+               }
+       }
+
        list_for_each_entry(reloc, &p->validated, tv.head) {
                struct reservation_object *resv;
                long owner = reloc->tv.shared ? (long)p->filp :
@@ -317,6 +335,10 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void 
*data)
                        if (p->chunks[i].length_dw == 0)
                                return -EINVAL;
                }
+               if (user_chunk.chunk_id == RADEON_CHUNK_ID_WAIT_FOR) {
+                       p->chunk_wait_for = &p->chunks[i];
+                       /* zero length wait for list is actually useful */
+               }

                size = p->chunks[i].length_dw;
                cdata = (void __user *)(unsigned long)user_chunk.chunk_data;
diff --git a/include/uapi/drm/radeon_drm.h b/include/uapi/drm/radeon_drm.h
index 6b2b2e7..a34e3db 100644
--- a/include/uapi/drm/radeon_drm.h
+++ b/include/uapi/drm/radeon_drm.h
@@ -942,10 +942,11 @@ struct drm_radeon_gem_va {
        uint64_t                offset;
 };

-#define RADEON_CHUNK_ID_RELOCS 0x01
-#define RADEON_CHUNK_ID_IB     0x02
-#define RADEON_CHUNK_ID_FLAGS  0x03
+#define RADEON_CHUNK_ID_RELOCS         0x01
+#define RADEON_CHUNK_ID_IB             0x02
+#define RADEON_CHUNK_ID_FLAGS          0x03
 #define RADEON_CHUNK_ID_CONST_IB       0x04
+#define RADEON_CHUNK_ID_WAIT_FOR       0x05

 /* The first dword of RADEON_CHUNK_ID_FLAGS is a uint32 of these flags: */
 #define RADEON_CS_KEEP_TILING_FLAGS 0x01
-- 
1.9.1

Reply via email to