From 9d96d3803ab5dc896d4844ac785db57bb1717f91 Mon Sep 17 00:00:00 2001 From: Timothy Arceri Date: Mon, 31 Oct 2016 23:54:03 +1100 Subject: [PATCH] glsl: create gl_program at the start of linking rather than the end This will allow us to directly store metadata we want to retain in gl_program this metadata is currently stored in gl_linked_shader and will be lost if relinking fails even though the program will remain in use and is still valid according to the spec. "If a program object that is active for any shader stage is re-linked unsuccessfully, the link status will be set to FALSE, but any existing executables and associated state will remain part of the current rendering state until a subsequent call to UseProgram, UseProgramStages, or BindProgramPipeline removes them from use." This change will also help avoid the double handing that happens in _mesa_copy_linked_program_data(). Reviewed-by: Emil Velikov --- src/compiler/glsl/linker.cpp | 16 ++++++++++++++++ src/mesa/drivers/dri/i965/brw_link.cpp | 10 +--------- src/mesa/program/ir_to_mesa.cpp | 7 +------ src/mesa/state_tracker/st_glsl_to_nir.cpp | 8 +------- src/mesa/state_tracker/st_glsl_to_tgsi.cpp | 8 +------- 5 files changed, 20 insertions(+), 29 deletions(-) diff --git a/src/compiler/glsl/linker.cpp b/src/compiler/glsl/linker.cpp index cc28b26964a..e34cf286b54 100644 --- a/src/compiler/glsl/linker.cpp +++ b/src/compiler/glsl/linker.cpp @@ -72,6 +72,7 @@ #include "ir.h" #include "program.h" #include "program/prog_instruction.h" +#include "program/program.h" #include "util/set.h" #include "util/string_to_uint_map.h" #include "linker.h" @@ -2187,6 +2188,21 @@ link_intrastage_shaders(void *mem_ctx, } gl_linked_shader *linked = ctx->Driver.NewShader(shader_list[0]->Stage); + + /* Create program and attach it to the linked shader */ + struct gl_program *gl_prog = + ctx->Driver.NewProgram(ctx, + _mesa_shader_stage_to_program(shader_list[0]->Stage), + prog->Name); + if (!prog) { + prog->LinkStatus = false; + _mesa_delete_linked_shader(ctx, linked); + return NULL; + } + + /* Don't use _mesa_reference_program() just take ownership */ + linked->Program = gl_prog; + linked->ir = new(linked) exec_list; clone_ir_list(mem_ctx, linked->ir, main->ir); diff --git a/src/mesa/drivers/dri/i965/brw_link.cpp b/src/mesa/drivers/dri/i965/brw_link.cpp index a0c9e20807c..3f6041b7ba2 100644 --- a/src/mesa/drivers/dri/i965/brw_link.cpp +++ b/src/mesa/drivers/dri/i965/brw_link.cpp @@ -221,15 +221,7 @@ brw_link_shader(struct gl_context *ctx, struct gl_shader_program *shProg) if (!shader) continue; - struct gl_program *prog = - ctx->Driver.NewProgram(ctx, _mesa_shader_stage_to_program(stage), - 0); - if (!prog) - return false; - - /* Don't use _mesa_reference_program() just take ownership */ - shader->Program = prog; - + struct gl_program *prog = shader->Program; prog->Parameters = _mesa_new_parameter_list(); process_glsl_ir(brw, shProg, shader); diff --git a/src/mesa/program/ir_to_mesa.cpp b/src/mesa/program/ir_to_mesa.cpp index 7f4212333f1..88a7f368ee1 100644 --- a/src/mesa/program/ir_to_mesa.cpp +++ b/src/mesa/program/ir_to_mesa.cpp @@ -2794,9 +2794,7 @@ get_mesa_program(struct gl_context *ctx, validate_ir_tree(shader->ir); - prog = ctx->Driver.NewProgram(ctx, target, shader_program->Name); - if (!prog) - return NULL; + prog = shader->Program; prog->Parameters = _mesa_new_parameter_list(); v.ctx = ctx; v.prog = prog; @@ -2929,9 +2927,6 @@ get_mesa_program(struct gl_context *ctx, prog->info.fs.depth_layout = shader_program->FragDepthLayout; } - /* Don't use _mesa_reference_program() just take ownership */ - shader->Program = prog; - if ((ctx->_Shader->Flags & GLSL_NO_OPT) == 0) { _mesa_optimize_program(ctx, prog, prog); } diff --git a/src/mesa/state_tracker/st_glsl_to_nir.cpp b/src/mesa/state_tracker/st_glsl_to_nir.cpp index 2d8cf81dcce..cbc7e5a693d 100644 --- a/src/mesa/state_tracker/st_glsl_to_nir.cpp +++ b/src/mesa/state_tracker/st_glsl_to_nir.cpp @@ -367,16 +367,10 @@ st_nir_get_mesa_program(struct gl_context *ctx, struct gl_linked_shader *shader) { struct gl_program *prog; - GLenum target = _mesa_shader_stage_to_program(shader->Stage); validate_ir_tree(shader->ir); - prog = ctx->Driver.NewProgram(ctx, target, shader_program->Name); - if (!prog) - return NULL; - - /* Don't use _mesa_reference_program() just take ownership */ - shader->Program = prog; + prog = shader->Program; prog->Parameters = _mesa_new_parameter_list(); diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp index b47e1470e3f..2c2bbb6c26b 100644 --- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp +++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp @@ -6407,7 +6407,6 @@ get_mesa_program_tgsi(struct gl_context *ctx, { glsl_to_tgsi_visitor* v; struct gl_program *prog; - GLenum target = _mesa_shader_stage_to_program(shader->Stage); struct gl_shader_compiler_options *options = &ctx->Const.ShaderCompilerOptions[shader->Stage]; struct pipe_screen *pscreen = ctx->st->pipe->screen; @@ -6415,12 +6414,7 @@ get_mesa_program_tgsi(struct gl_context *ctx, validate_ir_tree(shader->ir); - prog = ctx->Driver.NewProgram(ctx, target, shader_program->Name); - if (!prog) - return NULL; - - /* Don't use _mesa_reference_program() just take ownership */ - shader->Program = prog; + prog = shader->Program; prog->Parameters = _mesa_new_parameter_list(); v = new glsl_to_tgsi_visitor();