Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  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/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.  
  53. struct rbug_rbug
  54. {
  55.    struct rbug_screen *rb_screen;
  56.    struct rbug_connection *con;
  57.    pipe_thread thread;
  58.    boolean running;
  59. };
  60.  
  61. PIPE_THREAD_ROUTINE(rbug_thread, void_rbug);
  62.  
  63.  
  64. /**********************************************************
  65.  * Helper functions
  66.  */
  67.  
  68.  
  69. static struct rbug_context *
  70. rbug_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.  
  85. static struct rbug_shader *
  86. rbug_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.  
  101. static void *
  102. rbug_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.  
  129. static void
  130. rbug_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.  
  150. static void
  151. rbug_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.  
  176. static int
  177. rbug_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.  
  199. static int
  200. rbug_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.    unsigned num_layers;
  208.  
  209.    pipe_mutex_lock(rb_screen->list_mutex);
  210.    foreach(ptr, &rb_screen->resources) {
  211.       tr_tex = container_of(ptr, struct rbug_resource, list);
  212.       if (gpti->texture == VOID2U64(tr_tex))
  213.          break;
  214.       tr_tex = NULL;
  215.    }
  216.  
  217.    if (!tr_tex) {
  218.       pipe_mutex_unlock(rb_screen->list_mutex);
  219.       return -ESRCH;
  220.    }
  221.  
  222.    t = tr_tex->resource;
  223.    num_layers = util_max_layer(t, 0) + 1;
  224.  
  225.    rbug_send_texture_info_reply(tr_rbug->con, serial,
  226.                                t->target, t->format,
  227.                                &t->width0, 1,
  228.                                &t->height0, 1,
  229.                                &num_layers, 1,
  230.                                util_format_get_blockwidth(t->format),
  231.                                util_format_get_blockheight(t->format),
  232.                                util_format_get_blocksize(t->format),
  233.                                t->last_level,
  234.                                t->nr_samples,
  235.                                t->bind,
  236.                                NULL);
  237.  
  238.    pipe_mutex_unlock(rb_screen->list_mutex);
  239.  
  240.    return 0;
  241. }
  242.  
  243. static int
  244. rbug_texture_read(struct rbug_rbug *tr_rbug, struct rbug_header *header, uint32_t serial)
  245. {
  246.    struct rbug_proto_texture_read *gptr = (struct rbug_proto_texture_read *)header;
  247.  
  248.    struct rbug_screen *rb_screen = tr_rbug->rb_screen;
  249.    struct rbug_resource *tr_tex = NULL;
  250.    struct rbug_list *ptr;
  251.  
  252.    struct pipe_context *context = rb_screen->private_context;
  253.    struct pipe_resource *tex;
  254.    struct pipe_transfer *t;
  255.  
  256.    void *map;
  257.  
  258.    pipe_mutex_lock(rb_screen->list_mutex);
  259.    foreach(ptr, &rb_screen->resources) {
  260.       tr_tex = container_of(ptr, struct rbug_resource, list);
  261.       if (gptr->texture == VOID2U64(tr_tex))
  262.          break;
  263.       tr_tex = NULL;
  264.    }
  265.  
  266.    if (!tr_tex) {
  267.       pipe_mutex_unlock(rb_screen->list_mutex);
  268.       return -ESRCH;
  269.    }
  270.  
  271.    tex = tr_tex->resource;
  272.    map = pipe_transfer_map(context, tex,
  273.                            gptr->level, gptr->face + gptr->zslice,
  274.                            PIPE_TRANSFER_READ,
  275.                            gptr->x, gptr->y, gptr->w, gptr->h, &t);
  276.  
  277.    rbug_send_texture_read_reply(tr_rbug->con, serial,
  278.                                 t->resource->format,
  279.                                 util_format_get_blockwidth(t->resource->format),
  280.                                 util_format_get_blockheight(t->resource->format),
  281.                                 util_format_get_blocksize(t->resource->format),
  282.                                 (uint8_t*)map,
  283.                                 t->stride * util_format_get_nblocksy(t->resource->format,
  284.                                                                      t->box.height),
  285.                                 t->stride,
  286.                                 NULL);
  287.  
  288.    context->transfer_unmap(context, t);
  289.  
  290.    pipe_mutex_unlock(rb_screen->list_mutex);
  291.  
  292.    return 0;
  293. }
  294.  
  295. static int
  296. rbug_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.  
  318. static int
  319. rbug_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_SHADER_SAMPLER_VIEWS];
  327.    unsigned 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.  
  362. static int
  363. rbug_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.  
  387. static int
  388. rbug_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.  
  419. static int
  420. rbug_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.  
  452. static int
  453. rbug_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.  
  484. static int
  485. rbug_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, 0);
  504.  
  505.    pipe_mutex_unlock(rb_context->call_mutex);
  506.    pipe_mutex_unlock(rb_screen->list_mutex);
  507.  
  508.    return 0;
  509. }
  510.  
  511. static int
  512. rbug_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.  
  547. static int
  548. rbug_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.  
  597. static int
  598. rbug_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.  
  632. static int
  633. rbug_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.  
  697. out:
  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.  
  704. err:
  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.  
  715. static boolean
  716. rbug_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.  
  779. static void
  780. rbug_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.  
  802. PIPE_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 0;
  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 0;
  843. }
  844.  
  845. /**********************************************************
  846.  *
  847.  */
  848.  
  849. struct rbug_rbug *
  850. rbug_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.  
  863. void
  864. rbug_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.  
  877. void
  878. rbug_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.