radeon+libdrm-radeon: change relocation informations
authorJerome Glisse <glisse@freedesktop.org>
Wed, 12 Nov 2008 14:56:40 +0000 (15:56 +0100)
committerJerome Glisse <glisse@freedesktop.org>
Wed, 12 Nov 2008 15:57:09 +0000 (16:57 +0100)
Relocation now consist of the following informations (in this order) :
handle          buffer object handle identifier
start_offset    start offset of first data of the buffer object used by the cs
end_offset      end offset of last data of the buffer object used by the cs
read_domain     read domain (either VRAM, or GTT as GPU is invalid for CS)
write_domain    write domain (either VRAM, or GTT as GPU is invalid for CS)
flags           flags used for further optimization (like discard previous
                buffer content or forget buffer content after cs which can
                help in avoiding moving content in or out)

libdrm/radeon/Makefile.am
libdrm/radeon/radeon_cs.h
libdrm/radeon/radeon_cs_gem.c
linux-core/radeon_gem.c

index cc4951a..d15a266 100644 (file)
@@ -29,7 +29,7 @@ AM_CFLAGS = \
        $(PTHREADSTUBS_CFLAGS) \
        -I$(top_srcdir)/shared-core
 
-libdrm_radeon_la_LTLIBRARIES = libdrm_radeon.la
+libdrm_radeon_la_LTLIBRARIES = libdrm-radeon.la
 libdrm_radeon_ladir = $(libdir)
 libdrm_radeon_la_LDFLAGS = -version-number 1:0:0 -no-undefined
 libdrm_radeon_la_LIBADD = ../libdrm.la @PTHREADSTUBS_LIBS@
index 347e9f3..63f104b 100644 (file)
 
 struct radeon_cs_reloc {
     struct radeon_bo    *bo;
-    uint32_t            soffset;
-    uint32_t            eoffset;
-    uint32_t            size;
-    uint32_t            domains;
+    uint32_t            start_offset;
+    uint32_t            end_offset;
+    uint32_t            read_domain;
+    uint32_t            write_domain;
+    uint32_t            flags;
 };
 
 struct radeon_cs_manager;
