From cf5f8f55c3e25508fb975b263d6430a93442247a Mon Sep 17 00:00:00 2001 From: Timothy Arceri Date: Mon, 30 Oct 2017 15:11:10 +1100 Subject: [PATCH] nir: add tess patch support to nir_remove_unused_varyings() MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Reviewed-by: Nicolai Hähnle --- src/compiler/nir/nir_linking_helpers.c | 61 ++++++++++++++++++-------- 1 file changed, 42 insertions(+), 19 deletions(-) diff --git a/src/compiler/nir/nir_linking_helpers.c b/src/compiler/nir/nir_linking_helpers.c index 54ba1c85e58..4d709c1b3c5 100644 --- a/src/compiler/nir/nir_linking_helpers.c +++ b/src/compiler/nir/nir_linking_helpers.c @@ -37,10 +37,12 @@ static uint64_t get_variable_io_mask(nir_variable *var, gl_shader_stage stage) { - /* TODO: add support for tess patches */ - if (var->data.patch || var->data.location < 0) + if (var->data.location < 0) return 0; + unsigned location = var->data.patch ? + var->data.location - VARYING_SLOT_PATCH0 : var->data.location; + assert(var->data.mode == nir_var_shader_in || var->data.mode == nir_var_shader_out || var->data.mode == nir_var_system_value); @@ -53,11 +55,11 @@ get_variable_io_mask(nir_variable *var, gl_shader_stage stage) } unsigned slots = glsl_count_attribute_slots(type, false); - return ((1ull << slots) - 1) << var->data.location; + return ((1ull << slots) - 1) << location; } static void -tcs_add_output_reads(nir_shader *shader, uint64_t *read) +tcs_add_output_reads(nir_shader *shader, uint64_t *read, uint64_t *patches_read) { nir_foreach_function(function, shader) { if (function->impl) { @@ -73,9 +75,15 @@ tcs_add_output_reads(nir_shader *shader, uint64_t *read) nir_var_shader_out) { nir_variable *var = intrin_instr->variables[0]->var; - read[var->data.location_frac] |= - get_variable_io_mask(intrin_instr->variables[0]->var, - shader->info.stage); + if (var->data.patch) { + patches_read[var->data.location_frac] |= + get_variable_io_mask(intrin_instr->variables[0]->var, + shader->info.stage); + } else { + read[var->data.location_frac] |= + get_variable_io_mask(intrin_instr->variables[0]->var, + shader->info.stage); + } } } } @@ -85,14 +93,17 @@ tcs_add_output_reads(nir_shader *shader, uint64_t *read) static bool remove_unused_io_vars(nir_shader *shader, struct exec_list *var_list, - uint64_t *used_by_other_stage) + uint64_t *used_by_other_stage, + uint64_t *used_by_other_stage_patches) { bool progress = false; + uint64_t *used; nir_foreach_variable_safe(var, var_list) { - /* TODO: add patch support */ if (var->data.patch) - continue; + used = used_by_other_stage_patches; + else + used = used_by_other_stage; if (var->data.location < VARYING_SLOT_VAR0 && var->data.location >= 0) continue; @@ -100,7 +111,7 @@ remove_unused_io_vars(nir_shader *shader, struct exec_list *var_list, if (var->data.always_active_io) continue; - uint64_t other_stage = used_by_other_stage[var->data.location_frac]; + uint64_t other_stage = used[var->data.location_frac]; if (!(other_stage & get_variable_io_mask(var, shader->info.stage))) { /* This one is invalid, make it a global variable instead */ @@ -124,15 +135,26 @@ nir_remove_unused_varyings(nir_shader *producer, nir_shader *consumer) assert(consumer->info.stage != MESA_SHADER_VERTEX); uint64_t read[4] = { 0 }, written[4] = { 0 }; + uint64_t patches_read[4] = { 0 }, patches_written[4] = { 0 }; nir_foreach_variable(var, &producer->outputs) { - written[var->data.location_frac] |= - get_variable_io_mask(var, producer->info.stage); + if (var->data.patch) { + patches_written[var->data.location_frac] |= + get_variable_io_mask(var, producer->info.stage); + } else { + written[var->data.location_frac] |= + get_variable_io_mask(var, producer->info.stage); + } } nir_foreach_variable(var, &consumer->inputs) { - read[var->data.location_frac] |= - get_variable_io_mask(var, consumer->info.stage); + if (var->data.patch) { + patches_read[var->data.location_frac] |= + get_variable_io_mask(var, consumer->info.stage); + } else { + read[var->data.location_frac] |= + get_variable_io_mask(var, consumer->info.stage); + } } /* Each TCS invocation can read data written by other TCS invocations, @@ -140,13 +162,14 @@ nir_remove_unused_varyings(nir_shader *producer, nir_shader *consumer) * sure they are not read by the TCS before demoting them to globals. */ if (producer->info.stage == MESA_SHADER_TESS_CTRL) - tcs_add_output_reads(producer, read); + tcs_add_output_reads(producer, read, patches_read); bool progress = false; - progress = remove_unused_io_vars(producer, &producer->outputs, read); + progress = remove_unused_io_vars(producer, &producer->outputs, read, + patches_read); - progress = - remove_unused_io_vars(consumer, &consumer->inputs, written) || progress; + progress = remove_unused_io_vars(consumer, &consumer->inputs, written, + patches_written) || progress; return progress; } -- 2.30.2