gallium: add support for NIR as alternate IR
cover gallium: add support for NIR as alternate IR
From: Rob Clark <[email protected]>
Still quite rough around the edges, but now it's at the point of sorta- kinda-working-sometimes. So I guess time to get wider feedback.
The initial goal is to figure out things that glsl_to_nir does differently from tgsi_to_nir, so we can fix them up and have better likelyhood of drivers being able to consume NIR from multiple sources. Eventually I'd like to be able to re-use spriv->nir for compute/ clover support, for example. And at some point I'd like to be able to bypass the conversion from glsl->tgsi for mesa st. But for now, being able to track down and fix differences between glsl_to_nir vs tgsi_to_nir is a good start.
With what I've added to pipe_shader_state (which is, I suppose, missing some doc updates), the intention is that drivers can ask for an IR other than TGSI. And what they actually get will be either TGSI or their preferred IR. Drivers will have to always handle the TGSI case, so the intention isn't to port all the different state trackers (or internally generated shaders, etc).
I suppose pipe_compute_state needs similar treatment, but I've skipped that for now.
Currently only the direct GLSL->NIR path is implemented for vertex shaders, which results in a huge hack at the end of the series. It isn't ever intended for drivers to mix/match glsl->nir vs glsl->tgsi-> nir across shader stages. But this is sufficient for now for me to debug other issues.
Shader variant handling will be completely broken at the moment, without having a nir_clone()[1]. (Ian, depending on how far that is from the top of your TODO list, I can take a stab at that, since I might be the first consumer.)
Also, there is some trivial shader variant handling in mesa st which would have to be ported to NIR. Or, perhaps, just somehow expose the shader key to the driver. (Currently most drivers are doing much more variant handling within the driver, and having two levels of variants does seem a bit silly.)
[1] https://bugs.freedesktop.org/show_bug.cgi?id=89436
(First patch isn't actually RFC.. just an issue that I noticed in the process.)
Rob Clark (8):
nir: add nir_var_all enum
gallium: refactor pipe_shader_state to support multiple IR's
gallium: add NIR as a possible IR
mesa/st: add support for NIR as possible driver IR freedreno/ir3: drop tokens arg
freedreno/ir3: add support for NIR as preferred IR freedreno/ir3: fix const_index handling for uniforms
HACK: freedreno/ir3: hack for mismatch on varying slots for
glsl->tgsi->nir vs glsl->nir
src/gallium/auxiliary/hud/hud_context.c | 14 +- src/gallium/auxiliary/postprocess/pp_run.c | 4 +- src/gallium/auxiliary/tgsi/tgsi_ureg.c | 6 +- src/gallium/auxiliary/util/u_simple_shaders.c | 42 +++- src/gallium/auxiliary/util/u_tests.c | 7 +- src/gallium/drivers/freedreno/freedreno_screen.c | 5 +- src/gallium/drivers/freedreno/freedreno_util.h | 1 + .../drivers/freedreno/ir3/ir3_compiler_nir.c | 38 +++- src/gallium/drivers/freedreno/ir3/ir3_shader.c | 30 ++- src/gallium/drivers/freedreno/ir3/ir3_shader.h | 3 + src/gallium/include/pipe/p_defines.h | 13 +- src/gallium/include/pipe/p_state.h | 21 +- src/glsl/nir/nir.c | 4 + src/glsl/nir/nir.h | 1 + src/glsl/nir/nir_lower_io.c | 2 +- src/mesa/drivers/dri/i965/brw_nir.c | 3 +- src/mesa/state_tracker/st_glsl_to_tgsi.cpp | 223 ++++++++++++++++++++- src/mesa/state_tracker/st_program.c | 43 +++- 18 files changed, 422 insertions(+), 38 deletions(-)
Signature · 6 lines
2.5.0 _______________________________________________ dri-devel mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/dri-devel
PATCH 1/8 nir: add nir_var_all enum
Otherwise, passing -1 gets you:
error: invalid conversion from 'int' to 'nir_variable_mode' [-fpermissive]
--- src/glsl/nir/nir.c | 4 ++++ src/glsl/nir/nir.h | 1 + src/glsl/nir/nir_lower_io.c | 2 +- src/mesa/drivers/dri/i965/brw_nir.c | 3 ++- 4 files changed, 8 insertions(+), 2 deletions(-)
src/glsl/nir/nir.c +4 -0
@@ -107,6 +107,10 @@ void nir_shader_add_variable(nir_shader *shader, nir_variable *var) {switch (var->data.mode) { +case nir_var_all: +assert (!"invalid mode" ); +break ; +case nir_var_local:assert (!"nir_shader_add_variable cannot be used for local variables" );break ;
src/glsl/nir/nir.h +1 -0
@@ -82,6 +82,7 @@ typedef struct { } nir_state_slot; typedef enum { + nir_var_all = -1, nir_var_shader_in, nir_var_shader_out, nir_var_global,
src/glsl/nir/nir_lower_io.c +1 -1
@@ -176,7 +176,7 @@ nir_lower_io_block(nir_block *block, void *void_state)nir_variable_mode mode = intrin->variables[0 ]->var->data.mode; -if (state->mode !=-1 && state->mode != mode) +if (state->mode != nir_var_all && state->mode != mode)continue ;switch (intrin->intrinsic) {
src/mesa/drivers/dri/i965/brw_nir.c +2 -1
@@ -219,7 +219,8 @@ brw_create_nir(struct brw_context *brw,nir_assign_var_locations (&nir->uniforms, &nir->num_uniforms, is_scalar ? type_size_scalar : type_size_vec4); -nir_lower_io (nir,-1 , is_scalar ? type_size_scalar : type_size_vec4); +nir_lower_io (nir, nir_var_all, + is_scalar ? type_size_scalar : type_size_vec4);nir_validate_shader (nir);nir_remove_dead_variables (nir);
Signature · 6 lines
2.5.0 _______________________________________________ dri-devel mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/dri-devel
RFC 2/8 gallium: refactor pipe_shader_state to support multiple IR's
In reply to Rob ClarkThe goal is to allow the pipe driver to request something other than TGSI, but detect whether what is getting is TGSI vs what it requested. The pipe drivers will always have to support TGSI (and convert that into whatever it is that they prefer), but in some cases we should be able to skip the TGSI intermediate step (such as glsl->nir vs glsl->tgsi->nir).
I think pipe_compute_state should get similar treatment. Currently, afaict, it has one user and one consumer, which has allowed it to be sloppy wrt. supporting alternative IR's.
--- src/gallium/auxiliary/hud/hud_context.c | 14 +++++++-- src/gallium/auxiliary/postprocess/pp_run.c | 4 ++- src/gallium/auxiliary/tgsi/tgsi_ureg.c | 6 ++-- src/gallium/auxiliary/util/u_simple_shaders.c | 42 +++++++++++++++++++++++---- src/gallium/auxiliary/util/u_tests.c | 7 ++++- src/gallium/include/pipe/p_defines.h | 12 ++++++-- src/gallium/include/pipe/p_state.h | 20 +++++++++++-- 7 files changed, 89 insertions(+), 16 deletions(-)
src/gallium/auxiliary/hud/hud_context.c +12 -2
@@ -1179,7 +1179,12 @@ hud_create(struct pipe_context *pipe, struct cso_context *cso) };struct tgsi_token tokens[1000 ]; -struct pipe_shader_state state = {tokens}; +struct pipe_shader_state state; + +memset (&state,0 ,sizeof (state)); + + state.ir =PIPE_SHADER_IR_TGSI ; + state.tokens = tokens;if (!tgsi_text_translate (fragment_shader_text, tokens,Elements (tokens))) {assert (0 );
@@ -1226,7 +1231,12 @@ hud_create(struct pipe_context *pipe, struct cso_context *cso) };struct tgsi_token tokens[1000 ]; -struct pipe_shader_state state = {tokens}; +struct pipe_shader_state state; + +memset (&state,0 ,sizeof (state)); + + state.ir =PIPE_SHADER_IR_TGSI ; + state.tokens = tokens;if (!tgsi_text_translate (vertex_shader_text, tokens,Elements (tokens))) {assert (0 );
src/gallium/auxiliary/postprocess/pp_run.c +3 -1
@@ -272,8 +272,10 @@ pp_tgsi_to_state(struct pipe_context *pipe, const char *text, bool isvs,return NULL ; } +memset (&state,0 ,sizeof (state)); + + state.ir =PIPE_SHADER_IR_TGSI ; state.tokens = tokens; -memset (&state.stream_output,0 ,sizeof (state.stream_output));if (isvs) { ret_state = pipe->create_vs_state (pipe, &state);
src/gallium/auxiliary/tgsi/tgsi_ureg.c +4 -2
@@ -1777,14 +1777,16 @@ void *ureg_create_shader( struct ureg_program *ureg, {struct pipe_shader_state state; +memset (&state,0 ,sizeof (state)); + + state.ir =PIPE_SHADER_IR_TGSI ; + state.tokens =ureg_finalize (ureg);if (!state.tokens)return NULL ;if (so) state.stream_output = *so; -else -memset (&state.stream_output,0 ,sizeof (state.stream_output));switch (ureg->processor) {case TGSI_PROCESSOR_VERTEX :
src/gallium/auxiliary/util/u_simple_shaders.c +36 -6
78 lines not on this page · raw message
src/gallium/auxiliary/util/u_tests.c +6 -1
@@ -422,7 +422,12 @@ null_constant_buffer(struct pipe_context *ctx)"MOV OUT[0], CONST[0]\n" "END\n" ;struct tgsi_token tokens[1000 ]; -struct pipe_shader_state state = {tokens}; +struct pipe_shader_state state; + +memset (&state,0 ,sizeof (state)); + + state.ir =PIPE_SHADER_IR_TGSI ; + state.tokens = tokens;if (!tgsi_text_translate (text, tokens,Elements (tokens))) {puts ("Can't compile a fragment shader." );
src/gallium/include/pipe/p_defines.h +10 -2
@@ -701,12 +701,20 @@ enum pipe_shader_cap/** * Shader intermediate representation. +* +* Note that if the driver requests something other than TGSI, it must +* always be prepared to receive TGSI in addition to it's preferred IR. +* If the driver requests TGSI as it's preferred IR, it will *always* +* get TGSI. +* +* Note that PIPE_SHADER_IR_TGSI should be zero for backwards compat with +* state trackers that only understand TGSI. */ enum pipe_shader_ir { -PIPE_SHADER_IR_TGSI , +PIPE_SHADER_IR_TGSI =0 ,PIPE_SHADER_IR_LLVM , -PIPE_SHADER_IR_NATIVE +PIPE_SHADER_IR_NATIVE , };/**
src/gallium/include/pipe/p_state.h +18 -2
@@ -211,10 +211,26 @@ struct pipe_stream_output_info } output[PIPE_MAX_SO_OUTPUTS ]; }; - +/** +* The 'ir' parameter identifies whether the shader state contains TGSI +* tokens, etc. If the driver returns 'PIPE_SHADER_IR_TGSI' for the +* 'PIPE_SHADER_CAP_PREFERRED_IR' shader param, the ir will *always* be +* 'PIPE_SHADER_IR_TGSI' and the tokens ptr will be valid. If the driver +* requests a different 'pipe_shader_ir' type, then it must check the 'ir' +* enum to see if it is getting TGSI tokens or it's preferred IR. +* +* TODO pipe_compute_state should probably get similar treatment to handle +* multiple IR's in a cleaner way.. +*/ struct pipe_shader_state { -const struct tgsi_token *tokens; +enum pipe_shader_ir ir; +/* TODO are anon unions allowed? */ +union { +const struct tgsi_token *tokens; +void *llvm; +void *native; + };struct pipe_stream_output_info stream_output; };
Signature · 6 lines
2.5.0 _______________________________________________ dri-devel mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/dri-devel
RFC 3/8 gallium: add NIR as a possible IR
In reply to Rob Clark--- src/gallium/include/pipe/p_defines.h | 1 + src/gallium/include/pipe/p_state.h | 1 + 2 files changed, 2 insertions(+)
src/gallium/include/pipe/p_defines.h +1 -0
@@ -715,6 +715,7 @@ enum pipe_shader_irPIPE_SHADER_IR_TGSI =0 ,PIPE_SHADER_IR_LLVM ,PIPE_SHADER_IR_NATIVE , + PIPE_SHADER_IR_NIR, };/**
src/gallium/include/pipe/p_state.h +1 -0
@@ -230,6 +230,7 @@ struct pipe_shader_stateconst struct tgsi_token *tokens;void *llvm;void *native; +void *nir; };struct pipe_stream_output_info stream_output; };
Signature · 6 lines
2.5.0 _______________________________________________ dri-devel mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/dri-devel
RFC 4/8 mesa/st: add support for NIR as possible driver IR
In reply to Rob Clark--- src/mesa/state_tracker/st_glsl_to_tgsi.cpp | 223 ++++++++++++++++++++++++++++- src/mesa/state_tracker/st_program.c | 43 +++++- 2 files changed, 260 insertions(+), 6 deletions(-)
src/mesa/state_tracker/st_glsl_to_tgsi.cpp +220 -3
@@ -35,6 +35,9 @@ #include "glsl_parser_extras.h" #include "ir_optimization.h" +#include "nir.h" +#include "glsl_to_nir.h" + #include "main/errors.h" #include "main/shaderobj.h" #include "main/uniforms.h"
@@ -5486,9 +5489,9 @@ out: * generating Mesa IR. */ static struct gl_program * -get_mesa_program(struct gl_context *ctx, - struct gl_shader_program *shader_program, - struct gl_shader *shader) +get_mesa_program_tgsi(struct gl_context *ctx, + struct gl_shader_program *shader_program, + struct gl_shader *shader) { glsl_to_tgsi_visitor* v; struct gl_program *prog;
@@ -5680,6 +5683,220 @@ get_mesa_program(struct gl_context *ctx, return prog; } +/* TODO dup'd from brw_vec4_vistor.cpp.. what should we do? */ +static int +type_size_vec4(const struct glsl_type *type) +{ + unsigned int i; + int size; + + switch (type->base_type) { + case GLSL_TYPE_UINT: + case GLSL_TYPE_INT: + case GLSL_TYPE_FLOAT: + case GLSL_TYPE_BOOL: + if (type->is_matrix()) { + return type->matrix_columns; + } else { + /* Regardless of size of vector, it gets a vec4. This is bad + * packing for things like floats, but otherwise arrays become a + * mess. Hopefully a later pass over the code can pack scalars + * down if appropriate. + */ + return 1; + } + case GLSL_TYPE_ARRAY: + assert(type->length > 0); + return type_size_vec4(type->fields.array) * type->length; + case GLSL_TYPE_STRUCT: + size = 0; + for (i = 0; i < type->length; i++) { + size += type_size_vec4(type->fields.structure[i].type); + } + return size; + case GLSL_TYPE_SUBROUTINE: + return 1; + + case GLSL_TYPE_SAMPLER: + /* Samplers take up no register space, since they're baked in at + * link time. + */ + return 0; + case GLSL_TYPE_ATOMIC_UINT: + return 0; + case GLSL_TYPE_IMAGE: +// return DIV_ROUND_UP(BRW_IMAGE_PARAM_SIZE, 4); + case GLSL_TYPE_VOID: + case GLSL_TYPE_DOUBLE: + case GLSL_TYPE_ERROR: + case GLSL_TYPE_INTERFACE: + unreachable("not reached"); + } + + return 0; +} + +static struct gl_program * +get_mesa_program_nir(struct gl_context *ctx, + struct gl_shader_program *shader_program, + struct gl_shader *shader) +{ + struct gl_program *prog; + GLenum target = _mesa_shader_stage_to_program(shader->Stage); + struct gl_shader_compiler_options *options = + &ctx->Const.ShaderCompilerOptions[_mesa_shader_enum_to_shader_stage(shader->Type)]; + struct pipe_screen *pscreen = ctx->st->pipe->screen; + unsigned ptarget = st_shader_stage_to_ptarget(shader->Stage); + nir_shader_compiler_options nir_options = {0}; + nir_shader *nir; + + /* TODO maybe options marked with 'XXX' should be PIPE_SHADER_CAP_x's */ + nir_options.lower_ffma = + !pscreen->get_shader_param(pscreen, ptarget, PIPE_SHADER_CAP_TGSI_FMA_SUPPORTED); + nir_options.lower_flrp = true; // XXX + nir_options.lower_fpow = options->EmitNoPow; + nir_options.lower_fsat = options->EmitNoSat; + nir_options.lower_fsqrt = + !pscreen->get_shader_param(pscreen, ptarget, PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED); + nir_options.lower_negate = false; // XXX + nir_options.lower_sub = false; // XXX + nir_options.lower_scmp = true; // XXX + nir_options.fdot_replicates = false;// XXX + nir_options.lower_ffract = true; // XXX + nir_options.native_integers = ctx->Const.NativeIntegers; + + validate_ir_tree(shader->ir); + + prog = ctx->Driver.NewProgram(ctx, target, shader_program->Name); + if (!prog) + return NULL; + prog->Parameters = _mesa_new_parameter_list(); + + _mesa_copy_linked_program_data(shader->Stage, shader_program, prog); + _mesa_generate_parameters_list_for_uniforms(shader_program, shader, + prog->Parameters); + +// /* Remove reads from output registers. */ +// lower_output_reads(shader->Stage, shader->ir); + + /* Make a pass over the IR to add state references for any built-in + * uniforms that are used. This has to be done now (during linking). + * Code generation doesn't happen until the first time this shader is + * used for rendering. Waiting until then to generate the parameters is + * too late. At that point, the values for the built-in uniforms won't + * get sent to the shader. + */ + foreach_in_list(ir_instruction, node, shader->ir) { + ir_variable *var = node->as_variable(); + + if ((var == NULL) || (var->data.mode != ir_var_uniform) || + (strncmp(var->name, "gl_", 3) != 0)) + continue; + + const ir_state_slot *const slots = var->get_state_slots(); + assert(slots != NULL); + + for (unsigned int i = 0; i < var->get_num_state_slots(); i++) { + _mesa_add_state_reference(prog->Parameters, + (gl_state_index *) slots[i].tokens); + } + } + + if (ctx->_Shader->Flags & GLSL_DUMP) { + _mesa_log("\n"); + _mesa_log("GLSL IR for linked %s program %d:\n", + _mesa_shader_stage_to_string(shader->Stage), + shader_program->Name); + _mesa_print_ir(_mesa_get_log_file(), shader->ir, NULL); + _mesa_log("\n\n"); + } + + prog->Instructions = NULL; + prog->NumInstructions = 0; + + do_set_program_inouts(shader->ir, prog, shader->Stage); + + prog->SamplersUsed = shader->active_samplers; + prog->ShadowSamplers = shader->shadow_samplers; + _mesa_update_shader_textures_used(shader_program, prog); + + _mesa_reference_program(ctx, &shader->Program, prog); + + nir = glsl_to_nir(shader_program, shader->Stage, &nir_options); + prog->nir = nir; + + nir_validate_shader(nir); + + if (shader->Stage == MESA_SHADER_GEOMETRY) { + nir_lower_gs_intrinsics(nir); + nir_validate_shader(nir); + } + + nir_print_shader(nir, _mesa_get_log_file()); + + nir_lower_global_vars_to_local(nir); + nir_validate_shader(nir); + + nir_lower_var_copies(nir); + nir_validate_shader(nir); + + nir_assign_var_locations(&nir->inputs, + &nir->num_inputs, + type_size_vec4); + nir_assign_var_locations(&nir->outputs, + &nir->num_outputs, + type_size_vec4); + nir_assign_var_locations(&nir->uniforms, + &nir->num_uniforms, + type_size_vec4); + + nir_lower_io(nir, nir_var_all, type_size_vec4); + nir_validate_shader(nir); + + + // XXX do we need anything else from brw_create_nir().. and what + // is best way to split up which things should be here vs driver? + // currently just trying to make the result here similar to what + // we get from tgsi_to_nir().. so lower_io, etc.. + + // XXX new flag, probably? + if (ctx->_Shader->Flags & GLSL_DUMP) { + _mesa_log("\n"); + _mesa_log("NIR IR for linked %s program %d:\n", + _mesa_shader_stage_to_string(shader->Stage), + shader_program->Name); + nir_print_shader(nir, _mesa_get_log_file()); + _mesa_log("\n\n"); + } + + /* This has to be done last. Any operation the can cause + * prog->ParameterValues to get reallocated (e.g., anything that adds a + * program constant) has to happen before creating this linkage. + */ + _mesa_associate_uniform_storage(ctx, shader_program, prog->Parameters); + + return prog; +} + +static struct gl_program * +get_mesa_program(struct gl_context *ctx, + struct gl_shader_program *shader_program, + struct gl_shader *shader) +{ + struct pipe_screen *pscreen = ctx->st->pipe->screen; + unsigned ptarget = st_shader_stage_to_ptarget(shader->Stage); + enum pipe_shader_ir preferred_ir = (enum pipe_shader_ir) + pscreen->get_shader_param(pscreen, ptarget, PIPE_SHADER_CAP_PREFERRED_IR); + /* TODO: only do this for VERTEX stage for now: */ + if ((preferred_ir == PIPE_SHADER_IR_NIR) && + (shader->Type == GL_VERTEX_SHADER)) { + return get_mesa_program_nir(ctx, shader_program, shader); + } else { + return get_mesa_program_tgsi(ctx, shader_program, shader); + } +} + + extern "C" { static void
src/mesa/state_tracker/st_program.c +40 -3
70 lines not on this page · raw message
Signature · 6 lines
2.5.0 _______________________________________________ dri-devel mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/dri-devel
RFC 5/8 freedreno/ir3: drop tokens arg
In reply to Rob ClarkWe can get the tokens from variant->shader so drop the extra arg. This will make things easier to support either getting TGSI or NIR as input.
--- src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-)
src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c +6 -8
@@ -126,8 +126,8 @@ struct ir3_compile {static struct ir3_instruction *create_immed (struct ir3_block *block,uint32_t val);static struct ir3_block *get_block (struct ir3_compile *ctx,nir_block *nblock); -static struct nir_shader *to_nir (struct ir3_compile *ctx, -const struct tgsi_token *tokens,struct ir3_shader_variant *so) +static struct nir_shader * +to_nir (struct ir3_compile *ctx,struct ir3_shader_variant *so) {static const nir_shader_compiler_options options = { .lower_fpow = true,
@@ -164,7 +164,7 @@ static struct nir_shader *to_nir(struct ir3_compile *ctx, tex_options.lower_txp = (1 <<GLSL_SAMPLER_DIM_3D ); } -struct nir_shader *s =tgsi_to_nir (tokens, &options); +struct nir_shader *s =tgsi_to_nir (so->shader->tokens, &options);if (fd_mesa_debug &FD_DBG_OPTMSGS ) {debug_printf ("----------------------\n" );
@@ -214,9 +214,7 @@ static struct nir_shader *to_nir(struct ir3_compile *ctx, }static struct ir3_compile * -compile_init (struct ir3_compiler *compiler, -struct ir3_shader_variant *so, -const struct tgsi_token *tokens) +compile_init (struct ir3_compiler *compiler,struct ir3_shader_variant *so) { struct ir3_compile *ctx = rzalloc(NULL, struct ir3_compile);
@@ -245,7 +243,7 @@ compile_init(struct ir3_compiler *compiler, ctx->block_ht =_mesa_hash_table_create (ctx, _mesa_hash_pointer, _mesa_key_pointer_equal); - ctx->s =to_nir (ctx, tokens, so); + ctx->s =to_nir (ctx, so); so->first_driver_param = so->first_immediate = ctx->s->num_uniforms;
@@ -2432,7 +2430,7 @@ ir3_compile_shader_nir(struct ir3_compiler *compiler,assert (!so->ir); - ctx =compile_init (compiler, so, so->shader->tokens); + ctx =compile_init (compiler, so);if (!ctx) {DBG ("INIT failed!" ); ret =-1 ;
Signature · 6 lines
2.5.0 _______________________________________________ dri-devel mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/dri-devel
RFC 6/8 freedreno/ir3: add support for NIR as preferred IR
In reply to Rob ClarkFor now under debug flag, since only suitable for debugging/testing.
--- src/gallium/drivers/freedreno/freedreno_screen.c | 5 +++- src/gallium/drivers/freedreno/freedreno_util.h | 1 + .../drivers/freedreno/ir3/ir3_compiler_nir.c | 15 ++++++++++- src/gallium/drivers/freedreno/ir3/ir3_shader.c | 30 +++++++++++++++++++--- src/gallium/drivers/freedreno/ir3/ir3_shader.h | 3 +++ 5 files changed, 48 insertions(+), 6 deletions(-)
src/gallium/drivers/freedreno/freedreno_screen.c +4 -1
@@ -71,6 +71,7 @@ static const struct debug_named_value debug_options[] = { {"glsl120", FD_DBG_GLSL120,"Temporary flag to force GLSL 1.20 (rather than 1.30) on a3xx+"}, {"shaderdb", FD_DBG_SHADERDB, "Enable shaderdb output"}, {"flush", FD_DBG_FLUSH, "Force flush after every draw"}, + {"nir", FD_DBG_NIR, "Prefer NIR as native IR"},DEBUG_NAMED_VALUE_END };
@@ -398,7 +399,7 @@ fd_screen_get_shader_param(struct pipe_screen *pscreen, unsigned shader,case PIPE_SHADER_CAP_TGSI_DROUND_SUPPORTED :case PIPE_SHADER_CAP_TGSI_DFRACEXP_DLDEXP_SUPPORTED :case PIPE_SHADER_CAP_TGSI_FMA_SUPPORTED : -case PIPE_SHADER_CAP_TGSI_ANY_INOUT_DECL_RANGE : +case PIPE_SHADER_CAP_TGSI_ANY_INOUT_DECL_RANGE :return 0 ;case PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED :return 1 ;
@@ -410,6 +411,8 @@ fd_screen_get_shader_param(struct pipe_screen *pscreen, unsigned shader,case PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS :return 16 ;case PIPE_SHADER_CAP_PREFERRED_IR : +if ((fd_mesa_debug &FD_DBG_NIR ) &&is_ir3 (screen)) +return PIPE_SHADER_IR_NIR ;return PIPE_SHADER_IR_TGSI ; }debug_printf ("unknown shader param %d\n" , param);
src/gallium/drivers/freedreno/freedreno_util.h +1 -0
@@ -73,6 +73,7 @@ enum adreno_stencil_op fd_stencil_op(unsigned op);#define FD_DBG_GLSL120 0x0400#define FD_DBG_SHADERDB 0x0800#define FD_DBG_FLUSH 0x1000 +#define FD_DBG_NIR 0x2000extern int fd_mesa_debug;extern bool fd_binning_enabled;
src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c +14 -1
@@ -164,7 +164,14 @@ to_nir(struct ir3_compile *ctx, struct ir3_shader_variant *so) tex_options.lower_txp = (1 <<GLSL_SAMPLER_DIM_3D ); } -struct nir_shader *s =tgsi_to_nir (so->shader->tokens, &options); +struct nir_shader *s; + +if (so->shader->nir) { +// XXX need nir_clone() here.. + s = so->shader->nir; + }else { + s =tgsi_to_nir (so->shader->tokens, &options); + }if (fd_mesa_debug &FD_DBG_OPTMSGS ) {debug_printf ("----------------------\n" );
@@ -292,6 +299,12 @@ compile_error(struct ir3_compile *ctx, const char *format, ...)static void compile_free (struct ir3_compile *ctx) { +/* TODO .. probably need a ralloc_free(ctx->s) here, at least +* for the tgsi_to_nir case.. right now in the case we get +* NIR directly, we want to skip this since the nir_shader isn't +* getting cloned.. and/or if it was we might be wanting to +* free it in ir3_shader_destroy()?? +*/ ralloc_free (ctx); }
src/gallium/drivers/freedreno/ir3/ir3_shader.c +26 -4
@@ -39,6 +39,7 @@#include "ir3_shader.h" #include "ir3_compiler.h" +#include "ir3_nir.h" static void
@@ -188,9 +189,15 @@ create_variant(struct ir3_shader *shader, struct ir3_shader_key key) v->type = shader->type;if (fd_mesa_debug &FD_DBG_DISASM ) { -DBG ("dump tgsi: type=%d, k={bp=%u,cts=%u,hp=%u}" , shader->type, - key.binning_pass, key.color_two_side, key.half_precision); -tgsi_dump (shader->tokens,0 ); +if (shader->nir) { +DBG ("dump nir: type=%d, k={bp=%u,cts=%u,hp=%u}" , shader->type, + key.binning_pass, key.color_two_side, key.half_precision); +nir_print_shader (shader->nir, stderr); + }else { +DBG ("dump tgsi: type=%d, k={bp=%u,cts=%u,hp=%u}" , shader->type, + key.binning_pass, key.color_two_side, key.half_precision); +tgsi_dump (shader->tokens,0 ); + } } ret =ir3_compile_shader_nir (shader->compiler, v);
@@ -267,7 +274,9 @@ ir3_shader_destroy(struct ir3_shader *shader) v = v->next;delete_variant (t); } +free ((void *)shader->tokens); +/* XXX ralloc_free(shader->nir); */ free (shader); }
@@ -281,7 +290,20 @@ ir3_shader_create(struct pipe_context *pctx, shader->id = ++shader->compiler->shader_count; shader->pctx = pctx; shader->type = type; - shader->tokens =tgsi_dup_tokens (cso->tokens); +if (cso->ir ==PIPE_SHADER_IR_NIR ) { +/* TODO might need nir_clone() here.. Depends a bit on how we +* define the lifecycle of cso->nir. If we could assume that it +* always sticks around until the cso is destroyed, then we'd +* only need to clone in to_nir() (for the variant specific +* lowering), rather than both here and to_nir(). This is a bit +* different from the lifetime of cso->tokens which sometimes +* but not always goes away after the pipe->pipe_create_xyz_state() +* call (which is unfortunate, and maybe worth fixing). +*/ + shader->nir = cso->nir; + }else { + shader->tokens =tgsi_dup_tokens (cso->tokens); + } shader->stream_output = cso->stream_output;if (fd_mesa_debug &FD_DBG_SHADERDB ) {/* if shader-db run, create a standard variant immediately
src/gallium/drivers/freedreno/ir3/ir3_shader.h +3 -0
@@ -220,6 +220,8 @@ struct ir3_shader_variant {struct ir3_shader *shader; }; +typedef struct nir_shader nir_shader ; +struct ir3_shader {enum shader_t type;
@@ -230,6 +232,7 @@ struct ir3_shader {struct ir3_compiler *compiler;struct pipe_context *pctx; +nir_shader *nir;const struct tgsi_token *tokens;struct pipe_stream_output_info stream_output;
Signature · 6 lines
2.5.0 _______________________________________________ dri-devel mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/dri-devel
RFC 7/8 freedreno/ir3: fix const_index handling for uniforms
In reply to Rob ClarkWhen coming directly from glsl_to_nir (rather than via TGSI where information about, for example, mat4's is lost), both const_index fields will be used (vs. tgsi_to_nir where the 2nd is always zero).
For example:
decl_var uniform INTERP_QUALIFIER_NONE mat4 ModelViewProjectionMatrix (0, 0) decl_var uniform INTERP_QUALIFIER_NONE mat4 NormalMatrix (4, 4)
...
vec4 ssa_54 = intrinsic load_uniform () () (4, 0) /* NormalMatrix */ vec4 ssa_56 = intrinsic load_uniform () () (4, 1) /* NormalMatrix */
vs:
decl_var uniform INTERP_QUALIFIER_NONE vec4[8] uniform_0 (0, 0)
...
vec4 ssa_54 = intrinsic load_uniform () () (4, 0) vec4 ssa_56 = intrinsic load_uniform () () (5, 0) --- src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c +4 -1
@@ -1377,7 +1377,10 @@ emit_intrinisic(struct ir3_compile *ctx, nir_intrinsic_instr *intr)const nir_intrinsic_info *info = &nir_intrinsic_infos[intr->intrinsic];struct ir3_instruction **dst, **src;struct ir3_block *b = ctx->block; -unsigned idx = intr->const_index[0 ]; +unsigned idx =0 ; + +for (unsigned i =0 ; i < nir_intrinsic_infos[intr->intrinsic].num_indices; i++) + idx += intr->const_index[i];if (info->has_dest) { dst =get_dst (ctx, &intr->dest, intr->num_components);
Signature · 6 lines
2.5.0 _______________________________________________ dri-devel mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/dri-devel
RFC 8/8 freedreno/ir3: hack for mismatch on varying slots for glsl->tgsi->nir vs glsl->nir
In reply to Rob ClarkComplete hack just for debugging. It isn't intended that mixing and matching glsl->tgsi->nir vs glsl->nir between shader stages should actually work.
--- src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c | 6 ++++++ 1 file changed, 6 insertions(+)
src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c +6 -0
@@ -2232,6 +2232,12 @@ setup_output(struct ir3_compile *ctx, nir_variable *out)unsigned slot = out->data.location;unsigned comp =0 ; +// XXX temporary hack for NIR vs and TGSI fs.. since there is +// some disagreement about varying slots.. +if (ctx->so->shader->nir) +if (slot >=VARYING_SLOT_VAR0 ) + slot +=9 ; +DBG ("; out: slot=%u, len=%ux%u, drvloc=%u" , slot, array_len, ncomp, n);
Signature · 6 lines
2.5.0 _______________________________________________ dri-devel mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/dri-devel
Quoted 5 lines · Rob Clark
Also, there is some trivial shader variant handling in mesa st which would have to be ported to NIR. Or, perhaps, just somehow expose the shader key to the driver. (Currently most drivers are doing much more variant handling within the driver, and having two levels of variants does seem a bit silly.)
With Marek's latest series, the are no more variants in st/mesa (well, except for glDrawPixels/glBitmap-related shaders) provided that your driver exposes the right caps.
-ilia
_______________________________________________
dri-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/dri-devel