The SPIR-V Tools project provides an API and commands for processing SPIR-V modules.

Overview

SPIR-V Tools

Overview

The SPIR-V Tools project provides an API and commands for processing SPIR-V modules.

The project includes an assembler, binary module parser, disassembler, validator, and optimizer for SPIR-V. Except for the optimizer, all are based on a common static library. The library contains all of the implementation details, and is used in the standalone tools whilst also enabling integration into other code bases directly. The optimizer implementation resides in its own library, which depends on the core library.

The interfaces have stabilized: We don't anticipate making a breaking change for existing features.

SPIR-V is defined by the Khronos Group Inc. See the SPIR-V Registry for the SPIR-V specification, headers, and XML registry.

Downloads

LinuxLinux Build Status MacOSMacOS Build Status WindowsWindows Build Status

More downloads

Versioning SPIRV-Tools

See CHANGES for a high level summary of recent changes, by version.

SPIRV-Tools project version numbers are of the form vyear.index and with an optional -dev suffix to indicate work in progress. For example, the following versions are ordered from oldest to newest:

  • v2016.0
  • v2016.1-dev
  • v2016.1
  • v2016.2-dev
  • v2016.2

Use the --version option on each command line tool to see the software version. An API call reports the software version as a C-style string.

Releases

Some versions of SPIRV-Tools are tagged as stable releases (see tags on github). These versions undergo extra testing. Releases are not directly related to releases (or versions) of SPIRV-Headers. Releases of SPIRV-Tools are tested against the version of SPIRV-Headers listed in the DEPS file. The release generally uses the most recent compatible version of SPIRV-Headers available at the time of release. No version of SPIRV-Headers other than the one listed in the DEPS file is guaranteed to work with the SPIRV-Tools release.

Supported features

Assembler, binary parser, and disassembler

  • Support for SPIR-V 1.0, through 1.5
    • Based on SPIR-V syntax described by JSON grammar files in the SPIRV-Headers repository.
    • Usually, support for a new version of SPIR-V is ready within days after publication.
  • Support for extended instruction sets:
    • GLSL std450 version 1.0 Rev 3
    • OpenCL version 1.0 Rev 2
  • Assembler only does basic syntax checking. No cross validation of IDs or types is performed, except to check literal arguments to OpConstant, OpSpecConstant, and OpSwitch.

See docs/syntax.md for the assembly language syntax.

Validator

The validator checks validation rules described by the SPIR-V specification.

Khronos recommends that tools that create or transform SPIR-V modules use the validator to ensure their outputs are valid, and that tools that consume SPIR-V modules optionally use the validator to protect themselves from bad inputs. This is especially encouraged for debug and development scenarios.

The validator has one-sided error: it will only return an error when it has implemented a rule check and the module violates that rule.

The validator is incomplete. See the CHANGES file for reports on completed work, and the Validator sub-project for planned and in-progress work.

Note: The validator checks some Universal Limits, from section 2.17 of the SPIR-V spec. The validator will fail on a module that exceeds those minimum upper bound limits. It is future work to parameterize the validator to allow larger limits accepted by a more than minimally capable SPIR-V consumer.

Optimizer

The optimizer is a collection of code transforms, or "passes". Transforms are written for a diverse set of reasons:

  • To restructure, simplify, or normalize the code for further processing.
  • To eliminate undesirable code.
  • To improve code quality in some metric such as size or performance. Note: These transforms are not guaranteed to actually improve any given metric. Users should always measure results for their own situation.

As of this writing, there are 67 transforms including examples such as:

  • Simplification
    • Strip debug info
    • Strip reflection info
  • Specialization Constants
    • Set spec constant default value
    • Freeze spec constant to default value
    • Fold OpSpecConstantOp and OpSpecConstantComposite
    • Unify constants
    • Eliminate dead constant
  • Code Reduction
    • Inline all function calls exhaustively
    • Convert local access chains to inserts/extracts
    • Eliminate local load/store in single block
    • Eliminate local load/store with single store
    • Eliminate local load/store with multiple stores
    • Eliminate local extract from insert
    • Eliminate dead instructions (aggressive)
    • Eliminate dead branches
    • Merge single successor / single predecessor block pairs
    • Eliminate common uniform loads
    • Remove duplicates: Capabilities, extended instruction imports, types, and decorations.
  • Normalization
    • Compact IDs
    • CFG cleanup
    • Flatten decorations
    • Merge returns
    • Convert AMD-specific instructions to KHR instructions
  • Code improvement
    • Conditional constant propagation
    • If-conversion
    • Loop fission
    • Loop fusion
    • Loop-invariant code motion
    • Loop unroll
  • Other
    • Graphics robust access
    • Upgrade memory model to VulkanKHR

Additionally, certain sets of transformations have been packaged into higher-level recipes. These include:

  • Optimization for size (spirv-opt -Os)
  • Optimization for performance (spirv-opt -O)

For the latest list with detailed documentation, please refer to include/spirv-tools/optimizer.hpp.

For suggestions on using the code reduction options, please refer to this white paper.

Linker

Note: The linker is still under development.

Current features:

  • Combine multiple SPIR-V binary modules together.
  • Combine into a library (exports are retained) or an executable (no symbols are exported).

See the CHANGES file for reports on completed work, and the General sub-project for planned and in-progress work.

Reducer

Note: The reducer is still under development.

The reducer simplifies and shrinks a SPIR-V module with respect to a user-supplied interestingness function. For example, given a large SPIR-V module that cause some SPIR-V compiler to fail with a given fatal error message, the reducer could be used to look for a smaller version of the module that causes the compiler to fail with the same fatal error message.

To suggest an additional capability for the reducer, file an issue with "Reducer:" as the start of its title.

Fuzzer

Note: The fuzzer is still under development.

The fuzzer applies semantics-preserving transformations to a SPIR-V binary module, to produce an equivalent module. The original and transformed modules should produce essentially identical results when executed on identical inputs: their results should differ only due to floating-point round-off, if at all. Significant differences in results can pinpoint bugs in tools that process SPIR-V binaries, such as miscompilations. This metamorphic testing approach is similar to the method used by the GraphicsFuzz project for fuzzing of GLSL shaders.

To suggest an additional capability for the fuzzer, file an issue with "Fuzzer:" as the start of its title.

Extras

  • Utility filters
  • Build target spirv-tools-vimsyntax generates file spvasm.vim. Copy that file into your $HOME/.vim/syntax directory to get SPIR-V assembly syntax highlighting in Vim. This build target is not built by default.

Contributing

The SPIR-V Tools project is maintained by members of the The Khronos Group Inc., and is hosted at https://github.com/KhronosGroup/SPIRV-Tools.

Consider joining the [email protected] mailing list, via https://www.khronos.org/spir/spirv-tools-mailing-list/. The mailing list is used to discuss development plans for the SPIRV-Tools as an open source project. Once discussion is resolved, specific work is tracked via issues and sometimes in one of the projects.

(To provide feedback on the SPIR-V specification, file an issue on the SPIRV-Headers GitHub repository.)

See docs/projects.md to see how we use the GitHub Project feature to organize planned and in-progress work.

Contributions via merge request are welcome. Changes should:

We intend to maintain a linear history on the GitHub master branch.

Getting the source

Example of getting sources, assuming SPIRV-Tools is configured as a standalone project:

