mirror of
https://github.com/reactos/reactos.git
synced 2024-06-29 01:12:06 +00:00
[MESA]
- leaner build part 13 of X - Get rid of shaders and programs support (with assorted extensions), ARB_multitexture and ATI_envmap_bumpmap extensions. CORE-7499 svn path=/trunk/; revision=60576
This commit is contained in:
parent
41eb82dace
commit
c73334d7d3
|
@ -1,3 +1,2 @@
|
|||
|
||||
add_subdirectory(glsl)
|
||||
add_subdirectory(mesa)
|
||||
|
|
|
@ -1,88 +0,0 @@
|
|||
|
||||
set_cpp(WITH_STL)
|
||||
|
||||
# From Sconscript
|
||||
include_directories(
|
||||
../mapi
|
||||
../mesa
|
||||
.
|
||||
glcpp
|
||||
../../generated/glsl)
|
||||
|
||||
list(APPEND SOURCE
|
||||
# generated files
|
||||
../../generated/glsl/glcpp/glcpp-lex.c
|
||||
../../generated/glsl/glcpp/glcpp-parse.c
|
||||
../../generated/glsl/glsl_lexer.cpp
|
||||
../../generated/glsl/glsl_parser.cpp
|
||||
../../generated/glsl/builtin_function.cpp
|
||||
# Regular files
|
||||
strtod.c
|
||||
ralloc.c
|
||||
glcpp/pp.c
|
||||
ast_expr.cpp
|
||||
ast_function.cpp
|
||||
ast_to_hir.cpp
|
||||
ast_type.cpp
|
||||
builtin_variables.cpp
|
||||
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_refcount.cpp
|
||||
linker.cpp
|
||||
link_functions.cpp
|
||||
link_uniforms.cpp
|
||||
loop_analysis.cpp
|
||||
loop_controls.cpp
|
||||
loop_unroll.cpp
|
||||
lower_clip_distance.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_texture_projection.cpp
|
||||
lower_variable_index_to_cond_assign.cpp
|
||||
lower_vec_index_to_cond_assign.cpp
|
||||
lower_vec_index_to_swizzle.cpp
|
||||
lower_vector.cpp
|
||||
lower_output_reads.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
|
||||
s_expression.cpp)
|
||||
|
||||
# this is just a helper library, don't include it in the all target
|
||||
add_library(mesa_glsl STATIC EXCLUDE_FROM_ALL ${SOURCE})
|
|
@ -1,105 +0,0 @@
|
|||
# shared source lists for Makefile, SConscript, and Android.mk
|
||||
|
||||
# libglcpp
|
||||
|
||||
LIBGLCPP_SOURCES := \
|
||||
glcpp/pp.c
|
||||
|
||||
LIBGLCPP_GENERATED_SOURCES := \
|
||||
glcpp/glcpp-lex.c \
|
||||
glcpp/glcpp-parse.c
|
||||
|
||||
# libglsl
|
||||
|
||||
LIBGLSL_SOURCES := \
|
||||
strtod.c \
|
||||
ralloc.c
|
||||
|
||||
LIBGLSL_CXX_SOURCES := \
|
||||
ast_expr.cpp \
|
||||
ast_function.cpp \
|
||||
ast_to_hir.cpp \
|
||||
ast_type.cpp \
|
||||
builtin_variables.cpp \
|
||||
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_refcount.cpp \
|
||||
linker.cpp \
|
||||
link_functions.cpp \
|
||||
link_uniforms.cpp \
|
||||
loop_analysis.cpp \
|
||||
loop_controls.cpp \
|
||||
loop_unroll.cpp \
|
||||
lower_clip_distance.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_texture_projection.cpp \
|
||||
lower_variable_index_to_cond_assign.cpp \
|
||||
lower_vec_index_to_cond_assign.cpp \
|
||||
lower_vec_index_to_swizzle.cpp \
|
||||
lower_vector.cpp \
|
||||
lower_output_reads.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 \
|
||||
s_expression.cpp
|
||||
|
||||
# glsl_compiler
|
||||
|
||||
GLSL_COMPILER_CXX_SOURCES := \
|
||||
standalone_scaffolding.cpp \
|
||||
main.cpp
|
||||
|
||||
# builtin_compiler
|
||||
#
|
||||
# This is built before libglsl to generate builtin_funciton.cpp for libglsl.
|
||||
# For this to work, a dummy version of builtin_function.cpp,
|
||||
# builtin_stubs.cpp, is used.
|
||||
|
||||
BUILTIN_COMPILER_CXX_SOURCES := \
|
||||
builtin_stubs.cpp
|
||||
|
||||
BUILTIN_COMPILER_GENERATED_CXX_SOURCES := \
|
||||
glsl_lexer.cpp \
|
||||
glsl_parser.cpp
|
||||
|
||||
# libglsl generated sources
|
||||
LIBGLSL_GENERATED_CXX_SOURCES := \
|
||||
$(BUILTIN_COMPILER_GENERATED_CXX_SOURCES) \
|
||||
builtin_function.cpp
|
|
@ -1,229 +0,0 @@
|
|||
Welcome to Mesa's GLSL compiler. A brief overview of how things flow:
|
||||
|
||||
1) lex and yacc-based preprocessor takes the incoming shader string
|
||||
and produces a new string containing the preprocessed shader. This
|
||||
takes care of things like #if, #ifdef, #define, and preprocessor macro
|
||||
invocations. Note that #version, #extension, and some others are
|
||||
passed straight through. See glcpp/*
|
||||
|
||||
2) lex and yacc-based parser takes the preprocessed string and
|
||||
generates the AST (abstract syntax tree). Almost no checking is
|
||||
performed in this stage. See glsl_lexer.lpp and glsl_parser.ypp.
|
||||
|
||||
3) The AST is converted to "HIR". This is the intermediate
|
||||
representation of the compiler. Constructors are generated, function
|
||||
calls are resolved to particular function signatures, and all the
|
||||
semantic checking is performed. See ast_*.cpp for the conversion, and
|
||||
ir.h for the IR structures.
|
||||
|
||||
4) The driver (Mesa, or main.cpp for the standalone binary) performs
|
||||
optimizations. These include copy propagation, dead code elimination,
|
||||
constant folding, and others. Generally the driver will call
|
||||
optimizations in a loop, as each may open up opportunities for other
|
||||
optimizations to do additional work. See most files called ir_*.cpp
|
||||
|
||||
5) linking is performed. This does checking to ensure that the
|
||||
outputs of the vertex shader match the inputs of the fragment shader,
|
||||
and assigns locations to uniforms, attributes, and varyings. See
|
||||
linker.cpp.
|
||||
|
||||
6) The driver may perform additional optimization at this point, as
|
||||
for example dead code elimination previously couldn't remove functions
|
||||
or global variable usage when we didn't know what other code would be
|
||||
linked in.
|
||||
|
||||
7) The driver performs code generation out of the IR, taking a linked
|
||||
shader program and producing a compiled program for each stage. See
|
||||
ir_to_mesa.cpp for Mesa IR code generation.
|
||||
|
||||
FAQ:
|
||||
|
||||
Q: What is HIR versus IR versus LIR?
|
||||
|
||||
A: The idea behind the naming was that ast_to_hir would produce a
|
||||
high-level IR ("HIR"), with things like matrix operations, structure
|
||||
assignments, etc., present. A series of lowering passes would occur
|
||||
that do things like break matrix multiplication into a series of dot
|
||||
products/MADs, make structure assignment be a series of assignment of
|
||||
components, flatten if statements into conditional moves, and such,
|
||||
producing a low level IR ("LIR").
|
||||
|
||||
However, it now appears that each driver will have different
|
||||
requirements from a LIR. A 915-generation chipset wants all functions
|
||||
inlined, all loops unrolled, all ifs flattened, no variable array
|
||||
accesses, and matrix multiplication broken down. The Mesa IR backend
|
||||
for swrast would like matrices and structure assignment broken down,
|
||||
but it can support function calls and dynamic branching. A 965 vertex
|
||||
shader IR backend could potentially even handle some matrix operations
|
||||
without breaking them down, but the 965 fragment shader IR backend
|
||||
would want to break to have (almost) all operations down channel-wise
|
||||
and perform optimization on that. As a result, there's no single
|
||||
low-level IR that will make everyone happy. So that usage has fallen
|
||||
out of favor, and each driver will perform a series of lowering passes
|
||||
to take the HIR down to whatever restrictions it wants to impose
|
||||
before doing codegen.
|
||||
|
||||
Q: How is the IR structured?
|
||||
|
||||
A: The best way to get started seeing it would be to run the
|
||||
standalone compiler against a shader:
|
||||
|
||||
./glsl_compiler --dump-lir \
|
||||
~/src/piglit/tests/shaders/glsl-orangebook-ch06-bump.frag
|
||||
|
||||
So for example one of the ir_instructions in main() contains:
|
||||
|
||||
(assign (constant bool (1)) (var_ref litColor) (expression vec3 * (var_ref Surf
|
||||
aceColor) (var_ref __retval) ) )
|
||||
|
||||
Or more visually:
|
||||
(assign)
|
||||
/ | \
|
||||
(var_ref) (expression *) (constant bool 1)
|
||||
/ / \
|
||||
(litColor) (var_ref) (var_ref)
|
||||
/ \
|
||||
(SurfaceColor) (__retval)
|
||||
|
||||
which came from:
|
||||
|
||||
litColor = SurfaceColor * max(dot(normDelta, LightDir), 0.0);
|
||||
|
||||
(the max call is not represented in this expression tree, as it was a
|
||||
function call that got inlined but not brought into this expression
|
||||
tree)
|
||||
|
||||
Each of those nodes is a subclass of ir_instruction. A particular
|
||||
ir_instruction instance may only appear once in the whole IR tree with
|
||||
the exception of ir_variables, which appear once as variable
|
||||
declarations:
|
||||
|
||||
(declare () vec3 normDelta)
|
||||
|
||||
and multiple times as the targets of variable dereferences:
|
||||
...
|
||||
(assign (constant bool (1)) (var_ref __retval) (expression float dot
|
||||
(var_ref normDelta) (var_ref LightDir) ) )
|
||||
...
|
||||
(assign (constant bool (1)) (var_ref __retval) (expression vec3 -
|
||||
(var_ref LightDir) (expression vec3 * (constant float (2.000000))
|
||||
(expression vec3 * (expression float dot (var_ref normDelta) (var_ref
|
||||
LightDir) ) (var_ref normDelta) ) ) ) )
|
||||
...
|
||||
|
||||
Each node has a type. Expressions may involve several different types:
|
||||
(declare (uniform ) mat4 gl_ModelViewMatrix)
|
||||
((assign (constant bool (1)) (var_ref constructor_tmp) (expression
|
||||
vec4 * (var_ref gl_ModelViewMatrix) (var_ref gl_Vertex) ) )
|
||||
|
||||
An expression tree can be arbitrarily deep, and the compiler tries to
|
||||
keep them structured like that so that things like algebraic
|
||||
optimizations ((color * 1.0 == color) and ((mat1 * mat2) * vec == mat1
|
||||
* (mat2 * vec))) or recognizing operation patterns for code generation
|
||||
(vec1 * vec2 + vec3 == mad(vec1, vec2, vec3)) are easier. This comes
|
||||
at the expense of additional trickery in implementing some
|
||||
optimizations like CSE where one must navigate an expression tree.
|
||||
|
||||
Q: Why no SSA representation?
|
||||
|
||||
A: Converting an IR tree to SSA form makes dead code elmimination,
|
||||
common subexpression elimination, and many other optimizations much
|
||||
easier. However, in our primarily vector-based language, there's some
|
||||
major questions as to how it would work. Do we do SSA on the scalar
|
||||
or vector level? If we do it at the vector level, we're going to end
|
||||
up with many different versions of the variable when encountering code
|
||||
like:
|
||||
|
||||
(assign (constant bool (1)) (swiz x (var_ref __retval) ) (var_ref a) )
|
||||
(assign (constant bool (1)) (swiz y (var_ref __retval) ) (var_ref b) )
|
||||
(assign (constant bool (1)) (swiz z (var_ref __retval) ) (var_ref c) )
|
||||
|
||||
If every masked update of a component relies on the previous value of
|
||||
the variable, then we're probably going to be quite limited in our
|
||||
dead code elimination wins, and recognizing common expressions may
|
||||
just not happen. On the other hand, if we operate channel-wise, then
|
||||
we'll be prone to optimizing the operation on one of the channels at
|
||||
the expense of making its instruction flow different from the other
|
||||
channels, and a vector-based GPU would end up with worse code than if
|
||||
we didn't optimize operations on that channel!
|
||||
|
||||
Once again, it appears that our optimization requirements are driven
|
||||
significantly by the target architecture. For now, targeting the Mesa
|
||||
IR backend, SSA does not appear to be that important to producing
|
||||
excellent code, but we do expect to do some SSA-based optimizations
|
||||
for the 965 fragment shader backend when that is developed.
|
||||
|
||||
Q: How should I expand instructions that take multiple backend instructions?
|
||||
|
||||
Sometimes you'll have to do the expansion in your code generation --
|
||||
see, for example, ir_to_mesa.cpp's handling of ir_unop_sqrt. However,
|
||||
in many cases you'll want to do a pass over the IR to convert
|
||||
non-native instructions to a series of native instructions. For
|
||||
example, for the Mesa backend we have ir_div_to_mul_rcp.cpp because
|
||||
Mesa IR (and many hardware backends) only have a reciprocal
|
||||
instruction, not a divide. Implementing non-native instructions this
|
||||
way gives the chance for constant folding to occur, so (a / 2.0)
|
||||
becomes (a * 0.5) after codegen instead of (a * (1.0 / 2.0))
|
||||
|
||||
Q: How shoud I handle my special hardware instructions with respect to IR?
|
||||
|
||||
Our current theory is that if multiple targets have an instruction for
|
||||
some operation, then we should probably be able to represent that in
|
||||
the IR. Generally this is in the form of an ir_{bin,un}op expression
|
||||
type. For example, we initially implemented fract() using (a -
|
||||
floor(a)), but both 945 and 965 have instructions to give that result,
|
||||
and it would also simplify the implementation of mod(), so
|
||||
ir_unop_fract was added. The following areas need updating to add a
|
||||
new expression type:
|
||||
|
||||
ir.h (new enum)
|
||||
ir.cpp:get_num_operands() (used for ir_reader)
|
||||
ir.cpp:operator_strs (used for ir_reader)
|
||||
ir_constant_expression.cpp (you probably want to be able to constant fold)
|
||||
ir_validate.cpp (check users have the right types)
|
||||
|
||||
You may also need to update the backends if they will see the new expr type:
|
||||
|
||||
../mesa/shaders/ir_to_mesa.cpp
|
||||
|
||||
You can then use the new expression from builtins (if all backends
|
||||
would rather see it), or scan the IR and convert to use your new
|
||||
expression type (see ir_mod_to_fract, for example).
|
||||
|
||||
Q: How is memory management handled in the compiler?
|
||||
|
||||
The hierarchical memory allocator "talloc" developed for the Samba
|
||||
project is used, so that things like optimization passes don't have to
|
||||
worry about their garbage collection so much. It has a few nice
|
||||
features, including low performance overhead and good debugging
|
||||
support that's trivially available.
|
||||
|
||||
Generally, each stage of the compile creates a talloc context and
|
||||
allocates its memory out of that or children of it. At the end of the
|
||||
stage, the pieces still live are stolen to a new context and the old
|
||||
one freed, or the whole context is kept for use by the next stage.
|
||||
|
||||
For IR transformations, a temporary context is used, then at the end
|
||||
of all transformations, reparent_ir reparents all live nodes under the
|
||||
shader's IR list, and the old context full of dead nodes is freed.
|
||||
When developing a single IR transformation pass, this means that you
|
||||
want to allocate instruction nodes out of the temporary context, so if
|
||||
it becomes dead it doesn't live on as the child of a live node. At
|
||||
the moment, optimization passes aren't passed that temporary context,
|
||||
so they find it by calling talloc_parent() on a nearby IR node. The
|
||||
talloc_parent() call is expensive, so many passes will cache the
|
||||
result of the first talloc_parent(). Cleaning up all the optimization
|
||||
passes to take a context argument and not call talloc_parent() is left
|
||||
as an exercise.
|
||||
|
||||
Q: What is the file naming convention in this directory?
|
||||
|
||||
Initially, there really wasn't one. We have since adopted one:
|
||||
|
||||
- Files that implement code lowering passes should be named lower_*
|
||||
(e.g., lower_noise.cpp).
|
||||
- Files that implement optimization passes should be named opt_*.
|
||||
- Files that implement a class that is used throught the code should
|
||||
take the name of that class (e.g., ir_hierarchical_visitor.cpp).
|
||||
- Files that contain code not fitting in one of the previous
|
||||
categories should have a sensible name (e.g., glsl_parser.ypp).
|
|
@ -1,131 +0,0 @@
|
|||
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')
|
||||
|
||||
# common generated sources
|
||||
glsl_sources = [
|
||||
glcpp_lexer,
|
||||
glcpp_parser[0],
|
||||
glsl_lexer,
|
||||
glsl_parser[0],
|
||||
]
|
||||
|
||||
# parse Makefile.sources
|
||||
source_lists = env.ParseSourceList('Makefile.sources')
|
||||
|
||||
# add non-generated sources
|
||||
for l in ('LIBGLCPP_SOURCES', 'LIBGLSL_SOURCES', 'LIBGLSL_CXX_SOURCES'):
|
||||
glsl_sources += source_lists[l]
|
||||
|
||||
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'))
|
||||
|
||||
compiler_objs = env.StaticObject(source_lists['GLSL_COMPILER_CXX_SOURCES'])
|
||||
|
||||
mesa_objs = env.StaticObject([
|
||||
'hash_table.c',
|
||||
'symbol_table.c',
|
||||
])
|
||||
|
||||
compiler_objs += mesa_objs
|
||||
|
||||
builtin_compiler = env.Program(
|
||||
target = 'builtin_compiler',
|
||||
source = compiler_objs + glsl_sources + \
|
||||
source_lists['BUILTIN_COMPILER_CXX_SOURCES'],
|
||||
)
|
||||
|
||||
# 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 = compiler_objs,
|
||||
)
|
||||
env.Alias('glsl2', glsl2)
|
||||
|
||||
glcpp = env.Program(
|
||||
target = 'glcpp/glcpp',
|
||||
source = ['glcpp/glcpp.c'] + mesa_objs,
|
||||
)
|
||||
env.Alias('glcpp', glcpp)
|
|
@ -1,27 +0,0 @@
|
|||
- Detect code paths in non-void functions that don't reach a return statement
|
||||
|
||||
- Improve handling of constants and their initializers. Constant initializers
|
||||
should never generate any code. This is trival for scalar constants. It is
|
||||
also trivial for arrays, matrices, and vectors that are accessed with
|
||||
constant index values. For others it is more complicated. Perhaps these
|
||||
cases should be silently converted to uniforms?
|
||||
|
||||
- Implement support for ir_binop_dot in ir_algebraic.cpp. Perform
|
||||
transformations such as "dot(v, vec3(0.0, 1.0, 0.0))" -> v.y.
|
||||
|
||||
- Track source locations throughout the IR. There are currently several
|
||||
places where we cannot emit line numbers for errors (and currently emit 0:0)
|
||||
because we've "lost" the line number information. This is particularly
|
||||
noticeable at link time.
|
||||
|
||||
1.30 features:
|
||||
|
||||
- Implement AST-to-HIR conversion of switch-statements
|
||||
- switch
|
||||
- case
|
||||
- Update break to correcly handle mixed nexting of switch-statements
|
||||
and loops.
|
||||
|
||||
- Implement support for gl_ClipDistance. This is non-trivial because
|
||||
gl_ClipDistance is exposed as a float[8], but all hardware actually
|
||||
implements it as vec4[2].
|
|
@ -1,804 +0,0 @@
|
|||
/* -*- c++ -*- */
|
||||
/*
|
||||
* Copyright © 2009 Intel Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef AST_H
|
||||
#define AST_H
|
||||
|
||||
#include "list.h"
|
||||
#include "glsl_parser_extras.h"
|
||||
|
||||
struct _mesa_glsl_parse_state;
|
||||
|
||||
struct YYLTYPE;
|
||||
|
||||
/**
|
||||
* \defgroup AST Abstract syntax tree node definitions
|
||||
*
|
||||
* An abstract syntax tree is generated by the parser. This is a fairly
|
||||
* direct representation of the gramma derivation for the source program.
|
||||
* No symantic checking is done during the generation of the AST. Only
|
||||
* syntactic checking is done. Symantic checking is performed by a later
|
||||
* stage that converts the AST to a more generic intermediate representation.
|
||||
*
|
||||
*@{
|
||||
*/
|
||||
/**
|
||||
* Base class of all abstract syntax tree nodes
|
||||
*/
|
||||
class ast_node {
|
||||
public:
|
||||
/* Callers of this ralloc-based new need not call delete. It's
|
||||
* easier to just ralloc_free 'ctx' (or any of its ancestors). */
|
||||
static void* operator new(size_t size, void *ctx)
|
||||
{
|
||||
void *node;
|
||||
|
||||
node = rzalloc_size(ctx, size);
|
||||
assert(node != NULL);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
/* If the user *does* call delete, that's OK, we will just
|
||||
* ralloc_free in that case. */
|
||||
static void operator delete(void *table)
|
||||
{
|
||||
ralloc_free(table);
|
||||
}
|
||||
|
||||
/**
|
||||
* Print an AST node in something approximating the original GLSL code
|
||||
*/
|
||||
virtual void print(void) const;
|
||||
|
||||
/**
|
||||
* Convert the AST node to the high-level intermediate representation
|
||||
*/
|
||||
virtual ir_rvalue *hir(exec_list *instructions,
|
||||
struct _mesa_glsl_parse_state *state);
|
||||
|
||||
/**
|
||||
* Retrieve the source location of an AST node
|
||||
*
|
||||
* This function is primarily used to get the source position of an AST node
|
||||
* into a form that can be passed to \c _mesa_glsl_error.
|
||||
*
|
||||
* \sa _mesa_glsl_error, ast_node::set_location
|
||||
*/
|
||||
struct YYLTYPE get_location(void) const
|
||||
{
|
||||
struct YYLTYPE locp;
|
||||
|
||||
locp.source = this->location.source;
|
||||
locp.first_line = this->location.line;
|
||||
locp.first_column = this->location.column;
|
||||
locp.last_line = locp.first_line;
|
||||
locp.last_column = locp.first_column;
|
||||
|
||||
return locp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the source location of an AST node from a parser location
|
||||
*
|
||||
* \sa ast_node::get_location
|
||||
*/
|
||||
void set_location(const struct YYLTYPE &locp)
|
||||
{
|
||||
this->location.source = locp.source;
|
||||
this->location.line = locp.first_line;
|
||||
this->location.column = locp.first_column;
|
||||
}
|
||||
|
||||
/**
|
||||
* Source location of the AST node.
|
||||
*/
|
||||
struct {
|
||||
unsigned source; /**< GLSL source number. */
|
||||
unsigned line; /**< Line number within the source string. */
|
||||
unsigned column; /**< Column in the line. */
|
||||
} location;
|
||||
|
||||
exec_node link;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* The only constructor is protected so that only derived class objects can
|
||||
* be created.
|
||||
*/
|
||||
ast_node(void);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Operators for AST expression nodes.
|
||||
*/
|
||||
enum ast_operators {
|
||||
ast_assign,
|
||||
ast_plus, /**< Unary + operator. */
|
||||
ast_neg,
|
||||
ast_add,
|
||||
ast_sub,
|
||||
ast_mul,
|
||||
ast_div,
|
||||
ast_mod,
|
||||
ast_lshift,
|
||||
ast_rshift,
|
||||
ast_less,
|
||||
ast_greater,
|
||||
ast_lequal,
|
||||
ast_gequal,
|
||||
ast_equal,
|
||||
ast_nequal,
|
||||
ast_bit_and,
|
||||
ast_bit_xor,
|
||||
ast_bit_or,
|
||||
ast_bit_not,
|
||||
ast_logic_and,
|
||||
ast_logic_xor,
|
||||
ast_logic_or,
|
||||
ast_logic_not,
|
||||
|
||||
ast_mul_assign,
|
||||
ast_div_assign,
|
||||
ast_mod_assign,
|
||||
ast_add_assign,
|
||||
ast_sub_assign,
|
||||
ast_ls_assign,
|
||||
ast_rs_assign,
|
||||
ast_and_assign,
|
||||
ast_xor_assign,
|
||||
ast_or_assign,
|
||||
|
||||
ast_conditional,
|
||||
|
||||
ast_pre_inc,
|
||||
ast_pre_dec,
|
||||
ast_post_inc,
|
||||
ast_post_dec,
|
||||
ast_field_selection,
|
||||
ast_array_index,
|
||||
|
||||
ast_function_call,
|
||||
|
||||
ast_identifier,
|
||||
ast_int_constant,
|
||||
ast_uint_constant,
|
||||
ast_float_constant,
|
||||
ast_bool_constant,
|
||||
|
||||
ast_sequence
|
||||
};
|
||||
|
||||
/**
|
||||
* Representation of any sort of expression.
|
||||
*/
|
||||
class ast_expression : public ast_node {
|
||||
public:
|
||||
ast_expression(int oper, ast_expression *,
|
||||
ast_expression *, ast_expression *);
|
||||
|
||||
ast_expression(const char *identifier) :
|
||||
oper(ast_identifier)
|
||||
{
|
||||
subexpressions[0] = NULL;
|
||||
subexpressions[1] = NULL;
|
||||
subexpressions[2] = NULL;
|
||||
primary_expression.identifier = (char *) identifier;
|
||||
this->non_lvalue_description = NULL;
|
||||
}
|
||||
|
||||
static const char *operator_string(enum ast_operators op);
|
||||
|
||||
virtual ir_rvalue *hir(exec_list *instructions,
|
||||
struct _mesa_glsl_parse_state *state);
|
||||
|
||||
virtual void print(void) const;
|
||||
|
||||
enum ast_operators oper;
|
||||
|
||||
ast_expression *subexpressions[3];
|
||||
|
||||
union {
|
||||
char *identifier;
|
||||
int int_constant;
|
||||
float float_constant;
|
||||
unsigned uint_constant;
|
||||
int bool_constant;
|
||||
} primary_expression;
|
||||
|
||||
|
||||
/**
|
||||
* List of expressions for an \c ast_sequence or parameters for an
|
||||
* \c ast_function_call
|
||||
*/
|
||||
exec_list expressions;
|
||||
|
||||
/**
|
||||
* For things that can't be l-values, this describes what it is.
|
||||
*
|
||||
* This text is used by the code that generates IR for assignments to
|
||||
* detect and emit useful messages for assignments to some things that
|
||||
* can't be l-values. For example, pre- or post-incerement expressions.
|
||||
*
|
||||
* \note
|
||||
* This pointer may be \c NULL.
|
||||
*/
|
||||
const char *non_lvalue_description;
|
||||
};
|
||||
|
||||
class ast_expression_bin : public ast_expression {
|
||||
public:
|
||||
ast_expression_bin(int oper, ast_expression *, ast_expression *);
|
||||
|
||||
virtual void print(void) const;
|
||||
};
|
||||
|
||||
/**
|
||||
* Subclass of expressions for function calls
|
||||
*/
|
||||
class ast_function_expression : public ast_expression {
|
||||
public:
|
||||
ast_function_expression(ast_expression *callee)
|
||||
: ast_expression(ast_function_call, callee,
|
||||
NULL, NULL),
|
||||
cons(false)
|
||||
{
|
||||
/* empty */
|
||||
}
|
||||
|
||||
ast_function_expression(class ast_type_specifier *type)
|
||||
: ast_expression(ast_function_call, (ast_expression *) type,
|
||||
NULL, NULL),
|
||||
cons(true)
|
||||
{
|
||||
/* empty */
|
||||
}
|
||||
|
||||
bool is_constructor() const
|
||||
{
|
||||
return cons;
|
||||
}
|
||||
|
||||
virtual ir_rvalue *hir(exec_list *instructions,
|
||||
struct _mesa_glsl_parse_state *state);
|
||||
|
||||
private:
|
||||
/**
|
||||
* Is this function call actually a constructor?
|
||||
*/
|
||||
bool cons;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Number of possible operators for an ast_expression
|
||||
*
|
||||
* This is done as a define instead of as an additional value in the enum so
|
||||
* that the compiler won't generate spurious messages like "warning:
|
||||
* enumeration value ‘ast_num_operators’ not handled in switch"
|
||||
*/
|
||||
#define AST_NUM_OPERATORS (ast_sequence + 1)
|
||||
|
||||
|
||||
class ast_compound_statement : public ast_node {
|
||||
public:
|
||||
ast_compound_statement(int new_scope, ast_node *statements);
|
||||
virtual void print(void) const;
|
||||
|
||||
virtual ir_rvalue *hir(exec_list *instructions,
|
||||
struct _mesa_glsl_parse_state *state);
|
||||
|
||||
int new_scope;
|
||||
exec_list statements;
|
||||
};
|
||||
|
||||
class ast_declaration : public ast_node {
|
||||
public:
|
||||
ast_declaration(char *identifier, int is_array, ast_expression *array_size,
|
||||
ast_expression *initializer);
|
||||
virtual void print(void) const;
|
||||
|
||||
char *identifier;
|
||||
|
||||
int is_array;
|
||||
ast_expression *array_size;
|
||||
|
||||
ast_expression *initializer;
|
||||
};
|
||||
|
||||
|
||||
enum {
|
||||
ast_precision_none = 0, /**< Absence of precision qualifier. */
|
||||
ast_precision_high,
|
||||
ast_precision_medium,
|
||||
ast_precision_low
|
||||
};
|
||||
|
||||
struct ast_type_qualifier {
|
||||
union {
|
||||
struct {
|
||||
unsigned invariant:1;
|
||||
unsigned constant:1;
|
||||
unsigned attribute:1;
|
||||
unsigned varying:1;
|
||||
unsigned in:1;
|
||||
unsigned out:1;
|
||||
unsigned centroid:1;
|
||||
unsigned uniform:1;
|
||||
unsigned smooth:1;
|
||||
unsigned flat:1;
|
||||
unsigned noperspective:1;
|
||||
|
||||
/** \name Layout qualifiers for GL_AMD_conservative_depth */
|
||||
/** \{ */
|
||||
unsigned depth_any:1;
|
||||
unsigned depth_greater:1;
|
||||
unsigned depth_less:1;
|
||||
unsigned depth_unchanged:1;
|
||||
/** \} */
|
||||
}
|
||||
/** \brief Set of flags, accessed by name. */
|
||||
q;
|
||||
|
||||
/** \brief Set of flags, accessed as a bitmask. */
|
||||
unsigned i;
|
||||
} flags;
|
||||
|
||||
/**
|
||||
* Return true if and only if an interpolation qualifier is present.
|
||||
*/
|
||||
bool has_interpolation() const;
|
||||
|
||||
/**
|
||||
* \brief Return string representation of interpolation qualifier.
|
||||
*
|
||||
* If an interpolation qualifier is present, then return that qualifier's
|
||||
* string representation. Otherwise, return null. For example, if the
|
||||
* noperspective bit is set, then this returns "noperspective".
|
||||
*
|
||||
* If multiple interpolation qualifiers are somehow present, then the
|
||||
* returned string is undefined but not null.
|
||||
*/
|
||||
const char *interpolation_string() const;
|
||||
};
|
||||
|
||||
class ast_struct_specifier : public ast_node {
|
||||
public:
|
||||
ast_struct_specifier(char *identifier, ast_node *declarator_list);
|
||||
virtual void print(void) const;
|
||||
|
||||
virtual ir_rvalue *hir(exec_list *instructions,
|
||||
struct _mesa_glsl_parse_state *state);
|
||||
|
||||
char *name;
|
||||
exec_list declarations;
|
||||
};
|
||||
|
||||
|
||||
enum ast_types {
|
||||
ast_void,
|
||||
ast_float,
|
||||
ast_int,
|
||||
ast_uint,
|
||||
ast_bool,
|
||||
ast_vec2,
|
||||
ast_vec3,
|
||||
ast_vec4,
|
||||
ast_bvec2,
|
||||
ast_bvec3,
|
||||
ast_bvec4,
|
||||
ast_ivec2,
|
||||
ast_ivec3,
|
||||
ast_ivec4,
|
||||
ast_uvec2,
|
||||
ast_uvec3,
|
||||
ast_uvec4,
|
||||
ast_mat2,
|
||||
ast_mat2x3,
|
||||
ast_mat2x4,
|
||||
ast_mat3x2,
|
||||
ast_mat3,
|
||||
ast_mat3x4,
|
||||
ast_mat4x2,
|
||||
ast_mat4x3,
|
||||
ast_mat4,
|
||||
ast_sampler1d,
|
||||
ast_sampler2d,
|
||||
ast_sampler2drect,
|
||||
ast_sampler3d,
|
||||
ast_samplercube,
|
||||
ast_samplerexternaloes,
|
||||
ast_sampler1dshadow,
|
||||
ast_sampler2dshadow,
|
||||
ast_sampler2drectshadow,
|
||||
ast_samplercubeshadow,
|
||||
ast_sampler1darray,
|
||||
ast_sampler2darray,
|
||||
ast_sampler1darrayshadow,
|
||||
ast_sampler2darrayshadow,
|
||||
ast_isampler1d,
|
||||
ast_isampler2d,
|
||||
ast_isampler3d,
|
||||
ast_isamplercube,
|
||||
ast_isampler1darray,
|
||||
ast_isampler2darray,
|
||||
ast_usampler1d,
|
||||
ast_usampler2d,
|
||||
ast_usampler3d,
|
||||
ast_usamplercube,
|
||||
ast_usampler1darray,
|
||||
ast_usampler2darray,
|
||||
|
||||
ast_struct,
|
||||
ast_type_name
|
||||
};
|
||||
|
||||
|
||||
class ast_type_specifier : public ast_node {
|
||||
public:
|
||||
ast_type_specifier(int specifier);
|
||||
|
||||
/** Construct a type specifier from a type name */
|
||||
ast_type_specifier(const char *name)
|
||||
: type_specifier(ast_type_name), type_name(name), structure(NULL),
|
||||
is_array(false), array_size(NULL), precision(ast_precision_none),
|
||||
is_precision_statement(false)
|
||||
{
|
||||
/* empty */
|
||||
}
|
||||
|
||||
/** Construct a type specifier from a structure definition */
|
||||
ast_type_specifier(ast_struct_specifier *s)
|
||||
: type_specifier(ast_struct), type_name(s->name), structure(s),
|
||||
is_array(false), array_size(NULL), precision(ast_precision_none),
|
||||
is_precision_statement(false)
|
||||
{
|
||||
/* empty */
|
||||
}
|
||||
|
||||
const struct glsl_type *glsl_type(const char **name,
|
||||
struct _mesa_glsl_parse_state *state)
|
||||
const;
|
||||
|
||||
virtual void print(void) const;
|
||||
|
||||
ir_rvalue *hir(exec_list *, struct _mesa_glsl_parse_state *);
|
||||
|
||||
enum ast_types type_specifier;
|
||||
|
||||
const char *type_name;
|
||||
ast_struct_specifier *structure;
|
||||
|
||||
int is_array;
|
||||
ast_expression *array_size;
|
||||
|
||||
unsigned precision:2;
|
||||
|
||||
bool is_precision_statement;
|
||||
};
|
||||
|
||||
|
||||
class ast_fully_specified_type : public ast_node {
|
||||
public:
|
||||
virtual void print(void) const;
|
||||
bool has_qualifiers() const;
|
||||
|
||||
ast_type_qualifier qualifier;
|
||||
ast_type_specifier *specifier;
|
||||
};
|
||||
|
||||
|
||||
class ast_declarator_list : public ast_node {
|
||||
public:
|
||||
ast_declarator_list(ast_fully_specified_type *);
|
||||
virtual void print(void) const;
|
||||
|
||||
virtual ir_rvalue *hir(exec_list *instructions,
|
||||
struct _mesa_glsl_parse_state *state);
|
||||
|
||||
ast_fully_specified_type *type;
|
||||
exec_list declarations;
|
||||
|
||||
/**
|
||||
* Special flag for vertex shader "invariant" declarations.
|
||||
*
|
||||
* Vertex shaders can contain "invariant" variable redeclarations that do
|
||||
* not include a type. For example, "invariant gl_Position;". This flag
|
||||
* is used to note these cases when no type is specified.
|
||||
*/
|
||||
int invariant;
|
||||
};
|
||||
|
||||
|
||||
class ast_parameter_declarator : public ast_node {
|
||||
public:
|
||||
ast_parameter_declarator()
|
||||
{
|
||||
this->identifier = NULL;
|
||||
this->is_array = false;
|
||||
this->array_size = 0;
|
||||
}
|
||||
|
||||
virtual void print(void) const;
|
||||
|
||||
virtual ir_rvalue *hir(exec_list *instructions,
|
||||
struct _mesa_glsl_parse_state *state);
|
||||
|
||||
ast_fully_specified_type *type;
|
||||
char *identifier;
|
||||
int is_array;
|
||||
ast_expression *array_size;
|
||||
|
||||
static void parameters_to_hir(exec_list *ast_parameters,
|
||||
bool formal, exec_list *ir_parameters,
|
||||
struct _mesa_glsl_parse_state *state);
|
||||
|
||||
private:
|
||||
/** Is this parameter declaration part of a formal parameter list? */
|
||||
bool formal_parameter;
|
||||
|
||||
/**
|
||||
* Is this parameter 'void' type?
|
||||
*
|
||||
* This field is set by \c ::hir.
|
||||
*/
|
||||
bool is_void;
|
||||
};
|
||||
|
||||
|
||||
class ast_function : public ast_node {
|
||||
public:
|
||||
ast_function(void);
|
||||
|
||||
virtual void print(void) const;
|
||||
|
||||
virtual ir_rvalue *hir(exec_list *instructions,
|
||||
struct _mesa_glsl_parse_state *state);
|
||||
|
||||
ast_fully_specified_type *return_type;
|
||||
char *identifier;
|
||||
|
||||
exec_list parameters;
|
||||
|
||||
private:
|
||||
/**
|
||||
* Is this prototype part of the function definition?
|
||||
*
|
||||
* Used by ast_function_definition::hir to process the parameters, etc.
|
||||
* of the function.
|
||||
*
|
||||
* \sa ::hir
|
||||
*/
|
||||
bool is_definition;
|
||||
|
||||
/**
|
||||
* Function signature corresponding to this function prototype instance
|
||||
*
|
||||
* Used by ast_function_definition::hir to process the parameters, etc.
|
||||
* of the function.
|
||||
*
|
||||
* \sa ::hir
|
||||
*/
|
||||
class ir_function_signature *signature;
|
||||
|
||||
friend class ast_function_definition;
|
||||
};
|
||||
|
||||
|
||||
class ast_expression_statement : public ast_node {
|
||||
public:
|
||||
ast_expression_statement(ast_expression *);
|
||||
virtual void print(void) const;
|
||||
|
||||
virtual ir_rvalue *hir(exec_list *instructions,
|
||||
struct _mesa_glsl_parse_state *state);
|
||||
|
||||
ast_expression *expression;
|
||||
};
|
||||
|
||||
|
||||
class ast_case_label : public ast_node {
|
||||
public:
|
||||
ast_case_label(ast_expression *test_value);
|
||||
virtual void print(void) const;
|
||||
|
||||
virtual ir_rvalue *hir(exec_list *instructions,
|
||||
struct _mesa_glsl_parse_state *state);
|
||||
|
||||
/**
|
||||
* An test value of NULL means 'default'.
|
||||
*/
|
||||
ast_expression *test_value;
|
||||
};
|
||||
|
||||
|
||||
class ast_case_label_list : public ast_node {
|
||||
public:
|
||||
ast_case_label_list(void);
|
||||
virtual void print(void) const;
|
||||
|
||||
virtual ir_rvalue *hir(exec_list *instructions,
|
||||
struct _mesa_glsl_parse_state *state);
|
||||
|
||||
/**
|
||||
* A list of case labels.
|
||||
*/
|
||||
exec_list labels;
|
||||
};
|
||||
|
||||
|
||||
class ast_case_statement : public ast_node {
|
||||
public:
|
||||
ast_case_statement(ast_case_label_list *labels);
|
||||
virtual void print(void) const;
|
||||
|
||||
virtual ir_rvalue *hir(exec_list *instructions,
|
||||
struct _mesa_glsl_parse_state *state);
|
||||
|
||||
ast_case_label_list *labels;
|
||||
|
||||
/**
|
||||
* A list of statements.
|
||||
*/
|
||||
exec_list stmts;
|
||||
};
|
||||
|
||||
|
||||
class ast_case_statement_list : public ast_node {
|
||||
public:
|
||||
ast_case_statement_list(void);
|
||||
virtual void print(void) const;
|
||||
|
||||
virtual ir_rvalue *hir(exec_list *instructions,
|
||||
struct _mesa_glsl_parse_state *state);
|
||||
|
||||
/**
|
||||
* A list of cases.
|
||||
*/
|
||||
exec_list cases;
|
||||
};
|
||||
|
||||
|
||||
class ast_switch_body : public ast_node {
|
||||
public:
|
||||
ast_switch_body(ast_case_statement_list *stmts);
|
||||
virtual void print(void) const;
|
||||
|
||||
virtual ir_rvalue *hir(exec_list *instructions,
|
||||
struct _mesa_glsl_parse_state *state);
|
||||
|
||||
ast_case_statement_list *stmts;
|
||||
};
|
||||
|
||||
|
||||
class ast_selection_statement : public ast_node {
|
||||
public:
|
||||
ast_selection_statement(ast_expression *condition,
|
||||
ast_node *then_statement,
|
||||
ast_node *else_statement);
|
||||
virtual void print(void) const;
|
||||
|
||||
virtual ir_rvalue *hir(exec_list *instructions,
|
||||
struct _mesa_glsl_parse_state *state);
|
||||
|
||||
ast_expression *condition;
|
||||
ast_node *then_statement;
|
||||
ast_node *else_statement;
|
||||
};
|
||||
|
||||
|
||||
class ast_switch_statement : public ast_node {
|
||||
public:
|
||||
ast_switch_statement(ast_expression *test_expression,
|
||||
ast_node *body);
|
||||
virtual void print(void) const;
|
||||
|
||||
virtual ir_rvalue *hir(exec_list *instructions,
|
||||
struct _mesa_glsl_parse_state *state);
|
||||
|
||||
ast_expression *test_expression;
|
||||
ast_node *body;
|
||||
|
||||
protected:
|
||||
void test_to_hir(exec_list *, struct _mesa_glsl_parse_state *);
|
||||
};
|
||||
|
||||
class ast_iteration_statement : public ast_node {
|
||||
public:
|
||||
ast_iteration_statement(int mode, ast_node *init, ast_node *condition,
|
||||
ast_expression *rest_expression, ast_node *body);
|
||||
|
||||
virtual void print(void) const;
|
||||
|
||||
virtual ir_rvalue *hir(exec_list *, struct _mesa_glsl_parse_state *);
|
||||
|
||||
enum ast_iteration_modes {
|
||||
ast_for,
|
||||
ast_while,
|
||||
ast_do_while
|
||||
} mode;
|
||||
|
||||
|
||||
ast_node *init_statement;
|
||||
ast_node *condition;
|
||||
ast_expression *rest_expression;
|
||||
|
||||
ast_node *body;
|
||||
|
||||
private:
|
||||
/**
|
||||
* Generate IR from the condition of a loop
|
||||
*
|
||||
* This is factored out of ::hir because some loops have the condition
|
||||
* test at the top (for and while), and others have it at the end (do-while).
|
||||
*/
|
||||
void condition_to_hir(class ir_loop *, struct _mesa_glsl_parse_state *);
|
||||
};
|
||||
|
||||
|
||||
class ast_jump_statement : public ast_node {
|
||||
public:
|
||||
ast_jump_statement(int mode, ast_expression *return_value);
|
||||
virtual void print(void) const;
|
||||
|
||||
virtual ir_rvalue *hir(exec_list *instructions,
|
||||
struct _mesa_glsl_parse_state *state);
|
||||
|
||||
enum ast_jump_modes {
|
||||
ast_continue,
|
||||
ast_break,
|
||||
ast_return,
|
||||
ast_discard
|
||||
} mode;
|
||||
|
||||
ast_expression *opt_return_value;
|
||||
};
|
||||
|
||||
|
||||
class ast_function_definition : public ast_node {
|
||||
public:
|
||||
virtual void print(void) const;
|
||||
|
||||
virtual ir_rvalue *hir(exec_list *instructions,
|
||||
struct _mesa_glsl_parse_state *state);
|
||||
|
||||
ast_function *prototype;
|
||||
ast_compound_statement *body;
|
||||
};
|
||||
/*@}*/
|
||||
|
||||
extern void
|
||||
_mesa_ast_to_hir(exec_list *instructions, struct _mesa_glsl_parse_state *state);
|
||||
|
||||
extern ir_rvalue *
|
||||
_mesa_ast_field_selection_to_hir(const ast_expression *expr,
|
||||
exec_list *instructions,
|
||||
struct _mesa_glsl_parse_state *state);
|
||||
|
||||
void
|
||||
emit_function(_mesa_glsl_parse_state *state, ir_function *f);
|
||||
|
||||
#endif /* AST_H */
|
|
@ -1,95 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2010 Intel Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#include <assert.h>
|
||||
#include "ast.h"
|
||||
|
||||
const char *
|
||||
ast_expression::operator_string(enum ast_operators op)
|
||||
{
|
||||
static const char *const operators[] = {
|
||||
"=",
|
||||
"+",
|
||||
"-",
|
||||
"+",
|
||||
"-",
|
||||
"*",
|
||||
"/",
|
||||
"%",
|
||||
"<<",
|
||||
">>",
|
||||
"<",
|
||||
">",
|
||||
"<=",
|
||||
">=",
|
||||
"==",
|
||||
"!=",
|
||||
"&",
|
||||
"^",
|
||||
"|",
|
||||
"~",
|
||||
"&&",
|
||||
"^^",
|
||||
"||",
|
||||
"!",
|
||||
|
||||
"*=",
|
||||
"/=",
|
||||
"%=",
|
||||
"+=",
|
||||
"-=",
|
||||
"<<=",
|
||||
">>=",
|
||||
"&=",
|
||||
"^=",
|
||||
"|=",
|
||||
|
||||
"?:",
|
||||
|
||||
"++",
|
||||
"--",
|
||||
"++",
|
||||
"--",
|
||||
".",
|
||||
};
|
||||
|
||||
assert((unsigned int)op < sizeof(operators) / sizeof(operators[0]));
|
||||
|
||||
return operators[op];
|
||||
}
|
||||
|
||||
|
||||
ast_expression_bin::ast_expression_bin(int oper, ast_expression *ex0,
|
||||
ast_expression *ex1) :
|
||||
ast_expression(oper, ex0, ex1, NULL)
|
||||
{
|
||||
assert((oper >= ast_plus) && (oper <= ast_logic_not));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ast_expression_bin::print(void) const
|
||||
{
|
||||
subexpressions[0]->print();
|
||||
printf("%s ", operator_string(oper));
|
||||
subexpressions[1]->print();
|
||||
}
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -1,139 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2010 Intel Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "ast.h"
|
||||
extern "C" {
|
||||
#include "program/symbol_table.h"
|
||||
}
|
||||
|
||||
void
|
||||
ast_type_specifier::print(void) const
|
||||
{
|
||||
if (type_specifier == ast_struct) {
|
||||
structure->print();
|
||||
} else {
|
||||
printf("%s ", type_name);
|
||||
}
|
||||
|
||||
if (is_array) {
|
||||
printf("[ ");
|
||||
|
||||
if (array_size) {
|
||||
array_size->print();
|
||||
}
|
||||
|
||||
printf("] ");
|
||||
}
|
||||
}
|
||||
|
||||
ast_type_specifier::ast_type_specifier(int specifier)
|
||||
: type_specifier(ast_types(specifier)), type_name(NULL), structure(NULL),
|
||||
is_array(false), array_size(NULL), precision(ast_precision_none),
|
||||
is_precision_statement(false)
|
||||
{
|
||||
static const char *const names[] = {
|
||||
"void",
|
||||
"float",
|
||||
"int",
|
||||
"uint",
|
||||
"bool",
|
||||
"vec2",
|
||||
"vec3",
|
||||
"vec4",
|
||||
"bvec2",
|
||||
"bvec3",
|
||||
"bvec4",
|
||||
"ivec2",
|
||||
"ivec3",
|
||||
"ivec4",
|
||||
"uvec2",
|
||||
"uvec3",
|
||||
"uvec4",
|
||||
"mat2",
|
||||
"mat2x3",
|
||||
"mat2x4",
|
||||
"mat3x2",
|
||||
"mat3",
|
||||
"mat3x4",
|
||||
"mat4x2",
|
||||
"mat4x3",
|
||||
"mat4",
|
||||
"sampler1D",
|
||||
"sampler2D",
|
||||
"sampler2DRect",
|
||||
"sampler3D",
|
||||
"samplerCube",
|
||||
"samplerExternalOES",
|
||||
"sampler1DShadow",
|
||||
"sampler2DShadow",
|
||||
"sampler2DRectShadow",
|
||||
"samplerCubeShadow",
|
||||
"sampler1DArray",
|
||||
"sampler2DArray",
|
||||
"sampler1DArrayShadow",
|
||||
"sampler2DArrayShadow",
|
||||
"isampler1D",
|
||||
"isampler2D",
|
||||
"isampler3D",
|
||||
"isamplerCube",
|
||||
"isampler1DArray",
|
||||
"isampler2DArray",
|
||||
"usampler1D",
|
||||
"usampler2D",
|
||||
"usampler3D",
|
||||
"usamplerCube",
|
||||
"usampler1DArray",
|
||||
"usampler2DArray",
|
||||
|
||||
NULL, /* ast_struct */
|
||||
NULL /* ast_type_name */
|
||||
};
|
||||
|
||||
type_name = names[specifier];
|
||||
}
|
||||
|
||||
bool
|
||||
ast_fully_specified_type::has_qualifiers() const
|
||||
{
|
||||
return this->qualifier.flags.i != 0;
|
||||
}
|
||||
|
||||
bool ast_type_qualifier::has_interpolation() const
|
||||
{
|
||||
return this->flags.q.smooth
|
||||
|| this->flags.q.flat
|
||||
|| this->flags.q.noperspective;
|
||||
}
|
||||
|
||||
const char*
|
||||
ast_type_qualifier::interpolation_string() const
|
||||
{
|
||||
if (this->flags.q.smooth)
|
||||
return "smooth";
|
||||
else if (this->flags.q.flat)
|
||||
return "flat";
|
||||
else if (this->flags.q.noperspective)
|
||||
return "noperspective";
|
||||
else
|
||||
return NULL;
|
||||
}
|
|
@ -1,39 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2010 Intel Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "glsl_parser_extras.h"
|
||||
|
||||
/* A dummy file. When compiling prototypes, we don't care about builtins.
|
||||
* We really don't want to half-compile builtin_functions.cpp and fail, though.
|
||||
*/
|
||||
void
|
||||
_mesa_glsl_release_functions(void)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
_mesa_glsl_initialize_functions(_mesa_glsl_parse_state *state)
|
||||
{
|
||||
(void) state;
|
||||
}
|
|
@ -1,248 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2009 Intel Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
const glsl_type glsl_type::_error_type =
|
||||
glsl_type(GL_INVALID_ENUM, GLSL_TYPE_ERROR, 0, 0, "");
|
||||
|
||||
const glsl_type glsl_type::_void_type =
|
||||
glsl_type(GL_INVALID_ENUM, GLSL_TYPE_VOID, 0, 0, "void");
|
||||
|
||||
const glsl_type glsl_type::_sampler3D_type =
|
||||
glsl_type(GL_SAMPLER_3D, GLSL_SAMPLER_DIM_3D, 0, 0, GLSL_TYPE_FLOAT,
|
||||
"sampler3D");
|
||||
|
||||
const glsl_type *const glsl_type::error_type = & glsl_type::_error_type;
|
||||
const glsl_type *const glsl_type::void_type = & glsl_type::_void_type;
|
||||
|
||||
/** \name Core built-in types
|
||||
*
|
||||
* These types exist in all versions of GLSL.
|
||||
*/
|
||||
/*@{*/
|
||||
|
||||
const glsl_type glsl_type::builtin_core_types[] = {
|
||||
glsl_type(GL_BOOL, GLSL_TYPE_BOOL, 1, 1, "bool"),
|
||||
glsl_type(GL_BOOL_VEC2, GLSL_TYPE_BOOL, 2, 1, "bvec2"),
|
||||
glsl_type(GL_BOOL_VEC3, GLSL_TYPE_BOOL, 3, 1, "bvec3"),
|
||||
glsl_type(GL_BOOL_VEC4, GLSL_TYPE_BOOL, 4, 1, "bvec4"),
|
||||
glsl_type(GL_INT, GLSL_TYPE_INT, 1, 1, "int"),
|
||||
glsl_type(GL_INT_VEC2, GLSL_TYPE_INT, 2, 1, "ivec2"),
|
||||
glsl_type(GL_INT_VEC3, GLSL_TYPE_INT, 3, 1, "ivec3"),
|
||||
glsl_type(GL_INT_VEC4, GLSL_TYPE_INT, 4, 1, "ivec4"),
|
||||
glsl_type(GL_FLOAT, GLSL_TYPE_FLOAT, 1, 1, "float"),
|
||||
glsl_type(GL_FLOAT_VEC2, GLSL_TYPE_FLOAT, 2, 1, "vec2"),
|
||||
glsl_type(GL_FLOAT_VEC3, GLSL_TYPE_FLOAT, 3, 1, "vec3"),
|
||||
glsl_type(GL_FLOAT_VEC4, GLSL_TYPE_FLOAT, 4, 1, "vec4"),
|
||||
glsl_type(GL_FLOAT_MAT2, GLSL_TYPE_FLOAT, 2, 2, "mat2"),
|
||||
glsl_type(GL_FLOAT_MAT3, GLSL_TYPE_FLOAT, 3, 3, "mat3"),
|
||||
glsl_type(GL_FLOAT_MAT4, GLSL_TYPE_FLOAT, 4, 4, "mat4"),
|
||||
glsl_type(GL_SAMPLER_2D, GLSL_SAMPLER_DIM_2D, 0, 0, GLSL_TYPE_FLOAT,
|
||||
"sampler2D"),
|
||||
glsl_type(GL_SAMPLER_CUBE, GLSL_SAMPLER_DIM_CUBE, 0, 0, GLSL_TYPE_FLOAT,
|
||||
"samplerCube"),
|
||||
};
|
||||
|
||||
const glsl_type *const glsl_type::bool_type = & builtin_core_types[0];
|
||||
const glsl_type *const glsl_type::int_type = & builtin_core_types[4];
|
||||
const glsl_type *const glsl_type::ivec4_type = & builtin_core_types[7];
|
||||
const glsl_type *const glsl_type::float_type = & builtin_core_types[8];
|
||||
const glsl_type *const glsl_type::vec2_type = & builtin_core_types[9];
|
||||
const glsl_type *const glsl_type::vec3_type = & builtin_core_types[10];
|
||||
const glsl_type *const glsl_type::vec4_type = & builtin_core_types[11];
|
||||
const glsl_type *const glsl_type::mat2_type = & builtin_core_types[12];
|
||||
const glsl_type *const glsl_type::mat3_type = & builtin_core_types[13];
|
||||
const glsl_type *const glsl_type::mat4_type = & builtin_core_types[14];
|
||||
/*@}*/
|
||||
|
||||
/** \name GLSL structures that have not been deprecated.
|
||||
*/
|
||||
/*@{*/
|
||||
|
||||
static const struct glsl_struct_field gl_DepthRangeParameters_fields[] = {
|
||||
{ glsl_type::float_type, "near" },
|
||||
{ glsl_type::float_type, "far" },
|
||||
{ glsl_type::float_type, "diff" },
|
||||
};
|
||||
|
||||
const glsl_type glsl_type::builtin_structure_types[] = {
|
||||
glsl_type(gl_DepthRangeParameters_fields,
|
||||
Elements(gl_DepthRangeParameters_fields),
|
||||
"gl_DepthRangeParameters"),
|
||||
};
|
||||
/*@}*/
|
||||
|
||||
/** \name GLSL 1.00 / 1.10 structures that are deprecated in GLSL 1.30
|
||||
*/
|
||||
/*@{*/
|
||||
|
||||
static const struct glsl_struct_field gl_PointParameters_fields[] = {
|
||||
{ glsl_type::float_type, "size" },
|
||||
{ glsl_type::float_type, "sizeMin" },
|
||||
{ glsl_type::float_type, "sizeMax" },
|
||||
{ glsl_type::float_type, "fadeThresholdSize" },
|
||||
{ glsl_type::float_type, "distanceConstantAttenuation" },
|
||||
{ glsl_type::float_type, "distanceLinearAttenuation" },
|
||||
{ glsl_type::float_type, "distanceQuadraticAttenuation" },
|
||||
};
|
||||
|
||||
static const struct glsl_struct_field gl_MaterialParameters_fields[] = {
|
||||
{ glsl_type::vec4_type, "emission" },
|
||||
{ glsl_type::vec4_type, "ambient" },
|
||||
{ glsl_type::vec4_type, "diffuse" },
|
||||
{ glsl_type::vec4_type, "specular" },
|
||||
{ glsl_type::float_type, "shininess" },
|
||||
};
|
||||
|
||||
static const struct glsl_struct_field gl_LightSourceParameters_fields[] = {
|
||||
{ glsl_type::vec4_type, "ambient" },
|
||||
{ glsl_type::vec4_type, "diffuse" },
|
||||
{ glsl_type::vec4_type, "specular" },
|
||||
{ glsl_type::vec4_type, "position" },
|
||||
{ glsl_type::vec4_type, "halfVector" },
|
||||
{ glsl_type::vec3_type, "spotDirection" },
|
||||
{ glsl_type::float_type, "spotExponent" },
|
||||
{ glsl_type::float_type, "spotCutoff" },
|
||||
{ glsl_type::float_type, "spotCosCutoff" },
|
||||
{ glsl_type::float_type, "constantAttenuation" },
|
||||
{ glsl_type::float_type, "linearAttenuation" },
|
||||
{ glsl_type::float_type, "quadraticAttenuation" },
|
||||
};
|
||||
|
||||
static const struct glsl_struct_field gl_LightModelParameters_fields[] = {
|
||||
{ glsl_type::vec4_type, "ambient" },
|
||||
};
|
||||
|
||||
static const struct glsl_struct_field gl_LightModelProducts_fields[] = {
|
||||
{ glsl_type::vec4_type, "sceneColor" },
|
||||
};
|
||||
|
||||
static const struct glsl_struct_field gl_LightProducts_fields[] = {
|
||||
{ glsl_type::vec4_type, "ambient" },
|
||||
{ glsl_type::vec4_type, "diffuse" },
|
||||
{ glsl_type::vec4_type, "specular" },
|
||||
};
|
||||
|
||||
static const struct glsl_struct_field gl_FogParameters_fields[] = {
|
||||
{ glsl_type::vec4_type, "color" },
|
||||
{ glsl_type::float_type, "density" },
|
||||
{ glsl_type::float_type, "start" },
|
||||
{ glsl_type::float_type, "end" },
|
||||
{ glsl_type::float_type, "scale" },
|
||||
};
|
||||
|
||||
const glsl_type glsl_type::builtin_110_deprecated_structure_types[] = {
|
||||
glsl_type(gl_PointParameters_fields,
|
||||
Elements(gl_PointParameters_fields),
|
||||
"gl_PointParameters"),
|
||||
glsl_type(gl_MaterialParameters_fields,
|
||||
Elements(gl_MaterialParameters_fields),
|
||||
"gl_MaterialParameters"),
|
||||
glsl_type(gl_LightSourceParameters_fields,
|
||||
Elements(gl_LightSourceParameters_fields),
|
||||
"gl_LightSourceParameters"),
|
||||
glsl_type(gl_LightModelParameters_fields,
|
||||
Elements(gl_LightModelParameters_fields),
|
||||
"gl_LightModelParameters"),
|
||||
glsl_type(gl_LightModelProducts_fields,
|
||||
Elements(gl_LightModelProducts_fields),
|
||||
"gl_LightModelProducts"),
|
||||
glsl_type(gl_LightProducts_fields,
|
||||
Elements(gl_LightProducts_fields),
|
||||
"gl_LightProducts"),
|
||||
glsl_type(gl_FogParameters_fields,
|
||||
Elements(gl_FogParameters_fields),
|
||||
"gl_FogParameters"),
|
||||
};
|
||||
/*@}*/
|
||||
|
||||
/** \name Types in GLSL 1.10 (but not GLSL ES 1.00)
|
||||
*/
|
||||
/*@{*/
|
||||
const glsl_type glsl_type::builtin_110_types[] = {
|
||||
glsl_type(GL_SAMPLER_1D, GLSL_SAMPLER_DIM_1D, 0, 0, GLSL_TYPE_FLOAT,
|
||||
"sampler1D"),
|
||||
glsl_type(GL_SAMPLER_1D_SHADOW, GLSL_SAMPLER_DIM_1D, 1, 0, GLSL_TYPE_FLOAT,
|
||||
"sampler1DShadow"),
|
||||
glsl_type(GL_SAMPLER_2D_SHADOW, GLSL_SAMPLER_DIM_2D, 1, 0, GLSL_TYPE_FLOAT,
|
||||
"sampler2DShadow"),
|
||||
};
|
||||
/*@}*/
|
||||
|
||||
/** \name Types added in GLSL 1.20
|
||||
*/
|
||||
/*@{*/
|
||||
|
||||
const glsl_type glsl_type::builtin_120_types[] = {
|
||||
glsl_type(GL_FLOAT_MAT2x3, GLSL_TYPE_FLOAT, 3, 2, "mat2x3"),
|
||||
glsl_type(GL_FLOAT_MAT2x4, GLSL_TYPE_FLOAT, 4, 2, "mat2x4"),
|
||||
glsl_type(GL_FLOAT_MAT3x2, GLSL_TYPE_FLOAT, 2, 3, "mat3x2"),
|
||||
glsl_type(GL_FLOAT_MAT3x4, GLSL_TYPE_FLOAT, 4, 3, "mat3x4"),
|
||||
glsl_type(GL_FLOAT_MAT4x2, GLSL_TYPE_FLOAT, 2, 4, "mat4x2"),
|
||||
glsl_type(GL_FLOAT_MAT4x3, GLSL_TYPE_FLOAT, 3, 4, "mat4x3"),
|
||||
};
|
||||
const glsl_type *const glsl_type::mat2x3_type = & builtin_120_types[0];
|
||||
const glsl_type *const glsl_type::mat2x4_type = & builtin_120_types[1];
|
||||
const glsl_type *const glsl_type::mat3x2_type = & builtin_120_types[2];
|
||||
const glsl_type *const glsl_type::mat3x4_type = & builtin_120_types[3];
|
||||
const glsl_type *const glsl_type::mat4x2_type = & builtin_120_types[4];
|
||||
const glsl_type *const glsl_type::mat4x3_type = & builtin_120_types[5];
|
||||
/*@}*/
|
||||
|
||||
/** \name Types added in GLSL 1.30
|
||||
*/
|
||||
/*@{*/
|
||||
|
||||
const glsl_type glsl_type::builtin_130_types[] = {
|
||||
glsl_type(GL_UNSIGNED_INT, GLSL_TYPE_UINT, 1, 1, "uint"),
|
||||
glsl_type(GL_UNSIGNED_INT_VEC2, GLSL_TYPE_UINT, 2, 1, "uvec2"),
|
||||
glsl_type(GL_UNSIGNED_INT_VEC3, GLSL_TYPE_UINT, 3, 1, "uvec3"),
|
||||
glsl_type(GL_UNSIGNED_INT_VEC4, GLSL_TYPE_UINT, 4, 1, "uvec4"),
|
||||
|
||||
/* cube shadow samplers */
|
||||
glsl_type(GL_SAMPLER_CUBE_SHADOW,
|
||||
GLSL_SAMPLER_DIM_CUBE, 1, 0, GLSL_TYPE_FLOAT, "samplerCubeShadow"),
|
||||
|
||||
/* signed and unsigned integer samplers */
|
||||
glsl_type(GL_INT_SAMPLER_1D,
|
||||
GLSL_SAMPLER_DIM_1D, 0, 0, GLSL_TYPE_INT, "isampler1D"),
|
||||
glsl_type(GL_UNSIGNED_INT_SAMPLER_1D,
|
||||
GLSL_SAMPLER_DIM_1D, 0, 0, GLSL_TYPE_UINT, "usampler1D"),
|
||||
glsl_type(GL_INT_SAMPLER_2D,
|
||||
GLSL_SAMPLER_DIM_2D, 0, 0, GLSL_TYPE_INT, "isampler2D"),
|
||||
glsl_type(GL_UNSIGNED_INT_SAMPLER_2D,
|
||||
GLSL_SAMPLER_DIM_2D, 0, 0, GLSL_TYPE_UINT, "usampler2D"),
|
||||
glsl_type(GL_INT_SAMPLER_3D,
|
||||
GLSL_SAMPLER_DIM_3D, 0, 0, GLSL_TYPE_INT, "isampler3D"),
|
||||
glsl_type(GL_UNSIGNED_INT_SAMPLER_3D,
|
||||
GLSL_SAMPLER_DIM_3D, 0, 0, GLSL_TYPE_UINT, "usampler3D"),
|
||||
glsl_type(GL_INT_SAMPLER_CUBE,
|
||||
GLSL_SAMPLER_DIM_CUBE, 0, 0, GLSL_TYPE_INT, "isamplerCube"),
|
||||
glsl_type(GL_INT_SAMPLER_CUBE,
|
||||
GLSL_SAMPLER_DIM_CUBE, 0, 0, GLSL_TYPE_UINT, "usamplerCube"),
|
||||
};
|
||||
|
||||
const glsl_type *const glsl_type::uint_type = & builtin_130_types[0];
|
||||
const glsl_type *const glsl_type::uvec2_type = & builtin_130_types[1];
|
||||
const glsl_type *const glsl_type::uvec3_type = & builtin_130_types[2];
|
||||
const glsl_type *const glsl_type::uvec4_type = & builtin_130_types[3];
|
||||
/*@}*/
|
|
@ -1,969 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2010 Intel Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "ir.h"
|
||||
#include "glsl_parser_extras.h"
|
||||
#include "glsl_symbol_table.h"
|
||||
#include "main/core.h"
|
||||
#include "main/uniforms.h"
|
||||
#include "program/prog_parameter.h"
|
||||
#include "program/prog_statevars.h"
|
||||
#include "program/prog_instruction.h"
|
||||
|
||||
static void generate_ARB_draw_buffers_variables(exec_list *,
|
||||
struct _mesa_glsl_parse_state *,
|
||||
bool, _mesa_glsl_parser_targets);
|
||||
|
||||
struct builtin_variable {
|
||||
enum ir_variable_mode mode;
|
||||
int slot;
|
||||
const char *type;
|
||||
const char *name;
|
||||
};
|
||||
|
||||
static const builtin_variable builtin_core_vs_variables[] = {
|
||||
{ ir_var_out, VERT_RESULT_HPOS, "vec4", "gl_Position" },
|
||||
{ ir_var_out, VERT_RESULT_PSIZ, "float", "gl_PointSize" },
|
||||
};
|
||||
|
||||
static const builtin_variable builtin_core_fs_variables[] = {
|
||||
{ ir_var_in, FRAG_ATTRIB_WPOS, "vec4", "gl_FragCoord" },
|
||||
{ ir_var_in, FRAG_ATTRIB_FACE, "bool", "gl_FrontFacing" },
|
||||
{ ir_var_out, FRAG_RESULT_COLOR, "vec4", "gl_FragColor" },
|
||||
};
|
||||
|
||||
static const builtin_variable builtin_100ES_fs_variables[] = {
|
||||
{ ir_var_in, FRAG_ATTRIB_PNTC, "vec2", "gl_PointCoord" },
|
||||
};
|
||||
|
||||
static const builtin_variable builtin_110_fs_variables[] = {
|
||||
{ ir_var_out, FRAG_RESULT_DEPTH, "float", "gl_FragDepth" },
|
||||
};
|
||||
|
||||
static const builtin_variable builtin_110_deprecated_fs_variables[] = {
|
||||
{ ir_var_in, FRAG_ATTRIB_COL0, "vec4", "gl_Color" },
|
||||
{ ir_var_in, FRAG_ATTRIB_COL1, "vec4", "gl_SecondaryColor" },
|
||||
{ ir_var_in, FRAG_ATTRIB_FOGC, "float", "gl_FogFragCoord" },
|
||||
};
|
||||
|
||||
static const builtin_variable builtin_110_deprecated_vs_variables[] = {
|
||||
{ ir_var_in, VERT_ATTRIB_POS, "vec4", "gl_Vertex" },
|
||||
{ ir_var_in, VERT_ATTRIB_NORMAL, "vec3", "gl_Normal" },
|
||||
{ ir_var_in, VERT_ATTRIB_COLOR0, "vec4", "gl_Color" },
|
||||
{ ir_var_in, VERT_ATTRIB_COLOR1, "vec4", "gl_SecondaryColor" },
|
||||
{ ir_var_in, VERT_ATTRIB_TEX0, "vec4", "gl_MultiTexCoord0" },
|
||||
{ ir_var_in, VERT_ATTRIB_TEX1, "vec4", "gl_MultiTexCoord1" },
|
||||
{ ir_var_in, VERT_ATTRIB_TEX2, "vec4", "gl_MultiTexCoord2" },
|
||||
{ ir_var_in, VERT_ATTRIB_TEX3, "vec4", "gl_MultiTexCoord3" },
|
||||
{ ir_var_in, VERT_ATTRIB_TEX4, "vec4", "gl_MultiTexCoord4" },
|
||||
{ ir_var_in, VERT_ATTRIB_TEX5, "vec4", "gl_MultiTexCoord5" },
|
||||
{ ir_var_in, VERT_ATTRIB_TEX6, "vec4", "gl_MultiTexCoord6" },
|
||||
{ ir_var_in, VERT_ATTRIB_TEX7, "vec4", "gl_MultiTexCoord7" },
|
||||
{ ir_var_in, VERT_ATTRIB_FOG, "float", "gl_FogCoord" },
|
||||
{ ir_var_out, VERT_RESULT_CLIP_VERTEX, "vec4", "gl_ClipVertex" },
|
||||
{ ir_var_out, VERT_RESULT_COL0, "vec4", "gl_FrontColor" },
|
||||
{ ir_var_out, VERT_RESULT_BFC0, "vec4", "gl_BackColor" },
|
||||
{ ir_var_out, VERT_RESULT_COL1, "vec4", "gl_FrontSecondaryColor" },
|
||||
{ ir_var_out, VERT_RESULT_BFC1, "vec4", "gl_BackSecondaryColor" },
|
||||
{ ir_var_out, VERT_RESULT_FOGC, "float", "gl_FogFragCoord" },
|
||||
};
|
||||
|
||||
static const builtin_variable builtin_120_fs_variables[] = {
|
||||
{ ir_var_in, FRAG_ATTRIB_PNTC, "vec2", "gl_PointCoord" },
|
||||
};
|
||||
|
||||
static const builtin_variable builtin_130_vs_variables[] = {
|
||||
{ ir_var_system_value, SYSTEM_VALUE_VERTEX_ID, "int", "gl_VertexID" },
|
||||
};
|
||||
|
||||
static const builtin_variable builtin_110_deprecated_uniforms[] = {
|
||||
{ ir_var_uniform, -1, "mat4", "gl_ModelViewMatrix" },
|
||||
{ ir_var_uniform, -1, "mat4", "gl_ProjectionMatrix" },
|
||||
{ ir_var_uniform, -1, "mat4", "gl_ModelViewProjectionMatrix" },
|
||||
{ ir_var_uniform, -1, "mat3", "gl_NormalMatrix" },
|
||||
{ ir_var_uniform, -1, "mat4", "gl_ModelViewMatrixInverse" },
|
||||
{ ir_var_uniform, -1, "mat4", "gl_ProjectionMatrixInverse" },
|
||||
{ ir_var_uniform, -1, "mat4", "gl_ModelViewProjectionMatrixInverse" },
|
||||
{ ir_var_uniform, -1, "mat4", "gl_ModelViewMatrixTranspose" },
|
||||
{ ir_var_uniform, -1, "mat4", "gl_ProjectionMatrixTranspose" },
|
||||
{ ir_var_uniform, -1, "mat4", "gl_ModelViewProjectionMatrixTranspose" },
|
||||
{ ir_var_uniform, -1, "mat4", "gl_ModelViewMatrixInverseTranspose" },
|
||||
{ ir_var_uniform, -1, "mat4", "gl_ProjectionMatrixInverseTranspose" },
|
||||
{ ir_var_uniform, -1, "mat4", "gl_ModelViewProjectionMatrixInverseTranspose" },
|
||||
{ ir_var_uniform, -1, "float", "gl_NormalScale" },
|
||||
{ ir_var_uniform, -1, "gl_LightModelParameters", "gl_LightModel"},
|
||||
|
||||
/* Mesa-internal ATI_envmap_bumpmap state. */
|
||||
{ ir_var_uniform, -1, "vec2", "gl_BumpRotMatrix0MESA"},
|
||||
{ ir_var_uniform, -1, "vec2", "gl_BumpRotMatrix1MESA"},
|
||||
{ ir_var_uniform, -1, "vec4", "gl_FogParamsOptimizedMESA"},
|
||||
};
|
||||
|
||||
static struct gl_builtin_uniform_element gl_DepthRange_elements[] = {
|
||||
{"near", {STATE_DEPTH_RANGE, 0, 0}, SWIZZLE_XXXX},
|
||||
{"far", {STATE_DEPTH_RANGE, 0, 0}, SWIZZLE_YYYY},
|
||||
{"diff", {STATE_DEPTH_RANGE, 0, 0}, SWIZZLE_ZZZZ},
|
||||
};
|
||||
|
||||
static struct gl_builtin_uniform_element gl_ClipPlane_elements[] = {
|
||||
{NULL, {STATE_CLIPPLANE, 0, 0}, SWIZZLE_XYZW}
|
||||
};
|
||||
|
||||
static struct gl_builtin_uniform_element gl_Point_elements[] = {
|
||||
{"size", {STATE_POINT_SIZE}, SWIZZLE_XXXX},
|
||||
{"sizeMin", {STATE_POINT_SIZE}, SWIZZLE_YYYY},
|
||||
{"sizeMax", {STATE_POINT_SIZE}, SWIZZLE_ZZZZ},
|
||||
{"fadeThresholdSize", {STATE_POINT_SIZE}, SWIZZLE_WWWW},
|
||||
{"distanceConstantAttenuation", {STATE_POINT_ATTENUATION}, SWIZZLE_XXXX},
|
||||
{"distanceLinearAttenuation", {STATE_POINT_ATTENUATION}, SWIZZLE_YYYY},
|
||||
{"distanceQuadraticAttenuation", {STATE_POINT_ATTENUATION}, SWIZZLE_ZZZZ},
|
||||
};
|
||||
|
||||
static struct gl_builtin_uniform_element gl_FrontMaterial_elements[] = {
|
||||
{"emission", {STATE_MATERIAL, 0, STATE_EMISSION}, SWIZZLE_XYZW},
|
||||
{"ambient", {STATE_MATERIAL, 0, STATE_AMBIENT}, SWIZZLE_XYZW},
|
||||
{"diffuse", {STATE_MATERIAL, 0, STATE_DIFFUSE}, SWIZZLE_XYZW},
|
||||
{"specular", {STATE_MATERIAL, 0, STATE_SPECULAR}, SWIZZLE_XYZW},
|
||||
{"shininess", {STATE_MATERIAL, 0, STATE_SHININESS}, SWIZZLE_XXXX},
|
||||
};
|
||||
|
||||
static struct gl_builtin_uniform_element gl_BackMaterial_elements[] = {
|
||||
{"emission", {STATE_MATERIAL, 1, STATE_EMISSION}, SWIZZLE_XYZW},
|
||||
{"ambient", {STATE_MATERIAL, 1, STATE_AMBIENT}, SWIZZLE_XYZW},
|
||||
{"diffuse", {STATE_MATERIAL, 1, STATE_DIFFUSE}, SWIZZLE_XYZW},
|
||||
{"specular", {STATE_MATERIAL, 1, STATE_SPECULAR}, SWIZZLE_XYZW},
|
||||
{"shininess", {STATE_MATERIAL, 1, STATE_SHININESS}, SWIZZLE_XXXX},
|
||||
};
|
||||
|
||||
static struct gl_builtin_uniform_element gl_LightSource_elements[] = {
|
||||
{"ambient", {STATE_LIGHT, 0, STATE_AMBIENT}, SWIZZLE_XYZW},
|
||||
{"diffuse", {STATE_LIGHT, 0, STATE_DIFFUSE}, SWIZZLE_XYZW},
|
||||
{"specular", {STATE_LIGHT, 0, STATE_SPECULAR}, SWIZZLE_XYZW},
|
||||
{"position", {STATE_LIGHT, 0, STATE_POSITION}, SWIZZLE_XYZW},
|
||||
{"halfVector", {STATE_LIGHT, 0, STATE_HALF_VECTOR}, SWIZZLE_XYZW},
|
||||
{"spotDirection", {STATE_LIGHT, 0, STATE_SPOT_DIRECTION},
|
||||
MAKE_SWIZZLE4(SWIZZLE_X,
|
||||
SWIZZLE_Y,
|
||||
SWIZZLE_Z,
|
||||
SWIZZLE_Z)},
|
||||
{"spotCosCutoff", {STATE_LIGHT, 0, STATE_SPOT_DIRECTION}, SWIZZLE_WWWW},
|
||||
{"spotCutoff", {STATE_LIGHT, 0, STATE_SPOT_CUTOFF}, SWIZZLE_XXXX},
|
||||
{"spotExponent", {STATE_LIGHT, 0, STATE_ATTENUATION}, SWIZZLE_WWWW},
|
||||
{"constantAttenuation", {STATE_LIGHT, 0, STATE_ATTENUATION}, SWIZZLE_XXXX},
|
||||
{"linearAttenuation", {STATE_LIGHT, 0, STATE_ATTENUATION}, SWIZZLE_YYYY},
|
||||
{"quadraticAttenuation", {STATE_LIGHT, 0, STATE_ATTENUATION}, SWIZZLE_ZZZZ},
|
||||
};
|
||||
|
||||
static struct gl_builtin_uniform_element gl_LightModel_elements[] = {
|
||||
{"ambient", {STATE_LIGHTMODEL_AMBIENT, 0}, SWIZZLE_XYZW},
|
||||
};
|
||||
|
||||
static struct gl_builtin_uniform_element gl_FrontLightModelProduct_elements[] = {
|
||||
{"sceneColor", {STATE_LIGHTMODEL_SCENECOLOR, 0}, SWIZZLE_XYZW},
|
||||
};
|
||||
|
||||
static struct gl_builtin_uniform_element gl_BackLightModelProduct_elements[] = {
|
||||
{"sceneColor", {STATE_LIGHTMODEL_SCENECOLOR, 1}, SWIZZLE_XYZW},
|
||||
};
|
||||
|
||||
static struct gl_builtin_uniform_element gl_FrontLightProduct_elements[] = {
|
||||
{"ambient", {STATE_LIGHTPROD, 0, 0, STATE_AMBIENT}, SWIZZLE_XYZW},
|
||||
{"diffuse", {STATE_LIGHTPROD, 0, 0, STATE_DIFFUSE}, SWIZZLE_XYZW},
|
||||
{"specular", {STATE_LIGHTPROD, 0, 0, STATE_SPECULAR}, SWIZZLE_XYZW},
|
||||
};
|
||||
|
||||
static struct gl_builtin_uniform_element gl_BackLightProduct_elements[] = {
|
||||
{"ambient", {STATE_LIGHTPROD, 0, 1, STATE_AMBIENT}, SWIZZLE_XYZW},
|
||||
{"diffuse", {STATE_LIGHTPROD, 0, 1, STATE_DIFFUSE}, SWIZZLE_XYZW},
|
||||
{"specular", {STATE_LIGHTPROD, 0, 1, STATE_SPECULAR}, SWIZZLE_XYZW},
|
||||
};
|
||||
|
||||
static struct gl_builtin_uniform_element gl_TextureEnvColor_elements[] = {
|
||||
{NULL, {STATE_TEXENV_COLOR, 0}, SWIZZLE_XYZW},
|
||||
};
|
||||
|
||||
static struct gl_builtin_uniform_element gl_EyePlaneS_elements[] = {
|
||||
{NULL, {STATE_TEXGEN, 0, STATE_TEXGEN_EYE_S}, SWIZZLE_XYZW},
|
||||
};
|
||||
|
||||
static struct gl_builtin_uniform_element gl_EyePlaneT_elements[] = {
|
||||
{NULL, {STATE_TEXGEN, 0, STATE_TEXGEN_EYE_T}, SWIZZLE_XYZW},
|
||||
};
|
||||
|
||||
static struct gl_builtin_uniform_element gl_EyePlaneR_elements[] = {
|
||||
{NULL, {STATE_TEXGEN, 0, STATE_TEXGEN_EYE_R}, SWIZZLE_XYZW},
|
||||
};
|
||||
|
||||
static struct gl_builtin_uniform_element gl_EyePlaneQ_elements[] = {
|
||||
{NULL, {STATE_TEXGEN, 0, STATE_TEXGEN_EYE_Q}, SWIZZLE_XYZW},
|
||||
};
|
||||
|
||||
static struct gl_builtin_uniform_element gl_ObjectPlaneS_elements[] = {
|
||||
{NULL, {STATE_TEXGEN, 0, STATE_TEXGEN_OBJECT_S}, SWIZZLE_XYZW},
|
||||
};
|
||||
|
||||
static struct gl_builtin_uniform_element gl_ObjectPlaneT_elements[] = {
|
||||
{NULL, {STATE_TEXGEN, 0, STATE_TEXGEN_OBJECT_T}, SWIZZLE_XYZW},
|
||||
};
|
||||
|
||||
static struct gl_builtin_uniform_element gl_ObjectPlaneR_elements[] = {
|
||||
{NULL, {STATE_TEXGEN, 0, STATE_TEXGEN_OBJECT_R}, SWIZZLE_XYZW},
|
||||
};
|
||||
|
||||
static struct gl_builtin_uniform_element gl_ObjectPlaneQ_elements[] = {
|
||||
{NULL, {STATE_TEXGEN, 0, STATE_TEXGEN_OBJECT_Q}, SWIZZLE_XYZW},
|
||||
};
|
||||
|
||||
static struct gl_builtin_uniform_element gl_Fog_elements[] = {
|
||||
{"color", {STATE_FOG_COLOR}, SWIZZLE_XYZW},
|
||||
{"density", {STATE_FOG_PARAMS}, SWIZZLE_XXXX},
|
||||
{"start", {STATE_FOG_PARAMS}, SWIZZLE_YYYY},
|
||||
{"end", {STATE_FOG_PARAMS}, SWIZZLE_ZZZZ},
|
||||
{"scale", {STATE_FOG_PARAMS}, SWIZZLE_WWWW},
|
||||
};
|
||||
|
||||
static struct gl_builtin_uniform_element gl_NormalScale_elements[] = {
|
||||
{NULL, {STATE_NORMAL_SCALE}, SWIZZLE_XXXX},
|
||||
};
|
||||
|
||||
static struct gl_builtin_uniform_element gl_BumpRotMatrix0MESA_elements[] = {
|
||||
{NULL, {STATE_INTERNAL, STATE_ROT_MATRIX_0}, SWIZZLE_XYZW},
|
||||
};
|
||||
|
||||
static struct gl_builtin_uniform_element gl_BumpRotMatrix1MESA_elements[] = {
|
||||
{NULL, {STATE_INTERNAL, STATE_ROT_MATRIX_1}, SWIZZLE_XYZW},
|
||||
};
|
||||
|
||||
static struct gl_builtin_uniform_element gl_FogParamsOptimizedMESA_elements[] = {
|
||||
{NULL, {STATE_INTERNAL, STATE_FOG_PARAMS_OPTIMIZED}, SWIZZLE_XYZW},
|
||||
};
|
||||
|
||||
static struct gl_builtin_uniform_element gl_CurrentAttribVertMESA_elements[] = {
|
||||
{NULL, {STATE_INTERNAL, STATE_CURRENT_ATTRIB, 0}, SWIZZLE_XYZW},
|
||||
};
|
||||
|
||||
static struct gl_builtin_uniform_element gl_CurrentAttribFragMESA_elements[] = {
|
||||
{NULL, {STATE_INTERNAL, STATE_CURRENT_ATTRIB_MAYBE_VP_CLAMPED, 0}, SWIZZLE_XYZW},
|
||||
};
|
||||
|
||||
#define MATRIX(name, statevar, modifier) \
|
||||
static struct gl_builtin_uniform_element name ## _elements[] = { \
|
||||
{ NULL, { statevar, 0, 0, 0, modifier}, SWIZZLE_XYZW }, \
|
||||
{ NULL, { statevar, 0, 1, 1, modifier}, SWIZZLE_XYZW }, \
|
||||
{ NULL, { statevar, 0, 2, 2, modifier}, SWIZZLE_XYZW }, \
|
||||
{ NULL, { statevar, 0, 3, 3, modifier}, SWIZZLE_XYZW }, \
|
||||
}
|
||||
|
||||
MATRIX(gl_ModelViewMatrix,
|
||||
STATE_MODELVIEW_MATRIX, STATE_MATRIX_TRANSPOSE);
|
||||
MATRIX(gl_ModelViewMatrixInverse,
|
||||
STATE_MODELVIEW_MATRIX, STATE_MATRIX_INVTRANS);
|
||||
MATRIX(gl_ModelViewMatrixTranspose,
|
||||
STATE_MODELVIEW_MATRIX, 0);
|
||||
MATRIX(gl_ModelViewMatrixInverseTranspose,
|
||||
STATE_MODELVIEW_MATRIX, STATE_MATRIX_INVERSE);
|
||||
|
||||
MATRIX(gl_ProjectionMatrix,
|
||||
STATE_PROJECTION_MATRIX, STATE_MATRIX_TRANSPOSE);
|
||||
MATRIX(gl_ProjectionMatrixInverse,
|
||||
STATE_PROJECTION_MATRIX, STATE_MATRIX_INVTRANS);
|
||||
MATRIX(gl_ProjectionMatrixTranspose,
|
||||
STATE_PROJECTION_MATRIX, 0);
|
||||
MATRIX(gl_ProjectionMatrixInverseTranspose,
|
||||
STATE_PROJECTION_MATRIX, STATE_MATRIX_INVERSE);
|
||||
|
||||
MATRIX(gl_ModelViewProjectionMatrix,
|
||||
STATE_MVP_MATRIX, STATE_MATRIX_TRANSPOSE);
|
||||
MATRIX(gl_ModelViewProjectionMatrixInverse,
|
||||
STATE_MVP_MATRIX, STATE_MATRIX_INVTRANS);
|
||||
MATRIX(gl_ModelViewProjectionMatrixTranspose,
|
||||
STATE_MVP_MATRIX, 0);
|
||||
MATRIX(gl_ModelViewProjectionMatrixInverseTranspose,
|
||||
STATE_MVP_MATRIX, STATE_MATRIX_INVERSE);
|
||||
|
||||
MATRIX(gl_TextureMatrix,
|
||||
STATE_TEXTURE_MATRIX, STATE_MATRIX_TRANSPOSE);
|
||||
MATRIX(gl_TextureMatrixInverse,
|
||||
STATE_TEXTURE_MATRIX, STATE_MATRIX_INVTRANS);
|
||||
MATRIX(gl_TextureMatrixTranspose,
|
||||
STATE_TEXTURE_MATRIX, 0);
|
||||
MATRIX(gl_TextureMatrixInverseTranspose,
|
||||
STATE_TEXTURE_MATRIX, STATE_MATRIX_INVERSE);
|
||||
|
||||
static struct gl_builtin_uniform_element gl_NormalMatrix_elements[] = {
|
||||
{ NULL, { STATE_MODELVIEW_MATRIX, 0, 0, 0, STATE_MATRIX_INVERSE},
|
||||
MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_Z) },
|
||||
{ NULL, { STATE_MODELVIEW_MATRIX, 0, 1, 1, STATE_MATRIX_INVERSE},
|
||||
MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_Z) },
|
||||
{ NULL, { STATE_MODELVIEW_MATRIX, 0, 2, 2, STATE_MATRIX_INVERSE},
|
||||
MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_Z) },
|
||||
};
|
||||
|
||||
#undef MATRIX
|
||||
|
||||
#define STATEVAR(name) {#name, name ## _elements, Elements(name ## _elements)}
|
||||
|
||||
const struct gl_builtin_uniform_desc _mesa_builtin_uniform_desc[] = {
|
||||
STATEVAR(gl_DepthRange),
|
||||
STATEVAR(gl_ClipPlane),
|
||||
STATEVAR(gl_Point),
|
||||
STATEVAR(gl_FrontMaterial),
|
||||
STATEVAR(gl_BackMaterial),
|
||||
STATEVAR(gl_LightSource),
|
||||
STATEVAR(gl_LightModel),
|
||||
STATEVAR(gl_FrontLightModelProduct),
|
||||
STATEVAR(gl_BackLightModelProduct),
|
||||
STATEVAR(gl_FrontLightProduct),
|
||||
STATEVAR(gl_BackLightProduct),
|
||||
STATEVAR(gl_TextureEnvColor),
|
||||
STATEVAR(gl_EyePlaneS),
|
||||
STATEVAR(gl_EyePlaneT),
|
||||
STATEVAR(gl_EyePlaneR),
|
||||
STATEVAR(gl_EyePlaneQ),
|
||||
STATEVAR(gl_ObjectPlaneS),
|
||||
STATEVAR(gl_ObjectPlaneT),
|
||||
STATEVAR(gl_ObjectPlaneR),
|
||||
STATEVAR(gl_ObjectPlaneQ),
|
||||
STATEVAR(gl_Fog),
|
||||
|
||||
STATEVAR(gl_ModelViewMatrix),
|
||||
STATEVAR(gl_ModelViewMatrixInverse),
|
||||
STATEVAR(gl_ModelViewMatrixTranspose),
|
||||
STATEVAR(gl_ModelViewMatrixInverseTranspose),
|
||||
|
||||
STATEVAR(gl_ProjectionMatrix),
|
||||
STATEVAR(gl_ProjectionMatrixInverse),
|
||||
STATEVAR(gl_ProjectionMatrixTranspose),
|
||||
STATEVAR(gl_ProjectionMatrixInverseTranspose),
|
||||
|
||||
STATEVAR(gl_ModelViewProjectionMatrix),
|
||||
STATEVAR(gl_ModelViewProjectionMatrixInverse),
|
||||
STATEVAR(gl_ModelViewProjectionMatrixTranspose),
|
||||
STATEVAR(gl_ModelViewProjectionMatrixInverseTranspose),
|
||||
|
||||
STATEVAR(gl_TextureMatrix),
|
||||
STATEVAR(gl_TextureMatrixInverse),
|
||||
STATEVAR(gl_TextureMatrixTranspose),
|
||||
STATEVAR(gl_TextureMatrixInverseTranspose),
|
||||
|
||||
STATEVAR(gl_NormalMatrix),
|
||||
STATEVAR(gl_NormalScale),
|
||||
|
||||
STATEVAR(gl_BumpRotMatrix0MESA),
|
||||
STATEVAR(gl_BumpRotMatrix1MESA),
|
||||
STATEVAR(gl_FogParamsOptimizedMESA),
|
||||
STATEVAR(gl_CurrentAttribVertMESA),
|
||||
STATEVAR(gl_CurrentAttribFragMESA),
|
||||
|
||||
{NULL, NULL, 0}
|
||||
};
|
||||
|
||||
static ir_variable *
|
||||
add_variable(exec_list *instructions, glsl_symbol_table *symtab,
|
||||
const char *name, const glsl_type *type,
|
||||
enum ir_variable_mode mode, int slot)
|
||||
{
|
||||
ir_variable *var = new(symtab) ir_variable(type, name, mode);
|
||||
|
||||
switch (var->mode) {
|
||||
case ir_var_auto:
|
||||
case ir_var_in:
|
||||
case ir_var_const_in:
|
||||
case ir_var_uniform:
|
||||
case ir_var_system_value:
|
||||
var->read_only = true;
|
||||
break;
|
||||
case ir_var_inout:
|
||||
case ir_var_out:
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
|
||||
var->location = slot;
|
||||
|
||||
/* Once the variable is created an initialized, add it to the symbol table
|
||||
* and add the declaration to the IR stream.
|
||||
*/
|
||||
instructions->push_tail(var);
|
||||
|
||||
symtab->add_variable(var);
|
||||
return var;
|
||||
}
|
||||
|
||||
static ir_variable *
|
||||
add_uniform(exec_list *instructions, glsl_symbol_table *symtab,
|
||||
const char *name, const glsl_type *type)
|
||||
{
|
||||
ir_variable *const uni =
|
||||
add_variable(instructions, symtab, name, type, ir_var_uniform, -1);
|
||||
|
||||
unsigned i;
|
||||
for (i = 0; _mesa_builtin_uniform_desc[i].name != NULL; i++) {
|
||||
if (strcmp(_mesa_builtin_uniform_desc[i].name, name) == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
assert(_mesa_builtin_uniform_desc[i].name != NULL);
|
||||
const struct gl_builtin_uniform_desc* const statevar =
|
||||
&_mesa_builtin_uniform_desc[i];
|
||||
|
||||
const unsigned array_count = type->is_array() ? type->length : 1;
|
||||
uni->num_state_slots = array_count * statevar->num_elements;
|
||||
|
||||
ir_state_slot *slots =
|
||||
ralloc_array(uni, ir_state_slot, uni->num_state_slots);
|
||||
|
||||
uni->state_slots = slots;
|
||||
|
||||
for (unsigned a = 0; a < array_count; a++) {
|
||||
for (unsigned j = 0; j < statevar->num_elements; j++) {
|
||||
struct gl_builtin_uniform_element *element = &statevar->elements[j];
|
||||
|
||||
memcpy(slots->tokens, element->tokens, sizeof(element->tokens));
|
||||
if (type->is_array()) {
|
||||
if (strcmp(name, "gl_CurrentAttribVertMESA") == 0 ||
|
||||
strcmp(name, "gl_CurrentAttribFragMESA") == 0) {
|
||||
slots->tokens[2] = a;
|
||||
} else {
|
||||
slots->tokens[1] = a;
|
||||
}
|
||||
}
|
||||
|
||||
slots->swizzle = element->swizzle;
|
||||
slots++;
|
||||
}
|
||||
}
|
||||
|
||||
return uni;
|
||||
}
|
||||
|
||||
static void
|
||||
add_builtin_variable(exec_list *instructions, glsl_symbol_table *symtab,
|
||||
const builtin_variable *proto)
|
||||
{
|
||||
/* Create a new variable declaration from the description supplied by
|
||||
* the caller.
|
||||
*/
|
||||
const glsl_type *const type = symtab->get_type(proto->type);
|
||||
|
||||
assert(type != NULL);
|
||||
|
||||
if (proto->mode == ir_var_uniform) {
|
||||
add_uniform(instructions, symtab, proto->name, type);
|
||||
} else {
|
||||
add_variable(instructions, symtab, proto->name, type, proto->mode,
|
||||
proto->slot);
|
||||
}
|
||||
}
|
||||
|
||||
static ir_variable *
|
||||
add_builtin_constant(exec_list *instructions, glsl_symbol_table *symtab,
|
||||
const char *name, int value)
|
||||
{
|
||||
ir_variable *const var = add_variable(instructions, symtab,
|
||||
name, glsl_type::int_type,
|
||||
ir_var_auto, -1);
|
||||
var->constant_value = new(var) ir_constant(value);
|
||||
var->constant_initializer = new(var) ir_constant(value);
|
||||
var->has_initializer = true;
|
||||
return var;
|
||||
}
|
||||
|
||||
/* Several constants in GLSL ES have different names than normal desktop GLSL.
|
||||
* Therefore, this function should only be called on the ES path.
|
||||
*/
|
||||
static void
|
||||
generate_100ES_uniforms(exec_list *instructions,
|
||||
struct _mesa_glsl_parse_state *state)
|
||||
{
|
||||
glsl_symbol_table *const symtab = state->symbols;
|
||||
|
||||
add_builtin_constant(instructions, symtab, "gl_MaxVertexAttribs",
|
||||
state->Const.MaxVertexAttribs);
|
||||
add_builtin_constant(instructions, symtab, "gl_MaxVertexUniformVectors",
|
||||
state->Const.MaxVertexUniformComponents);
|
||||
add_builtin_constant(instructions, symtab, "gl_MaxVaryingVectors",
|
||||
state->Const.MaxVaryingFloats / 4);
|
||||
add_builtin_constant(instructions, symtab, "gl_MaxVertexTextureImageUnits",
|
||||
state->Const.MaxVertexTextureImageUnits);
|
||||
add_builtin_constant(instructions, symtab, "gl_MaxCombinedTextureImageUnits",
|
||||
state->Const.MaxCombinedTextureImageUnits);
|
||||
add_builtin_constant(instructions, symtab, "gl_MaxTextureImageUnits",
|
||||
state->Const.MaxTextureImageUnits);
|
||||
add_builtin_constant(instructions, symtab, "gl_MaxFragmentUniformVectors",
|
||||
state->Const.MaxFragmentUniformComponents);
|
||||
|
||||
add_uniform(instructions, symtab, "gl_DepthRange",
|
||||
state->symbols->get_type("gl_DepthRangeParameters"));
|
||||
}
|
||||
|
||||
static void
|
||||
generate_110_uniforms(exec_list *instructions,
|
||||
struct _mesa_glsl_parse_state *state)
|
||||
{
|
||||
glsl_symbol_table *const symtab = state->symbols;
|
||||
|
||||
for (unsigned i = 0
|
||||
; i < Elements(builtin_110_deprecated_uniforms)
|
||||
; i++) {
|
||||
add_builtin_variable(instructions, symtab,
|
||||
& builtin_110_deprecated_uniforms[i]);
|
||||
}
|
||||
|
||||
add_builtin_constant(instructions, symtab, "gl_MaxLights",
|
||||
state->Const.MaxLights);
|
||||
add_builtin_constant(instructions, symtab, "gl_MaxClipPlanes",
|
||||
state->Const.MaxClipPlanes);
|
||||
add_builtin_constant(instructions, symtab, "gl_MaxTextureUnits",
|
||||
state->Const.MaxTextureUnits);
|
||||
add_builtin_constant(instructions, symtab, "gl_MaxTextureCoords",
|
||||
state->Const.MaxTextureCoords);
|
||||
add_builtin_constant(instructions, symtab, "gl_MaxVertexAttribs",
|
||||
state->Const.MaxVertexAttribs);
|
||||
add_builtin_constant(instructions, symtab, "gl_MaxVertexUniformComponents",
|
||||
state->Const.MaxVertexUniformComponents);
|
||||
add_builtin_constant(instructions, symtab, "gl_MaxVaryingFloats",
|
||||
state->Const.MaxVaryingFloats);
|
||||
add_builtin_constant(instructions, symtab, "gl_MaxVertexTextureImageUnits",
|
||||
state->Const.MaxVertexTextureImageUnits);
|
||||
add_builtin_constant(instructions, symtab, "gl_MaxCombinedTextureImageUnits",
|
||||
state->Const.MaxCombinedTextureImageUnits);
|
||||
add_builtin_constant(instructions, symtab, "gl_MaxTextureImageUnits",
|
||||
state->Const.MaxTextureImageUnits);
|
||||
add_builtin_constant(instructions, symtab, "gl_MaxFragmentUniformComponents",
|
||||
state->Const.MaxFragmentUniformComponents);
|
||||
|
||||
const glsl_type *const mat4_array_type =
|
||||
glsl_type::get_array_instance(glsl_type::mat4_type,
|
||||
state->Const.MaxTextureCoords);
|
||||
|
||||
add_uniform(instructions, symtab, "gl_TextureMatrix", mat4_array_type);
|
||||
add_uniform(instructions, symtab, "gl_TextureMatrixInverse", mat4_array_type);
|
||||
add_uniform(instructions, symtab, "gl_TextureMatrixTranspose", mat4_array_type);
|
||||
add_uniform(instructions, symtab, "gl_TextureMatrixInverseTranspose", mat4_array_type);
|
||||
|
||||
add_uniform(instructions, symtab, "gl_DepthRange",
|
||||
symtab->get_type("gl_DepthRangeParameters"));
|
||||
|
||||
add_uniform(instructions, symtab, "gl_ClipPlane",
|
||||
glsl_type::get_array_instance(glsl_type::vec4_type,
|
||||
state->Const.MaxClipPlanes));
|
||||
add_uniform(instructions, symtab, "gl_Point",
|
||||
symtab->get_type("gl_PointParameters"));
|
||||
|
||||
const glsl_type *const material_parameters_type =
|
||||
symtab->get_type("gl_MaterialParameters");
|
||||
add_uniform(instructions, symtab, "gl_FrontMaterial", material_parameters_type);
|
||||
add_uniform(instructions, symtab, "gl_BackMaterial", material_parameters_type);
|
||||
|
||||
const glsl_type *const light_source_array_type =
|
||||
glsl_type::get_array_instance(symtab->get_type("gl_LightSourceParameters"), state->Const.MaxLights);
|
||||
|
||||
add_uniform(instructions, symtab, "gl_LightSource", light_source_array_type);
|
||||
|
||||
const glsl_type *const light_model_products_type =
|
||||
symtab->get_type("gl_LightModelProducts");
|
||||
add_uniform(instructions, symtab, "gl_FrontLightModelProduct",
|
||||
light_model_products_type);
|
||||
add_uniform(instructions, symtab, "gl_BackLightModelProduct",
|
||||
light_model_products_type);
|
||||
|
||||
const glsl_type *const light_products_type =
|
||||
glsl_type::get_array_instance(symtab->get_type("gl_LightProducts"),
|
||||
state->Const.MaxLights);
|
||||
add_uniform(instructions, symtab, "gl_FrontLightProduct", light_products_type);
|
||||
add_uniform(instructions, symtab, "gl_BackLightProduct", light_products_type);
|
||||
|
||||
add_uniform(instructions, symtab, "gl_TextureEnvColor",
|
||||
glsl_type::get_array_instance(glsl_type::vec4_type,
|
||||
state->Const.MaxTextureUnits));
|
||||
|
||||
const glsl_type *const texcoords_vec4 =
|
||||
glsl_type::get_array_instance(glsl_type::vec4_type,
|
||||
state->Const.MaxTextureCoords);
|
||||
add_uniform(instructions, symtab, "gl_EyePlaneS", texcoords_vec4);
|
||||
add_uniform(instructions, symtab, "gl_EyePlaneT", texcoords_vec4);
|
||||
add_uniform(instructions, symtab, "gl_EyePlaneR", texcoords_vec4);
|
||||
add_uniform(instructions, symtab, "gl_EyePlaneQ", texcoords_vec4);
|
||||
add_uniform(instructions, symtab, "gl_ObjectPlaneS", texcoords_vec4);
|
||||
add_uniform(instructions, symtab, "gl_ObjectPlaneT", texcoords_vec4);
|
||||
add_uniform(instructions, symtab, "gl_ObjectPlaneR", texcoords_vec4);
|
||||
add_uniform(instructions, symtab, "gl_ObjectPlaneQ", texcoords_vec4);
|
||||
|
||||
add_uniform(instructions, symtab, "gl_Fog",
|
||||
symtab->get_type("gl_FogParameters"));
|
||||
|
||||
/* Mesa-internal current attrib state */
|
||||
const glsl_type *const vert_attribs =
|
||||
glsl_type::get_array_instance(glsl_type::vec4_type, VERT_ATTRIB_MAX);
|
||||
add_uniform(instructions, symtab, "gl_CurrentAttribVertMESA", vert_attribs);
|
||||
const glsl_type *const frag_attribs =
|
||||
glsl_type::get_array_instance(glsl_type::vec4_type, FRAG_ATTRIB_MAX);
|
||||
add_uniform(instructions, symtab, "gl_CurrentAttribFragMESA", frag_attribs);
|
||||
}
|
||||
|
||||
/* This function should only be called for ES, not desktop GL. */
|
||||
static void
|
||||
generate_100ES_vs_variables(exec_list *instructions,
|
||||
struct _mesa_glsl_parse_state *state)
|
||||
{
|
||||
for (unsigned i = 0; i < Elements(builtin_core_vs_variables); i++) {
|
||||
add_builtin_variable(instructions, state->symbols,
|
||||
& builtin_core_vs_variables[i]);
|
||||
}
|
||||
|
||||
generate_100ES_uniforms(instructions, state);
|
||||
|
||||
generate_ARB_draw_buffers_variables(instructions, state, false,
|
||||
vertex_shader);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
generate_110_vs_variables(exec_list *instructions,
|
||||
struct _mesa_glsl_parse_state *state)
|
||||
{
|
||||
for (unsigned i = 0; i < Elements(builtin_core_vs_variables); i++) {
|
||||
add_builtin_variable(instructions, state->symbols,
|
||||
& builtin_core_vs_variables[i]);
|
||||
}
|
||||
|
||||
for (unsigned i = 0
|
||||
; i < Elements(builtin_110_deprecated_vs_variables)
|
||||
; i++) {
|
||||
add_builtin_variable(instructions, state->symbols,
|
||||
& builtin_110_deprecated_vs_variables[i]);
|
||||
}
|
||||
generate_110_uniforms(instructions, state);
|
||||
|
||||
/* From page 54 (page 60 of the PDF) of the GLSL 1.20 spec:
|
||||
*
|
||||
* "As with all arrays, indices used to subscript gl_TexCoord must
|
||||
* either be an integral constant expressions, or this array must be
|
||||
* re-declared by the shader with a size. The size can be at most
|
||||
* gl_MaxTextureCoords. Using indexes close to 0 may aid the
|
||||
* implementation in preserving varying resources."
|
||||
*/
|
||||
const glsl_type *const vec4_array_type =
|
||||
glsl_type::get_array_instance(glsl_type::vec4_type, 0);
|
||||
|
||||
add_variable(instructions, state->symbols,
|
||||
"gl_TexCoord", vec4_array_type, ir_var_out, VERT_RESULT_TEX0);
|
||||
|
||||
generate_ARB_draw_buffers_variables(instructions, state, false,
|
||||
vertex_shader);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
generate_120_vs_variables(exec_list *instructions,
|
||||
struct _mesa_glsl_parse_state *state)
|
||||
{
|
||||
/* GLSL version 1.20 did not add any built-in variables in the vertex
|
||||
* shader.
|
||||
*/
|
||||
generate_110_vs_variables(instructions, state);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
generate_130_uniforms(exec_list *instructions,
|
||||
struct _mesa_glsl_parse_state *state)
|
||||
{
|
||||
glsl_symbol_table *const symtab = state->symbols;
|
||||
|
||||
add_builtin_constant(instructions, symtab, "gl_MaxClipDistances",
|
||||
state->Const.MaxClipPlanes);
|
||||
add_builtin_constant(instructions, symtab, "gl_MaxVaryingComponents",
|
||||
state->Const.MaxVaryingFloats);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
generate_130_vs_variables(exec_list *instructions,
|
||||
struct _mesa_glsl_parse_state *state)
|
||||
{
|
||||
generate_120_vs_variables(instructions, state);
|
||||
|
||||
for (unsigned i = 0; i < Elements(builtin_130_vs_variables); i++) {
|
||||
add_builtin_variable(instructions, state->symbols,
|
||||
& builtin_130_vs_variables[i]);
|
||||
}
|
||||
|
||||
generate_130_uniforms(instructions, state);
|
||||
|
||||
/* From the GLSL 1.30 spec, section 7.1 (Vertex Shader Special
|
||||
* Variables):
|
||||
*
|
||||
* The gl_ClipDistance array is predeclared as unsized and must
|
||||
* be sized by the shader either redeclaring it with a size or
|
||||
* indexing it only with integral constant expressions.
|
||||
*
|
||||
* We represent this in Mesa by initially declaring the array as
|
||||
* size 0.
|
||||
*/
|
||||
const glsl_type *const clip_distance_array_type =
|
||||
glsl_type::get_array_instance(glsl_type::float_type, 0);
|
||||
|
||||
add_variable(instructions, state->symbols,
|
||||
"gl_ClipDistance", clip_distance_array_type, ir_var_out,
|
||||
VERT_RESULT_CLIP_DIST0);
|
||||
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
initialize_vs_variables(exec_list *instructions,
|
||||
struct _mesa_glsl_parse_state *state)
|
||||
{
|
||||
|
||||
switch (state->language_version) {
|
||||
case 100:
|
||||
generate_100ES_vs_variables(instructions, state);
|
||||
break;
|
||||
case 110:
|
||||
generate_110_vs_variables(instructions, state);
|
||||
break;
|
||||
case 120:
|
||||
generate_120_vs_variables(instructions, state);
|
||||
break;
|
||||
case 130:
|
||||
generate_130_vs_variables(instructions, state);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* This function should only be called for ES, not desktop GL. */
|
||||
static void
|
||||
generate_100ES_fs_variables(exec_list *instructions,
|
||||
struct _mesa_glsl_parse_state *state)
|
||||
{
|
||||
for (unsigned i = 0; i < Elements(builtin_core_fs_variables); i++) {
|
||||
add_builtin_variable(instructions, state->symbols,
|
||||
& builtin_core_fs_variables[i]);
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < Elements(builtin_100ES_fs_variables); i++) {
|
||||
add_builtin_variable(instructions, state->symbols,
|
||||
& builtin_100ES_fs_variables[i]);
|
||||
}
|
||||
|
||||
generate_100ES_uniforms(instructions, state);
|
||||
|
||||
generate_ARB_draw_buffers_variables(instructions, state, false,
|
||||
fragment_shader);
|
||||
}
|
||||
|
||||
static void
|
||||
generate_110_fs_variables(exec_list *instructions,
|
||||
struct _mesa_glsl_parse_state *state)
|
||||
{
|
||||
for (unsigned i = 0; i < Elements(builtin_core_fs_variables); i++) {
|
||||
add_builtin_variable(instructions, state->symbols,
|
||||
& builtin_core_fs_variables[i]);
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < Elements(builtin_110_fs_variables); i++) {
|
||||
add_builtin_variable(instructions, state->symbols,
|
||||
& builtin_110_fs_variables[i]);
|
||||
}
|
||||
|
||||
for (unsigned i = 0
|
||||
; i < Elements(builtin_110_deprecated_fs_variables)
|
||||
; i++) {
|
||||
add_builtin_variable(instructions, state->symbols,
|
||||
& builtin_110_deprecated_fs_variables[i]);
|
||||
}
|
||||
generate_110_uniforms(instructions, state);
|
||||
|
||||
/* From page 54 (page 60 of the PDF) of the GLSL 1.20 spec:
|
||||
*
|
||||
* "As with all arrays, indices used to subscript gl_TexCoord must
|
||||
* either be an integral constant expressions, or this array must be
|
||||
* re-declared by the shader with a size. The size can be at most
|
||||
* gl_MaxTextureCoords. Using indexes close to 0 may aid the
|
||||
* implementation in preserving varying resources."
|
||||
*/
|
||||
const glsl_type *const vec4_array_type =
|
||||
glsl_type::get_array_instance(glsl_type::vec4_type, 0);
|
||||
|
||||
add_variable(instructions, state->symbols,
|
||||
"gl_TexCoord", vec4_array_type, ir_var_in, FRAG_ATTRIB_TEX0);
|
||||
|
||||
generate_ARB_draw_buffers_variables(instructions, state, false,
|
||||
fragment_shader);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
generate_ARB_draw_buffers_variables(exec_list *instructions,
|
||||
struct _mesa_glsl_parse_state *state,
|
||||
bool warn, _mesa_glsl_parser_targets target)
|
||||
{
|
||||
/* gl_MaxDrawBuffers is available in all shader stages.
|
||||
*/
|
||||
ir_variable *const mdb =
|
||||
add_builtin_constant(instructions, state->symbols, "gl_MaxDrawBuffers",
|
||||
state->Const.MaxDrawBuffers);
|
||||
|
||||
if (warn)
|
||||
mdb->warn_extension = "GL_ARB_draw_buffers";
|
||||
|
||||
/* gl_FragData is only available in the fragment shader.
|
||||
*/
|
||||
if (target == fragment_shader) {
|
||||
const glsl_type *const vec4_array_type =
|
||||
glsl_type::get_array_instance(glsl_type::vec4_type,
|
||||
state->Const.MaxDrawBuffers);
|
||||
|
||||
ir_variable *const fd =
|
||||
add_variable(instructions, state->symbols,
|
||||
"gl_FragData", vec4_array_type,
|
||||
ir_var_out, FRAG_RESULT_DATA0);
|
||||
|
||||
if (warn)
|
||||
fd->warn_extension = "GL_ARB_draw_buffers";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
generate_ARB_shader_stencil_export_variables(exec_list *instructions,
|
||||
struct _mesa_glsl_parse_state *state,
|
||||
bool warn)
|
||||
{
|
||||
/* gl_FragStencilRefARB is only available in the fragment shader.
|
||||
*/
|
||||
ir_variable *const fd =
|
||||
add_variable(instructions, state->symbols,
|
||||
"gl_FragStencilRefARB", glsl_type::int_type,
|
||||
ir_var_out, FRAG_RESULT_STENCIL);
|
||||
|
||||
if (warn)
|
||||
fd->warn_extension = "GL_ARB_shader_stencil_export";
|
||||
}
|
||||
|
||||
static void
|
||||
generate_AMD_shader_stencil_export_variables(exec_list *instructions,
|
||||
struct _mesa_glsl_parse_state *state,
|
||||
bool warn)
|
||||
{
|
||||
/* gl_FragStencilRefAMD is only available in the fragment shader.
|
||||
*/
|
||||
ir_variable *const fd =
|
||||
add_variable(instructions, state->symbols,
|
||||
"gl_FragStencilRefAMD", glsl_type::int_type,
|
||||
ir_var_out, FRAG_RESULT_STENCIL);
|
||||
|
||||
if (warn)
|
||||
fd->warn_extension = "GL_AMD_shader_stencil_export";
|
||||
}
|
||||
|
||||
static void
|
||||
generate_120_fs_variables(exec_list *instructions,
|
||||
struct _mesa_glsl_parse_state *state)
|
||||
{
|
||||
generate_110_fs_variables(instructions, state);
|
||||
|
||||
for (unsigned i = 0
|
||||
; i < Elements(builtin_120_fs_variables)
|
||||
; i++) {
|
||||
add_builtin_variable(instructions, state->symbols,
|
||||
& builtin_120_fs_variables[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
generate_130_fs_variables(exec_list *instructions,
|
||||
struct _mesa_glsl_parse_state *state)
|
||||
{
|
||||
generate_120_fs_variables(instructions, state);
|
||||
|
||||
generate_130_uniforms(instructions, state);
|
||||
|
||||
/* From the GLSL 1.30 spec, section 7.2 (Fragment Shader Special
|
||||
* Variables):
|
||||
*
|
||||
* The built-in input variable gl_ClipDistance array contains linearly
|
||||
* interpolated values for the vertex values written by the vertex shader
|
||||
* to the gl_ClipDistance vertex output variable. This array must be
|
||||
* sized in the fragment shader either implicitly or explicitly to be the
|
||||
* same size as it was sized in the vertex shader.
|
||||
*
|
||||
* In other words, the array must be pre-declared as implicitly sized. We
|
||||
* represent this in Mesa by initially declaring the array as size 0.
|
||||
*/
|
||||
const glsl_type *const clip_distance_array_type =
|
||||
glsl_type::get_array_instance(glsl_type::float_type, 0);
|
||||
|
||||
add_variable(instructions, state->symbols,
|
||||
"gl_ClipDistance", clip_distance_array_type, ir_var_in,
|
||||
FRAG_ATTRIB_CLIP_DIST0);
|
||||
}
|
||||
|
||||
static void
|
||||
initialize_fs_variables(exec_list *instructions,
|
||||
struct _mesa_glsl_parse_state *state)
|
||||
{
|
||||
|
||||
switch (state->language_version) {
|
||||
case 100:
|
||||
generate_100ES_fs_variables(instructions, state);
|
||||
break;
|
||||
case 110:
|
||||
generate_110_fs_variables(instructions, state);
|
||||
break;
|
||||
case 120:
|
||||
generate_120_fs_variables(instructions, state);
|
||||
break;
|
||||
case 130:
|
||||
generate_130_fs_variables(instructions, state);
|
||||
break;
|
||||
}
|
||||
|
||||
if (state->ARB_shader_stencil_export_enable)
|
||||
generate_ARB_shader_stencil_export_variables(instructions, state,
|
||||
state->ARB_shader_stencil_export_warn);
|
||||
|
||||
if (state->AMD_shader_stencil_export_enable)
|
||||
generate_AMD_shader_stencil_export_variables(instructions, state,
|
||||
state->AMD_shader_stencil_export_warn);
|
||||
}
|
||||
|
||||
void
|
||||
_mesa_glsl_initialize_variables(exec_list *instructions,
|
||||
struct _mesa_glsl_parse_state *state)
|
||||
{
|
||||
switch (state->target) {
|
||||
case vertex_shader:
|
||||
initialize_vs_variables(instructions, state);
|
||||
break;
|
||||
case fragment_shader:
|
||||
initialize_fs_variables(instructions, state);
|
||||
break;
|
||||
}
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
glcpp -- GLSL "C" preprocessor
|
||||
|
||||
This is a simple preprocessor designed to provide the preprocessing
|
||||
needs of the GLSL language. The requirements for this preprocessor are
|
||||
specified in the GLSL 1.30 specification availble from:
|
||||
|
||||
http://www.opengl.org/registry/doc/GLSLangSpec.Full.1.30.10.pdf
|
||||
|
||||
This specification is not precise on some semantics, (for example,
|
||||
#define and #if), defining these merely "as is standard for C++
|
||||
preprocessors". To fill in these details, I've been using a draft of
|
||||
the C99 standard as available from:
|
||||
|
||||
http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf
|
||||
|
||||
Any downstream compiler accepting output from glcpp should be prepared
|
||||
to encounter and deal with the following preprocessor macros:
|
||||
|
||||
#line
|
||||
#pragma
|
||||
#extension
|
||||
|
||||
All other macros will be handles according to the GLSL specification
|
||||
and will not appear in the output.
|
||||
|
||||
Known limitations
|
||||
-----------------
|
||||
The __LINE__ and __FILE__ macros are not yet supported.
|
||||
|
||||
A file that ends with a function-like macro name as the last
|
||||
non-whitespace token will result in a parse error, (where it should be
|
||||
passed through as is).
|
File diff suppressed because it is too large
Load diff
|
@ -1,332 +0,0 @@
|
|||
%{
|
||||
/*
|
||||
* Copyright © 2010 Intel Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "glcpp.h"
|
||||
#include "glcpp-parse.h"
|
||||
|
||||
/* Flex annoyingly generates some functions without making them
|
||||
* static. Let's declare them here. */
|
||||
int glcpp_get_column (yyscan_t yyscanner);
|
||||
void glcpp_set_column (int column_no , yyscan_t yyscanner);
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define YY_NO_UNISTD_H
|
||||
#endif
|
||||
|
||||
#define YY_NO_INPUT
|
||||
|
||||
#define YY_USER_ACTION \
|
||||
do { \
|
||||
yylloc->first_column = yycolumn + 1; \
|
||||
yylloc->first_line = yylineno; \
|
||||
yycolumn += yyleng; \
|
||||
} while(0);
|
||||
|
||||
#define YY_USER_INIT \
|
||||
do { \
|
||||
yylineno = 1; \
|
||||
yycolumn = 1; \
|
||||
yylloc->source = 0; \
|
||||
} while(0)
|
||||
%}
|
||||
|
||||
%option bison-bridge bison-locations reentrant noyywrap
|
||||
%option extra-type="glcpp_parser_t *"
|
||||
%option prefix="glcpp_"
|
||||
%option stack
|
||||
%option never-interactive
|
||||
|
||||
%x DONE COMMENT UNREACHABLE SKIP
|
||||
|
||||
SPACE [[:space:]]
|
||||
NONSPACE [^[:space:]]
|
||||
NEWLINE [\n]
|
||||
HSPACE [ \t]
|
||||
HASH ^{HSPACE}*#{HSPACE}*
|
||||
IDENTIFIER [_a-zA-Z][_a-zA-Z0-9]*
|
||||
PUNCTUATION [][(){}.&*~!/%<>^|;,=+-]
|
||||
|
||||
/* The OTHER class is simply a catch-all for things that the CPP
|
||||
parser just doesn't care about. Since flex regular expressions that
|
||||
match longer strings take priority over those matching shorter
|
||||
strings, we have to be careful to avoid OTHER matching and hiding
|
||||
something that CPP does care about. So we simply exclude all
|
||||
characters that appear in any other expressions. */
|
||||
|
||||
OTHER [^][_#[:space:]#a-zA-Z0-9(){}.&*~!/%<>^|;,=+-]
|
||||
|
||||
DIGITS [0-9][0-9]*
|
||||
DECIMAL_INTEGER [1-9][0-9]*[uU]?
|
||||
OCTAL_INTEGER 0[0-7]*[uU]?
|
||||
HEXADECIMAL_INTEGER 0[xX][0-9a-fA-F]+[uU]?
|
||||
|
||||
%%
|
||||
/* Implicitly switch between SKIP and INITIAL (non-skipping);
|
||||
* don't switch if some other state was explicitly set.
|
||||
*/
|
||||
glcpp_parser_t *parser = yyextra;
|
||||
if (YY_START == 0 || YY_START == SKIP) {
|
||||
if (parser->lexing_if || parser->skip_stack == NULL || parser->skip_stack->type == SKIP_NO_SKIP) {
|
||||
BEGIN 0;
|
||||
} else {
|
||||
BEGIN SKIP;
|
||||
}
|
||||
}
|
||||
|
||||
/* Single-line comments */
|
||||
"//"[^\n]* {
|
||||
}
|
||||
|
||||
/* Multi-line comments */
|
||||
"/*" { yy_push_state(COMMENT, yyscanner); }
|
||||
<COMMENT>[^*\n]*
|
||||
<COMMENT>[^*\n]*\n { yylineno++; yycolumn = 0; return NEWLINE; }
|
||||
<COMMENT>"*"+[^*/\n]*
|
||||
<COMMENT>"*"+[^*/\n]*\n { yylineno++; yycolumn = 0; return NEWLINE; }
|
||||
<COMMENT>"*"+"/" {
|
||||
yy_pop_state(yyscanner);
|
||||
if (yyextra->space_tokens)
|
||||
return SPACE;
|
||||
}
|
||||
|
||||
{HASH}version {
|
||||
yylval->str = ralloc_strdup (yyextra, yytext);
|
||||
yyextra->space_tokens = 0;
|
||||
return HASH_VERSION;
|
||||
}
|
||||
|
||||
/* glcpp doesn't handle #extension, #version, or #pragma directives.
|
||||
* Simply pass them through to the main compiler's lexer/parser. */
|
||||
{HASH}(extension|pragma)[^\n]+ {
|
||||
yylval->str = ralloc_strdup (yyextra, yytext);
|
||||
yylineno++;
|
||||
yycolumn = 0;
|
||||
return OTHER;
|
||||
}
|
||||
|
||||
{HASH}line{HSPACE}+{DIGITS}{HSPACE}+{DIGITS}{HSPACE}*$ {
|
||||
/* Eat characters until the first digit is
|
||||
* encountered
|
||||
*/
|
||||
char *ptr = yytext;
|
||||
while (!isdigit(*ptr))
|
||||
ptr++;
|
||||
|
||||
/* Subtract one from the line number because
|
||||
* yylineno is zero-based instead of
|
||||
* one-based.
|
||||
*/
|
||||
yylineno = strtol(ptr, &ptr, 0) - 1;
|
||||
yylloc->source = strtol(ptr, NULL, 0);
|
||||
}
|
||||
|
||||
{HASH}line{HSPACE}+{DIGITS}{HSPACE}*$ {
|
||||
/* Eat characters until the first digit is
|
||||
* encountered
|
||||
*/
|
||||
char *ptr = yytext;
|
||||
while (!isdigit(*ptr))
|
||||
ptr++;
|
||||
|
||||
/* Subtract one from the line number because
|
||||
* yylineno is zero-based instead of
|
||||
* one-based.
|
||||
*/
|
||||
yylineno = strtol(ptr, &ptr, 0) - 1;
|
||||
}
|
||||
|
||||
<SKIP,INITIAL>{
|
||||
{HASH}ifdef {
|
||||
yyextra->lexing_if = 1;
|
||||
yyextra->space_tokens = 0;
|
||||
return HASH_IFDEF;
|
||||
}
|
||||
|
||||
{HASH}ifndef {
|
||||
yyextra->lexing_if = 1;
|
||||
yyextra->space_tokens = 0;
|
||||
return HASH_IFNDEF;
|
||||
}
|
||||
|
||||
{HASH}if/[^_a-zA-Z0-9] {
|
||||
yyextra->lexing_if = 1;
|
||||
yyextra->space_tokens = 0;
|
||||
return HASH_IF;
|
||||
}
|
||||
|
||||
{HASH}elif {
|
||||
yyextra->lexing_if = 1;
|
||||
yyextra->space_tokens = 0;
|
||||
return HASH_ELIF;
|
||||
}
|
||||
|
||||
{HASH}else {
|
||||
yyextra->space_tokens = 0;
|
||||
return HASH_ELSE;
|
||||
}
|
||||
|
||||
{HASH}endif {
|
||||
yyextra->space_tokens = 0;
|
||||
return HASH_ENDIF;
|
||||
}
|
||||
}
|
||||
|
||||
<SKIP>[^\n] ;
|
||||
|
||||
{HASH}error.* {
|
||||
char *p;
|
||||
for (p = yytext; !isalpha(p[0]); p++); /* skip " # " */
|
||||
p += 5; /* skip "error" */
|
||||
glcpp_error(yylloc, yyextra, "#error%s", p);
|
||||
}
|
||||
|
||||
{HASH}define{HSPACE}+/{IDENTIFIER}"(" {
|
||||
yyextra->space_tokens = 0;
|
||||
return HASH_DEFINE_FUNC;
|
||||
}
|
||||
|
||||
{HASH}define {
|
||||
yyextra->space_tokens = 0;
|
||||
return HASH_DEFINE_OBJ;
|
||||
}
|
||||
|
||||
{HASH}undef {
|
||||
yyextra->space_tokens = 0;
|
||||
return HASH_UNDEF;
|
||||
}
|
||||
|
||||
{HASH} {
|
||||
yyextra->space_tokens = 0;
|
||||
return HASH;
|
||||
}
|
||||
|
||||
{DECIMAL_INTEGER} {
|
||||
yylval->str = ralloc_strdup (yyextra, yytext);
|
||||
return INTEGER_STRING;
|
||||
}
|
||||
|
||||
{OCTAL_INTEGER} {
|
||||
yylval->str = ralloc_strdup (yyextra, yytext);
|
||||
return INTEGER_STRING;
|
||||
}
|
||||
|
||||
{HEXADECIMAL_INTEGER} {
|
||||
yylval->str = ralloc_strdup (yyextra, yytext);
|
||||
return INTEGER_STRING;
|
||||
}
|
||||
|
||||
"<<" {
|
||||
return LEFT_SHIFT;
|
||||
}
|
||||
|
||||
">>" {
|
||||
return RIGHT_SHIFT;
|
||||
}
|
||||
|
||||
"<=" {
|
||||
return LESS_OR_EQUAL;
|
||||
}
|
||||
|
||||
">=" {
|
||||
return GREATER_OR_EQUAL;
|
||||
}
|
||||
|
||||
"==" {
|
||||
return EQUAL;
|
||||
}
|
||||
|
||||
"!=" {
|
||||
return NOT_EQUAL;
|
||||
}
|
||||
|
||||
"&&" {
|
||||
return AND;
|
||||
}
|
||||
|
||||
"||" {
|
||||
return OR;
|
||||
}
|
||||
|
||||
"##" {
|
||||
return PASTE;
|
||||
}
|
||||
|
||||
"defined" {
|
||||
return DEFINED;
|
||||
}
|
||||
|
||||
{IDENTIFIER} {
|
||||
yylval->str = ralloc_strdup (yyextra, yytext);
|
||||
return IDENTIFIER;
|
||||
}
|
||||
|
||||
{PUNCTUATION} {
|
||||
return yytext[0];
|
||||
}
|
||||
|
||||
{OTHER}+ {
|
||||
yylval->str = ralloc_strdup (yyextra, yytext);
|
||||
return OTHER;
|
||||
}
|
||||
|
||||
{HSPACE}+ {
|
||||
if (yyextra->space_tokens) {
|
||||
return SPACE;
|
||||
}
|
||||
}
|
||||
|
||||
<SKIP,INITIAL>\n {
|
||||
yyextra->lexing_if = 0;
|
||||
yylineno++;
|
||||
yycolumn = 0;
|
||||
return NEWLINE;
|
||||
}
|
||||
|
||||
/* Handle missing newline at EOF. */
|
||||
<INITIAL><<EOF>> {
|
||||
BEGIN DONE; /* Don't keep matching this rule forever. */
|
||||
yyextra->lexing_if = 0;
|
||||
return NEWLINE;
|
||||
}
|
||||
|
||||
/* We don't actually use the UNREACHABLE start condition. We
|
||||
only have this action here so that we can pretend to call some
|
||||
generated functions, (to avoid "defined but not used"
|
||||
warnings. */
|
||||
<UNREACHABLE>. {
|
||||
unput('.');
|
||||
yy_top_state(yyextra);
|
||||
}
|
||||
|
||||
%%
|
||||
|
||||
void
|
||||
glcpp_lex_set_source_string(glcpp_parser_t *parser, const char *shader)
|
||||
{
|
||||
yy_scan_string(shader, parser->scanner);
|
||||
}
|
File diff suppressed because it is too large
Load diff
|
@ -1,100 +0,0 @@
|
|||
/* A Bison parser, made by GNU Bison 2.4.3. */
|
||||
|
||||
/* Skeleton interface for Bison's Yacc-like parsers in C
|
||||
|
||||
Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
|
||||
2009, 2010 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* As a special exception, you may create a larger work that contains
|
||||
part or all of the Bison parser skeleton and distribute that work
|
||||
under terms of your choice, so long as that work isn't itself a
|
||||
parser generator using the skeleton or a modified version thereof
|
||||
as a parser skeleton. Alternatively, if you modify or redistribute
|
||||
the parser skeleton itself, you may (at your option) remove this
|
||||
special exception, which will cause the skeleton and the resulting
|
||||
Bison output files to be licensed under the GNU General Public
|
||||
License without this special exception.
|
||||
|
||||
This special exception was added by the Free Software Foundation in
|
||||
version 2.2 of Bison. */
|
||||
|
||||
|
||||
/* Tokens. */
|
||||
#ifndef YYTOKENTYPE
|
||||
# define YYTOKENTYPE
|
||||
/* Put the tokens into the symbol table, so that GDB and other debuggers
|
||||
know about them. */
|
||||
enum yytokentype {
|
||||
COMMA_FINAL = 258,
|
||||
DEFINED = 259,
|
||||
ELIF_EXPANDED = 260,
|
||||
HASH = 261,
|
||||
HASH_DEFINE_FUNC = 262,
|
||||
HASH_DEFINE_OBJ = 263,
|
||||
HASH_ELIF = 264,
|
||||
HASH_ELSE = 265,
|
||||
HASH_ENDIF = 266,
|
||||
HASH_IF = 267,
|
||||
HASH_IFDEF = 268,
|
||||
HASH_IFNDEF = 269,
|
||||
HASH_UNDEF = 270,
|
||||
HASH_VERSION = 271,
|
||||
IDENTIFIER = 272,
|
||||
IF_EXPANDED = 273,
|
||||
INTEGER = 274,
|
||||
INTEGER_STRING = 275,
|
||||
NEWLINE = 276,
|
||||
OTHER = 277,
|
||||
PLACEHOLDER = 278,
|
||||
SPACE = 279,
|
||||
PASTE = 280,
|
||||
OR = 281,
|
||||
AND = 282,
|
||||
NOT_EQUAL = 283,
|
||||
EQUAL = 284,
|
||||
GREATER_OR_EQUAL = 285,
|
||||
LESS_OR_EQUAL = 286,
|
||||
RIGHT_SHIFT = 287,
|
||||
LEFT_SHIFT = 288,
|
||||
UNARY = 289
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
|
||||
|
||||
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
|
||||
# define YYSTYPE_IS_DECLARED 1
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
|
||||
typedef struct YYLTYPE
|
||||
{
|
||||
int first_line;
|
||||
int first_column;
|
||||
int last_line;
|
||||
int last_column;
|
||||
} YYLTYPE;
|
||||
# define yyltype YYLTYPE /* obsolescent; will be withdrawn */
|
||||
# define YYLTYPE_IS_DECLARED 1
|
||||
# define YYLTYPE_IS_TRIVIAL 1
|
||||
#endif
|
||||
|
||||
|
||||
|
File diff suppressed because it is too large
Load diff
|
@ -1,122 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2010 Intel Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include "glcpp.h"
|
||||
#include "main/mtypes.h"
|
||||
#include "main/shaderobj.h"
|
||||
|
||||
extern int yydebug;
|
||||
|
||||
void
|
||||
_mesa_reference_shader(struct gl_context *ctx, struct gl_shader **ptr,
|
||||
struct gl_shader *sh)
|
||||
{
|
||||
(void) ctx;
|
||||
*ptr = sh;
|
||||
}
|
||||
|
||||
/* Read from fp until EOF and return a string of everything read.
|
||||
*/
|
||||
static char *
|
||||
load_text_fp (void *ctx, FILE *fp)
|
||||
{
|
||||
#define CHUNK 4096
|
||||
char *text = NULL;
|
||||
size_t text_size = 0;
|
||||
size_t total_read = 0;
|
||||
size_t bytes;
|
||||
|
||||
while (1) {
|
||||
if (total_read + CHUNK + 1 > text_size) {
|
||||
text_size = text_size ? text_size * 2 : CHUNK + 1;
|
||||
text = reralloc_size (ctx, text, text_size);
|
||||
if (text == NULL) {
|
||||
fprintf (stderr, "Out of memory\n");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
bytes = fread (text + total_read, 1, CHUNK, fp);
|
||||
total_read += bytes;
|
||||
|
||||
if (bytes < CHUNK) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
text[total_read] = '\0';
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
static char *
|
||||
load_text_file(void *ctx, const char *filename)
|
||||
{
|
||||
char *text;
|
||||
FILE *fp;
|
||||
|
||||
if (filename == NULL || strcmp (filename, "-") == 0)
|
||||
return load_text_fp (ctx, stdin);
|
||||
|
||||
fp = fopen (filename, "r");
|
||||
if (fp == NULL) {
|
||||
fprintf (stderr, "Failed to open file %s: %s\n",
|
||||
filename, strerror (errno));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
text = load_text_fp (ctx, fp);
|
||||
|
||||
fclose(fp);
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
char *filename = NULL;
|
||||
void *ctx = ralloc(NULL, void*);
|
||||
char *info_log = ralloc_strdup(ctx, "");
|
||||
const char *shader;
|
||||
int ret;
|
||||
|
||||
if (argc) {
|
||||
filename = argv[1];
|
||||
}
|
||||
|
||||
shader = load_text_file (ctx, filename);
|
||||
if (shader == NULL)
|
||||
return 1;
|
||||
|
||||
ret = preprocess(ctx, &shader, &info_log, NULL);
|
||||
|
||||
printf("%s", shader);
|
||||
fprintf(stderr, "%s", info_log);
|
||||
|
||||
ralloc_free(ctx);
|
||||
|
||||
return ret;
|
||||
}
|
|
@ -1,222 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2010 Intel Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef GLCPP_H
|
||||
#define GLCPP_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "../ralloc.h"
|
||||
|
||||
#include "program/hash_table.h"
|
||||
|
||||
#define yyscan_t void*
|
||||
|
||||
/* Some data types used for parser values. */
|
||||
|
||||
typedef struct string_node {
|
||||
const char *str;
|
||||
struct string_node *next;
|
||||
} string_node_t;
|
||||
|
||||
typedef struct string_list {
|
||||
string_node_t *head;
|
||||
string_node_t *tail;
|
||||
} string_list_t;
|
||||
|
||||
typedef struct token token_t;
|
||||
typedef struct token_list token_list_t;
|
||||
|
||||
typedef union YYSTYPE
|
||||
{
|
||||
intmax_t ival;
|
||||
char *str;
|
||||
string_list_t *string_list;
|
||||
token_t *token;
|
||||
token_list_t *token_list;
|
||||
} YYSTYPE;
|
||||
|
||||
# define YYSTYPE_IS_TRIVIAL 1
|
||||
# define YYSTYPE_IS_DECLARED 1
|
||||
|
||||
typedef struct YYLTYPE {
|
||||
int first_line;
|
||||
int first_column;
|
||||
int last_line;
|
||||
int last_column;
|
||||
unsigned source;
|
||||
} YYLTYPE;
|
||||
# define YYLTYPE_IS_DECLARED 1
|
||||
# define YYLTYPE_IS_TRIVIAL 1
|
||||
|
||||
# define YYLLOC_DEFAULT(Current, Rhs, N) \
|
||||
do { \
|
||||
if (N) \
|
||||
{ \
|
||||
(Current).first_line = YYRHSLOC(Rhs, 1).first_line; \
|
||||
(Current).first_column = YYRHSLOC(Rhs, 1).first_column; \
|
||||
(Current).last_line = YYRHSLOC(Rhs, N).last_line; \
|
||||
(Current).last_column = YYRHSLOC(Rhs, N).last_column; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
(Current).first_line = (Current).last_line = \
|
||||
YYRHSLOC(Rhs, 0).last_line; \
|
||||
(Current).first_column = (Current).last_column = \
|
||||
YYRHSLOC(Rhs, 0).last_column; \
|
||||
} \
|
||||
(Current).source = 0; \
|
||||
} while (0)
|
||||
|
||||
struct token {
|
||||
int type;
|
||||
YYSTYPE value;
|
||||
YYLTYPE location;
|
||||
};
|
||||
|
||||
typedef struct token_node {
|
||||
token_t *token;
|
||||
struct token_node *next;
|
||||
} token_node_t;
|
||||
|
||||
struct token_list {
|
||||
token_node_t *head;
|
||||
token_node_t *tail;
|
||||
token_node_t *non_space_tail;
|
||||
};
|
||||
|
||||
typedef struct argument_node {
|
||||
token_list_t *argument;
|
||||
struct argument_node *next;
|
||||
} argument_node_t;
|
||||
|
||||
typedef struct argument_list {
|
||||
argument_node_t *head;
|
||||
argument_node_t *tail;
|
||||
} argument_list_t;
|
||||
|
||||
typedef struct glcpp_parser glcpp_parser_t;
|
||||
|
||||
typedef enum {
|
||||
TOKEN_CLASS_IDENTIFIER,
|
||||
TOKEN_CLASS_IDENTIFIER_FINALIZED,
|
||||
TOKEN_CLASS_FUNC_MACRO,
|
||||
TOKEN_CLASS_OBJ_MACRO
|
||||
} token_class_t;
|
||||
|
||||
token_class_t
|
||||
glcpp_parser_classify_token (glcpp_parser_t *parser,
|
||||
const char *identifier,
|
||||
int *parameter_index);
|
||||
|
||||
typedef struct {
|
||||
int is_function;
|
||||
string_list_t *parameters;
|
||||
const char *identifier;
|
||||
token_list_t *replacements;
|
||||
} macro_t;
|
||||
|
||||
typedef struct expansion_node {
|
||||
macro_t *macro;
|
||||
token_node_t *replacements;
|
||||
struct expansion_node *next;
|
||||
} expansion_node_t;
|
||||
|
||||
typedef enum skip_type {
|
||||
SKIP_NO_SKIP,
|
||||
SKIP_TO_ELSE,
|
||||
SKIP_TO_ENDIF
|
||||
} skip_type_t;
|
||||
|
||||
typedef struct skip_node {
|
||||
skip_type_t type;
|
||||
YYLTYPE loc; /* location of the initial #if/#elif/... */
|
||||
struct skip_node *next;
|
||||
} skip_node_t;
|
||||
|
||||
typedef struct active_list {
|
||||
const char *identifier;
|
||||
token_node_t *marker;
|
||||
struct active_list *next;
|
||||
} active_list_t;
|
||||
|
||||
struct glcpp_parser {
|
||||
yyscan_t scanner;
|
||||
struct hash_table *defines;
|
||||
active_list_t *active;
|
||||
int lexing_if;
|
||||
int space_tokens;
|
||||
int newline_as_space;
|
||||
int in_control_line;
|
||||
int paren_count;
|
||||
skip_node_t *skip_stack;
|
||||
token_list_t *lex_from_list;
|
||||
token_node_t *lex_from_node;
|
||||
char *output;
|
||||
char *info_log;
|
||||
int error;
|
||||
};
|
||||
|
||||
struct gl_extensions;
|
||||
|
||||
glcpp_parser_t *
|
||||
glcpp_parser_create (const struct gl_extensions *extensions);
|
||||
|
||||
int
|
||||
glcpp_parser_parse (glcpp_parser_t *parser);
|
||||
|
||||
void
|
||||
glcpp_parser_destroy (glcpp_parser_t *parser);
|
||||
|
||||
int
|
||||
preprocess(void *ralloc_ctx, const char **shader, char **info_log,
|
||||
const struct gl_extensions *extensions);
|
||||
|
||||
/* Functions for writing to the info log */
|
||||
|
||||
void
|
||||
glcpp_error (YYLTYPE *locp, glcpp_parser_t *parser, const char *fmt, ...);
|
||||
|
||||
void
|
||||
glcpp_warning (YYLTYPE *locp, glcpp_parser_t *parser, const char *fmt, ...);
|
||||
|
||||
/* Generated by glcpp-lex.l to glcpp-lex.c */
|
||||
|
||||
int
|
||||
glcpp_lex_init_extra (glcpp_parser_t *parser, yyscan_t* scanner);
|
||||
|
||||
void
|
||||
glcpp_lex_set_source_string(glcpp_parser_t *parser, const char *shader);
|
||||
|
||||
int
|
||||
glcpp_lex (YYSTYPE *lvalp, YYLTYPE *llocp, yyscan_t scanner);
|
||||
|
||||
int
|
||||
glcpp_lex_destroy (yyscan_t scanner);
|
||||
|
||||
/* Generated by glcpp-parse.y to glcpp-parse.c */
|
||||
|
||||
int
|
||||
yyparse (glcpp_parser_t *parser);
|
||||
|
||||
#endif
|
|
@ -1,165 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2010 Intel Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include "glcpp.h"
|
||||
#include "main/core.h" /* for isblank() on MSVC */
|
||||
|
||||
void
|
||||
glcpp_error (YYLTYPE *locp, glcpp_parser_t *parser, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
parser->error = 1;
|
||||
ralloc_asprintf_append(&parser->info_log, "%u:%u(%u): "
|
||||
"preprocessor error: ",
|
||||
locp->source,
|
||||
locp->first_line,
|
||||
locp->first_column);
|
||||
va_start(ap, fmt);
|
||||
ralloc_vasprintf_append(&parser->info_log, fmt, ap);
|
||||
va_end(ap);
|
||||
ralloc_strcat(&parser->info_log, "\n");
|
||||
}
|
||||
|
||||
void
|
||||
glcpp_warning (YYLTYPE *locp, glcpp_parser_t *parser, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
ralloc_asprintf_append(&parser->info_log, "%u:%u(%u): "
|
||||
"preprocessor warning: ",
|
||||
locp->source,
|
||||
locp->first_line,
|
||||
locp->first_column);
|
||||
va_start(ap, fmt);
|
||||
ralloc_vasprintf_append(&parser->info_log, fmt, ap);
|
||||
va_end(ap);
|
||||
ralloc_strcat(&parser->info_log, "\n");
|
||||
}
|
||||
|
||||
/* Searches backwards for '^ *#' from a given starting point. */
|
||||
static int
|
||||
in_directive(const char *shader, const char *ptr)
|
||||
{
|
||||
assert(ptr >= shader);
|
||||
|
||||
/* Search backwards for '#'. If we find a \n first, it doesn't count */
|
||||
for (; ptr >= shader && *ptr != '#'; ptr--) {
|
||||
if (*ptr == '\n')
|
||||
return 0;
|
||||
}
|
||||
if (ptr >= shader) {
|
||||
/* Found '#'...look for spaces preceded by a newline */
|
||||
for (ptr--; ptr >= shader && isblank(*ptr); ptr--);
|
||||
// FIXME: I don't think the '\n' case can happen
|
||||
if (ptr < shader || *ptr == '\n')
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Remove any line continuation characters in preprocessing directives.
|
||||
* However, ignore any in GLSL code, as "There is no line continuation
|
||||
* character" (1.30 page 9) in GLSL.
|
||||
*/
|
||||
static char *
|
||||
remove_line_continuations(glcpp_parser_t *ctx, const char *shader)
|
||||
{
|
||||
int in_continued_line = 0;
|
||||
int extra_newlines = 0;
|
||||
char *clean = ralloc_strdup(ctx, "");
|
||||
const char *search_start = shader;
|
||||
const char *newline;
|
||||
while ((newline = strchr(search_start, '\n')) != NULL) {
|
||||
const char *backslash = NULL;
|
||||
|
||||
/* # of characters preceding the newline. */
|
||||
int n = newline - shader;
|
||||
|
||||
/* Find the preceding '\', if it exists */
|
||||
if (n >= 1 && newline[-1] == '\\')
|
||||
backslash = newline - 1;
|
||||
else if (n >= 2 && newline[-1] == '\r' && newline[-2] == '\\')
|
||||
backslash = newline - 2;
|
||||
|
||||
/* Double backslashes don't count (the backslash is escaped) */
|
||||
if (backslash != NULL && backslash[-1] == '\\') {
|
||||
backslash = NULL;
|
||||
}
|
||||
|
||||
if (backslash != NULL) {
|
||||
/* We found a line continuation, but do we care? */
|
||||
if (!in_continued_line) {
|
||||
if (in_directive(shader, backslash)) {
|
||||
in_continued_line = 1;
|
||||
extra_newlines = 0;
|
||||
}
|
||||
}
|
||||
if (in_continued_line) {
|
||||
/* Copy everything before the \ */
|
||||
ralloc_strncat(&clean, shader, backslash - shader);
|
||||
shader = newline + 1;
|
||||
extra_newlines++;
|
||||
}
|
||||
} else if (in_continued_line) {
|
||||
/* Copy everything up to and including the \n */
|
||||
ralloc_strncat(&clean, shader, newline - shader + 1);
|
||||
shader = newline + 1;
|
||||
/* Output extra newlines to make line numbers match */
|
||||
for (; extra_newlines > 0; extra_newlines--)
|
||||
ralloc_strcat(&clean, "\n");
|
||||
in_continued_line = 0;
|
||||
}
|
||||
search_start = newline + 1;
|
||||
}
|
||||
ralloc_strcat(&clean, shader);
|
||||
return clean;
|
||||
}
|
||||
|
||||
int
|
||||
preprocess(void *ralloc_ctx, const char **shader, char **info_log,
|
||||
const struct gl_extensions *extensions)
|
||||
{
|
||||
int errors;
|
||||
glcpp_parser_t *parser = glcpp_parser_create (extensions);
|
||||
*shader = remove_line_continuations(parser, *shader);
|
||||
|
||||
glcpp_lex_set_source_string (parser, *shader);
|
||||
|
||||
glcpp_parser_parse (parser);
|
||||
|
||||
if (parser->skip_stack)
|
||||
glcpp_error (&parser->skip_stack->loc, parser, "Unterminated #if\n");
|
||||
|
||||
ralloc_strcat(info_log, parser->info_log);
|
||||
|
||||
ralloc_steal(ralloc_ctx, parser->output);
|
||||
*shader = parser->output;
|
||||
|
||||
errors = parser->error;
|
||||
glcpp_parser_destroy (parser);
|
||||
return errors;
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
this is four tokens
|
|
@ -1,2 +0,0 @@
|
|||
this is four tokens
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
#define foo 1
|
||||
foo
|
|
@ -1,3 +0,0 @@
|
|||
|
||||
1
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
#define foo 1
|
||||
#define bar foo
|
||||
bar
|
|
@ -1,4 +0,0 @@
|
|||
|
||||
|
||||
1
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
#define bar foo
|
||||
#define foo 1
|
||||
bar
|
|
@ -1,4 +0,0 @@
|
|||
|
||||
|
||||
1
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
#define foo bar
|
||||
#define bar baz
|
||||
#define baz foo
|
||||
foo
|
||||
bar
|
||||
baz
|
|
@ -1,7 +0,0 @@
|
|||
|
||||
|
||||
|
||||
foo
|
||||
bar
|
||||
baz
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
#define foo 1
|
||||
#define bar a foo
|
||||
bar
|
|
@ -1,4 +0,0 @@
|
|||
|
||||
|
||||
a 1
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
#define bar a foo
|
||||
#define foo 1
|
||||
bar
|
|
@ -1,4 +0,0 @@
|
|||
|
||||
|
||||
a 1
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
#define foo a bar
|
||||
#define bar b baz
|
||||
#define baz c foo
|
||||
foo
|
||||
bar
|
||||
baz
|
|
@ -1,7 +0,0 @@
|
|||
|
||||
|
||||
|
||||
a b c foo
|
||||
b c a bar
|
||||
c a b baz
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
#define foo
|
||||
foo
|
|
@ -1,4 +0,0 @@
|
|||
#define foo 1
|
||||
foo
|
||||
#undef foo
|
||||
foo
|
|
@ -1,5 +0,0 @@
|
|||
|
||||
1
|
||||
|
||||
foo
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
#define foo 1
|
||||
foo
|
||||
#undef foo
|
||||
foo
|
||||
#define foo 2
|
||||
foo
|
|
@ -1,7 +0,0 @@
|
|||
|
||||
1
|
||||
|
||||
foo
|
||||
|
||||
2
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
#define foo()
|
||||
foo()
|
|
@ -1,3 +0,0 @@
|
|||
|
||||
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
#define foo() bar
|
||||
foo()
|
|
@ -1,3 +0,0 @@
|
|||
|
||||
bar
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
#define foo(x) 1
|
||||
foo(bar)
|
|
@ -1,3 +0,0 @@
|
|||
|
||||
1
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
#define foo(x,y) 1
|
||||
foo(bar,baz)
|
|
@ -1,3 +0,0 @@
|
|||
|
||||
1
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
#define foo ()1
|
||||
foo()
|
||||
#define bar ()2
|
||||
bar()
|
|
@ -1,5 +0,0 @@
|
|||
|
||||
()1()
|
||||
|
||||
()2()
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
#define foo(x) ((x)+1)
|
||||
foo(bar)
|
|
@ -1,3 +0,0 @@
|
|||
|
||||
((bar)+1)
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
#define foo(x,y) ((x)*(y))
|
||||
foo(bar,baz)
|
|
@ -1,3 +0,0 @@
|
|||
|
||||
((bar)*(baz))
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
#define x 0
|
||||
#define foo(x) x
|
||||
foo(1)
|
|
@ -1,4 +0,0 @@
|
|||
|
||||
|
||||
1
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
#define foo(x) (x)
|
||||
foo(this is more than one word)
|
|
@ -1,3 +0,0 @@
|
|||
|
||||
(this is more than one word)
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
#define foo(x,y) x,two fish,red fish,y
|
||||
foo(one fish, blue fish)
|
|
@ -1,3 +0,0 @@
|
|||
|
||||
one fish,two fish,red fish,blue fish
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
#define bar(x) (1+(x))
|
||||
#define foo(y) (2*(y))
|
||||
foo(bar(3))
|
|
@ -1,4 +0,0 @@
|
|||
|
||||
|
||||
(2*((1+(3))))
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
#define foo(x) (x)
|
||||
foo(argument(including parens)for the win)
|
|
@ -1,3 +0,0 @@
|
|||
|
||||
(argument(including parens)for the win)
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
#define noargs() 1
|
||||
# define onearg(foo) foo
|
||||
# define twoargs( x , y ) x y
|
||||
# define threeargs( a , b , c ) a b c
|
||||
noargs ( )
|
||||
onearg ( 2 )
|
||||
twoargs ( 3 , 4 )
|
||||
threeargs ( 5 , 6 , 7 )
|
|
@ -1,9 +0,0 @@
|
|||
|
||||
|
||||
|
||||
|
||||
1
|
||||
2
|
||||
3 4
|
||||
5 6 7
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
#define foo foo
|
||||
#define bar foo
|
||||
bar
|
|
@ -1,4 +0,0 @@
|
|||
|
||||
|
||||
foo
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
#define foo(bar) bar
|
||||
foo bar
|
|
@ -1,3 +0,0 @@
|
|||
|
||||
foo bar
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
#define foo(a) bar
|
||||
|
||||
foo
|
||||
(
|
||||
1
|
||||
)
|
|
@ -1,4 +0,0 @@
|
|||
|
||||
|
||||
bar
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
#define failure() success
|
||||
#define foo failure()
|
||||
foo
|
|
@ -1,4 +0,0 @@
|
|||
|
||||
|
||||
success
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
#define success() failure
|
||||
#define foo success
|
||||
foo
|
|
@ -1,4 +0,0 @@
|
|||
|
||||
|
||||
success
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
#define bar(failure) failure
|
||||
#define foo bar(success)
|
||||
foo
|
|
@ -1,4 +0,0 @@
|
|||
|
||||
|
||||
success
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
#define baz(failure) failure
|
||||
#define bar(failure) failure
|
||||
#define foo bar(baz(success))
|
||||
foo
|
|
@ -1,5 +0,0 @@
|
|||
|
||||
|
||||
|
||||
success
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
#define baz(failure) failure
|
||||
#define bar(failure) failure
|
||||
#define foo() bar(baz(success))
|
||||
foo()
|
|
@ -1,5 +0,0 @@
|
|||
|
||||
|
||||
|
||||
success
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
#define foo(a) foo(2*(a))
|
||||
foo(3)
|
|
@ -1,3 +0,0 @@
|
|||
|
||||
foo(2*(3))
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
#define foo(a) foo(2*(a))
|
||||
foo(foo(3))
|
|
@ -1,3 +0,0 @@
|
|||
|
||||
foo(2*(foo(2*(3))))
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
#define foo(bar) bar
|
||||
foo(foo)
|
|
@ -1,3 +0,0 @@
|
|||
|
||||
foo
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
#define foo(bar) bar
|
||||
foo(1+foo)
|
|
@ -1,3 +0,0 @@
|
|||
|
||||
1+foo
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
#define bar success
|
||||
#define foo(x) x
|
||||
foo(more bar)
|
|
@ -1,4 +0,0 @@
|
|||
|
||||
|
||||
more success
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
#define expand(x) expand(x once)
|
||||
#define foo(x) x
|
||||
foo(expand(just))
|
|
@ -1,4 +0,0 @@
|
|||
|
||||
|
||||
expand(just once)
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
#define foo(x) success
|
||||
foo(argument (with,embedded , commas) -- tricky)
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue