I want to create ID3D12CommandAllocator*, for this I use:
for(UINT i=0;i<NUM_BACK_BUFFERS;i++)
ThrowFEX(DX12.d3dDevice->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&DX12.Buffers.pCommandAllocator[i])), ERROR_CREATECOMMANDALLOCATOR, DX12.d3dDevice);
CreateCommandAllocator returns DXGI_ERROR_ DEVICE_REMOVED and GetDeviceRemovedReason() returns DXGI_ERROR_INVALID_CALL. I found out that if I don't create a view for the render target, the error in CreateCommandAllocator() disappears. Here's how I create them:
D3D12_HEAP_PROPERTIES properties;
properties.Type=D3D12_HEAP_TYPE_DEFAULT;
properties.CPUPageProperty=D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
properties.MemoryPoolPreference=D3D12_MEMORY_POOL_UNKNOWN;
properties.CreationNodeMask=0;
properties.VisibleNodeMask=0;
D3D12_RESOURCE_DESC desc = {};
desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; // Resource type - buffer
desc.Alignment = 0; // Alignment in bytes, default 0
desc.Width = windowRect.right * windowRect.bottom * sizeof(DirectX::XMFLOAT4); // Resource size in bytes
desc.Height = 1; // Buffer height (1 for buffer)
desc.DepthOrArraySize = 1; // Depth or number of elements in the array (1 for buffer)
desc.MipLevels = 1; // Number of mipmap levels (1 for buffer)
desc.Format = DXGI_FORMAT_UNKNOWN; // Data format in the resource (unknown by default)
desc.SampleDesc.Count = 1; // Number of samples
desc.SampleDesc.Quality = 0; // Sampling quality
desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; // Layout of the data in the resource (default is string)
desc.Flags = D3D12_RESOURCE_FLAG_NONE; // Resource flags (no default flags)
// get frame buffers
for(UINT i=0;i<NUM_BACK_BUFFERS;i++){
ThrowF(DX12.ixgiSwapChain->GetBuffer(i, IID_PPV_ARGS(&DX12.Buffers.renderTargets[i])), ERROR_GETFRAMEBUFFERS);
ThrowF(DX12.d3dDevice->CreateCommittedResource(&properties, D3D12_HEAP_FLAG_NONE, &desc, D3D12_RESOURCE_STATE_PRESENT, nullptr, IID_PPV_ARGS(&DX12.Buffers.renderTargets[i])), ERROR_GETFRAMEBUFFERS);
}
D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle = DX12.rtvHeap->GetCPUDescriptorHandleForHeapStart(); // get the CPU handle from the frame view buffer
for(UINT i=0;i<NUM_BACK_BUFFERS;i++){//if I remove the following line the program works
DX12.d3dDevice->CreateRenderTargetView(DX12.Buffers.renderTargets[i], nullptr, rtvHandle); // create a view for the frame buffer
rtvHandle.ptr += i * DX12.d3dDevice->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV); // offset the handle by the size of the descriptor
}
There are no errors at any stage before CreateCommandAllocator. Since I don't know what could be causing this error, I'll also post the creation of SwapChain:
DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {};
swapChainDesc.Width=0;
swapChainDesc.Height=0;
swapChainDesc.BufferCount=NUM_BACK_BUFFERS;
swapChainDesc.AlphaMode=DXGI_ALPHA_MODE_UNSPECIFIED;
swapChainDesc.BufferUsage=DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapChainDesc.Flags=DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT;
swapChainDesc.Format=DXGI_FORMAT_R8G8B8A8_UNORM;
swapChainDesc.SampleDesc.Count=1;
swapChainDesc.SampleDesc.Quality=0;
swapChainDesc.Scaling=DXGI_SCALING_STRETCH;
swapChainDesc.SwapEffect=DXGI_SWAP_EFFECT_FLIP_DISCARD;
swapChainDesc.Stereo=FALSE;
ThrowF(DX12.dxgiFactory->CreateSwapChainForHwnd(DX12.d3dCommandQueue, hwnd, &swapChainDesc, NULL, NULL, &DX12.ixgiSwapChain), ERROR_CREATESWAPCHAIN)
Also device creation code. Perhaps there is an error in it:
D3D12_COMMAND_QUEUE_DESC desc = {};
desc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
desc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
desc.NodeMask = 0;
D3D12_DESCRIPTOR_HEAP_DESC heapDesc = {};
heapDesc.NumDescriptors = NUM_BACK_BUFFERS; // number of descriptors
heapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV; // heap type RTV
heapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE; // flags (not in this example)
ThrowF(CreateDXGIFactory1( IID_PPV_ARGS(&DX12.dxgiFactory) ), ERROR_CREATEDEVICE) // main factory
ThrowF(D3D12CreateDevice(nullptr, D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&DX12.d3dDevice) ), ERROR_CREATEDEVICE)
ThrowF(DX12.d3dDevice->CreateCommandQueue(&desc, IID_PPV_ARGS(&DX12.d3dCommandQueue)), ERROR_CREATEDEVICE)
ThrowF(DX12.d3dDevice->CreateDescriptorHeap(&heapDesc, IID_PPV_ARGS(&DX12.rtvHeap)), ERROR_CREATEDEVICE)
heapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV; // heap type CVB
heapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE; // flags (not in this example)
heapDesc.NumDescriptors = 1; // number of descriptors
for(int i;i<NUM_BACK_BUFFERS;i++)
ThrowF(DX12.d3dDevice->CreateDescriptorHeap(&heapDesc, IID_PPV_ARGS(&DX12.Buffers.cvbHeap[i])), ERROR_CREATEDEVICE)// the same for, but for a constant buffer
The problem turned out to be that I was creating frame buffers and constant buffers incorrectly. The "Dimension" field of the frame buffer has been changed to "D3D12_RESOURCE_DIMENSION_TEXTURE2D" and a name has been added for the constant buffer. This is what the final version of the code looks like: