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

sort by:
Revision Author Date Message Commit Date
bf92b6c Fixup for missing code in #896 (#900) The `tuple` case in `getPointedToType` was failing to add the elements it computed to the output tuple type. This isn't triggered in any of our test cases, but was caught by some work I was doing in another branch. 12 March 2019, 22:43:11 UTC
2ca792c Add -profile option to render-test to override a profile to use (#898) 12 March 2019, 20:37:59 UTC
3cfccfd Add options to control optimization and debug information (#897) The short version for command-line users is: * Use `-g` to get debug info in the output, where supported * Use `-O0` to disable optimizations, in case that improves debugability * Use `-O2` for optimized/release builds where you can spend the extra compile time The command-line options are matched with new API functions `spSetDebugInfoLevel()` and `spSetOptimizationLevel()` that set the equivalent information. Right now these settings only affect how we invoke fxc and dxc. In the longer run I expect we will want to use them to control other things: * Once we are emitting our own SPIR-V, the `-g` option should control what source-level name information we include in it. * Whether or not `-g` is used could be used to decide whether we preserve the "name hints" in the IR, which in turn decide whether we output GLSL/HLSL source that uses names based on the original program. * We will eventually need/want to include some amount of optimization passes on the Slang IR, and the `-O` options should control which of those passes are enabled on a particular invocation. In this change I decided to expose the options at the level of the entire compile request for API users, and to store the actual information on the Linkage. We might want to revisit this decision and instead allow for the level of optimization to be chosen per-target as part of back-end state. Similarly, we might want to have more fine-grained control over the level of debug output per-target (although we'd still need a front-end setting to determine what debug info is generated into the Slang IR). 12 March 2019, 19:24:03 UTC
9722990 Fix handling of arrays of resources in type legalization (#896) Before type legalization we might have code like: (using pseudo-Slang-IR): struct P { ... Texture2D<float>[] t; } global_param p : ParameterBlock<P>; ... // p.t[someIndex].Load(...); // let ptrToArrayOfTextures = getFieldPtr(p, "t") : Ptr<Texture2D<float>[]>; let ptrToTexture = getElementPtr(ptrToArrayOfTextures, someIndex) : Ptr<Texture2D<float>>; let texture = load(ptrToTexture) : Texture2D<float>; let result = call(loadFunc, texture, ...) : float; Legalization needs to move the `t` array there out of the `p` parameter block, so the global declarations become something like: struct P_Ordinary { ... }; // no more "t" field global_param p_ordinary : ParameterBlock<p_ordinary); global_param p_t : Texture2D<float>[]; In terms of the code to access `p.t[someIndex]` the problem is that `p_t` has one less level of indirection than `p.t` had. We solve this in the type legalization pass using "pseudo-types" and "pseudo-values," where one of the cases is `implicitIndirect` which holds a value of type `T`, but indicates that it should act like a value of type `T*`. We then use some basic rules for dealing with `implicitIndirect` values, such as: load(implicitDeref(x)) : T => x : T getFieldPtr(implicitDeref(s), f) => implicitDeref(getField(s, f)) getElementPtr(implicitDeref(a), i) => implicitDeref(getElement(a, i)) The bug here was that for the `getFieldPtr` and `getElementPtr` cases, we weren't computing the type of the `getField` or `getElement` instruction correctly. We were copying the type from the `getFieldPtr` or `getElementPtr` operation over directly, but those will be *pointer* types and we need the type of whatever they point to. Once the types are fixed, we can properly generate legalized IR for `p.t[someIndex].Load(...) that looks like: let arrayOfTextures = p_t : Texture2D<float>[]; let texture = getElement(arrayOfTextures, someIndex) : Texture2D<float>; let result = call(loadFunc, texture, ...) : float; The old was giving the `texture` intermediate a type of `Ptr<Texure2D<float>>`. That didn't actually trip up too many things, because we mostly just went on to emit code from something with slightly incorrect types for intermediates that never show up in the generated HLSL/GLSL. Where this caused a problem is for some of the intrinsic function definitions for the GLSL/Vulkan back-end, because those do things that inspect operand types. In particular the `$z` opcode in our intrinsic function strings triggers logic that looks at a texture operand, and uses its type to try to find the appropriate swizzle to get from a 4-component vector to the appropriate type for the operation (e.g., for a load from a `Texture2D<float>` we need to swizzle with `.x` to get a single scalar out of the matching GLSL texture fetch operation). The main fix in this change is thus to make `getElementPtr` and `getFieldPtr` legalization properly account for the fact that when switching to `getElement` or `getField` we need a result type that is the "pointee" of the original result. There was already logic to extract the pointed-to type from a pointer in `ir-specialize.cpp`, so I extracted that to a re-usable function in the IR as `tryGetPointedToType` (returns null if the type isn't actually a pointer). This logic needed to be extended for type legalization, to deal with the various "pseudo-type" cases. There is another fix in this change which is marking the `NonUniformResourceIndex` function as `[__readNone]`, which enables it to be more aggressively folded into use sites. Without that fix, we risk emitting code like: ```glsl int tmp = nonUniformEXT(someIndex); vec4 result = texelFetch(arrayOfTextures[tmp], ...); ``` The problem with that code is that (at least by my reading of the spec), assigning to the variable `tmp` that isn't declared with the `nonUniformEXT` qualifier effectively loses that qualifier, and drivers are free to assume that `tmp` is uniform when used to index into `arrayOfTextures`. Marking the `NonUniformResourceIndex` function as `[__readNone]` indicates that it has no side effects, which should mean that our emit logic no longer needs to emit it was its own line of code to be safe. The effects of this change are confirmed by both the new test case added, and the existing `non-uniform-indexing` test. 12 March 2019, 17:45:39 UTC
35c26f3 Merge pull request #893 from csyonghe/master Fix GLSL emit logic for select expr 10 March 2019, 23:19:23 UTC
fbba277 Fix GLSL emit logic for select expr 10 March 2019, 22:35:44 UTC
d549215 Fix `spReflection_FindTypeByName` (#891) 10 March 2019, 16:38:20 UTC
4f94dd4 Improve support for interfaces as shader parameters (#886) * Improve support for interfaces as shader parameters This change adds two main things over the existing support: 1. It is now possible to plug in concrete types that actually contain (uniform/ordinary) fields for the existential type parameters introduced by interface-type shader parameters. The `interface-shader-param2.slang` test shows that this works. 2. There is a limited amount of support for doing correct layout computation and generating output code that matches that layout, so that interface and ordinary-type fields can be interleaved to a limited extent. The `interface-shader-param3.slang` test confirms this behavior. There are several moving pieces in the change. * When it comes to terminology, we try to draw a more clear distinction between existial type parameters/arguments and existential/object value parametes/arguments. A simple way to look at it is that an `IFoo[3]` shader parameter introduces a single existential type parameter (so that a concrete type argument like `SomeThing` can be plugged in for the `IFoo`) but introduces three existential object/value parameters (to represent the concrete values for the array elements). * At the IR level, we support a few new operations. A `BindExistentialsType` can take a type that is not itself an interface/existential type but which depends on interfaces/existentials (e.g., `ConstantBuffer<IFoo>`) and plug in the concrete types to be used for its existential type slots. * Then a `wrapExistentials` instruction can take a type with all the existentials plugged in (possibly by `BindExistentialsType`) and wrap it into a value of the existential-using type (e.g., turn `ConstantBuffer<SomeThing>` into a `ConstantBuffer<IFoo>`). * The IR passes for doing generic/existential specialization have been updated to be able to desugar uses of these new operations just enough so that a `ConstantBuffer<IFoo>` can be used. * When we specialize an IR parameter of an interface type like `IFoo` based on a concrete type `SomeThing`, we turn the parameter into an `ExistentialBox<SomeThing>` to reflect the fact that we are conceptually referring to `SomeThing` indirectly (it shouldn't be factored into the layout of its surrounding type). * Parameter binding was updated so that it passes along the bound existential type arguments in a `Program` or `EntryPoint` to type layout, so that we can take them into account. The type layout code needs to do a little work to pass the appropriate range of arguments along to sub-fields when computing layout for aggregate types. * Type layout was updated to have a notion of "pending" items, which represent the concrete types of data that are logically being referenced by existential value slots. The basic idea is that these values aren't included in the layout of a type by default, but then they get "flushed" to come after all the non-existential-related data in a constant buffer, parameter block, etc. * The logic for computing a parameter group (`ConstantBuffer` or `ParameterBlock`) layout was updated to always "flush" the pending items on the element type of the group, so that the resource usage of specialized existential slots would be taken into account. * The type legalization pass has been adapted so that we can derive two different passes from it. One does resource-type legalization (which is all that the original pass did). The new pass uses the same basic machinery to legalize `ExistentialBox<T>` types by moving them out of their containing type(s), and then turning them into ordinary variables/parameters of type `T`. Big things missing from this change include: - Nothing is making sure that "pending" items at the global or entry-point level will get proper registers/bindings allocated to them. For the uniform case, all that matters in the current compiler is that we declare them in the right order in the output HLSL/GLSL, but for resources to be supported we will need to compute this layout information and start associating it with the existential/interface-type fields. - Nothing is being done to support `BindExistentials<S, ...>` where `S` is a `struct` type that might have existential-type fields (or nested fields...). Eventually we need to desugar a type like this into a fresh `struct` type that has the same field keys as `S`, but with fields replaced by suitable `BindExistentials` as needed. (The hard part of this would seem to be computing which slots go to which fields). As a practial matter, this missing feature means that interface-type members of `cbuffer` declarations won't work. The current tests carefully avoid both of these problems. They don't declare any buffer/texture fields in the concrete types, and they don't make use of `cbuffer` declarations or `ConstantBuffer`s over structure types with interface-type fields. * fixup: add override to methods * fixup: typos 09 March 2019, 00:24:02 UTC
281c67b Confirm layout for structured buffer of matrices, and related fixes (#889) * Fix up handling of NumElements for D3D buffer views For everything but structured buffers we'd been setting this to the size in bytes, but that isn't really valid at all. The `NumElements` member in the view descs is supposed to be the number of buffer elements, so it would be capped at the byte size divided by the element size. This change fixes the computation of `NumElements` to take the size of the format into account for non-structured views. For the "raw" case, we use a size of 4 bytes since that matches the `DXGI_FORMAT_R32_TYPELESS` format we use (which seems to be required for raw buffers). I also added support for the raw case for SRVs where it didn't seem to be supported before (not that any of our tests cover it). * Fix handling of size padding for D3D11 buffers The existing code was enforcing a 256-byte-aligned size for all buffers, but this can cause problems for a structured buffer. A structured buffer must have a size that is a multiple of the stride, so a structured buffer with a 48-byte stride and a 96-byte size would get rounded up to 256 bytes, which is not an integer multiple of 48. This change makes it so that we only apply the padding to constant buffers. According to MSDN, constant buffers only require padding to a 16-byte aligned size, and no other restrictions are listed for D3D11, but it is difficult to know whether those constrains are exhaustive. I've left in the 256-byte padding for now (rather than switch to 16-byte), even though I suspect that was only needed as a band-aid for the `NumElements` issue fixed by another commit. * Fix an IR generation bug when indxing into a strutured buffer element The problem here arises when we have a structured buffer of matrices (an array type would likely trigger it too): ```hlsl RWStructuredBuffer<float3x4> gMatrices; ``` and then we index into it directly, rather than copying to a temporary: ```hlsl // CRASH: float v = gMatrices[i][j][k]; // OKAY: float3x4 m = gMatrices[i]; float v = m[j][k]; ``` The underlying issue is that our IR lowering pass tries to defer the decision about whether to use a `get` vs. `set` vs. `ref` accessor for a subscript until as late as possible (this is to deal with the fact that sometimes D3D can provide a `ref` accessor where GLSL can only provide a `get` or `set`). We probably need to overhaul that aspect of IR codegen sooner or later, but this change uses some of the existing machinery to try to force the `gMatrices[i]` subexpression to take the form of a pointer when doing sub-indexing like this. This fixes the present case, and hopefully shouldn't break anything else that used to work (because the subroutines I'm using to coerce the `gMatrices[i]` expression should be idempotent on the cases that were already implemented). * Add a test case to confirm fxc/dxc layout for structured buffers of matrices Even when row-major layout is requested globally, fxc and dxc seem to lay out a `StructuredBuffer<float3x4>` with column-major layout on the elements. This commit adds a test that confirms that behavior. This commit does not try to implement a fix for the issue (either fixing Slang's layout reflection information to be correct for what fxc/dxc do in practice, or fixing Slang's HLSL output to work around the fxc/dxc behavior), but just documents the status quo. If/when we decide how we'd like to handle the issue long-term, this test can/should be updated to match the decision we make. * fixup: build breakage on clang/gcc This is one of those cases where the Microsoft compiler is letting through some stuff that isn't technically valid C++ ("delayed template parsing"). Fixed by just moving some declarations to earlier in the file. 08 March 2019, 22:59:47 UTC
4aab9cc Fix a 64-bit issue in our Windows UI code (#887) Fixes issue #874 The problem here was that a pointer was being cast to `LONG` so that it could be used with the `SetWindowLongPtr` API, but that API actually expects a `LONG_PTR`. Since `LONG` is a 32-bit type on 64-bit Windows, the pointer we stored was getting truncated, leading to crashes. I'm kind of surprised this wasn't biting more of our applications (e.g., the render tests). 08 March 2019, 16:43:49 UTC
74a3405 Properly initialize m_modulesBeingImported otherwize it will segfault (#888) 08 March 2019, 14:51:14 UTC
f33aee2 Fix problems with synthesized tests and inconsitent render-test command lines (#885) * * Check for inconsistent command line options for renderer * Moved RenderApiUtil into core so can be used in slang-test * Make it use the ShaderdLibrary for API testsing * Added some simplifying functions to StringUtil for spliting/comparisons * Refactored the synthesis of rendering tests so that inconsistent combinations are not produced * Add missing slang-render-api-util.cpp & .h * Stop warning on linux about _canLoadSharedLibrary not being used. 07 March 2019, 21:31:56 UTC
3f6609a On doing complete rebuild hlsl.meta.slang.h appears to be slightly out of step. (#884) 07 March 2019, 16:17:49 UTC
0630bf9 Fix rsqrt intrinsic for GLSL (#881) * Add support for glsl inversesqrt intrinsic * fixup for test failure 07 March 2019, 02:45:37 UTC
c850ba4 * Add support for enum and type lookup via :: (scope operator) (#882) * Added test for scope operator 07 March 2019, 01:16:20 UTC
87610f6 Add GLSL intrinsics for f32tof16() and f16tof32() (#883) 06 March 2019, 22:44:02 UTC
325b721 Fix dx12 root sig mismatch on texture2d-gather.hlsl test (#879) * Fix texture2d-gather test failure on dx12. * Fix tab 05 March 2019, 23:38:39 UTC
dcd9e57 Hotfix/crash invalid vk binding (#875) * Add diagnostic for vk::binding failure. * Add test for vk::binding failure. * Add the expected output for glsl-layout-define.hlsl * * Copy over initialize expr if available when validating unchecked * Fix unloop - because now it always has one parameter (when before it could have none) * Split vk::binding and layout tests with invalid parameters * Removed the diagnostic for 2 ints expected * Added vk::binding that doesn't specify set in vk-bindings.slang * * Fix typo * Improve comments. 05 March 2019, 22:24:44 UTC
3d55466 Hotfix/texture2d gather (#876) * First pass test to see if GatherRed works. * Add support for generating R_Float32 textures. * Set default texture format. * * Alter the texture2d-gather to work with a R_Float32 texture * Add support for scalar Texture2d types with GatherXXX in stdlib * Remove some left over commented out test code from texture2d-gather.hlsl 05 March 2019, 19:53:44 UTC
890403f * Fix issue with dependency including source path - even if source was compiled from a string (#878) * Added FromString Type to PathInfo to identify paths that are not from 'files' 05 March 2019, 18:30:36 UTC
69d2651 #include not using search paths (#873) * Fix warnings from visual studio due to coercion losing data. * Removed searchDirectories from FrontEndCompileRequest and use the one in Linkage as that is the one that is changed via Slang API. * * Add searchPaths back to FrontEndRequest * Add comments to explain the issue * Add a test to check include paths 02 March 2019, 13:22:38 UTC
620af1c Move enumeration of shader parameters to Program/EntryPoint (#870) There's a certain amount of logic in `parameter-binding.cpp` that just has to do with the basic problem of enumerating the shader parameters of a `Program`. The main source of complexity is that for legacy/compatibility reasons we need to consider two shader parameters with the same name as being the "same" parameter for layout purposes, and then we need to do a bunch of validation to ensure that these parameters have compatible types. The biggest part of this change is moving that logic to `Program`, so that it builds up a list of its shader parameters during the front-end work, so that any errors related to bad redeclarations will now come up even if we aren't generated target-specific layouts/code. All of the code for `getReflectionName`, `StructuralTypeMatchStack`, etc. is pretty much copy-pasted from `parameter-binding.cpp` over to `check.cpp`, with the `ParameterBindingContext` replaced with a `DiagnosticSink`. The `Program::_collectShaderParameters` function (renamed from `_collectExistentialParams`) then deals with the enumeration and deduplication logic that used to happen in `collectGlobalScopeParameters()`. The new declarations in `compiler.h` reveal the underlying reason for this change: by letting `Program` and `EntryPoint` handle the canonical enumeration of parameters, we can associate each parameter with the range of existential type slots it uses, which will simplify certain work around interfaces (not in this change...). Moving the code out of parameter binding and into `check.cpp` revealed some unused GLSL-related code that I removed while I was at it. I also found that the `IsDeclaration` case of `VarLayoutFlag` wasn't actually being used, so I went ahead and removed it (we can easily re-add it if we ever find a need for it). Overall this isn't a big cleanup (mostly just code moving, rather than being eliminated), but it will facilitate other changes, and it seems cleaner overall to do this work once in target-independent logic, rather than per-target. 01 March 2019, 17:43:47 UTC
efca2bb A small refactor to how implicit constant buffers are getting created. (#871) This affects layout computation for both the global and entry-point scopes, where multiple discrete shader parameters can be declared, but for layout purposes they must be treated as if they lived in the same `struct` type. If that `struct` type ends up consuming any "ordinary" data (`LayoutResourceKind::Uniform`) then an implicit constant buffer will be needed for that scope (e.g., the way fxc produces a `$Globals` constant buffer for the global scope). The logic for computing those scope layouts had a bug in it, in that the struct type was not being updated to have the right size for uniform data at the scope. That bug hasn't bitten anybody yet because no Slang users are relying on entry-point uniforms, and global-scope uniforms aren't fully implemented (and get diagnosed as an error elsewhere in the compiler). This change fixes that bug. This change also refactors things so that the logic for creating a constant buffer layout if and only if needed is moved into `type-layout.cpp` instead of relying on `parameter-binding.cpp` to compute whether or not it needs a block on its own. This is anticipating the rules for deciding whether or not a constant buffer is needed being slightly more thorny once interface types are in the mix. 01 March 2019, 16:20:09 UTC
852c88c Eliminate the specializeProgramLayout() function (#869) The `specializeProgramLayout()` primarily existed to support global generic parameters. The guiding idea of the design had been that plugging in concrete types for global generic parameters should only affect the layout/binding of shader parameters that depend on the global generic type parameters. All other shader parameters should keep the same layout/location across all specializations. This idea was implemented by conceptually having two phases of layout: * A generic-argument-independent phase would do layout on all the shader parameters that *don't* depend on global generic type parameters. * A second phase would then pick up where the other one left off (re-using existing parameter layouts to guarantee a match), and just layout out the shader parameters that *do* depend on global generic type parameters. Because the other parameters were already laid out, these new parameters would only ever fill in the gaps in layout (or come after all the other parameters, if explicit bindings aren't used). This implementation strategy proved to be a bit of a mess, since we had to duplicate most of the code between the two passes anyway. This commit eliminates `specializeProgramLayout()` entirely, and instead threads through global generic type arguments as part of the main layout pass. It is almost strictly a cleanup pass, now that the refactored logic for `Program` means the same layout algorithm can apply to specialized and unspecialized programs. This change has one important semantic consequence (which is technically a break in backwards compatiblity for anybody using global generic parameters). Parameters that depend on global generic type parameters now get laid out in declaration order, just like all other shader parameters. This simplifies the rules, and in my experience actually makes application code *easier* to write in a systematic way (whereas the original design was motivated by the idea that giving more things stable locations would be beneficial). A future improvement could be made so that we don't thread through the global generic substitution as part of layout. Instead, we could just attach a list of the global generic type arguments directly to the `TypeLayoutContext` and look those up on-demand when we encounter a global generic parameter type during layout. This would actually eliminate the need for global generics to appear as a `Substitution` entirely. 28 February 2019, 15:59:17 UTC
15bab62 Simplify type layout (#867) * Make vector/matrix type layouts include element type layouts Previously the `MatrixTypeLayout` class was a leaf node in the layout hierarchy, and vector types just used `TypeLayout` with no further refinement. This change adds a `VectorTypeLayout`, and makes all of vector, matrix, and array types inherit form a common base class for `SequenceTypeLayout`s. The actual layout computation logic was updated to compute layouts for the element types of vectors, and for the row (and element) types of matrices. Notes: * Because of the way varying input/output parameters are being handled, their type layouts won't include this new information, and they will just use `TypeLayout`. This was true even for the matrix case before. * I made the design choice in this change to have a matrix type always treat rows as the logical element type (since that is what is surfaced to ther user in the HLSL syntax). We could potentially make our lives easier during layout computation if we made the element type of a `MatrixTypeLayout` depend on the row-/column-major layout choice, but that would then require any algorithm that uses the new layout information to take row-vs-column-major into account. * No code is actually *using* this new information yet, although the work in `ir-union.cpp` could probably benefit from it. The main expected use case going forward is representing constant buffers as a "bag of bits." * Add a specialized type layout approach for varying parameters There is a lot of complexity in `GetLayoutImpl` because it needs to service both the "normal" case, which always wants a `TypeLayout` object to be returned, and the varying parameter case, where we currently don't care about getting back a `TypeLayout` object. Confusingly, the varying parameter layout logic actually *does* construct `TypeLayout` objects, and it just does it inside of `parameter-binding.cpp` rather than in `type-layout.cpp`. That logic cannot (easily) be shared with the `GetLayoutImpl` path because: * The varying case needs to deal with system-value semantics and also parameters that may be inputs, outputs, or both (so that they need to combine resource usage computed for inputs and outputs). * The varying case needs to special-case vectors (and to a lesser extent matrices) because of the quirks of uniform layout (e.g., four `float` varying inputs consume four `locations`, but a `float4` consumes only one location). This change introduces a customized layout function just for varying parameters, that only handles the scalar, vector, and matrix cases (since `parameter-binding.cpp` will have recursed through any strucures/arrays, and should error out on any other types that are illegal in varying parameter lists). In the long run we could consider trying to deduplicate code and share more of this logic with `GetLayoutImpl`, but that would require a more significant refactoring of type layout, which should probably wait until we are doing layout on IR types. * Rename CreateTypeLayout to createTypeLayout This is just a fixup to better reflect our established naming conventions. * Simplify type layout so that it always returns a layout object The core `GetLayoutImpl` routine included a fair bit of complexity to deal with the fact that its `outTypeLayout` parameter was optional. The caller could pass in null to say that it doesn't want a `TypeLayout` object to be constructed, and the routine would conditionalize a lot of its logic to deal with this case. This change simplifies the logic so that a `TypeLayout` is always constructed and returned. Instead of using a combination of a function result (for the `SimpleLayoutInfo`) and an output parameter (for the `TypeLayout`) we use a new `TypeLayoutResult` that acts as a tuple over the two. I had hoped for a more significant cleanup by also eliminating the need to return the `SimpleLayoutInfo` separately from the `TypeLayout`, but the simple layout info is what the underlying per-API/-context "rules" implementations use (so that they can avoid all the complexity of `TypeLayout`), and refactoring to derive the simple layout infor from a computed `TypeLayout` would be a bigger refactoring than I was ready for. * fixup: typos 27 February 2019, 22:58:02 UTC
413aa5a Make sure sourceManager is initialized on DiagnosticSink. (#868) Typo fix. 27 February 2019, 21:18:06 UTC
eee6820 Hotfix/fix stdlib error reporting (#866) * * Add 'identity' version of bit casts (asint, asuint, asfloat) for scalar and vector * Added identity bit casts for matrix (cos no op). We don't support matrix asint on glsl targets * Added tests in bit-cast.slang * Use kIRPseudoOp_Pos for identity asuint/asint/asfloat casts. * * Stop crash if error in stdlib * Use the buildin source manager when compiling stdlib - fixes that line numbers are displayed * Typo fix * Output line directives for 'meta' slang souce files into stdlib * Improve comments and function names. 27 February 2019, 20:17:13 UTC
8ac4452 Use kIRPseudoOp_Pos for identity asuint/asint/asfloat casts. (#865) * * Add 'identity' version of bit casts (asint, asuint, asfloat) for scalar and vector * Added identity bit casts for matrix (cos no op). We don't support matrix asint on glsl targets * Added tests in bit-cast.slang * Use kIRPseudoOp_Pos for identity asuint/asint/asfloat casts. 27 February 2019, 17:15:02 UTC
3fc4813 * Add 'identity' version of bit casts (asint, asuint, asfloat) for scalar and vector (#864) * Added identity bit casts for matrix (cos no op). We don't support matrix asint on glsl targets * Added tests in bit-cast.slang 27 February 2019, 15:38:51 UTC
13ad9c8 * Remove typo in TryRecover (#863) * Remove GLSL specific check - as no longer support GLSL * Remove erroneous check for { on parseClass 27 February 2019, 15:08:29 UTC
15ed452 Hotfix/device check review (#862) * Fix typo on return type. * * Inverted order of FlagCombiner (to make more 'nested for' like) * On Dx12 just use D3D_FEATURE_LEVEL_11_0 * Fix typo on dll name 27 February 2019, 14:14:11 UTC
d9b7326 Dx11 & Dx12 device startup (#861) * Added CombinationUtil to produce combinations of flags Used in Dx11 device creation making it fall back to release driver if debug driver is not found * Made dx12 renderer startup similar to dx11 - testing multiple configs. * Small improvements in naming. * * Moved functionality to gfx from core * Use FlagCombiner to simplify construction, and can be iterated over, without need for array * Share DeviceCheckFlags * Improve comments. * Re-add the comment about combinations tested to set up dx11 device. * More comment improvements. 26 February 2019, 17:25:02 UTC
ef12032 Add support for SV_PointSize semantic for glsl (#853) 23 February 2019, 17:28:21 UTC
32135c5 First steps toward supporting interface-type parameters on shaders (#852) * First steps toward supporting interface-type parameters on shaders What's New ---------- From the perspective of a user, the main thing this change adds is the ability to declare top-level shader parameters (either at global scope, or in an entry-point parameter list) with interface types. For example, the following becomes possible: ```hlsl // Define an interface to modify values interface IModifier { float4 modify(float4 val); } // Define some concrete implementations struct Doubler : IModifier { float4 modify(float4 val) { return val + val; } } struct Squarer : IModifier { ... } // Define a global shader parameter of interface type IModifier gGlobalModifier; // Define an entry point with an interface-type `uniform` parameter void myShader( unifrom IModifier entryPointModifier, float4 inColor : COLOR, out float4 outColor : SV_Target) { // Use the interface-type parameters to compute things float4 color = inColor; color = gGlobalModifier.modify(color); color = entryPointModifier.modify(color); outColor = color; } ``` The user can specialize that shader by specifying the concrete types to use for global and entry-point parameters of interface types (e.g., plugging in `Doubler` for `gGlobalModifier` and `Squarer` for `entryPointModifier`). The "plugging in" process is done in terms of a concept of both global and local "existential slots" which are a new `LayoutResourceKind` that represents the holes where concrete types need to be plugged in for existential/interface types. In simple cases like the above, each interface-type parameter will yield a single existential slot in either the global or entry-point parameter layout. Users can query the start slot and number of slots for each shader parameter, just like they would for any other resource that a parameter can consume. Before generating specialized code, the user plugs in the name of the concrete type they would like to use for each slot using `spSetTypeNameForGlobalExistentialSlot` and/or `spSetTypeNameForEntryPointExistentialSlot`. There are some major limitations to the implementation in this first change: * Parameters must be of interface type (e.g., `IFoo`) and not an array (`IFoo[3]`), or buffer (`ConstantBuffer<IFoo>`) over an interface type. Similarly, `struct` types with interface-type fields still don't work. * The work on interface-type function parameters still doesn't include support for `out` or `inout` parameters, nor for functions that return interface types (that isn't technically related to this change, but affects its usefullness). * No work is being done to correctly lay out shader parameters once the concrete types for existential slots are known, so that this change really only works when the concrete type that gets plugged in is empty. These limitations are severe enough that this feature isn't really usable as implemented in this change, and this merely represents a stepping stone toward a more complete implementation. Implementation -------------- The API side of thing largely mirrors what was already done to support passing strings for the type names to use for global/entry-point generic arguments, so there should be no major surprises there. The logic in `check.cpp` computes the list of existential slots when creating unspecialized `Program`s and `EntryPoint`s (this is logically the "front end" of the compiler), and then checks the supplied argument types against what is expected in each slot when creating specialized `Program`s and `EntryPoint`s. This again mirrors how generic arguments are handled. Type layout was extended to compute the number of existential slots that a type consumes, and will thus automatically assign ranges of slots to top-level and entry-point shader parameters in the same way it already allocates `register`s and `binding`s. The big missing feature is the ability to specialize a layout to account for the concrete types plugged into the existential-type slots. IR generation for specialized programs and entry points was slightly extended so that it attaches information about the concrete types plugged into the existential slots, and the witness tables that show how they conform to the interface for that slot. The linking step needed some small tweaks to make sure that information gets copied over to the target-specific program when we start code generation. The meat of the IR-level work is in `ir-bind-existentials.cpp`, which takes the information that was placed in the IR module by the generation/linking steps and uses it to rewrite shader parameters. For example, if there is a shader parameter `p` of type `IModifier`, and the corresponding existential slot has the type `Doubler` in it, we will rewrite the parameter to have type `Doubler`, and rewrite any uses of `p` to instead use `makeExistential(p, /*witness that Doubler conforms to IModifier*/)`. Once the replacement is done on the parameters, the existing work for specializing existential-based code when the input type(s) are known kicks in and does the rest. Testing ------- A single compute test is added to validate that this feature works. It is narrowly tailored to not require any of the features not supported by the initial implementation (e.g., all of the concrete types used have no members). The test case *does* include use of an associated type through one of these existential-type parameters, which has exposed a subtle bug in how "opening" of existential values is implemented in the front-end. Rather than fix the underlying problem, I cleaned up the code in the front-end to special case when the existential value being opened is a variable bound with `let`, to directly use a reference to that variable rather than introduce a temporary. Similarly, in the IR generation step, I added an optimization to make variables declared with `let` skip introducing an IR-level variable and just use the SSA value of their initializer directly instead. * fixup: missing files * fixup: incorrect type for unreachable return * fixup: actually comment ir-bind-existentials.cpp 19 February 2019, 19:46:05 UTC
a3fd4e2 Split front- and back-ends (#846) * Split front- and back-ends This change is a major refactor of several of the types that provide the behind-the-scenes implementation of the public C API. The goal of this refactor is primarily to allow for future API services that let the user operate both the front- and back-ends of the compiler in a more complex fashion. For example, as user should be able to compile a bunch of source code into modules, look up types, functions, etc. in those modules, specialize generic types/functions to the types they've looked up, and then finally request target code to be gernerated for specialized entry points. The back-end code generation they trigger should re-use the front-end compilation work (parsing, semantic checking, IR generation) that was already performed. The most visible change is that `CompileRequest` has been split up into several smaller types that take responsibility for parts of what it did: * The `Linkage` type owns the storage for `import`ed modules, and well as the `TargetRequest`s that represent code-generation targets. The intention is that an application could use a single `Linkage` for the duration of its runtime (so long as it was okay with the memory usage), so that each `import`ed module only gets loaded once. For now, this type needs to manage the search paths, file system, and source manager, because of its responsibility for loading files. * A `FrontEndCompileRequest` owns the stuff related to parsing, semantic checking, and initial IR generation. This most notably includes the `TranslationUnitRequest`s and the `FrontEndEntryPointRequest`s (which used to be just `EntryPointRequest`s). It's main job is to produce AST and IR modules for each translation unit, and to find and validate the entry points. The front-end request does *not* interact with generic arguments for global or entry-point generic parameters. * The main output of both `import` operations and front-end translation units is the `Module` type, which is just a simple container for both the AST module (to service the reflection/layout APIs, and also for semantic checking of code that `import`s the module) and the IR module (for linking and code generation). This type captures the commonalities between the old `LoadedModule` (which is now just an alias for `Module`) and `TranslationUnitRequest` (which now owns a `Module`). * The secondary output of front-end compilation is a `Program`, which comprises a list of referenced `Module`s and validated `EntryPoint`s that will be used together. Layout and code generation both need a `Program` to tell them what modules and entry points will be used together (we don't want to just code-gen everythin that has ever been loaded into the linakge). The `Program`s created by the front-end do not include generic arguments, so they may provide incomplete layout information and/or be unsuitable for code generation. * A `BackEndCompileRequest` owns stuff related to turning a `Program` into output kernels for the targets of a `Linkage`. Most of the data it owns beyond the `Program` to be compiled is minor, so this is a good candidate for demotion from a heap-allocated object to just a `struct` of options that gets passed around. * The `CompileRequestBase` type is an attempt to wrap up the common functionality of both front-end and back-end compile requests. Most of it is just exposing the availability of a linkage and `DiagnosticSink`, so this type is a good candidate for subsequent removal. The main interesting thing it has is the flags related to dumping and validation of IR, so there is probably a good refactoring still to be made around deciding how options should be handled going forward. * Behind the scenes, the `Program` type is set up to handle some level of on-line compilation and layout work. The `Program` knows the `Linkage` it belongs to, and allows for a `TargetProgram` to be looked up based on a specific `TargetRequest`. A `TargetProgram` then allows layout information and compiled kernel code to be asked for on-demand, in order to support eventual "live" compilation scenarios. * The `EndToEndCompileRequest` type is a composition/coordination type that replaces the old `CompileRequest` in a way that uses the services of the various other types. It owns a few pieces of state that only make sense in the context of an end-to-end compile (e.g., there is really no way to "pass through" code when the front- and back-ends are run separately) or a command-line compile (everything to do with specifying output paths for files is really just for the benefit of `slangc`, and might even be moved there over time). * One important detail is that the `EndToEndCompilRequest` owns all of the string-based generic arguments for both global and entry-point generic parameters. The logic in `check.cpp` for dealing with those arguments has been heavily refactored to separate out the parsings steps that are specific to end-to-end compilation with string-based type arguments, and the semantic checking steps that result in a specialized `Program` (which can be exposed through new APIs that aren't tied to end-to-end compilation). It is perhaps not surprising that this change had a lot of consequences, so I'll briefly run over some of the main categories of changes required: * I changed the way that global generic arguments are passed via API (use `spSetGlobalGenericArgs` instead of the generic arguments for `spAddEntryPointEx`, which are not just for entry-point generics), which has been a change that we've needed for a long time. This is technically a breaking API change, although we should have very few client applications that care about it. * A bunch of places that used to take "big" objects like `CompileRequest` now just take the sub-pieces they care about (e.g., a function might have only needed a `Linkage` and a `DiagnosticSink`). This makes many subroutines or "context" struct types more generally useful, at the cost of taking more parameters. * In a few cases the conceptually clean separation of the layers breaks down (often for edge-case or compatibility features), and so we may pass along additional objects that are allowed to be null, but are used when present. A big example of this is how the back-end code generation routines accept an `EndToEndCompileRequest` that is optional, and only used to check whether "pass through" compilation is needed. We should probably look into cleaning this kind of logic up over time so that we don't need to violate the apparent separation of phases of compilation. * In cases where separation of layers was being broken for the sake of GLSL features, I went ahead and ripped them out, since all of that should be dead code anyway. * In many cases I increased the encapsulation of data in the core types to help track down use sites and make sure they are following invariants better. * In cases where code was doing, e.g., `context->shared->compileRequest->session->getThing()` I have tried to introduce convenience routines so that the usage site is just `context->getThing()` to improve encapsulation and allow changes to be made more easily going forward. * The `noteInternalErrorLoc` functionality was moved off of the compile request and into `DiagnosticSink`, since that is the one type you can rely on having around when you want to note an internal error. We may consider going forward if (and how) it should reset the counter used for noting locations on internal errors. * A few APIs now take `DiagnosticSink*` arguments where they didn't before, and as a result some public APIs need to create `DiagnosticSink`s to pass in, before going ahead and ignoring the messages. In the future there should be variations of these APIs that accept an `ISlangBlob**` parameter for the output. * fixup: missing include for compilers with accurate template checking (non-VS) * fixup: review feedback 15 February 2019, 17:08:19 UTC
4cd317b Fix for Dx12 to stop crash when dxil cannot be handled by driver (#851) * If there is a problem with initialize RenderTestApp::initialize constructing the pipeline, this was not being reported as an error causing a later crash. * Use same style to return error. 14 February 2019, 16:24:40 UTC
b059de8 * Add cross compile test (#849) * Add intrinsic for StructuredBuffer.Load 14 February 2019, 13:27:46 UTC
4133192 Add a test for glslang errors when using StructuredBuffer Load() (#848) 13 February 2019, 20:37:14 UTC
d7280c3 Output readonly for suitable glsl buffers (#845) * Output readonly on buffers for glsl if resource is readonly. Didn't add to emitGLSLParameterGroup because the cases there seem to to either be implicitly read only, or allow write. * * Improve comments around use of 'readonly' on glsl output * Use readonly with shaderRecord * Add comment pointing out shader record can be rw on vk, so might require changes in the future. 13 February 2019, 19:49:02 UTC
8e7e74f Ignore expression if hit #if when skipping. (#844) * Ignore expression if hit #if when skipping. * Add test for #if parsing is ok * * Use SkipToEndOfLine * Improve comments slightly 13 February 2019, 18:43:00 UTC
259cfa9 Fix typos in diagnostic message and comments (#843) * * Fix some comment typos * Fix typo in diagnostic message * Fix typo in expected output of undefined-in-preprocessor-conditional 13 February 2019, 15:40:57 UTC
73af710 Track stage for varying sub-fields (#842) Fixes #841 This reverts a small change made in #815 that seemed innocent at the time: we stopped tracking an explicit `Stage` to go with every `VarLayout` that is part of an entry-point varying parameter, and instead only associated the stage with the top-level parameter. That change ended up breaking the logic to emit the `flat` modifier automatically for integer type fragment-shader inputs for GLSL, but we didn't have a regression test to catch that case. This change adds a regression test to cover this case, and adds the small number of lines that were removed from `parameter-binding.cpp`. A few other test outputs had to be updated for the change (these are outputs that were changed in #815 for the same reason). 12 February 2019, 23:13:00 UTC
fb6432b Feature/alloc for ir inst creation review (#839) * Make MemoryArena rewindable. * Add test for rewinding MemoryArena * Use memory rewinding in IRInst lookup instead of malloc/free. * Small tidy. * Don't bother recreating instruction if after lookup it's found it's new. * Fix 32 bit signed compare issue. * Improve documentation around MemoryArena. * * Improve perf of test for hash expansion on Dictionary * First attempt at TryGetOrAdd * Improve comments around findOrEmitHoistableInst * Removed template<T> from Dictionary. Use TryGetValueOrAdd to findOrEmitHoistableInst * Use TryGetValueOrAdd in findOrEmitHoistableInst * Use Type thing = {} to initialize type over Type thing{} style. 12 February 2019, 16:16:28 UTC
44bd4b5 * Use LayoutResourceKind for calcing total num regs used (#838) * Made diagnostic message more compliant + fixed test output * Typo fixes 11 February 2019, 17:21:38 UTC
e13fdd8 MemoryArena rewindability/Improved IRInst construction (#837) * Make MemoryArena rewindable. * Add test for rewinding MemoryArena * Use memory rewinding in IRInst lookup instead of malloc/free. * Small tidy. * Don't bother recreating instruction if after lookup it's found it's new. * Fix 32 bit signed compare issue. 11 February 2019, 15:54:58 UTC
1c969b9 [[vk::shader_record]] (#836) * * Replaced ShaderRecordNVLayoutModifier with ShaderRecordAttribute * Allowed attributed [[vk::shader_record] and [[shader_record]] * Checking there is at most 1 ShaderRecord active * Small typo fixes * Slightly improve diagnostic. Replace expected file. 11 February 2019, 14:41:10 UTC
9f8a92e Update to the latest version of the glslang reference compiler (#835) 08 February 2019, 20:36:31 UTC
ef08bda Hotfix/dispatch thread id improvements (#834) * * Make vector comparisons out correct functions on glsl * Test for vector comparisons * Typo fixes * Glsl vector comparisons use functions. * Added a coercion test. * Do checking for the SV_DispatchThreadId type to see if it appears valid. * Fix typo * Make glsl do type conversion for SV_DispatchThreadID parameter. * Fix glsl to match func-resource-param-array with changes to how SV_DispatchThreadID changes. 08 February 2019, 16:41:26 UTC
c34a5e7 Fix vector compares on GLSL targets (#833) * * Make vector comparisons out correct functions on glsl * Test for vector comparisons * Typo fixes * Glsl vector comparisons use functions. * Added a coercion test. 08 February 2019, 14:02:55 UTC
23b36c5 * Improve test coverage of bit cast, particularly for asfloat. Make the values being cast between valid floats. (#832) * Typo fix 08 February 2019, 00:37:26 UTC
4d593fe Hotfix/remove null this work around (#831) * Re-enable warnings around null this. * Remove testing for nullptr in Substitution::Equals tests * Fix ref counting problem in vulkan render. * * Remove SLANG_ASSERT(this) in mthods * Place asserts conservatively at method call sites where appropriate. 07 February 2019, 23:04:46 UTC
2d1291a Merge pull request #829 from tfoleyNV/fix-nested-type-conformances Fix checking of interface conformances for nested types 06 February 2019, 03:41:33 UTC
c6870dc Merge branch 'master' into fix-nested-type-conformances 06 February 2019, 02:47:55 UTC
3d62bea Merge pull request #830 from csyonghe/gencloser Allow generics to close with >> 06 February 2019, 02:46:04 UTC
a39fd3d Merge branch 'master' into gencloser 06 February 2019, 02:18:16 UTC
13d7e34 Merge branch 'master' into fix-nested-type-conformances 06 February 2019, 00:47:37 UTC
60cc9f2 Allow entry points to have explicit generic parameters (#826) * Allow entry points to have explicit generic parameters Prior to this change, the Slang implementation required users to use global `type_param` declarations in order to specialize a full shader. For example: ```hlsl type_param L : ILight; ParameterBlock<L> gLight; [shader("fragment")] float4 fs(...) { ... gLight.doSomething() ... } ``` With this change we can rewrite code like the above using explicit generics, plus the ability to have `uniform` entry-point parameters: ```hlsl [shader("fragment")] float4 fs<L : ILight>( uniform ParameterBlock<L> light, ...) { ... light.doSomething() ... } ``` Having this support in place should make it possible for us to eliminate global generic type parameters and the complications they cause (both at a conceptual and implementation level). The most central and visible piece of the change is that `EntryPointRequest` now holds a `DeclRef<FuncDecl>` instead of just ` RefPtr<FuncDecl>`, which allows it to refer to a specialization of a generic function. Various places in the code that refer to the `EntryPointRequest::decl` member now use a `getFuncDecl()` or `getFuncDeclRef()` method as appropriate (see `compiler.h`). In order to fill in the new data, the `findAndValidateEntryPoint` function has been greaterly overhauled. The changes to its operation include: * The by-name lookup step for the entry point function has been adapted to accept either a function or a generic function. * The generic argument strings provided by API or command line are no longer parsed all the way to `Type`s, but instead just to `Expr`s in the first pass. * There are now two cases for checking the global generic arguments against their matching parameters. The first case is the new one, where we plug the generic argument `Expr`s into the explicit generic parameters of an entry point (that case re-uses existing semantic checking logic). The second case is the pre-existing code for dealing with global generic type arguments. The `lower-to-ir.cpp` logic for hadling entry points then had to be extended. Making it deal with a full `DeclRef` instead of just a `Decl` was the easy part (just call `emitDeclRef` instead of `ensureDecl`). The more interesting bits were: * We need to carefully add the `IREntryPointDecoration` to the nested function and not the generic in the case where we have a generic entry point. There is a handy `getResolvedInstForDecorations` that can extract the return value for an IR generic so that we can decorate the right hting. * We need to make sure that in the case where we emit a `specialize` instruction (which normally wouldn't get a linkage decoration), we attach an `[export(...)]` decoration to it with the mangled name of the decl-ref, so that it can be found during the linking step. The IR linking step is then slightly more complicated because the mangled entry point name could either refer directly to an `IRFunc` or to a `specialize` instruction for a generic entry point. The logic was refactored to first clone the entry point symbol without concern for which case it is (the old code was specific to functions), and then *if* the result is a `specialize` instruction, we attempt to run generic specialization on-demand. That on-demand specialization is a bit of a kludge, but it deals with the fact that all the downstream passing only expect to see an `IRFunc`. A future cleanup might try to split out that specialization step into its own pass, which ends up being a limited form of the specialization pass. Since I was already having to touch a lot of the code around IR linking, I went ahead and refactored the signature of the operations. I eliminated the need for the caller to create, pass in, and then destroy an `IRSpecializationState` (really an IR *linking* state), and replaced it with a structure local to the pass (that data structure was a remnant of an older approach in the compiler), and then also renamed the main operation to `linkIR` to reflect what it is doing in our conceptual flow. Smaller changes made along the way include: * Refactored `visitGenericAppExpr` to create a subroutine `checkGenericAppWithCheckedArgs` so that it can be used by the entry-point validation logic described above). * Refactored the declarations around the IR passes in `emitEntryPoint()` (`emit.cpp`), to show that things are more self-contained than they used to be (e.g., that the `TypeLegalizationContext` is now only needed by one pass). * Refactored the generic specialization code so that there is a stand-along free function that can perform specialization on a `specialize` instruction without all the other context being required. This is only to support the limited specialization that needs to be done as part of linking. * Updated the `global-type-param.slang` test to actually test entry-point generic parameters. In a later pass we can/should rework all the tests/examples for global type parameters over to use explicit entry-point generic parameters (at which point we should rename the tests as well). For now I am leaving thigns with just one test case, with the expectation that bugs will be found and ironed out as we expand to more tests. * fixup * Fixup: don't leave entry-point decorations on stuff we don't want to keep The IR `[entryPoint]` decoration is effectively a "keep this alive" decoration, which means that attaching it to something we don't intend to keep around can lead to Bad Things. The approach to generic entry points was attaching `[entryPoint]` to the underlying `IRFunc` because that seemed to make sense, but that meant that the `specialize` instruction at global scope scould instantiate that generic and then keep it alive, even if the resulting function wouldn't be valid according to the language rules. As a quick fix, I'm attaching `[entryPoint]` to the `specialize` instruction instead in such cases, and then re-attaching it to the result of explicit specialization during linking. * Port most of remaining test and rename global type parameters This change ports as many as possible of the existing tests for global type parameters over to use entry-point generic parameters instead. For the most part this is a mechanical change. A few test cases remain using global generic parameters, as does the `model-viewer` example application. The reason for this is that the shaders have either or both the following features: * A vertex and fragment shader that can/shold agree on their parameters * A type declaration (e.g., a `struct`) that is dependent on one of the generic type parameters In these cases, it would really only make sense to switch to explicit parameters once we support shader entry points nested inside of a `struct` type, so that we can use an outer generic `struct` as a mechanism to scope the entry points and other type-dependent declrations. Since global-scope type parameters need to persist for at least a bit longer, I went ahead and renamed all the use sites over to use `type_param` for consistency. 06 February 2019, 00:47:25 UTC
c198eab Allow generics to close with >> 06 February 2019, 00:14:14 UTC
43950e2 Fix checking of interface conformances for nested types Before this change, code like the following would crash the compiler: ```hlsl interface IThing { /* ... */ } struct Outer { struct Inner : IThing {} } /* go on to use Outer.Inner */ ``` The problem was that the front-end logic for checking interface conformances was *only* checking declarations at the top level of a module, or nested under a generic. This change fixes the logic to recurse through the entire tree of declarations. I have added a test case that uses a nested `struct` type to satisfy an associated type requirement, to confirm that the new check works as intended. 05 February 2019, 21:55:17 UTC
314795b Fix confused definitions of pre/post increment/decrement (#827) * Fix confused definitions of pre/post increment/decrement We somehow have been compiling `++i` as `i++` (and vice versa) for a long time without noticing. This change fixes the implementation of these pseudo-ops in IR codegen, and adds a comment to explain the rationale for why their definitions should be what they are. * fixup: typo 05 February 2019, 21:46:32 UTC
a17b68a Produce a better error message on errors in inheritance clauses (#828) If I write: ``` struct Foo : IDoesntExist {} ``` Then currently Slang complains first that `IDoesntExist` is an undefined identifier, then it complains that it expected an interface type in the inheritance clause. The second ("cascading") error isn't really helpful, because of *course* if something isn't defined it isn't an interface. This change detects the case where the type expression is erroneous so that we avoid the cascading error. 05 February 2019, 21:41:04 UTC
9b80537 Feature/view path (#824) * Use 'is' over 'as' where appropriate. * dynamic_cast -> dynamicCast * Replace 'dynamicCast' with 'as' where has no change in behavior/ambiguity. * Replace dynamicCast with as where doesn't change behavior/non ambiguous. * Keep a per view path to the file loaded - such that diagnostic messages always display the path to the requested file. * Add simplifyPath to ISlangFileSystemExt Simplify (if possible) paths that are set on SourceFile and SourcView - doing so makes reading paths simpler. * Fix small typo. * Improve documentation in source for getFileUniqueIdentity * Fix override warning. 04 February 2019, 22:30:51 UTC
0d20699 Feature/casting tidyup (#822) * Use 'is' over 'as' where appropriate. * dynamic_cast -> dynamicCast * Replace 'dynamicCast' with 'as' where has no change in behavior/ambiguity. * Replace dynamicCast with as where doesn't change behavior/non ambiguous. 04 February 2019, 17:11:18 UTC
3726194 Feature/as refactor review (#821) * Replace dynamicCast with as where does not change behavior (ie not Type derived). Use free function where scoping is clear. * Replace uses of dynamicCast with as when there is no difference in behavior. * Remove the IsXXXX methods from Type. * Don't have separate smart pointer to store canonicalType on Type. * Simplify Slang.FilteredMemberRefList.Adjust, such does the cast directly. * Use free as where appropriate. * Use free function version of casts where appropriate. * Fix text in casting.md * Fix typos in decl-refs.md * Remove the uses of free function as on RefDecl. Add 'canAs' to RefDecl as a way to test if a cast is possible. Moved 'as' into RefDeclBase. * Use 'is' to test for as cast on smart pointers. Fix small scope issue. * * Cache stringType and enumTypeType on the Session * Make DeclRefType::Create return a RefPtr * Make casting of result use the *method* .as (cos using free function would mean objects being wrongly destroyed) * Make results from createInstance ref'd to avoid possible leaks. * Fix typo in template parameter for is on RefPtr. 02 February 2019, 16:58:54 UTC
6f2c034 Document how as and dynamicCast are used, and issues surrounding them. (#820) 01 February 2019, 15:56:44 UTC
d877e22 Merge pull request #819 from csyonghe/crashfix Fixes crashes at source error 31 January 2019, 22:05:16 UTC
bcb361d Merge branch 'master' into crashfix 31 January 2019, 21:35:03 UTC
f20c64c Initial support for uniform parameters on entry points (#815) * Initial support for uniform parameters on entry points The basic feature this work adds is the ability to define a shader entry point like: ```hlsl [shader("fragment")] float4 main( uniform Texture2D t, uniform SamplerState s, float2 uv : UV) { return t.Sample(s,uv); } ``` In this example, the `uniform` keyword is used to mark that the given entry point parameters are *not* varying input/output flowing through the pipeline, but rather uniform shader parameters that should function as if the shader was declared more like: ```hlsl Texture2D t, SamplerState s, [shader("fragment")] float4 main( float2 uv : UV) { return t.Sample(s,uv); } ``` Allowing `uniform` parameters on entry points makes it easier to define multiple entry points in one file without accidentally polluting the global scope with shader parameters that only certain entry points care about. This feature is also more or less a prerequisite for allowing generic type parameters directly on entry point functions, since the main use case for those type parameters is for determining what goes in various `ConstantBuffer`s or `ParameterBlock`s. There are two main pieces to the implementation. First, we need to be able to compute appropriate layout information for entry points that include `uniform` parameters. Second, we need to transform the entry point function to move any `uniform` parameters to be ordinary global-scope shader parameters, to make sure that all other back-end passes don't need to worry about this special case. The latter piece of the implementation is, relatively speaking, simpler. The pass in `ir-entry-point-uniforms.{h,cpp}` converts entry point parameters that are determined to be uniform (using the already-computed layout information) into fields of a `struct` type and then declares a global shader parameter based on that `struct` type (and applies already-computed layout information to that parameter). After that, the remaining IR passes (notably including type legalization) will handle things just as for any other global shader parameter. The changes to the layout step are more significant, but most of the changes are just cleanups and fixes to enable the feature. The two major changes that enable entry-point `uniform` parameters are: * In `collectEntryPointParameters` we now dispatch out to a new `computeEntryPointParameterTypeLayout` function, which decided whether to compute the type layout for a `uniform` parameter, or for a varying parameter (what used to be the default behavior handled by `processEntryPointParameterDecl`). * The main `generateParameterBindings` routine was extended so that it allocates registers/bindings to the resources required by each entry point (using `completeBindingsForParameter`) after it has allocated registers/binding to all of the global-scope parameters (this addition is mirrored in `specializeProgramLayout`). The effect of these changes is that the `uniform` parameters of any entry points specified in a compile request will be laid out after the global-scope parameters, in the order the entry points were specified in the compile request. A bunch of smaller changes were made around parameter layout that are worth enumerating so that the diffs make some sense: * The `EntryPointLayout` type was changed so that instead of trying to *be* a `StructTypeLayout`, it instead *owns* one, in the same fashion as `ProgramLayout`. This commonality was factored into a base class `ScopeLayout`, and a bunch of edits followed from that change. * Because `uniform` parameters are moved out of the entry point parameter list early in the IR transformations, the logic in `ir-glsl-legalize.cpp` that tried to look up parameter layout information by index would no longer work if the entry point parameter list had been altered. Instead, that logic now looks for the decorations directly on the parameters. * The `UsedRange` type in `parameter-binding.cpp` was tracking the existing parameter associated with a range using a `ParameterInfo*` (which accounts for the possibility of multiple `VarDecl`s mapping to the same logical shader parameter), when just using a `VarLayout*` is sufficient for all current use cases. The overhead of allocating a `ParameterInfo` seems like overkill for entry-point parameters, where there can't possibly be multiple declarations of the "same" parameter, so avoiding these overheads was a focus when trying to deduplicate code between the global and entry-point parameter cases. * A bunch of parameter binding logic that was specific to GLSL input has been deleted completely. There was no way to even execute this code in the compiler today, and there is pretty much zero chance of us needing (or wanting) to deal with GLSL input in the future. This includes custom `UsedRangeSet`s specific to each translation unit, which were only needed for global-scope `in` and `out` varying declarations in GLSL. * A bunch of functions with `EntryPointParameter` in their names were renamed to use `EntryPointVaryingParameter` to help distinguish that they only apply to the varying case, while entry point `uniform` parameters are handled elsewhere. * The `completeBindingsForParameter` function was re-worked into something that can be used for both global-scope shader parameters (where we have a `ParameterInfo` and possibly explicit bindings) and entry-point parameters (where we expect to have neither). This helps unify the (fairly subtle) logic for how we allocate and assign bindings for resources, constant buffers, parameter blocks, etc. * A small change was made so that the entry-point stage is attached directly to top-level parameters of the entry point, and *not* recursively to every field along the way. This could be a breaking change for some applications, but it makes more logical sense (to me); we'll have to check if this affects Falcor. This change produces different output for several of the reflection tests, but the changes are consistent with no longer attaching stage information to sub-fields of varying `struct`-type parameters. * Because there is a bunch of repeated logic in `parameter-binding.cpp` that has to do with computing a `struct` layout for ordinary/uniform data, I tried to factor that into a single `ScopeLayoutBuilder` type, which handles computing the offsets for any parameters with ordinary data, and then also handles wrapping up the layout in a constant buffer layout if there was any ordinary data at the end. * A similar convenience routine `maybeAllocateConstantBufferBinding` was added because I noticed multiple places in `parameter-binding.cpp` that were trying to allocate a constant buffer binding for global uniforms, and they were wildly inconsistent (and in most cases used logic that would only work for D3D). * The main `generateParameterBindings` routine is significantly shortened by using all of these utilities that were introduced. I tried to comment the places that changed to explain the overall flow correctly. * The `specializeProgramLayout` routine (used to take a `ProgramLayout` from `generateParameterBindings` and specialize it based on knowledge of global generic arguments) had basically been rewritten with more explicit commenting/rationale for what happens in each step. It makes use of the same shared utilities as `generateParameterBindings` and `collectEntryPointParameters`. In terms of testing: * I added a test case to specifically test the new behavior, and in particular I made sure to include a mix of both global and entry-point parameters and also to have entry-point parameters of both ordinary and resource/object types. * I tweaked an existing test for global type parameters to use an entry-point `uniform` parameter instead of a global one, in an effort to migrate it toward being able to use an explicitly generic entry point. * fixups from merge 31 January 2019, 19:33:57 UTC
11c547d Feature/as refactor (#817) * Made dynamicCast a free function. * Replace As with as or dynamicCast depending on if it is a type. * Fix problem with using non smart pointer cast. * Removed legacy asXXXX methods. * Remove As from Type. * Removed As from Qual type -> made coercable into Type*, such that can just use free 'as'. * Remove left over QualType::As() impl. * Remove As from SyntaxNodeBase. * Made as for instructions implemented by dynamicCast. * Replace As on DeclRef. Use the global as<> to do the cast. * Add const safe versions of dynamicCast and as for IRInst 31 January 2019, 15:14:26 UTC
c1fe5f2 fixup x86 compiler error. 31 January 2019, 04:46:03 UTC
04f1bad Fixes crashes at source error. 31 January 2019, 01:27:08 UTC
4db0aba Merge pull request #818 from csyonghe/fix-while-in-gen Fixing IR-lowering not properly registering func decl 31 January 2019, 01:25:09 UTC
c6e5551 Merge branch 'master' into fix-while-in-gen 30 January 2019, 23:40:00 UTC
8286737 Fixing IR-lowering not properly registering func decl 30 January 2019, 22:35:50 UTC
dc01803 Fix parsing of modifiers on generic declarations (#816) The way we handle generics in the AST is to have a `GenericDecl` AST node that can wrap an arbitrary "inner" `Decl`. This representation has proved valuable, but it also creates some gotchas because a `GenericDecl` is also a `Decl`. One example of where this can be tricky is for attributes and other modifiers attached to something generic: ```hlsl [special] void foo<T>(...) { ... } ``` In this case, the current parser logic was gobbling up a list of `Modifier`s (including the `[special]` attribute here), then parsing the declaration that follows, and then attaching those modifiers to the resulting declaration. In this case, however, the "resulting declaration" is not a `FuncDecl` as one might expect, but the `GenericDecl` that wraps it. The solution is pretty simple: when we are done parsing a declaration and are going to attach the modifiers we parsed to it, we should first "unwrap" any outer `GenericDecl` and apply the modifiers to the thing inside instead. This logic presumes that modifiers always want to apply to the inner declaration and not to the generic, an that seems reasonable for now. If we wanted we could add some special-case logic later in the compiler to implicitly "float" certain modifiers up to the generic, in cases where they are found to be inappropriate for the inner declaration. 30 January 2019, 22:35:44 UTC
685a811 Merge pull request #812 from csyonghe/attribute Add support for user defined attributes 29 January 2019, 23:18:15 UTC
c176128 Add underscores to `AttributeUsage` to signal its preview state. 29 January 2019, 21:35:23 UTC
d222889 Fix core.meta.slang Escaped expression cannot start with '('. 29 January 2019, 21:28:28 UTC
b7f8f7a Add support for user defined attributes. 29 January 2019, 19:41:54 UTC
f8b8ea0 Merge pull request #807 from csyonghe/yong-fix2 Fix type legalization to correctly handle nested empty struct fields 29 January 2019, 00:12:16 UTC
adb3e22 Merge branch 'master' into yong-fix2 28 January 2019, 22:21:21 UTC
3c3513a Support function parameters of existential (interface) type (#802) * Support function parameters of existential (interface) type The basic idea here is that you can define a function that takes an interface-type parameter: ```hlsl interface IThing { void doSOmething(); } void coolFunction(IThing thing) { ... thing.doSomething() ... } ``` and call it with a concrete value that implements the given interface: ```hlsl struct Stuff : IThing { void doSomething() { /* secret sauce */ } } ... Stuff stuff; coolFunction(stuff); ``` The compiler implementation will specialize `coolFunction` based on the concrete type that was actually passed in, resulting in output code along the lines of: ```hlsl struct Stuff { ... } void Stuff_doSomething(Stuff this) { /* secret sauce */ } void coolFunction_Stuff(Stuff thing) { ... Stuff_doSomething(thing); } ``` In terms of implementation the new specialization approach has been integrated into the existing pass for generic specialization (which has been refactored significantly along the way), because generic specialization can open up opportunities for existential/interface simplification and vice versa, so there is no fixed interleaving of the two passes that can clean up everything. The new logic therefore subsumes the old code for simplifying existential types (which only worked on local variables) in `ir-existential.{h,cpp}`. The local simplification rules from that implementation have become part of the core specialization pass instead, so that they can open up further transformation opportunities enabled by existential-type simplifications. This code in place right now only handles the basic case of a function parameter that directly uses an interface type, and not one that wraps up an interface type in an array, structure, etc. Additional simplifications need to be introduced to deal with those cases as well. * fixup: typos 28 January 2019, 22:20:44 UTC
3b9573a remove line directives in test files 28 January 2019, 18:53:09 UTC
9812963 Fix type legalization to correctly handle empty struct fields. 28 January 2019, 18:50:05 UTC
f2579a6 Merge pull request #806 from csyonghe/texture-fix Add GLSL translation rules for SampleCmp and bit reinterpretation functions 28 January 2019, 18:48:10 UTC
016f389 Merge pull request #805 from csyonghe/yong-fix More fixes to empty-struct parameters 28 January 2019, 18:47:48 UTC
962f265 Merge branch 'master' into yong-fix 28 January 2019, 17:45:42 UTC
71f1750 Merge branch 'master' into texture-fix 28 January 2019, 17:42:27 UTC
df9dc57 Feature/bit cast glsl (#808) * First attempt at asint, asuint, asfloat intrinsics. * Test with countbits * Placing glsl definitions first makes them get picked up. * Some more improvements around asint. * Add support for vector versions of asint/asunit * Fix some typos in asuint/asint intrinsics for glsl. Simplified and increased coverage of as/u/int tests. * Added bit-cast-double test. Added notional support for asdouble bit casts to glsl - but couldn't test because glslang doesn't seem to support the extension. * Try to get double bit casts working - doesn't work cos of block issue. * Only output parents on intrinic replacement if return type is not void. 28 January 2019, 17:28:05 UTC
eefe253 Add GLSL translation rules for `SampleCmp`, `asint` and `asfloat`. 26 January 2019, 02:11:57 UTC
864c38e fix up empty-struct-parameters 26 January 2019, 02:10:57 UTC
a38490d Move glsl entry point legalization to later stage of compilation. This allows generic types to be used in entry point parameters. 26 January 2019, 01:49:51 UTC
41fde4b Fix GLSL translation of several Texture* operations (#800) A user found that the `Texture2D<float2>.Load(...)` operation was not being compiled to GLSL properly, such that it returned a `vec4` instead of the expected `vec2`. The GLSL texture-related functions always return (and take) 4-component vectors, and we already have infrastructure in `emit.cpp` for recognizing a `$z` operator in the GLSL intrinsic definition to stand in for an appropriate swizzle based on teh number of components in the texture result type. This change just adds that `$z` operator to the GLSL code for several more texture operations (including `Load()`) that are defined on a `Texture*<T>` and that return `T`. This change doesn't try to add additional GLSL translations for texture-related operations (e.g., additional variations like `SampleCmp` that we have defined in the stdlib but not given GLSL translations for). That work still needs to be done. 25 January 2019, 20:02:50 UTC
027e451 If dxil fails to load, do not report it's missing as an error to the sink. It's missing will be detected later in processing and output as a warning. (#799) 25 January 2019, 18:30:41 UTC
3048d5d Fixup handling of empty structs in function return types and parameters. (#796) * Fixup handling of empty structs in function return types and parameters. * Bug fix in legalizeFunc() * More comprehensive empty struct test * Fix `legalizeFieldExtract` for empty struct field. * Add empty struct handling for construct inst 25 January 2019, 16:08:01 UTC
8171a55 Support "modern" declaration syntax as an option (#792) * Support "modern" declaration syntax as an option Fixed #202 This change adds four new declaration keywords: The `let` and `var` keywords introduce immutable and mutable variables, respectively. They can only be used to declare a single variable at a time (unlike C declaration syntax), and they support inference of the variable's type from its initial-value expression. Examples: ``` let a : int = 1; // immutable with explicit type and initial-value expression let b = a + 1; // immutable, with type inferred var c : float; // mutable, with explicit type var d = b + c; // mutable, with type inferred ``` These declaration forms can be used wherever ordinary global, local, or member variable declarations appeared before. Right now they do not change rules about what is or is not considered a shader parameter. The `static` modifier should work on these forms as expected, but a `static let` variable is *not* the same as a `static const`, so an explicit `const` is still needed if you want that behavior. A `typealias` declaration introduces a named type alias, similar to `typedef`, but with more reasonable syntax. It inherits from the same AST class that `typedef` uses, so all of the code after parsing should be able to treat them as equivalent. To give a simple example: ``` // typedef int MyArray[3]; typealais MyArray = int[3]; ``` A `func` declaration introduces a function. Like `typealias` it re-uses the existing AST class, so there is no need for major changes after parsing. A `func` declaration uses a syntax similar to `let` variables for its parameters, and takes the (optional) result type in a trailing position. For example: ``` func myAdd(a: int, b: int) -> int { return a + b; } ``` If a `func` declaration leaves of the return type clause, the return type is assumed to be `void`. The main difference (beyond the trailing return type) is that the parameters of a `func`-declared function are immutable (unless they are `out`/`inout`). This change doesn't add support for declaring operator overloads with `func`, but that should be added later, and I'd like to make that the only way to declare such operations: ``` func +(left: MyType, right: MyType) -> MyType { ... } ``` The use of `:` for declaring parameter types here means that a function declared with modern syntax currently cannot include HLSL-style semantics on its parameters (or its result). We might consider introducing an `[attribute]`-based syntax for adding semantics to parameters if we think this is important, but for now it is fine to insist that users declare their entry points using traditional syntax. This change strives to avoid unecessary changes after parsing, but if the new syntax catches on with users there are some small ways we can take advantage of it for performance. In particular, since `let` declarations and parameters of modern-style functions are immutable, we do not need to generate read/write local temporaries for them during lowering to the IR (technically we can make the same optimization for `const` locals). In the process of implementing these new forms I also added a few subroutines to help share code better between existing cases in the parser. In particular, parsing of generic parameter lists on declarations that can be generic is now simplified and more unified. * Fixup: remove leftover debugging code * fixup: typos 25 January 2019, 00:04:10 UTC
eda82cb Fix a regression in geometry shader cross-compilation (#794) The underlying problem here was that legalization of entry point parameters for GLSL eliminates all the parameters to `main()`, but we still left a dangling reference to one of those parameters if it was a geometry shader output stream. The un-parented parameter would lead to an infinite loop in a later IR step, because it would never be reached by the transformation, and thus could never change its status to the one for "visited" instructions. The fix here is to simply replace any refernces to the GS input stream parameter with an `undefined` instruction in the IR, and then rely on the fact that the downstream GLSL emit logic wouldn't actually reference that value anyway (hence why the danlging reference wasn't originally an issue). I included a basic cross-compilation test case for geometry shaders to try to avoid subsequent regressions like this (Vulkan GS support is one of the most commonly recurring regressions we've had). The comment I put into the IR legalization logic makes it clear that the strategy used there isn't 100% rock-solid anyway (it only works in all the `EmitVertex()` calls come from the shader entry point function, and not subroutines. Adding a better (more robust) translation strategy for geometry shaders would be a nice bit of future work. 24 January 2019, 19:31:35 UTC
968d7b4 Merge pull request #793 from csyonghe/yong-fix Fix handling of GLSL sign function 24 January 2019, 05:51:34 UTC
a426159 Fixing GLSL sign function. fixes #602 24 January 2019, 03:54:21 UTC
935b629 Fix IR emit logic for methods in `struct` types (#791) There was a bug in the logic for emitting initial IR, such that it was neglecting to emit "methods" (member functions) unless they were also referenced by a non-member (global) function, or were needed to satisfy an interface requirement. This would only matter for `import`ed modules, since for non-`import`ed code, anything relevant would be referenced by the entry point so that the problem would never surface. This change fixes the underlying problem by adding a step to the IR lowering pass called `ensureAllDeclsRec` that makes sure that not only global-scope declarations, but also anything nested under a `struct` type gets emitted to the initial IR module. There are also a few unrelated fixes in this PR, which are things I ran into while making the fix: * Deleted support for the (long gone) `IRDeclRef` type in our `slang.natvis` file * Added support for visualizing the value of IR string and integer literals when they appear in the debugger * Fixed IR dumping logic to not skip emitting `struct` and `interface` instructions. Switching those to inherit from `IRType` accidentally affected how they get printed in IR dumps by default. * Fixed up the IR linking logic so that it correctly takes `[export]` decorations into account, so that an exported definition will always be taken over any other (unless the latter is more specialized for the target). I initially implemented this in an attempt to fix the original issue, but found it wasn't a fix for the root cause. It is still a better approach than what was implemented previously, so I'm leaving it in place. 23 January 2019, 17:13:03 UTC
back to top