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/simple_list.h"
35 #include "util/u_network.h"
36 #include "util/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
;
62 rbug_thread(void *void_rbug
);
65 /**********************************************************
70 static struct rbug_context
*
71 rbug_get_context_locked(struct rbug_screen
*rb_screen
, rbug_context_t ctx
)
73 struct rbug_context
*rb_context
= NULL
;
74 struct rbug_list
*ptr
;
76 foreach(ptr
, &rb_screen
->contexts
) {
77 rb_context
= container_of(ptr
, struct rbug_context
, list
);
78 if (ctx
== VOID2U64(rb_context
))
86 static struct rbug_shader
*
87 rbug_get_shader_locked(struct rbug_context
*rb_context
, rbug_shader_t shdr
)
89 struct rbug_shader
*tr_shdr
= NULL
;
90 struct rbug_list
*ptr
;
92 foreach(ptr
, &rb_context
->shaders
) {
93 tr_shdr
= container_of(ptr
, struct rbug_shader
, list
);
94 if (shdr
== VOID2U64(tr_shdr
))
103 rbug_shader_create_locked(struct pipe_context
*pipe
,
104 struct rbug_shader
*rb_shader
,
105 struct tgsi_token
*tokens
)
108 struct pipe_shader_state pss
;
109 memset(&pss
, 0, sizeof(pss
));
112 switch(rb_shader
->type
) {
113 case RBUG_SHADER_FRAGMENT
:
114 state
= pipe
->create_fs_state(pipe
, &pss
);
116 case RBUG_SHADER_VERTEX
:
117 state
= pipe
->create_vs_state(pipe
, &pss
);
119 case RBUG_SHADER_GEOM
:
120 state
= pipe
->create_gs_state(pipe
, &pss
);
131 rbug_shader_bind_locked(struct pipe_context
*pipe
,
132 struct rbug_shader
*rb_shader
,
135 switch(rb_shader
->type
) {
136 case RBUG_SHADER_FRAGMENT
:
137 pipe
->bind_fs_state(pipe
, state
);
139 case RBUG_SHADER_VERTEX
:
140 pipe
->bind_vs_state(pipe
, state
);
142 case RBUG_SHADER_GEOM
:
143 pipe
->bind_gs_state(pipe
, state
);
152 rbug_shader_delete_locked(struct pipe_context
*pipe
,
153 struct rbug_shader
*rb_shader
,
156 switch(rb_shader
->type
) {
157 case RBUG_SHADER_FRAGMENT
:
158 pipe
->delete_fs_state(pipe
, state
);
160 case RBUG_SHADER_VERTEX
:
161 pipe
->delete_vs_state(pipe
, state
);
163 case RBUG_SHADER_GEOM
:
164 pipe
->delete_gs_state(pipe
, state
);
172 /************************************************
173 * Request handler functions
178 rbug_texture_list(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_list
*ptr
;
183 rbug_texture_t
*texs
;
186 mtx_lock(&rb_screen
->list_mutex
);
187 texs
= MALLOC(rb_screen
->num_resources
* sizeof(rbug_texture_t
));
188 foreach(ptr
, &rb_screen
->resources
) {
189 tr_tex
= container_of(ptr
, struct rbug_resource
, list
);
190 texs
[i
++] = VOID2U64(tr_tex
);
192 mtx_unlock(&rb_screen
->list_mutex
);
194 rbug_send_texture_list_reply(tr_rbug
->con
, serial
, texs
, i
, NULL
);
201 rbug_texture_info(struct rbug_rbug
*tr_rbug
, struct rbug_header
*header
, uint32_t serial
)
203 struct rbug_screen
*rb_screen
= tr_rbug
->rb_screen
;
204 struct rbug_resource
*tr_tex
= NULL
;
205 struct rbug_proto_texture_info
*gpti
= (struct rbug_proto_texture_info
*)header
;
206 struct rbug_list
*ptr
;
207 struct pipe_resource
*t
;
210 mtx_lock(&rb_screen
->list_mutex
);
211 foreach(ptr
, &rb_screen
->resources
) {
212 tr_tex
= container_of(ptr
, struct rbug_resource
, list
);
213 if (gpti
->texture
== VOID2U64(tr_tex
))
219 mtx_unlock(&rb_screen
->list_mutex
);
223 t
= tr_tex
->resource
;
224 num_layers
= util_max_layer(t
, 0) + 1;
226 rbug_send_texture_info_reply(tr_rbug
->con
, serial
,
227 t
->target
, t
->format
,
231 util_format_get_blockwidth(t
->format
),
232 util_format_get_blockheight(t
->format
),
233 util_format_get_blocksize(t
->format
),
239 mtx_unlock(&rb_screen
->list_mutex
);
245 rbug_texture_read(struct rbug_rbug
*tr_rbug
, struct rbug_header
*header
, uint32_t serial
)
247 struct rbug_proto_texture_read
*gptr
= (struct rbug_proto_texture_read
*)header
;
249 struct rbug_screen
*rb_screen
= tr_rbug
->rb_screen
;
250 struct rbug_resource
*tr_tex
= NULL
;
251 struct rbug_list
*ptr
;
253 struct pipe_context
*context
= rb_screen
->private_context
;
254 struct pipe_resource
*tex
;
255 struct pipe_transfer
*t
;
259 mtx_lock(&rb_screen
->list_mutex
);
260 foreach(ptr
, &rb_screen
->resources
) {
261 tr_tex
= container_of(ptr
, struct rbug_resource
, list
);
262 if (gptr
->texture
== VOID2U64(tr_tex
))
268 mtx_unlock(&rb_screen
->list_mutex
);
272 tex
= tr_tex
->resource
;
273 map
= pipe_transfer_map(context
, tex
,
274 gptr
->level
, gptr
->face
+ gptr
->zslice
,
276 gptr
->x
, gptr
->y
, gptr
->w
, gptr
->h
, &t
);
278 rbug_send_texture_read_reply(tr_rbug
->con
, serial
,
280 util_format_get_blockwidth(t
->resource
->format
),
281 util_format_get_blockheight(t
->resource
->format
),
282 util_format_get_blocksize(t
->resource
->format
),
284 t
->stride
* util_format_get_nblocksy(t
->resource
->format
,
289 context
->transfer_unmap(context
, t
);
291 mtx_unlock(&rb_screen
->list_mutex
);
297 rbug_context_list(struct rbug_rbug
*tr_rbug
, struct rbug_header
*header
, uint32_t serial
)
299 struct rbug_screen
*rb_screen
= tr_rbug
->rb_screen
;
300 struct rbug_list
*ptr
;
301 struct rbug_context
*rb_context
= NULL
;
302 rbug_context_t
*ctxs
;
305 mtx_lock(&rb_screen
->list_mutex
);
306 ctxs
= MALLOC(rb_screen
->num_contexts
* sizeof(rbug_context_t
));
307 foreach(ptr
, &rb_screen
->contexts
) {
308 rb_context
= container_of(ptr
, struct rbug_context
, list
);
309 ctxs
[i
++] = VOID2U64(rb_context
);
311 mtx_unlock(&rb_screen
->list_mutex
);
313 rbug_send_context_list_reply(tr_rbug
->con
, serial
, ctxs
, i
, NULL
);
320 rbug_context_info(struct rbug_rbug
*tr_rbug
, struct rbug_header
*header
, uint32_t serial
)
322 struct rbug_proto_context_info
*info
= (struct rbug_proto_context_info
*)header
;
324 struct rbug_screen
*rb_screen
= tr_rbug
->rb_screen
;
325 struct rbug_context
*rb_context
= NULL
;
326 rbug_texture_t cbufs
[PIPE_MAX_COLOR_BUFS
];
327 rbug_texture_t texs
[PIPE_MAX_SHADER_SAMPLER_VIEWS
];
330 mtx_lock(&rb_screen
->list_mutex
);
331 rb_context
= rbug_get_context_locked(rb_screen
, info
->context
);
334 mtx_unlock(&rb_screen
->list_mutex
);
338 /* protect the pipe context */
339 mtx_lock(&rb_context
->draw_mutex
);
340 mtx_lock(&rb_context
->call_mutex
);
342 for (i
= 0; i
< rb_context
->curr
.nr_cbufs
; i
++)
343 cbufs
[i
] = VOID2U64(rb_context
->curr
.cbufs
[i
]);
345 /* XXX what about vertex/geometry shader texture views? */
346 for (i
= 0; i
< rb_context
->curr
.num_views
[PIPE_SHADER_FRAGMENT
]; i
++)
347 texs
[i
] = VOID2U64(rb_context
->curr
.texs
[PIPE_SHADER_FRAGMENT
][i
]);
349 rbug_send_context_info_reply(tr_rbug
->con
, serial
,
350 VOID2U64(rb_context
->curr
.shader
[PIPE_SHADER_VERTEX
]), VOID2U64(rb_context
->curr
.shader
[PIPE_SHADER_FRAGMENT
]),
351 texs
, rb_context
->curr
.num_views
[PIPE_SHADER_FRAGMENT
],
352 cbufs
, rb_context
->curr
.nr_cbufs
,
353 VOID2U64(rb_context
->curr
.zsbuf
),
354 rb_context
->draw_blocker
, rb_context
->draw_blocked
, NULL
);
356 mtx_unlock(&rb_context
->call_mutex
);
357 mtx_unlock(&rb_context
->draw_mutex
);
358 mtx_unlock(&rb_screen
->list_mutex
);
364 rbug_context_draw_block(struct rbug_rbug
*tr_rbug
, struct rbug_header
*header
, uint32_t serial
)
366 struct rbug_proto_context_draw_block
*block
= (struct rbug_proto_context_draw_block
*)header
;
368 struct rbug_screen
*rb_screen
= tr_rbug
->rb_screen
;
369 struct rbug_context
*rb_context
= NULL
;
371 mtx_lock(&rb_screen
->list_mutex
);
372 rb_context
= rbug_get_context_locked(rb_screen
, block
->context
);
375 mtx_unlock(&rb_screen
->list_mutex
);
379 mtx_lock(&rb_context
->draw_mutex
);
380 rb_context
->draw_blocker
|= block
->block
;
381 mtx_unlock(&rb_context
->draw_mutex
);
383 mtx_unlock(&rb_screen
->list_mutex
);
389 rbug_context_draw_step(struct rbug_rbug
*tr_rbug
, struct rbug_header
*header
, uint32_t serial
)
391 struct rbug_proto_context_draw_step
*step
= (struct rbug_proto_context_draw_step
*)header
;
393 struct rbug_screen
*rb_screen
= tr_rbug
->rb_screen
;
394 struct rbug_context
*rb_context
= NULL
;
396 mtx_lock(&rb_screen
->list_mutex
);
397 rb_context
= rbug_get_context_locked(rb_screen
, step
->context
);
400 mtx_unlock(&rb_screen
->list_mutex
);
404 mtx_lock(&rb_context
->draw_mutex
);
405 if (rb_context
->draw_blocked
& RBUG_BLOCK_RULE
) {
406 if (step
->step
& RBUG_BLOCK_RULE
)
407 rb_context
->draw_blocked
&= ~RBUG_BLOCK_MASK
;
409 rb_context
->draw_blocked
&= ~step
->step
;
411 mtx_unlock(&rb_context
->draw_mutex
);
413 cnd_broadcast(&rb_context
->draw_cond
);
415 mtx_unlock(&rb_screen
->list_mutex
);
421 rbug_context_draw_unblock(struct rbug_rbug
*tr_rbug
, struct rbug_header
*header
, uint32_t serial
)
423 struct rbug_proto_context_draw_unblock
*unblock
= (struct rbug_proto_context_draw_unblock
*)header
;
425 struct rbug_screen
*rb_screen
= tr_rbug
->rb_screen
;
426 struct rbug_context
*rb_context
= NULL
;
428 mtx_lock(&rb_screen
->list_mutex
);
429 rb_context
= rbug_get_context_locked(rb_screen
, unblock
->context
);
432 mtx_unlock(&rb_screen
->list_mutex
);
436 mtx_lock(&rb_context
->draw_mutex
);
437 if (rb_context
->draw_blocked
& RBUG_BLOCK_RULE
) {
438 if (unblock
->unblock
& RBUG_BLOCK_RULE
)
439 rb_context
->draw_blocked
&= ~RBUG_BLOCK_MASK
;
441 rb_context
->draw_blocked
&= ~unblock
->unblock
;
443 rb_context
->draw_blocker
&= ~unblock
->unblock
;
444 mtx_unlock(&rb_context
->draw_mutex
);
446 cnd_broadcast(&rb_context
->draw_cond
);
448 mtx_unlock(&rb_screen
->list_mutex
);
454 rbug_context_draw_rule(struct rbug_rbug
*tr_rbug
, struct rbug_header
*header
, uint32_t serial
)
456 struct rbug_proto_context_draw_rule
*rule
= (struct rbug_proto_context_draw_rule
*)header
;
458 struct rbug_screen
*rb_screen
= tr_rbug
->rb_screen
;
459 struct rbug_context
*rb_context
= NULL
;
461 mtx_lock(&rb_screen
->list_mutex
);
462 rb_context
= rbug_get_context_locked(rb_screen
, rule
->context
);
465 mtx_unlock(&rb_screen
->list_mutex
);
469 mtx_lock(&rb_context
->draw_mutex
);
470 rb_context
->draw_rule
.shader
[PIPE_SHADER_VERTEX
] = U642VOID(rule
->vertex
);
471 rb_context
->draw_rule
.shader
[PIPE_SHADER_FRAGMENT
] = U642VOID(rule
->fragment
);
472 rb_context
->draw_rule
.texture
= U642VOID(rule
->texture
);
473 rb_context
->draw_rule
.surf
= U642VOID(rule
->surface
);
474 rb_context
->draw_rule
.blocker
= rule
->block
;
475 rb_context
->draw_blocker
|= RBUG_BLOCK_RULE
;
476 mtx_unlock(&rb_context
->draw_mutex
);
478 cnd_broadcast(&rb_context
->draw_cond
);
480 mtx_unlock(&rb_screen
->list_mutex
);
486 rbug_context_flush(struct rbug_rbug
*tr_rbug
, struct rbug_header
*header
, uint32_t serial
)
488 struct rbug_proto_context_flush
*flush
= (struct rbug_proto_context_flush
*)header
;
490 struct rbug_screen
*rb_screen
= tr_rbug
->rb_screen
;
491 struct rbug_context
*rb_context
= NULL
;
493 mtx_lock(&rb_screen
->list_mutex
);
494 rb_context
= rbug_get_context_locked(rb_screen
, flush
->context
);
497 mtx_unlock(&rb_screen
->list_mutex
);
501 /* protect the pipe context */
502 mtx_lock(&rb_context
->call_mutex
);
504 rb_context
->pipe
->flush(rb_context
->pipe
, NULL
, 0);
506 mtx_unlock(&rb_context
->call_mutex
);
507 mtx_unlock(&rb_screen
->list_mutex
);
513 rbug_shader_list(struct rbug_rbug
*tr_rbug
, struct rbug_header
*header
, uint32_t serial
)
515 struct rbug_proto_shader_list
*list
= (struct rbug_proto_shader_list
*)header
;
517 struct rbug_screen
*rb_screen
= tr_rbug
->rb_screen
;
518 struct rbug_context
*rb_context
= NULL
;
519 struct rbug_shader
*tr_shdr
= NULL
;
520 struct rbug_list
*ptr
;
521 rbug_shader_t
*shdrs
;
524 mtx_lock(&rb_screen
->list_mutex
);
525 rb_context
= rbug_get_context_locked(rb_screen
, list
->context
);
528 mtx_unlock(&rb_screen
->list_mutex
);
532 mtx_lock(&rb_context
->list_mutex
);
533 shdrs
= MALLOC(rb_context
->num_shaders
* sizeof(rbug_shader_t
));
534 foreach(ptr
, &rb_context
->shaders
) {
535 tr_shdr
= container_of(ptr
, struct rbug_shader
, list
);
536 shdrs
[i
++] = VOID2U64(tr_shdr
);
539 mtx_unlock(&rb_context
->list_mutex
);
540 mtx_unlock(&rb_screen
->list_mutex
);
542 rbug_send_shader_list_reply(tr_rbug
->con
, serial
, shdrs
, i
, NULL
);
549 rbug_shader_info(struct rbug_rbug
*tr_rbug
, struct rbug_header
*header
, uint32_t serial
)
551 struct rbug_proto_shader_info
*info
= (struct rbug_proto_shader_info
*)header
;
553 struct rbug_screen
*rb_screen
= tr_rbug
->rb_screen
;
554 struct rbug_context
*rb_context
= NULL
;
555 struct rbug_shader
*tr_shdr
= NULL
;
556 unsigned original_len
;
557 unsigned replaced_len
;
559 mtx_lock(&rb_screen
->list_mutex
);
560 rb_context
= rbug_get_context_locked(rb_screen
, info
->context
);
563 mtx_unlock(&rb_screen
->list_mutex
);
567 mtx_lock(&rb_context
->list_mutex
);
569 tr_shdr
= rbug_get_shader_locked(rb_context
, info
->shader
);
572 mtx_unlock(&rb_context
->list_mutex
);
573 mtx_unlock(&rb_screen
->list_mutex
);
578 assert(sizeof(struct tgsi_token
) == 4);
580 original_len
= tgsi_num_tokens(tr_shdr
->tokens
);
581 if (tr_shdr
->replaced_tokens
)
582 replaced_len
= tgsi_num_tokens(tr_shdr
->replaced_tokens
);
586 rbug_send_shader_info_reply(tr_rbug
->con
, serial
,
587 (uint32_t*)tr_shdr
->tokens
, original_len
,
588 (uint32_t*)tr_shdr
->replaced_tokens
, replaced_len
,
592 mtx_unlock(&rb_context
->list_mutex
);
593 mtx_unlock(&rb_screen
->list_mutex
);
599 rbug_shader_disable(struct rbug_rbug
*tr_rbug
, struct rbug_header
*header
)
601 struct rbug_proto_shader_disable
*dis
= (struct rbug_proto_shader_disable
*)header
;
603 struct rbug_screen
*rb_screen
= tr_rbug
->rb_screen
;
604 struct rbug_context
*rb_context
= NULL
;
605 struct rbug_shader
*tr_shdr
= NULL
;
607 mtx_lock(&rb_screen
->list_mutex
);
608 rb_context
= rbug_get_context_locked(rb_screen
, dis
->context
);
611 mtx_unlock(&rb_screen
->list_mutex
);
615 mtx_lock(&rb_context
->list_mutex
);
617 tr_shdr
= rbug_get_shader_locked(rb_context
, dis
->shader
);
620 mtx_unlock(&rb_context
->list_mutex
);
621 mtx_unlock(&rb_screen
->list_mutex
);
625 tr_shdr
->disabled
= dis
->disable
;
627 mtx_unlock(&rb_context
->list_mutex
);
628 mtx_unlock(&rb_screen
->list_mutex
);
634 rbug_shader_replace(struct rbug_rbug
*tr_rbug
, struct rbug_header
*header
)
636 struct rbug_proto_shader_replace
*rep
= (struct rbug_proto_shader_replace
*)header
;
638 struct rbug_screen
*rb_screen
= tr_rbug
->rb_screen
;
639 struct rbug_context
*rb_context
= NULL
;
640 struct rbug_shader
*tr_shdr
= NULL
;
641 struct pipe_context
*pipe
= NULL
;
644 mtx_lock(&rb_screen
->list_mutex
);
645 rb_context
= rbug_get_context_locked(rb_screen
, rep
->context
);
648 mtx_unlock(&rb_screen
->list_mutex
);
652 mtx_lock(&rb_context
->list_mutex
);
654 tr_shdr
= rbug_get_shader_locked(rb_context
, rep
->shader
);
657 mtx_unlock(&rb_context
->list_mutex
);
658 mtx_unlock(&rb_screen
->list_mutex
);
662 /* protect the pipe context */
663 mtx_lock(&rb_context
->call_mutex
);
665 pipe
= rb_context
->pipe
;
667 /* remove old replaced shader */
668 if (tr_shdr
->replaced_shader
) {
669 /* if this shader is bound rebind the original shader */
670 if (rb_context
->curr
.shader
[PIPE_SHADER_FRAGMENT
] == tr_shdr
|| rb_context
->curr
.shader
[PIPE_SHADER_VERTEX
] == tr_shdr
)
671 rbug_shader_bind_locked(pipe
, tr_shdr
, tr_shdr
->shader
);
673 FREE(tr_shdr
->replaced_tokens
);
674 rbug_shader_delete_locked(pipe
, tr_shdr
, tr_shdr
->replaced_shader
);
675 tr_shdr
->replaced_shader
= NULL
;
676 tr_shdr
->replaced_tokens
= NULL
;
679 /* empty inputs means restore old which we did above */
680 if (rep
->tokens_len
== 0)
683 tr_shdr
->replaced_tokens
= tgsi_dup_tokens((struct tgsi_token
*)rep
->tokens
);
684 if (!tr_shdr
->replaced_tokens
)
687 state
= rbug_shader_create_locked(pipe
, tr_shdr
, tr_shdr
->replaced_tokens
);
691 /* bind new shader if the shader is currently a bound */
692 if (rb_context
->curr
.shader
[PIPE_SHADER_FRAGMENT
] == tr_shdr
|| rb_context
->curr
.shader
[PIPE_SHADER_VERTEX
] == tr_shdr
)
693 rbug_shader_bind_locked(pipe
, tr_shdr
, state
);
696 tr_shdr
->replaced_shader
= state
;
699 mtx_unlock(&rb_context
->call_mutex
);
700 mtx_unlock(&rb_context
->list_mutex
);
701 mtx_unlock(&rb_screen
->list_mutex
);
706 FREE(tr_shdr
->replaced_tokens
);
707 tr_shdr
->replaced_shader
= NULL
;
708 tr_shdr
->replaced_tokens
= NULL
;
710 mtx_unlock(&rb_context
->call_mutex
);
711 mtx_unlock(&rb_context
->list_mutex
);
712 mtx_unlock(&rb_screen
->list_mutex
);
717 rbug_header(struct rbug_rbug
*tr_rbug
, struct rbug_header
*header
, uint32_t serial
)
721 switch(header
->opcode
) {
723 rbug_send_ping_reply(tr_rbug
->con
, serial
, NULL
);
725 case RBUG_OP_TEXTURE_LIST
:
726 ret
= rbug_texture_list(tr_rbug
, header
, serial
);
728 case RBUG_OP_TEXTURE_INFO
:
729 ret
= rbug_texture_info(tr_rbug
, header
, serial
);
731 case RBUG_OP_TEXTURE_READ
:
732 ret
= rbug_texture_read(tr_rbug
, header
, serial
);
734 case RBUG_OP_CONTEXT_LIST
:
735 ret
= rbug_context_list(tr_rbug
, header
, serial
);
737 case RBUG_OP_CONTEXT_INFO
:
738 ret
= rbug_context_info(tr_rbug
, header
, serial
);
740 case RBUG_OP_CONTEXT_DRAW_BLOCK
:
741 ret
= rbug_context_draw_block(tr_rbug
, header
, serial
);
743 case RBUG_OP_CONTEXT_DRAW_STEP
:
744 ret
= rbug_context_draw_step(tr_rbug
, header
, serial
);
746 case RBUG_OP_CONTEXT_DRAW_UNBLOCK
:
747 ret
= rbug_context_draw_unblock(tr_rbug
, header
, serial
);
749 case RBUG_OP_CONTEXT_DRAW_RULE
:
750 ret
= rbug_context_draw_rule(tr_rbug
, header
, serial
);
752 case RBUG_OP_CONTEXT_FLUSH
:
753 ret
= rbug_context_flush(tr_rbug
, header
, serial
);
755 case RBUG_OP_SHADER_LIST
:
756 ret
= rbug_shader_list(tr_rbug
, header
, serial
);
758 case RBUG_OP_SHADER_INFO
:
759 ret
= rbug_shader_info(tr_rbug
, header
, serial
);
761 case RBUG_OP_SHADER_DISABLE
:
762 ret
= rbug_shader_disable(tr_rbug
, header
);
764 case RBUG_OP_SHADER_REPLACE
:
765 ret
= rbug_shader_replace(tr_rbug
, header
);
768 debug_printf("%s - unsupported opcode %u\n", __FUNCTION__
, header
->opcode
);
772 rbug_free_header(header
);
775 rbug_send_error_reply(tr_rbug
->con
, serial
, ret
, NULL
);
781 rbug_con(struct rbug_rbug
*tr_rbug
)
783 struct rbug_header
*header
;
786 debug_printf("%s - connection received\n", __FUNCTION__
);
788 while(tr_rbug
->running
) {
789 header
= rbug_get_message(tr_rbug
->con
, &serial
);
793 if (!rbug_header(tr_rbug
, header
, serial
))
797 debug_printf("%s - connection closed\n", __FUNCTION__
);
799 rbug_disconnect(tr_rbug
->con
);
804 rbug_thread(void *void_tr_rbug
)
806 struct rbug_rbug
*tr_rbug
= void_tr_rbug
;
807 uint16_t port
= 13370;
813 for (;port
<= 13379 && s
< 0; port
++)
814 s
= u_socket_listen_on_port(port
);
817 debug_printf("rbug_rbug - failed to listen\n");
821 u_socket_block(s
, false);
823 debug_printf("rbug_rbug - remote debugging listening on port %u\n", --port
);
825 while(tr_rbug
->running
) {
828 c
= u_socket_accept(s
);
832 u_socket_block(c
, true);
833 tr_rbug
->con
= rbug_from_socket(c
);
847 /**********************************************************
852 rbug_start(struct rbug_screen
*rb_screen
)
854 struct rbug_rbug
*tr_rbug
= CALLOC_STRUCT(rbug_rbug
);
858 tr_rbug
->rb_screen
= rb_screen
;
859 tr_rbug
->running
= TRUE
;
860 tr_rbug
->thread
= u_thread_create(rbug_thread
, tr_rbug
);
866 rbug_stop(struct rbug_rbug
*tr_rbug
)
871 tr_rbug
->running
= false;
872 thrd_join(tr_rbug
->thread
, NULL
);
880 rbug_notify_draw_blocked(struct rbug_context
*rb_context
)
882 struct rbug_screen
*rb_screen
= rbug_screen(rb_context
->base
.screen
);
883 struct rbug_rbug
*tr_rbug
= rb_screen
->rbug
;
885 if (tr_rbug
&& tr_rbug
->con
)
886 rbug_send_context_draw_blocked(tr_rbug
->con
,
887 VOID2U64(rb_context
), rb_context
->draw_blocked
, NULL
);