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