ir_function_signature *
builtin_builder::_bitfieldInsert(const glsl_type *type)
{
+ bool is_uint = type->base_type == GLSL_TYPE_UINT;
ir_variable *base = in_var(type, "base");
ir_variable *insert = in_var(type, "insert");
ir_variable *offset = in_var(glsl_type::int_type, "offset");
ir_variable *bits = in_var(glsl_type::int_type, "bits");
MAKE_SIG(type, gpu_shader5_or_es31, 4, base, insert, offset, bits);
- body.emit(ret(bitfield_insert(base, insert, offset, bits)));
+ operand cast_offset = is_uint ? i2u(offset) : operand(offset);
+ operand cast_bits = is_uint ? i2u(bits) : operand(bits);
+
+ body.emit(ret(bitfield_insert(base, insert,
+ swizzle(cast_offset, SWIZZLE_XXXX, type->vector_elements),
+ swizzle(cast_bits, SWIZZLE_XXXX, type->vector_elements))));
return sig;
}
operation == ir_triop_vector_insert ||
operation == ir_quadop_vector ||
/* TODO: these can't currently be vectorized */
- operation == ir_quadop_bitfield_insert ||
operation == ir_triop_bitfield_extract;
}
}
case ir_quadop_bitfield_insert: {
- int offset = op[2]->value.i[0];
- int bits = op[3]->value.i[0];
-
for (unsigned c = 0; c < components; c++) {
+ int offset = op[2]->value.i[c];
+ int bits = op[3]->value.i[c];
+
if (bits == 0)
data.u[c] = op[0]->value.u[c];
else if (offset < 0 || bits < 0)
break;
case ir_quadop_bitfield_insert:
+ assert(ir->type->is_integer());
assert(ir->operands[0]->type == ir->type);
assert(ir->operands[1]->type == ir->type);
- assert(ir->operands[2]->type == glsl_type::int_type);
- assert(ir->operands[3]->type == glsl_type::int_type);
+ assert(ir->operands[2]->type == ir->type);
+ assert(ir->operands[3]->type == ir->type);
break;
case ir_quadop_vector:
ir_constant *sign_mask = new(ir) ir_constant(0x80000000u, vec_elem);
- ir_constant *exp_shift = new(ir) ir_constant(23);
- ir_constant *exp_width = new(ir) ir_constant(8);
+ ir_constant *exp_shift = new(ir) ir_constant(23, vec_elem);
+ ir_constant *exp_width = new(ir) ir_constant(8, vec_elem);
/* Temporary variables */
ir_variable *x = new(ir) ir_variable(ir->type, "x", ir_var_temporary);
ir_constant *sign_mask = new(ir) ir_constant(0x80000000u);
- ir_constant *exp_shift = new(ir) ir_constant(20);
- ir_constant *exp_width = new(ir) ir_constant(11);
+ ir_constant *exp_shift = new(ir) ir_constant(20, vec_elem);
+ ir_constant *exp_width = new(ir) ir_constant(11, vec_elem);
ir_constant *exp_bias = new(ir) ir_constant(1022, vec_elem);
/* Temporary variables */
if (op_mask & LOWER_PACK_USE_BFI) {
return bitfield_insert(bit_and(swizzle_x(u), constant(0xffffu)),
swizzle_y(u),
- constant(16),
- constant(16));
+ constant(16u),
+ constant(16u));
}
/* return (u.y << 16) | (u.x & 0xffff); */
return bitfield_insert(bitfield_insert(
bitfield_insert(
bit_and(swizzle_x(u), constant(0xffu)),
- swizzle_y(u), constant(8), constant(8)),
- swizzle_z(u), constant(16), constant(8)),
- swizzle_w(u), constant(24), constant(8));
+ swizzle_y(u), constant(8u), constant(8u)),
+ swizzle_z(u), constant(16u), constant(8u)),
+ swizzle_w(u), constant(24u), constant(8u));
}
/* uvec4 u = UVEC4_RVAL & 0xff */
[tuint, tuint, tuint, tuint],
"", const_expr)
-opcode("bitfield_insert", 0, tuint, [0, 0, 1, 1],
+opcode("bitfield_insert", 0, tuint, [0, 0, 0, 0],
[tuint, tuint, tint, tint], "", """
unsigned base = src0, insert = src1;
-int offset = src2.x, bits = src3.x;
+int offset = src2, bits = src3;
if (bits == 0) {
dst = 0;
} else if (offset < 0 || bits < 0 || bits + offset > 32) {