|
| 1 | +--- |
| 2 | +{ |
| 3 | +"TableOfContents": { |
| 4 | +"Name": "Silk.NET Structure Chaining", |
| 5 | +"Url": "structure-chaining.html", |
| 6 | +"Metadata": { |
| 7 | +"AuthorGitHub": "thargy", |
| 8 | +"DateTimeWritten": "09/12/2021 16:00", |
| 9 | +"PreviewImage": "images/blog/dec-2021/structure-chaining.png" |
| 10 | +} } } |
| 11 | +--- |
| 12 | + |
| 13 | +# Silk.NET Structure Chaining |
| 14 | + |
| 15 | +With the release of Silk.NET 2.11 we've enhanced the usability of `Silk.NET.Vulkan` by addressing one of its pain |
| 16 | +points, specifically building the [Singly Linked Lists](https://en.wikipedia.org/wiki/Linked_list) (or chains) of |
| 17 | +structures that are frequently used to pass information to, and from, the API. |
| 18 | + |
| 19 | +Up until now, it was not unusual to have to write quite a lot of unsafe code to work with the Vulkan API. For example, to |
| 20 | +query device features you would need to create a chain of empty structures to be populated by the API: |
| 21 | + |
| 22 | +```csharp |
| 23 | +var accelerationStructureFeaturesKhr = new PhysicalDeviceAccelerationStructureFeaturesKHR |
| 24 | + {SType = StructureType.PhysicalDeviceAccelerationStructureFeaturesKhr}; |
| 25 | +var indexingFeatures = new PhysicalDeviceDescriptorIndexingFeatures |
| 26 | +{ |
| 27 | + SType = StructureType.PhysicalDeviceDescriptorIndexingFeatures, |
| 28 | + PNext = &accelerationStructureFeaturesKhr |
| 29 | +}; |
| 30 | +var features2 = new PhysicalDeviceFeatures2 |
| 31 | +{ |
| 32 | + SType = StructureType.PhysicalDeviceFeatures2, |
| 33 | + PNext = &indexingFeatures |
| 34 | +}; |
| 35 | +vk.GetPhysicalDeviceFeatures2(device, &features2); |
| 36 | +``` |
| 37 | + |
| 38 | +Not only is this quite a bit of boiler plate (and it gets worse when you actually want to pass data to the API), it is |
| 39 | +really easy for developers, who are not always comfortable with `unsafe` code, memory management and pointers, to |
| 40 | +introduce subtle bugs by passing in pointers to structures they have previously generated and are now residing on the |
| 41 | +.NET heap. Such structures can be moved by the Garbage Collector at the most unexpected times! |
| 42 | + |
| 43 | +Thanks to Structure Chaining, we now have 2 new ways to write the above code. The most |
| 44 | +useful [Managed Chaining](https://github.com/dotnet/Silk.NET/blob/main/documentation/structure-chaining/managed-chaining.md), |
| 45 | +makes it much easier, _and safer_, to work with Vulkan Structure Chains. For example, the above code can now be written |
| 46 | +as: |
| 47 | + |
| 48 | +```csharp |
| 49 | +using var features2 = Chain.Create<PhysicalDeviceFeatures2, PhysicalDeviceDescriptorIndexingFeatures, |
| 50 | + PhysicalDeviceAccelerationStructureFeaturesKHR>(); |
| 51 | +vk.GetPhysicalDeviceFeatures2(device, features2); |
| 52 | +``` |
| 53 | + |
| 54 | +The new `Chain` classes manage the lifetime of the structures for you and they can be safely stored on the |
| 55 | +heap, like any object. They also efficiently handle the `SType` and `PNext` fields, ensuring they are always correct. It is |
| 56 | +also easy to modify and manipulate the chains. What is less obvious from the above example is that we are now able to |
| 57 | +validate that `PhysicalDeviceFeatures2` can be used as the _start_ of a chain, and that |
| 58 | +both `PhysicalDeviceDescriptorIndexingFeatures` and `PhysicalDeviceAccelerationStructureFeaturesKHR` are valid |
| 59 | +structures to appear in such a chain. That validation occurs at compile time, meaning that most modern IDEs will give |
| 60 | +you error 'squiggles' as soon as you try and use an invalid structure (according to the Vulkan Specification)! |
| 61 | + |
| 62 | +That 'magic' is possible due to a set of new interfaces we've added to Vulkan Structures to indicate when they can be |
| 63 | +used in chains, and, when the Vulkan Specification explicitly states it, what chains they can be used in. All without |
| 64 | +effecting runtime performance. |
| 65 | + |
| 66 | +Full documentation is |
| 67 | +available [here](https://github.com/dotnet/Silk.NET/blob/main/documentation/structure-chaining/overview.md), and we |
| 68 | +can't wait for you to start using the new features! If they prove popular, we plan on expanding the functionality to |
| 69 | +other APIs supported by Silk.NET. |
0 commit comments