Sometimes when debugging or logging, SPIR-V may be dumped as a stream of
hex values. There are tools to convert such a stream to binary
(such as [1]) but they create an inconvenient extra step when for
example the disassembly of that hex stream is needed.
[1]: https://www.khronos.org/spir/visualizer/hexdump.html
In this change, the binary reader used by the tools is enhanced to
detect when the binary is actually a hex stream, and parse that instead.
The following formats are accepted, detected based on how the SPIR-V
magic number is output:
=== Words
If the first token of the hex stream is one of 0x07230203, 0x7230203,
x07230203, or x7230203, the hex stream is expected to consist of 32-bit
hex words prefixed with 0x or x. For example:
0x7230203, 0x10400, 0x180001, 0x79, 0x0
is parsed as:
0x07230203 0x00010400 0x00180001 0x00000079 0x00000000
Note that `,` is optional in the stream, but the hex values are expected
to be delimited by either `,` or whitespace.
=== Bytes With Prefix
If the first token of the hex stream is one of 0x07, 0x7, x07, x7, 0x03,
0x3, x03, or x3, the hex stream is expected to consist of 8-bit hex
bytes prefixed with 0x or x. If the first token has a value of 7, the
stream is big-endian. Otherwise it's little-endian. For example:
0x3, 0x2, 0x23, 0x7, 0x0, 0x4, 0x1, 0x0, 0x1, 0x0, 0x18, 0x0, 0x79, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0
is parsed as:
0x07230203 0x00010400 0x00180001 0x00000079 0x00000000
Similar to "Words", `,` is optional in the stream, but the hex values
are expected to be delimited by either `,` or whitespace.
=== Bytes Without Prefix
If the first two characters of the hex stream is 07, or 03, the hex
stream is expected to consist of 8-bit hex bytes of 2 characters each.
If the first token is 07, the stream is big-endian. Otherwise it's
little-endian. Unlike the other modes, delimiter is optional (which
automatically handles 32-bit word streams), but no 0-padding is done.
For example, all of the following:
03, 02, 23, 07, 00, 04, 01, 00, 01, 00, 18, 00, 79, 00, 00, 00, 00, 00, 00, 00
03 02 23 07 00 04 01 00 01 00 18 00 79 00 00 00 00 00 00 00
03022307 00040100 01001800 79000000 00000000
07,23,02,03,00,01,04,00,00,18,00,01,00,00,00,79,00,00,00,00
07230203, 00010400, 00180001, 00000079, 00000000
are parsed as:
0x07230203 0x00010400 0x00180001 0x00000079 0x00000000
* linker: run dedup earlier
Otherwise `linkings_to_do` might end up with stale IDs.
* linker: allow linking functions with different pointer arguments
Since llvm-17 there are no typed pointers and hte SPIRV-LLVM-Translator
doesn't know the function signature of imported functions.
I'm investigating different ways of solving this problem and adding an
option to work around it inside `spirv-link` is one of those.
The code is almost complete, just I'm having troubles constructing the
bitcast to cast the pointer parameters to the final type.
Closes: https://github.com/KhronosGroup/SPIRV-LLVM-Translator/issues/2153
* test/linker: add tests to test the AllowPtrTypeMismatch feature
* opt: split composite from array flattening
DXC has an option to flatten resource arrays. But when this option
is not used, the resource arrays should be kept as-is.
On the other hand, when a struct contains resources, we MUST flatten is
to be compliant with the Vulkan spec.
Because this pass flattens both types of resources, using a struct of
resources automatically implied flattening arrays.
By adding those 2 new settings, we decide if the pass flattens only one type
of resources, or both.
Note: the flatten_arrays flag only impacts resource arrays.
Arrays of composites containing resources are still flattened.
Since the API is considered stable, I added 2 new functions to create
passes with one flag or the other, and kept the original behavior as-is.
Related to https://github.com/microsoft/DirectXShaderCompiler/issues/6745
Signed-off-by: Nathan Gauër <brioche@google.com>
* add commandline options
Signed-off-by: Nathan Gauër <brioche@google.com>
* clang-format
Signed-off-by: Nathan Gauër <brioche@google.com>
---------
Signed-off-by: Nathan Gauër <brioche@google.com>
With --nested-indent, the SPIR-V blocks are nested according to the
structured control flow. Each OpLabel is nested that much with the
contents of the block nested a little more. The blocks are separated by
a blank line for better visualization.
With --reorder-blocks, the SPIR-V blocks are reordered according to the
structured control flow. This is particularly useful with
--nested-indent.
Note that with --nested-indent, the disassembly does not exactly show
the binary as-is, and the instructions may be reordered.
The last three elements in the list of supported targets were
misaligned:
```
Targets:
SPIR-V 1.0
SPIR-V 1.1
...
SPIR-V 1.3 (under Vulkan 1.1 semantics)
SPIR-V 1.4 (under Vulkan 1.1 semantics)
SPIR-V 1.5 (under Vulkan 1.2 semantics)
SPIR-V 1.6 (under Vulkan 1.3 semantics)
```
Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
The optimizer is able to preserve the interface variables of the
shaders, but that feature has not been exposed to the command line
tool.
This commit adds an option `--preserve-interface` to spirv-opt that will
cause all calls to ADCE to leave the input and output variables, even if
the variable is unused. It will apply regardless of where the option
appears on the command line.
Fixes#5522
Android's bionic library blows up on this, contrary to the standard.
If std::system can't find a shell, you already have bigger problems.
Don't check specially for that condition. (That's the justification
Android uses, and I'm not going to fight it.)
Currently spirv-link fails if all input files don't use the same
SPIR-V version. Add an option to instead use the highest input
version as the output version. Note that if one of the 'old'
input files uses an opcode that is deprecated in the 'new'
version, the output spirv will be invalid.
Depenabot is not able to update these deps to avoid security issues. I'm
updating all of them manually. This was done by running `yarn upgrade
--latest`. I do not claim to understand the changes to `yarn.lock`.
* dump: add ability to extract HLSL from module
Only adds the code to extract the source from the module. The extracted files are written to the given directory.
Android NDK21 has C++17 support, but no std::filesystem support. (NDK22). As for now, the tool is not built on Android.
Might be something to revisit is the need to have this tool on Android arises.
* dump: add tool skeleton.
This tool aims to be used a bit like objdump (hence the name).
Allowing the user to dump some info from a spirv-binary.
* add test structure for spirv-dump
* add spirv-dump to bazel build file
* fix licenses
* fix compilation with ubsan
* remove fdiagnostics
* rename dump to objdump
* move tests to test/tools
* rename dump to objdump for bazel
This commit fixes the following build error when the source code is build
with MinGW gcc 12 and compiler switch '-Werror=maybe-uninitialized' is
added:
'file.{anonymous}::OutputFile::old_mode_' may be used uninitialized
in this function [-Werror=maybe-uninitialized]
* tools: refactorize tools flags parsing.
Each SPIR-V tool was handing their own flag parsing. This PR
adds a new flag parsing utility that should be flexible enough
for our usage, but generic enough so it can be shared across tools while
remaining simple to use.
* cfg: replace cfg option parsing with the new one.
* change spirv-dis parsing + title + summary
* clang format
* flags: fix static init fiasco & remove help
Static initialization order is important, and was
working just by sheer luck.
Also removing the help generation tooling. It's less flexible than the
hand-written string, and making it as-good and as-flexible brings too
much complexity.
* review feedback
We currently do not set stdout to binary mode when writing a binary
file on Windows. This cause some extra characters to be written that
mess up the output. We try to fix that.
Fixes#4793
* Remove deprecated `--decompose-initialized-variables` from spirv-opt help message
* Remove deprecated --strip-atomic-counter-memory flag from spirv-opt help message
spirv validation require OpFunctionCall with memory object, usually this
is non issue as all the functions are inlined.
This pass deal with some case for
DontInline function. accesschain input operand would be replaced new
created variable
In newer versions of protobuf the Status building code has been made
internal, so that embedders cannot build their own instances like is
being done here.
Changing this code to just use the .ok() method on the status object,
since if the status is OK or not is what is actually being tested.
This will make it easier in the future to update external/protobuf.
spirv-diff is a new tool that produces diff-style output comparing two
SPIR-V modules. The instructions between the src and dst modules are
matched as best as the tool can, and output is produced (in src
id-space) that shows which instructions are removed in src, added in dst
or modified between them. The order of instructions are not retained.
Matching instructions between two SPIR-V modules is not trivial, and
thus a number of heuristics are applied in this tool. In particular,
without debug information, it's hard to match functions as they can be
reordered. As such, this tool is primarily useful to produce the diff
of two SPIR-V modules derived from the same source.
This tool can be useful in a number of scenarios:
- Compare the SPIR-V before and after modifying a shader
- Compare the SPIR-V produced from a shader before and after compiler
codegen changes.
- Compare the SPIR-V produced from a shader before and after some
transformation or optimization.
- Compare the SPIR-V produced from a shader with different compilers.
Add a pass to spread Volatile semantics to variables with SMIDNV,
WarpIDNV, SubgroupSize, SubgroupLocalInvocationId, SubgroupEqMask,
SubgroupGeMask, SubgroupGtMask, SubgroupLeMask, or SubgroupLtMask BuiltIn
decorations or OpLoad for them when the shader model is the ray
generation, closest hit, miss, intersection, or callable shaders. This
pass can be used for VUID-StandaloneSpirv-VulkanMemoryModel-04678 and
VUID-StandaloneSpirv-VulkanMemoryModel-04679 (See "Standalone SPIR-V
Validation" section of Vulkan spec "Appendix A: Vulkan Environment for
SPIR-V").
Handle variables used by multiple entry points:
1. Update error check to make it working regardless of the order of
entry points.
2. For a variable, if it is used by two entry points E1 and E2 and
it needs the Volatile semantics for E1 while it does not for E2
- If VulkanMemoryModel capability is enabled, which means we have to
set memory operation of load instructions for the variable, we
update load instructions in E1, but do not update the ones in E2.
- If VulkanMemoryModel capability is disabled, which means we have
to add Volatile decoration for the variable, we report an error
because E1 needs to add Volatile decoration for the variable while
E2 does not.
For the simplicity of the implementation, we assume that all functions
other than entry point functions are inlined.
* test/linker: Code factorisation and small tweaks
* linker: Do not fail when going over limits
The limits are minima and implementations or APIs might support higher
limits, so just warn the user about it. And only check for the limits
right before emitting the binary, as limits might change earlier when
removing duplicate instructions, function prototypes, etc.
The only check performed right before merging, is making sure the ID
bound will not overflow the 32 bits following the merge.
Also, use the defines for the limits instead of hard-coding them.
* linker: Require a memory model in each input module
The existing code could run into weird situation. For example, if the
first module had no memory model, it would not emit any memory model
(sort of reasonable) and would accept without complains all possible mix
from later modules as it would not verify them.
* linker: Replace hex version with SPV_SPIRV_VERSION_WORD
* linker: Error out when linking together different versions
Fixes https://github.com/KhronosGroup/SPIRV-Tools/issues/4135
* tools/linker: Do not write to disk if linking failed
Also, do not consider warnings as errors.
* tools/linker: Fix formatting in help message
* tools/linker: Further clarify the use of --target-env
Also update the text for the default version to reflect the change made
in 7d768812 ("Basic support for SPIR-V 1.6 (#4663)").
* Basic support for SPIR-V 1.6
* Update SPIRV-Headers deps
* Add new environment enum for SPIR-V 1.6
* Make default environment 1.6 for most tools
* Update tests
* Disallow conditional branch with duplicate labels
* Disallow Dim=Buffer with sampled images
* Do not require the non-semantic extension after SPIR-V 1.5
In https://github.com/KhronosGroup/SPIRV-Tools/pull/3110, the strip reflect
pass was changed to also remove all explicitly nonsemantic instructions. This
makes it so that the name of the pass no longer reflects what the pass actually
does. This change renames the pass so that it reflects what the pass actaully does.
* detect iOS with CMAKE_SYSTEM_NAME
IOS_PLATFORM is not a regular variable, it comes from unofficial iOS toolchain
* fix installation of executables if BUNDLE enabled
CMAKE_MACOSX_BUNDLE is enabled by default if CMAKE_SYSTEM_NAME is iOS, tvOS or watchOS.
So installation of executables needs a BUNDLE DESTINATION otherwise configuration fails.