[Mesa-dev] [PATCH] r600g: gpu_shader5 gl_SampleMaskIn support

Glenn Kennard glenn.kennard at gmail.com
Wed Jul 23 02:57:55 PDT 2014


Map TGSI_SEMANTIC_SAMPLEMASK to register/component.
Enable face register when sample mask is needed by shader.
Requires Evergreen/Cayman
---
I think the rest of the sample related bits in gpu_shader5 are
from GL_ARB_sample_shading which isn't implemented yet in r600.

Passes samplemaskin-basic piglit, no regressions, on radeon 6670

 docs/GL3.txt                               |  2 +-
 src/gallium/drivers/r600/evergreen_state.c | 10 ++++++--
 src/gallium/drivers/r600/r600_shader.c     | 37 ++++++++++++++++++++++++++----
 3 files changed, 41 insertions(+), 8 deletions(-)

diff --git a/docs/GL3.txt b/docs/GL3.txt
index 8128692..53e19e0 100644
--- a/docs/GL3.txt
+++ b/docs/GL3.txt
@@ -109,7 +109,7 @@ GL 4.0:
   - Enhanced textureGather                             DONE (i965, nvc0, radeonsi)
   - Geometry shader instancing                         DONE (i965, nvc0)
   - Geometry shader multiple streams                   DONE (i965, nvc0)
-  - Enhanced per-sample shading                        DONE (i965)
+  - Enhanced per-sample shading                        DONE (i965, r600)
   - Interpolation functions                            DONE (i965)
   - New overload resolution rules                      DONE
   GL_ARB_gpu_shader_fp64                               started (Dave)
diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c
index 8f5ba5f..839d2ae 100644
--- a/src/gallium/drivers/r600/evergreen_state.c
+++ b/src/gallium/drivers/r600/evergreen_state.c
@@ -2843,8 +2843,14 @@ void evergreen_update_ps_state(struct pipe_context *ctx, struct r600_pipe_shader
 		   POSITION goes via GPRs from the SC so isn't counted */
 		if (rshader->input[i].name == TGSI_SEMANTIC_POSITION)
 			pos_index = i;
-		else if (rshader->input[i].name == TGSI_SEMANTIC_FACE)
-			face_index = i;
+		else if (rshader->input[i].name == TGSI_SEMANTIC_FACE) {
+			if (face_index == -1)
+				face_index = i;
+		}
+		else if (rshader->input[i].name == TGSI_SEMANTIC_SAMPLEMASK) {
+			if (face_index == -1)
+				face_index = i; /* lives in same register, same enable bit */
+		}
 		else {
 			ninterp++;
 			if (rshader->input[i].interpolate == TGSI_INTERPOLATE_LINEAR)
diff --git a/src/gallium/drivers/r600/r600_shader.c b/src/gallium/drivers/r600/r600_shader.c
index db928f3..c8ab4dd 100644
--- a/src/gallium/drivers/r600/r600_shader.c
+++ b/src/gallium/drivers/r600/r600_shader.c
@@ -287,7 +287,9 @@ struct r600_shader_ctx {
 	boolean                                 input_linear;
 	boolean                                 input_perspective;
 	int					num_interp_gpr;
+	/* evergreen/cayman also store sample mask in face register */
 	int					face_gpr;
+	boolean					has_samplemask;
 	int					colors_used;
 	boolean                 clip_vertex_write;
 	unsigned                cv_output;
@@ -498,7 +500,8 @@ static int r600_spi_sid(struct r600_shader_io * io)
 	if (name == TGSI_SEMANTIC_POSITION ||
 	    name == TGSI_SEMANTIC_PSIZE ||
 	    name == TGSI_SEMANTIC_EDGEFLAG ||
-	    name == TGSI_SEMANTIC_FACE)
+	    name == TGSI_SEMANTIC_FACE ||
+	    name == TGSI_SEMANTIC_SAMPLEMASK)
 		index = 0;
 	else {
 		if (name == TGSI_SEMANTIC_GENERIC) {
@@ -585,7 +588,8 @@ static int tgsi_declaration(struct r600_shader_ctx *ctx)
 			ctx->shader->input[i].spi_sid = r600_spi_sid(&ctx->shader->input[i]);
 			switch (ctx->shader->input[i].name) {
 			case TGSI_SEMANTIC_FACE:
-				ctx->face_gpr = ctx->shader->input[i].gpr;
+				if (ctx->face_gpr == -1)
+					ctx->face_gpr = ctx->shader->input[i].gpr;
 				break;
 			case TGSI_SEMANTIC_COLOR:
 				ctx->colors_used++;
@@ -675,7 +679,14 @@ static int tgsi_declaration(struct r600_shader_ctx *ctx)
 		break;
 
 	case TGSI_FILE_SYSTEM_VALUE:
-		if (d->Semantic.Name == TGSI_SEMANTIC_INSTANCEID) {
+		if (d->Semantic.Name == TGSI_SEMANTIC_SAMPLEMASK) {
+			ctx->has_samplemask = true;
+			/* lives in Front Face GPR */
+			if (ctx->face_gpr == -1)
+				ctx->face_gpr = ctx->file_offset[TGSI_FILE_SYSTEM_VALUE] + d->Range.First;
+			break;
+		}
+		else if (d->Semantic.Name == TGSI_SEMANTIC_INSTANCEID) {
 			if (!ctx->native_integers) {
 				struct r600_bytecode_alu alu;
 				memset(&alu, 0, sizeof(struct r600_bytecode_alu));
@@ -729,7 +740,8 @@ static int evergreen_gpr_count(struct r600_shader_ctx *ctx)
 	for (i = 0; i < ctx->info.num_inputs; i++) {
 		/* skip position/face */
 		if (ctx->info.input_semantic_name[i] == TGSI_SEMANTIC_POSITION ||
-		    ctx->info.input_semantic_name[i] == TGSI_SEMANTIC_FACE)
+		    ctx->info.input_semantic_name[i] == TGSI_SEMANTIC_FACE ||
+		    ctx->info.input_semantic_name[i] == TGSI_SEMANTIC_SAMPLEMASK)
 			continue;
 		if (ctx->info.input_interpolate[i] == TGSI_INTERPOLATE_LINEAR)
 			ctx->input_linear = TRUE;
@@ -781,7 +793,13 @@ static void tgsi_src(struct r600_shader_ctx *ctx,
 		r600_src->sel = V_SQ_ALU_SRC_LITERAL;
 		memcpy(r600_src->value, ctx->literals + index * 4, sizeof(r600_src->value));
 	} else if (tgsi_src->Register.File == TGSI_FILE_SYSTEM_VALUE) {
-		if (ctx->info.system_value_semantic_name[tgsi_src->Register.Index] == TGSI_SEMANTIC_INSTANCEID) {
+		if (ctx->info.system_value_semantic_name[tgsi_src->Register.Index] == TGSI_SEMANTIC_SAMPLEMASK) {
+			r600_src->swizzle[0] = 2; // Z value
+			r600_src->swizzle[0] = 2;
+			r600_src->swizzle[0] = 2;
+			r600_src->swizzle[0] = 2;
+			r600_src->sel = ctx->face_gpr;
+		} else if (ctx->info.system_value_semantic_name[tgsi_src->Register.Index] == TGSI_SEMANTIC_INSTANCEID) {
 			r600_src->swizzle[0] = 3;
 			r600_src->swizzle[1] = 3;
 			r600_src->swizzle[2] = 3;
@@ -1586,6 +1604,7 @@ static int r600_shader_from_tgsi(struct r600_context *rctx,
 	ctx.gs_next_vertex = 0;
 
 	ctx.face_gpr = -1;
+	ctx.has_samplemask = false;
 	ctx.fragcoord_input = -1;
 	ctx.colors_used = 0;
 	ctx.clip_vertex_write = 0;
@@ -1745,6 +1764,14 @@ static int r600_shader_from_tgsi(struct r600_context *rctx,
 	
 	shader->ring_item_size = ctx.next_ring_offset;
 
+	/* Need to tell setup to program FACE register */
+	if (ctx.has_samplemask && ctx.face_gpr != -1) {
+		i = ctx.shader->ninput++;
+		ctx.shader->input[i].name = TGSI_SEMANTIC_SAMPLEMASK;
+		ctx.shader->input[i].spi_sid = 0;
+		ctx.shader->input[i].gpr = ctx.face_gpr;
+	}
+
 	/* Process two side if needed */
 	if (shader->two_side && ctx.colors_used) {
 		int i, count = ctx.shader->ninput;
-- 
1.8.3.2



More information about the mesa-dev mailing list