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:
@@ -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_loads_stores_to_dxil);
|
||||||
NIR_PASS_V(nir, dxil_nir_lower_atomics_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 = {};
|
struct nir_to_dxil_options opts = {};
|
||||||
opts.interpolate_at_vertex = screen->have_load_at_vertex;
|
opts.interpolate_at_vertex = screen->have_load_at_vertex;
|
||||||
opts.lower_int16 = !screen->opts4.Native16BitShaderOpsSupported;
|
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.manual_depth_range != have->fs.manual_depth_range ||
|
||||||
expect->fs.polygon_stipple != have->fs.polygon_stipple ||
|
expect->fs.polygon_stipple != have->fs.polygon_stipple ||
|
||||||
expect->fs.cast_to_uint != have->fs.cast_to_uint ||
|
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;
|
return false;
|
||||||
} else if (expect->stage == PIPE_SHADER_COMPUTE) {
|
} else if (expect->stage == PIPE_SHADER_COMPUTE) {
|
||||||
if (memcmp(expect->cs.workgroup_size, have->cs.workgroup_size,
|
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.frag_result_color_lowering = sel_ctx->frag_result_color_lowering;
|
||||||
key->fs.manual_depth_range = sel_ctx->manual_depth_range;
|
key->fs.manual_depth_range = sel_ctx->manual_depth_range;
|
||||||
key->fs.polygon_stipple = sel_ctx->ctx->pstipple.enabled;
|
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 &&
|
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.blend->desc.RenderTarget[0].LogicOpEnable &&
|
||||||
!sel_ctx->ctx->gfx_pipeline_state.has_float_rtv) {
|
!sel_ctx->ctx->gfx_pipeline_state.has_float_rtv) {
|
||||||
|
|||||||
@@ -118,6 +118,7 @@ struct d3d12_shader_key {
|
|||||||
unsigned manual_depth_range : 1;
|
unsigned manual_depth_range : 1;
|
||||||
unsigned polygon_stipple : 1;
|
unsigned polygon_stipple : 1;
|
||||||
unsigned remap_front_facing : 1;
|
unsigned remap_front_facing : 1;
|
||||||
|
unsigned multisample_disabled : 1;
|
||||||
} fs;
|
} fs;
|
||||||
|
|
||||||
struct {
|
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);
|
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
|
bool
|
||||||
d3d12_lower_sample_pos(nir_shader *s);
|
d3d12_lower_sample_pos(nir_shader *s);
|
||||||
|
|
||||||
|
bool
|
||||||
|
d3d12_disable_multisampling(nir_shader *s);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -263,7 +263,14 @@ create_gfx_pipeline_state(struct d3d12_context *ctx)
|
|||||||
|
|
||||||
if (state->num_cbufs || state->dsv_format != DXGI_FORMAT_UNKNOWN) {
|
if (state->num_cbufs || state->dsv_format != DXGI_FORMAT_UNKNOWN) {
|
||||||
pso_desc.SampleDesc.Count = state->samples;
|
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.SampleDesc.Count = 1;
|
||||||
pso_desc.RasterizerState.ForcedSampleCount = state->samples;
|
pso_desc.RasterizerState.ForcedSampleCount = state->samples;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user