Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
5563 serge 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 
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
 
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
 
240
static int
241
rbug_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
   map = pipe_transfer_map(context, tex,
270
                           gptr->level, gptr->face + gptr->zslice,
271
                           PIPE_TRANSFER_READ,
272
                           gptr->x, gptr->y, gptr->w, gptr->h, &t);
273
 
274
   rbug_send_texture_read_reply(tr_rbug->con, serial,
275
                                t->resource->format,
276
                                util_format_get_blockwidth(t->resource->format),
277
                                util_format_get_blockheight(t->resource->format),
278
                                util_format_get_blocksize(t->resource->format),
279
                                (uint8_t*)map,
280
                                t->stride * util_format_get_nblocksy(t->resource->format,
281
                                                                     t->box.height),
282
                                t->stride,
283
                                NULL);
284
 
285
   context->transfer_unmap(context, t);
286
 
287
   pipe_mutex_unlock(rb_screen->list_mutex);
288
 
289
   return 0;
290
}
291
 
292
static int
293
rbug_context_list(struct rbug_rbug *tr_rbug, struct rbug_header *header, uint32_t serial)
294
{
295
   struct rbug_screen *rb_screen = tr_rbug->rb_screen;
296
   struct rbug_list *ptr;
297
   struct rbug_context *rb_context = NULL;
298
   rbug_context_t *ctxs;
299
   int i = 0;
300
 
301
   pipe_mutex_lock(rb_screen->list_mutex);
302
   ctxs = MALLOC(rb_screen->num_contexts * sizeof(rbug_context_t));
303
   foreach(ptr, &rb_screen->contexts) {
304
      rb_context = container_of(ptr, struct rbug_context, list);
305
      ctxs[i++] = VOID2U64(rb_context);
306
   }
307
   pipe_mutex_unlock(rb_screen->list_mutex);
308
 
309
   rbug_send_context_list_reply(tr_rbug->con, serial, ctxs, i, NULL);
310
   FREE(ctxs);
311
 
312
   return 0;
313
}
314
 
315
static int
316
rbug_context_info(struct rbug_rbug *tr_rbug, struct rbug_header *header, uint32_t serial)
317
{
318
   struct rbug_proto_context_info *info = (struct rbug_proto_context_info *)header;
319
 
320
   struct rbug_screen *rb_screen = tr_rbug->rb_screen;
321
   struct rbug_context *rb_context = NULL;
322
   rbug_texture_t cbufs[PIPE_MAX_COLOR_BUFS];
323
   rbug_texture_t texs[PIPE_MAX_SAMPLERS];
324
   unsigned i;
325
 
326
   pipe_mutex_lock(rb_screen->list_mutex);
327
   rb_context = rbug_get_context_locked(rb_screen, info->context);
328
 
329
   if (!rb_context) {
330
      pipe_mutex_unlock(rb_screen->list_mutex);
331
      return -ESRCH;
332
   }
333
 
334
   /* protect the pipe context */
335
   pipe_mutex_lock(rb_context->draw_mutex);
336
   pipe_mutex_lock(rb_context->call_mutex);
337
 
338
   for (i = 0; i < rb_context->curr.nr_cbufs; i++)
339
      cbufs[i] = VOID2U64(rb_context->curr.cbufs[i]);
340
 
341
   /* XXX what about vertex/geometry shader texture views? */
342
   for (i = 0; i < rb_context->curr.num_views[PIPE_SHADER_FRAGMENT]; i++)
343
      texs[i] = VOID2U64(rb_context->curr.texs[PIPE_SHADER_FRAGMENT][i]);
344
 
345
   rbug_send_context_info_reply(tr_rbug->con, serial,
346
                                VOID2U64(rb_context->curr.shader[PIPE_SHADER_VERTEX]), VOID2U64(rb_context->curr.shader[PIPE_SHADER_FRAGMENT]),
347
                                texs, rb_context->curr.num_views[PIPE_SHADER_FRAGMENT],
348
                                cbufs, rb_context->curr.nr_cbufs,
349
                                VOID2U64(rb_context->curr.zsbuf),
350
                                rb_context->draw_blocker, rb_context->draw_blocked, NULL);
351
 
352
   pipe_mutex_unlock(rb_context->call_mutex);
353
   pipe_mutex_unlock(rb_context->draw_mutex);
354
   pipe_mutex_unlock(rb_screen->list_mutex);
355
 
356
   return 0;
357
}
358
 
