Mesa (master): r300g: improve function radeon_bo_is_referenced_by_cs

Marek Olšák mareko at kemper.freedesktop.org
Sat Feb 12 02:09:26 UTC 2011


Module: Mesa
Branch: master
Commit: df54b53b7d12a3bca5867b6649cb308feb36f0da
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=df54b53b7d12a3bca5867b6649cb308feb36f0da

Author: Marek Olšák <maraeo at gmail.com>
Date:   Fri Feb 11 07:52:10 2011 +0100

r300g: improve function radeon_bo_is_referenced_by_cs

This should prevent calling into radeon_get_reloc when there's
only one context.

---

 src/gallium/winsys/radeon/drm/radeon_drm_bo.c |   24 +++++++++++++-----------
 src/gallium/winsys/radeon/drm/radeon_drm_bo.h |    8 ++++++--
 src/gallium/winsys/radeon/drm/radeon_drm_cs.c |    4 ++++
 src/gallium/winsys/radeon/drm/radeon_drm_cs.h |   11 ++++++-----
 src/gallium/winsys/radeon/drm/radeon_winsys.h |    1 +
 5 files changed, 30 insertions(+), 18 deletions(-)

diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_bo.c b/src/gallium/winsys/radeon/drm/radeon_drm_bo.c
index a9e913e..47d4f4d 100644
--- a/src/gallium/winsys/radeon/drm/radeon_drm_bo.c
+++ b/src/gallium/winsys/radeon/drm/radeon_drm_bo.c
@@ -91,7 +91,7 @@ void radeon_bo_unref(struct radeon_bo *bo)
 {
     struct drm_gem_close args = {};
 
-    if (!p_atomic_dec_zero(&bo->cref))
+    if (!p_atomic_dec_zero(&bo->ref_count))
         return;
 
     if (bo->name) {
@@ -106,7 +106,7 @@ void radeon_bo_unref(struct radeon_bo *bo)
 
     /* Close object. */
     args.handle = bo->handle;
-    drmIoctl(bo->mgr->rws->fd, DRM_IOCTL_GEM_CLOSE, &args);
+    drmIoctl(bo->rws->fd, DRM_IOCTL_GEM_CLOSE, &args);
     FREE(bo);
 }
 
@@ -116,7 +116,7 @@ static void radeon_bo_wait(struct r300_winsys_bo *_buf)
     struct drm_radeon_gem_wait_idle args = {};
 
     args.handle = bo->handle;
-    while (drmCommandWriteRead(bo->mgr->rws->fd, DRM_RADEON_GEM_WAIT_IDLE,
+    while (drmCommandWriteRead(bo->rws->fd, DRM_RADEON_GEM_WAIT_IDLE,
                                &args, sizeof(args)) == -EBUSY);
 }
 
@@ -126,7 +126,7 @@ static boolean radeon_bo_is_busy(struct r300_winsys_bo *_buf)
     struct drm_radeon_gem_busy args = {};
 
     args.handle = bo->handle;
-    return drmCommandWriteRead(bo->mgr->rws->fd, DRM_RADEON_GEM_BUSY,
+    return drmCommandWriteRead(bo->rws->fd, DRM_RADEON_GEM_BUSY,
                                &args, sizeof(args)) != 0;
 }
 
@@ -202,7 +202,7 @@ static void *radeon_bo_map_internal(struct pb_buffer *_buf,
         args.handle = bo->handle;
         args.offset = 0;
         args.size = (uint64_t)bo->size;
-        if (drmCommandWriteRead(bo->mgr->rws->fd,
+        if (drmCommandWriteRead(bo->rws->fd,
                                 DRM_RADEON_GEM_MMAP,
                                 &args,
                                 sizeof(args))) {
@@ -211,7 +211,7 @@ static void *radeon_bo_map_internal(struct pb_buffer *_buf,
             return NULL;
         }
         ptr = mmap(0, args.size, PROT_READ|PROT_WRITE, MAP_SHARED,
-                   bo->mgr->rws->fd, args.addr_ptr);
+                   bo->rws->fd, args.addr_ptr);
         if (ptr == MAP_FAILED) {
             fprintf(stderr, "radeon: mmap failed, errno: %i\n", errno);
             return NULL;
@@ -293,6 +293,7 @@ static struct pb_buffer *radeon_bomgr_create_bo(struct pb_manager *_mgr,
     bo->base.base.size = size;
     bo->base.vtbl = &radeon_bo_vtbl;
     bo->mgr = mgr;
+    bo->rws = mgr->rws;
     bo->handle = args.handle;
     bo->size = size;
 
@@ -359,7 +360,7 @@ static void radeon_bo_get_tiling(struct r300_winsys_bo *_buf,
 
     args.handle = bo->handle;
 
-    drmCommandWriteRead(bo->mgr->rws->fd,
+    drmCommandWriteRead(bo->rws->fd,
                         DRM_RADEON_GEM_GET_TILING,
                         &args,
                         sizeof(args));
@@ -392,7 +393,7 @@ static void radeon_bo_set_tiling(struct r300_winsys_bo *_buf,
     args.handle = bo->handle;
     args.pitch = pitch;
 
-    drmCommandWriteRead(bo->mgr->rws->fd,
+    drmCommandWriteRead(bo->rws->fd,
                         DRM_RADEON_GEM_SET_TILING,
                         &args,
                         sizeof(args));
@@ -504,6 +505,7 @@ static struct r300_winsys_bo *radeon_winsys_bo_from_handle(struct r300_winsys_sc
     bo->base.base.size = bo->size;
     bo->base.vtbl = &radeon_bo_vtbl;
     bo->mgr = mgr;
+    bo->rws = mgr->rws;
 
     util_hash_table_set(mgr->bo_handles, (void*)(uintptr_t)whandle->handle, bo);
 
@@ -528,14 +530,12 @@ static boolean radeon_winsys_bo_get_handle(struct r300_winsys_bo *buffer,
 {
     struct drm_gem_flink flink = {};
     struct radeon_bo *bo = get_radeon_bo(pb_buffer(buffer));
-    whandle->stride = stride;
-
 
     if (whandle->type == DRM_API_HANDLE_TYPE_SHARED) {
         if (!bo->flinked) {
             flink.handle = bo->handle;
 
-            if (ioctl(bo->mgr->rws->fd, DRM_IOCTL_GEM_FLINK, &flink)) {
+            if (ioctl(bo->rws->fd, DRM_IOCTL_GEM_FLINK, &flink)) {
                 return FALSE;
             }
 
@@ -546,6 +546,8 @@ static boolean radeon_winsys_bo_get_handle(struct r300_winsys_bo *buffer,
     } else if (whandle->type == DRM_API_HANDLE_TYPE_KMS) {
         whandle->handle = bo->handle;
     }
+
+    whandle->stride = stride;
     return TRUE;
 }
 
diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_bo.h b/src/gallium/winsys/radeon/drm/radeon_drm_bo.h
index 4d1f126..cb1afd6 100644
--- a/src/gallium/winsys/radeon/drm/radeon_drm_bo.h
+++ b/src/gallium/winsys/radeon/drm/radeon_drm_bo.h
@@ -44,13 +44,17 @@ struct radeon_bomgr;
 struct radeon_bo {
     struct pb_buffer base;
     struct radeon_bomgr *mgr;
+    struct radeon_drm_winsys *rws;
 
     void *ptr;
     uint32_t size;
     uint32_t handle;
     uint32_t name;
 
-    int cref;
+    int ref_count;
+
+    /* how many command streams is this bo referenced in? */
+    int num_cs_references;
 
     boolean flinked;
     uint32_t flink;
@@ -64,7 +68,7 @@ void radeon_bo_unref(struct radeon_bo *buf);
 
 static INLINE void radeon_bo_ref(struct radeon_bo *bo)
 {
-    p_atomic_inc(&bo->cref);
+    p_atomic_inc(&bo->ref_count);
 }
 
 static INLINE struct pb_buffer *
diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_cs.c b/src/gallium/winsys/radeon/drm/radeon_drm_cs.c
index 6aa3f2e..5b2a17c 100644
--- a/src/gallium/winsys/radeon/drm/radeon_drm_cs.c
+++ b/src/gallium/winsys/radeon/drm/radeon_drm_cs.c
@@ -106,6 +106,7 @@ static struct r300_winsys_cs *radeon_drm_cs_create(struct r300_winsys_screen *rw
     cs->chunks[1].chunk_id = RADEON_CHUNK_ID_RELOCS;
     cs->chunks[1].length_dw = 0;
     cs->chunks[1].chunk_data = (uint64_t)(uintptr_t)cs->relocs;
+    p_atomic_inc(&ws->num_cs);
     return &cs->base;
 }
 
@@ -215,6 +216,7 @@ static void radeon_add_reloc(struct radeon_drm_cs *cs,
 
     /* Initialize the new relocation. */
     radeon_bo_ref(bo);
+    p_atomic_inc(&bo->num_cs_references);
     cs->relocs_bo[cs->crelocs] = bo;
     reloc = &cs->relocs[cs->crelocs];
     reloc->handle = bo->handle;
@@ -315,6 +317,7 @@ static void radeon_drm_cs_emit(struct r300_winsys_cs *rcs)
     /* Unreference buffers, cleanup. */
     for (i = 0; i < cs->crelocs; i++) {
         radeon_bo_unref(cs->relocs_bo[i]);
+        p_atomic_dec(&cs->relocs_bo[i]->num_cs_references);
         cs->relocs_bo[i] = NULL;
     }
 
@@ -330,6 +333,7 @@ static void radeon_drm_cs_emit(struct r300_winsys_cs *rcs)
 static void radeon_drm_cs_destroy(struct r300_winsys_cs *rcs)
 {
     struct radeon_drm_cs *cs = radeon_drm_cs(rcs);
+    p_atomic_dec(&cs->ws->num_cs);
     FREE(cs->relocs_bo);
     FREE(cs->relocs);
     FREE(cs);
diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_cs.h b/src/gallium/winsys/radeon/drm/radeon_drm_cs.h
index b862032..0183b87 100644
--- a/src/gallium/winsys/radeon/drm/radeon_drm_cs.h
+++ b/src/gallium/winsys/radeon/drm/radeon_drm_cs.h
@@ -65,15 +65,16 @@ radeon_drm_cs(struct r300_winsys_cs *base)
     return (struct radeon_drm_cs*)base;
 }
 
-static INLINE int radeon_bo_is_referenced_by_cs(struct radeon_drm_cs *cs,
-                                                struct radeon_bo *bo)
+static INLINE boolean radeon_bo_is_referenced_by_cs(struct radeon_drm_cs *cs,
+                                                    struct radeon_bo *bo)
 {
-    return radeon_get_reloc(cs, bo) != -1;
+    return bo->num_cs_references == bo->rws->num_cs ||
+           (bo->num_cs_references && radeon_get_reloc(cs, bo) != -1);
 }
 
-static INLINE int radeon_bo_is_referenced_by_any_cs(struct radeon_bo *bo)
+static INLINE boolean radeon_bo_is_referenced_by_any_cs(struct radeon_bo *bo)
 {
-    return bo->cref > 1;
+    return bo->num_cs_references;
 }
 
 void radeon_drm_cs_init_functions(struct radeon_drm_winsys *ws);
diff --git a/src/gallium/winsys/radeon/drm/radeon_winsys.h b/src/gallium/winsys/radeon/drm/radeon_winsys.h
index be5614c..f8a89ab 100644
--- a/src/gallium/winsys/radeon/drm/radeon_winsys.h
+++ b/src/gallium/winsys/radeon/drm/radeon_winsys.h
@@ -36,6 +36,7 @@ struct radeon_drm_winsys {
     struct r300_winsys_screen base;
 
     int fd; /* DRM file descriptor */
+    int num_cs; /* The number of command streams created. */
 
     struct pb_manager *kman;
     struct pb_manager *cman;




More information about the mesa-commit mailing list