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 * Low-level OS/window system memory buffer
49 boolean userBuffer
; /** Is this a user-space buffer? */
58 /* Turn the softpipe opaque buffer pointer into a dri_bufmgr opaque
61 static inline struct xm_buffer
*
62 xm_bo( struct pipe_buffer_handle
*bo
)
64 return (struct xm_buffer
*) bo
;
67 static inline struct pipe_buffer_handle
*
68 pipe_bo( struct xm_buffer
*bo
)
70 return (struct pipe_buffer_handle
*) bo
;
74 /* Most callbacks map direcly onto dri_bufmgr operations:
77 xm_buffer_map(struct pipe_winsys
*pws
, struct pipe_buffer_handle
*buf
,
80 struct xm_buffer
*xm_buf
= xm_bo(buf
);
81 xm_buf
->mapped
= xm_buf
->data
;
82 return xm_buf
->mapped
;
86 xm_buffer_unmap(struct pipe_winsys
*pws
, struct pipe_buffer_handle
*buf
)
88 struct xm_buffer
*xm_buf
= xm_bo(buf
);
89 xm_buf
->mapped
= NULL
;
93 xm_buffer_reference(struct pipe_winsys
*pws
,
94 struct pipe_buffer_handle
**ptr
,
95 struct pipe_buffer_handle
*buf
)
98 struct xm_buffer
*oldBuf
= xm_bo(*ptr
);
100 assert(oldBuf
->refcount
>= 0);
101 if (oldBuf
->refcount
== 0) {
103 if (!oldBuf
->userBuffer
)
115 struct xm_buffer
*newBuf
= xm_bo(buf
);
122 xm_buffer_data(struct pipe_winsys
*pws
, struct pipe_buffer_handle
*buf
,
123 unsigned size
, const void *data
, unsigned usage
)
125 struct xm_buffer
*xm_buf
= xm_bo(buf
);
126 assert(!xm_buf
->userBuffer
);
127 if (xm_buf
->size
!= size
) {
130 xm_buf
->data
= malloc(size
);
134 memcpy(xm_buf
->data
, data
, size
);
138 xm_buffer_subdata(struct pipe_winsys
*pws
, struct pipe_buffer_handle
*buf
,
139 unsigned long offset
, unsigned long size
, const void *data
)
141 struct xm_buffer
*xm_buf
= xm_bo(buf
);
142 GLubyte
*b
= (GLubyte
*) xm_buf
->data
;
143 assert(!xm_buf
->userBuffer
);
145 memcpy(b
+ offset
, data
, size
);
149 xm_buffer_get_subdata(struct pipe_winsys
*pws
, struct pipe_buffer_handle
*buf
,
150 unsigned long offset
, unsigned long size
, void *data
)
152 const struct xm_buffer
*xm_buf
= xm_bo(buf
);
153 const GLubyte
*b
= (GLubyte
*) xm_buf
->data
;
154 assert(!xm_buf
->userBuffer
);
156 memcpy(data
, b
+ offset
, size
);
160 xm_flush_frontbuffer(struct pipe_winsys
*pws
,
161 struct pipe_surface
*surf
)
163 /* The Xlib driver's front color surfaces are actually X Windows so
164 * this flush is a no-op.
165 * If we instead did front buffer rendering to a temporary XImage,
166 * this would be the place to copy the Ximage to the on-screen Window.
171 xm_wait_idle(struct pipe_winsys
*pws
)
177 xm_printf(struct pipe_winsys
*pws
, const char *fmtString
, ...)
180 va_start( args
, fmtString
);
181 vfprintf(stderr
, fmtString
, args
);
186 xm_get_name(struct pipe_winsys
*pws
)
192 static struct pipe_buffer_handle
*
193 xm_buffer_create(struct pipe_winsys
*pws
, unsigned alignment
)
195 struct xm_buffer
*buffer
= CALLOC_STRUCT(xm_buffer
);
196 buffer
->refcount
= 1;
197 return pipe_bo(buffer
);
202 * Create buffer which wraps user-space data.
204 static struct pipe_buffer_handle
*
205 xm_user_buffer_create(struct pipe_winsys
*pws
, void *ptr
, unsigned bytes
)
207 struct xm_buffer
*buffer
= CALLOC_STRUCT(xm_buffer
);
208 buffer
->userBuffer
= TRUE
;
209 buffer
->refcount
= 1;
211 buffer
->size
= bytes
;
212 return pipe_bo(buffer
);
218 * Round n up to next multiple.
220 static INLINE
unsigned
221 round_up(unsigned n
, unsigned multiple
)
223 return (n
+ multiple
- 1) & ~(multiple
- 1);
227 static struct pipe_region
*
228 xm_region_alloc(struct pipe_winsys
*winsys
,
229 unsigned cpp
, unsigned width
, unsigned height
, unsigned flags
)
231 struct pipe_region
*region
= CALLOC_STRUCT(pipe_region
);
232 const unsigned alignment
= 64;
235 region
->pitch
= round_up(width
, alignment
/ cpp
);
236 region
->height
= height
;
237 region
->refcount
= 1;
239 assert(region
->pitch
> 0);
241 region
->buffer
= winsys
->buffer_create( winsys
, alignment
)
244 /* NULL data --> just allocate the space */
245 winsys
->buffer_data( winsys
,
247 region
->pitch
* cpp
* height
,
249 PIPE_BUFFER_USAGE_PIXEL
);
255 xm_region_release(struct pipe_winsys
*winsys
, struct pipe_region
**region
)
260 assert((*region
)->refcount
> 0);
261 (*region
)->refcount
--;
263 if ((*region
)->refcount
== 0) {
264 assert((*region
)->map_refcount
== 0);
266 winsys
->buffer_reference( winsys
, &((*region
)->buffer
), NULL
);
274 * Called via pipe->surface_alloc() to create new surfaces (textures,
275 * renderbuffers, etc.
277 static struct pipe_surface
*
278 xm_surface_alloc(struct pipe_winsys
*ws
, GLuint pipeFormat
)
280 struct xmesa_surface
*xms
= CALLOC_STRUCT(xmesa_surface
);
285 xms
->surface
.format
= pipeFormat
;
286 xms
->surface
.refcount
= 1;
287 xms
->surface
.winsys
= ws
;
290 * This is really just a softpipe surface, not an XImage/Pixmap surface.
292 softpipe_init_surface_funcs(&xms
->surface
);
294 return &xms
->surface
;
300 xm_surface_release(struct pipe_winsys
*winsys
, struct pipe_surface
**s
)
302 struct pipe_surface
*surf
= *s
;
304 if (surf
->refcount
== 0) {
306 winsys
->region_release(winsys
, &surf
->region
);
315 * Return pointer to a pipe_winsys object.
316 * For Xlib, this is a singleton object.
317 * Nothing special for the Xlib driver so no subclassing or anything.
320 xmesa_get_pipe_winsys(void)
322 static struct pipe_winsys
*ws
= NULL
;
325 ws
= CALLOC_STRUCT(pipe_winsys
);
327 /* Fill in this struct with callbacks that pipe will need to
328 * communicate with the window system, buffer manager, etc.
330 ws
->buffer_create
= xm_buffer_create
;
331 ws
->user_buffer_create
= xm_user_buffer_create
;
332 ws
->buffer_map
= xm_buffer_map
;
333 ws
->buffer_unmap
= xm_buffer_unmap
;
334 ws
->buffer_reference
= xm_buffer_reference
;
335 ws
->buffer_data
= xm_buffer_data
;
336 ws
->buffer_subdata
= xm_buffer_subdata
;
337 ws
->buffer_get_subdata
= xm_buffer_get_subdata
;
339 ws
->region_alloc
= xm_region_alloc
;
340 ws
->region_release
= xm_region_release
;
342 ws
->surface_alloc
= xm_surface_alloc
;
343 ws
->surface_release
= xm_surface_release
;
345 ws
->flush_frontbuffer
= xm_flush_frontbuffer
;
346 ws
->wait_idle
= xm_wait_idle
;
347 ws
->printf
= xm_printf
;
348 ws
->get_name
= xm_get_name
;
356 * XXX this depends on the depths supported by the screen (8/16/32/etc).
357 * Maybe when we're about to create a context/drawable we create a new
358 * softpipe_winsys object that corresponds to the specified screen...
360 * Also, this query only really matters for on-screen drawables.
361 * For textures and FBOs we (softpipe) can support any format.o
364 xmesa_is_format_supported(struct softpipe_winsys
*sws
, uint format
)
366 /* Any format supported by softpipe can be listed here.
367 * This query is not used for allocating window-system color buffers
368 * (which would depend on the screen depth/bpp).
371 case PIPE_FORMAT_U_A8_R8_G8_B8
:
372 case PIPE_FORMAT_S_R16_G16_B16_A16
:
373 case PIPE_FORMAT_S8_Z24
:
374 case PIPE_FORMAT_U_S8
:
375 case PIPE_FORMAT_U_Z16
:
376 /*case PIPE_FORMAT_U_Z32:*/
385 * Return pointer to a softpipe_winsys object.
386 * For Xlib, this is a singleton object.
388 static struct softpipe_winsys
*
389 xmesa_get_softpipe_winsys(void)
391 static struct softpipe_winsys
*spws
= NULL
;
394 spws
= CALLOC_STRUCT(softpipe_winsys
);
396 spws
->is_format_supported
= xmesa_is_format_supported
;
404 struct pipe_context
*
405 xmesa_create_context(XMesaContext xmesa
)
407 struct pipe_winsys
*pws
= xmesa_get_pipe_winsys();
408 struct softpipe_winsys
*spws
= xmesa_get_softpipe_winsys();
410 return softpipe_create( pws
, spws
);