[intel] Add a single-entry relocation buffer cache.
authorEric Anholt <eric@anholt.net>
Fri, 4 Jan 2008 00:08:40 +0000 (16:08 -0800)
committerEric Anholt <eric@anholt.net>
Fri, 4 Jan 2008 00:53:23 +0000 (16:53 -0800)
By avoiding the repeated relocation buffer creation/map/unmap/destroy for each
new batch buffer, this improves OpenArena framerates by 30%.  Caching batch
buffers themselves doesn't appear to be a significant performance win over
this change.

src/mesa/drivers/dri/intel/intel_bufmgr_ttm.c

index a5307f1939bc271f9b55be56a6f41052dbc84f98..bd37efa98794b328e8fb866dfe8bf6b8bb116b1d 100644 (file)
@@ -79,6 +79,9 @@ typedef struct _dri_bufmgr_ttm {
 
     uint32_t max_relocs;
     struct intel_bo_list list; /* list of buffers to be validated */
+
+    drmBO *cached_reloc_buf;
+    uint32_t *cached_reloc_buf_data;
 } dri_bufmgr_ttm;
 
 /**
@@ -322,32 +325,40 @@ intel_setup_reloc_list(dri_bo *bo)
     if (bo_ttm->reloc_buf != NULL)
        return 0;
 
-    bo_ttm->reloc_buf = malloc(sizeof(bo_ttm->drm_bo));
     bo_ttm->relocs = malloc(sizeof(struct dri_ttm_reloc) *
                            bufmgr_ttm->max_relocs);
 
-    ret = drmBOCreate(bufmgr_ttm->fd,
-                     RELOC_BUF_SIZE(bufmgr_ttm->max_relocs), 0,
-                     NULL,
-                     DRM_BO_FLAG_MEM_LOCAL |
-                     DRM_BO_FLAG_READ |
-                     DRM_BO_FLAG_WRITE |
-                     DRM_BO_FLAG_MAPPABLE |
-                     DRM_BO_FLAG_CACHED,
-                     0, bo_ttm->reloc_buf);
-    if (ret) {
-       fprintf(stderr, "Failed to create relocation BO: %s\n",
-              strerror(-ret));
-       return ret;
-    }
+    if (bufmgr_ttm->cached_reloc_buf != NULL) {
+       bo_ttm->reloc_buf = bufmgr_ttm->cached_reloc_buf;
+       bo_ttm->reloc_buf_data = bufmgr_ttm->cached_reloc_buf_data;
 
-    ret = drmBOMap(bufmgr_ttm->fd, bo_ttm->reloc_buf,
-                  DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE,
-                  0, (void **)&bo_ttm->reloc_buf_data);
-    if (ret) {
-       fprintf(stderr, "Failed to map relocation BO: %s\n",
-              strerror(-ret));
-       return ret;
+       bufmgr_ttm->cached_reloc_buf = NULL;
+       bufmgr_ttm->cached_reloc_buf_data = NULL;
+    } else {
+       bo_ttm->reloc_buf = malloc(sizeof(bo_ttm->drm_bo));
+       ret = drmBOCreate(bufmgr_ttm->fd,
+                        RELOC_BUF_SIZE(bufmgr_ttm->max_relocs), 0,
+                        NULL,
+                        DRM_BO_FLAG_MEM_LOCAL |
+                        DRM_BO_FLAG_READ |
+                        DRM_BO_FLAG_WRITE |
+                        DRM_BO_FLAG_MAPPABLE |
+                        DRM_BO_FLAG_CACHED,
+                        0, bo_ttm->reloc_buf);
+       if (ret) {
+         fprintf(stderr, "Failed to create relocation BO: %s\n",
+                 strerror(-ret));
+         return ret;
+       }
+
+       ret = drmBOMap(bufmgr_ttm->fd, bo_ttm->reloc_buf,
+                     DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE,
+                     0, (void **)&bo_ttm->reloc_buf_data);
+       if (ret) {
+         fprintf(stderr, "Failed to map relocation BO: %s\n",
+                 strerror(-ret));
+         return ret;
+       }
     }
 
     /* Initialize the relocation list with the header:
@@ -506,10 +517,19 @@ dri_ttm_bo_unreference(dri_bo *buf)
                 dri_bo_unreference(ttm_buf->relocs[i].target_buf);
            free(ttm_buf->relocs);
 
-           /* Free the kernel BO containing relocation entries */
-           drmBOUnmap(bufmgr_ttm->fd, ttm_buf->reloc_buf);
-           drmBOUnreference(bufmgr_ttm->fd, ttm_buf->reloc_buf);
-           free(ttm_buf->reloc_buf);
+           if (bufmgr_ttm->cached_reloc_buf == NULL) {
+              /* Cache a single relocation buffer allocation to avoid
+               * repeated create/map/unmap/destroy for batchbuffer
+               * relocations.
+               */
+              bufmgr_ttm->cached_reloc_buf = ttm_buf->reloc_buf;
+              bufmgr_ttm->cached_reloc_buf_data = ttm_buf->reloc_buf_data;
+           } else {
+              /* Free the kernel BO containing relocation entries */
+              drmBOUnmap(bufmgr_ttm->fd, ttm_buf->reloc_buf);
+              drmBOUnreference(bufmgr_ttm->fd, ttm_buf->reloc_buf);
+              free(ttm_buf->reloc_buf);
+           }
        }
 
        ret = drmBOUnreference(bufmgr_ttm->fd, &ttm_buf->drm_bo);
@@ -656,6 +676,13 @@ dri_bufmgr_ttm_destroy(dri_bufmgr *bufmgr)
 {
     dri_bufmgr_ttm *bufmgr_ttm = (dri_bufmgr_ttm *)bufmgr;
 
+    if (bufmgr_ttm->cached_reloc_buf) {
+       /* Free the cached kernel BO containing relocation entries */
+       drmBOUnmap(bufmgr_ttm->fd, bufmgr_ttm->cached_reloc_buf);
+       drmBOUnreference(bufmgr_ttm->fd, bufmgr_ttm->cached_reloc_buf);
+       free(bufmgr_ttm->cached_reloc_buf);
+    }
+
     intel_free_validate_list(bufmgr_ttm);
 
     free(bufmgr);