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_format.h"
30 #include "util/u_string.h"
31 #include "util/u_memory.h"
32 #include "util/u_simple_list.h"
33 #include "util/u_network.h"
35 #include "tgsi/tgsi_parse.h"
39 #include "tr_buffer.h"
40 #include "tr_texture.h"
42 #include "rbug/rbug.h"
46 #if defined(PIPE_SUBSYSTEM_WINDOWS_USER)
48 #elif defined(PIPE_OS_LINUX) || defined(PIPE_OS_APPLE)
52 # warning "No socket implementation"
55 #define U642VOID(x) ((void *)(unsigned long)(x))
56 #define VOID2U64(x) ((uint64_t)(unsigned long)(x))
60 struct trace_screen
*tr_scr
;
61 struct rbug_connection
*con
;
66 PIPE_THREAD_ROUTINE(trace_rbug_thread
, void_tr_rbug
);
69 /**********************************************************
74 static struct trace_context
*
75 trace_rbug_get_context_locked(struct trace_screen
*tr_scr
, rbug_context_t ctx
)
77 struct trace_context
*tr_ctx
= NULL
;
80 foreach(ptr
, &tr_scr
->contexts
) {
81 tr_ctx
= (struct trace_context
*)((char*)ptr
- offsetof(struct trace_context
, list
));
82 if (ctx
== VOID2U64(tr_ctx
))
90 static struct trace_shader
*
91 trace_rbug_get_shader_locked(struct trace_context
*tr_ctx
, rbug_shader_t shdr
)
93 struct trace_shader
*tr_shdr
= NULL
;
96 foreach(ptr
, &tr_ctx
->shaders
) {
97 tr_shdr
= (struct trace_shader
*)((char*)ptr
- offsetof(struct trace_shader
, list
));
98 if (shdr
== VOID2U64(tr_shdr
))
107 trace_shader_create_locked(struct pipe_context
*pipe
,
108 struct trace_shader
*tr_shdr
,
109 struct tgsi_token
*tokens
)
112 struct pipe_shader_state pss
= { 0 };
115 if (tr_shdr
->type
== TRACE_SHADER_FRAGMENT
) {
116 state
= pipe
->create_fs_state(pipe
, &pss
);
117 } else if (tr_shdr
->type
== TRACE_SHADER_VERTEX
) {
118 state
= pipe
->create_vs_state(pipe
, &pss
);
126 trace_shader_bind_locked(struct pipe_context
*pipe
,
127 struct trace_shader
*tr_shdr
,
130 if (tr_shdr
->type
== TRACE_SHADER_FRAGMENT
) {
131 pipe
->bind_fs_state(pipe
, state
);
132 } else if (tr_shdr
->type
== TRACE_SHADER_VERTEX
) {
133 pipe
->bind_vs_state(pipe
, state
);
139 trace_shader_delete_locked(struct pipe_context
*pipe
,
140 struct trace_shader
*tr_shdr
,
143 if (tr_shdr
->type
== TRACE_SHADER_FRAGMENT
) {
144 pipe
->delete_fs_state(pipe
, state
);
145 } else if (tr_shdr
->type
== TRACE_SHADER_VERTEX
) {
146 pipe
->delete_vs_state(pipe
, state
);
151 /************************************************
152 * Request handler functions
157 trace_rbug_texture_list(struct trace_rbug
*tr_rbug
, struct rbug_header
*header
, uint32_t serial
)
159 struct trace_screen
*tr_scr
= tr_rbug
->tr_scr
;
160 struct trace_texture
*tr_tex
= NULL
;
162 rbug_texture_t
*texs
;
165 pipe_mutex_lock(tr_scr
->list_mutex
);
166 texs
= MALLOC(tr_scr
->num_textures
* sizeof(rbug_texture_t
));
167 foreach(ptr
, &tr_scr
->textures
) {
168 tr_tex
= (struct trace_texture
*)((char*)ptr
- offsetof(struct trace_texture
, list
));
169 texs
[i
++] = VOID2U64(tr_tex
);
171 pipe_mutex_unlock(tr_scr
->list_mutex
);
173 rbug_send_texture_list_reply(tr_rbug
->con
, serial
, texs
, i
, NULL
);
180 trace_rbug_texture_info(struct trace_rbug
*tr_rbug
, struct rbug_header
*header
, uint32_t serial
)
182 struct trace_screen
*tr_scr
= tr_rbug
->tr_scr
;
183 struct trace_texture
*tr_tex
= NULL
;
184 struct rbug_proto_texture_info
*gpti
= (struct rbug_proto_texture_info
*)header
;
186 struct pipe_texture
*t
;
188 pipe_mutex_lock(tr_scr
->list_mutex
);
189 foreach(ptr
, &tr_scr
->textures
) {
190 tr_tex
= (struct trace_texture
*)((char*)ptr
- offsetof(struct trace_texture
, list
));
191 if (gpti
->texture
== VOID2U64(tr_tex
))
197 pipe_mutex_unlock(tr_scr
->list_mutex
);
202 rbug_send_texture_info_reply(tr_rbug
->con
, serial
,
203 t
->target
, t
->format
,
207 util_format_get_blockwidth(t
->format
),
208 util_format_get_blockheight(t
->format
),
209 util_format_get_blocksize(t
->format
),
215 pipe_mutex_unlock(tr_scr
->list_mutex
);
221 trace_rbug_texture_read(struct trace_rbug
*tr_rbug
, struct rbug_header
*header
, uint32_t serial
)
223 struct rbug_proto_texture_read
*gptr
= (struct rbug_proto_texture_read
*)header
;
225 struct trace_screen
*tr_scr
= tr_rbug
->tr_scr
;
226 struct trace_texture
*tr_tex
= NULL
;
229 struct pipe_screen
*screen
= tr_scr
->screen
;
230 struct pipe_texture
*tex
;
231 struct pipe_transfer
*t
;
235 pipe_mutex_lock(tr_scr
->list_mutex
);
236 foreach(ptr
, &tr_scr
->textures
) {
237 tr_tex
= (struct trace_texture
*)((char*)ptr
- offsetof(struct trace_texture
, list
));
238 if (gptr
->texture
== VOID2U64(tr_tex
))
244 pipe_mutex_unlock(tr_scr
->list_mutex
);
248 tex
= tr_tex
->texture
;
249 t
= screen
->get_tex_transfer(tr_scr
->screen
, tex
,
250 gptr
->face
, gptr
->level
, gptr
->zslice
,
252 gptr
->x
, gptr
->y
, gptr
->w
, gptr
->h
);
254 map
= screen
->transfer_map(screen
, t
);
256 rbug_send_texture_read_reply(tr_rbug
->con
, serial
,
258 util_format_get_blockwidth(t
->texture
->format
),
259 util_format_get_blockheight(t
->texture
->format
),
260 util_format_get_blocksize(t
->texture
->format
),
262 t
->stride
* util_format_get_nblocksy(t
->texture
->format
, t
->height
),
266 screen
->transfer_unmap(screen
, t
);
267 screen
->tex_transfer_destroy(t
);
269 pipe_mutex_unlock(tr_scr
->list_mutex
);
275 trace_rbug_context_list(struct trace_rbug
*tr_rbug
, struct rbug_header
*header
, uint32_t serial
)
277 struct trace_screen
*tr_scr
= tr_rbug
->tr_scr
;
279 struct trace_context
*tr_ctx
= NULL
;
280 rbug_context_t
*ctxs
;
283 pipe_mutex_lock(tr_scr
->list_mutex
);
284 ctxs
= MALLOC(tr_scr
->num_contexts
* sizeof(rbug_context_t
));
285 foreach(ptr
, &tr_scr
->contexts
) {
286 tr_ctx
= (struct trace_context
*)((char*)ptr
- offsetof(struct trace_context
, list
));
287 ctxs
[i
++] = VOID2U64(tr_ctx
);
289 pipe_mutex_unlock(tr_scr
->list_mutex
);
291 rbug_send_context_list_reply(tr_rbug
->con
, serial
, ctxs
, i
, NULL
);
298 trace_rbug_context_info(struct trace_rbug
*tr_rbug
, struct rbug_header
*header
, uint32_t serial
)
300 struct rbug_proto_context_info
*info
= (struct rbug_proto_context_info
*)header
;
302 struct trace_screen
*tr_scr
= tr_rbug
->tr_scr
;
303 struct trace_context
*tr_ctx
= NULL
;
304 rbug_texture_t cbufs
[PIPE_MAX_COLOR_BUFS
];
305 rbug_texture_t texs
[PIPE_MAX_SAMPLERS
];
308 pipe_mutex_lock(tr_scr
->list_mutex
);
309 tr_ctx
= trace_rbug_get_context_locked(tr_scr
, info
->context
);
312 pipe_mutex_unlock(tr_scr
->list_mutex
);
316 /* protect the pipe context */
317 pipe_mutex_lock(tr_ctx
->draw_mutex
);
318 trace_dump_call_lock();
320 for (i
= 0; i
< tr_ctx
->curr
.nr_cbufs
; i
++)
321 cbufs
[i
] = VOID2U64(tr_ctx
->curr
.cbufs
[i
]);
323 for (i
= 0; i
< tr_ctx
->curr
.num_texs
; i
++)
324 texs
[i
] = VOID2U64(tr_ctx
->curr
.tex
[i
]);
326 rbug_send_context_info_reply(tr_rbug
->con
, serial
,
327 VOID2U64(tr_ctx
->curr
.vs
), VOID2U64(tr_ctx
->curr
.fs
),
328 texs
, tr_ctx
->curr
.num_texs
,
329 cbufs
, tr_ctx
->curr
.nr_cbufs
,
330 VOID2U64(tr_ctx
->curr
.zsbuf
),
331 tr_ctx
->draw_blocker
, tr_ctx
->draw_blocked
, NULL
);
333 trace_dump_call_unlock();
334 pipe_mutex_unlock(tr_ctx
->draw_mutex
);
336 pipe_mutex_unlock(tr_scr
->list_mutex
);
342 trace_rbug_context_draw_block(struct trace_rbug
*tr_rbug
, struct rbug_header
*header
, uint32_t serial
)
344 struct rbug_proto_context_draw_block
*block
= (struct rbug_proto_context_draw_block
*)header
;
346 struct trace_screen
*tr_scr
= tr_rbug
->tr_scr
;
347 struct trace_context
*tr_ctx
= NULL
;
349 pipe_mutex_lock(tr_scr
->list_mutex
);
350 tr_ctx
= trace_rbug_get_context_locked(tr_scr
, block
->context
);
353 pipe_mutex_unlock(tr_scr
->list_mutex
);
357 pipe_mutex_lock(tr_ctx
->draw_mutex
);
358 tr_ctx
->draw_blocker
|= block
->block
;
359 pipe_mutex_unlock(tr_ctx
->draw_mutex
);
361 pipe_mutex_unlock(tr_scr
->list_mutex
);
367 trace_rbug_context_draw_step(struct trace_rbug
*tr_rbug
, struct rbug_header
*header
, uint32_t serial
)
369 struct rbug_proto_context_draw_step
*step
= (struct rbug_proto_context_draw_step
*)header
;
371 struct trace_screen
*tr_scr
= tr_rbug
->tr_scr
;
372 struct trace_context
*tr_ctx
= NULL
;
374 pipe_mutex_lock(tr_scr
->list_mutex
);
375 tr_ctx
= trace_rbug_get_context_locked(tr_scr
, step
->context
);
378 pipe_mutex_unlock(tr_scr
->list_mutex
);
382 pipe_mutex_lock(tr_ctx
->draw_mutex
);
383 if (tr_ctx
->draw_blocked
& RBUG_BLOCK_RULE
) {
384 if (step
->step
& RBUG_BLOCK_RULE
)
385 tr_ctx
->draw_blocked
&= ~RBUG_BLOCK_MASK
;
387 tr_ctx
->draw_blocked
&= ~step
->step
;
389 pipe_mutex_unlock(tr_ctx
->draw_mutex
);
391 #ifdef PIPE_THREAD_HAVE_CONDVAR
392 pipe_condvar_broadcast(tr_ctx
->draw_cond
);
395 pipe_mutex_unlock(tr_scr
->list_mutex
);
401 trace_rbug_context_draw_unblock(struct trace_rbug
*tr_rbug
, struct rbug_header
*header
, uint32_t serial
)
403 struct rbug_proto_context_draw_unblock
*unblock
= (struct rbug_proto_context_draw_unblock
*)header
;
405 struct trace_screen
*tr_scr
= tr_rbug
->tr_scr
;
406 struct trace_context
*tr_ctx
= NULL
;
408 pipe_mutex_lock(tr_scr
->list_mutex
);
409 tr_ctx
= trace_rbug_get_context_locked(tr_scr
, unblock
->context
);
412 pipe_mutex_unlock(tr_scr
->list_mutex
);
416 pipe_mutex_lock(tr_ctx
->draw_mutex
);
417 if (tr_ctx
->draw_blocked
& RBUG_BLOCK_RULE
) {
418 if (unblock
->unblock
& RBUG_BLOCK_RULE
)
419 tr_ctx
->draw_blocked
&= ~RBUG_BLOCK_MASK
;
421 tr_ctx
->draw_blocked
&= ~unblock
->unblock
;
423 tr_ctx
->draw_blocker
&= ~unblock
->unblock
;
424 pipe_mutex_unlock(tr_ctx
->draw_mutex
);
426 #ifdef PIPE_THREAD_HAVE_CONDVAR
427 pipe_condvar_broadcast(tr_ctx
->draw_cond
);
430 pipe_mutex_unlock(tr_scr
->list_mutex
);
436 trace_rbug_context_draw_rule(struct trace_rbug
*tr_rbug
, struct rbug_header
*header
, uint32_t serial
)
438 struct rbug_proto_context_draw_rule
*rule
= (struct rbug_proto_context_draw_rule
*)header
;
440 struct trace_screen
*tr_scr
= tr_rbug
->tr_scr
;
441 struct trace_context
*tr_ctx
= NULL
;
443 pipe_mutex_lock(tr_scr
->list_mutex
);
444 tr_ctx
= trace_rbug_get_context_locked(tr_scr
, rule
->context
);
447 pipe_mutex_unlock(tr_scr
->list_mutex
);
451 pipe_mutex_lock(tr_ctx
->draw_mutex
);
452 tr_ctx
->draw_rule
.vs
= U642VOID(rule
->vertex
);
453 tr_ctx
->draw_rule
.fs
= U642VOID(rule
->fragment
);
454 tr_ctx
->draw_rule
.tex
= U642VOID(rule
->texture
);
455 tr_ctx
->draw_rule
.surf
= U642VOID(rule
->surface
);
456 tr_ctx
->draw_rule
.blocker
= rule
->block
;
457 tr_ctx
->draw_blocker
|= RBUG_BLOCK_RULE
;
458 pipe_mutex_unlock(tr_ctx
->draw_mutex
);
460 #ifdef PIPE_THREAD_HAVE_CONDVAR
461 pipe_condvar_broadcast(tr_ctx
->draw_cond
);
464 pipe_mutex_unlock(tr_scr
->list_mutex
);
470 trace_rbug_context_flush(struct trace_rbug
*tr_rbug
, struct rbug_header
*header
, uint32_t serial
)
472 struct rbug_proto_context_flush
*flush
= (struct rbug_proto_context_flush
*)header
;
474 struct trace_screen
*tr_scr
= tr_rbug
->tr_scr
;
475 struct trace_context
*tr_ctx
= NULL
;
477 pipe_mutex_lock(tr_scr
->list_mutex
);
478 tr_ctx
= trace_rbug_get_context_locked(tr_scr
, flush
->context
);
481 pipe_mutex_unlock(tr_scr
->list_mutex
);
485 /* protect the pipe context */
486 trace_dump_call_lock();
488 tr_ctx
->pipe
->flush(tr_ctx
->pipe
, flush
->flags
, NULL
);
490 trace_dump_call_unlock();
491 pipe_mutex_unlock(tr_scr
->list_mutex
);
497 trace_rbug_shader_list(struct trace_rbug
*tr_rbug
, struct rbug_header
*header
, uint32_t serial
)
499 struct rbug_proto_shader_list
*list
= (struct rbug_proto_shader_list
*)header
;
501 struct trace_screen
*tr_scr
= tr_rbug
->tr_scr
;
502 struct trace_context
*tr_ctx
= NULL
;
503 struct trace_shader
*tr_shdr
= NULL
;
505 rbug_shader_t
*shdrs
;
508 pipe_mutex_lock(tr_scr
->list_mutex
);
509 tr_ctx
= trace_rbug_get_context_locked(tr_scr
, list
->context
);
512 pipe_mutex_unlock(tr_scr
->list_mutex
);
516 pipe_mutex_lock(tr_ctx
->list_mutex
);
517 shdrs
= MALLOC(tr_ctx
->num_shaders
* sizeof(rbug_shader_t
));
518 foreach(ptr
, &tr_ctx
->shaders
) {
519 tr_shdr
= (struct trace_shader
*)((char*)ptr
- offsetof(struct trace_shader
, list
));
520 shdrs
[i
++] = VOID2U64(tr_shdr
);
523 pipe_mutex_unlock(tr_ctx
->list_mutex
);
524 pipe_mutex_unlock(tr_scr
->list_mutex
);
526 rbug_send_shader_list_reply(tr_rbug
->con
, serial
, shdrs
, i
, NULL
);
533 trace_rbug_shader_info(struct trace_rbug
*tr_rbug
, struct rbug_header
*header
, uint32_t serial
)
535 struct rbug_proto_shader_info
*info
= (struct rbug_proto_shader_info
*)header
;
537 struct trace_screen
*tr_scr
= tr_rbug
->tr_scr
;
538 struct trace_context
*tr_ctx
= NULL
;
539 struct trace_shader
*tr_shdr
= NULL
;
540 unsigned original_len
;
541 unsigned replaced_len
;
543 pipe_mutex_lock(tr_scr
->list_mutex
);
544 tr_ctx
= trace_rbug_get_context_locked(tr_scr
, info
->context
);
547 pipe_mutex_unlock(tr_scr
->list_mutex
);
551 pipe_mutex_lock(tr_ctx
->list_mutex
);
553 tr_shdr
= trace_rbug_get_shader_locked(tr_ctx
, info
->shader
);
556 pipe_mutex_unlock(tr_ctx
->list_mutex
);
557 pipe_mutex_unlock(tr_scr
->list_mutex
);
562 assert(sizeof(struct tgsi_token
) == 4);
564 original_len
= tgsi_num_tokens(tr_shdr
->tokens
);
565 if (tr_shdr
->replaced_tokens
)
566 replaced_len
= tgsi_num_tokens(tr_shdr
->replaced_tokens
);
570 rbug_send_shader_info_reply(tr_rbug
->con
, serial
,
571 (uint32_t*)tr_shdr
->tokens
, original_len
,
572 (uint32_t*)tr_shdr
->replaced_tokens
, replaced_len
,
576 pipe_mutex_unlock(tr_ctx
->list_mutex
);
577 pipe_mutex_unlock(tr_scr
->list_mutex
);
583 trace_rbug_shader_disable(struct trace_rbug
*tr_rbug
, struct rbug_header
*header
)
585 struct rbug_proto_shader_disable
*dis
= (struct rbug_proto_shader_disable
*)header
;
587 struct trace_screen
*tr_scr
= tr_rbug
->tr_scr
;
588 struct trace_context
*tr_ctx
= NULL
;
589 struct trace_shader
*tr_shdr
= NULL
;
591 pipe_mutex_lock(tr_scr
->list_mutex
);
592 tr_ctx
= trace_rbug_get_context_locked(tr_scr
, dis
->context
);
595 pipe_mutex_unlock(tr_scr
->list_mutex
);
599 pipe_mutex_lock(tr_ctx
->list_mutex
);
601 tr_shdr
= trace_rbug_get_shader_locked(tr_ctx
, dis
->shader
);
604 pipe_mutex_unlock(tr_ctx
->list_mutex
);
605 pipe_mutex_unlock(tr_scr
->list_mutex
);
609 tr_shdr
->disabled
= dis
->disable
;
611 pipe_mutex_unlock(tr_ctx
->list_mutex
);
612 pipe_mutex_unlock(tr_scr
->list_mutex
);
618 trace_rbug_shader_replace(struct trace_rbug
*tr_rbug
, struct rbug_header
*header
)
620 struct rbug_proto_shader_replace
*rep
= (struct rbug_proto_shader_replace
*)header
;
622 struct trace_screen
*tr_scr
= tr_rbug
->tr_scr
;
623 struct trace_context
*tr_ctx
= NULL
;
624 struct trace_shader
*tr_shdr
= NULL
;
625 struct pipe_context
*pipe
= NULL
;
628 pipe_mutex_lock(tr_scr
->list_mutex
);
629 tr_ctx
= trace_rbug_get_context_locked(tr_scr
, rep
->context
);
632 pipe_mutex_unlock(tr_scr
->list_mutex
);
636 pipe_mutex_lock(tr_ctx
->list_mutex
);
638 tr_shdr
= trace_rbug_get_shader_locked(tr_ctx
, rep
->shader
);
641 pipe_mutex_unlock(tr_ctx
->list_mutex
);
642 pipe_mutex_unlock(tr_scr
->list_mutex
);
646 /* protect the pipe context */
647 trace_dump_call_lock();
651 /* remove old replaced shader */
652 if (tr_shdr
->replaced
) {
653 if (tr_ctx
->curr
.fs
== tr_shdr
|| tr_ctx
->curr
.vs
== tr_shdr
)
654 trace_shader_bind_locked(pipe
, tr_shdr
, tr_shdr
->state
);
656 FREE(tr_shdr
->replaced_tokens
);
657 trace_shader_delete_locked(pipe
, tr_shdr
, tr_shdr
->replaced
);
658 tr_shdr
->replaced
= NULL
;
659 tr_shdr
->replaced_tokens
= NULL
;
662 /* empty inputs means restore old which we did above */
663 if (rep
->tokens_len
== 0)
666 tr_shdr
->replaced_tokens
= tgsi_dup_tokens((struct tgsi_token
*)rep
->tokens
);
667 if (!tr_shdr
->replaced_tokens
)
670 state
= trace_shader_create_locked(pipe
, tr_shdr
, tr_shdr
->replaced_tokens
);
674 /* bind new shader if the shader is currently a bound */
675 if (tr_ctx
->curr
.fs
== tr_shdr
|| tr_ctx
->curr
.vs
== tr_shdr
)
676 trace_shader_bind_locked(pipe
, tr_shdr
, state
);
679 tr_shdr
->replaced
= state
;
682 trace_dump_call_unlock();
683 pipe_mutex_unlock(tr_ctx
->list_mutex
);
684 pipe_mutex_unlock(tr_scr
->list_mutex
);
689 FREE(tr_shdr
->replaced_tokens
);
690 tr_shdr
->replaced
= NULL
;
691 tr_shdr
->replaced_tokens
= NULL
;
693 trace_dump_call_unlock();
694 pipe_mutex_unlock(tr_ctx
->list_mutex
);
695 pipe_mutex_unlock(tr_scr
->list_mutex
);
700 trace_rbug_header(struct trace_rbug
*tr_rbug
, struct rbug_header
*header
, uint32_t serial
)
704 switch(header
->opcode
) {
706 rbug_send_ping_reply(tr_rbug
->con
, serial
, NULL
);
708 case RBUG_OP_TEXTURE_LIST
:
709 ret
= trace_rbug_texture_list(tr_rbug
, header
, serial
);
711 case RBUG_OP_TEXTURE_INFO
:
712 ret
= trace_rbug_texture_info(tr_rbug
, header
, serial
);
714 case RBUG_OP_TEXTURE_READ
:
715 ret
= trace_rbug_texture_read(tr_rbug
, header
, serial
);
717 case RBUG_OP_CONTEXT_LIST
:
718 ret
= trace_rbug_context_list(tr_rbug
, header
, serial
);
720 case RBUG_OP_CONTEXT_INFO
:
721 ret
= trace_rbug_context_info(tr_rbug
, header
, serial
);
723 case RBUG_OP_CONTEXT_DRAW_BLOCK
:
724 ret
= trace_rbug_context_draw_block(tr_rbug
, header
, serial
);
726 case RBUG_OP_CONTEXT_DRAW_STEP
:
727 ret
= trace_rbug_context_draw_step(tr_rbug
, header
, serial
);
729 case RBUG_OP_CONTEXT_DRAW_UNBLOCK
:
730 ret
= trace_rbug_context_draw_unblock(tr_rbug
, header
, serial
);
732 case RBUG_OP_CONTEXT_DRAW_RULE
:
733 ret
= trace_rbug_context_draw_rule(tr_rbug
, header
, serial
);
735 case RBUG_OP_CONTEXT_FLUSH
:
736 ret
= trace_rbug_context_flush(tr_rbug
, header
, serial
);
738 case RBUG_OP_SHADER_LIST
:
739 ret
= trace_rbug_shader_list(tr_rbug
, header
, serial
);
741 case RBUG_OP_SHADER_INFO
:
742 ret
= trace_rbug_shader_info(tr_rbug
, header
, serial
);
744 case RBUG_OP_SHADER_DISABLE
:
745 ret
= trace_rbug_shader_disable(tr_rbug
, header
);
747 case RBUG_OP_SHADER_REPLACE
:
748 ret
= trace_rbug_shader_replace(tr_rbug
, header
);
751 debug_printf("%s - unsupported opcode %u\n", __FUNCTION__
, header
->opcode
);
755 rbug_free_header(header
);
758 rbug_send_error_reply(tr_rbug
->con
, serial
, ret
, NULL
);
764 trace_rbug_con(struct trace_rbug
*tr_rbug
)
766 struct rbug_header
*header
;
769 debug_printf("%s - connection received\n", __FUNCTION__
);
771 while(tr_rbug
->running
) {
772 header
= rbug_get_message(tr_rbug
->con
, &serial
);
776 if (!trace_rbug_header(tr_rbug
, header
, serial
))
780 debug_printf("%s - connection closed\n", __FUNCTION__
);
782 rbug_disconnect(tr_rbug
->con
);
786 PIPE_THREAD_ROUTINE(trace_rbug_thread
, void_tr_rbug
)
788 struct trace_rbug
*tr_rbug
= void_tr_rbug
;
789 uint16_t port
= 13370;
795 for (;port
<= 13379 && s
< 0; port
++)
796 s
= u_socket_listen_on_port(port
);
799 debug_printf("trace_rbug - failed to listen\n");
803 u_socket_block(s
, false);
805 debug_printf("trace_rbug - remote debugging listening on port %u\n", --port
);
807 while(tr_rbug
->running
) {
810 c
= u_socket_accept(s
);
814 u_socket_block(c
, true);
815 tr_rbug
->con
= rbug_from_socket(c
);
817 trace_rbug_con(tr_rbug
);
829 /**********************************************************
834 trace_rbug_start(struct trace_screen
*tr_scr
)
836 struct trace_rbug
*tr_rbug
= CALLOC_STRUCT(trace_rbug
);
840 tr_rbug
->tr_scr
= tr_scr
;
841 tr_rbug
->running
= TRUE
;
842 tr_rbug
->thread
= pipe_thread_create(trace_rbug_thread
, tr_rbug
);
848 trace_rbug_stop(struct trace_rbug
*tr_rbug
)
853 tr_rbug
->running
= false;
854 pipe_thread_wait(tr_rbug
->thread
);
862 trace_rbug_notify_draw_blocked(struct trace_context
*tr_ctx
)
864 struct trace_screen
*tr_scr
= trace_screen(tr_ctx
->base
.screen
);
865 struct trace_rbug
*tr_rbug
= tr_scr
->rbug
;
867 if (tr_rbug
&& tr_rbug
->con
)
868 rbug_send_context_draw_blocked(tr_rbug
->con
,
869 VOID2U64(tr_ctx
), tr_ctx
->draw_blocked
, NULL
);