android: freedreno: move a2xx disasm out of gallium
[mesa.git] / src / gallium / winsys / svga / drm / vmw_screen_pools.c
index b9823d7857502fb50a3e47093877549955920672..29cdc69e285fb86ec82b18aa68589749ceb44bbd 100644 (file)
@@ -1,5 +1,5 @@
 /**********************************************************
- * Copyright 2009 VMware, Inc.  All rights reserved.
+ * Copyright 2009-2015 VMware, Inc.  All rights reserved.
  *
  * Permission is hereby granted, free of charge, to any person
  * obtaining a copy of this software and associated documentation
 #include "pipebuffer/pb_buffer.h"
 #include "pipebuffer/pb_bufmgr.h"
 
+/**
+ * vmw_pools_cleanup - Destroy the buffer pools.
+ *
+ * @vws: pointer to a struct vmw_winsys_screen.
+ */
 void
 vmw_pools_cleanup(struct vmw_winsys_screen *vws)
 {
+   if (vws->pools.mob_shader_slab_fenced)
+      vws->pools.mob_shader_slab_fenced->destroy
+         (vws->pools.mob_shader_slab_fenced);
+   if (vws->pools.mob_shader_slab)
+      vws->pools.mob_shader_slab->destroy(vws->pools.mob_shader_slab);
+   if (vws->pools.mob_fenced)
+      vws->pools.mob_fenced->destroy(vws->pools.mob_fenced);
+   if (vws->pools.mob_cache)
+      vws->pools.mob_cache->destroy(vws->pools.mob_cache);
+
+   if (vws->pools.query_fenced)
+      vws->pools.query_fenced->destroy(vws->pools.query_fenced);
+   if (vws->pools.query_mm)
+      vws->pools.query_mm->destroy(vws->pools.query_mm);
+
    if(vws->pools.gmr_fenced)
       vws->pools.gmr_fenced->destroy(vws->pools.gmr_fenced);
-
-   /* gmr_mm pool is already destroyed above */
+   if (vws->pools.gmr_mm)
+      vws->pools.gmr_mm->destroy(vws->pools.gmr_mm);
+   if (vws->pools.gmr_slab_fenced)
+      vws->pools.gmr_slab_fenced->destroy(vws->pools.gmr_slab_fenced);
+   if (vws->pools.gmr_slab)
+      vws->pools.gmr_slab->destroy(vws->pools.gmr_slab);
 
    if(vws->pools.gmr)
       vws->pools.gmr->destroy(vws->pools.gmr);
 }
 
 
