The question is more C# related, but I started learining sharpdx recently and I came up on two ways to initialize resources. First stores the resource (Texture2D in this example) as a global variable. Then in code assigns the value to it and passes it to sharpdx's method (and down to c++ that sharpdx encapsulates)
backBufferPtr = m_swapChain.GetBackBuffer<Texture2D>(0)
_renderTargetView = new RenderTargetView(m_device, backBufferPtr);
and then calls dispose on it, in the dispose method of the class that calls it, essentially keeping that Texture2D for entire lifetime of the class.
The other uses using statement:
using(Texture2D backBuffer = _swapChain.GetBackBuffer<Texture2D>(0))
{
_renderTargetView = new RenderTargetView(_d3d11Device, backBuffer);
}
And I wonder why the 2nd actually works. I checked it in debugger and as long as I stop inside using statement both the
backBuffer.NativePointer
_renderTargetView.Resource.NativePointer
point at the same object in the memmory. As soon as I leave the using statement backBuffer is disposed and no longer points at anything, but the _renderTargetView.Resource doesn't change, and still points at the object that it did in the using statement.
I did a quick test:
class innerClass
{
public Texture2D someResource;
}
/****/
innerClass ic = new innerClass();
using (Texture2D t2 = m_swapChain.GetBackBuffer<Texture2D>(0))
{
ic.someResource = t2;
}
Here both t2 and ic.someResource get disposed, and point at nothing, as soon as I leave the using block, which is how I expected it to work in the first place.
Now, the questions are:
1) Should I assume that, in the first example, it's actually sharpdx's method that makes sure the inner resuorce doesn't get disposed, even though the c# object, that got passed to it, did? And won't it crash at some point if C# decides to overwrite that memory block?
2) What's better/safer way of passing such resources? using block, or declare it at the beginning and dispose at the very end?
SharpDX keeps a count of references to the underlying graphics resources. So for example, when you acquire a reference to the back buffer:
Texture2D backBuffer = _swapChain.GetBackBuffer<Texture2D>(0)
and then obtain a render target view for the same underlying resources:
_renderTargetView = new RenderTargetView(_d3d11Device, backBuffer);
you would need to dispose both of them as well as the swap chain to release the back buffer resources from the GPU.
I quess that depends on the usage, but from what I've seen, usually the class that acquires the handle to the resource will dispose of it in its own implementation of
IDisposable
.