Fix the linker to deal with intrinsic functions which are undefined all the way down to the driver back-end, and introduce intrinsic definition helpers in the built-in generator.
We still need to figure out what kind of interface we want for drivers to communicate to the GLSL front-end which of the supported intrinsics should use a default GLSL implementation and which should use a hardware-specific override. As there's no default GLSL implementation for atomic ops, this seems like something we can worry about later on. --- src/glsl/builtin_functions.cpp | 21 ++++++++++++++++++--- src/glsl/ir.cpp | 4 ++-- src/glsl/ir.h | 6 ++++++ src/glsl/link_functions.cpp | 16 ++++++++++------ 4 files changed, 36 insertions(+), 11 deletions(-) diff --git a/src/glsl/builtin_functions.cpp b/src/glsl/builtin_functions.cpp index 72054e0..03efb6d 100644 --- a/src/glsl/builtin_functions.cpp +++ b/src/glsl/builtin_functions.cpp @@ -339,6 +339,7 @@ private: ir_variable *gl_Vertex; void create_shader(); + void create_intrinsics(); void create_builtins(); /** @@ -576,6 +577,7 @@ builtin_builder::initialize() mem_ctx = ralloc_context(NULL); create_shader(); + create_intrinsics(); create_builtins(); } @@ -613,6 +615,15 @@ builtin_builder::create_shader() /** @} */ /** + * Create ir_function and ir_function_signature objects for each + * intrinsic. + */ +void +builtin_builder::create_intrinsics() +{ +} + +/** * Create ir_function and ir_function_signature objects for each built-in. * * Contains a list of every available built-in. @@ -1865,8 +1876,6 @@ builtin_builder::add_function(const char *name, ...) if (sig == NULL) break; - sig->is_defined = true; - if (false) { exec_list stuff; stuff.push_tail(sig); @@ -1964,7 +1973,13 @@ builtin_builder::new_sig(const glsl_type *return_type, #define MAKE_SIG(return_type, avail, ...) \ ir_function_signature *sig = \ new_sig(return_type, avail, __VA_ARGS__); \ - ir_factory body(&sig->body, mem_ctx); + ir_factory body(&sig->body, mem_ctx); \ + sig->is_defined = true; + +#define MAKE_INTRINSIC(return_type, avail, ...) \ + ir_function_signature *sig = \ + new_sig(return_type, avail, __VA_ARGS__); \ + sig->is_intrinsic = true; ir_function_signature * builtin_builder::unop(builtin_available_predicate avail, diff --git a/src/glsl/ir.cpp b/src/glsl/ir.cpp index d65d8dc..02563e7 100644 --- a/src/glsl/ir.cpp +++ b/src/glsl/ir.cpp @@ -1633,8 +1633,8 @@ ir_variable::determine_interpolation_mode(bool flat_shade) ir_function_signature::ir_function_signature(const glsl_type *return_type, builtin_available_predicate b) - : return_type(return_type), is_defined(false), builtin_avail(b), - _function(NULL) + : return_type(return_type), is_defined(false), is_intrinsic(false), + builtin_avail(b), _function(NULL) { this->ir_type = ir_type_function_signature; this->origin = NULL; diff --git a/src/glsl/ir.h b/src/glsl/ir.h index fd12ae6..b87819c 100644 --- a/src/glsl/ir.h +++ b/src/glsl/ir.h @@ -694,6 +694,12 @@ public: /** Whether or not this function signature is a built-in. */ bool is_builtin() const; + /** + * Whether or not this function is an intrinsic to be implemented + * by the driver. + */ + bool is_intrinsic; + /** Whether or not a built-in is available for this shader. */ bool is_builtin_available(const _mesa_glsl_parse_state *state) const; diff --git a/src/glsl/link_functions.cpp b/src/glsl/link_functions.cpp index b1a68fd..c8531ed 100644 --- a/src/glsl/link_functions.cpp +++ b/src/glsl/link_functions.cpp @@ -155,14 +155,17 @@ public: linked_sig->replace_parameters(&formal_parameters); - foreach_list_const(node, &sig->body) { - const ir_instruction *const original = (ir_instruction *) node; + if (sig->is_defined) { + foreach_list_const(node, &sig->body) { + const ir_instruction *const original = (ir_instruction *) node; - ir_instruction *copy = original->clone(linked, ht); - linked_sig->body.push_tail(copy); + ir_instruction *copy = original->clone(linked, ht); + linked_sig->body.push_tail(copy); + } + + linked_sig->is_defined = true; } - linked_sig->is_defined = true; hash_table_dtor(ht); /* Patch references inside the function to things outside the function @@ -294,7 +297,8 @@ find_matching_signature(const char *name, const exec_list *actual_parameters, ir_function_signature *sig = f->matching_signature(NULL, actual_parameters); - if ((sig == NULL) || !sig->is_defined) + if ((sig == NULL) || + (!sig->is_defined && !sig->is_intrinsic)) continue; /* If this function expects to bind to a built-in function and the -- 1.8.3.4 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev