if (nir->info.stage == MESA_SHADER_FRAGMENT &&
nir->options->use_interpolated_input_intrinsics &&
var->data.interpolation != INTERP_MODE_FLAT) {
- assert(vertex_index == NULL);
-
- nir_intrinsic_op bary_op;
- if (var->data.sample ||
- (state->options & nir_lower_io_force_sample_interpolation))
- bary_op = nir_intrinsic_load_barycentric_sample;
- else if (var->data.centroid)
- bary_op = nir_intrinsic_load_barycentric_centroid;
- else
- bary_op = nir_intrinsic_load_barycentric_pixel;
-
- barycentric = nir_load_barycentric(&state->builder, bary_op,
- var->data.interpolation);
- op = nir_intrinsic_load_interpolated_input;
+ if (var->data.interpolation == INTERP_MODE_EXPLICIT) {
+ assert(vertex_index != NULL);
+ op = nir_intrinsic_load_input_vertex;
+ } else {
+ assert(vertex_index == NULL);
+
+ nir_intrinsic_op bary_op;
+ if (var->data.sample ||
+ (state->options & nir_lower_io_force_sample_interpolation))
+ bary_op = nir_intrinsic_load_barycentric_sample;
+ else if (var->data.centroid)
+ bary_op = nir_intrinsic_load_barycentric_centroid;
+ else
+ bary_op = nir_intrinsic_load_barycentric_pixel;
+
+ barycentric = nir_load_barycentric(&state->builder, bary_op,
+ var->data.interpolation);
+ op = nir_intrinsic_load_interpolated_input;
+ }
} else {
op = vertex_index ? nir_intrinsic_load_per_vertex_input :
nir_intrinsic_load_input;
state->type_size(var->type, var->data.bindless));
if (load->intrinsic == nir_intrinsic_load_input ||
+ load->intrinsic == nir_intrinsic_load_input_vertex ||
load->intrinsic == nir_intrinsic_load_uniform)
nir_intrinsic_set_type(load, type);
}
return nir_vec(b, comp64, intrin->dest.ssa.num_components);
+ } else if (intrin->dest.ssa.bit_size == 1) {
+ /* Booleans are 32-bit */
+ assert(glsl_type_is_boolean(type));
+ return nir_b2b1(&state->builder,
+ emit_load(state, vertex_index, var, offset, component,
+ intrin->dest.ssa.num_components, 32,
+ nir_type_bool32));
} else {
return emit_load(state, vertex_index, var, offset, component,
intrin->dest.ssa.num_components,
write_mask >>= num_comps;
offset = nir_iadd_imm(b, offset, slot_size);
}
+ } else if (intrin->dest.ssa.bit_size == 1) {
+ /* Booleans are 32-bit */
+ assert(glsl_type_is_boolean(type));
+ nir_ssa_def *b32_val = nir_b2b32(&state->builder, intrin->src[1].ssa);
+ emit_store(state, b32_val, vertex_index, var, offset,
+ component, intrin->num_components,
+ nir_intrinsic_write_mask(intrin),
+ nir_type_bool32);
} else {
emit_store(state, intrin->src[1].ssa, vertex_index, var, offset,
component, intrin->num_components,
nir_builder *b = &state->builder;
assert(var->data.mode == nir_var_shader_in);
- /* Ignore interpolateAt() for flat variables - flat is flat. */
- if (var->data.interpolation == INTERP_MODE_FLAT)
- return lower_load(intrin, state, NULL, var, offset, component, type);
+ /* Ignore interpolateAt() for flat variables - flat is flat. Lower
+ * interpolateAtVertex() for explicit variables.
+ */
+ if (var->data.interpolation == INTERP_MODE_FLAT ||
+ var->data.interpolation == INTERP_MODE_EXPLICIT) {
+ nir_ssa_def *vertex_index = NULL;
+
+ if (var->data.interpolation == INTERP_MODE_EXPLICIT) {
+ assert(intrin->intrinsic == nir_intrinsic_interp_deref_at_vertex);
+ vertex_index = intrin->src[1].ssa;
+ }
+
+ return lower_load(intrin, state, vertex_index, var, offset, component, type);
+ }
/* None of the supported APIs allow interpolation on 64-bit things */
assert(intrin->dest.is_ssa && intrin->dest.ssa.bit_size <= 32);
nir_intrinsic_set_interp_mode(bary_setup, var->data.interpolation);
if (intrin->intrinsic == nir_intrinsic_interp_deref_at_sample ||
- intrin->intrinsic == nir_intrinsic_interp_deref_at_offset)
+ intrin->intrinsic == nir_intrinsic_interp_deref_at_offset ||
+ intrin->intrinsic == nir_intrinsic_interp_deref_at_vertex)
nir_src_copy(&bary_setup->src[0], &intrin->src[1], bary_setup);
nir_builder_instr_insert(b, &bary_setup->instr);
case nir_intrinsic_interp_deref_at_centroid:
case nir_intrinsic_interp_deref_at_sample:
case nir_intrinsic_interp_deref_at_offset:
+ case nir_intrinsic_interp_deref_at_vertex:
/* We can optionally lower these to load_interpolated_input */
if (options->use_interpolated_input_intrinsics)
break;
case nir_intrinsic_interp_deref_at_centroid:
case nir_intrinsic_interp_deref_at_sample:
case nir_intrinsic_interp_deref_at_offset:
+ case nir_intrinsic_interp_deref_at_vertex:
assert(vertex_index == NULL);
replacement = lower_interpolate_at(intrin, state, var, offset,
component_offset, deref->type);
result = &load->dest.ssa;
}
- if (intrin->dest.ssa.bit_size == 1)
- result = nir_i2b(b, result);
+ if (intrin->dest.ssa.bit_size == 1) {
+ /* For shared, we can go ahead and use NIR's and/or the back-end's
+ * standard encoding for booleans rather than forcing a 0/1 boolean.
+ * This should save an instruction or two.
+ */
+ if (mode == nir_var_mem_shared)
+ result = nir_b2b1(b, result);
+ else
+ result = nir_i2b(b, result);
+ }
return result;
}
nir_intrinsic_instr *store = nir_intrinsic_instr_create(b->shader, op);
if (value->bit_size == 1) {
- /* TODO: Make the native bool bit_size an option. */
- value = nir_b2i(b, value, 32);
+ /* For shared, we can go ahead and use NIR's and/or the back-end's
+ * standard encoding for booleans rather than forcing a 0/1 boolean.
+ * This should save an instruction or two.
+ *
+ * TODO: Make the native bool bit_size an option.
+ */
+ if (mode == nir_var_mem_shared)
+ value = nir_b2b32(b, value);
+ else
+ value = nir_b2i(b, value, 32);
}
store->src[0] = nir_src_for_ssa(value);
* - compact shader inputs/outputs
* - interface types
*/
- nir_variable_mode supported = nir_var_mem_shared | nir_var_shader_temp | nir_var_function_temp;
+ ASSERTED nir_variable_mode supported = nir_var_mem_shared |
+ nir_var_shader_temp | nir_var_function_temp;
assert(!(modes & ~supported) && "unsupported");
bool progress = false;
case nir_intrinsic_store_shared:
case nir_intrinsic_store_global:
case nir_intrinsic_store_scratch:
+ case nir_intrinsic_ssbo_atomic_add:
+ case nir_intrinsic_ssbo_atomic_imin:
+ case nir_intrinsic_ssbo_atomic_umin:
+ case nir_intrinsic_ssbo_atomic_imax:
+ case nir_intrinsic_ssbo_atomic_umax:
+ case nir_intrinsic_ssbo_atomic_and:
+ case nir_intrinsic_ssbo_atomic_or:
+ case nir_intrinsic_ssbo_atomic_xor:
+ case nir_intrinsic_ssbo_atomic_exchange:
+ case nir_intrinsic_ssbo_atomic_comp_swap:
+ case nir_intrinsic_ssbo_atomic_fadd:
+ case nir_intrinsic_ssbo_atomic_fmin:
+ case nir_intrinsic_ssbo_atomic_fmax:
+ case nir_intrinsic_ssbo_atomic_fcomp_swap:
return &instr->src[1];
case nir_intrinsic_store_ssbo:
case nir_intrinsic_store_per_vertex_output: