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:
@@ -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(),
|
||||
},
|
||||
}
|
||||
|
@@ -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");
|
||||
|
@@ -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 {
|
||||
|
@@ -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);
|
||||
|
Reference in New Issue
Block a user