0a43f1f7f46e8e62fb7088ebd421001494aefb24
[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_stream.h"
33 #include "tr_dump.h"
34 #include "tr_state.h"
35 #include "tr_winsys.h"
36
37
38 static unsigned trace_buffer_hash(void *buffer)
39 {
40 return (unsigned)(uintptr_t)buffer;
41 }
42
43
44 static int trace_buffer_compare(void *buffer1, void *buffer2)
45 {
46 return (char *)buffer2 - (char *)buffer1;
47 }
48
49
50 static const char *
51 trace_winsys_get_name(struct pipe_winsys *_winsys)
52 {
53 struct trace_winsys *tr_ws = trace_winsys(_winsys);
54 struct trace_stream *stream = tr_ws->stream;
55 struct pipe_winsys *winsys = tr_ws->winsys;
56 const char *result;
57
58 trace_dump_call_begin(stream, "pipe_winsys", "get_name");
59
60 trace_dump_arg(stream, ptr, winsys);
61
62 result = winsys->get_name(winsys);
63
64 trace_dump_ret(stream, string, result);
65
66 trace_dump_call_end(stream);
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 trace_stream *stream = tr_ws->stream;
79 struct pipe_winsys *winsys = tr_ws->winsys;
80
81 trace_dump_call_begin(stream, "pipe_winsys", "flush_frontbuffer");
82
83 trace_dump_arg(stream, ptr, winsys);
84 trace_dump_arg(stream, ptr, surface);
85 trace_dump_arg(stream, ptr, context_private);
86
87 winsys->flush_frontbuffer(winsys, surface, context_private);
88
89 trace_dump_call_end(stream);
90 }
91
92
93 static struct pipe_surface *
94 trace_winsys_surface_alloc(struct pipe_winsys *_winsys)
95 {
96 struct trace_winsys *tr_ws = trace_winsys(_winsys);
97 struct trace_stream *stream = tr_ws->stream;
98 struct pipe_winsys *winsys = tr_ws->winsys;
99 struct pipe_surface *result;
100
101 trace_dump_call_begin(stream, "pipe_winsys", "surface_alloc");
102
103 trace_dump_arg(stream, ptr, winsys);
104
105 result = winsys->surface_alloc(winsys);
106
107 trace_dump_ret(stream, ptr, result);
108
109 trace_dump_call_end(stream);
110
111 return result;
112 }
113
114
115 static int
116 trace_winsys_surface_alloc_storage(struct pipe_winsys *_winsys,
117 struct pipe_surface *surface,
118 unsigned width, unsigned height,
119 enum pipe_format format,
120 unsigned flags,
121 unsigned tex_usage)
122 {
123 struct trace_winsys *tr_ws = trace_winsys(_winsys);
124 struct trace_stream *stream = tr_ws->stream;
125 struct pipe_winsys *winsys = tr_ws->winsys;
126 int result;
127
128 trace_dump_call_begin(stream, "pipe_winsys", "surface_alloc_storage");
129
130 trace_dump_arg(stream, ptr, winsys);
131 trace_dump_arg(stream, ptr, surface);
132 trace_dump_arg(stream, uint, width);
133 trace_dump_arg(stream, uint, height);
134 trace_dump_arg(stream, format, format);
135 trace_dump_arg(stream, uint, flags);
136 trace_dump_arg(stream, uint, tex_usage);
137
138 result = winsys->surface_alloc_storage(winsys,
139 surface,
140 width, height,
141 format,
142 flags,
143 tex_usage);
144
145 trace_dump_ret(stream, int, result);
146
147 trace_dump_call_end(stream);
148
149 return result;
150 }
151
152
153 static void
154 trace_winsys_surface_release(struct pipe_winsys *_winsys,
155 struct pipe_surface **psurface)
156 {
157 struct trace_winsys *tr_ws = trace_winsys(_winsys);
158 struct trace_stream *stream = tr_ws->stream;
159 struct pipe_winsys *winsys = tr_ws->winsys;
160 struct pipe_surface *surface = *psurface;
161
162 trace_dump_call_begin(stream, "pipe_winsys", "surface_release");
163
164 trace_dump_arg(stream, ptr, winsys);
165 trace_dump_arg(stream, ptr, surface);
166
167 winsys->surface_release(winsys, psurface);
168
169 trace_dump_call_end(stream);
170 }
171
172
173 static struct pipe_buffer *
174 trace_winsys_buffer_create(struct pipe_winsys *_winsys,
175 unsigned alignment,
176 unsigned usage,
177 unsigned size)
178 {
179 struct trace_winsys *tr_ws = trace_winsys(_winsys);
180 struct trace_stream *stream = tr_ws->stream;
181 struct pipe_winsys *winsys = tr_ws->winsys;
182 struct pipe_buffer *buffer;
183
184 trace_dump_call_begin(stream, "pipe_winsys", "buffer_create");
185
186 trace_dump_arg(stream, ptr, winsys);
187 trace_dump_arg(stream, uint, alignment);
188 trace_dump_arg(stream, uint, usage);
189 trace_dump_arg(stream, uint, size);
190
191 buffer = winsys->buffer_create(winsys, alignment, usage, size);
192
193 trace_dump_ret(stream, ptr, buffer);
194
195 trace_dump_call_end(stream);
196
197 /* Zero the buffer to avoid dumping uninitialized memory */
198 if(buffer->usage & PIPE_BUFFER_USAGE_CPU_WRITE) {
199 void *map;
200 map = winsys->buffer_map(winsys, buffer, PIPE_BUFFER_USAGE_CPU_WRITE);
201 if(map) {
202 memset(map, 0, buffer->size);
203 winsys->buffer_unmap(winsys, buffer);
204 }
205 }
206
207 return buffer;
208 }
209
210
211 static struct pipe_buffer *
212 trace_winsys_user_buffer_create(struct pipe_winsys *_winsys,
213 void *ptr,
214 unsigned bytes)
215 {
216 struct trace_winsys *tr_ws = trace_winsys(_winsys);
217 struct trace_stream *stream = tr_ws->stream;
218 struct pipe_winsys *winsys = tr_ws->winsys;
219 struct pipe_buffer *result;
220
221 trace_dump_call_begin(stream, "pipe_winsys", "user_buffer_create");
222
223 trace_dump_arg(stream, ptr, winsys);
224 trace_dump_arg(stream, ptr, ptr);
225 trace_dump_arg(stream, uint, bytes);
226
227 result = winsys->user_buffer_create(winsys, ptr, bytes);
228
229 trace_dump_ret(stream, ptr, result);
230
231 trace_dump_call_end(stream);
232
233 return result;
234 }
235
236
237 static void *
238 trace_winsys_buffer_map(struct pipe_winsys *_winsys,
239 struct pipe_buffer *buffer,
240 unsigned usage)
241 {
242 struct trace_winsys *tr_ws = trace_winsys(_winsys);
243 struct pipe_winsys *winsys = tr_ws->winsys;
244 void *map;
245
246 map = winsys->buffer_map(winsys, buffer, usage);
247 if(map) {
248 if(usage & PIPE_BUFFER_USAGE_CPU_WRITE) {
249 assert(!hash_table_get(tr_ws->buffer_maps, buffer));
250 hash_table_set(tr_ws->buffer_maps, buffer, map);
251 }
252 }
253
254 return map;
255 }
256
257
258 static void
259 trace_winsys_buffer_unmap(struct pipe_winsys *_winsys,
260 struct pipe_buffer *buffer)
261 {
262 struct trace_winsys *tr_ws = trace_winsys(_winsys);
263 struct trace_stream *stream = tr_ws->stream;
264 struct pipe_winsys *winsys = tr_ws->winsys;
265 const void *map;
266
267 map = hash_table_get(tr_ws->buffer_maps, buffer);
268 if(map) {
269 trace_dump_call_begin(stream, "pipe_winsys", "buffer_write");
270
271 trace_dump_arg(stream, ptr, buffer);
272
273 trace_dump_arg_begin(stream, "data");
274 trace_dump_bytes(stream, map, buffer->size);
275 trace_dump_arg_end(stream);
276
277 trace_dump_arg_begin(stream, "size");
278 trace_dump_uint(stream, buffer->size);
279 trace_dump_arg_end(stream);
280
281 trace_dump_call_end(stream);
282
283 hash_table_remove(tr_ws->buffer_maps, buffer);
284 }
285
286 winsys->buffer_unmap(winsys, buffer);
287 }
288
289
290 static void
291 trace_winsys_buffer_destroy(struct pipe_winsys *_winsys,
292 struct pipe_buffer *buffer)
293 {
294 struct trace_winsys *tr_ws = trace_winsys(_winsys);
295 struct trace_stream *stream = tr_ws->stream;
296 struct pipe_winsys *winsys = tr_ws->winsys;
297
298 trace_dump_call_begin(stream, "pipe_winsys", "buffer_destroy");
299
300 trace_dump_arg(stream, ptr, winsys);
301 trace_dump_arg(stream, ptr, buffer);
302
303 winsys->buffer_destroy(winsys, buffer);
304
305 trace_dump_call_end(stream);
306 }
307
308
309 static void
310 trace_winsys_fence_reference(struct pipe_winsys *_winsys,
311 struct pipe_fence_handle **pdst,
312 struct pipe_fence_handle *src)
313 {
314 struct trace_winsys *tr_ws = trace_winsys(_winsys);
315 struct trace_stream *stream = tr_ws->stream;
316 struct pipe_winsys *winsys = tr_ws->winsys;
317 struct pipe_fence_handle *dst = *pdst;
318
319 trace_dump_call_begin(stream, "pipe_winsys", "fence_reference");
320
321 trace_dump_arg(stream, ptr, winsys);
322 trace_dump_arg(stream, ptr, dst);
323 trace_dump_arg(stream, ptr, src);
324
325 winsys->fence_reference(winsys, pdst, src);
326
327 trace_dump_call_end(stream);
328 }
329
330
331 static int
332 trace_winsys_fence_signalled(struct pipe_winsys *_winsys,
333 struct pipe_fence_handle *fence,
334 unsigned flag)
335 {
336 struct trace_winsys *tr_ws = trace_winsys(_winsys);
337 struct trace_stream *stream = tr_ws->stream;
338 struct pipe_winsys *winsys = tr_ws->winsys;
339 int result;
340
341 trace_dump_call_begin(stream, "pipe_winsys", "fence_signalled");
342
343 trace_dump_arg(stream, ptr, winsys);
344 trace_dump_arg(stream, ptr, fence);
345 trace_dump_arg(stream, uint, flag);
346
347 result = winsys->fence_signalled(winsys, fence, flag);
348
349 trace_dump_ret(stream, int, result);
350
351 trace_dump_call_end(stream);
352
353 return result;
354 }
355
356
357 static int
358 trace_winsys_fence_finish(struct pipe_winsys *_winsys,
359 struct pipe_fence_handle *fence,
360 unsigned flag)
361 {
362 struct trace_winsys *tr_ws = trace_winsys(_winsys);
363 struct trace_stream *stream = tr_ws->stream;
364 struct pipe_winsys *winsys = tr_ws->winsys;
365 int result;
366
367 trace_dump_call_begin(stream, "pipe_winsys", "fence_finish");
368
369 trace_dump_arg(stream, ptr, winsys);
370 trace_dump_arg(stream, ptr, fence);
371 trace_dump_arg(stream, uint, flag);
372
373 result = winsys->fence_finish(winsys, fence, flag);
374
375 trace_dump_ret(stream, int, result);
376
377 trace_dump_call_end(stream);
378
379 return result;
380 }
381
382
383 static void
384 trace_winsys_destroy(struct pipe_winsys *_winsys)
385 {
386 struct trace_winsys *tr_ws = trace_winsys(_winsys);
387 struct trace_stream *stream = tr_ws->stream;
388 struct pipe_winsys *winsys = tr_ws->winsys;
389
390 trace_dump_call_begin(stream, "pipe_winsys", "destroy");
391
392 trace_dump_arg(stream, ptr, winsys);
393
394 winsys->destroy(winsys);
395
396 trace_dump_call_end(stream);
397
398 trace_dump_trace_end(stream);
399
400 hash_table_destroy(tr_ws->buffer_maps);
401
402 trace_stream_close(tr_ws->stream);
403
404 FREE(tr_ws);
405 }
406
407
408 struct pipe_winsys *
409 trace_winsys_create(struct pipe_winsys *winsys)
410 {
411 struct trace_stream *stream;
412 struct trace_winsys *tr_ws;
413
414 if(!debug_get_bool_option("GALLIUM_TRACE", FALSE))
415 return winsys;
416
417 tr_ws = CALLOC_STRUCT(trace_winsys);
418 if(!tr_ws)
419 return NULL;
420
421 tr_ws->base.destroy = trace_winsys_destroy;
422 tr_ws->base.get_name = trace_winsys_get_name;
423 tr_ws->base.flush_frontbuffer = trace_winsys_flush_frontbuffer;
424 tr_ws->base.surface_alloc = trace_winsys_surface_alloc;
425 tr_ws->base.surface_alloc_storage = trace_winsys_surface_alloc_storage;
426 tr_ws->base.surface_release = trace_winsys_surface_release;
427 tr_ws->base.buffer_create = trace_winsys_buffer_create;
428 tr_ws->base.user_buffer_create = trace_winsys_user_buffer_create;
429 tr_ws->base.buffer_map = trace_winsys_buffer_map;
430 tr_ws->base.buffer_unmap = trace_winsys_buffer_unmap;
431 tr_ws->base.buffer_destroy = trace_winsys_buffer_destroy;
432 tr_ws->base.fence_reference = trace_winsys_fence_reference;
433 tr_ws->base.fence_signalled = trace_winsys_fence_signalled;
434 tr_ws->base.fence_finish = trace_winsys_fence_finish;
435
436 tr_ws->winsys = winsys;
437
438 tr_ws->stream = stream = trace_stream_create("gallium", "trace");
439 if(!tr_ws->stream)
440 return NULL;
441
442 tr_ws->buffer_maps = hash_table_create(trace_buffer_hash,
443 trace_buffer_compare);
444 if(!tr_ws->buffer_maps)
445 return NULL;
446
447 trace_dump_trace_begin(tr_ws->stream, 0);
448
449 trace_dump_call_begin(stream, "", "pipe_winsys_create");
450 trace_dump_ret(stream, ptr, winsys);
451 trace_dump_call_end(stream);
452
453 return &tr_ws->base;
454 }