Sign in to follow this  
cozzie

Guideline for CComPtr and D3D11?

Recommended Posts

Hi all,

I've been reading through some articles on the usage CComPtr, in combination with the D3D11 API.

From this, I've concluded the following principle:

 

- use a CComPtr for D3D objects, when you expect that the lifetime will vary during runtime.

I.e. will point to something else then initially assigned, thus needing 'reference management'.

 

This means that there's not much use in using a CComPtr for the D3D11 device and context.

I've applied this as pasted below.

 

Question; would you say this is a safe assumption/ principle to follow?

class CD3d11
{
public:
	CD3d11();
	~CD3d11();

// more stuf

private:
	bool CreateSwapchain(HWND pHwnd);
	bool CreateRenderTarget();
	bool CreateDepthStencilBuffer();

	ID3D11Device					*mDevice;				// feature support, resource mgmt
	ID3D11DeviceContext				*mImmediateContext;		// everything else
	IDXGISwapChain					*mSwapChain;

	CComPtr<ID3D11Texture2D>		mDepthStencilBuffer;
	CComPtr<ID3D11Texture2D>		mRenderTargetTex;

	CComPtr<ID3D11RenderTargetView>	mRenderTargetView;
	CComPtr<ID3D11DepthStencilView>	mDepthStencilView;

	D3D_DRIVER_TYPE					mDriverType;
};

CD3d11::CD3d11() : 	
	mDriverType(D3D_DRIVER_TYPE_HARDWARE), mMSAAQuality(0),
	mDevice(nullptr), mImmediateContext(nullptr), mSwapChain(nullptr), mDepthStencilBuffer(nullptr), mRenderTargetTex(nullptr), mRenderTargetView(nullptr), mDepthStencilView(nullptr)
{
	// nothing yet, no ZeroMemory for viewport etc. (add later)
}

CD3d11::~CD3d11()
{
	if(!mSettings.GetWindowed() && mSwapChain) mSwapChain->SetFullscreenState(false, nullptr);
	
	ReleaseCOM(mSwapChain);

	// Restore all default settings.
	if(mImmediateContext) mImmediateContext->ClearState();

	ReleaseCOM(mImmediateContext);
	ReleaseCOM(mDevice);

	// CComPtr's
	mDepthStencilBuffer = nullptr;
	mRenderTargetTex	= nullptr;
	mRenderTargetView	= nullptr;
	mDepthStencilView	= nullptr;
}

// when reusing a CComPtr object
	mRenderTargetTex = nullptr;
	mRenderTargetView = nullptr;

	if(FAILED(mDevice->CreateTexture2D(&renderTargetTexDesc, 0, &mRenderTargetTex))) return false;
	if(FAILED(mDevice->CreateRenderTargetView(mRenderTargetTex, 0, &mRenderTargetView))) return false;

Share this post


Link to post
Share on other sites

Why not use it for everything? It self-initializes to nullptr so you don't need those objects in your initializer list. If you have it on the stack, it'll release the object when it goes out of scope, and if you put it in a class/struct, it'll release its object when its container goes away.

 

My rule of thumb is that every object should be owned by at least one CComPtr. If you want to use it like a unique_ptr, then use raw pointers everywhere else. If you want to use it like a shared_ptr, then use CComPtrs everywhere else too.

Share this post


Link to post
Share on other sites
Thanks.
I see the advantages of using them everywhere/ using them in the other cases I mentioned.

Does that mean:
- I can remove them from the initializer list(s) and also don't have to initalize them to nullptr when I create them in local scope/ on the stack?
- I don't have to set them to nullptr in the destructor of the class of which they are members of?
- I would still have to set them to nullptr before I "reuse" them?
(like in the example above)

Would that also mean that there are basically no downsides to using them everywhere?

Share this post


Link to post
Share on other sites

 

- I don't have to set them to nullptr in the destructor of the class of which they are members of?

Slight side note, you never have to set member pointers to nullptr in a destructor as after the destructor that memory is invalid and should not be accessed by anything!

 

 

It is still a good practice to get into, since if you mistakenly still reference that object's former memory location then you would be able to figure out it was already destructed.  Sometimes you can even write a particular value into the pointer value which helps in identifying this situation more easily.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this