1 /**************************************************************************
3 * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
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 above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 **************************************************************************/
29 * Totally software-based winsys layer.
30 * Note that the one winsys function that we can't implement here
31 * is flush_frontbuffer().
32 * Whoever uses this code will have to provide that.
38 #include "pipe/p_winsys.h"
39 #include "pipe/p_state.h"
40 #include "pipe/p_inlines.h"
41 #include "util/u_math.h"
42 #include "util/u_memory.h"
44 #include "sw_winsys.h"
48 /** Subclass of pipe_winsys */
51 struct pipe_winsys Base
;
52 /* no extra fields for now */
56 /** subclass of pipe_buffer */
59 struct pipe_buffer Base
;
60 boolean UserBuffer
; /** Is this a user-space buffer? */
67 static INLINE
struct sw_pipe_buffer
*
68 sw_pipe_buffer(struct pipe_buffer
*b
)
70 return (struct sw_pipe_buffer
*) b
;
75 * Round n up to next multiple.
77 static INLINE
unsigned
78 round_up(unsigned n
, unsigned multiple
)
80 return (n
+ multiple
- 1) & ~(multiple
- 1);
85 get_name(struct pipe_winsys
*pws
)
91 /** Create new pipe_buffer and allocate storage of given size */
92 static struct pipe_buffer
*
93 buffer_create(struct pipe_winsys
*pws
,
98 struct sw_pipe_buffer
*buffer
= CALLOC_STRUCT(sw_pipe_buffer
);
102 buffer
->Base
.refcount
= 1;
103 buffer
->Base
.alignment
= alignment
;
104 buffer
->Base
.usage
= usage
;
105 buffer
->Base
.size
= size
;
107 /* align to 16-byte multiple for Cell */
108 buffer
->Data
= align_malloc(size
, MAX2(alignment
, 16));
110 return &buffer
->Base
;
115 * Create buffer which wraps user-space data.
117 static struct pipe_buffer
*
118 user_buffer_create(struct pipe_winsys
*pws
, void *ptr
, unsigned bytes
)
120 struct sw_pipe_buffer
*buffer
= CALLOC_STRUCT(sw_pipe_buffer
);
124 buffer
->Base
.refcount
= 1;
125 buffer
->Base
.size
= bytes
;
126 buffer
->UserBuffer
= TRUE
;
129 return &buffer
->Base
;
134 buffer_map(struct pipe_winsys
*pws
, struct pipe_buffer
*buf
, unsigned flags
)
136 struct sw_pipe_buffer
*buffer
= sw_pipe_buffer(buf
);
137 buffer
->Mapped
= buffer
->Data
;
138 return buffer
->Mapped
;
143 buffer_unmap(struct pipe_winsys
*pws
, struct pipe_buffer
*buf
)
145 struct sw_pipe_buffer
*buffer
= sw_pipe_buffer(buf
);
146 buffer
->Mapped
= NULL
;
151 buffer_destroy(struct pipe_winsys
*pws
, struct pipe_buffer
*buf
)
153 struct sw_pipe_buffer
*buffer
= sw_pipe_buffer(buf
);
155 if (buffer
->Data
&& !buffer
->UserBuffer
) {
156 align_free(buffer
->Data
);
165 * Called via winsys->surface_alloc() to create new surfaces.
167 static struct pipe_surface
*
168 surface_alloc(struct pipe_winsys
*ws
)
170 struct pipe_surface
*surf
= CALLOC_STRUCT(pipe_surface
);
182 surface_alloc_storage(struct pipe_winsys
*winsys
,
183 struct pipe_surface
*surf
,
184 unsigned width
, unsigned height
,
185 enum pipe_format format
,
189 const unsigned alignment
= 64;
192 surf
->height
= height
;
193 surf
->format
= format
;
194 pf_get_block(surf
->format
, &surf
->block
);
195 surf
->nblocksx
= pf_get_nblocksx(&surf
->block
, width
);
196 surf
->nblocksy
= pf_get_nblocksy(&surf
->block
, height
);
197 surf
->stride
= round_up(surf
->nblocksx
* surf
->block
.size
, alignment
);
200 assert(!surf
->buffer
);
201 surf
->buffer
= winsys
->buffer_create(winsys
, alignment
,
202 PIPE_BUFFER_USAGE_PIXEL
,
203 surf
->stride
* height
);
212 surface_release(struct pipe_winsys
*winsys
, struct pipe_surface
**s
)
214 struct pipe_surface
*surf
= *s
;
215 assert(!surf
->texture
);
217 if (surf
->refcount
== 0) {
219 winsys_buffer_reference(winsys
, &surf
->buffer
, NULL
);
227 fence_reference(struct pipe_winsys
*sws
, struct pipe_fence_handle
**ptr
,
228 struct pipe_fence_handle
*fence
)
235 fence_signalled(struct pipe_winsys
*sws
, struct pipe_fence_handle
*fence
,
244 fence_finish(struct pipe_winsys
*sws
, struct pipe_fence_handle
*fence
,
253 * Create/return a new pipe_winsys object.
256 create_sw_winsys(void)
258 struct sw_pipe_winsys
*ws
= CALLOC_STRUCT(sw_pipe_winsys
);
262 /* Fill in this struct with callbacks that pipe will need to
263 * communicate with the window system, buffer manager, etc.
265 ws
->Base
.buffer_create
= buffer_create
;
266 ws
->Base
.user_buffer_create
= user_buffer_create
;
267 ws
->Base
.buffer_map
= buffer_map
;
268 ws
->Base
.buffer_unmap
= buffer_unmap
;
269 ws
->Base
.buffer_destroy
= buffer_destroy
;
271 ws
->Base
.surface_alloc
= surface_alloc
;
272 ws
->Base
.surface_alloc_storage
= surface_alloc_storage
;
273 ws
->Base
.surface_release
= surface_release
;
275 ws
->Base
.fence_reference
= fence_reference
;
276 ws
->Base
.fence_signalled
= fence_signalled
;
277 ws
->Base
.fence_finish
= fence_finish
;
279 ws
->Base
.flush_frontbuffer
= NULL
; /* not implemented here! */
281 ws
->Base
.get_name
= get_name
;