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
;
57 /* Turn a pipe winsys into an intel/pipe winsys:
59 static inline struct intel_pipe_winsys
*
60 intel_pipe_winsys( struct pipe_winsys
*winsys
)
62 return (struct intel_pipe_winsys
*)winsys
;
66 /* Most callbacks map direcly onto dri_bufmgr operations:
68 static void *intel_buffer_map(struct pipe_winsys
*winsys
,
69 struct pipe_buffer
*buf
,
72 unsigned drm_flags
= 0;
74 if (flags
& PIPE_BUFFER_USAGE_CPU_WRITE
)
75 drm_flags
|= DRM_BO_FLAG_WRITE
;
77 if (flags
& PIPE_BUFFER_USAGE_CPU_READ
)
78 drm_flags
|= DRM_BO_FLAG_READ
;
80 return driBOMap( dri_bo(buf
), drm_flags
, 0 );
83 static void intel_buffer_unmap(struct pipe_winsys
*winsys
,
84 struct pipe_buffer
*buf
)
86 driBOUnmap( dri_bo(buf
) );
91 intel_buffer_destroy(struct pipe_winsys
*winsys
,
92 struct pipe_buffer
*buf
)
94 driBOUnReference( dri_bo(buf
) );
98 /* Pipe has no concept of pools. We choose the tex/region pool
100 * Grabs the hardware lock!
102 static struct pipe_buffer
*
103 intel_buffer_create(struct pipe_winsys
*winsys
,
108 struct intel_buffer
*buffer
= CALLOC_STRUCT( intel_buffer
);
109 struct intel_pipe_winsys
*iws
= intel_pipe_winsys(winsys
);
112 buffer
->base
.refcount
= 1;
113 buffer
->base
.alignment
= alignment
;
114 buffer
->base
.usage
= usage
;
115 buffer
->base
.size
= size
;
117 if (usage
& (PIPE_BUFFER_USAGE_VERTEX
/*| IWS_BUFFER_USAGE_LOCAL*/)) {
118 flags
|= DRM_BO_FLAG_MEM_LOCAL
| DRM_BO_FLAG_CACHED
;
120 flags
|= DRM_BO_FLAG_MEM_VRAM
| DRM_BO_FLAG_MEM_TT
;
123 if (usage
& PIPE_BUFFER_USAGE_GPU_READ
)
124 flags
|= DRM_BO_FLAG_READ
;
126 if (usage
& PIPE_BUFFER_USAGE_GPU_WRITE
)
127 flags
|= DRM_BO_FLAG_WRITE
;
129 /* drm complains if we don't set any read/write flags.
131 if ((flags
& (DRM_BO_FLAG_READ
| DRM_BO_FLAG_WRITE
)) == 0)
132 flags
|= DRM_BO_FLAG_READ
| DRM_BO_FLAG_WRITE
;
135 if (flags
& IWS_BUFFER_USAGE_EXE
)
136 flags
|= DRM_BO_FLAG_EXE
;
138 if (usage
& IWS_BUFFER_USAGE_CACHED
)
139 flags
|= DRM_BO_FLAG_CACHED
;
142 driGenBuffers( iws
->regionPool
,
143 "pipe buffer", 1, &buffer
->driBO
, alignment
, flags
, 0 );
145 driBOData( buffer
->driBO
, size
, NULL
, 0 );
147 return &buffer
->base
;
151 static struct pipe_buffer
*
152 intel_user_buffer_create(struct pipe_winsys
*winsys
, void *ptr
, unsigned bytes
)
154 struct intel_buffer
*buffer
= CALLOC_STRUCT( intel_buffer
);
155 struct intel_pipe_winsys
*iws
= intel_pipe_winsys(winsys
);
157 driGenUserBuffer( iws
->regionPool
,
158 "pipe user buffer", &buffer
->driBO
, ptr
, bytes
);
160 return &buffer
->base
;
164 /* The state tracker (should!) keep track of whether the fake
165 * frontbuffer has been touched by any rendering since the last time
166 * we copied its contents to the real frontbuffer. Our task is easy:
169 intel_flush_frontbuffer( struct pipe_winsys
*winsys
,
170 struct pipe_surface
*surf
,
171 void *context_private
)
173 struct intel_context
*intel
= (struct intel_context
*) context_private
;
174 __DRIdrawablePrivate
*dPriv
= intel
->driDrawable
;
176 intelDisplaySurface(dPriv
, surf
, NULL
);
180 static struct pipe_surface
*
181 intel_i915_surface_alloc(struct pipe_winsys
*winsys
)
183 struct pipe_surface
*surf
= CALLOC_STRUCT(pipe_surface
);
186 surf
->winsys
= winsys
;
193 * Round n up to next multiple.
195 static INLINE
unsigned
196 round_up(unsigned n
, unsigned multiple
)
198 return (n
+ multiple
- 1) & ~(multiple
- 1);
202 * Copied from xm_winsys.c
205 intel_i915_surface_alloc_storage(struct pipe_winsys
*winsys
,
206 struct pipe_surface
*surf
,
207 unsigned width
, unsigned height
,
208 enum pipe_format format
,
211 const unsigned alignment
= 64;
215 surf
->height
= height
;
216 surf
->format
= format
;
217 surf
->cpp
= pf_get_size(format
);
218 surf
->pitch
= round_up(width
, alignment
/ surf
->cpp
);
220 assert(!surf
->buffer
);
221 surf
->buffer
= winsys
->buffer_create(winsys
, alignment
,
222 PIPE_BUFFER_USAGE_PIXEL
,
223 surf
->pitch
* surf
->cpp
* height
);
232 intel_i915_surface_release(struct pipe_winsys
*winsys
, struct pipe_surface
**s
)
234 struct pipe_surface
*surf
= *s
;
236 if (surf
->refcount
== 0) {
238 pipe_buffer_reference(winsys
, &surf
->buffer
, NULL
);
247 intel_printf( struct pipe_winsys
*winsys
, const char *fmtString
, ... )
250 va_start( args
, fmtString
);
251 vfprintf(stderr
, fmtString
, args
);
256 intel_get_name( struct pipe_winsys
*winsys
)
258 return "Intel/DRI/ttm";
263 intel_create_pipe_winsys( int fd
)
265 struct intel_pipe_winsys
*iws
= CALLOC_STRUCT( intel_pipe_winsys
);
267 /* Fill in this struct with callbacks that pipe will need to
268 * communicate with the window system, buffer manager, etc.
270 * Pipe would be happy with a malloc based memory manager, but
271 * the SwapBuffers implementation in this winsys driver requires
272 * that rendering be done to an appropriate _DriBufferObject.
274 iws
->winsys
.buffer_create
= intel_buffer_create
;
275 iws
->winsys
.user_buffer_create
= intel_user_buffer_create
;
276 iws
->winsys
.buffer_map
= intel_buffer_map
;
277 iws
->winsys
.buffer_unmap
= intel_buffer_unmap
;
278 iws
->winsys
.buffer_destroy
= intel_buffer_destroy
;
279 iws
->winsys
.flush_frontbuffer
= intel_flush_frontbuffer
;
280 iws
->winsys
.printf
= intel_printf
;
281 iws
->winsys
.get_name
= intel_get_name
;
282 iws
->winsys
.surface_alloc
= intel_i915_surface_alloc
;
283 iws
->winsys
.surface_alloc_storage
= intel_i915_surface_alloc_storage
;
284 iws
->winsys
.surface_release
= intel_i915_surface_release
;
287 iws
->regionPool
= driDRMPoolInit(fd
);
294 intel_destroy_pipe_winsys( struct pipe_winsys
*winsys
)
296 struct intel_pipe_winsys
*iws
= intel_pipe_winsys(winsys
);
297 if (iws
->regionPool
) {
298 driPoolTakeDown(iws
->regionPool
);