return SpvDim1D;
case GLSL_SAMPLER_DIM_2D:
return SpvDim2D;
- case GLSL_SAMPLER_DIM_RECT:
- return SpvDimRect;
- case GLSL_SAMPLER_DIM_CUBE:
- return SpvDimCube;
case GLSL_SAMPLER_DIM_3D:
return SpvDim3D;
+ case GLSL_SAMPLER_DIM_CUBE:
+ return SpvDimCube;
+ case GLSL_SAMPLER_DIM_RECT:
+ return SpvDimRect;
+ case GLSL_SAMPLER_DIM_BUF:
+ return SpvDimBuffer;
+ case GLSL_SAMPLER_DIM_EXTERNAL:
+ return SpvDim2D; /* seems dodgy... */
case GLSL_SAMPLER_DIM_MS:
*is_ms = true;
return SpvDim2D;
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),
result = emit_select(ctx, dest_type, src[0], src[1], src[2]);
break;
+ case nir_op_bany_fnequal2:
+ case nir_op_bany_fnequal3:
+ case nir_op_bany_fnequal4:
+ assert(nir_op_infos[alu->op].num_inputs == 2);
+ assert(alu_instr_src_components(alu, 0) ==
+ alu_instr_src_components(alu, 1));
+ result = emit_binop(ctx, SpvOpFOrdNotEqual,
+ get_bvec_type(ctx, alu_instr_src_components(alu, 0)),
+ src[0], src[1]);
+ result = emit_unop(ctx, SpvOpAny, dest_type, result);
+ break;
+
+ case nir_op_ball_fequal2:
+ case nir_op_ball_fequal3:
+ case nir_op_ball_fequal4:
+ assert(nir_op_infos[alu->op].num_inputs == 2);
+ assert(alu_instr_src_components(alu, 0) ==
+ alu_instr_src_components(alu, 1));
+ result = emit_binop(ctx, SpvOpFOrdEqual,
+ get_bvec_type(ctx, alu_instr_src_components(alu, 0)),
+ src[0], src[1]);
+ result = emit_unop(ctx, SpvOpAll, dest_type, result);
+ break;
+
+ case nir_op_bany_inequal2:
+ case nir_op_bany_inequal3:
+ case nir_op_bany_inequal4:
+ assert(nir_op_infos[alu->op].num_inputs == 2);
+ assert(alu_instr_src_components(alu, 0) ==
+ alu_instr_src_components(alu, 1));
+ result = emit_binop(ctx, SpvOpINotEqual,
+ get_bvec_type(ctx, alu_instr_src_components(alu, 0)),
+ src[0], src[1]);
+ result = emit_unop(ctx, SpvOpAny, dest_type, result);
+ break;
+
+ case nir_op_ball_iequal2:
+ case nir_op_ball_iequal3:
+ case nir_op_ball_iequal4:
+ assert(nir_op_infos[alu->op].num_inputs == 2);
+ assert(alu_instr_src_components(alu, 0) ==
+ alu_instr_src_components(alu, 1));
+ result = emit_binop(ctx, SpvOpIEqual,
+ get_bvec_type(ctx, alu_instr_src_components(alu, 0)),
+ src[0], src[1]);
+ result = emit_unop(ctx, SpvOpAll, dest_type, result);
+ break;
+
case nir_op_vec2:
case nir_op_vec3:
case nir_op_vec4: {
static void
emit_load_const(struct ntv_context *ctx, nir_load_const_instr *load_const)
{
- uint32_t values[NIR_MAX_VEC_COMPONENTS];
- for (int i = 0; i < load_const->def.num_components; ++i)
- values[i] = load_const->value[i].u32;
-
unsigned bit_size = load_const->def.bit_size;
unsigned num_components = load_const->def.num_components;
SpvId constant;
if (num_components > 1) {
SpvId components[num_components];
- for (int i = 0; i < num_components; i++)
- components[i] = emit_uint_const(ctx, bit_size, values[i]);
+ SpvId type;
+ if (bit_size == 1) {
+ for (int i = 0; i < num_components; i++)
+ components[i] = spirv_builder_const_bool(&ctx->builder,
+ load_const->value[i].b);
- SpvId type = get_uvec_type(ctx, bit_size, num_components);
+ type = get_bvec_type(ctx, num_components);
+ } else {
+ for (int i = 0; i < num_components; i++)
+ components[i] = emit_uint_const(ctx, bit_size,
+ load_const->value[i].u32);
+
+ type = get_uvec_type(ctx, bit_size, num_components);
+ }
constant = spirv_builder_const_composite(&ctx->builder, type,
components, num_components);
} else {
assert(num_components == 1);
- constant = emit_uint_const(ctx, bit_size, values[0]);
+ if (bit_size == 1)
+ constant = spirv_builder_const_bool(&ctx->builder,
+ load_const->value[0].b);
+ else
+ constant = emit_uint_const(ctx, bit_size, load_const->value[0].u32);
}
+ if (bit_size == 1)
+ constant = bvec_to_uvec(ctx, constant, num_components);
+
store_ssa_def_uint(ctx, &load_const->def, constant);
}
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);