[Mesa-dev] [PATCH 10/53] r600: add support for GDS clause to the assembler.

Dave Airlie airlied at gmail.com
Sun Nov 29 22:20:19 PST 2015


From: Dave Airlie <airlied at redhat.com>

This just adds enough for the tessellation shaders,
which require TF_WRITE to work.

Signed-off-by: Dave Airlie <airlied at redhat.com>
---
 src/gallium/drivers/r600/eg_asm.c   | 23 +++++++++++
 src/gallium/drivers/r600/eg_sq.h    | 21 ++++++++++
 src/gallium/drivers/r600/r600_asm.c | 82 +++++++++++++++++++++++++++++++++++++
 src/gallium/drivers/r600/r600_asm.h | 23 ++++++++++-
 4 files changed, 148 insertions(+), 1 deletion(-)

diff --git a/src/gallium/drivers/r600/eg_asm.c b/src/gallium/drivers/r600/eg_asm.c
index c32d317..f555649 100644
--- a/src/gallium/drivers/r600/eg_asm.c
+++ b/src/gallium/drivers/r600/eg_asm.c
@@ -193,3 +193,26 @@ int egcm_load_index_reg(struct r600_bytecode *bc, unsigned id, bool inside_alu_c
 
 	return 0;
 }
+
+int eg_bytecode_gds_build(struct r600_bytecode *bc, struct r600_bytecode_gds *gds, unsigned id)
+{
+	unsigned opcode = r600_isa_fetch_opcode(bc->isa->hw_class, gds->op) >> 8;
+	bc->bytecode[id++] = S_SQ_MEM_GDS_WORD0_MEM_INST(2) |
+		S_SQ_MEM_GDS_WORD0_MEM_OP(opcode) |
+		S_SQ_MEM_GDS_WORD0_SRC_GPR(gds->src_gpr) |
+		S_SQ_MEM_GDS_WORD0_SRC_REL(gds->src_rel) |
+		S_SQ_MEM_GDS_WORD0_SRC_SEL_X(gds->src_sel_x) |
+		S_SQ_MEM_GDS_WORD0_SRC_SEL_Y(gds->src_sel_y) |
+		S_SQ_MEM_GDS_WORD0_SRC_SEL_Z(gds->src_sel_z);
+
+	bc->bytecode[id++] = S_SQ_MEM_GDS_WORD1_DST_GPR(gds->dst_gpr) |
+		S_SQ_MEM_GDS_WORD1_DST_REL(gds->dst_rel) |
+		S_SQ_MEM_GDS_WORD1_GDS_OP(gds->gds_op) |
+		S_SQ_MEM_GDS_WORD1_SRC_GPR(gds->src_gpr2);
+
+	bc->bytecode[id++] = S_SQ_MEM_GDS_WORD2_DST_SEL_X(gds->dst_sel_x) |
+		S_SQ_MEM_GDS_WORD2_DST_SEL_Y(gds->dst_sel_y) |
+		S_SQ_MEM_GDS_WORD2_DST_SEL_Z(gds->dst_sel_z) |
+		S_SQ_MEM_GDS_WORD2_DST_SEL_W(gds->dst_sel_w);
+	return 0;
+}
diff --git a/src/gallium/drivers/r600/eg_sq.h b/src/gallium/drivers/r600/eg_sq.h
index 97e230f..3074cfe 100644
--- a/src/gallium/drivers/r600/eg_sq.h
+++ b/src/gallium/drivers/r600/eg_sq.h
@@ -514,6 +514,27 @@
 #define   G_SQ_TEX_WORD2_SRC_SEL_W(x)                                (((x) >> 29) & 0x7)
 #define   C_SQ_TEX_WORD2_SRC_SEL_W                                   0x1FFFFFFF
 
+#define P_SQ_MEM_GDS_WORD0
+#define   S_SQ_MEM_GDS_WORD0_MEM_INST(x)                             (((x) & 0x1f) << 0)
+#define   S_SQ_MEM_GDS_WORD0_MEM_OP(x)                               (((x) & 0x7) << 8)
+#define   S_SQ_MEM_GDS_WORD0_SRC_GPR(x)                              (((x) & 0x7f) << 11)
+#define   S_SQ_MEM_GDS_WORD0_SRC_REL(x)                              (((x) & 0x3) << 18)
+#define   S_SQ_MEM_GDS_WORD0_SRC_SEL_X(x)                            (((x) & 0x7) << 20)
+#define   S_SQ_MEM_GDS_WORD0_SRC_SEL_Y(x)                            (((x) & 0x7) << 23)
+#define   S_SQ_MEM_GDS_WORD0_SRC_SEL_Z(x)                            (((x) & 0x7) << 26)
+
+#define P_SQ_MEM_GDS_WORD1
+#define   S_SQ_MEM_GDS_WORD1_DST_GPR(x)                              (((x) & 0x7f) << 0)
+#define   S_SQ_MEM_GDS_WORD1_DST_REL(x)                              (((x) & 0x3) << 7)
+#define   S_SQ_MEM_GDS_WORD1_GDS_OP(x)                               (((x) & 0x3f) << 9)
+#define   S_SQ_MEM_GDS_WORD1_SRC_GPR(x)                              (((x) & 0x7f) << 16)
+
+#define P_SQ_MEM_GDS_WORD2
+#define   S_SQ_MEM_GDS_WORD2_DST_SEL_X(x)                            (((x) & 0x7) << 0)
+#define   S_SQ_MEM_GDS_WORD2_DST_SEL_Y(x)                            (((x) & 0x7) << 3)
+#define   S_SQ_MEM_GDS_WORD2_DST_SEL_Z(x)                            (((x) & 0x7) << 6)
+#define   S_SQ_MEM_GDS_WORD2_DST_SEL_W(x)                            (((x) & 0x7) << 9)
+
 #define V_SQ_CF_COND_ACTIVE                             0x00
 #define V_SQ_CF_COND_FALSE                              0x01
 #define V_SQ_CF_COND_BOOL                               0x02
