p0_unpacked.bias_supplied = true;
break;
case nir_tex_src_lod:
- /* XXX: Needs base level addition */
coords[next_coord++] =
- ntq_get_src(c, instr->src[i].src, 0);
+ vir_FADD(c,
+ ntq_get_src(c, instr->src[i].src, 0),
+ vir_uniform(c, QUNIFORM_TEXTURE_FIRST_LEVEL,
+ unit));
if (instr->op != nir_texop_txf &&
instr->op != nir_texop_tg4) {
STATIC_ASSERT(PIPE_SWIZZLE_X == 0);
chan = return_values[i / 2];
- enum v3d_qpu_input_unpack unpack;
- if (i & 1)
- unpack = V3D_QPU_UNPACK_H;
- else
- unpack = V3D_QPU_UNPACK_L;
+ if (nir_alu_type_get_base_type(instr->dest_type) ==
+ nir_type_float) {
+ enum v3d_qpu_input_unpack unpack;
+ if (i & 1)
+ unpack = V3D_QPU_UNPACK_H;
+ else
+ unpack = V3D_QPU_UNPACK_L;
- chan = vir_FMOV(c, chan);
- vir_set_unpack(c->defs[chan.index], 0, unpack);
+ chan = vir_FMOV(c, chan);
+ vir_set_unpack(c->defs[chan.index], 0, unpack);
+ } else {
+ /* If we're unpacking the low field, shift it
+ * up to the top first.
+ */
+ if ((i & 1) == 0) {
+ chan = vir_SHL(c, chan,
+ vir_uniform_ui(c, 16));
+ }
+
+ /* Do proper sign extension to a 32-bit int. */
+ if (nir_alu_type_get_base_type(instr->dest_type) ==
+ nir_type_int) {
+ chan = vir_ASR(c, chan,
+ vir_uniform_ui(c, 16));
+ } else {
+ chan = vir_SHR(c, chan,
+ vir_uniform_ui(c, 16));
+ }
+ }
} else {
chan = vir_MOV(c, return_values[i]);
}
emit_fragment_input(struct v3d_compile *c, int attr, nir_variable *var)
{
for (int i = 0; i < glsl_get_vector_elements(var->type); i++) {
- c->inputs[attr * 4 + i] =
- emit_fragment_varying(c, var, i);
+ int chan = var->data.location_frac + i;
+ c->inputs[attr * 4 + chan] =
+ emit_fragment_varying(c, var, chan);
}
}
}
*/
+ bool has_any_tlb_color_write = false;
+ for (int rt = 0; rt < c->fs_key->nr_cbufs; rt++) {
+ if (c->output_color_var[rt])
+ has_any_tlb_color_write = true;
+ }
+
if (c->output_position_index != -1) {
struct qinst *inst = vir_MOV_dest(c,
vir_reg(QFILE_TLBU, 0),
TLB_TYPE_DEPTH |
TLB_DEPTH_TYPE_PER_PIXEL |
0xffffff00);
- } else if (c->s->info.fs.uses_discard) {
+ } else if (c->s->info.fs.uses_discard || !has_any_tlb_color_write) {
+ /* Emit passthrough Z if it needed to be delayed until shader
+ * end due to potential discards.
+ *
+ * Since (single-threaded) fragment shaders always need a TLB
+ * write, emit passthrouh Z if we didn't have any color
+ * buffers and flag us as potentially discarding, so that we
+ * can use Z as the TLB write.
+ */
+ c->s->info.fs.uses_discard = true;
+
struct qinst *inst = vir_MOV_dest(c,
vir_reg(QFILE_TLBU, 0),
vir_reg(QFILE_NULL, 0));
assert(array_len == 1);
(void)array_len;
- for (int i = 0; i < 4; i++)
- add_output(c, loc + i, var->data.location, i);
+ for (int i = 0; i < glsl_get_vector_elements(var->type); i++) {
+ add_output(c, loc + var->data.location_frac + i,
+ var->data.location,
+ var->data.location_frac + i);
+ }
if (c->s->info.stage == MESA_SHADER_FRAGMENT) {
switch (var->data.location) {