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;
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,
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) {
{
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;
+}
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;
}