4 * Authors: Keith Whitwell <keithw-at-tungstengraphics-dot-com>
5 * Jakob Bornecrantz <jakob-at-tungstengraphics-dot-com>
8 #include "intel_be_device.h"
9 #include "ws_dri_bufmgr.h"
10 #include "ws_dri_bufpool.h"
11 #include "ws_dri_fencemgr.h"
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"
19 #include "i915simple/i915_screen.h"
21 /* Turn a pipe winsys into an intel/pipe winsys:
23 static INLINE
struct intel_be_device
*
24 intel_be_device( struct pipe_winsys
*winsys
)
26 return (struct intel_be_device
*)winsys
;
33 * Most callbacks map direcly onto dri_bufmgr operations:
36 static void *intel_be_buffer_map(struct pipe_winsys
*winsys
,
37 struct pipe_buffer
*buf
,
40 unsigned drm_flags
= 0;
42 if (flags
& PIPE_BUFFER_USAGE_CPU_WRITE
)
43 drm_flags
|= DRM_BO_FLAG_WRITE
;
45 if (flags
& PIPE_BUFFER_USAGE_CPU_READ
)
46 drm_flags
|= DRM_BO_FLAG_READ
;
48 return driBOMap( dri_bo(buf
), drm_flags
, 0 );
51 static void intel_be_buffer_unmap(struct pipe_winsys
*winsys
,
52 struct pipe_buffer
*buf
)
54 driBOUnmap( dri_bo(buf
) );
58 intel_be_buffer_destroy(struct pipe_winsys
*winsys
,
59 struct pipe_buffer
*buf
)
61 driBOUnReference( dri_bo(buf
) );
65 static struct pipe_buffer
*
66 intel_be_buffer_create(struct pipe_winsys
*winsys
,
71 struct intel_be_buffer
*buffer
= CALLOC_STRUCT( intel_be_buffer
);
72 struct intel_be_device
*iws
= intel_be_device(winsys
);
74 struct _DriBufferPool
*pool
;
76 buffer
->base
.refcount
= 1;
77 buffer
->base
.alignment
= alignment
;
78 buffer
->base
.usage
= usage
;
79 buffer
->base
.size
= size
;
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
;
89 flags
|= DRM_BO_FLAG_MEM_VRAM
| DRM_BO_FLAG_MEM_TT
;
90 pool
= iws
->regionPool
;
93 if (usage
& PIPE_BUFFER_USAGE_GPU_READ
)
94 flags
|= DRM_BO_FLAG_READ
;
96 if (usage
& PIPE_BUFFER_USAGE_GPU_WRITE
)
97 flags
|= DRM_BO_FLAG_WRITE
;
99 /* drm complains if we don't set any read/write flags.
101 if ((flags
& (DRM_BO_FLAG_READ
| DRM_BO_FLAG_WRITE
)) == 0)
102 flags
|= DRM_BO_FLAG_READ
| DRM_BO_FLAG_WRITE
;
105 driGenBuffers( buffer
->pool
,
106 "pipe buffer", 1, &buffer
->driBO
, alignment
, flags
, 0 );
108 driBOData( buffer
->driBO
, size
, NULL
, buffer
->pool
, 0 );
110 return &buffer
->base
;
114 static struct pipe_buffer
*
115 intel_be_user_buffer_create(struct pipe_winsys
*winsys
, void *ptr
, unsigned bytes
)
117 struct intel_be_buffer
*buffer
= CALLOC_STRUCT( intel_be_buffer
);
118 struct intel_be_device
*iws
= intel_be_device(winsys
);
120 driGenUserBuffer( iws
->regionPool
,
121 "pipe user buffer", &buffer
->driBO
, ptr
, bytes
);
123 buffer
->base
.refcount
= 1;
125 return &buffer
->base
;
129 intel_be_buffer_from_handle(struct intel_be_device
*device
,
130 const char* name
, unsigned handle
)
132 struct intel_be_buffer
*be_buf
= malloc(sizeof(*be_buf
));
133 struct pipe_buffer
*buffer
;
138 memset(be_buf
, 0, sizeof(*be_buf
));
140 driGenBuffers(device
->staticPool
, name
, 1, &be_buf
->driBO
, 0, 0, 0);
141 driBOSetReferenced(be_buf
->driBO
, handle
);
143 if (0) /** XXX TODO check error */
146 buffer
= &be_buf
->base
;
147 buffer
->refcount
= 1;
148 buffer
->alignment
= 0;
150 buffer
->size
= driBOSize(be_buf
->driBO
);
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
,
167 const unsigned alignment
= 64;
168 struct pipe_format_block block
;
169 unsigned nblocksx
, nblocksy
;
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
);
176 return winsys
->buffer_create(winsys
, alignment
,
187 intel_be_fence_reference( struct pipe_winsys
*sws
,
188 struct pipe_fence_handle
**ptr
,
189 struct pipe_fence_handle
*fence
)
192 driFenceUnReference((struct _DriFenceObject
**)ptr
);
195 *ptr
= (struct pipe_fence_handle
*)driFenceReference((struct _DriFenceObject
*)fence
);
199 intel_be_fence_signalled( struct pipe_winsys
*sws
,
200 struct pipe_fence_handle
*fence
,
203 return driFenceSignaled((struct _DriFenceObject
*)fence
, flag
);
207 intel_be_fence_finish( struct pipe_winsys
*sws
,
208 struct pipe_fence_handle
*fence
,
211 return driFenceFinish((struct _DriFenceObject
*)fence
, flag
, 0);
220 intel_be_init_device(struct intel_be_device
*dev
, int fd
, unsigned id
)
223 dev
->max_batch_size
= 16 * 4096;
224 dev
->max_vertex_size
= 128 * 4096;
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
;
236 #if 0 /* Set by the winsys */
237 dev
->base
.flush_frontbuffer
= intel_flush_frontbuffer
;
238 dev
->base
.get_name
= intel_get_name
;
241 dev
->fMan
= driInitFreeSlabManager(10, 10);
242 dev
->fenceMgr
= driFenceMgrTTMInit(dev
->fd
);
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
,
255 10, 120, 4096 * 64, 0,
258 dev
->vertexPool
= driSlabPoolInit(dev
->fd
,
265 dev
->max_vertex_size
,
266 1, 120, dev
->max_vertex_size
* 4, 0,
269 dev
->batchPool
= driSlabPoolInit(dev
->fd
,
275 1, 40, dev
->max_batch_size
* 16, 0,
278 /* Fill in this struct with callbacks that i915simple will need to
279 * communicate with the window system, buffer manager, etc.
281 dev
->screen
= i915_create_screen(&dev
->base
, id
);
287 intel_be_destroy_device(struct intel_be_device
*dev
)
289 driPoolTakeDown(dev
->mallocPool
);
290 driPoolTakeDown(dev
->staticPool
);
291 driPoolTakeDown(dev
->regionPool
);
292 driPoolTakeDown(dev
->vertexPool
);
293 driPoolTakeDown(dev
->batchPool
);
295 /** TODO takedown fenceMgr and fMan */