gallium: split CAP_INSTANCE_DRAWING into INSTANCEID and INSTANCE_DIVISOR
[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->level, gptr->face + 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 pipe_condvar_broadcast(rb_context->draw_cond);
411
412 pipe_mutex_unlock(rb_screen->list_mutex);
413
414 return 0;
415 }
416
417 static int
418 rbug_context_draw_unblock(struct rbug_rbug *tr_rbug, struct rbug_header *header, uint32_t serial)
419 {
420 struct rbug_proto_context_draw_unblock *unblock = (struct rbug_proto_context_draw_unblock *)header;
421
422 struct rbug_screen *rb_screen = tr_rbug->rb_screen;
423 struct rbug_context *rb_context = NULL;
424
425 pipe_mutex_lock(rb_screen->list_mutex);
426 rb_context = rbug_get_context_locked(rb_screen, unblock->context);
427
428 if (!rb_context) {
429 pipe_mutex_unlock(rb_screen->list_mutex);
430 return -ESRCH;
431 }
432
433 pipe_mutex_lock(rb_context->draw_mutex);
434 if (rb_context->draw_blocked & RBUG_BLOCK_RULE) {
435 if (unblock->unblock & RBUG_BLOCK_RULE)
436 rb_context->draw_blocked &= ~RBUG_BLOCK_MASK;
437 } else {
438 rb_context->draw_blocked &= ~unblock->unblock;
439 }
440 rb_context->draw_blocker &= ~unblock->unblock;
441 pipe_mutex_unlock(rb_context->draw_mutex);
442
443 pipe_condvar_broadcast(rb_context->draw_cond);
444
445 pipe_mutex_unlock(rb_screen->list_mutex);
446
447 return 0;
448 }
449
450 static int
451 rbug_context_draw_rule(struct rbug_rbug *tr_rbug, struct rbug_header *header, uint32_t serial)
452 {
453 struct rbug_proto_context_draw_rule *rule = (struct rbug_proto_context_draw_rule *)header;
454
455 struct rbug_screen *rb_screen = tr_rbug->rb_screen;
456 struct rbug_context *rb_context = NULL;
457
458 pipe_mutex_lock(rb_screen->list_mutex);
459 rb_context = rbug_get_context_locked(rb_screen, rule->context);
460
461 if (!rb_context) {
462 pipe_mutex_unlock(rb_screen->list_mutex);
463 return -ESRCH;
464 }
465
466 pipe_mutex_lock(rb_context->draw_mutex);
467 rb_context->draw_rule.vs = U642VOID(rule->vertex);
468 rb_context->draw_rule.fs = U642VOID(rule->fragment);
469 rb_context->draw_rule.texture = U642VOID(rule->texture);
470 rb_context->draw_rule.surf = U642VOID(rule->surface);
471 rb_context->draw_rule.blocker = rule->block;
472 rb_context->draw_blocker |= RBUG_BLOCK_RULE;
473 pipe_mutex_unlock(rb_context->draw_mutex);
474
475 pipe_condvar_broadcast(rb_context->draw_cond);
476
477 pipe_mutex_unlock(rb_screen->list_mutex);
478
479 return 0;
480 }
481
482 static int
483 rbug_context_flush(struct rbug_rbug *tr_rbug, struct rbug_header *header, uint32_t serial)
484 {
485 struct rbug_proto_context_flush *flush = (struct rbug_proto_context_flush *)header;
486
487 struct rbug_screen *rb_screen = tr_rbug->rb_screen;
488 struct rbug_context *rb_context = NULL;
489
490 pipe_mutex_lock(rb_screen->list_mutex);
491 rb_context = rbug_get_context_locked(rb_screen, flush->context);
492
493 if (!rb_context) {
494 pipe_mutex_unlock(rb_screen->list_mutex);
495 return -ESRCH;
496 }
497
498 /* protect the pipe context */
499 pipe_mutex_lock(rb_context->call_mutex);
500
501 rb_context->pipe->flush(rb_context->pipe, flush->flags, NULL);
502
503 pipe_mutex_unlock(rb_context->call_mutex);
504 pipe_mutex_unlock(rb_screen->list_mutex);
505
506 return 0;
507 }
508
509 static int
510 rbug_shader_list(struct rbug_rbug *tr_rbug, struct rbug_header *header, uint32_t serial)
511 {
512 struct rbug_proto_shader_list *list = (struct rbug_proto_shader_list *)header;
513
514 struct rbug_screen *rb_screen = tr_rbug->rb_screen;
515 struct rbug_context *rb_context = NULL;
516 struct rbug_shader *tr_shdr = NULL;
517 struct rbug_list *ptr;
518 rbug_shader_t *shdrs;
519 int i = 0;
520
521 pipe_mutex_lock(rb_screen->list_mutex);
522 rb_context = rbug_get_context_locked(rb_screen, list->context);
523
524 if (!rb_context) {
525 pipe_mutex_unlock(rb_screen->list_mutex);
526 return -ESRCH;
527 }
528
529 pipe_mutex_lock(rb_context->list_mutex);
530 shdrs = MALLOC(rb_context->num_shaders * sizeof(rbug_shader_t));
531 foreach(ptr, &rb_context->shaders) {
532 tr_shdr = container_of(ptr, struct rbug_shader, list);
533 shdrs[i++] = VOID2U64(tr_shdr);
534 }
535
536 pipe_mutex_unlock(rb_context->list_mutex);
537 pipe_mutex_unlock(rb_screen->list_mutex);
538
539 rbug_send_shader_list_reply(tr_rbug->con, serial, shdrs, i, NULL);
540 FREE(shdrs);
541
542 return 0;
543 }
544
545 static int
546 rbug_shader_info(struct rbug_rbug *tr_rbug, struct rbug_header *header, uint32_t serial)
547 {
548 struct rbug_proto_shader_info *info = (struct rbug_proto_shader_info *)header;
549
550 struct rbug_screen *rb_screen = tr_rbug->rb_screen;
551 struct rbug_context *rb_context = NULL;
552 struct rbug_shader *tr_shdr = NULL;
553 unsigned original_len;
554 unsigned replaced_len;
555
556 pipe_mutex_lock(rb_screen->list_mutex);
557 rb_context = rbug_get_context_locked(rb_screen, info->context);
558
559 if (!rb_context) {
560 pipe_mutex_unlock(rb_screen->list_mutex);
561 return -ESRCH;
562 }
563
564 pipe_mutex_lock(rb_context->list_mutex);
565
566 tr_shdr = rbug_get_shader_locked(rb_context, info->shader);
567
568 if (!tr_shdr) {
569 pipe_mutex_unlock(rb_context->list_mutex);
570 pipe_mutex_unlock(rb_screen->list_mutex);
571 return -ESRCH;
572 }
573
574 /* just in case */
575 assert(sizeof(struct tgsi_token) == 4);
576
577 original_len = tgsi_num_tokens(tr_shdr->tokens);
578 if (tr_shdr->replaced_tokens)
579 replaced_len = tgsi_num_tokens(tr_shdr->replaced_tokens);
580 else
581 replaced_len = 0;
582
583 rbug_send_shader_info_reply(tr_rbug->con, serial,
584 (uint32_t*)tr_shdr->tokens, original_len,
585 (uint32_t*)tr_shdr->replaced_tokens, replaced_len,
586 tr_shdr->disabled,
587 NULL);
588
589 pipe_mutex_unlock(rb_context->list_mutex);
590 pipe_mutex_unlock(rb_screen->list_mutex);
591
592 return 0;
593 }
594
595 static int
596 rbug_shader_disable(struct rbug_rbug *tr_rbug, struct rbug_header *header)
597 {
598 struct rbug_proto_shader_disable *dis = (struct rbug_proto_shader_disable *)header;
599
600 struct rbug_screen *rb_screen = tr_rbug->rb_screen;
601 struct rbug_context *rb_context = NULL;
602 struct rbug_shader *tr_shdr = NULL;
603
604 pipe_mutex_lock(rb_screen->list_mutex);
605 rb_context = rbug_get_context_locked(rb_screen, dis->context);
606
607 if (!rb_context) {
608 pipe_mutex_unlock(rb_screen->list_mutex);
609 return -ESRCH;
610 }
611
612 pipe_mutex_lock(rb_context->list_mutex);
613
614 tr_shdr = rbug_get_shader_locked(rb_context, dis->shader);
615
616 if (!tr_shdr) {
617 pipe_mutex_unlock(rb_context->list_mutex);
618 pipe_mutex_unlock(rb_screen->list_mutex);
619 return -ESRCH;
620 }
621
622 tr_shdr->disabled = dis->disable;
623
624 pipe_mutex_unlock(rb_context->list_mutex);
625 pipe_mutex_unlock(rb_screen->list_mutex);
626
627 return 0;
628 }
629
630 static int
631 rbug_shader_replace(struct rbug_rbug *tr_rbug, struct rbug_header *header)
632 {
633 struct rbug_proto_shader_replace *rep = (struct rbug_proto_shader_replace *)header;
634
635 struct rbug_screen *rb_screen = tr_rbug->rb_screen;
636 struct rbug_context *rb_context = NULL;
637 struct rbug_shader *tr_shdr = NULL;
638 struct pipe_context *pipe = NULL;
639 void *state;
640
641 pipe_mutex_lock(rb_screen->list_mutex);
642 rb_context = rbug_get_context_locked(rb_screen, rep->context);
643
644 if (!rb_context) {
645 pipe_mutex_unlock(rb_screen->list_mutex);
646 return -ESRCH;
647 }
648
649 pipe_mutex_lock(rb_context->list_mutex);
650
651 tr_shdr = rbug_get_shader_locked(rb_context, rep->shader);
652
653 if (!tr_shdr) {
654 pipe_mutex_unlock(rb_context->list_mutex);
655 pipe_mutex_unlock(rb_screen->list_mutex);
656 return -ESRCH;
657 }
658
659 /* protect the pipe context */
660 pipe_mutex_lock(rb_context->call_mutex);
661
662 pipe = rb_context->pipe;
663
664 /* remove old replaced shader */
665 if (tr_shdr->replaced_shader) {
666 /* if this shader is bound rebind the original shader */
667 if (rb_context->curr.fs == tr_shdr || rb_context->curr.vs == tr_shdr)
668 rbug_shader_bind_locked(pipe, tr_shdr, tr_shdr->shader);
669
670 FREE(tr_shdr->replaced_tokens);
671 rbug_shader_delete_locked(pipe, tr_shdr, tr_shdr->replaced_shader);
672 tr_shdr->replaced_shader = NULL;
673 tr_shdr->replaced_tokens = NULL;
674 }
675
676 /* empty inputs means restore old which we did above */
677 if (rep->tokens_len == 0)
678 goto out;
679
680 tr_shdr->replaced_tokens = tgsi_dup_tokens((struct tgsi_token *)rep->tokens);
681 if (!tr_shdr->replaced_tokens)
682 goto err;
683
684 state = rbug_shader_create_locked(pipe, tr_shdr, tr_shdr->replaced_tokens);
685 if (!state)
686 goto err;
687
688 /* bind new shader if the shader is currently a bound */
689 if (rb_context->curr.fs == tr_shdr || rb_context->curr.vs == tr_shdr)
690 rbug_shader_bind_locked(pipe, tr_shdr, state);
691
692 /* save state */
693 tr_shdr->replaced_shader = state;
694
695 out:
696 pipe_mutex_unlock(rb_context->call_mutex);
697 pipe_mutex_unlock(rb_context->list_mutex);
698 pipe_mutex_unlock(rb_screen->list_mutex);
699
700 return 0;
701
702 err:
703 FREE(tr_shdr->replaced_tokens);
704 tr_shdr->replaced_shader = NULL;
705 tr_shdr->replaced_tokens = NULL;
706
707 pipe_mutex_unlock(rb_context->call_mutex);
708 pipe_mutex_unlock(rb_context->list_mutex);
709 pipe_mutex_unlock(rb_screen->list_mutex);
710 return -EINVAL;
711 }
712
713 static boolean
714 rbug_header(struct rbug_rbug *tr_rbug, struct rbug_header *header, uint32_t serial)
715 {
716 int ret = 0;
717
718 switch(header->opcode) {
719 case RBUG_OP_PING:
720 rbug_send_ping_reply(tr_rbug->con, serial, NULL);
721 break;
722 case RBUG_OP_TEXTURE_LIST:
723 ret = rbug_texture_list(tr_rbug, header, serial);
724 break;
725 case RBUG_OP_TEXTURE_INFO:
726 ret = rbug_texture_info(tr_rbug, header, serial);
727 break;
728 case RBUG_OP_TEXTURE_READ:
729 ret = rbug_texture_read(tr_rbug, header, serial);
730 break;
731 case RBUG_OP_CONTEXT_LIST:
732 ret = rbug_context_list(tr_rbug, header, serial);
733 break;
734 case RBUG_OP_CONTEXT_INFO:
735 ret = rbug_context_info(tr_rbug, header, serial);
736 break;
737 case RBUG_OP_CONTEXT_DRAW_BLOCK:
738 ret = rbug_context_draw_block(tr_rbug, header, serial);
739 break;
740 case RBUG_OP_CONTEXT_DRAW_STEP:
741 ret = rbug_context_draw_step(tr_rbug, header, serial);
742 break;
743 case RBUG_OP_CONTEXT_DRAW_UNBLOCK:
744 ret = rbug_context_draw_unblock(tr_rbug, header, serial);
745 break;
746 case RBUG_OP_CONTEXT_DRAW_RULE:
747 ret = rbug_context_draw_rule(tr_rbug, header, serial);
748 break;
749 case RBUG_OP_CONTEXT_FLUSH:
750 ret = rbug_context_flush(tr_rbug, header, serial);
751 break;
752 case RBUG_OP_SHADER_LIST:
753 ret = rbug_shader_list(tr_rbug, header, serial);
754 break;
755 case RBUG_OP_SHADER_INFO:
756 ret = rbug_shader_info(tr_rbug, header, serial);
757 break;
758 case RBUG_OP_SHADER_DISABLE:
759 ret = rbug_shader_disable(tr_rbug, header);
760 break;
761 case RBUG_OP_SHADER_REPLACE:
762 ret = rbug_shader_replace(tr_rbug, header);
763 break;
764 default:
765 debug_printf("%s - unsupported opcode %u\n", __FUNCTION__, header->opcode);
766 ret = -ENOSYS;
767 break;
768 }
769 rbug_free_header(header);
770
771 if (ret)
772 rbug_send_error_reply(tr_rbug->con, serial, ret, NULL);
773
774 return TRUE;
775 }
776
777 static void
778 rbug_con(struct rbug_rbug *tr_rbug)
779 {
780 struct rbug_header *header;
781 uint32_t serial;
782
783 debug_printf("%s - connection received\n", __FUNCTION__);
784
785 while(tr_rbug->running) {
786 header = rbug_get_message(tr_rbug->con, &serial);
787 if (!header)
788 break;
789
790 if (!rbug_header(tr_rbug, header, serial))
791 break;
792 }
793
794 debug_printf("%s - connection closed\n", __FUNCTION__);
795
796 rbug_disconnect(tr_rbug->con);
797 tr_rbug->con = NULL;
798 }
799
800 PIPE_THREAD_ROUTINE(rbug_thread, void_tr_rbug)
801 {
802 struct rbug_rbug *tr_rbug = void_tr_rbug;
803 uint16_t port = 13370;
804 int s = -1;
805 int c;
806
807 u_socket_init();
808
809 for (;port <= 13379 && s < 0; port++)
810 s = u_socket_listen_on_port(port);
811
812 if (s < 0) {
813 debug_printf("rbug_rbug - failed to listen\n");
814 return NULL;
815 }
816
817 u_socket_block(s, false);
818
819 debug_printf("rbug_rbug - remote debugging listening on port %u\n", --port);
820
821 while(tr_rbug->running) {
822 os_time_sleep(1);
823
824 c = u_socket_accept(s);
825 if (c < 0)
826 continue;
827
828 u_socket_block(c, true);
829 tr_rbug->con = rbug_from_socket(c);
830
831 rbug_con(tr_rbug);
832
833 u_socket_close(c);
834 }
835
836 u_socket_close(s);
837
838 u_socket_stop();
839
840 return NULL;
841 }
842
843 /**********************************************************
844 *
845 */
846
847 struct rbug_rbug *
848 rbug_start(struct rbug_screen *rb_screen)
849 {
850 struct rbug_rbug *tr_rbug = CALLOC_STRUCT(rbug_rbug);
851 if (!tr_rbug)
852 return NULL;
853
854 tr_rbug->rb_screen = rb_screen;
855 tr_rbug->running = TRUE;
856 tr_rbug->thread = pipe_thread_create(rbug_thread, tr_rbug);
857
858 return tr_rbug;
859 }
860
861 void
862 rbug_stop(struct rbug_rbug *tr_rbug)
863 {
864 if (!tr_rbug)
865 return;
866
867 tr_rbug->running = false;
868 pipe_thread_wait(tr_rbug->thread);
869
870 FREE(tr_rbug);
871
872 return;
873 }
874
875 void
876 rbug_notify_draw_blocked(struct rbug_context *rb_context)
877 {
878 struct rbug_screen *rb_screen = rbug_screen(rb_context->base.screen);
879 struct rbug_rbug *tr_rbug = rb_screen->rbug;
880
881 if (tr_rbug && tr_rbug->con)
882 rbug_send_context_draw_blocked(tr_rbug->con,
883 VOID2U64(rb_context), rb_context->draw_blocked, NULL);
884 }