extern "C" {
/**
- * Link a shader.
- * Called via ctx->Driver.LinkShader()
- * This actually involves converting GLSL IR into Mesa gl_programs with
- * code lowering and other optimizations.
- */
-GLboolean
-_mesa_ir_link_shader(struct gl_context *ctx, struct gl_shader_program *prog)
-{
- assert(prog->data->LinkStatus);
-
- for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
- if (prog->_LinkedShaders[i] == NULL)
- continue;
-
- bool progress;
- exec_list *ir = prog->_LinkedShaders[i]->ir;
- const struct gl_shader_compiler_options *options =
- &ctx->Const.ShaderCompilerOptions[prog->_LinkedShaders[i]->Stage];
-
- do {
- progress = false;
-
- /* Lowering */
- do_mat_op_to_vec(ir);
- lower_instructions(ir, (MOD_TO_FLOOR | DIV_TO_MUL_RCP | EXP_TO_EXP2
- | LOG_TO_LOG2 | INT_DIV_TO_MUL_RCP
- | MUL64_TO_MUL_AND_MUL_HIGH
- | ((options->EmitNoPow) ? POW_TO_EXP2 : 0)));
-
- progress = do_common_optimization(ir, true, true,
- options, ctx->Const.NativeIntegers)
- || progress;
-
- progress = lower_quadop_vector(ir, true) || progress;
-
- if (options->MaxIfDepth == 0)
- progress = lower_discard(ir) || progress;
-
- progress = lower_if_to_cond_assign((gl_shader_stage)i, ir,
- options->MaxIfDepth) || progress;
-
- /* If there are forms of indirect addressing that the driver
- * cannot handle, perform the lowering pass.
- */
- if (options->EmitNoIndirectInput || options->EmitNoIndirectOutput
- || options->EmitNoIndirectTemp || options->EmitNoIndirectUniform)
- progress =
- lower_variable_index_to_cond_assign(prog->_LinkedShaders[i]->Stage, ir,
- options->EmitNoIndirectInput,
- options->EmitNoIndirectOutput,
- options->EmitNoIndirectTemp,
- options->EmitNoIndirectUniform)
- || progress;
-
- progress = do_vec_index_to_cond_assign(ir) || progress;
- progress = lower_vector_insert(ir, true) || progress;
- } while (progress);
-
- validate_ir_tree(ir);
- }
-
- for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
- struct gl_program *linked_prog;
-
- if (prog->_LinkedShaders[i] == NULL)
- continue;
-
- linked_prog = get_mesa_program(ctx, prog, prog->_LinkedShaders[i]);
-
- if (linked_prog) {
- _mesa_copy_linked_program_data(prog, prog->_LinkedShaders[i]);
-
- if (!ctx->Driver.ProgramStringNotify(ctx,
- _mesa_shader_stage_to_program(i),
- linked_prog)) {
- _mesa_reference_program(ctx, &prog->_LinkedShaders[i]->Program,
- NULL);
- return GL_FALSE;
- }
- }
- }
-
- build_program_resource_list(ctx, prog, false);
- return prog->data->LinkStatus;
-}
-
-/**
* Link a GLSL shader program. Called via glLinkProgram().
*/
void