1/************************************************************************** 2 * 3 * Copyright 2010 VMware, Inc. 4 * All Rights Reserved. 5 * 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: 13 * 14 * The above copyright notice and this permission notice (including the 15 * next paragraph) shall be included in all copies or substantial portions 16 * of the Software. 17 * 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. 25 * 26 **************************************************************************/ 27 28 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" 37 38#include "tgsi/tgsi_parse.h" 39 40#include "rbug_context.h" 41#include "rbug_objects.h" 42 43#include "rbug/rbug.h" 44 45#include <errno.h> 46 47#define U642VOID(x) ((void *)(unsigned long)(x)) 48#define VOID2U64(x) ((uint64_t)(unsigned long)(x)) 49 50#define container_of(ptr, type, field) \ 51 (type*)((char*)ptr - offsetof(type, field)) 52 53struct rbug_rbug 54{ 55 struct rbug_screen *rb_screen; 56 struct rbug_connection *con; 57 pipe_thread thread; 58 boolean running; 59}; 60 61PIPE_THREAD_ROUTINE(rbug_thread, void_rbug); 62 63 64/********************************************************** 65 * Helper functions 66 */ 67 68 69static struct rbug_context * 70rbug_get_context_locked(struct rbug_screen *rb_screen, rbug_context_t ctx) 71{ 72 struct rbug_context *rb_context = NULL; 73 struct rbug_list *ptr; 74 75 foreach(ptr, &rb_screen->contexts) { 76 rb_context = container_of(ptr, struct rbug_context, list); 77 if (ctx == VOID2U64(rb_context)) 78 break; 79 rb_context = NULL; 80 } 81 82 return rb_context; 83} 84 85static struct rbug_shader * 86rbug_get_shader_locked(struct rbug_context *rb_context, rbug_shader_t shdr) 87{ 88 struct rbug_shader *tr_shdr = NULL; 89 struct rbug_list *ptr; 90 91 foreach(ptr, &rb_context->shaders) { 92 tr_shdr = container_of(ptr, struct rbug_shader, list); 93 if (shdr == VOID2U64(tr_shdr)) 94 break; 95 tr_shdr = NULL; 96 } 97 98 return tr_shdr; 99} 100 101static void * 102rbug_shader_create_locked(struct pipe_context *pipe, 103 struct rbug_shader *rb_shader, 104 struct tgsi_token *tokens) 105{ 106 void *state = NULL; 107 struct pipe_shader_state pss; 108 memset(&pss, 0, sizeof(pss)); 109 pss.tokens = tokens; 110 111 switch(rb_shader->type) { 112 case RBUG_SHADER_FRAGMENT: 113 state = pipe->create_fs_state(pipe, &pss); 114 break; 115 case RBUG_SHADER_VERTEX: 116 state = pipe->create_vs_state(pipe, &pss); 117 break; 118 case RBUG_SHADER_GEOM: 119 state = pipe->create_gs_state(pipe, &pss); 120 break; 121 default: 122 assert(0); 123 break; 124 } 125 126 return state; 127} 128 129static void 130rbug_shader_bind_locked(struct pipe_context *pipe, 131 struct rbug_shader *rb_shader, 132 void *state) 133{ 134 switch(rb_shader->type) { 135 case RBUG_SHADER_FRAGMENT: 136 pipe->bind_fs_state(pipe, state); 137 break; 138 case RBUG_SHADER_VERTEX: 139 pipe->bind_vs_state(pipe, state); 140 break; 141 case RBUG_SHADER_GEOM: 142 pipe->bind_gs_state(pipe, state); 143 break; 144 default: 145 assert(0); 146 break; 147 } 148} 149 150static void 151rbug_shader_delete_locked(struct pipe_context *pipe, 152 struct rbug_shader *rb_shader, 153 void *state) 154{ 155 switch(rb_shader->type) { 156 case RBUG_SHADER_FRAGMENT: 157 pipe->delete_fs_state(pipe, state); 158 break; 159 case RBUG_SHADER_VERTEX: 160 pipe->delete_vs_state(pipe, state); 161 break; 162 case RBUG_SHADER_GEOM: 163 pipe->delete_gs_state(pipe, state); 164 break; 165 default: 166 assert(0); 167 break; 168 } 169} 170 171/************************************************ 172 * Request handler functions 173 */ 174 175 176static int 177rbug_texture_list(struct rbug_rbug *tr_rbug, struct rbug_header *header, uint32_t serial) 178{ 179 struct rbug_screen *rb_screen = tr_rbug->rb_screen; 180 struct rbug_resource *tr_tex = NULL; 181 struct rbug_list *ptr; 182 rbug_texture_t *texs; 183 int i = 0; 184 185 pipe_mutex_lock(rb_screen->list_mutex); 186 texs = MALLOC(rb_screen->num_resources * sizeof(rbug_texture_t)); 187 foreach(ptr, &rb_screen->resources) { 188 tr_tex = container_of(ptr, struct rbug_resource, list); 189 texs[i++] = VOID2U64(tr_tex); 190 } 191 pipe_mutex_unlock(rb_screen->list_mutex); 192 193 rbug_send_texture_list_reply(tr_rbug->con, serial, texs, i, NULL); 194 FREE(texs); 195 196 return 0; 197} 198 199static int 200rbug_texture_info(struct rbug_rbug *tr_rbug, struct rbug_header *header, uint32_t serial) 201{ 202 struct rbug_screen *rb_screen = tr_rbug->rb_screen; 203 struct rbug_resource *tr_tex = NULL; 204 struct rbug_proto_texture_info *gpti = (struct rbug_proto_texture_info *)header; 205 struct rbug_list *ptr; 206 struct pipe_resource *t; 207 208 pipe_mutex_lock(rb_screen->list_mutex); 209 foreach(ptr, &rb_screen->resources) { 210 tr_tex = container_of(ptr, struct rbug_resource, list); 211 if (gpti->texture == VOID2U64(tr_tex)) 212 break; 213 tr_tex = NULL; 214 } 215 216 if (!tr_tex) { 217 pipe_mutex_unlock(rb_screen->list_mutex); 218 return -ESRCH; 219 } 220 221 t = tr_tex->resource; 222 rbug_send_texture_info_reply(tr_rbug->con, serial, 223 t->target, t->format, 224 &t->width0, 1, 225 &t->height0, 1, 226 &t->depth0, 1, 227 util_format_get_blockwidth(t->format), 228 util_format_get_blockheight(t->format), 229 util_format_get_blocksize(t->format), 230 t->last_level, 231 t->nr_samples, 232 t->bind, 233 NULL); 234 235 pipe_mutex_unlock(rb_screen->list_mutex); 236 237 return 0; 238} 239 240static int 241rbug_texture_read(struct rbug_rbug *tr_rbug, struct rbug_header *header, uint32_t serial) 242{ 243 struct rbug_proto_texture_read *gptr = (struct rbug_proto_texture_read *)header; 244 245 struct rbug_screen *rb_screen = tr_rbug->rb_screen; 246 struct rbug_resource *tr_tex = NULL; 247 struct rbug_list *ptr; 248 249 struct pipe_context *context = rb_screen->private_context; 250 struct pipe_resource *tex; 251 struct pipe_transfer *t; 252 253 void *map; 254 255 pipe_mutex_lock(rb_screen->list_mutex); 256 foreach(ptr, &rb_screen->resources) { 257 tr_tex = container_of(ptr, struct rbug_resource, list); 258 if (gptr->texture == VOID2U64(tr_tex)) 259 break; 260 tr_tex = NULL; 261 } 262 263 if (!tr_tex) { 264 pipe_mutex_unlock(rb_screen->list_mutex); 265 return -ESRCH; 266 } 267 268 tex = tr_tex->resource; 269 t = pipe_get_transfer(context, tex, 270 gptr->level, gptr->face + gptr->zslice, 271 PIPE_TRANSFER_READ, 272 gptr->x, gptr->y, gptr->w, gptr->h); 273 274 map = context->transfer_map(context, t); 275 276 rbug_send_texture_read_reply(tr_rbug->con, serial, 277 t->resource->format, 278 util_format_get_blockwidth(t->resource->format), 279 util_format_get_blockheight(t->resource->format), 280 util_format_get_blocksize(t->resource->format), 281 (uint8_t*)map, 282 t->stride * util_format_get_nblocksy(t->resource->format, 283 t->box.height), 284 t->stride, 285 NULL); 286 287 context->transfer_unmap(context, t); 288 context->transfer_destroy(context, t); 289 290 pipe_mutex_unlock(rb_screen->list_mutex); 291 292 return 0; 293} 294 295static int 296rbug_context_list(struct rbug_rbug *tr_rbug, struct rbug_header *header, uint32_t serial) 297{ 298 struct rbug_screen *rb_screen = tr_rbug->rb_screen; 299 struct rbug_list *ptr; 300 struct rbug_context *rb_context = NULL; 301 rbug_context_t *ctxs; 302 int i = 0; 303 304 pipe_mutex_lock(rb_screen->list_mutex); 305 ctxs = MALLOC(rb_screen->num_contexts * sizeof(rbug_context_t)); 306 foreach(ptr, &rb_screen->contexts) { 307 rb_context = container_of(ptr, struct rbug_context, list); 308 ctxs[i++] = VOID2U64(rb_context); 309 } 310 pipe_mutex_unlock(rb_screen->list_mutex); 311 312 rbug_send_context_list_reply(tr_rbug->con, serial, ctxs, i, NULL); 313 FREE(ctxs); 314 315 return 0; 316} 317 318static int 319rbug_context_info(struct rbug_rbug *tr_rbug, struct rbug_header *header, uint32_t serial) 320{ 321 struct rbug_proto_context_info *info = (struct rbug_proto_context_info *)header; 322 323 struct rbug_screen *rb_screen = tr_rbug->rb_screen; 324 struct rbug_context *rb_context = NULL; 325 rbug_texture_t cbufs[PIPE_MAX_COLOR_BUFS]; 326 rbug_texture_t texs[PIPE_MAX_SAMPLERS]; 327 int i; 328 329 pipe_mutex_lock(rb_screen->list_mutex); 330 rb_context = rbug_get_context_locked(rb_screen, info->context); 331 332 if (!rb_context) { 333 pipe_mutex_unlock(rb_screen->list_mutex); 334 return -ESRCH; 335 } 336 337 /* protect the pipe context */ 338 pipe_mutex_lock(rb_context->draw_mutex); 339 pipe_mutex_lock(rb_context->call_mutex); 340 341 for (i = 0; i < rb_context->curr.nr_cbufs; i++) 342 cbufs[i] = VOID2U64(rb_context->curr.cbufs[i]); 343 344 /* XXX what about vertex/geometry shader texture views? */ 345 for (i = 0; i < rb_context->curr.num_views[PIPE_SHADER_FRAGMENT]; i++) 346 texs[i] = VOID2U64(rb_context->curr.texs[PIPE_SHADER_FRAGMENT][i]); 347 348 rbug_send_context_info_reply(tr_rbug->con, serial, 349 VOID2U64(rb_context->curr.shader[PIPE_SHADER_VERTEX]), VOID2U64(rb_context->curr.shader[PIPE_SHADER_FRAGMENT]), 350 texs, rb_context->curr.num_views[PIPE_SHADER_FRAGMENT], 351 cbufs, rb_context->curr.nr_cbufs, 352 VOID2U64(rb_context->curr.zsbuf), 353 rb_context->draw_blocker, rb_context->draw_blocked, NULL); 354 355 pipe_mutex_unlock(rb_context->call_mutex); 356 pipe_mutex_unlock(rb_context->draw_mutex); 357 pipe_mutex_unlock(rb_screen->list_mutex); 358 359 return 0; 360} 361 362static int 363rbug_context_draw_block(struct rbug_rbug *tr_rbug, struct rbug_header *header, uint32_t serial) 364{ 365 struct rbug_proto_context_draw_block *block = (struct rbug_proto_context_draw_block *)header; 366 367 struct rbug_screen *rb_screen = tr_rbug->rb_screen; 368 struct rbug_context *rb_context = NULL; 369 370 pipe_mutex_lock(rb_screen->list_mutex); 371 rb_context = rbug_get_context_locked(rb_screen, block->context); 372 373 if (!rb_context) { 374 pipe_mutex_unlock(rb_screen->list_mutex); 375 return -ESRCH; 376 } 377 378 pipe_mutex_lock(rb_context->draw_mutex); 379 rb_context->draw_blocker |= block->block; 380 pipe_mutex_unlock(rb_context->draw_mutex); 381 382 pipe_mutex_unlock(rb_screen->list_mutex); 383 384 return 0; 385} 386 387static int 388rbug_context_draw_step(struct rbug_rbug *tr_rbug, struct rbug_header *header, uint32_t serial) 389{ 390 struct rbug_proto_context_draw_step *step = (struct rbug_proto_context_draw_step *)header; 391 392 struct rbug_screen *rb_screen = tr_rbug->rb_screen; 393 struct rbug_context *rb_context = NULL; 394 395 pipe_mutex_lock(rb_screen->list_mutex); 396 rb_context = rbug_get_context_locked(rb_screen, step->context); 397 398 if (!rb_context) { 399 pipe_mutex_unlock(rb_screen->list_mutex); 400 return -ESRCH; 401 } 402 403 pipe_mutex_lock(rb_context->draw_mutex); 404 if (rb_context->draw_blocked & RBUG_BLOCK_RULE) { 405 if (step->step & RBUG_BLOCK_RULE) 406 rb_context->draw_blocked &= ~RBUG_BLOCK_MASK; 407 } else { 408 rb_context->draw_blocked &= ~step->step; 409 } 410 pipe_mutex_unlock(rb_context->draw_mutex); 411 412 pipe_condvar_broadcast(rb_context->draw_cond); 413 414 pipe_mutex_unlock(rb_screen->list_mutex); 415 416 return 0; 417} 418 419static int 420rbug_context_draw_unblock(struct rbug_rbug *tr_rbug, struct rbug_header *header, uint32_t serial) 421{ 422 struct rbug_proto_context_draw_unblock *unblock = (struct rbug_proto_context_draw_unblock *)header; 423 424 struct rbug_screen *rb_screen = tr_rbug->rb_screen; 425 struct rbug_context *rb_context = NULL; 426 427 pipe_mutex_lock(rb_screen->list_mutex); 428 rb_context = rbug_get_context_locked(rb_screen, unblock->context); 429 430 if (!rb_context) { 431 pipe_mutex_unlock(rb_screen->list_mutex); 432 return -ESRCH; 433 } 434 435 pipe_mutex_lock(rb_context->draw_mutex); 436 if (rb_context->draw_blocked & RBUG_BLOCK_RULE) { 437 if (unblock->unblock & RBUG_BLOCK_RULE) 438 rb_context->draw_blocked &= ~RBUG_BLOCK_MASK; 439 } else { 440 rb_context->draw_blocked &= ~unblock->unblock; 441 } 442 rb_context->draw_blocker &= ~unblock->unblock; 443 pipe_mutex_unlock(rb_context->draw_mutex); 444 445 pipe_condvar_broadcast(rb_context->draw_cond); 446 447 pipe_mutex_unlock(rb_screen->list_mutex); 448 449 return 0; 450} 451 452static int 453rbug_context_draw_rule(struct rbug_rbug *tr_rbug, struct rbug_header *header, uint32_t serial) 454{ 455 struct rbug_proto_context_draw_rule *rule = (struct rbug_proto_context_draw_rule *)header; 456 457 struct rbug_screen *rb_screen = tr_rbug->rb_screen; 458 struct rbug_context *rb_context = NULL; 459 460 pipe_mutex_lock(rb_screen->list_mutex); 461 rb_context = rbug_get_context_locked(rb_screen, rule->context); 462 463 if (!rb_context) { 464 pipe_mutex_unlock(rb_screen->list_mutex); 465 return -ESRCH; 466 } 467 468 pipe_mutex_lock(rb_context->draw_mutex); 469 rb_context->draw_rule.shader[PIPE_SHADER_VERTEX] = U642VOID(rule->vertex); 470 rb_context->draw_rule.shader[PIPE_SHADER_FRAGMENT] = U642VOID(rule->fragment); 471 rb_context->draw_rule.texture = U642VOID(rule->texture); 472 rb_context->draw_rule.surf = U642VOID(rule->surface); 473 rb_context->draw_rule.blocker = rule->block; 474 rb_context->draw_blocker |= RBUG_BLOCK_RULE; 475 pipe_mutex_unlock(rb_context->draw_mutex); 476 477 pipe_condvar_broadcast(rb_context->draw_cond); 478 479 pipe_mutex_unlock(rb_screen->list_mutex); 480 481 return 0; 482} 483 484static int 485rbug_context_flush(struct rbug_rbug *tr_rbug, struct rbug_header *header, uint32_t serial) 486{ 487 struct rbug_proto_context_flush *flush = (struct rbug_proto_context_flush *)header; 488 489 struct rbug_screen *rb_screen = tr_rbug->rb_screen; 490 struct rbug_context *rb_context = NULL; 491 492 pipe_mutex_lock(rb_screen->list_mutex); 493 rb_context = rbug_get_context_locked(rb_screen, flush->context); 494 495 if (!rb_context) { 496 pipe_mutex_unlock(rb_screen->list_mutex); 497 return -ESRCH; 498 } 499 500 /* protect the pipe context */ 501 pipe_mutex_lock(rb_context->call_mutex); 502 503 rb_context->pipe->flush(rb_context->pipe, NULL); 504 505 pipe_mutex_unlock(rb_context->call_mutex); 506 pipe_mutex_unlock(rb_screen->list_mutex); 507 508 return 0; 509} 510 511static int 512rbug_shader_list(struct rbug_rbug *tr_rbug, struct rbug_header *header, uint32_t serial) 513{ 514 struct rbug_proto_shader_list *list = (struct rbug_proto_shader_list *)header; 515 516 struct rbug_screen *rb_screen = tr_rbug->rb_screen; 517 struct rbug_context *rb_context = NULL; 518 struct rbug_shader *tr_shdr = NULL; 519 struct rbug_list *ptr; 520 rbug_shader_t *shdrs; 521 int i = 0; 522 523 pipe_mutex_lock(rb_screen->list_mutex); 524 rb_context = rbug_get_context_locked(rb_screen, list->context); 525 526 if (!rb_context) { 527 pipe_mutex_unlock(rb_screen->list_mutex); 528 return -ESRCH; 529 } 530 531 pipe_mutex_lock(rb_context->list_mutex); 532 shdrs = MALLOC(rb_context->num_shaders * sizeof(rbug_shader_t)); 533 foreach(ptr, &rb_context->shaders) { 534 tr_shdr = container_of(ptr, struct rbug_shader, list); 535 shdrs[i++] = VOID2U64(tr_shdr); 536 } 537 538 pipe_mutex_unlock(rb_context->list_mutex); 539 pipe_mutex_unlock(rb_screen->list_mutex); 540 541 rbug_send_shader_list_reply(tr_rbug->con, serial, shdrs, i, NULL); 542 FREE(shdrs); 543 544 return 0; 545} 546 547static int 548rbug_shader_info(struct rbug_rbug *tr_rbug, struct rbug_header *header, uint32_t serial) 549{ 550 struct rbug_proto_shader_info *info = (struct rbug_proto_shader_info *)header; 551 552 struct rbug_screen *rb_screen = tr_rbug->rb_screen; 553 struct rbug_context *rb_context = NULL; 554 struct rbug_shader *tr_shdr = NULL; 555 unsigned original_len; 556 unsigned replaced_len; 557 558 pipe_mutex_lock(rb_screen->list_mutex); 559 rb_context = rbug_get_context_locked(rb_screen, info->context); 560 561 if (!rb_context) { 562 pipe_mutex_unlock(rb_screen->list_mutex); 563 return -ESRCH; 564 } 565 566 pipe_mutex_lock(rb_context->list_mutex); 567 568 tr_shdr = rbug_get_shader_locked(rb_context, info->shader); 569 570 if (!tr_shdr) { 571 pipe_mutex_unlock(rb_context->list_mutex); 572 pipe_mutex_unlock(rb_screen->list_mutex); 573 return -ESRCH; 574 } 575 576 /* just in case */ 577 assert(sizeof(struct tgsi_token) == 4); 578 579 original_len = tgsi_num_tokens(tr_shdr->tokens); 580 if (tr_shdr->replaced_tokens) 581 replaced_len = tgsi_num_tokens(tr_shdr->replaced_tokens); 582 else 583 replaced_len = 0; 584 585 rbug_send_shader_info_reply(tr_rbug->con, serial, 586 (uint32_t*)tr_shdr->tokens, original_len, 587 (uint32_t*)tr_shdr->replaced_tokens, replaced_len, 588 tr_shdr->disabled, 589 NULL); 590 591 pipe_mutex_unlock(rb_context->list_mutex); 592 pipe_mutex_unlock(rb_screen->list_mutex); 593 594 return 0; 595} 596 597static int 598rbug_shader_disable(struct rbug_rbug *tr_rbug, struct rbug_header *header) 599{ 600 struct rbug_proto_shader_disable *dis = (struct rbug_proto_shader_disable *)header; 601 602 struct rbug_screen *rb_screen = tr_rbug->rb_screen; 603 struct rbug_context *rb_context = NULL; 604 struct rbug_shader *tr_shdr = NULL; 605 606 pipe_mutex_lock(rb_screen->list_mutex); 607 rb_context = rbug_get_context_locked(rb_screen, dis->context); 608 609 if (!rb_context) { 610 pipe_mutex_unlock(rb_screen->list_mutex); 611 return -ESRCH; 612 } 613 614 pipe_mutex_lock(rb_context->list_mutex); 615 616 tr_shdr = rbug_get_shader_locked(rb_context, dis->shader); 617 618 if (!tr_shdr) { 619 pipe_mutex_unlock(rb_context->list_mutex); 620 pipe_mutex_unlock(rb_screen->list_mutex); 621 return -ESRCH; 622 } 623 624 tr_shdr->disabled = dis->disable; 625 626 pipe_mutex_unlock(rb_context->list_mutex); 627 pipe_mutex_unlock(rb_screen->list_mutex); 628 629 return 0; 630} 631 632static int 633rbug_shader_replace(struct rbug_rbug *tr_rbug, struct rbug_header *header) 634{ 635 struct rbug_proto_shader_replace *rep = (struct rbug_proto_shader_replace *)header; 636 637 struct rbug_screen *rb_screen = tr_rbug->rb_screen; 638 struct rbug_context *rb_context = NULL; 639 struct rbug_shader *tr_shdr = NULL; 640 struct pipe_context *pipe = NULL; 641 void *state; 642 643 pipe_mutex_lock(rb_screen->list_mutex); 644 rb_context = rbug_get_context_locked(rb_screen, rep->context); 645 646 if (!rb_context) { 647 pipe_mutex_unlock(rb_screen->list_mutex); 648 return -ESRCH; 649 } 650 651 pipe_mutex_lock(rb_context->list_mutex); 652 653 tr_shdr = rbug_get_shader_locked(rb_context, rep->shader); 654 655 if (!tr_shdr) { 656 pipe_mutex_unlock(rb_context->list_mutex); 657 pipe_mutex_unlock(rb_screen->list_mutex); 658 return -ESRCH; 659 } 660 661 /* protect the pipe context */ 662 pipe_mutex_lock(rb_context->call_mutex); 663 664 pipe = rb_context->pipe; 665 666 /* remove old replaced shader */ 667 if (tr_shdr->replaced_shader) { 668 /* if this shader is bound rebind the original shader */ 669 if (rb_context->curr.shader[PIPE_SHADER_FRAGMENT] == tr_shdr || rb_context->curr.shader[PIPE_SHADER_VERTEX] == tr_shdr) 670 rbug_shader_bind_locked(pipe, tr_shdr, tr_shdr->shader); 671 672 FREE(tr_shdr->replaced_tokens); 673 rbug_shader_delete_locked(pipe, tr_shdr, tr_shdr->replaced_shader); 674 tr_shdr->replaced_shader = NULL; 675 tr_shdr->replaced_tokens = NULL; 676 } 677 678 /* empty inputs means restore old which we did above */ 679 if (rep->tokens_len == 0) 680 goto out; 681 682 tr_shdr->replaced_tokens = tgsi_dup_tokens((struct tgsi_token *)rep->tokens); 683 if (!tr_shdr->replaced_tokens) 684 goto err; 685 686 state = rbug_shader_create_locked(pipe, tr_shdr, tr_shdr->replaced_tokens); 687 if (!state) 688 goto err; 689 690 /* bind new shader if the shader is currently a bound */ 691 if (rb_context->curr.shader[PIPE_SHADER_FRAGMENT] == tr_shdr || rb_context->curr.shader[PIPE_SHADER_VERTEX] == tr_shdr) 692 rbug_shader_bind_locked(pipe, tr_shdr, state); 693 694 /* save state */ 695 tr_shdr->replaced_shader = state; 696 697out: 698 pipe_mutex_unlock(rb_context->call_mutex); 699 pipe_mutex_unlock(rb_context->list_mutex); 700 pipe_mutex_unlock(rb_screen->list_mutex); 701 702 return 0; 703 704err: 705 FREE(tr_shdr->replaced_tokens); 706 tr_shdr->replaced_shader = NULL; 707 tr_shdr->replaced_tokens = NULL; 708 709 pipe_mutex_unlock(rb_context->call_mutex); 710 pipe_mutex_unlock(rb_context->list_mutex); 711 pipe_mutex_unlock(rb_screen->list_mutex); 712 return -EINVAL; 713} 714 715static boolean 716rbug_header(struct rbug_rbug *tr_rbug, struct rbug_header *header, uint32_t serial) 717{ 718 int ret = 0; 719 720 switch(header->opcode) { 721 case RBUG_OP_PING: 722 rbug_send_ping_reply(tr_rbug->con, serial, NULL); 723 break; 724 case RBUG_OP_TEXTURE_LIST: 725 ret = rbug_texture_list(tr_rbug, header, serial); 726 break; 727 case RBUG_OP_TEXTURE_INFO: 728 ret = rbug_texture_info(tr_rbug, header, serial); 729 break; 730 case RBUG_OP_TEXTURE_READ: 731 ret = rbug_texture_read(tr_rbug, header, serial); 732 break; 733 case RBUG_OP_CONTEXT_LIST: 734 ret = rbug_context_list(tr_rbug, header, serial); 735 break; 736 case RBUG_OP_CONTEXT_INFO: 737 ret = rbug_context_info(tr_rbug, header, serial); 738 break; 739 case RBUG_OP_CONTEXT_DRAW_BLOCK: 740 ret = rbug_context_draw_block(tr_rbug, header, serial); 741 break; 742 case RBUG_OP_CONTEXT_DRAW_STEP: 743 ret = rbug_context_draw_step(tr_rbug, header, serial); 744 break; 745 case RBUG_OP_CONTEXT_DRAW_UNBLOCK: 746 ret = rbug_context_draw_unblock(tr_rbug, header, serial); 747 break; 748 case RBUG_OP_CONTEXT_DRAW_RULE: 749 ret = rbug_context_draw_rule(tr_rbug, header, serial); 750 break; 751 case RBUG_OP_CONTEXT_FLUSH: 752 ret = rbug_context_flush(tr_rbug, header, serial); 753 break; 754 case RBUG_OP_SHADER_LIST: 755 ret = rbug_shader_list(tr_rbug, header, serial); 756 break; 757 case RBUG_OP_SHADER_INFO: 758 ret = rbug_shader_info(tr_rbug, header, serial); 759 break; 760 case RBUG_OP_SHADER_DISABLE: 761 ret = rbug_shader_disable(tr_rbug, header); 762 break; 763 case RBUG_OP_SHADER_REPLACE: 764 ret = rbug_shader_replace(tr_rbug, header); 765 break; 766 default: 767 debug_printf("%s - unsupported opcode %u\n", __FUNCTION__, header->opcode); 768 ret = -ENOSYS; 769 break; 770 } 771 rbug_free_header(header); 772 773 if (ret) 774 rbug_send_error_reply(tr_rbug->con, serial, ret, NULL); 775 776 return TRUE; 777} 778 779static void 780rbug_con(struct rbug_rbug *tr_rbug) 781{ 782 struct rbug_header *header; 783 uint32_t serial; 784 785 debug_printf("%s - connection received\n", __FUNCTION__); 786 787 while(tr_rbug->running) { 788 header = rbug_get_message(tr_rbug->con, &serial); 789 if (!header) 790 break; 791 792 if (!rbug_header(tr_rbug, header, serial)) 793 break; 794 } 795 796 debug_printf("%s - connection closed\n", __FUNCTION__); 797 798 rbug_disconnect(tr_rbug->con); 799 tr_rbug->con = NULL; 800} 801 802PIPE_THREAD_ROUTINE(rbug_thread, void_tr_rbug) 803{ 804 struct rbug_rbug *tr_rbug = void_tr_rbug; 805 uint16_t port = 13370; 806 int s = -1; 807 int c; 808 809 u_socket_init(); 810 811 for (;port <= 13379 && s < 0; port++) 812 s = u_socket_listen_on_port(port); 813 814 if (s < 0) { 815 debug_printf("rbug_rbug - failed to listen\n"); 816 return NULL; 817 } 818 819 u_socket_block(s, false); 820 821 debug_printf("rbug_rbug - remote debugging listening on port %u\n", --port); 822 823 while(tr_rbug->running) { 824 os_time_sleep(1); 825 826 c = u_socket_accept(s); 827 if (c < 0) 828 continue; 829 830 u_socket_block(c, true); 831 tr_rbug->con = rbug_from_socket(c); 832 833 rbug_con(tr_rbug); 834 835 u_socket_close(c); 836 } 837 838 u_socket_close(s); 839 840 u_socket_stop(); 841 842 return NULL; 843} 844 845/********************************************************** 846 * 847 */ 848 849struct rbug_rbug * 850rbug_start(struct rbug_screen *rb_screen) 851{ 852 struct rbug_rbug *tr_rbug = CALLOC_STRUCT(rbug_rbug); 853 if (!tr_rbug) 854 return NULL; 855 856 tr_rbug->rb_screen = rb_screen; 857 tr_rbug->running = TRUE; 858 tr_rbug->thread = pipe_thread_create(rbug_thread, tr_rbug); 859 860 return tr_rbug; 861} 862 863void 864rbug_stop(struct rbug_rbug *tr_rbug) 865{ 866 if (!tr_rbug) 867 return; 868 869 tr_rbug->running = false; 870 pipe_thread_wait(tr_rbug->thread); 871 872 FREE(tr_rbug); 873 874 return; 875} 876 877void 878rbug_notify_draw_blocked(struct rbug_context *rb_context) 879{ 880 struct rbug_screen *rb_screen = rbug_screen(rb_context->base.screen); 881 struct rbug_rbug *tr_rbug = rb_screen->rbug; 882 883 if (tr_rbug && tr_rbug->con) 884 rbug_send_context_draw_blocked(tr_rbug->con, 885 VOID2U64(rb_context), rb_context->draw_blocked, NULL); 886} 887