#include "nir.h"
#include "nir_control_flow_private.h"
+#include "util/half_float.h"
+#include <limits.h>
#include <assert.h>
+#include <math.h>
nir_shader *
nir_shader_create(void *mem_ctx,
shader->options = options;
- if (si)
+ if (si) {
+ assert(si->stage == stage);
shader->info = *si;
+ } else {
+ shader->info.stage = stage;
+ }
exec_list_make_empty(&shader->functions);
exec_list_make_empty(&shader->registers);
shader->num_uniforms = 0;
shader->num_shared = 0;
- shader->stage = stage;
-
return shader;
}
break;
case nir_var_shared:
- assert(shader->stage == MESA_SHADER_COMPUTE);
+ assert(shader->info.stage == MESA_SHADER_COMPUTE);
exec_list_push_tail(&shader->shared, &var->node);
break;
var->type = type;
var->data.mode = mode;
- if ((mode == nir_var_shader_in && shader->stage != MESA_SHADER_VERTEX) ||
- (mode == nir_var_shader_out && shader->stage != MESA_SHADER_FRAGMENT))
+ if ((mode == nir_var_shader_in &&
+ shader->info.stage != MESA_SHADER_VERTEX) ||
+ (mode == nir_var_shader_out &&
+ shader->info.stage != MESA_SHADER_FRAGMENT))
var->data.interpolation = INTERP_MODE_SMOOTH;
if (mode == nir_var_shader_in || mode == nir_var_uniform)
return func;
}
+/* NOTE: if the instruction you are copying a src to is already added
+ * to the IR, use nir_instr_rewrite_src() instead.
+ */
void nir_src_copy(nir_src *dest, const nir_src *src, void *mem_ctx)
{
dest->is_ssa = src->is_ssa;
nir_load_const_instr_create(nir_shader *shader, unsigned num_components,
unsigned bit_size)
{
- nir_load_const_instr *instr = ralloc(shader, nir_load_const_instr);
+ nir_load_const_instr *instr = rzalloc(shader, nir_load_const_instr);
instr_init(&instr->instr, nir_instr_type_load_const);
nir_ssa_def_init(&instr->instr, &instr->def, num_components, bit_size, NULL);
return instr;
}
+void
+nir_tex_instr_add_src(nir_tex_instr *tex,
+ nir_tex_src_type src_type,
+ nir_src src)
+{
+ nir_tex_src *new_srcs = rzalloc_array(tex, nir_tex_src,
+ tex->num_srcs + 1);
+
+ for (unsigned i = 0; i < tex->num_srcs; i++) {
+ new_srcs[i].src_type = tex->src[i].src_type;
+ nir_instr_move_src(&tex->instr, &new_srcs[i].src,
+ &tex->src[i].src);
+ }
+
+ ralloc_free(tex->src);
+ tex->src = new_srcs;
+
+ tex->src[tex->num_srcs].src_type = src_type;
+ nir_instr_rewrite_src(&tex->instr, &tex->src[tex->num_srcs].src, src);
+ tex->num_srcs++;
+}
+
void
nir_tex_instr_remove_src(nir_tex_instr *tex, unsigned src_idx)
{
assert(tail->child == NULL);
switch (glsl_get_base_type(tail->type)) {
case GLSL_TYPE_UINT:
+ case GLSL_TYPE_UINT16:
case GLSL_TYPE_UINT64:
case GLSL_TYPE_INT:
+ case GLSL_TYPE_INT16:
case GLSL_TYPE_INT64:
case GLSL_TYPE_FLOAT:
+ case GLSL_TYPE_FLOAT16:
case GLSL_TYPE_DOUBLE:
case GLSL_TYPE_BOOL:
if (glsl_type_is_vector_or_scalar(tail->type))
case GLSL_TYPE_FLOAT:
case GLSL_TYPE_INT:
case GLSL_TYPE_UINT:
+ case GLSL_TYPE_FLOAT16:
case GLSL_TYPE_DOUBLE:
+ case GLSL_TYPE_INT16:
+ case GLSL_TYPE_UINT16:
case GLSL_TYPE_UINT64:
case GLSL_TYPE_INT64:
case GLSL_TYPE_BOOL:
return load;
}
+static nir_const_value
+const_value_float(double d, unsigned bit_size)
+{
+ nir_const_value v;
+ switch (bit_size) {
+ case 16: v.u16[0] = _mesa_float_to_half(d); break;
+ case 32: v.f32[0] = d; break;
+ case 64: v.f64[0] = d; break;
+ default:
+ unreachable("Invalid bit size");
+ }
+ return v;
+}
+
+static nir_const_value
+const_value_int(int64_t i, unsigned bit_size)
+{
+ nir_const_value v;
+ switch (bit_size) {
+ case 8: v.i8[0] = i; break;
+ case 16: v.i16[0] = i; break;
+ case 32: v.i32[0] = i; break;
+ case 64: v.i64[0] = i; break;
+ default:
+ unreachable("Invalid bit size");
+ }
+ return v;
+}
+
+nir_const_value
+nir_alu_binop_identity(nir_op binop, unsigned bit_size)
+{
+ const int64_t max_int = (1ull << (bit_size - 1)) - 1;
+ const int64_t min_int = -max_int - 1;
+ switch (binop) {
+ case nir_op_iadd:
+ return const_value_int(0, bit_size);
+ case nir_op_fadd:
+ return const_value_float(0, bit_size);
+ case nir_op_imul:
+ return const_value_int(1, bit_size);
+ case nir_op_fmul:
+ return const_value_float(1, bit_size);
+ case nir_op_imin:
+ return const_value_int(max_int, bit_size);
+ case nir_op_umin:
+ return const_value_int(~0ull, bit_size);
+ case nir_op_fmin:
+ return const_value_float(INFINITY, bit_size);
+ case nir_op_imax:
+ return const_value_int(min_int, bit_size);
+ case nir_op_umax:
+ return const_value_int(0, bit_size);
+ case nir_op_fmax:
+ return const_value_float(-INFINITY, bit_size);
+ case nir_op_iand:
+ return const_value_int(~0ull, bit_size);
+ case nir_op_ior:
+ return const_value_int(0, bit_size);
+ case nir_op_ixor:
+ return const_value_int(0, bit_size);
+ default:
+ unreachable("Invalid reduction operation");
+ }
+}
+
nir_function_impl *
nir_cf_node_get_function(nir_cf_node *node)
{
nir_foreach_src(instr, remove_use_cb, instr);
}
-void nir_instr_remove(nir_instr *instr)
+void nir_instr_remove_v(nir_instr *instr)
{
remove_defs_uses(instr);
exec_node_remove(&instr->node);
}
uint8_t
-nir_ssa_def_components_read(nir_ssa_def *def)
+nir_ssa_def_components_read(const nir_ssa_def *def)
{
uint8_t read_mask = 0;
nir_foreach_use(use, def) {
return nir_intrinsic_load_base_instance;
case SYSTEM_VALUE_VERTEX_ID_ZERO_BASE:
return nir_intrinsic_load_vertex_id_zero_base;
+ case SYSTEM_VALUE_IS_INDEXED_DRAW:
+ return nir_intrinsic_load_is_indexed_draw;
+ case SYSTEM_VALUE_FIRST_VERTEX:
+ return nir_intrinsic_load_first_vertex;
case SYSTEM_VALUE_BASE_VERTEX:
return nir_intrinsic_load_base_vertex;
case SYSTEM_VALUE_INVOCATION_ID:
return nir_intrinsic_load_subgroup_le_mask;
case SYSTEM_VALUE_SUBGROUP_LT_MASK:
return nir_intrinsic_load_subgroup_lt_mask;
+ case SYSTEM_VALUE_NUM_SUBGROUPS:
+ return nir_intrinsic_load_num_subgroups;
+ case SYSTEM_VALUE_SUBGROUP_ID:
+ return nir_intrinsic_load_subgroup_id;
+ case SYSTEM_VALUE_LOCAL_GROUP_SIZE:
+ return nir_intrinsic_load_local_group_size;
default:
unreachable("system value does not directly correspond to intrinsic");
}
return SYSTEM_VALUE_BASE_INSTANCE;
case nir_intrinsic_load_vertex_id_zero_base:
return SYSTEM_VALUE_VERTEX_ID_ZERO_BASE;
+ case nir_intrinsic_load_first_vertex:
+ return SYSTEM_VALUE_FIRST_VERTEX;
+ case nir_intrinsic_load_is_indexed_draw:
+ return SYSTEM_VALUE_IS_INDEXED_DRAW;
case nir_intrinsic_load_base_vertex:
return SYSTEM_VALUE_BASE_VERTEX;
case nir_intrinsic_load_invocation_id:
return SYSTEM_VALUE_HELPER_INVOCATION;
case nir_intrinsic_load_view_index:
return SYSTEM_VALUE_VIEW_INDEX;
- case SYSTEM_VALUE_SUBGROUP_SIZE:
- return nir_intrinsic_load_subgroup_size;
- case SYSTEM_VALUE_SUBGROUP_INVOCATION:
- return nir_intrinsic_load_subgroup_invocation;
+ case nir_intrinsic_load_subgroup_size:
+ return SYSTEM_VALUE_SUBGROUP_SIZE;
+ case nir_intrinsic_load_subgroup_invocation:
+ return SYSTEM_VALUE_SUBGROUP_INVOCATION;
case nir_intrinsic_load_subgroup_eq_mask:
return SYSTEM_VALUE_SUBGROUP_EQ_MASK;
case nir_intrinsic_load_subgroup_ge_mask:
return SYSTEM_VALUE_SUBGROUP_LE_MASK;
case nir_intrinsic_load_subgroup_lt_mask:
return SYSTEM_VALUE_SUBGROUP_LT_MASK;
+ case nir_intrinsic_load_num_subgroups:
+ return SYSTEM_VALUE_NUM_SUBGROUPS;
+ case nir_intrinsic_load_subgroup_id:
+ return SYSTEM_VALUE_SUBGROUP_ID;
+ case nir_intrinsic_load_local_group_size:
+ return SYSTEM_VALUE_LOCAL_GROUP_SIZE;
default:
unreachable("intrinsic doesn't produce a system value");
}