Home > front end >  Create CommandQueue and Command Allocator using IID_PPV_ARGS
Create CommandQueue and Command Allocator using IID_PPV_ARGS

Time:07-30

I am learning how to create CommandQueue, Command Allocator, and CommandList in DirectX 12.

However, a question arose in the process of creating each with the Create function.

The following is the code from the major.

ComPtr<ID3D12CommandQueue> mCommandQueue;
ComPtr<ID3D12CommandAllocator> mDirectCmdListAlloc;
ComPtr<ID3D12GraphicsCommandList> mCommandList;

ThrowIfFailed(md3dDevice->CreateCommandQueue(&queueDesc,IID_PPV_ARGS(&mCommandQueue)));

ThrowIfFailed(md3dDevice->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT,IID_PPV_ARGS(&mDirectCmdListAlloc.GetAddressof())));

If you look at this code, IID_PPV_ARGS and ComPtr pointer is used to create the CommandQueue.

However, when creating a CommandAllocator, IID_PPV_ARGS and ComPtr's GetAddressof() are used.

I don't understand why these two are different.

I know that if I put &ComPtr in IID_PPV_ARGS, it is converted to COM ID and void** using __uuidof and IID_PPV_ARGS_Helper.

What does it mean to put ComPtr.getAddressOf() instead of &ComPtr?

CodePudding user response:

IID_PPV_ARGS() expects the address of an interface pointer variable. Both ComPtr::operator& and ComPtr::GetAddressOf() return such an address - the address of the internal ComPtr::ptr_ data member. The only difference between them is that ComPtr::operator& calls Release() on the current interface if it is not null, whereas ComPtr::GetAddressOf() does not (use ComPtr::ReleaseAndGetAddressOf() for that).

However, that said, I would not expect IID_PPV_ARGS(&mDirectCmdListAlloc.GetAddressof()) to compile, for two reasons:

  • ComPtr::GetAddressOf() returns a temporary variable, and C does not allow taking the address of a temporary.

  • even if you could, ComPtr::GetAddressOf() returns a T** pointer, so taking its address would yield a T*** pointer, which is not what IID_PPV_ARGS() wants. It should be IID_PPV_ARGS(mDirectCmdListAlloc.GetAddressof()) instead, ie drop the &.

  • Related