rbug_context.c revision 25485f4b69447514ab8b595aced90c75606a99bd
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   rb_pipe->curr.zsbuf = NULL;
548
549   /* unwrap the input state */
550   if (_state) {
551      memcpy(&unwrapped_state, _state, sizeof(unwrapped_state));
552
553      rb_pipe->curr.nr_cbufs = _state->nr_cbufs;
554      for(i = 0; i < _state->nr_cbufs; i++) {
555         unwrapped_state.cbufs[i] = rbug_surface_unwrap(_state->cbufs[i]);
556         if (_state->cbufs[i])
557            rb_pipe->curr.cbufs[i] = rbug_resource(_state->cbufs[i]->texture);
558      }
559      unwrapped_state.zsbuf = rbug_surface_unwrap(_state->zsbuf);
560      if (_state->zsbuf)
561         rb_pipe->curr.zsbuf = rbug_resource(_state->zsbuf->texture);
562      state = &unwrapped_state;
563   }
564
565   pipe->set_framebuffer_state(pipe,
566                               state);
567}
568
569static void
570rbug_set_polygon_stipple(struct pipe_context *_pipe,
571                         const struct pipe_poly_stipple *poly_stipple)
572{
573   struct rbug_context *rb_pipe = rbug_context(_pipe);
574   struct pipe_context *pipe = rb_pipe->pipe;
575
576   pipe->set_polygon_stipple(pipe,
577                             poly_stipple);
578}
579
580static void
581rbug_set_scissor_state(struct pipe_context *_pipe,
582                       const struct pipe_scissor_state *scissor)
583{
584   struct rbug_context *rb_pipe = rbug_context(_pipe);
585   struct pipe_context *pipe = rb_pipe->pipe;
586
587   pipe->set_scissor_state(pipe,
588                           scissor);
589}
590
591static void
592rbug_set_viewport_state(struct pipe_context *_pipe,
593                        const struct pipe_viewport_state *viewport)
594{
595   struct rbug_context *rb_pipe = rbug_context(_pipe);
596   struct pipe_context *pipe = rb_pipe->pipe;
597
598   pipe->set_viewport_state(pipe,
599                            viewport);
600}
601
602static void
603rbug_set_fragment_sampler_views(struct pipe_context *_pipe,
604                                unsigned num,
605                                struct pipe_sampler_view **_views)
606{
607   struct rbug_context *rb_pipe = rbug_context(_pipe);
608   struct pipe_context *pipe = rb_pipe->pipe;
609   struct pipe_sampler_view *unwrapped_views[PIPE_MAX_SAMPLERS];
610   struct pipe_sampler_view **views = NULL;
611   unsigned i;
612
613   rb_pipe->curr.num_fs_views = 0;
614   memset(rb_pipe->curr.fs_views, 0, sizeof(rb_pipe->curr.fs_views));
615   memset(rb_pipe->curr.fs_texs, 0, sizeof(rb_pipe->curr.fs_texs));
616   memset(unwrapped_views, 0, sizeof(unwrapped_views));
617
618   if (_views) {
619      rb_pipe->curr.num_fs_views = num;
620      for (i = 0; i < num; i++) {
621         rb_pipe->curr.fs_views[i] = rbug_sampler_view(_views[i]);
622         rb_pipe->curr.fs_texs[i] = rbug_resource(_views[i] ? _views[i]->texture : NULL);
623         unwrapped_views[i] = rbug_sampler_view_unwrap(_views[i]);
624      }
625      views = unwrapped_views;
626   }
627
628   pipe->set_fragment_sampler_views(pipe, num, views);
629}
630
631static void
632rbug_set_vertex_sampler_views(struct pipe_context *_pipe,
633                              unsigned num,
634                              struct pipe_sampler_view **_views)
635{
636   struct rbug_context *rb_pipe = rbug_context(_pipe);
637   struct pipe_context *pipe = rb_pipe->pipe;
638   struct pipe_sampler_view *unwrapped_views[PIPE_MAX_VERTEX_SAMPLERS];
639   struct pipe_sampler_view **views = NULL;
640   unsigned i;
641
642   rb_pipe->curr.num_vs_views = 0;
643   memset(rb_pipe->curr.vs_views, 0, sizeof(rb_pipe->curr.vs_views));
644   memset(rb_pipe->curr.vs_texs, 0, sizeof(rb_pipe->curr.vs_texs));
645   memset(unwrapped_views, 0, sizeof(unwrapped_views));
646
647   if (_views) {
648      rb_pipe->curr.num_vs_views = num;
649      for (i = 0; i < num; i++) {
650         rb_pipe->curr.vs_views[i] = rbug_sampler_view(_views[i]);
651         rb_pipe->curr.vs_texs[i] = rbug_resource(_views[i]->texture);
652         unwrapped_views[i] = rbug_sampler_view_unwrap(_views[i]);
653      }
654      views = unwrapped_views;
655   }
656
657   pipe->set_vertex_sampler_views(pipe, num, views);
658}
659
660static void
661rbug_set_vertex_buffers(struct pipe_context *_pipe,
662                        unsigned num_buffers,
663                        const struct pipe_vertex_buffer *_buffers)
664{
665   struct rbug_context *rb_pipe = rbug_context(_pipe);
666   struct pipe_context *pipe = rb_pipe->pipe;
667   struct pipe_vertex_buffer unwrapped_buffers[PIPE_MAX_SHADER_INPUTS];
668   struct pipe_vertex_buffer *buffers = NULL;
669   unsigned i;
670
671   if (num_buffers) {
672      memcpy(unwrapped_buffers, _buffers, num_buffers * sizeof(*_buffers));
673      for (i = 0; i < num_buffers; i++)
674         unwrapped_buffers[i].buffer = rbug_resource_unwrap(_buffers[i].buffer);
675      buffers = unwrapped_buffers;
676   }
677
678   pipe->set_vertex_buffers(pipe,
679                            num_buffers,
680                            buffers);
681}
682
683static void
684rbug_set_index_buffer(struct pipe_context *_pipe,
685                      const struct pipe_index_buffer *_ib)
686{
687   struct rbug_context *rb_pipe = rbug_context(_pipe);
688   struct pipe_context *pipe = rb_pipe->pipe;
689   struct pipe_index_buffer unwrapped_ib, *ib = NULL;
690
691   if (_ib) {
692      unwrapped_ib = *_ib;
693      unwrapped_ib.buffer = rbug_resource_unwrap(_ib->buffer);
694      ib = &unwrapped_ib;
695   }
696
697   pipe->set_index_buffer(pipe, ib);
698}
699
700static void
701rbug_set_sample_mask(struct pipe_context *_pipe,
702                     unsigned sample_mask)
703{
704   struct rbug_context *rb_pipe = rbug_context(_pipe);
705   struct pipe_context *pipe = rb_pipe->pipe;
706
707   pipe->set_sample_mask(pipe, sample_mask);
708}
709
710static void
711rbug_resource_copy_region(struct pipe_context *_pipe,
712                          struct pipe_resource *_dst,
713                          unsigned dst_level,
714                          unsigned dstx,
715                          unsigned dsty,
716                          unsigned dstz,
717                          struct pipe_resource *_src,
718                          unsigned src_level,
719                          const struct pipe_box *src_box)
720{
721   struct rbug_context *rb_pipe = rbug_context(_pipe);
722   struct rbug_resource *rb_resource_dst = rbug_resource(_dst);
723   struct rbug_resource *rb_resource_src = rbug_resource(_src);
724   struct pipe_context *pipe = rb_pipe->pipe;
725   struct pipe_resource *dst = rb_resource_dst->resource;
726   struct pipe_resource *src = rb_resource_src->resource;
727
728   pipe->resource_copy_region(pipe,
729                              dst,
730                              dst_level,
731                              dstx,
732                              dsty,
733                              dstz,
734                              src,
735                              src_level,
736                              src_box);
737}
738
739static void
740rbug_clear(struct pipe_context *_pipe,
741           unsigned buffers,
742           const float *rgba,
743           double depth,
744           unsigned stencil)
745{
746   struct rbug_context *rb_pipe = rbug_context(_pipe);
747   struct pipe_context *pipe = rb_pipe->pipe;
748
749   pipe->clear(pipe,
750               buffers,
751               rgba,
752               depth,
753               stencil);
754}
755
756static void
757rbug_clear_render_target(struct pipe_context *_pipe,
758                         struct pipe_surface *_dst,
759                         const float *rgba,
760                         unsigned dstx, unsigned dsty,
761                         unsigned width, unsigned height)
762{
763   struct rbug_context *rb_pipe = rbug_context(_pipe);
764   struct rbug_surface *rb_surface_dst = rbug_surface(_dst);
765   struct pipe_context *pipe = rb_pipe->pipe;
766   struct pipe_surface *dst = rb_surface_dst->surface;
767
768   pipe->clear_render_target(pipe,
769                             dst,
770                             rgba,
771                             dstx,
772                             dsty,
773                             width,
774                             height);
775}
776
777static void
778rbug_clear_depth_stencil(struct pipe_context *_pipe,
779                         struct pipe_surface *_dst,
780                         unsigned clear_flags,
781                         double depth,
782                         unsigned stencil,
783                         unsigned dstx, unsigned dsty,
784                         unsigned width, unsigned height)
785{
786   struct rbug_context *rb_pipe = rbug_context(_pipe);
787   struct rbug_surface *rb_surface_dst = rbug_surface(_dst);
788   struct pipe_context *pipe = rb_pipe->pipe;
789   struct pipe_surface *dst = rb_surface_dst->surface;
790
791   pipe->clear_depth_stencil(pipe,
792                             dst,
793                             clear_flags,
794                             depth,
795                             stencil,
796                             dstx,
797                             dsty,
798                             width,
799                             height);
800}
801
802static void
803rbug_flush(struct pipe_context *_pipe,
804           unsigned flags,
805           struct pipe_fence_handle **fence)
806{
807   struct rbug_context *rb_pipe = rbug_context(_pipe);
808   struct pipe_context *pipe = rb_pipe->pipe;
809
810   pipe->flush(pipe,
811               flags,
812               fence);
813}
814
815static struct pipe_sampler_view *
816rbug_context_create_sampler_view(struct pipe_context *_pipe,
817                                 struct pipe_resource *_resource,
818                                 const struct pipe_sampler_view *templ)
819{
820   struct rbug_context *rb_pipe = rbug_context(_pipe);
821   struct rbug_resource *rb_resource = rbug_resource(_resource);
822   struct pipe_context *pipe = rb_pipe->pipe;
823   struct pipe_resource *resource = rb_resource->resource;
824   struct pipe_sampler_view *result;
825
826   result = pipe->create_sampler_view(pipe,
827                                      resource,
828                                      templ);
829
830   if (result)
831      return rbug_sampler_view_create(rb_pipe, rb_resource, result);
832   return NULL;
833}
834
835static void
836rbug_context_sampler_view_destroy(struct pipe_context *_pipe,
837                                  struct pipe_sampler_view *_view)
838{
839   rbug_sampler_view_destroy(rbug_context(_pipe),
840                             rbug_sampler_view(_view));
841}
842
843static struct pipe_surface *
844rbug_context_create_surface(struct pipe_context *_pipe,
845                            struct pipe_resource *_resource,
846                            const struct pipe_surface *surf_tmpl)
847{
848   struct rbug_context *rb_pipe = rbug_context(_pipe);
849   struct rbug_resource *rb_resource = rbug_resource(_resource);
850   struct pipe_context *pipe = rb_pipe->pipe;
851   struct pipe_resource *resource = rb_resource->resource;
852   struct pipe_surface *result;
853
854   result = pipe->create_surface(pipe,
855                                 resource,
856                                 surf_tmpl);
857
858   if (result)
859      return rbug_surface_create(rb_pipe, rb_resource, result);
860   return NULL;
861}
862
863static void
864rbug_context_surface_destroy(struct pipe_context *_pipe,
865                             struct pipe_surface *_surface)
866{
867   rbug_surface_destroy(rbug_context(_pipe),
868                        rbug_surface(_surface));
869}
870
871
872
873static struct pipe_transfer *
874rbug_context_get_transfer(struct pipe_context *_context,
875                          struct pipe_resource *_resource,
876                          unsigned level,
877                          unsigned usage,
878                          const struct pipe_box *box)
879{
880   struct rbug_context *rb_pipe = rbug_context(_context);
881   struct rbug_resource *rb_resource = rbug_resource(_resource);
882   struct pipe_context *context = rb_pipe->pipe;
883   struct pipe_resource *resource = rb_resource->resource;
884   struct pipe_transfer *result;
885
886   result = context->get_transfer(context,
887                                  resource,
888                                  level,
889                                  usage,
890                                  box);
891
892   if (result)
893      return rbug_transfer_create(rb_pipe, rb_resource, result);
894   return NULL;
895}
896
897static void
898rbug_context_transfer_destroy(struct pipe_context *_pipe,
899                              struct pipe_transfer *_transfer)
900{
901   rbug_transfer_destroy(rbug_context(_pipe),
902                             rbug_transfer(_transfer));
903}
904
905static void *
906rbug_context_transfer_map(struct pipe_context *_context,
907                          struct pipe_transfer *_transfer)
908{
909   struct rbug_context *rb_pipe = rbug_context(_context);
910   struct rbug_transfer *rb_transfer = rbug_transfer(_transfer);
911   struct pipe_context *context = rb_pipe->pipe;
912   struct pipe_transfer *transfer = rb_transfer->transfer;
913
914   return context->transfer_map(context,
915                                transfer);
916}
917
918
919
920static void
921rbug_context_transfer_flush_region(struct pipe_context *_context,
922                                   struct pipe_transfer *_transfer,
923                                   const struct pipe_box *box)
924{
925   struct rbug_context *rb_pipe = rbug_context(_context);
926   struct rbug_transfer *rb_transfer = rbug_transfer(_transfer);
927   struct pipe_context *context = rb_pipe->pipe;
928   struct pipe_transfer *transfer = rb_transfer->transfer;
929
930   context->transfer_flush_region(context,
931                                  transfer,
932                                  box);
933}
934
935
936static void
937rbug_context_transfer_unmap(struct pipe_context *_context,
938                            struct pipe_transfer *_transfer)
939{
940   struct rbug_context *rb_pipe = rbug_context(_context);
941   struct rbug_transfer *rb_transfer = rbug_transfer(_transfer);
942   struct pipe_context *context = rb_pipe->pipe;
943   struct pipe_transfer *transfer = rb_transfer->transfer;
944
945   context->transfer_unmap(context,
946                           transfer);
947}
948
949
950static void
951rbug_context_transfer_inline_write(struct pipe_context *_context,
952                                   struct pipe_resource *_resource,
953                                   unsigned level,
954                                   unsigned usage,
955                                   const struct pipe_box *box,
956                                   const void *data,
957                                   unsigned stride,
958                                   unsigned layer_stride)
959{
960   struct rbug_context *rb_pipe = rbug_context(_context);
961   struct rbug_resource *rb_resource = rbug_resource(_resource);
962   struct pipe_context *context = rb_pipe->pipe;
963   struct pipe_resource *resource = rb_resource->resource;
964
965   context->transfer_inline_write(context,
966                                  resource,
967                                  level,
968                                  usage,
969                                  box,
970                                  data,
971                                  stride,
972                                  layer_stride);
973}
974
975
976static void rbug_redefine_user_buffer(struct pipe_context *_context,
977                                      struct pipe_resource *_resource,
978                                      unsigned offset, unsigned size)
979{
980   struct rbug_context *rb_pipe = rbug_context(_context);
981   struct rbug_resource *rb_resource = rbug_resource(_resource);
982   struct pipe_context *context = rb_pipe->pipe;
983   struct pipe_resource *resource = rb_resource->resource;
984
985   context->redefine_user_buffer(context, resource, offset, size);
986}
987
988
989struct pipe_context *
990rbug_context_create(struct pipe_screen *_screen, struct pipe_context *pipe)
991{
992   struct rbug_context *rb_pipe;
993   struct rbug_screen *rb_screen = rbug_screen(_screen);
994
995   if (!rb_screen)
996      return NULL;
997
998   rb_pipe = CALLOC_STRUCT(rbug_context);
999   if (!rb_pipe)
1000      return NULL;
1001
1002   pipe_mutex_init(rb_pipe->draw_mutex);
1003   pipe_condvar_init(rb_pipe->draw_cond);
1004   pipe_mutex_init(rb_pipe->call_mutex);
1005   pipe_mutex_init(rb_pipe->list_mutex);
1006   make_empty_list(&rb_pipe->shaders);
1007
1008   rb_pipe->base.winsys = NULL;
1009   rb_pipe->base.screen = _screen;
1010   rb_pipe->base.priv = pipe->priv; /* expose wrapped data */
1011   rb_pipe->base.draw = NULL;
1012
1013   rb_pipe->base.destroy = rbug_destroy;
1014   rb_pipe->base.draw_vbo = rbug_draw_vbo;
1015   rb_pipe->base.create_query = rbug_create_query;
1016   rb_pipe->base.destroy_query = rbug_destroy_query;
1017   rb_pipe->base.begin_query = rbug_begin_query;
1018   rb_pipe->base.end_query = rbug_end_query;
1019   rb_pipe->base.get_query_result = rbug_get_query_result;
1020   rb_pipe->base.create_blend_state = rbug_create_blend_state;
1021   rb_pipe->base.bind_blend_state = rbug_bind_blend_state;
1022   rb_pipe->base.delete_blend_state = rbug_delete_blend_state;
1023   rb_pipe->base.create_sampler_state = rbug_create_sampler_state;
1024   rb_pipe->base.bind_fragment_sampler_states = rbug_bind_fragment_sampler_states;
1025   rb_pipe->base.bind_vertex_sampler_states = rbug_bind_vertex_sampler_states;
1026   rb_pipe->base.delete_sampler_state = rbug_delete_sampler_state;
1027   rb_pipe->base.create_rasterizer_state = rbug_create_rasterizer_state;
1028   rb_pipe->base.bind_rasterizer_state = rbug_bind_rasterizer_state;
1029   rb_pipe->base.delete_rasterizer_state = rbug_delete_rasterizer_state;
1030   rb_pipe->base.create_depth_stencil_alpha_state = rbug_create_depth_stencil_alpha_state;
1031   rb_pipe->base.bind_depth_stencil_alpha_state = rbug_bind_depth_stencil_alpha_state;
1032   rb_pipe->base.delete_depth_stencil_alpha_state = rbug_delete_depth_stencil_alpha_state;
1033   rb_pipe->base.create_fs_state = rbug_create_fs_state;
1034   rb_pipe->base.bind_fs_state = rbug_bind_fs_state;
1035   rb_pipe->base.delete_fs_state = rbug_delete_fs_state;
1036   rb_pipe->base.create_vs_state = rbug_create_vs_state;
1037   rb_pipe->base.bind_vs_state = rbug_bind_vs_state;
1038   rb_pipe->base.delete_vs_state = rbug_delete_vs_state;
1039   rb_pipe->base.create_gs_state = rbug_create_gs_state;
1040   rb_pipe->base.bind_gs_state = rbug_bind_gs_state;
1041   rb_pipe->base.delete_gs_state = rbug_delete_gs_state;
1042   rb_pipe->base.create_vertex_elements_state = rbug_create_vertex_elements_state;
1043   rb_pipe->base.bind_vertex_elements_state = rbug_bind_vertex_elements_state;
1044   rb_pipe->base.delete_vertex_elements_state = rbug_delete_vertex_elements_state;
1045   rb_pipe->base.set_blend_color = rbug_set_blend_color;
1046   rb_pipe->base.set_stencil_ref = rbug_set_stencil_ref;
1047   rb_pipe->base.set_clip_state = rbug_set_clip_state;
1048   rb_pipe->base.set_constant_buffer = rbug_set_constant_buffer;
1049   rb_pipe->base.set_framebuffer_state = rbug_set_framebuffer_state;
1050   rb_pipe->base.set_polygon_stipple = rbug_set_polygon_stipple;
1051   rb_pipe->base.set_scissor_state = rbug_set_scissor_state;
1052   rb_pipe->base.set_viewport_state = rbug_set_viewport_state;
1053   rb_pipe->base.set_fragment_sampler_views = rbug_set_fragment_sampler_views;
1054   rb_pipe->base.set_vertex_sampler_views = rbug_set_vertex_sampler_views;
1055   rb_pipe->base.set_vertex_buffers = rbug_set_vertex_buffers;
1056   rb_pipe->base.set_index_buffer = rbug_set_index_buffer;
1057   rb_pipe->base.set_sample_mask = rbug_set_sample_mask;
1058   rb_pipe->base.resource_copy_region = rbug_resource_copy_region;
1059   rb_pipe->base.clear = rbug_clear;
1060   rb_pipe->base.clear_render_target = rbug_clear_render_target;
1061   rb_pipe->base.clear_depth_stencil = rbug_clear_depth_stencil;
1062   rb_pipe->base.flush = rbug_flush;
1063   rb_pipe->base.create_sampler_view = rbug_context_create_sampler_view;
1064   rb_pipe->base.sampler_view_destroy = rbug_context_sampler_view_destroy;
1065   rb_pipe->base.create_surface = rbug_context_create_surface;
1066   rb_pipe->base.surface_destroy = rbug_context_surface_destroy;
1067   rb_pipe->base.get_transfer = rbug_context_get_transfer;
1068   rb_pipe->base.transfer_destroy = rbug_context_transfer_destroy;
1069   rb_pipe->base.transfer_map = rbug_context_transfer_map;
1070   rb_pipe->base.transfer_unmap = rbug_context_transfer_unmap;
1071   rb_pipe->base.transfer_flush_region = rbug_context_transfer_flush_region;
1072   rb_pipe->base.transfer_inline_write = rbug_context_transfer_inline_write;
1073   rb_pipe->base.redefine_user_buffer = rbug_redefine_user_buffer;
1074
1075   rb_pipe->pipe = pipe;
1076
1077   rbug_screen_add_to_list(rb_screen, contexts, rb_pipe);
1078
1079   return &rb_pipe->base;
1080}
1081