| Age | Commit message (Collapse) | Author |
|
`gl_Layer` as a fragment input requires at least version 4.30 of GLSL, so we try to track that information when we see the name used.
Note that this does *not* override a user-specified `#version` line.
This required re-ordering when lowering happens relative to emitting the `#version` directive, since this code works by actually modifying the chosen profile for the entry point.
Yes, that is kind of gross and we should do something cleaner in the long term.
|
|
Don't crash-fail on errors in entry point parameters
|
|
Work on #105
These can occur in unchecked code (or code that had a semantic error), so we need to be able to handle them.
|
|
- This was being mapped to `HLSLLineStreamType` because of a copy-paste typo
|
|
Work on #105
If a semantic error occurs in the type of an entry-point parameter, we need to be able to skip over it when doing parameter binding and reflection-generation work.
|
|
Fixes #103
- Previously I was relying on scalar-to-vector promotion to pick the right type in these cases, but I hadn't implemented scalar-to-matrix promotion (I should...)
- Rather than relying on promotion behavior, this change goes ahead and adds explicit overloads. I think this is probably a better decision in the long term, since one might want to support these cases for operators, while warning (or erroring) on the more general cases of implicit conversion.
- This covers matrix/scalar, scalar/matrix, vector/scalar, and scalar/vector cases
|
|
Fixes #104
- Map HLSL `nointerpolation` to GLSL `flat`
- When lowering a `struct` type varying input/output, look for interpolation modifiers along the "chain" from the leaf field up to the original shader input variable (and take the first one found)
- Not sure if this is strictly needed, but it seems like a reasonable policy
- Add `flat` to varying input of integer type, with no other interpolation modifier
- Note: I do *not* do anything to ignore a manually imposed interpolation modifier that might be incorrect
|
|
Fixes #15
These are the modifiers like:
layout(local_size_x = 16) in;
Unlike the HLSL case, these don't get attache to the entry point function itself, so there is a bit more work involed in looking them up.
Just to make sure I didn't mess up the HLSL case, I went ahead and added two tests for this capability: one for GLSL and one for HLSL.
|
|
If we have something like to following in HLSL:
cbuffer C { Texture2D t; ... }
and we are compiling to GLSL, then both `C` and `C.t` consume the same kind of resource (a descriptor-table slot).
The way reflection was working right now, querying the index of `C` would return its binding (let's say it is `4` just to be concrete) and then a query on `C::t` would give its offset, which was being computed as `0` because it is the first field in the logical `struct` type.
That obviously leads to bad math and requires some subtle `+1`s in cases to get things right (e.g., when scalaring during lowering, I had to carefully add one in some cases).
It is unreasonable to expect users to deal with this.
This commit changes it so that the offset of field `C::t` is `1` so that hopefully more things Just Work.
The special-case logic in lowering is now gone.
One important catch here is that this pretty much only works in the case where the element type of a parameter block is a `struct` type (which is really all that makes sense right now).
If we ever want to generalize this in the future, then it will probably be necessary to change the `TypeLayout` case for parameter blocks to store a `VarLayout` for the element, rather than just a `TypeLayout`.
|
|
Fixes #12
- This was a latent issue, but the previous commit brought it to the front.
- As indicated in #12, I don't allocate a descriptor-table slot to the block
- Instead I allocate a `PushConstantBuffer`
- Unlike what #12 asks for, I don't use a different resource type for the contents of the block
- Pretty much all the logic is easiest if these continue to be just plain `Uniform` data
|
|
Calling:
spSetDumpIntermedites(compileRequest, true);
will set up a mode where Slang tries to dump every intermediate HLSL, GLSL, DXBC, SPIR-V, etc. file it generates. If SPIR-V or DXBC is requested then we also dump assembly of those.
Right now the files are all named as `slang-<counter>.<ext>`, and get dropped in whatever the working directory is, but I'm open to ideas on how to improve that.
Note: this change introduces a new binary interface to `glslang`, so pulling it requires an updated `glslang.dll`.
|
|
Fixes #84
- When computing resource usage for an array type, don't multiply the resource usage of the element type by the element count foor descriptor-table-slot resources.
- When reporting the "stride" of an array type through reflection, report the stride for descriptor table slots as zero, always.
|
|
Fixes #81
- This is based on a san over the GLSL spec (but is probably not exhaustive)
- There are some qualifiers that are currently being handled by general-case code for all languages, and some of these happen to cover GLSL qualifiers too
- Some of the qualifiers being handled by the general-case mechanism are *accidentally* working for GLSL (e.g., the HLSL `shared` qualifier doesn't mean the same thing as GLSL `shared`, but as long as we spit it back out nobody seems to care).
- This should be fixed sooner or later.
|
|
Fixes #83
- The basic idea is that I added a bunch of more specific profile names line `glsl_vertex_430` which indicate the desired GLSL version the user wants.
- An explicit `#version` line in the code always overrides one specified by profile, though
|
|
Fixes #77
- The `spGetEntryPointSource` function is now no longer needed, but I'm not going to "deprecate" it just yet
|
|
- This fixes the render tests, which aren't tested by the continuous integration setup
- This was broken in the commit that decided to use C-style directives all the time.
- This works for stuff that eventually passes through glslang (or at least our build of it)
- It *doensn't* work if we take the GLSL and pass it off to an OpenGL driver (which is what I do for testing)
- A longer-term fix is still required to deal with line directives properly
|
|
When cross-compiling, we need to detect when an intrinsic is used that required non-default GLSL capabilities and emit an appropriate `#extension ... : require` line.
I'm handling this by attaching a custom modifier to declarations that require an extension in order to be callable.
|
|
An expression with error type may still fail the l-value check, but we don't want to emit an error in that case.
|
|
HLSL (and thus Slang) commonly puts interpolation modifiers like `sample` on the fields of `struct` types used as stage input/output, while GLSL only allows them on global-scope `in` and `out` variables (or ones in blocks).
This change emits a really hacky filtering step to skip over certain modifiers when emitting a declaration. This lets us skip interpolation-mode modifiers when outputting a struct field to GLSL.
Note: this probably gets the `in` or `out` block case wrong...
|
|
- As long as we are always going to pass GLSL through glslang, there should be no harm in this
- Eventually we may need to re-enable the old style
|
|
- The old code was just doing `exit(1)` if glslang or `D3DCompile` failed, which is obviously unacceptable
- The new approach adds the output to the diagnostic buffer (or invokes the callback), and tracks the error count just like any other errors
|
|
- When assigning tuples `(a0, ...) = (b0, ...)` generate a tuple of assignments `(a0 = b0, ...)`
- Given an expression statement on a tuple `(a0, ...);` generate a sequence of statements `a0; ...`
|
|
- This really just checks two basic things:
1. Was there any global variable declared with `in` and `sample`?
2. Did any code encountered during lowering referenece `gl_SampleIndex`?
- This doesn't cover what HLSL could need, nor what we would need for cross-compilation. Consider it GLSL-specific for now.
- In order to generate the information with even a reasonable chance of being accurate (not giving a ton of false positives) I tried to integrate the checks into the lowering process (so they only see code that is referenced, one hopes).
- For this to work with my testing setup, I needed to make sure that lowering is always performed, prior to emitting reflection info
- This change broke several reflection tests, because they had been using code that wouldn't actually pass the downstream compiler. I checked in fixes for those.
|
|
- This also adds reflection API for querying:
- Entry point name
- Entry point parameter list
|
|
Fixes #75
In order to avoid cascaded errors, I went ahead and made the parser refuse to skip past a `}` in recovery mode. The problem with this is that we fail to make forward progress if we are stuck on a `}` (this happens if you have an extra `}` at the global scope.
|
|
|
|
|
|
- Don't try to extract the body layout for a field without a layout
|
|
Improve reporting of GLSL `image*` types
|
|
- Update stdlib so taht `image*` types have read-write access encoded in their type
- TODO: this isn't 100% right, since there are GLSL qualifiers that might override this
- Add a test case to verify that the reflection API reports `image*` parameters
|
|
- The basic idea is that during the "lowering" pass, some types (notably: aggregate types that contain resource variables) will get turned into "tuple" types, which are pseduo-types that aren't meant to survive lowering.
- An attempt to declare a variable with a tuple type expands into a tuple of declarations
- An attempt to reference such a tuple-ified variable leads to a tuple of expressions
- An attempt to extract a member from such a tuple expression will pick the appropriate sub-element
- Dereference a tuple by dereferencing the primary expression
- Expand a tuple in the argument list to a call into N arguments (by recursively flattening the tuple)
- Don't create tuple types when not generating GLSL
- Make sure to preserve the specialized type of a call expression through lowering, since emission of unchecked calls relies on that info.
- TODO: maybe the infix/prefix/postifx/select information should come in as a side-band? Should we have modifiers on expressions?
- Make sure to offset the layout for a nested field based on teh base offset of its parent variable, when generating declarations for nested fields
|
|
Actually output SPIR-V/DXBC assembly as text, instead of binary.
This fixes a bunch of tests that were passing on accident, because nothing was producing output.
|
|
I haven't tried to be 100% exhaustie, but this should cover the main cases we are likely to encounter in library code.
|
|
This helps avoid the problem where we emit a function that does a `discard` and thus get a GLSL compilation failure in a vertex shader (that doesn't even call the function).
|
|
EntryPointResult/TranslationUnitResult, added helper functionality; Ensure null termination when printing raw data
|
|
|
|
The emit logic was checking for a missing decl, and then asking that same (missing) declaration for its name.
|
|
I forgot to include a trailing space.
|
|
This was mostly just a missing `typedef` in the Slang standard library code.
This should also cover `textureBuffer` and `samplerBuffer`.
|
|
- Try to handle `ErrorType` gracefully when computing type layouts
- When outputting a `TypeExp`, if the type part is errorneous (or missing), try to use the expression part
- Make sure to lower the expressions side of a `TypeExp` during lowering
|
|
I hadn't been lowering `SV_Position` outputs to `gl_Position`, and had somehow been relying on hidden driver behavior that I guess made things Just Work.
This change adds some infrastructure to handle `SV_` semantics during lowering of an entry point (currently only covering `SV_Position` and `SV_Target`, FWIW).
As a byproduct, this also means that a `VarLayout` stores semantic info, which could conceivably be exposed through reflection data now.
|
|
- Allow a code-generation target of `NONE` in order to suppress ordinary output in test cases where we don't care about the actual output (just pass/fail result)
- Add explicit `location` layout qualifiers to intermediate vertex-to-fragment variables in GLSL test cases for rendering, to work around apparent Intel driver bugs.
|
|
- Add GLSL mappings for more `Texture*` methods
- The annoying one here is `Texture*.Load()` because it doesn't take a sampler, but the GLSL equivalent needs one (while the SPIR-V does *not*). I've hacked this pretty seriously for now.
- Try to ensure that we add `uniform` to global declarations that need it in GLSL
- When outputting an `in` or `out` variable that might have been created from an `inout` shader parameter, filter the layout qualifiers that we output to only cover the appropriate resource kind.
|
|
If the user had a shader entry point with an `inout` parameter, we would end up lowering it to two GLSL global variables with the same name.
This change adds a `SLANG_in_` or `SLANG_out_` prefix to the two declarations.
Note: I haven't dealt with the issue that we end up printing two different `layout` qualifiers on such a variable...
|
|
The earier changes to add sequence statements and change how the `isBuildingStmt` logic in lowering works doesn't work for this logic, which assumes it can just set `isBuildingStmt` and be sure that decls will go into the right place.
|
|
The tricky bit here was that the `reflection-json` output format isn't really a code generation target like the others, and we need to be able to have multiple "targets" active to make sense of it. This needs cleaning-up.
|
|
- Expand most queries that handle `TextureType` to handle `TextureTypeBase`, in hopes that this covers most uses of `image*` types in Vulkan GLSL
- Adopt the quick fix from Falcor to return read-write access for shader-storage-block types. Something more comprehensive is probably needed if people want to do queries on these, since constant buffers should really be included, then.
|
|
Adding an explicit AST node for `(expr)` was a good change, but it broke constant folding because I forgot to handle it.
|
|
Code in Slang that is cross-compiled *might* introduce declarations that collide with language keywords that are reserved in the target.
This was previously being dealth with during final code emission, but the challenge there is that we want to allow user code that is being "rewritten" to use whatever identifiers it wants (they know better than us what is an error), and only apply renaming to our own code.
The approach here is to apply renaming during lowering - we validate each declaration to make sure its name is valid. Any expressions/types that refer to those declarations will automatically get emitted with the new name (while unchecked expressions will continue to be emitted with their existing name).
This isn't quite perfect, since we could in theory still rename a declaration in user code.
A more robust version down the line would try to determine if a declaration was nested inside code for the "rewriter."
Also note that this does *not* deal with any issues of name conflicts that might arise between modules. That would require a more complete and robust renaming pass, which seems tricky for me to pull off.
|
|
If the user doesn't use any `import` declarations, there is no reason to parse their code at all, so having the option of falling back to `UnparsedStmt` can potentially save us some headaches down the road.
The new rule now is that if you have the "no checking" flag on, *and* the parser hasn't yet seen any `import` declarations, then it still used `UnparsedStmt` to avoid touching function bodies.
Otherwise, I go ahead and parse function bodies, and assume I can rewrite any code I can semantically understand.
|