From 1e59cdbf779e58d55a00f51ea1143b92410cd0a8 Mon Sep 17 00:00:00 2001 From: Caio Marcelo de Oliveira Filho Date: Mon, 1 Feb 2021 23:19:13 -0800 Subject: [PATCH] spirv: Fail when parsing invalid Initializers Fail when parsing Initializers used in Variables with Storage Classes that doesn't support it. Reviewed-by: Jason Ekstrand Reviewed-by: Jesse Natalie Part-of: --- src/compiler/spirv/vtn_variables.c | 56 +++++++++++++++++++++++++++--- 1 file changed, 52 insertions(+), 4 deletions(-) diff --git a/src/compiler/spirv/vtn_variables.c b/src/compiler/spirv/vtn_variables.c index 6a72fbdae3e..39d0711b867 100644 --- a/src/compiler/spirv/vtn_variables.c +++ b/src/compiler/spirv/vtn_variables.c @@ -1977,8 +1977,8 @@ vtn_create_variable(struct vtn_builder *b, struct vtn_value *val, } if (initializer) { - switch (var->mode) { - case vtn_variable_mode_workgroup: + switch (storage_class) { + case SpvStorageClassWorkgroup: /* VK_KHR_zero_initialize_workgroup_memory. */ vtn_fail_if(b->options->environment != NIR_SPIRV_VULKAN, "Only Vulkan supports variable initializer " @@ -1992,9 +1992,57 @@ vtn_create_variable(struct vtn_builder *b, struct vtn_value *val, vtn_id_for_value(b, initializer)); b->shader->info.cs.zero_initialize_shared_memory = true; break; - default: - /* Nothing to check. */ + + case SpvStorageClassUniformConstant: + vtn_fail_if(b->options->environment != NIR_SPIRV_OPENGL && + b->options->environment != NIR_SPIRV_OPENCL, + "Only OpenGL and OpenCL support variable initializer " + "for UniformConstant variable %u\n", + vtn_id_for_value(b, val)); + vtn_fail_if(initializer->value_type != vtn_value_type_constant, + "UniformConstant variable %u can only have a constant " + "initializer, but have %u instead", + vtn_id_for_value(b, val), + vtn_id_for_value(b, initializer)); break; + + case SpvStorageClassOutput: + case SpvStorageClassPrivate: + vtn_assert(b->options->environment != NIR_SPIRV_OPENCL); + /* These can have any initializer. */ + break; + + case SpvStorageClassFunction: + /* These can have any initializer. */ + break; + + case SpvStorageClassCrossWorkgroup: + vtn_assert(b->options->environment == NIR_SPIRV_OPENCL); + vtn_fail("Initializer for CrossWorkgroup variable %u " + "not yet supported in Mesa.", + vtn_id_for_value(b, val)); + break; + + default: { + const enum nir_spirv_execution_environment env = + b->options->environment; + const char *env_name = + env == NIR_SPIRV_VULKAN ? "Vulkan" : + env == NIR_SPIRV_OPENCL ? "OpenCL" : + env == NIR_SPIRV_OPENGL ? "OpenGL" : + NULL; + vtn_assert(env_name); + vtn_fail("In %s, any OpVariable with an Initializer operand " + "must have %s%s%s, or Function as " + "its Storage Class operand. Variable %u has an " + "Initializer but its Storage Class is %s.", + env_name, + env == NIR_SPIRV_VULKAN ? "Private, Output, Workgroup" : "", + env == NIR_SPIRV_OPENCL ? "CrossWorkgroup, UniformConstant" : "", + env == NIR_SPIRV_OPENGL ? "Private, Output, UniformConstant" : "", + vtn_id_for_value(b, val), + spirv_storageclass_to_string(storage_class)); + } } switch (initializer->value_type) {