st/g3dvl: pass color values to softpipe clear function
[mesa.git] / src / gallium / winsys / g3dvl / xsp_winsys.c
1 #include "vl_winsys.h"
2 #include <X11/Xutil.h>
3 #include <pipe/internal/p_winsys_screen.h>
4 #include <pipe/p_state.h>
5 #include <pipe/p_inlines.h>
6 #include <util/u_memory.h>
7 #include <util/u_math.h>
8 #include <softpipe/sp_winsys.h>
9 #include <softpipe/sp_texture.h>
10
11 /* pipe_winsys implementation */
12
13 struct xsp_pipe_winsys
14 {
15 struct pipe_winsys base;
16 XImage fbimage;
17 };
18
19 struct xsp_context
20 {
21 Display *display;
22 int screen;
23 Drawable drawable;
24 int drawable_bound;
25 };
26
27 struct xsp_buffer
28 {
29 struct pipe_buffer base;
30 boolean is_user_buffer;
31 void *data;
32 void *mapped_data;
33 };
34
35 static struct pipe_buffer* xsp_buffer_create(struct pipe_winsys *pws, unsigned alignment, unsigned usage, unsigned size)
36 {
37 struct xsp_buffer *buffer;
38
39 assert(pws);
40
41 buffer = calloc(1, sizeof(struct xsp_buffer));
42 pipe_reference_init(&buffer->base.reference, 1);
43 buffer->base.alignment = alignment;
44 buffer->base.usage = usage;
45 buffer->base.size = size;
46 buffer->data = align_malloc(size, alignment);
47
48 return (struct pipe_buffer*)buffer;
49 }
50
51 static struct pipe_buffer* xsp_user_buffer_create(struct pipe_winsys *pws, void *data, unsigned size)
52 {
53 struct xsp_buffer *buffer;
54
55 assert(pws);
56
57 buffer = calloc(1, sizeof(struct xsp_buffer));
58 pipe_reference_init(&buffer->base.reference, 1);
59 buffer->base.size = size;
60 buffer->is_user_buffer = TRUE;
61 buffer->data = data;
62
63 return (struct pipe_buffer*)buffer;
64 }
65
66 static void* xsp_buffer_map(struct pipe_winsys *pws, struct pipe_buffer *buffer, unsigned flags)
67 {
68 struct xsp_buffer *xsp_buf = (struct xsp_buffer*)buffer;
69
70 assert(pws);
71 assert(buffer);
72
73 xsp_buf->mapped_data = xsp_buf->data;
74
75 return xsp_buf->mapped_data;
76 }
77
78 static void xsp_buffer_unmap(struct pipe_winsys *pws, struct pipe_buffer *buffer)
79 {
80 struct xsp_buffer *xsp_buf = (struct xsp_buffer*)buffer;
81
82 assert(pws);
83 assert(buffer);
84
85 xsp_buf->mapped_data = NULL;
86 }
87
88 static void xsp_buffer_destroy(struct pipe_winsys *pws, struct pipe_buffer *buffer)
89 {
90 struct xsp_buffer *xsp_buf = (struct xsp_buffer*)buffer;
91
92 assert(pws);
93 assert(buffer);
94
95 if (!xsp_buf->is_user_buffer)
96 align_free(xsp_buf->data);
97
98 free(xsp_buf);
99 }
100
101 static struct pipe_buffer* xsp_surface_buffer_create
102 (
103 struct pipe_winsys *pws,
104 unsigned width,
105 unsigned height,
106 enum pipe_format format,
107 unsigned usage,
108 unsigned tex_usage,
109 unsigned *stride
110 )
111 {
112 const unsigned int ALIGNMENT = 1;
113 struct pipe_format_block block;
114 unsigned nblocksx, nblocksy;
115
116 pf_get_block(format, &block);
117 nblocksx = pf_get_nblocksx(&block, width);
118 nblocksy = pf_get_nblocksy(&block, height);
119 *stride = align(nblocksx * block.size, ALIGNMENT);
120
121 return pws->buffer_create(pws, ALIGNMENT,
122 usage,
123 *stride * nblocksy);
124 }
125
126 static void xsp_fence_reference(struct pipe_winsys *pws, struct pipe_fence_handle **ptr, struct pipe_fence_handle *fence)
127 {
128 assert(pws);
129 assert(ptr);
130 assert(fence);
131 }
132
133 static int xsp_fence_signalled(struct pipe_winsys *pws, struct pipe_fence_handle *fence, unsigned flag)
134 {
135 assert(pws);
136 assert(fence);
137
138 return 0;
139 }
140
141 static int xsp_fence_finish(struct pipe_winsys *pws, struct pipe_fence_handle *fence, unsigned flag)
142 {
143 assert(pws);
144 assert(fence);
145
146 return 0;
147 }
148
149 static void xsp_flush_frontbuffer(struct pipe_winsys *pws, struct pipe_surface *surface, void *context_private)
150 {
151 struct xsp_pipe_winsys *xsp_winsys;
152 struct xsp_context *xsp_context;
153
154 assert(pws);
155 assert(surface);
156 assert(context_private);
157
158 xsp_winsys = (struct xsp_pipe_winsys*)pws;
159 xsp_context = (struct xsp_context*)context_private;
160
161 if (!xsp_context->drawable_bound)
162 return;
163
164 xsp_winsys->fbimage.width = surface->width;
165 xsp_winsys->fbimage.height = surface->height;
166 xsp_winsys->fbimage.bytes_per_line = surface->width * (xsp_winsys->fbimage.bits_per_pixel >> 3);
167 xsp_winsys->fbimage.data = ((struct xsp_buffer *)softpipe_texture(surface->texture)->buffer)->data + surface->offset;
168
169 XPutImage
170 (
171 xsp_context->display,
172 xsp_context->drawable,
173 XDefaultGC(xsp_context->display, xsp_context->screen),
174 &xsp_winsys->fbimage,
175 0,
176 0,
177 0,
178 0,
179 surface->width,
180 surface->height
181 );
182 XFlush(xsp_context->display);
183 }
184
185 static const char* xsp_get_name(struct pipe_winsys *pws)
186 {
187 assert(pws);
188 return "X11 SoftPipe";
189 }
190
191 /* Show starts here */
192
193 int bind_pipe_drawable(struct pipe_context *pipe, Drawable drawable)
194 {
195 struct xsp_context *xsp_context;
196
197 assert(pipe);
198
199 xsp_context = pipe->priv;
200 xsp_context->drawable = drawable;
201 xsp_context->drawable_bound = 1;
202
203 return 0;
204 }
205
206 int unbind_pipe_drawable(struct pipe_context *pipe)
207 {
208 struct xsp_context *xsp_context;
209
210 assert(pipe);
211
212 xsp_context = pipe->priv;
213 xsp_context->drawable_bound = 0;
214
215 return 0;
216 }
217
218 struct pipe_context* create_pipe_context(Display *display, int screen)
219 {
220 struct xsp_pipe_winsys *xsp_winsys;
221 struct xsp_context *xsp_context;
222 struct pipe_screen *sp_screen;
223 struct pipe_context *sp_pipe;
224
225 assert(display);
226
227 xsp_winsys = calloc(1, sizeof(struct xsp_pipe_winsys));
228 xsp_winsys->base.buffer_create = xsp_buffer_create;
229 xsp_winsys->base.user_buffer_create = xsp_user_buffer_create;
230 xsp_winsys->base.buffer_map = xsp_buffer_map;
231 xsp_winsys->base.buffer_unmap = xsp_buffer_unmap;
232 xsp_winsys->base.buffer_destroy = xsp_buffer_destroy;
233 xsp_winsys->base.surface_buffer_create = xsp_surface_buffer_create;
234 xsp_winsys->base.fence_reference = xsp_fence_reference;
235 xsp_winsys->base.fence_signalled = xsp_fence_signalled;
236 xsp_winsys->base.fence_finish = xsp_fence_finish;
237 xsp_winsys->base.flush_frontbuffer = xsp_flush_frontbuffer;
238 xsp_winsys->base.get_name = xsp_get_name;
239
240 {
241 /* XXX: Can't use the returned XImage* directly,
242 since we don't have control over winsys destruction
243 and we wouldn't be able to free it */
244 XImage *template = XCreateImage
245 (
246 display,
247 XDefaultVisual(display, XDefaultScreen(display)),
248 XDefaultDepth(display, XDefaultScreen(display)),
249 ZPixmap,
250 0,
251 NULL,
252 0, /* Don't know the width and height until flush_frontbuffer */
253 0,
254 32,
255 0
256 );
257
258 memcpy(&xsp_winsys->fbimage, template, sizeof(XImage));
259 XInitImage(&xsp_winsys->fbimage);
260
261 XDestroyImage(template);
262 }
263
264 sp_screen = softpipe_create_screen((struct pipe_winsys*)xsp_winsys);
265 sp_pipe = softpipe_create(sp_screen);
266
267 xsp_context = calloc(1, sizeof(struct xsp_context));
268 xsp_context->display = display;
269 xsp_context->screen = screen;
270
271 sp_pipe->priv = xsp_context;
272
273 return sp_pipe;
274 }
275
276 int destroy_pipe_context(struct pipe_context *pipe)
277 {
278 struct pipe_screen *screen;
279 struct pipe_winsys *winsys;
280
281 assert(pipe);
282
283 screen = pipe->screen;
284 winsys = pipe->winsys;
285 free(pipe->priv);
286 pipe->destroy(pipe);
287 screen->destroy(screen);
288 free(winsys);
289
290 return 0;
291 }