Open MaikKlein opened 6 years ago
A more complex example
Interestingly a very simple branch doesn't work.
#[spirv(fragment)]
fn color_frag(
frag: Fragment,
uv: Input<N0, Vec2<f32>>,
time: Descriptor<N2, N0, f32>,
) -> Output<N0, Vec4<f32>> {
let uv = uv.data;
let mut color = Vec3::new(1.0, 1.0, 0.0);
if uv.x > 0.5 {
color.x = 0.5;
}
Output::new(color.extend(1.0))
}
It crashes in Vulkan. Adding the else branch fixes it.
#[spirv(fragment)]
fn color_frag(
frag: Fragment,
uv: Input<N0, Vec2<f32>>,
time: Descriptor<N2, N0, f32>,
) -> Output<N0, Vec4<f32>> {
let uv = uv.data;
let mut color = Vec3::new(1.0, 1.0, 0.0);
if uv.x > 0.5 {
color.x = 0.5;
}
} else {
color.x = 0.5;
}
Output::new(color.extend(1.0))
}
I am not yet sure which rule I am violating.
After some testing it seems the problem is the OpSwitch
instruction. Switching to OpBranchConditional
fixes the problem. This might be a driver problem.
The current implementation seems to break for the ?
operator on options. It produces where weird looking cfgs
It seems rlsl doesn't correctly handle unwind and resume.
This results in the following CFG
Three branches which all converge into
bb7
. The dashed lines here are the merge blocks. While 30 is the "correct" merge block, in spir-v all merge blocks have to be unique.To address this issue we need to generate new blocks for:
And the new control flow node should be