nak: Rework fragment shader stage info

This adds a FragmentShaderStageInfo, moves uses_kill and does_interlock
there, and adds fields for API depth test bits.

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/30283>
This commit is contained in:
Faith Ekstrand
2024-07-18 23:25:39 -05:00
parent d96fe18547
commit f39b645c66
4 changed files with 35 additions and 23 deletions

View File

@@ -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(),
},
}

View File

@@ -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");

View File

@@ -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 {

View File

@@ -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);