@@ -68,9 +69,11 @@ struct radeon_cs_funcs {
     int (*cs_write_dword)(struct radeon_cs *cs, uint32_t dword);
     int (*cs_write_reloc)(struct radeon_cs *cs,
                           struct radeon_bo *bo,
-                          uint32_t soffset,
-                          uint32_t eoffset,
-                          uint32_t domains);
+                          uint32_t start_offset,
+                          uint32_t end_offset,
+                          uint32_t read_domain,
+                          uint32_t write_domain,
+                          uint32_t flags);
     int (*cs_begin)(struct radeon_cs *cs,
                     uint32_t ndw,
                     const char *file,
@@ -104,11 +107,19 @@ static inline int radeon_cs_write_dword(struct radeon_cs *cs, uint32_t dword)
 
 static inline int radeon_cs_write_reloc(struct radeon_cs *cs,
                                         struct radeon_bo *bo,
-                                        uint32_t soffset,
-                                        uint32_t eoffset,
-                                        uint32_t domains)
+                                        uint32_t start_offset,
+                                        uint32_t end_offset,
+                                        uint32_t read_domain,
+                                        uint32_t write_domain,
+                                        uint32_t flags)
 {
-    return cs->csm->funcs->cs_write_reloc(cs, bo, soffset, eoffset, domains);
+    return cs->csm->funcs->cs_write_reloc(cs,
+                                          bo,
+                                          start_offset,
+                                          end_offset,
+                                          read_domain,
+                                          write_domain,
+                                          flags);
 }
 
 static inline int radeon_cs_begin(struct radeon_cs *cs,
index 6be1728..f9c9fab 100644 (file)
 #pragma pack(1)
 struct cs_reloc_gem {
     uint32_t    handle;
-    uint32_t    rdomain;
-    uint32_t    wdomain;
-    uint32_t    cnt;
+    uint32_t    start_offset;
+    uint32_t    end_offset;
+    uint32_t    read_domain;
+    uint32_t    write_domain;
+    uint32_t    flags;
 };
 #pragma pack()
 
@@ -125,50 +127,74 @@ static int cs_gem_write_dword(struct radeon_cs *cs, uint32_t dword)
 
 static int cs_gem_write_reloc(struct radeon_cs *cs,
                               struct radeon_bo *bo,
-                              uint32_t soffset,
-                              uint32_t eoffset,
-                              uint32_t domains)
+                              uint32_t start_offset,
+                              uint32_t end_offset,
+                              uint32_t read_domain,
+                              uint32_t write_domain,
+                              uint32_t flags)
 {
     struct cs_gem *csg = (struct cs_gem*)cs;
     struct cs_reloc_gem *reloc;
     uint32_t idx;
     unsigned i;
 
+    /* check domains */
+    if ((read_domain && write_domain) || (!read_domain && !write_domain)) {
+        /* in one CS a bo can only be in read or write domain but not
+         * in read & write domain at the same sime
+         */
+        return -EINVAL;
+    }
+    if (read_domain == RADEON_GEM_DOMAIN_CPU) {
+        return -EINVAL;
+    }
+    if (write_domain == RADEON_GEM_DOMAIN_CPU) {
+        return -EINVAL;
+    }
     /* check reloc window */
-    if (eoffset > bo->size) {
+    if (end_offset > bo->size) {
         return -EINVAL;
     }
-    if (soffset > eoffset) {
+    if (start_offset > end_offset) {
         return -EINVAL;
     }
     /* check if bo is already referenced */
     for(i = 0; i < cs->crelocs; i++) {
-        idx = i * 4;
+        idx = i * 6;
         reloc = (struct cs_reloc_gem*)&csg->relocs[idx];
-
         if (reloc->handle == bo->handle) {
-            /* update start offset and size */
-            switch (bo->domains) {
-            case RADEON_GEM_DOMAIN_VRAM:
-                reloc->rdomain = 0;
-                reloc->wdomain = RADEON_GEM_DOMAIN_VRAM;
-                break;
-            case RADEON_GEM_DOMAIN_GTT:
-                reloc->rdomain = RADEON_GEM_DOMAIN_GTT;
-                reloc->wdomain = 0;
-                break;
-            default:
-                exit(0);
-                break;
+            /* Check domains must be in read or write. As we check already
+             * checked that in argument one of the read or write domain was
+             * set we only need to check that if previous reloc as the read
+             * domain set then the read_domain should also be set for this
+             * new relocation.
+             */
+            if (reloc->read_domain && !read_domain) {
+                return -EINVAL;
+            }
+            if (reloc->write_domain && !write_domain) {
+                return -EINVAL;
+            }
+            reloc->read_domain |= read_domain;
+            reloc->write_domain |= write_domain;
+            /* update start and end offset */
+            if (start_offset < reloc->start_offset) {
+                reloc->start_offset = start_offset;
             }
-            reloc->cnt++;
+            if (end_offset > reloc->end_offset) {
+                reloc->end_offset = end_offset;
+            }
+            /* update flags */
+            reloc->flags |= (flags & reloc->flags);
+            /* write relocation packet */
             cs_gem_write_dword(cs, 0xc0001000);
             cs_gem_write_dword(cs, idx);
             return 0;
         }
     }
-    /* add bo */
+    /* new relocation */
     if (csg->base.crelocs >= csg->nrelocs) {
+        /* allocate more memory (TODO: should use a slab allocatore maybe) */
         uint32_t *tmp, size;
         size = ((csg->nrelocs + 1) * sizeof(struct radeon_bo*));
         tmp = (uint32_t*)realloc(csg->relocs_bo, size);
@@ -176,7 +202,7 @@ static int cs_gem_write_reloc(struct radeon_cs *cs,
             return -ENOMEM;
         }
         csg->relocs_bo = (struct radeon_bo**)tmp;
-        size = ((csg->nrelocs + 1) * 4 * 4);
+        size = ((csg->nrelocs + 1) * 6 * 4);
         tmp = (uint32_t*)realloc(csg->relocs, size);
         if (tmp == NULL) {
             return -ENOMEM;
@@ -186,26 +212,15 @@ static int cs_gem_write_reloc(struct radeon_cs *cs,
         csg->chunks[1].chunk_data = (uint64_t)(intptr_t)csg->relocs;
     }
     csg->relocs_bo[csg->base.crelocs] = bo;
-    idx = (csg->base.crelocs++) * 4;
+    idx = (csg->base.crelocs++) * 6;
     reloc = (struct cs_reloc_gem*)&csg->relocs[idx];
     reloc->handle = bo->handle;
-    reloc->rdomain = bo->domains;
-    reloc->wdomain = bo->domains;
-    switch (bo->domains) {
-    case RADEON_GEM_DOMAIN_VRAM:
-        reloc->rdomain = 0;
-        reloc->wdomain = RADEON_GEM_DOMAIN_VRAM;
-        break;
-    case RADEON_GEM_DOMAIN_GTT:
-        reloc->rdomain = RADEON_GEM_DOMAIN_GTT;
-        reloc->wdomain = 0;
-        break;
-    default:
-        exit(0);
-        break;
-    }
-    reloc->cnt = 1;
-    csg->chunks[1].length_dw += 4;
+    reloc->start_offset = start_offset;
+    reloc->end_offset = end_offset;
+    reloc->read_domain = read_domain;
+    reloc->write_domain = write_domain;
+    reloc->flags = flags;
+    csg->chunks[1].length_dw += 6;
     radeon_bo_ref(bo);
     cs->relocs_total_size += bo->size;
     cs_gem_write_dword(cs, 0xc0001000);
index 2ed9bfc..b2e1d7f 100644 (file)
@@ -1213,8 +1213,8 @@ static int radeon_gem_find_reloc(struct drm_radeon_cs_parser *parser,
        }
 
        *handle = reloc_chunk->kdata[offset];
-       *read_domains = reloc_chunk->kdata[offset + 1];
-       *write_domain = reloc_chunk->kdata[offset + 2];
+       *read_domains = reloc_chunk->kdata[offset + 3];
+       *write_domain = reloc_chunk->kdata[offset + 4];
        return 0;
 }