Sergio0694 / ComputeSharp

A .NET library to run C# code in parallel on the GPU through DX12, D2D1, and dynamically generated HLSL compute and pixel shaders, with the goal of making GPU computing easy to use for all .NET developers! 🚀
MIT License
2.65k stars 122 forks source link

Marshaling to shader constants buffers should not use `Unsafe.SkipInit()` to avoid garbage in padding bytes #808

Closed rickbrew closed 1 month ago

rickbrew commented 1 month ago

As per discussion on Discord, https://discord.com/channels/143867839282020352/960223751599976479/1248401471813189795

The risk here is that two bitwise-equal shader structs could produce two constants buffers that are bitwise non-identical due to not setting the padding areas to zero.

This then defeats any sort of optimizations for checking to see if a property's new value is actually different than the old one, which then permits skipping ValueChanged events and also re-running PrepareForRender() and the like.

This is something I've seen significant performance wins from -- in my D2D1Properties wrapper, I check to see if setting an IUnknown* property will result in the same IUnknown* identity pointer, and then I don't forward the SetValue() call to Direct2D. This resulted in significant, measurable, even noticeable (framerate) performance improvements.

rickbrew commented 1 month ago

Here's the code in my ID2D1Properties wrapper where I perform my own optimization to skip the ID2D1Properties::SetValue() call, which then does not result in D2D thinking it needs to re-run PrepareForRender(), nor re-do layout (MapInputRectsToOutputRect), nor invalidate the output cache (if the Cached property is set, which I do occasionally use), etc

image