¶A shader compiler for VirtualDub, part 3
Okay, back to something VirtualDub related. :)
I went ahead and did some more work on the vdshader filter, and thus I present version 1.2:
http://www.virtualdub.org/downloads/vdshader-1.2.zip
http://www.virtualdub.org/downloads/vdshader-1.2-src.zip
This version has two major enhancements:
- The compiler now understands annotations, and I ported over the UI code from my GPU filter, so you can now add tunable parameters to your .fx file and the filter will automatically create UI for it.
- The filter now scans for an FXFilters subdirectory on startup and creates new video filter entries for each .fx file that it finds.
The combined effect of these two changes is that you can now make new VirtualDub filters entirely in vdshader, without writing any C++ code. The individual .fx files show up in the VirtualDub filter list, have their own config dialog, work in batch mode, and can be used just like any other VirtualDub filter written as a regular DLL.
Now, the performance of such a video filter won't be quite as good as a well-optimized C++/asm filter, but I've made some changes on that front, as well. First, vdshader now has an SSE2 JIT which transforms shaders into SoA form and does register allocations, thus running shaders much faster than the scalar x87 JIT. Second, the optimizer has been beefed up substantially and performs more optimizations, such as:
- constant folding
- unused interpolator elimination
- loop invariant hoisting
As an example, in the expression tex2D(src, float2(uv.x, pos*4-1)), the optimizer will identify that (pos*4-1) is an invariant, and hoist both it and the texture V axis clamp/wrap checks out of the loop. These optimizations are particularly useful for tunable parameters, where you can perform complex preconditioning on the parameters and the optimizer will ensure that the calculations are done only once before entering the pixel loop.
There are several other improvements:
- Several bugs in the text editor have been fixed and the syntax highlighting has been expanded.
- Sampler states are now supported, so you can switch between point/bilinear filtering and wrapping or clamping on each axis. The default is bilinear for compatibility reasons, but point is faster.
- The compiler now understands many more intrinsics, including asin(), acos(), atan(), reflect(), saturate(). Several of the existing intrinsics have also been expanded to support vectors.
- The shader IL now supports the _sat prefix for saturation to 0-1. I think that's the last PS2.0 feature that was missing, and in theory the engine should now be able to support hoisting D3D PS2.0 bytecode to vdshader IL.
- Constant registers c0 and c1 are now auto-bound to float4(width, height, counter, clock) and float4(1/width, 1/height, 0, 0) if they are not otherwise used, and sampler s0 is similarly auto-bound to the source.
- A rudimentary preprocessor has been added that understands parameterless #defines.
- VDShader can now run all of the stock Media Player Classic pixel shaders without modification.
Example of a custom shader after the jump.
We'll use this file as an example:
// Name: RGB Scale
// Author: Avery Lee
// Description: Scales individual RGB channels.float red <
bool vd_tunable = true;
float vd_tunablemin = 0;
float vd_tunablemax = 2;
float vd_tunablesteps = 200;
> = 1;float green <
bool vd_tunable = true;
float vd_tunablemin = 0;
float vd_tunablemax = 2;
float vd_tunablesteps = 200;
> = 1;float blue <
bool vd_tunable = true;
float vd_tunablemin = 0;
float vd_tunablemax = 2;
float vd_tunablesteps = 200;
> = 1;extern sampler src : register(s0);float4 main(float2 uv : TEXCOORD0) : COLOR0 {
return tex2D(src, uv) * float4(red, green, blue, 0);
}
With vdshader.vdf in the plugins or plugins32 subdirectory under VirtualDub.exe, and with this file saved as FXFilters\test.fx underneath that, this filter will then show up in the filter list:
Add this filter to the list and hit Configure, and vdshader automatically creates a configuration dialog based on the tunable parameters:
The configuration dialog exposes each tunable float parameter as a slider, and supports live preview functionality as well. (As I write this, I notice that I forgot to add code to change the dialog caption from "Dialog." Whoops.)
And finally, choosing the base vdshader filter brings up the IDE as usual, where you can interactively edit shader .fx files.