359
static int
360
rbug_context_draw_block(struct rbug_rbug *tr_rbug, struct rbug_header *header, uint32_t serial)
361
{
362
   struct rbug_proto_context_draw_block *block = (struct rbug_proto_context_draw_block *)header;
363
 
364
   struct rbug_screen *rb_screen = tr_rbug->rb_screen;
365
   struct rbug_context *rb_context = NULL;
366
 
367
   pipe_mutex_lock(rb_screen->list_mutex);
368
   rb_context = rbug_get_context_locked(rb_screen, block->context);
369
 
370
   if (!rb_context) {
371
      pipe_mutex_unlock(rb_screen->list_mutex);
372
      return -ESRCH;
373
   }
374
 
375
   pipe_mutex_lock(rb_context->draw_mutex);
376
   rb_context->draw_blocker |= block->block;
377
   pipe_mutex_unlock(rb_context->draw_mutex);
378
 
379
   pipe_mutex_unlock(rb_screen->list_mutex);
380
 
381
   return 0;
382
}
383
 
384
static int
385
rbug_context_draw_step(struct rbug_rbug *tr_rbug, struct rbug_header *header, uint32_t serial)
386
{
387
   struct rbug_proto_context_draw_step *step = (struct rbug_proto_context_draw_step *)header;
388
 
389
   struct rbug_screen *rb_screen = tr_rbug->rb_screen;
390
   struct rbug_context *rb_context = NULL;
391
 
392
   pipe_mutex_lock(rb_screen->list_mutex);
393
   rb_context = rbug_get_context_locked(rb_screen, step->context);
394
 
395
   if (!rb_context) {
396
      pipe_mutex_unlock(rb_screen->list_mutex);
397
      return -ESRCH;
398
   }
399
 
400
   pipe_mutex_lock(rb_context->draw_mutex);
401
   if (rb_context->draw_blocked & RBUG_BLOCK_RULE) {
402
      if (step->step & RBUG_BLOCK_RULE)
403
         rb_context->draw_blocked &= ~RBUG_BLOCK_MASK;
404
   } else {
405
      rb_context->draw_blocked &= ~step->step;
406
   }
407
   pipe_mutex_unlock(rb_context->draw_mutex);
408
 
409
   pipe_condvar_broadcast(rb_context->draw_cond);
410
 
411
   pipe_mutex_unlock(rb_screen->list_mutex);
412
 
413
   return 0;
414
}
415
 
416
static int
417
rbug_context_draw_unblock(struct rbug_rbug *tr_rbug, struct rbug_header *header, uint32_t serial)
418
{
419
   struct rbug_proto_context_draw_unblock *unblock = (struct rbug_proto_context_draw_unblock *)header;
420
 
421
   struct rbug_screen *rb_screen = tr_rbug->rb_screen;
422
   struct rbug_context *rb_context = NULL;
423
 
424
   pipe_mutex_lock(rb_screen->list_mutex);
425
   rb_context = rbug_get_context_locked(rb_screen, unblock->context);
426
 
427
   if (!rb_context) {
428
      pipe_mutex_unlock(rb_screen->list_mutex);
429
      return -ESRCH;
430
   }
431
 
432
   pipe_mutex_lock(rb_context->draw_mutex);
433
   if (rb_context->draw_blocked & RBUG_BLOCK_RULE) {
434
      if (unblock->unblock & RBUG_BLOCK_RULE)
435
         rb_context->draw_blocked &= ~RBUG_BLOCK_MASK;
436
   } else {
437
      rb_context->draw_blocked &= ~unblock->unblock;
438
   }
439
   rb_context->draw_blocker &= ~unblock->unblock;
440
   pipe_mutex_unlock(rb_context->draw_mutex);
441
 
442
   pipe_condvar_broadcast(rb_context->draw_cond);
443
 
444
   pipe_mutex_unlock(rb_screen->list_mutex);
445
 
446
   return 0;
447
}
448
 
