From: Samuel Pitoiset Date: Tue, 26 May 2020 11:54:34 +0000 (+0200) Subject: spirv: fix using OpSampledImage with OpUndef instead of OpType{Image,Sampler} X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=9b6a8d17424ac5fa11ccf44c02da2a237088cb76;p=mesa.git spirv: fix using OpSampledImage with OpUndef instead of OpType{Image,Sampler} This seems valid per the SPIR-V spec to use OpSampledImage with OpUndef instead of OpTypeImage or OpTypeSampler. When the image operand is undefined, SPIRV->NIR emits an undef instruction that can be removed later by the compiler. This fixes shader compilation crashes with Red Dead Redemption II. Cc: mesa-stable@lists.freedesktop.org> Signed-off-by: Samuel Pitoiset Reviewed-by: Jason Ekstrand Part-of: --- diff --git a/src/compiler/spirv/spirv_to_nir.c b/src/compiler/spirv/spirv_to_nir.c index cfe180c0489..10c5de55216 100644 --- a/src/compiler/spirv/spirv_to_nir.c +++ b/src/compiler/spirv/spirv_to_nir.c @@ -2259,10 +2259,23 @@ vtn_handle_texture(struct vtn_builder *b, SpvOp opcode, struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_sampled_image); val->sampled_image = ralloc(b, struct vtn_sampled_image); - val->sampled_image->image = - vtn_value(b, w[3], vtn_value_type_pointer)->pointer; - val->sampled_image->sampler = - vtn_value(b, w[4], vtn_value_type_pointer)->pointer; + + /* It seems valid to use OpSampledImage with OpUndef instead of + * OpTypeImage or OpTypeSampler. + */ + if (vtn_untyped_value(b, w[3])->value_type == vtn_value_type_undef) { + val->sampled_image->image = NULL; + } else { + val->sampled_image->image = + vtn_value(b, w[3], vtn_value_type_pointer)->pointer; + } + + if (vtn_untyped_value(b, w[4])->value_type == vtn_value_type_undef) { + val->sampled_image->sampler = NULL; + } else { + val->sampled_image->sampler = + vtn_value(b, w[4], vtn_value_type_pointer)->pointer; + } return; } else if (opcode == SpvOpImage) { struct vtn_value *src_val = vtn_untyped_value(b, w[3]); @@ -2287,6 +2300,11 @@ vtn_handle_texture(struct vtn_builder *b, SpvOp opcode, image = sampled_val->pointer; } + if (!image) { + vtn_push_value(b, w[2], vtn_value_type_undef); + return; + } + nir_deref_instr *image_deref = vtn_pointer_to_deref(b, image); nir_deref_instr *sampler_deref = sampler ? vtn_pointer_to_deref(b, sampler) : NULL;