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 <emil.velikov@collabora.com>
This commit is contained in:
Timothy Arceri
2016-10-31 23:54:03 +11:00
parent 2b8f97d0ff
commit 9d96d3803a
5 changed files with 20 additions and 29 deletions

View File

@@ -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);