brw_MOV(p, get_element_ud(header, 2),
brw_imm_ud(inst->texture_offset));
}
+
+ if (inst->sampler >= 16) {
+ /* The "Sampler Index" field can only store values between 0 and 15.
+ * However, we can add an offset to the "Sampler State Pointer"
+ * field, effectively selecting a different set of 16 samplers.
+ *
+ * The "Sampler State Pointer" needs to be aligned to a 32-byte
+ * offset, and each sampler state is only 16-bytes, so we can't
+ * exclusively use the offset - we have to use both.
+ */
+ assert(brw->is_haswell); /* field only exists on Haswell */
+ brw_ADD(p,
+ get_element_ud(header, 3),
+ get_element_ud(brw_vec8_grf(0, 0), 3),
+ brw_imm_ud(16 * (inst->sampler / 16) *
+ sizeof(gen7_sampler_state)));
+ }
brw_pop_insn_state(p);
}
}
inst->base_mrf,
src,
surface_index,
- inst->sampler,
+ inst->sampler % 16,
msg_type,
1, /* response length */
inst->mlen,
if (ir->op == ir_tg4)
inst->texture_offset |= gather_channel(ir, sampler) << 16;
- /* Texel offsets go in the message header; Gen4 also requires headers. */
+ /* The message header is necessary for:
+ * - Gen4 (always)
+ * - Texel offsets
+ * - Gather channel selection
+ * - Sampler indices too large to fit in a 4-bit value.
+ */
inst->header_present =
- brw->gen < 5 || inst->texture_offset != 0 || ir->op == ir_tg4;
+ brw->gen < 5 || inst->texture_offset != 0 || ir->op == ir_tg4 ||
+ sampler >= 16;
inst->base_mrf = 2;
inst->mlen = inst->header_present + 1; /* always at least one */
inst->sampler = sampler;