render: Implement PixelBender 'Step' opcode
This change implements the 'Step' opcode in the PixelBender shader infrastructure.
The 'Step' opcode behaves like the GLSL step(edge, x) function, returning 0.0 if x < edge and 1.0 if x >= edge, component-wise for vectors.
The implementation includes:
- Parsing logic for the 'Step' opcode in
render/src/pixel_bender.rs. - Naga IR generation for the 'Step' opcode in
render/naga-pixelbender/src/lib.rs. - A new test case
step_opcode_testthat defines a shader using the 'Step' opcode and verifies its compilation to Naga IR.
This addresses the issue of "Unimplemented opcode Step" when encountering shaders that utilize this instruction.
I am not sure how you feel about AI-coded improvements to the codebase. I used Google Jules to implement the missing "step" opcode and it does fix the problem allowing me to run an old PixelBender swf that did not work so far.
me to run an old PixelBender swf that did not work so far.
Can you please share that swf? There's an actual step function we can emit, rather than trying to reimplement the behaviour from scratch - but a swf to test with would be extremely valuable.
We have some issues for the missing Step opcode: https://github.com/ruffle-rs/ruffle/issues?q=is%3Aissue%20state%3Aopen%20%22unimplemented%20opcode%20Step%22
I did implement Step for one of these (I think it was https://github.com/ruffle-rs/ruffle/issues/14068) in the past, with something like (reproduced from memory):
Opcode::Step => {
let right = self.load_src_register(&dst)?;
self.evaluate_expr(Expression::Math {
fun: MathFunction::Step,
arg: src,
arg1: Some(right),
arg2: None,
arg3: None,
})
}
But it didn't render correctly and I didn't know whether that meant the implementation was wrong in some way or there was a completely unrelated bug somewhere else; so I never made a PR. I'm also curious as to what SWF the PR author is talking about, I'm very interested to test my old snippet on other SWFs.
As for this PR, unless there's a reason why plain MathFunction::Step wasn't used, unfortunately I don't think this code is usable. Especially the change in render/src/pixel_bender.rs makes no sense, as it doesn't seem any different from the catch-all case.
As for this PR, unless there's a reason why plain
MathFunction::Stepwasn't used, unfortunately I don't think this code is usable. Especially the change inrender/src/pixel_bender.rsmakes no sense, as it doesn't seem any different from the catch-all case.
I am not sure why one would use MathFunction inside of a shader, but then again I haven't looked into the inner workings of it - my implementation follows the principles that the implementations of other PixelBender opcodes use and none of those uses MathFunction, so I assume there is a reason for it. I also do not understand the question why a PixelBender opcode is added to the pixel_bender.rs code - it is where all the other opcode implementations are so it seems like the logical place to put it.
Lastly - if there is a catch-all it does not work as intended since when trying to run an swf that contains the step opcode inside of a PixelBender shader a panic is triggered.
All I can say is that my swf did not work before and it does work with the fix.
Again, can you please send us the SWF you're talking about? (if you can't share it, that's okay, just let us know)
Meanwhile, I merged https://github.com/ruffle-rs/ruffle/pull/20640 , so this generated PR isn't needed anymore. If you can check if your SWF now works with upstream Ruffle, that'd be great; if it doesn't, let us know and we'll look at it some more.