vtn: Fix atan2 for non-scalars.
authorKenneth Graunke <kenneth@whitecape.org>
Wed, 27 Jan 2016 23:07:18 +0000 (15:07 -0800)
committerKenneth Graunke <kenneth@whitecape.org>
Wed, 27 Jan 2016 23:07:42 +0000 (15:07 -0800)
The if/then/else block was bogus, as it can only take a scalar
condition, and we need to select component-wise.  The GLSL IR
implementation of atan2 handles this by looping over components,
but I decided to try and do it vector-wise, and messed up.

For now, just bcsel.  It means that we do the atan1 math even if
all components hit the quick case, but it works, and presumably
at least one component will hit the expensive path anyway.

src/glsl/nir/spirv/vtn_glsl450.c

index b98ef052cbf8db49623ae4cccec7efadc8bd6883..8d730168c085e62be42d0c8d451a4849a63fa862 100644 (file)
@@ -295,14 +295,11 @@ build_atan2(nir_builder *b, nir_ssa_def *y, nir_ssa_def *x)
    nir_ssa_def *zero = nir_imm_float(b, 0.0f);
 
    /* If |x| >= 1.0e-8 * |y|: */
-   nir_if *if_stmt = nir_if_create(b->shader);
-   if_stmt->condition = nir_src_for_ssa(
+   nir_ssa_def *condition =
       nir_fge(b, nir_fabs(b, x),
-              nir_fmul(b, nir_imm_float(b, 1.0e-8f), nir_fabs(b, y))));
-   nir_builder_cf_insert(b, &if_stmt->cf_node);
+              nir_fmul(b, nir_imm_float(b, 1.0e-8f), nir_fabs(b, y)));
 
    /* Then...call atan(y/x) and fix it up: */
-   b->cursor = nir_after_cf_list(&if_stmt->then_list);
    nir_ssa_def *atan1 = build_atan(b, nir_fdiv(b, y, x));
    nir_ssa_def *r_then =
       nir_bcsel(b, nir_flt(b, x, zero),
@@ -313,28 +310,10 @@ build_atan2(nir_builder *b, nir_ssa_def *y, nir_ssa_def *x)
                    atan1);
 
    /* Else... */
-   b->cursor = nir_after_cf_list(&if_stmt->else_list);
    nir_ssa_def *r_else =
       nir_fmul(b, nir_fsign(b, y), nir_imm_float(b, M_PI_2f));
 
-   b->cursor = nir_after_cf_node(&if_stmt->cf_node);
-
-   nir_phi_instr *phi = nir_phi_instr_create(b->shader);
-   nir_ssa_dest_init(&phi->instr, &phi->dest, r_then->num_components, NULL);
-
-   nir_phi_src *phi_src0 = ralloc(phi, nir_phi_src);
-   nir_phi_src *phi_src1 = ralloc(phi, nir_phi_src);
-
-   phi_src0->pred = nir_cf_node_as_block((nir_cf_node *) exec_list_get_head(&if_stmt->then_list));
-   phi_src0->src = nir_src_for_ssa(r_then);
-   exec_list_push_tail(&phi->srcs, &phi_src0->node);
-   phi_src1->pred = nir_cf_node_as_block((nir_cf_node *) exec_list_get_head(&if_stmt->else_list));
-   phi_src1->src = nir_src_for_ssa(r_else);
-   exec_list_push_tail(&phi->srcs, &phi_src1->node);
-
-   nir_builder_instr_insert(b, &phi->instr);
-
-   return &phi->dest.ssa;
+   return nir_bcsel(b, condition, r_then, r_else);
 }
 
 static nir_ssa_def *