unsigned nr_comp, unsigned component,
nir_src *indirect_offset, nir_alu_type type, bool flat)
{
- /* XXX: Half-floats? */
- /* TODO: swizzle, mask */
-
midgard_instruction ins = m_ld_vary_32(dest, PACK_LDST_ATTRIB_OFS(offset));
ins.mask = mask_of(nr_comp);
ins.dest_type = type;
for (unsigned i = 0; i < ARRAY_SIZE(ins.swizzle[0]); ++i)
ins.swizzle[0][i] = MIN2(i + component, COMPONENT_W);
-
midgard_varying_params p = {
.flat_shading = flat,
.perspective_correction = 1,
ins.load_store.arg_reg = REGISTER_LDST_ZERO;
ins.load_store.index_format = midgard_index_address_u32;
- /* Use the type appropriate load */
- switch (type) {
- case nir_type_uint32:
- case nir_type_bool32:
+ /* For flat shading, we always use .u32 and require 32-bit mode. For
+ * smooth shading, we use the appropriate floating-point type.
+ *
+ * This could be optimized, but it makes it easy to check correctness.
+ */
+ if (flat) {
+ assert(nir_alu_type_get_type_size(type) == 32);
ins.op = midgard_op_ld_vary_32u;
- break;
- case nir_type_int32:
- ins.op = midgard_op_ld_vary_32i;
- break;
- case nir_type_float32:
- ins.op = midgard_op_ld_vary_32;
- break;
- case nir_type_float16:
- ins.op = midgard_op_ld_vary_16;
- break;
- default:
- unreachable("Attempted to load unknown type");
- break;
+ } else {
+ assert(nir_alu_type_get_base_type(type) == nir_type_float);
+
+ ins.op = (nir_alu_type_get_type_size(type) == 32) ?
+ midgard_op_ld_vary_32 :
+ midgard_op_ld_vary_16;
}
emit_mir_instruction(ctx, ins);
unsigned dst_component = nir_intrinsic_component(instr);
unsigned nr_comp = nir_src_num_components(instr->src[0]);
+ /* ABI: Format controlled by the attribute descriptor.
+ * This simplifies flat shading, although it prevents
+ * certain (unimplemented) 16-bit optimizations.
+ *
+ * In particular, it lets the driver handle internal
+ * TGSI shaders that set flat in the VS but smooth in
+ * the FS. This matches our handling on Bifrost.
+ */
+ bool auto32 = true;
+ assert(nir_alu_type_get_type_size(nir_intrinsic_src_type(instr)) == 32);
+
+ /* ABI: varyings in the secondary attribute table */
+ bool secondary_table = true;
+
midgard_instruction st = m_st_vary_32(reg, PACK_LDST_ATTRIB_OFS(offset));
st.load_store.arg_reg = REGISTER_LDST_ZERO;
- st.load_store.index_format = midgard_index_address_u32;
st.load_store.index_reg = REGISTER_LDST_ZERO;
- switch (nir_alu_type_get_base_type(nir_intrinsic_src_type(instr))) {
- case nir_type_uint:
- case nir_type_bool:
- st.op = midgard_op_st_vary_32u;
- break;
- case nir_type_int:
- st.op = midgard_op_st_vary_32i;
- break;
- case nir_type_float:
- st.op = midgard_op_st_vary_32;
- break;
- default:
- unreachable("Attempted to store unknown type");
- break;
- }
+ /* Attribute instruction uses these 2-bits for the
+ * a32 and table bits, pack this specially.
+ */
+ st.load_store.index_format = (auto32 ? (1 << 0) : 0) |
+ (secondary_table ? (1 << 1) : 0);
/* nir_intrinsic_component(store_intr) encodes the
* destination component start. Source component offset