/* FALLTHROUGH */
case INTERP_MODE_SMOOTH:
if (var->data.centroid) {
+ BITSET_SET(c->centroid_flags, i);
return vir_FADD(c, vir_FMUL(c, vary,
c->payload_w_centroid), r5);
} else {
c->last_thrsw->is_last_thrsw = true;
}
+/* There's a flag in the shader for "centroid W used in addition to center W",
+ * so we need to walk the program after VIR optimization to see if both are
+ * used.
+ */
+static void
+vir_check_payload_w(struct v3d_compile *c)
+{
+ if (c->s->info.stage != MESA_SHADER_FRAGMENT)
+ return;
+
+ bool any_centroid = false;
+ for (int i = 0; i < ARRAY_SIZE(c->centroid_flags); i++) {
+ if (c->centroid_flags[i])
+ any_centroid = true;
+ }
+ if (!any_centroid)
+ return;
+
+ vir_for_each_inst_inorder(inst, c) {
+ for (int i = 0; i < vir_get_nsrc(inst); i++) {
+ if (inst->src[i].file == QFILE_REG &&
+ inst->src[i].index == 0) {
+ c->uses_centroid_and_center_w = true;
+ return;
+ }
+ }
+ }
+
+}
+
void
v3d_nir_to_vir(struct v3d_compile *c)
{
vir_optimize(c);
vir_lower_uniforms(c);
+ vir_check_payload_w(c);
+
/* XXX: vir_schedule_instructions(c); */
if (V3D_DEBUG & (V3D_DEBUG_VIR |
*/
uint32_t flat_shade_flags[BITSET_WORDS(V3D_MAX_FS_INPUTS)];
+ uint32_t centroid_flags[BITSET_WORDS(V3D_MAX_FS_INPUTS)];
+
+ bool uses_centroid_and_center_w;
+
struct v3d_ubo_range *ubo_ranges;
bool *ubo_range_used;
uint32_t ubo_ranges_array_size;
*/
uint32_t flat_shade_flags[((V3D_MAX_FS_INPUTS - 1) / 24) + 1];
+ uint32_t centroid_flags[((V3D_MAX_FS_INPUTS - 1) / 24) + 1];
+
bool writes_z;
bool discard;
+ bool uses_centroid_and_center_w;
};
/* Special nir_load_input intrinsic index for loading the current TLB
for (int i = 0; i < V3D_MAX_FS_INPUTS; i++) {
if (BITSET_TEST(c->flat_shade_flags, i))
prog_data->flat_shade_flags[i / 24] |= 1 << (i % 24);
+
+ if (BITSET_TEST(c->centroid_flags, i))
+ prog_data->centroid_flags[i / 24] |= 1 << (i % 24);
}
}
prog_data->writes_z = (c->s->info.outputs_written &
(1 << FRAG_RESULT_DEPTH));
prog_data->discard = c->s->info.fs.uses_discard;
+ prog_data->uses_centroid_and_center_w = c->uses_centroid_and_center_w;
return v3d_return_qpu_insts(c, final_assembly_size);
}
#define VC5_DIRTY_FS_INPUTS (1 << 26)
#define VC5_DIRTY_STREAMOUT (1 << 27)
#define VC5_DIRTY_OQ (1 << 28)
+#define VC5_DIRTY_CENTROID_FLAGS (1 << 29)
#define VC5_MAX_FS_INPUTS 64
(vc5->prog.fs->prog_data.fs->writes_z ||
vc5->prog.fs->prog_data.fs->discard);
+ shader.fragment_shader_uses_real_pixel_centre_w_in_addition_to_centroid_w2 =
+ vc5->prog.fs->prog_data.fs->uses_centroid_and_center_w;
+
shader.number_of_varyings_in_fragment_shader =
vc5->prog.fs->prog_data.base->num_inputs;
}
}
+#if V3D_VERSION >= 40
+ if (vc5->dirty & VC5_DIRTY_CENTROID_FLAGS) {
+ bool emitted_any = false;
+
+ for (int i = 0; i < ARRAY_SIZE(vc5->prog.fs->prog_data.fs->centroid_flags); i++) {
+ if (!vc5->prog.fs->prog_data.fs->centroid_flags[i])
+ continue;
+
+ cl_emit(&job->bcl, CENTROID_FLAGS, flags) {
+ flags.varying_offset_v0 = i;
+
+ if (emitted_any) {
+ flags.action_for_centroid_flags_of_lower_numbered_varyings =
+ V3D_VARYING_FLAGS_ACTION_UNCHANGED;
+ flags.action_for_centroid_flags_of_higher_numbered_varyings =
+ V3D_VARYING_FLAGS_ACTION_UNCHANGED;
+ } else {
+ flags.action_for_centroid_flags_of_lower_numbered_varyings =
+ ((i == 0) ?
+ V3D_VARYING_FLAGS_ACTION_UNCHANGED :
+ V3D_VARYING_FLAGS_ACTION_ZEROED);
+
+ flags.action_for_centroid_flags_of_higher_numbered_varyings =
+ V3D_VARYING_FLAGS_ACTION_ZEROED;
+ }
+
+ flags.centroid_flags_for_varyings_v024 =
+ vc5->prog.fs->prog_data.fs->centroid_flags[i];
+ }
+
+ emitted_any = true;
+ }
+
+ if (!emitted_any) {
+ cl_emit(&job->bcl, ZERO_ALL_CENTROID_FLAGS, flags);
+ }
+ }
+#endif
+
/* Set up the transform feedback data specs (which VPM entries to
* output to which buffers).
*/
vc5->dirty |= VC5_DIRTY_COMPILED_FS;
- if (old_fs &&
- vc5->prog.fs->prog_data.fs->flat_shade_flags !=
- old_fs->prog_data.fs->flat_shade_flags) {
- vc5->dirty |= VC5_DIRTY_FLAT_SHADE_FLAGS;
+ if (old_fs) {
+ if (vc5->prog.fs->prog_data.fs->flat_shade_flags !=
+ old_fs->prog_data.fs->flat_shade_flags) {
+ vc5->dirty |= VC5_DIRTY_FLAT_SHADE_FLAGS;
+ }
+
+ if (vc5->prog.fs->prog_data.fs->centroid_flags !=
+ old_fs->prog_data.fs->centroid_flags) {
+ vc5->dirty |= VC5_DIRTY_CENTROID_FLAGS;
+ }
}
if (old_fs && memcmp(vc5->prog.fs->prog_data.fs->input_slots,