diff --git a/src/nouveau/compiler/nak/api.rs b/src/nouveau/compiler/nak/api.rs index af617f4d4da..d87e70b3df0 100644 --- a/src/nouveau/compiler/nak/api.rs +++ b/src/nouveau/compiler/nak/api.rs @@ -334,21 +334,18 @@ pub extern "C" fn nak_compile_shader( }, } } - ShaderStageInfo::Fragment => { - let fs_info = match &s.info.io { + ShaderStageInfo::Fragment(fs_info) => { + let fs_io_info = match &s.info.io { ShaderIoInfo::Fragment(io) => io, _ => unreachable!(), }; - - let nir_fs_info = unsafe { &nir.info.__bindgen_anon_1.fs }; nak_shader_info__bindgen_ty_1 { fs: nak_shader_info__bindgen_ty_1__bindgen_ty_2 { - writes_depth: fs_info.writes_depth, - reads_sample_mask: fs_info.reads_sample_mask, - post_depth_coverage: nir_fs_info.post_depth_coverage(), - uses_sample_shading: nir_fs_info.uses_sample_shading(), - early_fragment_tests: nir_fs_info - .early_fragment_tests(), + writes_depth: fs_io_info.writes_depth, + reads_sample_mask: fs_io_info.reads_sample_mask, + post_depth_coverage: fs_info.post_depth_coverage, + uses_sample_shading: fs_info.uses_sample_shading, + early_fragment_tests: fs_info.early_fragment_tests, _pad: Default::default(), }, } diff --git a/src/nouveau/compiler/nak/from_nir.rs b/src/nouveau/compiler/nak/from_nir.rs index ce48394757b..6be4ce75b07 100644 --- a/src/nouveau/compiler/nak/from_nir.rs +++ b/src/nouveau/compiler/nak/from_nir.rs @@ -40,7 +40,16 @@ fn init_info_from_nir(nir: &nir_shader) -> ShaderInfo { }) } MESA_SHADER_VERTEX => ShaderStageInfo::Vertex, - MESA_SHADER_FRAGMENT => ShaderStageInfo::Fragment, + MESA_SHADER_FRAGMENT => { + let info_fs = unsafe { &nir.info.__bindgen_anon_1.fs }; + ShaderStageInfo::Fragment(FragmentShaderInfo { + uses_kill: false, + does_interlock: false, + post_depth_coverage: info_fs.post_depth_coverage(), + early_fragment_tests: info_fs.early_fragment_tests(), + uses_sample_shading: info_fs.uses_sample_shading(), + }) + } MESA_SHADER_GEOMETRY => { let info_gs = unsafe { &nir.info.__bindgen_anon_1.gs }; let output_topology = match info_gs.output_primitive { @@ -117,12 +126,9 @@ fn init_info_from_nir(nir: &nir_shader) -> ShaderInfo { attr_in: [PixelImap::Unused; 128], barycentric_attr_in: [0; 4], reads_sample_mask: false, - uses_kill: false, writes_color: 0, writes_sample_mask: false, writes_depth: false, - // TODO: Should be set if interlocks are in use. (VK_EXT_fragment_shader_interlock) - does_interlock: false, }), MESA_SHADER_VERTEX | MESA_SHADER_GEOMETRY @@ -2347,7 +2353,7 @@ impl<'a> ShaderFromNir<'a> { b.push_op(OpFSOut { srcs: srcs }); } nir_intrinsic_demote => { - if let ShaderIoInfo::Fragment(info) = &mut self.info.io { + if let ShaderStageInfo::Fragment(info) = &mut self.info.stage { info.uses_kill = true; } else { panic!("OpKill is only available in fragment shaders"); @@ -2355,7 +2361,7 @@ impl<'a> ShaderFromNir<'a> { b.push_op(OpKill {}); } nir_intrinsic_demote_if => { - if let ShaderIoInfo::Fragment(info) = &mut self.info.io { + if let ShaderStageInfo::Fragment(info) = &mut self.info.stage { info.uses_kill = true; } else { panic!("OpKill is only available in fragment shaders"); diff --git a/src/nouveau/compiler/nak/ir.rs b/src/nouveau/compiler/nak/ir.rs index 3035454f4d2..3d48ba47c89 100644 --- a/src/nouveau/compiler/nak/ir.rs +++ b/src/nouveau/compiler/nak/ir.rs @@ -6242,6 +6242,15 @@ pub struct ComputeShaderInfo { pub smem_size: u16, } +#[derive(Debug)] +pub struct FragmentShaderInfo { + pub uses_kill: bool, + pub does_interlock: bool, + pub post_depth_coverage: bool, + pub early_fragment_tests: bool, + pub uses_sample_shading: bool, +} + #[derive(Debug)] pub struct GeometryShaderInfo { pub passthrough_enable: bool, @@ -6305,7 +6314,7 @@ pub struct TessellationShaderInfo { pub enum ShaderStageInfo { Compute(ComputeShaderInfo), Vertex, - Fragment, + Fragment(FragmentShaderInfo), Geometry(GeometryShaderInfo), TessellationInit(TessellationInitShaderInfo), Tessellation(TessellationShaderInfo), @@ -6391,11 +6400,9 @@ pub struct FragmentIoInfo { pub barycentric_attr_in: [u32; 4], pub reads_sample_mask: bool, - pub uses_kill: bool, pub writes_color: u32, pub writes_sample_mask: bool, pub writes_depth: bool, - pub does_interlock: bool, } impl FragmentIoInfo { diff --git a/src/nouveau/compiler/nak/sph.rs b/src/nouveau/compiler/nak/sph.rs index 28b166a52a5..ea4a59d63c1 100644 --- a/src/nouveau/compiler/nak/sph.rs +++ b/src/nouveau/compiler/nak/sph.rs @@ -32,7 +32,7 @@ impl From<&ShaderStageInfo> for ShaderType { fn from(value: &ShaderStageInfo) -> Self { match value { ShaderStageInfo::Vertex => ShaderType::Vertex, - ShaderStageInfo::Fragment => ShaderType::Fragment, + ShaderStageInfo::Fragment(_) => ShaderType::Fragment, ShaderStageInfo::Geometry(_) => ShaderType::Geometry, ShaderStageInfo::TessellationInit(_) => { ShaderType::TessellationInit @@ -514,7 +514,6 @@ pub fn encode_header( sph.set_imap_vector_ps(index, *imap); } - let zs_self_dep = fs_key.map_or(false, |key| key.zs_self_dep); let uses_underestimate = fs_key.map_or(false, |key| key.uses_underestimate); @@ -526,11 +525,9 @@ pub fn encode_header( // explicit fragment output locations. sph.set_multiple_render_target_enable(true); - sph.set_kills_pixels(io.uses_kill || zs_self_dep); sph.set_omap_sample_mask(io.writes_sample_mask); sph.set_omap_depth(io.writes_depth); sph.set_omap_targets(io.writes_color); - sph.set_does_interlock(io.does_interlock); sph.set_uses_underestimate(uses_underestimate); for (index, value) in io.barycentric_attr_in.iter().enumerate() { @@ -541,6 +538,11 @@ pub fn encode_header( } match &shader_info.stage { + ShaderStageInfo::Fragment(stage) => { + let zs_self_dep = fs_key.map_or(false, |key| key.zs_self_dep); + sph.set_kills_pixels(stage.uses_kill || zs_self_dep); + sph.set_does_interlock(stage.does_interlock); + } ShaderStageInfo::Geometry(stage) => { sph.set_gs_passthrough_enable(stage.passthrough_enable); sph.set_stream_out_mask(stage.stream_out_mask);