tr_context.c revision 1b334587e998ea84fd0fa9276e3373e3ecef1e5b
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   return tr_buf->buffer;
56}
57
58
59static INLINE struct pipe_texture *
60trace_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
75static INLINE struct pipe_surface *
76trace_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
97static INLINE void
98trace_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
116static INLINE void
117trace_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 (%lu %lu) (%lu %lu) (%lu %u) (%lu %u)\n", __FUNCTION__,
129					tr_ctx->draw_rule.fs, tr_ctx->curr.fs,
130					tr_ctx->draw_rule.vs, tr_ctx->curr.vs,
131					tr_ctx->draw_rule.surf, 0,
132					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
175static INLINE boolean
176trace_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
207static INLINE boolean
208trace_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
247static INLINE boolean
248trace_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
296static INLINE struct pipe_query *
297trace_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
319static INLINE void
320trace_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
337static INLINE void
338trace_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
355static INLINE void
356trace_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
373static INLINE boolean
374trace_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
400static INLINE void *
401trace_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
423static INLINE void
424trace_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
441static INLINE void
442trace_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
459static INLINE void *
460trace_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
482static INLINE void
483trace_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
501static INLINE void
502trace_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
519static INLINE void *
520trace_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
542static INLINE void
543trace_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
560static INLINE void
561trace_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
578static INLINE void *
579trace_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
601static INLINE void
602trace_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
619static INLINE void
620trace_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
637static INLINE void *
638trace_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
662static INLINE void
663trace_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
687static INLINE void
688trace_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
709static INLINE void *
710trace_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
734static INLINE void
735trace_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
759static INLINE void
760trace_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
781static INLINE void
782trace_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
799static INLINE void
800trace_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
817static INLINE void
818trace_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
847static INLINE void
848trace_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
889static INLINE void
890trace_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
907static INLINE void
908trace_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
925static INLINE void
926trace_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
943static INLINE void
944trace_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
974static INLINE void
975trace_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
1010static INLINE void
1011trace_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
1033static INLINE void
1034trace_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
1067static INLINE void
1068trace_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
1094static INLINE void
1095trace_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
1118static INLINE void
1119trace_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
1140static INLINE void
1141trace_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
1158static unsigned int
1159trace_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
1183static unsigned int
1184trace_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
1205static const struct debug_named_value rbug_blocker_flags[] = {
1206   {"before", 1},
1207   {"after", 2},
1208   {NULL, 0},
1209};
1210
1211struct pipe_context *
1212trace_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   tr_ctx->base.surface_copy = trace_context_surface_copy;
1281   tr_ctx->base.surface_fill = trace_context_surface_fill;
1282   tr_ctx->base.clear = trace_context_clear;
1283   tr_ctx->base.flush = trace_context_flush;
1284   tr_ctx->base.is_texture_referenced = trace_is_texture_referenced;
1285   tr_ctx->base.is_buffer_referenced = trace_is_buffer_referenced;
1286
1287   tr_ctx->pipe = pipe;
1288
1289   trace_dump_call_begin("", "pipe_context_create");
1290   trace_dump_arg(ptr, screen);
1291   trace_dump_ret(ptr, pipe);
1292   trace_dump_call_end();
1293
1294   trace_screen_add_to_list(tr_scr, contexts, tr_ctx);
1295
1296   return &tr_ctx->base;
1297
1298error1:
1299   return pipe;
1300}
1301