mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-23 22:00:13 +01:00
d3d12: Modify shaders when MSAA is disabled
I couldn't find this in a spec but the builtin-gl-sample-mask piglit seems to expect writing to the output sample mask to do nothing when max num samples == 0. The ForcedSampleCount property should make everything appear as if MSAA is disabled. However, it's undefined behavior if depth is bound, so in that case, we can at least use a lowering pass to make things *look* like MSAA is off, unless you use atomics to count invocations. Reviewed-by: Sil Vilerino <sivileri@microsoft.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/14624>
This commit is contained in:
parent
aef777c95d
commit
e5cf19fced
5 changed files with 81 additions and 2 deletions
|
|
@ -176,6 +176,9 @@ compile_nir(struct d3d12_context *ctx, struct d3d12_shader_selector *sel,
|
|||
NIR_PASS_V(nir, dxil_nir_lower_loads_stores_to_dxil);
|
||||
NIR_PASS_V(nir, dxil_nir_lower_atomics_to_dxil);
|
||||
|
||||
if (key->fs.multisample_disabled)
|
||||
NIR_PASS_V(nir, d3d12_disable_multisampling);
|
||||
|
||||
struct nir_to_dxil_options opts = {};
|
||||
opts.interpolate_at_vertex = screen->have_load_at_vertex;
|
||||
opts.lower_int16 = !screen->opts4.Native16BitShaderOpsSupported;
|
||||
|
|
@ -619,7 +622,10 @@ d3d12_compare_shader_keys(const d3d12_shader_key *expect, const d3d12_shader_key
|
|||
expect->fs.manual_depth_range != have->fs.manual_depth_range ||
|
||||
expect->fs.polygon_stipple != have->fs.polygon_stipple ||
|
||||
expect->fs.cast_to_uint != have->fs.cast_to_uint ||
|
||||
expect->fs.cast_to_int != have->fs.cast_to_int)
|
||||
expect->fs.cast_to_int != have->fs.cast_to_int ||
|
||||
expect->fs.remap_front_facing != have->fs.remap_front_facing ||
|
||||
expect->fs.missing_dual_src_outputs != have->fs.missing_dual_src_outputs ||
|
||||
expect->fs.multisample_disabled != have->fs.multisample_disabled)
|
||||
return false;
|
||||
} else if (expect->stage == PIPE_SHADER_COMPUTE) {
|
||||
if (memcmp(expect->cs.workgroup_size, have->cs.workgroup_size,
|
||||
|
|
@ -760,6 +766,8 @@ d3d12_fill_shader_key(struct d3d12_selection_context *sel_ctx,
|
|||
key->fs.frag_result_color_lowering = sel_ctx->frag_result_color_lowering;
|
||||
key->fs.manual_depth_range = sel_ctx->manual_depth_range;
|
||||
key->fs.polygon_stipple = sel_ctx->ctx->pstipple.enabled;
|
||||
key->fs.multisample_disabled = sel_ctx->ctx->gfx_pipeline_state.rast &&
|
||||
!sel_ctx->ctx->gfx_pipeline_state.rast->desc.MultisampleEnable;
|
||||
if (sel_ctx->ctx->gfx_pipeline_state.blend &&
|
||||
sel_ctx->ctx->gfx_pipeline_state.blend->desc.RenderTarget[0].LogicOpEnable &&
|
||||
!sel_ctx->ctx->gfx_pipeline_state.has_float_rtv) {
|
||||
|
|
|
|||
|
|
@ -118,6 +118,7 @@ struct d3d12_shader_key {
|
|||
unsigned manual_depth_range : 1;
|
||||
unsigned polygon_stipple : 1;
|
||||
unsigned remap_front_facing : 1;
|
||||
unsigned multisample_disabled : 1;
|
||||
} fs;
|
||||
|
||||
struct {
|
||||
|
|
|
|||
|
|
@ -878,3 +878,63 @@ d3d12_lower_sample_pos(nir_shader *s)
|
|||
{
|
||||
return nir_shader_lower_instructions(s, is_sample_pos, lower_sample_pos, NULL);
|
||||
}
|
||||
|
||||
static bool
|
||||
is_multisampling_instr(const nir_instr *instr, const void *_data)
|
||||
{
|
||||
if (instr->type != nir_instr_type_intrinsic)
|
||||
return false;
|
||||
nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr);
|
||||
if (intr->intrinsic == nir_intrinsic_store_output) {
|
||||
nir_io_semantics semantics = nir_intrinsic_io_semantics(intr);
|
||||
return semantics.location == FRAG_RESULT_SAMPLE_MASK;
|
||||
} else if (intr->intrinsic == nir_intrinsic_store_deref) {
|
||||
nir_variable *var = nir_deref_instr_get_variable(nir_src_as_deref(intr->src[0]));
|
||||
return var->data.location == FRAG_RESULT_SAMPLE_MASK;
|
||||
} else if (intr->intrinsic == nir_intrinsic_load_sample_id ||
|
||||
intr->intrinsic == nir_intrinsic_load_sample_mask_in)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static nir_ssa_def *
|
||||
lower_multisampling_instr(nir_builder *b, nir_instr *instr, void *_data)
|
||||
{
|
||||
nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr);
|
||||
switch (intr->intrinsic) {
|
||||
case nir_intrinsic_store_output:
|
||||
case nir_intrinsic_store_deref:
|
||||
return NIR_LOWER_INSTR_PROGRESS_REPLACE;
|
||||
case nir_intrinsic_load_sample_id:
|
||||
return nir_imm_int(b, 0);
|
||||
case nir_intrinsic_load_sample_mask_in:
|
||||
return nir_imm_int(b, 1);
|
||||
default:
|
||||
unreachable("Invalid intrinsic");
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
d3d12_disable_multisampling(nir_shader *s)
|
||||
{
|
||||
if (s->info.stage != MESA_SHADER_FRAGMENT)
|
||||
return false;
|
||||
bool progress = nir_shader_lower_instructions(s, is_multisampling_instr, lower_multisampling_instr, NULL);
|
||||
|
||||
nir_foreach_variable_with_modes_safe(var, s, nir_var_shader_out) {
|
||||
if (var->data.location == FRAG_RESULT_SAMPLE_MASK) {
|
||||
exec_node_remove(&var->node);
|
||||
progress = true;
|
||||
}
|
||||
}
|
||||
nir_foreach_variable_with_modes_safe(var, s, nir_var_shader_in | nir_var_system_value) {
|
||||
if (var->data.location == SYSTEM_VALUE_SAMPLE_MASK_IN ||
|
||||
var->data.location == SYSTEM_VALUE_SAMPLE_ID) {
|
||||
exec_node_remove(&var->node);
|
||||
progress = true;
|
||||
}
|
||||
var->data.sample = false;
|
||||
}
|
||||
BITSET_CLEAR(s->info.system_values_read, SYSTEM_VALUE_SAMPLE_ID);
|
||||
return progress;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -101,6 +101,9 @@ d3d12_lower_image_casts(nir_shader *s, struct d3d12_image_format_conversion_info
|
|||
bool
|
||||
d3d12_lower_sample_pos(nir_shader *s);
|
||||
|
||||
bool
|
||||
d3d12_disable_multisampling(nir_shader *s);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -263,7 +263,14 @@ create_gfx_pipeline_state(struct d3d12_context *ctx)
|
|||
|
||||
if (state->num_cbufs || state->dsv_format != DXGI_FORMAT_UNKNOWN) {
|
||||
pso_desc.SampleDesc.Count = state->samples;
|
||||
} else {
|
||||
if (!state->zsa->desc.DepthEnable &&
|
||||
!state->zsa->desc.StencilEnable &&
|
||||
!state->rast->desc.MultisampleEnable &&
|
||||
state->samples > 1) {
|
||||
pso_desc.RasterizerState.ForcedSampleCount = 1;
|
||||
pso_desc.DSVFormat = DXGI_FORMAT_UNKNOWN;
|
||||
}
|
||||
} else if (state->samples > 1) {
|
||||
pso_desc.SampleDesc.Count = 1;
|
||||
pso_desc.RasterizerState.ForcedSampleCount = state->samples;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue