[Mesa-dev] [PATCH 1/2] r300/compiler: add support for saturate output modifier in r500 vertex shaders

Marek Olšák maraeo at gmail.com
Sun Feb 3 09:22:41 PST 2013


The GLSL compiler can simplify clamp(v,0,1) to saturate. The state tracker
doesn't use it yet, but it will.
---
 src/gallium/drivers/r300/compiler/r3xx_vertprog.c |   23 ++++++++++++++-------
 src/gallium/drivers/r300/r300_reg.h               |    6 ++++--
 2 files changed, 19 insertions(+), 10 deletions(-)

diff --git a/src/gallium/drivers/r300/compiler/r3xx_vertprog.c b/src/gallium/drivers/r300/compiler/r3xx_vertprog.c
index 94733d7..9c481f0 100644
--- a/src/gallium/drivers/r300/compiler/r3xx_vertprog.c
+++ b/src/gallium/drivers/r300/compiler/r3xx_vertprog.c
@@ -193,7 +193,8 @@ static void ei_vector1(struct r300_vertex_program_code *vp,
 				     0,
 				     t_dst_index(vp, &vpi->DstReg),
 				     t_dst_mask(vpi->DstReg.WriteMask),
-				     t_dst_class(vpi->DstReg.File));
+				     t_dst_class(vpi->DstReg.File),
+                                     vpi->SaturateMode == RC_SATURATE_ZERO_ONE);
 	inst[1] = t_src(vp, &vpi->SrcReg[0]);
 	inst[2] = __CONST(0, RC_SWIZZLE_ZERO);
 	inst[3] = __CONST(0, RC_SWIZZLE_ZERO);
@@ -209,7 +210,8 @@ static void ei_vector2(struct r300_vertex_program_code *vp,
 				     0,
 				     t_dst_index(vp, &vpi->DstReg),
 				     t_dst_mask(vpi->DstReg.WriteMask),
-				     t_dst_class(vpi->DstReg.File));
+				     t_dst_class(vpi->DstReg.File),
+                                     vpi->SaturateMode == RC_SATURATE_ZERO_ONE);
 	inst[1] = t_src(vp, &vpi->SrcReg[0]);
 	inst[2] = t_src(vp, &vpi->SrcReg[1]);
 	inst[3] = __CONST(1, RC_SWIZZLE_ZERO);
@@ -225,7 +227,8 @@ static void ei_math1(struct r300_vertex_program_code *vp,
 				     0,
 				     t_dst_index(vp, &vpi->DstReg),
 				     t_dst_mask(vpi->DstReg.WriteMask),
-				     t_dst_class(vpi->DstReg.File));
+				     t_dst_class(vpi->DstReg.File),
+                                     vpi->SaturateMode == RC_SATURATE_ZERO_ONE);
 	inst[1] = t_src_scalar(vp, &vpi->SrcReg[0]);
 	inst[2] = __CONST(0, RC_SWIZZLE_ZERO);
 	inst[3] = __CONST(0, RC_SWIZZLE_ZERO);
