i915: Revert accidental change
[mesa.git] / src / gallium / winsys / dri / intel / intel_winsys_pipe.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: Keith Whitwell <keithw-at-tungstengraphics-dot-com>
30 */
31
32 #include <stdlib.h>
33 #include <xf86drm.h>
34 //#include "dri_bufpool.h"
35 //#include "dri_bufmgr.h"
36
37 #include "intel_context.h"
38 #include "intel_winsys.h"
39 #include "intel_swapbuffers.h"
40 #include "intel_batchbuffer.h"
41
42 #include "pipe/p_winsys.h"
43 #include "pipe/p_defines.h"
44 #include "pipe/p_state.h"
45 #include "pipe/p_util.h"
46 #include "pipe/p_inlines.h"
47
48
49
50 struct intel_pipe_winsys {
51 struct pipe_winsys winsys;
52 struct _DriBufferPool *regionPool;
53 struct _DriBufferPool *mallocPool;
54 struct _DriBufferPool *vertexPool;
55 struct _DriFreeSlabManager *fMan; /** shared between all pipes */
56 };
57
58
59
60 /* Turn a pipe winsys into an intel/pipe winsys:
61 */
62 static inline struct intel_pipe_winsys *
63 intel_pipe_winsys( struct pipe_winsys *winsys )
64 {
65 return (struct intel_pipe_winsys *)winsys;
66 }
67
68
69 /* Most callbacks map direcly onto dri_bufmgr operations:
70 */
71 static void *intel_buffer_map(struct pipe_winsys *winsys,
72 struct pipe_buffer *buf,
73 unsigned flags )
74 {
75 unsigned drm_flags = 0;
76
77 if (flags & PIPE_BUFFER_USAGE_CPU_WRITE)
78 drm_flags |= DRM_BO_FLAG_WRITE;
79
80 if (flags & PIPE_BUFFER_USAGE_CPU_READ)
81 drm_flags |= DRM_BO_FLAG_READ;
82
83 return driBOMap( dri_bo(buf), drm_flags, 0 );
84 }
85
86 static void intel_buffer_unmap(struct pipe_winsys *winsys,
87 struct pipe_buffer *buf)
88 {
89 driBOUnmap( dri_bo(buf) );
90 }
91
92
93 static void
94 intel_buffer_destroy(struct pipe_winsys *winsys,
95 struct pipe_buffer *buf)
96 {
97 driBOUnReference( dri_bo(buf) );
98 FREE(buf);
99 }
100
101
102 /* Pipe has no concept of pools. We choose the tex/region pool
103 * for all buffers.
104 * Grabs the hardware lock!
105 */
106 static struct pipe_buffer *
107 intel_buffer_create(struct pipe_winsys *winsys,
108 unsigned alignment,
109 unsigned usage,
110 unsigned size )
111 {
112 struct intel_buffer *buffer = CALLOC_STRUCT( intel_buffer );
113 struct intel_pipe_winsys *iws = intel_pipe_winsys(winsys);
114 unsigned flags = 0;
115 struct _DriBufferPool *pool;
116
117 buffer->base.refcount = 1;
118 buffer->base.alignment = alignment;
119 buffer->base.usage = usage;
120 buffer->base.size = size;
121
122 if (usage & (PIPE_BUFFER_USAGE_VERTEX | PIPE_BUFFER_USAGE_CONSTANT)) {
123 flags |= DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_CACHED;
124 pool = iws->mallocPool;
125 } else if (usage & PIPE_BUFFER_USAGE_CUSTOM) {
126 /* For vertex buffers */
127 flags |= DRM_BO_FLAG_MEM_VRAM | DRM_BO_FLAG_MEM_TT;
128 pool = iws->vertexPool;
129 } else {
130 flags |= DRM_BO_FLAG_MEM_VRAM | DRM_BO_FLAG_MEM_TT;
131 pool = iws->regionPool;
132 }
133
134 if (usage & PIPE_BUFFER_USAGE_GPU_READ)
135 flags |= DRM_BO_FLAG_READ;
136
137 if (usage & PIPE_BUFFER_USAGE_GPU_WRITE)
138 flags |= DRM_BO_FLAG_WRITE;
139
140 /* drm complains if we don't set any read/write flags.
141 */
142 if ((flags & (DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE)) == 0)
143 flags |= DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE;
144
145 #if 0
146 if (flags & IWS_BUFFER_USAGE_EXE)
147 flags |= DRM_BO_FLAG_EXE;
148
149 if (usage & IWS_BUFFER_USAGE_CACHED)
150 flags |= DRM_BO_FLAG_CACHED;
151 #endif
152
153 buffer->pool = pool;
154 driGenBuffers( buffer->pool,
155 "pipe buffer", 1, &buffer->driBO, alignment, flags, 0 );
156
157 driBOData( buffer->driBO, size, NULL, buffer->pool, 0 );
158
159 return &buffer->base;
160 }
161
162
163 static struct pipe_buffer *
164 intel_user_buffer_create(struct pipe_winsys *winsys, void *ptr, unsigned bytes)
165 {
166 struct intel_buffer *buffer = CALLOC_STRUCT( intel_buffer );
167 struct intel_pipe_winsys *iws = intel_pipe_winsys(winsys);
168
169 driGenUserBuffer( iws->regionPool,
170 "pipe user buffer", &buffer->driBO, ptr, bytes );
171
172 buffer->base.refcount = 1;
173
174 return &buffer->base;
175 }
176
177
178 /* The state tracker (should!) keep track of whether the fake
179 * frontbuffer has been touched by any rendering since the last time
180 * we copied its contents to the real frontbuffer. Our task is easy:
181 */
182 static void
183 intel_flush_frontbuffer( struct pipe_winsys *winsys,
184 struct pipe_surface *surf,
185 void *context_private)
186 {
187 struct intel_context *intel = (struct intel_context *) context_private;
188 __DRIdrawablePrivate *dPriv = intel->driDrawable;
189
190 intelDisplaySurface(dPriv, surf, NULL);
191 }
192
193
194 static struct pipe_surface *
195 intel_i915_surface_alloc(struct pipe_winsys *winsys)
196 {
197 struct pipe_surface *surf = CALLOC_STRUCT(pipe_surface);
198 if (surf) {
199 surf->refcount = 1;
200 surf->winsys = winsys;
201 }
202 return surf;
203 }
204
205
206 /**
207 * Round n up to next multiple.
208 */
209 static INLINE unsigned
210 round_up(unsigned n, unsigned multiple)
211 {
212 return (n + multiple - 1) & ~(multiple - 1);
213 }
214
215 /**
216 * Copied from xm_winsys.c
217 */
218 static int
219 intel_i915_surface_alloc_storage(struct pipe_winsys *winsys,
220 struct pipe_surface *surf,
221 unsigned width, unsigned height,
222 enum pipe_format format,
223 unsigned flags)
224 {
225 const unsigned alignment = 64;
226 //int ret;
227
228 surf->width = width;
229 surf->height = height;
230 surf->format = format;
231 surf->cpp = pf_get_size(format);
232 surf->pitch = round_up(width, alignment / surf->cpp);
233
234 assert(!surf->buffer);
235 surf->buffer = winsys->buffer_create(winsys, alignment,
236 PIPE_BUFFER_USAGE_PIXEL,
237 surf->pitch * surf->cpp * height);
238 if(!surf->buffer)
239 return -1;
240
241 return 0;
242 }
243
244
245 static void
246 intel_i915_surface_release(struct pipe_winsys *winsys, struct pipe_surface **s)
247 {
248 struct pipe_surface *surf = *s;
249 surf->refcount--;
250 if (surf->refcount == 0) {
251 if (surf->buffer)
252 pipe_buffer_reference(winsys, &surf->buffer, NULL);
253 free(surf);
254 }
255 *s = NULL;
256 }
257
258
259
260 static const char *
261 intel_get_name( struct pipe_winsys *winsys )
262 {
263 return "Intel/DRI/ttm";
264 }
265
266 static void
267 intel_fence_reference( struct pipe_winsys *sws,
268 struct pipe_fence_handle **ptr,
269 struct pipe_fence_handle *fence )
270 {
271 if (*ptr)
272 driFenceUnReference((struct _DriFenceObject **)ptr);
273
274 if (fence)
275 *ptr = (struct pipe_fence_handle *)driFenceReference((struct _DriFenceObject *)fence);
276 }
277
278 static int
279 intel_fence_signalled( struct pipe_winsys *sws,
280 struct pipe_fence_handle *fence,
281 unsigned flag )
282 {
283 return driFenceSignaled((struct _DriFenceObject *)fence, flag);
284 }
285
286 static int
287 intel_fence_finish( struct pipe_winsys *sws,
288 struct pipe_fence_handle *fence,
289 unsigned flag )
290 {
291 return driFenceFinish((struct _DriFenceObject *)fence, flag, 0);
292 }
293
294 struct pipe_winsys *
295 intel_create_pipe_winsys( int fd, struct _DriFreeSlabManager *fMan )
296 {
297 struct intel_pipe_winsys *iws = CALLOC_STRUCT( intel_pipe_winsys );
298
299 /* Fill in this struct with callbacks that pipe will need to
300 * communicate with the window system, buffer manager, etc.
301 *
302 * Pipe would be happy with a malloc based memory manager, but
303 * the SwapBuffers implementation in this winsys driver requires
304 * that rendering be done to an appropriate _DriBufferObject.
305 */
306 iws->winsys.buffer_create = intel_buffer_create;
307 iws->winsys.user_buffer_create = intel_user_buffer_create;
308 iws->winsys.buffer_map = intel_buffer_map;
309 iws->winsys.buffer_unmap = intel_buffer_unmap;
310 iws->winsys.buffer_destroy = intel_buffer_destroy;
311 iws->winsys.flush_frontbuffer = intel_flush_frontbuffer;
312 iws->winsys.get_name = intel_get_name;
313 iws->winsys.surface_alloc = intel_i915_surface_alloc;
314 iws->winsys.surface_alloc_storage = intel_i915_surface_alloc_storage;
315 iws->winsys.surface_release = intel_i915_surface_release;
316
317 iws->winsys.fence_reference = intel_fence_reference;
318 iws->winsys.fence_signalled = intel_fence_signalled;
319 iws->winsys.fence_finish = intel_fence_finish;
320
321 if (fd) {
322 iws->regionPool = driDRMPoolInit(fd);
323 iws->vertexPool = driSlabPoolInit(fd,
324 DRM_BO_FLAG_READ |
325 DRM_BO_FLAG_WRITE |
326 DRM_BO_FLAG_MEM_TT,
327 DRM_BO_FLAG_READ |
328 DRM_BO_FLAG_WRITE |
329 DRM_BO_FLAG_MEM_TT,
330 32 * 4096,
331 1, 40, 32 * 4096 * 2, 0,
332 fMan);
333 }
334
335 iws->mallocPool = driMallocPoolInit();
336
337 return &iws->winsys;
338 }
339
340
341 void
342 intel_destroy_pipe_winsys( struct pipe_winsys *winsys )
343 {
344 struct intel_pipe_winsys *iws = intel_pipe_winsys(winsys);
345 if (iws->regionPool) {
346 driPoolTakeDown(iws->regionPool);
347 }
348 if (iws->mallocPool) {
349 driPoolTakeDown(iws->mallocPool);
350 }
351 free(iws);
352 }
353