How to fix error DXGI_ERROR_DEVICE_REMOVED from CreateCommandAllocator()?

40 views Asked by At

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
1

There are 1 answers

0
I101I On

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:

 D3D12_RESOURCE_DESC desc = {};
 desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D; // for the frame buffer you must use "D3D12_RESOURCE_DIMENSION_TEXTURE2D", which affects the filling of subsequent fields of the structure
 desc.Alignment = 0;
 desc.Width = windowRect.right;
 desc.Height = windowRect.bottom;
 desc.DepthOrArraySize = 1;
 desc.MipLevels = 1;
 desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
 desc.SampleDesc.Count = 1;
 desc.SampleDesc.Quality = 0;
 desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
 desc.Flags = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET;

 D3D12_RESOURCE_DESC descCons={};
 D3D12_HEAP_PROPERTIES propertiesConst={};
 D3D12_CONSTANT_BUFFER_VIEW_DESC descConsBufferView={};

 // get frame buffers
 D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle = DX12.rtvHeap->GetCPUDescriptorHandleForHeapStart();
 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);
    
     DX12.d3dDevice->CreateRenderTargetView(DX12.Buffers.renderTargets[i], nullptr, rtvHandle);
     rtvHandle.ptr += i * DX12.d3dDevice->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV);
 }

 descCons.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; // Resource type - buffer
 descCons.Alignment = 0; // Alignment in bytes, default 0
 descCons.Width = 1024 * 64; // buffer size, 64kb alignment
 descCons.Height = 1; // Buffer height (1 for buffer)
 descCons.DepthOrArraySize = 1; // Depth or number of elements in the array (1 for buffer)
 descCons.MipLevels = 1; // Number of mipmap levels (1 for buffer)
 descCons.Format = DXGI_FORMAT_UNKNOWN; // Data format in the resource (unknown by default)
 descCons.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; // Layout of the data in the resource (default is string)
 descCons.Flags = D3D12_RESOURCE_FLAG_NONE; // Resource flags (no default flags)
 descCons.SampleDesc.Count = 1; // Number of samples
 descCons.SampleDesc.Quality = 0; // Sampling quality

 propertiesConst.Type=D3D12_HEAP_TYPE_UPLOAD;// for a constant buffer
 propertiesConst.CPUPageProperty=D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
 propertiesConst.MemoryPoolPreference=D3D12_MEMORY_POOL_UNKNOWN;
 propertiesConst.CreationNodeMask=0;
 propertiesConst.VisibleNodeMask=0;
 for(UINT i=0;i<NUM_BACK_BUFFERS;i++){
 // create constant buffers
     ThrowF(DX12.d3dDevice->CreateCommittedResource(&propertiesConst, D3D12_HEAP_FLAG_NONE, &descCons, D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(&DX12.Buffers.constBuffers[i])), ERROR_GETFRAMEBUFFERS);
     DX12.Buffers.constBuffers[i]->SetName(L"Constant Buffer Upload Resource Heap");// the name of the constant buffer is set, without this the code does not work (I don’t know why)

 // Create views for frame constant buffers
     descConsBufferView.BufferLocation=DX12.Buffers.constBuffers[i]->GetGPUVirtualAddress();
     descConsBufferView.SizeInBytes=(sizeof(ConstantBuffer) + 255) & ~255;
     DX12.d3dDevice->CreateConstantBufferView(&descConsBufferView, DX12.Buffers.cvbHeap[i]->GetCPUDescriptorHandleForHeapStart());
 }