git clone https://github.com/KhronosGroup/SPIRV-Tools.git   spirv-tools
cd spirv-tools

# Check out sources for dependencies, at versions known to work together,
# as listed in the DEPS file.
python3 utils/git-sync-deps

For some kinds of development, you may need the latest sources from the third-party projects:

git clone https://github.com/KhronosGroup/SPIRV-Headers.git spirv-tools/external/spirv-headers
git clone https://github.com/google/googletest.git          spirv-tools/external/googletest
git clone https://github.com/google/effcee.git              spirv-tools/external/effcee
git clone https://github.com/google/re2.git                 spirv-tools/external/re2

Dependency on Effcee

Some tests depend on the Effcee library for stateful matching. Effcee itself depends on RE2.

  • If SPIRV-Tools is configured as part of a larger project that already uses Effcee, then that project should include Effcee before SPIRV-Tools.
  • Otherwise, SPIRV-Tools expects Effcee sources to appear in external/effcee and RE2 sources to appear in external/re2.

Source code organization

  • example: demo code of using SPIRV-Tools APIs
  • external/googletest: Intended location for the googletest sources, not provided
  • external/effcee: Location of Effcee sources, if the effcee library is not already configured by an enclosing project.
  • external/re2: Location of RE2 sources, if the re2 library is not already configured by an enclosing project. (The Effcee project already requires RE2.)
  • include/: API clients should add this directory to the include search path
  • external/spirv-headers: Intended location for SPIR-V headers, not provided
  • include/spirv-tools/libspirv.h: C API public interface
  • source/: API implementation
  • test/: Tests, using the googletest framework
  • tools/: Command line executables

Tests

The project contains a number of tests, used to drive development and ensure correctness. The tests are written using the googletest framework. The googletest source is not provided with this project. There are two ways to enable tests:

  • If SPIR-V Tools is configured as part of an enclosing project, then the enclosing project should configure googletest before configuring SPIR-V Tools.
  • If SPIR-V Tools is configured as a standalone project, then download the googletest source into the /external/googletest directory before configuring and building the project.

Build

Note: Prebuilt binaries are available from the downloads page.

First get the sources. Then build using CMake, Bazel, Android ndk-build, or the Emscripten SDK.

Build using CMake

You can build the project using CMake:

cd <spirv-dir>
mkdir build && cd build
cmake [-G <platform-generator>] <spirv-dir>

Once the build files have been generated, build using the appropriate build command (e.g. ninja, make, msbuild, etc.; this depends on the platform generator used above), or use your IDE, or use CMake to run the appropriate build command for you:

cmake --build . [--config Debug]  # runs `make` or `ninja` or `msbuild` etc.

Note about the fuzzer

The SPIR-V fuzzer, spirv-fuzz, can only be built via CMake, and is disabled by default. To build it, clone protobuf and use the SPIRV_BUILD_FUZZER CMake option, like so:

# In 
   
     (the SPIRV-Tools repo root):
   
git clone --depth=1 --branch v3.13.0.1 https://github.com/protocolbuffers/protobuf external/protobuf

# In your build directory:
cmake [-G <platform-generator>] <spirv-dir> -DSPIRV_BUILD_FUZZER=ON
cmake --build . --config Debug

You can also add -DSPIRV_ENABLE_LONG_FUZZER_TESTS=ON to build additional fuzzer tests.

Build using Bazel

You can also use Bazel to build the project.

cd <spirv-dir>
bazel build :all

Build a node.js package using Emscripten

The SPIRV-Tools core library can be built to a WebAssembly node.js module. The resulting SpirvTools WebAssembly module only exports methods to assemble and disassemble SPIR-V modules.

First, make sure you have the Emscripten SDK. Then:

cd <spirv-dir>
./source/wasm/build.sh

The resulting node package, with JavaScript and TypeScript bindings, is written to /out/web .

Note: This builds the package locally. It does not publish it to npm.

To test the result:

node ./test/wasm/test.js

Tools you'll need

For building and testing SPIRV-Tools, the following tools should be installed regardless of your OS:

  • CMake: if using CMake for generating compilation targets, you need to install CMake Version 2.8.12 or later.
  • Python 3: for utility scripts and running the test suite.
  • Bazel (optional): if building the source with Bazel, you need to install Bazel Version 0.29.1 on your machine. Other versions may also work, but are not verified.
  • Emscripten SDK (optional): if building the WebAssembly module.

SPIRV-Tools is regularly tested with the following compilers:

On Linux

  • GCC version 9.3
  • Clang version 10.0

On MacOS

  • AppleClang 11.0

On Windows

  • Visual Studio 2015
  • Visual Studio 2017

Other compilers or later versions may work, but they are not tested.

CMake options

The following CMake options are supported:

  • SPIRV_BUILD_FUZZER={ON|OFF}, default OFF - Build the spirv-fuzz tool.
  • SPIRV_COLOR_TERMINAL={ON|OFF}, default ON - Enables color console output.
  • SPIRV_SKIP_TESTS={ON|OFF}, default OFF- Build only the library and the command line tools. This will prevent the tests from being built.
  • SPIRV_SKIP_EXECUTABLES={ON|OFF}, default OFF- Build only the library, not the command line tools and tests.
  • SPIRV_USE_SANITIZER= , default is no sanitizing - On UNIX platforms with an appropriate version of clang this option enables the use of the sanitizers documented here. This should only be used with a debug build.
  • SPIRV_WARN_EVERYTHING={ON|OFF}, default OFF - On UNIX platforms enable more strict warnings. The code might not compile with this option enabled. For Clang, enables -Weverything. For GCC, enables -Wpedantic. See CMakeLists.txt for details.
  • SPIRV_WERROR={ON|OFF}, default ON - Forces a compilation error on any warnings encountered by enabling the compiler-specific compiler front-end option. No compiler front-end options are enabled when this option is OFF.

Additionally, you can pass additional C preprocessor definitions to SPIRV-Tools via setting SPIRV_TOOLS_EXTRA_DEFINITIONS. For example, by setting it to /D_ITERATOR_DEBUG_LEVEL=0 on Windows, you can disable checked iterators and iterator debugging.

Android ndk-build

SPIR-V Tools supports building static libraries libSPIRV-Tools.a and libSPIRV-Tools-opt.a for Android:

cd 
   
    

export ANDROID_NDK=/path/to/your/ndk

mkdir build && cd build
mkdir libs
mkdir app

$ANDROID_NDK/ndk-build -C ../android_test     \
                      NDK_PROJECT_PATH=.      \
                      NDK_LIBS_OUT=`pwd`/libs \
                      NDK_APP_OUT=`pwd`/app

   

Updating DEPS

Occasionally the entries in DEPS will need to be updated. This is done on demand when there is a request to do this, often due to downstream breakages. To update DEPS, run utils/roll_deps.sh and confirm that tests pass. The script requires Chromium's depot_tools.

Library

Usage

The internals of the library use C++11 features, and are exposed via both a C and C++ API.

