i965g: Move bootstrap code to targets
[mesa.git] / src / gallium / drivers / rbug / rbug_core.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 "os/os_thread.h"
30 #include "util/u_format.h"
31 #include "util/u_string.h"
32 #include "util/u_inlines.h"
33 #include "util/u_memory.h"
34 #include "util/u_simple_list.h"
35 #include "util/u_network.h"
36 #include "os/os_time.h"
37
38 #include "tgsi/tgsi_parse.h"
39
40 #include "rbug_context.h"
41 #include "rbug_objects.h"
42
43 #include "rbug/rbug.h"
44
45 #include <errno.h>
46
47 #define U642VOID(x) ((void *)(unsigned long)(x))
48 #define VOID2U64(x) ((uint64_t)(unsigned long)(x))
49
50 #define container_of(ptr, type, field) \
51 (type*)((char*)ptr - offsetof(type, field))
52
53 struct rbug_rbug
54 {
55 struct rbug_screen *rb_screen;
56 struct rbug_connection *con;
57 pipe_thread thread;
58 boolean running;
59 };
60
61 PIPE_THREAD_ROUTINE(rbug_thread, void_rbug);
62
63
64 /**********************************************************
65 * Helper functions
66 */
67
68
69 static struct rbug_context *
70 rbug_get_context_locked(struct rbug_screen *rb_screen, rbug_context_t ctx)
71 {
72 struct rbug_context *rb_context = NULL;
73 struct rbug_list *ptr;
74
75 foreach(ptr, &rb_screen->contexts) {
76 rb_context = container_of(ptr, struct rbug_context, list);
77 if (ctx == VOID2U64(rb_context))
78 break;
79 rb_context = NULL;
80 }
81
82 return rb_context;
83 }
84
85 static struct rbug_shader *
86 rbug_get_shader_locked(struct rbug_context *rb_context, rbug_shader_t shdr)
87 {
88 struct rbug_shader *tr_shdr = NULL;
89 struct rbug_list *ptr;
90
91 foreach(ptr, &rb_context->shaders) {
92 tr_shdr = container_of(ptr, struct rbug_shader, list);
93 if (shdr == VOID2U64(tr_shdr))
94 break;
95 tr_shdr = NULL;
96 }
97
98 return tr_shdr;
99 }
100
101 static void *
102 rbug_shader_create_locked(struct pipe_context *pipe,
103 struct rbug_shader *rb_shader,
104 struct tgsi_token *tokens)
105 {
106 void *state = NULL;
107 struct pipe_shader_state pss = { 0 };
108 pss.tokens = tokens;
109
110 switch(rb_shader->type) {
111 case RBUG_SHADER_FRAGMENT:
112 state = pipe->create_fs_state(pipe, &pss);
113 break;
114 case RBUG_SHADER_VERTEX:
115 state = pipe->create_vs_state(pipe, &pss);
116 break;
117 case RBUG_SHADER_GEOM:
118 state = pipe->create_gs_state(pipe, &pss);
119 break;
120 default:
121 assert(0);
122 break;
123 }
124
125 return state;
126 }
127
128 static void
129 rbug_shader_bind_locked(struct pipe_context *pipe,
130 struct rbug_shader *rb_shader,
131 void *state)
132 {
133 switch(rb_shader->type) {
134 case RBUG_SHADER_FRAGMENT:
135 pipe->bind_fs_state(pipe, state);
136 break;
137 case RBUG_SHADER_VERTEX:
138 pipe->bind_vs_state(pipe, state);
139 break;
140 case RBUG_SHADER_GEOM:
141 pipe->bind_gs_state(pipe, state);
142 break;
143 default:
144 assert(0);
145 break;
146 }
147 }
148
149 static void
150 rbug_shader_delete_locked(struct pipe_context *pipe,
151 struct rbug_shader *rb_shader,
152 void *state)
153 {
154 switch(rb_shader->type) {
155 case RBUG_SHADER_FRAGMENT:
156 pipe->delete_fs_state(pipe, state);
157 break;
158 case RBUG_SHADER_VERTEX:
159 pipe->delete_vs_state(pipe, state);
160 break;
161 case RBUG_SHADER_GEOM:
162 pipe->delete_gs_state(pipe, state);
163 break;
164 default:
165 assert(0);
166 break;
167 }
168 }
169
170 /************************************************
171 * Request handler functions
172 */
173
174
175 static int
176 rbug_texture_list(struct rbug_rbug *tr_rbug, struct rbug_header *header, uint32_t serial)
177 {
178 struct rbug_screen *rb_screen = tr_rbug->rb_screen;
179 struct rbug_resource *tr_tex = NULL;
180 struct rbug_list *ptr;
181 rbug_texture_t *texs;
182 int i = 0;
183
184 pipe_mutex_lock(rb_screen->list_mutex);
185 texs = MALLOC(rb_screen->num_resources * sizeof(rbug_texture_t));
186 foreach(ptr, &rb_screen->resources) {
187 tr_tex = container_of(ptr, struct rbug_resource, list);
188 texs[i++] = VOID2U64(tr_tex);
189 }
190 pipe_mutex_unlock(rb_screen->list_mutex);
191
192 rbug_send_texture_list_reply(tr_rbug->con, serial, texs, i, NULL);
193 FREE(texs);
194
195 return 0;
196 }
197
198 static int
199 rbug_texture_info(struct rbug_rbug *tr_rbug, struct rbug_header *header, uint32_t serial)
200 {
201 struct rbug_screen *rb_screen = tr_rbug->rb_screen;
202 struct rbug_resource *tr_tex = NULL;
203 struct rbug_proto_texture_info *gpti = (struct rbug_proto_texture_info *)header;
204 struct rbug_list *ptr;
205 struct pipe_resource *t;
206
207 pipe_mutex_lock(rb_screen->list_mutex);
208 foreach(ptr, &rb_screen->resources) {
209 tr_tex = container_of(ptr, struct rbug_resource, list);
210 if (gpti->texture == VOID2U64(tr_tex))
211 break;
212 tr_tex = NULL;
213 }
214
215 if (!tr_tex) {
216 pipe_mutex_unlock(rb_screen->list_mutex);
217 return -ESRCH;
218 }
219
220 t = tr_tex->resource;
221 rbug_send_texture_info_reply(tr_rbug->con, serial,
222 t->target, t->format,
223 &t->width0, 1,
224 &t->height0, 1,
225 &t->depth0, 1,
226 util_format_get_blockwidth(t->format),
227 util_format_get_blockheight(t->format),
228 util_format_get_blocksize(t->format),
229 t->last_level,
230 t->nr_samples,
231 t->bind,
232 NULL);
233
234 pipe_mutex_unlock(rb_screen->list_mutex);
235
236 return 0;
237 }
238
239 static int
240 rbug_texture_read(struct rbug_rbug *tr_rbug, struct rbug_header *header, uint32_t serial)
241 {
242 struct rbug_proto_texture_read *gptr = (struct rbug_proto_texture_read *)header;
243
244 struct rbug_screen *rb_screen = tr_rbug->rb_screen;
245 struct rbug_resource *tr_tex = NULL;
246 struct rbug_list *ptr;
247
248 struct pipe_context *context = rb_screen->private_context;
249 struct pipe_resource *tex;
250 struct pipe_transfer *t;
251
252 void *map;
253
254 pipe_mutex_lock(rb_screen->list_mutex);
255 foreach(ptr, &rb_screen->resources) {
256 tr_tex = container_of(ptr, struct rbug_resource, list);
257 if (gptr->texture == VOID2U64(tr_tex))
258 break;
259 tr_tex = NULL;
260 }
261
262 if (!tr_tex) {
263 pipe_mutex_unlock(rb_screen->list_mutex);
264 return -ESRCH;
265 }
266
267 tex = tr_tex->resource;
268 t = pipe_get_transfer(context, tex,
269 gptr->face, gptr->level, gptr->zslice,
270 PIPE_TRANSFER_READ,
271 gptr->x, gptr->y, gptr->w, gptr->h);
272
273 map = context->transfer_map(context, t);
274
275 rbug_send_texture_read_reply(tr_rbug->con, serial,
276 t->resource->format,
277 util_format_get_blockwidth(t->resource->format),
278 util_format_get_blockheight(t->resource->format),
279 util_format_get_blocksize(t->resource->format),
280 (uint8_t*)map,
281 t->stride * util_format_get_nblocksy(t->resource->format,
282 t->box.height),
283 t->stride,
284 NULL);
285
286 context->transfer_unmap(context, t);
287 context->transfer_destroy(context, t);
288
289 pipe_mutex_unlock(rb_screen->list_mutex);
290
291 return 0;
292 }
293
294 static int
295 rbug_context_list(struct rbug_rbug *tr_rbug, struct rbug_header *header, uint32_t serial)
296 {
297 struct rbug_screen *rb_screen = tr_rbug->rb_screen;
298 struct rbug_list *ptr;
299 struct rbug_context *rb_context = NULL;
300 rbug_context_t *ctxs;
301 int i = 0;
302
303 pipe_mutex_lock(rb_screen->list_mutex);
304 ctxs = MALLOC(rb_screen->num_contexts * sizeof(rbug_context_t));
305 foreach(ptr, &rb_screen->contexts) {
306 rb_context = container_of(ptr, struct rbug_context, list);
307 ctxs[i++] = VOID2U64(rb_context);
308 }
309 pipe_mutex_unlock(rb_screen->list_mutex);
310
311 rbug_send_context_list_reply(tr_rbug->con, serial, ctxs, i, NULL);
312 FREE(ctxs);
313
314 return 0;
315 }
316
317 static int
318 rbug_context_info(struct rbug_rbug *tr_rbug, struct rbug_header *header, uint32_t serial)
319 {
320 struct rbug_proto_context_info *info = (struct rbug_proto_context_info *)header;
321
322 struct rbug_screen *rb_screen = tr_rbug->rb_screen;
323 struct rbug_context *rb_context = NULL;
324 rbug_texture_t cbufs[PIPE_MAX_COLOR_BUFS];
325 rbug_texture_t texs[PIPE_MAX_SAMPLERS];
326 int i;
327
328 pipe_mutex_lock(rb_screen->list_mutex);
329 rb_context = rbug_get_context_locked(rb_screen, info->context);
330
331 if (!rb_context) {
332 pipe_mutex_unlock(rb_screen->list_mutex);
333 return -ESRCH;
334 }
335
336 /* protect the pipe context */
337 pipe_mutex_lock(rb_context->draw_mutex);
338 pipe_mutex_lock(rb_context->call_mutex);
339
340 for (i = 0; i < rb_context->curr.nr_cbufs; i++)
341 cbufs[i] = VOID2U64(rb_context->curr.cbufs[i]);
342
343 for (i = 0; i < rb_context->curr.num_fs_views; i++)
344 texs[i] = VOID2U64(rb_context->curr.fs_texs[i]);
345
346 rbug_send_context_info_reply(tr_rbug->con, serial,
347 VOID2U64(rb_context->curr.vs), VOID2U64(rb_context->curr.fs),
348 texs, rb_context->curr.num_fs_views,
349 cbufs, rb_context->curr.nr_cbufs,
350 VOID2U64(rb_context->curr.zsbuf),
351 rb_context->draw_blocker, rb_context->draw_blocked, NULL);
352
353 pipe_mutex_unlock(rb_context->call_mutex);
354 pipe_mutex_unlock(rb_context->draw_mutex);
355 pipe_mutex_unlock(rb_screen->list_mutex);
356
357 return 0;
358 }
359
360 static int
361 rbug_context_draw_block(struct rbug_rbug *tr_rbug, struct rbug_header *header, uint32_t serial)
362 {
363 struct rbug_proto_context_draw_block *block = (struct rbug_proto_context_draw_block *)header;
364
365 struct rbug_screen *rb_screen = tr_rbug->rb_screen;
366 struct rbug_context *rb_context = NULL;
367
368 pipe_mutex_lock(rb_screen->list_mutex);
369 rb_context = rbug_get_context_locked(rb_screen, block->context);
370
371 if (!rb_context) {
372 pipe_mutex_unlock(rb_screen->list_mutex);
373 return -ESRCH;
374 }
375
376 pipe_mutex_lock(rb_context->draw_mutex);
377 rb_context->draw_blocker |= block->block;
378 pipe_mutex_unlock(rb_context->draw_mutex);
379
380 pipe_mutex_unlock(rb_screen->list_mutex);
381
382 return 0;
383 }
384
385 static int
386 rbug_context_draw_step(struct rbug_rbug *tr_rbug, struct rbug_header *header, uint32_t serial)
387 {
388 struct rbug_proto_context_draw_step *step = (struct rbug_proto_context_draw_step *)header;
389
390 struct rbug_screen *rb_screen = tr_rbug->rb_screen;
391 struct rbug_context *rb_context = NULL;
392
393 pipe_mutex_lock(rb_screen->list_mutex);
394 rb_context = rbug_get_context_locked(rb_screen, step->context);
395
396 if (!rb_context) {
397 pipe_mutex_unlock(rb_screen->list_mutex);
398 return -ESRCH;
399 }
400
401 pipe_mutex_lock(rb_context->draw_mutex);
402 if (rb_context->draw_blocked & RBUG_BLOCK_RULE) {
403 if (step->step & RBUG_BLOCK_RULE)
404 rb_context->draw_blocked &= ~RBUG_BLOCK_MASK;
405 } else {
406 rb_context->draw_blocked &= ~step->step;
407 }
408 pipe_mutex_unlock(rb_context->draw_mutex);
409
410 #ifdef PIPE_THREAD_HAVE_CONDVAR
411 pipe_condvar_broadcast(rb_context->draw_cond);
412 #endif
413
414 pipe_mutex_unlock(rb_screen->list_mutex);
415
416 return 0;
417 }
418
419 static int
420 rbug_context_draw_unblock(struct rbug_rbug *tr_rbug, struct rbug_header *header, uint32_t serial)
421 {
422 struct rbug_proto_context_draw_unblock *unblock = (struct rbug_proto_context_draw_unblock *)header;
423
424 struct rbug_screen *rb_screen = tr_rbug->rb_screen;
425 struct rbug_context *rb_context = NULL;
426
427 pipe_mutex_lock(rb_screen->list_mutex);
428 rb_context = rbug_get_context_locked(rb_screen, unblock->context);
429
430 if (!rb_context) {
431 pipe_mutex_unlock(rb_screen->list_mutex);
432 return -ESRCH;
433 }
434
435 pipe_mutex_lock(rb_context->draw_mutex);
436 if (rb_context->draw_blocked & RBUG_BLOCK_RULE) {
437 if (unblock->unblock & RBUG_BLOCK_RULE)
438 rb_context->draw_blocked &= ~RBUG_BLOCK_MASK;
439 } else {
440 rb_context->draw_blocked &= ~unblock->unblock;
441 }
442 rb_context->draw_blocker &= ~unblock->unblock;
443 pipe_mutex_unlock(rb_context->draw_mutex);
444
445 #ifdef PIPE_THREAD_HAVE_CONDVAR
446 pipe_condvar_broadcast(rb_context->draw_cond);
447 #endif
448
449 pipe_mutex_unlock(rb_screen->list_mutex);
450
451 return 0;
452 }
453
454 static int
455 rbug_context_draw_rule(struct rbug_rbug *tr_rbug, struct rbug_header *header, uint32_t serial)
456 {
457 struct rbug_proto_context_draw_rule *rule = (struct rbug_proto_context_draw_rule *)header;
458
459 struct rbug_screen *rb_screen = tr_rbug->rb_screen;
460 struct rbug_context *rb_context = NULL;
461
462 pipe_mutex_lock(rb_screen->list_mutex);
463 rb_context = rbug_get_context_locked(rb_screen, rule->context);
464
465 if (!rb_context) {
466 pipe_mutex_unlock(rb_screen->list_mutex);
467 return -ESRCH;
468 }
469
470 pipe_mutex_lock(rb_context->draw_mutex);
471 rb_context->draw_rule.vs = U642VOID(rule->vertex);
472 rb_context->draw_rule.fs = U642VOID(rule->fragment);
473 rb_context->draw_rule.texture = U642VOID(rule->texture);
474 rb_context->draw_rule.surf = U642VOID(rule->surface);
475 rb_context->draw_rule.blocker = rule->block;
476 rb_context->draw_blocker |= RBUG_BLOCK_RULE;
477 pipe_mutex_unlock(rb_context->draw_mutex);
478
479 #ifdef PIPE_THREAD_HAVE_CONDVAR
480 pipe_condvar_broadcast(rb_context->draw_cond);
481 #endif
482
483 pipe_mutex_unlock(rb_screen->list_mutex);
484
485 return 0;
486 }
487
488 static int
489 rbug_context_flush(struct rbug_rbug *tr_rbug, struct rbug_header *header, uint32_t serial)
490 {
491 struct rbug_proto_context_flush *flush = (struct rbug_proto_context_flush *)header;
492
493 struct rbug_screen *rb_screen = tr_rbug->rb_screen;
494 struct rbug_context *rb_context = NULL;
495
496 pipe_mutex_lock(rb_screen->list_mutex);
497 rb_context = rbug_get_context_locked(rb_screen, flush->context);
498
499 if (!rb_context) {
500 pipe_mutex_unlock(rb_screen->list_mutex);
501 return -ESRCH;
502 }
503
504 /* protect the pipe context */
505 pipe_mutex_lock(rb_context->call_mutex);
506
507 rb_context->pipe->flush(rb_context->pipe, flush->flags, NULL);
508
509 pipe_mutex_unlock(rb_context->call_mutex);
510 pipe_mutex_unlock(rb_screen->list_mutex);
511
512 return 0;
513 }
514
515 static int
516 rbug_shader_list(struct rbug_rbug *tr_rbug, struct rbug_header *header, uint32_t serial)
517 {
518 struct rbug_proto_shader_list *list = (struct rbug_proto_shader_list *)header;
519
520 struct rbug_screen *rb_screen = tr_rbug->rb_screen;
521 struct rbug_context *rb_context = NULL;
522 struct rbug_shader *tr_shdr = NULL;
523 struct rbug_list *ptr;
524 rbug_shader_t *shdrs;
525 int i = 0;
526
527 pipe_mutex_lock(rb_screen->list_mutex);
528 rb_context = rbug_get_context_locked(rb_screen, list->context);
529
530 if (!rb_context) {
531 pipe_mutex_unlock(rb_screen->list_mutex);
532 return -ESRCH;
533 }
534
535 pipe_mutex_lock(rb_context->list_mutex);
536 shdrs = MALLOC(rb_context->num_shaders * sizeof(rbug_shader_t));
537 foreach(ptr, &rb_context->shaders) {
538 tr_shdr = container_of(ptr, struct rbug_shader, list);
539 shdrs[i++] = VOID2U64(tr_shdr);
540 }
541
542 pipe_mutex_unlock(rb_context->list_mutex);
543 pipe_mutex_unlock(rb_screen->list_mutex);
544
545 rbug_send_shader_list_reply(tr_rbug->con, serial, shdrs, i, NULL);
546 FREE(shdrs);
547
548 return 0;
549 }
550
551 static int
552 rbug_shader_info(struct rbug_rbug *tr_rbug, struct rbug_header *header, uint32_t serial)
553 {
554 struct rbug_proto_shader_info *info = (struct rbug_proto_shader_info *)header;
555
556 struct rbug_screen *rb_screen = tr_rbug->rb_screen;
557 struct rbug_context *rb_context = NULL;
558 struct rbug_shader *tr_shdr = NULL;
559 unsigned original_len;
560 unsigned replaced_len;
561
562 pipe_mutex_lock(rb_screen->list_mutex);
563 rb_context = rbug_get_context_locked(rb_screen, info->context);
564
565 if (!rb_context) {
566 pipe_mutex_unlock(rb_screen->list_mutex);
567 return -ESRCH;
568 }
569
570 pipe_mutex_lock(rb_context->list_mutex);
571
572 tr_shdr = rbug_get_shader_locked(rb_context, info->shader);
573
574 if (!tr_shdr) {
575 pipe_mutex_unlock(rb_context->list_mutex);
576 pipe_mutex_unlock(rb_screen->list_mutex);
577 return -ESRCH;
578 }
579
580 /* just in case */
581 assert(sizeof(struct tgsi_token) == 4);
582
583 original_len = tgsi_num_tokens(tr_shdr->tokens);
584 if (tr_shdr->replaced_tokens)
585 replaced_len = tgsi_num_tokens(tr_shdr->replaced_tokens);
586 else
587 replaced_len = 0;
588
589 rbug_send_shader_info_reply(tr_rbug->con, serial,
590 (uint32_t*)tr_shdr->tokens, original_len,
591 (uint32_t*)tr_shdr->replaced_tokens, replaced_len,
592 tr_shdr->disabled,
593 NULL);
594
595 pipe_mutex_unlock(rb_context->list_mutex);
596 pipe_mutex_unlock(rb_screen->list_mutex);
597
598 return 0;
599 }
600
601 static int
602 rbug_shader_disable(struct rbug_rbug *tr_rbug, struct rbug_header *header)
603 {
604 struct rbug_proto_shader_disable *dis = (struct rbug_proto_shader_disable *)header;
605
606 struct rbug_screen *rb_screen = tr_rbug->rb_screen;
607 struct rbug_context *rb_context = NULL;
608 struct rbug_shader *tr_shdr = NULL;
609
610 pipe_mutex_lock(rb_screen->list_mutex);
611 rb_context = rbug_get_context_locked(rb_screen, dis->context);
612
613 if (!rb_context) {
614 pipe_mutex_unlock(rb_screen->list_mutex);
615 return -ESRCH;
616 }
617
618 pipe_mutex_lock(rb_context->list_mutex);
619
620 tr_shdr = rbug_get_shader_locked(rb_context, dis->shader);
621
622 if (!tr_shdr) {
623 pipe_mutex_unlock(rb_context->list_mutex);
624 pipe_mutex_unlock(rb_screen->list_mutex);
625 return -ESRCH;
626 }
627
628 tr_shdr->disabled = dis->disable;
629
630 pipe_mutex_unlock(rb_context->list_mutex);
631 pipe_mutex_unlock(rb_screen->list_mutex);
632
633 return 0;
634 }
635
636 static int
637 rbug_shader_replace(struct rbug_rbug *tr_rbug, struct rbug_header *header)
638 {
639 struct rbug_proto_shader_replace *rep = (struct rbug_proto_shader_replace *)header;
640
641 struct rbug_screen *rb_screen = tr_rbug->rb_screen;
642 struct rbug_context *rb_context = NULL;
643 struct rbug_shader *tr_shdr = NULL;
644 struct pipe_context *pipe = NULL;
645 void *state;
646
647 pipe_mutex_lock(rb_screen->list_mutex);
648 rb_context = rbug_get_context_locked(rb_screen, rep->context);
649
650 if (!rb_context) {
651 pipe_mutex_unlock(rb_screen->list_mutex);
652 return -ESRCH;
653 }
654
655 pipe_mutex_lock(rb_context->list_mutex);
656
657 tr_shdr = rbug_get_shader_locked(rb_context, rep->shader);
658
659 if (!tr_shdr) {
660 pipe_mutex_unlock(rb_context->list_mutex);
661 pipe_mutex_unlock(rb_screen->list_mutex);
662 return -ESRCH;
663 }
664
665 /* protect the pipe context */
666 pipe_mutex_lock(rb_context->call_mutex);
667
668 pipe = rb_context->pipe;
669
670 /* remove old replaced shader */
671 if (tr_shdr->replaced_shader) {
672 /* if this shader is bound rebind the original shader */
673 if (rb_context->curr.fs == tr_shdr || rb_context->curr.vs == tr_shdr)
674 rbug_shader_bind_locked(pipe, tr_shdr, tr_shdr->shader);
675
676 FREE(tr_shdr->replaced_tokens);
677 rbug_shader_delete_locked(pipe, tr_shdr, tr_shdr->replaced_shader);
678 tr_shdr->replaced_shader = NULL;
679 tr_shdr->replaced_tokens = NULL;
680 }
681
682 /* empty inputs means restore old which we did above */
683 if (rep->tokens_len == 0)
684 goto out;
685
686 tr_shdr->replaced_tokens = tgsi_dup_tokens((struct tgsi_token *)rep->tokens);
687 if (!tr_shdr->replaced_tokens)
688 goto err;
689
690 state = rbug_shader_create_locked(pipe, tr_shdr, tr_shdr->replaced_tokens);
691 if (!state)
692 goto err;
693
694 /* bind new shader if the shader is currently a bound */
695 if (rb_context->curr.fs == tr_shdr || rb_context->curr.vs == tr_shdr)
696 rbug_shader_bind_locked(pipe, tr_shdr, state);
697
698 /* save state */
699 tr_shdr->replaced_shader = state;
700
701 out:
702 pipe_mutex_unlock(rb_context->call_mutex);
703 pipe_mutex_unlock(rb_context->list_mutex);
704 pipe_mutex_unlock(rb_screen->list_mutex);
705
706 return 0;
707
708 err:
709 FREE(tr_shdr->replaced_tokens);
710 tr_shdr->replaced_shader = NULL;
711 tr_shdr->replaced_tokens = NULL;
712
713 pipe_mutex_unlock(rb_context->call_mutex);
714 pipe_mutex_unlock(rb_context->list_mutex);
715 pipe_mutex_unlock(rb_screen->list_mutex);
716 return -EINVAL;
717 }
718
719 static boolean
720 rbug_header(struct rbug_rbug *tr_rbug, struct rbug_header *header, uint32_t serial)
721 {
722 int ret = 0;
723
724 switch(header->opcode) {
725 case RBUG_OP_PING:
726 rbug_send_ping_reply(tr_rbug->con, serial, NULL);
727 break;
728 case RBUG_OP_TEXTURE_LIST:
729 ret = rbug_texture_list(tr_rbug, header, serial);
730 break;
731 case RBUG_OP_TEXTURE_INFO:
732 ret = rbug_texture_info(tr_rbug, header, serial);
733 break;
734 case RBUG_OP_TEXTURE_READ:
735 ret = rbug_texture_read(tr_rbug, header, serial);
736 break;
737 case RBUG_OP_CONTEXT_LIST:
738 ret = rbug_context_list(tr_rbug, header, serial);
739 break;
740 case RBUG_OP_CONTEXT_INFO:
741 ret = rbug_context_info(tr_rbug, header, serial);
742 break;
743 case RBUG_OP_CONTEXT_DRAW_BLOCK:
744 ret = rbug_context_draw_block(tr_rbug, header, serial);
745 break;
746 case RBUG_OP_CONTEXT_DRAW_STEP:
747 ret = rbug_context_draw_step(tr_rbug, header, serial);
748 break;
749 case RBUG_OP_CONTEXT_DRAW_UNBLOCK:
750 ret = rbug_context_draw_unblock(tr_rbug, header, serial);
751 break;
752 case RBUG_OP_CONTEXT_DRAW_RULE:
753 ret = rbug_context_draw_rule(tr_rbug, header, serial);
754 break;
755 case RBUG_OP_CONTEXT_FLUSH:
756 ret = rbug_context_flush(tr_rbug, header, serial);
757 break;
758 case RBUG_OP_SHADER_LIST:
759 ret = rbug_shader_list(tr_rbug, header, serial);
760 break;
761 case RBUG_OP_SHADER_INFO:
762 ret = rbug_shader_info(tr_rbug, header, serial);
763 break;
764 case RBUG_OP_SHADER_DISABLE:
765 ret = rbug_shader_disable(tr_rbug, header);
766 break;
767 case RBUG_OP_SHADER_REPLACE:
768 ret = rbug_shader_replace(tr_rbug, header);
769 break;
770 default:
771 debug_printf("%s - unsupported opcode %u\n", __FUNCTION__, header->opcode);
772 ret = -ENOSYS;
773 break;
774 }
775 rbug_free_header(header);
776
777 if (ret)
778 rbug_send_error_reply(tr_rbug->con, serial, ret, NULL);
779
780 return TRUE;
781 }
782
783 static void
784 rbug_con(struct rbug_rbug *tr_rbug)
785 {
786 struct rbug_header *header;
787 uint32_t serial;
788
789 debug_printf("%s - connection received\n", __FUNCTION__);
790
791 while(tr_rbug->running) {
792 header = rbug_get_message(tr_rbug->con, &serial);
793 if (!header)
794 break;
795
796 if (!rbug_header(tr_rbug, header, serial))
797 break;
798 }
799
800 debug_printf("%s - connection closed\n", __FUNCTION__);
801
802 rbug_disconnect(tr_rbug->con);
803 tr_rbug->con = NULL;
804 }
805
806 PIPE_THREAD_ROUTINE(rbug_thread, void_tr_rbug)
807 {
808 struct rbug_rbug *tr_rbug = void_tr_rbug;
809 uint16_t port = 13370;
810 int s = -1;
811 int c;
812
813 u_socket_init();
814
815 for (;port <= 13379 && s < 0; port++)
816 s = u_socket_listen_on_port(port);
817
818 if (s < 0) {
819 debug_printf("rbug_rbug - failed to listen\n");
820 return NULL;
821 }
822
823 u_socket_block(s, false);
824
825 debug_printf("rbug_rbug - remote debugging listening on port %u\n", --port);
826
827 while(tr_rbug->running) {
828 os_time_sleep(1);
829
830 c = u_socket_accept(s);
831 if (c < 0)
832 continue;
833
834 u_socket_block(c, true);
835 tr_rbug->con = rbug_from_socket(c);
836
837 rbug_con(tr_rbug);
838
839 u_socket_close(c);
840 }
841
842 u_socket_close(s);
843
844 u_socket_stop();
845
846 return NULL;
847 }
848
849 /**********************************************************
850 *
851 */
852
853 struct rbug_rbug *
854 rbug_start(struct rbug_screen *rb_screen)
855 {
856 struct rbug_rbug *tr_rbug = CALLOC_STRUCT(rbug_rbug);
857 if (!tr_rbug)
858 return NULL;
859
860 tr_rbug->rb_screen = rb_screen;
861 tr_rbug->running = TRUE;
862 tr_rbug->thread = pipe_thread_create(rbug_thread, tr_rbug);
863
864 return tr_rbug;
865 }
866
867 void
868 rbug_stop(struct rbug_rbug *tr_rbug)
869 {
870 if (!tr_rbug)
871 return;
872
873 tr_rbug->running = false;
874 pipe_thread_wait(tr_rbug->thread);
875
876 FREE(tr_rbug);
877
878 return;
879 }
880
881 void
882 rbug_notify_draw_blocked(struct rbug_context *rb_context)
883 {
884 struct rbug_screen *rb_screen = rbug_screen(rb_context->base.screen);
885 struct rbug_rbug *tr_rbug = rb_screen->rbug;
886
887 if (tr_rbug && tr_rbug->con)
888 rbug_send_context_draw_blocked(tr_rbug->con,
889 VOID2U64(rb_context), rb_context->draw_blocked, NULL);
890 }