Browse Source

glsl: Basic support for built-in intrinsics.

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.

Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>

v2: Define local helper function to generate ir_call nodes in the
    builtin generator.
tags/mesa-10.1-devel
Francisco Jerez 12 years ago
parent
commit
9562922376
4 changed files with 64 additions and 11 deletions
  1. 46
    3
      src/glsl/builtin_functions.cpp
  2. 2
    2
      src/glsl/ir.cpp
  3. 6
    0
      src/glsl/ir.h
  4. 10
    6
      src/glsl/link_functions.cpp

+ 46
- 3
src/glsl/builtin_functions.cpp View File

@@ -365,6 +365,7 @@ private:
ir_variable *gl_Vertex;

void create_shader();
void create_intrinsics();
void create_builtins();

/**
@@ -386,6 +387,14 @@ private:

ir_expression *asin_expr(ir_variable *x);

/**
* Call function \param f with parameters specified as the linked
* list \param params of \c ir_variable objects. \param ret should
* point to the ir_variable that will hold the function return
* value, or be \c NULL if the function has void return type.
*/
ir_call *call(ir_function *f, ir_variable *ret, exec_list params);

/** Create a new function and add the given signatures. */
void add_function(const char *name, ...);

@@ -609,6 +618,7 @@ builtin_builder::initialize()

mem_ctx = ralloc_context(NULL);
create_shader();
create_intrinsics();
create_builtins();
}

@@ -645,6 +655,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.
*
@@ -2071,8 +2090,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);
@@ -2170,7 +2187,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,
@@ -2262,6 +2285,26 @@ builtin_builder::asin_expr(ir_variable *x)
mul(abs(x), imm(-0.03102955f))))))))));
}

ir_call *
builtin_builder::call(ir_function *f, ir_variable *ret, exec_list params)
{
exec_list actual_params;

foreach_iter(exec_list_iterator, it, params) {
ir_variable *var = ((ir_instruction *)it.get())->as_variable();
actual_params.push_tail(var_ref(var));
}

ir_function_signature *sig =
f->exact_matching_signature(NULL, &actual_params);
if (!sig)
return NULL;

ir_dereference_variable *deref =
(sig->return_type->is_void() ? NULL : var_ref(ret));

return new(mem_ctx) ir_call(sig, deref, &actual_params);
}

ir_function_signature *
builtin_builder::_asin(const glsl_type *type)

+ 2
- 2
src/glsl/ir.cpp View File

@@ -1647,8 +1647,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;

+ 6
- 0
src/glsl/ir.h View File

@@ -787,6 +787,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;


+ 10
- 6
src/glsl/link_functions.cpp View File

@@ -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
@@ -307,7 +310,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

Loading…
Cancel
Save