449
static int
450
rbug_context_draw_rule(struct rbug_rbug *tr_rbug, struct rbug_header *header, uint32_t serial)
451
{
452
   struct rbug_proto_context_draw_rule *rule = (struct rbug_proto_context_draw_rule *)header;
453
 
454
   struct rbug_screen *rb_screen = tr_rbug->rb_screen;
455
   struct rbug_context *rb_context = NULL;
456
 
457
   pipe_mutex_lock(rb_screen->list_mutex);
458
   rb_context = rbug_get_context_locked(rb_screen, rule->context);
459
 
460
   if (!rb_context) {
461
      pipe_mutex_unlock(rb_screen->list_mutex);
462
      return -ESRCH;
463
   }
464
 
465
   pipe_mutex_lock(rb_context->draw_mutex);
466
   rb_context->draw_rule.shader[PIPE_SHADER_VERTEX] = U642VOID(rule->vertex);
467
   rb_context->draw_rule.shader[PIPE_SHADER_FRAGMENT] = U642VOID(rule->fragment);
468
   rb_context->draw_rule.texture = U642VOID(rule->texture);
469
   rb_context->draw_rule.surf = U642VOID(rule->surface);
470
   rb_context->draw_rule.blocker = rule->block;
471
   rb_context->draw_blocker |= RBUG_BLOCK_RULE;
472
   pipe_mutex_unlock(rb_context->draw_mutex);
473
 
474
   pipe_condvar_broadcast(rb_context->draw_cond);
475
 
476
   pipe_mutex_unlock(rb_screen->list_mutex);
477
 
478
   return 0;
479
}
480
 
481
static int
482
rbug_context_flush(struct rbug_rbug *tr_rbug, struct rbug_header *header, uint32_t serial)
483
{
484
   struct rbug_proto_context_flush *flush = (struct rbug_proto_context_flush *)header;
485
 
486
   struct rbug_screen *rb_screen = tr_rbug->rb_screen;
487
   struct rbug_context *rb_context = NULL;
488
 
489
   pipe_mutex_lock(rb_screen->list_mutex);
490
   rb_context = rbug_get_context_locked(rb_screen, flush->context);
491
 
492
   if (!rb_context) {
493
      pipe_mutex_unlock(rb_screen->list_mutex);
494
      return -ESRCH;
495
   }
496
 
497
   /* protect the pipe context */
498
   pipe_mutex_lock(rb_context->call_mutex);
499
 
500
   rb_context->pipe->flush(rb_context->pipe, NULL, 0);
501
 
502
   pipe_mutex_unlock(rb_context->call_mutex);
503
   pipe_mutex_unlock(rb_screen->list_mutex);
504
 
505
   return 0;
506
}
507
 
508
static int
509
rbug_shader_list(struct rbug_rbug *tr_rbug, struct rbug_header *header, uint32_t serial)
510
{
511
   struct rbug_proto_shader_list *list = (struct rbug_proto_shader_list *)header;
512
 
513
   struct rbug_screen *rb_screen = tr_rbug->rb_screen;
514
   struct rbug_context *rb_context = NULL;
515
   struct rbug_shader *tr_shdr = NULL;
516
   struct rbug_list *ptr;
517
   rbug_shader_t *shdrs;
518
   int i = 0;
519
 
520
   pipe_mutex_lock(rb_screen->list_mutex);
521
   rb_context = rbug_get_context_locked(rb_screen, list->context);
522
 
523
   if (!rb_context) {
524
      pipe_mutex_unlock(rb_screen->list_mutex);
525
      return -ESRCH;
526
   }
527
 
528
   pipe_mutex_lock(rb_context->list_mutex);
529
   shdrs = MALLOC(rb_context->num_shaders * sizeof(rbug_shader_t));
530
   foreach(ptr, &rb_context->shaders) {
531
      tr_shdr = container_of(ptr, struct rbug_shader, list);
532
      shdrs[i++] = VOID2U64(tr_shdr);
533
   }
534
 
535
   pipe_mutex_unlock(rb_context->list_mutex);
536
   pipe_mutex_unlock(rb_screen->list_mutex);
537
 
538
   rbug_send_shader_list_reply(tr_rbug->con, serial, shdrs, i, NULL);
539
   FREE(shdrs);
540
 
541
   return 0;
542
}
543
 
