1 /**************************************************************************
3 * Copyright 2009 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 TUNGSTEN GRAPHICS 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 "util/u_string.h"
30 #include "util/u_memory.h"
31 #include "util/u_simple_list.h"
32 #include "util/u_network.h"
34 #include "tgsi/tgsi_parse.h"
38 #include "tr_buffer.h"
39 #include "tr_texture.h"
41 #include "rbug/rbug.h"
45 #if defined(PIPE_SUBSYSTEM_WINDOWS_USER)
47 #elif defined(PIPE_OS_LINUX)
51 # warning "No socket implementation"
54 #define U642VOID(x) ((void *)(unsigned long)(x))
55 #define VOID2U64(x) ((uint64_t)(unsigned long)(x))
59 struct trace_screen
*tr_scr
;
60 struct rbug_connection
*con
;
65 PIPE_THREAD_ROUTINE(trace_rbug_thread
, void_tr_rbug
);
68 /**********************************************************
73 static struct trace_context
*
74 trace_rbug_get_context_locked(struct trace_screen
*tr_scr
, rbug_context_t ctx
)
76 struct trace_context
*tr_ctx
= NULL
;
79 foreach(ptr
, &tr_scr
->contexts
) {
80 tr_ctx
= (struct trace_context
*)((char*)ptr
- offsetof(struct trace_context
, list
));
81 if (ctx
== VOID2U64(tr_ctx
))
89 static struct trace_shader
*
90 trace_rbug_get_shader_locked(struct trace_context
*tr_ctx
, rbug_shader_t shdr
)
92 struct trace_shader
*tr_shdr
= NULL
;
95 foreach(ptr
, &tr_ctx
->shaders
) {
96 tr_shdr
= (struct trace_shader
*)((char*)ptr
- offsetof(struct trace_shader
, list
));
97 if (shdr
== VOID2U64(tr_shdr
))
106 trace_shader_create_locked(struct pipe_context
*pipe
,
107 struct trace_shader
*tr_shdr
,
108 struct tgsi_token
*tokens
)
111 struct pipe_shader_state pss
= { 0 };
114 if (tr_shdr
->type
== TRACE_SHADER_FRAGMENT
) {
115 state
= pipe
->create_fs_state(pipe
, &pss
);
116 } else if (tr_shdr
->type
== TRACE_SHADER_VERTEX
) {
117 state
= pipe
->create_vs_state(pipe
, &pss
);
125 trace_shader_bind_locked(struct pipe_context
*pipe
,
126 struct trace_shader
*tr_shdr
,
129 if (tr_shdr
->type
== TRACE_SHADER_FRAGMENT
) {
130 pipe
->bind_fs_state(pipe
, state
);
131 } else if (tr_shdr
->type
== TRACE_SHADER_VERTEX
) {
132 pipe
->bind_vs_state(pipe
, state
);
138 trace_shader_delete_locked(struct pipe_context
*pipe
,
139 struct trace_shader
*tr_shdr
,
142 if (tr_shdr
->type
== TRACE_SHADER_FRAGMENT
) {
143 pipe
->delete_fs_state(pipe
, state
);
144 } else if (tr_shdr
->type
== TRACE_SHADER_VERTEX
) {
145 pipe
->delete_vs_state(pipe
, state
);
150 /************************************************
151 * Request handler functions
156 trace_rbug_texture_list(struct trace_rbug
*tr_rbug
, struct rbug_header
*header
, uint32_t serial
)
158 struct trace_screen
*tr_scr
= tr_rbug
->tr_scr
;
159 struct trace_texture
*tr_tex
= NULL
;
161 rbug_texture_t
*texs
;
164 pipe_mutex_lock(tr_scr
->list_mutex
);
165 texs
= MALLOC(tr_scr
->num_textures
* sizeof(rbug_texture_t
));
166 foreach(ptr
, &tr_scr
->textures
) {
167 tr_tex
= (struct trace_texture
*)((char*)ptr
- offsetof(struct trace_texture
, list
));
168 texs
[i
++] = VOID2U64(tr_tex
);
170 pipe_mutex_unlock(tr_scr
->list_mutex
);
172 rbug_send_texture_list_reply(tr_rbug
->con
, serial
, texs
, i
, NULL
);
179 trace_rbug_texture_info(struct trace_rbug
*tr_rbug
, struct rbug_header
*header
, uint32_t serial
)
181 struct trace_screen
*tr_scr
= tr_rbug
->tr_scr
;
182 struct trace_texture
*tr_tex
;
183 struct rbug_proto_texture_info
*gpti
= (struct rbug_proto_texture_info
*)header
;
185 struct pipe_texture
*t
;
187 pipe_mutex_lock(tr_scr
->list_mutex
);
188 foreach(ptr
, &tr_scr
->textures
) {
189 tr_tex
= (struct trace_texture
*)((char*)ptr
- offsetof(struct trace_texture
, list
));
190 if (gpti
->texture
== VOID2U64(tr_tex
))
196 pipe_mutex_unlock(tr_scr
->list_mutex
);
201 rbug_send_texture_info_reply(tr_rbug
->con
, serial
,
202 t
->target
, t
->format
,
203 t
->width
, t
->last_level
+ 1,
204 t
->height
, t
->last_level
+ 1,
205 t
->depth
, t
->last_level
+ 1,
206 t
->block
.width
, t
->block
.height
, t
->block
.size
,
212 pipe_mutex_unlock(tr_scr
->list_mutex
);
218 trace_rbug_texture_read(struct trace_rbug
*tr_rbug
, struct rbug_header
*header
, uint32_t serial
)
220 struct rbug_proto_texture_read
*gptr
= (struct rbug_proto_texture_read
*)header
;
222 struct trace_screen
*tr_scr
= tr_rbug
->tr_scr
;
223 struct trace_texture
*tr_tex
;
226 struct pipe_screen
*screen
= tr_scr
->screen
;
227 struct pipe_texture
*tex
;
228 struct pipe_transfer
*t
;
232 pipe_mutex_lock(tr_scr
->list_mutex
);
233 foreach(ptr
, &tr_scr
->textures
) {
234 tr_tex
= (struct trace_texture
*)((char*)ptr
- offsetof(struct trace_texture
, list
));
235 if (gptr
->texture
== VOID2U64(tr_tex
))
241 pipe_mutex_unlock(tr_scr
->list_mutex
);
245 tex
= tr_tex
->texture
;
246 t
= screen
->get_tex_transfer(tr_scr
->screen
, tex
,
247 gptr
->face
, gptr
->level
, gptr
->zslice
,
249 gptr
->x
, gptr
->y
, gptr
->w
, gptr
->h
);
251 map
= screen
->transfer_map(screen
, t
);
253 rbug_send_texture_read_reply(tr_rbug
->con
, serial
,
255 t
->block
.width
, t
->block
.height
, t
->block
.size
,
256 (uint8_t*)map
, t
->stride
* t
->nblocksy
,
260 screen
->transfer_unmap(screen
, t
);
261 screen
->tex_transfer_destroy(t
);
263 pipe_mutex_unlock(tr_scr
->list_mutex
);
269 trace_rbug_context_list(struct trace_rbug
*tr_rbug
, struct rbug_header
*header
, uint32_t serial
)
271 struct trace_screen
*tr_scr
= tr_rbug
->tr_scr
;
273 struct trace_context
*tr_ctx
= NULL
;
274 rbug_context_t
*ctxs
;
277 pipe_mutex_lock(tr_scr
->list_mutex
);
278 ctxs
= MALLOC(tr_scr
->num_contexts
* sizeof(rbug_context_t
));
279 foreach(ptr
, &tr_scr
->contexts
) {
280 tr_ctx
= (struct trace_context
*)((char*)ptr
- offsetof(struct trace_context
, list
));
281 ctxs
[i
++] = VOID2U64(tr_ctx
);
283 pipe_mutex_unlock(tr_scr
->list_mutex
);
285 rbug_send_context_list_reply(tr_rbug
->con
, serial
, ctxs
, i
, NULL
);
292 trace_rbug_context_info(struct trace_rbug
*tr_rbug
, struct rbug_header
*header
, uint32_t serial
)
294 struct rbug_proto_context_info
*info
= (struct rbug_proto_context_info
*)header
;
296 struct trace_screen
*tr_scr
= tr_rbug
->tr_scr
;
297 struct trace_context
*tr_ctx
= NULL
;
298 rbug_texture_t cbufs
[PIPE_MAX_COLOR_BUFS
];
299 rbug_texture_t texs
[PIPE_MAX_SAMPLERS
];
302 pipe_mutex_lock(tr_scr
->list_mutex
);
303 tr_ctx
= trace_rbug_get_context_locked(tr_scr
, info
->context
);
306 pipe_mutex_unlock(tr_scr
->list_mutex
);
310 /* protect the pipe context */
311 pipe_mutex_lock(tr_ctx
->draw_mutex
);
312 trace_dump_call_lock();
314 for (i
= 0; i
< tr_ctx
->curr
.nr_cbufs
; i
++)
315 cbufs
[i
] = VOID2U64(tr_ctx
->curr
.cbufs
[i
]);
317 for (i
= 0; i
< tr_ctx
->curr
.num_texs
; i
++)
318 texs
[i
] = VOID2U64(tr_ctx
->curr
.tex
[i
]);
320 rbug_send_context_info_reply(tr_rbug
->con
, serial
,
321 VOID2U64(tr_ctx
->curr
.vs
), VOID2U64(tr_ctx
->curr
.fs
),
322 texs
, tr_ctx
->curr
.num_texs
,
323 cbufs
, tr_ctx
->curr
.nr_cbufs
,
324 VOID2U64(tr_ctx
->curr
.zsbuf
),
325 tr_ctx
->draw_blocker
, tr_ctx
->draw_blocked
, NULL
);
327 trace_dump_call_unlock();
328 pipe_mutex_unlock(tr_ctx
->draw_mutex
);
330 pipe_mutex_unlock(tr_scr
->list_mutex
);
336 trace_rbug_context_draw_block(struct trace_rbug
*tr_rbug
, struct rbug_header
*header
, uint32_t serial
)
338 struct rbug_proto_context_draw_block
*block
= (struct rbug_proto_context_draw_block
*)header
;
340 struct trace_screen
*tr_scr
= tr_rbug
->tr_scr
;
341 struct trace_context
*tr_ctx
= NULL
;
343 pipe_mutex_lock(tr_scr
->list_mutex
);
344 tr_ctx
= trace_rbug_get_context_locked(tr_scr
, block
->context
);
347 pipe_mutex_unlock(tr_scr
->list_mutex
);
351 pipe_mutex_lock(tr_ctx
->draw_mutex
);
352 tr_ctx
->draw_blocker
|= block
->block
;
353 pipe_mutex_unlock(tr_ctx
->draw_mutex
);
355 pipe_mutex_unlock(tr_scr
->list_mutex
);
361 trace_rbug_context_draw_step(struct trace_rbug
*tr_rbug
, struct rbug_header
*header
, uint32_t serial
)
363 struct rbug_proto_context_draw_step
*step
= (struct rbug_proto_context_draw_step
*)header
;
365 struct trace_screen
*tr_scr
= tr_rbug
->tr_scr
;
366 struct trace_context
*tr_ctx
= NULL
;
368 pipe_mutex_lock(tr_scr
->list_mutex
);
369 tr_ctx
= trace_rbug_get_context_locked(tr_scr
, step
->context
);
372 pipe_mutex_unlock(tr_scr
->list_mutex
);
376 pipe_mutex_lock(tr_ctx
->draw_mutex
);
377 if (tr_ctx
->draw_blocked
& RBUG_BLOCK_RULE
) {
378 if (step
->step
& RBUG_BLOCK_RULE
)
379 tr_ctx
->draw_blocked
&= ~RBUG_BLOCK_MASK
;
381 tr_ctx
->draw_blocked
&= ~step
->step
;
383 pipe_mutex_unlock(tr_ctx
->draw_mutex
);
385 #ifdef PIPE_THREAD_HAVE_CONDVAR
386 pipe_condvar_broadcast(tr_ctx
->draw_cond
);
389 pipe_mutex_unlock(tr_scr
->list_mutex
);
395 trace_rbug_context_draw_unblock(struct trace_rbug
*tr_rbug
, struct rbug_header
*header
, uint32_t serial
)
397 struct rbug_proto_context_draw_unblock
*unblock
= (struct rbug_proto_context_draw_unblock
*)header
;
399 struct trace_screen
*tr_scr
= tr_rbug
->tr_scr
;
400 struct trace_context
*tr_ctx
= NULL
;
402 pipe_mutex_lock(tr_scr
->list_mutex
);
403 tr_ctx
= trace_rbug_get_context_locked(tr_scr
, unblock
->context
);
406 pipe_mutex_unlock(tr_scr
->list_mutex
);
410 pipe_mutex_lock(tr_ctx
->draw_mutex
);
411 if (tr_ctx
->draw_blocked
& RBUG_BLOCK_RULE
) {
412 if (unblock
->unblock
& RBUG_BLOCK_RULE
)
413 tr_ctx
->draw_blocked
&= ~RBUG_BLOCK_MASK
;
415 tr_ctx
->draw_blocked
&= ~unblock
->unblock
;
417 tr_ctx
->draw_blocker
&= ~unblock
->unblock
;
418 pipe_mutex_unlock(tr_ctx
->draw_mutex
);
420 #ifdef PIPE_THREAD_HAVE_CONDVAR
421 pipe_condvar_broadcast(tr_ctx
->draw_cond
);
424 pipe_mutex_unlock(tr_scr
->list_mutex
);
430 trace_rbug_context_draw_rule(struct trace_rbug
*tr_rbug
, struct rbug_header
*header
, uint32_t serial
)
432 struct rbug_proto_context_draw_rule
*rule
= (struct rbug_proto_context_draw_rule
*)header
;
434 struct trace_screen
*tr_scr
= tr_rbug
->tr_scr
;
435 struct trace_context
*tr_ctx
= NULL
;
437 pipe_mutex_lock(tr_scr
->list_mutex
);
438 tr_ctx
= trace_rbug_get_context_locked(tr_scr
, rule
->context
);
441 pipe_mutex_unlock(tr_scr
->list_mutex
);
445 pipe_mutex_lock(tr_ctx
->draw_mutex
);
446 tr_ctx
->draw_rule
.vs
= U642VOID(rule
->vertex
);
447 tr_ctx
->draw_rule
.fs
= U642VOID(rule
->fragment
);
448 tr_ctx
->draw_rule
.tex
= U642VOID(rule
->texture
);
449 tr_ctx
->draw_rule
.surf
= U642VOID(rule
->surface
);
450 tr_ctx
->draw_rule
.blocker
= rule
->block
;
451 tr_ctx
->draw_blocker
|= RBUG_BLOCK_RULE
;
452 pipe_mutex_unlock(tr_ctx
->draw_mutex
);
454 #ifdef PIPE_THREAD_HAVE_CONDVAR
455 pipe_condvar_broadcast(tr_ctx
->draw_cond
);
458 pipe_mutex_unlock(tr_scr
->list_mutex
);
464 trace_rbug_context_flush(struct trace_rbug
*tr_rbug
, struct rbug_header
*header
, uint32_t serial
)
466 struct rbug_proto_context_flush
*flush
= (struct rbug_proto_context_flush
*)header
;
468 struct trace_screen
*tr_scr
= tr_rbug
->tr_scr
;
469 struct trace_context
*tr_ctx
= NULL
;
471 pipe_mutex_lock(tr_scr
->list_mutex
);
472 tr_ctx
= trace_rbug_get_context_locked(tr_scr
, flush
->context
);
475 pipe_mutex_unlock(tr_scr
->list_mutex
);
479 /* protect the pipe context */
480 trace_dump_call_lock();
482 tr_ctx
->pipe
->flush(tr_ctx
->pipe
, flush
->flags
, NULL
);
484 trace_dump_call_unlock();
485 pipe_mutex_unlock(tr_scr
->list_mutex
);
491 trace_rbug_shader_list(struct trace_rbug
*tr_rbug
, struct rbug_header
*header
, uint32_t serial
)
493 struct rbug_proto_shader_list
*list
= (struct rbug_proto_shader_list
*)header
;
495 struct trace_screen
*tr_scr
= tr_rbug
->tr_scr
;
496 struct trace_context
*tr_ctx
= NULL
;
497 struct trace_shader
*tr_shdr
= NULL
;
499 rbug_shader_t
*shdrs
;
502 pipe_mutex_lock(tr_scr
->list_mutex
);
503 tr_ctx
= trace_rbug_get_context_locked(tr_scr
, list
->context
);
506 pipe_mutex_unlock(tr_scr
->list_mutex
);
510 pipe_mutex_lock(tr_ctx
->list_mutex
);
511 shdrs
= MALLOC(tr_ctx
->num_shaders
* sizeof(rbug_shader_t
));
512 foreach(ptr
, &tr_ctx
->shaders
) {
513 tr_shdr
= (struct trace_shader
*)((char*)ptr
- offsetof(struct trace_shader
, list
));
514 shdrs
[i
++] = VOID2U64(tr_shdr
);
517 pipe_mutex_unlock(tr_ctx
->list_mutex
);
518 pipe_mutex_unlock(tr_scr
->list_mutex
);
520 rbug_send_shader_list_reply(tr_rbug
->con
, serial
, shdrs
, i
, NULL
);
527 trace_rbug_shader_info(struct trace_rbug
*tr_rbug
, struct rbug_header
*header
, uint32_t serial
)
529 struct rbug_proto_shader_info
*info
= (struct rbug_proto_shader_info
*)header
;
531 struct trace_screen
*tr_scr
= tr_rbug
->tr_scr
;
532 struct trace_context
*tr_ctx
= NULL
;
533 struct trace_shader
*tr_shdr
= NULL
;
534 unsigned original_len
;
535 unsigned replaced_len
;
537 pipe_mutex_lock(tr_scr
->list_mutex
);
538 tr_ctx
= trace_rbug_get_context_locked(tr_scr
, info
->context
);
541 pipe_mutex_unlock(tr_scr
->list_mutex
);
545 pipe_mutex_lock(tr_ctx
->list_mutex
);
547 tr_shdr
= trace_rbug_get_shader_locked(tr_ctx
, info
->shader
);
550 pipe_mutex_unlock(tr_ctx
->list_mutex
);
551 pipe_mutex_unlock(tr_scr
->list_mutex
);
556 assert(sizeof(struct tgsi_token
) == 4);
558 original_len
= tgsi_num_tokens(tr_shdr
->tokens
);
559 if (tr_shdr
->replaced_tokens
)
560 replaced_len
= tgsi_num_tokens(tr_shdr
->replaced_tokens
);
564 rbug_send_shader_info_reply(tr_rbug
->con
, serial
,
565 (uint32_t*)tr_shdr
->tokens
, original_len
,
566 (uint32_t*)tr_shdr
->replaced_tokens
, replaced_len
,
570 pipe_mutex_unlock(tr_ctx
->list_mutex
);
571 pipe_mutex_unlock(tr_scr
->list_mutex
);
577 trace_rbug_shader_disable(struct trace_rbug
*tr_rbug
, struct rbug_header
*header
)
579 struct rbug_proto_shader_disable
*dis
= (struct rbug_proto_shader_disable
*)header
;
581 struct trace_screen
*tr_scr
= tr_rbug
->tr_scr
;
582 struct trace_context
*tr_ctx
= NULL
;
583 struct trace_shader
*tr_shdr
= NULL
;
585 pipe_mutex_lock(tr_scr
->list_mutex
);
586 tr_ctx
= trace_rbug_get_context_locked(tr_scr
, dis
->context
);
589 pipe_mutex_unlock(tr_scr
->list_mutex
);
593 pipe_mutex_lock(tr_ctx
->list_mutex
);
595 tr_shdr
= trace_rbug_get_shader_locked(tr_ctx
, dis
->shader
);
598 pipe_mutex_unlock(tr_ctx
->list_mutex
);
599 pipe_mutex_unlock(tr_scr
->list_mutex
);
603 tr_shdr
->disabled
= dis
->disable
;
605 pipe_mutex_unlock(tr_ctx
->list_mutex
);
606 pipe_mutex_unlock(tr_scr
->list_mutex
);
612 trace_rbug_shader_replace(struct trace_rbug
*tr_rbug
, struct rbug_header
*header
)
614 struct rbug_proto_shader_replace
*rep
= (struct rbug_proto_shader_replace
*)header
;
616 struct trace_screen
*tr_scr
= tr_rbug
->tr_scr
;
617 struct trace_context
*tr_ctx
= NULL
;
618 struct trace_shader
*tr_shdr
= NULL
;
619 struct pipe_context
*pipe
= NULL
;
622 pipe_mutex_lock(tr_scr
->list_mutex
);
623 tr_ctx
= trace_rbug_get_context_locked(tr_scr
, rep
->context
);
626 pipe_mutex_unlock(tr_scr
->list_mutex
);
630 pipe_mutex_lock(tr_ctx
->list_mutex
);
632 tr_shdr
= trace_rbug_get_shader_locked(tr_ctx
, rep
->shader
);
635 pipe_mutex_unlock(tr_ctx
->list_mutex
);
636 pipe_mutex_unlock(tr_scr
->list_mutex
);
640 /* protect the pipe context */
641 trace_dump_call_lock();
645 /* remove old replaced shader */
646 if (tr_shdr
->replaced
) {
647 if (tr_ctx
->curr
.fs
== tr_shdr
|| tr_ctx
->curr
.vs
== tr_shdr
)
648 trace_shader_bind_locked(pipe
, tr_shdr
, tr_shdr
->state
);
650 FREE(tr_shdr
->replaced_tokens
);
651 trace_shader_delete_locked(pipe
, tr_shdr
, tr_shdr
->replaced
);
652 tr_shdr
->replaced
= NULL
;
653 tr_shdr
->replaced_tokens
= NULL
;
656 /* empty inputs means restore old which we did above */
657 if (rep
->tokens_len
== 0)
660 tr_shdr
->replaced_tokens
= tgsi_dup_tokens((struct tgsi_token
*)rep
->tokens
);
661 if (!tr_shdr
->replaced_tokens
)
664 state
= trace_shader_create_locked(pipe
, tr_shdr
, tr_shdr
->replaced_tokens
);
668 /* bind new shader if the shader is currently a bound */
669 if (tr_ctx
->curr
.fs
== tr_shdr
|| tr_ctx
->curr
.vs
== tr_shdr
)
670 trace_shader_bind_locked(pipe
, tr_shdr
, state
);
673 tr_shdr
->replaced
= state
;
676 trace_dump_call_unlock();
677 pipe_mutex_unlock(tr_ctx
->list_mutex
);
678 pipe_mutex_unlock(tr_scr
->list_mutex
);
683 FREE(tr_shdr
->replaced_tokens
);
684 tr_shdr
->replaced
= NULL
;
685 tr_shdr
->replaced_tokens
= NULL
;
687 trace_dump_call_unlock();
688 pipe_mutex_unlock(tr_ctx
->list_mutex
);
689 pipe_mutex_unlock(tr_scr
->list_mutex
);
694 trace_rbug_header(struct trace_rbug
*tr_rbug
, struct rbug_header
*header
, uint32_t serial
)
698 switch(header
->opcode
) {
700 rbug_send_ping_reply(tr_rbug
->con
, serial
, NULL
);
702 case RBUG_OP_TEXTURE_LIST
:
703 ret
= trace_rbug_texture_list(tr_rbug
, header
, serial
);
705 case RBUG_OP_TEXTURE_INFO
:
706 ret
= trace_rbug_texture_info(tr_rbug
, header
, serial
);
708 case RBUG_OP_TEXTURE_READ
:
709 ret
= trace_rbug_texture_read(tr_rbug
, header
, serial
);
711 case RBUG_OP_CONTEXT_LIST
:
712 ret
= trace_rbug_context_list(tr_rbug
, header
, serial
);
714 case RBUG_OP_CONTEXT_INFO
:
715 ret
= trace_rbug_context_info(tr_rbug
, header
, serial
);
717 case RBUG_OP_CONTEXT_DRAW_BLOCK
:
718 ret
= trace_rbug_context_draw_block(tr_rbug
, header
, serial
);
720 case RBUG_OP_CONTEXT_DRAW_STEP
:
721 ret
= trace_rbug_context_draw_step(tr_rbug
, header
, serial
);
723 case RBUG_OP_CONTEXT_DRAW_UNBLOCK
:
724 ret
= trace_rbug_context_draw_unblock(tr_rbug
, header
, serial
);
726 case RBUG_OP_CONTEXT_DRAW_RULE
:
727 ret
= trace_rbug_context_draw_rule(tr_rbug
, header
, serial
);
729 case RBUG_OP_CONTEXT_FLUSH
:
730 ret
= trace_rbug_context_flush(tr_rbug
, header
, serial
);
732 case RBUG_OP_SHADER_LIST
:
733 ret
= trace_rbug_shader_list(tr_rbug
, header
, serial
);
735 case RBUG_OP_SHADER_INFO
:
736 ret
= trace_rbug_shader_info(tr_rbug
, header
, serial
);
738 case RBUG_OP_SHADER_DISABLE
:
739 ret
= trace_rbug_shader_disable(tr_rbug
, header
);
741 case RBUG_OP_SHADER_REPLACE
:
742 ret
= trace_rbug_shader_replace(tr_rbug
, header
);
745 debug_printf("%s - unsupported opcode %u\n", __FUNCTION__
, header
->opcode
);
749 rbug_free_header(header
);
752 rbug_send_error_reply(tr_rbug
->con
, serial
, ret
, NULL
);
758 trace_rbug_con(struct trace_rbug
*tr_rbug
)
760 struct rbug_header
*header
;
763 debug_printf("%s - connection received\n", __FUNCTION__
);
765 while(tr_rbug
->running
) {
766 header
= rbug_get_message(tr_rbug
->con
, &serial
);
770 if (!trace_rbug_header(tr_rbug
, header
, serial
))
774 debug_printf("%s - connection closed\n", __FUNCTION__
);
776 rbug_disconnect(tr_rbug
->con
);
780 PIPE_THREAD_ROUTINE(trace_rbug_thread
, void_tr_rbug
)
782 struct trace_rbug
*tr_rbug
= void_tr_rbug
;
783 uint16_t port
= 13370;
789 for (;port
<= 13379 && s
< 0; port
++)
790 s
= u_socket_listen_on_port(port
);
793 debug_printf("trace_rbug - failed to listen\n");
797 u_socket_block(s
, false);
799 debug_printf("trace_rbug - remote debugging listening on port %u\n", --port
);
801 while(tr_rbug
->running
) {
804 c
= u_socket_accept(s
);
808 u_socket_block(c
, true);
809 tr_rbug
->con
= rbug_from_socket(c
);
811 trace_rbug_con(tr_rbug
);
823 /**********************************************************
828 trace_rbug_start(struct trace_screen
*tr_scr
)
830 struct trace_rbug
*tr_rbug
= CALLOC_STRUCT(trace_rbug
);
834 tr_rbug
->tr_scr
= tr_scr
;
835 tr_rbug
->running
= TRUE
;
836 tr_rbug
->thread
= pipe_thread_create(trace_rbug_thread
, tr_rbug
);
842 trace_rbug_stop(struct trace_rbug
*tr_rbug
)
847 tr_rbug
->running
= false;
848 pipe_thread_wait(tr_rbug
->thread
);
856 trace_rbug_notify_draw_blocked(struct trace_context
*tr_ctx
)
858 struct trace_screen
*tr_scr
= trace_screen(tr_ctx
->base
.screen
);
859 struct trace_rbug
*tr_rbug
= tr_scr
->rbug
;
861 if (tr_rbug
&& tr_rbug
->con
)
862 rbug_send_context_draw_blocked(tr_rbug
->con
,
863 VOID2U64(tr_ctx
), tr_ctx
->draw_blocked
, NULL
);