mesa: glsl: only try to link shaders defining main()
authorBrian Paul <brian.paul@tungstengraphics.com>
Thu, 24 Jul 2008 20:56:54 +0000 (14:56 -0600)
committerBrian Paul <brian.paul@tungstengraphics.com>
Tue, 29 Jul 2008 23:23:37 +0000 (17:23 -0600)
src/mesa/main/mtypes.h
src/mesa/shader/shader_api.c
src/mesa/shader/slang/slang_compile.c
src/mesa/shader/slang/slang_link.c

index 9339146e25cba9d4103dd108a4c6cf671ea82874..6f17e46d0eeeb62752afc05bc356494e4588bda6 100644 (file)
@@ -2105,9 +2105,9 @@ struct gl_shader
 
    const GLchar *Source;  /**< Source code string */
    GLboolean CompileStatus;
-   GLuint NumPrograms;  /**< size of Programs[] array */
-   struct gl_program **Programs;  /**< Post-compile assembly code */
+   struct gl_program *Program;  /**< Post-compile assembly code */
    GLchar *InfoLog;
+   GLboolean Main;  /**< shader defines main() */
 };
 
 
index 5a15ec9dc0309c9d36c5623a73af857322924362..a401803c3e9d09e7b688a6b558f8f3c500b077a9 100644 (file)
@@ -262,15 +262,11 @@ _mesa_new_shader(GLcontext *ctx, GLuint name, GLenum type)
 void
 _mesa_free_shader(GLcontext *ctx, struct gl_shader *sh)
 {
-   GLuint i;
    if (sh->Source)
       _mesa_free((void *) sh->Source);
    if (sh->InfoLog)
       _mesa_free(sh->InfoLog);
-   for (i = 0; i < sh->NumPrograms; i++)
-      _mesa_reference_program(ctx, &sh->Programs[i], NULL);
-   if (sh->Programs)
-      _mesa_free(sh->Programs);
+   _mesa_reference_program(ctx, &sh->Program, NULL);
    _mesa_free(sh);
 }
 
