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