On Thu, Sep 05, 2013 at 02:27:04PM +0300, Pohjolainen, Topi wrote: > On Wed, Sep 04, 2013 at 03:22:41PM -0700, Kenneth Graunke wrote: > > This creates a new replacement for the existing built-in function code. > > The new module lives in builtin_functions.cpp (not builtin_function.cpp) > > and exists in parallel with the existing system. It isn't used yet. > > > > The new built-in function code takes a significantly different approach: > > > > Instead of implementing built-ins via printed IR, build time scripts, > > and run time parsing, we now implement them directly in C++, using > > ir_builder. This translates to faster load times, and a much less > > complex build system. > > > > It also takes a different approach to built-in availability: each > > signature now stores a boolean predicate, which makes it easy to > > construct arbitrary expressions based on _mesa_glsl_parse_state's > > fields. This is much more flexible than the old system, and also > > easier to use. > > > > Built-ins are also now stored in a single gl_shader object, rather > > than being spread out across a number of shaders that need to be linked. > > When searching for a matching prototype, we simply consult the > > availability predicate. This also simplifies the code. > > > > Signed-off-by: Kenneth Graunke <kenn...@whitecape.org> > > --- > > src/glsl/Makefile.sources | 1 + > > src/glsl/builtin_functions.cpp | 3466 > > ++++++++++++++++++++++++++++++++++++++++ > > src/glsl/ir.h | 10 + > > 3 files changed, 3477 insertions(+) > > create mode 100644 src/glsl/builtin_functions.cpp > > > > diff --git a/src/glsl/Makefile.sources b/src/glsl/Makefile.sources > > index 979c416..3e706ef 100644 > > --- a/src/glsl/Makefile.sources > > +++ b/src/glsl/Makefile.sources > > @@ -21,6 +21,7 @@ LIBGLSL_FILES = \ > > $(GLSL_SRCDIR)/ast_function.cpp \ > > $(GLSL_SRCDIR)/ast_to_hir.cpp \ > > $(GLSL_SRCDIR)/ast_type.cpp \ > > + $(GLSL_SRCDIR)/builtin_functions.cpp \ > > $(GLSL_SRCDIR)/builtin_types.cpp \ > > $(GLSL_SRCDIR)/builtin_variables.cpp \ > > $(GLSL_SRCDIR)/glsl_parser_extras.cpp \ > > diff --git a/src/glsl/builtin_functions.cpp b/src/glsl/builtin_functions.cpp > > new file mode 100644 > > index 0000000..440ec41 > > --- /dev/null > > +++ b/src/glsl/builtin_functions.cpp > > @@ -0,0 +1,3466 @@ > > +/* > > + * Copyright © 2013 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. > > + */ > > + > > +/** > > + * \file builtin_functions.cpp > > + * > > + * Support for GLSL built-in functions. > > + * > > + * This file is split into several main components: > > + * > > + * 1. Availability predicates > > + * > > + * A series of small functions that check whether the current shader > > + * supports the version/extensions required to expose a built-in. > > + * > > + * 2. Core builtin_builder class functionality > > + * > > + * 3. Lists of built-in functions > > + * > > + * The builtin_builder::create_builtins() function contains lists of all > > + * built-in function signatures, where they're available, what types > > they > > + * take, and so on. > > + * > > + * 4. Implementations of built-in function signatures > > + * > > + * A series of functions which create ir_function_signatures and emit IR > > + * via ir_builder to implement them. > > + * > > + * 5. External API > > + * > > + * A few functions the rest of the compiler can use to interact with the > > + * built-in function module. For example, searching for a built-in by > > + * name and parameters. > > + */ > > + > > +#include <stdarg.h> > > +#include <stdio.h> > > +#include "main/core.h" /* for struct gl_shader */ > > +#include "ir_builder.h" > > +#include "glsl_parser_extras.h" > > +#include "program/prog_instruction.h" > > +#include <limits> > > + > > +using namespace ir_builder; > > + > > +/** > > + * Availability predicates: > > + * @{ > > + */ > > +static bool > > +always_available(const _mesa_glsl_parse_state *state) > > +{ > > + return true; > > +} > > + > > +static bool > > +legacy_vs_only(const _mesa_glsl_parse_state *state) > > +{ > > + return state->target == vertex_shader && > > + state->language_version <= 130 && > > + !state->es_shader; > > +} > > + > > +static bool > > +fs_only(const _mesa_glsl_parse_state *state) > > +{ > > + return state->target == fragment_shader; > > +} > > + > > +static bool > > +gs_only(const _mesa_glsl_parse_state *state) > > +{ > > + return state->target == geometry_shader; > > +} > > + > > +static bool > > +v110(const _mesa_glsl_parse_state *state) > > +{ > > + return !state->es_shader; > > +} > > + > > +static bool > > +v110_fs_only(const _mesa_glsl_parse_state *state) > > +{ > > + return !state->es_shader && state->target == fragment_shader; > > +} > > + > > +static bool > > +v120(const _mesa_glsl_parse_state *state) > > +{ > > + return state->is_version(120, 300); > > +} > > + > > +static bool > > +v130(const _mesa_glsl_parse_state *state) > > +{ > > + return state->is_version(130, 300); > > +} > > + > > +static bool > > +v130_fs_only(const _mesa_glsl_parse_state *state) > > +{ > > + return state->is_version(130, 300) && > > + state->target == fragment_shader; > > +} > > + > > +static bool > > +v140(const _mesa_glsl_parse_state *state) > > +{ > > + return state->is_version(140, 0); > > +} > > + > > +static bool > > +texture_rectangle(const _mesa_glsl_parse_state *state) > > +{ > > + return state->ARB_texture_rectangle_enable; > > +} > > + > > +static bool > > +texture_external(const _mesa_glsl_parse_state *state) > > +{ > > + return state->OES_EGL_image_external_enable; > > +} > > + > > +static bool > > +vs_or_shader_texture_lod(const _mesa_glsl_parse_state *state) > > +{ > > + return state->target == vertex_shader || > > + state->ARB_shader_texture_lod_enable || > > + state->is_version(130, 0); > > +} > > + > > +static bool > > +v110_vs_or_shader_texture_lod(const _mesa_glsl_parse_state *state) > > +{ > > + return !state->es_shader && vs_or_shader_texture_lod(state); > > +} > > + > > +static bool > > +shader_texture_lod(const _mesa_glsl_parse_state *state) > > +{ > > + return state->ARB_shader_texture_lod_enable; > > +} > > + > > +static bool > > +shader_texture_lod_and_rect(const _mesa_glsl_parse_state *state) > > +{ > > + return state->ARB_shader_texture_lod_enable && > > + state->ARB_texture_rectangle_enable; > > +} > > + > > +static bool > > +shader_bit_encoding(const _mesa_glsl_parse_state *state) > > +{ > > + return state->is_version(330, 300) || > > + state->ARB_shader_bit_encoding_enable || > > + state->ARB_gpu_shader5_enable; > > +} > > + > > +static bool > > +shader_packing(const _mesa_glsl_parse_state *state) > > +{ > > + return state->ARB_shading_language_packing_enable || > > + state->is_version(400, 0); > > +} > > + > > +static bool > > +shader_packing_or_es3(const _mesa_glsl_parse_state *state) > > +{ > > + return state->ARB_shading_language_packing_enable || > > + state->is_version(400, 300); > > +} > > + > > +static bool > > +gpu_shader5(const _mesa_glsl_parse_state *state) > > +{ > > + return state->is_version(400, 0) || state->ARB_gpu_shader5_enable; > > +} > > + > > +static bool > > +vs_texture_array(const _mesa_glsl_parse_state *state) > > +{ > > + return state->target == vertex_shader && > > + state->EXT_texture_array_enable; > > +} > > + > > +static bool > > +fs_texture_array(const _mesa_glsl_parse_state *state) > > +{ > > + return state->target == fragment_shader && > > + state->EXT_texture_array_enable; > > +} > > + > > +static bool > > +texture_array(const _mesa_glsl_parse_state *state) > > +{ > > + return state->EXT_texture_array_enable; > > +} > > + > > +static bool > > +texture_multisample(const _mesa_glsl_parse_state *state) > > +{ > > + return state->is_version(150, 0) || > > + state->ARB_texture_multisample_enable; > > +} > > + > > +static bool > > +fs_texture_cube_map_array(const _mesa_glsl_parse_state *state) > > +{ > > + return state->target == fragment_shader && > > + (state->is_version(400, 0) || > > + state->ARB_texture_cube_map_array_enable); > > +} > > + > > +static bool > > +texture_cube_map_array(const _mesa_glsl_parse_state *state) > > +{ > > + return state->is_version(400, 0) || > > + state->ARB_texture_cube_map_array_enable; > > +} > > + > > +static bool > > +texture_query_lod(const _mesa_glsl_parse_state *state) > > +{ > > + return state->target == fragment_shader && > > + (state->is_version(400, 0) || > > state->ARB_texture_query_lod_enable); > > +} > > + > > +/* Desktop GL or OES_standard_derivatives + fragment shader only */ > > +static bool > > +fs_oes_derivatives(const _mesa_glsl_parse_state *state) > > +{ > > + return state->target == fragment_shader && > > + (!state->es_shader || state->OES_standard_derivatives_enable); > > +} > > + > > +static bool > > +oes_tex3d(const _mesa_glsl_parse_state *state) > > +{ > > + return !state->es_shader || state->OES_texture_3D_enable; > > +} > > + > > +static bool > > +vs_oes_tex3d(const _mesa_glsl_parse_state *state) > > +{ > > + return state->target == vertex_shader && > > + (!state->es_shader || state->OES_texture_3D_enable); > > +} > > + > > +static bool > > +fs_oes_tex3d(const _mesa_glsl_parse_state *state) > > +{ > > + return state->target == fragment_shader && > > + (!state->es_shader || state->OES_texture_3D_enable); > > +} > > + > > +static bool > > +vs_oes_tex3d_or_shader_texture_lod(const _mesa_glsl_parse_state *state) > > +{ > > + return state->ARB_shader_texture_lod_enable || vs_oes_tex3d(state); > > +} > > +/** @} */ > > + > > +/******************************************************************************/ > > + > > +/** > > + * builtin_builder: A singleton object representing the core of the > > built-in > > + * function module. > > I also started wondering about the meaning for "singleton" here, below there > is > public constructor allowing one to create more than one instance. >
I should have read until the end before commenting - even though the class does not limit the number of instances, there is only one static instance created out of the class. Sorry for the noise. > > + * > > + * It has code to generate > > + * It generates IR for every built-in function signature, and organizes > > them > > + * into functions. > > + */ > > +class builtin_builder { > > +public: > > + builtin_builder(); > > + ~builtin_builder(); > > + > > + void initialize(); > > + void release(); > > + ir_function_signature *find(_mesa_glsl_parse_state *state, > > + const char *name, exec_list > > *actual_parameters); > > + > > +private: > > + void *mem_ctx; > > + gl_shader *shader; > > + > > + /** Global variables used by built-in functions. */ > > + ir_variable *gl_ModelViewProjectionMatrix; > > + ir_variable *gl_Vertex; > > + > > + void create_shader(); > > + void create_builtins(); > > + > > + /** > > + * IR builder helpers: > > + * > > + * These convenience functions assist in emitting IR, but don't > > necessarily > > + * fit in ir_builder itself. Many of them rely on having a mem_ctx > > class > > + * member available. > > + */ > > + ir_variable *in_var(const glsl_type *type, const char *name); > > + ir_constant *imm(float f); > > + ir_constant *imm(int i); > > + ir_constant *imm(unsigned u); > > + ir_constant *imm(const glsl_type *type, const ir_constant_data &); > > + ir_dereference_variable *var_ref(ir_variable *var); > > + ir_dereference_array *array_ref(ir_variable *var, int i); > > + ir_swizzle *matrix_elt(ir_variable *var, int col, int row); > > + > > + ir_expression *asin_expr(ir_variable *x); > > + > > + /** Create a new function and add the given signatures. */ > > + void add_function(const char *name, ...); > > + > > + ir_function_signature *new_sig(const glsl_type *return_type, > > + builtin_available_predicate avail, > > + int num_params, ...); > > + > > + /** > > + * Function signature generators: > > + * @{ > > + */ > > + ir_function_signature *unop(builtin_available_predicate avail, > > + ir_expression_operation opcode, > > + const glsl_type *return_type, > > + const glsl_type *param_type); > > + ir_function_signature *binop(ir_expression_operation opcode, > > + builtin_available_predicate avail, > > + const glsl_type *return_type, > > + const glsl_type *param0_type, > > + const glsl_type *param1_type); > > + > > +#define B0(X) ir_function_signature *_##X(); > > +#define B1(X) ir_function_signature *_##X(const glsl_type *); > > +#define B2(X) ir_function_signature *_##X(const glsl_type *, const > > glsl_type *); > > +#define B3(X) ir_function_signature *_##X(const glsl_type *, const > > glsl_type *, const glsl_type *); > > + B1(radians) > > + B1(degrees) > > + B1(sin) > > + B1(cos) > > + B1(tan) > > + B1(asin) > > + B1(acos) > > + B1(atan2) > > + B1(atan) > > + B1(sinh) > > + B1(cosh) > > + B1(tanh) > > + B1(asinh) > > + B1(acosh) > > + B1(atanh) > > + B1(pow) > > + B1(exp) > > + B1(log) > > + B1(exp2) > > + B1(log2) > > + B1(sqrt) > > + B1(inversesqrt) > > + B1(abs) > > + B1(sign) > > + B1(floor) > > + B1(trunc) > > + B1(round) > > + B1(roundEven) > > + B1(ceil) > > + B1(fract) > > + B2(mod) > > + B1(modf) > > + B2(min) > > + B2(max) > > + B2(clamp) > > + B2(mix_lrp) > > + B2(mix_sel) > > + B2(step) > > + B2(smoothstep) > > + B1(isnan) > > + B1(isinf) > > + B1(floatBitsToInt) > > + B1(floatBitsToUint) > > + B1(intBitsToFloat) > > + B1(uintBitsToFloat) > > + ir_function_signature *_packUnorm2x16(builtin_available_predicate > > avail); > > + ir_function_signature *_packSnorm2x16(builtin_available_predicate > > avail); > > + ir_function_signature *_packUnorm4x8(builtin_available_predicate avail); > > + ir_function_signature *_packSnorm4x8(builtin_available_predicate avail); > > + ir_function_signature *_unpackUnorm2x16(builtin_available_predicate > > avail); > > + ir_function_signature *_unpackSnorm2x16(builtin_available_predicate > > avail); > > + ir_function_signature *_unpackUnorm4x8(builtin_available_predicate > > avail); > > + ir_function_signature *_unpackSnorm4x8(builtin_available_predicate > > avail); > > + ir_function_signature *_packHalf2x16(builtin_available_predicate avail); > > + ir_function_signature *_unpackHalf2x16(builtin_available_predicate > > avail); > > + B1(length) > > + B1(distance); > > + B1(dot); > > + B1(cross); > > + B1(normalize); > > + B0(ftransform); > > + B1(faceforward); > > + B1(reflect); > > + B1(refract); > > + B1(matrixCompMult); > > + B1(outerProduct); > > + B0(determinant_mat2); > > + B0(determinant_mat3); > > + B0(determinant_mat4); > > + B0(inverse_mat2); > > + B0(inverse_mat3); > > + B0(inverse_mat4); > > + B1(transpose); > > + B1(lessThan); > > + B1(lessThanEqual); > > + B1(greaterThan); > > + B1(greaterThanEqual); > > + B1(equal); > > + B1(notEqual); > > + B1(any); > > + B1(all); > > + B1(not); > > + B2(textureSize); > > + ir_function_signature *_textureSize(builtin_available_predicate avail, > > + const glsl_type *return_type, > > + const glsl_type *sampler_type); > > + > > +/** Flags to _texture() */ > > +#define TEX_PROJECT 1 > > +#define TEX_OFFSET 2 > > + > > + ir_function_signature *_texture(ir_texture_opcode opcode, > > + builtin_available_predicate avail, > > + const glsl_type *return_type, > > + const glsl_type *sampler_type, > > + int coord_size, > > + const glsl_type *coord_type, > > + int flags = 0); > > + B0(textureCubeArrayShadow); > > + ir_function_signature *_texelFetch(builtin_available_predicate avail, > > + const glsl_type *return_type, > > + const glsl_type *sampler_type, > > + const glsl_type *coord_type, > > + const glsl_type *offset_type = NULL); > > + > > + B0(EmitVertex) > > + B0(EndPrimitive) > > + > > + B2(textureQueryLOD); > > + B1(dFdx); > > + B1(dFdy); > > + B1(fwidth); > > + B1(noise1); > > + B1(noise2); > > + B1(noise3); > > + B1(noise4); > > + > > + B1(bitfieldExtract) > > + B1(bitfieldInsert) > > + B1(bitfieldReverse) > > + B1(bitCount) > > + B1(findLSB) > > + B1(findMSB) > > + B1(fma) > > +#undef B > > + /** @} */ > > +}; > > <snip> > _______________________________________________ > mesa-dev mailing list > mesa-dev@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/mesa-dev _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev