mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-18 09:28:06 +02:00
The GLSL 1.20 and later specs say:
"Recursion is not allowed, not even statically. Static recursion is
present if the static function call graph of the program contains
cycles."
Recursion is detected and rejected both a compile-time and at
link-time. The complie-time check happens to detect some cases that
may be removed by various optimization passes. The spec doesn't seem
to allow this, but other vendors (e.g., NVIDIA) appear to only check
at link-time after all optimizations.
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=33885
Reviewed-by: Paul Berry <stereotype441@gmail.com>
Reviewed-by: Eric Anholt <eric@anholt.net>
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
(cherry picked from commit 02c5ae1b3f)
This also squashes in the following commit to make sure that bisects
in scons builds work:
glsl: Add ir_function_detect_recursion.cpp to SConscript.
(cherry picked from commit 76bccaff0c)
182 lines
4.8 KiB
Python
182 lines
4.8 KiB
Python
import common
|
|
|
|
Import('*')
|
|
|
|
from sys import executable as python_cmd
|
|
|
|
env = env.Clone()
|
|
|
|
env.Prepend(CPPPATH = [
|
|
'#include',
|
|
'#src/mapi',
|
|
'#src/mesa',
|
|
'#src/glsl',
|
|
'#src/glsl/glcpp',
|
|
])
|
|
|
|
# Make glcpp/glcpp-parse.h and glsl_parser.h reacheable from the include path
|
|
env.Append(CPPPATH = [Dir('.').abspath])
|
|
|
|
env.Append(YACCFLAGS = '-d')
|
|
|
|
parser_env = env.Clone()
|
|
parser_env.Append(YACCFLAGS = [
|
|
'--defines=%s' % File('glsl_parser.h').abspath,
|
|
'-p', '_mesa_glsl_',
|
|
])
|
|
|
|
glcpp_lexer = env.CFile('glcpp/glcpp-lex.c', 'glcpp/glcpp-lex.l')
|
|
glcpp_parser = env.CFile('glcpp/glcpp-parse.c', 'glcpp/glcpp-parse.y')
|
|
glsl_lexer = parser_env.CXXFile('glsl_lexer.cpp', 'glsl_lexer.ll')
|
|
glsl_parser = parser_env.CXXFile('glsl_parser.cpp', 'glsl_parser.yy')
|
|
|
|
glsl_sources = [
|
|
glcpp_lexer,
|
|
glcpp_parser[0],
|
|
'glcpp/pp.c',
|
|
'ast_expr.cpp',
|
|
'ast_function.cpp',
|
|
'ast_to_hir.cpp',
|
|
'ast_type.cpp',
|
|
glsl_lexer,
|
|
glsl_parser[0],
|
|
'glsl_parser_extras.cpp',
|
|
'glsl_types.cpp',
|
|
'glsl_symbol_table.cpp',
|
|
'hir_field_selection.cpp',
|
|
'ir_basic_block.cpp',
|
|
'ir_clone.cpp',
|
|
'ir_constant_expression.cpp',
|
|
'ir.cpp',
|
|
'ir_expression_flattening.cpp',
|
|
'ir_function_can_inline.cpp',
|
|
'ir_function_detect_recursion.cpp',
|
|
'ir_function.cpp',
|
|
'ir_hierarchical_visitor.cpp',
|
|
'ir_hv_accept.cpp',
|
|
'ir_import_prototypes.cpp',
|
|
'ir_print_visitor.cpp',
|
|
'ir_reader.cpp',
|
|
'ir_rvalue_visitor.cpp',
|
|
'ir_set_program_inouts.cpp',
|
|
'ir_validate.cpp',
|
|
'ir_variable.cpp',
|
|
'ir_variable_refcount.cpp',
|
|
'linker.cpp',
|
|
'link_functions.cpp',
|
|
'loop_analysis.cpp',
|
|
'loop_controls.cpp',
|
|
'loop_unroll.cpp',
|
|
'lower_discard.cpp',
|
|
'lower_if_to_cond_assign.cpp',
|
|
'lower_instructions.cpp',
|
|
'lower_jumps.cpp',
|
|
'lower_mat_op_to_vec.cpp',
|
|
'lower_noise.cpp',
|
|
'lower_variable_index_to_cond_assign.cpp',
|
|
'lower_vec_index_to_cond_assign.cpp',
|
|
'lower_vec_index_to_swizzle.cpp',
|
|
'lower_vector.cpp',
|
|
'opt_algebraic.cpp',
|
|
'opt_constant_folding.cpp',
|
|
'opt_constant_propagation.cpp',
|
|
'opt_constant_variable.cpp',
|
|
'opt_copy_propagation.cpp',
|
|
'opt_copy_propagation_elements.cpp',
|
|
'opt_dead_code.cpp',
|
|
'opt_dead_code_local.cpp',
|
|
'opt_dead_functions.cpp',
|
|
'opt_discard_simplification.cpp',
|
|
'opt_function_inlining.cpp',
|
|
'opt_if_simplification.cpp',
|
|
'opt_noop_swizzle.cpp',
|
|
'opt_redundant_jumps.cpp',
|
|
'opt_structure_splitting.cpp',
|
|
'opt_swizzle_swizzle.cpp',
|
|
'opt_tree_grafting.cpp',
|
|
'ralloc.c',
|
|
's_expression.cpp',
|
|
'strtod.c',
|
|
]
|
|
|
|
if env['msvc']:
|
|
env.Prepend(CPPPATH = ['#/src/getopt'])
|
|
env.PrependUnique(LIBS = [getopt])
|
|
|
|
if env['crosscompile'] and not env['embedded']:
|
|
Import('builtin_glsl_function')
|
|
else:
|
|
# Copy these files to avoid generation object files into src/mesa/program
|
|
env.Prepend(CPPPATH = ['#src/mesa/program'])
|
|
env.Command('hash_table.c', '#src/mesa/program/hash_table.c', Copy('$TARGET', '$SOURCE'))
|
|
env.Command('symbol_table.c', '#src/mesa/program/symbol_table.c', Copy('$TARGET', '$SOURCE'))
|
|
|
|
main_obj = env.StaticObject('main.cpp')
|
|
|
|
mesa_objs = env.StaticObject([
|
|
'hash_table.c',
|
|
'symbol_table.c',
|
|
])
|
|
|
|
builtin_compiler = env.Program(
|
|
target = 'builtin_compiler',
|
|
source = main_obj + glsl_sources + ['builtin_stubs.cpp'] + mesa_objs,
|
|
)
|
|
|
|
# SCons builtin dependency scanner doesn't detect that glsl_lexer.ll
|
|
# depends on glsl_parser.h
|
|
env.Depends(builtin_compiler, glsl_parser)
|
|
|
|
builtin_glsl_function = env.CodeGenerate(
|
|
target = 'builtin_function.cpp',
|
|
script = 'builtins/tools/generate_builtins.py',
|
|
source = builtin_compiler,
|
|
command = python_cmd + ' $SCRIPT $SOURCE > $TARGET'
|
|
)
|
|
|
|
env.Depends(builtin_glsl_function, ['builtins/tools/generate_builtins.py', 'builtins/tools/texture_builtins.py'] + Glob('builtins/ir/*'))
|
|
|
|
Export('builtin_glsl_function')
|
|
|
|
if env['hostonly']:
|
|
Return()
|
|
|
|
|
|
glsl_sources += builtin_glsl_function
|
|
|
|
glsl = env.ConvenienceLibrary(
|
|
target = 'glsl',
|
|
source = glsl_sources,
|
|
)
|
|
|
|
# SCons builtin dependency scanner doesn't detect that glsl_lexer.ll depends on
|
|
# glsl_parser.h
|
|
env.Depends(glsl, glsl_parser)
|
|
|
|
Export('glsl')
|
|
|
|
# Skip building these programs as they will cause SCons error "Two environments
|
|
# with different actions were specified for the same target"
|
|
if env['crosscompile'] or env['embedded']:
|
|
Return()
|
|
|
|
env = env.Clone()
|
|
|
|
if env['platform'] == 'windows':
|
|
env.PrependUnique(LIBS = [
|
|
'user32',
|
|
])
|
|
|
|
env.Prepend(LIBS = [glsl])
|
|
|
|
glsl2 = env.Program(
|
|
target = 'glsl2',
|
|
source = main_obj + mesa_objs,
|
|
)
|
|
env.Alias('glsl2', glsl2)
|
|
|
|
glcpp = env.Program(
|
|
target = 'glcpp/glcpp',
|
|
source = ['glcpp/glcpp.c'] + mesa_objs,
|
|
)
|
|
env.Alias('glcpp', glcpp)
|