nir_setup_system_values();
/* get the main function and emit it */
- nir_foreach_function(nir, function) {
+ nir_foreach_function(function, nir) {
assert(strcmp(function->name, "main") == 0);
assert(function->impl);
nir_emit_impl(function->impl);
case nir_intrinsic_load_vertex_id_zero_base:
reg = &nir_system_values[SYSTEM_VALUE_VERTEX_ID_ZERO_BASE];
if (reg->file == BAD_FILE)
- *reg = *make_reg_for_system_value(SYSTEM_VALUE_VERTEX_ID_ZERO_BASE,
- glsl_type::int_type);
+ *reg = *make_reg_for_system_value(SYSTEM_VALUE_VERTEX_ID_ZERO_BASE);
break;
case nir_intrinsic_load_base_vertex:
reg = &nir_system_values[SYSTEM_VALUE_BASE_VERTEX];
if (reg->file == BAD_FILE)
- *reg = *make_reg_for_system_value(SYSTEM_VALUE_BASE_VERTEX,
- glsl_type::int_type);
+ *reg = *make_reg_for_system_value(SYSTEM_VALUE_BASE_VERTEX);
break;
case nir_intrinsic_load_instance_id:
reg = &nir_system_values[SYSTEM_VALUE_INSTANCE_ID];
if (reg->file == BAD_FILE)
- *reg = *make_reg_for_system_value(SYSTEM_VALUE_INSTANCE_ID,
- glsl_type::int_type);
+ *reg = *make_reg_for_system_value(SYSTEM_VALUE_INSTANCE_ID);
break;
case nir_intrinsic_load_base_instance:
reg = &nir_system_values[SYSTEM_VALUE_BASE_INSTANCE];
if (reg->file == BAD_FILE)
- *reg = *make_reg_for_system_value(SYSTEM_VALUE_BASE_INSTANCE,
- glsl_type::int_type);
+ *reg = *make_reg_for_system_value(SYSTEM_VALUE_BASE_INSTANCE);
break;
case nir_intrinsic_load_draw_id:
reg = &nir_system_values[SYSTEM_VALUE_DRAW_ID];
if (reg->file == BAD_FILE)
- *reg = *make_reg_for_system_value(SYSTEM_VALUE_DRAW_ID,
- glsl_type::int_type);
+ *reg = *make_reg_for_system_value(SYSTEM_VALUE_DRAW_ID);
break;
default:
}
static bool
-setup_system_values_block(nir_block *block, void *void_visitor)
+setup_system_values_block(nir_block *block, vec4_visitor *v)
{
- vec4_visitor *v = (vec4_visitor *)void_visitor;
-
- nir_foreach_instr(block, instr) {
+ nir_foreach_instr(instr, block) {
if (instr->type != nir_instr_type_intrinsic)
continue;
nir_system_values[i] = dst_reg();
}
- nir_foreach_function(nir, function) {
+ nir_foreach_function(function, nir) {
assert(strcmp(function->name, "main") == 0);
assert(function->impl);
- nir_foreach_block(function->impl, setup_system_values_block, this);
+ nir_foreach_block(block, function->impl) {
+ setup_system_values_block(block, this);
+ }
}
}
foreach_list_typed(nir_register, reg, node, &impl->registers) {
unsigned array_elems =
reg->num_array_elems == 0 ? 1 : reg->num_array_elems;
+ const unsigned num_regs = array_elems * DIV_ROUND_UP(reg->bit_size, 32);
+ nir_locals[reg->index] = dst_reg(VGRF, alloc.allocate(num_regs));
- nir_locals[reg->index] = dst_reg(VGRF, alloc.allocate(array_elems));
+ if (reg->bit_size == 64)
+ nir_locals[reg->index].type = BRW_REGISTER_TYPE_DF;
}
nir_ssa_values = ralloc_array(mem_ctx, dst_reg, impl->ssa_alloc);
void
vec4_visitor::nir_emit_block(nir_block *block)
{
- nir_foreach_instr(block, instr) {
+ nir_foreach_instr(instr, block) {
nir_emit_instr(instr);
}
}
dst_reg reg;
reg = v->nir_locals[nir_reg->index];
- reg = offset(reg, base_offset);
+ if (nir_reg->bit_size == 64)
+ reg.type = BRW_REGISTER_TYPE_DF;
+ reg = offset(reg, 8, base_offset);
if (indirect) {
reg.reladdr =
new(v->mem_ctx) src_reg(v->get_nir_src(*indirect,
}
dst_reg
-vec4_visitor::get_nir_dest(nir_dest dest)
+vec4_visitor::get_nir_dest(const nir_dest &dest)
{
if (dest.is_ssa) {
- dst_reg dst = dst_reg(VGRF, alloc.allocate(1));
+ dst_reg dst =
+ dst_reg(VGRF, alloc.allocate(DIV_ROUND_UP(dest.ssa.bit_size, 32)));
+ if (dest.ssa.bit_size == 64)
+ dst.type = BRW_REGISTER_TYPE_DF;
nir_ssa_values[dest.ssa.index] = dst;
return dst;
} else {
}
dst_reg
-vec4_visitor::get_nir_dest(nir_dest dest, enum brw_reg_type type)
+vec4_visitor::get_nir_dest(const nir_dest &dest, enum brw_reg_type type)
{
return retype(get_nir_dest(dest), type);
}
dst_reg
-vec4_visitor::get_nir_dest(nir_dest dest, nir_alu_type type)
+vec4_visitor::get_nir_dest(const nir_dest &dest, nir_alu_type type)
{
return get_nir_dest(dest, brw_type_for_nir_type(type));
}
src_reg
-vec4_visitor::get_nir_src(nir_src src, enum brw_reg_type type,
+vec4_visitor::get_nir_src(const nir_src &src, enum brw_reg_type type,
unsigned num_components)
{
dst_reg reg;
reg = nir_ssa_values[src.ssa->index];
}
else {
- reg = dst_reg_for_nir_reg(this, src.reg.reg, src.reg.base_offset,
- src.reg.indirect);
+ reg = dst_reg_for_nir_reg(this, src.reg.reg, src.reg.base_offset,
+ src.reg.indirect);
}
reg = retype(reg, type);
}
src_reg
-vec4_visitor::get_nir_src(nir_src src, nir_alu_type type,
+vec4_visitor::get_nir_src(const nir_src &src, nir_alu_type type,
unsigned num_components)
{
return get_nir_src(src, brw_type_for_nir_type(type), num_components);
}
src_reg
-vec4_visitor::get_nir_src(nir_src src, unsigned num_components)
+vec4_visitor::get_nir_src(const nir_src &src, unsigned num_components)
{
/* if type is not specified, default to signed int */
- return get_nir_src(src, nir_type_int, num_components);
+ return get_nir_src(src, nir_type_int32, num_components);
}
src_reg
* add_const_offset_to_base() will fold other constant offsets
* into instr->const_index[0].
*/
- assert(const_value->u[0] == 0);
+ assert(const_value->u32[0] == 0);
return src_reg();
}
void
vec4_visitor::nir_emit_load_const(nir_load_const_instr *instr)
{
- dst_reg reg = dst_reg(VGRF, alloc.allocate(1));
- reg.type = BRW_REGISTER_TYPE_D;
+ dst_reg reg;
+
+ if (instr->def.bit_size == 64) {
+ reg = dst_reg(VGRF, alloc.allocate(2));
+ reg.type = BRW_REGISTER_TYPE_DF;
+ } else {
+ reg = dst_reg(VGRF, alloc.allocate(1));
+ reg.type = BRW_REGISTER_TYPE_D;
+ }
unsigned remaining = brw_writemask_for_size(instr->def.num_components);
continue;
for (unsigned j = i; j < instr->def.num_components; j++) {
- if (instr->value.u[i] == instr->value.u[j]) {
+ if ((instr->def.bit_size == 32 &&
+ instr->value.u32[i] == instr->value.u32[j]) ||
+ (instr->def.bit_size == 64 &&
+ instr->value.f64[i] == instr->value.f64[j])) {
writemask |= 1 << j;
}
}
reg.writemask = writemask;
- emit(MOV(reg, brw_imm_d(instr->value.i[i])));
+ if (instr->def.bit_size == 64) {
+ emit(MOV(reg, brw_imm_df(instr->value.f64[i])));
+ } else {
+ emit(MOV(reg, brw_imm_d(instr->value.i32[i])));
+ }
remaining &= ~writemask;
}
/* We set EmitNoIndirectInput for VS */
assert(const_offset);
- src = src_reg(ATTR, instr->const_index[0] + const_offset->u[0],
+ src = src_reg(ATTR, instr->const_index[0] + const_offset->u32[0],
glsl_type::uvec4_type);
+ /* Swizzle source based on component layout qualifier */
+ src.swizzle = BRW_SWZ_COMP_INPUT(nir_intrinsic_component(instr));
dest = get_nir_dest(instr->dest, src.type);
dest.writemask = brw_writemask_for_size(instr->num_components);
nir_const_value *const_offset = nir_src_as_const_value(instr->src[1]);
assert(const_offset);
- int varying = instr->const_index[0] + const_offset->u[0];
+ int varying = instr->const_index[0] + const_offset->u32[0];
src = get_nir_src(instr->src[0], BRW_REGISTER_TYPE_F,
instr->num_components);
- output_reg[varying] = dst_reg(src);
+ unsigned c = nir_intrinsic_component(instr);
+ output_reg[varying][c] = dst_reg(src);
+ output_num_components[varying][c] = instr->num_components;
break;
}
case nir_intrinsic_get_buffer_size: {
nir_const_value *const_uniform_block = nir_src_as_const_value(instr->src[0]);
- unsigned ssbo_index = const_uniform_block ? const_uniform_block->u[0] : 0;
+ unsigned ssbo_index = const_uniform_block ? const_uniform_block->u32[0] : 0;
const unsigned index =
prog_data->base.binding_table.ssbo_start + ssbo_index;
nir_src_as_const_value(instr->src[1]);
if (const_uniform_block) {
unsigned index = prog_data->base.binding_table.ssbo_start +
- const_uniform_block->u[0];
+ const_uniform_block->u32[0];
surf_index = brw_imm_ud(index);
brw_mark_surface_used(&prog_data->base, index);
} else {
brw_mark_surface_used(&prog_data->base,
prog_data->base.binding_table.ssbo_start +
- nir->info.num_ssbos - 1);
+ nir->info->num_ssbos - 1);
}
/* Offset */
src_reg offset_reg;
nir_const_value *const_offset = nir_src_as_const_value(instr->src[2]);
if (const_offset) {
- offset_reg = brw_imm_ud(const_offset->u[0]);
+ offset_reg = brw_imm_ud(const_offset->u32[0]);
} else {
offset_reg = get_nir_src(instr->src[2], 1);
}
src_reg surf_index;
if (const_uniform_block) {
unsigned index = prog_data->base.binding_table.ssbo_start +
- const_uniform_block->u[0];
+ const_uniform_block->u32[0];
surf_index = brw_imm_ud(index);
brw_mark_surface_used(&prog_data->base, index);
*/
brw_mark_surface_used(&prog_data->base,
prog_data->base.binding_table.ssbo_start +
- nir->info.num_ssbos - 1);
+ nir->info->num_ssbos - 1);
}
src_reg offset_reg;
nir_const_value *const_offset = nir_src_as_const_value(instr->src[1]);
if (const_offset) {
- offset_reg = brw_imm_ud(const_offset->u[0]);
+ offset_reg = brw_imm_ud(const_offset->u32[0]);
} else {
offset_reg = get_nir_src(instr->src[1], 1);
}
case nir_intrinsic_load_instance_id:
case nir_intrinsic_load_base_instance:
case nir_intrinsic_load_draw_id:
- case nir_intrinsic_load_invocation_id:
- case nir_intrinsic_load_tess_level_inner:
- case nir_intrinsic_load_tess_level_outer: {
+ case nir_intrinsic_load_invocation_id: {
gl_system_value sv = nir_system_value_from_intrinsic(instr->intrinsic);
src_reg val = src_reg(nir_system_values[sv]);
assert(val.file != BAD_FILE);
}
case nir_intrinsic_load_uniform: {
- /* Offsets are in bytes but they should always be multiples of 16 */
- assert(instr->const_index[0] % 16 == 0);
+ /* Offsets are in bytes but they should always be multiples of 4 */
+ assert(nir_intrinsic_base(instr) % 4 == 0);
dest = get_nir_dest(instr->dest);
- src = src_reg(dst_reg(UNIFORM, instr->const_index[0] / 16));
+ src = src_reg(dst_reg(UNIFORM, nir_intrinsic_base(instr) / 16));
src.type = dest.type;
+ /* Uniforms don't actually have to be vec4 aligned. In the case that
+ * it isn't, we have to use a swizzle to shift things around. They
+ * do still have the std140 alignment requirement that vec2's have to
+ * be vec2-aligned and vec3's and vec4's have to be vec4-aligned.
+ *
+ * The swizzle also works in the indirect case as the generator adds
+ * the swizzle to the offset for us.
+ */
+ unsigned shift = (nir_intrinsic_base(instr) % 16) / 4;
+ assert(shift + instr->num_components <= 4);
+
nir_const_value *const_offset = nir_src_as_const_value(instr->src[0]);
if (const_offset) {
- /* Offsets are in bytes but they should always be multiples of 16 */
- assert(const_offset->u[0] % 16 == 0);
- src.reg_offset = const_offset->u[0] / 16;
+ /* Offsets are in bytes but they should always be multiples of 4 */
+ assert(const_offset->u32[0] % 4 == 0);
+
+ unsigned offset = const_offset->u32[0] + shift * 4;
+ src.offset = ROUND_DOWN_TO(offset, 16);
+ shift = (offset % 16) / 4;
+ src.swizzle += BRW_SWIZZLE4(shift, shift, shift, shift);
emit(MOV(dest, src));
} else {
+ src.swizzle += BRW_SWIZZLE4(shift, shift, shift, shift);
+
src_reg indirect = get_nir_src(instr->src[0], BRW_REGISTER_TYPE_UD, 1);
+ /* MOV_INDIRECT is going to stomp the whole thing anyway */
+ dest.writemask = WRITEMASK_XYZW;
+
emit(SHADER_OPCODE_MOV_INDIRECT, dest, src,
indirect, brw_imm_ud(instr->const_index[1]));
}
case nir_intrinsic_atomic_counter_dec: {
unsigned surf_index = prog_data->base.binding_table.abo_start +
(unsigned) instr->const_index[0];
- src_reg offset = get_nir_src(instr->src[0], nir_type_int,
+ const vec4_builder bld =
+ vec4_builder(this).at_end().annotate(current_annotation, base_ir);
+
+ /* Get some metadata from the image intrinsic. */
+ const nir_intrinsic_info *info = &nir_intrinsic_infos[instr->intrinsic];
+
+ /* Get the arguments of the atomic intrinsic. */
+ src_reg offset = get_nir_src(instr->src[0], nir_type_int32,
instr->num_components);
+ const src_reg surface = brw_imm_ud(surf_index);
+ const src_reg src0 = (info->num_srcs >= 2
+ ? get_nir_src(instr->src[1]) : src_reg());
+ const src_reg src1 = (info->num_srcs >= 3
+ ? get_nir_src(instr->src[2]) : src_reg());
+
+ src_reg tmp;
+
dest = get_nir_dest(instr->dest);
- switch (instr->intrinsic) {
- case nir_intrinsic_atomic_counter_inc:
- emit_untyped_atomic(BRW_AOP_INC, surf_index, dest, offset,
- src_reg(), src_reg());
- break;
- case nir_intrinsic_atomic_counter_dec:
- emit_untyped_atomic(BRW_AOP_PREDEC, surf_index, dest, offset,
- src_reg(), src_reg());
- break;
- case nir_intrinsic_atomic_counter_read:
- emit_untyped_surface_read(surf_index, dest, offset);
- break;
- default:
- unreachable("Unreachable");
+ if (instr->intrinsic == nir_intrinsic_atomic_counter_read) {
+ tmp = emit_untyped_read(bld, surface, offset, 1, 1);
+ } else {
+ tmp = emit_untyped_atomic(bld, surface, offset,
+ src0, src1,
+ 1, 1,
+ get_atomic_counter_op(instr->intrinsic));
}
+ bld.MOV(retype(dest, tmp.type), tmp);
brw_mark_surface_used(stage_prog_data, surf_index);
break;
}
* as an immediate.
*/
const unsigned index = prog_data->base.binding_table.ubo_start +
- const_block_index->u[0];
+ const_block_index->u32[0];
surf_index = brw_imm_ud(index);
brw_mark_surface_used(&prog_data->base, index);
} else {
* from any live channel.
*/
surf_index = src_reg(this, glsl_type::uint_type);
- emit(ADD(dst_reg(surf_index), get_nir_src(instr->src[0], nir_type_int,
+ emit(ADD(dst_reg(surf_index), get_nir_src(instr->src[0], nir_type_int32,
instr->num_components),
brw_imm_ud(prog_data->base.binding_table.ubo_start)));
surf_index = emit_uniformize(surf_index);
*/
brw_mark_surface_used(&prog_data->base,
prog_data->base.binding_table.ubo_start +
- nir->info.num_ubos - 1);
+ nir->info->num_ubos - 1);
}
src_reg offset;
nir_const_value *const_offset = nir_src_as_const_value(instr->src[1]);
if (const_offset) {
- offset = brw_imm_ud(const_offset->u[0] & ~15);
+ offset = brw_imm_ud(const_offset->u32[0] & ~15);
} else {
- offset = get_nir_src(instr->src[1], nir_type_int, 1);
+ offset = get_nir_src(instr->src[1], nir_type_uint32, 1);
}
src_reg packed_consts = src_reg(this, glsl_type::vec4_type);
packed_consts.swizzle = brw_swizzle_for_size(instr->num_components);
if (const_offset) {
- packed_consts.swizzle += BRW_SWIZZLE4(const_offset->u[0] % 16 / 4,
- const_offset->u[0] % 16 / 4,
- const_offset->u[0] % 16 / 4,
- const_offset->u[0] % 16 / 4);
+ packed_consts.swizzle += BRW_SWIZZLE4(const_offset->u32[0] % 16 / 4,
+ const_offset->u32[0] % 16 / 4,
+ const_offset->u32[0] % 16 / 4,
+ const_offset->u32[0] % 16 / 4);
}
emit(MOV(dest, packed_consts));
vec4_builder(this).at_end().annotate(current_annotation, base_ir);
const dst_reg tmp = bld.vgrf(BRW_REGISTER_TYPE_UD, 2);
bld.emit(SHADER_OPCODE_MEMORY_FENCE, tmp)
- ->regs_written = 2;
+ ->size_written = 2 * REG_SIZE;
break;
}
nir_const_value *const_surface = nir_src_as_const_value(instr->src[0]);
if (const_surface) {
unsigned surf_index = prog_data->base.binding_table.ssbo_start +
- const_surface->u[0];
+ const_surface->u32[0];
surface = brw_imm_ud(surf_index);
brw_mark_surface_used(&prog_data->base, surf_index);
} else {
*/
brw_mark_surface_used(&prog_data->base,
prog_data->base.binding_table.ssbo_start +
- nir->info.num_ssbos - 1);
+ nir->info->num_ssbos - 1);
}
src_reg offset = get_nir_src(instr->src[1], 1);
const vec4_builder bld =
vec4_builder(this).at_end().annotate(current_annotation, base_ir);
- src_reg atomic_result =
- surface_access::emit_untyped_atomic(bld, surface, offset,
- data1, data2,
- 1 /* dims */, 1 /* rsize */,
- op,
- BRW_PREDICATE_NONE);
+ src_reg atomic_result = emit_untyped_atomic(bld, surface, offset,
+ data1, data2,
+ 1 /* dims */, 1 /* rsize */,
+ op,
+ BRW_PREDICATE_NONE);
dest.type = atomic_result.type;
bld.MOV(dest, atomic_result);
}
src_reg op[2];
assert(nir_op_infos[cmp_instr->op].num_inputs == 2);
for (unsigned i = 0; i < 2; i++) {
- op[i] = get_nir_src(cmp_instr->src[i].src,
- nir_op_infos[cmp_instr->op].input_types[i], 4);
+ nir_alu_type type = nir_op_infos[cmp_instr->op].input_types[i];
+ unsigned bit_size = nir_src_bit_size(cmp_instr->src[i].src);
+ type = (nir_alu_type) (((unsigned) type) | bit_size);
+ op[i] = get_nir_src(cmp_instr->src[i].src, type, 4);
unsigned base_swizzle =
brw_swizzle_for_nir_swizzle(cmp_instr->src[i].swizzle);
op[i].swizzle = brw_compose_swizzle(size_swizzle, base_swizzle);
return true;
}
+static void
+emit_find_msb_using_lzd(const vec4_builder &bld,
+ const dst_reg &dst,
+ const src_reg &src,
+ bool is_signed)
+{
+ vec4_instruction *inst;
+ src_reg temp = src;
+
+ if (is_signed) {
+ /* LZD of an absolute value source almost always does the right
+ * thing. There are two problem values:
+ *
+ * * 0x80000000. Since abs(0x80000000) == 0x80000000, LZD returns
+ * 0. However, findMSB(int(0x80000000)) == 30.
+ *
+ * * 0xffffffff. Since abs(0xffffffff) == 1, LZD returns
+ * 31. Section 8.8 (Integer Functions) of the GLSL 4.50 spec says:
+ *
+ * For a value of zero or negative one, -1 will be returned.
+ *
+ * * Negative powers of two. LZD(abs(-(1<<x))) returns x, but
+ * findMSB(-(1<<x)) should return x-1.
+ *
+ * For all negative number cases, including 0x80000000 and
+ * 0xffffffff, the correct value is obtained from LZD if instead of
+ * negating the (already negative) value the logical-not is used. A
+ * conditonal logical-not can be achieved in two instructions.
+ */
+ temp = src_reg(bld.vgrf(BRW_REGISTER_TYPE_D));
+
+ bld.ASR(dst_reg(temp), src, brw_imm_d(31));
+ bld.XOR(dst_reg(temp), temp, src);
+ }
+
+ bld.LZD(retype(dst, BRW_REGISTER_TYPE_UD),
+ retype(temp, BRW_REGISTER_TYPE_UD));
+
+ /* LZD counts from the MSB side, while GLSL's findMSB() wants the count
+ * from the LSB side. Subtract the result from 31 to convert the MSB count
+ * into an LSB count. If no bits are set, LZD will return 32. 31-32 = -1,
+ * which is exactly what findMSB() is supposed to return.
+ */
+ inst = bld.ADD(dst, retype(src_reg(dst), BRW_REGISTER_TYPE_D),
+ brw_imm_d(31));
+ inst->src[0].negate = true;
+}
+
+void
+vec4_visitor::emit_conversion_from_double(dst_reg dst, src_reg src,
+ bool saturate,
+ brw_reg_type single_type)
+{
+ /* BDW PRM vol 15 - workarounds:
+ * DF->f format conversion for Align16 has wrong emask calculation when
+ * source is immediate.
+ */
+ if (devinfo->gen == 8 && single_type == BRW_REGISTER_TYPE_F &&
+ src.file == BRW_IMMEDIATE_VALUE) {
+ vec4_instruction *inst = emit(MOV(dst, brw_imm_f(src.df)));
+ inst->saturate = saturate;
+ return;
+ }
+
+ dst_reg temp = dst_reg(this, glsl_type::dvec4_type);
+ emit(MOV(temp, src));
+
+ dst_reg temp2 = dst_reg(this, glsl_type::dvec4_type);
+ temp2 = retype(temp2, single_type);
+ emit(VEC4_OPCODE_FROM_DOUBLE, temp2, src_reg(temp))
+ ->size_written = 2 * REG_SIZE;
+
+ vec4_instruction *inst = emit(MOV(dst, src_reg(temp2)));
+ inst->saturate = saturate;
+}
+
+void
+vec4_visitor::emit_conversion_to_double(dst_reg dst, src_reg src,
+ bool saturate,
+ brw_reg_type single_type)
+{
+ dst_reg tmp_dst = dst_reg(src_reg(this, glsl_type::dvec4_type));
+ src_reg tmp_src = retype(src_reg(this, glsl_type::vec4_type), single_type);
+ emit(MOV(dst_reg(tmp_src), retype(src, single_type)));
+ emit(VEC4_OPCODE_TO_DOUBLE, tmp_dst, tmp_src);
+ vec4_instruction *inst = emit(MOV(dst, src_reg(tmp_dst)));
+ inst->saturate = saturate;
+}
+
void
vec4_visitor::nir_emit_alu(nir_alu_instr *instr)
{
vec4_instruction *inst;
- dst_reg dst = get_nir_dest(instr->dest.dest,
- nir_op_infos[instr->op].output_type);
+ nir_alu_type dst_type = (nir_alu_type) (nir_op_infos[instr->op].output_type |
+ nir_dest_bit_size(instr->dest.dest));
+ dst_reg dst = get_nir_dest(instr->dest.dest, dst_type);
dst.writemask = instr->dest.write_mask;
src_reg op[4];
for (unsigned i = 0; i < nir_op_infos[instr->op].num_inputs; i++) {
- op[i] = get_nir_src(instr->src[i].src,
- nir_op_infos[instr->op].input_types[i], 4);
+ nir_alu_type src_type = (nir_alu_type)
+ (nir_op_infos[instr->op].input_types[i] |
+ nir_src_bit_size(instr->src[i].src));
+ op[i] = get_nir_src(instr->src[i].src, src_type, 4);
op[i].swizzle = brw_swizzle_for_nir_swizzle(instr->src[i].swizzle);
op[i].abs = instr->src[i].abs;
op[i].negate = instr->src[i].negate;
inst = emit(MOV(dst, op[0]));
break;
- case nir_op_fadd:
- /* fall through */
+ case nir_op_d2f:
+ emit_conversion_from_double(dst, op[0], instr->dest.saturate,
+ BRW_REGISTER_TYPE_F);
+ break;
+
+ case nir_op_f2d:
+ emit_conversion_to_double(dst, op[0], instr->dest.saturate,
+ BRW_REGISTER_TYPE_F);
+ break;
+
+ case nir_op_d2i:
+ case nir_op_d2u:
+ emit_conversion_from_double(dst, op[0], instr->dest.saturate,
+ instr->op == nir_op_d2i ? BRW_REGISTER_TYPE_D :
+ BRW_REGISTER_TYPE_UD);
+ break;
+
+ case nir_op_i2d:
+ case nir_op_u2d:
+ emit_conversion_to_double(dst, op[0], instr->dest.saturate,
+ instr->op == nir_op_i2d ? BRW_REGISTER_TYPE_D :
+ BRW_REGISTER_TYPE_UD);
+ break;
+
case nir_op_iadd:
+ assert(nir_dest_bit_size(instr->dest.dest) < 64);
+ case nir_op_fadd:
inst = emit(ADD(dst, op[0], op[1]));
inst->saturate = instr->dest.saturate;
break;
break;
case nir_op_imul: {
+ assert(nir_dest_bit_size(instr->dest.dest) < 64);
if (devinfo->gen < 8) {
nir_const_value *value0 = nir_src_as_const_value(instr->src[0].src);
nir_const_value *value1 = nir_src_as_const_value(instr->src[1].src);
* operand. If we can determine that one of the args is in the low
* 16 bits, though, we can just emit a single MUL.
*/
- if (value0 && value0->u[0] < (1 << 16)) {
+ if (value0 && value0->u32[0] < (1 << 16)) {
if (devinfo->gen < 7)
emit(MUL(dst, op[0], op[1]));
else
emit(MUL(dst, op[1], op[0]));
- } else if (value1 && value1->u[0] < (1 << 16)) {
+ } else if (value1 && value1->u32[0] < (1 << 16)) {
if (devinfo->gen < 7)
emit(MUL(dst, op[1], op[0]));
else
case nir_op_imul_high:
case nir_op_umul_high: {
+ assert(nir_dest_bit_size(instr->dest.dest) < 64);
struct brw_reg acc = retype(brw_acc_reg(8), dst.type);
- if (devinfo->gen >=8)
+ if (devinfo->gen >= 8)
emit(MUL(acc, op[0], retype(op[1], BRW_REGISTER_TYPE_UW)));
else
emit(MUL(acc, op[0], op[1]));
case nir_op_idiv:
case nir_op_udiv:
+ assert(nir_dest_bit_size(instr->dest.dest) < 64);
emit_math(SHADER_OPCODE_INT_QUOTIENT, dst, op[0], op[1]);
break;
* appears that our hardware just does the right thing for signed
* remainder.
*/
+ assert(nir_dest_bit_size(instr->dest.dest) < 64);
emit_math(SHADER_OPCODE_INT_REMAINDER, dst, op[0], op[1]);
break;
* When we XOR the sources, the top bit is 0 if they are the same and 1
* if they are different. We can then use a conditional modifier to
* turn that into a predicate. This leads us to an XOR.l instruction.
+ *
+ * Technically, according to the PRM, you're not allowed to use .l on a
+ * XOR instruction. However, emperical experiments and Curro's reading
+ * of the simulator source both indicate that it's safe.
*/
src_reg tmp = src_reg(this, glsl_type::ivec4_type);
inst = emit(XOR(dst_reg(tmp), op[0], op[1]));
break;
case nir_op_uadd_carry: {
+ assert(nir_dest_bit_size(instr->dest.dest) < 64);
struct brw_reg acc = retype(brw_acc_reg(8), BRW_REGISTER_TYPE_UD);
emit(ADDC(dst_null_ud(), op[0], op[1]));
}
case nir_op_usub_borrow: {
+ assert(nir_dest_bit_size(instr->dest.dest) < 64);
struct brw_reg acc = retype(brw_acc_reg(8), BRW_REGISTER_TYPE_UD);
emit(SUBB(dst_null_ud(), op[0], op[1]));
/* Select that or zero based on normal status */
inst = emit(BRW_OPCODE_SEL, dst, zero, tmp32);
inst->predicate = BRW_PREDICATE_NORMAL;
- inst->predicate_inverse = true;
inst->saturate = instr->dest.saturate;
break;
}
- case nir_op_fmin:
case nir_op_imin:
case nir_op_umin:
+ assert(nir_dest_bit_size(instr->dest.dest) < 64);
+ case nir_op_fmin:
inst = emit_minmax(BRW_CONDITIONAL_L, dst, op[0], op[1]);
inst->saturate = instr->dest.saturate;
break;
- case nir_op_fmax:
case nir_op_imax:
case nir_op_umax:
+ assert(nir_dest_bit_size(instr->dest.dest) < 64);
+ case nir_op_fmax:
inst = emit_minmax(BRW_CONDITIONAL_GE, dst, op[0], op[1]);
inst->saturate = instr->dest.saturate;
break;
case nir_op_fddy_fine:
unreachable("derivatives are not valid in vertex shaders");
- case nir_op_flt:
case nir_op_ilt:
case nir_op_ult:
- case nir_op_fge:
case nir_op_ige:
case nir_op_uge:
- case nir_op_feq:
case nir_op_ieq:
- case nir_op_fne:
case nir_op_ine:
- emit(CMP(dst, op[0], op[1],
- brw_conditional_for_nir_comparison(instr->op)));
+ assert(nir_dest_bit_size(instr->dest.dest) < 64);
+ /* Fallthrough */
+ case nir_op_flt:
+ case nir_op_fge:
+ case nir_op_feq:
+ case nir_op_fne: {
+ enum brw_conditional_mod conditional_mod =
+ brw_conditional_for_nir_comparison(instr->op);
+
+ if (nir_src_bit_size(instr->src[0].src) < 64) {
+ emit(CMP(dst, op[0], op[1], conditional_mod));
+ } else {
+ /* Produce a 32-bit boolean result from the DF comparison by selecting
+ * only the low 32-bit in each DF produced. Do this in a temporary
+ * so we can then move from there to the result using align16 again
+ * to honor the original writemask.
+ */
+ dst_reg temp = dst_reg(this, glsl_type::dvec4_type);
+ emit(CMP(temp, op[0], op[1], conditional_mod));
+ dst_reg result = dst_reg(this, glsl_type::bvec4_type);
+ emit(VEC4_OPCODE_PICK_LOW_32BIT, result, src_reg(temp));
+ emit(MOV(dst, src_reg(result)));
+ }
break;
+ }
- case nir_op_ball_fequal2:
case nir_op_ball_iequal2:
- case nir_op_ball_fequal3:
case nir_op_ball_iequal3:
- case nir_op_ball_fequal4:
- case nir_op_ball_iequal4: {
+ case nir_op_ball_iequal4:
+ assert(nir_dest_bit_size(instr->dest.dest) < 64);
+ /* Fallthrough */
+ case nir_op_ball_fequal2:
+ case nir_op_ball_fequal3:
+ case nir_op_ball_fequal4: {
unsigned swiz =
brw_swizzle_for_size(nir_op_infos[instr->op].input_sizes[0]);
break;
}
- case nir_op_bany_fnequal2:
case nir_op_bany_inequal2:
- case nir_op_bany_fnequal3:
case nir_op_bany_inequal3:
- case nir_op_bany_fnequal4:
- case nir_op_bany_inequal4: {
+ case nir_op_bany_inequal4:
+ assert(nir_dest_bit_size(instr->dest.dest) < 64);
+ /* Fallthrough */
+ case nir_op_bany_fnequal2:
+ case nir_op_bany_fnequal3:
+ case nir_op_bany_fnequal4: {
unsigned swiz =
brw_swizzle_for_size(nir_op_infos[instr->op].input_sizes[0]);
}
case nir_op_inot:
+ assert(nir_dest_bit_size(instr->dest.dest) < 64);
if (devinfo->gen >= 8) {
op[0] = resolve_source_modifiers(op[0]);
}
break;
case nir_op_ixor:
+ assert(nir_dest_bit_size(instr->dest.dest) < 64);
if (devinfo->gen >= 8) {
op[0] = resolve_source_modifiers(op[0]);
op[1] = resolve_source_modifiers(op[1]);
break;
case nir_op_ior:
+ assert(nir_dest_bit_size(instr->dest.dest) < 64);
if (devinfo->gen >= 8) {
op[0] = resolve_source_modifiers(op[0]);
op[1] = resolve_source_modifiers(op[1]);
break;
case nir_op_iand:
+ assert(nir_dest_bit_size(instr->dest.dest) < 64);
if (devinfo->gen >= 8) {
op[0] = resolve_source_modifiers(op[0]);
op[1] = resolve_source_modifiers(op[1]);
emit(CMP(dst, op[0], brw_imm_f(0.0f), BRW_CONDITIONAL_NZ));
break;
+ case nir_op_d2b: {
+ /* We use a MOV with conditional_mod to check if the provided value is
+ * 0.0. We want this to flush denormalized numbers to zero, so we set a
+ * source modifier on the source operand to trigger this, as source
+ * modifiers don't affect the result of the testing against 0.0.
+ */
+ src_reg value = op[0];
+ value.abs = true;
+ vec4_instruction *inst = emit(MOV(dst_null_df(), value));
+ inst->conditional_mod = BRW_CONDITIONAL_NZ;
+
+ src_reg one = src_reg(this, glsl_type::ivec4_type);
+ emit(MOV(dst_reg(one), brw_imm_d(~0)));
+ inst = emit(BRW_OPCODE_SEL, dst, one, brw_imm_d(0));
+ inst->predicate = BRW_PREDICATE_NORMAL;
+ break;
+ }
+
case nir_op_i2b:
emit(CMP(dst, op[0], brw_imm_d(0), BRW_CONDITIONAL_NZ));
break;
case nir_op_pack_unorm_2x16:
unreachable("not reached: should be handled by lower_packing_builtins");
+ case nir_op_pack_uvec4_to_uint:
+ unreachable("not reached");
+
+ case nir_op_pack_uvec2_to_uint: {
+ dst_reg tmp1 = dst_reg(this, glsl_type::uint_type);
+ tmp1.writemask = WRITEMASK_X;
+ op[0].swizzle = BRW_SWIZZLE_YYYY;
+ emit(SHL(tmp1, op[0], src_reg(brw_imm_ud(16u))));
+
+ dst_reg tmp2 = dst_reg(this, glsl_type::uint_type);
+ tmp2.writemask = WRITEMASK_X;
+ op[0].swizzle = BRW_SWIZZLE_XXXX;
+ emit(AND(tmp2, op[0], src_reg(brw_imm_ud(0xffffu))));
+
+ emit(OR(dst, src_reg(tmp1), src_reg(tmp2)));
+ break;
+ }
+
+ case nir_op_pack_double_2x32_split: {
+ dst_reg result = dst_reg(this, glsl_type::dvec4_type);
+ dst_reg tmp = dst_reg(this, glsl_type::uvec4_type);
+ emit(MOV(tmp, retype(op[0], BRW_REGISTER_TYPE_UD)));
+ emit(VEC4_OPCODE_SET_LOW_32BIT, result, src_reg(tmp));
+ emit(MOV(tmp, retype(op[1], BRW_REGISTER_TYPE_UD)));
+ emit(VEC4_OPCODE_SET_HIGH_32BIT, result, src_reg(tmp));
+ emit(MOV(dst, src_reg(result)));
+ break;
+ }
+
+ case nir_op_unpack_double_2x32_split_x:
+ case nir_op_unpack_double_2x32_split_y: {
+ enum opcode oper = (instr->op == nir_op_unpack_double_2x32_split_x) ?
+ VEC4_OPCODE_PICK_LOW_32BIT : VEC4_OPCODE_PICK_HIGH_32BIT;
+ dst_reg tmp = dst_reg(this, glsl_type::dvec4_type);
+ emit(MOV(tmp, op[0]));
+ dst_reg tmp2 = dst_reg(this, glsl_type::uvec4_type);
+ emit(oper, tmp2, src_reg(tmp));
+ emit(MOV(dst, src_reg(tmp2)));
+ break;
+ }
+
case nir_op_unpack_half_2x16:
/* As NIR does not guarantee that we have a correct swizzle outside the
* boundaries of a vector, and the implementation of emit_unpack_half_2x16
break;
case nir_op_unpack_unorm_4x8:
+ assert(nir_dest_bit_size(instr->dest.dest) < 64);
emit_unpack_unorm_4x8(dst, op[0]);
break;
case nir_op_pack_unorm_4x8:
+ assert(nir_dest_bit_size(instr->dest.dest) < 64);
emit_pack_unorm_4x8(dst, op[0]);
break;
case nir_op_unpack_snorm_4x8:
+ assert(nir_dest_bit_size(instr->dest.dest) < 64);
emit_unpack_snorm_4x8(dst, op[0]);
break;
case nir_op_pack_snorm_4x8:
+ assert(nir_dest_bit_size(instr->dest.dest) < 64);
emit_pack_snorm_4x8(dst, op[0]);
break;
case nir_op_bitfield_reverse:
+ assert(nir_dest_bit_size(instr->dest.dest) < 64);
emit(BFREV(dst, op[0]));
break;
case nir_op_bit_count:
+ assert(nir_dest_bit_size(instr->dest.dest) < 64);
emit(CBIT(dst, op[0]));
break;
case nir_op_ufind_msb:
- case nir_op_ifind_msb: {
- emit(FBH(retype(dst, BRW_REGISTER_TYPE_UD), op[0]));
+ assert(nir_dest_bit_size(instr->dest.dest) < 64);
+ emit_find_msb_using_lzd(vec4_builder(this).at_end(), dst, op[0], false);
+ break;
- /* FBH counts from the MSB side, while GLSL's findMSB() wants the count
- * from the LSB side. If FBH didn't return an error (0xFFFFFFFF), then
- * subtract the result from 31 to convert the MSB count into an LSB count.
- */
+ case nir_op_ifind_msb: {
+ assert(nir_dest_bit_size(instr->dest.dest) < 64);
+ vec4_builder bld = vec4_builder(this).at_end();
src_reg src(dst);
- emit(CMP(dst_null_d(), src, brw_imm_d(-1), BRW_CONDITIONAL_NZ));
- inst = emit(ADD(dst, src, brw_imm_d(31)));
- inst->predicate = BRW_PREDICATE_NORMAL;
- inst->src[0].negate = true;
+ if (devinfo->gen < 7) {
+ emit_find_msb_using_lzd(bld, dst, op[0], true);
+ } else {
+ emit(FBH(retype(dst, BRW_REGISTER_TYPE_UD), op[0]));
+
+ /* FBH counts from the MSB side, while GLSL's findMSB() wants the
+ * count from the LSB side. If FBH didn't return an error
+ * (0xFFFFFFFF), then subtract the result from 31 to convert the MSB
+ * count into an LSB count.
+ */
+ bld.CMP(dst_null_d(), src, brw_imm_d(-1), BRW_CONDITIONAL_NZ);
+
+ inst = bld.ADD(dst, src, brw_imm_d(31));
+ inst->predicate = BRW_PREDICATE_NORMAL;
+ inst->src[0].negate = true;
+ }
break;
}
- case nir_op_find_lsb:
- emit(FBL(dst, op[0]));
+ case nir_op_find_lsb: {
+ assert(nir_dest_bit_size(instr->dest.dest) < 64);
+ vec4_builder bld = vec4_builder(this).at_end();
+
+ if (devinfo->gen < 7) {
+ dst_reg temp = bld.vgrf(BRW_REGISTER_TYPE_D);
+
+ /* (x & -x) generates a value that consists of only the LSB of x.
+ * For all powers of 2, findMSB(y) == findLSB(y).
+ */
+ src_reg src = src_reg(retype(op[0], BRW_REGISTER_TYPE_D));
+ src_reg negated_src = src;
+
+ /* One must be negated, and the other must be non-negated. It
+ * doesn't matter which is which.
+ */
+ negated_src.negate = true;
+ src.negate = false;
+
+ bld.AND(temp, src, negated_src);
+ emit_find_msb_using_lzd(bld, dst, src_reg(temp), false);
+ } else {
+ bld.FBL(dst, op[0]);
+ }
break;
+ }
case nir_op_ubitfield_extract:
case nir_op_ibitfield_extract:
unreachable("should have been lowered");
case nir_op_ubfe:
case nir_op_ibfe:
+ assert(nir_dest_bit_size(instr->dest.dest) < 64);
op[0] = fix_3src_operand(op[0]);
op[1] = fix_3src_operand(op[1]);
op[2] = fix_3src_operand(op[2]);
break;
case nir_op_bfm:
+ assert(nir_dest_bit_size(instr->dest.dest) < 64);
emit(BFI1(dst, op[0], op[1]));
break;
case nir_op_bfi:
+ assert(nir_dest_bit_size(instr->dest.dest) < 64);
op[0] = fix_3src_operand(op[0]);
op[1] = fix_3src_operand(op[1]);
op[2] = fix_3src_operand(op[2]);
unreachable("not reached: should have been lowered");
case nir_op_fsign:
- /* AND(val, 0x80000000) gives the sign bit.
- *
- * Predicated OR ORs 1.0 (0x3f800000) with the sign bit if val is not
- * zero.
- */
- emit(CMP(dst_null_f(), op[0], brw_imm_f(0.0f), BRW_CONDITIONAL_NZ));
+ if (type_sz(op[0].type) < 8) {
+ /* AND(val, 0x80000000) gives the sign bit.
+ *
+ * Predicated OR ORs 1.0 (0x3f800000) with the sign bit if val is not
+ * zero.
+ */
+ emit(CMP(dst_null_f(), op[0], brw_imm_f(0.0f), BRW_CONDITIONAL_NZ));
- op[0].type = BRW_REGISTER_TYPE_UD;
- dst.type = BRW_REGISTER_TYPE_UD;
- emit(AND(dst, op[0], brw_imm_ud(0x80000000u)));
+ op[0].type = BRW_REGISTER_TYPE_UD;
+ dst.type = BRW_REGISTER_TYPE_UD;
+ emit(AND(dst, op[0], brw_imm_ud(0x80000000u)));
- inst = emit(OR(dst, src_reg(dst), brw_imm_ud(0x3f800000u)));
- inst->predicate = BRW_PREDICATE_NORMAL;
- dst.type = BRW_REGISTER_TYPE_F;
+ inst = emit(OR(dst, src_reg(dst), brw_imm_ud(0x3f800000u)));
+ inst->predicate = BRW_PREDICATE_NORMAL;
+ dst.type = BRW_REGISTER_TYPE_F;
+
+ if (instr->dest.saturate) {
+ inst = emit(MOV(dst, src_reg(dst)));
+ inst->saturate = true;
+ }
+ } else {
+ /* For doubles we do the same but we need to consider:
+ *
+ * - We use a MOV with conditional_mod instead of a CMP so that we can
+ * skip loading a 0.0 immediate. We use a source modifier on the
+ * source of the MOV so that we flush denormalized values to 0.
+ * Since we want to compare against 0, this won't alter the result.
+ * - We need to extract the high 32-bit of each DF where the sign
+ * is stored.
+ * - We need to produce a DF result.
+ */
+
+ /* Check for zero */
+ src_reg value = op[0];
+ value.abs = true;
+ inst = emit(MOV(dst_null_df(), value));
+ inst->conditional_mod = BRW_CONDITIONAL_NZ;
- if (instr->dest.saturate) {
- inst = emit(MOV(dst, src_reg(dst)));
- inst->saturate = true;
+ /* AND each high 32-bit channel with 0x80000000u */
+ dst_reg tmp = dst_reg(this, glsl_type::uvec4_type);
+ emit(VEC4_OPCODE_PICK_HIGH_32BIT, tmp, op[0]);
+ emit(AND(tmp, src_reg(tmp), brw_imm_ud(0x80000000u)));
+
+ /* Add 1.0 to each channel, predicated to skip the cases where the
+ * channel's value was 0
+ */
+ inst = emit(OR(tmp, src_reg(tmp), brw_imm_ud(0x3f800000u)));
+ inst->predicate = BRW_PREDICATE_NORMAL;
+
+ /* Now convert the result from float to double */
+ emit_conversion_to_double(dst, src_reg(tmp), instr->dest.saturate,
+ BRW_REGISTER_TYPE_F);
}
break;
* -> non-negative val generates 0x00000000.
* Predicated OR sets 1 if val is positive.
*/
+ assert(nir_dest_bit_size(instr->dest.dest) < 64);
emit(CMP(dst_null_d(), op[0], brw_imm_d(0), BRW_CONDITIONAL_G));
emit(ASR(dst, op[0], brw_imm_d(31)));
inst = emit(OR(dst, src_reg(dst), brw_imm_d(1)));
break;
case nir_op_ishl:
+ assert(nir_dest_bit_size(instr->dest.dest) < 64);
emit(SHL(dst, op[0], op[1]));
break;
case nir_op_ishr:
+ assert(nir_dest_bit_size(instr->dest.dest) < 64);
emit(ASR(dst, op[0], op[1]));
break;
case nir_op_ushr:
+ assert(nir_dest_bit_size(instr->dest.dest) < 64);
emit(SHR(dst, op[0], op[1]));
break;
inst->saturate = instr->dest.saturate;
break;
- case nir_op_fabs:
case nir_op_iabs:
- case nir_op_fneg:
case nir_op_ineg:
+ assert(nir_dest_bit_size(instr->dest.dest) < 64);
+ case nir_op_fabs:
+ case nir_op_fneg:
case nir_op_fsat:
unreachable("not reached: should be lowered by lower_source mods");
break;
case nir_jump_return:
+ /* fall through */
default:
unreachable("unknown jump");
}
glsl_type_for_nir_alu_type(nir_alu_type alu_type,
unsigned components)
{
- switch (alu_type) {
- case nir_type_float:
- return glsl_type::vec(components);
- case nir_type_int:
- return glsl_type::ivec(components);
- case nir_type_uint:
- return glsl_type::uvec(components);
- case nir_type_bool:
- return glsl_type::bvec(components);
- default:
- return glsl_type::error_type;
- }
-
- return glsl_type::error_type;
+ return glsl_type::get_instance(brw_glsl_base_type_for_nir_type(alu_type),
+ components, 1);
}
void
src_reg sampler_reg = brw_imm_ud(sampler);
src_reg coordinate;
const glsl_type *coord_type = NULL;
- src_reg shadow_comparitor;
+ src_reg shadow_comparator;
src_reg offset_value;
src_reg lod, lod2;
src_reg sample_index;
nir_tex_instr_dest_size(instr));
dst_reg dest = get_nir_dest(instr->dest, instr->dest_type);
- /* Our hardware requires a LOD for buffer textures */
+ /* The hardware requires a LOD for buffer textures */
if (instr->sampler_dim == GLSL_SAMPLER_DIM_BUF)
lod = brw_imm_d(0);
/* Load the texture operation sources */
+ uint32_t constant_offset = 0;
for (unsigned i = 0; i < instr->num_srcs; i++) {
switch (instr->src[i].src_type) {
- case nir_tex_src_comparitor:
- shadow_comparitor = get_nir_src(instr->src[i].src,
+ case nir_tex_src_comparator:
+ shadow_comparator = get_nir_src(instr->src[i].src,
BRW_REGISTER_TYPE_F, 1);
break;
break;
}
- case nir_tex_src_offset:
- offset_value = get_nir_src(instr->src[i].src, BRW_REGISTER_TYPE_D, 2);
+ case nir_tex_src_offset: {
+ nir_const_value *const_offset =
+ nir_src_as_const_value(instr->src[i].src);
+ if (!const_offset ||
+ !brw_texture_offset(const_offset->i32,
+ nir_tex_instr_src_size(instr, i),
+ &constant_offset)) {
+ offset_value =
+ get_nir_src(instr->src[i].src, BRW_REGISTER_TYPE_D, 2);
+ }
break;
+ }
case nir_tex_src_texture_offset: {
/* The highest texture which may be used by this operation is
* the last element of the array. Mark it here, because the generator
* doesn't have enough information to determine the bound.
*/
- uint32_t max_used = texture + instr->texture_array_size - 1;
+ uint32_t array_size = instr->texture_array_size;
+ uint32_t max_used = texture + array_size - 1;
if (instr->op == nir_texop_tg4) {
max_used += prog_data->base.binding_table.gather_texture_start;
} else {
instr->op == nir_texop_samples_identical) {
assert(coord_type != NULL);
if (devinfo->gen >= 7 &&
- key_tex->compressed_multisample_layout_mask & (1 << sampler)) {
- mcs = emit_mcs_fetch(coord_type, coordinate, sampler_reg);
+ key_tex->compressed_multisample_layout_mask & (1 << texture)) {
+ mcs = emit_mcs_fetch(coord_type, coordinate, texture_reg);
} else {
mcs = brw_imm_ud(0u);
}
}
- uint32_t constant_offset = 0;
- for (unsigned i = 0; i < 3; i++) {
- if (instr->const_offset[i] != 0) {
- constant_offset = brw_texture_offset(instr->const_offset, 3);
- break;
- }
- }
-
/* Stuff the channel select bits in the top of the texture offset */
if (instr->op == nir_texop_tg4) {
if (instr->component == 1 &&
ir_texture_opcode op = ir_texture_opcode_for_nir_texop(instr->op);
- bool is_cube_array =
- instr->op == nir_texop_txs &&
- instr->sampler_dim == GLSL_SAMPLER_DIM_CUBE &&
- instr->is_array;
-
emit_texture(op, dest, dest_type, coordinate, instr->coord_components,
- shadow_comparitor,
+ shadow_comparator,
lod, lod2, sample_index,
- constant_offset, offset_value,
- mcs, is_cube_array,
- texture, texture_reg, sampler, sampler_reg);
+ constant_offset, offset_value, mcs,
+ texture, texture_reg, sampler_reg);
}
void
vec4_visitor::nir_emit_undef(nir_ssa_undef_instr *instr)
{
- nir_ssa_values[instr->def.index] = dst_reg(VGRF, alloc.allocate(1));
+ nir_ssa_values[instr->def.index] =
+ dst_reg(VGRF, alloc.allocate(DIV_ROUND_UP(instr->def.bit_size, 32)));
}
}