summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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 ad3d9866d53..2aa58ebf0cb 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 4c08cfdb6ad..ee2f80e7f35 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;
}