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 aT**pointer, so taking its address would yield aT***pointer, which is not whatIID_PPV_ARGS()wants. It should beIID_PPV_ARGS(mDirectCmdListAlloc.GetAddressof())instead, ie drop the&.
