2c7a6f893b0a043d54ccb48426e83a786d1df989
[mesa.git] / src / gallium / drivers / trace / tr_winsys.c
1 /**************************************************************************
2 *
3 * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
4 * All Rights Reserved.
5 *
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:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
16 * of the Software.
17 *
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.
25 *
26 **************************************************************************/
27
28 #include "pipe/p_util.h"
29 #include "pipe/p_state.h"
30 #include "util/u_hash_table.h"
31
32 #include "tr_dump.h"
33 #include "tr_state.h"
34 #include "tr_screen.h"
35 #include "tr_texture.h"
36 #include "tr_winsys.h"
37
38
39 static unsigned trace_buffer_hash(void *buffer)
40 {
41 return (unsigned)(uintptr_t)buffer;
42 }
43
44
45 static int trace_buffer_compare(void *buffer1, void *buffer2)
46 {
47 return (char *)buffer2 - (char *)buffer1;
48 }
49
50
51 static const char *
52 trace_winsys_get_name(struct pipe_winsys *_winsys)
53 {
54 struct trace_winsys *tr_ws = trace_winsys(_winsys);
55 struct pipe_winsys *winsys = tr_ws->winsys;
56 const char *result;
57
58 trace_dump_call_begin("pipe_winsys", "get_name");
59
60 trace_dump_arg(ptr, winsys);
61
62 result = winsys->get_name(winsys);
63
64 trace_dump_ret(string, result);
65
66 trace_dump_call_end();
67
68 return result;
69 }
70
71
72 static void
73 trace_winsys_flush_frontbuffer(struct pipe_winsys *_winsys,
74 struct pipe_surface *surface,
75 void *context_private)
76 {
77 struct trace_winsys *tr_ws = trace_winsys(_winsys);
78 struct pipe_winsys *winsys = tr_ws->winsys;
79
80 assert(surface);
81 if(surface->texture) {
82 struct trace_screen *tr_scr = trace_screen(surface->texture->screen);
83 struct trace_texture *tr_tex = trace_texture(tr_scr, surface->texture);
84 struct trace_surface *tr_surf = trace_surface(tr_tex, surface);
85 surface = tr_surf->surface;
86 }
87
88 trace_dump_call_begin("pipe_winsys", "flush_frontbuffer");
89
90 trace_dump_arg(ptr, winsys);
91 trace_dump_arg(ptr, surface);
92 /* XXX: hide, as there is nothing we can do with this
93 trace_dump_arg(ptr, context_private);
94 */
95
96 winsys->flush_frontbuffer(winsys, surface, context_private);
97
98 trace_dump_call_end();
99 }
100
101
102 static struct pipe_surface *
103 trace_winsys_surface_alloc(struct pipe_winsys *_winsys)
104 {
105 struct trace_winsys *tr_ws = trace_winsys(_winsys);
106 struct pipe_winsys *winsys = tr_ws->winsys;
107 struct pipe_surface *result;
108
109 trace_dump_call_begin("pipe_winsys", "surface_alloc");
110
111 trace_dump_arg(ptr, winsys);
112
113 result = winsys->surface_alloc(winsys);
114
115 trace_dump_ret(ptr, result);
116
117 trace_dump_call_end();
118
119 assert(!result || !result->texture);
120
121 return result;
122 }
123
124
125 static int
126 trace_winsys_surface_alloc_storage(struct pipe_winsys *_winsys,
127 struct pipe_surface *surface,
128 unsigned width, unsigned height,
129 enum pipe_format format,
130 unsigned flags,
131 unsigned tex_usage)
132 {
133 struct trace_winsys *tr_ws = trace_winsys(_winsys);
134 struct pipe_winsys *winsys = tr_ws->winsys;
135 int result;
136
137 assert(surface && !surface->texture);
138
139 trace_dump_call_begin("pipe_winsys", "surface_alloc_storage");
140
141 trace_dump_arg(ptr, winsys);
142 trace_dump_arg(ptr, surface);
143 trace_dump_arg(uint, width);
144 trace_dump_arg(uint, height);
145 trace_dump_arg(format, format);
146 trace_dump_arg(uint, flags);
147 trace_dump_arg(uint, tex_usage);
148
149 result = winsys->surface_alloc_storage(winsys,
150 surface,
151 width, height,
152 format,
153 flags,
154 tex_usage);
155
156 trace_dump_ret(int, result);
157
158 trace_dump_call_end();
159
160 return result;
161 }
162
163
164 static void
165 trace_winsys_surface_release(struct pipe_winsys *_winsys,
166 struct pipe_surface **psurface)
167 {
168 struct trace_winsys *tr_ws = trace_winsys(_winsys);
169 struct pipe_winsys *winsys = tr_ws->winsys;
170 struct pipe_surface *surface = *psurface;
171
172 assert(psurface && *psurface && !(*psurface)->texture);
173
174 trace_dump_call_begin("pipe_winsys", "surface_release");
175
176 trace_dump_arg(ptr, winsys);
177 trace_dump_arg(ptr, surface);
178
179 winsys->surface_release(winsys, psurface);
180
181 trace_dump_call_end();
182 }
183
184
185 static struct pipe_buffer *
186 trace_winsys_buffer_create(struct pipe_winsys *_winsys,
187 unsigned alignment,
188 unsigned usage,
189 unsigned size)
190 {
191 struct trace_winsys *tr_ws = trace_winsys(_winsys);
192 struct pipe_winsys *winsys = tr_ws->winsys;
193 struct pipe_buffer *buffer;
194
195 trace_dump_call_begin("pipe_winsys", "buffer_create");
196
197 trace_dump_arg(ptr, winsys);
198 trace_dump_arg(uint, alignment);
199 trace_dump_arg(uint, usage);
200 trace_dump_arg(uint, size);
201
202 buffer = winsys->buffer_create(winsys, alignment, usage, size);
203
204 trace_dump_ret(ptr, buffer);
205
206 trace_dump_call_end();
207
208 /* Zero the buffer to avoid dumping uninitialized memory */
209 if(buffer->usage & PIPE_BUFFER_USAGE_CPU_WRITE) {
210 void *map;
211 map = winsys->buffer_map(winsys, buffer, PIPE_BUFFER_USAGE_CPU_WRITE);
212 if(map) {
213 memset(map, 0, buffer->size);
214 winsys->buffer_unmap(winsys, buffer);
215 }
216 }
217
218 return buffer;
219 }
220
221
222 static struct pipe_buffer *
223 trace_winsys_user_buffer_create(struct pipe_winsys *_winsys,
224 void *data,
225 unsigned size)
226 {
227 struct trace_winsys *tr_ws = trace_winsys(_winsys);
228 struct pipe_winsys *winsys = tr_ws->winsys;
229 struct pipe_buffer *result;
230
231 trace_dump_call_begin("pipe_winsys", "user_buffer_create");
232
233 trace_dump_arg(ptr, winsys);
234 trace_dump_arg_begin("data");
235 trace_dump_bytes(data, size);
236 trace_dump_arg_end();
237 trace_dump_arg(uint, size);
238
239 result = winsys->user_buffer_create(winsys, data, size);
240
241 trace_dump_ret(ptr, result);
242
243 trace_dump_call_end();
244
245 /* XXX: Mark the user buffers. (we should wrap pipe_buffers, but is is
246 * impossible to do so while texture-less surfaces are still around */
247 if(result) {
248 assert(!(result->usage & TRACE_BUFFER_USAGE_USER));
249 result->usage |= TRACE_BUFFER_USAGE_USER;
250 }
251
252 return result;
253 }
254
255
256 void
257 trace_winsys_user_buffer_update(struct pipe_winsys *_winsys,
258 struct pipe_buffer *buffer)
259 {
260 struct trace_winsys *tr_ws = trace_winsys(_winsys);
261 struct pipe_winsys *winsys = tr_ws->winsys;
262 const void *map;
263
264 if(buffer && buffer->usage & TRACE_BUFFER_USAGE_USER) {
265 map = winsys->buffer_map(winsys, buffer, PIPE_BUFFER_USAGE_CPU_READ);
266 if(map) {
267 trace_dump_call_begin("pipe_winsys", "buffer_write");
268
269 trace_dump_arg(ptr, winsys);
270
271 trace_dump_arg(ptr, buffer);
272
273 trace_dump_arg_begin("data");
274 trace_dump_bytes(map, buffer->size);
275 trace_dump_arg_end();
276
277 trace_dump_arg_begin("size");
278 trace_dump_uint(buffer->size);
279 trace_dump_arg_end();
280
281 trace_dump_call_end();
282
283 winsys->buffer_unmap(winsys, buffer);
284 }
285 }
286 }
287
288
289 static void *
290 trace_winsys_buffer_map(struct pipe_winsys *_winsys,
291 struct pipe_buffer *buffer,
292 unsigned usage)
293 {
294 struct trace_winsys *tr_ws = trace_winsys(_winsys);
295 struct pipe_winsys *winsys = tr_ws->winsys;
296 void *map;
297
298 map = winsys->buffer_map(winsys, buffer, usage);
299 if(map) {
300 if(usage & PIPE_BUFFER_USAGE_CPU_WRITE) {
301 assert(!hash_table_get(tr_ws->buffer_maps, buffer));
302 hash_table_set(tr_ws->buffer_maps, buffer, map);
303 }
304 }
305
306 return map;
307 }
308
309
310 static void
311 trace_winsys_buffer_unmap(struct pipe_winsys *_winsys,
312 struct pipe_buffer *buffer)
313 {
314 struct trace_winsys *tr_ws = trace_winsys(_winsys);
315 struct pipe_winsys *winsys = tr_ws->winsys;
316 const void *map;
317
318 map = hash_table_get(tr_ws->buffer_maps, buffer);
319 if(map) {
320 trace_dump_call_begin("pipe_winsys", "buffer_write");
321
322 trace_dump_arg(ptr, winsys);
323
324 trace_dump_arg(ptr, buffer);
325
326 trace_dump_arg_begin("data");
327 trace_dump_bytes(map, buffer->size);
328 trace_dump_arg_end();
329
330 trace_dump_arg_begin("size");
331 trace_dump_uint(buffer->size);
332 trace_dump_arg_end();
333
334 trace_dump_call_end();
335
336 hash_table_remove(tr_ws->buffer_maps, buffer);
337 }
338
339 winsys->buffer_unmap(winsys, buffer);
340 }
341
342
343 static void
344 trace_winsys_buffer_destroy(struct pipe_winsys *_winsys,
345 struct pipe_buffer *buffer)
346 {
347 struct trace_winsys *tr_ws = trace_winsys(_winsys);
348 struct pipe_winsys *winsys = tr_ws->winsys;
349
350 trace_dump_call_begin("pipe_winsys", "buffer_destroy");
351
352 trace_dump_arg(ptr, winsys);
353 trace_dump_arg(ptr, buffer);
354
355 winsys->buffer_destroy(winsys, buffer);
356
357 trace_dump_call_end();
358 }
359
360
361 static void
362 trace_winsys_fence_reference(struct pipe_winsys *_winsys,
363 struct pipe_fence_handle **pdst,
364 struct pipe_fence_handle *src)
365 {
366 struct trace_winsys *tr_ws = trace_winsys(_winsys);
367 struct pipe_winsys *winsys = tr_ws->winsys;
368 struct pipe_fence_handle *dst = *pdst;
369
370 trace_dump_call_begin("pipe_winsys", "fence_reference");
371
372 trace_dump_arg(ptr, winsys);
373 trace_dump_arg(ptr, dst);
374 trace_dump_arg(ptr, src);
375
376 winsys->fence_reference(winsys, pdst, src);
377
378 trace_dump_call_end();
379 }
380
381
382 static int
383 trace_winsys_fence_signalled(struct pipe_winsys *_winsys,
384 struct pipe_fence_handle *fence,
385 unsigned flag)
386 {
387 struct trace_winsys *tr_ws = trace_winsys(_winsys);
388 struct pipe_winsys *winsys = tr_ws->winsys;
389 int result;
390
391 trace_dump_call_begin("pipe_winsys", "fence_signalled");
392
393 trace_dump_arg(ptr, winsys);
394 trace_dump_arg(ptr, fence);
395 trace_dump_arg(uint, flag);
396
397 result = winsys->fence_signalled(winsys, fence, flag);
398
399 trace_dump_ret(int, result);
400
401 trace_dump_call_end();
402
403 return result;
404 }
405
406
407 static int
408 trace_winsys_fence_finish(struct pipe_winsys *_winsys,
409 struct pipe_fence_handle *fence,
410 unsigned flag)
411 {
412 struct trace_winsys *tr_ws = trace_winsys(_winsys);
413 struct pipe_winsys *winsys = tr_ws->winsys;
414 int result;
415
416 trace_dump_call_begin("pipe_winsys", "fence_finish");
417
418 trace_dump_arg(ptr, winsys);
419 trace_dump_arg(ptr, fence);
420 trace_dump_arg(uint, flag);
421
422 result = winsys->fence_finish(winsys, fence, flag);
423
424 trace_dump_ret(int, result);
425
426 trace_dump_call_end();
427
428 return result;
429 }
430
431
432 static void
433 trace_winsys_destroy(struct pipe_winsys *_winsys)
434 {
435 struct trace_winsys *tr_ws = trace_winsys(_winsys);
436 struct pipe_winsys *winsys = tr_ws->winsys;
437
438 trace_dump_call_begin("pipe_winsys", "destroy");
439
440 trace_dump_arg(ptr, winsys);
441
442 /*
443 winsys->destroy(winsys);
444 */
445
446 trace_dump_call_end();
447
448 hash_table_destroy(tr_ws->buffer_maps);
449
450 FREE(tr_ws);
451 }
452
453
454 struct pipe_winsys *
455 trace_winsys_create(struct pipe_winsys *winsys)
456 {
457 struct trace_winsys *tr_ws;
458
459 if(!winsys)
460 goto error1;
461
462 tr_ws = CALLOC_STRUCT(trace_winsys);
463 if(!tr_ws)
464 goto error1;
465
466 tr_ws->base.destroy = trace_winsys_destroy;
467 tr_ws->base.get_name = trace_winsys_get_name;
468 tr_ws->base.flush_frontbuffer = trace_winsys_flush_frontbuffer;
469 tr_ws->base.surface_alloc = trace_winsys_surface_alloc;
470 tr_ws->base.surface_alloc_storage = trace_winsys_surface_alloc_storage;
471 tr_ws->base.surface_release = trace_winsys_surface_release;
472 tr_ws->base.buffer_create = trace_winsys_buffer_create;
473 tr_ws->base.user_buffer_create = trace_winsys_user_buffer_create;
474 tr_ws->base.buffer_map = trace_winsys_buffer_map;
475 tr_ws->base.buffer_unmap = trace_winsys_buffer_unmap;
476 tr_ws->base.buffer_destroy = trace_winsys_buffer_destroy;
477 tr_ws->base.fence_reference = trace_winsys_fence_reference;
478 tr_ws->base.fence_signalled = trace_winsys_fence_signalled;
479 tr_ws->base.fence_finish = trace_winsys_fence_finish;
480
481 tr_ws->winsys = winsys;
482
483 tr_ws->buffer_maps = hash_table_create(trace_buffer_hash,
484 trace_buffer_compare);
485 if(!tr_ws->buffer_maps)
486 goto error2;
487
488 trace_dump_call_begin("", "pipe_winsys_create");
489 trace_dump_ret(ptr, winsys);
490 trace_dump_call_end();
491
492 return &tr_ws->base;
493
494 error2:
495 FREE(tr_ws);
496 error1:
497 return winsys;
498 }