1 /********************************************************** 2 * Copyright 2009-2015 VMware, Inc. All rights reserved. 3 * 4 * Permission is hereby granted, free of charge, to any person 5 * obtaining a copy of this software and associated documentation 6 * files (the "Software"), to deal in the Software without 7 * restriction, including without limitation the rights to use, copy, 8 * modify, merge, publish, distribute, sublicense, and/or sell copies 9 * of the Software, and to permit persons to whom the Software is 10 * furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice shall be 13 * included in all copies or substantial portions of the Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 * SOFTWARE. 23 * 24 **********************************************************/ 25 26 27 #include "vmw_screen.h" 28 29 #include "vmw_buffer.h" 30 #include "vmw_fence.h" 31 32 #include "pipebuffer/pb_buffer.h" 33 #include "pipebuffer/pb_bufmgr.h" 34 35 /** 36 * vmw_pools_cleanup - Destroy the buffer pools. 37 * 38 * @vws: pointer to a struct vmw_winsys_screen. 39 */ 40 void 41 vmw_pools_cleanup(struct vmw_winsys_screen *vws) 42 { 43 if (vws->pools.mob_shader_slab_fenced) 44 vws->pools.mob_shader_slab_fenced->destroy 45 (vws->pools.mob_shader_slab_fenced); 46 if (vws->pools.mob_shader_slab) 47 vws->pools.mob_shader_slab->destroy(vws->pools.mob_shader_slab); 48 if (vws->pools.mob_fenced) 49 vws->pools.mob_fenced->destroy(vws->pools.mob_fenced); 50 if (vws->pools.mob_cache) 51 vws->pools.mob_cache->destroy(vws->pools.mob_cache); 52 53 if (vws->pools.query_fenced) 54 vws->pools.query_fenced->destroy(vws->pools.query_fenced); 55 if (vws->pools.query_mm) 56 vws->pools.query_mm->destroy(vws->pools.query_mm); 57 58 if(vws->pools.gmr_fenced) 59 vws->pools.gmr_fenced->destroy(vws->pools.gmr_fenced); 60 if (vws->pools.gmr_mm) 61 vws->pools.gmr_mm->destroy(vws->pools.gmr_mm); 62 if (vws->pools.gmr_slab_fenced) 63 vws->pools.gmr_slab_fenced->destroy(vws->pools.gmr_slab_fenced); 64 if (vws->pools.gmr_slab) 65 vws->pools.gmr_slab->destroy(vws->pools.gmr_slab); 66 67 if(vws->pools.gmr) 68 vws->pools.gmr->destroy(vws->pools.gmr); 69 } 70 71 72 /** 73 * vmw_query_pools_init - Create a pool of query buffers. 74 * 75 * @vws: Pointer to a struct vmw_winsys_screen. 76 * 77 * Typically this pool should be created on demand when we 78 * detect that the app will be using queries. There's nothing 79 * special with this pool other than the backing kernel buffer sizes, 80 * which are limited to 8192. 81 * If there is a performance issue with allocation and freeing of the 82 * query slabs, it should be easily fixable by allocating them out 83 * of a buffer cache. 84 */ 85 boolean 86 vmw_query_pools_init(struct vmw_winsys_screen *vws) 87 { 88 struct pb_desc desc; 89 90 desc.alignment = 16; 91 desc.usage = ~(VMW_BUFFER_USAGE_SHARED | VMW_BUFFER_USAGE_SYNC); 92 93 vws->pools.query_mm = pb_slab_range_manager_create(vws->pools.gmr, 16, 128, 94 VMW_QUERY_POOL_SIZE, 95 &desc); 96 if (!vws->pools.query_mm) 97 return FALSE; 98 99 vws->pools.query_fenced = simple_fenced_bufmgr_create( 100 vws->pools.query_mm, vws->fence_ops); 101 102 if(!vws->pools.query_fenced) 103 goto out_no_query_fenced; 104 105 return TRUE; 106 107 out_no_query_fenced: 108 vws->pools.query_mm->destroy(vws->pools.query_mm); 109 return FALSE; 110 } 111 112 /** 113 * vmw_mob_pool_init - Create a pool of fenced kernel buffers. 114 * 115 * @vws: Pointer to a struct vmw_winsys_screen. 116 * 117 * Typically this pool should be created on demand when we 118 * detect that the app will be using MOB buffers. 119 */ 120 boolean 121 vmw_mob_pools_init(struct vmw_winsys_screen *vws) 122 { 123 struct pb_desc desc; 124 125 vws->pools.mob_cache = 126 pb_cache_manager_create(vws->pools.gmr, 100000, 2.0f, 127 VMW_BUFFER_USAGE_SHARED, 128 64 * 1024 * 1024); 129 if (!vws->pools.mob_cache) 130 return FALSE; 131 132 vws->pools.mob_fenced = 133 simple_fenced_bufmgr_create(vws->pools.mob_cache, 134 vws->fence_ops); 135 if(!vws->pools.mob_fenced) 136 goto out_no_mob_fenced; 137 138 desc.alignment = 64; 139 desc.usage = ~(SVGA_BUFFER_USAGE_PINNED | VMW_BUFFER_USAGE_SHARED | 140 VMW_BUFFER_USAGE_SYNC); 141 vws->pools.mob_shader_slab = 142 pb_slab_range_manager_create(vws->pools.mob_cache, 143 64, 144 8192, 145 16384, 146 &desc); 147 if(!vws->pools.mob_shader_slab) 148 goto out_no_mob_shader_slab; 149 150 vws->pools.mob_shader_slab_fenced = 151 simple_fenced_bufmgr_create(vws->pools.mob_shader_slab, 152 vws->fence_ops); 153 if(!vws->pools.mob_fenced) 154 goto out_no_mob_shader_slab_fenced; 155 156 return TRUE; 157 158 out_no_mob_shader_slab_fenced: 159 vws->pools.mob_shader_slab->destroy(vws->pools.mob_shader_slab); 160 out_no_mob_shader_slab: 161 vws->pools.mob_fenced->destroy(vws->pools.mob_fenced); 162 out_no_mob_fenced: 163 vws->pools.mob_cache->destroy(vws->pools.mob_cache); 164 return FALSE; 165 } 166 167 /** 168 * vmw_pools_init - Create a pool of GMR buffers. 169 * 170 * @vws: Pointer to a struct vmw_winsys_screen. 171 */ 172 boolean 173 vmw_pools_init(struct vmw_winsys_screen *vws) 174 { 175 struct pb_desc desc; 176 177 vws->pools.gmr = vmw_gmr_bufmgr_create(vws); 178 if(!vws->pools.gmr) 179 goto error; 180 181 if ((vws->base.have_gb_objects && vws->base.have_gb_dma) || 182 !vws->base.have_gb_objects) { 183 /* 184 * A managed pool for DMA buffers. 185 */ 186 vws->pools.gmr_mm = mm_bufmgr_create(vws->pools.gmr, 187 VMW_GMR_POOL_SIZE, 188 12 /* 4096 alignment */); 189 if(!vws->pools.gmr_mm) 190 goto error; 191 192 vws->pools.gmr_fenced = simple_fenced_bufmgr_create 193 (vws->pools.gmr_mm, vws->fence_ops); 194 195 #ifdef DEBUG 196 vws->pools.gmr_fenced = pb_debug_manager_create(vws->pools.gmr_fenced, 197 4096, 198 4096); 199 #endif 200 if(!vws->pools.gmr_fenced) 201 goto error; 202 203 /* 204 * The slab pool allocates buffers directly from the kernel except 205 * for very small buffers which are allocated from a slab in order 206 * not to waste memory, since a kernel buffer is a minimum 4096 bytes. 207 * 208 * Here we use it only for emergency in the case our pre-allocated 209 * managed buffer pool runs out of memory. 210 */ 211 212 desc.alignment = 64; 213 desc.usage = ~(SVGA_BUFFER_USAGE_PINNED | SVGA_BUFFER_USAGE_SHADER | 214 VMW_BUFFER_USAGE_SHARED | VMW_BUFFER_USAGE_SYNC); 215 vws->pools.gmr_slab = pb_slab_range_manager_create(vws->pools.gmr, 216 64, 217 8192, 218 16384, 219 &desc); 220 if (!vws->pools.gmr_slab) 221 goto error; 222 223 vws->pools.gmr_slab_fenced = 224 simple_fenced_bufmgr_create(vws->pools.gmr_slab, vws->fence_ops); 225 226 if (!vws->pools.gmr_slab_fenced) 227 goto error; 228 } 229 230 vws->pools.query_fenced = NULL; 231 vws->pools.query_mm = NULL; 232 vws->pools.mob_cache = NULL; 233 234 if (vws->base.have_gb_objects && !vmw_mob_pools_init(vws)) 235 goto error; 236 237 return TRUE; 238 239 error: 240 vmw_pools_cleanup(vws); 241 return FALSE; 242 } 243