haasn / libplacebo

Official mirror of libplacebo
http://libplacebo.org/
GNU Lesser General Public License v2.1
547 stars 69 forks source link

Preferred type for user shader parameters ? #189

Closed butterw closed 1 year ago

butterw commented 1 year ago

I have a typical user shader which takes a single float parameter (the strength of the effect): https://github.com/butterw/bShaders/blob/master/mpv/vibrance_next.hk

I'm using mpv and --gpu-shader-cache is enabled. Could you clarify when does vo_gpu_next/libplacebo recompile shaders and the preferred TYPE to use in the shader PARAM bloc to avoid unecessary recompilations.

For this shader typically only two values are used 0.35 and -0.15, though over values can be selected.
//!PARAM vibr //!DESC Saturates/deSaturates //!TYPE CONSTANT float //!MINIMUM -1 0.35

haasn commented 1 year ago

http://libplacebo.org/custom-shaders/#type-define-dynamic-constant-type

The optional qualifiers DYNAMIC or CONSTANT mark the parameter as dynamically changing and compile-time constant, respectively. A DYNAMIC variable is assumed to change frequently, and will be grouped with other frequently-changing input parameters. A CONSTANT parameter will be introduced as a compile-time constant into the shader header, which means thy can be used in e.g. constant expressions such as array sizes.3

I would recommend to just leave it as default, i.e. //!TYPE float.

butterw commented 1 year ago

OK, thanks.

Based on what you wrote in https://github.com/mpv-player/mpv/pull/10827 (paraphrased below) A) I understand that TYPE float never triggers recompilation. B) I would further assume modifying a TYPE DEFINE parameter value always forces recompilation. C) With a TYPE CONSTANT parameters are multiple versions of the compiled shader cached or D) does a new parameter value simply overwrite the previous compiled shader ?

TYPE is a normal variable (int, uint, float). These will never trigger recompilation when changed, but may be offloaded to a UBO to save on registers. TYPE DYNAMIC is like a normal variable but marked as dynamic (expected to change frequently). TYPE CONSTANT refers to a compile-time constant. They trigger recompilation when changed. But, they can be used to size arrays. TYPE DEFINE (no extra type argument) refers to a preprocessor variable, which will be available inside #if expressions.

haasn commented 1 year ago

B) Unless the shader is already cached. With TYPE DEFINE, every 'variant' is its own shader, and may coexist in the shader cache. C+D) On Vulkan, TYPE CONSTANT only results in a single shader being compiled, although re-specialization at runtime may end up being just as slow as compiling a new shader, so it's not necessarily a speed-up. The main benefit is to avoid having a separate entry in the shader cache for every possible variant, which is what would happen with TYPE DEFINE. On non-vulkan there is no distinction between the two.