nir_setup_system_values();
/* get the main function and emit it */
- nir_foreach_function(nir, function) {
+ nir_foreach_function(function, nir) {
assert(strcmp(function->name, "main") == 0);
assert(function->impl);
nir_emit_impl(function->impl);
case nir_intrinsic_load_vertex_id_zero_base:
reg = &nir_system_values[SYSTEM_VALUE_VERTEX_ID_ZERO_BASE];
if (reg->file == BAD_FILE)
- *reg = *make_reg_for_system_value(SYSTEM_VALUE_VERTEX_ID_ZERO_BASE,
- glsl_type::int_type);
+ *reg = *make_reg_for_system_value(SYSTEM_VALUE_VERTEX_ID_ZERO_BASE);
break;
case nir_intrinsic_load_base_vertex:
reg = &nir_system_values[SYSTEM_VALUE_BASE_VERTEX];
if (reg->file == BAD_FILE)
- *reg = *make_reg_for_system_value(SYSTEM_VALUE_BASE_VERTEX,
- glsl_type::int_type);
+ *reg = *make_reg_for_system_value(SYSTEM_VALUE_BASE_VERTEX);
break;
case nir_intrinsic_load_instance_id:
reg = &nir_system_values[SYSTEM_VALUE_INSTANCE_ID];
if (reg->file == BAD_FILE)
- *reg = *make_reg_for_system_value(SYSTEM_VALUE_INSTANCE_ID,
- glsl_type::int_type);
+ *reg = *make_reg_for_system_value(SYSTEM_VALUE_INSTANCE_ID);
break;
case nir_intrinsic_load_base_instance:
reg = &nir_system_values[SYSTEM_VALUE_BASE_INSTANCE];
if (reg->file == BAD_FILE)
- *reg = *make_reg_for_system_value(SYSTEM_VALUE_BASE_INSTANCE,
- glsl_type::int_type);
+ *reg = *make_reg_for_system_value(SYSTEM_VALUE_BASE_INSTANCE);
break;
case nir_intrinsic_load_draw_id:
reg = &nir_system_values[SYSTEM_VALUE_DRAW_ID];
if (reg->file == BAD_FILE)
- *reg = *make_reg_for_system_value(SYSTEM_VALUE_DRAW_ID,
- glsl_type::int_type);
+ *reg = *make_reg_for_system_value(SYSTEM_VALUE_DRAW_ID);
break;
default:
}
static bool
-setup_system_values_block(nir_block *block, void *void_visitor)
+setup_system_values_block(nir_block *block, vec4_visitor *v)
{
- vec4_visitor *v = (vec4_visitor *)void_visitor;
-
- nir_foreach_instr(block, instr) {
+ nir_foreach_instr(instr, block) {
if (instr->type != nir_instr_type_intrinsic)
continue;
nir_system_values[i] = dst_reg();
}
- nir_foreach_function(nir, function) {
+ nir_foreach_function(function, nir) {
assert(strcmp(function->name, "main") == 0);
assert(function->impl);
- nir_foreach_block(function->impl, setup_system_values_block, this);
+ nir_foreach_block(block, function->impl) {
+ setup_system_values_block(block, this);
+ }
}
}
vec4_visitor::nir_setup_uniforms()
{
uniforms = nir->num_uniforms / 16;
-
- nir_foreach_variable(var, &nir->uniforms) {
- /* UBO's and atomics don't take up space in the uniform file */
- if (var->interface_type != NULL || var->type->contains_atomic())
- continue;
-
- if (type_size_vec4(var->type) > 0)
- uniform_size[var->data.driver_location / 16] = type_size_vec4(var->type);
- }
}
void
void
vec4_visitor::nir_emit_block(nir_block *block)
{
- nir_foreach_instr(block, instr) {
+ nir_foreach_instr(instr, block) {
nir_emit_instr(instr);
}
}
}
case nir_intrinsic_load_uniform: {
- /* Offsets are in bytes but they should always be multiples of 16 */
- assert(instr->const_index[0] % 16 == 0);
+ /* Offsets are in bytes but they should always be multiples of 4 */
+ assert(nir_intrinsic_base(instr) % 4 == 0);
dest = get_nir_dest(instr->dest);
- src = src_reg(dst_reg(UNIFORM, instr->const_index[0] / 16));
+ src = src_reg(dst_reg(UNIFORM, nir_intrinsic_base(instr) / 16));
src.type = dest.type;
+ /* Uniforms don't actually have to be vec4 aligned. In the case that
+ * it isn't, we have to use a swizzle to shift things around. They
+ * do still have the std140 alignment requirement that vec2's have to
+ * be vec2-aligned and vec3's and vec4's have to be vec4-aligned.
+ *
+ * The swizzle also works in the indirect case as the generator adds
+ * the swizzle to the offset for us.
+ */
+ unsigned shift = (nir_intrinsic_base(instr) % 16) / 4;
+ assert(shift + instr->num_components <= 4);
+
nir_const_value *const_offset = nir_src_as_const_value(instr->src[0]);
if (const_offset) {
- /* Offsets are in bytes but they should always be multiples of 16 */
- assert(const_offset->u32[0] % 16 == 0);
- src.reg_offset = const_offset->u32[0] / 16;
+ /* Offsets are in bytes but they should always be multiples of 4 */
+ assert(const_offset->u32[0] % 4 == 0);
+
+ unsigned offset = const_offset->u32[0] + shift * 4;
+ src.reg_offset = offset / 16;
+ shift = (offset % 16) / 4;
+ src.swizzle += BRW_SWIZZLE4(shift, shift, shift, shift);
+
+ emit(MOV(dest, src));
} else {
- src_reg tmp = get_nir_src(instr->src[0], BRW_REGISTER_TYPE_D, 1);
- src.reladdr = new(mem_ctx) src_reg(tmp);
- }
+ src.swizzle += BRW_SWIZZLE4(shift, shift, shift, shift);
- emit(MOV(dest, src));
+ src_reg indirect = get_nir_src(instr->src[0], BRW_REGISTER_TYPE_UD, 1);
+
+ /* MOV_INDIRECT is going to stomp the whole thing anyway */
+ dest.writemask = WRITEMASK_XYZW;
+
+ emit(SHADER_OPCODE_MOV_INDIRECT, dest, src,
+ indirect, brw_imm_ud(instr->const_index[1]));
+ }
break;
}