Merge remote branch 'origin/master' into lp-setup-llvm
[mesa.git] / src / glsl / builtins / tools / generate_builtins.py
index 2eb67e398a6ab51550e937626185e0effa07d152..e8191ee9fdc9d786568b4eb3510a24432304297f 100755 (executable)
@@ -1,7 +1,8 @@
 #!/usr/bin/python
-# -*- coding: UTF-8 -*-
+# -*- coding: utf-8 -*-
 
-import re, glob, sys
+import re
+from glob import glob
 from os import path
 from subprocess import Popen, PIPE
 
@@ -12,7 +13,7 @@ builtins_dir = path.join(path.dirname(path.abspath(__file__)), "..")
 
 # Read the files in builtins/ir/*...add them to the supplied dictionary.
 def read_ir_files(fs):
-    for filename in glob.glob(path.join(path.join(builtins_dir, 'ir'), '*')):
+    for filename in glob(path.join(path.join(builtins_dir, 'ir'), '*')):
         with open(filename) as f:
             fs[path.basename(filename)] = f.read()
 
@@ -29,7 +30,7 @@ def stringify(s):
 
 def write_function_definitions():
     fs = get_builtin_definitions()
-    for k, v in fs.iteritems():
+    for k, v in sorted(fs.iteritems()):
         print 'static const char *builtin_' + k + ' ='
         print stringify(v), ';'
 
@@ -38,6 +39,14 @@ def run_compiler(args):
     command = [compiler_path, '--dump-lir'] + args
     p = Popen(command, 1, stdout=PIPE, shell=False)
     output = p.communicate()[0]
+
+    # Clean up output a bit by killing whitespace before a closing paren.
+    kill_paren_whitespace = re.compile(r'[ \n]*\)', re.MULTILINE);
+    output = kill_paren_whitespace.sub(')', output);
+
+    # Also toss any duplicate newlines
+    output = output.replace('\n\n', '\n')
+
     return (output, p.returncode)
 
 def write_profile(filename, profile):
@@ -51,6 +60,10 @@ def write_profile(filename, profile):
     kill_globals = re.compile(r'^\(declare.*\n', re.MULTILINE);
     proto_ir = kill_globals.sub('', proto_ir)
 
+    # Kill pointer addresses.  They're not necessary in prototypes and just
+    # clutter the diff output.
+    proto_ir = re.sub(r'@0x[0-9a-f]+', '', proto_ir);
+
     print 'static const char *prototypes_for_' + profile + ' ='
     print stringify(proto_ir), ';'
 
@@ -62,7 +75,7 @@ def write_profile(filename, profile):
         function_names.add(func.group(1))
 
     print 'static const char *functions_for_' + profile + ' [] = {'
-    for func in function_names:
+    for func in sorted(function_names):
         print '   builtin_' + func + ','
     print '};'
 
@@ -73,7 +86,7 @@ def write_profiles():
 
 def get_profile_list():
     profiles = []
-    for pfile in glob.glob(path.join(path.join(builtins_dir, 'profiles'), '*')):
+    for pfile in sorted(glob(path.join(path.join(builtins_dir, 'profiles'), '*'))):
         profiles.append((pfile, path.basename(pfile).replace('.', '_')))
     return profiles
 
@@ -103,23 +116,26 @@ if __name__ == "__main__":
  */
 
 #include <stdio.h>
-#include "main/compiler.h"
+#include "main/core.h" /* for struct gl_shader */
 #include "glsl_parser_extras.h"
 #include "ir_reader.h"
 #include "program.h"
 #include "ast.h"
 
 extern "C" struct gl_shader *
