rbug_context.c revision 4c7001462607e6e99e474d6271dd481d3f8f201c
1/**************************************************************************
2 *
3 * Copyright 2010 VMware, Inc.
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 VMWARE 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
29#include "pipe/p_context.h"
30#include "util/u_memory.h"
31#include "util/u_inlines.h"
32#include "util/u_simple_list.h"
33
34#include "rbug/rbug_context.h"
35
36#include "rbug_context.h"
37#include "rbug_objects.h"
38
39
40static void
41rbug_destroy(struct pipe_context *_pipe)
42{
43   struct rbug_context *rb_pipe = rbug_context(_pipe);
44   struct pipe_context *pipe = rb_pipe->pipe;
45
46   remove_from_list(&rb_pipe->list);
47   pipe->destroy(pipe);
48
49   FREE(rb_pipe);
50}
51
52static void
53rbug_draw_block_locked(struct rbug_context *rb_pipe, int flag)
54{
55
56   if (rb_pipe->draw_blocker & flag) {
57      rb_pipe->draw_blocked |= flag;
58   } else if ((rb_pipe->draw_rule.blocker & flag) &&
59              (rb_pipe->draw_blocker & RBUG_BLOCK_RULE)) {
60      int k;
61      boolean block = FALSE;
62      debug_printf("%s (%p %p) (%p %p) (%p %u) (%p %u)\n", __FUNCTION__,
63                   (void *) rb_pipe->draw_rule.fs, (void *) rb_pipe->curr.fs,
64                   (void *) rb_pipe->draw_rule.vs, (void *) rb_pipe->curr.vs,
65                   (void *) rb_pipe->draw_rule.surf, 0,
66                   (void *) rb_pipe->draw_rule.texture, 0);
67      if (rb_pipe->draw_rule.fs &&
68          rb_pipe->draw_rule.fs == rb_pipe->curr.fs)
69         block = TRUE;
70      if (rb_pipe->draw_rule.vs &&
71          rb_pipe->draw_rule.vs == rb_pipe->curr.vs)
72         block = TRUE;
73      if (rb_pipe->draw_rule.surf &&
74          rb_pipe->draw_rule.surf == rb_pipe->curr.zsbuf)
75            block = TRUE;
76      if (rb_pipe->draw_rule.surf)
77         for (k = 0; k < rb_pipe->curr.nr_cbufs; k++)
78            if (rb_pipe->draw_rule.surf == rb_pipe->curr.cbufs[k])
79               block = TRUE;
80      if (rb_pipe->draw_rule.texture) {
81         for (k = 0; k < rb_pipe->curr.num_fs_views; k++)
82            if (rb_pipe->draw_rule.texture == rb_pipe->curr.fs_texs[k])
83               block = TRUE;
84         for (k = 0; k < rb_pipe->curr.num_vs_views; k++) {
85            if (rb_pipe->draw_rule.texture == rb_pipe->curr.vs_texs[k]) {
86               block = TRUE;
87            }
88         }
89      }
90
91      if (block)
92         rb_pipe->draw_blocked |= (flag | RBUG_BLOCK_RULE);
93   }
94
95   if (rb_pipe->draw_blocked)
96      rbug_notify_draw_blocked(rb_pipe);
97
98   /* wait for rbug to clear the blocked flag */
99   while (rb_pipe->draw_blocked & flag) {
100      rb_pipe->draw_blocked |= flag;
101      pipe_condvar_wait(rb_pipe->draw_cond, rb_pipe->draw_mutex);
102   }
103
104}
105
106static void
107rbug_draw_vbo(struct pipe_context *_pipe, const struct pipe_draw_info *info)
108{
109   struct rbug_context *rb_pipe = rbug_context(_pipe);
110   struct pipe_context *pipe = rb_pipe->pipe;
111
112   pipe_mutex_lock(rb_pipe->draw_mutex);
113   rbug_draw_block_locked(rb_pipe, RBUG_BLOCK_BEFORE);
114
115   pipe->draw_vbo(pipe, info);
116
117   rbug_draw_block_locked(rb_pipe, RBUG_BLOCK_AFTER);
118   pipe_mutex_unlock(rb_pipe->draw_mutex);
119}
120
121static struct pipe_query *
122rbug_create_query(struct pipe_context *_pipe,
123                  unsigned query_type)
124{
125   struct rbug_context *rb_pipe = rbug_context(_pipe);
126   struct pipe_context *pipe = rb_pipe->pipe;
127
128   return pipe->create_query(pipe,
129                             query_type);
130}
131
132static void
133rbug_destroy_query(struct pipe_context *_pipe,
134                   struct pipe_query *query)
135{
136   struct rbug_context *rb_pipe = rbug_context(_pipe);
137   struct pipe_context *pipe = rb_pipe->pipe;
138
139   pipe->destroy_query(pipe,
140                       query);
141}
142
143static void
144rbug_begin_query(struct pipe_context *_pipe,
145                 struct pipe_query *query)
146{
147   struct rbug_context *rb_pipe = rbug_context(_pipe);
148   struct pipe_context *pipe = rb_pipe->pipe;
149
150   pipe->begin_query(pipe,
151                     query);
152}
153
154static void
155rbug_end_query(struct pipe_context *_pipe,
156               struct pipe_query *query)
157{
158   struct rbug_context *rb_pipe = rbug_context(_pipe);
159   struct pipe_context *pipe = rb_pipe->pipe;
160
161   pipe->end_query(pipe,
162                   query);
163}
164
165static boolean
166rbug_get_query_result(struct pipe_context *_pipe,
167                      struct pipe_query *query,
168                      boolean wait,
169                      void *result)
170{
171   struct rbug_context *rb_pipe = rbug_context(_pipe);
172   struct pipe_context *pipe = rb_pipe->pipe;
173
174   return pipe->get_query_result(pipe,
175                                 query,
176                                 wait,
177                                 result);
178}
179
180static void *
181rbug_create_blend_state(struct pipe_context *_pipe,
182                        const struct pipe_blend_state *blend)
183{
184   struct rbug_context *rb_pipe = rbug_context(_pipe);
185   struct pipe_context *pipe = rb_pipe->pipe;
186
187   return pipe->create_blend_state(pipe,
188                                   blend);
189}
190
191static void
192rbug_bind_blend_state(struct pipe_context *_pipe,
193                      void *blend)
194{
195   struct rbug_context *rb_pipe = rbug_context(_pipe);
196   struct pipe_context *pipe = rb_pipe->pipe;
197
198   pipe->bind_blend_state(pipe,
199                              blend);
200}
201
202static void
203rbug_delete_blend_state(struct pipe_context *_pipe,
204                        void *blend)
205{
206   struct rbug_context *rb_pipe = rbug_context(_pipe);
207   struct pipe_context *pipe = rb_pipe->pipe;
208
209   pipe->delete_blend_state(pipe,
210                            blend);
211}
212
213static void *
214rbug_create_sampler_state(struct pipe_context *_pipe,
215                          const struct pipe_sampler_state *sampler)
216{
217   struct rbug_context *rb_pipe = rbug_context(_pipe);
218   struct pipe_context *pipe = rb_pipe->pipe;
219
220   return pipe->create_sampler_state(pipe,
221                                     sampler);
222}
223
224static void
225rbug_bind_fragment_sampler_states(struct pipe_context *_pipe,
226                                  unsigned num_samplers,
227                                  void **samplers)
228{
229   struct rbug_context *rb_pipe = rbug_context(_pipe);
230   struct pipe_context *pipe = rb_pipe->pipe;
231
232   pipe->bind_fragment_sampler_states(pipe,
233                                      num_samplers,
234                                      samplers);
235}
236
237static void
238rbug_bind_vertex_sampler_states(struct pipe_context *_pipe,
239                                unsigned num_samplers,
240                                void **samplers)
241{
242   struct rbug_context *rb_pipe = rbug_context(_pipe);
243   struct pipe_context *pipe = rb_pipe->pipe;
244
245   pipe->bind_vertex_sampler_states(pipe,
246                                    num_samplers,
247                                    samplers);
248}
249
250static void
251rbug_delete_sampler_state(struct pipe_context *_pipe,
252                          void *sampler)
253{
254   struct rbug_context *rb_pipe = rbug_context(_pipe);
255   struct pipe_context *pipe = rb_pipe->pipe;
256
257   pipe->delete_sampler_state(pipe,
258                              sampler);
259}
260
261static void *
262rbug_create_rasterizer_state(struct pipe_context *_pipe,
263                             const struct pipe_rasterizer_state *rasterizer)
264{
265   struct rbug_context *rb_pipe = rbug_context(_pipe);
266   struct pipe_context *pipe = rb_pipe->pipe;
267
268   return pipe->create_rasterizer_state(pipe,
269                                        rasterizer);
270}
271
272static void
273rbug_bind_rasterizer_state(struct pipe_context *_pipe,
274                           void *rasterizer)
275{
276   struct rbug_context *rb_pipe = rbug_context(_pipe);
277   struct pipe_context *pipe = rb_pipe->pipe;
278
279   pipe->bind_rasterizer_state(pipe,
280                               rasterizer);
281}
282
283static void
284rbug_delete_rasterizer_state(struct pipe_context *_pipe,
285                             void *rasterizer)
286{
287   struct rbug_context *rb_pipe = rbug_context(_pipe);
288   struct pipe_context *pipe = rb_pipe->pipe;
289
290   pipe->delete_rasterizer_state(pipe,
291                                 rasterizer);
292}
293
294static void *
295rbug_create_depth_stencil_alpha_state(struct pipe_context *_pipe,
296                                      const struct pipe_depth_stencil_alpha_state *depth_stencil_alpha)
297{
298   struct rbug_context *rb_pipe = rbug_context(_pipe);
299   struct pipe_context *pipe = rb_pipe->pipe;
300
301   return pipe->create_depth_stencil_alpha_state(pipe,
302                                                 depth_stencil_alpha);
303}
304
305static void
306rbug_bind_depth_stencil_alpha_state(struct pipe_context *_pipe,
307                                    void *depth_stencil_alpha)
308{
309   struct rbug_context *rb_pipe = rbug_context(_pipe);
310   struct pipe_context *pipe = rb_pipe->pipe;
311
312   pipe->bind_depth_stencil_alpha_state(pipe,
313                                        depth_stencil_alpha);
314}
315
316static void
317rbug_delete_depth_stencil_alpha_state(struct pipe_context *_pipe,
318                                      void *depth_stencil_alpha)
319{
320   struct rbug_context *rb_pipe = rbug_context(_pipe);
321   struct pipe_context *pipe = rb_pipe->pipe;
322
323   pipe->delete_depth_stencil_alpha_state(pipe,
324                                          depth_stencil_alpha);
325}
326
327static void *
328rbug_create_fs_state(struct pipe_context *_pipe,
329                     const struct pipe_shader_state *state)
330{
331   struct rbug_context *rb_pipe = rbug_context(_pipe);
332   struct pipe_context *pipe = rb_pipe->pipe;
333   void *result;
334
335   result = pipe->create_fs_state(pipe, state);
336   if (!result)
337      return NULL;
338
339   return rbug_shader_create(rb_pipe, state, result, RBUG_SHADER_FRAGMENT);
340}
341
342static void
343rbug_bind_fs_state(struct pipe_context *_pipe,
344                   void *_fs)
345{
346   struct rbug_context *rb_pipe = rbug_context(_pipe);
347   struct pipe_context *pipe = rb_pipe->pipe;
348   void *fs;
349
350   fs = rbug_shader_unwrap(_fs);
351   rb_pipe->curr.fs = rbug_shader(_fs);
352   pipe->bind_fs_state(pipe,
353                       fs);
354}
355
356static void
357rbug_delete_fs_state(struct pipe_context *_pipe,
358                     void *_fs)
359{
360   struct rbug_context *rb_pipe = rbug_context(_pipe);
361   struct rbug_shader *rb_shader = rbug_shader(_fs);
362
363   rbug_shader_destroy(rb_pipe, rb_shader);
364}
365
366static void *
367rbug_create_vs_state(struct pipe_context *_pipe,
368                     const struct pipe_shader_state *state)
369{
370   struct rbug_context *rb_pipe = rbug_context(_pipe);
371   struct pipe_context *pipe = rb_pipe->pipe;
372   void *result;
373
374   result = pipe->create_vs_state(pipe, state);
375   if (!result)
376      return NULL;
377
378   return rbug_shader_create(rb_pipe, state, result, RBUG_SHADER_VERTEX);
379}
380
381static void
382rbug_bind_vs_state(struct pipe_context *_pipe,
383                   void *_vs)
384{
385   struct rbug_context *rb_pipe = rbug_context(_pipe);
386   struct pipe_context *pipe = rb_pipe->pipe;
387   void *vs;
388
389   vs = rbug_shader_unwrap(_vs);
390   rb_pipe->curr.vs = rbug_shader(_vs);
391   pipe->bind_vs_state(pipe,
392                       vs);
393}
394
395static void
396rbug_delete_vs_state(struct pipe_context *_pipe,
397                     void *_vs)
398{
399   struct rbug_context *rb_pipe = rbug_context(_pipe);
400   struct rbug_shader *rb_shader = rbug_shader(_vs);
401
402   rbug_shader_destroy(rb_pipe, rb_shader);
403}
404
405static void *
406rbug_create_gs_state(struct pipe_context *_pipe,
407                     const struct pipe_shader_state *state)
408{
409   struct rbug_context *rb_pipe = rbug_context(_pipe);
410   struct pipe_context *pipe = rb_pipe->pipe;
411   void *result;
412
413   result = pipe->create_gs_state(pipe, state);
414   if (!result)
415      return NULL;
416
417   return rbug_shader_create(rb_pipe, state, result, RBUG_SHADER_GEOM);
418}
419
420static void
421rbug_bind_gs_state(struct pipe_context *_pipe,
422                   void *_gs)
423{
424   struct rbug_context *rb_pipe = rbug_context(_pipe);
425   struct pipe_context *pipe = rb_pipe->pipe;
426   void *gs;
427
428   gs = rbug_shader_unwrap(_gs);
429   rb_pipe->curr.gs = rbug_shader(_gs);
430   pipe->bind_gs_state(pipe,
431                       gs);
432}
433
434static void
435rbug_delete_gs_state(struct pipe_context *_pipe,
436                     void *_gs)
437{
438   struct rbug_context *rb_pipe = rbug_context(_pipe);
439   struct rbug_shader *rb_shader = rbug_shader(_gs);
440
441   rbug_shader_destroy(rb_pipe, rb_shader);
442}
443
444static void *
445rbug_create_vertex_elements_state(struct pipe_context *_pipe,
446                                  unsigned num_elements,
447                                  const struct pipe_vertex_element *vertex_elements)
448{
449   struct rbug_context *rb_pipe = rbug_context(_pipe);
450   struct pipe_context *pipe = rb_pipe->pipe;
451
452   return pipe->create_vertex_elements_state(pipe,
453                                             num_elements,
454                                             vertex_elements);
455}
456
457static void
458rbug_bind_vertex_elements_state(struct pipe_context *_pipe,
459                                void *velems)
460{
461   struct rbug_context *rb_pipe = rbug_context(_pipe);
462   struct pipe_context *pipe = rb_pipe->pipe;
463
464   pipe->bind_vertex_elements_state(pipe,
465                                    velems);
466}
467
468static void
469rbug_delete_vertex_elements_state(struct pipe_context *_pipe,
470                                  void *velems)
471{
472   struct rbug_context *rb_pipe = rbug_context(_pipe);
473   struct pipe_context *pipe = rb_pipe->pipe;
474
475   pipe->delete_vertex_elements_state(pipe,
476                                      velems);
477}
478
479static void
480rbug_set_blend_color(struct pipe_context *_pipe,
481                     const struct pipe_blend_color *blend_color)
482{
483   struct rbug_context *rb_pipe = rbug_context(_pipe);
484   struct pipe_context *pipe = rb_pipe->pipe;
485
486   pipe->set_blend_color(pipe,
487                         blend_color);
488}
489
490static void
491rbug_set_stencil_ref(struct pipe_context *_pipe,
492                     const struct pipe_stencil_ref *stencil_ref)
493{
494   struct rbug_context *rb_pipe = rbug_context(_pipe);
495   struct pipe_context *pipe = rb_pipe->pipe;
496
497   pipe->set_stencil_ref(pipe,
498                         stencil_ref);
499}
500
501static void
502rbug_set_clip_state(struct pipe_context *_pipe,
503                    const struct pipe_clip_state *clip)
504{
505   struct rbug_context *rb_pipe = rbug_context(_pipe);
506   struct pipe_context *pipe = rb_pipe->pipe;
507
508   pipe->set_clip_state(pipe,
509                        clip);
510}
511
512static void
513rbug_set_constant_buffer(struct pipe_context *_pipe,
514                         uint shader,
515                         uint index,
516                         struct pipe_resource *_resource)
517{
518   struct rbug_context *rb_pipe = rbug_context(_pipe);
519   struct pipe_context *pipe = rb_pipe->pipe;
520   struct pipe_resource *unwrapped_resource;
521   struct pipe_resource *resource = NULL;
522
523   /* XXX hmm? unwrap the input state */
524   if (_resource) {
525      unwrapped_resource = rbug_resource_unwrap(_resource);
526      resource = unwrapped_resource;
527   }
528
529   pipe->set_constant_buffer(pipe,
530                             shader,
531                             index,
532                             resource);
533}
534
535static void
536rbug_set_framebuffer_state(struct pipe_context *_pipe,
537                           const struct pipe_framebuffer_state *_state)
538{
539   struct rbug_context *rb_pipe = rbug_context(_pipe);
540   struct pipe_context *pipe = rb_pipe->pipe;
541   struct pipe_framebuffer_state unwrapped_state;
542   struct pipe_framebuffer_state *state = NULL;
543   unsigned i;
544
545   rb_pipe->curr.nr_cbufs = 0;
546   memset(rb_pipe->curr.cbufs, 0, sizeof(rb_pipe->curr.cbufs));
547
548   /* unwrap the input state */
549   if (_state) {
550      memcpy(&unwrapped_state, _state, sizeof(unwrapped_state));
551
552      rb_pipe->curr.nr_cbufs = _state->nr_cbufs;
553      for(i = 0; i < _state->nr_cbufs; i++) {
554         unwrapped_state.cbufs[i] = rbug_surface_unwrap(_state->cbufs[i]);
555         if (_state->cbufs[i])
556            rb_pipe->curr.cbufs[i] = rbug_resource(_state->cbufs[i]->texture);
557      }
558      unwrapped_state.zsbuf = rbug_surface_unwrap(_state->zsbuf);
559      state = &unwrapped_state;
560   }
561
562   pipe->set_framebuffer_state(pipe,
563                               state);
564}
565
566static void
567rbug_set_polygon_stipple(struct pipe_context *_pipe,
568                         const struct pipe_poly_stipple *poly_stipple)
569{
570   struct rbug_context *rb_pipe = rbug_context(_pipe);
571   struct pipe_context *pipe = rb_pipe->pipe;
572
573   pipe->set_polygon_stipple(pipe,
574                             poly_stipple);
575}
576
577static void
578rbug_set_scissor_state(struct pipe_context *_pipe,
579                       const struct pipe_scissor_state *scissor)
580{
581   struct rbug_context *rb_pipe = rbug_context(_pipe);
582   struct pipe_context *pipe = rb_pipe->pipe;
583
584   pipe->set_scissor_state(pipe,
585                           scissor);
586}
587
588static void
589rbug_set_viewport_state(struct pipe_context *_pipe,
590                        const struct pipe_viewport_state *viewport)
591{
592   struct rbug_context *rb_pipe = rbug_context(_pipe);
593   struct pipe_context *pipe = rb_pipe->pipe;
594
595   pipe->set_viewport_state(pipe,
596                            viewport);
597}
598
599static void
600rbug_set_fragment_sampler_views(struct pipe_context *_pipe,
601                                unsigned num,
602                                struct pipe_sampler_view **_views)
603{
604   struct rbug_context *rb_pipe = rbug_context(_pipe);
605   struct pipe_context *pipe = rb_pipe->pipe;
606   struct pipe_sampler_view *unwrapped_views[PIPE_MAX_SAMPLERS];
607   struct pipe_sampler_view **views = NULL;
608   unsigned i;
609
610   rb_pipe->curr.num_fs_views = 0;
611   memset(rb_pipe->curr.fs_views, 0, sizeof(rb_pipe->curr.fs_views));
612   memset(rb_pipe->curr.fs_texs, 0, sizeof(rb_pipe->curr.fs_texs));
613   memset(unwrapped_views, 0, sizeof(unwrapped_views));
614
615   if (_views) {
616      rb_pipe->curr.num_fs_views = num;
617      for (i = 0; i < num; i++) {
618         rb_pipe->curr.fs_views[i] = rbug_sampler_view(_views[i]);
619         rb_pipe->curr.fs_texs[i] = rbug_resource(_views[i] ? _views[i]->texture : NULL);
620         unwrapped_views[i] = rbug_sampler_view_unwrap(_views[i]);
621      }
622      views = unwrapped_views;
623   }
624
625   pipe->set_fragment_sampler_views(pipe, num, views);
626}
627
628static void
629rbug_set_vertex_sampler_views(struct pipe_context *_pipe,
630                              unsigned num,
631                              struct pipe_sampler_view **_views)
632{
633   struct rbug_context *rb_pipe = rbug_context(_pipe);
634   struct pipe_context *pipe = rb_pipe->pipe;
635   struct pipe_sampler_view *unwrapped_views[PIPE_MAX_VERTEX_SAMPLERS];
636   struct pipe_sampler_view **views = NULL;
637   unsigned i;
638
639   rb_pipe->curr.num_vs_views = 0;
640   memset(rb_pipe->curr.vs_views, 0, sizeof(rb_pipe->curr.vs_views));
641   memset(rb_pipe->curr.vs_texs, 0, sizeof(rb_pipe->curr.vs_texs));
642   memset(unwrapped_views, 0, sizeof(unwrapped_views));
643
644   if (_views) {
645      rb_pipe->curr.num_vs_views = num;
646      for (i = 0; i < num; i++) {
647         rb_pipe->curr.vs_views[i] = rbug_sampler_view(_views[i]);
648         rb_pipe->curr.vs_texs[i] = rbug_resource(_views[i]->texture);
649         unwrapped_views[i] = rbug_sampler_view_unwrap(_views[i]);
650      }
651      views = unwrapped_views;
652   }
653
654   pipe->set_vertex_sampler_views(pipe, num, views);
655}
656
657static void
658rbug_set_vertex_buffers(struct pipe_context *_pipe,
659                        unsigned num_buffers,
660                        const struct pipe_vertex_buffer *_buffers)
661{
662   struct rbug_context *rb_pipe = rbug_context(_pipe);
663   struct pipe_context *pipe = rb_pipe->pipe;
664   struct pipe_vertex_buffer unwrapped_buffers[PIPE_MAX_SHADER_INPUTS];
665   struct pipe_vertex_buffer *buffers = NULL;
666   unsigned i;
667
668   if (num_buffers) {
669      memcpy(unwrapped_buffers, _buffers, num_buffers * sizeof(*_buffers));
670      for (i = 0; i < num_buffers; i++)
671         unwrapped_buffers[i].buffer = rbug_resource_unwrap(_buffers[i].buffer);
672      buffers = unwrapped_buffers;
673   }
674
675   pipe->set_vertex_buffers(pipe,
676                            num_buffers,
677                            buffers);
678}
679
680static void
681rbug_set_index_buffer(struct pipe_context *_pipe,
682                      const struct pipe_index_buffer *_ib)
683{
684   struct rbug_context *rb_pipe = rbug_context(_pipe);
685   struct pipe_context *pipe = rb_pipe->pipe;
686   struct pipe_index_buffer unwrapped_ib, *ib = NULL;
687
688   if (_ib) {
689      unwrapped_ib = *_ib;
690      unwrapped_ib.buffer = rbug_resource_unwrap(_ib->buffer);
691      ib = &unwrapped_ib;
692   }
693
694   pipe->set_index_buffer(pipe, ib);
695}
696
697static void
698rbug_set_sample_mask(struct pipe_context *_pipe,
699                     unsigned sample_mask)
700{
701   struct rbug_context *rb_pipe = rbug_context(_pipe);
702   struct pipe_context *pipe = rb_pipe->pipe;
703
704   pipe->set_sample_mask(pipe, sample_mask);
705}
706
707static void
708rbug_resource_copy_region(struct pipe_context *_pipe,
709                          struct pipe_resource *_dst,
710                          unsigned dst_level,
711                          unsigned dstx,
712                          unsigned dsty,
713                          unsigned dstz,
714                          struct pipe_resource *_src,
715                          unsigned src_level,
716                          const struct pipe_box *src_box)
717{
718   struct rbug_context *rb_pipe = rbug_context(_pipe);
719   struct rbug_resource *rb_resource_dst = rbug_resource(_dst);
720   struct rbug_resource *rb_resource_src = rbug_resource(_src);
721   struct pipe_context *pipe = rb_pipe->pipe;
722   struct pipe_resource *dst = rb_resource_dst->resource;
723   struct pipe_resource *src = rb_resource_src->resource;
724
725   pipe->resource_copy_region(pipe,
726                              dst,
727                              dst_level,
728                              dstx,
729                              dsty,
730                              dstz,
731                              src,
732                              src_level,
733                              src_box);
734}
735
736static void
737rbug_clear(struct pipe_context *_pipe,
738           unsigned buffers,
739           const float *rgba,
740           double depth,
741           unsigned stencil)
742{
743   struct rbug_context *rb_pipe = rbug_context(_pipe);
744   struct pipe_context *pipe = rb_pipe->pipe;
745
746   pipe->clear(pipe,
747               buffers,
748               rgba,
749               depth,
750               stencil);
751}
752
753static void
754rbug_clear_render_target(struct pipe_context *_pipe,
755                         struct pipe_surface *_dst,
756                         const float *rgba,
757                         unsigned dstx, unsigned dsty,
758                         unsigned width, unsigned height)
759{
760   struct rbug_context *rb_pipe = rbug_context(_pipe);
761   struct rbug_surface *rb_surface_dst = rbug_surface(_dst);
762   struct pipe_context *pipe = rb_pipe->pipe;
763   struct pipe_surface *dst = rb_surface_dst->surface;
764
765   pipe->clear_render_target(pipe,
766                             dst,
767                             rgba,
768                             dstx,
769                             dsty,
770                             width,
771                             height);
772}
773
774static void
775rbug_clear_depth_stencil(struct pipe_context *_pipe,
776                         struct pipe_surface *_dst,
777                         unsigned clear_flags,
778                         double depth,
779                         unsigned stencil,
780                         unsigned dstx, unsigned dsty,
781                         unsigned width, unsigned height)
782{
783   struct rbug_context *rb_pipe = rbug_context(_pipe);
784   struct rbug_surface *rb_surface_dst = rbug_surface(_dst);
785   struct pipe_context *pipe = rb_pipe->pipe;
786   struct pipe_surface *dst = rb_surface_dst->surface;
787
788   pipe->clear_depth_stencil(pipe,
789                             dst,
790                             clear_flags,
791                             depth,
792                             stencil,
793                             dstx,
794                             dsty,
795                             width,
796                             height);
797}
798
799static void
800rbug_flush(struct pipe_context *_pipe,
801           unsigned flags,
802           struct pipe_fence_handle **fence)
803{
804   struct rbug_context *rb_pipe = rbug_context(_pipe);
805   struct pipe_context *pipe = rb_pipe->pipe;
806
807   pipe->flush(pipe,
808               flags,
809               fence);
810}
811
812static unsigned int
813rbug_is_resource_referenced(struct pipe_context *_pipe,
814                            struct pipe_resource *_resource,
815                            unsigned level,
816                            int layer)
817{
818   struct rbug_context *rb_pipe = rbug_context(_pipe);
819   struct rbug_resource *rb_resource = rbug_resource(_resource);
820   struct pipe_context *pipe = rb_pipe->pipe;
821   struct pipe_resource *resource = rb_resource->resource;
822
823   return pipe->is_resource_referenced(pipe,
824                                       resource,
825                                       level,
826                                       layer);
827}
828
829static struct pipe_sampler_view *
830rbug_context_create_sampler_view(struct pipe_context *_pipe,
831                                 struct pipe_resource *_resource,
832                                 const struct pipe_sampler_view *templ)
833{
834   struct rbug_context *rb_pipe = rbug_context(_pipe);
835   struct rbug_resource *rb_resource = rbug_resource(_resource);
836   struct pipe_context *pipe = rb_pipe->pipe;
837   struct pipe_resource *resource = rb_resource->resource;
838   struct pipe_sampler_view *result;
839
840   result = pipe->create_sampler_view(pipe,
841                                      resource,
842                                      templ);
843
844   if (result)
845      return rbug_sampler_view_create(rb_pipe, rb_resource, result);
846   return NULL;
847}
848
849static void
850rbug_context_sampler_view_destroy(struct pipe_context *_pipe,
851                                  struct pipe_sampler_view *_view)
852{
853   rbug_sampler_view_destroy(rbug_context(_pipe),
854                             rbug_sampler_view(_view));
855}
856
857static struct pipe_surface *
858rbug_context_create_surface(struct pipe_context *_pipe,
859                            struct pipe_resource *_resource,
860                            const struct pipe_surface *surf_tmpl)
861{
862   struct rbug_context *rb_pipe = rbug_context(_pipe);
863   struct rbug_resource *rb_resource = rbug_resource(_resource);
864   struct pipe_context *pipe = rb_pipe->pipe;
865   struct pipe_resource *resource = rb_resource->resource;
866   struct pipe_surface *result;
867
868   result = pipe->create_surface(pipe,
869                                 resource,
870                                 surf_tmpl);
871
872   if (result)
873      return rbug_surface_create(rb_pipe, rb_resource, result);
874   return NULL;
875}
876
877static void
878rbug_context_surface_destroy(struct pipe_context *_pipe,
879                             struct pipe_surface *_surface)
880{
881   rbug_surface_destroy(rbug_context(_pipe),
882                        rbug_surface(_surface));
883}
884
885
886
887static struct pipe_transfer *
888rbug_context_get_transfer(struct pipe_context *_context,
889                          struct pipe_resource *_resource,
890                          unsigned level,
891                          unsigned usage,
892                          const struct pipe_box *box)
893{
894   struct rbug_context *rb_pipe = rbug_context(_context);
895   struct rbug_resource *rb_resource = rbug_resource(_resource);
896   struct pipe_context *context = rb_pipe->pipe;
897   struct pipe_resource *resource = rb_resource->resource;
898   struct pipe_transfer *result;
899
900   result = context->get_transfer(context,
901                                  resource,
902                                  level,
903                                  usage,
904                                  box);
905
906   if (result)
907      return rbug_transfer_create(rb_pipe, rb_resource, result);
908   return NULL;
909}
910
911static void
912rbug_context_transfer_destroy(struct pipe_context *_pipe,
913                              struct pipe_transfer *_transfer)
914{
915   rbug_transfer_destroy(rbug_context(_pipe),
916                             rbug_transfer(_transfer));
917}
918
919static void *
920rbug_context_transfer_map(struct pipe_context *_context,
921                          struct pipe_transfer *_transfer)
922{
923   struct rbug_context *rb_pipe = rbug_context(_context);
924   struct rbug_transfer *rb_transfer = rbug_transfer(_transfer);
925   struct pipe_context *context = rb_pipe->pipe;
926   struct pipe_transfer *transfer = rb_transfer->transfer;
927
928   return context->transfer_map(context,
929                                transfer);
930}
931
932
933
934static void
935rbug_context_transfer_flush_region(struct pipe_context *_context,
936                                   struct pipe_transfer *_transfer,
937                                   const struct pipe_box *box)
938{
939   struct rbug_context *rb_pipe = rbug_context(_context);
940   struct rbug_transfer *rb_transfer = rbug_transfer(_transfer);
941   struct pipe_context *context = rb_pipe->pipe;
942   struct pipe_transfer *transfer = rb_transfer->transfer;
943
944   context->transfer_flush_region(context,
945                                  transfer,
946                                  box);
947}
948
949
950static void
951rbug_context_transfer_unmap(struct pipe_context *_context,
952                            struct pipe_transfer *_transfer)
953{
954   struct rbug_context *rb_pipe = rbug_context(_context);
955   struct rbug_transfer *rb_transfer = rbug_transfer(_transfer);
956   struct pipe_context *context = rb_pipe->pipe;
957   struct pipe_transfer *transfer = rb_transfer->transfer;
958
959   context->transfer_unmap(context,
960                           transfer);
961}
962
963
964static void
965rbug_context_transfer_inline_write(struct pipe_context *_context,
966                                   struct pipe_resource *_resource,
967                                   unsigned level,
968                                   unsigned usage,
969                                   const struct pipe_box *box,
970                                   const void *data,
971                                   unsigned stride,
972                                   unsigned layer_stride)
973{
974   struct rbug_context *rb_pipe = rbug_context(_context);
975   struct rbug_resource *rb_resource = rbug_resource(_resource);
976   struct pipe_context *context = rb_pipe->pipe;
977   struct pipe_resource *resource = rb_resource->resource;
978
979   context->transfer_inline_write(context,
980                                  resource,
981                                  level,
982                                  usage,
983                                  box,
984                                  data,
985                                  stride,
986                                  layer_stride);
987}
988
989
990struct pipe_context *
991rbug_context_create(struct pipe_screen *_screen, struct pipe_context *pipe)
992{
993   struct rbug_context *rb_pipe;
994   struct rbug_screen *rb_screen = rbug_screen(_screen);
995
996   if (!rb_screen)
997      return NULL;
998
999   rb_pipe = CALLOC_STRUCT(rbug_context);
1000   if (!rb_pipe)
1001      return NULL;
1002
1003   pipe_mutex_init(rb_pipe->draw_mutex);
1004   pipe_condvar_init(rb_pipe->draw_cond);
1005   pipe_mutex_init(rb_pipe->call_mutex);
1006   pipe_mutex_init(rb_pipe->list_mutex);
1007   make_empty_list(&rb_pipe->shaders);
1008
1009   rb_pipe->base.winsys = NULL;
1010   rb_pipe->base.screen = _screen;
1011   rb_pipe->base.priv = pipe->priv; /* expose wrapped data */
1012   rb_pipe->base.draw = NULL;
1013
1014   rb_pipe->base.destroy = rbug_destroy;
1015   rb_pipe->base.draw_vbo = rbug_draw_vbo;
1016   rb_pipe->base.create_query = rbug_create_query;
1017   rb_pipe->base.destroy_query = rbug_destroy_query;
1018   rb_pipe->base.begin_query = rbug_begin_query;
1019   rb_pipe->base.end_query = rbug_end_query;
1020   rb_pipe->base.get_query_result = rbug_get_query_result;
1021   rb_pipe->base.create_blend_state = rbug_create_blend_state;
1022   rb_pipe->base.bind_blend_state = rbug_bind_blend_state;
1023   rb_pipe->base.delete_blend_state = rbug_delete_blend_state;
1024   rb_pipe->base.create_sampler_state = rbug_create_sampler_state;
1025   rb_pipe->base.bind_fragment_sampler_states = rbug_bind_fragment_sampler_states;
1026   rb_pipe->base.bind_vertex_sampler_states = rbug_bind_vertex_sampler_states;
1027   rb_pipe->base.delete_sampler_state = rbug_delete_sampler_state;
1028   rb_pipe->base.create_rasterizer_state = rbug_create_rasterizer_state;
1029   rb_pipe->base.bind_rasterizer_state = rbug_bind_rasterizer_state;
1030   rb_pipe->base.delete_rasterizer_state = rbug_delete_rasterizer_state;
1031   rb_pipe->base.create_depth_stencil_alpha_state = rbug_create_depth_stencil_alpha_state;
1032   rb_pipe->base.bind_depth_stencil_alpha_state = rbug_bind_depth_stencil_alpha_state;
1033   rb_pipe->base.delete_depth_stencil_alpha_state = rbug_delete_depth_stencil_alpha_state;
1034   rb_pipe->base.create_fs_state = rbug_create_fs_state;
1035   rb_pipe->base.bind_fs_state = rbug_bind_fs_state;
1036   rb_pipe->base.delete_fs_state = rbug_delete_fs_state;
1037   rb_pipe->base.create_vs_state = rbug_create_vs_state;
1038   rb_pipe->base.bind_vs_state = rbug_bind_vs_state;
1039   rb_pipe->base.delete_vs_state = rbug_delete_vs_state;
1040   rb_pipe->base.create_gs_state = rbug_create_gs_state;
1041   rb_pipe->base.bind_gs_state = rbug_bind_gs_state;
1042   rb_pipe->base.delete_gs_state = rbug_delete_gs_state;
1043   rb_pipe->base.create_vertex_elements_state = rbug_create_vertex_elements_state;
1044   rb_pipe->base.bind_vertex_elements_state = rbug_bind_vertex_elements_state;
1045   rb_pipe->base.delete_vertex_elements_state = rbug_delete_vertex_elements_state;
1046   rb_pipe->base.set_blend_color = rbug_set_blend_color;
1047   rb_pipe->base.set_stencil_ref = rbug_set_stencil_ref;
1048   rb_pipe->base.set_clip_state = rbug_set_clip_state;
1049   rb_pipe->base.set_constant_buffer = rbug_set_constant_buffer;
1050   rb_pipe->base.set_framebuffer_state = rbug_set_framebuffer_state;
1051   rb_pipe->base.set_polygon_stipple = rbug_set_polygon_stipple;
1052   rb_pipe->base.set_scissor_state = rbug_set_scissor_state;
1053   rb_pipe->base.set_viewport_state = rbug_set_viewport_state;
1054   rb_pipe->base.set_fragment_sampler_views = rbug_set_fragment_sampler_views;
1055   rb_pipe->base.set_vertex_sampler_views = rbug_set_vertex_sampler_views;
1056   rb_pipe->base.set_vertex_buffers = rbug_set_vertex_buffers;
1057   rb_pipe->base.set_index_buffer = rbug_set_index_buffer;
1058   rb_pipe->base.set_sample_mask = rbug_set_sample_mask;
1059   rb_pipe->base.resource_copy_region = rbug_resource_copy_region;
1060   rb_pipe->base.clear = rbug_clear;
1061   rb_pipe->base.clear_render_target = rbug_clear_render_target;
1062   rb_pipe->base.clear_depth_stencil = rbug_clear_depth_stencil;
1063   rb_pipe->base.flush = rbug_flush;
1064   rb_pipe->base.is_resource_referenced = rbug_is_resource_referenced;
1065   rb_pipe->base.create_sampler_view = rbug_context_create_sampler_view;
1066   rb_pipe->base.sampler_view_destroy = rbug_context_sampler_view_destroy;
1067   rb_pipe->base.create_surface = rbug_context_create_surface;
1068   rb_pipe->base.surface_destroy = rbug_context_surface_destroy;
1069   rb_pipe->base.get_transfer = rbug_context_get_transfer;
1070   rb_pipe->base.transfer_destroy = rbug_context_transfer_destroy;
1071   rb_pipe->base.transfer_map = rbug_context_transfer_map;
1072   rb_pipe->base.transfer_unmap = rbug_context_transfer_unmap;
1073   rb_pipe->base.transfer_flush_region = rbug_context_transfer_flush_region;
1074   rb_pipe->base.transfer_inline_write = rbug_context_transfer_inline_write;
1075
1076   rb_pipe->pipe = pipe;
1077
1078   rbug_screen_add_to_list(rb_screen, contexts, rb_pipe);
1079
1080   return &rb_pipe->base;
1081}
1082