Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compute shader usability #94

Closed
luithefirst opened this issue Aug 23, 2022 · 3 comments
Closed

Compute shader usability #94

luithefirst opened this issue Aug 23, 2022 · 3 comments
Milestone

Comments

@luithefirst
Copy link
Member

luithefirst commented Aug 23, 2022

Compute shaders/tasks have a shadowy existence besides other shaders. A long-term goala should be to unify more of the code behind and make the usage consistent with other shaders/tasks (i.e. raytracing task).

I'm currently implementing a complex post-processing pipeline, that currently has 4 passes (shaders) with each having many inputs (main effect 27). A reoccurring pitfall is that there is no validation if all inputs are supplied when running the task. E.g. when I implement lots of new code and use a uniform input that I have already defined/used in another pass and then forget to also set the appropriate input when running the commands/task there is no warning or error.
The generated code also does not seem to get the same level of optimization as I'm used from other shaders. One particular issue is that I cannot use compile-time constant arguments to generate shader variants. Here is an example:

[<LocalSize(X = 8, Y = 8)>]
let filter (mode : FilterMode) () = // NOTE: second unit argument is required!?
    compute {  ....  }

let CompileMainFilter(runtime : IRuntime) =
    runtime.CreateComputeShader (reblurFilter ReblurFilterMode.MainFilter)

Results in:

layout(std140, binding = 1)
uniform Arguments
{
    int cs_mode;
};

void main()
{
....
    if ((cs_mode == 1))
....
}

So it generates a shader that requires "mode" as input (no input check/validation -> double fail).

Here is a list of improvements that we should consider:

  1. Input Validation: There should be a check if all inputs (uniforms) are supplied and the type is compatible with the requested one
  2. Support for compile-time constant arguments
  3. Similar compile/optimization pipeline as other shaders: Dead code elimination (there only seem to be one pass of constant folding, but unused statements remain), function inlining (does not seem to work)
  4. Shader caches (Shader cache for compute/raytracing shaders #85)
  5. More ComputeCommands: GenerateMipLevels, Clear, etc.
  6. Compute tasks: adaptive value inputs (map<Symbol, IAdaptiveValue>) (NOTE: I would see this as nice to have)
  7. Resource management: Texture2d, ArrayBuffer, and similar (NOTE: Also "nice to have". I can very well live without this and manually prepare this kind of data)
  8. Add line number to when code is printed

I've already mentioned some points to @hyazinthh and he could work on improvements when there is time. It would be nice to collect input from others on my suggestions and consider that there are already quite a lot of compute shaders in production usage and how we want to approach this.

@krauthaufen
Copy link
Member

krauthaufen commented Aug 23, 2022

@1 afaik there is lots of validation which e.g. prints unassigned inputs, etc. (maybe just disabled?)

@2 can be achieved via Expr splicing afaik

@3 I tried optimizing the code in FShade but it's quite hard to do since there are many mutations to consider, so clearly these things would require substantial effort

@luithefirst
Copy link
Member Author

@1 Maybe in Vulkan, but in OpenGL I can comment half of my inputs and it still runs without a warning/error

@hyazinthh hyazinthh added this to the 5.4 milestone Dec 19, 2022
hyazinthh added a commit that referenced this issue Feb 6, 2023
hyazinthh added a commit that referenced this issue Feb 8, 2023
Initial implementation for the new compute task API

See: #94
hyazinthh added a commit that referenced this issue Feb 16, 2023
hyazinthh added a commit that referenced this issue Feb 21, 2023
@hyazinthh
Copy link
Member

I've implemented a new compute task API in the computetask branch. To summarize the initial points and what we have discussed:

  1. The new implementation uses the same code as normal render tasks, including uniform validation.
  2. Not trivial to solve due to how compute shaders accept inputs as function arguments. Use expression splicing as a workaround (see Aardvark.GPGPU primitives).
  3. Also not trivial, we assume that the GLSL compiler is smart enough to do these optimizations.
  4. Already added.
  5. Those commands do not really fit here, in Vulkan a pure compute queue cannot even perform them. It may be possible to add them as RuntimeCommand and properly support compute task invocations there (see https://github.com/aardvark-platform/aardvark.rendering/blob/master/src/Aardvark.Rendering/Runtime/RuntimeCommand.fs).
  6. Compute tasks use IUniformProvider.
  7. Solved.
  8. Already added.

The new API is backwards compatible, so old compute-related code should just work. Unit tests are all green, but we still need to test this on some real projects.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants