op, args, ARRAY_SIZE(args));
}
+static SpvId
+emit_builtin_triop(struct ntv_context *ctx, enum GLSLstd450 op, SpvId type,
+ SpvId src0, SpvId src1, SpvId src2)
+{
+ SpvId args[] = { src0, src1, src2 };
+ return spirv_builder_emit_ext_inst(&ctx->builder, type, ctx->GLSL_std_450,
+ op, args, ARRAY_SIZE(args));
+}
+
static SpvId
get_fvec_constant(struct ntv_context *ctx, unsigned bit_size,
unsigned num_components, float value)
result = emit_builtin_unop(ctx, spirv_op, dest_type, src[0]); \
break;
+ BUILTIN_UNOP(nir_op_iabs, GLSLstd450SAbs)
BUILTIN_UNOP(nir_op_fabs, GLSLstd450FAbs)
BUILTIN_UNOP(nir_op_fsqrt, GLSLstd450Sqrt)
BUILTIN_UNOP(nir_op_frsq, GLSLstd450InverseSqrt)
BINOP(nir_op_imul, SpvOpIMul)
BINOP(nir_op_idiv, SpvOpSDiv)
BINOP(nir_op_udiv, SpvOpUDiv)
+ BINOP(nir_op_umod, SpvOpUMod)
BINOP(nir_op_fadd, SpvOpFAdd)
BINOP(nir_op_fsub, SpvOpFSub)
BINOP(nir_op_fmul, SpvOpFMul)
BINOP(nir_op_ige, SpvOpSGreaterThanEqual)
BINOP(nir_op_ieq, SpvOpIEqual)
BINOP(nir_op_ine, SpvOpINotEqual)
+ BINOP(nir_op_uge, SpvOpUGreaterThanEqual)
BINOP(nir_op_flt, SpvOpFOrdLessThan)
BINOP(nir_op_fge, SpvOpFOrdGreaterThanEqual)
BINOP(nir_op_feq, SpvOpFOrdEqual)
}
break;
+ case nir_op_flrp:
+ assert(nir_op_infos[alu->op].num_inputs == 3);
+ result = emit_builtin_triop(ctx, GLSLstd450FMix, dest_type,
+ src[0], src[1], src[2]);
+ break;
+
case nir_op_fcsel:
result = emit_binop(ctx, SpvOpFOrdGreaterThan,
get_bvec_type(ctx, num_components),
return bitcast_to_fvec(ctx, def, bit_size, num_components);
}
+static SpvId
+get_src_int(struct ntv_context *ctx, nir_src *src)
+{
+ SpvId def = get_src_uint(ctx, src);
+ unsigned num_components = nir_src_num_components(*src);
+ unsigned bit_size = nir_src_bit_size(*src);
+ return bitcast_to_ivec(ctx, def, bit_size, num_components);
+}
+
static void
emit_tex(struct ntv_context *ctx, nir_tex_instr *tex)
{
assert(tex->op == nir_texop_tex ||
tex->op == nir_texop_txb ||
- tex->op == nir_texop_txl);
+ tex->op == nir_texop_txl ||
+ tex->op == nir_texop_txd ||
+ tex->op == nir_texop_txf);
assert(nir_alu_type_get_base_type(tex->dest_type) == nir_type_float);
assert(tex->texture_index == tex->sampler_index);
- SpvId coord = 0, proj = 0, bias = 0, lod = 0, dref = 0;
- unsigned coord_components;
+ SpvId coord = 0, proj = 0, bias = 0, lod = 0, dref = 0, dx = 0, dy = 0;
+ unsigned coord_components = 0;
for (unsigned i = 0; i < tex->num_srcs; i++) {
switch (tex->src[i].src_type) {
case nir_tex_src_coord:
- coord = get_src_float(ctx, &tex->src[i].src);
+ if (tex->op == nir_texop_txf)
+ coord = get_src_int(ctx, &tex->src[i].src);
+ else
+ coord = get_src_float(ctx, &tex->src[i].src);
coord_components = nir_src_num_components(tex->src[i].src);
break;
case nir_tex_src_lod:
assert(nir_src_num_components(tex->src[i].src) == 1);
- lod = get_src_float(ctx, &tex->src[i].src);
+ if (tex->op == nir_texop_txf)
+ lod = get_src_int(ctx, &tex->src[i].src);
+ else
+ lod = get_src_float(ctx, &tex->src[i].src);
assert(lod != 0);
break;
assert(dref != 0);
break;
+ case nir_tex_src_ddx:
+ dx = get_src_float(ctx, &tex->src[i].src);
+ assert(dx != 0);
+ break;
+
+ case nir_tex_src_ddy:
+ dy = get_src_float(ctx, &tex->src[i].src);
+ assert(dy != 0);
+ break;
+
default:
fprintf(stderr, "texture source: %d\n", tex->src[i].src_type);
unreachable("unknown texture source");
if (dref)
actual_dest_type = float_type;
- SpvId result = spirv_builder_emit_image_sample(&ctx->builder,
- actual_dest_type, load,
- coord,
- proj != 0,
- lod, bias, dref);
+ SpvId result;
+ if (tex->op == nir_texop_txf) {
+ SpvId image = spirv_builder_emit_image(&ctx->builder, image_type, load);
+ result = spirv_builder_emit_image_fetch(&ctx->builder, dest_type,
+ image, coord, lod);
+ } else {
+ result = spirv_builder_emit_image_sample(&ctx->builder,
+ actual_dest_type, load,
+ coord,
+ proj != 0,
+ lod, bias, dref, dx, dy);
+ }
+
spirv_builder_emit_decoration(&ctx->builder, result,
SpvDecorationRelaxedPrecision);