Mesa (master): r600g: add point/sprite rendering support

Jerome Glisse glisse at kemper.freedesktop.org
Wed Aug 11 16:20:08 UTC 2010


Module: Mesa
Branch: master
Commit: 457378e031ffb89a2011604c7798a6f5f2142207
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=457378e031ffb89a2011604c7798a6f5f2142207

Author: Jerome Glisse <jglisse at redhat.com>
Date:   Wed Aug 11 12:19:33 2010 -0400

r600g: add point/sprite rendering support

Signed-off-by: Jerome Glisse <jglisse at redhat.com>

---

 src/gallium/drivers/r600/r600_shader.c |   60 +++++++++++++++++++----
 src/gallium/drivers/r600/r600_state.c  |   23 ++++++++-
 src/gallium/drivers/r600/r600d.h       |   80 ++++++++++++++++++++++++++++++++
 3 files changed, 149 insertions(+), 14 deletions(-)

diff --git a/src/gallium/drivers/r600/r600_shader.c b/src/gallium/drivers/r600/r600_shader.c
index 8a778f5..ca65bff 100644
--- a/src/gallium/drivers/r600/r600_shader.c
+++ b/src/gallium/drivers/r600/r600_shader.c
@@ -105,8 +105,8 @@ int r600_pipe_shader_create(struct pipe_context *ctx,
 	struct r600_screen *rscreen = r600_screen(ctx->screen);
 	int r;
 
-//fprintf(stderr, "--------------------------------------------------------------\n");
-//tgsi_dump(tokens, 0);
+fprintf(stderr, "--------------------------------------------------------------\n");
+tgsi_dump(tokens, 0);
 	if (rpshader == NULL)
 		return -ENOMEM;
 	rpshader->shader.family = radeon_get_family(rscreen->rw);
@@ -120,7 +120,7 @@ int r600_pipe_shader_create(struct pipe_context *ctx,
 		R600_ERR("building bytecode failed !\n");
 		return r;
 	}
-//fprintf(stderr, "______________________________________________________________\n");
+fprintf(stderr, "______________________________________________________________\n");
 	return 0;
 }
 