-_mesa_new_shader(GLcontext *ctx, GLuint name, GLenum type);
+_mesa_new_shader(struct gl_context *ctx, GLuint name, GLenum type);
 
 gl_shader *
 read_builtins(GLenum target, const char *protos, const char **functions, unsigned count)
 {
+   struct gl_context fakeCtx;
+   fakeCtx.API = API_OPENGL;
    gl_shader *sh = _mesa_new_shader(NULL, 0, target);
    struct _mesa_glsl_parse_state *st =
-      new(sh) _mesa_glsl_parse_state(NULL, target, sh);
+      new(sh) _mesa_glsl_parse_state(&fakeCtx, target, sh);
 
    st->language_version = 130;
+   st->symbols->language_version = 130;
    st->ARB_texture_rectangle_enable = true;
    st->EXT_texture_array_enable = true;
    _mesa_glsl_initialize_types(st);
@@ -139,6 +155,7 @@ read_builtins(GLenum target, const char *protos, const char **functions, unsigne
 
       if (st->error) {
          printf("error reading builtin: %.35s ...\\n", functions[i]);
+         printf("Info log:\\n%s\\n", st->info_log);
          talloc_free(sh);
          return NULL;
       }
@@ -154,26 +171,55 @@ read_builtins(GLenum target, const char *protos, const char **functions, unsigne
     write_function_definitions()
     write_profiles()
 
+    profiles = get_profile_list()
+
+    print 'static gl_shader *builtin_profiles[%d];' % len(profiles)
+
     print """
 void *builtin_mem_ctx = NULL;
 
 void
 _mesa_glsl_release_functions(void)
 {
-    talloc_free(builtin_mem_ctx);
+   talloc_free(builtin_mem_ctx);
+   builtin_mem_ctx = NULL;
+   memset(builtin_profiles, 0, sizeof(builtin_profiles));
+}
+
+static void
+_mesa_read_profile(struct _mesa_glsl_parse_state *state,
+                  exec_list *instructions,
+                   int profile_index,
+                  const char *prototypes,
+                  const char **functions,
+                   int count)
+{
+   gl_shader *sh = builtin_profiles[profile_index];
+
+   if (sh == NULL) {
+      sh = read_builtins(GL_VERTEX_SHADER, prototypes, functions, count);
+      talloc_steal(builtin_mem_ctx, sh);
+      builtin_profiles[profile_index] = sh;
+   }
+
+   import_prototypes(sh->ir, instructions, state->symbols, state);
+   state->builtins_to_link[state->num_builtins_to_link] = sh;
+   state->num_builtins_to_link++;
 }
 
 void
 _mesa_glsl_initialize_functions(exec_list *instructions,
                                 struct _mesa_glsl_parse_state *state)
 {
-   if (builtin_mem_ctx == NULL)
+   if (builtin_mem_ctx == NULL) {
       builtin_mem_ctx = talloc_init("GLSL built-in functions");
+      memset(&builtin_profiles, 0, sizeof(builtin_profiles));
+   }
 
    state->num_builtins_to_link = 0;
 """
 
-    profiles = get_profile_list()
+    i=0
     for (filename, profile) in profiles:
         if profile.endswith('_vert'):
             check = 'state->target == vertex_shader && '
@@ -187,21 +233,12 @@ _mesa_glsl_initialize_functions(exec_list *instructions,
             check += 'state->' + version + '_enable'
 
         print '   if (' + check + ') {'
-        print '      static gl_shader *sh = NULL;'
-        print '      if (sh == NULL) {'
-        print '         sh = read_builtins(GL_VERTEX_SHADER,'
-        print '                            prototypes_for_' + profile + ','
-        print '                            functions_for_' + profile + ','
-        print '                            Elements(functions_for_' + profile,
-        print '));'
-        print '         talloc_steal(builtin_mem_ctx, sh);'
-        print '      }'
-        print
-        print '      import_prototypes(sh->ir, instructions, state->symbols,'
-        print '                        state);'
-        print '      state->builtins_to_link[state->num_builtins_to_link] = sh;'
-        print '      state->num_builtins_to_link++;'
+        print '      _mesa_read_profile(state, instructions, %d,' % i
+        print '                         prototypes_for_' + profile + ','
+        print '                         functions_for_' + profile + ','
+        print '                         Elements(functions_for_' + profile + '));'
         print '   }'
         print
+        i = i + 1
     print '}'