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