diff options
author | Jason Ekstrand <[email protected]> | 2015-10-19 11:15:32 -0700 |
---|---|---|
committer | Jason Ekstrand <[email protected]> | 2015-10-19 14:14:21 -0700 |
commit | 958fc04dc51a2561c8598f42df59e3d9139e56a7 (patch) | |
tree | b6acf05aa073e97ae8e58647bf05c2c3e816f041 /src/glsl/nir/nir.c | |
parent | 995d9c4ac7fb046e01196cec308ebe10002a28da (diff) | |
parent | de862f03accb12b044ced60cb98f47a055457223 (diff) |
Merge remote-tracking branch 'mesa-public/master' into vulkan
Diffstat (limited to 'src/glsl/nir/nir.c')
-rw-r--r-- | src/glsl/nir/nir.c | 108 |
1 files changed, 88 insertions, 20 deletions
diff --git a/src/glsl/nir/nir.c b/src/glsl/nir/nir.c index e12da805281..793bdafb54b 100644 --- a/src/glsl/nir/nir.c +++ b/src/glsl/nir/nir.c @@ -103,6 +103,72 @@ nir_reg_remove(nir_register *reg) exec_node_remove(®->node); } +void +nir_shader_add_variable(nir_shader *shader, nir_variable *var) +{ + switch (var->data.mode) { + case nir_var_local: + assert(!"nir_shader_add_variable cannot be used for local variables"); + break; + + case nir_var_global: + exec_list_push_tail(&shader->globals, &var->node); + break; + + case nir_var_shader_in: + exec_list_push_tail(&shader->inputs, &var->node); + break; + + case nir_var_shader_out: + exec_list_push_tail(&shader->outputs, &var->node); + break; + + case nir_var_uniform: + case nir_var_shader_storage: + exec_list_push_tail(&shader->uniforms, &var->node); + break; + + case nir_var_system_value: + exec_list_push_tail(&shader->system_values, &var->node); + break; + } +} + +nir_variable * +nir_variable_create(nir_shader *shader, nir_variable_mode mode, + const struct glsl_type *type, const char *name) +{ + nir_variable *var = rzalloc(shader, nir_variable); + var->name = ralloc_strdup(var, name); + var->type = type; + var->data.mode = mode; + + if ((mode == nir_var_shader_in && shader->stage != MESA_SHADER_VERTEX) || + (mode == nir_var_shader_out && shader->stage != MESA_SHADER_FRAGMENT)) + var->data.interpolation = INTERP_QUALIFIER_SMOOTH; + + if (mode == nir_var_shader_in || mode == nir_var_uniform) + var->data.read_only = true; + + nir_shader_add_variable(shader, var); + + return var; +} + +nir_variable * +nir_local_variable_create(nir_function_impl *impl, + const struct glsl_type *type, const char *name) +{ + nir_variable *var = rzalloc(impl->overload->function->shader, nir_variable); + var->name = ralloc_strdup(var, name); + var->type = type; + var->data.mode = nir_var_local; + + nir_function_impl_add_variable(impl, var); + + return var; +} + nir_function * nir_function_create(nir_shader *shader, const char *name) { @@ -1080,31 +1146,33 @@ nir_src_as_const_value(nir_src src) return &load->value; } +/** + * Returns true if the source is known to be dynamically uniform. Otherwise it + * returns false which means it may or may not be dynamically uniform but it + * can't be determined. + */ bool -nir_srcs_equal(nir_src src1, nir_src src2) +nir_src_is_dynamically_uniform(nir_src src) { - if (src1.is_ssa) { - if (src2.is_ssa) { - return src1.ssa == src2.ssa; - } else { - return false; - } - } else { - if (src2.is_ssa) { - return false; - } else { - if ((src1.reg.indirect == NULL) != (src2.reg.indirect == NULL)) - return false; + if (!src.is_ssa) + return false; - if (src1.reg.indirect) { - if (!nir_srcs_equal(*src1.reg.indirect, *src2.reg.indirect)) - return false; - } + /* Constants are trivially dynamically uniform */ + if (src.ssa->parent_instr->type == nir_instr_type_load_const) + return true; - return src1.reg.reg == src2.reg.reg && - src1.reg.base_offset == src2.reg.base_offset; - } + /* As are uniform variables */ + if (src.ssa->parent_instr->type == nir_instr_type_intrinsic) { + nir_intrinsic_instr *intr = nir_instr_as_intrinsic(src.ssa->parent_instr); + + if (intr->intrinsic == nir_intrinsic_load_uniform) + return true; } + + /* XXX: this could have many more tests, such as when a sampler function is + * called with dynamically uniform arguments. + */ + return false; } static void |