void BBWin8Game::ValidateOrientation(){ int devrot=DeviceRotation(); if( CFG_WIN8_SCREEN_ORIENTATION & (1<<DeviceOrientation()) ) _deviceRotation=devrot; #if WINDOWS_8 _inputRotation=(4-devrot+_deviceRotation)&3; if( _swapChain ) _swapChain->SetRotation( SwapChainRotation() ); Windows::UI::Core::CoreWindowResizeManager::GetForCurrentView()->NotifyLayoutCompleted(); #elif WINDOWS_PHONE_8 _inputRotation=_deviceRotation; #endif }
void BBWin8Game::CreateD3dDevice(){ CoreWindow ^window=CoreWindow::GetForCurrentThread(); int width=DipsToPixels( window->Bounds.Width ); int height=DipsToPixels( window->Bounds.Height ); #if WINDOWS_8 switch( DisplayProperties::CurrentOrientation ){ case DisplayOrientations::Portrait: case DisplayOrientations::PortraitFlipped: std::swap( width,height ); break; } #endif UINT creationFlags=D3D11_CREATE_DEVICE_BGRA_SUPPORT; #ifdef _DEBUG creationFlags|=D3D11_CREATE_DEVICE_DEBUG; #endif #if WINDOWS_8 D3D_FEATURE_LEVEL featureLevels[]={ D3D_FEATURE_LEVEL_11_1, D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_1, D3D_FEATURE_LEVEL_10_0, D3D_FEATURE_LEVEL_9_3, D3D_FEATURE_LEVEL_9_2, D3D_FEATURE_LEVEL_9_1 }; #elif WINDOWS_PHONE_8 D3D_FEATURE_LEVEL featureLevels[]={ D3D_FEATURE_LEVEL_11_1, D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_1, D3D_FEATURE_LEVEL_10_0, D3D_FEATURE_LEVEL_9_3 }; #endif ID3D11Device *device; ID3D11DeviceContext *context; DXASS( D3D11CreateDevice( 0, D3D_DRIVER_TYPE_HARDWARE, 0, creationFlags, featureLevels, ARRAYSIZE(featureLevels), D3D11_SDK_VERSION, &device, &_featureLevel, &context ) ); DXASS( device->QueryInterface( __uuidof( ID3D11Device1 ),(void**)&_d3dDevice ) ); DXASS( context->QueryInterface( __uuidof( ID3D11DeviceContext1 ),(void**)&_d3dContext ) ); device->Release(); context->Release(); //create swap chain if( _swapChain ){ DXASS( _swapChain->ResizeBuffers( 2,width,height,DXGI_FORMAT_B8G8R8A8_UNORM,0 ) ); }else{ #if WINDOWS_8 DXGI_SWAP_CHAIN_DESC1 swapChainDesc={0}; swapChainDesc.Width=width; swapChainDesc.Height=height; swapChainDesc.Format=DXGI_FORMAT_B8G8R8A8_UNORM; swapChainDesc.Stereo=false; swapChainDesc.SampleDesc.Count=1; swapChainDesc.SampleDesc.Quality=0; swapChainDesc.BufferUsage=DXGI_USAGE_RENDER_TARGET_OUTPUT; swapChainDesc.BufferCount=2; swapChainDesc.Scaling=DXGI_SCALING_NONE; swapChainDesc.SwapEffect=DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; swapChainDesc.Flags=0; #elif WINDOWS_PHONE_8 DXGI_SWAP_CHAIN_DESC1 swapChainDesc={0}; swapChainDesc.Width=width; swapChainDesc.Height=height; swapChainDesc.Format=DXGI_FORMAT_B8G8R8A8_UNORM; swapChainDesc.Stereo=false; swapChainDesc.SampleDesc.Count=1; swapChainDesc.SampleDesc.Quality=0; swapChainDesc.BufferUsage=DXGI_USAGE_RENDER_TARGET_OUTPUT; swapChainDesc.BufferCount=1; swapChainDesc.Scaling=DXGI_SCALING_STRETCH; swapChainDesc.SwapEffect=DXGI_SWAP_EFFECT_DISCARD; swapChainDesc.Flags=0; #endif IDXGIDevice1 *dxgiDevice; DXASS( _d3dDevice->QueryInterface( __uuidof( IDXGIDevice1 ),(void**)&dxgiDevice ) ); IDXGIAdapter *dxgiAdapter; DXASS( dxgiDevice->GetAdapter( &dxgiAdapter ) ); IDXGIFactory2 *dxgiFactory; DXASS( dxgiAdapter->GetParent( __uuidof( IDXGIFactory2 ),(void**)&dxgiFactory ) ); DXASS( dxgiFactory->CreateSwapChainForCoreWindow( _d3dDevice,(IUnknown*)window,&swapChainDesc,0,&_swapChain ) ); DXASS( dxgiDevice->SetMaximumFrameLatency( 1 ) ); dxgiFactory->Release(); dxgiAdapter->Release(); dxgiDevice->Release(); } // Create a render target view of the swap chain back buffer. // ID3D11Texture2D *backBuffer; DXASS( _swapChain->GetBuffer( 0,__uuidof( ID3D11Texture2D ),(void**)&backBuffer ) ); DXASS( _d3dDevice->CreateRenderTargetView( backBuffer,0,&_renderTargetView ) ); backBuffer->Release(); /* // Create a depth stencil view // D3D11_TEXTURE2D_DESC dsdesc; ZEROMEM( dsdesc ); dsdesc.Width=width; dsdesc.Height=height; dsdesc.MipLevels=1; dsdesc.ArraySize=1; dsdesc.Format=DXGI_FORMAT_D24_UNORM_S8_UINT; dsdesc.SampleDesc.Count=1; dsdesc.SampleDesc.Quality=0; dsdesc.Usage=D3D11_USAGE_DEFAULT; dsdesc.BindFlags=D3D11_BIND_DEPTH_STENCIL; dsdesc.CpuAccessFlags=0; dsdesc.MiscFlags=0; ID3D11Texture2D *depthStencil; DXASS( _d3dDevice->CreateTexture2D( &dsdesc,0,&depthStencil ) ); DXASS( _d3dDevice->CreateDepthStencilView( depthStencil,0,&_depthStencilView ) ); depthStencil->Release(); */ D3D11_VIEWPORT viewport={ 0,0,width,height,0,1 }; _d3dContext->RSSetViewports( 1,&viewport ); }
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(); }
bool Direct3D12Backend::initialize(const BackendParameters& params) { HRESULT hr; parameters = params; if (!initializeDirect3D12()) { logger.error(LOG_GRAPHICS, "Direct3D12Backend::initialize: Could not load Direct3D12 dynamic library"); return false; } IDXGIFactory4* factory; hr = _CreateDXGIFactory1(IID_PPV_ARGS(&factory)); if (FAILED(hr)) { logger.error(LOG_GRAPHICS, "Direct3D12Backend::initialize: CreateDXGIFactory1 failed (0x%X)", hr); return false; } #if defined(NUCLEUS_BUILD_DEBUG) debug.enable(); #endif hr = _D3D12CreateDevice(nullptr, D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&device)); if (FAILED(hr)) { logger.warning(LOG_GRAPHICS, "Direct3D12Backend::initialize: Creating WARP device"); factory->EnumWarpAdapter(IID_PPV_ARGS(&adapter)); hr = _D3D12CreateDevice(adapter, D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&device)); if (FAILED(hr)) { logger.error(LOG_GRAPHICS, "Direct3D12Backend::initialize: D3D12CreateDevice failed (0x%X)", hr); return false; } } #if defined(NUCLEUS_BUILD_DEBUG) debug.initialize(device); #endif // Create main command queue D3D12_COMMAND_QUEUE_DESC queueDesc = {}; queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE; queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT; hr = device->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(&queue)); if (FAILED(hr)) { logger.error(LOG_GRAPHICS, "Direct3D12Backend::initialize: Could not create main command queue (0x%X)", hr); return false; } // Create swap chain IDXGISwapChain1* tempSwapChain; DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {}; swapChainDesc.Width = params.width; swapChainDesc.Height = params.height; swapChainDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; swapChainDesc.Stereo = false; swapChainDesc.SampleDesc.Count = 1; swapChainDesc.SampleDesc.Quality = 0; swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; swapChainDesc.BufferCount = 2; swapChainDesc.Scaling = DXGI_SCALING_NONE; swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; swapChainDesc.AlphaMode = DXGI_ALPHA_MODE_IGNORE; swapChainDesc.Flags = 0; DXGI_SWAP_CHAIN_FULLSCREEN_DESC swapChainFullscreenDesc = {}; swapChainFullscreenDesc.RefreshRate.Numerator = 60; swapChainFullscreenDesc.RefreshRate.Denominator = 1; swapChainFullscreenDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; swapChainFullscreenDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; swapChainFullscreenDesc.Windowed = TRUE; #ifdef NUCLEUS_TARGET_UWP hr = factory->CreateSwapChainForCoreWindow(queue, params.window, &swapChainDesc, nullptr, &tempSwapChain); #else hr = factory->CreateSwapChainForHwnd(queue, params.hwnd, &swapChainDesc, &swapChainFullscreenDesc, nullptr, &tempSwapChain); #endif if (FAILED(hr)) { logger.error(LOG_GRAPHICS, "Direct3D12Backend::initialize: Could not create swap chain (0x%X)", hr); return false; } hr = tempSwapChain->QueryInterface(IID_PPV_ARGS(&swapChain)); if (FAILED(hr)) { logger.error(LOG_GRAPHICS, "Direct3D12Backend::initialize: Could not request a IDXGISwapChain3 swap chain (0x%X)", hr); return false; } // Get render target buffers from swap chain D3D12_DESCRIPTOR_HEAP_DESC swapChainRTVHeapDesc = {}; swapChainRTVHeapDesc.NumDescriptors = 2; swapChainRTVHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV; swapChainRTVHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE; device->CreateDescriptorHeap(&swapChainRTVHeapDesc, IID_PPV_ARGS(&swapChainRTVHeap)); Direct3D12ColorTarget swapChainColorTargets[2]; D3D12_CPU_DESCRIPTOR_HANDLE swapChainRTVHeapStart = swapChainRTVHeap->GetCPUDescriptorHandleForHeapStart(); unsigned int rtvDescriptorSize = device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV); for (UINT i = 0; i < swapChainRTVHeapDesc.NumDescriptors; i++) { swapChainColorTargets[i].handle.ptr = swapChainRTVHeapStart.ptr + (i * rtvDescriptorSize); swapChain->GetBuffer(i, IID_PPV_ARGS(&swapChainRenderBuffer[i])); device->CreateRenderTargetView(swapChainRenderBuffer[i], NULL, swapChainColorTargets[i].handle); } if (swapChain->GetCurrentBackBufferIndex() == 0) { screenBackTarget = new Direct3D12ColorTarget(swapChainColorTargets[0]); screenFrontTarget = new Direct3D12ColorTarget(swapChainColorTargets[1]); screenBackBuffer = new Direct3D12Texture(swapChainRenderBuffer[0]); screenFrontBuffer = new Direct3D12Texture(swapChainRenderBuffer[1]); } else { screenBackTarget = new Direct3D12ColorTarget(swapChainColorTargets[1]); screenFrontTarget = new Direct3D12ColorTarget(swapChainColorTargets[0]); screenBackBuffer = new Direct3D12Texture(swapChainRenderBuffer[1]); screenFrontBuffer = new Direct3D12Texture(swapChainRenderBuffer[0]); } return true; }