- Replace ostringstream with custom implementation.
~30% performance uplift on vector-shuffle-oom test.
Allocations are measurably reduced in Valgrind.
- Replace std::vector with SmallVector.
Classic malloc optimization, small vectors are backed by inline data.
~ 7-8% gain on vector-shuffle-oom on GCC 8 on Linux.
- Use an object pool for IVariant type.
We generally allocate a lot of SPIR* objects. We can amortize these
allocations neatly by pooling them.
- ~15% overall uplift on ./test_shaders.py --iterations 10000 shaders/.
We had a bug where error conditions in DoWhileLoop emit path would not
detect that statements were being emitted due to the masking behavior
which happens when force_recompile is true. Fix this.
Also, refactor force_recompile into member functions so we can properly
break on any situation where this is set, without having to rely on
watchpoints in debuggers.
This is a pragmatic trick to avoid symbol collision where a project
links against SPIRV-Cross statically, while linking to other projects
which also use SPIRV-Cross statically. We can end up with very awkward
symbol collisions which can resolve themselves silently because
SPIRV-Cross is pulled in as necessary. To fix this, we must use
different symbols and embed two copies of SPIRV-Cross in this scenario,
now with different namespaces, which in turn leads to different symbols.
We were using std::locale::global() to force a C locale which is not
safe when SPIRV-Cross is used in a multi-threaded environment.
To fix this, we could tap into various per-platform specific locale
handling to get safe thread-local locales, but since locales only affect
the decimal point in floats, we simply query the locale instead and do
the necessary radix replacement ourselves, without touching the locale.
This should be much safer and cleaner than the alternative.
This is a large refactor which splits out the SPIR-V parser from
Compiler and moves it into its more appropriately named Parser module.
The Parser is responsible for building a ParsedIR structure which is
then consumed by one or more compilers.
Compiler can take a ParsedIR by value or move reference. This should
allow for optimal case for both multiple compilations and single
compilation scenarios.
They might potentially be used as part of OpStore in the SPIRV-Tools
inliner in some cases.
Implement these as declared variables but without any initializer.
The size of an array can be a specialization constant or a spec constant
op. This complicates things quite a lot.
Reflection becomes very painful in the presence of expressions instead
of literals so add a new array which expresses this.
It is unlikely that we will need to do accurate reflection of interface
types which have specialization constant size.
SSBOs and UBOs will for now throw exception if a dynamic size is used since it
is very difficult to know the real size.
Fix some minor missing pieces from C++.
Type remapping like this doesn't seem to fit MSL backend so well, as it
does a lot of remapping internally on its own.
Type name remapping, really is for fringe extension cases in GLSL which
aren't yet supported in SPIR-V.
- Only consider I/O variables if part of OpEntryPoint.
- Keep a safe fallback if #entry-points is 1 to avoid potentially
breaking previously working shaders.
OpName is only for debug information, so we must be very careful that
we do not reuse the same name for different variables.
This was previously done for local variables, but this commit extends
this to global variables as well.
This is supported as compiler extensions, but we can be standards
compliant here, so use the classic workaround of having a single entry
array at the end of the structs instead.
Reformats the entire codebase. Better to do it now than later.
Adds .clang-format and a convenience script format_all.sh which formats
everything automatically.