544
static int
545
rbug_shader_info(struct rbug_rbug *tr_rbug, struct rbug_header *header, uint32_t serial)
546
{
547
   struct rbug_proto_shader_info *info = (struct rbug_proto_shader_info *)header;
548
 
549
   struct rbug_screen *rb_screen = tr_rbug->rb_screen;
550
   struct rbug_context *rb_context = NULL;
551
   struct rbug_shader *tr_shdr = NULL;
552
   unsigned original_len;
553
   unsigned replaced_len;
554
 
555
   pipe_mutex_lock(rb_screen->list_mutex);
556
   rb_context = rbug_get_context_locked(rb_screen, info->context);
557
 
558
   if (!rb_context) {
559
      pipe_mutex_unlock(rb_screen->list_mutex);
560
      return -ESRCH;
561
   }
562
 
563
   pipe_mutex_lock(rb_context->list_mutex);
564
 
565
   tr_shdr = rbug_get_shader_locked(rb_context, info->shader);
566
 
567
   if (!tr_shdr) {
568
      pipe_mutex_unlock(rb_context->list_mutex);
569
      pipe_mutex_unlock(rb_screen->list_mutex);
570
      return -ESRCH;
571
   }
572
 
573
   /* just in case */
574
   assert(sizeof(struct tgsi_token) == 4);
575
 
576
   original_len = tgsi_num_tokens(tr_shdr->tokens);
577
   if (tr_shdr->replaced_tokens)
578
      replaced_len = tgsi_num_tokens(tr_shdr->replaced_tokens);
579
   else
580
      replaced_len = 0;
581
 
582
   rbug_send_shader_info_reply(tr_rbug->con, serial,
583
                               (uint32_t*)tr_shdr->tokens, original_len,
584
                               (uint32_t*)tr_shdr->replaced_tokens, replaced_len,
585
                               tr_shdr->disabled,
586
                               NULL);
587
 
588
   pipe_mutex_unlock(rb_context->list_mutex);
589
   pipe_mutex_unlock(rb_screen->list_mutex);
590
 
591
   return 0;
592
}
593
 
594
static int
595
rbug_shader_disable(struct rbug_rbug *tr_rbug, struct rbug_header *header)
596
{
597
   struct rbug_proto_shader_disable *dis = (struct rbug_proto_shader_disable *)header;
598
 
599
   struct rbug_screen *rb_screen = tr_rbug->rb_screen;
600
   struct rbug_context *rb_context = NULL;
601
   struct rbug_shader *tr_shdr = NULL;
602
 
603
   pipe_mutex_lock(rb_screen->list_mutex);
604
   rb_context = rbug_get_context_locked(rb_screen, dis->context);
605
 
606
   if (!rb_context) {
607
      pipe_mutex_unlock(rb_screen->list_mutex);
608
      return -ESRCH;
609
   }
610
 
611
   pipe_mutex_lock(rb_context->list_mutex);
612
 
613
   tr_shdr = rbug_get_shader_locked(rb_context, dis->shader);
614
 
615
   if (!tr_shdr) {
616
      pipe_mutex_unlock(rb_context->list_mutex);
617
      pipe_mutex_unlock(rb_screen->list_mutex);
618
      return -ESRCH;
619
   }
620
 
621
   tr_shdr->disabled = dis->disable;
622
 
623
   pipe_mutex_unlock(rb_context->list_mutex);
624
   pipe_mutex_unlock(rb_screen->list_mutex);
625
 
626
   return 0;
627
}
628
 
