+ bool msaa = rast->multisample;
+ fragmeta->coverage_mask = msaa ? ctx->sample_mask : ~0;
+
+ fragmeta->unknown2_3 = MALI_DEPTH_FUNC(MALI_FUNC_ALWAYS) | 0x10;
+ fragmeta->unknown2_4 = 0x4e0;
+
+ /* TODO: Sample size */
+ SET_BIT(fragmeta->unknown2_3, MALI_HAS_MSAA, msaa);
+ SET_BIT(fragmeta->unknown2_4, MALI_NO_MSAA, !msaa);
+
+ /* EXT_shader_framebuffer_fetch requires the shader to be run
+ * per-sample when outputs are read. */
+ bool per_sample = ctx->min_samples > 1 || fs->outputs_read;
+ SET_BIT(fragmeta->unknown2_3, MALI_PER_SAMPLE, msaa && per_sample);
+
+ fragmeta->depth_units = rast->offset_units * 2.0f;
+ fragmeta->depth_factor = rast->offset_scale;
+
+ /* XXX: Which bit is which? Does this maybe allow offseting not-tri? */
+
+ SET_BIT(fragmeta->unknown2_4, MALI_DEPTH_RANGE_A, rast->offset_tri);
+ SET_BIT(fragmeta->unknown2_4, MALI_DEPTH_RANGE_B, rast->offset_tri);
+
+ SET_BIT(fragmeta->unknown2_3, MALI_DEPTH_CLIP_NEAR, rast->depth_clip_near);
+ SET_BIT(fragmeta->unknown2_3, MALI_DEPTH_CLIP_FAR, rast->depth_clip_far);
+
+ SET_BIT(fragmeta->unknown2_4, MALI_STENCIL_TEST,
+ zsa->base.stencil[0].enabled);
+
+ fragmeta->stencil_mask_front = zsa->stencil_mask_front;
+ fragmeta->stencil_mask_back = zsa->stencil_mask_back;
+
+ /* Bottom bits for stencil ref, exactly one word */
+ fragmeta->stencil_front.opaque[0] = zsa->stencil_front.opaque[0] | ctx->stencil_ref.ref_value[0];
+
+ /* If back-stencil is not enabled, use the front values */
+
+ if (zsa->base.stencil[1].enabled)
+ fragmeta->stencil_back.opaque[0] = zsa->stencil_back.opaque[0] | ctx->stencil_ref.ref_value[1];
+ else
+ fragmeta->stencil_back = fragmeta->stencil_front;
+
+ SET_BIT(fragmeta->unknown2_3, MALI_DEPTH_WRITEMASK,
+ zsa->base.depth.writemask);
+
+ fragmeta->unknown2_3 &= ~MALI_DEPTH_FUNC_MASK;
+ fragmeta->unknown2_3 |= MALI_DEPTH_FUNC(panfrost_translate_compare_func(
+ zsa->base.depth.enabled ? zsa->base.depth.func : PIPE_FUNC_ALWAYS));
+
+ SET_BIT(fragmeta->unknown2_4, MALI_NO_DITHER,
+ (dev->quirks & MIDGARD_SFBD) && ctx->blend &&
+ !ctx->blend->base.dither);
+
+ SET_BIT(fragmeta->unknown2_4, 0x10, dev->quirks & MIDGARD_SFBD);
+
+ SET_BIT(fragmeta->unknown2_4, MALI_ALPHA_TO_COVERAGE,
+ ctx->blend->base.alpha_to_coverage);
+
+ /* Get blending setup */
+ unsigned rt_count = ctx->pipe_framebuffer.nr_cbufs;
+
+ /* Disable shader execution if we can */
+ if (dev->quirks & MIDGARD_SHADERLESS
+ && !panfrost_fs_required(fs, blend, rt_count)) {
+ fragmeta->shader = 0x1;
+ fragmeta->attribute_count = 0;
+ fragmeta->varying_count = 0;
+ fragmeta->texture_count = 0;
+ fragmeta->sampler_count = 0;
+
+ /* This feature is not known to work on Bifrost */
+ struct mali_midgard_properties_packed prop;
+
+ pan_pack(&prop, MIDGARD_PROPERTIES, cfg) {
+ cfg.work_register_count = 1;
+ cfg.depth_source = MALI_DEPTH_SOURCE_FIXED_FUNCTION;
+ cfg.early_z_enable = true;
+ }
+
+ memcpy(&fragmeta->midgard1, &prop, sizeof(prop));
+ }
+
+ /* If there is a blend shader, work registers are shared. We impose 8
+ * work registers as a limit for blend shaders. Should be lower XXX */
+
+ if (!(dev->quirks & IS_BIFROST)) {
+ for (unsigned c = 0; c < rt_count; ++c) {
+ if (blend[c].is_shader) {
+ fragmeta->midgard1.work_count =
+ MAX2(fragmeta->midgard1.work_count, 8);
+ }
+ }
+ }