2 # -*- coding: utf-8 -*-
7 from subprocess
import Popen
, PIPE
9 # Local module: generator for texture lookup builtins
10 from texture_builtins
import generate_texture_functions
12 builtins_dir
= path
.join(path
.dirname(path
.abspath(__file__
)), "..")
14 # Read the files in builtins/ir/*...add them to the supplied dictionary.
15 def read_ir_files(fs
):
16 for filename
in glob(path
.join(path
.join(builtins_dir
, 'ir'), '*')):
17 with
open(filename
) as f
:
18 fs
[path
.basename(filename
)] = f
.read()
20 # Return a dictionary containing all builtin definitions (even generated)
21 def get_builtin_definitions():
23 generate_texture_functions(fs
)
28 t
= s
.replace('\\', '\\\\').replace('"', '\\"').replace('\n', '\\n"\n "')
29 return ' "' + t
+ '"\n'
31 def write_function_definitions():
32 fs
= get_builtin_definitions()
33 for k
, v
in sorted(fs
.iteritems()):
34 print 'static const char *builtin_' + k
+ ' ='
35 print stringify(v
), ';'
37 def run_compiler(args
):
38 compiler_path
= path
.join(path
.join(builtins_dir
, '..'), 'glsl_compiler')
39 command
= [compiler_path
, '--dump-lir'] + args
40 p
= Popen(command
, 1, stdout
=PIPE
, shell
=False)
41 output
= p
.communicate()[0]
43 # Clean up output a bit by killing whitespace before a closing paren.
44 kill_paren_whitespace
= re
.compile(r
'[ \n]*\)', re
.MULTILINE
);
45 output
= kill_paren_whitespace
.sub(')', output
);
47 # Also toss any duplicate newlines
48 output
= output
.replace('\n\n', '\n')
50 return (output
, p
.returncode
)
52 def write_profile(filename
, profile
):
53 (proto_ir
, returncode
) = run_compiler([filename
])
56 print '#error builtins profile', profile
, 'failed to compile'
59 # Kill any global variable declarations. We don't want them.
60 kill_globals
= re
.compile(r
'^\(declare.*\n', re
.MULTILINE
);
61 proto_ir
= kill_globals
.sub('', proto_ir
)
63 # Kill pointer addresses. They're not necessary in prototypes and just
64 # clutter the diff output.
65 proto_ir
= re
.sub(r
'@0x[0-9a-f]+', '', proto_ir
);
67 print 'static const char *prototypes_for_' + profile
+ ' ='
68 print stringify(proto_ir
), ';'
70 # Print a table of all the functions (not signatures) referenced.
71 # This is done so we can avoid bothering with a hash table in the C++ code.
73 function_names
= set()
74 for func
in re
.finditer(r
'\(function (.+)\n', proto_ir
):
75 function_names
.add(func
.group(1))
77 print 'static const char *functions_for_' + profile
+ ' [] = {'
78 for func
in sorted(function_names
):
79 print ' builtin_' + func
+ ','
83 profiles
= get_profile_list()
84 for (filename
, profile
) in profiles
:
85 write_profile(filename
, profile
)
87 def get_profile_list():
89 for pfile
in sorted(glob(path
.join(path
.join(builtins_dir
, 'profiles'), '*'))):
90 profiles
.append((pfile
, path
.basename(pfile
).replace('.', '_')))
93 if __name__
== "__main__":
94 print """/* DO NOT MODIFY - automatically generated by generate_builtins.py */
96 * Copyright © 2010 Intel Corporation
98 * Permission is hereby granted, free of charge, to any person obtaining a
99 * copy of this software and associated documentation files (the "Software"),
100 * to deal in the Software without restriction, including without limitation
101 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
102 * and/or sell copies of the Software, and to permit persons to whom the
103 * Software is furnished to do so, subject to the following conditions:
105 * The above copyright notice and this permission notice (including the next
106 * paragraph) shall be included in all copies or substantial portions of the
109 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
110 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
111 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
112 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
113 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
114 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
115 * DEALINGS IN THE SOFTWARE.
119 #include "main/core.h" /* for struct gl_shader */
120 #include "glsl_parser_extras.h"
121 #include "ir_reader.h"
125 extern "C" struct gl_shader *
126 _mesa_new_shader(GLcontext *ctx, GLuint name, GLenum type);
129 read_builtins(GLenum target, const char *protos, const char **functions, unsigned count)
131 gl_shader *sh = _mesa_new_shader(NULL, 0, target);
132 struct _mesa_glsl_parse_state *st =
133 new(sh) _mesa_glsl_parse_state(NULL, target, sh);
135 st->language_version = 130;
136 st->symbols->language_version = 130;
137 st->ARB_texture_rectangle_enable = true;
138 st->EXT_texture_array_enable = true;
139 _mesa_glsl_initialize_types(st);
141 sh->ir = new(sh) exec_list;
142 sh->symbols = st->symbols;
144 /* Read the IR containing the prototypes */
145 _mesa_glsl_read_ir(st, sh->ir, protos, true);
147 /* Read ALL the function bodies, telling the IR reader not to scan for
148 * prototypes (we've already created them). The IR reader will skip any
149 * signature that does not already exist as a prototype.
151 for (unsigned i = 0; i < count; i++) {
152 _mesa_glsl_read_ir(st, sh->ir, functions[i], false);
155 printf("error reading builtin: %.35s ...\\n", functions[i]);
161 reparent_ir(sh->ir, sh);
168 write_function_definitions()
171 profiles
= get_profile_list()
173 print 'static gl_shader *builtin_profiles[%d];' % len(profiles
)
176 void *builtin_mem_ctx = NULL;
179 _mesa_glsl_release_functions(void)
181 talloc_free(builtin_mem_ctx);
182 builtin_mem_ctx = NULL;
186 _mesa_read_profile(struct _mesa_glsl_parse_state *state,
187 exec_list *instructions,
189 const char *prototypes,
190 const char **functions,
193 gl_shader *sh = builtin_profiles[profile_index];
196 sh = read_builtins(GL_VERTEX_SHADER, prototypes, functions, count);
197 talloc_steal(builtin_mem_ctx, sh);
198 builtin_profiles[profile_index] = sh;
201 import_prototypes(sh->ir, instructions, state->symbols, state);
202 state->builtins_to_link[state->num_builtins_to_link] = sh;
203 state->num_builtins_to_link++;
207 _mesa_glsl_initialize_functions(exec_list *instructions,
208 struct _mesa_glsl_parse_state *state)
210 if (builtin_mem_ctx == NULL) {
211 builtin_mem_ctx = talloc_init("GLSL built-in functions");
212 memset(&builtin_profiles, 0, sizeof(builtin_profiles));
215 state->num_builtins_to_link = 0;
219 for (filename
, profile
) in profiles
:
220 if profile
.endswith('_vert'):
221 check
= 'state->target == vertex_shader && '
222 elif profile
.endswith('_frag'):
223 check
= 'state->target == fragment_shader && '
225 version
= re
.sub(r
'_(vert|frag)$', '', profile
)
226 if version
.isdigit():
227 check
+= 'state->language_version == ' + version
228 else: # an extension name
229 check
+= 'state->' + version
+ '_enable'
231 print ' if (' + check
+ ') {'
232 print ' _mesa_read_profile(state, instructions, %d,' % i
233 print ' prototypes_for_' + profile
+ ','
234 print ' functions_for_' + profile
+ ','
235 print ' Elements(functions_for_' + profile
+ '));'