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