1 /**************************************************************************
3 * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA
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:
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.
22 * The above copyright notice and this permission notice (including the
23 * next paragraph) shall be included in all copies or substantial portions
27 **************************************************************************/
29 * Authors: Keith Whitwell <keithw-at-tungstengraphics-dot-com>
34 //#include "dri_bufpool.h"
35 //#include "dri_bufmgr.h"
37 #include "intel_context.h"
38 #include "intel_winsys.h"
39 #include "intel_swapbuffers.h"
40 #include "intel_batchbuffer.h"
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"
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 */
60 /* Turn a pipe winsys into an intel/pipe winsys:
62 static inline struct intel_pipe_winsys
*
63 intel_pipe_winsys( struct pipe_winsys
*winsys
)
65 return (struct intel_pipe_winsys
*)winsys
;
69 /* Most callbacks map direcly onto dri_bufmgr operations:
71 static void *intel_buffer_map(struct pipe_winsys
*winsys
,
72 struct pipe_buffer
*buf
,
75 unsigned drm_flags
= 0;
77 if (flags
& PIPE_BUFFER_USAGE_CPU_WRITE
)
78 drm_flags
|= DRM_BO_FLAG_WRITE
;
80 if (flags
& PIPE_BUFFER_USAGE_CPU_READ
)
81 drm_flags
|= DRM_BO_FLAG_READ
;
83 return driBOMap( dri_bo(buf
), drm_flags
, 0 );
86 static void intel_buffer_unmap(struct pipe_winsys
*winsys
,
87 struct pipe_buffer
*buf
)
89 driBOUnmap( dri_bo(buf
) );
94 intel_buffer_destroy(struct pipe_winsys
*winsys
,
95 struct pipe_buffer
*buf
)
97 driBOUnReference( dri_bo(buf
) );
102 /* Pipe has no concept of pools. We choose the tex/region pool
104 * Grabs the hardware lock!
106 static struct pipe_buffer
*
107 intel_buffer_create(struct pipe_winsys
*winsys
,
112 struct intel_buffer
*buffer
= CALLOC_STRUCT( intel_buffer
);
113 struct intel_pipe_winsys
*iws
= intel_pipe_winsys(winsys
);
115 struct _DriBufferPool
*pool
;
117 buffer
->base
.refcount
= 1;
118 buffer
->base
.alignment
= alignment
;
119 buffer
->base
.usage
= usage
;
120 buffer
->base
.size
= size
;
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
;
130 flags
|= DRM_BO_FLAG_MEM_VRAM
| DRM_BO_FLAG_MEM_TT
;
131 pool
= iws
->regionPool
;
134 if (usage
& PIPE_BUFFER_USAGE_GPU_READ
)
135 flags
|= DRM_BO_FLAG_READ
;
137 if (usage
& PIPE_BUFFER_USAGE_GPU_WRITE
)
138 flags
|= DRM_BO_FLAG_WRITE
;
140 /* drm complains if we don't set any read/write flags.
142 if ((flags
& (DRM_BO_FLAG_READ
| DRM_BO_FLAG_WRITE
)) == 0)
143 flags
|= DRM_BO_FLAG_READ
| DRM_BO_FLAG_WRITE
;
146 if (flags
& IWS_BUFFER_USAGE_EXE
)
147 flags
|= DRM_BO_FLAG_EXE
;
149 if (usage
& IWS_BUFFER_USAGE_CACHED
)
150 flags
|= DRM_BO_FLAG_CACHED
;
154 driGenBuffers( buffer
->pool
,
155 "pipe buffer", 1, &buffer
->driBO
, alignment
, flags
, 0 );
157 driBOData( buffer
->driBO
, size
, NULL
, buffer
->pool
, 0 );
159 return &buffer
->base
;
163 static struct pipe_buffer
*
164 intel_user_buffer_create(struct pipe_winsys
*winsys
, void *ptr
, unsigned bytes
)
166 struct intel_buffer
*buffer
= CALLOC_STRUCT( intel_buffer
);
167 struct intel_pipe_winsys
*iws
= intel_pipe_winsys(winsys
);
169 driGenUserBuffer( iws
->regionPool
,
170 "pipe user buffer", &buffer
->driBO
, ptr
, bytes
);
172 buffer
->base
.refcount
= 1;
174 return &buffer
->base
;
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:
183 intel_flush_frontbuffer( struct pipe_winsys
*winsys
,
184 struct pipe_surface
*surf
,
185 void *context_private
)
187 struct intel_context
*intel
= (struct intel_context
*) context_private
;
188 __DRIdrawablePrivate
*dPriv
= intel
->driDrawable
;
190 intelDisplaySurface(dPriv
, surf
, NULL
);
194 static struct pipe_surface
*
195 intel_i915_surface_alloc(struct pipe_winsys
*winsys
)
197 struct pipe_surface
*surf
= CALLOC_STRUCT(pipe_surface
);
200 surf
->winsys
= winsys
;
207 * Round n up to next multiple.
209 static INLINE
unsigned
210 round_up(unsigned n
, unsigned multiple
)
212 return (n
+ multiple
- 1) & ~(multiple
- 1);
216 * Copied from xm_winsys.c
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
,
225 const unsigned alignment
= 64;
229 surf
->height
= height
;
230 surf
->format
= format
;
231 surf
->cpp
= pf_get_size(format
);
232 surf
->pitch
= round_up(width
, alignment
/ surf
->cpp
);
234 assert(!surf
->buffer
);
235 surf
->buffer
= winsys
->buffer_create(winsys
, alignment
,
236 PIPE_BUFFER_USAGE_PIXEL
,
237 surf
->pitch
* surf
->cpp
* height
);
246 intel_i915_surface_release(struct pipe_winsys
*winsys
, struct pipe_surface
**s
)
248 struct pipe_surface
*surf
= *s
;
250 if (surf
->refcount
== 0) {
252 pipe_buffer_reference(winsys
, &surf
->buffer
, NULL
);
261 intel_get_name( struct pipe_winsys
*winsys
)
263 return "Intel/DRI/ttm";
267 intel_fence_reference( struct pipe_winsys
*sws
,
268 struct pipe_fence_handle
**ptr
,
269 struct pipe_fence_handle
*fence
)
272 driFenceUnReference((struct _DriFenceObject
**)ptr
);
275 *ptr
= (struct pipe_fence_handle
*)driFenceReference((struct _DriFenceObject
*)fence
);
279 intel_fence_signalled( struct pipe_winsys
*sws
,
280 struct pipe_fence_handle
*fence
,
283 return driFenceSignaled((struct _DriFenceObject
*)fence
, flag
);
287 intel_fence_finish( struct pipe_winsys
*sws
,
288 struct pipe_fence_handle
*fence
,
291 return driFenceFinish((struct _DriFenceObject
*)fence
, flag
, 0);
295 intel_create_pipe_winsys( int fd
, struct _DriFreeSlabManager
*fMan
)
297 struct intel_pipe_winsys
*iws
= CALLOC_STRUCT( intel_pipe_winsys
);
299 /* Fill in this struct with callbacks that pipe will need to
300 * communicate with the window system, buffer manager, etc.
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.
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
;
317 iws
->winsys
.fence_reference
= intel_fence_reference
;
318 iws
->winsys
.fence_signalled
= intel_fence_signalled
;
319 iws
->winsys
.fence_finish
= intel_fence_finish
;
322 iws
->regionPool
= driDRMPoolInit(fd
);
323 iws
->vertexPool
= driSlabPoolInit(fd
,
331 1, 40, 32 * 4096 * 2, 0,
335 iws
->mallocPool
= driMallocPoolInit();
342 intel_destroy_pipe_winsys( struct pipe_winsys
*winsys
)
344 struct intel_pipe_winsys
*iws
= intel_pipe_winsys(winsys
);
345 if (iws
->regionPool
) {
346 driPoolTakeDown(iws
->regionPool
);
348 if (iws
->mallocPool
) {
349 driPoolTakeDown(iws
->mallocPool
);