r300g: improve function radeon_bo_is_referenced_by_cs
authorMarek Olšák <maraeo@gmail.com>
Fri, 11 Feb 2011 06:52:10 +0000 (07:52 +0100)
committerMarek Olšák <maraeo@gmail.com>
Sat, 12 Feb 2011 02:08:39 +0000 (03:08 +0100)
This should prevent calling into radeon_get_reloc when there's
only one context.

src/gallium/winsys/radeon/drm/radeon_drm_bo.c
src/gallium/winsys/radeon/drm/radeon_drm_bo.h
src/gallium/winsys/radeon/drm/radeon_drm_cs.c
src/gallium/winsys/radeon/drm/radeon_drm_cs.h
src/gallium/winsys/radeon/drm/radeon_winsys.h

index a9e913e76219d6a4ae8875c065be66f8caf46c66..47d4f4d78466bba7c6478df5a5d7c11b79e94973 100644 (file)
@@ -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;
 }
 
index 4d1f126db6d98395b3c81ccafc7e104eb2bf2882..cb1afd625785676ac9497f0f392fa631aa565fda 100644 (file)
@@ -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 *
index 6aa3f2ecce13b46475d302bb9054298f3334748c..5b2a17c856e0b4465401f523323afb09c65e5fcd 100644 (file)
@@ -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);
index b862032b1665bc79cefe4f20e4464612211a92de..0183b877a3e7f96e501467149cb0c0d3fb5da900 100644 (file)
@@ -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);
index be5614ce3ec91bf281d4e5461e577ea775de3311..f8a89abcfe45922c040055e3ba3c46aba0902f79 100644 (file)
@@ -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;