From: Jason Ekstrand Date: Fri, 25 Mar 2016 22:15:45 +0000 (-0700) Subject: spirv/glsl: Add a helper for converting glsl opcodes into nir opcodes X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=00fa795cd3bfd89b925698367173167656d4ae6c;p=mesa.git spirv/glsl: Add a helper for converting glsl opcodes into nir opcodes This is similar to the way that regular ALU operations are handled. --- diff --git a/src/compiler/nir/spirv/vtn_glsl450.c b/src/compiler/nir/spirv/vtn_glsl450.c index 3360fda067a..e05d28ffede 100644 --- a/src/compiler/nir/spirv/vtn_glsl450.c +++ b/src/compiler/nir/spirv/vtn_glsl450.c @@ -359,6 +359,57 @@ build_frexp(nir_builder *b, nir_ssa_def *x, nir_ssa_def **exponent) nir_bcsel(b, is_not_zero, exponent_value, zero)); } +static nir_op +vtn_nir_alu_op_for_spirv_glsl_opcode(enum GLSLstd450 opcode) +{ + switch (opcode) { + case GLSLstd450Round: return nir_op_fround_even; + case GLSLstd450RoundEven: return nir_op_fround_even; + case GLSLstd450Trunc: return nir_op_ftrunc; + case GLSLstd450FAbs: return nir_op_fabs; + case GLSLstd450SAbs: return nir_op_iabs; + case GLSLstd450FSign: return nir_op_fsign; + case GLSLstd450SSign: return nir_op_isign; + case GLSLstd450Floor: return nir_op_ffloor; + case GLSLstd450Ceil: return nir_op_fceil; + case GLSLstd450Fract: return nir_op_ffract; + case GLSLstd450Sin: return nir_op_fsin; + case GLSLstd450Cos: return nir_op_fcos; + case GLSLstd450Pow: return nir_op_fpow; + case GLSLstd450Exp2: return nir_op_fexp2; + case GLSLstd450Log2: return nir_op_flog2; + case GLSLstd450Sqrt: return nir_op_fsqrt; + case GLSLstd450InverseSqrt: return nir_op_frsq; + case GLSLstd450FMin: return nir_op_fmin; + case GLSLstd450UMin: return nir_op_umin; + case GLSLstd450SMin: return nir_op_imin; + case GLSLstd450FMax: return nir_op_fmax; + case GLSLstd450UMax: return nir_op_umax; + case GLSLstd450SMax: return nir_op_imax; + case GLSLstd450FMix: return nir_op_flrp; + case GLSLstd450Fma: return nir_op_ffma; + case GLSLstd450Ldexp: return nir_op_ldexp; + case GLSLstd450FindILsb: return nir_op_find_lsb; + case GLSLstd450FindSMsb: return nir_op_ifind_msb; + case GLSLstd450FindUMsb: return nir_op_ufind_msb; + + /* Packing/Unpacking functions */ + case GLSLstd450PackSnorm4x8: return nir_op_pack_snorm_4x8; + case GLSLstd450PackUnorm4x8: return nir_op_pack_unorm_4x8; + case GLSLstd450PackSnorm2x16: return nir_op_pack_snorm_2x16; + case GLSLstd450PackUnorm2x16: return nir_op_pack_unorm_2x16; + case GLSLstd450PackHalf2x16: return nir_op_pack_half_2x16; + case GLSLstd450UnpackSnorm4x8: return nir_op_unpack_snorm_4x8; + case GLSLstd450UnpackUnorm4x8: return nir_op_unpack_unorm_4x8; + case GLSLstd450UnpackSnorm2x16: return nir_op_unpack_snorm_2x16; + case GLSLstd450UnpackUnorm2x16: return nir_op_unpack_unorm_2x16; + case GLSLstd450UnpackHalf2x16: return nir_op_unpack_half_2x16; + + default: + unreachable("No NIR equivalent"); + } +} + static void handle_glsl450_alu(struct vtn_builder *b, enum GLSLstd450 entrypoint, const uint32_t *w, unsigned count) @@ -372,39 +423,21 @@ handle_glsl450_alu(struct vtn_builder *b, enum GLSLstd450 entrypoint, /* Collect the various SSA sources */ unsigned num_inputs = count - 5; - nir_ssa_def *src[3]; + nir_ssa_def *src[3] = { NULL, }; for (unsigned i = 0; i < num_inputs; i++) src[i] = vtn_ssa_value(b, w[i + 5])->def; - nir_op op; switch (entrypoint) { - case GLSLstd450Round: op = nir_op_fround_even; break; /* TODO */ - case GLSLstd450RoundEven: op = nir_op_fround_even; break; - case GLSLstd450Trunc: op = nir_op_ftrunc; break; - case GLSLstd450FAbs: op = nir_op_fabs; break; - case GLSLstd450SAbs: op = nir_op_iabs; break; - case GLSLstd450FSign: op = nir_op_fsign; break; - case GLSLstd450SSign: op = nir_op_isign; break; - case GLSLstd450Floor: op = nir_op_ffloor; break; - case GLSLstd450Ceil: op = nir_op_fceil; break; - case GLSLstd450Fract: op = nir_op_ffract; break; case GLSLstd450Radians: val->ssa->def = nir_fmul(nb, src[0], nir_imm_float(nb, 0.01745329251)); return; case GLSLstd450Degrees: val->ssa->def = nir_fmul(nb, src[0], nir_imm_float(nb, 57.2957795131)); return; - case GLSLstd450Sin: op = nir_op_fsin; break; - case GLSLstd450Cos: op = nir_op_fcos; break; case GLSLstd450Tan: val->ssa->def = nir_fdiv(nb, nir_fsin(nb, src[0]), nir_fcos(nb, src[0])); return; - case GLSLstd450Pow: op = nir_op_fpow; break; - case GLSLstd450Exp2: op = nir_op_fexp2; break; - case GLSLstd450Log2: op = nir_op_flog2; break; - case GLSLstd450Sqrt: op = nir_op_fsqrt; break; - case GLSLstd450InverseSqrt: op = nir_op_frsq; break; case GLSLstd450Modf: { nir_ssa_def *sign = nir_fsign(nb, src[0]); @@ -424,32 +457,10 @@ handle_glsl450_alu(struct vtn_builder *b, enum GLSLstd450 entrypoint, return; } - case GLSLstd450FMin: op = nir_op_fmin; break; - case GLSLstd450UMin: op = nir_op_umin; break; - case GLSLstd450SMin: op = nir_op_imin; break; - case GLSLstd450FMax: op = nir_op_fmax; break; - case GLSLstd450UMax: op = nir_op_umax; break; - case GLSLstd450SMax: op = nir_op_imax; break; - case GLSLstd450FMix: op = nir_op_flrp; break; case GLSLstd450Step: val->ssa->def = nir_sge(nb, src[1], src[0]); return; - case GLSLstd450Fma: op = nir_op_ffma; break; - case GLSLstd450Ldexp: op = nir_op_ldexp; break; - - /* Packing/Unpacking functions */ - case GLSLstd450PackSnorm4x8: op = nir_op_pack_snorm_4x8; break; - case GLSLstd450PackUnorm4x8: op = nir_op_pack_unorm_4x8; break; - case GLSLstd450PackSnorm2x16: op = nir_op_pack_snorm_2x16; break; - case GLSLstd450PackUnorm2x16: op = nir_op_pack_unorm_2x16; break; - case GLSLstd450PackHalf2x16: op = nir_op_pack_half_2x16; break; - case GLSLstd450UnpackSnorm4x8: op = nir_op_unpack_snorm_4x8; break; - case GLSLstd450UnpackUnorm4x8: op = nir_op_unpack_unorm_4x8; break; - case GLSLstd450UnpackSnorm2x16: op = nir_op_unpack_snorm_2x16; break; - case GLSLstd450UnpackUnorm2x16: op = nir_op_unpack_unorm_2x16; break; - case GLSLstd450UnpackHalf2x16: op = nir_op_unpack_half_2x16; break; - case GLSLstd450Length: val->ssa->def = build_length(nb, src[0]); return; @@ -584,10 +595,6 @@ handle_glsl450_alu(struct vtn_builder *b, enum GLSLstd450 entrypoint, return; } - case GLSLstd450FindILsb: op = nir_op_find_lsb; break; - case GLSLstd450FindSMsb: op = nir_op_ifind_msb; break; - case GLSLstd450FindUMsb: op = nir_op_ufind_msb; break; - case GLSLstd450Asin: val->ssa->def = build_asin(nb, src[0], 0.086566724, -0.03102955); return; @@ -619,24 +626,12 @@ handle_glsl450_alu(struct vtn_builder *b, enum GLSLstd450 entrypoint, return; } - case GLSLstd450PackDouble2x32: - case GLSLstd450UnpackDouble2x32: default: - unreachable("Unhandled opcode"); + val->ssa->def = + nir_build_alu(&b->nb, vtn_nir_alu_op_for_spirv_glsl_opcode(entrypoint), + src[0], src[1], src[2], NULL); + return; } - - nir_alu_instr *instr = nir_alu_instr_create(b->shader, op); - nir_ssa_dest_init(&instr->instr, &instr->dest.dest, - glsl_get_vector_elements(val->ssa->type), - glsl_get_bit_size(glsl_get_base_type(val->ssa->type)), - val->name); - instr->dest.write_mask = (1 << instr->dest.dest.ssa.num_components) - 1; - val->ssa->def = &instr->dest.dest.ssa; - - for (unsigned i = 0; i < nir_op_infos[op].num_inputs; i++) - instr->src[i].src = nir_src_for_ssa(src[i]); - - nir_builder_instr_insert(nb, &instr->instr); } bool