[Mesa-dev] [PATCH 06/10] radeonsi: write shader descriptors into hang reports

Marek Olšák maraeo at gmail.com
Fri Dec 2 20:39:25 UTC 2016


From: Marek Olšák <marek.olsak at amd.com>

---
 src/gallium/drivers/radeonsi/si_debug.c       | 114 ++++++++++++++++++++++++++
 src/gallium/drivers/radeonsi/si_descriptors.c |   1 +
 src/gallium/drivers/radeonsi/si_state.h       |   2 +
 3 files changed, 117 insertions(+)

diff --git a/src/gallium/drivers/radeonsi/si_debug.c b/src/gallium/drivers/radeonsi/si_debug.c
index b2c3574..1090dda 100644
--- a/src/gallium/drivers/radeonsi/si_debug.c
+++ b/src/gallium/drivers/radeonsi/si_debug.c
@@ -667,37 +667,151 @@ static void si_dump_framebuffer(struct si_context *sctx, FILE *f)
 	}
 
 	if (state->zsbuf) {
 		rtex = (struct r600_texture*)state->zsbuf->texture;
 		fprintf(f, COLOR_YELLOW "Depth-stencil buffer:" COLOR_RESET "\n");
 		r600_print_texture_info(rtex, f);
 		fprintf(f, "\n");
 	}
 }
 
