r600g: implement edge flags
authorMarek Olšák <marek.olsak@amd.com>
Mon, 3 Mar 2014 01:20:45 +0000 (02:20 +0100)
committerMarek Olšák <marek.olsak@amd.com>
Tue, 4 Mar 2014 11:26:16 +0000 (12:26 +0100)
Cc: mesa-stable@lists.freedesktop.org
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
src/gallium/drivers/r600/evergreen_state.c
src/gallium/drivers/r600/r600_shader.c
src/gallium/drivers/r600/r600_shader.h

index 3859c4ca3614af0d3d8bd4b8ce191e4026cd08cc..e48d693a13070130d451669e220a0e933557b855 100644 (file)
@@ -3283,6 +3283,7 @@ void evergreen_update_vs_state(struct pipe_context *ctx, struct r600_pipe_shader
                S_02881C_VS_OUT_CCDIST1_VEC_ENA((rshader->clip_dist_write & 0xF0) != 0) |
                S_02881C_VS_OUT_MISC_VEC_ENA(rshader->vs_out_misc_write) |
                S_02881C_USE_VTX_POINT_SIZE(rshader->vs_out_point_size) |
+               S_02881C_USE_VTX_EDGE_FLAG(rshader->vs_out_edgeflag) |
                S_02881C_USE_VTX_VIEWPORT_INDX(rshader->vs_out_viewport) |
                S_02881C_USE_VTX_RENDER_TARGET_INDX(rshader->vs_out_layer);
 }
index 38c68e48aafe54f0ddd4223f869a29132e1d0c56..fabadd80e62b0ae6802822d054fccb2a87a3218a 100644 (file)
@@ -286,6 +286,7 @@ struct r600_shader_ctx {
        int                                     colors_used;
        boolean                 clip_vertex_write;
        unsigned                cv_output;
+       unsigned                edgeflag_output;
        int                                     fragcoord_input;
        int                                     native_integers;
        int                                     next_ring_offset;
@@ -490,10 +491,11 @@ static int r600_spi_sid(struct r600_shader_io * io)
         * semantic indices, so we'll use 0 for them.
         */
        if (name == TGSI_SEMANTIC_POSITION ||
-               name == TGSI_SEMANTIC_PSIZE ||
-               name == TGSI_SEMANTIC_LAYER ||
-               name == TGSI_SEMANTIC_VIEWPORT_INDEX ||
-               name == TGSI_SEMANTIC_FACE)
+           name == TGSI_SEMANTIC_PSIZE ||
+           name == TGSI_SEMANTIC_EDGEFLAG ||
+           name == TGSI_SEMANTIC_LAYER ||
+           name == TGSI_SEMANTIC_VIEWPORT_INDEX ||
+           name == TGSI_SEMANTIC_FACE)
                index = 0;
        else {
                if (name == TGSI_SEMANTIC_GENERIC) {
@@ -624,6 +626,11 @@ static int tgsi_declaration(struct r600_shader_ctx *ctx)
                                ctx->shader->vs_out_misc_write = 1;
                                ctx->shader->vs_out_point_size = 1;
                                break;
+                       case TGSI_SEMANTIC_EDGEFLAG:
+                               ctx->shader->vs_out_misc_write = 1;
+                               ctx->shader->vs_out_edgeflag = 1;
+                               ctx->edgeflag_output = i;
+                               break;
                        case TGSI_SEMANTIC_VIEWPORT_INDEX:
                                ctx->shader->vs_out_misc_write = 1;
                                ctx->shader->vs_out_viewport = 1;
@@ -1162,6 +1169,35 @@ out_err:
        return r;
 }
 
+static void convert_edgeflag_to_int(struct r600_shader_ctx *ctx)
+{
+       struct r600_bytecode_alu alu;
+       unsigned reg;
+
+       if (!ctx->shader->vs_out_edgeflag)
+               return;
+
+       reg = ctx->shader->output[ctx->edgeflag_output].gpr;
+
+       /* clamp(x, 0, 1) */
+       memset(&alu, 0, sizeof(alu));
+       alu.op = ALU_OP1_MOV;
+       alu.src[0].sel = reg;
+       alu.dst.sel = reg;
+       alu.dst.write = 1;
+       alu.dst.clamp = 1;
+       alu.last = 1;
+       r600_bytecode_add_alu(ctx->bc, &alu);
+
+       memset(&alu, 0, sizeof(alu));
+       alu.op = ALU_OP1_FLT_TO_INT;
+       alu.src[0].sel = reg;
+       alu.dst.sel = reg;
+       alu.dst.write = 1;
+       alu.last = 1;
+       r600_bytecode_add_alu(ctx->bc, &alu);
+}
+
 static int generate_gs_copy_shader(struct r600_context *rctx,
                                   struct r600_pipe_shader *gs,
                                   struct pipe_stream_output_info *so)
@@ -1918,6 +1954,8 @@ static int r600_shader_from_tgsi(struct r600_context *rctx,
            so.num_outputs && !use_llvm)
                emit_streamout(&ctx, &so);
 
+       convert_edgeflag_to_int(&ctx);
+
        if (ring_outputs) {
                if (key.vs_as_es)
                        emit_gs_ring_writes(&ctx, FALSE);
@@ -1953,6 +1991,15 @@ static int r600_shader_from_tgsi(struct r600_context *rctx,
                                        output[j].type = V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_POS;
                                        pos_emitted = true;
                                        break;
+                               case TGSI_SEMANTIC_EDGEFLAG:
+                                       output[j].array_base = 61;
+                                       output[j].swizzle_x = 7;
+                                       output[j].swizzle_y = 0;
+                                       output[j].swizzle_z = 7;
+                                       output[j].swizzle_w = 7;
+                                       output[j].type = V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_POS;
+                                       pos_emitted = true;
+                                       break;
                                case TGSI_SEMANTIC_LAYER:
                                        output[j].array_base = 61;
                                        output[j].swizzle_x = 7;
index 519d0aaf0bf0c8cbee375b4946eb644a682a3f00..ab9f1f02736565ac64f80f560150c35c1c87ccca 100644 (file)
@@ -64,6 +64,7 @@ struct r600_shader {
        boolean                 vs_out_point_size;
        boolean                 vs_out_layer;
        boolean                 vs_out_viewport;
+       boolean                 vs_out_edgeflag;
        boolean                 has_txq_cube_array_z_comp;
        boolean                 uses_tex_buffers;
        boolean                 gs_prim_id_input;