In osu!framework, we delay disposal of all native resources by 3 frames to make sure that they're not still in-flight by the GPU driver. We may not need to do this anymore under the Veldrid backend, but we do it anyway, because that's what's been safe for us in the past.
Here we encounter an issue, and it starts with the following:
So... In our finalizer, we enqueue an action that happens 3 frames in the future. In that same frame, the Veldrid Texture
gets finalised. Because IsReleaseOnFinalizerEnabled
is false
, the Texture
doesn't get released, and instead the pointer is lost. Our enqueued action runs, tires to dispose the texture, but this is now a no-op.
Oh, and all of this happens in SharpGen
, the binding generator used by Vortice.Windows
, used by Veldrid`. It's two too many layers deep for us to fix this for our specific usage.
There are four solutions here:
We can just bypass the finaliser in this one specific case.
Difficulty: Easy
Check whether this is a problem that needs to be resolved in SharpGen
itself.
It seems fundamentally broken to me that the pointers can just get lost like this. The difficulty here is that this is two levels of packages, and I'm not sure SharpGen is well supported anymore given it's gone 7 months without updates.
Difficulty: Medium
Check if osu!framework needs to schedule disposal under the Veldrid backend
This is going to require a lot of work and validation on every surface. Besides, this is technically not correct anyway as the D3D docs state that you should be waiting to dispose until calling ClearState()
at the beginning of the next frame.
Difficulty: Hard
Use another library than Vortice.Windows
(Silk.NET?)
I have made significant progress on this, but I have once again reaffirmed that the Silk.NET project is truly insane. To be blunt, if the library is bricking IDEs then I have no interest in using it.
Difficulty: Extreme