diff options
-rw-r--r-- | src/compiler/nir/nir.h | 6 | ||||
-rw-r--r-- | src/compiler/nir/nir_builder.h | 11 | ||||
-rw-r--r-- | src/compiler/nir/nir_intrinsics.h | 32 | ||||
-rw-r--r-- | src/compiler/nir/nir_lower_io.c | 1 | ||||
-rw-r--r-- | src/compiler/nir/nir_print.c | 1 |
5 files changed, 51 insertions, 0 deletions
diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h index c5d3b6b698d..ac119981ec9 100644 --- a/src/compiler/nir/nir.h +++ b/src/compiler/nir/nir.h @@ -992,6 +992,11 @@ typedef enum { */ NIR_INTRINSIC_COMPONENT = 8, + /** + * Interpolation mode (only meaningful for FS inputs). + */ + NIR_INTRINSIC_INTERP_MODE = 9, + NIR_INTRINSIC_NUM_INDEX_FLAGS, } nir_intrinsic_index_flag; @@ -1059,6 +1064,7 @@ INTRINSIC_IDX_ACCESSORS(range, RANGE, unsigned) INTRINSIC_IDX_ACCESSORS(desc_set, DESC_SET, unsigned) INTRINSIC_IDX_ACCESSORS(binding, BINDING, unsigned) INTRINSIC_IDX_ACCESSORS(component, COMPONENT, unsigned) +INTRINSIC_IDX_ACCESSORS(interp_mode, INTERP_MODE, unsigned) /** * \group texture information diff --git a/src/compiler/nir/nir_builder.h b/src/compiler/nir/nir_builder.h index 09cdf72bfff..435582aca3c 100644 --- a/src/compiler/nir/nir_builder.h +++ b/src/compiler/nir/nir_builder.h @@ -458,6 +458,17 @@ nir_load_system_value(nir_builder *build, nir_intrinsic_op op, int index) return &load->dest.ssa; } +static inline nir_ssa_def * +nir_load_barycentric(nir_builder *build, nir_intrinsic_op op, + unsigned interp_mode) +{ + nir_intrinsic_instr *bary = nir_intrinsic_instr_create(build->shader, op); + nir_ssa_dest_init(&bary->instr, &bary->dest, 2, 32, NULL); + nir_intrinsic_set_interp_mode(bary, interp_mode); + nir_builder_instr_insert(build, &bary->instr); + return &bary->dest.ssa; +} + static inline void nir_jump(nir_builder *build, nir_jump_type jump_type) { diff --git a/src/compiler/nir/nir_intrinsics.h b/src/compiler/nir/nir_intrinsics.h index 2f74555ee48..cf2ddc8ac72 100644 --- a/src/compiler/nir/nir_intrinsics.h +++ b/src/compiler/nir/nir_intrinsics.h @@ -306,6 +306,35 @@ SYSTEM_VALUE(num_work_groups, 3, 0, xx, xx, xx) SYSTEM_VALUE(helper_invocation, 1, 0, xx, xx, xx) SYSTEM_VALUE(channel_num, 1, 0, xx, xx, xx) +/** + * Barycentric coordinate intrinsics. + * + * These set up the barycentric coordinates for a particular interpolation. + * The first three are for the simple cases: pixel, centroid, or per-sample + * (at gl_SampleID). The next two handle interpolating at a specified + * sample location, or interpolating with a vec2 offset, + * + * The interp_mode index should be either the INTERP_MODE_SMOOTH or + * INTERP_MODE_NOPERSPECTIVE enum values. + * + * The vec2 value produced by these intrinsics is intended for use as the + * barycoord source of a load_interpolated_input intrinsic. + */ + +#define BARYCENTRIC(name, sources, source_components) \ + INTRINSIC(load_barycentric_##name, sources, ARR(source_components), \ + true, 2, 0, 1, INTERP_MODE, xx, xx, \ + NIR_INTRINSIC_CAN_ELIMINATE | NIR_INTRINSIC_CAN_REORDER) + +/* no sources. const_index[] = { interp_mode } */ +BARYCENTRIC(pixel, 0, 0) +BARYCENTRIC(centroid, 0, 0) +BARYCENTRIC(sample, 0, 0) +/* src[] = { sample_id }. const_index[] = { interp_mode } */ +BARYCENTRIC(at_sample, 1, 1) +/* src[] = { offset.xy }. const_index[] = { interp_mode } */ +BARYCENTRIC(at_offset, 1, 2) + /* * Load operations pull data from some piece of GPU memory. All load * operations operate in terms of offsets into some piece of theoretical @@ -339,6 +368,9 @@ LOAD(ubo, 2, 0, xx, xx, xx, NIR_INTRINSIC_CAN_ELIMINATE | NIR_INTRINSIC_CAN_REOR LOAD(input, 1, 2, BASE, COMPONENT, xx, NIR_INTRINSIC_CAN_ELIMINATE | NIR_INTRINSIC_CAN_REORDER) /* src[] = { vertex, offset }. const_index[] = { base, component } */ LOAD(per_vertex_input, 2, 2, BASE, COMPONENT, xx, NIR_INTRINSIC_CAN_ELIMINATE | NIR_INTRINSIC_CAN_REORDER) +/* src[] = { barycoord, offset }. const_index[] = { base, component } */ +LOAD(interpolated_input, 2, 2, BASE, COMPONENT, xx, NIR_INTRINSIC_CAN_ELIMINATE | NIR_INTRINSIC_CAN_REORDER) + /* src[] = { buffer_index, offset }. No const_index */ LOAD(ssbo, 2, 0, xx, xx, xx, NIR_INTRINSIC_CAN_ELIMINATE) /* src[] = { offset }. const_index[] = { base, component } */ diff --git a/src/compiler/nir/nir_lower_io.c b/src/compiler/nir/nir_lower_io.c index 189370df364..9c1096179b1 100644 --- a/src/compiler/nir/nir_lower_io.c +++ b/src/compiler/nir/nir_lower_io.c @@ -436,6 +436,7 @@ nir_get_io_offset_src(nir_intrinsic_instr *instr) case nir_intrinsic_load_ssbo: case nir_intrinsic_load_per_vertex_input: case nir_intrinsic_load_per_vertex_output: + case nir_intrinsic_load_interpolated_input: case nir_intrinsic_store_output: return &instr->src[1]; case nir_intrinsic_store_ssbo: diff --git a/src/compiler/nir/nir_print.c b/src/compiler/nir/nir_print.c index a3380e677d1..3beb70a75d3 100644 --- a/src/compiler/nir/nir_print.c +++ b/src/compiler/nir/nir_print.c @@ -571,6 +571,7 @@ print_intrinsic_instr(nir_intrinsic_instr *instr, print_state *state) [NIR_INTRINSIC_DESC_SET] = "desc-set", [NIR_INTRINSIC_BINDING] = "binding", [NIR_INTRINSIC_COMPONENT] = "component", + [NIR_INTRINSIC_INTERP_MODE] = "interp_mode", }; for (unsigned idx = 1; idx < NIR_INTRINSIC_NUM_INDEX_FLAGS; idx++) { if (!info->index_map[idx]) |