629
static int
630
rbug_shader_replace(struct rbug_rbug *tr_rbug, struct rbug_header *header)
631
{
632
   struct rbug_proto_shader_replace *rep = (struct rbug_proto_shader_replace *)header;
633
 
634
   struct rbug_screen *rb_screen = tr_rbug->rb_screen;
635
   struct rbug_context *rb_context = NULL;
636
   struct rbug_shader *tr_shdr = NULL;
637
   struct pipe_context *pipe = NULL;
638
   void *state;
639
 
640
   pipe_mutex_lock(rb_screen->list_mutex);
641
   rb_context = rbug_get_context_locked(rb_screen, rep->context);
642
 
643
   if (!rb_context) {
644
      pipe_mutex_unlock(rb_screen->list_mutex);
645
      return -ESRCH;
646
   }
647
 
648
   pipe_mutex_lock(rb_context->list_mutex);
649
 
650
   tr_shdr = rbug_get_shader_locked(rb_context, rep->shader);
651
 
652
   if (!tr_shdr) {
653
      pipe_mutex_unlock(rb_context->list_mutex);
654
      pipe_mutex_unlock(rb_screen->list_mutex);
655
      return -ESRCH;
656
   }
657
 
658
   /* protect the pipe context */
659
   pipe_mutex_lock(rb_context->call_mutex);
660
 
661
   pipe = rb_context->pipe;
662
 
663
   /* remove old replaced shader */
664
   if (tr_shdr->replaced_shader) {
665
      /* if this shader is bound rebind the original shader */
666
      if (rb_context->curr.shader[PIPE_SHADER_FRAGMENT] == tr_shdr || rb_context->curr.shader[PIPE_SHADER_VERTEX] == tr_shdr)
667
         rbug_shader_bind_locked(pipe, tr_shdr, tr_shdr->shader);
668
 
669
      FREE(tr_shdr->replaced_tokens);
670
      rbug_shader_delete_locked(pipe, tr_shdr, tr_shdr->replaced_shader);
671
      tr_shdr->replaced_shader = NULL;
672
      tr_shdr->replaced_tokens = NULL;
673
   }
674
 
675
   /* empty inputs means restore old which we did above */
676
   if (rep->tokens_len == 0)
677
      goto out;
678
 
679
   tr_shdr->replaced_tokens = tgsi_dup_tokens((struct tgsi_token *)rep->tokens);
680
   if (!tr_shdr->replaced_tokens)
681
      goto err;
682
 
683
   state = rbug_shader_create_locked(pipe, tr_shdr, tr_shdr->replaced_tokens);
684
   if (!state)
685
      goto err;
686
 
687
   /* bind new shader if the shader is currently a bound */
688
   if (rb_context->curr.shader[PIPE_SHADER_FRAGMENT] == tr_shdr || rb_context->curr.shader[PIPE_SHADER_VERTEX] == tr_shdr)
689
      rbug_shader_bind_locked(pipe, tr_shdr, state);
690
 
691
   /* save state */
692
   tr_shdr->replaced_shader = state;
693
 
694
out:
695
   pipe_mutex_unlock(rb_context->call_mutex);
696
   pipe_mutex_unlock(rb_context->list_mutex);
697
   pipe_mutex_unlock(rb_screen->list_mutex);
698
 
699
   return 0;
700
 
701
err:
702
   FREE(tr_shdr->replaced_tokens);
703
   tr_shdr->replaced_shader = NULL;
704
   tr_shdr->replaced_tokens = NULL;
705
 
706
   pipe_mutex_unlock(rb_context->call_mutex);
707
   pipe_mutex_unlock(rb_context->list_mutex);
708
   pipe_mutex_unlock(rb_screen->list_mutex);
709
   return -EINVAL;
710
}
711
 
712
static boolean
713
rbug_header(struct rbug_rbug *tr_rbug, struct rbug_header *header, uint32_t serial)
714
{
715
   int ret = 0;
716
 
717
   switch(header->opcode) {
718
      case RBUG_OP_PING:
719
         rbug_send_ping_reply(tr_rbug->con, serial, NULL);
720
         break;
721
      case RBUG_OP_TEXTURE_LIST:
722
         ret = rbug_texture_list(tr_rbug, header, serial);
723
         break;
724
      case RBUG_OP_TEXTURE_INFO:
725
         ret = rbug_texture_info(tr_rbug, header, serial);
726
         break;
727
      case RBUG_OP_TEXTURE_READ:
728
         ret = rbug_texture_read(tr_rbug, header, serial);
729
         break;
730
      case RBUG_OP_CONTEXT_LIST:
731
         ret = rbug_context_list(tr_rbug, header, serial);
732
         break;
733
      case RBUG_OP_CONTEXT_INFO:
734
         ret = rbug_context_info(tr_rbug, header, serial);
735
         break;
736
      case RBUG_OP_CONTEXT_DRAW_BLOCK:
737
         ret = rbug_context_draw_block(tr_rbug, header, serial);
738
         break;
739
      case RBUG_OP_CONTEXT_DRAW_STEP:
740
         ret = rbug_context_draw_step(tr_rbug, header, serial);
741
         break;
742
      case RBUG_OP_CONTEXT_DRAW_UNBLOCK:
743
         ret = rbug_context_draw_unblock(tr_rbug, header, serial);
744
         break;
745
      case RBUG_OP_CONTEXT_DRAW_RULE:
746
         ret = rbug_context_draw_rule(tr_rbug, header, serial);
747
         break;
748
      case RBUG_OP_CONTEXT_FLUSH:
749
         ret = rbug_context_flush(tr_rbug, header, serial);
750
         break;
751
      case RBUG_OP_SHADER_LIST:
752
         ret = rbug_shader_list(tr_rbug, header, serial);
753
         break;
754
      case RBUG_OP_SHADER_INFO:
755
         ret = rbug_shader_info(tr_rbug, header, serial);
756
         break;
757
      case RBUG_OP_SHADER_DISABLE:
758
         ret = rbug_shader_disable(tr_rbug, header);
759
         break;
760
      case RBUG_OP_SHADER_REPLACE:
761
         ret = rbug_shader_replace(tr_rbug, header);
762
         break;
763
      default:
764
         debug_printf("%s - unsupported opcode %u\n", __FUNCTION__, header->opcode);
765
         ret = -ENOSYS;
766
         break;
767
   }
768
   rbug_free_header(header);
769
 
770
   if (ret)
771
      rbug_send_error_reply(tr_rbug->con, serial, ret, NULL);
772
 
773
   return TRUE;
774
}
775
 
