summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJason Ekstrand <[email protected]>2017-12-06 09:14:20 -0800
committerJason Ekstrand <[email protected]>2017-12-11 22:28:34 -0800
commita7c2be9944a9e2028a02fcfbab501891293401b1 (patch)
tree2f2e20f719a2fcebec7e7313a9edb38344487188 /src
parent6737b1b859aadad64e5fe04a92d196a672413e06 (diff)
spirv: Add type validation for OpSelect
Reviewed-by: Samuel Iglesias Gonsálvez <[email protected]> Reviewed-by: Ian Romanick <[email protected]>
Diffstat (limited to 'src')
-rw-r--r--src/compiler/spirv/spirv_to_nir.c32
1 files changed, 32 insertions, 0 deletions
diff --git a/src/compiler/spirv/spirv_to_nir.c b/src/compiler/spirv/spirv_to_nir.c
index 7cbf0c9d90e..685cbd7e4de 100644
--- a/src/compiler/spirv/spirv_to_nir.c
+++ b/src/compiler/spirv/spirv_to_nir.c
@@ -3475,6 +3475,38 @@ vtn_handle_body_instruction(struct vtn_builder *b, SpvOp opcode,
/* Handle OpSelect up-front here because it needs to be able to handle
* pointers and not just regular vectors and scalars.
*/
+ struct vtn_value *res_val = vtn_untyped_value(b, w[2]);
+ struct vtn_value *sel_val = vtn_untyped_value(b, w[3]);
+ struct vtn_value *obj1_val = vtn_untyped_value(b, w[4]);
+ struct vtn_value *obj2_val = vtn_untyped_value(b, w[5]);
+
+ const struct glsl_type *sel_type;
+ switch (res_val->type->base_type) {
+ case vtn_base_type_scalar:
+ sel_type = glsl_bool_type();
+ break;
+ case vtn_base_type_vector:
+ sel_type = glsl_vector_type(GLSL_TYPE_BOOL, res_val->type->length);
+ break;
+ case vtn_base_type_pointer:
+ /* We need to have actual storage for pointer types */
+ vtn_fail_if(res_val->type->type == NULL,
+ "Invalid pointer result type for OpSelect");
+ sel_type = glsl_bool_type();
+ break;
+ default:
+ vtn_fail("Result type of OpSelect must be a scalar, vector, or pointer");
+ }
+
+ vtn_fail_if(sel_val->type->type != sel_type,
+ "Condition type of OpSelect must be a scalar or vector of "
+ "Boolean type. It must have the same number of components "
+ "as Result Type");
+
+ vtn_fail_if(obj1_val->type != res_val->type ||
+ obj2_val->type != res_val->type,
+ "Object types must match the result type in OpSelect");
+
struct vtn_type *res_type = vtn_value(b, w[1], vtn_value_type_type)->type;
struct vtn_ssa_value *ssa = vtn_create_ssa_value(b, res_type->type);
ssa->def = nir_bcsel(&b->nb, vtn_ssa_value(b, w[3])->def,