index a4e7b4a35b9a78b63cd87e62844e23528f399806..b43803b6dac8be8317c5c25ee0f02d98e1846157 100644 (file)
@@ -1930,7 +1930,7 @@ parse_invariant(slang_parse_ctx * C, slang_output_ctx * O)
 
 static GLboolean
 parse_code_unit(slang_parse_ctx * C, slang_code_unit * unit,
-                struct gl_program *program)
+                struct gl_shader *shader)
 {
    GET_CURRENT_CONTEXT(ctx);
    slang_output_ctx o;
@@ -1954,7 +1954,7 @@ parse_code_unit(slang_parse_ctx * C, slang_code_unit * unit,
    o.structs = &unit->structs;
    o.vars = &unit->vars;
    o.global_pool = &unit->object->varpool;
-   o.program = program;
+   o.program = shader ? shader->Program : NULL;
    o.vartable = _slang_new_var_table(maxRegs);
    _slang_push_var_table(o.vartable);
 
@@ -2007,6 +2007,7 @@ parse_code_unit(slang_parse_ctx * C, slang_code_unit * unit,
 
       _slang_codegen_function(&A, mainFunc);
 
+      shader->Main = GL_TRUE; /* this shader defines main() */
    }
 
    _slang_pop_var_table(o.vartable);
@@ -2020,7 +2021,7 @@ compile_binary(const byte * prod, slang_code_unit * unit,
                GLuint version,
                slang_unit_type type, slang_info_log * infolog,
                slang_code_unit * builtin, slang_code_unit * downlink,
-               struct gl_program *program)
+               struct gl_shader *shader)
 {
    slang_parse_ctx C;
 
@@ -2045,14 +2046,14 @@ compile_binary(const byte * prod, slang_code_unit * unit,
    }
 
    /* parse translation unit */
-   return parse_code_unit(&C, unit, program);
+   return parse_code_unit(&C, unit, shader);
 }
 
 static GLboolean
 compile_with_grammar(grammar id, const char *source, slang_code_unit * unit,
                      slang_unit_type type, slang_info_log * infolog,
                      slang_code_unit * builtin,
-                     struct gl_program *program)
+                     struct gl_shader *shader)
 {
    byte *prod;
    GLuint size, start, version;
@@ -2114,7 +2115,7 @@ compile_with_grammar(grammar id, const char *source, slang_code_unit * unit,
    /* Syntax is okay - translate it to internal representation. */
    if (!compile_binary(prod, unit, version, type, infolog, builtin,
                        &builtin[SLANG_BUILTIN_TOTAL - 1],
-                       program)) {
+                       shader)) {
       grammar_alloc_free(prod);
       return GL_FALSE;
    }
@@ -2153,7 +2154,7 @@ static const byte slang_vertex_builtin_gc[] = {
 static GLboolean
 compile_object(grammar * id, const char *source, slang_code_object * object,
                slang_unit_type type, slang_info_log * infolog,
-               struct gl_program *program)
+               struct gl_shader *shader)
 {
    slang_code_unit *builtins = NULL;
    GLuint base_version = 110;
@@ -2252,7 +2253,7 @@ compile_object(grammar * id, const char *source, slang_code_object * object,
 
    /* compile the actual shader - pass-in built-in library for external shader */
    return compile_with_grammar(*id, source, &object->unit, type, infolog,
-                               builtins, program);
+                               builtins, shader);
 }
 
 
@@ -2261,7 +2262,6 @@ compile_shader(GLcontext *ctx, slang_code_object * object,
                slang_unit_type type, slang_info_log * infolog,
                struct gl_shader *shader)
 {
-   struct gl_program *program = shader->Programs[0];
    GLboolean success;
    grammar id = 0;
 
@@ -2271,12 +2271,12 @@ compile_shader(GLcontext *ctx, slang_code_object * object,
    _mesa_printf("************************************\n");
 #endif
 
-   assert(program);
+   assert(shader->Program);
 
    _slang_code_object_dtr(object);
    _slang_code_object_ctr(object);
 
-   success = compile_object(&id, shader->Source, object, type, infolog, program);
+   success = compile_object(&id, shader->Source, object, type, infolog, shader);
    if (id != 0)
       grammar_destroy(id);
    if (!success)
@@ -2308,21 +2308,18 @@ _slang_compile(GLcontext *ctx, struct gl_shader *shader)
 
    ctx->Shader.MemPool = _slang_new_mempool(1024*1024);
 
-   /* XXX temporary hack */
-   if (!shader->Programs) {
+   shader->Main = GL_FALSE;
+
+   if (!shader->Program) {
       GLenum progTarget;
       if (shader->Type == GL_VERTEX_SHADER)
          progTarget = GL_VERTEX_PROGRAM_ARB;
       else
          progTarget = GL_FRAGMENT_PROGRAM_ARB;
-      shader->Programs
-         = (struct gl_program **) malloc(sizeof(struct gl_program*));
-      shader->Programs[0] = ctx->Driver.NewProgram(ctx, progTarget, 1);
-      shader->NumPrograms = 1;
-
-      shader->Programs[0]->Parameters = _mesa_new_parameter_list();
-      shader->Programs[0]->Varying = _mesa_new_parameter_list();
-      shader->Programs[0]->Attributes = _mesa_new_parameter_list();
+      shader->Program = ctx->Driver.NewProgram(ctx, progTarget, 1);
+      shader->Program->Parameters = _mesa_new_parameter_list();
+      shader->Program->Varying = _mesa_new_parameter_list();
+      shader->Program->Attributes = _mesa_new_parameter_list();
    }
 
    slang_info_log_construct(&info_log);
@@ -2355,13 +2352,13 @@ _slang_compile(GLcontext *ctx, struct gl_shader *shader)
       /* remove any reads of varying (output) registers */
 #if 0
       printf("Pre-remove output reads:\n");
-      _mesa_print_program(shader->Programs[0]);
+      _mesa_print_program(shader->Programs);
 #endif
-      _mesa_remove_output_reads(shader->Programs[0], PROGRAM_VARYING);
-      _mesa_remove_output_reads(shader->Programs[0], PROGRAM_OUTPUT);
+      _mesa_remove_output_reads(shader->Program, PROGRAM_VARYING);
+      _mesa_remove_output_reads(shader->Program, PROGRAM_OUTPUT);
 #if 0
       printf("Post-remove output reads:\n");
-      _mesa_print_program(shader->Programs[0]);
+      _mesa_print_program(shader->Programs);
 #endif
    }
 
index 8a66b78ec2e9a6b4593c2bcbf7d0367b8ac60ebf..26959d9d1514b975b5d5b92f763a69ec4294c928 100644 (file)
@@ -401,15 +401,16 @@ _slang_link(GLcontext *ctx,
    shProg->Varying = _mesa_new_parameter_list();
 
    /**
-    * Find attached vertex shader, fragment shader
+    * Find attached vertex, fragment shaders defining main()
     */
    vertProg = NULL;
    fragProg = NULL;
    for (i = 0; i < shProg->NumShaders; i++) {
-      if (shProg->Shaders[i]->Type == GL_VERTEX_SHADER)
-         vertProg = vertex_program(shProg->Shaders[i]->Programs[0]);
-      else if (shProg->Shaders[i]->Type == GL_FRAGMENT_SHADER)
-         fragProg = fragment_program(shProg->Shaders[i]->Programs[0]);
+      struct gl_shader *shader = shProg->Shaders[i];
+      if (shader->Type == GL_VERTEX_SHADER && shader->Main)
+         vertProg = vertex_program(shader->Program);
+      else if (shader->Type == GL_FRAGMENT_SHADER && shader->Main)
+         fragProg = fragment_program(shader->Program);
       else
          _mesa_problem(ctx, "unexpected shader target in slang_link()");
    }