98b3e5b | Tim Foley | 11 July 2017, 16:57:13 UTC | Merge pull request #70 from tfoleyNV/support-more-sv-semantics Support more sv semantics | 11 July 2017, 16:57:13 UTC |
1b6af03 | Tim Foley | 10 July 2017, 19:17:36 UTC | Add GLSL translations for many `SV_*` semantics I haven't tried to be 100% exhaustie, but this should cover the main cases we are likely to encounter in library code. | 11 July 2017, 16:38:28 UTC |
d86748d | Tim Foley | 10 July 2017, 18:31:16 UTC | Don't emitting an imported declaration unless it is used. 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). | 11 July 2017, 16:38:28 UTC |
7d2c2f1 | Tim Foley | 10 July 2017, 18:19:00 UTC | Update `.gitignore` to deal with render-test output The rule of thumb so far is that expected output for `.slang` files should be checked in, but not for `.hlsl` or `.glsl`. The render test breaks that rule, because we never want to check in the expected output. | 11 July 2017, 16:38:28 UTC |
a923aff | Tim Foley | 11 July 2017, 02:45:21 UTC | Merge pull request #67 from kyaoNV/spirv SPIR-V Support | 11 July 2017, 02:45:21 UTC |
22c7a4d | Kai-Hwa Yao | 11 July 2017, 00:44:14 UTC | Removed spGetTranslationUnitCode; Unified EntryPointResult/TranslationUnitResult, added helper functionality; Ensure null termination when printing raw data | 11 July 2017, 00:54:50 UTC |
61a816c | Kai-Hwa Yao | 10 July 2017, 21:11:26 UTC | Don't assume vector contains contents | 11 July 2017, 00:49:35 UTC |
7c0ebee | Kai-Hwa Yao | 10 July 2017, 20:50:16 UTC | Refactored compile output to work with raw data instead of Strings | 11 July 2017, 00:49:35 UTC |
4bb88c4 | Kai-Hwa Yao | 10 July 2017, 05:58:41 UTC | Allow glslang wrapper to output regular SPIRV before disassembly | 11 July 2017, 00:49:35 UTC |
5577e2d | Tim Foley | 10 July 2017, 22:06:14 UTC | Merge pull request #69 from tfoleyNV/falcor-fixes Handle function name properly for unchecked call | 10 July 2017, 22:06:14 UTC |
f8c6905 | Tim Foley | 10 July 2017, 22:02:47 UTC | Handle function name properly for unchecked call The emit logic was checking for a missing decl, and then asking that same (missing) declaration for its name. | 10 July 2017, 22:02:47 UTC |
d24eaa5 | Tim Foley | 10 July 2017, 21:20:25 UTC | Merge pull request #68 from tfoleyNV/static-bug-fix Fix emission of `static` for HLSL | 10 July 2017, 21:20:25 UTC |
1669b43 | Tim Foley | 10 July 2017, 21:18:44 UTC | Fix emission of `static` for HLSL I forgot to include a trailing space. | 10 July 2017, 21:18:44 UTC |
3c92fed | Tim Foley | 10 July 2017, 17:58:47 UTC | Merge pull request #66 from tfoleyNV/falcor-work Falcor work | 10 July 2017, 17:58:47 UTC |
d6d49ea | Tim Foley | 10 July 2017, 17:52:30 UTC | Add support for `imageBuffer` This was mostly just a missing `typedef` in the Slang standard library code. This should also cover `textureBuffer` and `samplerBuffer`. | 10 July 2017, 17:52:30 UTC |
b2fb0f7 | Tim Foley | 10 July 2017, 17:44:02 UTC | Try to be more robust against un-checked types during lowering, etc. - 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 | 10 July 2017, 17:44:02 UTC |
8abdf2d | Tim Foley | 10 July 2017, 16:49:46 UTC | Merge pull request #65 from tfoleyNV/falcor-work Falcor work | 10 July 2017, 16:49:46 UTC |
5b7c254 | Tim Foley | 10 July 2017, 16:29:11 UTC | Start handling system-value semantics 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. | 10 July 2017, 16:29:11 UTC |
7af89d1 | Tim Foley | 10 July 2017, 16:04:50 UTC | Cleanups for test cases: - 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. | 10 July 2017, 16:04:50 UTC |
0e220da | Tim Foley | 10 July 2017, 15:34:52 UTC | More cross-compilation fixes - 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. | 10 July 2017, 15:34:52 UTC |
928cc86 | Tim Foley | 10 July 2017, 02:42:35 UTC | Ensure that lowered globals for `inout` shader parameters have unique names 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... | 10 July 2017, 02:42:35 UTC |
8aa0dcf | Tim Foley | 10 July 2017, 01:38:46 UTC | Fix up scoping for cross-compiled `main()` body 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. | 10 July 2017, 01:38:46 UTC |
064c28f | Tim Foley | 10 July 2017, 01:08:22 UTC | Pick layout rules based on target languge, not source. 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. | 10 July 2017, 01:08:22 UTC |
54364eb | Tim Foley | 10 July 2017, 00:09:58 UTC | Some quick fixes to reflection API to try to help Falcor - 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. | 10 July 2017, 00:09:58 UTC |
68df74b | Tim Foley | 09 July 2017, 01:58:42 UTC | Merge pull request #60 from tfoleyNV/revise-rewriter Revise rewriter | 09 July 2017, 01:58:42 UTC |
767d47a | Tim Foley | 09 July 2017, 01:13:53 UTC | Fix constant folding for `ParenExpr` Adding an explicit AST node for `(expr)` was a good change, but it broke constant folding because I forgot to handle it. | 09 July 2017, 01:22:26 UTC |
5c864cb | Tim Foley | 09 July 2017, 01:05:02 UTC | Move renaming logic to lowering pass. 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. | 09 July 2017, 01:22:26 UTC |
780a0bc | Tim Foley | 09 July 2017, 00:47:31 UTC | Add back `UnparsedStmt` 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. | 09 July 2017, 01:22:26 UTC |
a40b667 | Tim Foley | 09 July 2017, 00:21:37 UTC | Differentiate HLSL `for` loops in AST HLSL has the bad scoping behavior for `for` loops, and we need to respect that. But, we need to have correct scoping for GLSL, and we'd like it for Slang. We also need to ensure that `for` loops written in a "correct" language get the correct behavior when emitted as HLSL. There was already code to handle this in the emit pass, but it was unfortunately using an `isRewrite` flag to try to tell if the HLSL behavior was wanted. This doesn't work when the code being emitted might come from a mix of languages. This change adds a distinct `UnscopedForStmt` syntax node type, and uses that when parsing HLSL input (bot not for other languages). We make sure to preserve this node type through lowering, and then specialize our emit logic on this case. With this, there are no more remaining uses of `isRewrite` in the emit logic, which is good because it didn't mean what I needed it to mean any more (since we now emit only a single module, that was merged during lowering). | 09 July 2017, 01:22:26 UTC |
6233f9b | Tim Foley | 09 July 2017, 00:04:31 UTC | Revise how hidden implicit casts are recognized. The old approach used an `isRewriter` flag in the emit logic, but I kind of need that flag to go away. Instead, I now how the semantic checking pass detect whether an implicitly-generated type cast is in rewriter code, and if so it uses the new `HiddenImplicitCastExpr` AST node. The emit logic then looks for that specific node and eliminates it. | 09 July 2017, 01:22:26 UTC |
c77c039 | Tim Foley | 08 July 2017, 23:54:33 UTC | Revise the (only) rewriter-error test case This was testing that we let the downstream compiler report a parse error, but that is no longer a goal (because we need to rewrite function bodies to deal with type validation). I've switched it to a type error in the function body, and confirmed that we do let fxc report the problem. | 09 July 2017, 01:22:26 UTC |
836a998 | Tim Foley | 08 July 2017, 23:44:48 UTC | Try to emit expressions with minimal parentheses When emitting code it is easy to be overly defensive and emit tons of extra parentheses. In some cases these are just annoying, and make the output more cluttered than it needs to be. In other cases, though, being over-aggressive here can actually break things when a downstream compiler has more stringent requirements (e.g., doesn't allow a general expression for the function in a call expression, but only a particular set of atomic/postfix expressions). This wasn't as bad when we weren't parsing function bodies in user code, but now that we *are* it becomes important to not emit bad parentheses and screw up their code. At the same time, though, we don't want to fail to output them and silently break code. A nice property today is that we preserve parentheses in the input code, so hopefully we don't ever break operator precedence. The code already had an approach to avoid *some* parens, by tracking an "outer precedence" and only emitting parens for an expression if they were needed relative to this outer precedence. That approach doesn't handle associativity, and so it doesn't work for things like chains of postfix operators. The new approach basically tracks *two* outer precedence levels: one on the left, and one on the right. When recursing into a sub-expression of an op (e.g., the `A` in `A + B`) on of the precdence levels for the recursive call will come from the outer environment, and the other from the operation itself (e.g., `A` has `(X, +)` as its left/right precdence, where `X` is whatever was to the left of `A + B`, while `B` gets `(+,Y)`). One more piece of the puzzle is that an operator like `+` actually exposes *two* precedence levels: one for the left-hand side and one for the right-hand, so that if both `A` and `B` are themselves uses of `+`, `A` won't get parens, but `B` will. Finally, when we have an un-checked application of an operator (which our AST stores as something like a function-call node), we do a little lookup step to find the corresponding operator and its precedence (while for things that actually got resolved we *know* the precedence. | 09 July 2017, 01:22:25 UTC |
f69bc6c | Tim Foley | 07 July 2017, 21:30:26 UTC | Fully parse function bodies, even in "rewriter" mode This is in anticipation of needing to have more complete knowledge to be able to handle user code that `import`s library functionality. The big picture of this change is just to remove the `UnparsedStmt` class that was used to hold the bodies of user functions as opaque token streams, and thus to let the full parser and compiler loose on that code. That is the easy part, of course, and the hard part is all the fixes that this requires in the rest of the compielr to make this even remotely work. Subsequent commit address a lot of other issues, so this particular commit mostly represents work-in-progress. One detail is that this change puts a conditional around nearly every diagnostic message in `check.cpp` to suppress thing when in rewriter mode. I have yet to check how that works out if there are errors in anything we actually need to understand for the purposes of generating reflection data. | 09 July 2017, 01:18:36 UTC |
c07a6e6 | Tim Foley | 07 July 2017, 22:06:16 UTC | Merge pull request #59 from tfoleyNV/cross-compilation More work on cross compilation | 07 July 2017, 22:06:16 UTC |
f3fe9dd | Tim Foley | 07 July 2017, 20:34:23 UTC | Map HLSL `lerp` to GLSL `mix` - Also fix a bug in `emit.cpp` where I wasn't detecting `__intrinsic` remaps that don't include `$` (this is a byproduct of changing the string index type to be unsigned; other bugs like this may be lurking) | 07 July 2017, 20:34:23 UTC |
f70699c | Tim Foley | 07 July 2017, 20:27:00 UTC | Don't emit `[unroll]` or `[loop]` to GLSL - I really ought to make these semantically understood attributes, which might make this logic easier - Long-term if we start emitting SPIR-V directly, we should translte these, of course | 07 July 2017, 20:27:00 UTC |
20ac581 | Tim Foley | 07 July 2017, 20:15:08 UTC | Add GLSL equivalents for some stdlib operations. - Map HLSL `atan2(y,x)` to GLSL `atan(y,x)` - Add support for `$p` escape in `__intrinsic` modifier, which allows generating GLSL texture-sampler pairs more easily - Also added a `$o` escape to represent the base object in an OOP-style call (`obj.F(...)`) - This isn't used in the texture functions right now, because getting the right GLSL texture type in this context is a bit thorny (the prefix depends on the generic parameter being used) - Used the `$p` capability to add mappings for `SampleBias` and `SampleLevel` | 07 July 2017, 20:15:08 UTC |
c0bcb9c | Tim Foley | 07 July 2017, 19:31:38 UTC | Overhaul emit logic to use visitor abstraction - This is in preparation for splitting out HLSL vs. GLSL emit as different cases. - Along the way, I added more cases to the visitor implementation, to handle visitors with arguments - This is getting a bit busy, though, and we might be reaching the breaking point where a more general bit of meta-magic is needed to clean things up (either going further down the ugly template route, or plugging in a more real code generation strategy) | 07 July 2017, 19:37:15 UTC |
6da1782 | Tim Foley | 07 July 2017, 03:47:20 UTC | Don't emit the `static` keyword when generating GLSL GLSL doesn't support `static` at all, while HLSL uses it for multiple things: - To mark global variables that are "thread local" rather than shader parameters - In the C/C++ style to mark `static` allocation for variables inside a function or type The latter case needs to be handled during lowering (but isn't handled right now). The former case can be solved just by dropping the `static` keyword. | 07 July 2017, 17:00:25 UTC |
4921bdb | Tim Foley | 07 July 2017, 03:40:42 UTC | Eliminate `typedef`s when lowering to GLSL GLSL doesn't support `typedef` declarations. The lowering code already lowered any named types (references to `typedef`s) to their underlying definition when targetting GLSL. This changes makes sure that we also don't generate any lowered output for `typedef` declarations in the source program. | 07 July 2017, 17:00:24 UTC |
56b44cb | Tim Foley | 07 July 2017, 16:57:26 UTC | Fix up visitor approach. The existing code used a catch-all `visit()` method, and then relied on overloading to find the right version (allowing fallback to a `visit()` method taking a base-class parameter). This approach works, but has some big down-sides: - When browsing the code, you have a bunch of identically-named methods, and it can be hard to find the one you want. - It is impossible to use inheritance to implement fallback for `visit()` methods, because *any* method in the derived class with that name hides *all* methods with the same name in a base class This change makes the `visit()` methods use the name of the corresponding syntax class, and then has visitors inherit the fallback methods they need from the base visitor template class. | 07 July 2017, 16:57:26 UTC |
975e4b3 | Tim Foley | 07 July 2017, 16:14:18 UTC | Merge pull request #58 from tfoleyNV/bug-57 Bug 57 | 07 July 2017, 16:14:18 UTC |
c47f23c | Tim Foley | 07 July 2017, 15:50:00 UTC | Merge pull request #56 from tfoleyNV/bug-55 Bug 55 | 07 July 2017, 15:50:00 UTC |
d35b4d4 | Tim Foley | 07 July 2017, 15:48:45 UTC | Fix support for `std430` layout Fixes #57 There were a bunch of issues in how `std430` was being implemented, largely due to just stubbing it in without any test cases. This commit adds a reasonably good test case to ensure that we've got things basically working. | 07 July 2017, 15:48:45 UTC |
d644ddc | Tim Foley | 07 July 2017, 15:37:39 UTC | Add some reflection support for SSBO and `tbuffer` declarations These are mostly copy-pasted from the existing `cbuffer` support, so there might be details I'm missing. | 07 July 2017, 15:37:39 UTC |
54519ed | Tim Foley | 07 July 2017, 15:16:09 UTC | Fix alignment computation for `std140` uniforms Fixes #55 I was incorrectly computing alignment as `elementSize * elementAlignment`, rounded up to a power of two (which works out to be `elementSize` squared), when I should have been using `elementSize * elementCount`, rounded up to a power of two. | 07 July 2017, 15:16:09 UTC |
b6c299e | Tim Foley | 07 July 2017, 15:14:01 UTC | Handle new parameter category cases in reflection JSON emit This logic hadn't been updated for Vulkan GLSL. | 07 July 2017, 15:14:01 UTC |
0f1d661 | Tim Foley | 07 July 2017, 15:13:27 UTC | Fix typo in parameter category name `SPECIALIZTION` -> `SPECIALIZATION` | 07 July 2017, 15:13:27 UTC |
32deeef | Tim Foley | 07 July 2017, 15:12:50 UTC | Fix signed/unsigned comparison warning. | 07 July 2017, 15:12:50 UTC |
af8c0ea | Tim Foley | 06 July 2017, 20:15:26 UTC | Merge pull request #54 from tfoleyNV/falcor-fixes Fix issues found during testing of v0.4.0 with Falcor | 06 July 2017, 20:15:26 UTC |
9795ed6 | Tim Foley | 06 July 2017, 19:58:23 UTC | Fix bug in `String::To{Upper|Lower}` These were accidentally calling the version of `String::append()` that takes an `int` and prints its decimal value, rather than the version that takes a `char` and appends the corresponding ASCII character. | 06 July 2017, 19:58:23 UTC |
098a544 | Tim Foley | 06 July 2017, 19:30:19 UTC | More exhaustive lowering - Handle all statement cases explicitly (rather than falling back to the "structural recursion" mess) - Handle back-references from child statements to their parents | 06 July 2017, 19:30:19 UTC |
e05fba9 | Tim Foley | 06 July 2017, 18:29:59 UTC | Add missing declaration types to lowering pass. Most of these are cases we don't expect to encounter, but the big missing one was `TypeDefDecl`. | 06 July 2017, 18:29:59 UTC |
03de737 | Tim Foley | 06 July 2017, 18:11:01 UTC | Fix many warnings-as-errors issues. The code should now compile cleanly with warnings as errors for VS2015 with `W3`. Most of the changes had to do with propagating a real pointer-sized integer type through code that had been using `int`. | 06 July 2017, 18:18:09 UTC |
21a14cb | Tim Foley | 06 July 2017, 16:52:53 UTC | Merge pull request #53 from tfoleyNV/cross-compilation Initial work on cross-compilation | 06 July 2017, 16:52:53 UTC |
f145e09 | Tim Foley | 28 June 2017, 20:34:38 UTC | Start to support cross-compilation via "lowering" pass - The big change here is the introduction of a "lowering" pass that takes an input AST from the semantic checker, and produces an output AST suitable for emitting. The intention is that he lowering pass is responsible for: - Stripping out unused code (when we have enough information to do so), by only outputting declarations that are transitively references from an entry point - When cross-compiling to GLSL, generating a suitable `void main()` entry point to wrap the user-written entry-point function - (Eventually) legalizing types in the program, by scalarizing aggregate types that mix uniform and resource types - (Eventually) instantiating generic declarations so that the resulting code only deals with fully specialized declarations - (Eventually) de-sugaring OOP constructs into basic "structs and functions" form - (Eventually) instantiating code that depends on interface types at the concrete types chosen - It is clear that there is still a lot of work to be done there, to this change is really about getting infrastructure in place without breaking the existing test cases. - One cleanup here is that we get rid of the idea of whole-translation-unit output, since that was specific to HLSL output, and there is really no strong reason for keeping it. Users should now just ask for the output for each entry point that they wanted to generate. - The biggest source of complexity for the lowering process is that it needs to produce the same AST structure as the input, to deal with the complexity of the rewriter case. That is, we need the output to be able to reproduce the input exactly in the case where we are rewriting and nothing needs to change, so the output format needs at least the degrees of freedom of the input. - As a result, we end up having to distinguish "rewriter" and "full" modes in both lowering and code-emit steps, so that we can react appropriately. - Generating a GLSL `main()` also adds a lot of complexity. Right now I'm using the simplest approach, where we always output the Slang/HLSL entry point as an ordinary function (as written) and then emit a simple GLSL `main()` to call it. I generate globals for all the shader inputs/outputs (these need to be scalarized and have explicit `location`s attached), and then collect these into the `struct` types of the original parameters as needed. - This approach will start to have some major down-sides once we have to deal with "arrayed" input/output - A long-term question here is how to replace entry-point parameter types with scalarized and/or "transposed" versions, while still letting the original code work as written (including copying those inputs to temporary arrays) - Split `BlockStatementSyntaxNode` into: - `BlockStmt` which just provides a scope around a `body` statement - `SeqStmt` which just allows multiple statements to be treated as one - Change how we emit `for` loops, to deal with the case where the initialization part might expand into multiple statements - Basically `for(A;B;C) {D}` becomes `{A; for(;B;C) {D}}`, so we can handle arbitrary statements for `A` - As an additional wrinkle, when we are rewriting HLSL, we just generate `A; for(;B;C) {D}` to deal with the broken scoping there - This change is needed because the lowering pass was sometimes expanding the original initialization statement `A` into a block `{A}`. Certainly if it declared multiple variables we'd need to handle it, and this seemed the easiest way - A more significant challenge for lowering would come if/when we ever wanted to support true short-circuiting behavior for `&&` and `||` - For right now I'm not changing the behavior of the "rewriter" mode, so we still have `UnparsedStmt` instances being generated, but it is clear that eventually we need to parse *all* input, even if we can't type-check 100% of it. This is required so that we can rewrite user code that might refer to a shader input with interface type. | 06 July 2017, 16:17:04 UTC |
c0d2c17 | Tim Foley | 28 June 2017, 20:34:21 UTC | Add initial cross-compilation test case. | 30 June 2017, 20:39:30 UTC |
f313df3 | Tim Foley | 30 June 2017, 20:12:50 UTC | Merge pull request #52 from tfoleyNV/syntax-meta Add meta-definitions for AST types | 30 June 2017, 20:12:50 UTC |
cab694d | Tim Foley | 29 June 2017, 15:55:09 UTC | Add meta-definitions for AST types - The big change here is that all the definitions for syntax-node classes have been macro-ized, to that we can do light metaprogramming over them - The use of macros for this has big down-sides, but I'm not quite ready to do anything more heavy-weight right now - The macro-ized definitions can be included multiple times, to generate different declarations/code as needed - The first example of using this meta-programming facility is a new visitor system - The actual visitor base classes and the dispatch logic are all generated from the meta-files - There was only one visitor left in the code: the semantics checker, so that was ported to the new system. - All current test cases pass, so *of course* that means all is well. | 30 June 2017, 19:22:33 UTC |
b2b0867 | Tim Foley | 29 June 2017, 21:16:38 UTC | Merge pull request #51 from tfoleyNV/refptr-string-cleanup Overhaul `RefPtr` and `String` | 29 June 2017, 21:16:38 UTC |
f4d900d | Tim Foley | 29 June 2017, 18:50:55 UTC | Overhaul `RefPtr` and `String` - `RefPtr` no longer tries to have distinct cases for interal-vs-external reference counts. Instead we always require an internal reference count. - Types the used `RefPtr` but weren't `RefObject` were made to inherit `RefObject` - The `ReferenceCounted` base class was removed, so that only `RefObject` remains - Implicit conversion from `RefPtr<T>` to `T*` added - This created some complicates for other types that relied on implicit conversions, so this isn't a net cleanup right now - The main type that got messed up by the above was `String`, which previously held a `RefPtr<char, ...>`. This change thus *also* includes a major overhaul of `String`: - `String` now holds all its data via indirection, using a `StringRepresentation` that is a `RefObject`. This object holds a length, capacity, and directly stores the character data in its allocation. This means that `sizeof(String)==sizeof(void*)` - It is now possible to directly mutate a `String` by appending to its representation (we just need to ensure it has a reference count of `1`, possibly by cloning it). This means that `StringBuilder` is now basically just an idomatic use of `String` - A couple operations that just return sub-ranges of a `String` now return `StringSlice` to avoid allocation when it isn't needed. This required more work. - Indices into strings changed from `int` to `UInt` (which is pointer-sized). This had a bunch of follow-on changes because the value `-1` sometimes needs to be special-cased in code that uses indices. Further cleanups are probably needed here. | 29 June 2017, 20:18:32 UTC |
16613ed | Tim Foley | 28 June 2017, 19:17:47 UTC | Merge pull request #50 from tfoleyNV/literal-fix-fix Store integer literals at high precision in AST | 28 June 2017, 19:17:47 UTC |
ff53669 | Tim Foley | 28 June 2017, 18:39:40 UTC | Store integer literals at high precision in AST The lexer was creating an `unsigned long long` value, and then the AST was storing it in an `int`. This change makes both use a `long long`. This is obviously still a stopgap until I can get arbitrary precisions in here. | 28 June 2017, 18:51:23 UTC |
b8e3168 | Tim Foley | 28 June 2017, 18:26:02 UTC | Merge pull request #48 from tfoleyNV/literal-suffix-fix Fix handling of literal suffixes | 28 June 2017, 18:26:02 UTC |
d601921 | Tim Foley | 28 June 2017, 17:20:16 UTC | Actually respect suffixes on numeric literals. - Add logic to extract the value and suffix from a numeric literal - This duplicates some of the lexing logic, but this is hard to avoid without redundant runtime work - Note that I'm not using and stdlib string-to-number code. This should be more robust once it is working, but it is obviously error prone in the near term. The main up-sides to this are: - We can handle binary integer literals - We can handle hexadecimal floating-point literals without stdlib support - We can hypothetically support digit separators, if we ever wanted - The parser looks at the suffix characters sliced off by the lexer, and tries to pick a type to use for a literal - It uses `NULL` if there is no suffix, to avoid some nasty order dependencies where the stdlib might need to parse a number before it has seen the definition of `int` - Right now I only handle a few cases, so there may be bugs lurking here - The emit logic needs to handle the fact that a literal node in the AST might have a non-default type attached. - Right now I just quickly check for the most likely types, and emit the literal with a matching suffix. This doesn't seem robust if any source language supports a suffix for a type where a target has no corresponding suffix. In the long term some amount of casting is probably required. | 28 June 2017, 18:08:03 UTC |
4b3936e | Tim Foley | 28 June 2017, 15:49:04 UTC | Rename literal tokens. These had a typo (`Literial`), so they needed a fix eventually. I also went ahead and made things a bit more verbose (`IntegerLiteral`, `FloatingPointLiteral`) because these names don't get used often enough for the brevity to pay off. | 28 June 2017, 15:49:04 UTC |
afe41a6 | Tim Foley | 27 June 2017, 21:43:53 UTC | Merge pull request #47 from tfoleyNV/import-subdir Allow "dotted" import paths | 27 June 2017, 21:43:53 UTC |
9eee117 | Tim Foley | 27 June 2017, 21:22:01 UTC | Allow "dotted" import paths The code: __import foo.bar; will try to import from a file matching "foo/bar.slang". I also went ahead and allowed a raw string literal in and import: __import "foo/bar"; (In the latter case, an explicit `/` must be used instead of `.`) | 27 June 2017, 21:22:01 UTC |
97f2531 | Tim Foley | 27 June 2017, 18:13:21 UTC | Merge pull request #46 from tfoleyNV/import-exported Allow for re-export of an `import` declaration | 27 June 2017, 18:13:21 UTC |
31293d6 | Tim Foley | 27 June 2017, 17:24:25 UTC | Allow for re-export of an `import` declaration If module `A.slang` contains `__exported __import B;` then any declarations from `B.slang` will be visible to any client code that does `__import A;`. This allows a user to make a single "umbrella" file that encompases a bunch of code files. Note that this really only affects scoping during Slang compilation/checking; at code generation time everything always gets emitted as raw HLSL/GLSL so that names will be visible whether we want them to be or not. | 27 June 2017, 17:24:25 UTC |
1716208 | Tim Foley | 27 June 2017, 16:36:19 UTC | Merge pull request #45 from tfoleyNV/emit-imported-parameters Emit global-scope parameters from imported files. | 27 June 2017, 16:36:19 UTC |
996d4dc | Tim Foley | 27 June 2017, 16:13:19 UTC | Emit global-scope parameters from imported files. This fixes up a bug in the earlier change that provided reflection for imported parameters; I'd failed to confirm that the code generation logic can handle imported parameters correctly. The main fix was to have an `import` declaration automatically use the global-scope layout already determined, sine imported parameters will in general appear there. | 27 June 2017, 16:13:19 UTC |
8824b10 | Tim Foley | 26 June 2017, 21:31:31 UTC | Merge pull request #44 from tfoleyNV/string-literal-parsing-fix Fix parsing of string literals. | 26 June 2017, 21:31:31 UTC |
7d97d42 | Tim Foley | 26 June 2017, 21:09:53 UTC | Fix parsing of string literals. String literals can be used as part of attributes, but we lacked an actual AST representation for them. This change adds basic parsing for string literals, as well as emit logic for them. I also included a fix for parsing of chained right-associative operators. To test these fixes, I've re-enabled one of the HLSL tests I disabled a while back. It would be good to go through and see how many of those we can re-enable now. | 26 June 2017, 21:14:06 UTC |
0259ddb | Tim Foley | 26 June 2017, 20:47:08 UTC | Merge pull request #43 from tfoleyNV/import-macros Add support for `#import` | 26 June 2017, 20:47:08 UTC |
f6cb66f | Tim Foley | 26 June 2017, 17:52:31 UTC | Check for re-import at translation-unit level Previously the code checked for a duplicate `#import` using a data structure attached to the compile request, but this would fail for nested imports. It also wouldn't work for a combination of `#import` and `__import`. This change makes it so that we instead track a set of already-imported modules in the semantic checking visitor, which is instantiated once per translation unit. We also key this set on the actual module (AST) imported, rather than on path/name/whatever, so hopefully it will be robust to the same thing getting imported multiple ways. | 26 June 2017, 19:17:49 UTC |
6e99b81 | Tim Foley | 26 June 2017, 17:11:00 UTC | Make `#import` work with preprocessor macros With this change, there is now a meaningful semantic difference between `__import` and `#import`. An `__import` compiles the target file in a fresh environment, only providing it any macro definitions passed via command line or API. Any macros defined in the imported file are not made visible at the import site. One can think of an `__import` as a bit like `using namespace` in C++. A `#import` will tokenize the input in the same preprocessor environment as the importing file, and any macros defined along the way will be visible in the parent file. It is a *bit* like a `#include` with two big differences: - The imported code is always parsed as Slang, and as its own module with default flags, etc. (so semantic checks are on even if we are in "rewriter" mode). It is pulled into the outer namespace just as for `__import`. - A given file will only get `#import`ed once for a translation unit, so it behaves a bit like there is an implicit `#pragma once` in the target file | 26 June 2017, 19:06:54 UTC |
7d3bfe4 | Tim Foley | 26 June 2017, 16:32:40 UTC | Replace "auto-import" with `#import` Right now `#import` only differs from `#include` in that it takes a string literal for a file name instead of a raw identifier (to which `.slang` gets appended). The next step is to make `#import` respect preprocessor state, while `__import` doesn't. | 26 June 2017, 19:06:54 UTC |
3f316dc | Tim Foley | 26 June 2017, 19:04:54 UTC | Merge pull request #42 from tfoleyNV/reflect-imported Reflect imported code | 26 June 2017, 19:04:54 UTC |
07f9b9e | Tim Foley | 26 June 2017, 18:37:09 UTC | Add expected output file for test. This is the cause of the test failures on AppVeyor. | 26 June 2017, 18:37:09 UTC |
0df1cca | Tim Foley | 26 June 2017, 18:13:27 UTC | typo | 26 June 2017, 18:13:27 UTC |
3609c40 | Tim Foley | 26 June 2017, 17:55:19 UTC | Turn on some debug output for AppVeyor test failure. | 26 June 2017, 17:55:19 UTC |
c16fc84 | Tim Foley | 26 June 2017, 16:07:07 UTC | Include imported code when generating reflection data - The basic idea is simple: be sure to enumerate code in `__import`ed modules when generating reflection info - Note that we don't currently allow an entry point to appear in an imported module, so we only consider globlal-scope parameters - Although there isn't currently a real implementation of namespacing, I went ahead and ensured that parameters in imported modules are treated as distinct from parameters in the user's code, even if they have the same name. | 26 June 2017, 17:31:43 UTC |
d506737 | Tim Foley | 22 June 2017, 22:32:42 UTC | Merge pull request #39 from tfoleyNV/vector-constructors Standard library additions + supporting features | 22 June 2017, 22:32:42 UTC |
1eb5a1b | Tim Foley | 21 June 2017, 18:34:56 UTC | Revamp definitions of texture `Load` and `GetDimensions` These are annoyingly subtle. | 21 June 2017, 18:59:52 UTC |
c92d06c | Tim Foley | 21 June 2017, 18:23:04 UTC | Bug fix: correct attribute on `operator~` The operator was being declared as `IntrinsicOp::Not` when it should be `IntrinsicOp::BitNot` | 21 June 2017, 18:59:52 UTC |
bdfe06d | Tim Foley | 21 June 2017, 18:18:33 UTC | Emit: Add support for `while` and `do {} while` statements These were being passed over by the emit logic because I didn't have tests that used them. | 21 June 2017, 18:59:52 UTC |
7f7864e | Tim Foley | 21 June 2017, 17:43:25 UTC | Support texture `Gather*()` operations The catch with these operations is that they return a vector based on the scalar of the element type of the texture. That is, given `Texture2D<float> t` the operation `t.GatherRed(...)` should return a `float4`. The ideal way to solve this would use associated types, but we aren't there yet, so I am using extension declarations. An extension can "capture" the identity of the element type, like so: __generic<T, let N : int> __extension Texture2D<vector<T,N> > { ... } That extension will match `Texture2D<float3>` and correctly capture `T == float`, so that we can use it in other operations. Getting this working required a bunch of changes: - Actually emit the relevant extension declarations in the stdlib - Fix the parser to be able to parse `Texture2D<vector<T,N> >` (that is, a nested generic app). - I actually went ahead and significantly overhauled the expression parser while I was there, because I just couldn't deal with the existing code any longer. - Added support for general-case lookup to look through `__extension` declarations. I had logic in place to special-case this for looking up "constructors" but hadn't done anything for general member lookup yet. - This required some annoying holes to be punched through the layers, because lookup might need to invoke semantic analysis to ensure that an extension has been checked. - There is some first-pass code trying to support looking up a `typedef` nested inside the `vector` type. This is a nice idea in principle, but the problem is that the `Texture2D<T>` definition would be looking up `T.Element` and not `float4.Element`, and that means we'd need machinery for doing lookup *through* interface conformances for a type parameter like `T` The big gotcha here is that none of this logic applies to `Texture2D<float>` (the original case I mentioned) because I am matching vector types and not scalars. Matching scalars *should* be as easy as: __generic<T : __BuitlinScalarType> __extension Texture2D<T> { ... } But I'd need to confirm that interface constraints like that actually work, or else that extension would *also* apply to `Texture2D<float4>` and break everything. | 21 June 2017, 18:59:51 UTC |
5148c59 | Tim Foley | 20 June 2017, 21:38:50 UTC | HLSL/Slang standard library additions - Vector constructors that take two vectors that add up to the target size (`float4(float2, float2)`) - I now realize I implemented the general case here, but there really is only the one case... - Geometry shader output stream types now have `Append()` and `RestartStrip()` methods | 20 June 2017, 21:38:50 UTC |
5170a56 | Tim Foley | 20 June 2017, 21:17:15 UTC | Merge pull request #37 from tfoleyNV/falcor-work Falcor work | 20 June 2017, 21:17:15 UTC |
d852ad9 | Tim Foley | 20 June 2017, 20:57:46 UTC | Only emit each `import`ed module once. If the user imports a module along more than one path, we need to make sure we don't emit the code twice. I handle this by keeping a set of already-emitted modules. Down the line, a more robust code generation strategy for non-"rewriter" use cases would be handling this at the per-declaration level, and this logic wouldn't really be needed. | 20 June 2017, 20:57:46 UTC |
4313db8 | Tim Foley | 20 June 2017, 20:57:20 UTC | Add a useful source location to `typedef` declarations This was just missing logic in the parser. | 20 June 2017, 20:57:20 UTC |
3d29c90 | Tim Foley | 20 June 2017, 19:52:12 UTC | Check `import` decls before all others. This helps ensure that we pull things into scope at the right time. | 20 June 2017, 19:52:12 UTC |
338232b | Tim Foley | 20 June 2017, 19:14:31 UTC | Merge pull request #36 from tfoleyNV/entry-point-indexing Overhaul handling of entry points and translation units. | 20 June 2017, 19:14:31 UTC |
327f2b7 | Tim Foley | 20 June 2017, 15:11:27 UTC | Overhaul handling of entry points and translation units. The main user-visible change here is that instead of `spAddTranslationUnitEntryPoint` we have `spAddEntryPoint`, to reflect that the list of entry points is "global" to a compile request. As a result, `spGetEntryPointSource` now only needs the entry point index, and not the translation unit index. There are a bunch more behind-the-scenes changes, though, reflecting a streamlining of the concepts related to compilation into a smaller number of classes. Now there is: - `Session` (unchanged) to manage the lifetimes of shared stuff like the stdlib - `CompileRequest` (merges in `CompileOptions`) to handle all the lifetime related to a single invocation of the compiler - `TranslationUnitRequest` (merges `TranslationUnitOptions`, `CompileUnit`) to represent a single translation unit ("module") that the user is trying to compile. This is a single file for HLSL/GLSL, but can be multiple files for Slang. - `EntryPointRequest` (merges `EntryPointOption` and a bit of `EntryPointResult`) to track a single entry point that the user is asking to compile (that entry point always comes from a single translation unit) A lot of functions used to take some combination of these and end up with really long signatures. I've given most of the objects "parent" pointers so that they can get back to all the context they need, so most functions don't need as many parameters. It may eventually be important to tease these apart again, in particular: - The code-generation side of things (the `*Result` types) might need to be pulled out in case we want to codegen multiple times from the same AST - Similarly, the layout stuff may also need to be pulled out, in case we want to lay things out multiple times with different rules. | 20 June 2017, 18:54:35 UTC |
40617db | Tim Foley | 20 June 2017, 16:54:38 UTC | Merge pull request #35 from tfoleyNV/input-patch-type-fix Fix types for `InputPatch` and `OutputPatch` | 20 June 2017, 16:54:38 UTC |
c163c33 | Tim Foley | 20 June 2017, 16:24:31 UTC | Fix types for `InputPatch` and `OutputPatch` Fixes #34. I'd declared these as if they were `InputPatch<T>`, but they are really `InputPatch<T,N>`. This change fixes the declarations, and makes these types no longer inherit from the contrived `BuiltinGenericType`. Instead they are more-or-less ordinary `DeclRefType`s using the same approach that `MatrixExpressionType` uses. | 20 June 2017, 16:35:51 UTC |
5b85b51 | Tim Foley | 19 June 2017, 21:42:18 UTC | Merge pull request #32 from tfoleyNV/line-directives Line directives | 19 June 2017, 21:42:18 UTC |
110b0b3 | Tim Foley | 19 June 2017, 21:26:49 UTC | Merge pull request #33 from tfoleyNV/preprocessor-bug-fixes Fixes for preprocessor conditionals that use macros | 19 June 2017, 21:26:49 UTC |
01cdb43 | Tim Foley | 19 June 2017, 21:26:41 UTC | Merge pull request #31 from tfoleyNV/escaped-newlines Bug fix for newline escaping. | 19 June 2017, 21:26:41 UTC |