i965/bufmgr: Add a BO_ALLOC_ZEROED flag
authorJason Ekstrand <jason.ekstrand@intel.com>
Wed, 12 Jul 2017 23:48:43 +0000 (16:48 -0700)
committerJason Ekstrand <jason.ekstrand@intel.com>
Mon, 17 Jul 2017 20:48:38 +0000 (13:48 -0700)
Reviewed-by: Chad Versace <chadversary@chromium.org>
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
src/mesa/drivers/dri/i965/brw_bufmgr.c
src/mesa/drivers/dri/i965/brw_bufmgr.h

index 64e503fb2be73bc12e02ee1fa2d90823ca90a5a1..46da53d3530928a1492793b66f4721c51de5fd65 100644 (file)
@@ -265,10 +265,20 @@ bo_alloc_internal(struct brw_bufmgr *bufmgr,
    bool alloc_from_cache;
    uint64_t bo_size;
    bool for_render = false;
+   bool zeroed = false;
 
    if (flags & BO_ALLOC_FOR_RENDER)
       for_render = true;
 
+   if (flags & BO_ALLOC_ZEROED)
+      zeroed = true;
+
+   /* FOR_RENDER really means "I'm ok with a busy BO".  This doesn't really
+    * jive with ZEROED as we have to wait for it to be idle before we can
+    * memset.  Just disallow that combination.
+    */
+   assert(!(for_render && zeroed));
+
    /* Round the allocated size up to a power of two number of pages. */
    bucket = bucket_for_size(bufmgr, size);
 
@@ -288,10 +298,12 @@ bo_alloc_internal(struct brw_bufmgr *bufmgr,
 retry:
    alloc_from_cache = false;
    if (bucket != NULL && !list_empty(&bucket->head)) {
-      if (for_render) {
+      if (for_render && !zeroed) {
          /* Allocate new render-target BOs from the tail (MRU)
           * of the list, as it will likely be hot in the GPU
-          * cache and in the aperture for us.
+          * cache and in the aperture for us.  If the caller
+          * asked us to zero the buffer, we don't want this
+          * because we are going to mmap it.
           */
          bo = LIST_ENTRY(struct brw_bo, bucket->head.prev, head);
          list_del(&bo->head);
@@ -324,6 +336,15 @@ retry:
             bo_free(bo);
             goto retry;
          }
+
+         if (zeroed) {
+            void *map = brw_bo_map(NULL, bo, MAP_WRITE | MAP_RAW);
+            if (!map) {
+               bo_free(bo);
+               goto retry;
+            }
+            memset(map, 0, bo_size);
+         }
       }
    }
 
@@ -340,6 +361,9 @@ retry:
       memclear(create);
       create.size = bo_size;
 
+      /* All new BOs we get from the kernel are zeroed, so we don't need to
+       * worry about that here.
+       */
       ret = drmIoctl(bufmgr->fd, DRM_IOCTL_I915_GEM_CREATE, &create);
       if (ret != 0) {
          free(bo);
index 01a540f5315be15bb9d06b100f9d38510054435b..6a6051bb71ca1488d4833cac0347bd83391e166a 100644 (file)
@@ -135,6 +135,7 @@ struct brw_bo {
 };
 
 #define BO_ALLOC_FOR_RENDER (1<<0)
+#define BO_ALLOC_ZEROED     (1<<1)
 
 /**
  * Allocate a buffer object.