diff options
Diffstat (limited to 'src/mesa/shader/slang')
-rw-r--r-- | src/mesa/shader/slang/slang_codegen.c | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c index d594650c5ba..3b58ee4cbd3 100644 --- a/src/mesa/shader/slang/slang_codegen.c +++ b/src/mesa/shader/slang/slang_codegen.c @@ -1391,6 +1391,27 @@ slang_inline_function_call(slang_assemble_ctx * A, slang_function *fun, } +/** + * Insert declaration for "bool _returnFlag" in given block operation. + * This is used when we can't emit "early" return statements in subroutines. + */ +static void +declare_return_flag(slang_assemble_ctx *A, slang_operation *oper) +{ + slang_operation *decl; + + assert(oper->type == SLANG_OPER_BLOCK_NEW_SCOPE || + oper->type == SLANG_OPER_SEQUENCE); + + decl = slang_operation_insert_child(oper, 1); + + slang_generate_declaration(A, oper->locals, decl, + SLANG_SPEC_BOOL, "_returnFlag", GL_FALSE); + + slang_print_tree(oper, 0); +} + + static slang_ir_node * _slang_gen_function_call(slang_assemble_ctx *A, slang_function *fun, slang_operation *oper, slang_operation *dest) @@ -1453,6 +1474,18 @@ _slang_gen_function_call(slang_assemble_ctx *A, slang_function *fun, else { callOper = inlined; } + + if (!A->EmitContReturn) { + /* Early returns not supported. Create a _returnFlag variable + * that's set upon 'return' and tested elsewhere to no-op any + * remaining instructions in the subroutine. + */ + assert(callOper->type == SLANG_OPER_BLOCK_NEW_SCOPE || + callOper->type == SLANG_OPER_SEQUENCE); + declare_return_flag(A, callOper); + printf("DECLARE _returnFlag\n"); + + } callOper->type = SLANG_OPER_NON_INLINED_CALL; callOper->fun = fun; callOper->label = _slang_label_new_unique((char*) fun->header.a_name); |