tr_context.c revision 618e7e0c88400dc853b0ff4792a0c70800587073
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_create_vertex_elements_state(struct pipe_context *_pipe,
778                                           unsigned num_elements,
779                                           const struct  pipe_vertex_element *elements)
780{
781   struct trace_context *tr_ctx = trace_context(_pipe);
782   struct pipe_context *pipe = tr_ctx->pipe;
783   void * result;
784
785   trace_dump_call_begin("pipe_context", "create_vertex_elements_state");
786
787   trace_dump_arg(ptr, pipe);
788   trace_dump_arg(uint, num_elements);
789
790   trace_dump_arg_begin("elements");
791   trace_dump_struct_array(vertex_element, elements, num_elements);
792   trace_dump_arg_end();
793
794   result = pipe->create_vertex_elements_state(pipe, num_elements, elements);
795
796   trace_dump_ret(ptr, result);
797
798   trace_dump_call_end();
799
800   return result;
801}
802
803
804static INLINE void
805trace_context_bind_vertex_elements_state(struct pipe_context *_pipe,
806                                         void *state)
807{
808   struct trace_context *tr_ctx = trace_context(_pipe);
809   struct pipe_context *pipe = tr_ctx->pipe;
810
811   trace_dump_call_begin("pipe_context", "bind_vertex_elements_state");
812
813   trace_dump_arg(ptr, pipe);
814   trace_dump_arg(ptr, state);
815
816   pipe->bind_vertex_elements_state(pipe, state);
817
818   trace_dump_call_end();
819}
820
821
822static INLINE void
823trace_context_delete_vertex_elements_state(struct pipe_context *_pipe,
824                                           void *state)
825{
826   struct trace_context *tr_ctx = trace_context(_pipe);
827   struct pipe_context *pipe = tr_ctx->pipe;
828
829   trace_dump_call_begin("pipe_context", "delete_verte_elements_state");
830
831   trace_dump_arg(ptr, pipe);
832   trace_dump_arg(ptr, state);
833
834   pipe->delete_vertex_elements_state(pipe, state);
835
836   trace_dump_call_end();
837}
838
839
840static INLINE void
841trace_context_set_blend_color(struct pipe_context *_pipe,
842                              const struct pipe_blend_color *state)
843{
844   struct trace_context *tr_ctx = trace_context(_pipe);
845   struct pipe_context *pipe = tr_ctx->pipe;
846
847   trace_dump_call_begin("pipe_context", "set_blend_color");
848
849   trace_dump_arg(ptr, pipe);
850   trace_dump_arg(blend_color, state);
851
852   pipe->set_blend_color(pipe, state);
853
854   trace_dump_call_end();
855}
856
857
858static INLINE void
859trace_context_set_stencil_ref(struct pipe_context *_pipe,
860                              const struct pipe_stencil_ref *state)
861{
862   struct trace_context *tr_ctx = trace_context(_pipe);
863   struct pipe_context *pipe = tr_ctx->pipe;
864
865   trace_dump_call_begin("pipe_context", "set_stencil_ref");
866
867   trace_dump_arg(ptr, pipe);
868   trace_dump_arg(stencil_ref, state);
869
870   pipe->set_stencil_ref(pipe, state);
871
872   trace_dump_call_end();
873}
874
875
876static INLINE void
877trace_context_set_clip_state(struct pipe_context *_pipe,
878                             const struct pipe_clip_state *state)
879{
880   struct trace_context *tr_ctx = trace_context(_pipe);
881   struct pipe_context *pipe = tr_ctx->pipe;
882
883   trace_dump_call_begin("pipe_context", "set_clip_state");
884
885   trace_dump_arg(ptr, pipe);
886   trace_dump_arg(clip_state, state);
887
888   pipe->set_clip_state(pipe, state);
889
890   trace_dump_call_end();
891}
892
893
894static INLINE void
895trace_context_set_constant_buffer(struct pipe_context *_pipe,
896                                  uint shader, uint index,
897                                  struct pipe_buffer *buffer)
898{
899   struct trace_context *tr_ctx = trace_context(_pipe);
900   struct pipe_context *pipe = tr_ctx->pipe;
901
902   if (buffer) {
903      trace_screen_user_buffer_update(_pipe->screen, buffer);
904      buffer = trace_buffer_unwrap(tr_ctx, buffer);
905   }
906
907   trace_dump_call_begin("pipe_context", "set_constant_buffer");
908
909   trace_dump_arg(ptr, pipe);
910   trace_dump_arg(uint, shader);
911   trace_dump_arg(uint, index);
912   trace_dump_arg(ptr, buffer);
913
914   pipe->set_constant_buffer(pipe, shader, index, buffer);
915
916   trace_dump_call_end();
917}
918
919
920static INLINE void
921trace_context_set_framebuffer_state(struct pipe_context *_pipe,
922                                    const struct pipe_framebuffer_state *state)
923{
924   struct trace_context *tr_ctx = trace_context(_pipe);
925   struct pipe_context *pipe = tr_ctx->pipe;
926   struct pipe_framebuffer_state unwrapped_state;
927   unsigned i;
928
929   {
930      tr_ctx->curr.nr_cbufs = state->nr_cbufs;
931      for (i = 0; i < state->nr_cbufs; i++)
932         if (state->cbufs[i])
933            tr_ctx->curr.cbufs[i] = trace_texture(state->cbufs[i]->texture);
934         else
935            tr_ctx->curr.cbufs[i] = NULL;
936      if (state->zsbuf)
937         tr_ctx->curr.zsbuf = trace_texture(state->zsbuf->texture);
938      else
939         tr_ctx->curr.zsbuf = NULL;
940   }
941
942   /* Unwrap the input state */
943   memcpy(&unwrapped_state, state, sizeof(unwrapped_state));
944   for(i = 0; i < state->nr_cbufs; ++i)
945      unwrapped_state.cbufs[i] = trace_surface_unwrap(tr_ctx, state->cbufs[i]);
946   for(i = state->nr_cbufs; i < PIPE_MAX_COLOR_BUFS; ++i)
947      unwrapped_state.cbufs[i] = NULL;
948   unwrapped_state.zsbuf = trace_surface_unwrap(tr_ctx, state->zsbuf);
949   state = &unwrapped_state;
950
951   trace_dump_call_begin("pipe_context", "set_framebuffer_state");
952
953   trace_dump_arg(ptr, pipe);
954   trace_dump_arg(framebuffer_state, state);
955
956   pipe->set_framebuffer_state(pipe, state);
957
958   trace_dump_call_end();
959}
960
961
962static INLINE void
963trace_context_set_polygon_stipple(struct pipe_context *_pipe,
964                                  const struct pipe_poly_stipple *state)
965{
966   struct trace_context *tr_ctx = trace_context(_pipe);
967   struct pipe_context *pipe = tr_ctx->pipe;
968
969   trace_dump_call_begin("pipe_context", "set_polygon_stipple");
970
971   trace_dump_arg(ptr, pipe);
972   trace_dump_arg(poly_stipple, state);
973
974   pipe->set_polygon_stipple(pipe, state);
975
976   trace_dump_call_end();
977}
978
979
980static INLINE void
981trace_context_set_scissor_state(struct pipe_context *_pipe,
982                                const struct pipe_scissor_state *state)
983{
984   struct trace_context *tr_ctx = trace_context(_pipe);
985   struct pipe_context *pipe = tr_ctx->pipe;
986
987   trace_dump_call_begin("pipe_context", "set_scissor_state");
988
989   trace_dump_arg(ptr, pipe);
990   trace_dump_arg(scissor_state, state);
991
992   pipe->set_scissor_state(pipe, state);
993
994   trace_dump_call_end();
995}
996
997
998static INLINE void
999trace_context_set_viewport_state(struct pipe_context *_pipe,
1000                                 const struct pipe_viewport_state *state)
1001{
1002   struct trace_context *tr_ctx = trace_context(_pipe);
1003   struct pipe_context *pipe = tr_ctx->pipe;
1004
1005   trace_dump_call_begin("pipe_context", "set_viewport_state");
1006
1007   trace_dump_arg(ptr, pipe);
1008   trace_dump_arg(viewport_state, state);
1009
1010   pipe->set_viewport_state(pipe, state);
1011
1012   trace_dump_call_end();
1013}
1014
1015
1016static INLINE void
1017trace_context_set_fragment_sampler_textures(struct pipe_context *_pipe,
1018                                            unsigned num_textures,
1019                                            struct pipe_texture **textures)
1020{
1021   struct trace_context *tr_ctx = trace_context(_pipe);
1022   struct trace_texture *tr_tex;
1023   struct pipe_context *pipe = tr_ctx->pipe;
1024   struct pipe_texture *unwrapped_textures[PIPE_MAX_SAMPLERS];
1025   unsigned i;
1026
1027   tr_ctx->curr.num_texs = num_textures;
1028   for(i = 0; i < num_textures; ++i) {
1029      tr_tex = trace_texture(textures[i]);
1030      tr_ctx->curr.tex[i] = tr_tex;
1031      unwrapped_textures[i] = tr_tex ? tr_tex->texture : NULL;
1032   }
1033   textures = unwrapped_textures;
1034
1035   trace_dump_call_begin("pipe_context", "set_fragment_sampler_textures");
1036
1037   trace_dump_arg(ptr, pipe);
1038   trace_dump_arg(uint, num_textures);
1039   trace_dump_arg_array(ptr, textures, num_textures);
1040
1041   pipe->set_fragment_sampler_textures(pipe, num_textures, textures);
1042
1043   trace_dump_call_end();
1044}
1045
1046
1047static INLINE void
1048trace_context_set_vertex_sampler_textures(struct pipe_context *_pipe,
1049                                          unsigned num_textures,
1050                                          struct pipe_texture **textures)
1051{
1052   struct trace_context *tr_ctx = trace_context(_pipe);
1053   struct trace_texture *tr_tex;
1054   struct pipe_context *pipe = tr_ctx->pipe;
1055   struct pipe_texture *unwrapped_textures[PIPE_MAX_VERTEX_SAMPLERS];
1056   unsigned i;
1057
1058   tr_ctx->curr.num_vert_texs = num_textures;
1059   for(i = 0; i < num_textures; ++i) {
1060      tr_tex = trace_texture(textures[i]);
1061      tr_ctx->curr.vert_tex[i] = tr_tex;
1062      unwrapped_textures[i] = tr_tex ? tr_tex->texture : NULL;
1063   }
1064   textures = unwrapped_textures;
1065
1066   trace_dump_call_begin("pipe_context", "set_vertex_sampler_textures");
1067
1068   trace_dump_arg(ptr, pipe);
1069   trace_dump_arg(uint, num_textures);
1070   trace_dump_arg_array(ptr, textures, num_textures);
1071
1072   pipe->set_vertex_sampler_textures(pipe, num_textures, textures);
1073
1074   trace_dump_call_end();
1075}
1076
1077
1078static INLINE void
1079trace_context_set_vertex_buffers(struct pipe_context *_pipe,
1080                                 unsigned num_buffers,
1081                                 const struct pipe_vertex_buffer *buffers)
1082{
1083   struct trace_context *tr_ctx = trace_context(_pipe);
1084   struct pipe_context *pipe = tr_ctx->pipe;
1085   unsigned i;
1086
1087   for(i = 0; i < num_buffers; ++i)
1088      trace_screen_user_buffer_update(_pipe->screen, buffers[i].buffer);
1089
1090   trace_dump_call_begin("pipe_context", "set_vertex_buffers");
1091
1092   trace_dump_arg(ptr, pipe);
1093   trace_dump_arg(uint, num_buffers);
1094
1095   trace_dump_arg_begin("buffers");
1096   trace_dump_struct_array(vertex_buffer, buffers, num_buffers);
1097   trace_dump_arg_end();
1098
1099   if (num_buffers) {
1100      struct pipe_vertex_buffer *_buffers = malloc(num_buffers * sizeof(*_buffers));
1101      memcpy(_buffers, buffers, num_buffers * sizeof(*_buffers));
1102      for (i = 0; i < num_buffers; i++)
1103         _buffers[i].buffer = trace_buffer_unwrap(tr_ctx, buffers[i].buffer);
1104      pipe->set_vertex_buffers(pipe, num_buffers, _buffers);
1105      free(_buffers);
1106   } else {
1107      pipe->set_vertex_buffers(pipe, num_buffers, NULL);
1108   }
1109
1110   trace_dump_call_end();
1111}
1112
1113
1114static INLINE void
1115trace_context_surface_copy(struct pipe_context *_pipe,
1116                           struct pipe_surface *dest,
1117                           unsigned destx, unsigned desty,
1118                           struct pipe_surface *src,
1119                           unsigned srcx, unsigned srcy,
1120                           unsigned width, unsigned height)
1121{
1122   struct trace_context *tr_ctx = trace_context(_pipe);
1123   struct pipe_context *pipe = tr_ctx->pipe;
1124
1125   dest = trace_surface_unwrap(tr_ctx, dest);
1126   src = trace_surface_unwrap(tr_ctx, src);
1127
1128   trace_dump_call_begin("pipe_context", "surface_copy");
1129
1130   trace_dump_arg(ptr, pipe);
1131   trace_dump_arg(ptr, dest);
1132   trace_dump_arg(uint, destx);
1133   trace_dump_arg(uint, desty);
1134   trace_dump_arg(ptr, src);
1135   trace_dump_arg(uint, srcx);
1136   trace_dump_arg(uint, srcy);
1137   trace_dump_arg(uint, width);
1138   trace_dump_arg(uint, height);
1139
1140   pipe->surface_copy(pipe,
1141                      dest, destx, desty,
1142                      src, srcx, srcy, width, height);
1143
1144   trace_dump_call_end();
1145}
1146
1147
1148static INLINE void
1149trace_context_surface_fill(struct pipe_context *_pipe,
1150                           struct pipe_surface *dst,
1151                           unsigned dstx, unsigned dsty,
1152                           unsigned width, unsigned height,
1153                           unsigned value)
1154{
1155   struct trace_context *tr_ctx = trace_context(_pipe);
1156   struct pipe_context *pipe = tr_ctx->pipe;
1157
1158   dst = trace_surface_unwrap(tr_ctx, dst);
1159
1160   trace_dump_call_begin("pipe_context", "surface_fill");
1161
1162   trace_dump_arg(ptr, pipe);
1163   trace_dump_arg(ptr, dst);
1164   trace_dump_arg(uint, dstx);
1165   trace_dump_arg(uint, dsty);
1166   trace_dump_arg(uint, width);
1167   trace_dump_arg(uint, height);
1168
1169   pipe->surface_fill(pipe, dst, dstx, dsty, width, height, value);
1170
1171   trace_dump_call_end();
1172}
1173
1174
1175static INLINE void
1176trace_context_clear(struct pipe_context *_pipe,
1177                    unsigned buffers,
1178                    const float *rgba,
1179                    double depth,
1180                    unsigned stencil)
1181{
1182   struct trace_context *tr_ctx = trace_context(_pipe);
1183   struct pipe_context *pipe = tr_ctx->pipe;
1184
1185   trace_dump_call_begin("pipe_context", "clear");
1186
1187   trace_dump_arg(ptr, pipe);
1188   trace_dump_arg(uint, buffers);
1189   trace_dump_arg_array(float, rgba, 4);
1190   trace_dump_arg(float, depth);
1191   trace_dump_arg(uint, stencil);
1192
1193   pipe->clear(pipe, buffers, rgba, depth, stencil);
1194
1195   trace_dump_call_end();
1196}
1197
1198
1199static INLINE void
1200trace_context_flush(struct pipe_context *_pipe,
1201                    unsigned flags,
1202                    struct pipe_fence_handle **fence)
1203{
1204   struct trace_context *tr_ctx = trace_context(_pipe);
1205   struct pipe_context *pipe = tr_ctx->pipe;
1206
1207   trace_dump_call_begin("pipe_context", "flush");
1208
1209   trace_dump_arg(ptr, pipe);
1210   trace_dump_arg(uint, flags);
1211
1212   pipe->flush(pipe, flags, fence);
1213
1214   if(fence)
1215      trace_dump_ret(ptr, *fence);
1216
1217   trace_dump_call_end();
1218}
1219
1220
1221static INLINE void
1222trace_context_destroy(struct pipe_context *_pipe)
1223{
1224   struct trace_screen *tr_scr = trace_screen(_pipe->screen);
1225   struct trace_context *tr_ctx = trace_context(_pipe);
1226   struct pipe_context *pipe = tr_ctx->pipe;
1227
1228   trace_dump_call_begin("pipe_context", "destroy");
1229   trace_dump_arg(ptr, pipe);
1230   trace_dump_call_end();
1231
1232   trace_screen_remove_from_list(tr_scr, contexts, tr_ctx);
1233
1234   pipe->destroy(pipe);
1235
1236   FREE(tr_ctx);
1237}
1238
1239static unsigned int
1240trace_is_texture_referenced( struct pipe_context *_pipe,
1241			    struct pipe_texture *_texture,
1242			    unsigned face, unsigned level)
1243{
1244   struct trace_context *tr_ctx = trace_context(_pipe);
1245   struct trace_texture *tr_tex = trace_texture(_texture);
1246   struct pipe_context *pipe = tr_ctx->pipe;
1247   struct pipe_texture *texture = tr_tex->texture;
1248   unsigned int referenced;
1249
1250   trace_dump_call_begin("pipe_context", "is_texture_referenced");
1251   trace_dump_arg(ptr, pipe);
1252   trace_dump_arg(ptr, texture);
1253   trace_dump_arg(uint, face);
1254   trace_dump_arg(uint, level);
1255
1256   referenced = pipe->is_texture_referenced(pipe, texture, face, level);
1257
1258   trace_dump_ret(uint, referenced);
1259   trace_dump_call_end();
1260
1261   return referenced;
1262}
1263
1264static unsigned int
1265trace_is_buffer_referenced( struct pipe_context *_pipe,
1266			    struct pipe_buffer *_buf)
1267{
1268   struct trace_context *tr_ctx = trace_context(_pipe);
1269   struct trace_buffer *tr_buf = trace_buffer(_buf);
1270   struct pipe_context *pipe = tr_ctx->pipe;
1271   struct pipe_buffer *buf = tr_buf->buffer;
1272   unsigned int referenced;
1273
1274   trace_dump_call_begin("pipe_context", "is_buffer_referenced");
1275   trace_dump_arg(ptr, pipe);
1276   trace_dump_arg(ptr, buf);
1277
1278   referenced = pipe->is_buffer_referenced(pipe, buf);
1279
1280   trace_dump_ret(uint, referenced);
1281   trace_dump_call_end();
1282
1283   return referenced;
1284}
1285
1286static const struct debug_named_value rbug_blocker_flags[] = {
1287   {"before", 1},
1288   {"after", 2},
1289   {NULL, 0},
1290};
1291
1292struct pipe_context *
1293trace_context_create(struct trace_screen *tr_scr,
1294                     struct pipe_context *pipe)
1295{
1296   struct trace_context *tr_ctx;
1297
1298   if(!pipe)
1299      goto error1;
1300
1301   if(!trace_enabled())
1302      goto error1;
1303
1304   tr_ctx = CALLOC_STRUCT(trace_context);
1305   if(!tr_ctx)
1306      goto error1;
1307
1308   tr_ctx->base.winsys = NULL;
1309   tr_ctx->base.priv = pipe->priv; /* expose wrapped priv data */
1310   tr_ctx->base.screen = &tr_scr->base;
1311   tr_ctx->draw_blocker = debug_get_flags_option("RBUG_BLOCK",
1312                                                 rbug_blocker_flags,
1313                                                 0);
1314   pipe_mutex_init(tr_ctx->draw_mutex);
1315   pipe_condvar_init(tr_ctx->draw_cond);
1316   pipe_mutex_init(tr_ctx->list_mutex);
1317   make_empty_list(&tr_ctx->shaders);
1318
1319   tr_ctx->base.destroy = trace_context_destroy;
1320   tr_ctx->base.draw_arrays = trace_context_draw_arrays;
1321   tr_ctx->base.draw_elements = trace_context_draw_elements;
1322   tr_ctx->base.draw_range_elements = trace_context_draw_range_elements;
1323   tr_ctx->base.create_query = trace_context_create_query;
1324   tr_ctx->base.destroy_query = trace_context_destroy_query;
1325   tr_ctx->base.begin_query = trace_context_begin_query;
1326   tr_ctx->base.end_query = trace_context_end_query;
1327   tr_ctx->base.get_query_result = trace_context_get_query_result;
1328   tr_ctx->base.create_blend_state = trace_context_create_blend_state;
1329   tr_ctx->base.bind_blend_state = trace_context_bind_blend_state;
1330   tr_ctx->base.delete_blend_state = trace_context_delete_blend_state;
1331   tr_ctx->base.create_sampler_state = trace_context_create_sampler_state;
1332   tr_ctx->base.bind_fragment_sampler_states = trace_context_bind_fragment_sampler_states;
1333   tr_ctx->base.bind_vertex_sampler_states = trace_context_bind_vertex_sampler_states;
1334   tr_ctx->base.delete_sampler_state = trace_context_delete_sampler_state;
1335   tr_ctx->base.create_rasterizer_state = trace_context_create_rasterizer_state;
1336   tr_ctx->base.bind_rasterizer_state = trace_context_bind_rasterizer_state;
1337   tr_ctx->base.delete_rasterizer_state = trace_context_delete_rasterizer_state;
1338   tr_ctx->base.create_depth_stencil_alpha_state = trace_context_create_depth_stencil_alpha_state;
1339   tr_ctx->base.bind_depth_stencil_alpha_state = trace_context_bind_depth_stencil_alpha_state;
1340   tr_ctx->base.delete_depth_stencil_alpha_state = trace_context_delete_depth_stencil_alpha_state;
1341   tr_ctx->base.create_fs_state = trace_context_create_fs_state;
1342   tr_ctx->base.bind_fs_state = trace_context_bind_fs_state;
1343   tr_ctx->base.delete_fs_state = trace_context_delete_fs_state;
1344   tr_ctx->base.create_vs_state = trace_context_create_vs_state;
1345   tr_ctx->base.bind_vs_state = trace_context_bind_vs_state;
1346   tr_ctx->base.delete_vs_state = trace_context_delete_vs_state;
1347   tr_ctx->base.create_vertex_elements_state = trace_context_create_vertex_elements_state;
1348   tr_ctx->base.bind_vertex_elements_state = trace_context_bind_vertex_elements_state;
1349   tr_ctx->base.delete_vertex_elements_state = trace_context_delete_vertex_elements_state;
1350   tr_ctx->base.set_blend_color = trace_context_set_blend_color;
1351   tr_ctx->base.set_stencil_ref = trace_context_set_stencil_ref;
1352   tr_ctx->base.set_clip_state = trace_context_set_clip_state;
1353   tr_ctx->base.set_constant_buffer = trace_context_set_constant_buffer;
1354   tr_ctx->base.set_framebuffer_state = trace_context_set_framebuffer_state;
1355   tr_ctx->base.set_polygon_stipple = trace_context_set_polygon_stipple;
1356   tr_ctx->base.set_scissor_state = trace_context_set_scissor_state;
1357   tr_ctx->base.set_viewport_state = trace_context_set_viewport_state;
1358   tr_ctx->base.set_fragment_sampler_textures = trace_context_set_fragment_sampler_textures;
1359   tr_ctx->base.set_vertex_sampler_textures = trace_context_set_vertex_sampler_textures;
1360   tr_ctx->base.set_vertex_buffers = trace_context_set_vertex_buffers;
1361   if (pipe->surface_copy)
1362      tr_ctx->base.surface_copy = trace_context_surface_copy;
1363   if (pipe->surface_fill)
1364      tr_ctx->base.surface_fill = trace_context_surface_fill;
1365   tr_ctx->base.clear = trace_context_clear;
1366   tr_ctx->base.flush = trace_context_flush;
1367   tr_ctx->base.is_texture_referenced = trace_is_texture_referenced;
1368   tr_ctx->base.is_buffer_referenced = trace_is_buffer_referenced;
1369
1370   tr_ctx->pipe = pipe;
1371
1372   trace_screen_add_to_list(tr_scr, contexts, tr_ctx);
1373
1374   return &tr_ctx->base;
1375
1376error1:
1377   return pipe;
1378}
1379