In order to use the library from an application, the include path should point to /include , which will enable the application to include the header /include/spirv-tools/libspirv.h{|pp} then linking against the static library in /source/libSPIRV-Tools.a or /source/SPIRV-Tools.lib . For optimization, the header file is /include/spirv-tools/optimizer.hpp , and the static library is /source/libSPIRV-Tools-opt.a or /source/SPIRV-Tools-opt.lib .

  • SPIRV-Tools CMake target: Creates the static library:
    • /source/libSPIRV-Tools.a on Linux and OS X.
    • /source/libSPIRV-Tools.lib on Windows.
  • SPIRV-Tools-opt CMake target: Creates the static library:
    • /source/libSPIRV-Tools-opt.a on Linux and OS X.
    • /source/libSPIRV-Tools-opt.lib on Windows.

Entry points

The interfaces are still under development, and are expected to change.

There are five main entry points into the library in the C interface:

  • spvTextToBinary: An assembler, translating text to a binary SPIR-V module.
  • spvBinaryToText: A disassembler, translating a binary SPIR-V module to text.
  • spvBinaryParse: The entry point to a binary parser API. It issues callbacks for the header and each parsed instruction. The disassembler is implemented as a client of spvBinaryParse.
  • spvValidate implements the validator functionality. Incomplete
  • spvValidateBinary implements the validator functionality. Incomplete

The C++ interface is comprised of three classes, SpirvTools, Optimizer and Linker, all in the spvtools namespace.

  • SpirvTools provides Assemble, Disassemble, and Validate methods.
  • Optimizer provides methods for registering and running optimization passes.
  • Linker provides methods for combining together multiple binaries.

Command line tools

Command line tools, which wrap the above library functions, are provided to assemble or disassemble shader files. It's a convention to name SPIR-V assembly and binary files with suffix .spvasm and .spv, respectively.

Assembler tool

The assembler reads the assembly language text, and emits the binary form.

The standalone assembler is the executable called spirv-as, and is located in /tools/spirv-as . The functionality of the assembler is implemented by the spvTextToBinary library function.

  • spirv-as - the standalone assembler
    • /tools/as

Use option -h to print help.

Disassembler tool

The disassembler reads the binary form, and emits assembly language text.

The standalone disassembler is the executable called spirv-dis, and is located in /tools/spirv-dis . The functionality of the disassembler is implemented by the spvBinaryToText library function.

  • spirv-dis - the standalone disassembler
    • /tools/dis

Use option -h to print help.

The output includes syntax colouring when printing to the standard output stream, on Linux, Windows, and OS X.

Linker tool

The linker combines multiple SPIR-V binary modules together, resulting in a single binary module as output.

This is a work in progress. The linker does not support OpenCL program linking options related to math flags. (See section 5.6.5.2 in OpenCL 1.2)

  • spirv-link - the standalone linker
    • /tools/link

Optimizer tool

The optimizer processes a SPIR-V binary module, applying transformations in the specified order.

This is a work in progress, with initially only few available transformations.

  • spirv-opt - the standalone optimizer
    • /tools/opt

Validator tool

Warning: This functionality is under development, and is incomplete.

The standalone validator is the executable called spirv-val, and is located in /tools/spirv-val . The functionality of the validator is implemented by the spvValidate library function.

The validator operates on the binary form.

  • spirv-val - the standalone validator
    • /tools/val

Reducer tool

The reducer shrinks a SPIR-V binary module, guided by a user-supplied interestingness test.

This is a work in progress, with initially only shrinks a module in a few ways.

  • spirv-reduce - the standalone reducer
    • /tools/reduce

Run spirv-reduce --help to see how to specify interestingness.

Fuzzer tool

The fuzzer transforms a SPIR-V binary module into a semantically-equivalent SPIR-V binary module by applying transformations in a randomized fashion.

This is a work in progress, with initially only a few semantics-preserving transformations.

  • spirv-fuzz - the standalone fuzzer
    • /tools/fuzz

Run spirv-fuzz --help for a detailed list of options.

Control flow dumper tool

The control flow dumper prints the control flow graph for a SPIR-V module as a GraphViz graph.

This is experimental.

  • spirv-cfg - the control flow graph dumper
    • /tools/cfg

Utility filters

  • spirv-lesspipe.sh - Automatically disassembles .spv binary files for the less program, on compatible systems. For example, set the LESSOPEN environment variable as follows, assuming both spirv-lesspipe.sh and spirv-dis are on your executable search path:

     export LESSOPEN='| spirv-lesspipe.sh "%s"'
    

    Then you page through a disassembled module as follows:

    less foo.spv
    
    • The spirv-lesspipe.sh script will pass through any extra arguments to spirv-dis. So, for example, you can turn off colours and friendly ID naming as follows:
      export LESSOPEN='| spirv-lesspipe.sh "%s" --no-color --raw-id'
      
  • vim-spirv - A vim plugin which supports automatic disassembly of .spv files using the :edit command and assembly using the :write command. The plugin also provides additional features which include; syntax highlighting; highlighting of all ID's matching the ID under the cursor; and highlighting errors where the Instruction operand of OpExtInst is used without an appropriate OpExtInstImport.

  • 50spirv-tools.el - Automatically disassembles '.spv' binary files when loaded into the emacs text editor, and re-assembles them when saved, provided any modifications to the file are valid. This functionality must be explicitly requested by defining the symbol SPIRV_TOOLS_INSTALL_EMACS_HELPERS as follows:

    cmake -DSPIRV_TOOLS_INSTALL_EMACS_HELPERS=true ...
    

    In addition, this helper is only installed if the directory /etc/emacs/site-start.d exists, which is typically true if emacs is installed on the system.

    Note that symbol IDs are not currently preserved through a load/edit/save operation. This may change if the ability is added to spirv-as.

Tests

Tests are only built when googletest is found.

Running test with CMake

Use ctest -j to run all the tests. To run tests using all threads:

ctest -j$(nproc)

To run a single test target, use ctest [-j ] -R . For example, you can run all opt tests with:

ctest -R 'spirv-tools-test_opt'

Running test with Bazel

Use bazel test :all to run all tests. This will run tests in parallel by default.

To run a single test target, specify :my_test_target instead of :all. Test target names get printed when you run bazel test :all. For example, you can run opt_def_use_test with:

bazel test :opt_def_use_test

Future Work

See the projects pages for more information.

Assembler and disassembler

  • The disassembler could emit helpful annotations in comments. For example:
    • Use variable name information from debug instructions to annotate key operations on variables.
    • Show control flow information by annotating OpLabel instructions with that basic block's predecessors.
  • Error messages could be improved.

Validator

This is a work in progress.

Linker

  • The linker could accept math transformations such as allowing MADs, or other math flags passed at linking-time in OpenCL.
  • Linkage attributes can not be applied through a group.
  • Check decorations of linked functions attributes.
  • Remove dead instructions, such as OpName targeting imported symbols.

Licence

Full license terms are in LICENSE

