Addresses issue #304 and issue #307 by replacing unmatched type OpStores with
per-member copies. Covers assignment statements and most argument passing, but
does not yet cover r-value-based argument passing.
Takes some pressure off of issue #304.
Structures don't inherit locations and then explicitly decorate
members with them, so removed this reason to have another instance
of a structure type.
From the ES spec + Bugzilla 15931 and GL_KHR_vulkan_glsl:
- Update precision qualifiers for all built-in function prototypes.
- Implement the new algorithm used to distinguish built-in function
operation precisions from result precisions.
Also add tracking of separate result and operation precisions, and
use that in generating SPIR-V.
(SPIR-V cares about precision of operation, while the front-end
cares about precision of result, for propagation.)
- Support GL_AMD_shader_ballot (SPV_AMD_shader_ballot).
- Support GL_AMD_shader_trinary_minmax (SPV_AMD_shader_trinary_minmax).
- Support GL_AMD_shader_explicit_vertex_parameter
(SPV_AMD_shader_explicit_vertex_parameter).
- Support GL_AMD_gcn_shader (SPV_AMD_gcn_shader).
This is used by OpenGL, but not Vulkan.
Includes:
- atomicCounter, atomicIncrement, atomicCounterDecrement
- atomic_uint layout-offset checking
- AtomicStorage capability
SPV doesn't allow gaps in the components of the texturing coordinate.
It also removes the shadow reference.
So, close up the components so all used components are together.
For opaque types such as samplers, images, and atomic counters, we want to
reference the actual object in the child function. For a long time, we
used a shadow variable and made a copy of the image/sampler. In 76d0ac1a,
this was changed to not shadow samplers. However, this didn't cover all
opaque types and it also didn't get the pointer storage classes right.
This commit fixes both of these issues.
Fixes#324
The compiler will mark struct members with those builtins, but won't
declare the capability until that member is accessed by some executable
instruction.
Test changes:
- spv.430.vert: was missing ClipDistance capability.
- spv.precise.tese: remove TessellationPointSize capability.
GLSL interpolation qualifiers and auxiliary storage qualifiers are not
mutually exclusive. So when they are translated to SPIR-V decorations, two
independent utility methods should be employed to do this job.
Spec for decorating the OpVariable:
"The remaining variables listed by OpEntryPoint with the Input or Output storage class form the user-defined variable interface. These variables must be identified with a Location decoration"
Spec for decorating struct type:
"The layout of a structure type used as an Input or Output depends on whether it is also a Block (i.e. has a Block decoration).
If it is a not a Block, then the structure type must have a Location decoration"
These capabalities were added on declaration of the members, but
that is considered too aggressive, as those members are automatically
declared in some shaders that don't use them. Now, actual access
is needed to make the capabalities be declared.
1. Sink adding noContraction decoration to createBinaryOperation() and
createUnaryOperation().
2. Fix comments.
3. Remove the #define of my delimiter, use global constant char.
Reimplement the whole workflow to make that: precise'ness of struct
members won't spread to other non-precise members of the same struct
instance.
Approach:
1. Build the map from symbols to their defining nodes. And for each
object node (StructIndex, DirectIndex, Symbol nodes, etc), generates an
accesschain path. Different AST nodes that indicating a same object
should have the same accesschain path.
2. Along the building phase in step 1, collect the initial set of
'precise' (AST qualifier: 'noContraction') objects' accesschain paths.
3. Start with the initial set of 'precise' accesschain paths, use it as
a worklist, do as the following steps until the worklist is empty:
1) Pop an accesschain path from worklist.
2) Get the symbol part from the accesschain path.
3) Find the defining nodes of that symbol.
4) For each defining node, check whether it is defining a 'precise'
object, or its assignee has nested 'precise' object. Get the
incremental path from assignee to its nested 'precise' object (if
any).
5) Traverse the right side of the defining node, obtain the
accesschain paths of the corresponding involved 'precise' objects.
Update the worklist with those new objects' accesschain paths.
Label involved operations with 'noContraction'.
In each step, whenever we find the parent object of an nested object is
'precise' (has 'noContraction' qualifier), we let the nested object
inherit the 'precise'ness from its parent object.
This fixes some vulkanCTS tests that use struct arrays as a member of in/out interface blocks.
From Vulkan spec:
"If it is a not a Block, then the structure type must have a Location decoration. Its members are assigned consecutive locations in their declaration order, with the first member assigned to the location specified for the structure type. >>>>> The members, and their nested types, must not themselves have Location decorations <<<<"
From SPIR-V spec:
"When applied to structure-type members, the Decorations Noperspective, Flat, Patch, Centroid, and Sample can only be applied to the top-level members of the structure type. (Nested objects' types cannot be structures whose members are decorated with these decorations.)"
Previously GlslangToSpv() reported missing/TBD functionalities
by directly writing to stdout using printf. That could cause
problems to callers of GlslangToSpv(). This patch cleans up
the error reporting logic in GlslangToSpv(), TGlslangToSpvTraverser,
and spv::Builder a little bit to use ostringstream.
Also fixed the usage of GlslangToSpv() in GTest fixtures to
capture warnings/errors reported when translating AST to SPIR-V.
- Add new keyword int64_t/uint64_t/i64vec/u64vec.
- Support 64-bit integer literals (dec/hex/oct).
- Support built-in operators for 64-bit integer type.
- Add implicit and explicit type conversion for 64-bit integer type.
- Add new built-in functions defined in this extension.
Fix issue: #237
1. The code generated for matrix constructor should 1) build column
vectors first, 2) build matrix with the vectors.
2. When there is only one scalar type constituent in vector's
constructor, we should populate the constituent to fill all the slots in
the vector. As for matrix, the single constituent should be populated to
the diagonal positions (top-left to bottom-right diagonal).
remove createSpvConstantFromConstSubTree()
Bool -> uint/int with OpSpecConstantOp OpSelect instruction.
uint <-> int conversion with OpSpecConstantOp OpIAdd instruction.
Note, implicit conversion: `const uint = an_int_spec_constant` is not
supported. Explicit type casting is required: `const uint =
uint(an_int_spec_constant)`
Move SpecConstantOpModeGuard from makeSpvConstantFromConstSubTree() to
visitbinary() and visitunary(). Checking if the visiting node is a spec
constants, if so, turn on the SpecConstantOpMode, otherwise, stay in the
normal mode.
Approach:
Add a flag in `Builder` to indicate 'spec constant mode' and 'normal
mode'. When the builder is in 'normal mode', nothing changed. When the
builder is in 'spec constant mode', binary, unary and other instruction
creation rountines will be redirected to `createSpecConstantOp()` to
create instrution at module level with `OpSpecConstantOp <original
opcode> <operands>`.
'spec constant mode' should be enabled if and only if we are creating
spec constants. So a flager setter/recover guard is added when handling
binary/unary nodes in `createSpvConstantsFromConstSubTree()`.
Note when handling spec constants which are represented as ConstantUnion
Node, we should not use `OpSpecConstantOp` to initialize the composite
constant, so builder is set to 'normal mode'.
Tests:
Tests are added in Test/spv.specConstantOperations.vert, including:
1) Arithmetic, shift opeations for both scalar and composite type spec constants.
2) Size conversion from/to float and double for both scalar and vector.
3) Bitwise and/or/xor for both scalar and vector.
4) Unary negate/not for both scalar and vector.
5) Vector swizzles.
6) Comparisons for scalars.
7) == and != for composite type spec constants
Issues:
1) To implement == and != for composite type spec constants, the Spec needs
to allow OpAll, OpAny, OpFOrdEqual, OpFUnordEqual, OpOrdNotEqual,
OpFUnordNotEqual. Currently none of them are allowed in the Spec.
Much about const or temp is mechanical, about actual declaration,
while much is semantic, about something higher level. This commit
checks every use everywhere, and for the high-level ones, substitutes
an encapsulated version instead.
Fix issue #185 by removing OpDecorate instructions whose target IDs are
defined in unreachable blocks and thus not dumped in the generated
SPIR-V code.
SPIR-V bool is abstract; it has no bit pattern for storage with transparent memory.
OpenGL's convention is a bool in a uniform buffer is 32-bit int with non-0 being 'true'.
A removed block releases its instructions, so Module::idToInstruction
suddenly contains dangling references. The original motivation for
block removal was to skip some unreachable blocks, but that's already
achieved by InReadableOrder.cpp.
Also updated stale comments.
To ensure back branches always go to a header block, create a header
block even for !testFirst loops. Then unify common code between the
testFirst/!testFirst cases.
Generate the header-block code first, so update golden files.
Realize that certain infinite loops generate invalid SPIR-V, so put a
TODO to instead abort code generation in such cases.
Change-Id: I1e173c8f73daad186cfc666b7d72bd563ed7665d
Before, it was only including explicit interface, sufficient for IO-Block-declared
oriented interface, but not sufficient for all modes GLSL might be used with
SPIR-V.
Two things are accomplished now:
1) each id will appear exactly once
2) the OpEntryPoint list will union static use with declarations
When emitting SPIR-V code for frexp, avoid access
beyond the end of the operands vector. When constructing
the OpExtInst, construct a new arguments vector instead of
modifying the existing operands vector. In the case of OpFrexp,
well need that last operand later on to generate the store.
Fixes https://github.com/KhronosGroup/glslang/issues/110
Change-Id: Ibc380fadf5e600ac491932e9ecef7afe2d72fd7f
Structured control-flow rules allow leaving the middle of a construct through
a return, but not through a jump to a block that does a return.
Addresses issue #58.
This generally simplifies access chain generation, with far fewer type conversions.
It is particularly important to future SPIR-V changes where there is less aggregate
type uniqueness due to carrying different layout information with the type.
If this breaks your AST consumer, best is to modify it to test
against the enum values instead of doing string comparisons on
built-in function names. This is the reason the change was made.
If you need the old behavior, you should be able to get it back by changing
PureOperatorBuiltins to be false instead of true. This path will work for
a while, but is marked deprecated.
Also, the old behavior is tagged as release 2.4.
There will be subsequent commits to refine semantics, esp. version-specific semantics,
as well as I/O functionality and restrictions.
Note: I'm getting white-space differences in the preprocessor test results,
which I'm not checking in. I think they need to be tagged as binary or something.
The loop test is always emitted before the loop body.
For do-while loops, use a phi node to track whether we're
on the first loop iteration, and only check the loop test
on the second and subsequent iterations.
For do-while loops, the loop test branch no longer occurs
at the top of the loop, so it must get its own selection
merge instruction.
A block can't be the target of more than one merge instruction.
So when the loop test executes after the body (as in do-while in GLSL)
we need to introduce a dummy block to be the target of the selection
merge just before the loop test conditional branch.
The other arm of the branch exits the loop and hence is the
"break block" exception in the structured control flow rules.