Skip to content

Commit 0a5aede

Browse files
thargyPerksey
andauthored
Vulkan struct chaining (#706)
* feat: Initial working sample * Created class library with 3 chainable structs * Added `IChainable` interface hierarchy * Added chaining methods `Chain`, `CreateNext`, `SetNext` and `End` * Added tests * feat: Now supports limiting allowed structs. * Added tests to check that invalid structs don't compile * Minimal additional code required per struct - just add an interface for each allowed `PNext` struct; and, - add a short static method `Chain` (technically optional), and a short instance method `SetNext`. * docs: Added Readme.md * fix: Change __makeref to Unsafe.AsPointer * chore: Retargeting Retargeted project to ensure that it only targets the same includes, etc. as `Silk.Next.Core` and `Silk.Net.Vulkan` * refactor: Various changes * Added `IStructureType` for any struct that has a `StructureType SType` field. This is usually added automatically by one of the other interfaces; and allows the structure type to be automatically corrected and retrieved using the `StructureType IStructuredType.StructureType()` method. * Added `IChainStart` to indicate a type that can form the start of a chain. * `IChainable<...>` was replaced with `IExtendsChain<T>` which matches the Vulkan specification more readily. * The chaining methods now all accept, and return, a reference to an `IChainStart`, making it easier to scan a chain for existing items, and making use of the auto-generated `IExtendsChain<T>` to validate types at compile time. * `SetNext`, by default, will now replace existing chain entries if they match the supplied `SType`. This behaviour can be overriden with the optional `alwaysAdd` parameter. * `CreateNext` is now called `AddNext` to indicate it always adds to the end of a Chain.cs * `TryAddNext` added to only create a new structure if it is not already there. * `IndexOf` added to return the index of a structure in a chain. * Updated Readme.md. * chore: Updated readme.md Updated `Changes Required` section. * feat: Added ManagedChain * ManagedChain holds structures in unmanaged memory, preventing their movement, and it can be safely held on the heap itself. * It allows for easy modification and manipulation of the chain. * feat: Added static `ManagedChain.Create` example * feat: ManagedChain uses a single memory block. * feat: Added T4 template. `ManagedChain` now supports 2-16 chain items. * feat: Added `ManagedChain.Append` Can now easily append an item to an existing `ManagedChain` to efficiently create a new `ManagedChain`. * feat: Loading of unmanaged chains `ManagedChain` now has a constructor that will load an unmanaged chain allowing it to be safely stored on the heap. * feat: Added `IReadOnlyList` support to `ManagedChain` * feat: Added deconstructor to `ManageChain<...>` * feat: Added static `ManagedChain.Load` Also improved loading to detect when the unmanaged chain is too long. * chore: Readme.md updated * chore: Added Lab projects to Solution Also added the new blank proposals. * chore: Fixed issues with previous commit * docs: Finished initial draft #1 Proposal - Vulkan Struct Chaining - #1 StructureType correction.md * docs: Embedded code sample directly into Proposal #1 * docs: Updated the Unmanaged Chaining Proposal. * chore: Minor fixes to lab * Restored targets for PrototypeStructChaining.csproj to match `Silk.Net.Vulkan` targets. * Upped the generated `ManageChain<T...` to 16. * docs: Initial work on Managed Chaining Proposal. * docs: Finished draft proposal for Managed Chains * feat: Numerous enhancements to ManagedChains * IChainable now exposes `Chain* PNext` property. * Added `ManagedChain<TChain>` as smallest chain (just the head) * All `IntPtr`s are replaced with `nint`s. * Pointer offsets are calculated once per chain type and stored in statics, meaning that a chain contains a single `nint` field internally, making it incredibly lightweight. Getting the sizes once may also improve the performance, and has simplified the code. * Various fixes to ensure tail always has `PNext` set to `null` (0). * Added `Truncate` instance methods. * docs: Updated Chaining proposals to match new functionality. Also cleaned up some tests. * feat: Added chain metadata extensions. * Added the `Extensions`, `Extenders`, `ClrTypes` and `StructureTypes` dictionaries to `Chain`. * Added the `ClrType`, `StructureType`, `IsChainStart`, `IsChainable`, `CanExtend` and `CanBeExtendedBy` extension methods to `ChainExtensions`. * Finished Proposal #4 on Chaining Metadata extension. * docs: Added suggestion for specific chain interfaces * docs: Updated to use `BaseInStructure` * `Chain` was replaced by `BaseInStructure`, which is supplied by the Vulkan Specification already. * `ChainExtensions` was renamed to `Chain`. * feat: Implements `IStructuredType` Full implementation of [proposal 1](https://github.com/dotnet/Silk.NET/blob/866f2dcdcc7817995e9fb633213e7630d510ee35/documentation/proposals/Proposal%20-%20Vulkan%20Struct%20Chaining%20-%20%231%20StructureType%20correction.md). * Adds `$VKSTRUCTUREDTYPE` intrinsic to indicate that a struct implements `IStructuredType`, and includes the default `StructureType` * Adds `IStructuredType` interface to relevant structs, implementing them explicitly. * feat: Implements Unmanaged Chains Full implementation of [Proposal 2] (https://github.com/dotnet/Silk.NET/blob/866f2dcdcc7817995e9fb633213e7630d510ee35/documentation/proposals/Proposal%20-%20Vulkan%20Struct%20Chaining%20-%20%232%20Unmanaged%20Chaining.md) * Added `IReadOnlyList<string> Extends` property to `StructureDefinition`, to store the `structextends` values. * Added `string Alias` property to `StructureDefinition`, to store the value of the `alias` attribute. * Added `Clone()` methods to `Struct` and `Attribute`, to make alias creation faster and easier. * `VulkanReader` creates aliases by cloning existing structs, making it slightly faster to build. This speed improvement is then used to handle the complex chaining logic which requires alias expansion, creating a net even performance. * Added `$VKCHAINABLE` intrinsic to indicate a structure is `IChainable` (a lower bar than a chain start or chain extension). * Added `$VKALIASOF` intrinsic to indicate a structure is an alias of another structure. * Added `$VKALIASES` intrinsic to indicate which structures are aliases of the current structure. * Added `$VKEXTENDSCHAIN` intrinsic to indicate which structures the current structure extends. * Added `$VKCHAINSTART` intrinsic to indicate which structures the current structure can be extended by. * `StructWriter` uses the intrinsics to annotate the structs. * Added `Chain` extensions from proposal. * Added `IChainable`, `IChainStart` and `IExtendsChain` interfaces from proposal. * `ProjectWriter` has `GetFilename` added, which will disambiguate filenames whenever case-sensitivity is an issue (hasn't actually occurred yet though). TODOs * Update `PrototypeStructChaining` projects to remove manually generated code and instead link directly to `Silk.NET.Vulkan` project. * Run tests to confirm functionality. * Update proposals with any changes (e.g. `IChainable.PNext`) * Consider what to do with teh 208 structures (out of 739) that implement `IChainable` directly (i.e. are not part of a specified chain). * Check in the changes to generated structs in a standalone commit. * chore: Committing structure changes Commiting just the auto-generated files to not muddy other commits. * fix: Fixed capitalization of struct aliases. * chore: Committing structure changes * feat: Linked `PrototypeStructChaining` projects to implementation * Removed the manually generated code that is replaced by the auto-generated code now that it is implemented * Removed the solution. * Corrected namespace to `Silk.NET.Vulkan`. * Fixed issue clash of `System.Buffer` and `Silk.NET.Vulkan.Buffer`. * feat: Added `Any` overloads As ~30% of Vulkan Structures are purely `IChainable`, that is they are not included in one of the Vulkan Specification `structextends` chains, but do implement `SType` and `PNext` correctly, I have added `Any` versions of each of the unmanaged chain extension methods. These methods accept `IChainable` directly for the `chain` and `next` parameters, making them work with any `IChainable` structure. Indeed the stricter non-`Any` methods, call the looser `Any` methods directly and serve merely as more rigorous compile time checks. Improved the inline documentation of the extensions methods. * docs: Updated the first two proposals Added details about PRs and the new `Any` extension methods. * feat: Added `Any` functionality to `ManagedChain` * Removed instance methods and converted into static extension methods. * Added `Any` equivalents with looser constraints. * Various fixes to make prototype match more closely with current draft implementations, and `Silk.NET.Vulkan`. * Added tests. * Added efficient equality overloads. * Added ToString(). * Expose the `HeadPtr` and `Size` in the base class. * feat: Added `GetHashCode` implementation This is a proposed implementation that only checks the start of the payload. We may change this to check the full payload Also updated the proposals to match the new `Any` functionality. * fix: Fixed GetHashCode Fixed broken pointer arithmetic. Also changed to hash entire structure for better separation. * feat: Moved ManagedChain.gen.tt to Silk.NET.Vulkan * feat: `IExtendsChain` constraints reviewed. * `TChain` is constrained to `IChainStart`, it should only be constrained to `IChainable` on `*Any` extensions, not the interface. * refactor: Renamed `ManagedChain` to `Chain` * All extension methods now in `ChainExtensions`. * Also corrected Proposal 3, and updated references from `Append` to `Add` to match code (and Working Group request). * refactor: Changed Marshal calls * Changed all chain constructs to be the tighter `unmanaged` constraint (as opposed to `struct`) guaranteeing blittability. * Replaced `Marshal.StructureToPtr` calls with faster `System.Buffer.MemoryCopy` calls (as structs are all `unmanaged`). * Replaced `Marshal.AllocHGlobal` with `SilkMarshal.Allocate` and `Marshal.FreeHGlobal` with `SilkMarshal.Free`. * Remove `Marshal.DestroyStructure` calls (as structs unmanaged). * Replaced `Marshal.SizeOf` with `sizeof`. * feat: Added mutation method to base `Chain` * Split out non-auto-generated code in `Chain` to `Chain.cs` for easier maintenance. * Added `AddAny`, `DuplicateAny` and `TruncateAny` instance methods to `Chain` to allow for easier manipulation of runtime chains. * Added new `MaximumCount` property to `Chain` to indicate the currently supported maximum (16). * feat: Optimised copy * Removed unnecessary `MemoryCopy` calls. * Moved modification extension methods back into instance, this allows the return type to be overriden for concrete classes (i.e. `Duplicate` on the concrete class will return the concrete type, overriding the base class version, which returns `Chain`). * Removed `DuplicateAny` as you type constraints are checked again on duplication. (Base method also renamed to `Duplicate`). * `IExtends<TChain>` constraint relaxed back to `IChainable`. This is required as it doesn't really add anything but it prevents loosely constrained types checking if a type extends their head. This became an issue when returning the extension methods to the instance. * chore: Moved tests to `Silk.NET.Vulkan.Test` * feat: Added `Chain.Clear` method. * Sets all chain elements (optionally excluding the head) to their default value. * feat: Added implicit conversions to `Chain` * Implicit conversion added to convert to `nint`, `void*` and `BaseInStructure*` to convert to a pointer to the head of the chain, for all `Chain` classes, including the abstract base `Chain`. * Implicit conversion added to convert to `TChain*` for the concrete `Chain<TChain...>` classes. * Added missing license header to interfaces * docs: Started adding documentation for structure chaining. * testing: Added tests for casts and Clear Fixed namespace for `Silk.NET.Vulkan.Test` tests. * feat: Added `IEquatable<Chain>` to `Chain` * Also added operator overloads. * docs: Finished all but structure chaining docs * Removed implemented proposals * Renamed Metadata proposal (as this will remain on hold and isn't in the scope of this PR) * Added Chaining UML class diagram * Updated TOCs * Documented Managed chaining * Added correct summary comments to `Chain` equality operator overloads. * chore: Added license to top of `Chain.gen.cs` * Update src/Core/Silk.NET.BuildTools/Bind/StructWriter.cs Co-authored-by: Dylan Perks <[email protected]> * Update src/Core/Silk.NET.BuildTools/Bind/StructWriter.cs Co-authored-by: Dylan Perks <[email protected]> * Update src/Core/Silk.NET.BuildTools/Bind/StructWriter.cs Co-authored-by: Dylan Perks <[email protected]> * chore: Removed imported .idea files. * chore: Renamed `Silk.NET.Vulkan.Test` to `Silk.NET.Vulkan.Tests` * fix: Full disposal pattern implementation for `Chain` Added finalizer and `GC.SuppressFinalize(this)` when disposing explicitly. * fix: Renamed `Chain.gen.cs` to `Chain.g.cs` `BuildTools` deletes all `.gen.cs` files which can cause collisions. * docs: Finished first pass of documentation * Removed the Unmanaged Chaining proposal as implemented. * feat: Optimized `Chain.Load(TChain)` * No longer allocates a `StringBuilder` when no `out string errors` is required. * Added CS0661 suppression to `Chain` base class, as `GetHashCode()` is correctly overriden in concrete descendents. Co-authored-by: Dylan Perks <[email protected]>
1 parent 1d263c7 commit 0a5aede