Copyright (c) 2015-2016 The Khronos Group Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Issues
  • WIP: Implement a SPIR-V linker

    WIP: Implement a SPIR-V linker

    Still a work-in-progress and I can most likely reuse more code, but at least I adapted the code to use some of the SPIRV-Tools interface/code.

    Missing:

    • [x] Update SPIR-V version support from 1.0 to 1.2
    • [X] Remove duplicate types
    • [x] Remove duplicate decorations
    • [ ] Remove duplicate names
    • [X] Remove duplicate categories
    • [x] Remove duplicate SpvOpExtInstImport
    • [x] Tests
    • [x] Ensure that an import/export pair of variables or functions have the same interface before accepting to link

    Questions:

    • Should the linker require the given binaries to be valid SPIR-V binaries?
    • Should the linker require the given binaries to have the same endianness as the host?
    opened by pierremoreau 36
  • Add validation for structs decorated as Block or BufferBlock.

    Add validation for structs decorated as Block or BufferBlock.

    Fixes https://github.com/KhronosGroup/SPIRV-Tools/issues/937

    The following checks are performed for structs that are decorated as Block or BufferBlock:

    • No GLSLShared or GLSLPacked decoration should be used by any members.
    • All members need to have Offset decoration. Arrays should have ArrayStride and matrices MatrixStride decorations.
    • Blocks need to follow std140 rules.
    • BufferBlocks need to follow std430 rules.
    opened by asuonpaa 27
  • CFG Cleanup pass - Remove unreachable blocks.

    CFG Cleanup pass - Remove unreachable blocks.

    This change adds a new CFG cleanup pass to spirv-opt. The intent of the pass is to act as a repository of a variety of common CFG cleanup actions (straightening, removal of unreachable code, etc).

    It's my first change to SPIRV-Tools, so I'm sure it's full of inconsistencies and missing bits. One of the things I've been thinking is that it may make sense to coalesce other existing CFG cleanup passes into this one in the hopes of reducing the number of CFG/IR traversals needed during cleanup.

    Or, perhaps, it's preferable to keep these passes separate. I understand that compile time is not an issue now, but I'm not sure if this might be challenging in the future (in my experience, this tends to be true at some point).

    The code works and passes the trivial test I've added. I need to add more, but I want a first review pass so I can learn preferred idioms and ways of structuring the code.

    Thanks.

    opened by dnovillo 27
  • ADCE: Dead if elimination

    ADCE: Dead if elimination

    This pass essentially eliminates "if" control flow when the "then" and "else" parts are empty.

    Mark structured conditional branches live only if one or more instructions in their associated construct is marked live. After closure, replace dead structured conditional branches with a branch to its merge and remove dead blocks.

    Besides eliminating a not-insignificant amount of dead code (up to %30) from real shaders, this optimization is most necessary for legalization as there are real life codes that are expecting the frontend/optimizer/spirv-generator to eliminate references to objects that are referenced statically but not dynamically under compile-time-constant conditions.

    This code does its own dead block elimination, but will ultimately be replaced with a call the newly integrated cfg cleanup code.

    opened by greg-lunarg 22
  • Should SROA eliminate structs in this shader?

    Should SROA eliminate structs in this shader?

    My understanding is that there is a pass that does SROA (scalar_replacement_pass), so I'm somewhat surprised that in the attached shader it doesn't remove the struct

    Here's a snippet from the shader:

        %152 = OpCompositeInsert %_struct_9 %123 %175 0
        %154 = OpCompositeInsert %_struct_9 %float_0 %152 0 2
        // snip
        %166 = OpCompositeExtract %v4float %154 0
        %168 = OpCompositeExtract %float %166 1
         %94 = OpFNegate %float %168
        %170 = OpCompositeInsert %v4float %94 %166 1
               OpStore %gl_Position %170
    

    The shader has been compiled from HLSL via glslang, so the fact that the original shader has a struct makes sense - this is the struct for the vertex shader output - but it's odd that it's still there after all the optimizations.

    sky.spv.zip

    opened by zeux 21
  • Add DeadBranchElimPass

    Add DeadBranchElimPass

    This is another in a series of passes designed to reduce SPIR-V file size.

    For each entry point function, this pass will look for BranchConditionals with constant condition and convert to a branch. Any resulting dead blocks are eliminated. For all phi functions in merge block, replace all uses with the id corresponding to the living predecessor.

    This pass requires that all control flow be structured to allow optimization.

    This pass is most effective when preceeded by passes which eliminate local loads and stores, effectively propagating constant values into BranchConditionals where possible.

    Note that is pass contains functions and data from previous passes in this series. These will be coalesced under the planned optimization context class.

    opened by greg-lunarg 21
  • Problematic `switch(0u): default` branch idiom in merge return pass

    Problematic `switch(0u): default` branch idiom in merge return pass

    I have opened an issue about this in glslang, before figuring out it's actually due to a recent change in SPIRV-Tools https://github.com/KhronosGroup/glslang/issues/2148

    Let me copy the initial issue here under The only additional information I've uncovered since, is that this is indeed due to a quite recent change in how the merge return pass is implemented: https://github.com/KhronosGroup/SPIRV-Tools/commit/e7afeb060e1637ca964c62517c3e6c225704b7eb which was undertaken under this issue https://github.com/KhronosGroup/SPIRV-Tools/issues/3127


    It seems glslang has come up with (or increased the frequency of), sometimes in the previous months, I think, a rather peculiar pattern which looks something like this (in pseudo-code since the output is actually SPIR-V):

        vec4 _801;
        switch (0u)
        {
            default:
            {
                if (/* ... */)
                {
                    _801 = /* assign a value */;
                    break;
                }
                _801 = /* assign another value */;
                break;
            }
        }
    

    This seems to happen in the HLSL to SPIR-V path at least, when inlining a function that conditionally returns different possible values, although I couldn't reduce my sample far enough to isolate exactly when that happens. Is there a good specific reason for this peculiar idiom ?

    Albeit not incorrect, this kind of code is problematic in the case of D3D related pipelines. When fed to the D3D shader compiler, such code, having gone through glslang at some point, turns out to be highly problematic, as the D3D compiler is both incapable to correctly analyse that no code paths ends up with the variable potentially uninitialized — in the case of those tricky switch statements, and at the same time very picky about reading from unitialized variables, producing hard compile errors in those cases.

    I'm not opening this issue to unequivocally say: it's something glslang should fix, but if you have any insights about how this was introduced and potential ways to workaround this problem. The responsibility of fixing this could be pushed to the next cross compiler in the chain, but it seems a rather complex task, so I'm pessimistic about the feasability. Fixing the D3D compiler itself doesn't seem easily doable either. Finally, would it be conceivable to make this behavior somehow togglable trough some sort of option ?

    opened by hugoam 20
  • spirv-val: Header block is contained in the loop construct but its merge block is not

    spirv-val: Header block is contained in the loop construct but its merge block is not

    Many of my shaders that were previously passing spirv-val (last tested at Vulkan SDK 1.1.121.0) now fail with Vulkan SDK 1.2.131.2. The specific error is:

    c:\vulkansdk\1.2.131.2\Bin\spirv-val shader_0085.spv error: line 956: Header block 12163[%12163] is contained in the loop construct headed by 6548[%6548], but its merge block 17470[%17470] is not %12163 = OpLabel

    An example spir-v file is attached. I was talking to @greg-lunarg about this. The question is whether this is legitimately a bad shader or a spirv-val bug, and then second where in the spirv-opt chain this might get introduced.

    Filing here first to triage the issue, also in case someone else already has hunted this down and knows offhand what the problem is.

    shader_0085.zip

    opened by danginsburg 19
  • The spirv-opt remove-duplicates pass makes a seemingly erroneous transformation of my shader

    The spirv-opt remove-duplicates pass makes a seemingly erroneous transformation of my shader

    I have run into a problem with spirv-opt since the release of Vulkan SDK 1.0.68.0. The remove-duplicates pass seems to be clobbering my shader. Prior to that release, things were fine. This may well be something that I am doing wrong, but I have been unable to determine what thus far.

    spirv-opt from Vulkan SDK 1.0.68.0 self-identifies as:

    SPIRV-Tools v2018.1-dev v2018.0-6-g9e19fc0
    

    The original SPIR-V is constructed by glslangValidator from the same SDK.

    Some relevant bits from my shader:

    layout(set = 0, binding = 5, std140) uniform atmosphere_fragment_uniforms {
    	float sun_radius;
    };
    
    layout(set = 1, binding = 12, std140) uniform planet_dynamic_uniforms {
    	float lod_factor;
    };
    

    Before any optimisation the disassembly shows the following section:

    OpName %planet_dynamic_uniforms "planet_dynamic_uniforms"
    OpMemberName %planet_dynamic_uniforms 0 "lod_factor"
    

    After running just the remove-duplicates pass this has changed to:

    OpName %atmosphere_fragment_uniforms "planet_dynamic_uniforms"
    OpMemberName %atmosphere_fragment_uniforms 0 "lod_factor"
    

    There are other changes, but off the bat this seems odd.

    Running the optimiser with every -O pass except for remove-duplicates generates SPIR-V that appears to work fine.

    I tried using spirv-opt from the CI build from commit 6cd6e5ebef0623a863ca2d8152edda75dd5001df, but with no change in behaviour.

    The following is a cut-down that generates the odd difference when running just remove-duplicates:

    #version 450 core
    
    layout(set = 1, binding = 12, std140) uniform planet_dynamic_uniforms {
    	float lod_factor;
    };
    
    layout(set = 0, binding = 5, std140) uniform atmosphere_fragment_uniforms {
    	float sun_radius;
    };
    
    layout(location = 0) out vec4 out_colour;
    
    void main() {
    	out_colour = vec4(1.0);
    }
    

    To demonstrate the difference:

    glslangValidator -V -o cutdown.spv cutdown.frag
    spirv-opt -o cutdown.opt.spv --remove-duplicates cutdown.spv
    spirv-dis -o cutdown.s cutdown.spv
    spirv-dis -o cutdown.opt.s cutdown.opt.spv
    fc /l cutdown.s cutdown.opt.s
    
    opened by StrayLightning 19
  • spriv-opt producing invalid SPIR-V for shader (crashing two drivers tested on)

    spriv-opt producing invalid SPIR-V for shader (crashing two drivers tested on)

    The attached zip file contains three SPIR-V fragment shaders that demonstrate spirv-opt producing invalid SPIR-V. Unfortunately, the SPIR-V does not fail spirv-val, but it has crashed on two different drivers. Kerch Holt looked at the SPIR-V and determined there was a problem. Specifically:

    The following snippet of SPIRV seems incorrect. It doesn’t seem like it is “structured control flow”. The OpSelectionMerge is pointing to %7205 yet there are jumps outside of this region. Seems like this code is something like : cond ? goto X : goto Y; That isn’t allowed in structured flow: 1987 OpSelectionMerge %7205 None 1988 OpBranchConditional %22516 %21999 %7205 1989 %21999 = OpLabel 1990 OpBranch %24266 1991 %7205 = OpLabel 1992 OpBranch %7840 1993 %7840 = OpLabel 1994 %11181 = OpPhi %float %11180 %21998 %20516 %7205 1995 %14351 = OpPhi %v3float %14347 %21998 %7885 %7205 1996 %12949 = OpPhi %mat3v4float %15174 %21998 %14541 %7205 1997 %16228 = OpPhi %_struct_1268 %15060 %21998 %7120 %7205 1998 %17815 = OpFAdd %float %15154 %float_1 1999 OpBranch %20259 2000 %24266 = OpLabel"

    The shaders attached to the bug are:

    • generic_vfx_ps_1.spv - this is the SPIR-V that comes out of the HLSL front-end of glslang
    • generic.vfx_ps_1.spvopt.spv - this is after running spirv-opt with the following options: spirv-opt.exe --inline-entry-points-exhaustive --convert-local-access-chains --eliminate-local-single-block --eliminate-local-single-store --eliminate-insert-extract --eliminate-dead-code-aggressive --eliminate-dead-branches --merge-blocks --eliminate-local-single-block --eliminate-local-single-store --eliminate-local-multi-store --eliminate-insert-extract --eliminate-dead-code-aggressive
    • generic.vfx_ps_1.spvopt_spvremapper.spv - this is the shader we actually send to the driver which runs spirv-remapper

    Both of the last two shaders are crashing drivers, so spirv-opt alone is enough to cause the crash. I included the last one because it has the code that Kerch identified as being incorrect so hopefully makes it easier to identify the issue.

    spirv_opt_bug.zip

    A secondary issue here is once there is agreement this is invalid spirv, spirv-val should probably get an issue to detect this case since it currently does not.

    opened by danginsburg 19
  • Vulkan conformance test gets access violation in spvValidate

    Vulkan conformance test gets access violation in spvValidate

    Specifics Windows 7, Nvidia GTX 660 Ti, Driver 368.39

    Have Vulkan SDK 1.0.21 installed for validation layers and set environment variable VK_INSTANCE_LAYERS=VK_LAYER_LUNARG_standard_validation

    To reproduce I run all of the dEQP-VK.glsl.functions.control_flow.* tests from the Vulkan Conformance Test Suite

    Message: Exception thrown: read access violation. this was nullptr. (debugger confirms that variable "this" is NULL)

    Location: BasicBlock.h:

    76 /// Returns true if the block is reachable in the CFG
    77 bool reachable() const { return reachable_; }
    

    Call Stack:

        VkLayer_core_validation.dll!libspirv::BasicBlock::reachable() Line 77   C++
    
        VkLayer_core_validation.dll!libspirv::StructuredControlFlowChecks(const libspirv::ValidationState_t & _, const libspirv::Function & function, const std::vector<std::pair<unsigned int,unsigned int>,std::allocator<std::pair<unsigned int,unsigned int> > > & back_edges) Line 349 C++
    
        VkLayer_core_validation.dll!libspirv::PerformCfgChecks(libspirv::ValidationState_t & _) Line 478    C++
    
        VkLayer_core_validation.dll!spvValidate(const spv_context_t * const context, spv_const_binary_t * const binary, spv_diagnostic_t * * pDiagnostic) Line 209  C++
    
        VkLayer_core_validation.dll!core_validation::CreateShaderModule(VkDevice_T * device, const VkShaderModuleCreateInfo * pCreateInfo, const VkAllocationCallbacks * pAllocator, VkShaderModule_T * * pShaderModule) Line 9069  C++
    
        VkLayer_object_tracker.dll!object_tracker::CreateShaderModule(VkDevice_T * device, const VkShaderModuleCreateInfo * pCreateInfo, const VkAllocationCallbacks * pAllocator, VkShaderModule_T * * pShaderModule) Line 3583    C++
    
        VkLayer_parameter_validation.dll!parameter_validation::CreateShaderModule(VkDevice_T * device, const VkShaderModuleCreateInfo * pCreateInfo, const VkAllocationCallbacks * pAllocator, VkShaderModule_T * * pShaderModule) Line 2621    C++
    
        VkLayer_threading.dll!threading::CreateShaderModule(VkDevice_T * device, const VkShaderModuleCreateInfo * pCreateInfo, const VkAllocationCallbacks * pAllocator, VkShaderModule_T * * pShaderModule) Line 1133  C++
    
        deqp-vk.exe!vk::DeviceDriver::createShaderModule(vk::VkDevice_s * device, const vk::VkShaderModuleCreateInfo * pCreateInfo, const vk::VkAllocationCallbacks * pAllocator, vk::Handle<14> * pShaderModule) Line 218  C++
    
        deqp-vk.exe!vk::createShaderModule(const vk::DeviceInterface & vk, vk::VkDevice_s * device, const vk::VkShaderModuleCreateInfo * pCreateInfo, const vk::VkAllocationCallbacks * pAllocator) Line 209    C++
    
        deqp-vk.exe!vk::createShaderModule(const vk::DeviceInterface & deviceInterface, vk::VkDevice_s * device, const vk::ProgramBinary & binary, unsigned int flags) Line 206 C++
        deqp-vk.exe!vkt::`anonymous namespace'::PipelineProgram::PipelineProgram(vkt::Context & context, const glu::sl::ShaderCaseSpecification & spec) Line 745    C++
    
        deqp-vk.exe!vkt::`anonymous namespace'::ShaderCaseInstance::ShaderCaseInstance(vkt::Context & context, const glu::sl::ShaderCaseSpecification & spec) Line 1410 C++
    
        deqp-vk.exe!vkt::`anonymous namespace'::ShaderCase::createInstance(vkt::Context & context) Line 1791    C++
    
        deqp-vk.exe!vkt::TestCaseExecutor::init(tcu::TestCase * testCase, const std::basic_string<char,std::char_traits<char>,std::allocator<char> > & casePath) Line 246   C++
    
        deqp-vk.exe!tcu::TestSessionExecutor::enterTestCase(tcu::TestCase * testCase, const std::basic_string<char,std::char_traits<char>,std::allocator<char> > & casePath) Line 181   C++
    
        deqp-vk.exe!tcu::TestSessionExecutor::iterate() Line 101    C++
    
        deqp-vk.exe!tcu::App::iterate() Line 172    C++
    
        deqp-vk.exe!main(int argc, const char * * argv) Line 55 C++
        [External Code] 
    

    Bisected to spirv-tools commit: f61db0bcc6717b4b60a7e38e7c3c58ad02110aa8 Validator structured flow checks: back-edge, constructs

    Originally posted by @Tony-LunarG in https://github.com/google/shaderc/issues/234:

    opened by antiagainst 18
  • Fixed crash unrolling loops with residual iterations

    Fixed crash unrolling loops with residual iterations

    Current implementation crashes running pass configuration like this:

      opt.RegisterPerformancePasses()
        .RegisterPass(spvtools::CreateStripDebugInfoPass())
        .RegisterPass(spvtools::CreateStripReflectInfoPass())
        // A pass I wrote to specialize loop ranges and it calls `LoopUtils::PartiallyUnroll`.
        .RegisterPass(spvtools::CreateMyPass())
        .RegisterPerformancePasses() // <- Crashed in a `DeadBranchElimPass` here
        ;
    

    and the assertion failure reads:

    Assertion failed: (block_to_move->GetParent() == ip->GetParent() && "Both blocks have to be in the same function."), function MoveBasicBlockToAfter, file function.h, line 234.
    

    with the following stacktrace:

    __pthread_kill (@__pthread_kill:5)
    pthread_kill (@pthread_kill:75)
    abort (@abort:44)
    __assert_rtn (@err:3)
    spvtools::opt::Function::MoveBasicBlockToAfter(unsigned int, spvtools::opt::BasicBlock*) (/Users/penguinliong/Repositories/SpirvToolsLab/third/SPIRV-Tools/source/opt/function.h:233)
    spvtools::opt::DeadBranchElimPass::FixBlockOrder()::$_3::operator()(spvtools::opt::Function*) const (/Users/penguinliong/Repositories/SpirvToolsLab/third/SPIRV-Tools/source/opt/dead_branch_elim_pass.cpp:471)
    decltype(static_cast<spvtools::opt::DeadBranchElimPass::FixBlockOrder()::$_3&>(fp)(static_cast<spvtools::opt::Function*>(fp0))) std::__1::__invoke<spvtools::opt::DeadBranchElimPass::FixBlockOrder()::$_3&, spvtools::opt::Function*>(spvtools::opt::DeadBranchElimPass::FixBlockOrder()::$_3&, spvtools::opt::Function*&&) (/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.3.sdk/usr/include/c++/v1/type_traits:3918)
    bool std::__1::__invoke_void_return_wrapper<bool, false>::__call<spvtools::opt::DeadBranchElimPass::FixBlockOrder()::$_3&, spvtools::opt::Function*>(spvtools::opt::DeadBranchElimPass::FixBlockOrder()::$_3&, spvtools::opt::Function*&&) (/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.3.sdk/usr/include/c++/v1/__functional/invoke.h:30)
    std::__1::__function::__alloc_func<spvtools::opt::DeadBranchElimPass::FixBlockOrder()::$_3, std::__1::allocator<spvtools::opt::DeadBranchElimPass::FixBlockOrder()::$_3>, bool (spvtools::opt::Function*)>::operator()(spvtools::opt::Function*&&) (/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.3.sdk/usr/include/c++/v1/__functional/function.h:178)
    std::__1::__function::__func<spvtools::opt::DeadBranchElimPass::FixBlockOrder()::$_3, std::__1::allocator<spvtools::opt::DeadBranchElimPass::FixBlockOrder()::$_3>, bool (spvtools::opt::Function*)>::operator()(spvtools::opt::Function*&&) (/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.3.sdk/usr/include/c++/v1/__functional/function.h:352)
    std::__1::__function::__value_func<bool (spvtools::opt::Function*)>::operator()(spvtools::opt::Function*&&) const (/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.3.sdk/usr/include/c++/v1/__functional/function.h:505)
    std::__1::function<bool (spvtools::opt::Function*)>::operator()(spvtools::opt::Function*) const (/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.3.sdk/usr/include/c++/v1/__functional/function.h:1182)
    spvtools::opt::IRContext::ProcessCallTreeFromRoots(std::__1::function<bool (spvtools::opt::Function*)>&, std::__1::queue<unsigned int, std::__1::deque<unsigned int, std::__1::allocator<unsigned int> > >*) (/Users/penguinliong/Repositories/SpirvToolsLab/third/SPIRV-Tools/source/opt/ir_context.cpp:922)
    spvtools::opt::IRContext::ProcessReachableCallTree(std::__1::function<bool (spvtools::opt::Function*)>&) (/Users/penguinliong/Repositories/SpirvToolsLab/third/SPIRV-Tools/source/opt/ir_context.cpp:907)
    spvtools::opt::DeadBranchElimPass::FixBlockOrder() (/Users/penguinliong/Repositories/SpirvToolsLab/third/SPIRV-Tools/source/opt/dead_branch_elim_pass.cpp:478)
    spvtools::opt::DeadBranchElimPass::Process() (/Users/penguinliong/Repositories/SpirvToolsLab/third/SPIRV-Tools/source/opt/dead_branch_elim_pass.cpp:495)
    spvtools::opt::Pass::Run(spvtools::opt::IRContext*) (/Users/penguinliong/Repositories/SpirvToolsLab/third/SPIRV-Tools/source/opt/pass.cpp:40)
    spvtools::opt::PassManager::Run(spvtools::opt::IRContext*) (/Users/penguinliong/Repositories/SpirvToolsLab/third/SPIRV-Tools/source/opt/pass_manager.cpp:58)
    spvtools::Optimizer::Run(unsigned int const*, unsigned long, std::__1::vector<unsigned int, std::__1::allocator<unsigned int> >*, spv_optimizer_options_t*) const (/Users/penguinliong/Repositories/SpirvToolsLab/third/SPIRV-Tools/source/opt/optimizer.cpp:605)
    spvtools::Optimizer::Run(unsigned int const*, unsigned long, std::__1::vector<unsigned int, std::__1::allocator<unsigned int> >*) const (/Users/penguinliong/Repositories/SpirvToolsLab/third/SPIRV-Tools/source/opt/optimizer.cpp:567)
    guarded_main() (/Users/penguinliong/Repositories/SpirvToolsLab/src/app.cpp:129)
    main (/Users/penguinliong/Repositories/SpirvToolsLab/src/app.cpp:181)
    start (@start:133)
    
    opened by PENGUINLIONG 1
  • spirv-opt: Invalid SPIR-V generated when optimizing for performance without merge-return

    spirv-opt: Invalid SPIR-V generated when optimizing for performance without merge-return

    Optimizing for performance without merge-return, then running --convert-relaxed-to-half passes generates invalid SPIR-V. When merge-return is enabled, everything compiles correctly.

    error: line 59: Result type (OpTypeVector) does not match the type that results from indexing into the composite (OpTypeVector).
      %181 = OpCompositeExtract %v3half %81 0
    

    To reproduce:

    repro.zip

    # SPIRV-Tools v2022.3-dev v2022.2-28-gc9450135
    # Glslang Version: 10:11.10.0
    
    # Compile.
    glslangValidator -V -o unoptimized.spv test.frag
    
    # Optimize for performance (without merge-return).
    spirv-opt -Oconfig=optimizations.cfg unoptimized.spv -o optimized.spv
    
    # Check that it's good so far.
    spirv-val optimized.spv
    
    # Convert relaxed to half.
    spirv-opt \
        --convert-relaxed-to-half \
        --simplify-instructions \
        --redundancy-elimination \
        --eliminate-dead-code-aggressive \
        optimized.spv \
        -o half.spv
    
    # Validate the SPIR-V (this fails)
    # error: line 59: Result type (OpTypeVector) does not match the type that results from indexing into the composite (OpTypeVector).
    #   %181 = OpCompositeExtract %v3half %81 0
    spirv-val half.spv
    
    opened by bejado 0
  • Instructions involving constant matrices are not getting folded

    Instructions involving constant matrices are not getting folded

    Latest SPIRV-Tools binaries from master branch

    Using HLSL->SpirV->SpirvOpt->SpirvCross-MSL

    Following HLSL code does not get optimized in the SpirvOpt stage and the generated MSL code still has the matrix which can be evaluated to 0 when going through instruction folding in spirv-opt

    HLSL

    struct PixelInput 
    { 
        float4 svPosition : SV_POSITION; 
        float2 texCoords : TEXCOORD0; 
    };
    
    struct PixelOutput
    {
        [[vk::location(0)]] float4 color : SV_TARGET0;
    };
    
    PixelOutput ps_main (const PixelInput pixel)
    {
    	float2 uv = pixel.texCoords.xy;
    	uv += mul (float2x2(float2(1.0f, 0.0f) , float2(0.0f, 1.0f)) , float2(0.0f, 0.0f));
    	PixelOutput retVal = (PixelOutput)0;
    	retVal.color = float4(uv.xy, uv.yx) + pixel.svPosition;
        return retVal;
    }
    

    MSL

    #include <metal_stdlib>
    #include <simd/simd.h>
    
    using namespace metal;
    
    struct ps_main_out
    {
        float4 out_var_SV_TARGET0 [[color(0)]];
    };
    
    struct ps_main_in
    {
        float2 in_var_TEXCOORD0 [[user(locn0)]];
    };
    
    fragment ps_main_out ps_main(ps_main_in in [[stage_in]], float4 gl_FragCoord [[position]])
    {
        ps_main_out out = {};
        float4 _24 = gl_FragCoord;
        _24.w = 1.0 / gl_FragCoord.w;
        out.out_var_SV_TARGET0 = float4((in.in_var_TEXCOORD0 + (float2(0.0) * float2x2(float2(1.0, 0.0), float2(0.0, 1.0)))).xyyx) + _24;
        return out;
    }
    

    We are using pretty much all passes offered by spirv-opt other than the ones that remove unused struct members

    Passes used in order

    CreateWrapOpKillPass
    CreateDeadBranchElimPass
    CreateMergeReturnPass
    CreateInlineExhaustivePass
    CreateEliminateDeadFunctionsPass
    CreatePrivateToLocalPass
    CreateLocalSingleBlockLoadStoreElimPass
    CreateLocalSingleStoreElimPass
    CreateScalarReplacementPass
    CreateLocalAccessChainConvertPass
    CreateLocalSingleBlockLoadStoreElimPass
    CreateLocalSingleStoreElimPass
    CreateLocalMultiStoreElimPass
    CreateCCPPass
    CreateLoopUnrollPasstrue
    CreateDeadBranchElimPass
    CreateRedundancyEliminationPass
    CreateCombineAccessChainsPass
    CreateSimplificationPass
    CreateScalarReplacementPass
    CreateLocalAccessChainConvertPass
    CreateLocalSingleBlockLoadStoreElimPass
    CreateLocalSingleStoreElimPass
    CreateSSARewritePass
    CreateVectorDCEPass
    CreateDeadInsertElimPass
    CreateDeadBranchElimPass
    CreateSimplificationPass
    CreateIfConversionPass
    CreateCopyPropagateArraysPass
    CreateBlockMergePass
    CreateRedundancyEliminationPass
    CreateDeadBranchElimPass
    CreateBlockMergePass
    CreateSimplificationPass
    

    Attached the base and optimized spirv. They are identical ps_main.zip

    opened by manas-kulkarni 1
  • `std::aligned_storage` is deprecated in C++23

    `std::aligned_storage` is deprecated in C++23

    I work on MSVC's C++ Standard Library, where we've recently implemented a C++23 paper that affects your project. (We regularly build many open-source projects to prevent compiler/library regressions, and this also allows us to notify projects of breaking changes that will affect them.)

    The C++23 paper is https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p1413r3.pdf "Deprecate std::aligned_storage and std::aligned_union". We've merged a PR (https://github.com/microsoft/STL/pull/2583 ) that makes aligned_storage, aligned_storage_t, aligned_union, and aligned_union_t emit deprecation warnings when compiled in C++23 mode (/std:c++latest). This will be available in VS 2022 17.3 Preview 3. Although your project might not use /std:c++latest right now, we run such test coverage to identify issues that you might encounter in the future.

    I searched and one line of affected code appears to be (there may be more):

    https://github.com/KhronosGroup/SPIRV-Tools/blob/c26712784629f54c71b84b07bf161eabc0342ebe/source/util/small_vector.h#L470

    (This emitted a warning when used by https://github.com/google/swiftshader , the project we built in our test harness.)

    In general, the recommended replacement is to use the alignas keyword. We do provide an "escape hatch" macro to silence the deprecation warning, if necessary.

    opened by StephanTLavavej 0
  • Missing validation for static workgroup size dimensions nonzero product.

    Missing validation for static workgroup size dimensions nonzero product.

    From section "2.16.1. Universal Validation Rules" of the SPIR-V 1.6 specification: "If the workgroup size is statically specified (using the LocalSize, LocalSizeId execution modes, or the WorkgroupSize BuiltIn), the product of all workgroup size dimensions must not be zero".

    The following shader violates this rule, but no validation message is emitted:

    ; SPIR-V
    ; Version: 1.3
    ; Generator: Khronos SPIR-V Tools Assembler; 0
    ; Bound: 5
    ; Schema: 0
                   OpCapability Shader
                   OpMemoryModel Logical GLSL450
                   OpEntryPoint GLCompute %1 "main"
                   OpExecutionMode %1 LocalSize 0 0 0
           %void = OpTypeVoid
              %3 = OpTypeFunction %void
              %1 = OpFunction %void None %3
              %4 = OpLabel
                   OpReturn
                   OpFunctionEnd
    
    

    My spirv-val --version says this: SPIRV-Tools v2022.2-dev unknown hash, 2022-04-11T17:22:03

    opened by Jonathan-Weinstein 0
Releases(v2022.2)
Owner
The Khronos Group
Connecting Software to Silicon
The Khronos Group
GraphicsFuzz provides tools for automatically finding and simplifying bugs in graphics drivers, specifically graphics shader compilers.

GraphicsFuzz GraphicsFuzz is a set of tools for testing shader compilers GraphicsFuzz provides tools for automatically finding and simplifying bugs in

Google 499 Jun 22, 2022
Suckless-tools - My fork of suckless tools.

suckless-tools Here is my fork of suckless tools. I didn't include tabbed, i was using but not actively. I am using xfce4-terminal instead of st. Beca

null 2 Jan 7, 2022
The Vulkan Profiles Tools are a collection of tools delivered with the Vulkan SDK for Vulkan application developers to leverage Vulkan Profiles while developing a Vulkan application

Copyright © 2021-2022 LunarG, Inc. Vulkan Profiles Tools (BETA) The Vulkan Profiles Tools are a collection of tools delivered with the Vulkan SDK for

The Khronos Group 52 Jun 9, 2022
Allows for multiple SwitchBot buttons and curtains to be controlled via MQTT sent to ESP32. ESP32 will send BLE commands to switchbots and return MQTT responses to the broker. Also supports Meter/Temp Sensor

SwitchBot-MQTT-BLE-ESP32 Switchbot local control using ESP32. no switchbot hub used/required. works with any smarthub that supports MQTT https://githu

null 244 Jun 29, 2022
Serial Data Monitor is a multiplatform (Windows, Linux, Mac, ...) tool to interactively receive/edit/monitor data and send commands to an embedded system via the serial bus

See wiki for full documentation Serial Data Monitor Description Serial Data Monitor is a multiplatform (Windows, Linux, Mac, ...) tool to interactivel

monnoliv 4 Oct 29, 2021
A sketch that not only parses NMEA sentences, but also allows sending UBX commands and decrypt answers from the ublox module

RAK4631-ublox-Commander This is a tokenizer and parser for raw NMEA sentences. This is not intended (yet anyway) for production, but as an exercice in

Kongduino 2 May 29, 2022
Shell program written in C to implement various system calls, with support of executing commands, output redirection and signals.

Use ./shell command to start the shell. $<space>path/executable to run the executable(please specify the path without beginning it with "/"). Eg. type

Ayuj Panchal 1 Nov 15, 2021
32Kb, small memory footprint, single binary that run list of commands in parallel and waits for their termination

await 32K, small memory footprint, single binary that run list of commands in parallel and waits for their termination documentation linux install cur

Slava 52 Jun 24, 2022
Proof of concept userspace filesystem that executes filenames as shell commands and makes the result accessible though reading the file.

ExecFS Proof of concept userspace filesystem that executes filenames as shell commands and makes the result accessible though reading the file. $ ./ex

Camel Coder 9 Apr 14, 2022
LLVM IR and optimizer for shaders, including front-end adapters for GLSL and SPIR-V and back-end adapter for GLSL

Licensing LunarGLASS is available via a three clause BSD-style open source license. Goals The primary goals of the LunarGLASS project are: Reduce the

LunarG, Inc. 151 Jun 18, 2022
hooking the execve syscall, to randomly sabotage typed bash commands.

Syscall hooks A small project of hooking the execve() syscall, to randomly sabotage typed bash commands. This project was tested on 5.11.0-38-generic.

ilevi 4 Jun 19, 2022
A sample project for building Zygisk modules

Developing Zygisk Modules This repository hosts a template zygisk module for developers to start developing Zygisk modules. Before developing Zygisk m

John Wu 187 Jun 24, 2022
SPIRV-Cross is a tool designed for parsing and converting SPIR-V to other shader languages.

SPIRV-Cross SPIRV-Cross is a tool designed for parsing and converting SPIR-V to other shader languages. Features Convert SPIR-V to readable, usable an

The Khronos Group 1.5k Jun 22, 2022
yariv.h is a single C/C++ header to encode and decode SPIR-V shaders into a more compressed form I've called YARI-V.

YARI-V yariv.h is a single C/C++ header to encode and decode SPIR-V shaders into a more compressed form I've called YARI-V. YARI-V is an alternative e

Neil Henning 32 May 3, 2022
Khronos-reference front end for GLSL/ESSL, partial front end for HLSL, and a SPIR-V generator.

News Visual Studio 2013 is no longer supported As scheduled, Microsoft Visual Studio 2013 is no longer officially supported. Please upgrade to at leas

The Khronos Group 2.2k Jun 25, 2022
This repository contains machine-readable files for the SPIR-V Registry

SPIR-V Headers This repository contains machine-readable files for the SPIR-V Registry. This includes: Header files for various languages. JSON files

The Khronos Group 184 Jun 24, 2022
SMOL-V: like Vulkan/Khronos SPIR-V, but smaller.

SMOL-V: like Vulkan/Khronos SPIR-V, but smaller. Overview SMOL-V encodes Vulkan/Khronos SPIR-V format programs into a form that is smoller, and is mor

Aras Pranckevičius 266 Jun 20, 2022
The OpenEXR project provides the specification and reference implementation of the EXR file format, the professional-grade image storage format of the motion picture industry.

OpenEXR OpenEXR provides the specification and reference implementation of the EXR file format, the professional-grade image storage format of the mot

Academy Software Foundation 1.2k Jun 27, 2022
ESP32 firmware to read and control EMS and Heatronic compatible equipment such as boilers, thermostats, solar modules, and heat pumps

EMS-ESP is an open-source firmware for the Espressif ESP8266 and ESP32 microcontroller that communicates with EMS (Energy Management System) based equipment from manufacturers like Bosch, Buderus, Nefit, Junkers, Worcester and Sieger.

EMS-ESP 152 Jun 16, 2022