776
static void
777
rbug_con(struct rbug_rbug *tr_rbug)
778
{
779
   struct rbug_header *header;
780
   uint32_t serial;
781
 
782
   debug_printf("%s - connection received\n", __FUNCTION__);
783
 
784
   while(tr_rbug->running) {
785
      header = rbug_get_message(tr_rbug->con, &serial);
786
      if (!header)
787
         break;
788
 
789
      if (!rbug_header(tr_rbug, header, serial))
790
         break;
791
   }
792
 
793
   debug_printf("%s - connection closed\n", __FUNCTION__);
794
 
795
   rbug_disconnect(tr_rbug->con);
796
   tr_rbug->con = NULL;
797
}
798
 
799
PIPE_THREAD_ROUTINE(rbug_thread, void_tr_rbug)
800
{
801
   struct rbug_rbug *tr_rbug = void_tr_rbug;
802
   uint16_t port = 13370;
803
   int s = -1;
804
   int c;
805
 
806
   u_socket_init();
807
 
808
   for (;port <= 13379 && s < 0; port++)
809
      s = u_socket_listen_on_port(port);
810
 
811
   if (s < 0) {
812
      debug_printf("rbug_rbug - failed to listen\n");
813
      return NULL;
814
   }
815
 
816
   u_socket_block(s, false);
817
 
818
   debug_printf("rbug_rbug - remote debugging listening on port %u\n", --port);
819
 
820
   while(tr_rbug->running) {
821
      os_time_sleep(1);
822
 
823
      c = u_socket_accept(s);
824
      if (c < 0)
825
         continue;
826
 
827
      u_socket_block(c, true);
828
      tr_rbug->con = rbug_from_socket(c);
829
 
830
      rbug_con(tr_rbug);
831
 
832
      u_socket_close(c);
833
   }
834
 
835
   u_socket_close(s);
836
 
837
   u_socket_stop();
838
 
839
   return NULL;
840
}
841
 
842
/**********************************************************
843
 *
844
 */
845
 
846
struct rbug_rbug *
847
rbug_start(struct rbug_screen *rb_screen)
848
{
849
   struct rbug_rbug *tr_rbug = CALLOC_STRUCT(rbug_rbug);
850
   if (!tr_rbug)
851
      return NULL;
852
 
853
   tr_rbug->rb_screen = rb_screen;
854
   tr_rbug->running = TRUE;
855
   tr_rbug->thread = pipe_thread_create(rbug_thread, tr_rbug);
856
 
857
   return tr_rbug;
858
}
859
 
860
void
861
rbug_stop(struct rbug_rbug *tr_rbug)
862
{
863
   if (!tr_rbug)
864
      return;
865
 
866
   tr_rbug->running = false;
867
   pipe_thread_wait(tr_rbug->thread);
868
 
869
   FREE(tr_rbug);
870
 
871
   return;
872
}
873
 
874
void
875
rbug_notify_draw_blocked(struct rbug_context *rb_context)
876
{
877
   struct rbug_screen *rb_screen = rbug_screen(rb_context->base.screen);
878
   struct rbug_rbug *tr_rbug = rb_screen->rbug;
879
 
880
   if (tr_rbug && tr_rbug->con)
881
      rbug_send_context_draw_blocked(tr_rbug->con,
882
                                     VOID2U64(rb_context), rb_context->draw_blocked, NULL);
883
}