void KGraphicsDevice::Present() { m_SwapChain->Present(0, 0); m_SwapIndex = (1 + m_SwapIndex) % 2; WaitForGPU(); }
void AppTest::Destroy() { WaitForGPU(); SwapChain->SetFullscreenState(FALSE, nullptr); CloseHandle(HandleEvent); #ifdef DEBUG novus::MallocTracker::GetInstance()->DumpTrackedMemory(); #endif }
IRenderer::Impl::Impl(HWND hwnd, U32 windowWidth, U32 windowHeight, IRenderer* pRenderer) : m_viewport(static_cast<F32>(windowWidth), static_cast<F32>(windowHeight)) , m_scissorRect(windowWidth, windowHeight) , m_psoManager(&m_device, &m_resCache, &m_rootSignature) , m_pRenderer(pRenderer) { // TEMP: Select the second(integrated card) adapter due to some problem with nvidia I can't pinpoint. auto pAdapter = m_hwCaps.GetDisplayAdapter(1).Get(); m_device.Init(pAdapter.Get()); m_hwCaps.CheckMSAASupport(m_device.Get()); m_commandQueue.Init(m_device.Get()); m_swapChain.Init(m_device.Get(), m_commandQueue.Get(), hwnd); m_commandAllocator.Init(m_device.Get()); CreateRootSignature(); // Create Resources ResourceConfig descCB(ResourceType::BUFFER, sizeof(XMFLOAT4X4)); m_viewProjConstBuffer.CreateCommited(m_device.Get(), descCB, &m_pViewProjDataBegin); // Create Descriptor Heaps m_cbDescHeap.Init(m_device.Get(), DescHeapType::CB_SR_UA, MAX_RENDER_ITEMS, true); m_dsvDescHeap.Init(m_device.Get(), DescHeapType::DEPTH_STENCIL, 1); // Create Depth Buffer ClearValue clearValue(DXGI_FORMAT_D32_FLOAT, 1.0f); ResourceConfig dbConfig(ResourceType::TEXTURE2D, 800, 600, DXGI_FORMAT_R32_TYPELESS, TextureLayout::UNKNOWN, ResourceFlag::ALLOW_DEPTH_STENCIL); m_depthBuffer.CreateCommited(m_device.Get(), dbConfig, nullptr, nullptr, 0, D3D12_HEAP_TYPE_DEFAULT, D3D12_RESOURCE_STATE_DEPTH_WRITE, &clearValue); DepthStencilView dsvDesc; m_device.Get()->CreateDepthStencilView(m_depthBuffer.Get(), &dsvDesc, m_dsvDescHeap.GetCPUHandle(0)); // Create a command list m_commandList.Init(m_device.Get(), m_commandAllocator.Get()); m_commandList.Close(); // Create synchronization objects m_fence.Init(m_device.Get(), 0); m_currentFence = 1; m_handleEvent = CreateEventEx(nullptr, FALSE, FALSE, EVENT_ALL_ACCESS); // Synchronize WaitForGPU(); m_resCache.Init(m_device.Get()); }
Direct3DManager::~Direct3DManager() { WaitForGPU(); ReleaseSwapChainDependentResources(); mSwapChain->Release(); mSwapChain = NULL; delete mContextManager; mContextManager = NULL; mDevice->Release(); mDevice = NULL; mDXGIFactory->Release(); mDXGIFactory = NULL; }
void AppTest::Render() { PopulateCommandLists(); //Execute command lists std::vector<ID3D12CommandList*> commandLists; commandLists.push_back(CommandList.Get()); for (auto const& it : CommandListArray) { commandLists.push_back(it.Get()); } CommandQueue->ExecuteCommandLists((UINT)commandLists.size(), &commandLists[0]); //Swap back and front buffers SwapChain->Present(1, 0); IndexLastSwapBuf = (1 + IndexLastSwapBuf) % NumSwapBufs; SwapChain->GetBuffer(IndexLastSwapBuf, IID_PPV_ARGS(RenderTarget.ReleaseAndGetAddressOf())); Device->CreateRenderTargetView(RenderTarget.Get(), nullptr, DescriptorHeap->GetCPUDescriptorHandleForHeapStart()); WaitForGPU(); }
ResourceManager::~ResourceManager() { if (m_pUpload) { WaitForGPU(); m_pUpload->Release(); m_pUpload = nullptr; } m_pDev = nullptr; CloseHandle(m_hdlFenceEvent); if (m_pFence) { m_pFence->Release(); m_pFence = nullptr; } if (m_pCmdAllocator) { m_pCmdAllocator->Release(); m_pCmdAllocator = nullptr; } if (m_pCmdList) { m_pCmdList->Release(); m_pCmdList = nullptr; } while (!m_listFileData.empty()) { unsigned char* tmp = m_listFileData.back(); if (tmp) delete[] tmp; m_listFileData.pop_back(); } while (!m_listResources.empty()) { ID3D12Resource* tex = m_listResources.back(); if (tex) tex->Release(); m_listResources.pop_back(); } if (m_pheapSampler) { m_pheapSampler->Release(); m_pheapSampler = nullptr; } if (m_pheapCBVSRVUAV) { m_pheapCBVSRVUAV->Release(); m_pheapCBVSRVUAV = nullptr; } if (m_pheapDSV) { m_pheapDSV->Release(); m_pheapDSV = nullptr; } if (m_pheapRTV) { m_pheapRTV->Release(); m_pheapRTV = nullptr; } }
// Upload to the buffer stored at index i. void ResourceManager::UploadToBuffer(unsigned int i, unsigned int numSubResources, D3D12_SUBRESOURCE_DATA* data, D3D12_RESOURCE_STATES initialState) { if (i < 0 || i >= m_listResources.size()) { std::string msg = "ResourceManager::UploadToBuffer failed due to index " + std::to_string(i) + " out of bounds."; throw GFX_Exception(msg.c_str()); } if (FAILED(m_pCmdList->Reset(m_pCmdAllocator, NULL))) { throw GFX_Exception("ResourceManager::UploadToBuffer: CommandList Reset failed."); } m_pCmdList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_listResources[i], initialState, D3D12_RESOURCE_STATE_COPY_DEST)); auto size = GetRequiredIntermediateSize(m_listResources[i], 0, numSubResources); size = (UINT64)pow(2.0, ceil(log(size) / log(2))); // round size up to the next power of 2 to ensure good alignment in upload buffer. if (size > DEFAULT_UPLOAD_BUFFER_SIZE) { // then we're going to have to create a new temporary buffer. ID3D12Resource* tmpUpload; m_pDev->CreateCommittedResource(tmpUpload, &CD3DX12_RESOURCE_DESC::Buffer(size), &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD), D3D12_HEAP_FLAG_NONE, D3D12_RESOURCE_STATE_GENERIC_READ, nullptr); UpdateSubresources(m_pCmdList, m_listResources[i], tmpUpload, 0, 0, numSubResources, data); // set resource barriers to inform GPU that data is ready for use. m_pCmdList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_listResources[i], initialState, D3D12_RESOURCE_STATE_COPY_DEST)); // close the command list. if (FAILED(m_pCmdList->Close())) { throw GFX_Exception("ResourceManager::UploadToBuffer: CommandList Close failed."); } // load the command list. ID3D12CommandList* lCmds[] = { m_pCmdList }; m_pDev->ExecuteCommandLists(lCmds, __crt_countof(lCmds)); // add fence signal. ++m_valFence; m_pDev->SetFence(m_pFence, m_valFence); WaitForGPU(); tmpUpload->Release(); } else { if (size > DEFAULT_UPLOAD_BUFFER_SIZE - m_iUpload) { // then we need to wait for the GPU to finish with whatever it is currently uploading. // check to see if it is already done. if (m_pFence->GetCompletedValue() < m_valFence) { // then we're not done, so wait. WaitForGPU(); } m_iUpload = 0; } UpdateSubresources(m_pCmdList, m_listResources[i], m_pUpload, m_iUpload, 0, numSubResources, data); m_iUpload += size; // set resource barriers to inform GPU that data is ready for use. m_pCmdList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_listResources[i], D3D12_RESOURCE_STATE_COPY_DEST, initialState)); // close the command list. if (FAILED(m_pCmdList->Close())) { throw GFX_Exception("ResourceManager::UploadToBuffer: CommandList Close failed."); } // load the command list. ID3D12CommandList* lCmds[] = { m_pCmdList }; m_pDev->ExecuteCommandLists(lCmds, __crt_countof(lCmds)); // add fence signal. ++m_valFence; m_pDev->SetFence(m_pFence, m_valFence); } }
void AppTest::LoadAssets() { //Load and compile the shaders D3D12Shader vertShader = D3D12Shader(ShaderType::Vertex, L"TestShader.hlsl", "VS"); D3D12Shader pixelShader = D3D12Shader(ShaderType::Pixel, L"TestShader.hlsl", "PS"); std::vector<ShaderMacro> macros; macros.push_back({ "BOXCOLOR", "float4(1.0f, 1.0f, 1.0f, 1.0f)" }); vertShader.Compile(¯os[0], static_cast<uint32_t>(macros.size())); pixelShader.Compile(¯os[0], static_cast<uint32_t>(macros.size())); D3D12_INPUT_ELEMENT_DESC layout[] = { { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, { "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA , 0} }; UINT numElements = ARRAYSIZE(layout); //Create root signiture with one root constant buffer view D3D12_ROOT_PARAMETER param; D3D12_DESCRIPTOR_RANGE descriptorRange = {}; if (UseRootLevelCBV) { param.ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV; param.ShaderVisibility = D3D12_SHADER_VISIBILITY_VERTEX; param.Descriptor = { 0, 0 }; } else { //Used for if you need non root level constant buffer views //This is somewhat slower than switching out a root level CBV descriptorRange.BaseShaderRegister = 0; descriptorRange.NumDescriptors = 1; descriptorRange.OffsetInDescriptorsFromTableStart = 0; descriptorRange.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_CBV; descriptorRange.RegisterSpace = 0; param.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; param.ShaderVisibility = D3D12_SHADER_VISIBILITY_VERTEX; param.DescriptorTable.NumDescriptorRanges = 1; param.DescriptorTable.pDescriptorRanges = &descriptorRange; } ComPtr<ID3D10Blob> pOutBlob, pErrorBlob; D3D12_ROOT_SIGNATURE_DESC rootSigDesc; rootSigDesc.NumParameters = 1; rootSigDesc.pParameters = ¶m; rootSigDesc.NumStaticSamplers = 0; rootSigDesc.pStaticSamplers = nullptr; rootSigDesc.Flags = D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT; CHK(D3D12SerializeRootSignature(&rootSigDesc, D3D_ROOT_SIGNATURE_VERSION_1, pOutBlob.GetAddressOf(), pErrorBlob.GetAddressOf())); CHK(Device->CreateRootSignature(0, pOutBlob->GetBufferPointer(), pOutBlob->GetBufferSize(), IID_PPV_ARGS(RootSignature.GetAddressOf()))); //Create the PSO D3D12_GRAPHICS_PIPELINE_STATE_DESC psoDesc; ZeroMemory(&psoDesc, sizeof(psoDesc)); psoDesc.InputLayout = { layout, numElements }; psoDesc.pRootSignature = RootSignature.Get(); psoDesc.VS = { reinterpret_cast<BYTE*>(vertShader.GetByteCodePtr()), vertShader.GetSize() }; psoDesc.PS = { reinterpret_cast<BYTE*>(pixelShader.GetByteCodePtr()), pixelShader.GetSize() }; psoDesc.RasterizerState = CD3DX12_RASTERIZER_DESC(D3D12_DEFAULT);; psoDesc.RasterizerState.FrontCounterClockwise = true; //Using RH coordinate system psoDesc.BlendState = CD3DX12_BLEND_DESC(D3D12_DEFAULT); psoDesc.DepthStencilState.DepthEnable = true; psoDesc.DepthStencilState.DepthFunc = D3D12_COMPARISON_FUNC_LESS_EQUAL; psoDesc.DepthStencilState.DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ALL; psoDesc.DepthStencilState.StencilEnable = false; psoDesc.SampleMask = UINT_MAX; psoDesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; psoDesc.NumRenderTargets = 1; psoDesc.RTVFormats[0] = DXGI_FORMAT_R8G8B8A8_UNORM; psoDesc.DSVFormat = DXGI_FORMAT_D32_FLOAT; psoDesc.SampleDesc.Count = 1; psoDesc.SampleDesc.Quality = 0; CHK(Device->CreateGraphicsPipelineState(&psoDesc, IID_PPV_ARGS(PSO.GetAddressOf()))); //Create descriptor heap D3D12_DESCRIPTOR_HEAP_DESC descHeapDesc = {}; descHeapDesc.NumDescriptors = 1; descHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV; descHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE; CHK(Device->CreateDescriptorHeap(&descHeapDesc, IID_PPV_ARGS(DescriptorHeap.GetAddressOf()))); D3D12_DESCRIPTOR_HEAP_DESC DSVDescHeapDesc = {}; DSVDescHeapDesc.NumDescriptors = 1; DSVDescHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_DSV; DSVDescHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE; CHK(Device->CreateDescriptorHeap(&DSVDescHeapDesc, IID_PPV_ARGS(DSVDescriptorHeap.GetAddressOf()))); CHK(Device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, CommandAllocator.Get(), PSO.Get(), IID_PPV_ARGS(CommandList.GetAddressOf()))); //Create the command lists for each thread for (unsigned int i = 0; i < ThreadCount; i++) { CHK(Device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, CommandAllocatorArray[i].Get(), PSO.Get(), IID_PPV_ARGS(CommandListArray[i].GetAddressOf()))); CommandListArray[i].Get()->Close(); } //Create back buffer and render target CHK(SwapChain->GetBuffer(0, IID_PPV_ARGS(RenderTarget.GetAddressOf()))); Device->CreateRenderTargetView(RenderTarget.Get(), nullptr, DescriptorHeap->GetCPUDescriptorHandleForHeapStart()); Viewport.TopLeftX = 0.0f; Viewport.TopLeftY = 0.0f; Viewport.Width = static_cast<float>(ViewportWidth); Viewport.Height = static_cast<float>(ViewportHeight); Viewport.MinDepth = 0.0f; Viewport.MaxDepth = 1.0f; RectScissor.left = 0; RectScissor.top = 0; RectScissor.right = ViewportWidth; RectScissor.bottom = ViewportHeight; //Create depth buffer D3D12_RESOURCE_DESC depthResDesc = CD3DX12_RESOURCE_DESC::Tex2D( DXGI_FORMAT_R32_TYPELESS, ViewportWidth, ViewportHeight, 1, 1, 1, 0, D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL, D3D12_TEXTURE_LAYOUT_UNKNOWN); D3D12_CLEAR_VALUE dsvClearValue; dsvClearValue.Format = DXGI_FORMAT_D32_FLOAT; dsvClearValue.DepthStencil.Depth = 1.0f; dsvClearValue.DepthStencil.Stencil = 0; CHK(Device->CreateCommittedResource( &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), D3D12_HEAP_FLAG_NONE, &depthResDesc, D3D12_RESOURCE_STATE_DEPTH_WRITE, &dsvClearValue, IID_PPV_ARGS(DepthBufferTexture.GetAddressOf()))); DepthBufferTexture->SetName(L"Depth Buffer"); D3D12_DEPTH_STENCIL_VIEW_DESC dsvDesc = {}; dsvDesc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2D; dsvDesc.Format = DXGI_FORMAT_D32_FLOAT; dsvDesc.Texture2D.MipSlice = 0; dsvDesc.Flags = D3D12_DSV_FLAG_NONE; Device->CreateDepthStencilView(DepthBufferTexture.Get(), &dsvDesc, DSVDescriptorHeap->GetCPUDescriptorHandleForHeapStart()); //Allocate buffer for all constant buffers PerObjectConstantBuffers.Init(BoxCount, sizeof(CBPerObject), Device.Get()); //Create the constant buffer descriptor heap and populate it if (!UseRootLevelCBV) { ConstantBufferDescriptorHeap = std::make_unique<D3D12RHIDescriptorHeap>(BoxCount, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, true); HRESULT hr = ConstantBufferDescriptorHeap->Init(Device.Get()); assert(SUCCEEDED(hr)); D3D12_CONSTANT_BUFFER_VIEW_DESC constantBufferViewDesc = {}; constantBufferViewDesc.SizeInBytes = PerObjectConstantBuffers.GetAlignedStride(); D3D12_CPU_DESCRIPTOR_HANDLE cpuDescriptorHandle; for (unsigned int i = 0; i < BoxCount; i++) { cpuDescriptorHandle.ptr = reinterpret_cast<size_t>(ConstantBufferDescriptorHeap->GetDescriptorCPUPtr(i)); constantBufferViewDesc.BufferLocation = PerObjectConstantBuffers.GetGPUHandle(i); Device->CreateConstantBufferView(&constantBufferViewDesc, cpuDescriptorHandle); } } //Generate mesh GeometryGenerator::SimpleMesh shapeMesh; GeometryGenerator::CreateBox(1.0f, 1.0f, 1.0f, shapeMesh); //GeometryGenerator::CreateSphere(1.0f, 10, 10, shapeMesh); IndexCount = static_cast<uint32_t>(shapeMesh.Indices.size()); //Copy vertex data to buffer //This should be put into its own job system using the copy engine eventually Device->CreateCommittedResource( &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD), D3D12_HEAP_FLAG_NONE, &CD3DX12_RESOURCE_DESC::Buffer(sizeof(GeometryGenerator::SimpleVertex) * shapeMesh.Vertices.size()), D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(VertBuffer.GetAddressOf())); Device->CreateCommittedResource( &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD), D3D12_HEAP_FLAG_NONE, &CD3DX12_RESOURCE_DESC::Buffer(sizeof(uint32_t) * shapeMesh.Indices.size()), D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(IndexBuffer.GetAddressOf())); UINT8* dataBegin; VertBuffer->Map(0, nullptr, reinterpret_cast<void**>(&dataBegin)); memcpy(dataBegin, &shapeMesh.Vertices[0], sizeof(GeometryGenerator::SimpleVertex) * shapeMesh.Vertices.size()); VertBuffer->Unmap(0, nullptr); IndexBuffer->Map(0, nullptr, reinterpret_cast<void**>(&dataBegin)); memcpy(dataBegin, &shapeMesh.Indices[0], sizeof(uint32_t) * shapeMesh.Indices.size()); IndexBuffer->Unmap(0, nullptr); //Create vertex buffer view DescViewBufVert.BufferLocation = VertBuffer->GetGPUVirtualAddress(); DescViewBufVert.StrideInBytes = sizeof(GeometryGenerator::SimpleVertex); DescViewBufVert.SizeInBytes = static_cast<UINT>(sizeof(GeometryGenerator::SimpleVertex) * shapeMesh.Vertices.size()); DescViewBufIndex.BufferLocation = IndexBuffer->GetGPUVirtualAddress(); DescViewBufIndex.Format = DXGI_FORMAT_R32_UINT; DescViewBufIndex.SizeInBytes = static_cast<UINT>(sizeof(uint32_t) * shapeMesh.Indices.size()); //Create fencing object Device->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(Fence.GetAddressOf())); CurrentFence = 1; //Initialize bundles for drawing if (UseBundles) { InitBundles(); } //Close the command list and use it to execute the GPU setup CommandList->Close(); ID3D12CommandList* ppCommandLists[] = { CommandList.Get() }; CommandQueue->ExecuteCommandLists(1, ppCommandLists); HandleEvent = CreateEventEx(nullptr, false, false, EVENT_ALL_ACCESS); WaitForGPU(); }
void Direct3DManager::CreateWindowDependentResources(Vector2 screenSize, HWND windowHandle, bool vsync /*= false*/, bool fullScreen /*= false*/) { // Wait until all previous GPU work is complete. WaitForGPU(); mOutputSize = screenSize; mUseVsync = vsync; //need to handle if vsync or fullscreen changes mIsFullScreen = fullScreen; // The width and height of the swap chain must be based on the window's // natively-oriented width and height. If the window is not in the native // orientation, the dimensions must be reversed. DXGI_MODE_ROTATION displayRotation = ComputeDisplayRotation(); bool swapDimensions = displayRotation == DXGI_MODE_ROTATION_ROTATE90 || displayRotation == DXGI_MODE_ROTATION_ROTATE270; mOutputSize.X = swapDimensions ? screenSize.Y : screenSize.X; mOutputSize.Y = swapDimensions ? screenSize.X : screenSize.Y; if (mSwapChain != NULL) { ReleaseSwapChainDependentResources(); // If the swap chain already exists, resize it. HRESULT hr = mSwapChain->ResizeBuffers(BACK_BUFFER_COUNT, lround(mOutputSize.X), lround(mOutputSize.Y), DXGI_FORMAT_R8G8B8A8_UNORM, 0); if (hr == DXGI_ERROR_DEVICE_REMOVED || hr == DXGI_ERROR_DEVICE_RESET) { // If the device was removed for any reason, a new device and swap chain will need to be created. mDeviceRemoved = true; // Do not continue execution of this method. DeviceResources will be destroyed and re-created. return; } else { Direct3DUtils::ThrowIfHRESULTFailed(hr); } } else { // Otherwise, create a new one using the same adapter as the existing Direct3D device. IDXGIAdapter* adapter = NULL; IDXGIOutput* adapterOutput = NULL; uint32 numDisplayModes = 0; Direct3DUtils::ThrowIfHRESULTFailed(mDXGIFactory->EnumAdapters(0, &adapter)); Direct3DUtils::ThrowIfHRESULTFailed(adapter->EnumOutputs(0, &adapterOutput)); Direct3DUtils::ThrowIfHRESULTFailed(adapterOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &numDisplayModes, NULL)); DXGI_MODE_DESC *displayModeList = new DXGI_MODE_DESC[numDisplayModes]; Direct3DUtils::ThrowIfHRESULTFailed(adapterOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &numDisplayModes, displayModeList)); uint32 numerator = 0; uint32 denominator = 0; for (uint32 i = 0; i < numDisplayModes; i++) { if (displayModeList[i].Height == (uint32)mOutputSize.X) { if (displayModeList[i].Width == (uint32)mOutputSize.Y) { numerator = displayModeList[i].RefreshRate.Numerator; denominator = displayModeList[i].RefreshRate.Denominator; } } } /* DXGI_ADAPTER_DESC adapterDesc; // Get the adapter (video card) description. result = adapter->GetDesc(&adapterDesc); if(FAILED(result)) { return false; } // Store the dedicated video card memory in megabytes. m_videoCardMemory = (int)(adapterDesc.DedicatedVideoMemory / 1024 / 1024); // Convert the name of the video card to a character array and store it. error = wcstombs_s(&stringLength, m_videoCardDescription, 128, adapterDesc.Description, 128); if(error != 0) { return false; } */ delete[] displayModeList; displayModeList = NULL; adapterOutput->Release(); adapterOutput = NULL; adapter->Release(); adapter = NULL; DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {}; ZeroMemory(&swapChainDesc, sizeof(swapChainDesc)); swapChainDesc.Width = lround(mOutputSize.X); // Match the size of the window. swapChainDesc.Height = lround(mOutputSize.Y); swapChainDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; // This is the most common swap chain format. swapChainDesc.Stereo = false; swapChainDesc.SampleDesc.Count = 1; // Don't use multi-sampling. swapChainDesc.SampleDesc.Quality = 0; swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; swapChainDesc.BufferCount = BACK_BUFFER_COUNT; // Use triple-buffering to minimize latency. swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; // All Windows Universal apps must use _FLIP_ SwapEffects swapChainDesc.Flags = 0; swapChainDesc.Scaling = DXGI_SCALING_NONE; swapChainDesc.AlphaMode = DXGI_ALPHA_MODE_UNSPECIFIED; DXGI_SWAP_CHAIN_FULLSCREEN_DESC swapChainFullScreenDesc = {}; ZeroMemory(&swapChainFullScreenDesc, sizeof(swapChainFullScreenDesc)); swapChainFullScreenDesc.Windowed = !mIsFullScreen; swapChainFullScreenDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; swapChainFullScreenDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; if (mUseVsync) { swapChainFullScreenDesc.RefreshRate.Numerator = numerator; swapChainFullScreenDesc.RefreshRate.Denominator = denominator; } else { swapChainFullScreenDesc.RefreshRate.Numerator = 0; swapChainFullScreenDesc.RefreshRate.Denominator = 1; } IDXGISwapChain1 *swapChain = NULL; Direct3DUtils::ThrowIfHRESULTFailed( mDXGIFactory->CreateSwapChainForHwnd( mContextManager->GetQueueManager()->GetGraphicsQueue()->GetCommandQueue(), windowHandle, &swapChainDesc, &swapChainFullScreenDesc, NULL, &swapChain ) ); Direct3DUtils::ThrowIfHRESULTFailed(swapChain->QueryInterface(__uuidof(IDXGISwapChain3), (void**)&mSwapChain)); } Direct3DUtils::ThrowIfHRESULTFailed(mSwapChain->SetRotation(displayRotation)); BuildSwapChainDependentResources(); // Set the 3D rendering viewport to target the entire window. mScreenViewport = { 0.0f, 0.0f, mOutputSize.X, mOutputSize.Y, 0.0f, 1.0f }; WaitForGPU(); }