CreateSwapChain function returns empty/NULL tempSwapChain
Hi, I have been following the DirectX 12 tutorial and it has been great. Thank you by the way! I am having a little bit of trouble with one thing though and was hoping you may be able to help me. In Part 4, Drawing! This function returns an empty/NULL tempSwapChain. dxgiFactory->CreateSwapChain( commandQueue, // the queue will be flushed once the swap chain is created &swapChainDesc, // give it the swap chain description we created above &tempSwapChain // store the created swap chain in a temp IDXGISwapChain interface ); I was hoping someone had an idea of what could be causing that problem. I did not change any of the code in the InitD3D function. I did put everything in classes though, instead of all the global stuff. Anyway, thanks in advance for any help. bool Direct3D::InitD3D() { HRESULT hr; // -- Create the Device -- // IDXGIFactory4* dxgiFactory; hr = CreateDXGIFactory(IID_PPV_ARGS(&dxgiFactory)); if (FAILED(hr)) { MessageBox(NULL, L"Error Creating DXGIFactory1", L"Error", MB_OK | MB_ICONERROR); return false; } IDXGIAdapter1* adapter; // adapters are the graphics card (this includes the embedded graphics on the motherboard) int adapterIndex = 0; // we'll start looking for directx 12 compatible graphics devices starting at index 0 bool adapterFound = false; // set this to true when a good one was found // find first hardware gpu that supports d3d 12 while (dxgiFactory->EnumAdapters1(adapterIndex, &adapter) != DXGI_ERROR_NOT_FOUND) { DXGI_ADAPTER_DESC1 desc; adapter->GetDesc1(&desc); if (desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE) { // we dont want a software device continue; } // we want a device that is compatible with direct3d 12 (feature level 11 or higher) hr = D3D12CreateDevice(adapter, D3D_FEATURE_LEVEL_11_0, _uuidof(ID3D12Device), nullptr); if (SUCCEEDED(hr)) { adapterFound = true; break; } adapterIndex++; } if (!adapterFound) { return false; } // Create the device hr = D3D12CreateDevice(adapter, D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&device)); if (FAILED(hr)) { MessageBox(NULL, L"Error Creating Device", L"Error", MB_OK | MB_ICONERROR); return false; } // -- Create a direct command queue -- // D3D12_COMMAND_QUEUE_DESC cqDesc = {}; cqDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE; cqDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT; // direct means the gpu can directly execute this command queue hr = device->CreateCommandQueue(&cqDesc, IID_PPV_ARGS(&commandQueue)); // create the command queue if (FAILED(hr)) { MessageBox(NULL, L"Error Creating Command Queue", L"Error", MB_OK | MB_ICONERROR); return false; } // -- Create the Swap Chain (double/tripple buffering) -- // DXGI_MODE_DESC backBufferDesc = {}; // this is to describe our display mode backBufferDesc.Width = width; // buffer width backBufferDesc.Height = height; // buffer height backBufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; // format of the buffer (rgba 32 bits, 8 bits for each chanel) // describe our multi-sampling. We are not multi-sampling, so we set the count to 1 (we need at least one sample of course) DXGI_SAMPLE_DESC sampleDesc = {}; sampleDesc.Count = 1; // multisample count (no multisampling, so we just put 1, since we still need 1 sample) // Describe and create the swap chain. DXGI_SWAP_CHAIN_DESC swapChainDesc = {}; swapChainDesc.BufferCount = frameBufferCount; // number of buffers we have swapChainDesc.BufferDesc = backBufferDesc; // our back buffer description swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; // this says the pipeline will render to this swap chain swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; // dxgi will discard the buffer (data) after we call present swapChainDesc.OutputWindow = hwnd; // handle to our window swapChainDesc.SampleDesc = sampleDesc; // our multi-sampling description swapChainDesc.Windowed = !fullscreen; // set to true, then if in fullscreen must call SetFullScreenState with true for full screen to get uncapped fps IDXGISwapChain* tempSwapChain; dxgiFactory->CreateSwapChain( commandQueue, // the queue will be flushed once the swap chain is created &swapChainDesc, // give it the swap chain description we created above &tempSwapChain // store the created swap chain in a temp IDXGISwapChain interface );
what is the return value of CreateSwapChain?
on Jan 22 `17
iedoc
When stepping through the code, the CreateSwapChain function seems to be skipped. When I press step in, it just goes over like I pressed step over. Seems wrong to me but perhaps it is supposed to do that? So sorry but I do not know what the return value is. Unless there is another way of finding out what it is? Also, if that helps... Looking at dxgiFactory, it says 'Information not available, no symbols loaded for dxgi.dll' Again, not sure if that is supposed to be there or not...
on Jan 22 `17
CoconutDug
can you post the code of that init till CreateSwapChain function? I have all packed in classes and works fine, maybe you just missed something?
on Jan 23 `17
maxiorek82
When I assign the return value of CreateSwapChain function to a HRESULT, stepping through the code, that HRESULT says E_OUTOFMEMORY Ran out of memory. Is that what you originally asked?
on Jan 23 `17
CoconutDug
I added the code of the InitD3D function in my question.
on Jan 23 `17
CoconutDug
I just had a thought, could the problem be because the tutorial uses x64 but I used x86? For reasons I cannot remember now.
on Jan 23 `17
CoconutDug
Well, not to mention the obvious, but E_OUTOFMEMORY means you do not have enough memory for the function to finish its job. Can you check resource monitor to see how much memory your application is using? x86 is only able to have up to 2 gigs of memory per process, so if for some reason your application is using nearly 2 gigs, that's why, and the problem is now not the CreateSwapChain, but somewhere else you have a memory leak. Otherwise, are you making your back buffers huge? if they are too big they might suck up a lot of memory and cause you to run out.
on Jan 23 `17
iedoc
One more thing, always remember to assign these functions to an HRESULT and check the result always. I don't do it often in my tutorials, but i believe i mention it a couple times. You will have to look up the api's you are using to see their return values. most of dxgi and directx have a return result of HRESULT
on Jan 23 `17
iedoc
Sign in to comment
Chosen Answer
I doubt that this is because difference between x86 and x64, I looked at my source and I had it transformed a little bit D3D12_COMMAND_QUEUE_DESC queueDesc = {}; queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE; queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT; hr = pDevice->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(&pCommandQueue)); if (FAILED(hr)) { Write(hr); } DXGI_SAMPLE_DESC sampleDesc{}; sampleDesc.Count = 1; DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {}; swapChainDesc.BufferCount = FrameCount; swapChainDesc.Width = Width; swapChainDesc.Height = Height; swapChainDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; swapChainDesc.SampleDesc = sampleDesc; ComPtr<IDXGISwapChain1> swapChain{}; hr = factory->CreateSwapChainForHwnd(pCommandQueue.Get(), MainWnd, &swapChainDesc, nullptr, nullptr, &swapChain); if (FAILED(hr)) { Write(hr); } hr = factory->MakeWindowAssociation(MainWnd, DXGI_MWA_NO_ALT_ENTER); if (FAILED(hr)) { Write(hr); } hr = swapChain.As(&pSwapChain); if (FAILED(hr)) { Write(hr); } to be honest the only thing that don't work at my code at this moment is only fullscreen, but most of my code is modified code of iedoc (most of it heavy modified) try this and give a note how it works :) I've also modified code that checks suport of Dx12 cause I work on Software and Hardware modes Regards,
Right, I managed to fix it, nothing wrong with the code, it was my own mistakes which led to the problem. Apologies for that! I'll mark this as the answer to close the question. Hope that is ok.
on Jan 23 `17
CoconutDug