1

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?

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
우현우
  • 45
  • 4

1 Answers1

3

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 &.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • 1
    Thank you very much. I understand. '&mDirectCmdListAlloc.GetAddressof()' is typo, 'mDirectCmdListAlloc.GetAddressof()' is right – 우현우 Jul 29 '22 at 18:02
  • Obtaining an interface to COM pointers with either `IID_PPV_ARGS(&m_COM_Object)` or `IID_PPV_ARGS(m_COM_Object.GetAddressOf())` is most likely due to author preference and I've seen both styles occur in equal proportion across all the DirectX 12 code I've read. I prefer the latter style because it makes your intention explicit. If both styles are found to occur within the same author's code, it's most likely a sign of inattentive coding and poor practice. I was also confused by the indiscriminate use of both styles while a novice to DirectX 12 and COM pointers. – Maico De Blasio Jul 30 '22 at 07:59