From cd394017c85efeff15893e30388567c4b4a0d280 Mon Sep 17 00:00:00 2001 From: Caio Marcelo de Oliveira Filho Date: Mon, 3 May 2021 12:04:01 -0700 Subject: [PATCH] nir: Add per-primitive I/O intrinsics MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Kenneth Graunke Reviewed-by: Timur Kristóf Part-of: --- src/compiler/nir/nir_gather_info.c | 2 ++ src/compiler/nir/nir_intrinsics.py | 4 ++++ src/compiler/nir/nir_lower_io.c | 16 +++++++++++----- src/compiler/nir/nir_opt_undef.c | 1 + src/compiler/nir/nir_validate.c | 1 + 5 files changed, 19 insertions(+), 5 deletions(-) diff --git a/src/compiler/nir/nir_gather_info.c b/src/compiler/nir/nir_gather_info.c index 9472f898c06..b44a04bf2ab 100644 --- a/src/compiler/nir/nir_gather_info.c +++ b/src/compiler/nir/nir_gather_info.c @@ -533,6 +533,7 @@ gather_intrinsic_info(nir_intrinsic_instr *instr, nir_shader *shader, case nir_intrinsic_load_output: case nir_intrinsic_load_per_vertex_output: + case nir_intrinsic_load_per_primitive_output: if (shader->info.stage == MESA_SHADER_TESS_CTRL && instr->intrinsic == nir_intrinsic_load_output) { shader->info.patch_outputs_read |= slot_mask; @@ -559,6 +560,7 @@ gather_intrinsic_info(nir_intrinsic_instr *instr, nir_shader *shader, case nir_intrinsic_store_output: case nir_intrinsic_store_per_vertex_output: + case nir_intrinsic_store_per_primitive_output: if (shader->info.stage == MESA_SHADER_TESS_CTRL && instr->intrinsic == nir_intrinsic_store_output) { shader->info.patch_outputs_written |= slot_mask; diff --git a/src/compiler/nir/nir_intrinsics.py b/src/compiler/nir/nir_intrinsics.py index f3f62ad452b..fdc5e7882ee 100644 --- a/src/compiler/nir/nir_intrinsics.py +++ b/src/compiler/nir/nir_intrinsics.py @@ -921,6 +921,8 @@ load("ssbo_address", [1], [], [CAN_ELIMINATE, CAN_REORDER]) load("output", [1], [BASE, COMPONENT, DEST_TYPE, IO_SEMANTICS], flags=[CAN_ELIMINATE]) # src[] = { vertex, offset }. load("per_vertex_output", [1, 1], [BASE, COMPONENT, DEST_TYPE, IO_SEMANTICS], [CAN_ELIMINATE]) +# src[] = { primitive, offset }. +load("per_primitive_output", [1, 1], [BASE, COMPONENT, DEST_TYPE, IO_SEMANTICS], [CAN_ELIMINATE]) # src[] = { offset }. load("shared", [1], [BASE, ALIGN_MUL, ALIGN_OFFSET], [CAN_ELIMINATE]) # src[] = { offset }. @@ -956,6 +958,8 @@ def store(name, srcs, indices=[], flags=[]): store("output", [1], [BASE, WRITE_MASK, COMPONENT, SRC_TYPE, IO_SEMANTICS]) # src[] = { value, vertex, offset }. store("per_vertex_output", [1, 1], [BASE, WRITE_MASK, COMPONENT, SRC_TYPE, IO_SEMANTICS]) +# src[] = { value, primitive, offset }. +store("per_primitive_output", [1, 1], [BASE, WRITE_MASK, COMPONENT, SRC_TYPE, IO_SEMANTICS]) # src[] = { value, block_index, offset } store("ssbo", [-1, 1], [WRITE_MASK, ACCESS, ALIGN_MUL, ALIGN_OFFSET]) # src[] = { value, offset }. diff --git a/src/compiler/nir/nir_lower_io.c b/src/compiler/nir/nir_lower_io.c index 71bd31c618b..c9aa0b26e9c 100644 --- a/src/compiler/nir/nir_lower_io.c +++ b/src/compiler/nir/nir_lower_io.c @@ -282,8 +282,9 @@ emit_load(struct lower_io_state *state, } break; case nir_var_shader_out: - op = array_index ? nir_intrinsic_load_per_vertex_output : - nir_intrinsic_load_output; + op = !array_index ? nir_intrinsic_load_output : + var->data.per_primitive ? nir_intrinsic_load_per_primitive_output : + nir_intrinsic_load_per_vertex_output; break; case nir_var_uniform: op = nir_intrinsic_load_uniform; @@ -394,8 +395,9 @@ emit_store(struct lower_io_state *state, nir_ssa_def *data, assert(var->data.mode == nir_var_shader_out); nir_intrinsic_op op = - array_index ? nir_intrinsic_store_per_vertex_output : - nir_intrinsic_store_output; + !array_index ? nir_intrinsic_store_output : + var->data.per_primitive ? nir_intrinsic_store_per_primitive_output : + nir_intrinsic_store_per_vertex_output; nir_intrinsic_instr *store = nir_intrinsic_instr_create(state->builder.shader, op); @@ -2472,6 +2474,7 @@ nir_get_io_offset_src(nir_intrinsic_instr *instr) case nir_intrinsic_load_input_vertex: case nir_intrinsic_load_per_vertex_input: case nir_intrinsic_load_per_vertex_output: + case nir_intrinsic_load_per_primitive_output: case nir_intrinsic_load_interpolated_input: case nir_intrinsic_store_output: case nir_intrinsic_store_shared: @@ -2494,6 +2497,7 @@ nir_get_io_offset_src(nir_intrinsic_instr *instr) return &instr->src[1]; case nir_intrinsic_store_ssbo: case nir_intrinsic_store_per_vertex_output: + case nir_intrinsic_store_per_primitive_output: return &instr->src[2]; default: return NULL; @@ -2632,8 +2636,10 @@ is_output(nir_intrinsic_instr *intrin) { return intrin->intrinsic == nir_intrinsic_load_output || intrin->intrinsic == nir_intrinsic_load_per_vertex_output || + intrin->intrinsic == nir_intrinsic_load_per_primitive_output || intrin->intrinsic == nir_intrinsic_store_output || - intrin->intrinsic == nir_intrinsic_store_per_vertex_output; + intrin->intrinsic == nir_intrinsic_store_per_vertex_output || + intrin->intrinsic == nir_intrinsic_store_per_primitive_output; } static bool is_dual_slot(nir_intrinsic_instr *intrin) diff --git a/src/compiler/nir/nir_opt_undef.c b/src/compiler/nir/nir_opt_undef.c index 20b31a4adad..fd8fb2c7590 100644 --- a/src/compiler/nir/nir_opt_undef.c +++ b/src/compiler/nir/nir_opt_undef.c @@ -137,6 +137,7 @@ opt_undef_store(nir_intrinsic_instr *intrin) break; case nir_intrinsic_store_output: case nir_intrinsic_store_per_vertex_output: + case nir_intrinsic_store_per_primitive_output: case nir_intrinsic_store_ssbo: case nir_intrinsic_store_shared: case nir_intrinsic_store_global: diff --git a/src/compiler/nir/nir_validate.c b/src/compiler/nir/nir_validate.c index 648e5af7a1a..b27cbc01d26 100644 --- a/src/compiler/nir/nir_validate.c +++ b/src/compiler/nir/nir_validate.c @@ -676,6 +676,7 @@ validate_intrinsic_instr(nir_intrinsic_instr *instr, validate_state *state) case nir_intrinsic_load_interpolated_input: case nir_intrinsic_load_output: case nir_intrinsic_load_per_vertex_output: + case nir_intrinsic_load_per_primitive_output: case nir_intrinsic_load_push_constant: /* All memory load operations must load at least a byte */ validate_assert(state, nir_dest_bit_size(instr->dest) >= 8);