r300/compiler: add support for saturate output modifier in r500 vertex shaders
authorMarek Olšák <maraeo@gmail.com>
Sat, 2 Feb 2013 03:59:27 +0000 (04:59 +0100)
committerMarek Olšák <maraeo@gmail.com>
Wed, 6 Feb 2013 13:45:16 +0000 (14:45 +0100)
The GLSL compiler can simplify clamp(v,0,1) to saturate. The state tracker
doesn't use it yet, but it will.

Reviewed-by: Tom Stellard <thomas.stellard@amd.com>
src/gallium/drivers/r300/compiler/r3xx_vertprog.c
src/gallium/drivers/r300/r300_reg.h

index 94733d7..9c481f0 100644 (file)
@@ -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");
                        }
index 8342ef5..46aeba0 100644 (file)
@@ -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)                         \