aboutsummaryrefslogtreecommitdiffstats
path: root/src/gallium
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium')
-rw-r--r--src/gallium/drivers/radeonsi/r600_hw_context.c58
-rw-r--r--src/gallium/drivers/radeonsi/radeonsi_pipe.c22
-rw-r--r--src/gallium/drivers/radeonsi/radeonsi_pipe.h12
-rw-r--r--src/gallium/drivers/radeonsi/radeonsi_pm4.c12
-rw-r--r--src/gallium/drivers/radeonsi/si_state_draw.c7
-rw-r--r--src/gallium/drivers/radeonsi/sid.h14
6 files changed, 124 insertions, 1 deletions
diff --git a/src/gallium/drivers/radeonsi/r600_hw_context.c b/src/gallium/drivers/radeonsi/r600_hw_context.c
index bd348f9fe14..0975a1fe978 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;
+
+ va = r600_resource_va(&rscreen->screen, (void*)rscreen->trace_bo);
+ r600_context_bo_reloc(rctx, rscreen->trace_bo, RADEON_USAGE_READWRITE);
+ cs->buf[cs->cdw++] = PKT3(PKT3_WRITE_DATA, 4, 0);
+ cs->buf[cs->cdw++] = PKT3_WRITE_DATA_DST_SEL(PKT3_WRITE_DATA_DST_SEL_MEM_SYNC) |
+ PKT3_WRITE_DATA_WR_CONFIRM |
+ PKT3_WRITE_DATA_ENGINE_SEL(PKT3_WRITE_DATA_ENGINE_SEL_ME);
+ cs->buf[cs->cdw++] = va & 0xFFFFFFFFUL;
+ cs->buf[cs->cdw++] = (va >> 32UL) & 0xFFFFFFFFUL;
+ cs->buf[cs->cdw++] = cs->cdw;
+ cs->buf[cs->cdw++] = rscreen->cs_count;
+}
+#endif
diff --git a/src/gallium/drivers/radeonsi/radeonsi_pipe.c b/src/gallium/drivers/radeonsi/radeonsi_pipe.c
index 672017a4ec7..0d243097839 100644
--- a/src/gallium/drivers/radeonsi/radeonsi_pipe.c
+++ b/src/gallium/drivers/radeonsi/radeonsi_pipe.c
@@ -522,6 +522,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);
@@ -724,5 +732,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 d0f04f40562..40a5c8c3d90 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 6
+
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 79a2521f339..8e01738253e 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 a78751bf802..1e1d1cc6d6b 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. */
diff --git a/src/gallium/drivers/radeonsi/sid.h b/src/gallium/drivers/radeonsi/sid.h
index 57553a69be2..8528981ab79 100644
--- a/src/gallium/drivers/radeonsi/sid.h
+++ b/src/gallium/drivers/radeonsi/sid.h
@@ -77,6 +77,20 @@
#define PKT3_DRAW_INDEX_IMMD 0x2E
#define PKT3_NUM_INSTANCES 0x2F
#define PKT3_STRMOUT_BUFFER_UPDATE 0x34
+#define PKT3_WRITE_DATA 0x37
+#define PKT3_WRITE_DATA_DST_SEL(x) ((x) << 8)
+#define PKT3_WRITE_DATA_DST_SEL_REG 0
+#define PKT3_WRITE_DATA_DST_SEL_MEM_SYNC 1
+#define PKT3_WRITE_DATA_DST_SEL_TC_OR_L2 2
+#define PKT3_WRITE_DATA_DST_SEL_GDS 3
+#define PKT3_WRITE_DATA_DST_SEL_RESERVED_4 4
+#define PKT3_WRITE_DATA_DST_SEL_MEM_ASYNC 5
+#define PKT3_WR_ONE_ADDR (1 << 16)
+#define PKT3_WRITE_DATA_WR_CONFIRM (1 << 20)
+#define PKT3_WRITE_DATA_ENGINE_SEL(x) ((x) << 30)
+#define PKT3_WRITE_DATA_ENGINE_SEL_ME 0
+#define PKT3_WRITE_DATA_ENGINE_SEL_PFP 1
+#define PKT3_WRITE_DATA_ENGINE_SEL_CE 2
#define PKT3_MEM_SEMAPHORE 0x39
#define PKT3_MPEG_INDEX 0x3A
#define PKT3_WAIT_REG_MEM 0x3C