@@ -155,11 +155,14 @@ static int r600_pipe_shader_vs(struct pipe_context *ctx, struct r600_context_sta
 
 static int r600_pipe_shader_ps(struct pipe_context *ctx, struct r600_context_state *rpshader)
 {
+	const struct pipe_rasterizer_state *rasterizer;
 	struct r600_screen *rscreen = r600_screen(ctx->screen);
 	struct r600_shader *rshader = &rpshader->shader;
+	struct r600_context *rctx = r600_context(ctx);
 	struct radeon_state *state;
 	unsigned i, tmp, exports_ps, num_cout;
 
+	rasterizer = &rctx->rasterizer->state.rasterizer;
 	rpshader->rstate = radeon_state_decref(rpshader->rstate);
 	state = radeon_state(rscreen->rw, R600_PS_SHADER_TYPE, R600_PS_SHADER);
 	if (state == NULL)
@@ -171,6 +174,9 @@ static int r600_pipe_shader_ps(struct pipe_context *ctx, struct r600_context_sta
 			rshader->input[i].name == TGSI_SEMANTIC_BCOLOR) {
 			tmp |= S_028644_FLAT_SHADE(rshader->flat_shade);
 		}
+		if (rasterizer->sprite_coord_enable & (1 << i)) {
+			tmp |= S_028644_PT_SPRITE_TEX(1);
+		}
 		state->states[R600_PS_SHADER__SPI_PS_INPUT_CNTL_0 + i] = tmp;
 	}
 
@@ -340,7 +346,7 @@ int r600_shader_from_tgsi(const struct tgsi_token *tokens, struct r600_shader *s
 	struct tgsi_full_immediate *immediate;
 	struct r600_shader_ctx ctx;
 	struct r600_bc_output output[32];
-	unsigned output_done;
+	unsigned output_done, noutput;
 	unsigned opcode;
 	int i, r = 0, pos0;
 
@@ -418,7 +424,8 @@ int r600_shader_from_tgsi(const struct tgsi_token *tokens, struct r600_shader *s
 		}
 	}
 	/* export output */
-	for (i = 0, pos0 = 0; i < shader->noutput; i++) {
+	noutput = shader->noutput;
+	for (i = 0, pos0 = 0; i < noutput; i++) {
 		memset(&output[i], 0, sizeof(struct r600_bc_output));
 		output[i].gpr = shader->output[i].gpr;
 		output[i].elem_size = 3;
@@ -430,13 +437,19 @@ int r600_shader_from_tgsi(const struct tgsi_token *tokens, struct r600_shader *s
 		output[i].type = V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_PARAM;
 		output[i].array_base = i - pos0;
 		output[i].inst = V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT;
-		switch (ctx.type == TGSI_PROCESSOR_VERTEX) {
+		switch (ctx.type) {
 		case TGSI_PROCESSOR_VERTEX:
 			if (shader->output[i].name == TGSI_SEMANTIC_POSITION) {
 				output[i].array_base = 60;
 				output[i].type = V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_POS;
 				/* position doesn't count in array_base */
-				pos0 = 1;
+				pos0++;
+			}
+			if (shader->output[i].name == TGSI_SEMANTIC_PSIZE) {
+				output[i].array_base = 61;
+				output[i].type = V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_POS;
+				/* position doesn't count in array_base */
+				pos0++;
 			}
 			break;
 		case TGSI_PROCESSOR_FRAGMENT:
@@ -457,17 +470,42 @@ int r600_shader_from_tgsi(const struct tgsi_token *tokens, struct r600_shader *s
 			r = -EINVAL;
 			goto out_err;
 		}
-		if (i == (shader->noutput - 1)) {
-			output[i].end_of_program = 1;
+	}
+	/* add fake param output for vertex shader if no param is exported */
+	if (ctx.type == TGSI_PROCESSOR_VERTEX) {
+		for (i = 0, pos0 = 0; i < noutput; i++) {
+			if (output[i].type == V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_PARAM) {
+				pos0 = 1;
+				break;
+			}
+		}
+		if (!pos0) {
+			memset(&output[i], 0, sizeof(struct r600_bc_output));
+			output[i].gpr = 0;
+			output[i].elem_size = 3;
+			output[i].swizzle_x = 0;
+			output[i].swizzle_y = 1;
+			output[i].swizzle_z = 2;
+			output[i].swizzle_w = 3;
+			output[i].barrier = 1;
+			output[i].type = V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_PARAM;
+			output[i].array_base = 0;
+			output[i].inst = V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT;
+			noutput++;
 		}
 	}
-	for (i = shader->noutput - 1, output_done = 0; i >= 0; i--) {
+	/* set export done on last export of each type */
+	for (i = noutput - 1, output_done = 0; i >= 0; i--) {
+		if (i == (noutput - 1)) {
+			output[i].end_of_program = 1;
+		}
 		if (!(output_done & (1 << output[i].type))) {
 			output_done |= (1 << output[i].type);
 			output[i].inst = V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT_DONE;
 		}
 	}
-	for (i = 0; i < shader->noutput; i++) {
+	/* add output to bytecode */
+	for (i = 0; i < noutput; i++) {
 		r = r600_bc_add_output(ctx.bc, &output[i]);
 		if (r)
 			goto out_err;
diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c
index cad5185..a50b75c 100644
--- a/src/gallium/drivers/r600/r600_state.c
+++ b/src/gallium/drivers/r600/r600_state.c
@@ -769,6 +769,7 @@ static struct radeon_state *r600_rasterizer(struct r600_context *rctx)
 	float offset_units = 0, offset_scale = 0;
 	char depth = 0;
 	unsigned offset_db_fmt_cntl = 0;
+	unsigned tmp;
 
 	if (fb->zsbuf) {
 		offset_units = state->offset_units;
@@ -800,6 +801,18 @@ static struct radeon_state *r600_rasterizer(struct r600_context *rctx)
 	if (rstate == NULL)
 		return NULL;
 	rstate->states[R600_RASTERIZER__SPI_INTERP_CONTROL_0] = 0x00000001;
+	if (state->sprite_coord_enable) {
+		rstate->states[R600_RASTERIZER__SPI_INTERP_CONTROL_0] |=
+				S_0286D4_PNT_SPRITE_ENA(1) |
+				S_0286D4_PNT_SPRITE_OVRD_X(2) |
+				S_0286D4_PNT_SPRITE_OVRD_Y(3) |
+				S_0286D4_PNT_SPRITE_OVRD_Z(0) |
+				S_0286D4_PNT_SPRITE_OVRD_W(1);
+		if (state->sprite_coord_mode != PIPE_SPRITE_COORD_UPPER_LEFT) {
+			rstate->states[R600_RASTERIZER__SPI_INTERP_CONTROL_0] |=
+					S_0286D4_PNT_SPRITE_TOP_1(1);
+		}
+	}
 	rstate->states[R600_RASTERIZER__PA_CL_CLIP_CNTL] = 0x00000000;
 	rstate->states[R600_RASTERIZER__PA_SU_SC_MODE_CNTL] = 0x00080000 |
 			S_028814_CULL_FRONT((state->cull_face & PIPE_FACE_FRONT) ? 1 : 0) |
@@ -808,10 +821,14 @@ static struct radeon_state *r600_rasterizer(struct r600_context *rctx)
 			S_028814_POLY_OFFSET_FRONT_ENABLE(state->offset_tri) |
 			S_028814_POLY_OFFSET_BACK_ENABLE(state->offset_tri) |
 			S_028814_POLY_OFFSET_PARA_ENABLE(state->offset_tri);
-	rstate->states[R600_RASTERIZER__PA_CL_VS_OUT_CNTL] = 0x00000000;
+	rstate->states[R600_RASTERIZER__PA_CL_VS_OUT_CNTL] =
+			S_02881C_USE_VTX_POINT_SIZE(state->point_size_per_vertex) |
+			S_02881C_VS_OUT_MISC_VEC_ENA(state->point_size_per_vertex);
 	rstate->states[R600_RASTERIZER__PA_CL_NANINF_CNTL] = 0x00000000;
-	rstate->states[R600_RASTERIZER__PA_SU_POINT_SIZE] = 0x00080008;
-	rstate->states[R600_RASTERIZER__PA_SU_POINT_MINMAX] = 0x00000000;
+	/* point size 12.4 fixed point */
+	tmp = (unsigned)(state->point_size * 8.0 / 2.0);
+	rstate->states[R600_RASTERIZER__PA_SU_POINT_SIZE] = S_028A00_HEIGHT(tmp) | S_028A00_WIDTH(tmp);
+	rstate->states[R600_RASTERIZER__PA_SU_POINT_MINMAX] = 0x80000000;
 	rstate->states[R600_RASTERIZER__PA_SU_LINE_CNTL] = 0x00000008;
 	rstate->states[R600_RASTERIZER__PA_SC_LINE_STIPPLE] = 0x00000005;
 	rstate->states[R600_RASTERIZER__PA_SC_MPASS_PS_CNTL] = 0x00000000;
diff --git a/src/gallium/drivers/r600/r600d.h b/src/gallium/drivers/r600/r600d.h
index af93731..53388f8 100644
--- a/src/gallium/drivers/r600/r600d.h
+++ b/src/gallium/drivers/r600/r600d.h
@@ -654,6 +654,13 @@
 #define   S_028E0C_OFFSET(x)                           (((x) & 0xFFFFFFFF) << 0)
 #define   G_028E0C_OFFSET(x)                           (((x) >> 0) & 0xFFFFFFFF)
 #define   C_028E0C_OFFSET                              0x00000000
+#define R_028A00_PA_SU_POINT_SIZE                    0x028A00
+#define   S_028A00_HEIGHT(x)                           (((x) & 0xFFFF) << 0)
+#define   G_028A00_HEIGHT(x)                           (((x) >> 0) & 0xFFFF)
+#define   C_028A00_HEIGHT                              0xFFFF0000
+#define   S_028A00_WIDTH(x)                            (((x) & 0xFFFF) << 16)
+#define   G_028A00_WIDTH(x)                            (((x) >> 16) & 0xFFFF)
+#define   C_028A00_WIDTH                               0x0000FFFF
 #define R_028A40_VGT_GS_MODE                         0x028A40
 #define   S_028A40_MODE(x)                             (((x) & 0x3) << 0)
 #define   G_028A40_MODE(x)                             (((x) >> 0) & 0x3)
@@ -1153,6 +1160,79 @@
 #define     V_008958_DI_PT_2D_FILL_RECT_LIST           0x0000001A
 #define     V_008958_DI_PT_2D_LINE_STRIP               0x0000001B
 #define     V_008958_DI_PT_2D_TRI_STRIP                0x0000001C
+#define R_02881C_PA_CL_VS_OUT_CNTL                   0x02881C
+#define   S_02881C_CLIP_DIST_ENA_0(x)                  (((x) & 0x1) << 0)
+#define   G_02881C_CLIP_DIST_ENA_0(x)                  (((x) >> 0) & 0x1)
+#define   C_02881C_CLIP_DIST_ENA_0                     0xFFFFFFFE
+#define   S_02881C_CLIP_DIST_ENA_1(x)                  (((x) & 0x1) << 1)
+#define   G_02881C_CLIP_DIST_ENA_1(x)                  (((x) >> 1) & 0x1)
+#define   C_02881C_CLIP_DIST_ENA_1                     0xFFFFFFFD
+#define   S_02881C_CLIP_DIST_ENA_2(x)                  (((x) & 0x1) << 2)
+#define   G_02881C_CLIP_DIST_ENA_2(x)                  (((x) >> 2) & 0x1)
+#define   C_02881C_CLIP_DIST_ENA_2                     0xFFFFFFFB
+#define   S_02881C_CLIP_DIST_ENA_3(x)                  (((x) & 0x1) << 3)
+#define   G_02881C_CLIP_DIST_ENA_3(x)                  (((x) >> 3) & 0x1)
+#define   C_02881C_CLIP_DIST_ENA_3                     0xFFFFFFF7
+#define   S_02881C_CLIP_DIST_ENA_4(x)                  (((x) & 0x1) << 4)
+#define   G_02881C_CLIP_DIST_ENA_4(x)                  (((x) >> 4) & 0x1)
+#define   C_02881C_CLIP_DIST_ENA_4                     0xFFFFFFEF
+#define   S_02881C_CLIP_DIST_ENA_5(x)                  (((x) & 0x1) << 5)
+#define   G_02881C_CLIP_DIST_ENA_5(x)                  (((x) >> 5) & 0x1)
+#define   C_02881C_CLIP_DIST_ENA_5                     0xFFFFFFDF
+#define   S_02881C_CLIP_DIST_ENA_6(x)                  (((x) & 0x1) << 6)
+#define   G_02881C_CLIP_DIST_ENA_6(x)                  (((x) >> 6) & 0x1)
+#define   C_02881C_CLIP_DIST_ENA_6                     0xFFFFFFBF
+#define   S_02881C_CLIP_DIST_ENA_7(x)                  (((x) & 0x1) << 7)
+#define   G_02881C_CLIP_DIST_ENA_7(x)                  (((x) >> 7) & 0x1)
+#define   C_02881C_CLIP_DIST_ENA_7                     0xFFFFFF7F
+#define   S_02881C_CULL_DIST_ENA_0(x)                  (((x) & 0x1) << 8)
+#define   G_02881C_CULL_DIST_ENA_0(x)                  (((x) >> 8) & 0x1)
+#define   C_02881C_CULL_DIST_ENA_0                     0xFFFFFEFF
+#define   S_02881C_CULL_DIST_ENA_1(x)                  (((x) & 0x1) << 9)
+#define   G_02881C_CULL_DIST_ENA_1(x)                  (((x) >> 9) & 0x1)
+#define   C_02881C_CULL_DIST_ENA_1                     0xFFFFFDFF
+#define   S_02881C_CULL_DIST_ENA_2(x)                  (((x) & 0x1) << 10)
+#define   G_02881C_CULL_DIST_ENA_2(x)                  (((x) >> 10) & 0x1)
+#define   C_02881C_CULL_DIST_ENA_2                     0xFFFFFBFF
+#define   S_02881C_CULL_DIST_ENA_3(x)                  (((x) & 0x1) << 11)
+#define   G_02881C_CULL_DIST_ENA_3(x)                  (((x) >> 11) & 0x1)
+#define   C_02881C_CULL_DIST_ENA_3                     0xFFFFF7FF
+#define   S_02881C_CULL_DIST_ENA_4(x)                  (((x) & 0x1) << 12)
+#define   G_02881C_CULL_DIST_ENA_4(x)                  (((x) >> 12) & 0x1)
+#define   C_02881C_CULL_DIST_ENA_4                     0xFFFFEFFF
+#define   S_02881C_CULL_DIST_ENA_5(x)                  (((x) & 0x1) << 13)
+#define   G_02881C_CULL_DIST_ENA_5(x)                  (((x) >> 13) & 0x1)
+#define   C_02881C_CULL_DIST_ENA_5                     0xFFFFDFFF
+#define   S_02881C_CULL_DIST_ENA_6(x)                  (((x) & 0x1) << 14)
+#define   G_02881C_CULL_DIST_ENA_6(x)                  (((x) >> 14) & 0x1)
+#define   C_02881C_CULL_DIST_ENA_6                     0xFFFFBFFF
+#define   S_02881C_CULL_DIST_ENA_7(x)                  (((x) & 0x1) << 15)
+#define   G_02881C_CULL_DIST_ENA_7(x)                  (((x) >> 15) & 0x1)
+#define   C_02881C_CULL_DIST_ENA_7                     0xFFFF7FFF
+#define   S_02881C_USE_VTX_POINT_SIZE(x)               (((x) & 0x1) << 16)
+#define   G_02881C_USE_VTX_POINT_SIZE(x)               (((x) >> 16) & 0x1)
+#define   C_02881C_USE_VTX_POINT_SIZE                  0xFFFEFFFF
+#define   S_02881C_USE_VTX_EDGE_FLAG(x)                (((x) & 0x1) << 17)
+#define   G_02881C_USE_VTX_EDGE_FLAG(x)                (((x) >> 17) & 0x1)
+#define   C_02881C_USE_VTX_EDGE_FLAG                   0xFFFDFFFF
+#define   S_02881C_USE_VTX_RENDER_TARGET_INDX(x)       (((x) & 0x1) << 18)
+#define   G_02881C_USE_VTX_RENDER_TARGET_INDX(x)       (((x) >> 18) & 0x1)
+#define   C_02881C_USE_VTX_RENDER_TARGET_INDX          0xFFFBFFFF
+#define   S_02881C_USE_VTX_VIEWPORT_INDX(x)            (((x) & 0x1) << 19)
+#define   G_02881C_USE_VTX_VIEWPORT_INDX(x)            (((x) >> 19) & 0x1)
+#define   C_02881C_USE_VTX_VIEWPORT_INDX               0xFFF7FFFF
+#define   S_02881C_USE_VTX_KILL_FLAG(x)                (((x) & 0x1) << 20)
+#define   G_02881C_USE_VTX_KILL_FLAG(x)                (((x) >> 20) & 0x1)
+#define   C_02881C_USE_VTX_KILL_FLAG                   0xFFEFFFFF
+#define   S_02881C_VS_OUT_MISC_VEC_ENA(x)              (((x) & 0x1) << 21)
+#define   G_02881C_VS_OUT_MISC_VEC_ENA(x)              (((x) >> 21) & 0x1)
+#define   C_02881C_VS_OUT_MISC_VEC_ENA                 0xFFDFFFFF
+#define   S_02881C_VS_OUT_CCDIST0_VEC_ENA(x)           (((x) & 0x1) << 22)
+#define   G_02881C_VS_OUT_CCDIST0_VEC_ENA(x)           (((x) >> 22) & 0x1)
+#define   C_02881C_VS_OUT_CCDIST0_VEC_ENA              0xFFBFFFFF
+#define   S_02881C_VS_OUT_CCDIST1_VEC_ENA(x)           (((x) & 0x1) << 23)
+#define   G_02881C_VS_OUT_CCDIST1_VEC_ENA(x)           (((x) >> 23) & 0x1)
+#define   C_02881C_VS_OUT_CCDIST1_VEC_ENA              0xFF7FFFFF
 #define R_028868_SQ_PGM_RESOURCES_VS                 0x028868
 #define   S_028868_NUM_GPRS(x)                         (((x) & 0xFF) << 0)
 #define   G_028868_NUM_GPRS(x)                         (((x) >> 0) & 0xFF)




More information about the mesa-commit mailing list