diff --git a/src/amd/compiler/aco_assembler.cpp b/src/amd/compiler/aco_assembler.cpp index 52b6528ac84..7e6aa4eea48 100644 --- a/src/amd/compiler/aco_assembler.cpp +++ b/src/amd/compiler/aco_assembler.cpp @@ -1279,7 +1279,8 @@ align_block(asm_context& ctx, std::vector& code, Block& block) } unsigned -emit_program(Program* program, std::vector& code, std::vector* symbols) +emit_program(Program* program, std::vector& code, std::vector* symbols, + bool append_endpgm) { asm_context ctx(program, symbols); @@ -1298,7 +1299,8 @@ emit_program(Program* program, std::vector& code, std::vectorkind |= block_kind_uniform; - Builder bld(ctx.program, ctx.block); - bld.sopp(aco_opcode::s_endpgm); + + if (!ctx.program->info.has_epilog) { + Builder bld(ctx.program, ctx.block); + bld.sopp(aco_opcode::s_endpgm); + } cleanup_cfg(program); } diff --git a/src/amd/compiler/aco_interface.cpp b/src/amd/compiler/aco_interface.cpp index fccad69a5c0..3b5148b6be4 100644 --- a/src/amd/compiler/aco_interface.cpp +++ b/src/amd/compiler/aco_interface.cpp @@ -236,7 +236,11 @@ aco_compile_shader(const struct aco_compiler_options* options, const struct aco_ /* assembly */ std::vector code; std::vector symbols; - unsigned exec_size = aco::emit_program(program.get(), code, &symbols); + /* OpenGL combine multi shader parts into one continous code block, + * so only last part need the s_endpgm instruction. + */ + bool append_endpgm = !(options->is_opengl && info->has_epilog); + unsigned exec_size = aco::emit_program(program.get(), code, &symbols, append_endpgm); if (program->collect_statistics) aco::collect_postasm_stats(program.get(), code); @@ -284,7 +288,7 @@ aco_compile_rt_prolog(const struct aco_compiler_options* options, /* assembly */ std::vector code; code.reserve(align(program->blocks[0].instructions.size() * 2, 16)); - unsigned exec_size = aco::emit_program(program.get(), code, NULL); + unsigned exec_size = aco::emit_program(program.get(), code); bool get_disasm = options->dump_shader || options->record_ir; @@ -322,7 +326,7 @@ aco_compile_vs_prolog(const struct aco_compiler_options* options, /* assembly */ std::vector code; code.reserve(align(program->blocks[0].instructions.size() * 2, 16)); - unsigned exec_size = aco::emit_program(program.get(), code, NULL); + unsigned exec_size = aco::emit_program(program.get(), code); bool get_disasm = options->dump_shader || options->record_ir; @@ -365,7 +369,7 @@ aco_compile_shader_part(const struct aco_compiler_options* options, /* assembly */ std::vector code; - unsigned exec_size = aco::emit_program(program.get(), code, NULL); + unsigned exec_size = aco::emit_program(program.get(), code); bool get_disasm = options->dump_shader || options->record_ir; diff --git a/src/amd/compiler/aco_ir.h b/src/amd/compiler/aco_ir.h index 09b1da18503..94ae241a966 100644 --- a/src/amd/compiler/aco_ir.h +++ b/src/amd/compiler/aco_ir.h @@ -2262,7 +2262,7 @@ bool dealloc_vgprs(Program* program); void insert_NOPs(Program* program); void form_hard_clauses(Program* program); unsigned emit_program(Program* program, std::vector& code, - std::vector* symbols); + std::vector* symbols = NULL, bool append_endpgm = true); /** * Returns true if print_asm can disassemble the given program for the current build/runtime * configuration diff --git a/src/amd/compiler/tests/helpers.cpp b/src/amd/compiler/tests/helpers.cpp index caa8b51eeeb..407b1d7eb81 100644 --- a/src/amd/compiler/tests/helpers.cpp +++ b/src/amd/compiler/tests/helpers.cpp @@ -269,7 +269,7 @@ finish_assembler_test() { finish_program(program.get()); std::vector binary; - unsigned exec_size = emit_program(program.get(), binary, NULL); + unsigned exec_size = emit_program(program.get(), binary); /* we could use CLRX for disassembly but that would require it to be * installed */