File tree

777 files changed

+39070
-834
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

777 files changed

+39070
-834
lines changed

Silk.NET.sln

Lines changed: 51 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -270,9 +270,9 @@ EndProject
270270
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Silk.NET.NUKE", "build\nuke\Silk.NET.NUKE.csproj", "{B9A8D738-FE7D-4860-A446-4A03E3DDEB74}"
271271
EndProject
272272
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Microsoft", "Microsoft", "{F2CF5D32-4B41-425E-B229-8FFC48F88063}"
273-
ProjectSection(SolutionItems) = preProject
274-
src\Microsoft\dxva.h = src\Microsoft\dxva.h
275-
EndProjectSection
273+
ProjectSection(SolutionItems) = preProject
274+
src\Microsoft\dxva.h = src\Microsoft\dxva.h
275+
EndProjectSection
276276
EndProject
277277
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Silk.NET.Direct3D11", "src\Microsoft\Silk.NET.Direct3D11\Silk.NET.Direct3D11.csproj", "{F3B7A9D6-5B15-45E8-925B-20B5BBD33428}"
278278
EndProject
@@ -474,6 +474,14 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Silk.NET.OpenXR.Extensions.
474474
EndProject
475475
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Silk.NET.OpenXR.Extensions.HTCX", "src\OpenXR\Extensions\Silk.NET.OpenXR.Extensions.HTCX\Silk.NET.OpenXR.Extensions.HTCX.csproj", "{782B6A7E-9F04-429A-9DCD-D7273AA3882E}"
476476
EndProject
477+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "PrototypeStructChaining", "PrototypeStructChaining", "{B15922CB-815C-4038-B635-EE2D8A8F700B}"
478+
EndProject
479+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PrototypeStructChaining", "src\Lab\Experiments\PrototypeStructChaining\PrototypeStructChaining\PrototypeStructChaining.csproj", "{EEFF37DA-E4F2-406E-AF97-8615BB7BC34C}"
480+
EndProject
481+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PrototypeStructChaining.Test", "src\Lab\Experiments\PrototypeStructChaining\PrototypeStructChaining.Test\PrototypeStructChaining.Test.csproj", "{BD19250B-E143-4F4E-9E1D-18829CCB3642}"
482+
EndProject
483+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Silk.NET.Vulkan.Tests", "src\Vulkan\Silk.NET.Vulkan.Tests\Silk.NET.Vulkan.Tests.csproj", "{225BA79C-36FE-421A-85E4-D15F8B61869B}"
484+
EndProject
477485
Global
478486
GlobalSection(SolutionConfigurationPlatforms) = preSolution
479487
Debug|Any CPU = Debug|Any CPU
@@ -2823,6 +2831,42 @@ Global
28232831
{782B6A7E-9F04-429A-9DCD-D7273AA3882E}.Release|x64.Build.0 = Release|Any CPU
28242832
{782B6A7E-9F04-429A-9DCD-D7273AA3882E}.Release|x86.ActiveCfg = Release|Any CPU
28252833
{782B6A7E-9F04-429A-9DCD-D7273AA3882E}.Release|x86.Build.0 = Release|Any CPU
2834+
{EEFF37DA-E4F2-406E-AF97-8615BB7BC34C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
2835+
{EEFF37DA-E4F2-406E-AF97-8615BB7BC34C}.Debug|Any CPU.Build.0 = Debug|Any CPU
2836+
{EEFF37DA-E4F2-406E-AF97-8615BB7BC34C}.Debug|x64.ActiveCfg = Debug|Any CPU
2837+
{EEFF37DA-E4F2-406E-AF97-8615BB7BC34C}.Debug|x64.Build.0 = Debug|Any CPU
2838+
{EEFF37DA-E4F2-406E-AF97-8615BB7BC34C}.Debug|x86.ActiveCfg = Debug|Any CPU
2839+
{EEFF37DA-E4F2-406E-AF97-8615BB7BC34C}.Debug|x86.Build.0 = Debug|Any CPU
2840+
{EEFF37DA-E4F2-406E-AF97-8615BB7BC34C}.Release|Any CPU.ActiveCfg = Release|Any CPU
2841+
{EEFF37DA-E4F2-406E-AF97-8615BB7BC34C}.Release|Any CPU.Build.0 = Release|Any CPU
2842+
{EEFF37DA-E4F2-406E-AF97-8615BB7BC34C}.Release|x64.ActiveCfg = Release|Any CPU
2843+
{EEFF37DA-E4F2-406E-AF97-8615BB7BC34C}.Release|x64.Build.0 = Release|Any CPU
2844+
{EEFF37DA-E4F2-406E-AF97-8615BB7BC34C}.Release|x86.ActiveCfg = Release|Any CPU
2845+
{EEFF37DA-E4F2-406E-AF97-8615BB7BC34C}.Release|x86.Build.0 = Release|Any CPU
2846+
{BD19250B-E143-4F4E-9E1D-18829CCB3642}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
2847+
{BD19250B-E143-4F4E-9E1D-18829CCB3642}.Debug|Any CPU.Build.0 = Debug|Any CPU
2848+
{BD19250B-E143-4F4E-9E1D-18829CCB3642}.Debug|x64.ActiveCfg = Debug|Any CPU
2849+
{BD19250B-E143-4F4E-9E1D-18829CCB3642}.Debug|x64.Build.0 = Debug|Any CPU
2850+
{BD19250B-E143-4F4E-9E1D-18829CCB3642}.Debug|x86.ActiveCfg = Debug|Any CPU
2851+
{BD19250B-E143-4F4E-9E1D-18829CCB3642}.Debug|x86.Build.0 = Debug|Any CPU
2852+
{BD19250B-E143-4F4E-9E1D-18829CCB3642}.Release|Any CPU.ActiveCfg = Release|Any CPU
2853+
{BD19250B-E143-4F4E-9E1D-18829CCB3642}.Release|Any CPU.Build.0 = Release|Any CPU
2854+
{BD19250B-E143-4F4E-9E1D-18829CCB3642}.Release|x64.ActiveCfg = Release|Any CPU
2855+
{BD19250B-E143-4F4E-9E1D-18829CCB3642}.Release|x64.Build.0 = Release|Any CPU
2856+
{BD19250B-E143-4F4E-9E1D-18829CCB3642}.Release|x86.ActiveCfg = Release|Any CPU
2857+
{BD19250B-E143-4F4E-9E1D-18829CCB3642}.Release|x86.Build.0 = Release|Any CPU
2858+
{225BA79C-36FE-421A-85E4-D15F8B61869B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
2859+
{225BA79C-36FE-421A-85E4-D15F8B61869B}.Debug|Any CPU.Build.0 = Debug|Any CPU
2860+
{225BA79C-36FE-421A-85E4-D15F8B61869B}.Debug|x64.ActiveCfg = Debug|Any CPU
2861+
{225BA79C-36FE-421A-85E4-D15F8B61869B}.Debug|x64.Build.0 = Debug|Any CPU
2862+
{225BA79C-36FE-421A-85E4-D15F8B61869B}.Debug|x86.ActiveCfg = Debug|Any CPU
2863+
{225BA79C-36FE-421A-85E4-D15F8B61869B}.Debug|x86.Build.0 = Debug|Any CPU
2864+
{225BA79C-36FE-421A-85E4-D15F8B61869B}.Release|Any CPU.ActiveCfg = Release|Any CPU
2865+
{225BA79C-36FE-421A-85E4-D15F8B61869B}.Release|Any CPU.Build.0 = Release|Any CPU
2866+
{225BA79C-36FE-421A-85E4-D15F8B61869B}.Release|x64.ActiveCfg = Release|Any CPU
2867+
{225BA79C-36FE-421A-85E4-D15F8B61869B}.Release|x64.Build.0 = Release|Any CPU
2868+
{225BA79C-36FE-421A-85E4-D15F8B61869B}.Release|x86.ActiveCfg = Release|Any CPU
2869+
{225BA79C-36FE-421A-85E4-D15F8B61869B}.Release|x86.Build.0 = Release|Any CPU
28262870
EndGlobalSection
28272871
GlobalSection(SolutionProperties) = preSolution
28282872
HideSolutionNode = FALSE
@@ -3052,6 +3096,10 @@ Global
30523096
{3E30D674-9282-4297-AD1F-9B233A166308} = {0651C5EF-50AA-4598-8D9C-8F210ADD8490}
30533097
{606214B8-07FC-436F-9523-02AF32E1AB1E} = {90471225-AC23-424E-B62E-F6EC4C6ECAC0}
30543098
{782B6A7E-9F04-429A-9DCD-D7273AA3882E} = {90471225-AC23-424E-B62E-F6EC4C6ECAC0}
3099+
{B15922CB-815C-4038-B635-EE2D8A8F700B} = {39B598E9-44BA-4A61-A1BB-7C543734DBA6}
3100+
{EEFF37DA-E4F2-406E-AF97-8615BB7BC34C} = {B15922CB-815C-4038-B635-EE2D8A8F700B}
3101+
{BD19250B-E143-4F4E-9E1D-18829CCB3642} = {B15922CB-815C-4038-B635-EE2D8A8F700B}
3102+
{225BA79C-36FE-421A-85E4-D15F8B61869B} = {E2ABDF45-C329-47B2-8E09-B7298E2557F7}
30553103
EndGlobalSection
30563104
GlobalSection(ExtensibilityGlobals) = postSolution
30573105
SolutionGuid = {F5273D7F-3334-48DF-94E3-41AE6816CD4D}

Silk.NET.sln.DotSettings

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
<s:Boolean x:Key="/Default/UserDictionary/Words/=trimmable/@EntryIndexedValue">True</s:Boolean>
5858
<s:Boolean x:Key="/Default/UserDictionary/Words/=typemap/@EntryIndexedValue">True</s:Boolean>
5959
<s:Boolean x:Key="/Default/UserDictionary/Words/=typemaps/@EntryIndexedValue">True</s:Boolean>
60+
<s:Boolean x:Key="/Default/UserDictionary/Words/=typeparam/@EntryIndexedValue">True</s:Boolean>
6061
<s:Boolean x:Key="/Default/UserDictionary/Words/=Ultz/@EntryIndexedValue">True</s:Boolean>
6162
<s:Boolean x:Key="/Default/UserDictionary/Words/=vsync/@EntryIndexedValue">True</s:Boolean>
6263
<s:Boolean x:Key="/Default/UserDictionary/Words/=Vulkan/@EntryIndexedValue">True</s:Boolean>

build/cache/vulkan.json.gz

14.7 KB
Binary file not shown.

0 commit comments

Comments
 (0)