mirror of
https://github.com/gfx-rs/wgpu.git
synced 2026-04-22 03:02:01 -04:00
[glsl-in] Keep around extra linkage variables
WGSL will require this. Note that this still might cause some issues with multi-entry-point GLSL that I didn't know how to handle. That is, we will handle unused builtin inputs but not unused builtin outputs correctly right now. This is an existing issue though, not a regression. This is also provided as an option, but I feel like the more correct approach is to never strip linkage variables. We'll see though.
This commit is contained in:
committed by
Dzmitry Malyshau
parent
0b69aa8b8a
commit
0995c7161e
@@ -166,6 +166,7 @@ fn main() {
|
||||
&naga::front::glsl::Options {
|
||||
entry_points,
|
||||
defines: Default::default(),
|
||||
strip_unused_linkages: false,
|
||||
},
|
||||
)
|
||||
.unwrap_or_else(|err| {
|
||||
@@ -183,6 +184,7 @@ fn main() {
|
||||
&naga::front::glsl::Options {
|
||||
entry_points,
|
||||
defines: Default::default(),
|
||||
strip_unused_linkages: false,
|
||||
},
|
||||
)
|
||||
.unwrap_or_else(|err| {
|
||||
@@ -200,6 +202,7 @@ fn main() {
|
||||
&naga::front::glsl::Options {
|
||||
entry_points,
|
||||
defines: Default::default(),
|
||||
strip_unused_linkages: false,
|
||||
},
|
||||
)
|
||||
.unwrap_or_else(|err| {
|
||||
|
||||
@@ -69,6 +69,7 @@ pub struct EntryArg {
|
||||
pub binding: Binding,
|
||||
pub handle: Handle<GlobalVariable>,
|
||||
pub prologue: PrologueStage,
|
||||
pub storage: StorageQualifier,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
@@ -76,6 +77,7 @@ pub struct Program<'a> {
|
||||
pub version: u16,
|
||||
pub profile: Profile,
|
||||
pub entry_points: &'a FastHashMap<String, ShaderStage>,
|
||||
pub strip_unused_linkages: bool,
|
||||
|
||||
pub workgroup_size: [u32; 3],
|
||||
pub early_fragment_tests: bool,
|
||||
@@ -94,11 +96,12 @@ pub struct Program<'a> {
|
||||
}
|
||||
|
||||
impl<'a> Program<'a> {
|
||||
pub fn new(entry_points: &'a FastHashMap<String, ShaderStage>) -> Program<'a> {
|
||||
pub fn new(entry_points: &'a FastHashMap<String, ShaderStage>, strip_unused_linkages: bool) -> Program<'a> {
|
||||
Program {
|
||||
version: 0,
|
||||
profile: Profile::Core,
|
||||
entry_points,
|
||||
strip_unused_linkages,
|
||||
|
||||
workgroup_size: [1; 3],
|
||||
early_fragment_tests: false,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use crate::{
|
||||
proc::ensure_block_returns, Arena, BinaryOperator, Block, Constant, ConstantInner, EntryPoint,
|
||||
Expression, Function, FunctionArgument, FunctionResult, Handle, ImageQuery, LocalVariable,
|
||||
MathFunction, RelationalFunction, SampleLevel, ScalarKind, ScalarValue, Statement,
|
||||
MathFunction, RelationalFunction, SampleLevel, ScalarKind, ScalarValue, ShaderStage, Statement,
|
||||
StructMember, SwizzleComponent, Type, TypeInner, VectorSize,
|
||||
};
|
||||
|
||||
@@ -1159,12 +1159,23 @@ impl Program<'_> {
|
||||
let mut expressions = Arena::new();
|
||||
let mut body = Vec::new();
|
||||
|
||||
let can_strip_stage_inputs = self.strip_unused_linkages || stage != ShaderStage::Fragment;
|
||||
let can_strip_stage_outputs = self.strip_unused_linkages || stage != ShaderStage::Vertex;
|
||||
|
||||
for (i, arg) in self.entry_args.iter().enumerate() {
|
||||
if function_arg_use[function.index()]
|
||||
if arg.storage != StorageQualifier::Input {
|
||||
continue;
|
||||
}
|
||||
|
||||
if !arg.prologue.contains(stage.into()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let is_used = function_arg_use[function.index()]
|
||||
.get(i)
|
||||
.map_or(true, |u| !u.contains(EntryArgUse::READ))
|
||||
|| !arg.prologue.contains(stage.into())
|
||||
{
|
||||
.map_or(false, |u| u.contains(EntryArgUse::READ));
|
||||
|
||||
if can_strip_stage_inputs && !is_used {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1194,10 +1205,15 @@ impl Program<'_> {
|
||||
let mut components = Vec::new();
|
||||
|
||||
for (i, arg) in self.entry_args.iter().enumerate() {
|
||||
if function_arg_use[function.index()]
|
||||
if arg.storage != StorageQualifier::Output {
|
||||
continue;
|
||||
}
|
||||
|
||||
let is_used = function_arg_use[function.index()]
|
||||
.get(i)
|
||||
.map_or(true, |u| !u.contains(EntryArgUse::WRITE))
|
||||
{
|
||||
.map_or(false, |u| u.contains(EntryArgUse::WRITE));
|
||||
|
||||
if can_strip_stage_outputs && !is_used {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -23,10 +23,11 @@ mod variables;
|
||||
pub struct Options {
|
||||
pub entry_points: FastHashMap<String, ShaderStage>,
|
||||
pub defines: FastHashMap<String, String>,
|
||||
pub strip_unused_linkages: bool,
|
||||
}
|
||||
|
||||
pub fn parse_str(source: &str, options: &Options) -> Result<Module, ParseError> {
|
||||
let mut program = Program::new(&options.entry_points);
|
||||
let mut program = Program::new(&options.entry_points, options.strip_unused_linkages);
|
||||
|
||||
let lex = lex::Lexer::new(source, &options.defines);
|
||||
let mut parser = parser::Parser::new(&mut program, lex);
|
||||
|
||||
@@ -14,7 +14,7 @@ fn parse_program<'a>(
|
||||
source: &str,
|
||||
entry_points: &'a crate::FastHashMap<String, ShaderStage>,
|
||||
) -> Result<Program<'a>, ErrorKind> {
|
||||
let mut program = Program::new(entry_points);
|
||||
let mut program = Program::new(entry_points, true);
|
||||
let defines = crate::FastHashMap::default();
|
||||
let lex = Lexer::new(source, &defines);
|
||||
let mut parser = parser::Parser::new(&mut program, lex);
|
||||
|
||||
@@ -45,7 +45,7 @@ impl Program<'_> {
|
||||
return Ok(Some(global_var));
|
||||
}
|
||||
|
||||
let mut add_builtin = |inner, builtin, mutable, prologue| {
|
||||
let mut add_builtin = |inner, builtin, mutable, prologue, storage| {
|
||||
let ty = self
|
||||
.module
|
||||
.types
|
||||
@@ -66,6 +66,7 @@ impl Program<'_> {
|
||||
binding: Binding::BuiltIn(builtin),
|
||||
handle,
|
||||
prologue,
|
||||
storage,
|
||||
});
|
||||
|
||||
self.global_variables.push((
|
||||
@@ -101,6 +102,7 @@ impl Program<'_> {
|
||||
BuiltIn::Position,
|
||||
true,
|
||||
PrologueStage::empty(),
|
||||
StorageQualifier::Output,
|
||||
),
|
||||
"gl_FragCoord" => add_builtin(
|
||||
TypeInner::Vector {
|
||||
@@ -111,6 +113,7 @@ impl Program<'_> {
|
||||
BuiltIn::Position,
|
||||
false,
|
||||
PrologueStage::FRAGMENT,
|
||||
StorageQualifier::Input,
|
||||
),
|
||||
"gl_FragDepth" => add_builtin(
|
||||
TypeInner::Scalar {
|
||||
@@ -120,6 +123,7 @@ impl Program<'_> {
|
||||
BuiltIn::FragDepth,
|
||||
true,
|
||||
PrologueStage::empty(),
|
||||
StorageQualifier::Output,
|
||||
),
|
||||
"gl_VertexIndex" => add_builtin(
|
||||
TypeInner::Scalar {
|
||||
@@ -129,6 +133,7 @@ impl Program<'_> {
|
||||
BuiltIn::VertexIndex,
|
||||
false,
|
||||
PrologueStage::VERTEX,
|
||||
StorageQualifier::Input,
|
||||
),
|
||||
"gl_InstanceIndex" => add_builtin(
|
||||
TypeInner::Scalar {
|
||||
@@ -138,6 +143,7 @@ impl Program<'_> {
|
||||
BuiltIn::InstanceIndex,
|
||||
false,
|
||||
PrologueStage::VERTEX,
|
||||
StorageQualifier::Input,
|
||||
),
|
||||
"gl_GlobalInvocationID" => add_builtin(
|
||||
TypeInner::Vector {
|
||||
@@ -148,6 +154,7 @@ impl Program<'_> {
|
||||
BuiltIn::GlobalInvocationId,
|
||||
false,
|
||||
PrologueStage::COMPUTE,
|
||||
StorageQualifier::Input,
|
||||
),
|
||||
"gl_FrontFacing" => add_builtin(
|
||||
TypeInner::Scalar {
|
||||
@@ -157,6 +164,7 @@ impl Program<'_> {
|
||||
BuiltIn::FrontFacing,
|
||||
false,
|
||||
PrologueStage::FRAGMENT,
|
||||
StorageQualifier::Input,
|
||||
),
|
||||
_ => Ok(None),
|
||||
}
|
||||
@@ -440,6 +448,7 @@ impl Program<'_> {
|
||||
},
|
||||
handle,
|
||||
prologue,
|
||||
storage,
|
||||
});
|
||||
|
||||
if let Some(name) = name {
|
||||
|
||||
@@ -7,7 +7,7 @@ struct FragmentOutput {
|
||||
[[location(0)]] o_Target: vec4<f32>;
|
||||
};
|
||||
|
||||
var<private> v_Uv: vec2<f32>;
|
||||
var<private> v_Uv1: vec2<f32>;
|
||||
var<private> o_Target: vec4<f32>;
|
||||
[[group(1), binding(0)]]
|
||||
var<uniform> global: ColorMaterial_color;
|
||||
@@ -23,8 +23,9 @@ fn main1() {
|
||||
}
|
||||
|
||||
[[stage(fragment)]]
|
||||
fn main() -> FragmentOutput {
|
||||
fn main([[location(0)]] v_Uv: vec2<f32>) -> FragmentOutput {
|
||||
v_Uv1 = v_Uv;
|
||||
main1();
|
||||
let _e1: vec4<f32> = o_Target;
|
||||
return FragmentOutput(_e1);
|
||||
let _e3: vec4<f32> = o_Target;
|
||||
return FragmentOutput(_e3);
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ struct FragmentOutput {
|
||||
[[location(0)]] o_color: vec4<f32>;
|
||||
};
|
||||
|
||||
var<private> v_uv: vec2<f32>;
|
||||
var<private> v_uv1: vec2<f32>;
|
||||
var<private> o_color: vec4<f32>;
|
||||
|
||||
fn main1() {
|
||||
@@ -11,8 +11,9 @@ fn main1() {
|
||||
}
|
||||
|
||||
[[stage(fragment)]]
|
||||
fn main() -> FragmentOutput {
|
||||
fn main([[location(0)]] v_uv: vec2<f32>) -> FragmentOutput {
|
||||
v_uv1 = v_uv;
|
||||
main1();
|
||||
let _e1: vec4<f32> = o_color;
|
||||
return FragmentOutput(_e1);
|
||||
let _e3: vec4<f32> = o_color;
|
||||
return FragmentOutput(_e3);
|
||||
}
|
||||
|
||||
@@ -457,6 +457,7 @@ fn convert_glsl_folder() {
|
||||
for entry in std::fs::read_dir(format!("{}/{}/glsl", root, BASE_DIR_IN)).unwrap() {
|
||||
let entry = entry.unwrap();
|
||||
let file_name = entry.file_name().into_string().unwrap();
|
||||
|
||||
if file_name.ends_with(".ron") {
|
||||
// No needed to validate ron files
|
||||
continue;
|
||||
@@ -498,11 +499,13 @@ fn convert_glsl_folder() {
|
||||
entry_points.insert("main".to_string(), stage);
|
||||
}
|
||||
|
||||
let strip_unused_linkages = entry_points.len() > 1;
|
||||
let module = naga::front::glsl::parse_str(
|
||||
&fs::read_to_string(entry.path()).expect("Couldn't find glsl file"),
|
||||
&naga::front::glsl::Options {
|
||||
entry_points,
|
||||
defines: Default::default(),
|
||||
strip_unused_linkages: strip_unused_linkages,
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
Reference in New Issue
Block a user