r600g: implement TGSI_OPCODE_BREAKC
authorChristoph Bumiller <christoph.bumiller@speed.at>
Fri, 16 May 2014 23:20:16 +0000 (01:20 +0200)
committerMarek Olšák <marek.olsak@amd.com>
Mon, 2 Jun 2014 10:49:03 +0000 (12:49 +0200)
Signed-off-by: Marek Olšák <marek.olsak@amd.com>
src/gallium/drivers/r600/r600_shader.c

index a397f0e75e77126be7ca4d42abb9a137fdd6e680..5823ba2e857cc1c8cbaf699d76acdcdedae50836 100644 (file)
@@ -6265,6 +6265,29 @@ static int tgsi_endloop(struct r600_shader_ctx *ctx)
        return 0;
 }
 
+static int tgsi_loop_breakc(struct r600_shader_ctx *ctx)
+{
+       int r;
+       unsigned int fscp;
+
+       for (fscp = ctx->bc->fc_sp; fscp > 0; fscp--)
+       {
+               if (FC_LOOP == ctx->bc->fc_stack[fscp].type)
+                       break;
+       }
+       if (fscp == 0) {
+               R600_ERR("BREAKC not inside loop/endloop pair\n");
+               return -EINVAL;
+       }
+
+       r = emit_logic_pred(ctx, ALU_OP2_PRED_SETE_INT, CF_OP_ALU_BREAK);
+       if (r)
+               return r;
+       fc_set_mid(ctx, fscp);
+
+       return 0;
+}
+
 static int tgsi_loop_brk_cont(struct r600_shader_ctx *ctx)
 {
        unsigned int fscp;
@@ -6496,7 +6519,7 @@ static struct r600_shader_tgsi_instruction r600_shader_tgsi_instruction[] = {
        {TGSI_OPCODE_CALLNZ,    0, ALU_OP0_NOP, tgsi_unsupported},
        /* gap */
        {114,                   0, ALU_OP0_NOP, tgsi_unsupported},
-       {TGSI_OPCODE_BREAKC,    0, ALU_OP0_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_BREAKC,    0, ALU_OP0_NOP, tgsi_loop_breakc},
        {TGSI_OPCODE_KILL_IF,   0, ALU_OP2_KILLGT, tgsi_kill},  /* conditional kill */
        {TGSI_OPCODE_END,       0, ALU_OP0_NOP, tgsi_end},  /* aka HALT */
        /* gap */