summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/compiler/nir/nir.h6
-rw-r--r--src/compiler/nir/nir_builder.h11
-rw-r--r--src/compiler/nir/nir_intrinsics.h32
-rw-r--r--src/compiler/nir/nir_lower_io.c1
-rw-r--r--src/compiler/nir/nir_print.c1
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])