diff options
author | Jason Ekstrand <[email protected]> | 2017-12-14 19:53:05 -0800 |
---|---|---|
committer | Jason Ekstrand <[email protected]> | 2017-12-18 09:48:58 -0800 |
commit | 3be382cd7cb637f463a4618dc19d87d66a644b0e (patch) | |
tree | d108e1d1aa2521dd021ed9294a41b95dc76737ea /src | |
parent | 8d00e63ca8e8f357624549c97d9cb705afd522cb (diff) |
spirv: Relax the validation conditions of OpSelect
The Talos Principle contains shaders with an OpSelect between two
vectors where the condition is a scalar boolean. This is technically
against the spec bout nir_builder gracefully handles it by splatting
out the condition to all the channels. So long as the condition is a
boolean, just emit a warning instead of failing.
Reviewed-by: Lionel Landwerlin <[email protected]>
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=104246
Diffstat (limited to 'src')
-rw-r--r-- | src/compiler/spirv/spirv_to_nir.c | 25 |
1 files changed, 21 insertions, 4 deletions
diff --git a/src/compiler/spirv/spirv_to_nir.c b/src/compiler/spirv/spirv_to_nir.c index 0493dd3a8b1..39c0b5f5dbc 100644 --- a/src/compiler/spirv/spirv_to_nir.c +++ b/src/compiler/spirv/spirv_to_nir.c @@ -3511,10 +3511,27 @@ vtn_handle_body_instruction(struct vtn_builder *b, SpvOp opcode, 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"); + if (unlikely(sel_val->type->type != sel_type)) { + if (sel_val->type->type == glsl_bool_type()) { + /* This case is illegal but some older versions of GLSLang produce + * it. The GLSLang issue was fixed on March 30, 2017: + * + * https://github.com/KhronosGroup/glslang/issues/809 + * + * Unfortunately, there are applications in the wild which are + * shipping with this bug so it isn't nice to fail on them so we + * throw a warning instead. It's not actually a problem for us as + * nir_builder will just splat the condition out which is most + * likely what the client wanted anyway. + */ + vtn_warn("Condition type of OpSelect must have the same number " + "of components as Result Type"); + } else { + vtn_fail("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, |