diff options
author | Jason Ekstrand <jason.ekstrand@intel.com> | 2016-09-13 21:10:13 -0700 |
---|---|---|
committer | Jason Ekstrand <jason.ekstrand@intel.com> | 2016-09-21 05:39:06 -0700 |
commit | d2f42a945ec0fbcc51b59cfd329258bd62ebf0d2 (patch) | |
tree | bc1448755483dd8290e0cf3853b59573aa782be6 | |
parent | a5296448892e63791a457c19a6593161da9b42a8 (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.c | 54 |
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); |