https://github.com/shader-slang/slang

sort by:
Revision Author Date Message Commit Date
652a3c9 Fix a bug in import handling (#394) The recent change that removed `#import` accidentally introduced a regression that made *any* code that imports the same module in more than one place fail. I'm just fixing the bug for now to unblock users, but this should really get a regression test. 01 February 2018, 22:41:34 UTC
4583e39 Implement type splitting for raw buffers (#393) * Fix render-test to handle raw buffers I don't know if this fix will work for UAVs that are neither structured nor raw, but it fixes the code that currently only really works if every UAV is structured (since it doesn't set a format). * Make type legalization consider raw buffer types The type layout logic was already handling these, but the type splitting logic in legalization was failing to split structure types that contain, e.g., `RWByteAddressBuffer`. A compute test case has been added to confirm the fix. 01 February 2018, 20:06:06 UTC
b6bc083 Remove #import directive (#389) Fixes #380 The `#import` directive was a stopgap measure to allow a macro-heavy shader library to incrementally adopt `import`, but it has turned out to cause as many problems as it fixes (not least because users have never been able to form a good mental model around which kind of import to do when). This change yanks support for the feature. 30 January 2018, 00:32:52 UTC
06f0eff Fix handling of errors in imported modules (#387) * Fix handling of errors in imported modules - If a semantic error is detected in an imported module, then don't try to generate IR code for it - Also, if a module (transitively) imports itself, then report that as an error - The way I'm checking for this is a bit hacky (I'm adding the module to the map of loaded modules, but in an "unfinished" state, and then using that unfinished state to detect the import of a module already being imported). This isn't a 100% complete solution for any of the related problems, but it improves the user experience for the common case. * Remove #import test. The feature is slated to be removed, so it isn't worth fixing up this test case. 26 January 2018, 23:30:23 UTC
a050f4a Fix some crashing bugs around local variable declarations. (#385) The basic problem here arises when a local variable is used either before its own declaration: ```hlsl int a = b; ... int b = 0; ``` or when a local variable is used *in* its own decalration: ```hlsl int b = b; ``` In each case, Slang considers the scope of the `{}`-enclosed function body (or nested statement) as a whole, and so the lookup can "see" the declaration even if it is later in the same function. This behavior isn't really correct for HLSL semantics, so the right long-term fix is to change our scoping rules, but for now users really just want the compiler to not crash on code like this, and give an error message that points at the issue. This change makes both of the above examples print an error message saying that variable `b` was used before its declaration, which is accurate to the way that Slang is interpreting those code examples. This is currently treated as a fatal error, so that compilation aborts right away, to avoid all of the downstream crashes that these cases were causing. 26 January 2018, 21:23:16 UTC
4cd18ec Update README.md 23 January 2018, 21:04:45 UTC
94fd60e Merge pull request #379 from tfoleyNV/generic-extension-fixes Generic extension fixes 22 January 2018, 02:25:05 UTC
f114c37 A hacky fix for specializing methods from extensions If we don't find the generic we expect in the first pass during IR specialization, then we check for the special case where we are trying to specialize something from a generic extension, using the type being extended. We assume that the generic parameter lists match (that part is the huge hack), and collect the arguments as if they were for the extension instead of the type. This will break when/if we ever have generic extensions with parameter lists that don't match the type being extended. 22 January 2018, 02:06:40 UTC
ef2f92f Trying to get generic extensions to work - Don't drop specializations on a method when adding it to requirement dictionary - Handle extension declarations under a generic when emitting to IR 22 January 2018, 02:06:40 UTC
4131120 Fix legalization of generic types (#377) Previously, all legalizations of a generic type would use the name of the original decl for the "ordinary" part of things, and this would lead to collisions because the names didn't include the mangled generic arguments. This is now fixed by storing the mangled name of the original inside of `struct` declarations created for legalization, and using those names instead. Also adds support for `getElementPtr` instructions when doing IR type legalization. Also tries to make a `DeclRefType` convert to a string using the underlying `DeclRef`. This doesn't help because `DeclRef::toString` doesn't actually include generic arguments either. 22 January 2018, 02:05:39 UTC
8196dc4 specialize witness tables when needed when specializing `lookup_witness_table` instruction. (#376) 22 January 2018, 00:26:52 UTC
4044a1d Merge pull request #372 from csyonghe/master Allow type expression as type argument, fix global param enum order 21 January 2018, 18:48:31 UTC
f681a15 Add directive to ignore file for test runner 21 January 2018, 17:45:58 UTC
ce87911 Improvements and bug fixes for global type parameters 1. allow spReflection_FindTypeByName to accept arbitrary type expression string 2. allow const int generic value to be used as expression value, and as array size 3. various bug fixes in witness table specialization / function cloning during specializeIRForEntryPoint to avoid creating duplicate global values, not copying the right definition of a function from the other module, not cloning witness tables that are required by specializeGenerics etc. 21 January 2018, 12:09:55 UTC
913f4d0 bug fixes fixes #373 fixes bug that misses current translation unit's scope when resolving entry-point global type argument expression. 20 January 2018, 07:48:12 UTC
6dd64fd Make specialization presserve global parameter enumeration order in reflection data 20 January 2018, 03:21:29 UTC
9d515dd Allow arbitrary type string as type argument in spAddEntryPointEx. 20 January 2018, 03:21:29 UTC
2079b94 Merge pull request #371 from csyonghe/master All compiler fixes to get ir branch work with falcor feature demo. 18 January 2018, 20:49:59 UTC
9eb8b4e rename expected test result file. 18 January 2018, 20:51:32 UTC
9cecdfb cleanup unused code. 18 January 2018, 01:58:00 UTC
caf6f7a All compiler fixes to get ir branch work with falcor feature demo. - support overloaded generic function. this involves adding a new expression type, `OverloadedExpr2` to hold the candidate expressions for the generic function decl being referenced. - make BitNot a normal IROp instead of an IRPseudoOp - make sure we clone the decorations of parameters when cloning ir functions - propagate geometry shader entry point attributes (`[maxvertexcount]` and `[instance]`) through HLSL emit - IR emit: handle geometry shader entry-point parameter decorations, such as 'triangle'. - IR emit: treat geometry shader stream output typed ir value as `should fold into use`. 18 January 2018, 01:54:56 UTC
68f529a Merge pull request #370 from csyonghe/master bug fixes to get falcor example shader code to compile. 16 January 2018, 22:52:06 UTC
a74a549 bug fixes to get falcor example shader code to compile. 1. prevent cyclic lookups when an interface inherits transitively from itself. 2. in `createGlobalGenericParamSubstitution`, create a default substitution for the base type declref before using it to lookup the witness table. 16 January 2018, 20:38:36 UTC
59691ae Allow extension on interface (#369) This completes item 5 in issue #361. The interesting change is that when checking for interface conformance, we include the requirements (include transitive interfaces) defined in extensions as well. (check.cpp line 1946) All the other changes are for one thing: reoder the semantic checkings to two explicit stages: check header and check body. In check header phase, we check everything except function bodies, register all extensions with their target decls, then check interface conformances for all concrete types. In body checking phase, we look inside the function bodies and check concrete statements/expressions. This change ensures that we take extension into consideration in all places where it should be. 16 January 2018, 18:52:10 UTC
68fd448 Merge pull request #367 from csyonghe/extension2 Support transitive interfaces 16 January 2018, 03:22:39 UTC
513f56b cleanup debug code 15 January 2018, 23:30:11 UTC
3d4eaf3 Support transitive interfaces This commit is a bunch of quick hacks to get transitive interfaces to work. The idea is for each concrete type we create one giant witness table that contains entries for all the transitively reachable interface requirements, and then create one copy of that witness table for each interface it implements. `DoLocalLookupImpl` now also looks up in inherited interface decles when looking up for a symbol in an interface decl. When visiting `InheritanceDecl` in `lower-to-ir`, create copies of the giant witness table for each transitively inherited interface, so that these witness tables can be found later when the IR is specialized. Re-enable the `copy all witness tables` hack in `specializeIRForEntryPoint` to ensure those transitive witness tables are copied over. 15 January 2018, 23:18:25 UTC
8abae05 Merge pull request #365 from csyonghe/extension Allow extension of a concrete type to implement additional interface 15 January 2018, 21:54:57 UTC
cff418b Merge branch 'master' into extension 15 January 2018, 21:54:32 UTC
e86ab5f Merge pull request #366 from csyonghe/keywordrename add support for `extension` and `type_param` keywords 15 January 2018, 21:21:34 UTC
8e67c48 add support for `extension` and `type_param` keywords 15 January 2018, 02:38:35 UTC
436f0e7 temporary workaround to fix test case failures. 14 January 2018, 23:20:46 UTC
ae8ef43 Fixup field lookup from a member function defined in an extension This fixes item 2 in #361 Modifies existing extension-multi-interface.slang test case to cover the additional scenario. 14 January 2018, 21:52:02 UTC
d33e6b7 allow extension of a concrete type to implement additional interface Also support the scenario that the extension declares conformance to interface I, and a method M in I is already supported by the base implementation. 14 January 2018, 21:22:11 UTC
d4dab2c Merge pull request #364 from csyonghe/assoctype Support nested generics 13 January 2018, 21:17:02 UTC
4d2086f Fix creation of `ThisTypeSubstitution`. `createDefaultSubstitutions` now responsible for creating a `ThisTypeSubstitution` when `decl` is an `InterfaceDecl`. This is to ensure a reference to an associated type decl from the same interface that defines the assoctype decl will get a `ThisTypeSubstitution` so that the right hand side of it can be replaced by future substitutions. 13 January 2018, 20:17:43 UTC
99f49e4 remove out-of-date changes 13 January 2018, 19:30:37 UTC
4b284da Support nested generics fixes #362 13 January 2018, 04:55:38 UTC
df6eeb9 Refactor substitution representation in DeclRefBase (#363) This commit changes the type of `DeclRefBase::substitutions` from `RefPtr<Substitutions>` to `SubstitutionSet`, which is a new type defined as following: ``` struct SubstitutionSet { RefPtr<GenericSubstitution> genericSubstitutions; RefPtr<ThisTypeSubstitution> thisTypeSubstitution; RefPtr<GlobalGenericParamSubstitution> globalGenParamSubstitutions; } ``` This change get rid of most helper functions to retreive the substitution of a certain type, as well as surgery operations to insert a `ThisTypeSubstitution` or `GlobalGenericTypeSubstittuion` at top or bottom of the substitution chain. It also simplies type comparison when certain type of substitution should not be considered as part of type definition. 12 January 2018, 22:15:56 UTC
8daafcc bruteforce implementation of witness table resolution for associated (#358) 09 January 2018, 18:50:44 UTC
3d435f7 Bug fixes for Slang integration (#356) * fix #353 * move validateEntryPoint to after all entrypoints has been checked * bug fix: DeclRefType::SubstituteImpl should change ioDiff * bug fix: generic resource usage should have count of 1 instead of 0. * update test case 04 January 2018, 21:41:09 UTC
e90dfcf Merge pull request #349 from csyonghe/master Add API for querying TypeLayout from a Type 04 January 2018, 02:09:35 UTC
550405d Fix type lookup of global type arguments Global type argument lookup should be done in both loaded modules and current trnaslation units. This is the same as the logic of spReflection_FindTypeByName, so it is extracted into `CompileRequest::lookupGlobalDecl(Name*)` method and reused in places. 04 January 2018, 01:15:03 UTC
61b206d Merge https://github.com/shader-slang/slang 04 January 2018, 01:12:46 UTC
5da16a6 Fix bug around arrays of structs of resources (#352) Should fix #351 The basic problem is that the type layout logic in Slang isn't taking into account the way that resource-type fields in aggregate types get split. When you just have a bare aggregate, this oversight doesn't cause a problem, but once you put those aggregates into an array, the problems become clear. Given: ```hlsl struct Test { Texture2D a; Texture2D b; }; Test test[8]; ``` The default type-layout algorithm gives `Test::a` an offset of zero, and `Test::b` an offset of one. However, after splitting, we have something like: ```hlsl Texture2D test_a[8]; Texture2D test_b[8]; ``` It is clear in this case that `test_b` can't start at an offset of one relative to `test_a` - it needs to start at `register(t8)`. This change handles things by adjusting the layout of an array type to account for this detail as soon as it is created. The alternative would have been to not change layout rules at all, but to instead try to adjust things at the point where types get split (and the layout for the un-split case gets applied to the split variable). The reason for doing it the way it is in this change is that the reflection API will hopefully provide accurate information. Related to reflection information, one thing that is missing here is proper computation of the "stride" for an array like this. We'll see if that needs to be addressed in a follow-up. 04 January 2018, 00:22:37 UTC
771da26 spReflection_FindTypeByName: add lookup in translationUnits. 03 January 2018, 20:53:16 UTC
36bc65a Merge https://github.com/shader-slang/slang 03 January 2018, 20:47:46 UTC
9f89c3b Add API for querying TypeLayout from a Type Added two API functions: 1. `spReflection_FindTypeByName`, which returns a DeclRefType to the struct type with the given name. The function finds from all loaded modules in a `CompileRequest` for a decl with the given name, construct a `Type` object and cache it in `CompileRequest::types` dictionary. The subsequent calls to `spReflection_FindTypeByName` with the same name will simply returned the cached Type objects. 2. `spReflection_GetTypeLayout`, which returns a `TypeLayout` for a given `Type`. This function creates and caches the `TypeLayout` in the `TargetRequest` object that is used to create the `ProgramLayout`. 03 January 2018, 20:46:23 UTC
f52b93e add call to `EnsureDecl` in `SpecializeGenericForOverload`. 03 January 2018, 20:38:48 UTC
51f0701 Fix struct decl order again (#348) * Add core.natvis file to Slang DLL build It seems that when `slang.dll` gets loaded into a user's project, the debugger is able to pick up the custom visualizers implemented in `slang.natvis` (which is directly added to the DLL project) but not `core.natvis` (which is added to a static library project that the DLL project references). Adding `core.natvis` to the DLL project directly seems to resolve this and greatly improve the debugging experience when in user code. * Bug fix: emit type of CB before CB when using IR The problem here was the logic for emitting types used by an IR declaration before the declaration. I refactored it to share logic between variables with initializers and functions, but in doing so failed to have an ordinary variable (which includes constant buffers) ensure that its own type was emitted before the variable. This is a one-line fix. 03 January 2018, 18:17:17 UTC
1e0aabf no-codegen compile flag and global generics reflection (#347) * no-codegen compile flag and global generics reflection 1. Add SLANG_COMPILE_FLAG_NO_CODEGEN (-no-codegen) compiler flag to skip code generation stage, so that a shader that uses global generic type parmameters can be parsed, checked and introspected without knowing the final specialization. 2. Add reflection API to query for global generic type parameters, global parameters of generic type, and the generic type parameter index related to a global generic parameter. 3. Add a reflection test case for global generic type parameters. * add expected result for global-type-params test case. * fix reflection json output. * fix branch condition errors * fix expected result for global-type-params.slang * fix expected test case output 03 January 2018, 06:04:50 UTC
66f9a7c Bug fix for humane source location computation. (#346) Fixes #345 A brief refresher: a `SourceLoc` in the Slang implementation is just an integer (more or less an absolute byte index into all of the source compiled so far). We convert that integer to a "humane" source location (a file name and line/column numbers) by finding the file and line that match the integer via binary search. The data structures used for that search are owned by a `SourceManager`. In order to avoid running out of source locations when used in a long-running application (that might reload shaders many times), the implementation creates one `SourceManager` per `CompileRequest`, along with a single shared `SourceManager` that is used for locations in the builtin libraries. The root of the bug here was that some code was using the `SourceManager` for a compile request when it should have been using the one for the builtins. This happened because one source manager was asked to translate a `SourceLoc` into a humane location, which first involves "expanding" that location (figuring out which file it belongs to, and which source manager owns that file), and failed to realize that the expanded location might use a different source manager (either the current one or one of its "parents"). I fixed this by reworking the API so that the mapping from an expanded location to a humane one is no longer a member of a source manager (since the correct source manager can be looked up in the associated expanded location). Hopefully this will prevent this class of error in the future. 02 January 2018, 18:44:05 UTC
17369d9 Always respect dependency order when lowering decls via AST (#344) Fixes #333 The code in `ast-legalize` is passed an array of declarations that have been ordered by dependencies using a topological sort. Unfortunately, it was only using that list in the case where the request was considered to be a "rewrite" request, and would otherwise rely on the order in which things get forced during the recursive walk (which doesn't really work for our needs). 02 January 2018, 17:29:21 UTC
bdc1fa5 Merge pull request #342 from csyonghe/fix-341 Fix type substitution for associatedtype 29 December 2017, 04:32:02 UTC
37cff92 fixup substitution of typedef associated type implementation via GetType() call. 29 December 2017, 03:51:58 UTC
ee1ea35 Merge branch 'struct-in-generic' 28 December 2017, 22:43:45 UTC
9efd959 Fix substitution for associatedtype. fixes #341 When a typedef definition is used to satisfy an associated type, we must also substitute the resulting typedef type using parent substitution, in the case that the typedef is a generic application. 28 December 2017, 22:39:14 UTC
bcfe836 Merge pull request #340 from csyonghe/struct-in-generic Fix NameExprType returning deleted canonical type when it's in a generic parent 28 December 2017, 12:18:27 UTC
d46aeb0 Fix NameExprType returning deleted canonical type when it's in a generic parent. fixes #339 `NamedExpressionType::CreateCanonicalType()` may return a deleted pointer. The original implementation is as follows: ``` Type* NamedExpressionType::CreateCanonicalType() { return GetType(declRef)->GetCanonicalType(); } ``` If `GetType()` returns a newly constructed Type (this happens when the `typedef` is defined inside a generic parent, which triggers a non-trivial substitution), the temporary type will be deleted when the function returns. The fix is to store the temporary type as a field of NamedExpressionType (`innerType`). A relevant fix (though not the true cause of issue #339) is to have `Type::GetCanonicalType()` also hold a `RefPtr` to the constructed canonical type, when the canonical type is not `this`. This prevents a returned canonical type being assigned to a RefPtr, which makes it possible for that RefPtr to be the sole owner of the canonical type and deleteing the canonical type when that RefPtr is destroyed. 28 December 2017, 11:53:19 UTC
7e340c2 Merge pull request #337 from csyonghe/master Using a visitor to replace lookup scopes of generic function's return type expr 28 December 2017, 07:13:37 UTC
57d9498 Merge branch 'master' into master 28 December 2017, 02:52:39 UTC
eaf3d84 Using a visitor to systematically replace lookup scopes of generic function's return type expression. fixes #336 Add a `ReplaceScopeVisitor` to replace the scopes of the return type expression tree to use the generic decl's scope instead of module's scope after parser has determined the decl is a generic function header decl. 28 December 2017, 02:51:56 UTC
e370fe2 Merge pull request #335 from csyonghe/master Support nested generic types (e.g. L<T<S>>) 28 December 2017, 01:17:36 UTC
d55b56b fix test cases 28 December 2017, 00:19:09 UTC
3379f7a fix project file. 28 December 2017, 00:02:22 UTC
87cba14 Support nested generic types (e.g. L<T<S>>) fixes #325 This commit includes following changes: 1. Including a default DeclaredSubtypeWitness argument when creating a default GenericSubstitution for a DeclRefType, so that the witness argument can be successfully replaced with an actual witness table after specialization. (check,cpp) 2. Not emitting full mangled name for struct field members. Since the declref of the member access instruction do not include necessary generic substitutions for its parent generic parameters, so the mangled names of the declaration site and use site mismatches. Instead we just emit the original name for struct fields. (emit.cpp) 3. Allow IRWitnessTable to represent a generic witness table for generic structs. Adds necessary fields to IRWitnessTable for generic specialization. For now, the user field of the IRUse is not used and is nullptr. (ir-inst.h) 4. Make IRProxyVal use an IRUse instead of an IRValue*, so that an IRValue referenced by IRProxyVal (as a substitution argument) can be managed by the def-use chain for easy replacement. This is used for specializing witness tables. (ir.cpp, ir.h) 5. Add a `String dumpIRFunc(IRFunc*)` function for debugging. 6. Add name mangling for generic / specialized witness tables (mangle.cpp) 7. improved natvis file for inspecting witness tables. 8. Add specialization of witness tables: 1) `findWitnessTable` will simply return the specialize IRInst for a generic witness table. 2) make `cloneSubstitutionArg` call `cloneValue` to clone the argument instead of calling `context->maybeCloneValue`, so we can make use of the cloned value lookup machanism to directly return the specialized witness table (which is done when we process the `specialize` instruction on the generic witness table before process the decl ref). 3) bug fix: the argument in ir.cpp:3338 should be `newArg` instead of `arg`. 4) add `specializeWitnessTable` function to specailize a generic witness table. It clones the witness table, and recursively calls `getSpecailizedFunc` for the witness table entries. 5) make `specailizeGenerics` function also handle the case when an operand of the `specialize` instruction is a witness table. We will call `specializeWitnessTable` here and replace the `specialize` instruction with the specialized witness table. The replacement mechanism based on IR def-use chain works here because we have already make IRProxyVal a part of the def-use chain. 9. Add two more test cases for nested generics with constraints. (generic-list.slang and generic-struct-with-constraint.slang) 27 December 2017, 23:50:32 UTC
6924239 Merge pull request #330 from tfoleyNV/implicit-generic-app Support generic type constraints when implicitly invoking generic 27 December 2017, 02:04:53 UTC
fd0b8ca fix ast-lowering of `TransitiveSubtypeWitness` values. 27 December 2017, 01:20:54 UTC
4b53fd5 Merge branch 'master' into implicit-generic-app 22 December 2017, 20:09:39 UTC
d1c3852 Support for transitive subtype witnesses (#331) * Change stdlib `saturate` to explicitly specialize `clamp` This exposes issue #329, and so gives us an easy way to see if transitive subtype witnesses have been implemented correctly. * Fixup: invoke correct `clamp` overloads When switching the `clamp` calls in the stdlib definition of `saturate` I made two big mistakes: 1. I was passing in `<T>` in all cases, instead of, e.g., `<vector<T,N>>` in the vector case 2. Of course, the overloads don't actually take `<vector<T,N>>` for the vector case, because `vector<T,N>` is not a `__BuiltinArithmeticType` (`T` is), so instead it should be `clamp<T,N>(...)`. The issue behind (2) is that we don't support "conditional conformances," which would be a way to say that when `T : __BuiltinArithmeticType` then `vector<T,N> : __BuiltinArithmeticType`. That would be a great long-term wish-list feature, but not something I can see us adding in a hurry. Anyway the fix here is the simple one: change the vector/matrix call sites to invoke the correct overload in each case. * Add a notion of transitive subtype witnesses There are two pieces here: 1. Add the `TransitiveSubtypeWitness` class. This is a witness that `A : C` that works by storing nested subtype witnesses that show that `A : B` and `B : C` for some intermediate type `B`. All the basic `Val` operations are easy enough to define on this. - The one gotcha case is whether we can ever simplify away a `TransitiveSubtypeWitness` as part of substitution. That is, if we end up substituting so that both `A` and `B` end up as the same type, then we really just need the `B : C` sub-part. Stuff like that is left as future work. 2. Make the logic in `check.cpp` that constructs subtype witnesses based on found inheritance and constraint declarations able to build up transitive chains. Most of the required infrastructure was already there (the search process maintains a trail of "breadcrumbs" that represent all the steps getting from `A : B` to `B : C` to `C : D` ...). This change does *not* deal with the required changes in the IR to take advantage of transitive witnesses. 22 December 2017, 20:09:26 UTC
7ebc987 Support generic type constraints when implicitly invoking generic Fixes #326 This basically just copy-pastes logic from the explicit case over to the implicit case. After we've solved for the explicit type/value arguments, we loop over the constraints and for each one we try to find a suitable subtype witness to use (after substituting in the arguments solved so far). This change includes a test case for the new functionality. 22 December 2017, 18:50:32 UTC
fab52a1 Merge pull request #324 from tfoleyNV/generic-struct-specialization Support generic `struct` types during IR-based emit 22 December 2017, 00:50:22 UTC
0049015 Support generic `struct` types during IR-based emit Fixes #318 Most of the required support was actually in place, so this is just a bunch of fixes: - Detect when we are in "full IR" mode, so that we can always emit `struct` declarations with their mangled named (which will produce different names for different specializations, since we emit decl-refs) - Carefully exclude builtin types from this for now. We'll need a more complete solution for mapping HLSL/Slang builtin types to their GLSL equivalents soon. - Skip emitting types referenced by generic IR functions, since they might not be usable. - Also fix things up so that we emit types used in the initializer for any global variables. - Fix bug in generic specialization where we specialize the same function more than once, with different type arguments. We were crashing on a `Dictionary::Add` call where the key already exists from a previous specialization attempt. - Fix name-mangling logic so that when outputting a possibly-specialized generic it looks for the outer-most `GenericSubstitution` rather than just the first one in the list. This is to handle the way that we insert other substitutions willy-nilly in places where they realistically don't belong. :( All of these changes together allow us to pass a slightly modified (more advanced) version of the test case posted to #318. 22 December 2017, 00:16:23 UTC
6f68127 IR: fixes for subscript accessors (#322) * IR: fixes for subscript accessors Fixes #320 This is a bunch of fixes for handling of `__subscript` operations on builtin types (notably `RWStructuredBuffer` and `StructuredBuffer` at this point). - Automatically add a `GetterDecl` to any subscript decalratio was declithout any accessors. This avoids hitting a null- dereference in the emit logic. - Add a notion of a `RefAccessor` (declared with `ref`) as a peer to getters and setters. The idea is that a `ref` accessor returns a pointer to the element data, so that it can be used for both getting and setting values. This is closer to the behavior of `RWStructuredBuffer` element access in HLSL. - Fixes for dealing with "access chains" where there might be a combination of a subscript (where the is a `get` and `set` but no `ref`) and member access, so that we have to read the base value into a temp, modify it, and then write it back. - This logic is still a bit of a mess, so we will eventually want to take a more consistent pass over this to deal with how we "materialize" values for setters. - Update `RWStructuredBuffer` to have a `ref` accessor, and then fix up the IR tests to handle the new opcode that I added for it. - Note: I didn't handle this as an intrinsic simply because the `tests/ir/*` tests aren't really set up to handle builtins with ugly mangled names. * Fixup: type error in VM for buffer element ref I was using the result type of the op as the element type for computing the element address, but the result type is a pointer to the real element type. This caused test failures on 64-bit platforms, where the stride of the buffer in the `ir/factorial` test needs to be 4. The fix is to assume the result type is a pointer, and extract the pointed-to type out of that. 21 December 2017, 01:35:10 UTC
35318fb More fixes for Falcor IR support (#317) * Fix: try to improve float literal formatting An earlier change switched to using the C++ stdlib to format floats, but I neglected to check that it would correctly print values that happen to be integral with a decimal place (e.g., print `1.0` instead of just `1`). That causes some obscure cases to fail (e.g., when you write `1.0.xxxx` in HLSL, and we print out `1.xxxx`). I've tried to resolve the issue by using the "fixed" output format, but that may also create problems for extremely large or small values (which really need to use scientific notation). However, this at least puts us back where we were before... * Add support for source locations to the IR - Add a `sourceLocation` field to all `IRValue`s - Add some logic to associate locations with operations while lowering (using a slightly "clever" RAII approach) - Make sure that when cloning instructions, we also clone the location - Make the emit logic use the existing support for source locations when emitting code from the IR A nice cleanup to this work would be to have the source locations for IR values not be hyper-specific about both line and column; it is probably enough to just emit on the correct line. 20 December 2017, 22:06:59 UTC
8e0e6b6 Support simple generics syntax (#319) * Support simple generics syntax. This commit enables simpler generics syntax, e.g. T test<T>(T arg) {} or struct Gen<T>{T x;}; * Support simple generics syntax. This commit enables simpler generics syntax, e.g. T test<T>(T arg) {} or struct Gen<T>{T x;}; * add expected test result for compute/generics-syntax.slang 20 December 2017, 16:01:36 UTC
563fc0c Fix up parameter block emit for mixed rewriter+IR (#316) * Fix up parameter block emit for mixed rewriter+IR The basic problem here arose when a parameter block was declared in code that will be lowered via IR, but is referenced from user code that will use the AST-based lowering pass. The type legalization would split up the parameter block, and the AST would refer to the new variables, but it would fail to recognize when those variables represent constant buffers, and thus should get implicit-dereference behavior. The fix here was just to propagate type information through when creating new AST (pseudo-)expressions to represent IR declarations that were split. A more complete fix down the road should try to make sure that both the expression emit logic and the declaration-emit logic agree on whether a particular declaration of a parameter block or constant buffer needs to support the "implicit dereference" case or not. I'm leaving that to future work. With this change, two test cases that had been disabled now pass. * Fixup: don't do implicit deref for `ParameterBlock` values Right now the rules for `ParameterBlock` and all other uniform praameter groups needs to be different, but the `isImplicitBaseExpr` logic wasn't taking that into account. 19 December 2017, 23:17:23 UTC
acf2625 Fix floating-point literal emit to be locale-independent. (#315) There was a bug that arose in the context of Falcor, because: - Slang uses `sprintf` to format floating-point values when outputting HLSL/GLSL source - Falcor (or a library it uses) does the equivalent of `setlocale(LC_ALL, "")` to set the global locale for the process based on the user's environment variables This led to a floating-point literal of `0.5` getting printed as `0,5f`, with a comma for the decimal point. This then gets consumed by `glslang` which (luckily for us) complains that `5f` is not a valid floating-point literal in their language (since it has neither decimal point nor exponent). The most expedient fix in this case was to switch from using C `sprintf` for formatting floating-point numbers over to using the C++ `<stdio>` implementation, which allows the locale to be set per-stream so that we don't have to rely on (or potentially disrupt) the global locale set by an application using Slang. Longer term if we have the time/resources to do the Right Thing, it would be best to implement our own printing logic for floating-point numbers, since we would eventually need/want to support arbitrary-precision numbers for literals. 19 December 2017, 19:49:36 UTC
393e25f Work on getting rewriter + IR playing nice together. (#314) * Work on getting rewriter + IR playing nice together. There are a few different changes here, with the goal of improving the interaction between the "rewriter" code generation approach and the new IR and type legalization code. The main changes are: - Add a new pass that occurs before the AST legalization pass, which walks the (used) AST declarations and tries to discover (1) which declarations need to be specialized/lowered via the IR, and (2) which declarations need to be included in the resulting AST module. - AST-based legalization now uses the generated list when in "rewriter" mode, so that we should be working around issues that users were seeing with types not getting emitted. - TODO: we still need an equivalent fixup in the case of non-"rewriter" emit, so this may still be a problem for `.slang` files. - IR type legalization now precedes AST legalization, so that we can record information on how any IR global values got legalized (e.g., if they got split). Then AST legalization includes logic to reconstruct suitable tuple expressions to reference a split global. - When emitting using IR + AST, we walk all of the declarations that we decided belonged to the IR, but which were subsequently referenced in the AST, to make sure they get output (this would include `struct` types that are declared in a file compiled via IR, but never used in IR-based code). The rewriter+IR use case still doesn't *quite* work, but the logic for walking the AST in a pre-pass ends up being needed/useful to fix some pure rewriter bugs, so I'm getting this checked in sooner rather than later. * Fixup: walk arguments to generic declaration reference The gotcha here is that the code for walking the AST would walk a line of code like: SomeType a; and know to traverse the declaration of `SomeType`, but if it saw a line of code like: ParameterBlock<SomeType> b; it would traverse the declaration of `ParameterBlock`, but fail to visit that of `SomeType`. 18 December 2017, 23:14:59 UTC
46b68ed Add sample-rate-input detection for HLSL. (#312) * Add sample-rate-input detection for HLSL. In the HLSL case, it is possible to do this detection entirely based on declared signatures (it doesn't have a dependency on code generation like the GLSL case does). I've added test cases for the two main ways that a shader can become sample rate: 1. Qualify a fragment input with `sample` 2. Accept an input with the `SV_SampleIndex` semantic In each case I nested the input inside a `struct` to try to match common HLSL idiom, and to make sure that we handle the nested case. This code is *not* robust against shaders that declare such an input and then never use it, but that is to be expected given the goals for Slang. * Fixup: add missing test output files 15 December 2017, 22:26:58 UTC
81c0cd8 More fixups for parameter block binding generation (#311) * More fixups for parameter block binding generation The bug in this case arises when there is both a parameter block and global-scope resources, all of which are relying on automatic binding assignment. If the parameter block is the first global-scope parameter that gets encountered, then it is possible for it to allocate regsiter space/set zero for itself, which confuses the logic for handling other global-scope parameters (which assumes that *they* get space/set zero). I've also made some fixup to the reflection test harness and reflection API code: - Have the hardness handle register-space allocations when printing, and be sure to only show their `index` and not their `space` (since that would be redundant) - Have the reflection API only auto-redirect queries on a parameter group type layout to its container type layout *if* the container type layout has a non-zero number of resource allocations. The problem that arises here is a `ParameterBlock<X>` where `X` doesn't contain any uniforms, so that no container is needed. In that case the container ends up with no resource allocation(s). * Fixups for test failures. - The thread-group size tests failed because they had shader parameters with no resources to back them (built-in `SV_` inputs), and the printing of those changed. I fixed up the baseline, but also had to fix a few bugs in the reflection test fixture's printing logic. - The GLSL parameter block test revealed a corner case of the existing logic: because we always need to generate a binding for the "hack" sampler (even if code doesn't end up needing it), and that sampler should always go in the "default" set (should be set zero), the user's `ParameterBlock` will always end up as `set=1` or later, even if there are no other global-scope parameters. - This will be fixed once we don't have to rely on glslang's annoying behavior in this one case, either because glslang gets fixed, or because we implement our own SPIR-V codegen. 15 December 2017, 19:57:53 UTC
4137f9d More fixups for Vulkan parameter block bindings (#309) I'm adding a small cross-compilation test to try to make sure that we are testing the binding generation for GLSL output. We probably still need a more complex test that uses multiple blocks, plus variables not in a block. The big changes here are: - Change the `containerTypeLayout` field to a `containerVarLayout` in the `ParameterGroupTypeLayout`, so that we can store the base offsets for the fields in a uniform fashion (even though these will all be zero). - Switch the emit logic to carefully use either the container or element var layout depending on what they are emitting bindings for. This involved adding something akin to the "reflection path" notion that Falcor has to use, but only for the emit step. 14 December 2017, 19:51:29 UTC
6d61421 Fix parameter block binding for Vulkan (#308) Fixes #307 This ends up being a major overhaul over how type layout computation is structured and exposed. The big problems all arise around cases where both the "container" for a parameter block or CB, and the "element" type both use the same kind of resource. E.g., if you define a CB with a texture in it, then in Vulkan both the CB and the texture use the same kind of resource, and so if you query the CB's resource usage it will just tell you it uses two descriptor-table slots, but nothing more than that. Similar confusion still arises in the HLSL case, when a CB with a texture in it reports its parameter category as "mixed" so that a user might query for a category they didn't mean to. There were also cases in the existing code where a parameter block might expose *both* a register-space usage and another concrete resource type, which isn't right. The most important changes here are: - A `ParameterGroupTypeLayout` now has a more refined internal structure, consisting of: - A `containerTypeLayout`, which represents the resource usage of the buffer/block itself (e.g., if a constant buffer had to be allocated) - An `elementVarLayout` which stores the offsets that need to be applied to get from the `VarLayout` for an instance of this parameter-group type to the offsets of its elements. The `TypeLayout` for this variable layout should be the "raw" type of the block/CB element. - The `offsetElementTypeLayout` (formerly just `elementTypeLayout`) which represents the element type, but in the case of a `struct` element type, will have fields offset similar to the `elementVarLayout`. This is what all the old code used to use, so we need to keep it for compatibility. - When doing reflection on a `ParameterGroupTypeLayout`, we now only report the resource usage of the `containerTypeLayout`. This is technically a potentially breaking change in the public API, but I don't think Falcor will mind, since they actually want something closer to this behavior. - Add a new public API for querying the element variable layout of a parameter block of constant buffer. This could be used by savvy applications to fold the handling of CB element offsetting into some notion of a "reflection path." This would be required for applications that want to handle CBs or parameter blocks where the element type is *not* a `struct` type. - Remove old logic for applying an offset when creating a type layout for constant buffer element, and instead perform offsetting more uniformly later, by constructing the `offsetElementTypeLayout` from the `rawElementTypeLayout`. This is useful both because we want to keep both (the "raw" type layout becomes the type layout of the `elementVarLayout`), and also because we can decide later whether we even want to allocate a CB register for a buffer, based on whether it actually contains any uniform data. - Fix cases where we might end up with a parameter block type reporting both that it uses a whole register space (and thus should not expose the resource usage of the container/element type) *and* a constant-buffer register/slot. The latter should be hidden inside the regsiter space. - Clean up the `spReflectionParameter_GetBinding{Index,Space}` functions to just route to `spReflectionVariableLayout_Get{Offset,Space}`, using the "default" category of the parameter - Try to make the `GetSpace` query take into account cases where a variable also has an explicit `RegisterSpace` allocation. - This probably still needs some cleanup, since ideally we'd just move things into the `space` field on the `ReosurceInfo` and have an invariant that a variable *either* has a `RegisterSpace` allocation, or it has other resource infos, but never both... - Add some ad-hoc logic so that if the user queries for a binding index/space using a parameter category that doesn't actually apply (e.g., they query for a D3D `t` register when using Vulkan), we can optionally remap it to the resource type they "probably" meant. This is a mess of Do What I Mean code, but it is also what our users want right now. - Fix various bits of emit logic so that if a parameter block has a register space/set allocated to it, we properly output that as part of the binding information for it. - This is another thing that might be cleaned up if we rationale the way that things get split during legalization. - Add a GLSL case for emitting a parameter block variable as a `cbuffer`. 13 December 2017, 23:48:29 UTC
0f55649 Cleanups to `ParameterBlock<T>` behavior. (#304) * Cleanups to `ParameterBlock<T>` behavior. These add some more realistic tests using the `ParameterBlock<T>` support, and show that it can work with the "rewriter" mode. Unfortunately, this code does *not* currently work with the rewriter + the IR at once. That will need to be fixed in a follow-on change, because I now see that the root problem is pretty ugly. * cleanup 08 December 2017, 22:23:12 UTC
301cdf5 Make AST and IR share type legalization code (#303) * Make AST and IR share type legalization code A previous change already made it so that the AST-to-AST lowering/legalization pass could work together with IR-based lowering of `import`ed code, but that change didn't take into account the case where a function written in the AST needed to call an IR function and pass in a type that required legalization. Both the IR-based and AST-based passes had their own approaches to type legalization, that mostly agreed on the desired output, but they ended up creating their own representations for legalized types which would mean that for a function call the caller and callee might end up legalizing the parameter list to use different types. This change tries to fix this issue (and adds a new test case that relies on the fix) by massively overhauling the AST-based legalization pass so that it uses the same type legalization code as the IR. The shared code has been moved out into `legalize-types.{h,cpp}`. Notes: - I eliminated the `FilteredTupleType` type, since it was starting to cause code duplication in a lot of places. Instead, type legalization just creates new `struct` types to represent the result of filtering. - One big consequence of this is that the `LegalType::pair` case needs to remember for each field in the original type which field (if any) in the new `struct` type it maps to - A big source of complexity (and probably bugs) in this code is trying to figure out how to parent these new `struct` definitions effectively. A good follow-on change would be something that outputs declarations on-demand during the AST emit logic (as we do for the IR), just to avoid some of this song and dance. - The old AST type legalization had a notion of both a "tuple" type and a "varying tuple" type. The "tuple" case was quite complex, and combined behavior currently handled by `LegalType::pair` (for splitting into ordinary and special sides) and `LegalType::tuple` (for holding multiple distinct elements to represent the fields of an aggregate). The "varying tuple" case was closer to `LegalType::tuple`, so I tried to just re-use the existing logic for that too. The one place this potentially gets messy is in `reifyTuple()`. - The messiest bit of handling the "varying tuple" concept (which is used for GLSL shader inputs/outputs since they have to be scalarized) is that when passing them as function arguments we need to reify the tuple back into a structured value. Because the `LegalExpr` hierarchy doesn't have type information, but constructing a value of the "original" type requires such information, things get a little messy. - I did *not* try to deal with any of the logic related to handling system inputs/outputs for cross-compilation purposes. Of course, the long-term goal is that any actual cross-compilation is handled via the IR, but this change can't afford to break the AST-based path just yet. As a result, there is still quite a bit of complexity in the handling of assignment, to deal with cases where "fixups" are required. * fixup: bad code in macro, not caught by Visual Studio compiler * fixup: more stuff missed by VS compiler * fixup: VS continutes to miss stuff in UNREACHABLE_RETURN 06 December 2017, 21:55:31 UTC
b487516 Add API to query stage of varying parameter (#302) Fixes #301 The problem here is that if you have input GLSL code like: ```glsl // example.vs in vec3 pos; ``` and: ```glsl // example.fs in vec3 worldPos; ``` Then both `pos` and `worldPos` are reflected as global variables (parameters of the *program*), which both get bound to "varying input" resources, but there is no way to tell through the API that `pos` is a vertex parameter while `worldPos` is a fragment one. The original request in issue #301 was to expose parameters like this not as a global variables, but rather as parameters of the entry point in their specific file. That is, treat it as if the user had written, e.g.: ```glsl // example.vs void vsMain(in vec3 pos) { ... } ``` Doing that would unify the GLSL and HLSL/Slang cases a bit, but would require the Slang reflection API to lie about the structure of code the user wrote. At a more basic level, that would have been hard to implement because the current reflection API just exposes the underlying AST, and the AST *needs* to leave `pos` at the global scope so that when we go and spit GLSL back out we retain the original structure. This PR implements a more simplistic solution, where the user is allowed to query the stage that a varying parameter "belongs" to. For right now I'm only enabling this to work for varying parameters (but it doesn't care if they are entry-point or global-scope varyings). Despite what I said on #301, this should work for both the top-level parameter's variable layout, *and* any variable layouts for fields within its type reflection. In terms of implementation, I took the simple but wasteful route: every `VarLayout` now has a `stage` field that is by default initialized to `SLANG_STAGE_NONE`. When collecting varying parameters, I take advantage of the fact that everything bottlenecks through `processEntryPointParameter()` which takes an `EntryPointParameterState` so that I can set the `VarLayout::stage` field for any varying parameter in one place. While I was making this change, I also did a bit of cleanup so that the "official" names for the varying parameter categories are `VARYING_INPUT` and `VARYING_OUTPUT`, with `VERTEX_INPUT` and `FRAGMENT_OUTPUT` being "deprecated" in principle. I didn't do the bulk rename inside the codebase yet. 29 November 2017, 19:45:15 UTC
7139380 Enable HLSL/GLSL "rewrite" + IR-based Slang codegen (#300) The big picture here is that the AST-to-AST pass in `ast-legalize` will now detect when a declaration being referenced comes from an `import`ed module, and (if IR codegen is enabled), it will trigger cloning of the IR for the chosen symbol into an IR module that will sit alongside the legalized AST. Then, during HLSL/GLSL code emit, we emit all the IR-based code first, and then the AST-based code. Whenever the AST code references a symbol that was lowered via IR (we keep track of these) we emit the mangled name of the IR symbol. Notes/details: - A lot of the logic for cloning IR symbols referenced by the AST matches the same logic that would clone them for completely IR-based codegen, so I tried to hoist out the common logic and share it (e.g., so that we apply the same guaranteed transformations in both cases). This required basically rewriting the logic in `emit.cpp` that decomposed the various cases. - There is a new compute test case added to test this functionality. `tests/compute/rewriter.hlsl` confirms that we can use the `-no-checking` mode for the HLSL code, but still make use of a library of Slang code that employs generics, etc. - Adding this test case required adding a new compute test mode that invokes `render-test` with the `-hlsl-rewrite` flag. - It turns out that the existing `tests/render/cross-compile0.hlsl` test should have been using this functionality already. It was opting into the use of the IR via `-use-ir`, and the `render-test` application already tries to set `-no-checking` for non-Slang input languages by default. Fixing the code path this test triggers means that it is now a second test of rewriter+IR codegen. - The `translateDeclRef` logic in `ast-legalize.cpp` seemed sloppy in places, and would potentially clone declarations, when declaration references were desired. I tried to clean a bit of this up, so some call sites are now changed. - This change tries to clean up some work around cloning of global values - All global value kinds (not just functions) now go through the logic of trying to pick a "best" definition, so that they can be used when we are linking multiple modules - The logic for registering cloned values has been unified a bit, so that clients always pass in an `IROriginalValuesForClone` that either wraps a single value (maybe just null), or an `IRSpecSymbol*` that gives a list of values to regsiter the new value as a clone for. - I made one piece of code that was cloning witness tables as part of generic specializations *not* register a clone. I think this is correct because we may specialize the same generic multiple ways, so registering any values we clone is not the right idea, but I might be missing something... - I also reorganized this logic so that it would be easier to clone a global value when we only know its mangled name (which is the case when it is the AST that triggers cloning) - I made sure that when loading a module via `import`, the translation unit for the new module copies the `-use-ir` flag from the overall compile request, if it is present (otherwise we wouldn't generate IR for loaded modules at all... oops). - Note that `getSpecializedGlobalValueForDeclRef()`, which is the main routine used by the AST legalization to trigger cloning of an IR value does *not* currently handle declaration references that require specialization. - This change does *not* deal with trying to unify the type legalization logic between the AST-to-AST rewriter and the IR-based codegen, so if you call an imported function with types that require legalization, Bad Things are expected to happen right now. 29 November 2017, 03:49:21 UTC
4951003 Generate IR per-module for loaded modules (#299) The basic idea here is that for each module that gets loaded via `import`, we should also generate the initial IR for the declarations in that module at the time it gets loaded. Furthermore, when we generate initial IR for a module, we will only generate IR *declarations* (not *definitions*) for any functions/variables in modules it imports. Later, when cloning IR to begin code generation for an entry point, we will effectively "link" all of the loadedm modules together, so that a given global value can get its definition from any of the IR modules present. - Change the `loadedModulesList` and related data structures to hold a new `LoadedModule` type, instead of just the AST (and then have a `LoadedModule` own both the AST and the IR module) - Share some logic between the `import` and `#import` cases, so that we always try to generate IR for modules we load. - Make sure that IR generation always gets skipped if the command-line flags tell us not to use the IR. - A few small fixups for cases that didn't arise in IR lowering so far, but come up when we try to actually generate IR for things like the stdlib. There are some notable gaps in this work right now: - The stdlib modules are exempted from this behavior; we always generate IR for stdlib functions in any user module that calls them. This is just a workaround for the fact that the stdlib modules don't show up in the list of imported modules right now. - We don't currently have logic that does the "linking" step for global variables like we do for functions. We really need to look up the symbols with the same mangled name, and favor any one of them that has a definition (if there is one) - Similarly, the handling of witness tables is incomplete. During initial IR generation, we should probably be generating empty witness tables for any conformances that were declared in other modules (but are being used locally in this module), and then the "linking" step should favor non-empty witness tables over empty ones. Still, all the test cases pass with the code like this, and this seems like an important step in the right direction. 28 November 2017, 14:42:13 UTC
3199385 Cleanups (#298) * Rename `lower.{h,cpp}` to `ast-legalize.{h,cpp}` This pass isn't really performing lowering akin to `lower-to-ir.{h,cpp}` so the file name is misleading. By renaming this pass we emphasize its role as an AST-related pass. Also update the comment at the top of `ast-legalize.h` to reflect the intended purpose of this pass in a world where we have the IR up and running. * Allow `import` as an alias for `__import` The use of double underscores to mark our new syntax has so far had two purposes: 1. It helps identify syntax that isn't meant to be exposed to users in its current form (e.g., `__generic` gets a double underscore because we want users to have a more pleasant surface syntax for generics that they write). This rationale doesn't apply to `__import`, which is a major language feature that users need to interact with. 2. It helps avoid the problem where the compiler treats something as a keyword that isn't supposed to be reserved in HLSL/GLSL and so causes existing user code to fail to parse (e.g., when the user tries to write a function called `import`). This no longer matters because we look up almost all of our keywords using the existing lexical scoping in the language (so the user can shadow almost any keyword with a local declaration). So, neither of the original two reasons applies to `__import`, and it makes sense to expose it as `import`. Doing so is a one-line change. 28 November 2017, 00:33:28 UTC
109ee8a Fix substitution mechanism to remove special cases for global params (#297) Add a new function: `substituteSubstitutions(Substitutions * substHead, Substitutions subst, int * ioDiff)` This function substitutes the type arguments referenced in a linked list of substitutions headed at `substHead` using the substitutions specified by `subst`. If the linked list `substHead` does not contain `GlobalGenericParamSubstitution` entries, they will be added to the bottom (outter most) of the linked list. Note that this function should be called when `substHead` is known to be the head of substitution linked list because the existance of `GlobalGenericPaaramSubstitution` is detected assuming the linked lists starts at `substHead`. If a substitution that is not the head of a substitution linked list is passed in, duplicate `GlobalGenericParamSubstitution`s could be appended to the linked list. This means that this function should *not* be called in places like `GenericSubstitution::SubstitutionImpl()` for its outer substitutions, because `outer` is obviously not the head of the linked list. Instead, use this function to substitution the substitution lists of `DeclRef` etc. instead of calling `declRef.substitutions->SubstituteImpl()` where the head to the linked list is known as a member of that class. With this function, IRSpecContext::maybeCloneType() is simplified down to `originalType->Substitute(subst)` Updates `DeclRefBase::SubstituteImpl` and `DeclRefType::SubstituteImpl` to call `substituteSubstitutions` instead of making direct `substitutions->SubstituteImpl` call. Providing actual implementation of `GlobalGenericParamSubstitution::SubstituteImpl` instead of just returning `this` to deal with potential situations where a true substitution is needed. 24 November 2017, 16:55:54 UTC
83d49ce Merge pull request #293 from csyonghe/generic-param-fix Fixup global generic parameters 22 November 2017, 22:32:15 UTC
581b30d Merge branch 'master' into generic-param-fix 22 November 2017, 21:58:16 UTC
56e49fe Fix emitting of loop attributes for HLSL pass-through (#296) Fixes #295. The code previously had a white list of attributes that it passed through, implemented in `emit.cpp` in an ad hoc fashion. The fix here is to just pass through whatever attributes the user wrote, and then let the downstream compiler diagnose if any of them are errorneous. 22 November 2017, 19:28:29 UTC
cd2d646 Merge branch 'master' into generic-param-fix 22 November 2017, 00:55:23 UTC
43434bf update input layout definition of test case `global-type-param-in-entrypoint` 22 November 2017, 00:26:56 UTC
64108c8 Add logic to propagate GlobalGenericParamSubstitution 22 November 2017, 00:26:17 UTC
37315c9 IR: support global variable with initializers (#294) The big change here is that the ability to contain basic blocks with instructions in them has been hoisted from `IRFunc` into a new base type `IRGlobalValueWithCode` shared with `IRGlobalVar`. The basic blocks of a global variable define initialization logic for it; they can be looked at like a function that returns the initial value. Places in the IR that used to assume functions contain all the code need to be updated, but so far I only handled the cloning step. The emit logic currently handles an initializer for a global variable by outputting its logic as a separate function, and then having the variable call that function to initialize itself. This should be cleaned up over time so that we generate an ordinary expression whenever possible. I also made the emit logic correctly label any global variable without a layout (that is, any that don't represent a shader parameter) as `static` so that the downstream HLSL compiler sees them as variables rather than parameters. 20 November 2017, 21:45:10 UTC
ab49ac3 fix warnings 20 November 2017, 10:49:57 UTC
d6130ba fixup global generic parameters 1. simplify RoundUpToAlignment() 2. add new a render-compute test case to cover the situation where the entry-point interface (parameter/return types of an entry-point function) is dependent on the global generic type. 3. initial fixes to get this test case to compile (but is not producing correct HLSL output yet) 20 November 2017, 10:28:22 UTC
3dff5a5 IR: add lowering for initializer list expressions (#290) * IR: add lowering for initializer list expressions This is relatively straightforward in the easy cases, because the front-end will have already type-checked the elements of the initializer list, and attached an appropriate type to the overall expression. Notes: - We are assuming in this code that if the user provides a "flattened" initializer list when dealing with nested aggregates, then the front-end is responsible for grouping things up apprporiately (this is not actually implemented in the front-end today). - I have only handled arrays and `struct` types here, so uses of initializer lists for anything else will fail. - I have not tried to handle the common HLSL idiom of using `{0}` as a way to default-initialize things, even when their first field is not compatible with the expression `0` - I have not implemented support for default-initializing fields/elements beyond those for which explicit initializers were provided. This can be addressed as a follow-on change. This change is one clear place where the front-end lowering logic could potentially be made much cleaner using a "destination-driven" code generation strategy. For example, given the following code ```hlsl struct A { int a0; a1; }; struct B { A b0; A b1; }; struct C { B c0; B c1; }; // ... C c = { { { 0, 1 }, {2, 3}, }, /* ... */ }; ``` Our current code generator will end up allocating local variables for 1 instance of `C`, two instances of `B`, and four instances of `C`, for over 3x the allocation that would be done by a good destination-driven code generator. Yes, later optimization passes should be able to clean up the waste, but avoiding the waste from the start should result in faster compiles and also easier debugging (since intermediate IR won't be as messy in general). * Fixup: try to appease clang compiler 18 November 2017, 03:38:26 UTC
back to top