diff options
author | Timothy Arceri <[email protected]> | 2019-02-20 17:13:49 +1100 |
---|---|---|
committer | Timothy Arceri <[email protected]> | 2019-03-06 23:05:20 +0000 |
commit | 7e60d5a501f311fa5e7bca5335adc6013dc1aeb9 (patch) | |
tree | 9dac6cae42a538fd3d904920e11058d8a1c8ba8c /src/compiler | |
parent | 7530d4abfcf9d39fb1b4abeb77cdbf6cf1d411a7 (diff) |
glsl: use NIR function inlining for drivers that use glsl_to_nir()
glsl_to_nir() is still missing support for converting certain
functions to NIR, so for those we use the GLSL IR optimisations
to remove the functions.
Reviewed-by: Eric Anholt <[email protected]>
Diffstat (limited to 'src/compiler')
-rw-r--r-- | src/compiler/glsl/glsl_to_nir.cpp | 82 | ||||
-rw-r--r-- | src/compiler/glsl/glsl_to_nir.h | 3 |
2 files changed, 83 insertions, 2 deletions
diff --git a/src/compiler/glsl/glsl_to_nir.cpp b/src/compiler/glsl/glsl_to_nir.cpp index 062434d066b..004a430d124 100644 --- a/src/compiler/glsl/glsl_to_nir.cpp +++ b/src/compiler/glsl/glsl_to_nir.cpp @@ -30,6 +30,7 @@ #include "ir_visitor.h" #include "ir_hierarchical_visitor.h" #include "ir.h" +#include "ir_optimization.h" #include "program.h" #include "compiler/nir/nir_control_flow.h" #include "compiler/nir/nir_builder.h" @@ -133,15 +134,74 @@ private: nir_visitor *visitor; }; +/* glsl_to_nir can only handle converting certain function paramaters + * to NIR. This visitor checks for parameters it can't currently handle. + */ +class ir_function_param_visitor : public ir_hierarchical_visitor +{ +public: + ir_function_param_visitor() + : unsupported(false) + { + } + + virtual ir_visitor_status visit_enter(ir_function_signature *ir) + { + + if (ir->is_intrinsic()) + return visit_continue; + + foreach_in_list(ir_variable, param, &ir->parameters) { + if (!param->type->is_vector() || !param->type->is_scalar()) { + unsupported = true; + return visit_stop; + } + + if (param->data.mode == ir_var_function_inout) { + unsupported = true; + return visit_stop; + } + } + + return visit_continue; + } + + bool unsupported; +}; + } /* end of anonymous namespace */ + +static bool +has_unsupported_function_param(exec_list *ir) +{ + ir_function_param_visitor visitor; + visit_list_elements(&visitor, ir); + return visitor.unsupported; +} + nir_shader * -glsl_to_nir(const struct gl_shader_program *shader_prog, +glsl_to_nir(struct gl_context *ctx, + const struct gl_shader_program *shader_prog, gl_shader_stage stage, const nir_shader_compiler_options *options) { struct gl_linked_shader *sh = shader_prog->_LinkedShaders[stage]; + const struct gl_shader_compiler_options *gl_options = + &ctx->Const.ShaderCompilerOptions[stage]; + + /* glsl_to_nir can only handle converting certain function paramaters + * to NIR. If we find something we can't handle then we get the GLSL IR + * opts to remove it before we continue on. + * + * TODO: add missing glsl ir to nir support and remove this loop. + */ + while (has_unsupported_function_param(sh->ir)) { + do_common_optimization(sh->ir, true, true, gl_options, + ctx->Const.NativeIntegers); + } + nir_shader *shader = nir_shader_create(NULL, stage, options, &sh->Program->info); @@ -150,7 +210,27 @@ glsl_to_nir(const struct gl_shader_program *shader_prog, v2.run(sh->ir); visit_exec_list(sh->ir, &v1); + nir_validate_shader(shader, "after glsl to nir, before function inline"); + + /* We have to lower away local constant initializers right before we + * inline functions. That way they get properly initialized at the top + * of the function and not at the top of its caller. + */ nir_lower_constant_initializers(shader, (nir_variable_mode)~0); + nir_lower_returns(shader); + nir_inline_functions(shader); + nir_opt_deref(shader); + + nir_validate_shader(shader, "after function inlining and return lowering"); + + /* Now that we have inlined everything remove all of the functions except + * main(). + */ + foreach_list_typed_safe(nir_function, function, node, &(shader)->functions){ + if (strcmp("main", function->name) != 0) { + exec_node_remove(&function->node); + } + } /* Remap the locations to slots so those requiring two slots will occupy * two locations. For instance, if we have in the IR code a dvec3 attr0 in diff --git a/src/compiler/glsl/glsl_to_nir.h b/src/compiler/glsl/glsl_to_nir.h index 115c8e1270b..38728d3ff26 100644 --- a/src/compiler/glsl/glsl_to_nir.h +++ b/src/compiler/glsl/glsl_to_nir.h @@ -36,7 +36,8 @@ extern "C" { struct gl_shader_program; -nir_shader *glsl_to_nir(const struct gl_shader_program *shader_prog, +nir_shader *glsl_to_nir(struct gl_context *ctx, + const struct gl_shader_program *shader_prog, gl_shader_stage stage, const nir_shader_compiler_options *options); |