Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does ComPtr.As() do?

Tags:

c++

com

I am working on learning DirectX 12 from some examples but I am having trouble understanding what does the ComPtr.As() method does.

ComPtr<ID3D12Device> device;
ComPtr<ID3D12Device> device2; 

// Do Stuff with Device
device.As(&device2); // What does this do?
like image 220
Dylan Avatar asked Oct 19 '22 16:10

Dylan


1 Answers

Where did you find this example code? It looks fishy. This is kind of a nonsense use of As. It's equally silly if you expand it to the underlying QueryInterface:

hr = device->QueryInterface( IID_PPV_ARGS(device2) );

In fact, your code would be better written as:

device2 = device;

Typically you'd use As to obtain a new interface from an existing interface. For example with Direct3D 11, you create the device as a Direct3D 11.0 interface and then have to QueryInterface the 11.1, 11.2, 11.3, and/or 11.4 versions to use them:

ComPtr<ID3D11Device> device;
DX::ThrowIfFailed(D3D11CreateDevice(..., device.ReleaseAndGetAddressOf());

ComPtr<ID3D11Device2> device2;
hr = device.As(&device2);
if (FAILED(hr))
    // Do whatever handling you do if the system doesn't support 11.2

Another common use with Direct3D 11 is dealing with the debug interfaces which may not be present:

#ifndef NDEBUG
    ComPtr<ID3D11Debug> d3dDebug;
    if (SUCCEEDED(device.As(&d3dDebug)))
    {
        ComPtr<ID3D11InfoQueue> d3dInfoQueue;
        if (SUCCEEDED(d3dDebug.As(&d3dInfoQueue)))
        {
#ifdef _DEBUG
            d3dInfoQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_CORRUPTION, true);
            d3dInfoQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_ERROR, true);
#endif
            D3D11_MESSAGE_ID hide [] =
            {
                D3D11_MESSAGE_ID_SETPRIVATEDATA_CHANGINGPARAMS,
                // TODO: Add more message IDs here as needed.
            };
            D3D11_INFO_QUEUE_FILTER filter = {};
            filter.DenyList.NumIDs = _countof(hide);
            filter.DenyList.pIDList = hide;
            d3dInfoQueue->AddStorageFilterEntries(&filter);
        }
    }
#endif

It's also important to not ignore the HRESULT return value that comes back from As. You should use SUCCEEDED or FAILED macro, or a fast-fail like ThrowIfFailed.

See ComPtr.

like image 188
Chuck Walbourn Avatar answered Oct 21 '22 06:10

Chuck Walbourn