diff options
-rw-r--r-- | src/gallium/drivers/trace/tr_context.c | 57 | ||||
-rw-r--r-- | src/gallium/drivers/trace/tr_context.h | 11 | ||||
-rw-r--r-- | src/gallium/drivers/trace/tr_rbug.c | 169 |
3 files changed, 236 insertions, 1 deletions
diff --git a/src/gallium/drivers/trace/tr_context.c b/src/gallium/drivers/trace/tr_context.c index 2ad5ca4998..b04cc2ce56 100644 --- a/src/gallium/drivers/trace/tr_context.c +++ b/src/gallium/drivers/trace/tr_context.c @@ -113,6 +113,28 @@ trace_context_set_edgeflags(struct pipe_context *_pipe, } +static INLINE void +trace_context_draw_block(struct trace_context *tr_ctx, int flag) +{ + pipe_mutex_lock(tr_ctx->draw_mutex); + + if (tr_ctx->draw_blocker & flag) { + tr_ctx->draw_blocked |= flag; + + trace_rbug_notify_draw_blocked(tr_ctx); + } + + /* wait for rbug to clear the blocked flag */ + while (tr_ctx->draw_blocked & flag) { + tr_ctx->draw_blocked |= flag; + pipe_mutex_unlock(tr_ctx->draw_mutex); + /* TODO sleep or use conditional */ + pipe_mutex_lock(tr_ctx->draw_mutex); + } + + pipe_mutex_unlock(tr_ctx->draw_mutex); +} + static INLINE boolean trace_context_draw_arrays(struct pipe_context *_pipe, unsigned mode, unsigned start, unsigned count) @@ -124,6 +146,8 @@ trace_context_draw_arrays(struct pipe_context *_pipe, if (tr_ctx->curr.fs->disabled || tr_ctx->curr.vs->disabled) return 0; + trace_context_draw_block(tr_ctx, 1); + trace_dump_call_begin("pipe_context", "draw_arrays"); trace_dump_arg(ptr, pipe); @@ -137,6 +161,8 @@ trace_context_draw_arrays(struct pipe_context *_pipe, trace_dump_call_end(); + trace_context_draw_block(tr_ctx, 2); + return result; } @@ -156,6 +182,8 @@ trace_context_draw_elements(struct pipe_context *_pipe, if (tr_ctx->curr.fs->disabled || tr_ctx->curr.vs->disabled) return 0; + trace_context_draw_block(tr_ctx, 1); + trace_screen_user_buffer_update(_pipe->screen, indexBuffer); trace_dump_call_begin("pipe_context", "draw_elements"); @@ -173,6 +201,8 @@ trace_context_draw_elements(struct pipe_context *_pipe, trace_dump_call_end(); + trace_context_draw_block(tr_ctx, 2); + return result; } @@ -196,6 +226,8 @@ trace_context_draw_range_elements(struct pipe_context *_pipe, if (tr_ctx->curr.fs->disabled || tr_ctx->curr.vs->disabled) return 0; + trace_context_draw_block(tr_ctx, 1); + trace_screen_user_buffer_update(_pipe->screen, indexBuffer); trace_dump_call_begin("pipe_context", "draw_range_elements"); @@ -218,6 +250,8 @@ trace_context_draw_range_elements(struct pipe_context *_pipe, trace_dump_call_end(); + trace_context_draw_block(tr_ctx, 2); + return result; } @@ -782,6 +816,19 @@ trace_context_set_framebuffer_state(struct pipe_context *_pipe, struct pipe_framebuffer_state unwrapped_state; unsigned i; + { + tr_ctx->curr.nr_cbufs = state->nr_cbufs; + for (i = 0; i < state->nr_cbufs; i++) + if (state->cbufs[i]) + tr_ctx->curr.cbufs[i] = trace_texture(state->cbufs[i]->texture); + else + tr_ctx->curr.cbufs[i] = NULL; + if (state->zsbuf) + tr_ctx->curr.zsbuf = trace_texture(state->zsbuf->texture); + else + tr_ctx->curr.zsbuf = NULL; + } + /* Unwrap the input state */ memcpy(&unwrapped_state, state, sizeof(unwrapped_state)); for(i = 0; i < state->nr_cbufs; ++i) @@ -1113,6 +1160,12 @@ trace_is_buffer_referenced( struct pipe_context *_pipe, return referenced; } +static const struct debug_named_value rbug_blocker_flags[] = { + {"before", 1}, + {"after", 2}, + {NULL, 0}, +}; + struct pipe_context * trace_context_create(struct pipe_screen *_screen, struct pipe_context *pipe) @@ -1134,6 +1187,10 @@ trace_context_create(struct pipe_screen *_screen, if(!tr_ctx) goto error1; + tr_ctx->draw_blocker = debug_get_flags_option("RBUG_BLOCK", + rbug_blocker_flags, + 0); + pipe_mutex_init(tr_ctx->draw_mutex); pipe_mutex_init(tr_ctx->list_mutex); make_empty_list(&tr_ctx->shaders); diff --git a/src/gallium/drivers/trace/tr_context.h b/src/gallium/drivers/trace/tr_context.h index 86827f97b2..770e975a14 100644 --- a/src/gallium/drivers/trace/tr_context.h +++ b/src/gallium/drivers/trace/tr_context.h @@ -50,8 +50,16 @@ struct trace_context struct { struct trace_shader *fs; struct trace_shader *vs; + + unsigned nr_cbufs; + struct trace_texture *cbufs[PIPE_MAX_COLOR_BUFS]; + struct trace_texture *zsbuf; } curr; + pipe_mutex draw_mutex; + int draw_blocker; + int draw_blocked; + /* for list on screen */ struct tr_list list; @@ -75,6 +83,9 @@ struct pipe_context * trace_context_create(struct pipe_screen *screen, struct pipe_context *pipe); +void +trace_rbug_notify_draw_blocked(struct trace_context *tr_ctx); + #ifdef __cplusplus } diff --git a/src/gallium/drivers/trace/tr_rbug.c b/src/gallium/drivers/trace/tr_rbug.c index 1b26f60da4..db9de8f3c4 100644 --- a/src/gallium/drivers/trace/tr_rbug.c +++ b/src/gallium/drivers/trace/tr_rbug.c @@ -289,6 +289,147 @@ trace_rbug_context_list(struct trace_rbug *tr_rbug, struct rbug_header *header, } static int +trace_rbug_context_info(struct trace_rbug *tr_rbug, struct rbug_header *header, uint32_t serial) +{ + struct rbug_proto_context_info *info = (struct rbug_proto_context_info *)header; + + struct trace_screen *tr_scr = tr_rbug->tr_scr; + struct trace_context *tr_ctx = NULL; + rbug_texture_t cbufs[PIPE_MAX_COLOR_BUFS]; + int i; + + pipe_mutex_lock(tr_scr->list_mutex); + tr_ctx = trace_rbug_get_context_locked(tr_scr, info->context); + + if (!tr_ctx) { + pipe_mutex_unlock(tr_scr->list_mutex); + return -ESRCH; + } + + /* protect the pipe context */ + pipe_mutex_lock(tr_ctx->draw_mutex); + trace_dump_call_lock(); + + for (i = 0; i < tr_ctx->curr.nr_cbufs; i++) + cbufs[i] = VOID2U64(tr_ctx->curr.cbufs[i]); + + rbug_send_context_info_reply(tr_rbug->con, serial, + VOID2U64(tr_ctx->curr.vs), VOID2U64(tr_ctx->curr.fs), + cbufs, tr_ctx->curr.nr_cbufs, VOID2U64(tr_ctx->curr.zsbuf), + tr_ctx->draw_blocker, tr_ctx->draw_blocked, NULL); + + trace_dump_call_unlock(); + pipe_mutex_unlock(tr_ctx->draw_mutex); + + pipe_mutex_unlock(tr_scr->list_mutex); + + return 0; +} + +static int +trace_rbug_context_draw_block(struct trace_rbug *tr_rbug, struct rbug_header *header, uint32_t serial) +{ + struct rbug_proto_context_draw_block *block = (struct rbug_proto_context_draw_block *)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, block->context); + + if (!tr_ctx) { + pipe_mutex_unlock(tr_scr->list_mutex); + return -ESRCH; + } + + pipe_mutex_lock(tr_ctx->draw_mutex); + tr_ctx->draw_blocker |= block->block; + pipe_mutex_unlock(tr_ctx->draw_mutex); + + pipe_mutex_unlock(tr_scr->list_mutex); + + return 0; +} + +static int +trace_rbug_context_draw_step(struct trace_rbug *tr_rbug, struct rbug_header *header, uint32_t serial) +{ + struct rbug_proto_context_draw_step *step = (struct rbug_proto_context_draw_step *)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, step->context); + + if (!tr_ctx) { + pipe_mutex_unlock(tr_scr->list_mutex); + return -ESRCH; + } + + pipe_mutex_lock(tr_ctx->draw_mutex); + tr_ctx->draw_blocked &= ~step->step; + pipe_mutex_unlock(tr_ctx->draw_mutex); + + pipe_mutex_unlock(tr_scr->list_mutex); + + return 0; +} + +static int +trace_rbug_context_draw_unblock(struct trace_rbug *tr_rbug, struct rbug_header *header, uint32_t serial) +{ + struct rbug_proto_context_draw_unblock *unblock = (struct rbug_proto_context_draw_unblock *)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, unblock->context); + + if (!tr_ctx) { + pipe_mutex_unlock(tr_scr->list_mutex); + return -ESRCH; + } + + pipe_mutex_lock(tr_ctx->draw_mutex); + tr_ctx->draw_blocked &= ~unblock->unblock; + tr_ctx->draw_blocker &= ~unblock->unblock; + pipe_mutex_unlock(tr_ctx->draw_mutex); + + 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; + + 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, flush->context); + + if (!tr_ctx) { + pipe_mutex_unlock(tr_scr->list_mutex); + return -ESRCH; + } + + /* protect the pipe context */ + trace_dump_call_lock(); + + tr_ctx->pipe->flush(tr_ctx->pipe, flush->flags, NULL); + + trace_dump_call_unlock(); + pipe_mutex_unlock(tr_scr->list_mutex); + + return 0; +} + +static int trace_rbug_shader_list(struct trace_rbug *tr_rbug, struct rbug_header *header, uint32_t serial) { struct rbug_proto_shader_list *list = (struct rbug_proto_shader_list *)header; @@ -512,6 +653,21 @@ trace_rbug_header(struct trace_rbug *tr_rbug, struct rbug_header *header, uint32 case RBUG_OP_CONTEXT_LIST: ret = trace_rbug_context_list(tr_rbug, header, serial); break; + case RBUG_OP_CONTEXT_INFO: + ret = trace_rbug_context_info(tr_rbug, header, serial); + break; + case RBUG_OP_CONTEXT_DRAW_BLOCK: + ret = trace_rbug_context_draw_block(tr_rbug, header, serial); + break; + case RBUG_OP_CONTEXT_DRAW_STEP: + ret = trace_rbug_context_draw_step(tr_rbug, header, serial); + break; + case RBUG_OP_CONTEXT_DRAW_UNBLOCK: + ret = trace_rbug_context_draw_unblock(tr_rbug, header, serial); + break; + case RBUG_OP_CONTEXT_FLUSH: + ret = trace_rbug_context_flush(tr_rbug, header, serial); + break; case RBUG_OP_SHADER_LIST: ret = trace_rbug_shader_list(tr_rbug, header, serial); break; @@ -610,7 +766,7 @@ PIPE_THREAD_ROUTINE(trace_rbug_thread, void_tr_rbug) struct trace_rbug * trace_rbug_start(struct trace_screen *tr_scr) { - struct trace_rbug *tr_rbug = MALLOC_STRUCT(trace_rbug); + struct trace_rbug *tr_rbug = CALLOC_STRUCT(trace_rbug); if (!tr_rbug) return NULL; @@ -634,3 +790,14 @@ trace_rbug_stop(struct trace_rbug *tr_rbug) return; } + +void +trace_rbug_notify_draw_blocked(struct trace_context *tr_ctx) +{ + struct trace_screen *tr_scr = trace_screen(tr_ctx->base.screen); + struct trace_rbug *tr_rbug = tr_scr->rbug; + + if (tr_rbug && tr_rbug->con) + rbug_send_context_draw_blocked(tr_rbug->con, + VOID2U64(tr_ctx), tr_ctx->draw_blocked, NULL); +} |