On Mon, Mar 25, 2013 at 12:01 PM, <j.gli...@gmail.com> wrote: > From: Jerome Glisse <jgli...@redhat.com> > > Same as on r600, trace cs execution by writting cs offset after each > states, this allow to pin point lockup inside command stream and > narrow down the scope of lockup investigation. > > Signed-off-by: Jerome Glisse <jgli...@redhat.com> > --- > src/gallium/drivers/radeonsi/r600_hw_context.c | 58 > ++++++++++++++++++++++++++ > src/gallium/drivers/radeonsi/r600_texture.c | 2 +- > src/gallium/drivers/radeonsi/radeonsi_pipe.c | 22 ++++++++++ > src/gallium/drivers/radeonsi/radeonsi_pipe.h | 12 ++++++ > src/gallium/drivers/radeonsi/radeonsi_pm4.c | 12 ++++++ > src/gallium/drivers/radeonsi/si_state_draw.c | 7 +++- > 6 files changed, 111 insertions(+), 2 deletions(-) > > diff --git a/src/gallium/drivers/radeonsi/r600_hw_context.c > b/src/gallium/drivers/radeonsi/r600_hw_context.c > index bd348f9..3cd5d0e 100644 > --- a/src/gallium/drivers/radeonsi/r600_hw_context.c > +++ b/src/gallium/drivers/radeonsi/r600_hw_context.c > @@ -142,6 +142,12 @@ void si_need_cs_space(struct r600_context *ctx, unsigned > num_dw, > /* Save 16 dwords for the fence mechanism. */ > num_dw += 16; > > +#if R600_TRACE_CS > + if (ctx->screen->trace_bo) { > + num_dw += R600_TRACE_CS_DWORDS; > + } > +#endif > + > /* Flush if there's not enough space. */ > if (num_dw > RADEON_MAX_CMDBUF_DWORDS) { > radeonsi_flush(&ctx->context, NULL, RADEON_FLUSH_ASYNC); > @@ -206,9 +212,41 @@ void si_context_flush(struct r600_context *ctx, unsigned > flags) > /* force to keep tiling flags */ > flags |= RADEON_FLUSH_KEEP_TILING_FLAGS; > > +#if R600_TRACE_CS > + if (ctx->screen->trace_bo) { > + struct r600_screen *rscreen = ctx->screen; > + unsigned i; > + > + for (i = 0; i < cs->cdw; i++) { > + fprintf(stderr, "[%4d] [%5d] 0x%08x\n", > rscreen->cs_count, i, cs->buf[i]); > + } > + rscreen->cs_count++; > + } > +#endif > + > /* Flush the CS. */ > ctx->ws->cs_flush(ctx->cs, flags); > > +#if R600_TRACE_CS > + if (ctx->screen->trace_bo) { > + struct r600_screen *rscreen = ctx->screen; > + unsigned i; > + > + for (i = 0; i < 10; i++) { > + usleep(5); > + if (!ctx->ws->buffer_is_busy(rscreen->trace_bo->buf, > RADEON_USAGE_READWRITE)) { > + break; > + } > + } > + if (i == 10) { > + fprintf(stderr, "timeout on cs lockup likely happen > at cs %d dw %d\n", > + rscreen->trace_ptr[1], rscreen->trace_ptr[0]); > + } else { > + fprintf(stderr, "cs %d executed in %dms\n", > rscreen->trace_ptr[1], i * 5); > + } > + } > +#endif > + > ctx->pm4_dirty_cdwords = 0; > ctx->flags = 0; > > @@ -665,3 +703,23 @@ void r600_context_draw_opaque_count(struct r600_context > *ctx, struct r600_so_tar > cs->buf[cs->cdw++] = r600_context_bo_reloc(ctx, t->filled_size, > RADEON_USAGE_READ); > > } > + > +#if R600_TRACE_CS > +void r600_trace_emit(struct r600_context *rctx) > +{ > + struct r600_screen *rscreen = rctx->screen; > + struct radeon_winsys_cs *cs = rctx->cs; > + uint64_t va; > + uint32_t reloc; > + > + va = r600_resource_va(&rscreen->screen, (void*)rscreen->trace_bo); > + reloc = r600_context_bo_reloc(rctx, rscreen->trace_bo, > RADEON_USAGE_READWRITE); > + cs->buf[cs->cdw++] = PKT3(PKT3_MEM_WRITE, 3, 0);
I would suggest using the WRITE_DATA packet here since MEM_WRITE is deprecated on SI. Alex > + cs->buf[cs->cdw++] = va & 0xFFFFFFFFUL; > + cs->buf[cs->cdw++] = (va >> 32UL) & 0xFFUL; > + cs->buf[cs->cdw++] = cs->cdw; > + cs->buf[cs->cdw++] = rscreen->cs_count; > + cs->buf[cs->cdw++] = PKT3(PKT3_NOP, 0, 0); > + cs->buf[cs->cdw++] = reloc; > +} > +#endif > diff --git a/src/gallium/drivers/radeonsi/r600_texture.c > b/src/gallium/drivers/radeonsi/r600_texture.c > index 6cafc3d..3d074a3 100644 > --- a/src/gallium/drivers/radeonsi/r600_texture.c > +++ b/src/gallium/drivers/radeonsi/r600_texture.c > @@ -550,7 +550,7 @@ struct pipe_resource *si_texture_create(struct > pipe_screen *screen, > > if (!(templ->flags & R600_RESOURCE_FLAG_TRANSFER) && > !(templ->bind & PIPE_BIND_SCANOUT)) { > - array_mode = V_009910_ARRAY_2D_TILED_THIN1; > + array_mode = V_009910_ARRAY_1D_TILED_THIN1; > } > > r = r600_init_surface(rscreen, &surface, templ, array_mode, > diff --git a/src/gallium/drivers/radeonsi/radeonsi_pipe.c > b/src/gallium/drivers/radeonsi/radeonsi_pipe.c > index c5dac29..a370d7e 100644 > --- a/src/gallium/drivers/radeonsi/radeonsi_pipe.c > +++ b/src/gallium/drivers/radeonsi/radeonsi_pipe.c > @@ -525,6 +525,14 @@ static void r600_destroy_screen(struct pipe_screen* > pscreen) > rscreen->ws->buffer_unmap(rscreen->fences.bo->cs_buf); > si_resource_reference(&rscreen->fences.bo, NULL); > } > + > +#if R600_TRACE_CS > + if (rscreen->trace_bo) { > + rscreen->ws->buffer_unmap(rscreen->trace_bo->cs_buf); > + pipe_resource_reference((struct > pipe_resource**)&rscreen->trace_bo, NULL); > + } > +#endif > + > pipe_mutex_destroy(rscreen->fences.mutex); > > rscreen->ws->destroy(rscreen->ws); > @@ -727,5 +735,19 @@ struct pipe_screen *radeonsi_screen_create(struct > radeon_winsys *ws) > LIST_INITHEAD(&rscreen->fences.blocks); > pipe_mutex_init(rscreen->fences.mutex); > > +#if R600_TRACE_CS > + rscreen->cs_count = 0; > + if (rscreen->info.drm_minor >= 28) { > + rscreen->trace_bo = (struct > si_resource*)pipe_buffer_create(&rscreen->screen, > + > PIPE_BIND_CUSTOM, > + > PIPE_USAGE_STAGING, > + > 4096); > + if (rscreen->trace_bo) { > + rscreen->trace_ptr = > rscreen->ws->buffer_map(rscreen->trace_bo->cs_buf, NULL, > + > PIPE_TRANSFER_UNSYNCHRONIZED); > + } > + } > +#endif > + > return &rscreen->screen; > } > diff --git a/src/gallium/drivers/radeonsi/radeonsi_pipe.h > b/src/gallium/drivers/radeonsi/radeonsi_pipe.h > index d0f04f4..f5c03ce 100644 > --- a/src/gallium/drivers/radeonsi/radeonsi_pipe.h > +++ b/src/gallium/drivers/radeonsi/radeonsi_pipe.h > @@ -47,6 +47,9 @@ > #define R600_BIG_ENDIAN 0 > #endif > > +#define R600_TRACE_CS 0 > +#define R600_TRACE_CS_DWORDS 7 > + > struct r600_pipe_fences { > struct si_resource *bo; > unsigned *data; > @@ -67,6 +70,11 @@ struct r600_screen { > struct r600_tiling_info tiling_info; > struct util_slab_mempool pool_buffers; > struct r600_pipe_fences fences; > +#if R600_TRACE_CS > + struct si_resource *trace_bo; > + uint32_t *trace_ptr; > + unsigned cs_count; > +#endif > }; > > struct si_pipe_sampler_view { > @@ -226,6 +234,10 @@ void r600_translate_index_buffer(struct r600_context > *r600, > struct pipe_index_buffer *ib, > unsigned count); > > +#if R600_TRACE_CS > +void r600_trace_emit(struct r600_context *rctx); > +#endif > + > /* > * common helpers > */ > diff --git a/src/gallium/drivers/radeonsi/radeonsi_pm4.c > b/src/gallium/drivers/radeonsi/radeonsi_pm4.c > index 79a2521..8e01738 100644 > --- a/src/gallium/drivers/radeonsi/radeonsi_pm4.c > +++ b/src/gallium/drivers/radeonsi/radeonsi_pm4.c > @@ -199,6 +199,12 @@ unsigned si_pm4_dirty_dw(struct r600_context *rctx) > continue; > > count += state->ndw; > +#if R600_TRACE_CS > + /* for tracing each states */ > + if (rctx->screen->trace_bo) { > + count += R600_TRACE_CS_DWORDS; > + } > +#endif > } > > return count; > @@ -219,6 +225,12 @@ void si_pm4_emit(struct r600_context *rctx, struct > si_pm4_state *state) > } > > cs->cdw += state->ndw; > + > +#if R600_TRACE_CS > + if (rctx->screen->trace_bo) { > + r600_trace_emit(rctx); > + } > +#endif > } > > void si_pm4_emit_dirty(struct r600_context *rctx) > diff --git a/src/gallium/drivers/radeonsi/si_state_draw.c > b/src/gallium/drivers/radeonsi/si_state_draw.c > index a78751b..1e1d1cc 100644 > --- a/src/gallium/drivers/radeonsi/si_state_draw.c > +++ b/src/gallium/drivers/radeonsi/si_state_draw.c > @@ -579,6 +579,12 @@ void si_draw_vbo(struct pipe_context *ctx, const struct > pipe_draw_info *info) > si_pm4_emit_dirty(rctx); > rctx->pm4_dirty_cdwords = 0; > > +#if R600_TRACE_CS > + if (rctx->screen->trace_bo) { > + r600_trace_emit(rctx); > + } > +#endif > + > #if 0 > /* Enable stream out if needed. */ > if (rctx->streamout_start) { > @@ -587,7 +593,6 @@ void si_draw_vbo(struct pipe_context *ctx, const struct > pipe_draw_info *info) > } > #endif > > - > rctx->flags |= R600_CONTEXT_DST_CACHES_DIRTY; > > /* Set the depth buffer as dirty. */ > -- > 1.8.1.4 > > _______________________________________________ > mesa-dev mailing list > mesa-dev@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/mesa-dev _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev