mirror of
https://github.com/bevyengine/bevy
synced 2024-11-24 21:53:07 +00:00
bevy_render2: Support nested shader defs (#3113)
# Objective Fix nested shader defs. For example, in: ```rust #ifdef A #ifdef B some code here #endif #endif ``` ...before this PR, if `A` *is not* defined, and `B` *is* defined, then `some code here` will be output. ## Solution - Combine the logic of whether the parent and child scope guards are defined and use that as the resulting child scope guard boolean value
This commit is contained in:
parent
213839f503
commit
14ce281904
1 changed files with 181 additions and 2 deletions
|
@ -268,10 +268,10 @@ impl ShaderProcessor {
|
|||
for line in shader.split('\n') {
|
||||
if let Some(cap) = self.ifdef_regex.captures(line) {
|
||||
let def = cap.get(1).unwrap();
|
||||
scopes.push(shader_defs.contains(def.as_str()));
|
||||
scopes.push(*scopes.last().unwrap() && shader_defs.contains(def.as_str()));
|
||||
} else if let Some(cap) = self.ifndef_regex.captures(line) {
|
||||
let def = cap.get(1).unwrap();
|
||||
scopes.push(!shader_defs.contains(def.as_str()));
|
||||
scopes.push(*scopes.last().unwrap() && !shader_defs.contains(def.as_str()));
|
||||
} else if self.endif_regex.is_match(line) {
|
||||
scopes.pop();
|
||||
if scopes.is_empty() {
|
||||
|
@ -315,6 +315,38 @@ struct VertexOutput {
|
|||
[[builtin(position)]] position: vec4<f32>;
|
||||
};
|
||||
|
||||
[[stage(vertex)]]
|
||||
fn vertex(
|
||||
[[location(0)]] vertex_position: vec3<f32>,
|
||||
[[location(1)]] vertex_uv: vec2<f32>
|
||||
) -> VertexOutput {
|
||||
var out: VertexOutput;
|
||||
out.uv = vertex_uv;
|
||||
out.position = view.view_proj * vec4<f32>(vertex_position, 1.0);
|
||||
return out;
|
||||
}
|
||||
";
|
||||
const WGSL_NESTED_IFDEF: &str = r"
|
||||
[[block]]
|
||||
struct View {
|
||||
view_proj: mat4x4<f32>;
|
||||
world_position: vec3<f32>;
|
||||
};
|
||||
[[group(0), binding(0)]]
|
||||
var<uniform> view: View;
|
||||
|
||||
# ifdef TEXTURE
|
||||
# ifdef ATTRIBUTE
|
||||
[[group(1), binding(0)]]
|
||||
var sprite_texture: texture_2d<f32>;
|
||||
# endif
|
||||
# endif
|
||||
|
||||
struct VertexOutput {
|
||||
[[location(0)]] uv: vec2<f32>;
|
||||
[[builtin(position)]] position: vec4<f32>;
|
||||
};
|
||||
|
||||
[[stage(vertex)]]
|
||||
fn vertex(
|
||||
[[location(0)]] vertex_position: vec3<f32>,
|
||||
|
@ -432,4 +464,151 @@ fn foo() { }
|
|||
let result = processor.process_str(INPUT, &[]).unwrap();
|
||||
assert_eq!(result, INPUT);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn process_nested_shader_def_outer_defined_inner_not() {
|
||||
#[rustfmt::skip]
|
||||
const EXPECTED: &str = r"
|
||||
[[block]]
|
||||
struct View {
|
||||
view_proj: mat4x4<f32>;
|
||||
world_position: vec3<f32>;
|
||||
};
|
||||
[[group(0), binding(0)]]
|
||||
var<uniform> view: View;
|
||||
|
||||
|
||||
struct VertexOutput {
|
||||
[[location(0)]] uv: vec2<f32>;
|
||||
[[builtin(position)]] position: vec4<f32>;
|
||||
};
|
||||
|
||||
[[stage(vertex)]]
|
||||
fn vertex(
|
||||
[[location(0)]] vertex_position: vec3<f32>,
|
||||
[[location(1)]] vertex_uv: vec2<f32>
|
||||
) -> VertexOutput {
|
||||
var out: VertexOutput;
|
||||
out.uv = vertex_uv;
|
||||
out.position = view.view_proj * vec4<f32>(vertex_position, 1.0);
|
||||
return out;
|
||||
}
|
||||
";
|
||||
let processor = ShaderProcessor::default();
|
||||
let result = processor
|
||||
.process_str(WGSL_NESTED_IFDEF, &["TEXTURE".to_string()])
|
||||
.unwrap();
|
||||
assert_eq!(result, EXPECTED);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn process_nested_shader_def_neither_defined() {
|
||||
#[rustfmt::skip]
|
||||
const EXPECTED: &str = r"
|
||||
[[block]]
|
||||
struct View {
|
||||
view_proj: mat4x4<f32>;
|
||||
world_position: vec3<f32>;
|
||||
};
|
||||
[[group(0), binding(0)]]
|
||||
var<uniform> view: View;
|
||||
|
||||
|
||||
struct VertexOutput {
|
||||
[[location(0)]] uv: vec2<f32>;
|
||||
[[builtin(position)]] position: vec4<f32>;
|
||||
};
|
||||
|
||||
[[stage(vertex)]]
|
||||
fn vertex(
|
||||
[[location(0)]] vertex_position: vec3<f32>,
|
||||
[[location(1)]] vertex_uv: vec2<f32>
|
||||
) -> VertexOutput {
|
||||
var out: VertexOutput;
|
||||
out.uv = vertex_uv;
|
||||
out.position = view.view_proj * vec4<f32>(vertex_position, 1.0);
|
||||
return out;
|
||||
}
|
||||
";
|
||||
let processor = ShaderProcessor::default();
|
||||
let result = processor.process_str(WGSL_NESTED_IFDEF, &[]).unwrap();
|
||||
assert_eq!(result, EXPECTED);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn process_nested_shader_def_inner_defined_outer_not() {
|
||||
#[rustfmt::skip]
|
||||
const EXPECTED: &str = r"
|
||||
[[block]]
|
||||
struct View {
|
||||
view_proj: mat4x4<f32>;
|
||||
world_position: vec3<f32>;
|
||||
};
|
||||
[[group(0), binding(0)]]
|
||||
var<uniform> view: View;
|
||||
|
||||
|
||||
struct VertexOutput {
|
||||
[[location(0)]] uv: vec2<f32>;
|
||||
[[builtin(position)]] position: vec4<f32>;
|
||||
};
|
||||
|
||||
[[stage(vertex)]]
|
||||
fn vertex(
|
||||
[[location(0)]] vertex_position: vec3<f32>,
|
||||
[[location(1)]] vertex_uv: vec2<f32>
|
||||
) -> VertexOutput {
|
||||
var out: VertexOutput;
|
||||
out.uv = vertex_uv;
|
||||
out.position = view.view_proj * vec4<f32>(vertex_position, 1.0);
|
||||
return out;
|
||||
}
|
||||
";
|
||||
let processor = ShaderProcessor::default();
|
||||
let result = processor
|
||||
.process_str(WGSL_NESTED_IFDEF, &["ATTRIBUTE".to_string()])
|
||||
.unwrap();
|
||||
assert_eq!(result, EXPECTED);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn process_nested_shader_def_both_defined() {
|
||||
#[rustfmt::skip]
|
||||
const EXPECTED: &str = r"
|
||||
[[block]]
|
||||
struct View {
|
||||
view_proj: mat4x4<f32>;
|
||||
world_position: vec3<f32>;
|
||||
};
|
||||
[[group(0), binding(0)]]
|
||||
var<uniform> view: View;
|
||||
|
||||
[[group(1), binding(0)]]
|
||||
var sprite_texture: texture_2d<f32>;
|
||||
|
||||
struct VertexOutput {
|
||||
[[location(0)]] uv: vec2<f32>;
|
||||
[[builtin(position)]] position: vec4<f32>;
|
||||
};
|
||||
|
||||
[[stage(vertex)]]
|
||||
fn vertex(
|
||||
[[location(0)]] vertex_position: vec3<f32>,
|
||||
[[location(1)]] vertex_uv: vec2<f32>
|
||||
) -> VertexOutput {
|
||||
var out: VertexOutput;
|
||||
out.uv = vertex_uv;
|
||||
out.position = view.view_proj * vec4<f32>(vertex_position, 1.0);
|
||||
return out;
|
||||
}
|
||||
";
|
||||
let processor = ShaderProcessor::default();
|
||||
let result = processor
|
||||
.process_str(
|
||||
WGSL_NESTED_IFDEF,
|
||||
&["TEXTURE".to_string(), "ATTRIBUTE".to_string()],
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(result, EXPECTED);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue