summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Ekstrand <jason.ekstrand@intel.com>2014-12-17 12:34:27 -0800
committerJason Ekstrand <jason.ekstrand@intel.com>2014-12-17 21:08:13 -0800
commit4f40f8e80d40992c54f20c8d997b57766421ad41 (patch)
tree8a535e856b95df7ea86d29d0341bd732a24b29f7
parent1aadc289f7bd5c9a8e4a10b1bebb5ebb060461d8 (diff)
i965/fs_nir: Handle sample ID, position, and mask better
Before, we were emitting the full pile of setup instructions for sample_id and sample_pos every time they were used. With this commit, we emit them in their own pass once at the beginning of the shader and simply emit uses later on. When it comes time for setting up VS, we can put setup for its special values in the same pass.
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs.h2
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs_nir.cpp81
2 files changed, 71 insertions, 12 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_fs.h b/src/mesa/drivers/dri/i965/brw_fs.h
index 8f6b3b0557..0cd3966ff5 100644
--- a/src/mesa/drivers/dri/i965/brw_fs.h
+++ b/src/mesa/drivers/dri/i965/brw_fs.h
@@ -574,6 +574,7 @@ public:
void nir_setup_uniforms(nir_shader *shader);
void nir_setup_uniform(nir_variable *var);
void nir_setup_builtin_uniform(nir_variable *var);
+ void nir_emit_system_values(nir_shader *shader);
void nir_emit_impl(nir_function_impl *impl);
void nir_emit_cf_list(exec_list *list);
void nir_emit_if(nir_if *if_stmt);
@@ -701,6 +702,7 @@ public:
fs_reg nir_inputs;
fs_reg nir_outputs;
fs_reg nir_uniforms;
+ fs_reg *nir_system_values;
/** @{ debug annotation info */
const char *current_annotation;
diff --git a/src/mesa/drivers/dri/i965/brw_fs_nir.cpp b/src/mesa/drivers/dri/i965/brw_fs_nir.cpp
index 9046e262e7..32f9538fc8 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_nir.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_nir.cpp
@@ -106,6 +106,8 @@ fs_visitor::emit_nir_code()
nir_setup_uniforms(nir);
}
+ nir_emit_system_values(nir);
+
nir_globals = ralloc_array(mem_ctx, fs_reg, nir->reg_alloc);
foreach_list_typed(nir_register, reg, node, &nir->registers) {
unsigned array_elems =
@@ -289,6 +291,60 @@ fs_visitor::nir_setup_builtin_uniform(nir_variable *var)
}
}
+static bool
+emit_system_values_block(nir_block *block, void *void_visitor)
+{
+ fs_visitor *v = (fs_visitor *)void_visitor;
+ fs_reg *reg;
+
+ nir_foreach_instr(block, instr) {
+ if (instr->type != nir_instr_type_intrinsic)
+ continue;
+
+ nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr);
+ switch (intrin->intrinsic) {
+ case nir_intrinsic_load_sample_pos:
+ assert(v->stage == MESA_SHADER_FRAGMENT);
+ reg = &v->nir_system_values[SYSTEM_VALUE_SAMPLE_POS];
+ if (reg->file == BAD_FILE)
+ *reg = *v->emit_samplepos_setup();
+ break;
+
+ case nir_intrinsic_load_sample_id:
+ assert(v->stage == MESA_SHADER_FRAGMENT);
+ reg = &v->nir_system_values[SYSTEM_VALUE_SAMPLE_ID];
+ if (reg->file == BAD_FILE)
+ *reg = *v->emit_sampleid_setup();
+ break;
+
+ case nir_intrinsic_load_sample_mask_in:
+ assert(v->stage == MESA_SHADER_FRAGMENT);
+ assert(v->brw->gen >= 7);
+ reg = &v->nir_system_values[SYSTEM_VALUE_SAMPLE_MASK_IN];
+ if (reg->file == BAD_FILE)
+ *reg = fs_reg(retype(brw_vec8_grf(v->payload.sample_mask_in_reg, 0),
+ BRW_REGISTER_TYPE_D));
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return true;
+}
+
+void
+fs_visitor::nir_emit_system_values(nir_shader *shader)
+{
+ nir_system_values = ralloc_array(mem_ctx, fs_reg, SYSTEM_VALUE_MAX);
+ nir_foreach_overload(shader, overload) {
+ assert(strcmp(overload->function->name, "main") == 0);
+ assert(overload->impl);
+ nir_foreach_block(overload->impl, emit_system_values_block, this);
+ }
+}
+
void
fs_visitor::nir_emit_impl(nir_function_impl *impl)
{
@@ -1276,26 +1332,27 @@ fs_visitor::nir_emit_intrinsic(nir_intrinsic_instr *instr)
assert(!"TODO");
case nir_intrinsic_load_sample_mask_in: {
- assert(brw->gen >= 7);
- fs_reg reg = fs_reg(retype(brw_vec8_grf(payload.sample_mask_in_reg, 0),
- BRW_REGISTER_TYPE_D));
- dest.type = reg.type;
- emit(MOV(dest, reg));
+ fs_reg sample_mask_in = nir_system_values[SYSTEM_VALUE_SAMPLE_MASK_IN];
+ assert(sample_mask_in.file != BAD_FILE);
+ dest.type = sample_mask_in.type;
+ emit(MOV(dest, sample_mask_in));
break;
}
case nir_intrinsic_load_sample_pos: {
- fs_reg *reg = emit_samplepos_setup();
- dest.type = reg->type;
- emit(MOV(dest, *reg));
- emit(MOV(offset(dest, 1), offset(*reg, 1)));
+ fs_reg sample_pos = nir_system_values[SYSTEM_VALUE_SAMPLE_POS];
+ assert(sample_pos.file != BAD_FILE);
+ dest.type = sample_pos.type;
+ emit(MOV(dest, sample_pos));
+ emit(MOV(offset(dest, 1), offset(sample_pos, 1)));
break;
}
case nir_intrinsic_load_sample_id: {
- fs_reg *reg = emit_sampleid_setup();
- dest.type = reg->type;
- emit(MOV(dest, *reg));
+ fs_reg sample_id = nir_system_values[SYSTEM_VALUE_SAMPLE_ID];
+ assert(sample_id.file != BAD_FILE);
+ dest.type = sample_id.type;
+ emit(MOV(dest, sample_id));
break;
}