diff options
author | Nicolai Hähnle <nicolai.haehnle@amd.com> | 2017-06-22 23:06:49 +0200 |
---|---|---|
committer | Nicolai Hähnle <nicolai.haehnle@amd.com> | 2017-07-13 13:27:42 +0200 |
commit | 009ade10ae1c37f8ff781cffeaf6f5ab8cf5e60f (patch) | |
tree | f1eb14a7c00bea98628b9e989c1852920293a799 | |
parent | 357936dc7911e4b061e5e8488c1fb44714148d3e (diff) |
glsl/linker: prevent segfaults in packed varyings when linking SPIR-V shaders
We could actually disable (most?) of lower_packed_varyings entirely,
because SPIR-V mandates explicit locations for varyings. Anyway, we don't
have a main function in the IR, so skip the corresponding insertions.
-rw-r--r-- | src/compiler/glsl/lower_packed_varyings.cpp | 29 |
1 files changed, 22 insertions, 7 deletions
diff --git a/src/compiler/glsl/lower_packed_varyings.cpp b/src/compiler/glsl/lower_packed_varyings.cpp index 1aec7ee7dc..789658a7a7 100644 --- a/src/compiler/glsl/lower_packed_varyings.cpp +++ b/src/compiler/glsl/lower_packed_varyings.cpp @@ -874,7 +874,7 @@ lower_packed_varyings(void *mem_ctx, unsigned locations_used, ir_function *main_func = shader->symbols->get_function("main"); exec_list void_parameters; ir_function_signature *main_func_sig - = main_func->matching_signature(NULL, &void_parameters, false); + = main_func ? main_func->matching_signature(NULL, &void_parameters, false) : NULL; exec_list new_instructions, new_variables; lower_packed_varyings_visitor visitor(mem_ctx, locations_used, @@ -893,8 +893,12 @@ lower_packed_varyings(void *mem_ctx, unsigned locations_used, */ lower_packed_varyings_gs_splicer splicer(mem_ctx, &new_instructions); - /* Add all the variables in first. */ - main_func_sig->body.get_head_raw()->insert_before(&new_variables); + assert(new_variables.is_empty() || main_func_sig != NULL); + + if (!new_variables.is_empty()) { + /* Add all the variables in first. */ + main_func_sig->body.get_head_raw()->insert_before(&new_variables); + } /* Now update all the EmitVertex instances */ splicer.run(instructions); @@ -905,20 +909,31 @@ lower_packed_varyings(void *mem_ctx, unsigned locations_used, lower_packed_varyings_return_splicer splicer(mem_ctx, &new_instructions); - main_func_sig->body.get_head_raw()->insert_before(&new_variables); + assert(new_variables.is_empty() || main_func_sig != NULL); + + if (!new_variables.is_empty()) + main_func_sig->body.get_head_raw()->insert_before(&new_variables); splicer.run(instructions); + assert(new_instructions.is_empty() || main_func_sig != NULL); + /* Lower outputs at the end of main() if the last instruction is not * a return statement */ - if (((ir_instruction*)instructions->get_tail())->ir_type != ir_type_return) { + if (main_func_sig != NULL && + ((ir_instruction*)instructions->get_tail())->ir_type != ir_type_return) { main_func_sig->body.append_list(&new_instructions); } } } else { + assert((new_instructions.is_empty() && new_variables.is_empty()) || + main_func_sig != NULL); + /* Shader inputs need to be lowered at the beginning of main() */ - main_func_sig->body.get_head_raw()->insert_before(&new_instructions); - main_func_sig->body.get_head_raw()->insert_before(&new_variables); + if (!new_instructions.is_empty()) + main_func_sig->body.get_head_raw()->insert_before(&new_instructions); + if (!new_variables.is_empty()) + main_func_sig->body.get_head_raw()->insert_before(&new_variables); } } |