X-Git-Url: https://git.libre-soc.org/?p=mesa.git;a=blobdiff_plain;f=src%2Fmesa%2Fstate_tracker%2Fst_glsl_to_nir.cpp;h=442f1ffeeb8eecca77c2cfe96bdea8806eb89cf7;hp=35464c982a6b0835f077b43c3a8b0d2159cd4c34;hb=2519472845a7eccd9ff2bfc8a3061ec2ae00de06;hpb=d0975bfc4ab766a6a0fd65d3f54a608fa5622f59 diff --git a/src/mesa/state_tracker/st_glsl_to_nir.cpp b/src/mesa/state_tracker/st_glsl_to_nir.cpp index 35464c982a6..442f1ffeeb8 100644 --- a/src/mesa/state_tracker/st_glsl_to_nir.cpp +++ b/src/mesa/state_tracker/st_glsl_to_nir.cpp @@ -63,14 +63,17 @@ type_size(const struct glsl_type *type) * with the anything->tgsi->nir path. */ static void -st_nir_fixup_varying_slots(struct st_context *st, struct exec_list *var_list) +st_nir_fixup_varying_slots(struct st_context *st, nir_shader *shader, + nir_variable_mode mode) { if (st->needs_texcoord_semantic) return; - nir_foreach_variable(var, var_list) { + nir_foreach_variable_with_modes(var, shader, mode) { if (var->data.location >= VARYING_SLOT_VAR0) { var->data.location += 9; + } else if (var->data.location == VARYING_SLOT_PNTC) { + var->data.location = VARYING_SLOT_VAR8; } else if ((var->data.location >= VARYING_SLOT_TEX0) && (var->data.location <= VARYING_SLOT_TEX7)) { var->data.location += VARYING_SLOT_VAR0 - VARYING_SLOT_TEX0; @@ -78,6 +81,19 @@ st_nir_fixup_varying_slots(struct st_context *st, struct exec_list *var_list) } } +static void +st_shader_gather_info(nir_shader *nir, struct gl_program *prog) +{ + nir_shader_gather_info(nir, nir_shader_get_entrypoint(nir)); + + /* Copy the info we just generated back into the gl_program */ + const char *prog_name = prog->info.name; + const char *prog_label = prog->info.label; + prog->info = nir->info; + prog->info.name = prog_name; + prog->info.label = prog_label; +} + /* input location assignment for VS inputs must be handled specially, so * that it is aligned w/ st's vbo state. * (This isn't the case with, for ex, FS inputs, which only need to agree @@ -89,10 +105,37 @@ st_nir_assign_vs_in_locations(struct nir_shader *nir) if (nir->info.stage != MESA_SHADER_VERTEX) return; + nir->num_inputs = util_bitcount64(nir->info.inputs_read); + + if (nir->info.io_lowered) { + /* Adjust the locations in load_input intrinsics. */ + nir_foreach_function(f, nir) { + if (f->impl) { + nir_foreach_block(block, f->impl) { + nir_foreach_instr_safe(instr, block) { + if (instr->type == nir_instr_type_intrinsic) { + nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr); + + if (intrin->intrinsic == nir_intrinsic_load_input) { + unsigned base = nir_intrinsic_base(intrin); + unsigned loc = nir_intrinsic_io_semantics(intrin).location; + + assert(nir->info.inputs_read & BITFIELD64_BIT(loc)); + base = util_bitcount64(nir->info.inputs_read & + BITFIELD64_MASK(loc)); + nir_intrinsic_set_base(intrin, base); + } + } + } + } + } + } + return; + } + bool removed_inputs = false; - nir->num_inputs = util_bitcount64(nir->info.inputs_read); - nir_foreach_variable_safe(var, &nir->inputs) { + nir_foreach_shader_in_variable_safe(var, nir) { /* NIR already assigns dual-slot inputs to two locations so all we have * to do is compact everything down. */ @@ -101,14 +144,12 @@ st_nir_assign_vs_in_locations(struct nir_shader *nir) util_bitcount64(nir->info.inputs_read & BITFIELD64_MASK(var->data.location)); } else { - /* Move unused input variables to the globals list (with no + /* Convert unused input variables to shader_temp (with no * initialization), to avoid confusing drivers looking through the * inputs array and expecting to find inputs with a driver_location * set. */ - exec_node_remove(&var->node); var->data.mode = nir_var_shader_temp; - exec_list_push_tail(&nir->globals, &var->node); removed_inputs = true; } } @@ -180,21 +221,14 @@ st_nir_lookup_parameter_index(struct gl_program *prog, nir_variable *var) static void st_nir_assign_uniform_locations(struct gl_context *ctx, struct gl_program *prog, - struct exec_list *uniform_list) + nir_shader *nir) { int shaderidx = 0; int imageidx = 0; - nir_foreach_variable(uniform, uniform_list) { + nir_foreach_uniform_variable(uniform, nir) { int loc; - /* - * UBO's have their own address spaces, so don't count them towards the - * number of global uniforms - */ - if (uniform->data.mode == nir_var_mem_ubo || uniform->data.mode == nir_var_mem_ssbo) - continue; - const struct glsl_type *type = glsl_without_array(uniform->type); if (!uniform->data.bindless && (type->is_sampler() || type->is_image())) { if (type->is_sampler()) { @@ -258,7 +292,8 @@ st_nir_opts(nir_shader *nir) NIR_PASS(progress, nir, nir_remove_dead_variables, (nir_variable_mode)(nir_var_function_temp | nir_var_shader_temp | - nir_var_mem_shared)); + nir_var_mem_shared), + NULL); NIR_PASS(progress, nir, nir_opt_copy_prop_vars); NIR_PASS(progress, nir, nir_opt_dead_write_vars); @@ -376,7 +411,7 @@ st_nir_preprocess(struct st_context *st, struct gl_program *prog, if (!_mesa_is_gles(st->ctx) || !nir->info.separate_shader) { nir_variable_mode mask = (nir_variable_mode) (nir_var_shader_in | nir_var_shader_out); - nir_remove_dead_variables(nir, mask); + nir_remove_dead_variables(nir, mask, NULL); } if (options->lower_all_io_to_temps || @@ -401,7 +436,7 @@ st_nir_preprocess(struct st_context *st, struct gl_program *prog, } /* before buffers and vars_to_ssa */ - NIR_PASS_V(nir, gl_nir_lower_bindless_images); + NIR_PASS_V(nir, gl_nir_lower_images, true); /* TODO: Change GLSL to not lower shared memory. */ if (prog->nir->info.stage == MESA_SHADER_COMPUTE && @@ -424,6 +459,7 @@ st_glsl_to_nir_post_opts(struct st_context *st, struct gl_program *prog, struct gl_shader_program *shader_program) { nir_shader *nir = prog->nir; + struct pipe_screen *screen = st->pipe->screen; /* 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). @@ -432,17 +468,14 @@ st_glsl_to_nir_post_opts(struct st_context *st, struct gl_program *prog, * too late. At that point, the values for the built-in uniforms won't * get sent to the shader. */ - nir_foreach_variable(var, &nir->uniforms) { + nir_foreach_uniform_variable(var, nir) { const nir_state_slot *const slots = var->state_slots; if (slots != NULL) { const struct glsl_type *type = glsl_without_array(var->type); for (unsigned int i = 0; i < var->num_state_slots; i++) { unsigned comps; if (glsl_type_is_struct_or_ifc(type)) { - /* Builtin struct require specical handling for now we just - * make all members vec4. See st_nir_lower_builtin. - */ - comps = 4; + comps = _mesa_program_state_value_size(slots[i].tokens); } else { comps = glsl_get_vector_elements(type); } @@ -474,12 +507,16 @@ st_glsl_to_nir_post_opts(struct st_context *st, struct gl_program *prog, st_set_prog_affected_state_flags(prog); /* None of the builtins being lowered here can be produced by SPIR-V. See - * _mesa_builtin_uniform_desc. + * _mesa_builtin_uniform_desc. Also drivers that support packed uniform + * storage don't need to lower builtins. */ - if (!shader_program->data->spirv) + if (!shader_program->data->spirv && + !st->ctx->Const.PackedDriverUniformStorage) NIR_PASS_V(nir, st_nir_lower_builtin); - NIR_PASS_V(nir, gl_nir_lower_atomics, shader_program, true); + if (!screen->get_param(screen, PIPE_CAP_NIR_ATOMICS_AS_DEREF)) + NIR_PASS_V(nir, gl_nir_lower_atomics, shader_program, true); + NIR_PASS_V(nir, nir_opt_intrinsics); /* Lower 64-bit ops. */ @@ -490,10 +527,8 @@ st_glsl_to_nir_post_opts(struct st_context *st, struct gl_program *prog, NIR_PASS(lowered_64bit_ops, nir, nir_lower_doubles, st->ctx->SoftFP64, nir->options->lower_doubles_options); } - if (nir->options->lower_int64_options) { - NIR_PASS(lowered_64bit_ops, nir, nir_lower_int64, - nir->options->lower_int64_options); - } + if (nir->options->lower_int64_options) + NIR_PASS(lowered_64bit_ops, nir, nir_lower_int64); if (lowered_64bit_ops) st_nir_opts(nir); @@ -501,9 +536,9 @@ st_glsl_to_nir_post_opts(struct st_context *st, struct gl_program *prog, nir_variable_mode mask = (nir_variable_mode) (nir_var_shader_in | nir_var_shader_out | nir_var_function_temp ); - nir_remove_dead_variables(nir, mask); + nir_remove_dead_variables(nir, mask, NULL); - if (!st->has_hw_atomics) + if (!st->has_hw_atomics && !screen->get_param(screen, PIPE_CAP_NIR_ATOMICS_AS_DEREF)) NIR_PASS_V(nir, nir_lower_atomics_to_ssbo); st_finalize_nir_before_variants(nir); @@ -559,8 +594,8 @@ st_nir_link_shaders(nir_shader *producer, nir_shader *consumer) if (nir_link_opt_varyings(producer, consumer)) st_nir_opts(consumer); - NIR_PASS_V(producer, nir_remove_dead_variables, nir_var_shader_out); - NIR_PASS_V(consumer, nir_remove_dead_variables, nir_var_shader_in); + NIR_PASS_V(producer, nir_remove_dead_variables, nir_var_shader_out, NULL); + NIR_PASS_V(consumer, nir_remove_dead_variables, nir_var_shader_in, NULL); if (nir_remove_unused_varyings(producer, consumer)) { NIR_PASS_V(producer, nir_lower_global_vars_to_local); @@ -573,8 +608,10 @@ st_nir_link_shaders(nir_shader *producer, nir_shader *consumer) * nir_compact_varyings() depends on all dead varyings being removed so * we need to call nir_remove_dead_variables() again here. */ - NIR_PASS_V(producer, nir_remove_dead_variables, nir_var_shader_out); - NIR_PASS_V(consumer, nir_remove_dead_variables, nir_var_shader_in); + NIR_PASS_V(producer, nir_remove_dead_variables, nir_var_shader_out, + NULL); + NIR_PASS_V(consumer, nir_remove_dead_variables, nir_var_shader_in, + NULL); } } @@ -661,18 +698,14 @@ st_link_nir(struct gl_context *ctx, stp->shader_program = shader_program; stp->state.type = PIPE_SHADER_IR_NIR; - if (shader_program->data->spirv) { - prog->Parameters = _mesa_new_parameter_list(); - /* Parameters will be filled during NIR linking. */ + /* Parameters will be filled during NIR linking. */ + prog->Parameters = _mesa_new_parameter_list(); + if (shader_program->data->spirv) { prog->nir = _mesa_spirv_to_nir(ctx, shader_program, shader->Stage, options); } else { validate_ir_tree(shader->ir); - prog->Parameters = _mesa_new_parameter_list(); - _mesa_generate_parameters_list_for_uniforms(ctx, shader_program, shader, - prog->Parameters); - if (ctx->_Shader->Flags & GLSL_DUMP) { _mesa_log("\n"); _mesa_log("GLSL IR for linked %s program %d:\n", @@ -682,9 +715,6 @@ st_link_nir(struct gl_context *ctx, _mesa_log("\n\n"); } - prog->ExternalSamplersUsed = gl_external_samplers(prog); - _mesa_update_shader_textures_used(shader_program, prog); - prog->nir = glsl_to_nir(st->ctx, shader_program, shader->Stage, options); st_nir_preprocess(st, prog, shader_program, shader->Stage); } @@ -738,6 +768,12 @@ st_link_nir(struct gl_context *ctx, if (!gl_nir_link_glsl(ctx, shader_program)) return GL_FALSE; + for (unsigned i = 0; i < num_shaders; i++) { + struct gl_program *prog = linked_shader[i]->Program; + prog->ExternalSamplersUsed = gl_external_samplers(prog); + _mesa_update_shader_textures_used(shader_program, prog); + } + nir_build_program_resource_list(ctx, shader_program, false); } @@ -762,10 +798,11 @@ st_link_nir(struct gl_context *ctx, st->pipe->screen); NIR_PASS_V(nir, nir_lower_system_values); + NIR_PASS_V(nir, nir_lower_compute_system_values, NULL); + NIR_PASS_V(nir, nir_lower_clip_cull_distance_arrays); - nir_shader_gather_info(nir, nir_shader_get_entrypoint(nir)); - shader->Program->info = nir->info; + st_shader_gather_info(nir, shader->Program); if (shader->Stage == MESA_SHADER_VERTEX) { /* NIR expands dual-slot inputs out to two locations. We need to * compact things back down GL-style single-slot inputs to avoid @@ -793,6 +830,25 @@ st_link_nir(struct gl_context *ctx, } } + struct shader_info *prev_info = NULL; + + for (unsigned i = 0; i < num_shaders; i++) { + struct gl_linked_shader *shader = linked_shader[i]; + struct shader_info *info = &shader->Program->nir->info; + + if (prev_info && + ctx->Const.ShaderCompilerOptions[shader->Stage].NirOptions->unify_interfaces) { + prev_info->outputs_written |= info->inputs_read & + ~(VARYING_BIT_TESS_LEVEL_INNER | VARYING_BIT_TESS_LEVEL_OUTER); + info->inputs_read |= prev_info->outputs_written & + ~(VARYING_BIT_TESS_LEVEL_INNER | VARYING_BIT_TESS_LEVEL_OUTER); + + prev_info->patch_outputs_written |= info->patch_inputs_read; + info->patch_inputs_read |= prev_info->patch_outputs_written; + } + prev_info = info; + } + for (unsigned i = 0; i < num_shaders; i++) { struct gl_linked_shader *shader = linked_shader[i]; struct gl_program *prog = shader->Program; @@ -819,28 +875,6 @@ st_link_nir(struct gl_context *ctx, shader->ir = NULL; } - struct shader_info *prev_info = NULL; - - for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { - struct gl_linked_shader *shader = shader_program->_LinkedShaders[i]; - if (!shader) - continue; - - struct shader_info *info = &shader->Program->nir->info; - - if (prev_info && - ctx->Const.ShaderCompilerOptions[i].NirOptions->unify_interfaces) { - prev_info->outputs_written |= info->inputs_read & - ~(VARYING_BIT_TESS_LEVEL_INNER | VARYING_BIT_TESS_LEVEL_OUTER); - info->inputs_read |= prev_info->outputs_written & - ~(VARYING_BIT_TESS_LEVEL_INNER | VARYING_BIT_TESS_LEVEL_OUTER); - - prev_info->patch_outputs_written |= info->patch_inputs_read; - info->patch_inputs_read |= prev_info->patch_outputs_written; - } - prev_info = info; - } - return true; } @@ -848,28 +882,28 @@ void st_nir_assign_varying_locations(struct st_context *st, nir_shader *nir) { if (nir->info.stage == MESA_SHADER_VERTEX) { - nir_assign_io_var_locations(&nir->outputs, + nir_assign_io_var_locations(nir, nir_var_shader_out, &nir->num_outputs, nir->info.stage); - st_nir_fixup_varying_slots(st, &nir->outputs); + st_nir_fixup_varying_slots(st, nir, nir_var_shader_out); } else if (nir->info.stage == MESA_SHADER_GEOMETRY || nir->info.stage == MESA_SHADER_TESS_CTRL || nir->info.stage == MESA_SHADER_TESS_EVAL) { - nir_assign_io_var_locations(&nir->inputs, + nir_assign_io_var_locations(nir, nir_var_shader_in, &nir->num_inputs, nir->info.stage); - st_nir_fixup_varying_slots(st, &nir->inputs); + st_nir_fixup_varying_slots(st, nir, nir_var_shader_in); - nir_assign_io_var_locations(&nir->outputs, + nir_assign_io_var_locations(nir, nir_var_shader_out, &nir->num_outputs, nir->info.stage); - st_nir_fixup_varying_slots(st, &nir->outputs); + st_nir_fixup_varying_slots(st, nir, nir_var_shader_out); } else if (nir->info.stage == MESA_SHADER_FRAGMENT) { - nir_assign_io_var_locations(&nir->inputs, + nir_assign_io_var_locations(nir, nir_var_shader_in, &nir->num_inputs, nir->info.stage); - st_nir_fixup_varying_slots(st, &nir->inputs); - nir_assign_io_var_locations(&nir->outputs, + st_nir_fixup_varying_slots(st, nir, nir_var_shader_in); + nir_assign_io_var_locations(nir, nir_var_shader_out, &nir->num_outputs, nir->info.stage); } else if (nir->info.stage == MESA_SHADER_COMPUTE) { @@ -892,6 +926,7 @@ st_nir_lower_samplers(struct pipe_screen *screen, nir_shader *nir, if (prog) { prog->info.textures_used = nir->info.textures_used; prog->info.textures_used_by_txf = nir->info.textures_used_by_txf; + prog->info.images_used = nir->info.images_used; } } @@ -936,14 +971,15 @@ st_finalize_nir(struct st_context *st, struct gl_program *prog, NIR_PASS_V(nir, nir_lower_var_copies); st_nir_assign_varying_locations(st, nir); - st_nir_assign_uniform_locations(st->ctx, prog, - &nir->uniforms); + st_nir_assign_uniform_locations(st->ctx, prog, nir); /* Set num_uniforms in number of attribute slots (vec4s) */ nir->num_uniforms = DIV_ROUND_UP(prog->Parameters->NumParameterValues, 4); st_nir_lower_uniforms(st, nir); st_nir_lower_samplers(screen, nir, shader_program, prog); + if (!screen->get_param(screen, PIPE_CAP_NIR_IMAGES_AS_DEREF)) + NIR_PASS_V(nir, gl_nir_lower_images, false); if (finalize_by_driver && screen->finalize_nir) screen->finalize_nir(screen, nir, false);