Selaa lähdekoodia

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 <eric@anholt.net>
tags/19.1-branchpoint
Timothy Arceri 6 vuotta sitten
vanhempi
commit
7e60d5a501

+ 81
- 1
src/compiler/glsl/glsl_to_nir.cpp Näytä tiedosto

@@ -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

+ 2
- 1
src/compiler/glsl/glsl_to_nir.h Näytä tiedosto

@@ -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);


+ 1
- 1
src/gallium/drivers/freedreno/ir3/ir3_cmdline.c Näytä tiedosto

@@ -116,7 +116,7 @@ load_glsl(unsigned num_files, char* const* files, gl_shader_stage stage)
if (!prog)
errx(1, "couldn't parse `%s'", files[0]);

nir_shader *nir = glsl_to_nir(prog, stage, nir_options);
nir_shader *nir = glsl_to_nir(&local_ctx, prog, stage, nir_options);

/* required NIR passes: */
if (nir_options->lower_all_io_to_temps ||

+ 3
- 3
src/gallium/drivers/panfrost/midgard/cmdline.c Näytä tiedosto

@@ -66,11 +66,11 @@ compile_shader(char **argv)
}

midgard_program compiled;
nir = glsl_to_nir(prog, MESA_SHADER_VERTEX, &midgard_nir_options);
nir = glsl_to_nir(&local_ctx, prog, MESA_SHADER_VERTEX, &midgard_nir_options);
midgard_compile_shader_nir(nir, &compiled, false);
finalise_to_disk("vertex.bin", &compiled.compiled);

nir = glsl_to_nir(prog, MESA_SHADER_FRAGMENT, &midgard_nir_options);
nir = glsl_to_nir(&local_ctx, prog, MESA_SHADER_FRAGMENT, &midgard_nir_options);
midgard_compile_shader_nir(nir, &compiled, false);
finalise_to_disk("fragment.bin", &compiled.compiled);
}
@@ -91,7 +91,7 @@ compile_blend(char **argv)
prog->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program->info.stage = MESA_SHADER_FRAGMENT;

midgard_program program;
nir = glsl_to_nir(prog, MESA_SHADER_FRAGMENT, &midgard_nir_options);
nir = glsl_to_nir(&local_ctx, prog, MESA_SHADER_FRAGMENT, &midgard_nir_options);
midgard_compile_shader_nir(nir, &program, true);
finalise_to_disk("blend.bin", &program.compiled);
}

+ 1
- 1
src/mesa/drivers/dri/i965/brw_program.c Näytä tiedosto

@@ -93,7 +93,7 @@ brw_create_nir(struct brw_context *brw,
if (shader_prog->data->spirv) {
nir = _mesa_spirv_to_nir(ctx, shader_prog, stage, options);
} else {
nir = glsl_to_nir(shader_prog, stage, options);
nir = glsl_to_nir(ctx, shader_prog, stage, options);
}
assert (nir);


+ 1
- 1
src/mesa/state_tracker/st_glsl_to_nir.cpp Näytä tiedosto

@@ -361,7 +361,7 @@ st_glsl_to_nir(struct st_context *st, struct gl_program *prog,
if (prog->nir)
return prog->nir;

nir_shader *nir = glsl_to_nir(shader_program, stage, options);
nir_shader *nir = glsl_to_nir(st->ctx, shader_program, stage, options);

/* Set the next shader stage hint for VS and TES. */
if (!nir->info.separate_shader &&

Loading…
Peruuta
Tallenna