1 /**************************************************************************
3 * Copyright 2007 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 **************************************************************************/
36 #include "glxheader.h"
38 #include "main/macros.h"
40 #include "pipe/p_winsys.h"
41 #include "pipe/softpipe/sp_winsys.h"
45 * XMesa winsys, derived from softpipe winsys.
46 * NOTE: there's nothing really X-specific in this winsys layer so
47 * we could probably lift it up somewhere.
51 struct softpipe_winsys sws
;
52 int foo
; /* placeholder */
57 * Low-level OS/window system memory buffer
61 boolean userBuffer
; /** Is this a user-space buffer? */
70 /* Turn the softpipe opaque buffer pointer into a dri_bufmgr opaque
73 static inline struct xm_buffer
*
74 xm_bo( struct pipe_buffer_handle
*bo
)
76 return (struct xm_buffer
*) bo
;
79 static inline struct pipe_buffer_handle
*
80 pipe_bo( struct xm_buffer
*bo
)
82 return (struct pipe_buffer_handle
*) bo
;
85 /* Turn a softpipe winsys into an xm/softpipe winsys:
87 static inline struct xm_winsys
*
88 xm_winsys(struct softpipe_winsys
*sws
)
90 return (struct xm_winsys
*) sws
;
94 /* Most callbacks map direcly onto dri_bufmgr operations:
97 xm_buffer_map(struct pipe_winsys
*pws
, struct pipe_buffer_handle
*buf
,
100 struct xm_buffer
*xm_buf
= xm_bo(buf
);
101 xm_buf
->mapped
= xm_buf
->data
;
102 return xm_buf
->mapped
;
106 xm_buffer_unmap(struct pipe_winsys
*pws
, struct pipe_buffer_handle
*buf
)
108 struct xm_buffer
*xm_buf
= xm_bo(buf
);
109 xm_buf
->mapped
= NULL
;
113 xm_buffer_reference(struct pipe_winsys
*pws
,
114 struct pipe_buffer_handle
**ptr
,
115 struct pipe_buffer_handle
*buf
)
118 struct xm_buffer
*oldBuf
= xm_bo(*ptr
);
120 assert(oldBuf
->refcount
>= 0);
121 if (oldBuf
->refcount
== 0) {
123 if (!oldBuf
->userBuffer
)
135 struct xm_buffer
*newBuf
= xm_bo(buf
);
142 xm_buffer_data(struct pipe_winsys
*pws
, struct pipe_buffer_handle
*buf
,
143 unsigned size
, const void *data
)
145 struct xm_buffer
*xm_buf
= xm_bo(buf
);
146 assert(!xm_buf
->userBuffer
);
147 if (xm_buf
->size
!= size
) {
150 xm_buf
->data
= malloc(size
);
154 memcpy(xm_buf
->data
, data
, size
);
158 xm_buffer_subdata(struct pipe_winsys
*pws
, struct pipe_buffer_handle
*buf
,
159 unsigned long offset
, unsigned long size
, const void *data
)
161 struct xm_buffer
*xm_buf
= xm_bo(buf
);
162 GLubyte
*b
= (GLubyte
*) xm_buf
->data
;
163 assert(!xm_buf
->userBuffer
);
165 memcpy(b
+ offset
, data
, size
);
169 xm_buffer_get_subdata(struct pipe_winsys
*pws
, struct pipe_buffer_handle
*buf
,
170 unsigned long offset
, unsigned long size
, void *data
)
172 const struct xm_buffer
*xm_buf
= xm_bo(buf
);
173 const GLubyte
*b
= (GLubyte
*) xm_buf
->data
;
174 assert(!xm_buf
->userBuffer
);
176 memcpy(data
, b
+ offset
, size
);
180 xm_flush_frontbuffer(struct pipe_winsys
*pws
)
183 struct intel_context *intel = intel_pipe_winsys(sws)->intel;
184 __DRIdrawablePrivate *dPriv = intel->driDrawable;
186 intelCopyBuffer(dPriv, NULL);
191 xm_wait_idle(struct pipe_winsys
*pws
)
197 xm_printf(struct pipe_winsys
*pws
, const char *fmtString
, ...)
200 va_start( args
, fmtString
);
201 vfprintf(stderr
, fmtString
, args
);
206 xm_get_name(struct pipe_winsys
*pws
)
212 static struct pipe_buffer_handle
*
213 xm_buffer_create(struct pipe_winsys
*pws
, unsigned alignment
)
215 struct xm_buffer
*buffer
= CALLOC_STRUCT(xm_buffer
);
216 buffer
->refcount
= 1;
217 return pipe_bo(buffer
);
222 * Create buffer which wraps user-space data.
224 static struct pipe_buffer_handle
*
225 xm_user_buffer_create(struct pipe_winsys
*pws
, void *ptr
, unsigned bytes
)
227 struct xm_buffer
*buffer
= CALLOC_STRUCT(xm_buffer
);
228 buffer
->userBuffer
= TRUE
;
229 buffer
->refcount
= 1;
231 buffer
->size
= bytes
;
232 return pipe_bo(buffer
);
238 * Round n up to next multiple.
240 static INLINE
unsigned
241 round_up(unsigned n
, unsigned multiple
)
243 return (n
+ multiple
- 1) & ~(multiple
- 1);
247 static struct pipe_region
*
248 xm_region_alloc(struct pipe_winsys
*winsys
,
249 unsigned cpp
, unsigned width
, unsigned height
, unsigned flags
)
251 struct pipe_region
*region
= CALLOC_STRUCT(pipe_region
);
252 const unsigned alignment
= 64;
255 region
->pitch
= round_up(width
, alignment
/ cpp
);
256 region
->height
= height
;
257 region
->refcount
= 1;
259 assert(region
->pitch
> 0);
261 region
->buffer
= winsys
->buffer_create( winsys
, alignment
)
264 /* NULL data --> just allocate the space */
265 winsys
->buffer_data( winsys
,
267 region
->pitch
* cpp
* height
,
274 xm_region_release(struct pipe_winsys
*winsys
, struct pipe_region
**region
)
279 assert((*region
)->refcount
> 0);
280 (*region
)->refcount
--;
282 if ((*region
)->refcount
== 0) {
283 assert((*region
)->map_refcount
== 0);
285 winsys
->buffer_reference( winsys
, &((*region
)->buffer
), NULL
);
293 * Called via pipe->surface_alloc() to create new surfaces (textures,
294 * renderbuffers, etc.
296 static struct pipe_surface
*
297 xm_surface_alloc(struct pipe_winsys
*ws
, GLuint pipeFormat
)
299 struct xmesa_surface
*xms
= CALLOC_STRUCT(xmesa_surface
);
304 xms
->surface
.format
= pipeFormat
;
305 xms
->surface
.refcount
= 1;
308 * This is really just a softpipe surface, not an XImage/Pixmap surface.
310 softpipe_init_surface_funcs(&xms
->surface
);
312 return &xms
->surface
;
318 struct xmesa_pipe_winsys
320 struct pipe_winsys winsys
;
324 static struct pipe_winsys
*
325 xmesa_create_pipe_winsys( XMesaContext xmesa
)
327 struct xmesa_pipe_winsys
*xws
= CALLOC_STRUCT(xmesa_pipe_winsys
);
329 /* Fill in this struct with callbacks that pipe will need to
330 * communicate with the window system, buffer manager, etc.
332 * Pipe would be happy with a malloc based memory manager, but
333 * the SwapBuffers implementation in this winsys driver requires
334 * that rendering be done to an appropriate _DriBufferObject.
336 xws
->winsys
.buffer_create
= xm_buffer_create
;
337 xws
->winsys
.user_buffer_create
= xm_user_buffer_create
;
338 xws
->winsys
.buffer_map
= xm_buffer_map
;
339 xws
->winsys
.buffer_unmap
= xm_buffer_unmap
;
340 xws
->winsys
.buffer_reference
= xm_buffer_reference
;
341 xws
->winsys
.buffer_data
= xm_buffer_data
;
342 xws
->winsys
.buffer_subdata
= xm_buffer_subdata
;
343 xws
->winsys
.buffer_get_subdata
= xm_buffer_get_subdata
;
345 xws
->winsys
.region_alloc
= xm_region_alloc
;
346 xws
->winsys
.region_release
= xm_region_release
;
348 xws
->winsys
.surface_alloc
= xm_surface_alloc
;
350 xws
->winsys
.flush_frontbuffer
= xm_flush_frontbuffer
;
351 xws
->winsys
.wait_idle
= xm_wait_idle
;
352 xws
->winsys
.printf
= xm_printf
;
353 xws
->winsys
.get_name
= xm_get_name
;
360 struct pipe_context
*
361 xmesa_create_softpipe(XMesaContext xmesa
)
363 struct xm_winsys
*xm_ws
= CALLOC_STRUCT( xm_winsys
);
365 /* Create the softpipe context:
367 return softpipe_create( xmesa_create_pipe_winsys(xmesa
), &xm_ws
->sws
);