buildaworldnet / IrrlichtBAW

Build A World fork of Irrlicht
http://www.buildaworld.net
Apache License 2.0
122 stars 28 forks source link

Add SPIR-V introspection and GLSL downcompile for OpenGL #130

Closed devshgraphicsprogramming closed 5 years ago

devshgraphicsprogramming commented 6 years ago

Use SPIRV-Cross https://www.khronos.org/assets/uploads/developers/library/2016-vulkan-devday-uk/4-Using-spir-v-with-spirv-cross.pdf https://github.com/KhronosGroup/SPIRV-Cross

to enable some introspection for asset::ISPIR_VShader

SPIRV-Cross does have some overhead, so introspection data should be gathered only on demand through bool asset::ISPIR_VShader::initIntrospection()

OpenGL 4.5 backend and below will need this to down-compile SPIR-V back to GLSL and will have to define their own workarounds to push_constants and descriptor sets as per https://github.com/buildaworldnet/IrrlichtBAW/wiki/Vulkan-Limitations-due-to-OpenGL-Support

Depends on #129

devshgraphicsprogramming commented 5 years ago

Each context exists as long as preprocessing of its assigned source lasts (by "assigned source" i mean the shader source put into GLSL compiler).

Is this actually possible without modifying shaderc?

This way it can prevent from including more than once (i.e. working as include guards).

We actually need the header to include itself numerous times (header guard won't do), consider this

#ifdef GL_ARB_some_extension
    #define ENABLE_FEATURE_X
    #include "something.glh"
#else
    #define ENABLE_FEATURE_Y
    #include "something.glh"
#endif

I know in this trivial example the #include can be moved out and work, but it would be hard to explain to someone why the above scheme doesn't work with our compiler and they need to rewrite it.

We can't leave/resolve any of the ifdefs etc, because they might depend on whether an extension is defined or not, we also need to comment out the #defines and #undefs because its the preprocessor conditional statements that guard them and apply them.

Hence this would have to become

//#ifdef GL_ARB_some_extension
    //#define ENABLE_FEATURE_X
    #include "something.glh"
//#else
    //#define ENABLE_FEATURE_Y
    #include "something.glh"
//#endif

Both includes have to be honoured, without an include guard, otherwise this won't work when the old preprocessor directives are brought back.

So there shouldn't be a limit on how many times an include can be included, only a limit on how many times it can appear in the include stack (limit recursive inclusion).

However the number of recursive inclusions should definitely be more than one.

Do you think my "preprocessor abuse" idea above (nr 2) would work for this?

Crisspl commented 5 years ago

Is this actually possible without modifying shaderc?

I think yes. As I said

This would most likely mean IGLSLCompiler creating such context for include handler, putting our include handler into shaderc (wrapped in this shaderc::IncludeInterface) and removing context after work done

I think IGLSLCompile can take care of it.

We actually need the header to include itself numerous times (header guard won't do), consider this (...)

Your really thought of a lot of scenarios! Quoting myself:

Context is some kind of map [key=absolute_include_path, val=number_of_this_path_being_included]

Here i meant the val is incremented each time the file gets included. So for solving this we can just allow including more than once.

Do you think my "preprocessor abuse" idea above (nr 2) would work for this?

I'm not sure i understand it completely, but anyway I think it's too complicated

devshgraphicsprogramming commented 5 years ago

I'm not sure i understand it completely, but anyway I think it's too complicated

I think its actually less complicated and less code than your solution.

It uses the preprocessor fully to achieve that val counter, but with macro defines. The only thing to watch out for is that the XXX in _GENERATED_INCLUDE_GUARD_XXX gets replaced with a unique identifier per processed file (same for the same file).

Crisspl commented 5 years ago

I think we have to discuss more about

Also I've realised that we need to retain the ability to serialize shaders that need custom compilation per-platform (extensions) and hence are unsuitable to be serialized in SPIR-V (one spir-v program per every permutation of compile-time options), shader source files could also be assets. Then the ICPUShader could come in two variants, as an already compiled SPIR-V program and one that needs to be created (compiled) from references to the shader source objects it needs for compilation.

devshgraphicsprogramming commented 5 years ago

I believe we have the concept ironed out more or less, closing the issue.