radeon/r200/r300: cleanup some of the renderbuffer code
[mesa.git] / src / gallium / winsys / drm / intel / common / intel_be_device.c
1
2
3 /*
4 * Authors: Keith Whitwell <keithw-at-tungstengraphics-dot-com>
5 * Jakob Bornecrantz <jakob-at-tungstengraphics-dot-com>
6 */
7
8 #include "intel_be_device.h"
9 #include "ws_dri_bufmgr.h"
10 #include "ws_dri_bufpool.h"
11 #include "ws_dri_fencemgr.h"
12
13 #include "pipe/internal/p_winsys_screen.h"
14 #include "pipe/p_defines.h"
15 #include "pipe/p_state.h"
16 #include "pipe/p_inlines.h"
17 #include "util/u_memory.h"
18
19 #include "i915simple/i915_screen.h"
20
21 /* Turn a pipe winsys into an intel/pipe winsys:
22 */
23 static INLINE struct intel_be_device *
24 intel_be_device( struct pipe_winsys *winsys )
25 {
26 return (struct intel_be_device *)winsys;
27 }
28
29
30 /*
31 * Buffer functions.
32 *
33 * Most callbacks map direcly onto dri_bufmgr operations:
34 */
35
36 static void *intel_be_buffer_map(struct pipe_winsys *winsys,
37 struct pipe_buffer *buf,
38 unsigned flags )
39 {
40 unsigned drm_flags = 0;
41
42 if (flags & PIPE_BUFFER_USAGE_CPU_WRITE)
43 drm_flags |= DRM_BO_FLAG_WRITE;
44
45 if (flags & PIPE_BUFFER_USAGE_CPU_READ)
46 drm_flags |= DRM_BO_FLAG_READ;
47
48 return driBOMap( dri_bo(buf), drm_flags, 0 );
49 }
50
51 static void intel_be_buffer_unmap(struct pipe_winsys *winsys,
52 struct pipe_buffer *buf)
53 {
54 driBOUnmap( dri_bo(buf) );
55 }
56
57 static void
58 intel_be_buffer_destroy(struct pipe_winsys *winsys,
59 struct pipe_buffer *buf)
60 {
61 driBOUnReference( dri_bo(buf) );
62 FREE(buf);
63 }
64
65 static struct pipe_buffer *
66 intel_be_buffer_create(struct pipe_winsys *winsys,
67 unsigned alignment,
68 unsigned usage,
69 unsigned size )
70 {
71 struct intel_be_buffer *buffer = CALLOC_STRUCT( intel_be_buffer );
72 struct intel_be_device *iws = intel_be_device(winsys);
73 unsigned flags = 0;
74 struct _DriBufferPool *pool;
75
76 buffer->base.refcount = 1;
77 buffer->base.alignment = alignment;
78 buffer->base.usage = usage;
79 buffer->base.size = size;
80
81 if (usage & (PIPE_BUFFER_USAGE_VERTEX | PIPE_BUFFER_USAGE_CONSTANT)) {
82 flags |= DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_CACHED;
83 pool = iws->mallocPool;
84 } else if (usage & PIPE_BUFFER_USAGE_CUSTOM) {
85 /* For vertex buffers */
86 flags |= DRM_BO_FLAG_MEM_VRAM | DRM_BO_FLAG_MEM_TT;
87 pool = iws->vertexPool;
88 } else {
89 flags |= DRM_BO_FLAG_MEM_VRAM | DRM_BO_FLAG_MEM_TT;
90 pool = iws->regionPool;
91 }
92
93 if (usage & PIPE_BUFFER_USAGE_GPU_READ)
94 flags |= DRM_BO_FLAG_READ;
95
96 if (usage & PIPE_BUFFER_USAGE_GPU_WRITE)
97 flags |= DRM_BO_FLAG_WRITE;
98
99 /* drm complains if we don't set any read/write flags.
100 */
101 if ((flags & (DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE)) == 0)
102 flags |= DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE;
103
104 buffer->pool = pool;
105 driGenBuffers( buffer->pool,
106 "pipe buffer", 1, &buffer->driBO, alignment, flags, 0 );
107
108 driBOData( buffer->driBO, size, NULL, buffer->pool, 0 );
109
110 return &buffer->base;
111 }
112
113
114 static struct pipe_buffer *
115 intel_be_user_buffer_create(struct pipe_winsys *winsys, void *ptr, unsigned bytes)
116 {
117 struct intel_be_buffer *buffer = CALLOC_STRUCT( intel_be_buffer );
118 struct intel_be_device *iws = intel_be_device(winsys);
119
120 driGenUserBuffer( iws->regionPool,
121 "pipe user buffer", &buffer->driBO, ptr, bytes );
122
123 buffer->base.refcount = 1;
124
125 return &buffer->base;
126 }
127
128 struct pipe_buffer *
129 intel_be_buffer_from_handle(struct intel_be_device *device,
130 const char* name, unsigned handle)
131 {
132 struct intel_be_buffer *be_buf = malloc(sizeof(*be_buf));
133 struct pipe_buffer *buffer;
134
135 if (!be_buf)
136 goto err;
137
138 memset(be_buf, 0, sizeof(*be_buf));
139
140 driGenBuffers(device->staticPool, name, 1, &be_buf->driBO, 0, 0, 0);
141 driBOSetReferenced(be_buf->driBO, handle);
142
143 if (0) /** XXX TODO check error */
144 goto err_bo;
145
146 buffer = &be_buf->base;
147 buffer->refcount = 1;
148 buffer->alignment = 0;
149 buffer->usage = 0;
150 buffer->size = driBOSize(be_buf->driBO);
151
152 return buffer;
153 err_bo:
154 free(be_buf);
155 err:
156 return NULL;
157 }
158
159
160 static struct pipe_buffer *
161 intel_i915_surface_buffer_create(struct pipe_winsys *winsys,
162 unsigned width, unsigned height,
163 enum pipe_format format,
164 unsigned usage,
165 unsigned *stride)
166 {
167 const unsigned alignment = 64;
168 struct pipe_format_block block;
169 unsigned nblocksx, nblocksy;
170
171 pf_get_block(format, &block);
172 nblocksx = pf_get_nblocksx(&block, width);
173 nblocksy = pf_get_nblocksy(&block, height);
174 *stride = round_up(nblocksx * block.size, alignment);
175
176 return winsys->buffer_create(winsys, alignment,
177 usage,
178 *stride * nblocksy);
179 }
180
181
182 /*
183 * Fence functions
184 */
185
186 static void
187 intel_be_fence_reference( struct pipe_winsys *sws,
188 struct pipe_fence_handle **ptr,
189 struct pipe_fence_handle *fence )
190 {
191 if (*ptr)
192 driFenceUnReference((struct _DriFenceObject **)ptr);
193
194 if (fence)
195 *ptr = (struct pipe_fence_handle *)driFenceReference((struct _DriFenceObject *)fence);
196 }
197
198 static int
199 intel_be_fence_signalled( struct pipe_winsys *sws,
200 struct pipe_fence_handle *fence,
201 unsigned flag )
202 {
203 return driFenceSignaled((struct _DriFenceObject *)fence, flag);
204 }
205
206 static int
207 intel_be_fence_finish( struct pipe_winsys *sws,
208 struct pipe_fence_handle *fence,
209 unsigned flag )
210 {
211 return driFenceFinish((struct _DriFenceObject *)fence, flag, 0);
212 }
213
214
215 /*
216 * Misc functions
217 */
218
219 boolean
220 intel_be_init_device(struct intel_be_device *dev, int fd, unsigned id)
221 {
222 dev->fd = fd;
223 dev->max_batch_size = 16 * 4096;
224 dev->max_vertex_size = 128 * 4096;
225
226 dev->base.buffer_create = intel_be_buffer_create;
227 dev->base.user_buffer_create = intel_be_user_buffer_create;
228 dev->base.buffer_map = intel_be_buffer_map;
229 dev->base.buffer_unmap = intel_be_buffer_unmap;
230 dev->base.buffer_destroy = intel_be_buffer_destroy;
231 dev->base.surface_buffer_create = intel_i915_surface_buffer_create;
232 dev->base.fence_reference = intel_be_fence_reference;
233 dev->base.fence_signalled = intel_be_fence_signalled;
234 dev->base.fence_finish = intel_be_fence_finish;
235
236 #if 0 /* Set by the winsys */
237 dev->base.flush_frontbuffer = intel_flush_frontbuffer;
238 dev->base.get_name = intel_get_name;
239 #endif
240
241 dev->fMan = driInitFreeSlabManager(10, 10);
242 dev->fenceMgr = driFenceMgrTTMInit(dev->fd);
243
244 dev->mallocPool = driMallocPoolInit();
245 dev->staticPool = driDRMPoolInit(dev->fd);
246 /* Sizes: 64 128 256 512 1024 2048 4096 8192 16384 32768 */
247 dev->regionPool = driSlabPoolInit(dev->fd,
248 DRM_BO_FLAG_READ |
249 DRM_BO_FLAG_WRITE |
250 DRM_BO_FLAG_MEM_TT,
251 DRM_BO_FLAG_READ |
252 DRM_BO_FLAG_WRITE |
253 DRM_BO_FLAG_MEM_TT,
254 64,
255 10, 120, 4096 * 64, 0,
256 dev->fMan);
257
258 dev->vertexPool = driSlabPoolInit(dev->fd,
259 DRM_BO_FLAG_READ |
260 DRM_BO_FLAG_WRITE |
261 DRM_BO_FLAG_MEM_TT,
262 DRM_BO_FLAG_READ |
263 DRM_BO_FLAG_WRITE |
264 DRM_BO_FLAG_MEM_TT,
265 dev->max_vertex_size,
266 1, 120, dev->max_vertex_size * 4, 0,
267 dev->fMan);
268
269 dev->batchPool = driSlabPoolInit(dev->fd,
270 DRM_BO_FLAG_EXE |
271 DRM_BO_FLAG_MEM_TT,
272 DRM_BO_FLAG_EXE |
273 DRM_BO_FLAG_MEM_TT,
274 dev->max_batch_size,
275 1, 40, dev->max_batch_size * 16, 0,
276 dev->fMan);
277
278 /* Fill in this struct with callbacks that i915simple will need to
279 * communicate with the window system, buffer manager, etc.
280 */
281 dev->screen = i915_create_screen(&dev->base, id);
282
283 return true;
284 }
285
286 void
287 intel_be_destroy_device(struct intel_be_device *dev)
288 {
289 driPoolTakeDown(dev->mallocPool);
290 driPoolTakeDown(dev->staticPool);
291 driPoolTakeDown(dev->regionPool);
292 driPoolTakeDown(dev->vertexPool);
293 driPoolTakeDown(dev->batchPool);
294
295 /** TODO takedown fenceMgr and fMan */
296 }