Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
5563 | serge | 1 | /********************************************************** |
2 | * Copyright 2009 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 | * TODO: Have the query pool always ask the fence manager for |
||
37 | * SVGA_FENCE_FLAG_QUERY signaled. Unfortunately, pb_fenced doesn't |
||
38 | * support that currently, so we'd have to create a separate |
||
39 | * pb_fence_ops wrapper that does this implicitly. |
||
40 | */ |
||
41 | |||
42 | /** |
||
43 | * vmw_pools_cleanup - Destroy the buffer pools. |
||
44 | * |
||
45 | * @vws: pointer to a struct vmw_winsys_screen. |
||
46 | */ |
||
47 | void |
||
48 | vmw_pools_cleanup(struct vmw_winsys_screen *vws) |
||
49 | { |
||
50 | if(vws->pools.gmr_fenced) |
||
51 | vws->pools.gmr_fenced->destroy(vws->pools.gmr_fenced); |
||
52 | if (vws->pools.query_fenced) |
||
53 | vws->pools.query_fenced->destroy(vws->pools.query_fenced); |
||
54 | |||
55 | /* gmr_mm pool is already destroyed above */ |
||
56 | |||
57 | if (vws->pools.gmr_slab_fenced) |
||
58 | vws->pools.gmr_slab_fenced->destroy(vws->pools.gmr_slab_fenced); |
||
59 | |||
60 | if(vws->pools.gmr) |
||
61 | vws->pools.gmr->destroy(vws->pools.gmr); |
||
62 | if(vws->pools.query) |
||
63 | vws->pools.query->destroy(vws->pools.query); |
||
64 | } |
||
65 | |||
66 | |||
67 | /** |
||
68 | * vmw_query_pools_init - Create a pool of query buffers. |
||
69 | * |
||
70 | * @vws: Pointer to a struct vmw_winsys_screen. |
||
71 | * |
||
72 | * Typically this pool should be created on demand when we |
||
73 | * detect that the app will be using queries. There's nothing |
||
74 | * special with this pool other than the backing kernel buffer size, |
||
75 | * which is limited to 8192. |
||
76 | */ |
||
77 | boolean |
||
78 | vmw_query_pools_init(struct vmw_winsys_screen *vws) |
||
79 | { |
||
80 | vws->pools.query = vmw_gmr_bufmgr_create(vws); |
||
81 | if(!vws->pools.query) |
||
82 | return FALSE; |
||
83 | |||
84 | vws->pools.query_mm = mm_bufmgr_create(vws->pools.query, |
||
85 | VMW_QUERY_POOL_SIZE, |
||
86 | 3 /* 8 alignment */); |
||
87 | if(!vws->pools.query_mm) |
||
88 | goto out_no_query_mm; |
||
89 | |||
90 | vws->pools.query_fenced = fenced_bufmgr_create( |
||
91 | vws->pools.query_mm, |
||
92 | vmw_fence_ops_create(vws), |
||
93 | VMW_QUERY_POOL_SIZE, |
||
94 | ~0); |
||
95 | |||
96 | if(!vws->pools.query_fenced) |
||
97 | goto out_no_query_fenced; |
||
98 | |||
99 | return TRUE; |
||
100 | |||
101 | out_no_query_fenced: |
||
102 | vws->pools.query_mm->destroy(vws->pools.query_mm); |
||
103 | out_no_query_mm: |
||
104 | vws->pools.query->destroy(vws->pools.query); |
||
105 | return FALSE; |
||
106 | } |
||
107 | |||
108 | /** |
||
109 | * vmw_pools_init - Create a pool of GMR buffers. |
||
110 | * |
||
111 | * @vws: Pointer to a struct vmw_winsys_screen. |
||
112 | */ |
||
113 | boolean |
||
114 | vmw_pools_init(struct vmw_winsys_screen *vws) |
||
115 | { |
||
116 | struct pb_desc desc; |
||
117 | |||
118 | vws->pools.gmr = vmw_gmr_bufmgr_create(vws); |
||
119 | if(!vws->pools.gmr) |
||
120 | goto error; |
||
121 | |||
122 | vws->pools.gmr_mm = mm_bufmgr_create(vws->pools.gmr, |
||
123 | VMW_GMR_POOL_SIZE, |
||
124 | 12 /* 4096 alignment */); |
||
125 | if(!vws->pools.gmr_mm) |
||
126 | goto error; |
||
127 | |||
128 | /* |
||
129 | * We disallow "CPU" buffers to be created by the fenced_bufmgr_create, |
||
130 | * because that defers "GPU" buffer creation to buffer validation, |
||
131 | * and at buffer validation we have no means of handling failures |
||
132 | * due to pools space shortage or fragmentation. Effectively this |
||
133 | * makes sure all failures are reported immediately on buffer allocation, |
||
134 | * and we can revert to allocating directly from the kernel. |
||
135 | */ |
||
136 | vws->pools.gmr_fenced = fenced_bufmgr_create( |
||
137 | vws->pools.gmr_mm, |
||
138 | vmw_fence_ops_create(vws), |
||
139 | VMW_GMR_POOL_SIZE, |
||
140 | 0); |
||
141 | |||
142 | #ifdef DEBUG |
||
143 | vws->pools.gmr_fenced = pb_debug_manager_create(vws->pools.gmr_fenced, |
||
144 | 4096, |
||
145 | 4096); |
||
146 | #endif |
||
147 | if(!vws->pools.gmr_fenced) |
||
148 | goto error; |
||
149 | |||
150 | /* |
||
151 | * The slab pool allocates buffers directly from the kernel except |
||
152 | * for very small buffers which are allocated from a slab in order |
||
153 | * not to waste memory, since a kernel buffer is a minimum 4096 bytes. |
||
154 | * |
||
155 | * Here we use it only for emergency in the case our pre-allocated |
||
156 | * buffer pool runs out of memory. |
||
157 | */ |
||
158 | desc.alignment = 64; |
||
159 | desc.usage = ~0; |
||
160 | vws->pools.gmr_slab = pb_slab_range_manager_create(vws->pools.gmr, |
||
161 | 64, |
||
162 | 8192, |
||
163 | 16384, |
||
164 | &desc); |
||
165 | if (!vws->pools.gmr_slab) |
||
166 | goto error; |
||
167 | |||
168 | vws->pools.gmr_slab_fenced = |
||
169 | fenced_bufmgr_create(vws->pools.gmr_slab, |
||
170 | vmw_fence_ops_create(vws), |
||
171 | VMW_MAX_BUFFER_SIZE, |
||
172 | 0); |
||
173 | |||
174 | if (!vws->pools.gmr_slab_fenced) |
||
175 | goto error; |
||
176 | |||
177 | vws->pools.query_fenced = NULL; |
||
178 | vws->pools.query_mm = NULL; |
||
179 | vws->pools.query = NULL; |
||
180 | |||
181 | return TRUE; |
||
182 | |||
183 | error: |
||
184 | vmw_pools_cleanup(vws); |
||
185 | return FALSE; |
||
186 | } |
||
187 |