class nir_visitor : public ir_visitor
{
public:
- nir_visitor(nir_shader *shader);
+ nir_visitor(nir_shader *shader, gl_shader *sh);
~nir_visitor();
virtual void visit(ir_variable *);
virtual void visit(ir_dereference_array *);
virtual void visit(ir_barrier *);
- void create_function(ir_function *ir);
+ void create_function(ir_function_signature *ir);
private:
- void create_overload(ir_function_signature *ir, nir_function *function);
void add_instr(nir_instr *instr, unsigned num_components);
nir_ssa_def *evaluate_rvalue(ir_rvalue *ir);
bool supports_ints;
+ struct gl_shader *sh;
+
nir_shader *shader;
nir_function_impl *impl;
nir_builder b;
nir_shader *shader = nir_shader_create(NULL, stage, options);
- nir_visitor v1(shader);
+ nir_visitor v1(shader, sh);
nir_function_visitor v2(&v1);
v2.run(sh->ir);
visit_exec_list(sh->ir, &v1);
- nir_lower_outputs_to_temporaries(shader);
+ nir_function *main = NULL;
+ nir_foreach_function(shader, func) {
+ if (strcmp(func->name, "main") == 0) {
+ main = func;
+ break;
+ }
+ }
+ assert(main);
+
+ nir_lower_outputs_to_temporaries(shader, main);
shader->info.name = ralloc_asprintf(shader, "GLSL%d", shader_prog->Name);
if (shader_prog->Label)
return shader;
}
-nir_visitor::nir_visitor(nir_shader *shader)
+nir_visitor::nir_visitor(nir_shader *shader, gl_shader *sh)
{
this->supports_ints = shader->options->native_integers;
this->shader = shader;
+ this->sh = sh;
this->is_global = true;
this->var_table = _mesa_hash_table_create(NULL, _mesa_hash_pointer,
_mesa_key_pointer_equal);
}
var->data.index = ir->data.index;
+ var->data.descriptor_set = 0;
var->data.binding = ir->data.binding;
- var->data.atomic.offset = ir->data.atomic.offset;
+ var->data.offset = ir->data.offset;
var->data.image.read_only = ir->data.image_read_only;
var->data.image.write_only = ir->data.image_write_only;
var->data.image.coherent = ir->data.image_coherent;
ir_visitor_status
nir_function_visitor::visit_enter(ir_function *ir)
{
- visitor->create_function(ir);
- return visit_continue_with_parent;
-}
-
-
-void
-nir_visitor::create_function(ir_function *ir)
-{
- nir_function *func = nir_function_create(this->shader, ir->name);
foreach_in_list(ir_function_signature, sig, &ir->signatures) {
- create_overload(sig, func);
+ visitor->create_function(sig);
}
+ return visit_continue_with_parent;
}
-
-
void
-nir_visitor::create_overload(ir_function_signature *ir, nir_function *function)
+nir_visitor::create_function(ir_function_signature *ir)
{
if (ir->is_intrinsic)
return;
- nir_function_overload *overload = nir_function_overload_create(function);
+ nir_function *func = nir_function_create(shader, ir->function_name());
unsigned num_params = ir->parameters.length();
- overload->num_params = num_params;
- overload->params = ralloc_array(shader, nir_parameter, num_params);
+ func->num_params = num_params;
+ func->params = ralloc_array(shader, nir_parameter, num_params);
unsigned i = 0;
foreach_in_list(ir_variable, param, &ir->parameters) {
switch (param->data.mode) {
case ir_var_function_in:
- overload->params[i].param_type = nir_parameter_in;
+ func->params[i].param_type = nir_parameter_in;
break;
case ir_var_function_out:
- overload->params[i].param_type = nir_parameter_out;
+ func->params[i].param_type = nir_parameter_out;
break;
case ir_var_function_inout:
- overload->params[i].param_type = nir_parameter_inout;
+ func->params[i].param_type = nir_parameter_inout;
break;
default:
unreachable("not reached");
}
- overload->params[i].type = param->type;
+ func->params[i].type = param->type;
i++;
}
- overload->return_type = ir->return_type;
+ func->return_type = ir->return_type;
- _mesa_hash_table_insert(this->overload_table, ir, overload);
+ _mesa_hash_table_insert(this->overload_table, ir, func);
}
void
_mesa_hash_table_search(this->overload_table, ir);
assert(entry);
- nir_function_overload *overload = (nir_function_overload *) entry->data;
+ nir_function *func = (nir_function *) entry->data;
if (ir->is_defined) {
- nir_function_impl *impl = nir_function_impl_create(overload);
+ nir_function_impl *impl = nir_function_impl_create(func);
this->impl = impl;
- unsigned num_params = overload->num_params;
+ unsigned num_params = func->num_params;
impl->num_params = num_params;
impl->params = ralloc_array(this->shader, nir_variable *, num_params);
unsigned i = 0;
i++;
}
- if (overload->return_type == glsl_type::void_type) {
+ if (func->return_type == glsl_type::void_type) {
impl->return_var = NULL;
} else {
impl->return_var = ralloc(this->shader, nir_variable);
impl->return_var->name = ralloc_strdup(impl->return_var,
"return_var");
- impl->return_var->type = overload->return_type;
+ impl->return_var->type = func->return_type;
}
this->is_global = false;
this->is_global = true;
} else {
- overload->impl = NULL;
+ func->impl = NULL;
}
}
nir_intrinsic_instr *store_instr =
nir_intrinsic_instr_create(shader, nir_intrinsic_store_var);
store_instr->num_components = ir->return_deref->type->vector_elements;
+ store_instr->const_index[0] = (1 << store_instr->num_components) - 1;
store_instr->variables[0] =
evaluate_deref(&store_instr->instr, ir->return_deref);
struct hash_entry *entry =
_mesa_hash_table_search(this->overload_table, ir->callee);
assert(entry);
- nir_function_overload *callee = (nir_function_overload *) entry->data;
+ nir_function *callee = (nir_function *) entry->data;
nir_call_instr *instr = nir_call_instr_create(this->shader, callee);
nir_ssa_def *src = evaluate_rvalue(ir->rhs);
if (ir->write_mask != (1 << num_components) - 1 && ir->write_mask != 0) {
- /*
- * We have no good way to update only part of a variable, so just load
- * the LHS and do a vec operation to combine the old with the new, and
- * then store it
- * back into the LHS. Copy propagation should get rid of the mess.
+ /* GLSL IR will give us the input to the write-masked assignment in a
+ * single packed vector. So, for example, if the writemask is xzw, then
+ * we have to swizzle x -> x, y -> z, and z -> w and get the y component
+ * from the load.
*/
-
- nir_intrinsic_instr *load =
- nir_intrinsic_instr_create(this->shader, nir_intrinsic_load_var);
- load->num_components = ir->lhs->type->vector_elements;
- nir_ssa_dest_init(&load->instr, &load->dest, num_components, NULL);
- load->variables[0] = lhs_deref;
- ralloc_steal(load, load->variables[0]);
- nir_builder_instr_insert(&b, &load->instr);
-
- nir_ssa_def *srcs[4];
-
+ unsigned swiz[4];
unsigned component = 0;
- for (unsigned i = 0; i < ir->lhs->type->vector_elements; i++) {
- if (ir->write_mask & (1 << i)) {
- /* GLSL IR will give us the input to the write-masked assignment
- * in a single packed vector. So, for example, if the
- * writemask is xzw, then we have to swizzle x -> x, y -> z,
- * and z -> w and get the y component from the load.
- */
- srcs[i] = nir_channel(&b, src, component++);
- } else {
- srcs[i] = nir_channel(&b, &load->dest.ssa, i);
- }
+ for (unsigned i = 0; i < 4; i++) {
+ swiz[i] = ir->write_mask & (1 << i) ? component++ : 0;
}
-
- src = nir_vec(&b, srcs, ir->lhs->type->vector_elements);
+ src = nir_swizzle(&b, src, swiz, num_components, !supports_ints);
}
nir_intrinsic_instr *store =
nir_intrinsic_instr_create(this->shader, nir_intrinsic_store_var);
store->num_components = ir->lhs->type->vector_elements;
+ store->const_index[0] = ir->write_mask;
nir_deref *store_deref = nir_copy_deref(store, &lhs_deref->deref);
store->variables[0] = nir_deref_as_var(store_deref);
store->src[0] = nir_src_for_ssa(src);
case ir_binop_pack_half_2x16_split:
result = nir_pack_half_2x16_split(&b, srcs[0], srcs[1]);
break;
- case ir_binop_bfm: result = nir_bfm(&b, srcs[0], srcs[1]); break;
case ir_binop_ldexp: result = nir_ldexp(&b, srcs[0], srcs[1]); break;
case ir_triop_fma:
result = nir_ffma(&b, srcs[0], srcs[1], srcs[2]);
else
result = nir_fcsel(&b, srcs[0], srcs[1], srcs[2]);
break;
- case ir_triop_bfi:
- result = nir_bfi(&b, srcs[0], srcs[1], srcs[2]);
- break;
case ir_triop_bitfield_extract:
result = (out_type == GLSL_TYPE_INT) ?
nir_ibitfield_extract(&b, srcs[0], srcs[1], srcs[2]) :