diff --git a/src/gallium/drivers/r600/r600_asm.c b/src/gallium/drivers/r600/r600_asm.c
index 91faa82..41e9c19 100644
--- a/src/gallium/drivers/r600/r600_asm.c
+++ b/src/gallium/drivers/r600/r600_asm.c
@@ -61,6 +61,7 @@ static struct r600_bytecode_cf *r600_bytecode_cf(void)
 	LIST_INITHEAD(&cf->alu);
 	LIST_INITHEAD(&cf->vtx);
 	LIST_INITHEAD(&cf->tex);
+	LIST_INITHEAD(&cf->gds);
 	return cf;
 }
 
@@ -94,6 +95,16 @@ static struct r600_bytecode_tex *r600_bytecode_tex(void)
 	return tex;
 }
 
+static struct r600_bytecode_gds *r600_bytecode_gds(void)
+{
+	struct r600_bytecode_gds *gds = CALLOC_STRUCT(r600_bytecode_gds);
+
+	if (gds == NULL)
+		return NULL;
+	LIST_INITHEAD(&gds->list);
+	return gds;
+}
+
 static unsigned stack_entry_size(enum radeon_family chip) {
 	/* Wavefront size:
 	 *   64: R600/RV670/RV770/Cypress/R740/Barts/Turks/Caicos/
@@ -1412,6 +1423,33 @@ int r600_bytecode_add_tex(struct r600_bytecode *bc, const struct r600_bytecode_t
 	return 0;
 }
 
+int r600_bytecode_add_gds(struct r600_bytecode *bc, const struct r600_bytecode_gds *gds)
+{
+	struct r600_bytecode_gds *ngds = r600_bytecode_gds();
+	int r;
+
+	if (ngds == NULL)
+		return -ENOMEM;
+	memcpy(ngds, gds, sizeof(struct r600_bytecode_gds));
+
+	if (bc->cf_last == NULL ||
+	    bc->cf_last->op != CF_OP_GDS ||
+	    bc->force_add_cf) {
+		r = r600_bytecode_add_cf(bc);
+		if (r) {
+			free(ngds);
+			return r;
+		}
+		bc->cf_last->op = CF_OP_GDS;
+	}
+
+	LIST_ADDTAIL(&ngds->list, &bc->cf_last->gds);
+	bc->cf_last->ndw += 4; /* each GDS uses 4 dwords */
+	if ((bc->cf_last->ndw / 4) >= r600_bytecode_num_tex_and_vtx_instructions(bc))
+		bc->force_add_cf = 1;
+	return 0;
+}
+
 int r600_bytecode_add_cfinst(struct r600_bytecode *bc, unsigned op)
 {
 	int r;
@@ -1623,6 +1661,7 @@ int r600_bytecode_build(struct r600_bytecode *bc)
 	struct r600_bytecode_alu *alu;
 	struct r600_bytecode_vtx *vtx;
 	struct r600_bytecode_tex *tex;
+	struct r600_bytecode_gds *gds;
 	uint32_t literal[4];
 	unsigned nliteral;
 	unsigned addr;
@@ -1701,6 +1740,14 @@ int r600_bytecode_build(struct r600_bytecode *bc)
 					return r;
 				addr += 4;
 			}