+static void si_dump_descriptor_list(struct si_descriptors *desc,
+				    const char *shader_name,
+				    const char *elem_name,
+				    unsigned num_elements,
+				    FILE *f)
+{
+	unsigned i, j;
+	uint32_t *cpu_list = desc->list;
+	uint32_t *gpu_list = desc->gpu_list;
+	const char *list_note = "GPU list";
+
+	if (!gpu_list) {
+		gpu_list = cpu_list;
+		list_note = "CPU list";
+	}
+
+	for (i = 0; i < num_elements; i++) {
+		fprintf(f, COLOR_GREEN "%s%s slot %u (%s):" COLOR_RESET "\n",
+			shader_name, elem_name, i, list_note);
+
+		switch (desc->element_dw_size) {
+		case 4:
+			for (j = 0; j < 4; j++)
+				si_dump_reg(f, R_008F00_SQ_BUF_RSRC_WORD0 + j*4,
+					    gpu_list[j], 0xffffffff);
+			break;
+		case 8:
+			for (j = 0; j < 8; j++)
+				si_dump_reg(f, R_008F10_SQ_IMG_RSRC_WORD0 + j*4,
+					    gpu_list[j], 0xffffffff);
+
+			fprintf(f, COLOR_CYAN "    Buffer:" COLOR_RESET "\n");
+			for (j = 0; j < 4; j++)
+				si_dump_reg(f, R_008F00_SQ_BUF_RSRC_WORD0 + j*4,
+					    gpu_list[4+j], 0xffffffff);
+			break;
+		case 16:
+			for (j = 0; j < 8; j++)
+				si_dump_reg(f, R_008F10_SQ_IMG_RSRC_WORD0 + j*4,
+					    gpu_list[j], 0xffffffff);
+
+			fprintf(f, COLOR_CYAN "    Buffer:" COLOR_RESET "\n");
+			for (j = 0; j < 4; j++)
+				si_dump_reg(f, R_008F00_SQ_BUF_RSRC_WORD0 + j*4,
+					    gpu_list[4+j], 0xffffffff);
+
+			fprintf(f, COLOR_CYAN "    FMASK:" COLOR_RESET "\n");
+			for (j = 0; j < 8; j++)
+				si_dump_reg(f, R_008F10_SQ_IMG_RSRC_WORD0 + j*4,
+					    gpu_list[8+j], 0xffffffff);
+
+			fprintf(f, COLOR_CYAN "    Sampler state:" COLOR_RESET "\n");
+			for (j = 0; j < 4; j++)
+				si_dump_reg(f, R_008F30_SQ_IMG_SAMP_WORD0 + j*4,
+					    gpu_list[12+j], 0xffffffff);
+			break;
+		}
+
+		if (memcmp(gpu_list, cpu_list, desc->element_dw_size * 4) != 0) {
+			fprintf(f, COLOR_RED "!!!!! This slot was corrupted in GPU memory !!!!!"
+				COLOR_RESET "\n");
+		}
+
+		fprintf(f, "\n");
+		gpu_list += desc->element_dw_size;
+		cpu_list += desc->element_dw_size;
+	}
+}
+
+static void si_dump_descriptors(struct si_context *sctx,
+				struct si_shader_ctx_state *state,
+				FILE *f)
+{
+	if (!state->cso || !state->current)
+		return;
+
+	unsigned type = state->cso->type;
+	const struct tgsi_shader_info *info = &state->cso->info;
+	struct si_descriptors *descs =
+		&sctx->descriptors[SI_DESCS_FIRST_SHADER +
+				   type * SI_NUM_SHADER_DESCS];
+	static const char *shader_name[] = {"VS", "PS", "GS", "TCS", "TES", "CS"};
+
+	static const char *elem_name[] = {
+		" - Constant buffer",
+		" - Shader buffer",
+		" - Sampler",
+		" - Image",
+	};
+	unsigned num_elements[] = {
+		util_last_bit(info->const_buffers_declared),
+		util_last_bit(info->shader_buffers_declared),
+		util_last_bit(info->samplers_declared),
+		util_last_bit(info->images_declared),
+	};
+
+	if (type == PIPE_SHADER_VERTEX) {
+		si_dump_descriptor_list(&sctx->vertex_buffers, shader_name[type],
+					" - Vertex buffer", info->num_inputs, f);
+	}
+
+	for (unsigned i = 0; i < SI_NUM_SHADER_DESCS; ++i, ++descs)
+		si_dump_descriptor_list(descs, shader_name[type], elem_name[i],
+					num_elements[i], f);
+}
+
 static void si_dump_debug_state(struct pipe_context *ctx, FILE *f,
 				unsigned flags)
 {
 	struct si_context *sctx = (struct si_context*)ctx;
 
 	if (flags & PIPE_DUMP_DEVICE_STATUS_REGISTERS)
 		si_dump_debug_registers(sctx, f);
 
 	if (flags & PIPE_DUMP_CURRENT_STATES)
 		si_dump_framebuffer(sctx, f);
 
 	if (flags & PIPE_DUMP_CURRENT_SHADERS) {
 		si_dump_shader(sctx->screen, &sctx->vs_shader, f);
 		si_dump_shader(sctx->screen, &sctx->tcs_shader, f);
 		si_dump_shader(sctx->screen, &sctx->tes_shader, f);
 		si_dump_shader(sctx->screen, &sctx->gs_shader, f);
 		si_dump_shader(sctx->screen, &sctx->ps_shader, f);
+
+		si_dump_descriptor_list(&sctx->descriptors[SI_DESCS_RW_BUFFERS],
+					"", "RW buffers", SI_NUM_RW_BUFFERS, f);
+		si_dump_descriptors(sctx, &sctx->vs_shader, f);
+		si_dump_descriptors(sctx, &sctx->tcs_shader, f);
+		si_dump_descriptors(sctx, &sctx->tes_shader, f);
+		si_dump_descriptors(sctx, &sctx->gs_shader, f);
+		si_dump_descriptors(sctx, &sctx->ps_shader, f);
 	}
 
 	if (flags & PIPE_DUMP_LAST_COMMAND_BUFFER) {
 		si_dump_bo_list(sctx, &sctx->last_gfx, f);
 		si_dump_last_ib(sctx, f);
 
 		fprintf(f, "Done.\n");
 
 		/* dump only once */
 		radeon_clear_saved_cs(&sctx->last_gfx);
diff --git a/src/gallium/drivers/radeonsi/si_descriptors.c b/src/gallium/drivers/radeonsi/si_descriptors.c
index 4f78b1a..681c3f9 100644
--- a/src/gallium/drivers/radeonsi/si_descriptors.c
+++ b/src/gallium/drivers/radeonsi/si_descriptors.c
@@ -234,20 +234,21 @@ static bool si_upload_descriptors(struct si_context *sctx,
 	} else {
 		void *ptr;
 
 		u_upload_alloc(sctx->b.uploader, 0, list_size, 256,
 			&desc->buffer_offset,
 			(struct pipe_resource**)&desc->buffer, &ptr);
 		if (!desc->buffer)
 			return false; /* skip the draw call */
 
 		util_memcpy_cpu_to_le32(ptr, desc->list, list_size);
+		desc->gpu_list = ptr;
 
 		radeon_add_to_buffer_list(&sctx->b, &sctx->b.gfx, desc->buffer,
 	                            RADEON_USAGE_READ, RADEON_PRIO_DESCRIPTORS);
 	}
 	desc->pointer_dirty = true;
 	desc->dirty_mask = 0;
 
 	if (atom)
 		si_mark_atom_dirty(sctx, atom);
 
diff --git a/src/gallium/drivers/radeonsi/si_state.h b/src/gallium/drivers/radeonsi/si_state.h
index eb7a69f..d8e6024 100644
--- a/src/gallium/drivers/radeonsi/si_state.h
+++ b/src/gallium/drivers/radeonsi/si_state.h
@@ -210,20 +210,22 @@ enum {
                                         PIPE_SHADER_COMPUTE * SI_NUM_SHADER_DESCS)
 #define SI_NUM_DESCS                   (SI_DESCS_FIRST_SHADER + \
                                         SI_NUM_SHADERS * SI_NUM_SHADER_DESCS)
 
 /* This represents descriptors in memory, such as buffer resources,
  * image resources, and sampler states.
  */
 struct si_descriptors {
 	/* The list of descriptors in malloc'd memory. */
 	uint32_t *list;
+	/* The list in mapped GPU memory. */
+	uint32_t *gpu_list;
 	/* The size of one descriptor. */
 	unsigned element_dw_size;
 	/* The maximum number of descriptors. */
 	unsigned num_elements;
 
 	/* The buffer where the descriptors have been uploaded. */
 	struct r600_resource *buffer;
 	unsigned buffer_offset;
 
 	/* Offset in CE RAM */
-- 
2.7.4



More information about the mesa-dev mailing list