diff options
Diffstat (limited to 'src/gallium/drivers/trace')
-rw-r--r-- | src/gallium/drivers/trace/tr_context.c | 33 | ||||
-rw-r--r-- | src/gallium/drivers/trace/tr_context.h | 10 | ||||
-rw-r--r-- | src/gallium/drivers/trace/tr_rbug.c | 51 |
3 files changed, 91 insertions, 3 deletions
diff --git a/src/gallium/drivers/trace/tr_context.c b/src/gallium/drivers/trace/tr_context.c index 7a39bdb42c2..24e4e3e09b5 100644 --- a/src/gallium/drivers/trace/tr_context.c +++ b/src/gallium/drivers/trace/tr_context.c @@ -116,13 +116,44 @@ trace_context_set_edgeflags(struct pipe_context *_pipe, static INLINE void trace_context_draw_block(struct trace_context *tr_ctx, int flag) { + int k; + pipe_mutex_lock(tr_ctx->draw_mutex); if (tr_ctx->draw_blocker & flag) { tr_ctx->draw_blocked |= flag; + } else if ((tr_ctx->draw_rule.blocker & flag) && + (tr_ctx->draw_blocker & 4)) { + boolean block = FALSE; + debug_printf("%s (%lu %lu) (%lu %lu) (%lu %u) (%lu %u)\n", __func__, + tr_ctx->draw_rule.fs, tr_ctx->curr.fs, + tr_ctx->draw_rule.vs, tr_ctx->curr.vs, + tr_ctx->draw_rule.surf, 0, + tr_ctx->draw_rule.tex, 0); + if (tr_ctx->draw_rule.fs && + tr_ctx->draw_rule.fs == tr_ctx->curr.fs) + block = TRUE; + if (tr_ctx->draw_rule.vs && + tr_ctx->draw_rule.vs == tr_ctx->curr.vs) + block = TRUE; + if (tr_ctx->draw_rule.surf && + tr_ctx->draw_rule.surf == tr_ctx->curr.zsbuf) + block = TRUE; + if (tr_ctx->draw_rule.surf) + for (k = 0; k < tr_ctx->curr.nr_cbufs; k++) + if (tr_ctx->draw_rule.surf == tr_ctx->curr.cbufs[k]) + block = TRUE; + if (tr_ctx->draw_rule.tex) + for (k = 0; k < tr_ctx->curr.num_texs; k++) + if (tr_ctx->draw_rule.tex == tr_ctx->curr.tex[k]) + block = TRUE; + + if (block) + tr_ctx->draw_blocked |= (flag | 4); + } + if (tr_ctx->draw_blocked) trace_rbug_notify_draw_blocked(tr_ctx); - } /* wait for rbug to clear the blocked flag */ while (tr_ctx->draw_blocked & flag) { diff --git a/src/gallium/drivers/trace/tr_context.h b/src/gallium/drivers/trace/tr_context.h index ff86b6d1055..6febe4b4114 100644 --- a/src/gallium/drivers/trace/tr_context.h +++ b/src/gallium/drivers/trace/tr_context.h @@ -59,6 +59,16 @@ struct trace_context struct trace_texture *zsbuf; } curr; + struct { + struct trace_shader *fs; + struct trace_shader *vs; + + struct trace_texture *tex; + struct trace_texture *surf; + + int blocker; + } draw_rule; + unsigned draw_num_rules; pipe_condvar draw_cond; pipe_mutex draw_mutex; int draw_blocker; diff --git a/src/gallium/drivers/trace/tr_rbug.c b/src/gallium/drivers/trace/tr_rbug.c index 68184e9a5d6..e85ac15edca 100644 --- a/src/gallium/drivers/trace/tr_rbug.c +++ b/src/gallium/drivers/trace/tr_rbug.c @@ -374,7 +374,12 @@ trace_rbug_context_draw_step(struct trace_rbug *tr_rbug, struct rbug_header *hea } pipe_mutex_lock(tr_ctx->draw_mutex); - tr_ctx->draw_blocked &= ~step->step; + if (tr_ctx->draw_blocked & RBUG_BLOCK_RULE) { + if (step->step & RBUG_BLOCK_RULE) + tr_ctx->draw_blocked &= ~RBUG_BLOCK_MASK; + } else { + tr_ctx->draw_blocked &= ~step->step; + } pipe_mutex_unlock(tr_ctx->draw_mutex); #ifdef PIPE_THREAD_HAVE_CONDVAR @@ -403,7 +408,12 @@ trace_rbug_context_draw_unblock(struct trace_rbug *tr_rbug, struct rbug_header * } pipe_mutex_lock(tr_ctx->draw_mutex); - tr_ctx->draw_blocked &= ~unblock->unblock; + if (tr_ctx->draw_blocked & RBUG_BLOCK_RULE) { + if (unblock->unblock & RBUG_BLOCK_RULE) + tr_ctx->draw_blocked &= ~RBUG_BLOCK_MASK; + } else { + tr_ctx->draw_blocked &= ~unblock->unblock; + } tr_ctx->draw_blocker &= ~unblock->unblock; pipe_mutex_unlock(tr_ctx->draw_mutex); @@ -417,6 +427,40 @@ trace_rbug_context_draw_unblock(struct trace_rbug *tr_rbug, struct rbug_header * } static int +trace_rbug_context_draw_rule(struct trace_rbug *tr_rbug, struct rbug_header *header, uint32_t serial) +{ + struct rbug_proto_context_draw_rule *rule = (struct rbug_proto_context_draw_rule *)header; + + struct trace_screen *tr_scr = tr_rbug->tr_scr; + struct trace_context *tr_ctx = NULL; + + pipe_mutex_lock(tr_scr->list_mutex); + tr_ctx = trace_rbug_get_context_locked(tr_scr, rule->context); + + if (!tr_ctx) { + pipe_mutex_unlock(tr_scr->list_mutex); + return -ESRCH; + } + + pipe_mutex_lock(tr_ctx->draw_mutex); + tr_ctx->draw_rule.vs = U642VOID(rule->vertex); + tr_ctx->draw_rule.fs = U642VOID(rule->fragment); + tr_ctx->draw_rule.tex = U642VOID(rule->texture); + tr_ctx->draw_rule.surf = U642VOID(rule->surface); + tr_ctx->draw_rule.blocker = rule->block; + tr_ctx->draw_blocker |= RBUG_BLOCK_RULE; + pipe_mutex_unlock(tr_ctx->draw_mutex); + +#ifdef PIPE_THREAD_HAVE_CONDVAR + pipe_condvar_broadcast(tr_ctx->draw_cond); +#endif + + pipe_mutex_unlock(tr_scr->list_mutex); + + return 0; +} + +static int trace_rbug_context_flush(struct trace_rbug *tr_rbug, struct rbug_header *header, uint32_t serial) { struct rbug_proto_context_flush *flush = (struct rbug_proto_context_flush *)header; @@ -679,6 +723,9 @@ trace_rbug_header(struct trace_rbug *tr_rbug, struct rbug_header *header, uint32 case RBUG_OP_CONTEXT_DRAW_UNBLOCK: ret = trace_rbug_context_draw_unblock(tr_rbug, header, serial); break; + case RBUG_OP_CONTEXT_DRAW_RULE: + ret = trace_rbug_context_draw_rule(tr_rbug, header, serial); + break; case RBUG_OP_CONTEXT_FLUSH: ret = trace_rbug_context_flush(tr_rbug, header, serial); break; |