Page MenuHome

GPUShaderCreateInfo for interface abstraction
ClosedPublic

Authored by Clément Foucault (fclem) on Nov 24 2021, 10:15 PM.

Details

Summary

This is a first part of the Shader Create Info system could be.

A shader create info provides a way to define shader structure, resources
and interfaces. This makes for a quick way to provide backend agnostic
binding informations while also making shader variations easy to declare.

  • Clear source input (only one file). Cleans up the GPU api since we can create a shader from one descriptor
  • Resources and interfaces are generated by the backend (much simpler than parsing).
  • Bindings are explicit from position in the array.
  • GPUShaderInterface becomes a trivial translation of enums and string copy.
  • No external dependency to third party lib.
  • Cleaner code, less fragmentation of resources in several libs.
  • Easy to modify / extend at runtime.
  • no parser involve, very easy to code.
  • Does not hold any data, can be static and kept on disc.
  • Could hold precompiled bytecode for static shaders.

This also includes a new global dependency system.
GLSL shaders can include other sources by using #pragma BLENDER_REQUIRE(...).

This patch already migrated several builtin shaders. Other shaders should be migrated
one at a time, and could be done inside master.

There is a new compile directive WITH_GPU_SHADER_BUILDER this is an optional
directive for linting shaders to increase turn around time.

What is remaining:

  • pyGPU API
  • Migration of other shaders. This could be a community effort.

Diff Detail

Repository
rB Blender
Branch
tmp-gpu-shader-descriptor-2
Build Status
Buildable 19936
Build 19936: arc lint + arc unit

Event Timeline

Clément Foucault (fclem) requested review of this revision.Nov 24 2021, 10:15 PM
Clément Foucault (fclem) created this revision.

Ignore most of the cmake hackery, yes it's kludgy and there's bits of code duplicated here and there, i'll clean that up at a later point in time, best not to be distracted by this for the rest of the review.

Naming: Is "descriptor" too much similar to vulkans descriptors set? This might create confusion. Maybe MetaData is better? But it may hold more than meta data.

Yes descriptors have a different meaning in vulkan. "A descriptor is an opaque data structure representing a shader respirce such as a buffer view, image view, sampler or combined image sampler".

We are referring to shader bindings and stage interfaces, what could also be considered as a binding. BindingInfo?

Choose the right extension for descriptor files.

Should reflect the term we chose for descriptors.

Choose the right folder. Do we keep them alongside shader files even if name could differ?

