1 /**************************************************************************
3 * Copyright 2010 VMware, Inc.
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:
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
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.
26 **************************************************************************/
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"
38 #include "tgsi/tgsi_parse.h"
40 #include "rbug_context.h"
41 #include "rbug_objects.h"
43 #include "rbug/rbug.h"
47 #define U642VOID(x) ((void *)(unsigned long)(x))
48 #define VOID2U64(x) ((uint64_t)(unsigned long)(x))
50 #define container_of(ptr, type, field) \
51 (type*)((char*)ptr - offsetof(type, field))
55 struct rbug_screen
*rb_screen
;
56 struct rbug_connection
*con
;
61 PIPE_THREAD_ROUTINE(rbug_thread
, void_rbug
);
64 /**********************************************************
69 static struct rbug_context
*
70 rbug_get_context_locked(struct rbug_screen
*rb_screen
, rbug_context_t ctx
)
72 struct rbug_context
*rb_context
= NULL
;
73 struct rbug_list
*ptr
;
75 foreach(ptr
, &rb_screen
->contexts
) {
76 rb_context
= container_of(ptr
, struct rbug_context
, list
);
77 if (ctx
== VOID2U64(rb_context
))
85 static struct rbug_shader
*
86 rbug_get_shader_locked(struct rbug_context
*rb_context
, rbug_shader_t shdr
)
88 struct rbug_shader
*tr_shdr
= NULL
;
89 struct rbug_list
*ptr
;
91 foreach(ptr
, &rb_context
->shaders
) {
92 tr_shdr
= container_of(ptr
, struct rbug_shader
, list
);
93 if (shdr
== VOID2U64(tr_shdr
))
102 rbug_shader_create_locked(struct pipe_context
*pipe
,
103 struct rbug_shader
*rb_shader
,
104 struct tgsi_token
*tokens
)
107 struct pipe_shader_state pss
;
108 memset(&pss
, 0, sizeof(pss
));
111 switch(rb_shader
->type
) {
112 case RBUG_SHADER_FRAGMENT
:
113 state
= pipe
->create_fs_state(pipe
, &pss
);
115 case RBUG_SHADER_VERTEX
:
116 state
= pipe
->create_vs_state(pipe
, &pss
);
118 case RBUG_SHADER_GEOM
:
119 state
= pipe
->create_gs_state(pipe
, &pss
);
130 rbug_shader_bind_locked(struct pipe_context
*pipe
,
131 struct rbug_shader
*rb_shader
,
134 switch(rb_shader
->type
) {
135 case RBUG_SHADER_FRAGMENT
:
136 pipe
->bind_fs_state(pipe
, state
);
138 case RBUG_SHADER_VERTEX
:
139 pipe
->bind_vs_state(pipe
, state
);
141 case RBUG_SHADER_GEOM
:
142 pipe
->bind_gs_state(pipe
, state
);
151 rbug_shader_delete_locked(struct pipe_context
*pipe
,
152 struct rbug_shader
*rb_shader
,
155 switch(rb_shader
->type
) {
156 case RBUG_SHADER_FRAGMENT
:
157 pipe
->delete_fs_state(pipe
, state
);
159 case RBUG_SHADER_VERTEX
:
160 pipe
->delete_vs_state(pipe
, state
);
162 case RBUG_SHADER_GEOM
:
163 pipe
->delete_gs_state(pipe
, state
);
171 /************************************************
172 * Request handler functions
177 rbug_texture_list(struct rbug_rbug
*tr_rbug
, struct rbug_header
*header
, uint32_t serial
)
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
;
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
);
191 pipe_mutex_unlock(rb_screen
->list_mutex
);
193 rbug_send_texture_list_reply(tr_rbug
->con
, serial
, texs
, i
, NULL
);
200 rbug_texture_info(struct rbug_rbug
*tr_rbug
, struct rbug_header
*header
, uint32_t serial
)
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
;
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
))
217 pipe_mutex_unlock(rb_screen
->list_mutex
);
221 t
= tr_tex
->resource
;
222 rbug_send_texture_info_reply(tr_rbug
->con
, serial
,
223 t
->target
, t
->format
,
227 util_format_get_blockwidth(t
->format
),
228 util_format_get_blockheight(t
->format
),
229 util_format_get_blocksize(t
->format
),
235 pipe_mutex_unlock(rb_screen
->list_mutex
);
241 rbug_texture_read(struct rbug_rbug
*tr_rbug
, struct rbug_header
*header
, uint32_t serial
)
243 struct rbug_proto_texture_read
*gptr
= (struct rbug_proto_texture_read
*)header
;
245 struct rbug_screen
*rb_screen
= tr_rbug
->rb_screen
;
246 struct rbug_resource
*tr_tex
= NULL
;
247 struct rbug_list
*ptr
;
249 struct pipe_context
*context
= rb_screen
->private_context
;
250 struct pipe_resource
*tex
;
251 struct pipe_transfer
*t
;
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
))
264 pipe_mutex_unlock(rb_screen
->list_mutex
);
268 tex
= tr_tex
->resource
;
269 map
= pipe_transfer_map(context
, tex
,
270 gptr
->level
, gptr
->face
+ gptr
->zslice
,
272 gptr
->x
, gptr
->y
, gptr
->w
, gptr
->h
, &t
);
274 rbug_send_texture_read_reply(tr_rbug
->con
, serial
,
276 util_format_get_blockwidth(t
->resource
->format
),
277 util_format_get_blockheight(t
->resource
->format
),
278 util_format_get_blocksize(t
->resource
->format
),
280 t
->stride
* util_format_get_nblocksy(t
->resource
->format
,
285 context
->transfer_unmap(context
, t
);
287 pipe_mutex_unlock(rb_screen
->list_mutex
);
293 rbug_context_list(struct rbug_rbug
*tr_rbug
, struct rbug_header
*header
, uint32_t serial
)
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
;
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
);
307 pipe_mutex_unlock(rb_screen
->list_mutex
);
309 rbug_send_context_list_reply(tr_rbug
->con
, serial
, ctxs
, i
, NULL
);
316 rbug_context_info(struct rbug_rbug
*tr_rbug
, struct rbug_header
*header
, uint32_t serial
)
318 struct rbug_proto_context_info
*info
= (struct rbug_proto_context_info
*)header
;
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
];
326 pipe_mutex_lock(rb_screen
->list_mutex
);
327 rb_context
= rbug_get_context_locked(rb_screen
, info
->context
);
330 pipe_mutex_unlock(rb_screen
->list_mutex
);
334 /* protect the pipe context */
335 pipe_mutex_lock(rb_context
->draw_mutex
);
336 pipe_mutex_lock(rb_context
->call_mutex
);
338 for (i
= 0; i
< rb_context
->curr
.nr_cbufs
; i
++)
339 cbufs
[i
] = VOID2U64(rb_context
->curr
.cbufs
[i
]);
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
]);
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
);
352 pipe_mutex_unlock(rb_context
->call_mutex
);
353 pipe_mutex_unlock(rb_context
->draw_mutex
);
354 pipe_mutex_unlock(rb_screen
->list_mutex
);
360 rbug_context_draw_block(struct rbug_rbug
*tr_rbug
, struct rbug_header
*header
, uint32_t serial
)
362 struct rbug_proto_context_draw_block
*block
= (struct rbug_proto_context_draw_block
*)header
;
364 struct rbug_screen
*rb_screen
= tr_rbug
->rb_screen
;
365 struct rbug_context
*rb_context
= NULL
;
367 pipe_mutex_lock(rb_screen
->list_mutex
);
368 rb_context
= rbug_get_context_locked(rb_screen
, block
->context
);
371 pipe_mutex_unlock(rb_screen
->list_mutex
);
375 pipe_mutex_lock(rb_context
->draw_mutex
);
376 rb_context
->draw_blocker
|= block
->block
;
377 pipe_mutex_unlock(rb_context
->draw_mutex
);
379 pipe_mutex_unlock(rb_screen
->list_mutex
);
385 rbug_context_draw_step(struct rbug_rbug
*tr_rbug
, struct rbug_header
*header
, uint32_t serial
)
387 struct rbug_proto_context_draw_step
*step
= (struct rbug_proto_context_draw_step
*)header
;
389 struct rbug_screen
*rb_screen
= tr_rbug
->rb_screen
;
390 struct rbug_context
*rb_context
= NULL
;
392 pipe_mutex_lock(rb_screen
->list_mutex
);
393 rb_context
= rbug_get_context_locked(rb_screen
, step
->context
);
396 pipe_mutex_unlock(rb_screen
->list_mutex
);
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
;
405 rb_context
->draw_blocked
&= ~step
->step
;
407 pipe_mutex_unlock(rb_context
->draw_mutex
);
409 pipe_condvar_broadcast(rb_context
->draw_cond
);
411 pipe_mutex_unlock(rb_screen
->list_mutex
);
417 rbug_context_draw_unblock(struct rbug_rbug
*tr_rbug
, struct rbug_header
*header
, uint32_t serial
)
419 struct rbug_proto_context_draw_unblock
*unblock
= (struct rbug_proto_context_draw_unblock
*)header
;
421 struct rbug_screen
*rb_screen
= tr_rbug
->rb_screen
;
422 struct rbug_context
*rb_context
= NULL
;
424 pipe_mutex_lock(rb_screen
->list_mutex
);
425 rb_context
= rbug_get_context_locked(rb_screen
, unblock
->context
);
428 pipe_mutex_unlock(rb_screen
->list_mutex
);
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
;
437 rb_context
->draw_blocked
&= ~unblock
->unblock
;
439 rb_context
->draw_blocker
&= ~unblock
->unblock
;
440 pipe_mutex_unlock(rb_context
->draw_mutex
);
442 pipe_condvar_broadcast(rb_context
->draw_cond
);
444 pipe_mutex_unlock(rb_screen
->list_mutex
);
450 rbug_context_draw_rule(struct rbug_rbug
*tr_rbug
, struct rbug_header
*header
, uint32_t serial
)
452 struct rbug_proto_context_draw_rule
*rule
= (struct rbug_proto_context_draw_rule
*)header
;
454 struct rbug_screen
*rb_screen
= tr_rbug
->rb_screen
;
455 struct rbug_context
*rb_context
= NULL
;
457 pipe_mutex_lock(rb_screen
->list_mutex
);
458 rb_context
= rbug_get_context_locked(rb_screen
, rule
->context
);
461 pipe_mutex_unlock(rb_screen
->list_mutex
);
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
);
474 pipe_condvar_broadcast(rb_context
->draw_cond
);
476 pipe_mutex_unlock(rb_screen
->list_mutex
);
482 rbug_context_flush(struct rbug_rbug
*tr_rbug
, struct rbug_header
*header
, uint32_t serial
)
484 struct rbug_proto_context_flush
*flush
= (struct rbug_proto_context_flush
*)header
;
486 struct rbug_screen
*rb_screen
= tr_rbug
->rb_screen
;
487 struct rbug_context
*rb_context
= NULL
;
489 pipe_mutex_lock(rb_screen
->list_mutex
);
490 rb_context
= rbug_get_context_locked(rb_screen
, flush
->context
);
493 pipe_mutex_unlock(rb_screen
->list_mutex
);
497 /* protect the pipe context */
498 pipe_mutex_lock(rb_context
->call_mutex
);
500 rb_context
->pipe
->flush(rb_context
->pipe
, NULL
, 0);
502 pipe_mutex_unlock(rb_context
->call_mutex
);
503 pipe_mutex_unlock(rb_screen
->list_mutex
);
509 rbug_shader_list(struct rbug_rbug
*tr_rbug
, struct rbug_header
*header
, uint32_t serial
)
511 struct rbug_proto_shader_list
*list
= (struct rbug_proto_shader_list
*)header
;
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
;
520 pipe_mutex_lock(rb_screen
->list_mutex
);
521 rb_context
= rbug_get_context_locked(rb_screen
, list
->context
);
524 pipe_mutex_unlock(rb_screen
->list_mutex
);
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
);
535 pipe_mutex_unlock(rb_context
->list_mutex
);
536 pipe_mutex_unlock(rb_screen
->list_mutex
);
538 rbug_send_shader_list_reply(tr_rbug
->con
, serial
, shdrs
, i
, NULL
);
545 rbug_shader_info(struct rbug_rbug
*tr_rbug
, struct rbug_header
*header
, uint32_t serial
)
547 struct rbug_proto_shader_info
*info
= (struct rbug_proto_shader_info
*)header
;
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
;
555 pipe_mutex_lock(rb_screen
->list_mutex
);
556 rb_context
= rbug_get_context_locked(rb_screen
, info
->context
);
559 pipe_mutex_unlock(rb_screen
->list_mutex
);
563 pipe_mutex_lock(rb_context
->list_mutex
);
565 tr_shdr
= rbug_get_shader_locked(rb_context
, info
->shader
);
568 pipe_mutex_unlock(rb_context
->list_mutex
);
569 pipe_mutex_unlock(rb_screen
->list_mutex
);
574 assert(sizeof(struct tgsi_token
) == 4);
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
);
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
,
588 pipe_mutex_unlock(rb_context
->list_mutex
);
589 pipe_mutex_unlock(rb_screen
->list_mutex
);
595 rbug_shader_disable(struct rbug_rbug
*tr_rbug
, struct rbug_header
*header
)
597 struct rbug_proto_shader_disable
*dis
= (struct rbug_proto_shader_disable
*)header
;
599 struct rbug_screen
*rb_screen
= tr_rbug
->rb_screen
;
600 struct rbug_context
*rb_context
= NULL
;
601 struct rbug_shader
*tr_shdr
= NULL
;
603 pipe_mutex_lock(rb_screen
->list_mutex
);
604 rb_context
= rbug_get_context_locked(rb_screen
, dis
->context
);
607 pipe_mutex_unlock(rb_screen
->list_mutex
);
611 pipe_mutex_lock(rb_context
->list_mutex
);
613 tr_shdr
= rbug_get_shader_locked(rb_context
, dis
->shader
);
616 pipe_mutex_unlock(rb_context
->list_mutex
);
617 pipe_mutex_unlock(rb_screen
->list_mutex
);
621 tr_shdr
->disabled
= dis
->disable
;
623 pipe_mutex_unlock(rb_context
->list_mutex
);
624 pipe_mutex_unlock(rb_screen
->list_mutex
);
630 rbug_shader_replace(struct rbug_rbug
*tr_rbug
, struct rbug_header
*header
)
632 struct rbug_proto_shader_replace
*rep
= (struct rbug_proto_shader_replace
*)header
;
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
;
640 pipe_mutex_lock(rb_screen
->list_mutex
);
641 rb_context
= rbug_get_context_locked(rb_screen
, rep
->context
);
644 pipe_mutex_unlock(rb_screen
->list_mutex
);
648 pipe_mutex_lock(rb_context
->list_mutex
);
650 tr_shdr
= rbug_get_shader_locked(rb_context
, rep
->shader
);
653 pipe_mutex_unlock(rb_context
->list_mutex
);
654 pipe_mutex_unlock(rb_screen
->list_mutex
);
658 /* protect the pipe context */
659 pipe_mutex_lock(rb_context
->call_mutex
);
661 pipe
= rb_context
->pipe
;
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
);
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
;
675 /* empty inputs means restore old which we did above */
676 if (rep
->tokens_len
== 0)
679 tr_shdr
->replaced_tokens
= tgsi_dup_tokens((struct tgsi_token
*)rep
->tokens
);
680 if (!tr_shdr
->replaced_tokens
)
683 state
= rbug_shader_create_locked(pipe
, tr_shdr
, tr_shdr
->replaced_tokens
);
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
);
692 tr_shdr
->replaced_shader
= state
;
695 pipe_mutex_unlock(rb_context
->call_mutex
);
696 pipe_mutex_unlock(rb_context
->list_mutex
);
697 pipe_mutex_unlock(rb_screen
->list_mutex
);
702 FREE(tr_shdr
->replaced_tokens
);
703 tr_shdr
->replaced_shader
= NULL
;
704 tr_shdr
->replaced_tokens
= NULL
;
706 pipe_mutex_unlock(rb_context
->call_mutex
);
707 pipe_mutex_unlock(rb_context
->list_mutex
);
708 pipe_mutex_unlock(rb_screen
->list_mutex
);
713 rbug_header(struct rbug_rbug
*tr_rbug
, struct rbug_header
*header
, uint32_t serial
)
717 switch(header
->opcode
) {
719 rbug_send_ping_reply(tr_rbug
->con
, serial
, NULL
);
721 case RBUG_OP_TEXTURE_LIST
:
722 ret
= rbug_texture_list(tr_rbug
, header
, serial
);
724 case RBUG_OP_TEXTURE_INFO
:
725 ret
= rbug_texture_info(tr_rbug
, header
, serial
);
727 case RBUG_OP_TEXTURE_READ
:
728 ret
= rbug_texture_read(tr_rbug
, header
, serial
);
730 case RBUG_OP_CONTEXT_LIST
:
731 ret
= rbug_context_list(tr_rbug
, header
, serial
);
733 case RBUG_OP_CONTEXT_INFO
:
734 ret
= rbug_context_info(tr_rbug
, header
, serial
);
736 case RBUG_OP_CONTEXT_DRAW_BLOCK
:
737 ret
= rbug_context_draw_block(tr_rbug
, header
, serial
);
739 case RBUG_OP_CONTEXT_DRAW_STEP
:
740 ret
= rbug_context_draw_step(tr_rbug
, header
, serial
);
742 case RBUG_OP_CONTEXT_DRAW_UNBLOCK
:
743 ret
= rbug_context_draw_unblock(tr_rbug
, header
, serial
);
745 case RBUG_OP_CONTEXT_DRAW_RULE
:
746 ret
= rbug_context_draw_rule(tr_rbug
, header
, serial
);
748 case RBUG_OP_CONTEXT_FLUSH
:
749 ret
= rbug_context_flush(tr_rbug
, header
, serial
);
751 case RBUG_OP_SHADER_LIST
:
752 ret
= rbug_shader_list(tr_rbug
, header
, serial
);
754 case RBUG_OP_SHADER_INFO
:
755 ret
= rbug_shader_info(tr_rbug
, header
, serial
);
757 case RBUG_OP_SHADER_DISABLE
:
758 ret
= rbug_shader_disable(tr_rbug
, header
);
760 case RBUG_OP_SHADER_REPLACE
:
761 ret
= rbug_shader_replace(tr_rbug
, header
);
764 debug_printf("%s - unsupported opcode %u\n", __FUNCTION__
, header
->opcode
);
768 rbug_free_header(header
);
771 rbug_send_error_reply(tr_rbug
->con
, serial
, ret
, NULL
);
777 rbug_con(struct rbug_rbug
*tr_rbug
)
779 struct rbug_header
*header
;
782 debug_printf("%s - connection received\n", __FUNCTION__
);
784 while(tr_rbug
->running
) {
785 header
= rbug_get_message(tr_rbug
->con
, &serial
);
789 if (!rbug_header(tr_rbug
, header
, serial
))
793 debug_printf("%s - connection closed\n", __FUNCTION__
);
795 rbug_disconnect(tr_rbug
->con
);
799 PIPE_THREAD_ROUTINE(rbug_thread
, void_tr_rbug
)
801 struct rbug_rbug
*tr_rbug
= void_tr_rbug
;
802 uint16_t port
= 13370;
808 for (;port
<= 13379 && s
< 0; port
++)
809 s
= u_socket_listen_on_port(port
);
812 debug_printf("rbug_rbug - failed to listen\n");
816 u_socket_block(s
, false);
818 debug_printf("rbug_rbug - remote debugging listening on port %u\n", --port
);
820 while(tr_rbug
->running
) {
823 c
= u_socket_accept(s
);
827 u_socket_block(c
, true);
828 tr_rbug
->con
= rbug_from_socket(c
);
842 /**********************************************************
847 rbug_start(struct rbug_screen
*rb_screen
)
849 struct rbug_rbug
*tr_rbug
= CALLOC_STRUCT(rbug_rbug
);
853 tr_rbug
->rb_screen
= rb_screen
;
854 tr_rbug
->running
= TRUE
;
855 tr_rbug
->thread
= pipe_thread_create(rbug_thread
, tr_rbug
);
861 rbug_stop(struct rbug_rbug
*tr_rbug
)
866 tr_rbug
->running
= false;
867 pipe_thread_wait(tr_rbug
->thread
);
875 rbug_notify_draw_blocked(struct rbug_context
*rb_context
)
877 struct rbug_screen
*rb_screen
= rbug_screen(rb_context
->base
.screen
);
878 struct rbug_rbug
*tr_rbug
= rb_screen
->rbug
;
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
);