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))
52 struct rbug_screen
*rb_screen
;
53 struct rbug_connection
*con
;
58 PIPE_THREAD_ROUTINE(rbug_thread
, void_rbug
);
61 /**********************************************************
66 static struct rbug_context
*
67 rbug_get_context_locked(struct rbug_screen
*rb_screen
, rbug_context_t ctx
)
69 struct rbug_context
*rb_context
= NULL
;
70 struct rbug_list
*ptr
;
72 foreach(ptr
, &rb_screen
->contexts
) {
73 rb_context
= (struct rbug_context
*)((char*)ptr
- offsetof(struct rbug_context
, list
));
74 if (ctx
== VOID2U64(rb_context
))
82 static struct rbug_shader
*
83 rbug_get_shader_locked(struct rbug_context
*rb_context
, rbug_shader_t shdr
)
85 struct rbug_shader
*tr_shdr
= NULL
;
86 struct rbug_list
*ptr
;
88 foreach(ptr
, &rb_context
->shaders
) {
89 tr_shdr
= (struct rbug_shader
*)((char*)ptr
- offsetof(struct rbug_shader
, list
));
90 if (shdr
== VOID2U64(tr_shdr
))
99 rbug_shader_create_locked(struct pipe_context
*pipe
,
100 struct rbug_shader
*tr_shdr
,
101 struct tgsi_token
*tokens
)
104 struct pipe_shader_state pss
= { 0 };
108 if (tr_shdr
->type
== TRACE_SHADER_FRAGMENT
) {
109 state
= pipe
->create_fs_state(pipe
, &pss
);
110 } else if (tr_shdr
->type
== TRACE_SHADER_VERTEX
) {
111 state
= pipe
->create_vs_state(pipe
, &pss
);
120 rbug_shader_bind_locked(struct pipe_context
*pipe
,
121 struct rbug_shader
*tr_shdr
,
125 if (tr_shdr
->type
== TRACE_SHADER_FRAGMENT
) {
126 pipe
->bind_fs_state(pipe
, state
);
127 } else if (tr_shdr
->type
== TRACE_SHADER_VERTEX
) {
128 pipe
->bind_vs_state(pipe
, state
);
135 rbug_shader_delete_locked(struct pipe_context
*pipe
,
136 struct rbug_shader
*tr_shdr
,
140 if (tr_shdr
->type
== TRACE_SHADER_FRAGMENT
) {
141 pipe
->delete_fs_state(pipe
, state
);
142 } else if (tr_shdr
->type
== TRACE_SHADER_VERTEX
) {
143 pipe
->delete_vs_state(pipe
, state
);
149 /************************************************
150 * Request handler functions
155 rbug_texture_list(struct rbug_rbug
*tr_rbug
, struct rbug_header
*header
, uint32_t serial
)
157 struct rbug_screen
*rb_screen
= tr_rbug
->rb_screen
;
158 struct rbug_resource
*tr_tex
= NULL
;
159 struct rbug_list
*ptr
;
160 rbug_texture_t
*texs
;
163 pipe_mutex_lock(rb_screen
->list_mutex
);
164 texs
= MALLOC(rb_screen
->num_resources
* sizeof(rbug_texture_t
));
165 foreach(ptr
, &rb_screen
->resources
) {
166 tr_tex
= (struct rbug_resource
*)((char*)ptr
- offsetof(struct rbug_resource
, list
));
167 texs
[i
++] = VOID2U64(tr_tex
);
169 pipe_mutex_unlock(rb_screen
->list_mutex
);
171 rbug_send_texture_list_reply(tr_rbug
->con
, serial
, texs
, i
, NULL
);
178 rbug_texture_info(struct rbug_rbug
*tr_rbug
, struct rbug_header
*header
, uint32_t serial
)
180 struct rbug_screen
*rb_screen
= tr_rbug
->rb_screen
;
181 struct rbug_resource
*tr_tex
= NULL
;
182 struct rbug_proto_texture_info
*gpti
= (struct rbug_proto_texture_info
*)header
;
183 struct rbug_list
*ptr
;
184 struct pipe_resource
*t
;
186 pipe_mutex_lock(rb_screen
->list_mutex
);
187 foreach(ptr
, &rb_screen
->resources
) {
188 tr_tex
= (struct rbug_resource
*)((char*)ptr
- offsetof(struct rbug_resource
, list
));
189 if (gpti
->texture
== VOID2U64(tr_tex
))
195 pipe_mutex_unlock(rb_screen
->list_mutex
);
199 t
= tr_tex
->resource
;
200 rbug_send_texture_info_reply(tr_rbug
->con
, serial
,
201 t
->target
, t
->format
,
205 util_format_get_blockwidth(t
->format
),
206 util_format_get_blockheight(t
->format
),
207 util_format_get_blocksize(t
->format
),
213 pipe_mutex_unlock(rb_screen
->list_mutex
);
219 rbug_texture_read(struct rbug_rbug
*tr_rbug
, struct rbug_header
*header
, uint32_t serial
)
221 struct rbug_proto_texture_read
*gptr
= (struct rbug_proto_texture_read
*)header
;
223 struct rbug_screen
*rb_screen
= tr_rbug
->rb_screen
;
224 struct rbug_resource
*tr_tex
= NULL
;
225 struct rbug_list
*ptr
;
227 struct pipe_context
*context
= rb_screen
->private_context
;
228 struct pipe_resource
*tex
;
229 struct pipe_transfer
*t
;
233 pipe_mutex_lock(rb_screen
->list_mutex
);
234 foreach(ptr
, &rb_screen
->resources
) {
235 tr_tex
= (struct rbug_resource
*)((char*)ptr
- offsetof(struct rbug_resource
, list
));
236 if (gptr
->texture
== VOID2U64(tr_tex
))
242 pipe_mutex_unlock(rb_screen
->list_mutex
);
246 tex
= tr_tex
->resource
;
247 t
= pipe_get_transfer(context
, tex
,
248 gptr
->face
, gptr
->level
, gptr
->zslice
,
250 gptr
->x
, gptr
->y
, gptr
->w
, gptr
->h
);
252 map
= context
->transfer_map(context
, t
);
254 rbug_send_texture_read_reply(tr_rbug
->con
, serial
,
256 util_format_get_blockwidth(t
->resource
->format
),
257 util_format_get_blockheight(t
->resource
->format
),
258 util_format_get_blocksize(t
->resource
->format
),
260 t
->stride
* util_format_get_nblocksy(t
->resource
->format
,
265 context
->transfer_unmap(context
, t
);
266 context
->transfer_destroy(context
, t
);
268 pipe_mutex_unlock(rb_screen
->list_mutex
);
274 rbug_context_list(struct rbug_rbug
*tr_rbug
, struct rbug_header
*header
, uint32_t serial
)
276 struct rbug_screen
*rb_screen
= tr_rbug
->rb_screen
;
277 struct rbug_list
*ptr
;
278 struct rbug_context
*rb_context
= NULL
;
279 rbug_context_t
*ctxs
;
282 pipe_mutex_lock(rb_screen
->list_mutex
);
283 ctxs
= MALLOC(rb_screen
->num_contexts
* sizeof(rbug_context_t
));
284 foreach(ptr
, &rb_screen
->contexts
) {
285 rb_context
= (struct rbug_context
*)((char*)ptr
- offsetof(struct rbug_context
, list
));
286 ctxs
[i
++] = VOID2U64(rb_context
);
288 pipe_mutex_unlock(rb_screen
->list_mutex
);
290 rbug_send_context_list_reply(tr_rbug
->con
, serial
, ctxs
, i
, NULL
);
297 rbug_context_info(struct rbug_rbug
*tr_rbug
, struct rbug_header
*header
, uint32_t serial
)
299 struct rbug_proto_context_info
*info
= (struct rbug_proto_context_info
*)header
;
301 struct rbug_screen
*rb_screen
= tr_rbug
->rb_screen
;
302 struct rbug_context
*rb_context
= NULL
;
303 rbug_texture_t cbufs
[PIPE_MAX_COLOR_BUFS
];
304 rbug_texture_t texs
[PIPE_MAX_SAMPLERS
];
307 pipe_mutex_lock(rb_screen
->list_mutex
);
308 rb_context
= rbug_get_context_locked(rb_screen
, info
->context
);
311 pipe_mutex_unlock(rb_screen
->list_mutex
);
315 /* protect the pipe context */
316 pipe_mutex_lock(rb_context
->draw_mutex
);
317 pipe_mutex_lock(rb_context
->call_mutex
);
319 for (i
= 0; i
< rb_context
->curr
.nr_cbufs
; i
++)
320 cbufs
[i
] = VOID2U64(rb_context
->curr
.cbufs
[i
]);
322 for (i
= 0; i
< rb_context
->curr
.num_sampler_views
; i
++)
323 texs
[i
] = VOID2U64(rb_context
->curr
.sampler_views
[i
]);
325 rbug_send_context_info_reply(tr_rbug
->con
, serial
,
326 VOID2U64(rb_context
->curr
.vs
), VOID2U64(rb_context
->curr
.fs
),
327 texs
, rb_context
->curr
.num_sampler_views
,
328 cbufs
, rb_context
->curr
.nr_cbufs
,
329 VOID2U64(rb_context
->curr
.zsbuf
),
330 rb_context
->draw_blocker
, rb_context
->draw_blocked
, NULL
);
332 pipe_mutex_unlock(rb_context
->call_mutex
);
333 pipe_mutex_unlock(rb_context
->draw_mutex
);
334 pipe_mutex_unlock(rb_screen
->list_mutex
);
340 rbug_context_draw_block(struct rbug_rbug
*tr_rbug
, struct rbug_header
*header
, uint32_t serial
)
342 struct rbug_proto_context_draw_block
*block
= (struct rbug_proto_context_draw_block
*)header
;
344 struct rbug_screen
*rb_screen
= tr_rbug
->rb_screen
;
345 struct rbug_context
*rb_context
= NULL
;
347 pipe_mutex_lock(rb_screen
->list_mutex
);
348 rb_context
= rbug_get_context_locked(rb_screen
, block
->context
);
351 pipe_mutex_unlock(rb_screen
->list_mutex
);
355 pipe_mutex_lock(rb_context
->draw_mutex
);
356 rb_context
->draw_blocker
|= block
->block
;
357 pipe_mutex_unlock(rb_context
->draw_mutex
);
359 pipe_mutex_unlock(rb_screen
->list_mutex
);
365 rbug_context_draw_step(struct rbug_rbug
*tr_rbug
, struct rbug_header
*header
, uint32_t serial
)
367 struct rbug_proto_context_draw_step
*step
= (struct rbug_proto_context_draw_step
*)header
;
369 struct rbug_screen
*rb_screen
= tr_rbug
->rb_screen
;
370 struct rbug_context
*rb_context
= NULL
;
372 pipe_mutex_lock(rb_screen
->list_mutex
);
373 rb_context
= rbug_get_context_locked(rb_screen
, step
->context
);
376 pipe_mutex_unlock(rb_screen
->list_mutex
);
380 pipe_mutex_lock(rb_context
->draw_mutex
);
381 if (rb_context
->draw_blocked
& RBUG_BLOCK_RULE
) {
382 if (step
->step
& RBUG_BLOCK_RULE
)
383 rb_context
->draw_blocked
&= ~RBUG_BLOCK_MASK
;
385 rb_context
->draw_blocked
&= ~step
->step
;
387 pipe_mutex_unlock(rb_context
->draw_mutex
);
389 #ifdef PIPE_THREAD_HAVE_CONDVAR
390 pipe_condvar_broadcast(rb_context
->draw_cond
);
393 pipe_mutex_unlock(rb_screen
->list_mutex
);
399 rbug_context_draw_unblock(struct rbug_rbug
*tr_rbug
, struct rbug_header
*header
, uint32_t serial
)
401 struct rbug_proto_context_draw_unblock
*unblock
= (struct rbug_proto_context_draw_unblock
*)header
;
403 struct rbug_screen
*rb_screen
= tr_rbug
->rb_screen
;
404 struct rbug_context
*rb_context
= NULL
;
406 pipe_mutex_lock(rb_screen
->list_mutex
);
407 rb_context
= rbug_get_context_locked(rb_screen
, unblock
->context
);
410 pipe_mutex_unlock(rb_screen
->list_mutex
);
414 pipe_mutex_lock(rb_context
->draw_mutex
);
415 if (rb_context
->draw_blocked
& RBUG_BLOCK_RULE
) {
416 if (unblock
->unblock
& RBUG_BLOCK_RULE
)
417 rb_context
->draw_blocked
&= ~RBUG_BLOCK_MASK
;
419 rb_context
->draw_blocked
&= ~unblock
->unblock
;
421 rb_context
->draw_blocker
&= ~unblock
->unblock
;
422 pipe_mutex_unlock(rb_context
->draw_mutex
);
424 #ifdef PIPE_THREAD_HAVE_CONDVAR
425 pipe_condvar_broadcast(rb_context
->draw_cond
);
428 pipe_mutex_unlock(rb_screen
->list_mutex
);
434 rbug_context_draw_rule(struct rbug_rbug
*tr_rbug
, struct rbug_header
*header
, uint32_t serial
)
436 struct rbug_proto_context_draw_rule
*rule
= (struct rbug_proto_context_draw_rule
*)header
;
438 struct rbug_screen
*rb_screen
= tr_rbug
->rb_screen
;
439 struct rbug_context
*rb_context
= NULL
;
441 pipe_mutex_lock(rb_screen
->list_mutex
);
442 rb_context
= rbug_get_context_locked(rb_screen
, rule
->context
);
445 pipe_mutex_unlock(rb_screen
->list_mutex
);
449 pipe_mutex_lock(rb_context
->draw_mutex
);
450 rb_context
->draw_rule
.vs
= U642VOID(rule
->vertex
);
451 rb_context
->draw_rule
.fs
= U642VOID(rule
->fragment
);
452 rb_context
->draw_rule
.sampler_view
= U642VOID(rule
->texture
);
453 rb_context
->draw_rule
.surf
= U642VOID(rule
->surface
);
454 rb_context
->draw_rule
.blocker
= rule
->block
;
455 rb_context
->draw_blocker
|= RBUG_BLOCK_RULE
;
456 pipe_mutex_unlock(rb_context
->draw_mutex
);
458 #ifdef PIPE_THREAD_HAVE_CONDVAR
459 pipe_condvar_broadcast(rb_context
->draw_cond
);
462 pipe_mutex_unlock(rb_screen
->list_mutex
);
468 rbug_context_flush(struct rbug_rbug
*tr_rbug
, struct rbug_header
*header
, uint32_t serial
)
470 struct rbug_proto_context_flush
*flush
= (struct rbug_proto_context_flush
*)header
;
472 struct rbug_screen
*rb_screen
= tr_rbug
->rb_screen
;
473 struct rbug_context
*rb_context
= NULL
;
475 pipe_mutex_lock(rb_screen
->list_mutex
);
476 rb_context
= rbug_get_context_locked(rb_screen
, flush
->context
);
479 pipe_mutex_unlock(rb_screen
->list_mutex
);
483 /* protect the pipe context */
484 pipe_mutex_lock(rb_context
->call_mutex
);
486 rb_context
->pipe
->flush(rb_context
->pipe
, flush
->flags
, NULL
);
488 pipe_mutex_unlock(rb_context
->call_mutex
);
489 pipe_mutex_unlock(rb_screen
->list_mutex
);
495 rbug_shader_list(struct rbug_rbug
*tr_rbug
, struct rbug_header
*header
, uint32_t serial
)
497 struct rbug_proto_shader_list
*list
= (struct rbug_proto_shader_list
*)header
;
499 struct rbug_screen
*rb_screen
= tr_rbug
->rb_screen
;
500 struct rbug_context
*rb_context
= NULL
;
501 struct rbug_shader
*tr_shdr
= NULL
;
502 struct rbug_list
*ptr
;
503 rbug_shader_t
*shdrs
;
506 pipe_mutex_lock(rb_screen
->list_mutex
);
507 rb_context
= rbug_get_context_locked(rb_screen
, list
->context
);
510 pipe_mutex_unlock(rb_screen
->list_mutex
);
514 pipe_mutex_lock(rb_context
->list_mutex
);
515 shdrs
= MALLOC(rb_context
->num_shaders
* sizeof(rbug_shader_t
));
516 foreach(ptr
, &rb_context
->shaders
) {
517 tr_shdr
= (struct rbug_shader
*)((char*)ptr
- offsetof(struct rbug_shader
, list
));
518 shdrs
[i
++] = VOID2U64(tr_shdr
);
521 pipe_mutex_unlock(rb_context
->list_mutex
);
522 pipe_mutex_unlock(rb_screen
->list_mutex
);
524 rbug_send_shader_list_reply(tr_rbug
->con
, serial
, shdrs
, i
, NULL
);
531 rbug_shader_info(struct rbug_rbug
*tr_rbug
, struct rbug_header
*header
, uint32_t serial
)
533 struct rbug_proto_shader_info
*info
= (struct rbug_proto_shader_info
*)header
;
535 struct rbug_screen
*rb_screen
= tr_rbug
->rb_screen
;
536 struct rbug_context
*rb_context
= NULL
;
537 struct rbug_shader
*tr_shdr
= NULL
;
538 unsigned original_len
;
539 unsigned replaced_len
;
541 pipe_mutex_lock(rb_screen
->list_mutex
);
542 rb_context
= rbug_get_context_locked(rb_screen
, info
->context
);
545 pipe_mutex_unlock(rb_screen
->list_mutex
);
549 pipe_mutex_lock(rb_context
->list_mutex
);
551 tr_shdr
= rbug_get_shader_locked(rb_context
, info
->shader
);
554 pipe_mutex_unlock(rb_context
->list_mutex
);
555 pipe_mutex_unlock(rb_screen
->list_mutex
);
560 assert(sizeof(struct tgsi_token
) == 4);
562 original_len
= tgsi_num_tokens(tr_shdr
->tokens
);
563 if (tr_shdr
->replaced_tokens
)
564 replaced_len
= tgsi_num_tokens(tr_shdr
->replaced_tokens
);
568 rbug_send_shader_info_reply(tr_rbug
->con
, serial
,
569 (uint32_t*)tr_shdr
->tokens
, original_len
,
570 (uint32_t*)tr_shdr
->replaced_tokens
, replaced_len
,
574 pipe_mutex_unlock(rb_context
->list_mutex
);
575 pipe_mutex_unlock(rb_screen
->list_mutex
);
581 rbug_shader_disable(struct rbug_rbug
*tr_rbug
, struct rbug_header
*header
)
583 struct rbug_proto_shader_disable
*dis
= (struct rbug_proto_shader_disable
*)header
;
585 struct rbug_screen
*rb_screen
= tr_rbug
->rb_screen
;
586 struct rbug_context
*rb_context
= NULL
;
587 struct rbug_shader
*tr_shdr
= NULL
;
589 pipe_mutex_lock(rb_screen
->list_mutex
);
590 rb_context
= rbug_get_context_locked(rb_screen
, dis
->context
);
593 pipe_mutex_unlock(rb_screen
->list_mutex
);
597 pipe_mutex_lock(rb_context
->list_mutex
);
599 tr_shdr
= rbug_get_shader_locked(rb_context
, dis
->shader
);
602 pipe_mutex_unlock(rb_context
->list_mutex
);
603 pipe_mutex_unlock(rb_screen
->list_mutex
);
607 tr_shdr
->disabled
= dis
->disable
;
609 pipe_mutex_unlock(rb_context
->list_mutex
);
610 pipe_mutex_unlock(rb_screen
->list_mutex
);
616 rbug_shader_replace(struct rbug_rbug
*tr_rbug
, struct rbug_header
*header
)
618 struct rbug_proto_shader_replace
*rep
= (struct rbug_proto_shader_replace
*)header
;
620 struct rbug_screen
*rb_screen
= tr_rbug
->rb_screen
;
621 struct rbug_context
*rb_context
= NULL
;
622 struct rbug_shader
*tr_shdr
= NULL
;
623 struct pipe_context
*pipe
= NULL
;
626 pipe_mutex_lock(rb_screen
->list_mutex
);
627 rb_context
= rbug_get_context_locked(rb_screen
, rep
->context
);
630 pipe_mutex_unlock(rb_screen
->list_mutex
);
634 pipe_mutex_lock(rb_context
->list_mutex
);
636 tr_shdr
= rbug_get_shader_locked(rb_context
, rep
->shader
);
639 pipe_mutex_unlock(rb_context
->list_mutex
);
640 pipe_mutex_unlock(rb_screen
->list_mutex
);
644 /* protect the pipe context */
645 pipe_mutex_lock(rb_context
->call_mutex
);
647 pipe
= rb_context
->pipe
;
649 /* remove old replaced shader */
650 if (tr_shdr
->replaced_shader
) {
651 /* if this shader is bound rebind the original shader */
652 if (rb_context
->curr
.fs
== tr_shdr
|| rb_context
->curr
.vs
== tr_shdr
)
653 rbug_shader_bind_locked(pipe
, tr_shdr
, tr_shdr
->shader
);
655 FREE(tr_shdr
->replaced_tokens
);
656 rbug_shader_delete_locked(pipe
, tr_shdr
, tr_shdr
->replaced_shader
);
657 tr_shdr
->replaced_shader
= NULL
;
658 tr_shdr
->replaced_tokens
= NULL
;
661 /* empty inputs means restore old which we did above */
662 if (rep
->tokens_len
== 0)
665 tr_shdr
->replaced_tokens
= tgsi_dup_tokens((struct tgsi_token
*)rep
->tokens
);
666 if (!tr_shdr
->replaced_tokens
)
669 state
= rbug_shader_create_locked(pipe
, tr_shdr
, tr_shdr
->replaced_tokens
);
673 /* bind new shader if the shader is currently a bound */
674 if (rb_context
->curr
.fs
== tr_shdr
|| rb_context
->curr
.vs
== tr_shdr
)
675 rbug_shader_bind_locked(pipe
, tr_shdr
, state
);
678 tr_shdr
->replaced_shader
= state
;
681 pipe_mutex_unlock(rb_context
->call_mutex
);
682 pipe_mutex_unlock(rb_context
->list_mutex
);
683 pipe_mutex_unlock(rb_screen
->list_mutex
);
688 FREE(tr_shdr
->replaced_tokens
);
689 tr_shdr
->replaced_shader
= NULL
;
690 tr_shdr
->replaced_tokens
= NULL
;
692 pipe_mutex_unlock(rb_context
->call_mutex
);
693 pipe_mutex_unlock(rb_context
->list_mutex
);
694 pipe_mutex_unlock(rb_screen
->list_mutex
);
699 rbug_header(struct rbug_rbug
*tr_rbug
, struct rbug_header
*header
, uint32_t serial
)
703 switch(header
->opcode
) {
705 rbug_send_ping_reply(tr_rbug
->con
, serial
, NULL
);
707 case RBUG_OP_TEXTURE_LIST
:
708 ret
= rbug_texture_list(tr_rbug
, header
, serial
);
710 case RBUG_OP_TEXTURE_INFO
:
711 ret
= rbug_texture_info(tr_rbug
, header
, serial
);
713 case RBUG_OP_TEXTURE_READ
:
714 ret
= rbug_texture_read(tr_rbug
, header
, serial
);
716 case RBUG_OP_CONTEXT_LIST
:
717 ret
= rbug_context_list(tr_rbug
, header
, serial
);
719 case RBUG_OP_CONTEXT_INFO
:
720 ret
= rbug_context_info(tr_rbug
, header
, serial
);
722 case RBUG_OP_CONTEXT_DRAW_BLOCK
:
723 ret
= rbug_context_draw_block(tr_rbug
, header
, serial
);
725 case RBUG_OP_CONTEXT_DRAW_STEP
:
726 ret
= rbug_context_draw_step(tr_rbug
, header
, serial
);
728 case RBUG_OP_CONTEXT_DRAW_UNBLOCK
:
729 ret
= rbug_context_draw_unblock(tr_rbug
, header
, serial
);
731 case RBUG_OP_CONTEXT_DRAW_RULE
:
732 ret
= rbug_context_draw_rule(tr_rbug
, header
, serial
);
734 case RBUG_OP_CONTEXT_FLUSH
:
735 ret
= rbug_context_flush(tr_rbug
, header
, serial
);
737 case RBUG_OP_SHADER_LIST
:
738 ret
= rbug_shader_list(tr_rbug
, header
, serial
);
740 case RBUG_OP_SHADER_INFO
:
741 ret
= rbug_shader_info(tr_rbug
, header
, serial
);
743 case RBUG_OP_SHADER_DISABLE
:
744 ret
= rbug_shader_disable(tr_rbug
, header
);
746 case RBUG_OP_SHADER_REPLACE
:
747 ret
= rbug_shader_replace(tr_rbug
, header
);
750 debug_printf("%s - unsupported opcode %u\n", __FUNCTION__
, header
->opcode
);
754 rbug_free_header(header
);
757 rbug_send_error_reply(tr_rbug
->con
, serial
, ret
, NULL
);
763 rbug_con(struct rbug_rbug
*tr_rbug
)
765 struct rbug_header
*header
;
768 debug_printf("%s - connection received\n", __FUNCTION__
);
770 while(tr_rbug
->running
) {
771 header
= rbug_get_message(tr_rbug
->con
, &serial
);
775 if (!rbug_header(tr_rbug
, header
, serial
))
779 debug_printf("%s - connection closed\n", __FUNCTION__
);
781 rbug_disconnect(tr_rbug
->con
);
785 PIPE_THREAD_ROUTINE(rbug_thread
, void_tr_rbug
)
787 struct rbug_rbug
*tr_rbug
= void_tr_rbug
;
788 uint16_t port
= 13370;
794 for (;port
<= 13379 && s
< 0; port
++)
795 s
= u_socket_listen_on_port(port
);
798 debug_printf("rbug_rbug - failed to listen\n");
802 u_socket_block(s
, false);
804 debug_printf("rbug_rbug - remote debugging listening on port %u\n", --port
);
806 while(tr_rbug
->running
) {
809 c
= u_socket_accept(s
);
813 u_socket_block(c
, true);
814 tr_rbug
->con
= rbug_from_socket(c
);
828 /**********************************************************
833 rbug_start(struct rbug_screen
*rb_screen
)
835 struct rbug_rbug
*tr_rbug
= CALLOC_STRUCT(rbug_rbug
);
839 tr_rbug
->rb_screen
= rb_screen
;
840 tr_rbug
->running
= TRUE
;
841 tr_rbug
->thread
= pipe_thread_create(rbug_thread
, tr_rbug
);
847 rbug_stop(struct rbug_rbug
*tr_rbug
)
852 tr_rbug
->running
= false;
853 pipe_thread_wait(tr_rbug
->thread
);
861 rbug_notify_draw_blocked(struct rbug_context
*rb_context
)
863 struct rbug_screen
*rb_screen
= rbug_screen(rb_context
->base
.screen
);
864 struct rbug_rbug
*tr_rbug
= rb_screen
->rbug
;
866 if (tr_rbug
&& tr_rbug
->con
)
867 rbug_send_context_draw_blocked(tr_rbug
->con
,
868 VOID2U64(rb_context
), rb_context
->draw_blocked
, NULL
);