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 "os/os_thread.h"
30 #include "util/u_format.h"
31 #include "util/u_string.h"
32 #include "util/u_memory.h"
33 #include "util/u_simple_list.h"
34 #include "util/u_network.h"
35 #include "os/os_time.h"
37 #include "tgsi/tgsi_parse.h"
41 #include "tr_buffer.h"
42 #include "tr_texture.h"
44 #include "rbug/rbug.h"
48 #define U642VOID(x) ((void *)(unsigned long)(x))
49 #define VOID2U64(x) ((uint64_t)(unsigned long)(x))
53 struct trace_screen
*tr_scr
;
54 struct rbug_connection
*con
;
59 PIPE_THREAD_ROUTINE(trace_rbug_thread
, void_tr_rbug
);
62 /**********************************************************
67 static struct trace_context
*
68 trace_rbug_get_context_locked(struct trace_screen
*tr_scr
, rbug_context_t ctx
)
70 struct trace_context
*tr_ctx
= NULL
;
73 foreach(ptr
, &tr_scr
->contexts
) {
74 tr_ctx
= (struct trace_context
*)((char*)ptr
- offsetof(struct trace_context
, list
));
75 if (ctx
== VOID2U64(tr_ctx
))
83 static struct trace_shader
*
84 trace_rbug_get_shader_locked(struct trace_context
*tr_ctx
, rbug_shader_t shdr
)
86 struct trace_shader
*tr_shdr
= NULL
;
89 foreach(ptr
, &tr_ctx
->shaders
) {
90 tr_shdr
= (struct trace_shader
*)((char*)ptr
- offsetof(struct trace_shader
, list
));
91 if (shdr
== VOID2U64(tr_shdr
))
100 trace_shader_create_locked(struct pipe_context
*pipe
,
101 struct trace_shader
*tr_shdr
,
102 struct tgsi_token
*tokens
)
105 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
);
119 trace_shader_bind_locked(struct pipe_context
*pipe
,
120 struct trace_shader
*tr_shdr
,
123 if (tr_shdr
->type
== TRACE_SHADER_FRAGMENT
) {
124 pipe
->bind_fs_state(pipe
, state
);
125 } else if (tr_shdr
->type
== TRACE_SHADER_VERTEX
) {
126 pipe
->bind_vs_state(pipe
, state
);
132 trace_shader_delete_locked(struct pipe_context
*pipe
,
133 struct trace_shader
*tr_shdr
,
136 if (tr_shdr
->type
== TRACE_SHADER_FRAGMENT
) {
137 pipe
->delete_fs_state(pipe
, state
);
138 } else if (tr_shdr
->type
== TRACE_SHADER_VERTEX
) {
139 pipe
->delete_vs_state(pipe
, state
);
144 /************************************************
145 * Request handler functions
150 trace_rbug_texture_list(struct trace_rbug
*tr_rbug
, struct rbug_header
*header
, uint32_t serial
)
152 struct trace_screen
*tr_scr
= tr_rbug
->tr_scr
;
153 struct trace_texture
*tr_tex
= NULL
;
155 rbug_texture_t
*texs
;
158 pipe_mutex_lock(tr_scr
->list_mutex
);
159 texs
= MALLOC(tr_scr
->num_textures
* sizeof(rbug_texture_t
));
160 foreach(ptr
, &tr_scr
->textures
) {
161 tr_tex
= (struct trace_texture
*)((char*)ptr
- offsetof(struct trace_texture
, list
));
162 texs
[i
++] = VOID2U64(tr_tex
);
164 pipe_mutex_unlock(tr_scr
->list_mutex
);
166 rbug_send_texture_list_reply(tr_rbug
->con
, serial
, texs
, i
, NULL
);
173 trace_rbug_texture_info(struct trace_rbug
*tr_rbug
, struct rbug_header
*header
, uint32_t serial
)
175 struct trace_screen
*tr_scr
= tr_rbug
->tr_scr
;
176 struct trace_texture
*tr_tex
= NULL
;
177 struct rbug_proto_texture_info
*gpti
= (struct rbug_proto_texture_info
*)header
;
179 struct pipe_texture
*t
;
181 pipe_mutex_lock(tr_scr
->list_mutex
);
182 foreach(ptr
, &tr_scr
->textures
) {
183 tr_tex
= (struct trace_texture
*)((char*)ptr
- offsetof(struct trace_texture
, list
));
184 if (gpti
->texture
== VOID2U64(tr_tex
))
190 pipe_mutex_unlock(tr_scr
->list_mutex
);
195 rbug_send_texture_info_reply(tr_rbug
->con
, serial
,
196 t
->target
, t
->format
,
200 util_format_get_blockwidth(t
->format
),
201 util_format_get_blockheight(t
->format
),
202 util_format_get_blocksize(t
->format
),
208 pipe_mutex_unlock(tr_scr
->list_mutex
);
214 trace_rbug_texture_read(struct trace_rbug
*tr_rbug
, struct rbug_header
*header
, uint32_t serial
)
216 struct rbug_proto_texture_read
*gptr
= (struct rbug_proto_texture_read
*)header
;
218 struct trace_screen
*tr_scr
= tr_rbug
->tr_scr
;
219 struct trace_texture
*tr_tex
= NULL
;
222 struct pipe_context
*context
= tr_scr
->private_context
;
223 struct pipe_texture
*tex
;
224 struct pipe_transfer
*t
;
228 pipe_mutex_lock(tr_scr
->list_mutex
);
229 foreach(ptr
, &tr_scr
->textures
) {
230 tr_tex
= (struct trace_texture
*)((char*)ptr
- offsetof(struct trace_texture
, list
));
231 if (gptr
->texture
== VOID2U64(tr_tex
))
237 pipe_mutex_unlock(tr_scr
->list_mutex
);
241 tex
= tr_tex
->texture
;
242 t
= context
->get_tex_transfer(context
, tex
,
243 gptr
->face
, gptr
->level
, gptr
->zslice
,
245 gptr
->x
, gptr
->y
, gptr
->w
, gptr
->h
);
247 map
= context
->transfer_map(context
, t
);
249 rbug_send_texture_read_reply(tr_rbug
->con
, serial
,
251 util_format_get_blockwidth(t
->texture
->format
),
252 util_format_get_blockheight(t
->texture
->format
),
253 util_format_get_blocksize(t
->texture
->format
),
255 t
->stride
* util_format_get_nblocksy(t
->texture
->format
, t
->height
),
259 context
->transfer_unmap(context
, t
);
260 context
->tex_transfer_destroy(context
, t
);
262 pipe_mutex_unlock(tr_scr
->list_mutex
);
268 trace_rbug_context_list(struct trace_rbug
*tr_rbug
, struct rbug_header
*header
, uint32_t serial
)
270 struct trace_screen
*tr_scr
= tr_rbug
->tr_scr
;
272 struct trace_context
*tr_ctx
= NULL
;
273 rbug_context_t
*ctxs
;
276 pipe_mutex_lock(tr_scr
->list_mutex
);
277 ctxs
= MALLOC(tr_scr
->num_contexts
* sizeof(rbug_context_t
));
278 foreach(ptr
, &tr_scr
->contexts
) {
279 tr_ctx
= (struct trace_context
*)((char*)ptr
- offsetof(struct trace_context
, list
));
280 ctxs
[i
++] = VOID2U64(tr_ctx
);
282 pipe_mutex_unlock(tr_scr
->list_mutex
);
284 rbug_send_context_list_reply(tr_rbug
->con
, serial
, ctxs
, i
, NULL
);
291 trace_rbug_context_info(struct trace_rbug
*tr_rbug
, struct rbug_header
*header
, uint32_t serial
)
293 struct rbug_proto_context_info
*info
= (struct rbug_proto_context_info
*)header
;
295 struct trace_screen
*tr_scr
= tr_rbug
->tr_scr
;
296 struct trace_context
*tr_ctx
= NULL
;
297 rbug_texture_t cbufs
[PIPE_MAX_COLOR_BUFS
];
298 rbug_texture_t texs
[PIPE_MAX_SAMPLERS
];
301 pipe_mutex_lock(tr_scr
->list_mutex
);
302 tr_ctx
= trace_rbug_get_context_locked(tr_scr
, info
->context
);
305 pipe_mutex_unlock(tr_scr
->list_mutex
);
309 /* protect the pipe context */
310 pipe_mutex_lock(tr_ctx
->draw_mutex
);
311 trace_dump_call_lock();
313 for (i
= 0; i
< tr_ctx
->curr
.nr_cbufs
; i
++)
314 cbufs
[i
] = VOID2U64(tr_ctx
->curr
.cbufs
[i
]);
316 for (i
= 0; i
< tr_ctx
->curr
.num_sampler_views
; i
++)
317 texs
[i
] = VOID2U64(tr_ctx
->curr
.sampler_views
[i
]);
319 rbug_send_context_info_reply(tr_rbug
->con
, serial
,
320 VOID2U64(tr_ctx
->curr
.vs
), VOID2U64(tr_ctx
->curr
.fs
),
321 texs
, tr_ctx
->curr
.num_sampler_views
,
322 cbufs
, tr_ctx
->curr
.nr_cbufs
,
323 VOID2U64(tr_ctx
->curr
.zsbuf
),
324 tr_ctx
->draw_blocker
, tr_ctx
->draw_blocked
, NULL
);
326 trace_dump_call_unlock();
327 pipe_mutex_unlock(tr_ctx
->draw_mutex
);
329 pipe_mutex_unlock(tr_scr
->list_mutex
);
335 trace_rbug_context_draw_block(struct trace_rbug
*tr_rbug
, struct rbug_header
*header
, uint32_t serial
)
337 struct rbug_proto_context_draw_block
*block
= (struct rbug_proto_context_draw_block
*)header
;
339 struct trace_screen
*tr_scr
= tr_rbug
->tr_scr
;
340 struct trace_context
*tr_ctx
= NULL
;
342 pipe_mutex_lock(tr_scr
->list_mutex
);
343 tr_ctx
= trace_rbug_get_context_locked(tr_scr
, block
->context
);
346 pipe_mutex_unlock(tr_scr
->list_mutex
);
350 pipe_mutex_lock(tr_ctx
->draw_mutex
);
351 tr_ctx
->draw_blocker
|= block
->block
;
352 pipe_mutex_unlock(tr_ctx
->draw_mutex
);
354 pipe_mutex_unlock(tr_scr
->list_mutex
);
360 trace_rbug_context_draw_step(struct trace_rbug
*tr_rbug
, struct rbug_header
*header
, uint32_t serial
)
362 struct rbug_proto_context_draw_step
*step
= (struct rbug_proto_context_draw_step
*)header
;
364 struct trace_screen
*tr_scr
= tr_rbug
->tr_scr
;
365 struct trace_context
*tr_ctx
= NULL
;
367 pipe_mutex_lock(tr_scr
->list_mutex
);
368 tr_ctx
= trace_rbug_get_context_locked(tr_scr
, step
->context
);
371 pipe_mutex_unlock(tr_scr
->list_mutex
);
375 pipe_mutex_lock(tr_ctx
->draw_mutex
);
376 if (tr_ctx
->draw_blocked
& RBUG_BLOCK_RULE
) {
377 if (step
->step
& RBUG_BLOCK_RULE
)
378 tr_ctx
->draw_blocked
&= ~RBUG_BLOCK_MASK
;
380 tr_ctx
->draw_blocked
&= ~step
->step
;
382 pipe_mutex_unlock(tr_ctx
->draw_mutex
);
384 #ifdef PIPE_THREAD_HAVE_CONDVAR
385 pipe_condvar_broadcast(tr_ctx
->draw_cond
);
388 pipe_mutex_unlock(tr_scr
->list_mutex
);
394 trace_rbug_context_draw_unblock(struct trace_rbug
*tr_rbug
, struct rbug_header
*header
, uint32_t serial
)
396 struct rbug_proto_context_draw_unblock
*unblock
= (struct rbug_proto_context_draw_unblock
*)header
;
398 struct trace_screen
*tr_scr
= tr_rbug
->tr_scr
;
399 struct trace_context
*tr_ctx
= NULL
;
401 pipe_mutex_lock(tr_scr
->list_mutex
);
402 tr_ctx
= trace_rbug_get_context_locked(tr_scr
, unblock
->context
);
405 pipe_mutex_unlock(tr_scr
->list_mutex
);
409 pipe_mutex_lock(tr_ctx
->draw_mutex
);
410 if (tr_ctx
->draw_blocked
& RBUG_BLOCK_RULE
) {
411 if (unblock
->unblock
& RBUG_BLOCK_RULE
)
412 tr_ctx
->draw_blocked
&= ~RBUG_BLOCK_MASK
;
414 tr_ctx
->draw_blocked
&= ~unblock
->unblock
;
416 tr_ctx
->draw_blocker
&= ~unblock
->unblock
;
417 pipe_mutex_unlock(tr_ctx
->draw_mutex
);
419 #ifdef PIPE_THREAD_HAVE_CONDVAR
420 pipe_condvar_broadcast(tr_ctx
->draw_cond
);
423 pipe_mutex_unlock(tr_scr
->list_mutex
);
429 trace_rbug_context_draw_rule(struct trace_rbug
*tr_rbug
, struct rbug_header
*header
, uint32_t serial
)
431 struct rbug_proto_context_draw_rule
*rule
= (struct rbug_proto_context_draw_rule
*)header
;
433 struct trace_screen
*tr_scr
= tr_rbug
->tr_scr
;
434 struct trace_context
*tr_ctx
= NULL
;
436 pipe_mutex_lock(tr_scr
->list_mutex
);
437 tr_ctx
= trace_rbug_get_context_locked(tr_scr
, rule
->context
);
440 pipe_mutex_unlock(tr_scr
->list_mutex
);
444 pipe_mutex_lock(tr_ctx
->draw_mutex
);
445 tr_ctx
->draw_rule
.vs
= U642VOID(rule
->vertex
);
446 tr_ctx
->draw_rule
.fs
= U642VOID(rule
->fragment
);
447 tr_ctx
->draw_rule
.sampler_view
= U642VOID(rule
->texture
);
448 tr_ctx
->draw_rule
.surf
= U642VOID(rule
->surface
);
449 tr_ctx
->draw_rule
.blocker
= rule
->block
;
450 tr_ctx
->draw_blocker
|= RBUG_BLOCK_RULE
;
451 pipe_mutex_unlock(tr_ctx
->draw_mutex
);
453 #ifdef PIPE_THREAD_HAVE_CONDVAR
454 pipe_condvar_broadcast(tr_ctx
->draw_cond
);
457 pipe_mutex_unlock(tr_scr
->list_mutex
);
463 trace_rbug_context_flush(struct trace_rbug
*tr_rbug
, struct rbug_header
*header
, uint32_t serial
)
465 struct rbug_proto_context_flush
*flush
= (struct rbug_proto_context_flush
*)header
;
467 struct trace_screen
*tr_scr
= tr_rbug
->tr_scr
;
468 struct trace_context
*tr_ctx
= NULL
;
470 pipe_mutex_lock(tr_scr
->list_mutex
);
471 tr_ctx
= trace_rbug_get_context_locked(tr_scr
, flush
->context
);
474 pipe_mutex_unlock(tr_scr
->list_mutex
);
478 /* protect the pipe context */
479 trace_dump_call_lock();
481 tr_ctx
->pipe
->flush(tr_ctx
->pipe
, flush
->flags
, NULL
);
483 trace_dump_call_unlock();
484 pipe_mutex_unlock(tr_scr
->list_mutex
);
490 trace_rbug_shader_list(struct trace_rbug
*tr_rbug
, struct rbug_header
*header
, uint32_t serial
)
492 struct rbug_proto_shader_list
*list
= (struct rbug_proto_shader_list
*)header
;
494 struct trace_screen
*tr_scr
= tr_rbug
->tr_scr
;
495 struct trace_context
*tr_ctx
= NULL
;
496 struct trace_shader
*tr_shdr
= NULL
;
498 rbug_shader_t
*shdrs
;
501 pipe_mutex_lock(tr_scr
->list_mutex
);
502 tr_ctx
= trace_rbug_get_context_locked(tr_scr
, list
->context
);
505 pipe_mutex_unlock(tr_scr
->list_mutex
);
509 pipe_mutex_lock(tr_ctx
->list_mutex
);
510 shdrs
= MALLOC(tr_ctx
->num_shaders
* sizeof(rbug_shader_t
));
511 foreach(ptr
, &tr_ctx
->shaders
) {
512 tr_shdr
= (struct trace_shader
*)((char*)ptr
- offsetof(struct trace_shader
, list
));
513 shdrs
[i
++] = VOID2U64(tr_shdr
);
516 pipe_mutex_unlock(tr_ctx
->list_mutex
);
517 pipe_mutex_unlock(tr_scr
->list_mutex
);
519 rbug_send_shader_list_reply(tr_rbug
->con
, serial
, shdrs
, i
, NULL
);
526 trace_rbug_shader_info(struct trace_rbug
*tr_rbug
, struct rbug_header
*header
, uint32_t serial
)
528 struct rbug_proto_shader_info
*info
= (struct rbug_proto_shader_info
*)header
;
530 struct trace_screen
*tr_scr
= tr_rbug
->tr_scr
;
531 struct trace_context
*tr_ctx
= NULL
;
532 struct trace_shader
*tr_shdr
= NULL
;
533 unsigned original_len
;
534 unsigned replaced_len
;
536 pipe_mutex_lock(tr_scr
->list_mutex
);
537 tr_ctx
= trace_rbug_get_context_locked(tr_scr
, info
->context
);
540 pipe_mutex_unlock(tr_scr
->list_mutex
);
544 pipe_mutex_lock(tr_ctx
->list_mutex
);
546 tr_shdr
= trace_rbug_get_shader_locked(tr_ctx
, info
->shader
);
549 pipe_mutex_unlock(tr_ctx
->list_mutex
);
550 pipe_mutex_unlock(tr_scr
->list_mutex
);
555 assert(sizeof(struct tgsi_token
) == 4);
557 original_len
= tgsi_num_tokens(tr_shdr
->tokens
);
558 if (tr_shdr
->replaced_tokens
)
559 replaced_len
= tgsi_num_tokens(tr_shdr
->replaced_tokens
);
563 rbug_send_shader_info_reply(tr_rbug
->con
, serial
,
564 (uint32_t*)tr_shdr
->tokens
, original_len
,
565 (uint32_t*)tr_shdr
->replaced_tokens
, replaced_len
,
569 pipe_mutex_unlock(tr_ctx
->list_mutex
);
570 pipe_mutex_unlock(tr_scr
->list_mutex
);
576 trace_rbug_shader_disable(struct trace_rbug
*tr_rbug
, struct rbug_header
*header
)
578 struct rbug_proto_shader_disable
*dis
= (struct rbug_proto_shader_disable
*)header
;
580 struct trace_screen
*tr_scr
= tr_rbug
->tr_scr
;
581 struct trace_context
*tr_ctx
= NULL
;
582 struct trace_shader
*tr_shdr
= NULL
;
584 pipe_mutex_lock(tr_scr
->list_mutex
);
585 tr_ctx
= trace_rbug_get_context_locked(tr_scr
, dis
->context
);
588 pipe_mutex_unlock(tr_scr
->list_mutex
);
592 pipe_mutex_lock(tr_ctx
->list_mutex
);
594 tr_shdr
= trace_rbug_get_shader_locked(tr_ctx
, dis
->shader
);
597 pipe_mutex_unlock(tr_ctx
->list_mutex
);
598 pipe_mutex_unlock(tr_scr
->list_mutex
);
602 tr_shdr
->disabled
= dis
->disable
;
604 pipe_mutex_unlock(tr_ctx
->list_mutex
);
605 pipe_mutex_unlock(tr_scr
->list_mutex
);
611 trace_rbug_shader_replace(struct trace_rbug
*tr_rbug
, struct rbug_header
*header
)
613 struct rbug_proto_shader_replace
*rep
= (struct rbug_proto_shader_replace
*)header
;
615 struct trace_screen
*tr_scr
= tr_rbug
->tr_scr
;
616 struct trace_context
*tr_ctx
= NULL
;
617 struct trace_shader
*tr_shdr
= NULL
;
618 struct pipe_context
*pipe
= NULL
;
621 pipe_mutex_lock(tr_scr
->list_mutex
);
622 tr_ctx
= trace_rbug_get_context_locked(tr_scr
, rep
->context
);
625 pipe_mutex_unlock(tr_scr
->list_mutex
);
629 pipe_mutex_lock(tr_ctx
->list_mutex
);
631 tr_shdr
= trace_rbug_get_shader_locked(tr_ctx
, rep
->shader
);
634 pipe_mutex_unlock(tr_ctx
->list_mutex
);
635 pipe_mutex_unlock(tr_scr
->list_mutex
);
639 /* protect the pipe context */
640 trace_dump_call_lock();
644 /* remove old replaced shader */
645 if (tr_shdr
->replaced
) {
646 if (tr_ctx
->curr
.fs
== tr_shdr
|| tr_ctx
->curr
.vs
== tr_shdr
)
647 trace_shader_bind_locked(pipe
, tr_shdr
, tr_shdr
->state
);
649 FREE(tr_shdr
->replaced_tokens
);
650 trace_shader_delete_locked(pipe
, tr_shdr
, tr_shdr
->replaced
);
651 tr_shdr
->replaced
= NULL
;
652 tr_shdr
->replaced_tokens
= NULL
;
655 /* empty inputs means restore old which we did above */
656 if (rep
->tokens_len
== 0)
659 tr_shdr
->replaced_tokens
= tgsi_dup_tokens((struct tgsi_token
*)rep
->tokens
);
660 if (!tr_shdr
->replaced_tokens
)
663 state
= trace_shader_create_locked(pipe
, tr_shdr
, tr_shdr
->replaced_tokens
);
667 /* bind new shader if the shader is currently a bound */
668 if (tr_ctx
->curr
.fs
== tr_shdr
|| tr_ctx
->curr
.vs
== tr_shdr
)
669 trace_shader_bind_locked(pipe
, tr_shdr
, state
);
672 tr_shdr
->replaced
= state
;
675 trace_dump_call_unlock();
676 pipe_mutex_unlock(tr_ctx
->list_mutex
);
677 pipe_mutex_unlock(tr_scr
->list_mutex
);
682 FREE(tr_shdr
->replaced_tokens
);
683 tr_shdr
->replaced
= NULL
;
684 tr_shdr
->replaced_tokens
= NULL
;
686 trace_dump_call_unlock();
687 pipe_mutex_unlock(tr_ctx
->list_mutex
);
688 pipe_mutex_unlock(tr_scr
->list_mutex
);
693 trace_rbug_header(struct trace_rbug
*tr_rbug
, struct rbug_header
*header
, uint32_t serial
)
697 switch(header
->opcode
) {
699 rbug_send_ping_reply(tr_rbug
->con
, serial
, NULL
);
701 case RBUG_OP_TEXTURE_LIST
:
702 ret
= trace_rbug_texture_list(tr_rbug
, header
, serial
);
704 case RBUG_OP_TEXTURE_INFO
:
705 ret
= trace_rbug_texture_info(tr_rbug
, header
, serial
);
707 case RBUG_OP_TEXTURE_READ
:
708 ret
= trace_rbug_texture_read(tr_rbug
, header
, serial
);
710 case RBUG_OP_CONTEXT_LIST
:
711 ret
= trace_rbug_context_list(tr_rbug
, header
, serial
);
713 case RBUG_OP_CONTEXT_INFO
:
714 ret
= trace_rbug_context_info(tr_rbug
, header
, serial
);
716 case RBUG_OP_CONTEXT_DRAW_BLOCK
:
717 ret
= trace_rbug_context_draw_block(tr_rbug
, header
, serial
);
719 case RBUG_OP_CONTEXT_DRAW_STEP
:
720 ret
= trace_rbug_context_draw_step(tr_rbug
, header
, serial
);
722 case RBUG_OP_CONTEXT_DRAW_UNBLOCK
:
723 ret
= trace_rbug_context_draw_unblock(tr_rbug
, header
, serial
);
725 case RBUG_OP_CONTEXT_DRAW_RULE
:
726 ret
= trace_rbug_context_draw_rule(tr_rbug
, header
, serial
);
728 case RBUG_OP_CONTEXT_FLUSH
:
729 ret
= trace_rbug_context_flush(tr_rbug
, header
, serial
);
731 case RBUG_OP_SHADER_LIST
:
732 ret
= trace_rbug_shader_list(tr_rbug
, header
, serial
);
734 case RBUG_OP_SHADER_INFO
:
735 ret
= trace_rbug_shader_info(tr_rbug
, header
, serial
);
737 case RBUG_OP_SHADER_DISABLE
:
738 ret
= trace_rbug_shader_disable(tr_rbug
, header
);
740 case RBUG_OP_SHADER_REPLACE
:
741 ret
= trace_rbug_shader_replace(tr_rbug
, header
);
744 debug_printf("%s - unsupported opcode %u\n", __FUNCTION__
, header
->opcode
);
748 rbug_free_header(header
);
751 rbug_send_error_reply(tr_rbug
->con
, serial
, ret
, NULL
);
757 trace_rbug_con(struct trace_rbug
*tr_rbug
)
759 struct rbug_header
*header
;
762 debug_printf("%s - connection received\n", __FUNCTION__
);
764 while(tr_rbug
->running
) {
765 header
= rbug_get_message(tr_rbug
->con
, &serial
);
769 if (!trace_rbug_header(tr_rbug
, header
, serial
))
773 debug_printf("%s - connection closed\n", __FUNCTION__
);
775 rbug_disconnect(tr_rbug
->con
);
779 PIPE_THREAD_ROUTINE(trace_rbug_thread
, void_tr_rbug
)
781 struct trace_rbug
*tr_rbug
= void_tr_rbug
;
782 uint16_t port
= 13370;
788 for (;port
<= 13379 && s
< 0; port
++)
789 s
= u_socket_listen_on_port(port
);
792 debug_printf("trace_rbug - failed to listen\n");
796 u_socket_block(s
, false);
798 debug_printf("trace_rbug - remote debugging listening on port %u\n", --port
);
800 while(tr_rbug
->running
) {
803 c
= u_socket_accept(s
);
807 u_socket_block(c
, true);
808 tr_rbug
->con
= rbug_from_socket(c
);
810 trace_rbug_con(tr_rbug
);
822 /**********************************************************
827 trace_rbug_start(struct trace_screen
*tr_scr
)
829 struct trace_rbug
*tr_rbug
= CALLOC_STRUCT(trace_rbug
);
833 tr_rbug
->tr_scr
= tr_scr
;
834 tr_rbug
->running
= TRUE
;
835 tr_rbug
->thread
= pipe_thread_create(trace_rbug_thread
, tr_rbug
);
841 trace_rbug_stop(struct trace_rbug
*tr_rbug
)
846 tr_rbug
->running
= false;
847 pipe_thread_wait(tr_rbug
->thread
);
855 trace_rbug_notify_draw_blocked(struct trace_context
*tr_ctx
)
857 struct trace_screen
*tr_scr
= trace_screen(tr_ctx
->base
.screen
);
858 struct trace_rbug
*tr_rbug
= tr_scr
->rbug
;
860 if (tr_rbug
&& tr_rbug
->con
)
861 rbug_send_context_draw_blocked(tr_rbug
->con
,
862 VOID2U64(tr_ctx
), tr_ctx
->draw_blocked
, NULL
);