Commit Graph

143 Commits

Author SHA1 Message Date
alan-baker
de3d5acc04
Add tooling support for SPV_KHR_maximal_reconvergence (#5542)
* Validation for SPV_KHR_maximal_reconvergence
* Add pass to add/remove maximal reconvergence execution mode
---------

Co-authored-by: David Neto <dneto@google.com>
2024-01-25 09:39:49 -05:00
Cassandra Beckley
1bc0e6f59a
Add a new legalization pass to dedupe invocation interlock instructions (#5409)
Add a new legalization pass to dedupe invocation interlock instructions

DXC will be adding support for HLSL's rasterizer ordered views by using
the SPV_EXT_fragment_shader_interlock_extension. That extension
stipulates that if an entry point has an interlock ordering execution
mode, it must dynamically execute OpBeginInvocationInterlockEXT and
OpEndInvocationInterlockEXT, in that order, exactly once. This would be
difficult to determine in DXC's SPIR-V backend, so instead we will emit
these instructions potentially multiple times, and use this legalization
pass to ensure that the final SPIR-V follows the specification.

This PR uses data-flow analysis to determine where to place begin and
end instructions; in essence, determining whether a block contains or is
preceded by a begin instruction is similar to a specialized case of a
reaching definitions analysis, where we have only a single definition,
such as `bool has_begun = false`. For this simpler case, we can compute
the set of blocks using BFS to determine the reachability of the begin
instruction.

We need to do this for both begin and end instructions, so I have
generalized portions of the code to run both forward and backward over
the CFG for each respective case.
2023-09-27 19:54:10 -04:00
Jeremy Gebben
714966003d
opt: Add SwitchDescriptorSetPass (#5375)
This is a simple pass to change DescriptorSet decoration values.
2023-08-22 00:16:35 +00:00
Nathan Gauër
35d8b05de4
opt: add capability trimming pass (not default). (#5278)
This commit adds a new optimization which tries to remove unnecessary
capabilities from a SPIR-V module.

When compiling a SPIR-V module, you may have some dead-code using
features gated by a capability.
DCE will remove this code, but the capability will remain. This means
your module would still require some capability, even if it doesn't
require it. Calling this pass on your module would remove obsolete
capabilities.

This pass wouldn't be enabled by default, and would only be usable
from the API (at least for now).

NOTE: this commit only adds the basic skeleton/structure, and
doesn't mark as supported many capabilities it could support.
I'll add them as supported as I write tests.

Signed-off-by: Nathan Gauër <brioche@google.com>
2023-07-25 16:52:41 +02:00
Juan Ramos
1dad991441
cmake: Modernize install(TARGET) usage (#5056) 2023-01-16 10:55:35 -05:00
Greg Fischer
00018e58af
Change EliminateDeadInputComponentsPass to EliminateDeadIOComponentsPass (#4997)
To reflect processing of both Input and Output variables.

Also renamed files as needed.
2022-11-25 16:48:13 -07:00
Greg Fischer
c8e1588cfa
Add passes to eliminate dead output stores (#4970)
This adds two passes to accomplish this: one pass to analyze a shader
to determine the input slots that are live. The second pass is run on
the preceding shader to eliminate any stores to output slots that are
not consumed by the following shader.

These passes support vert, tesc, tese, geom, and frag shaders.

These passes are currently only available through the API.

These passes together with dead code elimination, and elimination of
dead input and output components and variables (WIP), will allow users
to do dead code elimination across shader boundaries.
2022-11-02 11:23:25 -06:00
Jaebaek Seo
ad3514b732
spirv-opt: add pass for interface variable scalar replacement (#4779)
Replace shader's stage variables whose types are array or matrix
with scalars/vectors.
For example,
```
Before:
  %foo = OpVariable %_ptr_Output__arr_v2float_uint_4 Output
After:
  %foo = OpVariable %_ptr_Output_v2float Output
  %foo_0 = OpVariable %_ptr_Output_v2float Output
  %foo_1 = OpVariable %_ptr_Output_v2float Output
  %foo_2 = OpVariable %_ptr_Output_v2float Output
```
2022-05-09 14:04:52 -04:00
JiaoluAMD
c11ea09652
spirv-opt : Add FixFuncCallArgumentsPass (#4775)
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
2022-05-06 10:39:26 -04:00
Greg Fischer
9d1b572884
spirv-opt: (WIP) Eliminate Dead Input Component Pass (#4720)
This adds the --eliminate-dead-input-components pass which currently
removes trailing unused components from input arrays.

Fixes #4532
2022-03-22 20:50:52 -06:00
Steven Perron
920156cf18
Add pass to remove DontInline function control (#4747)
Swift shader needs a way to inline all functions, even those marked as
DontInline.  See https://github.com/KhronosGroup/SPIRV-Tools/pull/4471.
This implements the suggestion I made in the PR.  We add a pass that
will remove the DontInline function control, so that the inlining passes
will inline them.

SwiftShader will still have to modify their code to add this pass before
the other passes are run.
2022-03-07 12:45:17 -05:00
Jaebaek Seo
fb9a10cd48
spirv-opt: add pass to Spread Volatile semantics (#4667)
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.
2022-01-25 13:14:36 -05:00
Steven Perron
354a46a2a2
Rename strip reflect to strip nonsemantic (#4661)
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.
2021-12-15 09:55:30 -05:00
Jaebaek Seo
d997c83b10
Add spirv-opt pass to replace descriptor accesses based on variable indices (#4574)
This commit adds a spirv-opt pass to replace accesses to
descriptor array based on variable indices with constant
elements.

Before:
```
%descriptor = OpVariable %_ptr_array_Image Uniform
...
%ac = OpAccessChain %_ptr_Image %descriptor %variable_index
(some image instructions using %ac)
```
After:
```
%descriptor = OpVariable %_ptr_array_Image Uniform
...
OpSwitch %variable_index 0 %case0 1 %case1 ...
...
%case0 = OpLabel
%ac = OpAccessChain %_ptr_Image %descriptor %uint_0
...
%case1 = OpLabel
%ac = OpAccessChain %_ptr_Image %descriptor %uint_1
...
(use OpPhi for value with concrete type)
```
2021-10-26 17:20:58 -04:00
Jaebaek Seo
57e1d8ebe3
Add spirv-opt convert-to-sampled-image pass (#4340)
convert-to-sampled-image pass converts images and/or samplers with
given pairs of descriptor set and binding to sampled image.

If a pair of an image and a sampler have the same pair of descriptor
set and binding that is one of the given pairs, they will be
converted to a sampled image. In addition, if only an image has the
descriptor set and binding that is one of the given pairs, it will
be converted to a sampled image as well.

For example, when we have

  %a = OpLoad %type_2d_image %texture
  %b = OpLoad %type_sampler %sampler
  %combined = OpSampledImage %type_sampled_image %a %b
  %value = OpImageSampleExplicitLod %v4float %combined ...

1. If %texture and %sampler have the same descriptor set and binding

  %combine_texture_and_sampler = OpVaraible %ptr_type_sampled_image_Uniform
  ...
  %combined = OpLoad %type_sampled_image %combine_texture_and_sampler
  %value = OpImageSampleExplicitLod %v4float %combined ...

2. If %texture and %sampler have different pairs of descriptor set and binding

  %a = OpLoad %type_sampled_image %texture
  %extracted_image = OpImage %type_2d_image %a
  %b = OpLoad %type_sampler %sampler
  %combined = OpSampledImage %type_sampled_image %extracted_image %b
  %value = OpImageSampleExplicitLod %v4float %combined ...
2021-08-18 08:30:48 -04:00
dong-ja
c4c6f2ba5c
spirv-opt: Add dataflow analysis framework (#4402)
This PR adds a generic dataflow analysis framework to SPIRV-opt, with the intent of being used in SPIRV-lint. This may also be useful for SPIRV-opt, as existing ad-hoc analyses can be rewritten to use a common framework, but this is not the target of this PR.
2021-08-09 16:43:36 -04:00
dong-ja
7dadcf9c76
Add control dependence analysis to opt (#4380)
Control dependence analysis constructs a control dependence graph,
representing the conditions for a block's execution relative to the
results of other blocks with conditional branches, etc.
This is an analysis pass that will be useful for the linter and
potentially also useful in opt. Currently it is unused except for the
added unit tests.
2021-07-28 12:44:32 -04:00
ZHOU He
f9893c4549
spirv-opt: A pass to removed unused input on OpEntryPoint instructions. (#4275)
The new pass will removed interface variable on the OpEntryPoint instruction when they are not statically referenced in the call tree of the entry point.

It can be enabled on the command line using the options `remove-unused-interface-variables`.
2021-06-29 11:33:58 -04:00
Greg Fischer
48007a5c7f
Add interpolate legalization pass (#4220)
This pass converts an internal form of GLSLstd450 Interpolate ops
to the externally valid form. The external form takes the lvalue
of the interpolant. The internal form can do a load of the interpolant.
The pass replaces the load with its pointer. The internal form is
generated by glslang and possibly other frontends for HLSL shaders.
The new pass is called as part of HLSL legalization after all
propagation is complete.

Also adds internal interpolate form to pre-legalization validation
2021-03-31 14:26:36 -04:00
Ryan Harrison
9150cd441f
Remove WebGPU support (#4108)
Leaves SPV_ENV_WEBGPU_0 enum in place, but marked deprecated, so users
of the library are not broken by an API enum being removed.

Fixes #4101
2021-01-14 16:45:18 -05:00
Jaebaek Seo
f7da527757
Temporarily add EmptyPass to prevent glslang from failing (#4004)
Removing PropagateLineInfoPass and RedundantLineInfoElimPass from
56d0f5035 makes unit tests of many open source projects fail.
It will happen before submitting this glslang PR
https://github.com/KhronosGroup/glslang/pull/2440. This commit will be
git-reverted after merging the glslang PR.
2020-10-30 18:03:56 -04:00
Jaebaek Seo
56d0f50357
Propagate OpLine to all applied instructions in spirv-opt (#3951)
Based on the OpLine spec, an OpLine instruction must be applied to
the instructions physically following it up to the first occurrence
of the next end of block, the next OpLine instruction, or the next
OpNoLine instruction.

```
OpLine %file 0 0
OpNoLine
OpLine %file 1 1
OpStore %foo %int_1
%value = OpLoad %int %foo
OpLine %file 2 2
```

For the above code, the current spirv-opt keeps three line
instructions `OpLine %file 0 0`, `OpNoLine`, and `OpLine %file 1 1`
in `std::vector<Instruction> dbg_line_insts_` of Instruction class
for `OpStore %foo %int_1`. It does not put any line instruction to
`std::vector<Instruction> dbg_line_insts_` of
`%value = OpLoad %int %foo` even though `OpLine %file 1 1` must be
applied to `%value = OpLoad %int %foo` based on the spec.

This results in the missing line information for
`%value = OpLoad %int %foo` while each spirv-opt pass optimizes the
code. We have to put `OpLine %file 1 1` to
`std::vector<Instruction> dbg_line_insts_` of
both `%value = OpLoad %int %foo` and `OpStore %foo %int_1`.

This commit conducts the line instruction propagation and skips
emitting the eliminated line instructions at the end, which are the same
with PropagateLineInfoPass and RedundantLineInfoElimPass. This
commit removes PropagateLineInfoPass and RedundantLineInfoElimPass.

KhronosGroup/glslang#2440 is a related PR that stop using
PropagateLineInfoPass and RedundantLineInfoElimPass from glslang.
When the code in this PR applied, the glslang tests will pass.
2020-10-29 13:06:30 -04:00
Ben Clayton
7403dfafd8
CMake: Add SPIRV_TOOLS_BUILD_STATIC flag (#3910)
If enabled the following targets will be created:

* `${SPIRV_TOOLS}-static` - `STATIC` library. Has full public symbol visibility.
* `${SPIRV_TOOLS}-shared` - `SHARED` library. Has default-hidden symbol visibility.
* `${SPIRV_TOOLS}`        - will alias to one of above, based on BUILD_SHARED_LIBS.

If disabled the following targets will be created:

* `${SPIRV_TOOLS}`        - either `STATIC` or `SHARED` based on the new `SPIRV_TOOLS_LIBRARY_TYPE` flag. Has full public symbol visibility.
* `${SPIRV_TOOLS}-shared` - `SHARED` library. Has default-hidden symbol visibility.

Defaults to `ON`, matching existing build behavior.

This flag can be used by package maintainers to ensure that all libraries are built as shared objects.
2020-10-29 09:25:26 -04:00
Steven Perron
2990a21926
Avoid using /MP4 for clang on windows. (#3662) 2020-08-10 10:59:24 -04:00
Ben Clayton
6aed7ffbc7
CMake: Enable building with BUILD_SHARED_LIBS=1 (#3490)
Rename the `${SPIRV_TOOLS}` target to `${SPIRV_TOOLS}-static` and alias `${SPIRV_TOOLS}` to either `${SPIRV_TOOLS}-static` or `${SPIRV_TOOLS}-shared` depending on `BUILD_SHARED_LIBS`.

Re-point all internal uses of `${SPIRV_TOOLS}` to `${SPIRV_TOOLS}-static`.

`${SPIRV_TOOLS}-static` is explicitly renamed to just `${SPIRV_TOOLS}` to ensure the name does not change from current behavior.

Build the `SPIRV-Tools-*` libraries as static, as this is what they always were.

Force the external targets `gmock` and `effcee` to be built statically. These either do not support being built as shared libraries, or require special flags.

Issue: #3482
2020-07-27 13:29:07 -04:00
Jaebaek Seo
42268740c9
Add debug information analysis (#3305)
We need an analysis for OpenCL.DebugInfo.100 extension instructions such
as a map between function id and its DebugFunction. This commit add an
analysis for it.
2020-04-27 15:18:55 -04:00
greg-lunarg
1fe9bcc108
Instrument: Debug Printf support (#3215)
Create a pass to instrument OpDebugPrintf instructions.  This pass replaces all OpDebugPrintf instructions with instructions to write a record containing the string id and the all specified values into a special printf output buffer (if space allows). This pass is designed to support the printf validation in the Vulkan validation layers.

Fixes #3210
2020-03-12 09:19:52 -04:00
Aaron Barany
9c0ae6bb8e Improved CMake install step. (#2963)
Added exports for libraries. External libraries that themselves use
libraries require all dependencies have exports, so not having exports can
cause major problems when used within other projects.

Install paths for exports are now placed in the proper directories expected
by Windows and *nix systems. Config files are generated as well, which
should work with CMake's find_package() function once installed.
2019-10-17 11:36:55 -04:00
Steven Perron
35c9518c4e
Handle id overflow in the ssa rewriter. (#2845)
* Handle id overflow in the ssa rewriter.

Remove LocalSSAElim pass at the same time.  It does the same thing as the SSARewrite pass. Then even share almost all of the same code.

Fixes crbug.com/997246
2019-09-10 09:38:23 -04:00
rumblehhh
1dfb5fc12e Export SPIRV-Tools targets on installation (#2785)
This allows the targets to be used in other cmake projects. See the following for more details:
https://cmake.org/cmake/help/latest/manual/cmake-packages.7.html#creating-packages
https://foonathan.net/blog/2016/07/07/cmake-dependency-handling.html
2019-09-04 12:45:26 -04:00
greg-lunarg
d11725b1d4 Add --relax-float-ops and --convert-relaxed-to-half (#2808)
The first pass applies the RelaxedPrecision decoration to all executable
instructions with float32 based type results. The second pass converts
all executable instructions with RelaxedPrecision result to the equivalent
float16 type, inserting converts where necessary.
2019-09-03 13:22:13 -04:00
Steven Perron
35d98be3bc
Amd ext to khr (#2811)
Add the first steps to removing the AMD extension VK_AMD_shader_ballot.
Splitting up to make the PRs smaller.

Adding utilities to add capabilities and change the version of the
module.

Replaces the instructions:

OpGroupIAddNonUniformAMD = 5000
OpGroupFAddNonUniformAMD = 5001
OpGroupFMinNonUniformAMD = 5002
OpGroupUMinNonUniformAMD = 5003
OpGroupSMinNonUniformAMD = 5004
OpGroupFMaxNonUniformAMD = 5005
OpGroupUMaxNonUniformAMD = 5006
OpGroupSMaxNonUniformAMD = 5007

and extentend instructions

WriteInvocationAMD = 3
MbcntAMD = 4

Part of #2814
2019-08-29 12:48:17 -04:00
greg-lunarg
06407250a1 Instrument: Add support for Buffer Device Address extension (#2792) 2019-08-16 09:18:34 -04:00
Steven Perron
60043edfa1
Replace OpKill With function call. (#2790)
We are no able to inline OpKill instructions into a continue construct.
See #2433.  However, we have to be able to inline to correctly do
legalization.  This commit creates a pass that will wrap OpKill
instructions into a function of its own.  That way we are able to inline
the rest of the code.

The follow up to this will be to not inline any function that contains
an OpKill.

Fixes #2726
2019-08-14 09:27:12 -04:00
Steven Perron
4b64beb1ae
Add descriptor array scalar replacement (#2742)
Creates a pass that will replace a descriptor array with individual variables.  See #2740 for details.

Fixes #2740.
2019-08-08 10:53:19 -04:00
David Neto
31590104ec
Add pass to inject code for robust-buffer-access semantics (#2771)
spirv-opt: Add --graphics-robust-access

Clamps access chain indices so they are always
in bounds.

Assumes:
- Logical addressing mode
- No runtime-array-descriptor-indexing
- No variable pointers

Adds stub code for clamping coordinate and samples
for OpImageTexelPointer.

Adds SinglePassRunAndFail optimizer test fixture.

Android.mk: add source/opt/graphics_robust_access_pass.cpp

Adds Constant::GetSignExtendedValue, Constant::GetZeroExtendedValue
2019-07-30 19:52:46 -04:00
greg-lunarg
92c41ff1e7 Remove Common Uniform Elimination Pass (#2731)
Remove Common Uniform Elimination Pass

Fixes #2520.
2019-07-12 11:02:10 -04:00
Ryan Harrison
f6d9a17843
Add pass to fix some invalid unreachable blocks for WebGPU (#2563)
Attempts to split up unreachable blocks that are used both as a
merge-block and a continue-target.

Fixes #2429
2019-05-09 12:56:10 -04:00
Ryan Harrison
048dcd38ce
Implement WebGPU->Vulkan initializer conversion for 'Function' variables (#2513)
WebGPU requires certain variables to be initialized, whereas there are
known issues with using initializers in Vulkan. This PR is the first
of three implementing a pass to decompose initialized variables into
a variable declaration followed by a store. This has been broken up
into multiple PRs, because there 3 distinct cases that need to be
handled, which require separate implementations.

This first PR implements the basic infrastructure that is needed, and
handling of Function storage class variables. Private and Output will
be handled in future PRs.

This is part of resolving #2388
2019-04-16 14:31:36 -04:00
Ryan Harrison
102e430a88
Add pass to legalize OpVectorShuffle for WebGPU (#2509)
In WebGPU, the component operand 0xFFFFFFFF is forbidden, but in
Vulkan it is used to indicate a value is undefined. When converting to
WebGPU, 0xFFFFFFFF needs to converted to a legal value, though the
specific one does not matter, since it was used to indicate an
undefined entry in the original code. Choosing to use 0, since the
operands are required to be on [0, N-1], so 0 is guaranteed to always
be valid.

Fixes #2349
2019-04-12 12:14:23 -04:00
Steven Perron
3a0bc9e724
Add fix storage class code. (#2434)
This pass tries to fix validation error due to a mismatch of storage classes
in instructions.  There is no guarantee that all such error will be fixed,
and it is possible that in fixing these errors, it could lead to other
errors.

Fixes #2430.
2019-04-05 13:12:08 -04:00
Ryan Harrison
01964e325f
Add pass to generate needed initializers for WebGPU (#2481)
Fixes #2387
2019-04-03 11:44:09 -04:00
Ryan Harrison
e545522146
Add --strip-atomic-counter-memory (#2413)
Adds an optimization pass to remove usages of AtomicCounterMemory
bit. This bit is ignored in Vulkan environments and outright forbidden
in WebGPU ones.

Fixes #2242
2019-03-14 13:34:33 -04:00
Steven Perron
1b0047f210
Add pass to remove dead members. (#2379)
Add a pass that looks for members of structs whose values do not affects
the output of the shader. Those members are then removed and just
treated like padding in the struct.
2019-02-14 13:42:35 -05:00
Alastair Donaldson
34c5ac614c
Fixes #2358. Added to the reducer the ability to remove a function t… (#2361)
* Fixes #2358.  Added to the reducer the ability to remove a function that is not directly called.  Factored out some code from the optimizer to help with this.
2019-02-08 16:20:29 +00:00
Alastair Donaldson
3345fe6a9d
Extracted block merging functionality into its own utility file (#2325)
* Extracted useful functionality from block merger and exposed it as stand-alone methods.

* Separated these methods into a utility file.
2019-01-25 10:57:13 +00:00
Steven Perron
dd4157dcee
Sink (#2284)
Add code sinking pass. It will move OpLoad and OpAccessChain instructions as close as possible to their uses.

Part of #1611.
2019-01-17 15:56:36 -05:00
alan-baker
e510b1bac5
Update memory model (#1904)
Upgrade to VulkanKHR memory model

* Converts Logical GLSL450 memory model to Logical VulkanKHR
* Adds extension and capability
* Removes deprecated decorations and replaces them with appropriate
flags on downstream instructions
* Support for Workgroup upgrades
* Support for copy memory
* Adding support for image functions
* Adding barrier upgrades and tests
* Use QueueFamilyKHR scope instead of device
2018-11-30 14:15:51 -05:00
greg-lunarg
c37388f1ad Add passes to propagate and eliminate redundant line instructions (#2027). (#2039)
These are bookend passes designed to help preserve line information
across passes which delete, move and clone instructions. The propagation
pass attaches a debug line instruction to every instruction based on
SPIR-V line propagation rules. It should be performed before optimization.
The redundant line elimination pass eliminates all line instructions
which match the previous line instruction. This pass should be performed
at the end of optimization to reduce physical SPIR-V file size.

Fixes #2027.
2018-11-15 14:06:17 -05:00
greg-lunarg
1e9fc1aac1 Add base and core bindless validation instrumentation classes (#2014)
* Add base and core bindless validation instrumentation classes

* Fix formatting.

* Few more formatting fixes

* Fix build failure

* More build fixes

* Need to call non-const functions in order.

Specifically, these are functions which call TakeNextId(). These need to
be called in a specific order to guarantee that tests which do exact
compares will work across all platforms. c++ pretty much does not
guarantee order of evaluation of operands, so any such functions need to
be called separately in individual statements to guarantee order.

* More ordering.

* And more ordering.

* And more formatting.

* Attempt to fix NDK build

* Another attempt to address NDK build problem.

* One more attempt at NDK build failure

* Add instrument.hpp to BUILD.gn

* Some name improvement in instrument.hpp

* Change all types in instrument.hpp to int.

* Improve documentation in instrument.hpp

* Format fixes

* Comment clean up in instrument.hpp

* imageInst -> image_inst

* Fix GetLabel() issue.
2018-11-08 13:54:54 -05:00