diff options
Diffstat (limited to 'src/compiler')
-rw-r--r-- | src/compiler/nir/nir.h | 3 | ||||
-rw-r--r-- | src/compiler/nir/nir_lower_patch_vertices.c | 68 |
2 files changed, 64 insertions, 7 deletions
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; } |