From: Kenneth Graunke Date: Wed, 18 Jul 2018 23:42:03 +0000 (-0700) Subject: i965: Combine both gl_PatchVerticesIn lowering passes. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=488972222c6454551ab1559f753c13a493dc513f;p=mesa.git i965: Combine both gl_PatchVerticesIn lowering passes. Until now, we had separate passes for lowering gl_PatchVerticesIn to a statically known constant (for TES inputs when linked against a TCS), and a uniform in the other cases. Annoyingly, one had to be run before nir_lower_system_values, and the other afterward. This simplified the passes, but made life painful for the callers. This patch combines both into a single pass. If you give it a non-zero static count, it uses that. If you give it Mesa state slots, it turns it back into a built-in uniform. Otherwise, it does nothing. This also moves the i965 uniform lowering out to shared code. v2: Make token arrays const. Reviewed-by: Eric Anholt --- diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h index 4213d6208cb..2ca92e8f34e 100644 --- a/src/compiler/nir/nir.h +++ b/src/compiler/nir/nir.h @@ -2809,7 +2809,8 @@ void nir_lower_two_sided_color(nir_shader *shader); bool nir_lower_clamp_color_outputs(nir_shader *shader); void nir_lower_passthrough_edgeflags(nir_shader *shader); -void nir_lower_tes_patch_vertices(nir_shader *tes, unsigned patch_vertices); +bool nir_lower_patch_vertices(nir_shader *nir, unsigned static_count, + const gl_state_index16 *uniform_state_tokens); typedef struct nir_lower_wpos_ytransform_options { gl_state_index16 state_tokens[STATE_LENGTH]; diff --git a/src/compiler/nir/nir_lower_patch_vertices.c b/src/compiler/nir/nir_lower_patch_vertices.c index d196576b993..8e89268ca41 100644 --- a/src/compiler/nir/nir_lower_patch_vertices.c +++ b/src/compiler/nir/nir_lower_patch_vertices.c @@ -22,11 +22,52 @@ */ #include "nir_builder.h" +#include "program/prog_instruction.h" -void -nir_lower_tes_patch_vertices(nir_shader *tes_nir, unsigned patch_vertices) +static nir_variable * +make_uniform(nir_shader *nir, const gl_state_index16 *tokens) { - nir_foreach_function(function, tes_nir) { + /* Note: name must be prefixed with "gl_" to trigger slot based + * special handling in uniform setup. + */ + nir_variable *var = + nir_variable_create(nir, nir_var_uniform, glsl_int_type(), + "gl_PatchVerticesIn"); + var->num_state_slots = 1; + var->state_slots = ralloc_array(var, nir_state_slot, var->num_state_slots); + memcpy(var->state_slots[0].tokens, tokens, sizeof(*tokens) * STATE_LENGTH); + var->state_slots[0].swizzle = SWIZZLE_XXXX; + + return var; +} + +/** + * This pass lowers the load_patch_vertices_in intrinsic. + * + * - If we statically know the value, we lower it to a constant. + * (If a TES is linked against a TCS, the TCS tells us the TES input count.) + * + * - If not, and we're given Mesa state slots, we lower it to a uniform. + * + * - Otherwise, we leave it as a system value. + * + * This pass must be run after nir_lower_system_values(). + */ +bool +nir_lower_patch_vertices(nir_shader *nir, + unsigned static_count, + const gl_state_index16 *uniform_state_tokens) +{ + bool progress = false; + nir_variable *var = NULL; + + /* If there's no static count and we don't want uniforms, there's no + * lowering to do...just bail early. + */ + if (static_count == 0 && !uniform_state_tokens) + return false; + + nir_foreach_function(function, nir) { if (function->impl) { nir_foreach_block(block, function->impl) { nir_builder b; @@ -38,7 +79,18 @@ nir_lower_tes_patch_vertices(nir_shader *tes_nir, unsigned patch_vertices) continue; b.cursor = nir_before_instr(&intr->instr); - nir_ssa_def *val = nir_imm_int(&b, patch_vertices); + + nir_ssa_def *val = NULL; + if (static_count) { + val = nir_imm_int(&b, static_count); + } else { + if (!var) + var = make_uniform(nir, uniform_state_tokens); + + val = nir_load_var(&b, var); + } + + progress = true; nir_ssa_def_rewrite_uses(&intr->dest.ssa, nir_src_for_ssa(val)); nir_instr_remove(instr); @@ -46,8 +98,12 @@ nir_lower_tes_patch_vertices(nir_shader *tes_nir, unsigned patch_vertices) } } - nir_metadata_preserve(function->impl, nir_metadata_block_index | - nir_metadata_dominance); + if (progress) { + nir_metadata_preserve(function->impl, nir_metadata_block_index | + nir_metadata_dominance); + } } } + + return progress; } diff --git a/src/intel/compiler/brw_nir.h b/src/intel/compiler/brw_nir.h index 7d82edafe46..00b61731526 100644 --- a/src/intel/compiler/brw_nir.h +++ b/src/intel/compiler/brw_nir.h @@ -144,8 +144,6 @@ void brw_nir_setup_arb_uniforms(void *mem_ctx, nir_shader *shader, struct gl_program *prog, struct brw_stage_prog_data *stage_prog_data); -void brw_nir_lower_patch_vertices_in_to_uniform(nir_shader *nir); - void brw_nir_analyze_ubo_ranges(const struct brw_compiler *compiler, nir_shader *nir, const struct brw_vs_prog_key *vs_key, diff --git a/src/intel/vulkan/anv_pipeline.c b/src/intel/vulkan/anv_pipeline.c index 9972db88f04..fa3d3e7a309 100644 --- a/src/intel/vulkan/anv_pipeline.c +++ b/src/intel/vulkan/anv_pipeline.c @@ -684,8 +684,8 @@ anv_pipeline_compile_tcs_tes(struct anv_pipeline *pipeline, return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY); } - nir_lower_tes_patch_vertices(tes_nir, - tcs_nir->info.tess.tcs_vertices_out); + nir_lower_patch_vertices(tes_nir, tcs_nir->info.tess.tcs_vertices_out, + NULL); /* Copy TCS info into the TES info */ merge_tess_info(&tes_nir->info, &tcs_nir->info); diff --git a/src/mesa/drivers/dri/i965/brw_nir_uniforms.cpp b/src/mesa/drivers/dri/i965/brw_nir_uniforms.cpp index 28a60691926..54f9f9b1a6b 100644 --- a/src/mesa/drivers/dri/i965/brw_nir_uniforms.cpp +++ b/src/mesa/drivers/dri/i965/brw_nir_uniforms.cpp @@ -267,31 +267,3 @@ brw_nir_setup_arb_uniforms(void *mem_ctx, nir_shader *shader, stage_prog_data->param[4 * p + i] = BRW_PARAM_BUILTIN_ZERO; } } - -void -brw_nir_lower_patch_vertices_in_to_uniform(nir_shader *nir) -{ - nir_foreach_variable_safe(var, &nir->system_values) { - if (var->data.location != SYSTEM_VALUE_VERTICES_IN) - continue; - - gl_state_index16 tokens[STATE_LENGTH] = { - STATE_INTERNAL, - nir->info.stage == MESA_SHADER_TESS_CTRL ? - (gl_state_index16)STATE_TCS_PATCH_VERTICES_IN : - (gl_state_index16)STATE_TES_PATCH_VERTICES_IN, - }; - var->num_state_slots = 1; - var->state_slots = - ralloc_array(var, nir_state_slot, var->num_state_slots); - memcpy(var->state_slots[0].tokens, tokens, sizeof(tokens)); - var->state_slots[0].swizzle = SWIZZLE_XXXX; - - var->data.mode = nir_var_uniform; - var->data.location = -1; - exec_node_remove(&var->node); - exec_list_push_tail(&nir->uniforms, &var->node); - } - - nir_fixup_deref_modes(nir); -} diff --git a/src/mesa/drivers/dri/i965/brw_program.c b/src/mesa/drivers/dri/i965/brw_program.c index 9fa1b4b9bb7..7adb75d0eaa 100644 --- a/src/mesa/drivers/dri/i965/brw_program.c +++ b/src/mesa/drivers/dri/i965/brw_program.c @@ -74,6 +74,7 @@ brw_create_nir(struct brw_context *brw, gl_shader_stage stage, bool is_scalar) { + const struct gen_device_info *devinfo = &brw->screen->devinfo; struct gl_context *ctx = &brw->ctx; const nir_shader_compiler_options *options = ctx->Const.ShaderCompilerOptions[stage].NirOptions; @@ -99,32 +100,26 @@ brw_create_nir(struct brw_context *brw, } nir_validate_shader(nir); - /* Lower PatchVerticesIn from system value to uniform. This needs to - * happen before brw_preprocess_nir, since that will lower system values - * to intrinsics. - * - * We only do this for TES if no TCS is present, since otherwise we know - * the number of vertices in the patch at link time and we can lower it - * directly to a constant. We do this in nir_lower_patch_vertices, which - * needs to run after brw_nir_preprocess has turned the system values - * into intrinsics. - */ - const bool lower_patch_vertices_in_to_uniform = - (stage == MESA_SHADER_TESS_CTRL && brw->screen->devinfo.gen >= 8) || - (stage == MESA_SHADER_TESS_EVAL && - !shader_prog->_LinkedShaders[MESA_SHADER_TESS_CTRL]); - - if (lower_patch_vertices_in_to_uniform) - brw_nir_lower_patch_vertices_in_to_uniform(nir); - nir = brw_preprocess_nir(brw->screen->compiler, nir); - if (stage == MESA_SHADER_TESS_EVAL && !lower_patch_vertices_in_to_uniform) { - assert(shader_prog->_LinkedShaders[MESA_SHADER_TESS_CTRL]); - struct gl_linked_shader *linked_tcs = + if (stage == MESA_SHADER_TESS_CTRL) { + /* Lower gl_PatchVerticesIn from a sys. value to a uniform on Gen8+. */ + static const gl_state_index16 tokens[STATE_LENGTH] = + { STATE_INTERNAL, STATE_TCS_PATCH_VERTICES_IN }; + nir_lower_patch_vertices(nir, 0, devinfo->gen >= 8 ? tokens : NULL); + } + + if (stage == MESA_SHADER_TESS_EVAL) { + /* Lower gl_PatchVerticesIn to a constant if we have a TCS, or + * a uniform if we don't. + */ + struct gl_linked_shader *tcs = shader_prog->_LinkedShaders[MESA_SHADER_TESS_CTRL]; - uint32_t patch_vertices = linked_tcs->Program->info.tess.tcs_vertices_out; - nir_lower_tes_patch_vertices(nir, patch_vertices); + uint32_t static_patch_vertices = + tcs ? tcs->Program->info.tess.tcs_vertices_out : 0; + static const gl_state_index16 tokens[STATE_LENGTH] = + { STATE_INTERNAL, STATE_TES_PATCH_VERTICES_IN }; + nir_lower_patch_vertices(nir, static_patch_vertices, tokens); } if (stage == MESA_SHADER_FRAGMENT) {