glsl: create gl_program at the start of linking rather than the end
authorTimothy Arceri <timothy.arceri@collabora.com>
Mon, 31 Oct 2016 12:54:03 +0000 (23:54 +1100)
committerTimothy Arceri <timothy.arceri@collabora.com>
Fri, 18 Nov 2016 20:42:33 +0000 (07:42 +1100)
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>
src/compiler/glsl/linker.cpp
src/mesa/drivers/dri/i965/brw_link.cpp
src/mesa/program/ir_to_mesa.cpp
src/mesa/state_tracker/st_glsl_to_nir.cpp
src/mesa/state_tracker/st_glsl_to_tgsi.cpp

index cc28b26964a46bd64b3576f17e7f04937338dfc3..e34cf286b54ead594bc6d0b6b59cbf02b327dc12 100644 (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);
 
index a0c9e20807c684788cd5c186a95f116b3bdc4140..3f6041b7ba2426493a37a2c0dbb1a00e742529f9 100644 (file)
@@ -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);
index 7f4212333f11b219601b4e92582f8c65547203b5..88a7f368ee176d1bd2ef87c16a5fb6abfb4695da 100644 (file)
@@ -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);
    }
index 2d8cf81dcce9c0f63ab528594429ef8c065b3eff..cbc7e5a693d35097ba5571b1985164faceffa0d5 100644 (file)
@@ -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();
 
index b47e1470e3f13dc656e0212a6c5b1663c2242cab..2c2bbb6c26b5926168ff60f7e55906e930f97a37 100644 (file)
@@ -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();