Merge commit 'origin/master' into gallium-0.2
[mesa.git] / src / gallium / winsys / drm / intel / common / ws_dri_drmpool.c
1 /**************************************************************************
2 *
3 * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
18 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20 * USE OR OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * The above copyright notice and this permission notice (including the
23 * next paragraph) shall be included in all copies or substantial portions
24 * of the Software.
25 *
26 *
27 **************************************************************************/
28 /*
29 * Authors: Thomas Hellström <thomas-at-tungstengraphics-dot-com>
30 */
31
32 #include <xf86drm.h>
33 #include <stdlib.h>
34 #include <unistd.h>
35 #include "ws_dri_bufpool.h"
36 #include "ws_dri_bufmgr.h"
37 #include "assert.h"
38
39 /*
40 * Buffer pool implementation using DRM buffer objects as DRI buffer objects.
41 */
42
43 static void *
44 pool_create(struct _DriBufferPool *pool,
45 unsigned long size, uint64_t flags, unsigned hint,
46 unsigned alignment)
47 {
48 drmBO *buf = (drmBO *) malloc(sizeof(*buf));
49 int ret;
50 unsigned pageSize = getpagesize();
51
52 if (!buf)
53 return NULL;
54
55 if ((alignment > pageSize) && (alignment % pageSize)) {
56 free(buf);
57 return NULL;
58 }
59
60 ret = drmBOCreate(pool->fd, size, alignment / pageSize,
61 NULL,
62 flags, hint, buf);
63 if (ret) {
64 free(buf);
65 return NULL;
66 }
67
68 return (void *) buf;
69 }
70
71 static void *
72 pool_reference(struct _DriBufferPool *pool, unsigned handle)
73 {
74 drmBO *buf = (drmBO *) malloc(sizeof(*buf));
75 int ret;
76
77 if (!buf)
78 return NULL;
79
80 ret = drmBOReference(pool->fd, handle, buf);
81
82 if (ret) {
83 free(buf);
84 return NULL;
85 }
86
87 return (void *) buf;
88 }
89
90 static int
91 pool_destroy(struct _DriBufferPool *pool, void *private)
92 {
93 int ret;
94 drmBO *buf = (drmBO *) private;
95 driReadLockKernelBO();
96 ret = drmBOUnreference(pool->fd, buf);
97 free(buf);
98 driReadUnlockKernelBO();
99 return ret;
100 }
101
102 static int
103 pool_unreference(struct _DriBufferPool *pool, void *private)
104 {
105 int ret;
106 drmBO *buf = (drmBO *) private;
107 driReadLockKernelBO();
108 ret = drmBOUnreference(pool->fd, buf);
109 free(buf);
110 driReadUnlockKernelBO();
111 return ret;
112 }
113
114 static int
115 pool_map(struct _DriBufferPool *pool, void *private, unsigned flags,
116 int hint, pipe_mutex *mutex, void **virtual)
117 {
118 drmBO *buf = (drmBO *) private;
119 int ret;
120
121 driReadLockKernelBO();
122 ret = drmBOMap(pool->fd, buf, flags, hint, virtual);
123 driReadUnlockKernelBO();
124 return ret;
125 }
126
127 static int
128 pool_unmap(struct _DriBufferPool *pool, void *private)
129 {
130 drmBO *buf = (drmBO *) private;
131 int ret;
132
133 driReadLockKernelBO();
134 ret = drmBOUnmap(pool->fd, buf);
135 driReadUnlockKernelBO();
136
137 return ret;
138 }
139
140 static unsigned long
141 pool_offset(struct _DriBufferPool *pool, void *private)
142 {
143 drmBO *buf = (drmBO *) private;
144 unsigned long offset;
145
146 driReadLockKernelBO();
147 assert(buf->flags & DRM_BO_FLAG_NO_MOVE);
148 offset = buf->offset;
149 driReadUnlockKernelBO();
150
151 return buf->offset;
152 }
153
154 static unsigned long
155 pool_poolOffset(struct _DriBufferPool *pool, void *private)
156 {
157 return 0;
158 }
159
160 static uint64_t
161 pool_flags(struct _DriBufferPool *pool, void *private)
162 {
163 drmBO *buf = (drmBO *) private;
164 uint64_t flags;
165
166 driReadLockKernelBO();
167 flags = buf->flags;
168 driReadUnlockKernelBO();
169
170 return flags;
171 }
172
173
174 static unsigned long
175 pool_size(struct _DriBufferPool *pool, void *private)
176 {
177 drmBO *buf = (drmBO *) private;
178 unsigned long size;
179
180 driReadLockKernelBO();
181 size = buf->size;
182 driReadUnlockKernelBO();
183
184 return buf->size;
185 }
186
187 static int
188 pool_fence(struct _DriBufferPool *pool, void *private,
189 struct _DriFenceObject *fence)
190 {
191 /*
192 * Noop. The kernel handles all fencing.
193 */
194
195 return 0;
196 }
197
198 static drmBO *
199 pool_kernel(struct _DriBufferPool *pool, void *private)
200 {
201 return (drmBO *) private;
202 }
203
204 static int
205 pool_waitIdle(struct _DriBufferPool *pool, void *private, pipe_mutex *mutex,
206 int lazy)
207 {
208 drmBO *buf = (drmBO *) private;
209 int ret;
210
211 driReadLockKernelBO();
212 ret = drmBOWaitIdle(pool->fd, buf, (lazy) ? DRM_BO_HINT_WAIT_LAZY:0);
213 driReadUnlockKernelBO();
214
215 return ret;
216 }
217
218
219 static void
220 pool_takedown(struct _DriBufferPool *pool)
221 {
222 free(pool);
223 }
224
225 /*static int
226 pool_setStatus(struct _DriBufferPool *pool, void *private,
227 uint64_t flag_diff, uint64_t old_flags)
228 {
229 drmBO *buf = (drmBO *) private;
230 uint64_t new_flags = old_flags ^ flag_diff;
231 int ret;
232
233 driReadLockKernelBO();
234 ret = drmBOSetStatus(pool->fd, buf, new_flags, flag_diff,
235 0, 0, 0);
236 driReadUnlockKernelBO();
237 return ret;
238 }*/
239
240 struct _DriBufferPool *
241 driDRMPoolInit(int fd)
242 {
243 struct _DriBufferPool *pool;
244
245 pool = (struct _DriBufferPool *) malloc(sizeof(*pool));
246
247 if (!pool)
248 return NULL;
249
250 pool->fd = fd;
251 pool->map = &pool_map;
252 pool->unmap = &pool_unmap;
253 pool->destroy = &pool_destroy;
254 pool->offset = &pool_offset;
255 pool->poolOffset = &pool_poolOffset;
256 pool->flags = &pool_flags;
257 pool->size = &pool_size;
258 pool->create = &pool_create;
259 pool->fence = &pool_fence;
260 pool->kernel = &pool_kernel;
261 pool->validate = NULL;
262 pool->waitIdle = &pool_waitIdle;
263 pool->takeDown = &pool_takedown;
264 pool->reference = &pool_reference;
265 pool->unreference = &pool_unreference;
266 pool->data = NULL;
267 return pool;
268 }