@@ -242,7 +245,8 @@ static void ei_lit(struct r300_vertex_program_code *vp,
 				     0,
 				     t_dst_index(vp, &vpi->DstReg),
 				     t_dst_mask(vpi->DstReg.WriteMask),
-				     t_dst_class(vpi->DstReg.File));
+				     t_dst_class(vpi->DstReg.File),
+                                     vpi->SaturateMode == RC_SATURATE_ZERO_ONE);
 	/* NOTE: Users swizzling might not work. */
 	inst[1] = PVS_SRC_OPERAND(t_src_index(vp, &vpi->SrcReg[0]), t_swizzle(GET_SWZ(vpi->SrcReg[0].Swizzle, 0)),	// X
 				  t_swizzle(GET_SWZ(vpi->SrcReg[0].Swizzle, 3)),	// W
@@ -309,14 +313,16 @@ static void ei_mad(struct r300_vertex_program_code *vp,
 				1,
 				t_dst_index(vp, &vpi->DstReg),
 				t_dst_mask(vpi->DstReg.WriteMask),
-				t_dst_class(vpi->DstReg.File));
+				t_dst_class(vpi->DstReg.File),
+                                vpi->SaturateMode == RC_SATURATE_ZERO_ONE);
 	} else {
 		inst[0] = PVS_OP_DST_OPERAND(VE_MULTIPLY_ADD,
 				0,
 				0,
 				t_dst_index(vp, &vpi->DstReg),
 				t_dst_mask(vpi->DstReg.WriteMask),
-				t_dst_class(vpi->DstReg.File));
+				t_dst_class(vpi->DstReg.File),
+                                vpi->SaturateMode == RC_SATURATE_ZERO_ONE);
 
 		/* Arguments with constant swizzles still count as a unique
 		 * temporary, so we should make sure these arguments share a
@@ -349,7 +355,8 @@ static void ei_pow(struct r300_vertex_program_code *vp,
 				     0,
 				     t_dst_index(vp, &vpi->DstReg),
 				     t_dst_mask(vpi->DstReg.WriteMask),
-				     t_dst_class(vpi->DstReg.File));
+				     t_dst_class(vpi->DstReg.File),
+                                     vpi->SaturateMode == RC_SATURATE_ZERO_ONE);
 	inst[1] = t_src_scalar(vp, &vpi->SrcReg[0]);
 	inst[2] = __CONST(0, RC_SWIZZLE_ZERO);
 	inst[3] = t_src_scalar(vp, &vpi->SrcReg[1]);
@@ -380,7 +387,7 @@ static void translate_vertex_program(struct radeon_compiler *c, void *user)
 
 		if (info->HasDstReg) {
 			/* Neither is Saturate. */
-			if (vpi->SaturateMode != RC_SATURATE_NONE) {
+			if (vpi->SaturateMode != RC_SATURATE_NONE && !c->is_r500) {
 				rc_error(&compiler->Base, "Vertex program does not support the Saturate "
 					 "modifier (yet).\n");
 			}
diff --git a/src/gallium/drivers/r300/r300_reg.h b/src/gallium/drivers/r300/r300_reg.h
index 8342ef5..46aeba0 100644
--- a/src/gallium/drivers/r300/r300_reg.h
+++ b/src/gallium/drivers/r300/r300_reg.h
@@ -2960,13 +2960,15 @@ enum {
 
 /*\}*/
 
-#define PVS_OP_DST_OPERAND(opcode, math_inst, macro_inst, reg_index, reg_writemask, reg_class)	\
+#define PVS_OP_DST_OPERAND(opcode, math_inst, macro_inst, reg_index, reg_writemask, reg_class, saturate)	\
 	 (((opcode & PVS_DST_OPCODE_MASK) << PVS_DST_OPCODE_SHIFT)	\
 	 | ((math_inst & PVS_DST_MATH_INST_MASK) << PVS_DST_MATH_INST_SHIFT)	\
 	 | ((macro_inst & PVS_DST_MACRO_INST_MASK) << PVS_DST_MACRO_INST_SHIFT)	\
 	 | ((reg_index & PVS_DST_OFFSET_MASK) << PVS_DST_OFFSET_SHIFT)	\
 	 | ((reg_writemask & 0xf) << PVS_DST_WE_X_SHIFT)	/* X Y Z W */	\
-	 | ((reg_class & PVS_DST_REG_TYPE_MASK) << PVS_DST_REG_TYPE_SHIFT))
+	 | ((reg_class & PVS_DST_REG_TYPE_MASK) << PVS_DST_REG_TYPE_SHIFT)) \
+         | ((math_inst) ? (((saturate) & PVS_DST_ME_SAT_MASK) << PVS_DST_ME_SAT_SHIFT) : \
+                          (((saturate) & PVS_DST_VE_SAT_MASK) << PVS_DST_VE_SAT_SHIFT))
 
 #define PVS_SRC_OPERAND(in_reg_index, comp_x, comp_y, comp_z, comp_w, reg_class, negate)	\
 	(((in_reg_index & PVS_SRC_OFFSET_MASK) << PVS_SRC_OFFSET_SHIFT)				\
-- 
1.7.10.4



More information about the mesa-dev mailing list