+/**
+ * vmw_query_pools_init - Create a pool of query buffers.
+ *
+ * @vws: Pointer to a struct vmw_winsys_screen.
+ *
+ * Typically this pool should be created on demand when we
+ * detect that the app will be using queries. There's nothing
+ * special with this pool other than the backing kernel buffer sizes,
+ * which are limited to 8192.
+ * If there is a performance issue with allocation and freeing of the
+ * query slabs, it should be easily fixable by allocating them out
+ * of a buffer cache.
+ */
+boolean
+vmw_query_pools_init(struct vmw_winsys_screen *vws)
+{
+   struct pb_desc desc;
+
+   desc.alignment = 16;
+   desc.usage = ~(VMW_BUFFER_USAGE_SHARED | VMW_BUFFER_USAGE_SYNC);
+
+   vws->pools.query_mm = pb_slab_range_manager_create(vws->pools.gmr, 16, 128,
+                                                      VMW_QUERY_POOL_SIZE,
+                                                      &desc);
+   if (!vws->pools.query_mm)
+      return FALSE;
+
+   vws->pools.query_fenced = simple_fenced_bufmgr_create(
+      vws->pools.query_mm, vws->fence_ops);
+
+   if(!vws->pools.query_fenced)
+      goto out_no_query_fenced;
+
+   return TRUE;
+
+  out_no_query_fenced:
+   vws->pools.query_mm->destroy(vws->pools.query_mm);
+   return FALSE;
+}
+
+/**
+ * vmw_mob_pool_init - Create a pool of fenced kernel buffers.
+ *
+ * @vws: Pointer to a struct vmw_winsys_screen.
+ *
+ * Typically this pool should be created on demand when we
+ * detect that the app will be using MOB buffers.
+ */
+boolean
+vmw_mob_pools_init(struct vmw_winsys_screen *vws)
+{
+   struct pb_desc desc;
+
+   vws->pools.mob_cache = 
+      pb_cache_manager_create(vws->pools.gmr, 100000, 2.0f,
+                              VMW_BUFFER_USAGE_SHARED,
+                              64 * 1024 * 1024);
+   if (!vws->pools.mob_cache)
+      return FALSE;
+
+   vws->pools.mob_fenced = 
+      simple_fenced_bufmgr_create(vws->pools.mob_cache,
+                                  vws->fence_ops);
+   if(!vws->pools.mob_fenced)
+      goto out_no_mob_fenced;
+   
+   desc.alignment = 64;
+   desc.usage = ~(SVGA_BUFFER_USAGE_PINNED | VMW_BUFFER_USAGE_SHARED |
+                  VMW_BUFFER_USAGE_SYNC);
+   vws->pools.mob_shader_slab =
+      pb_slab_range_manager_create(vws->pools.mob_cache,
+                                   64,
+                                   8192,
+                                   16384,
+                                   &desc);
+   if(!vws->pools.mob_shader_slab)
+      goto out_no_mob_shader_slab;
+
+   vws->pools.mob_shader_slab_fenced =
+      simple_fenced_bufmgr_create(vws->pools.mob_shader_slab,
+                                 vws->fence_ops);
+   if(!vws->pools.mob_shader_slab_fenced)
+      goto out_no_mob_shader_slab_fenced;
+
+   return TRUE;
+
+ out_no_mob_shader_slab_fenced:
+   vws->pools.mob_shader_slab->destroy(vws->pools.mob_shader_slab);
+ out_no_mob_shader_slab:
+   vws->pools.mob_fenced->destroy(vws->pools.mob_fenced);
+ out_no_mob_fenced:
+   vws->pools.mob_cache->destroy(vws->pools.mob_cache);
+   return FALSE;
+}
+
+/**
+ * vmw_pools_init - Create a pool of GMR buffers.
+ *
+ * @vws: Pointer to a struct vmw_winsys_screen.
+ */
 boolean
 vmw_pools_init(struct vmw_winsys_screen *vws)
 {
+   struct pb_desc desc;
+
    vws->pools.gmr = vmw_gmr_bufmgr_create(vws);
    if(!vws->pools.gmr)
       goto error;
 
-   vws->pools.gmr_mm = mm_bufmgr_create(vws->pools.gmr,
-                                        VMW_GMR_POOL_SIZE,
-                                        12 /* 4096 alignment */);
-   if(!vws->pools.gmr_mm)
-      goto error;
+   if ((vws->base.have_gb_objects && vws->base.have_gb_dma) ||
+       !vws->base.have_gb_objects) {
+      /*
+       * A managed pool for DMA buffers.
+       */
+      vws->pools.gmr_mm = mm_bufmgr_create(vws->pools.gmr,
+                                           VMW_GMR_POOL_SIZE,
+                                           12 /* 4096 alignment */);
+      if(!vws->pools.gmr_mm)
+         goto error;
+
+      vws->pools.gmr_fenced = simple_fenced_bufmgr_create
+         (vws->pools.gmr_mm, vws->fence_ops);
+
+#ifdef DEBUG
+      vws->pools.gmr_fenced = pb_debug_manager_create(vws->pools.gmr_fenced,
+                                                      4096,
+                                                      4096);
+#endif
+      if(!vws->pools.gmr_fenced)
+         goto error;
 
    /*
-    * GMR buffers are typically shortlived, but it's possible that at a given
-    * instance a buffer is mapped. So to avoid stalling we tell pipebuffer to
-    * forbid creation of buffers beyond half the GMR pool size,
+    * The slab pool allocates buffers directly from the kernel except
+    * for very small buffers which are allocated from a slab in order
+    * not to waste memory, since a kernel buffer is a minimum 4096 bytes.
     *
-    * XXX: It is unclear weather we want to limit the total amount of temporary
-    * malloc memory used to backup unvalidated GMR buffers. On one hand it is
-    * preferrable to fail an allocation than exhausting the guest memory with
-    * temporary data, but on the other hand it is possible that a stupid
-    * application creates large vertex buffers and does not use them for a long
-    * time -- since the svga pipe driver only emits the DMA uploads when a
-    * buffer is used for drawing this would effectively disabling swapping GMR
-    * buffers to memory. So far, the preemptively flush already seems to keep
-    * total allocated memory within relatively small numbers, so we don't
-    * limit.
+    * Here we use it only for emergency in the case our pre-allocated
+    * managed buffer pool runs out of memory.
     */
-   vws->pools.gmr_fenced = fenced_bufmgr_create(
-      vws->pools.gmr_mm,
-      vmw_fence_ops_create(vws),
-      VMW_GMR_POOL_SIZE/2,
-      ~0);
 
-#ifdef DEBUG
-   vws->pools.gmr_fenced = pb_debug_manager_create(vws->pools.gmr_fenced,
-                                                  4096,
-                                                  4096);
-#endif
-   if(!vws->pools.gmr_fenced)
+      desc.alignment = 64;
+      desc.usage = ~(SVGA_BUFFER_USAGE_PINNED | SVGA_BUFFER_USAGE_SHADER |
+                     VMW_BUFFER_USAGE_SHARED | VMW_BUFFER_USAGE_SYNC);
+      vws->pools.gmr_slab = pb_slab_range_manager_create(vws->pools.gmr,
+                                                         64,
+                                                         8192,
+                                                         16384,
+                                                         &desc);
+      if (!vws->pools.gmr_slab)
+         goto error;
+
+      vws->pools.gmr_slab_fenced =
+         simple_fenced_bufmgr_create(vws->pools.gmr_slab, vws->fence_ops);
+
+      if (!vws->pools.gmr_slab_fenced)
+         goto error;
+   }
+
+   vws->pools.query_fenced = NULL;
+   vws->pools.query_mm = NULL;
+   vws->pools.mob_cache = NULL;
+
+   if (vws->base.have_gb_objects && !vmw_mob_pools_init(vws))
       goto error;
 
    return TRUE;
@@ -94,4 +240,3 @@ error:
    vmw_pools_cleanup(vws);
    return FALSE;
 }
-