!reladdr && !r.reladdr);
}
+bool
+src_reg::negative_equals(const src_reg &r) const
+{
+ return this->backend_reg::negative_equals(r) &&
+ !reladdr && !r.reladdr;
+}
+
bool
vec4_visitor::opt_vector_float()
{
* the next part of our packing algorithm.
*/
int reg = inst->src[0].nr;
- for (unsigned i = 0; i < vec4s_read; i++)
+ int channel_size = type_sz(inst->src[0].type) / 4;
+ for (unsigned i = 0; i < vec4s_read; i++) {
chans_used[reg + i] = 4;
+ channel_sizes[reg + i] = MAX2(channel_sizes[reg + i], channel_size);
+ }
}
}
}
break;
+ case BRW_OPCODE_OR:
+ if (inst->src[1].is_zero()) {
+ inst->opcode = BRW_OPCODE_MOV;
+ inst->src[1] = src_reg();
+ progress = true;
+ }
+ break;
+
case VEC4_OPCODE_UNPACK_UNIFORM:
if (inst->src[0].file != UNIFORM) {
inst->opcode = BRW_OPCODE_MOV;
}
}
+ /* VS_OPCODE_UNPACK_FLAGS_SIMD4X2 generates a bunch of mov(1)
+ * instructions, and this optimization pass is not capable of
+ * handling that. Bail on these instructions and hope that some
+ * later optimization pass can do the right thing after they are
+ * expanded.
+ */
+ if (scan_inst->opcode == VS_OPCODE_UNPACK_FLAGS_SIMD4X2)
+ break;
+
/* This doesn't handle saturation on the instruction we
* want to coalesce away if the register types do not match.
* But if scan_inst is a non type-converting 'mov', we can fix
vec4_instruction *inst = (vec4_instruction *)be_inst;
if (inst->predicate) {
- fprintf(file, "(%cf0.%d%s) ",
+ fprintf(file, "(%cf%d.%d%s) ",
inst->predicate_inverse ? '-' : '+',
- inst->flag_subreg,
+ inst->flag_subreg / 2,
+ inst->flag_subreg % 2,
pred_ctrl_align16[inst->predicate]);
}
fprintf(file, "%s", conditional_modifier[inst->conditional_mod]);
if (!inst->predicate &&
(devinfo->gen < 5 || (inst->opcode != BRW_OPCODE_SEL &&
+ inst->opcode != BRW_OPCODE_CSEL &&
inst->opcode != BRW_OPCODE_IF &&
inst->opcode != BRW_OPCODE_WHILE))) {
- fprintf(file, ".f0.%d", inst->flag_subreg);
+ fprintf(file, ".f%d.%d", inst->flag_subreg / 2, inst->flag_subreg % 2);
}
}
fprintf(file, " ");
}
}
+/**
+ * Three source instruction must have a GRF/MRF destination register.
+ * ARF NULL is not allowed. Fix that up by allocating a temporary GRF.
+ */
+void
+vec4_visitor::fixup_3src_null_dest()
+{
+ bool progress = false;
+
+ foreach_block_and_inst_safe (block, vec4_instruction, inst, cfg) {
+ if (inst->is_3src(devinfo) && inst->dst.is_null()) {
+ const unsigned size_written = type_sz(inst->dst.type);
+ const unsigned num_regs = DIV_ROUND_UP(size_written, REG_SIZE);
+
+ inst->dst = retype(dst_reg(VGRF, alloc.allocate(num_regs)),
+ inst->dst.type);
+ progress = true;
+ }
+ }
+
+ if (progress)
+ invalidate_live_intervals();
+}
+
void
vec4_visitor::convert_to_hw_regs()
{
OPT(scalarize_df);
}
+ fixup_3src_null_dest();
+
bool allocated_without_spills = reg_allocate();
if (!allocated_without_spills) {
}
prog_data->inputs_read = shader->info.inputs_read;
- prog_data->double_inputs_read = shader->info.double_inputs_read;
+ prog_data->double_inputs_read = shader->info.vs.double_inputs;
brw_nir_lower_vs_inputs(shader, key->gl_attrib_wa_flags);
brw_nir_lower_vue_outputs(shader, is_scalar);
* incoming vertex attribute. So, add an extra slot.
*/
if (shader->info.system_values_read &
- (BITFIELD64_BIT(SYSTEM_VALUE_BASE_VERTEX) |
+ (BITFIELD64_BIT(SYSTEM_VALUE_FIRST_VERTEX) |
BITFIELD64_BIT(SYSTEM_VALUE_BASE_INSTANCE) |
BITFIELD64_BIT(SYSTEM_VALUE_VERTEX_ID_ZERO_BASE) |
BITFIELD64_BIT(SYSTEM_VALUE_INSTANCE_ID))) {
nr_attribute_slots++;
}
+ /* gl_DrawID and IsIndexedDraw share its very own vec4 */
+ if (shader->info.system_values_read &
+ (BITFIELD64_BIT(SYSTEM_VALUE_DRAW_ID) |
+ BITFIELD64_BIT(SYSTEM_VALUE_IS_INDEXED_DRAW))) {
+ nr_attribute_slots++;
+ }
+
if (shader->info.system_values_read &
- BITFIELD64_BIT(SYSTEM_VALUE_BASE_VERTEX))
- prog_data->uses_basevertex = true;
+ BITFIELD64_BIT(SYSTEM_VALUE_IS_INDEXED_DRAW))
+ prog_data->uses_is_indexed_draw = true;
+
+ if (shader->info.system_values_read &
+ BITFIELD64_BIT(SYSTEM_VALUE_FIRST_VERTEX))
+ prog_data->uses_firstvertex = true;
if (shader->info.system_values_read &
BITFIELD64_BIT(SYSTEM_VALUE_BASE_INSTANCE))
BITFIELD64_BIT(SYSTEM_VALUE_INSTANCE_ID))
prog_data->uses_instanceid = true;
- /* gl_DrawID has its very own vec4 */
if (shader->info.system_values_read &
- BITFIELD64_BIT(SYSTEM_VALUE_DRAW_ID)) {
- prog_data->uses_drawid = true;
- nr_attribute_slots++;
- }
+ BITFIELD64_BIT(SYSTEM_VALUE_DRAW_ID))
+ prog_data->uses_drawid = true;
/* The 3DSTATE_VS documentation lists the lower bound on "Vertex URB Entry
* Read Length" as 1 in vec4 mode, and 0 in SIMD8 mode. Empirically, in
prog_data->base.base.dispatch_grf_start_reg = v.payload.num_regs;
- fs_generator g(compiler, log_data, mem_ctx, (void *) key,
+ fs_generator g(compiler, log_data, mem_ctx,
&prog_data->base.base, v.promoted_constants,
v.runtime_check_aads_emit, MESA_SHADER_VERTEX);
if (INTEL_DEBUG & DEBUG_VS) {
g.enable_debug(debug_name);
}
g.generate_code(v.cfg, 8);
- assembly = g.get_assembly(&prog_data->base.base.program_size);
+ assembly = g.get_assembly();
}
if (!assembly) {
}
assembly = brw_vec4_generate_assembly(compiler, log_data, mem_ctx,
- shader, &prog_data->base, v.cfg,
- &prog_data->base.base.program_size);
+ shader, &prog_data->base, v.cfg);
}
return assembly;