From: Kenneth Graunke Date: Tue, 19 Jan 2016 23:56:50 +0000 (-0800) Subject: nir/spirv/glsl450: Blindly implement Atan2. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=68c9ca1a94de785660c61789c2d9e5b26569ee45;p=mesa.git nir/spirv/glsl450: Blindly implement Atan2. This is untested and probably broken. We already passed the atan2 CTS tests before implementing this opcode. Presumably, glslang or something was giving us a plain Atan opcode instead of Atan2. I don't know why. --- diff --git a/src/glsl/nir/spirv/vtn_glsl450.c b/src/glsl/nir/spirv/vtn_glsl450.c index 1c5f115f128..c9a7195c47f 100644 --- a/src/glsl/nir/spirv/vtn_glsl450.c +++ b/src/glsl/nir/spirv/vtn_glsl450.c @@ -289,6 +289,54 @@ build_atan(nir_builder *b, nir_ssa_def *y_over_x) return nir_fmul(b, tmp, nir_fsign(b, y_over_x)); } +static nir_ssa_def * +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_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); + + /* 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), + nir_fadd(b, atan1, + nir_bcsel(b, nir_fge(b, y, zero), + nir_imm_float(b, M_PIf), + nir_imm_float(b, -M_PIf))), + 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; +} + static void handle_glsl450_alu(struct vtn_builder *b, enum GLSLstd450 entrypoint, const uint32_t *w, unsigned count) @@ -518,6 +566,9 @@ handle_glsl450_alu(struct vtn_builder *b, enum GLSLstd450 entrypoint, return; case GLSLstd450Atan2: + val->ssa->def = build_atan2(nb, src[0], src[1]); + return; + case GLSLstd450ModfStruct: case GLSLstd450Frexp: case GLSLstd450FrexpStruct: