if (inst->is_send_from_grf())
return false;
+ if (!inst->can_do_source_mods())
+ return false;
+
return true;
}
return 2;
case VS_OPCODE_SCRATCH_WRITE:
return 3;
+ case GS_OPCODE_URB_WRITE:
+ case GS_OPCODE_THREAD_END:
+ return 0;
case SHADER_OPCODE_SHADER_TIME_ADD:
return 0;
case SHADER_OPCODE_TEX:
case SHADER_OPCODE_TXF:
case SHADER_OPCODE_TXF_MS:
case SHADER_OPCODE_TXS:
+ case SHADER_OPCODE_TG4:
return inst->header_present ? 1 : 0;
default:
assert(!"not reached");
if (inst->dst.file == GRF) {
assert(this->virtual_grf_end[inst->dst.reg] >= pc);
if (this->virtual_grf_end[inst->dst.reg] == pc) {
- inst->remove();
+ /* Don't dead code eliminate instructions that write to the
+ * accumulator as a side-effect. Instead just set the destination
+ * to the null register to free it.
+ */
+ switch (inst->opcode) {
+ case BRW_OPCODE_ADDC:
+ case BRW_OPCODE_SUBB:
+ case BRW_OPCODE_MACH:
+ inst->dst = dst_reg(retype(brw_null_reg(), inst->dst.type));
+ break;
+ default:
+ inst->remove();
+ break;
+ }
progress = true;
}
}
vec4_instruction *inst = (vec4_instruction *)node;
/* If there's a SEND message loading from a GRF on gen7+, it needs to be
- * contiguous. Assume that the GRF for the SEND is always in src[0].
+ * contiguous.
*/
if (inst->is_send_from_grf()) {
- split_grf[inst->src[0].reg] = false;
+ for (int i = 0; i < 3; i++) {
+ if (inst->src[i].file == GRF) {
+ split_grf[inst->src[i].reg] = false;
+ }
+ }
}
}
int
vec4_visitor::setup_uniforms(int reg)
{
+ prog_data->dispatch_grf_start_reg = reg;
+
/* The pre-gen6 VS requires that some push constants get loaded no
* matter what, or the GPU would hang.
*/
if (brw->gen < 6 && this->uniforms == 0) {
this->uniform_vector_size[this->uniforms] = 1;
+ prog_data->param = reralloc(NULL, prog_data->param, const float *, 4);
for (unsigned int i = 0; i < 4; i++) {
unsigned int slot = this->uniforms * 4 + i;
static float zero = 0.0;
prog_data->nr_params = this->uniforms * 4;
- prog_data->curb_read_length = reg - 1;
+ prog_data->curb_read_length = reg - prog_data->dispatch_grf_start_reg;
return reg;
}
void
-vec4_visitor::setup_payload(void)
+vec4_vs_visitor::setup_payload(void)
{
int reg = 0;
if (INTEL_DEBUG & DEBUG_SHADER_TIME)
emit_shader_time_begin();
+ assign_common_binding_table_offsets(0);
+
emit_prolog();
/* Generate VS IR for main(). (the visitor only descends into
}
base_ir = NULL;
- if (key->userclip_active && !key->uses_clip_distance)
+ if (key->userclip_active && !prog->UsesClipDistanceOut)
setup_uniform_clipplane_values();
emit_thread_end();
return generated;
}
+
+bool
+brw_vec4_prog_data_compare(const struct brw_vec4_prog_data *a,
+ const struct brw_vec4_prog_data *b)
+{
+ /* Compare all the struct (including the base) up to the pointers. */
+ if (memcmp(a, b, offsetof(struct brw_vec4_prog_data, param)))
+ return false;
+
+ if (memcmp(a->param, b->param, a->nr_params * sizeof(void *)))
+ return false;
+
+ if (memcmp(a->pull_param, b->pull_param, a->nr_pull_params * sizeof(void *)))
+ return false;
+
+ return true;
+}
+
+
+void
+brw_vec4_prog_data_free(const struct brw_vec4_prog_data *prog_data)
+{
+ ralloc_free((void *)prog_data->param);
+ ralloc_free((void *)prog_data->pull_param);
+}
+
+
} /* extern "C" */