summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Ekstrand <jason.ekstrand@intel.com>2016-09-13 21:10:13 -0700
committerJason Ekstrand <jason.ekstrand@intel.com>2016-09-21 05:39:06 -0700
commitd2f42a945ec0fbcc51b59cfd329258bd62ebf0d2 (patch)
treebc1448755483dd8290e0cf3853b59573aa782be6
parenta5296448892e63791a457c19a6593161da9b42a8 (diff)
nir/spirv/glsl450: Add support for the InterpolateAt opcodes
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net> Reviewed-by: Dave Airlie <airlied@redhat.com>
-rw-r--r--src/compiler/spirv/vtn_glsl450.c54
1 files changed, 53 insertions, 1 deletions
diff --git a/src/compiler/spirv/vtn_glsl450.c b/src/compiler/spirv/vtn_glsl450.c
index e05d28ffed..cb0570d385 100644
--- a/src/compiler/spirv/vtn_glsl450.c
+++ b/src/compiler/spirv/vtn_glsl450.c
@@ -634,6 +634,57 @@ handle_glsl450_alu(struct vtn_builder *b, enum GLSLstd450 entrypoint,
}
}
+static void
+handle_glsl450_interpolation(struct vtn_builder *b, enum GLSLstd450 opcode,
+ const uint32_t *w, unsigned count)
+{
+ const struct glsl_type *dest_type =
+ vtn_value(b, w[1], vtn_value_type_type)->type->type;
+
+ struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_ssa);
+ val->ssa = vtn_create_ssa_value(b, dest_type);
+
+ nir_intrinsic_op op;
+ switch (opcode) {
+ case GLSLstd450InterpolateAtCentroid:
+ op = nir_intrinsic_interp_var_at_centroid;
+ break;
+ case GLSLstd450InterpolateAtSample:
+ op = nir_intrinsic_interp_var_at_sample;
+ break;
+ case GLSLstd450InterpolateAtOffset:
+ op = nir_intrinsic_interp_var_at_offset;
+ break;
+ default:
+ unreachable("Invalid opcode");
+ }
+
+ nir_intrinsic_instr *intrin = nir_intrinsic_instr_create(b->nb.shader, op);
+
+ nir_deref_var *deref = vtn_nir_deref(b, w[5]);
+ intrin->variables[0] =
+ nir_deref_as_var(nir_copy_deref(intrin, &deref->deref));
+
+ switch (opcode) {
+ case GLSLstd450InterpolateAtCentroid:
+ break;
+ case GLSLstd450InterpolateAtSample:
+ case GLSLstd450InterpolateAtOffset:
+ intrin->src[0] = nir_src_for_ssa(vtn_ssa_value(b, w[6])->def);
+ break;
+ default:
+ unreachable("Invalid opcode");
+ }
+
+ intrin->num_components = glsl_get_vector_elements(dest_type);
+ nir_ssa_dest_init(&intrin->instr, &intrin->dest,
+ glsl_get_vector_elements(dest_type),
+ glsl_get_bit_size(dest_type), NULL);
+ val->ssa->def = &intrin->dest.ssa;
+
+ nir_builder_instr_insert(&b->nb, &intrin->instr);
+}
+
bool
vtn_handle_glsl450_instruction(struct vtn_builder *b, uint32_t ext_opcode,
const uint32_t *w, unsigned count)
@@ -656,7 +707,8 @@ vtn_handle_glsl450_instruction(struct vtn_builder *b, uint32_t ext_opcode,
case GLSLstd450InterpolateAtCentroid:
case GLSLstd450InterpolateAtSample:
case GLSLstd450InterpolateAtOffset:
- unreachable("Unhandled opcode");
+ handle_glsl450_interpolation(b, ext_opcode, w, count);
+ break;
default:
handle_glsl450_alu(b, (enum GLSLstd450)ext_opcode, w, count);