Prefer to keep it close to the shader files. although as they are more generic and shaders could be used by multiple descriptors We could move it to a folder next to shaders.
/shaders/*.glsl
/shader_desc/...

Not to far away, but also not seen as the same category of files.

Indentation is 4 spaces for some reasons in descriptors definitions.

Could be that your IDE detects a different format and use other settings. Would prefer to keep it to 2 spaces for readability.

Memory usage might be a concern. We are talking about ~3 MByte of data in the executable.

Would expect that most would be for the workbench variations. We could see how we can add the concept of variations into the descriptor so we could reduce memory usage but with a bit of overhead. We can do some profiling to see where the memory goes to.

If memory is a concern we could also add a mechanism to have active an inactive descriptors. inactive could be offloaded/compressed.

Syntax: Is using [0] to specify binding index clear enough or using VERTEX_INPUT(0, ...) makes more sense? What about future proofing if we one day want to compile this as C++ code.

I would prefer VERTEX_INPUT. it is hard to know what issues there will be in the future. having a macro here would add some flexibility.

This format has nice benefits but it needs manual writting on our ends to modify the shaders. That said, writing all shaders variations for the workbench prepass was quite easy and fast.

Other benefit is to generate the shader documentation for gpu module for builtin shaders. They are out of date.

How would we expose this through pyGPU?

I would suggest a must have for writing custom shaders. But would also be nice to traverse it when a shader is built (for debugging/life coding).

It's not really clear to me why this uses code generation for the GPUShaderDescriptor data structure. Is there some reason this can only be done at compile time, or is it an optimization to avoid runtime overhead? I understand there may be some slow operations like processing shader source code that have a good reason to be done at compile time, but would like to understand the motivation. If this is to be used for the Python gpu module also, I guess there must be a runtime implementation as well?

It might be useful to take inspiration from the new C++ node socket declaration code, if you wanted a single system that can both be quite readable as a declaration but could also be wrapped with a Python API.

b.add_input<decl::Float>(N_("Scale"))
    .min(-1000.0f)
    .max(1000.0f)
    .default_value(5.0f)
    .no_muted_links();

@Brecht Van Lommel (brecht)

It's not really clear to me why this uses code generation for the GPUShaderDescriptor data structure.

The main reason is that we can precompile many variations at build time and assign byte code / SpirV to every one of them. However, it is not the goal to generate the shader variations sources and write them. They will still be created at runtime.

Another reason is that it makes every GPUShaderDescriptor static so we can reference them from either C or C++ without interfaces nor setup code.
It also puts every descriptors in a single file and avoids any ordering conflict by doing the dependencies at compile time.
This is also a good way to validate every shaders at this point.

It might be useful to take inspiration from the new C++ node socket declaration code,

This does look nicer P2628. However this mean that declaring and defining is only doable in C++. Which might not be a real issue in practice since the only part that needs to manipulate GPUShaderDescriptiors is EEVEE materials which is (in eevee-rewrite) already written in C++.
I might find a way to only expose handles to the actual descriptors and define them at runtime. This would avoid the memory usage in the binary and keep the preprocessing simpler.

@Jeroen Bakker (jbakker)

We are referring to shader bindings and stage interfaces, what could also be considered as a binding. BindingInfo?

There is more than bindings inside this structure so I don't think it fits. Here are more propositions:
GPUShaderDescription
GPUShaderCreateInfo
GPUShaderMetaInfo
GPUShaderMetadata
GPUShaderInfo

If memory is a concern we could also add a mechanism to have active an inactive descriptors. inactive could be offloaded/compressed.

The memory concern is only about the size of the binary. They are likely not all loaded at runtime.

Prefer to keep it close to the shader files. although as they are more generic and shaders could be used by multiple descriptors We could move it to a folder next to shaders.

What about putting descriptors in workbench/shaders and source files in workbench/shaders/source or src.

Could be that your IDE detects a different format and use other settings. Would prefer to keep it to 2 spaces for readability.

It is not about my IDE but about clang-format. I don't think it has to do with the file extension. I could not find a way to make it work so I'm asking for help here.

  • Merge branch 'master' into gpu-shader-descriptor
  • ShaderCreateInfo: Rewrite implementation in C++
  • Implement OpenGL backend support 1/2
  • Merge branch 'master' into gpu-shader-descriptor
  • Implement OpenGL backend support 2/2
  • Add support for builtins
  • Cleanup: Make binding always first in generated layout
  • Add Shader Shared utils and structs for draw and workbench
  • Fix errors in GL backend
  • fix shared utils
  • Fix more bug and missing attribute handling in depedency propagation
  • Make all existing descriptors compile
  • Fix shader-builder should exit when no parameters are given.
  • Compilation of shader_builder.
  • Removed one level of libraries for shader_builder.
  • Reduce compile units for shader_builder.
  • Enable compilation for gpu_shader_3D_flat_color variants.
  • Add create info for gpu_shader_3D_image_modulate_alpha.
  • Enable explicit vertex & uniform location
  • Moved builtin create infos into infos folder.
  • Fix compilation noperspective.
  • Fail compilation when a shader can't be compiled.
  • Migrated GPU_SHADER_TEXT.
  • Fix compilation issues GPU_SHADER_3D_FLAT_COLOR.
  • Migrated GPU_SHADER_KEYFRAME_SHAPE.
  • Migrate GPU_SHADER_2D_CHECKER.
  • Migrated shaders.
  • Migrated shaders.
  • Added #ifndefs in all builtin shaders.
  • Added stubs for all missing shaders.
  • EditUVs faces, edges and facedots.
  • Moved missing shaders to gpu_shader_todo_info.hh
  • gpu_shader_2D_point_varying_size_varying_color.
  • gpu_shader_2D_point_uniform_size_uniform_color_aa.
  • gpu_shader_2D_point_uniform_size_uniform_color_outline_aa.
  • gpu_shader_2D_point_uniform_size_varying_color_outline_aa.
  • gpu_shader_2D_uv_verts.
  • gpu_shader_2D_uv_uniform_color.
  • gpu_shader_2D_area_edges.
  • gpu_shader_instance_varying_color_varying_size.
  • gpu_shader_3d_point_*.
  • Merge branch 'master' into tmp-gpu-shader-descriptor-2
  • gpu_shader_2D_nodelink + gpu_shader_2D_nodelink_inst.
  • Fix memory leak.
  • Switched builtin shaders to use create infos.
  • gpu_shader_gpencil_stroke.
  • Merge branch 'master' into tmp-gpu-shader-descriptor-2
  • Fix clang-tidy warnings.
  • gpu_shader_3d_flat_color.
  • gpu_shader_3d_depth_only.
  • Fix create info mismatch.
  • gpu_shader_3D_uniform_color.
  • gpu_shader_3D_smooth_color.
  • gpu_shader_3D_point*.
  • gpu_shader_simple_lighting.
  • Check ubo struct sizes during compilation.
  • Merge branch 'master' into tmp-gpu-shader-descriptor-2
Jeroen Bakker (jbakker) retitled this revision from GPUShaderDescriptor for interface abstraction to GPUShaderCreateInfo for interface abstraction.Jan 12 2022, 11:48 AM
Jeroen Bakker (jbakker) edited the summary of this revision. (Show Details)
Jeroen Bakker (jbakker) edited the summary of this revision. (Show Details)

Added license notices.

source/blender/gpu/CMakeLists.txt
408

These should be enabled.

435

These should be moved to gpu_shader_todo_info.hh

503

remove this line

source/blender/gpu/GPU_shader_shared.h
2

Missing license header

source/blender/gpu/intern/gpu_shader_builtin.c
169–170

remove .vert and .frag

source/blender/gpu/intern/gpu_shader_info_baked.cc
2

Remove file

source/blender/gpu/intern/gpu_shader_info_baked.hh
1 ↗(On Diff #46972)

Remove file

source/blender/gpu/intern/gpu_shader_info_baked_stub.cc
1 ↗(On Diff #46972)

Remove file.

source/blender/gpu/opengl/gl_shader.cc
493

Should be reverted?

source/blender/gpu/shaders/infos/gpu_shader_todo_info.hh
1 ↗(On Diff #46972)

Remove file it is tracked using gpu_shader_builtin.c

  • Add missing license notice.
  • Add missing USE_GPU_SHADER_CREATE_INFO.
  • Removed parts of the build scripts that are currently not needed.
  • Remove .vert/frag from already converted shaders.
Jeroen Bakker (jbakker) requested changes to this revision.Jan 12 2022, 2:25 PM

I did do some of the notes. These are the open issues for me.

  • Separate the changes in draw module. workbench isn't compiling and the shaders aren't used. (except source/blender/draw/intern/draw_manager.c)
  • Check the glsl version 330 is working on all platforms.
This revision now requires changes to proceed.Jan 12 2022, 2:25 PM

Push latest changes from development branch.

  • GL Backend: Wrap uniform access in macros
  • Fix workbench prepass info
  • Make push constant array size known at compile time
  • Add support for non-explicit bindings in GL < 4.3

Patch is stable and can be extended. Approving so the base can land in master and we can continue migrating the rest of the shaders.
Will also spend time on creating a manual how this system works.

This revision is now accepted and ready to land.Jan 17 2022, 2:10 PM