iris: Implement force_dual_color_blend_by_location via NIR

We can just have iris look at its own program key and change the
fragment shader output variable's location/index in the NIR.  By
doing this before lowering fragment shader outputs, the rest of
the output lowering does the right thing, and the backend no longer
has to consider hacks for broken OpenGL apps.

Reviewed-by: Alyssa Rosenzweig <alyssa.rosenzweig@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/41122>
This commit is contained in:
Kenneth Graunke 2026-04-23 15:31:54 -07:00 committed by Marge Bot
parent e3beb262bd
commit fbaa5ad0c3
4 changed files with 16 additions and 7 deletions

View file

@ -558,7 +558,6 @@ iris_to_brw_fs_key(const struct iris_screen *screen,
.alpha_to_coverage = key->alpha_to_coverage ? INTEL_ALWAYS : INTEL_NEVER,
.persample_interp = key->persample_interp ? INTEL_ALWAYS : INTEL_NEVER,
.multisample_fbo = key->multisample_fbo ? INTEL_ALWAYS : INTEL_NEVER,
.force_dual_color_blend = key->force_dual_color_blend,
.ignore_sample_mask_out = !key->multisample_fbo,
};
}
@ -638,7 +637,6 @@ iris_to_elk_fs_key(const struct iris_screen *screen,
.alpha_to_coverage = key->alpha_to_coverage ? ELK_ALWAYS : ELK_NEVER,
.persample_interp = key->persample_interp ? ELK_ALWAYS : ELK_NEVER,
.multisample_fbo = key->multisample_fbo ? ELK_ALWAYS : ELK_NEVER,
.force_dual_color_blend = key->force_dual_color_blend,
.coherent_fb_fetch = key->coherent_fb_fetch,
.color_outputs_valid = key->color_outputs_valid,
.input_slots_valid = key->input_slots_valid,
@ -2734,6 +2732,17 @@ iris_update_compiled_gs(struct iris_context *ice)
}
}
static void
iris_force_dual_color_blend(nir_shader *nir)
{
nir_variable *var = nir_find_variable_with_location(nir, nir_var_shader_out,
FRAG_RESULT_DATA1);
if (var) {
var->data.location = FRAG_RESULT_DATA0;
var->data.index = 1;
}
}
/**
* Compile a fragment (pixel) shader, and upload the assembly.
*/
@ -2760,6 +2769,9 @@ iris_compile_fs(struct iris_screen *screen,
iris_setup_uniforms(devinfo, mem_ctx, nir, &system_values,
&num_system_values, &num_cbufs);
if (key->force_dual_color_blend)
iris_force_dual_color_blend(nir);
/* Lower output variables to load_output intrinsics before setting up
* binding tables, so iris_setup_binding_table can map any load_output
* intrinsics to IRIS_SURFACE_GROUP_RENDER_TARGET_READ on Gfx8 for

View file

@ -371,8 +371,6 @@ struct brw_fs_prog_key {
bool alpha_test_replicate_alpha:1;
enum intel_sometimes alpha_to_coverage:2;
bool force_dual_color_blend:1;
/** Whether or inputs are interpolated at sample rate by default
*
* This corresponds to the sample shading API bit in Vulkan or OpenGL which
@ -395,7 +393,7 @@ struct brw_fs_prog_key {
bool ignore_sample_mask_out:1;
bool coarse_pixel:1;
bool api_sample_shading:1;
unsigned pad:12;
unsigned pad:13;
};
static inline bool

View file

@ -3292,7 +3292,7 @@ alloc_frag_output(nir_to_brw_state &ntb, unsigned location)
const unsigned l = GET_FIELD(location, BRW_NIR_FRAG_OUTPUT_LOCATION);
const unsigned i = GET_FIELD(location, BRW_NIR_FRAG_OUTPUT_INDEX);
if (i > 0 || (key->force_dual_color_blend && l == FRAG_RESULT_DATA1))
if (i > 0)
return alloc_temporary(ntb.bld, 4, &s.dual_src_output, 1);
else if (l == FRAG_RESULT_COLOR)

View file

@ -364,7 +364,6 @@ jay_process_nir(const struct intel_device_info *devinfo,
&prog_data->vue.vue_map, 0, 0);
} else if (stage == MESA_SHADER_FRAGMENT) {
assert(key->fs.mesh_input == INTEL_NEVER && "todo");
assert(!key->fs.force_dual_color_blend && "todo");
brw_nir_apply_key(pt, &key->base, 32);
brw_nir_lower_fs_inputs(nir, devinfo, &key->fs);
brw_nir_lower_fs_outputs(nir);