Merge branch 'mesa_7_6_branch'
[mesa.git] / src / gallium / drivers / trace / tr_context.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 "util/u_memory.h"
29 #include "util/u_simple_list.h"
30
31 #include "pipe/p_screen.h"
32
33 #include "tr_dump.h"
34 #include "tr_dump_state.h"
35 #include "tr_state.h"
36 #include "tr_buffer.h"
37 #include "tr_screen.h"
38 #include "tr_texture.h"
39
40
41 static INLINE struct pipe_buffer *
42 trace_buffer_unwrap(struct trace_context *tr_ctx,
43 struct pipe_buffer *buffer)
44 {
45 struct trace_screen *tr_scr = trace_screen(tr_ctx->base.screen);
46 struct trace_buffer *tr_buf;
47
48 if(!buffer)
49 return NULL;
50
51 tr_buf = trace_buffer(buffer);
52
53 assert(tr_buf->buffer);
54 assert(tr_buf->buffer->screen == tr_scr->screen);
55 return tr_buf->buffer;
56 }
57
58
59 static INLINE struct pipe_texture *
60 trace_texture_unwrap(struct trace_context *tr_ctx,
61 struct pipe_texture *texture)
62 {
63 struct trace_texture *tr_tex;
64
65 if(!texture)
66 return NULL;
67
68 tr_tex = trace_texture(texture);
69
70 assert(tr_tex->texture);
71 return tr_tex->texture;
72 }
73
74
75 static INLINE struct pipe_surface *
76 trace_surface_unwrap(struct trace_context *tr_ctx,
77 struct pipe_surface *surface)
78 {
79 struct trace_screen *tr_scr = trace_screen(tr_ctx->base.screen);
80 struct trace_surface *tr_surf;
81
82 if(!surface)
83 return NULL;
84
85 assert(surface->texture);
86 if(!surface->texture)
87 return surface;
88
89 tr_surf = trace_surface(surface);
90
91 assert(tr_surf->surface);
92 assert(tr_surf->surface->texture->screen == tr_scr->screen);
93 return tr_surf->surface;
94 }
95
96
97 static INLINE void
98 trace_context_set_edgeflags(struct pipe_context *_pipe,
99 const unsigned *bitfield)
100 {
101 struct trace_context *tr_ctx = trace_context(_pipe);
102 struct pipe_context *pipe = tr_ctx->pipe;
103
104 trace_dump_call_begin("pipe_context", "set_edgeflags");
105
106 trace_dump_arg(ptr, pipe);
107 /* FIXME: we don't know how big this array is */
108 trace_dump_arg(ptr, bitfield);
109
110 pipe->set_edgeflags(pipe, bitfield);;
111
112 trace_dump_call_end();
113 }
114
115
116 static INLINE void
117 trace_context_draw_block(struct trace_context *tr_ctx, int flag)
118 {
119 int k;
120
121 pipe_mutex_lock(tr_ctx->draw_mutex);
122
123 if (tr_ctx->draw_blocker & flag) {
124 tr_ctx->draw_blocked |= flag;
125 } else if ((tr_ctx->draw_rule.blocker & flag) &&
126 (tr_ctx->draw_blocker & 4)) {
127 boolean block = FALSE;
128 debug_printf("%s (%p %p) (%p %p) (%p %u) (%p %u)\n", __FUNCTION__,
129 (void *) tr_ctx->draw_rule.fs, (void *) tr_ctx->curr.fs,
130 (void *) tr_ctx->draw_rule.vs, (void *) tr_ctx->curr.vs,
131 (void *) tr_ctx->draw_rule.surf, 0,
132 (void *) tr_ctx->draw_rule.tex, 0);
133 if (tr_ctx->draw_rule.fs &&
134 tr_ctx->draw_rule.fs == tr_ctx->curr.fs)
135 block = TRUE;
136 if (tr_ctx->draw_rule.vs &&
137 tr_ctx->draw_rule.vs == tr_ctx->curr.vs)
138 block = TRUE;
139 if (tr_ctx->draw_rule.surf &&
140 tr_ctx->draw_rule.surf == tr_ctx->curr.zsbuf)
141 block = TRUE;
142 if (tr_ctx->draw_rule.surf)
143 for (k = 0; k < tr_ctx->curr.nr_cbufs; k++)
144 if (tr_ctx->draw_rule.surf == tr_ctx->curr.cbufs[k])
145 block = TRUE;
146 if (tr_ctx->draw_rule.tex)
147 for (k = 0; k < tr_ctx->curr.num_texs; k++)
148 if (tr_ctx->draw_rule.tex == tr_ctx->curr.tex[k])
149 block = TRUE;
150
151 if (block)
152 tr_ctx->draw_blocked |= (flag | 4);
153 }
154
155 if (tr_ctx->draw_blocked)
156 trace_rbug_notify_draw_blocked(tr_ctx);
157
158 /* wait for rbug to clear the blocked flag */
159 while (tr_ctx->draw_blocked & flag) {
160 tr_ctx->draw_blocked |= flag;
161 #ifdef PIPE_THREAD_HAVE_CONDVAR
162 pipe_condvar_wait(tr_ctx->draw_cond, tr_ctx->draw_mutex);
163 #else
164 pipe_mutex_unlock(tr_ctx->draw_mutex);
165 #ifdef PIPE_SUBSYSTEM_WINDOWS_USER
166 Sleep(1);
167 #endif
168 pipe_mutex_lock(tr_ctx->draw_mutex);
169 #endif
170 }
171
172 pipe_mutex_unlock(tr_ctx->draw_mutex);
173 }
174
175 static INLINE boolean
176 trace_context_draw_arrays(struct pipe_context *_pipe,
177 unsigned mode, unsigned start, unsigned count)
178 {
179 struct trace_context *tr_ctx = trace_context(_pipe);
180 struct pipe_context *pipe = tr_ctx->pipe;
181 boolean result;
182
183 if (tr_ctx->curr.fs->disabled || tr_ctx->curr.vs->disabled)
184 return 0;
185
186 trace_context_draw_block(tr_ctx, 1);
187
188 trace_dump_call_begin("pipe_context", "draw_arrays");
189
190 trace_dump_arg(ptr, pipe);
191 trace_dump_arg(uint, mode);
192 trace_dump_arg(uint, start);
193 trace_dump_arg(uint, count);
194
195 result = pipe->draw_arrays(pipe, mode, start, count);;
196
197 trace_dump_ret(bool, result);
198
199 trace_dump_call_end();
200
201 trace_context_draw_block(tr_ctx, 2);
202
203 return result;
204 }
205
206
207 static INLINE boolean
208 trace_context_draw_elements(struct pipe_context *_pipe,
209 struct pipe_buffer *_indexBuffer,
210 unsigned indexSize,
211 unsigned mode, unsigned start, unsigned count)
212 {
213 struct trace_context *tr_ctx = trace_context(_pipe);
214 struct trace_buffer *tr_buf = trace_buffer(_indexBuffer);
215 struct pipe_context *pipe = tr_ctx->pipe;
216 struct pipe_buffer *indexBuffer = tr_buf->buffer;
217 boolean result;
218
219 if (tr_ctx->curr.fs->disabled || tr_ctx->curr.vs->disabled)
220 return 0;
221
222 trace_context_draw_block(tr_ctx, 1);
223
224 trace_screen_user_buffer_update(_pipe->screen, indexBuffer);
225
226 trace_dump_call_begin("pipe_context", "draw_elements");
227
228 trace_dump_arg(ptr, pipe);
229 trace_dump_arg(ptr, indexBuffer);
230 trace_dump_arg(uint, indexSize);
231 trace_dump_arg(uint, mode);
232 trace_dump_arg(uint, start);
233 trace_dump_arg(uint, count);
234
235 result = pipe->draw_elements(pipe, indexBuffer, indexSize, mode, start, count);;
236
237 trace_dump_ret(bool, result);
238
239 trace_dump_call_end();
240
241 trace_context_draw_block(tr_ctx, 2);
242
243 return result;
244 }
245
246
247 static INLINE boolean
248 trace_context_draw_range_elements(struct pipe_context *_pipe,
249 struct pipe_buffer *_indexBuffer,
250 unsigned indexSize,
251 unsigned minIndex,
252 unsigned maxIndex,
253 unsigned mode,
254 unsigned start,
255 unsigned count)
256 {
257 struct trace_context *tr_ctx = trace_context(_pipe);
258 struct trace_buffer *tr_buf = trace_buffer(_indexBuffer);
259 struct pipe_context *pipe = tr_ctx->pipe;
260 struct pipe_buffer *indexBuffer = tr_buf->buffer;
261 boolean result;
262
263 if (tr_ctx->curr.fs->disabled || tr_ctx->curr.vs->disabled)
264 return 0;
265
266 trace_context_draw_block(tr_ctx, 1);
267
268 trace_screen_user_buffer_update(_pipe->screen, indexBuffer);
269
270 trace_dump_call_begin("pipe_context", "draw_range_elements");
271
272 trace_dump_arg(ptr, pipe);
273 trace_dump_arg(ptr, indexBuffer);
274 trace_dump_arg(uint, indexSize);
275 trace_dump_arg(uint, minIndex);
276 trace_dump_arg(uint, maxIndex);
277 trace_dump_arg(uint, mode);
278 trace_dump_arg(uint, start);
279 trace_dump_arg(uint, count);
280
281 result = pipe->draw_range_elements(pipe,
282 indexBuffer,
283 indexSize, minIndex, maxIndex,
284 mode, start, count);
285
286 trace_dump_ret(bool, result);
287
288 trace_dump_call_end();
289
290 trace_context_draw_block(tr_ctx, 2);
291
292 return result;
293 }
294
295
296 static INLINE struct pipe_query *
297 trace_context_create_query(struct pipe_context *_pipe,
298 unsigned query_type)
299 {
300 struct trace_context *tr_ctx = trace_context(_pipe);
301 struct pipe_context *pipe = tr_ctx->pipe;
302 struct pipe_query *result;
303
304 trace_dump_call_begin("pipe_context", "create_query");
305
306 trace_dump_arg(ptr, pipe);
307 trace_dump_arg(uint, query_type);
308
309 result = pipe->create_query(pipe, query_type);;
310
311 trace_dump_ret(ptr, result);
312
313 trace_dump_call_end();
314
315 return result;
316 }
317
318
319 static INLINE void
320 trace_context_destroy_query(struct pipe_context *_pipe,
321 struct pipe_query *query)
322 {
323 struct trace_context *tr_ctx = trace_context(_pipe);
324 struct pipe_context *pipe = tr_ctx->pipe;
325
326 trace_dump_call_begin("pipe_context", "destroy_query");
327
328 trace_dump_arg(ptr, pipe);
329 trace_dump_arg(ptr, query);
330
331 pipe->destroy_query(pipe, query);;
332
333 trace_dump_call_end();
334 }
335
336
337 static INLINE void
338 trace_context_begin_query(struct pipe_context *_pipe,
339 struct pipe_query *query)
340 {
341 struct trace_context *tr_ctx = trace_context(_pipe);
342 struct pipe_context *pipe = tr_ctx->pipe;
343
344 trace_dump_call_begin("pipe_context", "begin_query");
345
346 trace_dump_arg(ptr, pipe);
347 trace_dump_arg(ptr, query);
348
349 pipe->begin_query(pipe, query);;
350
351 trace_dump_call_end();
352 }
353
354
355 static INLINE void
356 trace_context_end_query(struct pipe_context *_pipe,
357 struct pipe_query *query)
358 {
359 struct trace_context *tr_ctx = trace_context(_pipe);
360 struct pipe_context *pipe = tr_ctx->pipe;
361
362 trace_dump_call_begin("pipe_context", "end_query");
363
364 trace_dump_arg(ptr, pipe);
365 trace_dump_arg(ptr, query);
366
367 pipe->end_query(pipe, query);
368
369 trace_dump_call_end();
370 }
371
372
373 static INLINE boolean
374 trace_context_get_query_result(struct pipe_context *_pipe,
375 struct pipe_query *query,
376 boolean wait,
377 uint64_t *presult)
378 {
379 struct trace_context *tr_ctx = trace_context(_pipe);
380 struct pipe_context *pipe = tr_ctx->pipe;
381 uint64_t result;
382 boolean _result;
383
384 trace_dump_call_begin("pipe_context", "get_query_result");
385
386 trace_dump_arg(ptr, pipe);
387
388 _result = pipe->get_query_result(pipe, query, wait, presult);;
389 result = *presult;
390
391 trace_dump_arg(uint, result);
392 trace_dump_ret(bool, _result);
393
394 trace_dump_call_end();
395
396 return _result;
397 }
398
399
400 static INLINE void *
401 trace_context_create_blend_state(struct pipe_context *_pipe,
402 const struct pipe_blend_state *state)
403 {
404 struct trace_context *tr_ctx = trace_context(_pipe);
405 struct pipe_context *pipe = tr_ctx->pipe;
406 void * result;
407
408 trace_dump_call_begin("pipe_context", "create_blend_state");
409
410 trace_dump_arg(ptr, pipe);
411 trace_dump_arg(blend_state, state);
412
413 result = pipe->create_blend_state(pipe, state);;
414
415 trace_dump_ret(ptr, result);
416
417 trace_dump_call_end();
418
419 return result;
420 }
421
422
423 static INLINE void
424 trace_context_bind_blend_state(struct pipe_context *_pipe,
425 void *state)
426 {
427 struct trace_context *tr_ctx = trace_context(_pipe);
428 struct pipe_context *pipe = tr_ctx->pipe;
429
430 trace_dump_call_begin("pipe_context", "bind_blend_state");
431
432 trace_dump_arg(ptr, pipe);
433 trace_dump_arg(ptr, state);
434
435 pipe->bind_blend_state(pipe, state);;
436
437 trace_dump_call_end();
438 }
439
440
441 static INLINE void
442 trace_context_delete_blend_state(struct pipe_context *_pipe,
443 void *state)
444 {
445 struct trace_context *tr_ctx = trace_context(_pipe);
446 struct pipe_context *pipe = tr_ctx->pipe;
447
448 trace_dump_call_begin("pipe_context", "delete_blend_state");
449
450 trace_dump_arg(ptr, pipe);
451 trace_dump_arg(ptr, state);
452
453 pipe->delete_blend_state(pipe, state);;
454
455 trace_dump_call_end();
456 }
457
458
459 static INLINE void *
460 trace_context_create_sampler_state(struct pipe_context *_pipe,
461 const struct pipe_sampler_state *state)
462 {
463 struct trace_context *tr_ctx = trace_context(_pipe);
464 struct pipe_context *pipe = tr_ctx->pipe;
465 void * result;
466
467 trace_dump_call_begin("pipe_context", "create_sampler_state");
468
469 trace_dump_arg(ptr, pipe);
470 trace_dump_arg(sampler_state, state);
471
472 result = pipe->create_sampler_state(pipe, state);;
473
474 trace_dump_ret(ptr, result);
475
476 trace_dump_call_end();
477
478 return result;
479 }
480
481
482 static INLINE void
483 trace_context_bind_sampler_states(struct pipe_context *_pipe,
484 unsigned num_states, void **states)
485 {
486 struct trace_context *tr_ctx = trace_context(_pipe);
487 struct pipe_context *pipe = tr_ctx->pipe;
488
489 trace_dump_call_begin("pipe_context", "bind_sampler_states");
490
491 trace_dump_arg(ptr, pipe);
492 trace_dump_arg(uint, num_states);
493 trace_dump_arg_array(ptr, states, num_states);
494
495 pipe->bind_sampler_states(pipe, num_states, states);;
496
497 trace_dump_call_end();
498 }
499
500
501 static INLINE void
502 trace_context_delete_sampler_state(struct pipe_context *_pipe,
503 void *state)
504 {
505 struct trace_context *tr_ctx = trace_context(_pipe);
506 struct pipe_context *pipe = tr_ctx->pipe;
507
508 trace_dump_call_begin("pipe_context", "delete_sampler_state");
509
510 trace_dump_arg(ptr, pipe);
511 trace_dump_arg(ptr, state);
512
513 pipe->delete_sampler_state(pipe, state);;
514
515 trace_dump_call_end();
516 }
517
518
519 static INLINE void *
520 trace_context_create_rasterizer_state(struct pipe_context *_pipe,
521 const struct pipe_rasterizer_state *state)
522 {
523 struct trace_context *tr_ctx = trace_context(_pipe);
524 struct pipe_context *pipe = tr_ctx->pipe;
525 void * result;
526
527 trace_dump_call_begin("pipe_context", "create_rasterizer_state");
528
529 trace_dump_arg(ptr, pipe);
530 trace_dump_arg(rasterizer_state, state);
531
532 result = pipe->create_rasterizer_state(pipe, state);;
533
534 trace_dump_ret(ptr, result);
535
536 trace_dump_call_end();
537
538 return result;
539 }
540
541
542 static INLINE void
543 trace_context_bind_rasterizer_state(struct pipe_context *_pipe,
544 void *state)
545 {
546 struct trace_context *tr_ctx = trace_context(_pipe);
547 struct pipe_context *pipe = tr_ctx->pipe;
548
549 trace_dump_call_begin("pipe_context", "bind_rasterizer_state");
550
551 trace_dump_arg(ptr, pipe);
552 trace_dump_arg(ptr, state);
553
554 pipe->bind_rasterizer_state(pipe, state);;
555
556 trace_dump_call_end();
557 }
558
559
560 static INLINE void
561 trace_context_delete_rasterizer_state(struct pipe_context *_pipe,
562 void *state)
563 {
564 struct trace_context *tr_ctx = trace_context(_pipe);
565 struct pipe_context *pipe = tr_ctx->pipe;
566
567 trace_dump_call_begin("pipe_context", "delete_rasterizer_state");
568
569 trace_dump_arg(ptr, pipe);
570 trace_dump_arg(ptr, state);
571
572 pipe->delete_rasterizer_state(pipe, state);;
573
574 trace_dump_call_end();
575 }
576
577
578 static INLINE void *
579 trace_context_create_depth_stencil_alpha_state(struct pipe_context *_pipe,
580 const struct pipe_depth_stencil_alpha_state *state)
581 {
582 struct trace_context *tr_ctx = trace_context(_pipe);
583 struct pipe_context *pipe = tr_ctx->pipe;
584 void * result;
585
586 trace_dump_call_begin("pipe_context", "create_depth_stencil_alpha_state");
587
588 result = pipe->create_depth_stencil_alpha_state(pipe, state);;
589
590 trace_dump_arg(ptr, pipe);
591 trace_dump_arg(depth_stencil_alpha_state, state);
592
593 trace_dump_ret(ptr, result);
594
595 trace_dump_call_end();
596
597 return result;
598 }
599
600
601 static INLINE void
602 trace_context_bind_depth_stencil_alpha_state(struct pipe_context *_pipe,
603 void *state)
604 {
605 struct trace_context *tr_ctx = trace_context(_pipe);
606 struct pipe_context *pipe = tr_ctx->pipe;
607
608 trace_dump_call_begin("pipe_context", "bind_depth_stencil_alpha_state");
609
610 trace_dump_arg(ptr, pipe);
611 trace_dump_arg(ptr, state);
612
613 pipe->bind_depth_stencil_alpha_state(pipe, state);;
614
615 trace_dump_call_end();
616 }
617
618
619 static INLINE void
620 trace_context_delete_depth_stencil_alpha_state(struct pipe_context *_pipe,
621 void *state)
622 {
623 struct trace_context *tr_ctx = trace_context(_pipe);
624 struct pipe_context *pipe = tr_ctx->pipe;
625
626 trace_dump_call_begin("pipe_context", "delete_depth_stencil_alpha_state");
627
628 trace_dump_arg(ptr, pipe);
629 trace_dump_arg(ptr, state);
630
631 pipe->delete_depth_stencil_alpha_state(pipe, state);;
632
633 trace_dump_call_end();
634 }
635
636
637 static INLINE void *
638 trace_context_create_fs_state(struct pipe_context *_pipe,
639 const struct pipe_shader_state *state)
640 {
641 struct trace_context *tr_ctx = trace_context(_pipe);
642 struct pipe_context *pipe = tr_ctx->pipe;
643 void * result;
644
645 trace_dump_call_begin("pipe_context", "create_fs_state");
646
647 trace_dump_arg(ptr, pipe);
648 trace_dump_arg(shader_state, state);
649
650 result = pipe->create_fs_state(pipe, state);;
651
652 trace_dump_ret(ptr, result);
653
654 trace_dump_call_end();
655
656 result = trace_shader_create(tr_ctx, state, result, TRACE_SHADER_FRAGMENT);
657
658 return result;
659 }
660
661
662 static INLINE void
663 trace_context_bind_fs_state(struct pipe_context *_pipe,
664 void *_state)
665 {
666 struct trace_context *tr_ctx = trace_context(_pipe);
667 struct trace_shader *tr_shdr = trace_shader(_state);
668 struct pipe_context *pipe = tr_ctx->pipe;
669 void *state = tr_shdr ? tr_shdr->state : NULL;
670
671 trace_dump_call_begin("pipe_context", "bind_fs_state");
672
673 trace_dump_arg(ptr, pipe);
674 trace_dump_arg(ptr, state);
675
676 tr_ctx->curr.fs = tr_shdr;
677
678 if (tr_shdr && tr_shdr->replaced)
679 state = tr_shdr->replaced;
680
681 pipe->bind_fs_state(pipe, state);
682
683 trace_dump_call_end();
684 }
685
686
687 static INLINE void
688 trace_context_delete_fs_state(struct pipe_context *_pipe,
689 void *_state)
690 {
691 struct trace_context *tr_ctx = trace_context(_pipe);
692 struct trace_shader *tr_shdr = trace_shader(_state);
693 struct pipe_context *pipe = tr_ctx->pipe;
694 void *state = tr_shdr->state;
695
696 trace_dump_call_begin("pipe_context", "delete_fs_state");
697
698 trace_dump_arg(ptr, pipe);
699 trace_dump_arg(ptr, state);
700
701 pipe->delete_fs_state(pipe, state);
702
703 trace_dump_call_end();
704
705 trace_shader_destroy(tr_ctx, tr_shdr);
706 }
707
708
709 static INLINE void *
710 trace_context_create_vs_state(struct pipe_context *_pipe,
711 const struct pipe_shader_state *state)
712 {
713 struct trace_context *tr_ctx = trace_context(_pipe);
714 struct pipe_context *pipe = tr_ctx->pipe;
715 void * result;
716
717 trace_dump_call_begin("pipe_context", "create_vs_state");
718
719 trace_dump_arg(ptr, pipe);
720 trace_dump_arg(shader_state, state);
721
722 result = pipe->create_vs_state(pipe, state);
723
724 trace_dump_ret(ptr, result);
725
726 trace_dump_call_end();
727
728 result = trace_shader_create(tr_ctx, state, result, TRACE_SHADER_VERTEX);
729
730 return result;
731 }
732
733
734 static INLINE void
735 trace_context_bind_vs_state(struct pipe_context *_pipe,
736 void *_state)
737 {
738 struct trace_context *tr_ctx = trace_context(_pipe);
739 struct trace_shader *tr_shdr = trace_shader(_state);
740 struct pipe_context *pipe = tr_ctx->pipe;
741 void *state = tr_shdr ? tr_shdr->state : NULL;
742
743 trace_dump_call_begin("pipe_context", "bind_vs_state");
744
745 trace_dump_arg(ptr, pipe);
746 trace_dump_arg(ptr, state);
747
748 tr_ctx->curr.vs = tr_shdr;
749
750 if (tr_shdr && tr_shdr->replaced)
751 state = tr_shdr->replaced;
752
753 pipe->bind_vs_state(pipe, state);;
754
755 trace_dump_call_end();
756 }
757
758
759 static INLINE void
760 trace_context_delete_vs_state(struct pipe_context *_pipe,
761 void *_state)
762 {
763 struct trace_context *tr_ctx = trace_context(_pipe);
764 struct trace_shader *tr_shdr = trace_shader(_state);
765 struct pipe_context *pipe = tr_ctx->pipe;
766 void *state = tr_shdr->state;
767
768 trace_dump_call_begin("pipe_context", "delete_vs_state");
769
770 trace_dump_arg(ptr, pipe);
771 trace_dump_arg(ptr, state);
772
773 pipe->delete_vs_state(pipe, state);;
774
775 trace_dump_call_end();
776
777 trace_shader_destroy(tr_ctx, tr_shdr);
778 }
779
780
781 static INLINE void
782 trace_context_set_blend_color(struct pipe_context *_pipe,
783 const struct pipe_blend_color *state)
784 {
785 struct trace_context *tr_ctx = trace_context(_pipe);
786 struct pipe_context *pipe = tr_ctx->pipe;
787
788 trace_dump_call_begin("pipe_context", "set_blend_color");
789
790 trace_dump_arg(ptr, pipe);
791 trace_dump_arg(blend_color, state);
792
793 pipe->set_blend_color(pipe, state);;
794
795 trace_dump_call_end();
796 }
797
798
799 static INLINE void
800 trace_context_set_clip_state(struct pipe_context *_pipe,
801 const struct pipe_clip_state *state)
802 {
803 struct trace_context *tr_ctx = trace_context(_pipe);
804 struct pipe_context *pipe = tr_ctx->pipe;
805
806 trace_dump_call_begin("pipe_context", "set_clip_state");
807
808 trace_dump_arg(ptr, pipe);
809 trace_dump_arg(clip_state, state);
810
811 pipe->set_clip_state(pipe, state);;
812
813 trace_dump_call_end();
814 }
815
816
817 static INLINE void
818 trace_context_set_constant_buffer(struct pipe_context *_pipe,
819 uint shader, uint index,
820 const struct pipe_constant_buffer *buffer)
821 {
822 struct trace_context *tr_ctx = trace_context(_pipe);
823 struct pipe_context *pipe = tr_ctx->pipe;
824
825 if (buffer)
826 trace_screen_user_buffer_update(_pipe->screen, buffer->buffer);
827
828 trace_dump_call_begin("pipe_context", "set_constant_buffer");
829
830 trace_dump_arg(ptr, pipe);
831 trace_dump_arg(uint, shader);
832 trace_dump_arg(uint, index);
833 trace_dump_arg(constant_buffer, buffer);
834
835 if (buffer) {
836 struct pipe_constant_buffer _buffer;
837 _buffer.buffer = trace_buffer_unwrap(tr_ctx, buffer->buffer);
838 pipe->set_constant_buffer(pipe, shader, index, &_buffer);
839 } else {
840 pipe->set_constant_buffer(pipe, shader, index, buffer);
841 }
842
843 trace_dump_call_end();
844 }
845
846
847 static INLINE void
848 trace_context_set_framebuffer_state(struct pipe_context *_pipe,
849 const struct pipe_framebuffer_state *state)
850 {
851 struct trace_context *tr_ctx = trace_context(_pipe);
852 struct pipe_context *pipe = tr_ctx->pipe;
853 struct pipe_framebuffer_state unwrapped_state;
854 unsigned i;
855
856 {
857 tr_ctx->curr.nr_cbufs = state->nr_cbufs;
858 for (i = 0; i < state->nr_cbufs; i++)
859 if (state->cbufs[i])
860 tr_ctx->curr.cbufs[i] = trace_texture(state->cbufs[i]->texture);
861 else
862 tr_ctx->curr.cbufs[i] = NULL;
863 if (state->zsbuf)
864 tr_ctx->curr.zsbuf = trace_texture(state->zsbuf->texture);
865 else
866 tr_ctx->curr.zsbuf = NULL;
867 }
868
869 /* Unwrap the input state */
870 memcpy(&unwrapped_state, state, sizeof(unwrapped_state));
871 for(i = 0; i < state->nr_cbufs; ++i)
872 unwrapped_state.cbufs[i] = trace_surface_unwrap(tr_ctx, state->cbufs[i]);
873 for(i = state->nr_cbufs; i < PIPE_MAX_COLOR_BUFS; ++i)
874 unwrapped_state.cbufs[i] = NULL;
875 unwrapped_state.zsbuf = trace_surface_unwrap(tr_ctx, state->zsbuf);
876 state = &unwrapped_state;
877
878 trace_dump_call_begin("pipe_context", "set_framebuffer_state");
879
880 trace_dump_arg(ptr, pipe);
881 trace_dump_arg(framebuffer_state, state);
882
883 pipe->set_framebuffer_state(pipe, state);;
884
885 trace_dump_call_end();
886 }
887
888
889 static INLINE void
890 trace_context_set_polygon_stipple(struct pipe_context *_pipe,
891 const struct pipe_poly_stipple *state)
892 {
893 struct trace_context *tr_ctx = trace_context(_pipe);
894 struct pipe_context *pipe = tr_ctx->pipe;
895
896 trace_dump_call_begin("pipe_context", "set_polygon_stipple");
897
898 trace_dump_arg(ptr, pipe);
899 trace_dump_arg(poly_stipple, state);
900
901 pipe->set_polygon_stipple(pipe, state);;
902
903 trace_dump_call_end();
904 }
905
906
907 static INLINE void
908 trace_context_set_scissor_state(struct pipe_context *_pipe,
909 const struct pipe_scissor_state *state)
910 {
911 struct trace_context *tr_ctx = trace_context(_pipe);
912 struct pipe_context *pipe = tr_ctx->pipe;
913
914 trace_dump_call_begin("pipe_context", "set_scissor_state");
915
916 trace_dump_arg(ptr, pipe);
917 trace_dump_arg(scissor_state, state);
918
919 pipe->set_scissor_state(pipe, state);;
920
921 trace_dump_call_end();
922 }
923
924
925 static INLINE void
926 trace_context_set_viewport_state(struct pipe_context *_pipe,
927 const struct pipe_viewport_state *state)
928 {
929 struct trace_context *tr_ctx = trace_context(_pipe);
930 struct pipe_context *pipe = tr_ctx->pipe;
931
932 trace_dump_call_begin("pipe_context", "set_viewport_state");
933
934 trace_dump_arg(ptr, pipe);
935 trace_dump_arg(viewport_state, state);
936
937 pipe->set_viewport_state(pipe, state);;
938
939 trace_dump_call_end();
940 }
941
942
943 static INLINE void
944 trace_context_set_sampler_textures(struct pipe_context *_pipe,
945 unsigned num_textures,
946 struct pipe_texture **textures)
947 {
948 struct trace_context *tr_ctx = trace_context(_pipe);
949 struct trace_texture *tr_tex;
950 struct pipe_context *pipe = tr_ctx->pipe;
951 struct pipe_texture *unwrapped_textures[PIPE_MAX_SAMPLERS];
952 unsigned i;
953
954 tr_ctx->curr.num_texs = num_textures;
955 for(i = 0; i < num_textures; ++i) {
956 tr_tex = trace_texture(textures[i]);
957 tr_ctx->curr.tex[i] = tr_tex;
958 unwrapped_textures[i] = tr_tex ? tr_tex->texture : NULL;
959 }
960 textures = unwrapped_textures;
961
962 trace_dump_call_begin("pipe_context", "set_sampler_textures");
963
964 trace_dump_arg(ptr, pipe);
965 trace_dump_arg(uint, num_textures);
966 trace_dump_arg_array(ptr, textures, num_textures);
967
968 pipe->set_sampler_textures(pipe, num_textures, textures);;
969
970 trace_dump_call_end();
971 }
972
973
974 static INLINE void
975 trace_context_set_vertex_buffers(struct pipe_context *_pipe,
976 unsigned num_buffers,
977 const struct pipe_vertex_buffer *buffers)
978 {
979 struct trace_context *tr_ctx = trace_context(_pipe);
980 struct pipe_context *pipe = tr_ctx->pipe;
981 unsigned i;
982
983 for(i = 0; i < num_buffers; ++i)
984 trace_screen_user_buffer_update(_pipe->screen, buffers[i].buffer);
985
986 trace_dump_call_begin("pipe_context", "set_vertex_buffers");
987
988 trace_dump_arg(ptr, pipe);
989 trace_dump_arg(uint, num_buffers);
990
991 trace_dump_arg_begin("buffers");
992 trace_dump_struct_array(vertex_buffer, buffers, num_buffers);
993 trace_dump_arg_end();
994
995 if (num_buffers) {
996 struct pipe_vertex_buffer *_buffers = malloc(num_buffers * sizeof(*_buffers));
997 memcpy(_buffers, buffers, num_buffers * sizeof(*_buffers));
998 for (i = 0; i < num_buffers; i++)
999 _buffers[i].buffer = trace_buffer_unwrap(tr_ctx, buffers[i].buffer);
1000 pipe->set_vertex_buffers(pipe, num_buffers, _buffers);
1001 free(_buffers);
1002 } else {
1003 pipe->set_vertex_buffers(pipe, num_buffers, NULL);
1004 }
1005
1006 trace_dump_call_end();
1007 }
1008
1009
1010 static INLINE void
1011 trace_context_set_vertex_elements(struct pipe_context *_pipe,
1012 unsigned num_elements,
1013 const struct pipe_vertex_element *elements)
1014 {
1015 struct trace_context *tr_ctx = trace_context(_pipe);
1016 struct pipe_context *pipe = tr_ctx->pipe;
1017
1018 trace_dump_call_begin("pipe_context", "set_vertex_elements");
1019
1020 trace_dump_arg(ptr, pipe);
1021 trace_dump_arg(uint, num_elements);
1022
1023 trace_dump_arg_begin("elements");
1024 trace_dump_struct_array(vertex_element, elements, num_elements);
1025 trace_dump_arg_end();
1026
1027 pipe->set_vertex_elements(pipe, num_elements, elements);;
1028
1029 trace_dump_call_end();
1030 }
1031
1032
1033 static INLINE void
1034 trace_context_surface_copy(struct pipe_context *_pipe,
1035 struct pipe_surface *dest,
1036 unsigned destx, unsigned desty,
1037 struct pipe_surface *src,
1038 unsigned srcx, unsigned srcy,
1039 unsigned width, unsigned height)
1040 {
1041 struct trace_context *tr_ctx = trace_context(_pipe);
1042 struct pipe_context *pipe = tr_ctx->pipe;
1043
1044 dest = trace_surface_unwrap(tr_ctx, dest);
1045 src = trace_surface_unwrap(tr_ctx, src);
1046
1047 trace_dump_call_begin("pipe_context", "surface_copy");
1048
1049 trace_dump_arg(ptr, pipe);
1050 trace_dump_arg(ptr, dest);
1051 trace_dump_arg(uint, destx);
1052 trace_dump_arg(uint, desty);
1053 trace_dump_arg(ptr, src);
1054 trace_dump_arg(uint, srcx);
1055 trace_dump_arg(uint, srcy);
1056 trace_dump_arg(uint, width);
1057 trace_dump_arg(uint, height);
1058
1059 pipe->surface_copy(pipe,
1060 dest, destx, desty,
1061 src, srcx, srcy, width, height);
1062
1063 trace_dump_call_end();
1064 }
1065
1066
1067 static INLINE void
1068 trace_context_surface_fill(struct pipe_context *_pipe,
1069 struct pipe_surface *dst,
1070 unsigned dstx, unsigned dsty,
1071 unsigned width, unsigned height,
1072 unsigned value)
1073 {
1074 struct trace_context *tr_ctx = trace_context(_pipe);
1075 struct pipe_context *pipe = tr_ctx->pipe;
1076
1077 dst = trace_surface_unwrap(tr_ctx, dst);
1078
1079 trace_dump_call_begin("pipe_context", "surface_fill");
1080
1081 trace_dump_arg(ptr, pipe);
1082 trace_dump_arg(ptr, dst);
1083 trace_dump_arg(uint, dstx);
1084 trace_dump_arg(uint, dsty);
1085 trace_dump_arg(uint, width);
1086 trace_dump_arg(uint, height);
1087
1088 pipe->surface_fill(pipe, dst, dstx, dsty, width, height, value);;
1089
1090 trace_dump_call_end();
1091 }
1092
1093
1094 static INLINE void
1095 trace_context_clear(struct pipe_context *_pipe,
1096 unsigned buffers,
1097 const float *rgba,
1098 double depth,
1099 unsigned stencil)
1100 {
1101 struct trace_context *tr_ctx = trace_context(_pipe);
1102 struct pipe_context *pipe = tr_ctx->pipe;
1103
1104 trace_dump_call_begin("pipe_context", "clear");
1105
1106 trace_dump_arg(ptr, pipe);
1107 trace_dump_arg(uint, buffers);
1108 trace_dump_arg_array(float, rgba, 4);
1109 trace_dump_arg(float, depth);
1110 trace_dump_arg(uint, stencil);
1111
1112 pipe->clear(pipe, buffers, rgba, depth, stencil);
1113
1114 trace_dump_call_end();
1115 }
1116
1117
1118 static INLINE void
1119 trace_context_flush(struct pipe_context *_pipe,
1120 unsigned flags,
1121 struct pipe_fence_handle **fence)
1122 {
1123 struct trace_context *tr_ctx = trace_context(_pipe);
1124 struct pipe_context *pipe = tr_ctx->pipe;
1125
1126 trace_dump_call_begin("pipe_context", "flush");
1127
1128 trace_dump_arg(ptr, pipe);
1129 trace_dump_arg(uint, flags);
1130
1131 pipe->flush(pipe, flags, fence);;
1132
1133 if(fence)
1134 trace_dump_ret(ptr, *fence);
1135
1136 trace_dump_call_end();
1137 }
1138
1139
1140 static INLINE void
1141 trace_context_destroy(struct pipe_context *_pipe)
1142 {
1143 struct trace_screen *tr_scr = trace_screen(_pipe->screen);
1144 struct trace_context *tr_ctx = trace_context(_pipe);
1145 struct pipe_context *pipe = tr_ctx->pipe;
1146
1147 trace_dump_call_begin("pipe_context", "destroy");
1148 trace_dump_arg(ptr, pipe);
1149 trace_dump_call_end();
1150
1151 trace_screen_remove_from_list(tr_scr, contexts, tr_ctx);
1152
1153 pipe->destroy(pipe);
1154
1155 FREE(tr_ctx);
1156 }
1157
1158 static unsigned int
1159 trace_is_texture_referenced( struct pipe_context *_pipe,
1160 struct pipe_texture *_texture,
1161 unsigned face, unsigned level)
1162 {
1163 struct trace_context *tr_ctx = trace_context(_pipe);
1164 struct trace_texture *tr_tex = trace_texture(_texture);
1165 struct pipe_context *pipe = tr_ctx->pipe;
1166 struct pipe_texture *texture = tr_tex->texture;
1167 unsigned int referenced;
1168
1169 trace_dump_call_begin("pipe_context", "is_texture_referenced");
1170 trace_dump_arg(ptr, pipe);
1171 trace_dump_arg(ptr, texture);
1172 trace_dump_arg(uint, face);
1173 trace_dump_arg(uint, level);
1174
1175 referenced = pipe->is_texture_referenced(pipe, texture, face, level);
1176
1177 trace_dump_ret(uint, referenced);
1178 trace_dump_call_end();
1179
1180 return referenced;
1181 }
1182
1183 static unsigned int
1184 trace_is_buffer_referenced( struct pipe_context *_pipe,
1185 struct pipe_buffer *_buf)
1186 {
1187 struct trace_context *tr_ctx = trace_context(_pipe);
1188 struct trace_buffer *tr_buf = trace_buffer(_buf);
1189 struct pipe_context *pipe = tr_ctx->pipe;
1190 struct pipe_buffer *buf = tr_buf->buffer;
1191 unsigned int referenced;
1192
1193 trace_dump_call_begin("pipe_context", "is_buffer_referenced");
1194 trace_dump_arg(ptr, pipe);
1195 trace_dump_arg(ptr, buf);
1196
1197 referenced = pipe->is_buffer_referenced(pipe, buf);
1198
1199 trace_dump_ret(uint, referenced);
1200 trace_dump_call_end();
1201
1202 return referenced;
1203 }
1204
1205 static const struct debug_named_value rbug_blocker_flags[] = {
1206 {"before", 1},
1207 {"after", 2},
1208 {NULL, 0},
1209 };
1210
1211 struct pipe_context *
1212 trace_context_create(struct pipe_screen *_screen,
1213 struct pipe_context *pipe)
1214 {
1215 struct trace_screen *tr_scr;
1216 struct trace_context *tr_ctx;
1217 struct pipe_screen *screen;
1218
1219 if(!pipe)
1220 goto error1;
1221
1222 if(!trace_enabled())
1223 goto error1;
1224
1225 tr_scr = trace_screen(_screen);
1226 screen = tr_scr->screen;
1227
1228 tr_ctx = CALLOC_STRUCT(trace_context);
1229 if(!tr_ctx)
1230 goto error1;
1231
1232 tr_ctx->draw_blocker = debug_get_flags_option("RBUG_BLOCK",
1233 rbug_blocker_flags,
1234 0);
1235 pipe_mutex_init(tr_ctx->draw_mutex);
1236 pipe_condvar_init(tr_ctx->draw_cond);
1237 pipe_mutex_init(tr_ctx->list_mutex);
1238 make_empty_list(&tr_ctx->shaders);
1239
1240 tr_ctx->base.winsys = _screen->winsys;
1241 tr_ctx->base.screen = _screen;
1242 tr_ctx->base.destroy = trace_context_destroy;
1243 tr_ctx->base.set_edgeflags = trace_context_set_edgeflags;
1244 tr_ctx->base.draw_arrays = trace_context_draw_arrays;
1245 tr_ctx->base.draw_elements = trace_context_draw_elements;
1246 tr_ctx->base.draw_range_elements = trace_context_draw_range_elements;
1247 tr_ctx->base.create_query = trace_context_create_query;
1248 tr_ctx->base.destroy_query = trace_context_destroy_query;
1249 tr_ctx->base.begin_query = trace_context_begin_query;
1250 tr_ctx->base.end_query = trace_context_end_query;
1251 tr_ctx->base.get_query_result = trace_context_get_query_result;
1252 tr_ctx->base.create_blend_state = trace_context_create_blend_state;
1253 tr_ctx->base.bind_blend_state = trace_context_bind_blend_state;
1254 tr_ctx->base.delete_blend_state = trace_context_delete_blend_state;
1255 tr_ctx->base.create_sampler_state = trace_context_create_sampler_state;
1256 tr_ctx->base.bind_sampler_states = trace_context_bind_sampler_states;
1257 tr_ctx->base.delete_sampler_state = trace_context_delete_sampler_state;
1258 tr_ctx->base.create_rasterizer_state = trace_context_create_rasterizer_state;
1259 tr_ctx->base.bind_rasterizer_state = trace_context_bind_rasterizer_state;
1260 tr_ctx->base.delete_rasterizer_state = trace_context_delete_rasterizer_state;
1261 tr_ctx->base.create_depth_stencil_alpha_state = trace_context_create_depth_stencil_alpha_state;
1262 tr_ctx->base.bind_depth_stencil_alpha_state = trace_context_bind_depth_stencil_alpha_state;
1263 tr_ctx->base.delete_depth_stencil_alpha_state = trace_context_delete_depth_stencil_alpha_state;
1264 tr_ctx->base.create_fs_state = trace_context_create_fs_state;
1265 tr_ctx->base.bind_fs_state = trace_context_bind_fs_state;
1266 tr_ctx->base.delete_fs_state = trace_context_delete_fs_state;
1267 tr_ctx->base.create_vs_state = trace_context_create_vs_state;
1268 tr_ctx->base.bind_vs_state = trace_context_bind_vs_state;
1269 tr_ctx->base.delete_vs_state = trace_context_delete_vs_state;
1270 tr_ctx->base.set_blend_color = trace_context_set_blend_color;
1271 tr_ctx->base.set_clip_state = trace_context_set_clip_state;
1272 tr_ctx->base.set_constant_buffer = trace_context_set_constant_buffer;
1273 tr_ctx->base.set_framebuffer_state = trace_context_set_framebuffer_state;
1274 tr_ctx->base.set_polygon_stipple = trace_context_set_polygon_stipple;
1275 tr_ctx->base.set_scissor_state = trace_context_set_scissor_state;
1276 tr_ctx->base.set_viewport_state = trace_context_set_viewport_state;
1277 tr_ctx->base.set_sampler_textures = trace_context_set_sampler_textures;
1278 tr_ctx->base.set_vertex_buffers = trace_context_set_vertex_buffers;
1279 tr_ctx->base.set_vertex_elements = trace_context_set_vertex_elements;
1280 if (pipe->surface_copy)
1281 tr_ctx->base.surface_copy = trace_context_surface_copy;
1282 if (pipe->surface_fill)
1283 tr_ctx->base.surface_fill = trace_context_surface_fill;
1284 tr_ctx->base.clear = trace_context_clear;
1285 tr_ctx->base.flush = trace_context_flush;
1286 tr_ctx->base.is_texture_referenced = trace_is_texture_referenced;
1287 tr_ctx->base.is_buffer_referenced = trace_is_buffer_referenced;
1288
1289 tr_ctx->pipe = pipe;
1290
1291 trace_dump_call_begin("", "pipe_context_create");
1292 trace_dump_arg(ptr, screen);
1293 trace_dump_ret(ptr, pipe);
1294 trace_dump_call_end();
1295
1296 trace_screen_add_to_list(tr_scr, contexts, tr_ctx);
1297
1298 return &tr_ctx->base;
1299
1300 error1:
1301 return pipe;
1302 }