+		} else if (cf->op == CF_OP_GDS) {
+			assert(bc->chip_class >= EVERGREEN);
+			LIST_FOR_EACH_ENTRY(gds, &cf->gds, list) {
+				r = eg_bytecode_gds_build(bc, gds, addr);
+				if (r)
+					return r;
+				addr += 4;
+			}
 		} else if (cf->op == CF_OP_TEX) {
 			LIST_FOR_EACH_ENTRY(vtx, &cf->vtx, list) {
 				assert(bc->chip_class >= EVERGREEN);
@@ -1731,6 +1778,7 @@ void r600_bytecode_clear(struct r600_bytecode *bc)
 		struct r600_bytecode_alu *alu = NULL, *next_alu;
 		struct r600_bytecode_tex *tex = NULL, *next_tex;
 		struct r600_bytecode_tex *vtx = NULL, *next_vtx;
+		struct r600_bytecode_gds *gds = NULL, *next_gds;
 
 		LIST_FOR_EACH_ENTRY_SAFE(alu, next_alu, &cf->alu, list) {
 			free(alu);
@@ -1750,6 +1798,12 @@ void r600_bytecode_clear(struct r600_bytecode *bc)
 
 		LIST_INITHEAD(&cf->vtx);
 
+		LIST_FOR_EACH_ENTRY_SAFE(gds, next_gds, &cf->gds, list) {
+			free(gds);
+		}
+
+		LIST_INITHEAD(&cf->gds);
+
 		free(cf);
 	}
 
@@ -1911,6 +1965,7 @@ void r600_bytecode_disasm(struct r600_bytecode *bc)
 	struct r600_bytecode_alu *alu = NULL;
 	struct r600_bytecode_vtx *vtx = NULL;
 	struct r600_bytecode_tex *tex = NULL;
+	struct r600_bytecode_gds *gds = NULL;
 
 	unsigned i, id, ngr = 0, last;
 	uint32_t literal[4];
@@ -2194,6 +2249,33 @@ void r600_bytecode_disasm(struct r600_bytecode *bc)
 
 			id += 4;
 		}
+
+		LIST_FOR_EACH_ENTRY(gds, &cf->gds, list) {
+			int o = 0;
+			o += fprintf(stderr, " %04d %08X %08X %08X   ", id, bc->bytecode[id],
+					bc->bytecode[id + 1], bc->bytecode[id + 2]);
+
+			o += fprintf(stderr, "%s ", r600_isa_fetch(gds->op)->name);
+
+			if (gds->op != FETCH_OP_TF_WRITE) {
+				o += fprintf(stderr, "R%d.", gds->dst_gpr);
+				o += print_swizzle(gds->dst_sel_x);
+				o += print_swizzle(gds->dst_sel_y);
+				o += print_swizzle(gds->dst_sel_z);
+				o += print_swizzle(gds->dst_sel_w);
+			}
+
+			o += fprintf(stderr, ", R%d.", gds->src_gpr);
+			o += print_swizzle(gds->src_sel_x);
+			o += print_swizzle(gds->src_sel_y);
+			o += print_swizzle(gds->src_sel_z);
+
+			if (gds->op != FETCH_OP_TF_WRITE) {
+				o += fprintf(stderr, ", R%d.", gds->src_gpr2);
+			}
+			fprintf(stderr, "\n");
+			id += 4;
+		}
 	}
 
 	fprintf(stderr, "--------------------------------------\n");
diff --git a/src/gallium/drivers/r600/r600_asm.h b/src/gallium/drivers/r600/r600_asm.h
index d48ad1e..f786bab 100644
--- a/src/gallium/drivers/r600/r600_asm.h
+++ b/src/gallium/drivers/r600/r600_asm.h
@@ -115,6 +115,24 @@ struct r600_bytecode_vtx {
 	unsigned			buffer_index_mode;
 };
 
+struct r600_bytecode_gds {
+	struct list_head		list;
+	unsigned			op;
+	unsigned                        gds_op;
+	unsigned			src_gpr;
+	unsigned			src_rel;
+	unsigned			src_sel_x;
+	unsigned			src_sel_y;
+	unsigned			src_sel_z;
+	unsigned			src_gpr2;
+	unsigned			dst_gpr;
+	unsigned			dst_rel;
+	unsigned			dst_sel_x;
+	unsigned			dst_sel_y;
+	unsigned			dst_sel_z;
+	unsigned			dst_sel_w;
+};
+
 struct r600_bytecode_output {
 	unsigned			array_base;
 	unsigned			array_size;
@@ -159,6 +177,7 @@ struct r600_bytecode_cf {
 	struct list_head		alu;
 	struct list_head		tex;
 	struct list_head		vtx;
+	struct list_head		gds;
 	struct r600_bytecode_output		output;
 	struct r600_bytecode_alu		*curr_bs_head;
 	struct r600_bytecode_alu		*prev_bs_head;
@@ -233,7 +252,7 @@ struct r600_bytecode {
 /* eg_asm.c */
 int eg_bytecode_cf_build(struct r600_bytecode *bc, struct r600_bytecode_cf *cf);
 int egcm_load_index_reg(struct r600_bytecode *bc, unsigned id, bool inside_alu_clause);
-
+int eg_bytecode_gds_build(struct r600_bytecode *bc, struct r600_bytecode_gds *gds, unsigned id);
 /* r600_asm.c */
 void r600_bytecode_init(struct r600_bytecode *bc,
 			enum chip_class chip_class,
@@ -246,6 +265,8 @@ int r600_bytecode_add_vtx(struct r600_bytecode *bc,
 		const struct r600_bytecode_vtx *vtx);
 int r600_bytecode_add_tex(struct r600_bytecode *bc,
 		const struct r600_bytecode_tex *tex);
+int r600_bytecode_add_gds(struct r600_bytecode *bc,
+		const struct r600_bytecode_gds *gds);
 int r600_bytecode_add_output(struct r600_bytecode *bc,
 		const struct r600_bytecode_output *output);
 int r600_bytecode_build(struct r600_bytecode *bc);
-- 
2.5.0



More information about the mesa-dev mailing list