MaterialX icon indicating copy to clipboard operation
MaterialX copied to clipboard

Proposal: Add Support for Vulkan

Open kwokcb opened this issue 4 years ago • 9 comments

Proposal For Vulkan Support In MaterialX

Shader Generation Ecosystem

The following shows how Vulkan code generation would fit into the current eco-system (at time of writing). Note that the intention is to reuse current GLSL code with customizations provided by a new Vulkan code generator classs which is derived from the base GLSL generator. image

Code Generation / Rendering Support Timeline

The following is a possible timeline.

  • The next patch release (at time of writing is 1.38.4) which would be the target for creating a new generator along with appropriate source code validation.
  • Naturally rendering would come later with a possible target of a patch release or as part of the 1.39 release.
  • The initial goal is only to support code generation for a rasterizer and a simple sample renderer to use this code. One main reason is that the current GLSL code emits code which only works for rasterization. It is to be determined what the appropriate generation will be for a path tracer.
  • There will be no new source code implementations required. Instead a new code generator will emit the appropriate variation of GLSL required for Vulkan compliance. This is similar to how the existing ESSL generator is structured.
  • This means that there are no additional tooling dependencies such as SPIRV for code generation.
  • The tooling for code syntax validation will remain glslValidator. This is currently part of the the CI workflow and as desired will be an option for local unit test validation (unit test suite validation is currently too expensive to run on CI).
  • OCIO support in MaterialX is a related dependency, for which Vulkan support adds an additional requirement. This support will not be part of this proposal, except to note that the base colorspace transforms provided as part of the MaterialX core distribution should be supported. image

Details:

Handling Vulkan GLSL

  • KHR_vulkan_glsl extension on OpenGL GLSL
  • Minor differences in functions, main changes in input and resource binding.
  • Default uniforms not allowed
    • e.g., uniform float base=1.0 is not allowed
  • Use layout identifier
    • e.g., layout (set=M, binding=N) uniform sampler2D variableName;
  • Use of sampler2D replaced by sampler and texture2D with separate binding points
  • Uniform Buffers to group uniforms by access and frequency of update
  • Advanced usage (for future exploration)
  •  Storage Images (Image2d)
    • Push constants
    • Descriptor Sets
    • Storage buffers

Vulkan ShaderGen

  • Generate Vulkan compliant GLSL.
  • GLSL Shaders are compiled to SPIRV using Vulkan SDK tools.
  • Vulkan ShaderGen will not generate SPIRV. 
  • A new Vulkan rasterization sample to demonstrate use of GLSL - SPRIV in a runtime environment.
  • Build framework to pull in the required Vulkan SDK.
  • Vulkan SDK is not a requirement to use MaterialX Vulkan ShaderGen.
  • Vulkan SDK is a requirement for validation, testing and samples.

kwokcb avatar Feb 01 '22 19:02 kwokcb

What are the next steps? Are there any blockers?

fire avatar Feb 05 '23 03:02 fire

From a rasterizer support point of view, code generation has been added. A sample renderer was started, but no active work is being done currently. Color management support I don't believe has been tested. No path tracer support has been started.

kwokcb avatar Feb 05 '23 15:02 kwokcb

How would you recommend I implement MaterialX for Godot Engine which choosing either vulkan or an opengl renderer?

fire avatar Mar 14 '23 17:03 fire

Hi @fire, I assume this is the related project: ? Sorry if this is a bit long-winded but I'm not sure of the final intent and not familiar with Godot Engine -- so take this as initial thoughts :)


Possible Intent: (?)

  1. If the intent is to retain the existing constructs in Godot and simply use MaterialX for reference implementations then it's possible to take the current Blender approach and create definitions of Godot nodes in MaterialX. Then you can parse them and map them directly to native Godot constructs.

  2. If the intent is to support the shading models found in MaterialX then I'd assume a custom material is required within Godot.

  3. If the intent is just to use procedural upstream graphs in MaterialX form, then you can code generate just that portion (with some caveats). Baking is also an option, which seems to have been tried already.

  4. Other ?


Approaches:

  1. One option is to derive from the Vulkan or GL code generator to produce exactly what is required for a Godot shader / material. This could be used to target creating built in Godot materials or custom materials. This approach has been taken for example for the HDStorm render delegate and Maya integration.

  2. Another is to take the code as is and try to bind Godot resources (streams, geometry, lights) to it. This I think fits with a custom material approach. I assume this is the fastest way to see results, but integrating into the rendering pipeline may be harder long term?

For shading models, these could be "black-boxes" where you have the "Godot versions" predefined. A number of renderers have taken this approach to avoid trying to figure out how to fit the fix shading logic produced by the generators into their renderers. Upstream graph code can be generated.

I'm pinging @niklasharrysson for other possible ideas, noting that there is the future intent to allow producing shader fragments for better integration with custom shading logic.

kwokcb avatar Mar 15 '23 20:03 kwokcb

Is it possible to reuse any work from Metal to support Vulkan?

fire avatar Apr 21 '23 19:04 fire

I think this question is about generating shaders for Vulkan for use in Godot, more than it is about adding a Vulkan mode to the bundled MaterialX viewer.

I don't think the Metal code will be helpful in that case, but I do think the glsl code will be helpful.

I don't know what tooling Godot uses for shaders, but I think you can use the glsl shader gen from MaterialX for your purposes? Save out the shaders and run them through glslang to get SPIR-V?

I can imagine am ambition to emit SPIR-V directly, but without introducing an optimizer to the shader generator, that would be .... unoptimal.

meshula avatar Apr 22 '23 17:04 meshula

Godot Engine has a glsl-like code that will be sent to possible targets like Dx12, Opengl and Vulkan.

That's probably a viable approach.

fire avatar Apr 22 '23 17:04 fire

An interesting approach would be to see if you can specialize a Godot code generator from the glsl one then ~ recently some work was done by @kwokcb when the MSL generator was added that should make it easier to do things like that.

meshula avatar Apr 22 '23 21:04 meshula

A customized code generator was "approach 1" I mentioned above and seems the better long term approach. This may or may not be a large undertaking so I was wondering as a first step whether "approach 2" works. That is just get something to show up by using an existing generator ?

The Metal work has helped to refactor / distill the existing code so there is a better "hardware" generator base logic. More work will be done there. A 3rd possibility is to enhance the Vulkan or base hw generators to support Godot requirements.

kwokcb avatar Apr 24 '23 14:04 kwokcb