https://github.com/shader-slang/slang
Revision e66d66b88e1c6ef8499708952fcbe3ba873f6e4c authored by Tim Foley on 14 June 2018, 18:56:31 UTC, committed by GitHub on 14 June 2018, 18:56:31 UTC
* Add support for "blobs" and a file-system callback

The most obvious change here is that the Slang header now includes a few COM-style interfaces that can be used for communication between the application and compiler. In order to support the declaration of COM-like interfaces, several platform-detection macros were lifted out of `slang-defines.h` and into the public `slang.h` header. As it exists right now, this change makes the Slang API C++-only, but a C-compatible version can be defined later with the help of lots of macros (and/or something like an IDL compiler).

The two big interfaces introduced are:

* The `ISlangBlob` interface, which is compatible with `ID3DBlob`, `IDxcBlob`, etc. This is used to pass ownership of source/compiled code across the API boundary without copies. New versions of various entry points have been added to allow passing blobs: e.g., `spAddTranslationUnitSourceBlob` and `spGetEntryPointCodeBlob`.

* The `ISlangFileSystem` interface, which is used to allow applications to intercept any attempt by the Slang compiler to load a file (input source files, include files, etc.). This is *not* the same as the `IDxcIncludeHandler` interface, because it assumes UTF-8 encoded path names, instead of the 16-bit encoding that dxc/Windows prefer. It is also not very similar to `ID3DInclude` as used by fxc, because this callback interface is *not* responsible for handling the search through include paths, etc. - it is just a file-system abstraction layer.

Internally, a few different parts of the compiler were changed to either store data in blob form all the time, or to be able to synthesize a blob on-demand. Because our internal `String` type is a reference-counted copy-on-write type, using a `SlangStringBlob` to hold string data should achieve transfer of ownership back to the application without extraneous copies. There is plenty of room to clean up the architecture of some of these internal pieces if they *know* that their data will end up in a blob.

The existing Slang testing doesn't touch any of the APIs introduced here, so they can only confirm that existing functionality hasn't been broken. The new ability to return code blobs has been tested by integration of that feature into Falcor, but there has been zero testing of the ability to pass *in* source code as blobs, and the ability to hook file loading. Future changes will need to add test coverage for the new features.

* fixup: define SLANG_NO_THROW for non-Windows builds

* fixup: header copy-paste error caught by clang/gcc

* Cleanup: return reference-counted objects via output parameters

Returning a reference-counted object through the API as a raw pointer creates challenges.
The "obvious" answer is that the returned pointer should have an added reference (it is returned at "+1"), and the caller is responsible for releasing that reference. This makes sense when using raw pointers on the calling side:

```c++
IFoo* foo = spGetFoo(...);
...
foo->Release();
```

However, as soon as smart pointers start getting involved (to handle releasing reference counts when we are done with things), the picture gets more complicated:

```c++
MySmartPtr<IFoo> foo = spGetFoo(...);
...
```

The intention of code like that is that `foo` gets released when the smart pointer goes out of scope, but this probably doesn't happen with most smart pointer implementations. If the `MySmartPtr` constructor that takes a raw pointer retains it, then the destructor will only release *that* reference, and so the object will leak.

It is possible that the user will have a smart pointer type where the constructor that takes a raw pointer doesn't retain it, but in general such types introduce the potential for errors of their own, and no matter what the Slang API shouldn't go in assuming any particular policy.

This change makes it so that any reference-counted objects that are logically returned from a call are returned through output pointers. This design makes the leak-free cases easy (enough) to implement with raw pointers or smart pointers:

```c++
// raw pointer
IFoo* foo = nullptr;
spGetFoo(..., &foo);
...
foo->Release();

// smart pointer
MySmartPtr<IFoo> foo;
spGetFoo(..., foo.writeableRef());
...
```

The only assumption here is that any COM smart-pointer type needs to provide an operation like `writableRef` that is suitable for using that pointer as an output parameter. Given that COM *loves* output parameters, this seems like a safe assumption (at the very least, anybody who interacts with COM would be used to this convention).

Future changes might introduce inline convenience methods for various operations that return results more directly, possibly by introducing a minimal smart-pointer type in the `slang.h` header (without prescribing that clients must use it...).

* fixup: another error caught by gcc/clang
1 parent 126e75d
History
Tip revision: e66d66b88e1c6ef8499708952fcbe3ba873f6e4c authored by Tim Foley on 14 June 2018, 18:56:31 UTC
Add support for "blobs" and a file-system callback (#596)
Tip revision: e66d66b
File Mode Size
docs
examples
external
source
tests
tools
.editorconfig -rw-r--r-- 937 bytes
.gitattributes -rw-r--r-- 95 bytes
.gitignore -rw-r--r-- 398 bytes
.gitmodules -rw-r--r-- 107 bytes
.travis.yml -rw-r--r-- 1.6 KB
CODE_OF_CONDUCT.md -rw-r--r-- 3.1 KB
LICENSE -rw-r--r-- 1.1 KB
Makefile -rw-r--r-- 6.3 KB
README.md -rw-r--r-- 4.9 KB
appveyor.yml -rw-r--r-- 3.5 KB
premake5.lua -rw-r--r-- 20.4 KB
slang.h -rw-r--r-- 55.0 KB
slang.sln -rw-r--r-- 8.9 KB
test.bat -rw-r--r-- 1.4 KB

README.md

back to top