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