diff --git a/Engine/source/gfx/D3D11/gfxD3D11Device.cpp b/Engine/source/gfx/D3D11/gfxD3D11Device.cpp index a71e9c932..352523f36 100644 --- a/Engine/source/gfx/D3D11/gfxD3D11Device.cpp +++ b/Engine/source/gfx/D3D11/gfxD3D11Device.cpp @@ -261,73 +261,59 @@ void GFXD3D11Device::enumerateVideoModes() SAFE_RELEASE(DXGIFactory); } -IDXGISwapChain* GFXD3D11Device::getSwapChain() -{ - return mSwapChain; -} - void GFXD3D11Device::init(const GFXVideoMode &mode, PlatformWindow *window) { AssertFatal(window, "GFXD3D11Device::init - must specify a window!"); - HWND winHwnd = (HWND)window->getSystemWindow( PlatformWindow::WindowSystem_Windows ); - UINT createDeviceFlags = D3D11_CREATE_DEVICE_SINGLETHREADED | D3D11_CREATE_DEVICE_BGRA_SUPPORT; #ifdef TORQUE_DEBUG createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG; mDebugLayers = true; #endif - DXGI_SWAP_CHAIN_DESC d3dpp = setupPresentParams(mode, winHwnd); - D3D_FEATURE_LEVEL deviceFeature; D3D_DRIVER_TYPE driverType = D3D_DRIVER_TYPE_HARDWARE;// use D3D_DRIVER_TYPE_REFERENCE for reference device - // create a device, device context and swap chain using the information in the d3dpp struct - HRESULT hres = D3D11CreateDeviceAndSwapChain(NULL, - driverType, - NULL, - createDeviceFlags, - NULL, - 0, - D3D11_SDK_VERSION, - &d3dpp, - &mSwapChain, - &mD3DDevice, - &deviceFeature, - &mD3DDeviceContext); + // create a device & device context + HRESULT hres = D3D11CreateDevice(NULL, + driverType, + NULL, + createDeviceFlags, + NULL, + 0, + D3D11_SDK_VERSION, + &mD3DDevice, + &deviceFeature, + &mD3DDeviceContext); if(FAILED(hres)) { #ifdef TORQUE_DEBUG - //try again without debug device layer enabled - createDeviceFlags &= ~D3D11_CREATE_DEVICE_DEBUG; - HRESULT hres = D3D11CreateDeviceAndSwapChain(NULL, driverType,NULL,createDeviceFlags,NULL, 0, - D3D11_SDK_VERSION, - &d3dpp, - &mSwapChain, - &mD3DDevice, - &deviceFeature, - &mD3DDeviceContext); - //if we failed again than we definitely have a problem - if (FAILED(hres)) - AssertFatal(false, "GFXD3D11Device::init - D3D11CreateDeviceAndSwapChain failed!"); + //try again without debug device layer enabled + createDeviceFlags &= ~D3D11_CREATE_DEVICE_DEBUG; + hres = D3D11CreateDevice(NULL, + driverType, + NULL, + createDeviceFlags, + NULL, + 0, + D3D11_SDK_VERSION, + &mD3DDevice, + &deviceFeature, + &mD3DDeviceContext); + //if we failed again than we definitely have a problem + if (FAILED(hres)) + AssertFatal(false, "GFXD3D11Device::init - D3D11CreateDeviceAndSwapChain failed!"); - Con::warnf("GFXD3D11Device::init - Debug layers not detected!"); - mDebugLayers = false; + Con::warnf("GFXD3D11Device::init - Debug layers not detected!"); + mDebugLayers = false; #else - AssertFatal(false, "GFXD3D11Device::init - D3D11CreateDeviceAndSwapChain failed!"); + AssertFatal(false, "GFXD3D11Device::init - D3D11CreateDeviceAndSwapChain failed!"); #endif } - //set the fullscreen state here if we need to - if(mode.fullScreen) - { - hres = mSwapChain->SetFullscreenState(TRUE, NULL); - if(FAILED(hres)) - { - AssertFatal(false, "GFXD3D11Device::init- Failed to set fullscreen state!"); - } - } +#ifdef TORQUE_DEBUG + _suppressDebugMessages(); +#endif mTextureManager = new GFXD3D11TextureManager(); @@ -355,68 +341,6 @@ void GFXD3D11Device::init(const GFXVideoMode &mode, PlatformWindow *window) mCardProfiler = new GFXD3D11CardProfiler(); mCardProfiler->init(); - D3D11_TEXTURE2D_DESC desc; - desc.BindFlags = D3D11_BIND_DEPTH_STENCIL; - desc.CPUAccessFlags = 0; - desc.Format = GFXD3D11TextureFormat[GFXFormatD24S8]; - desc.MipLevels = 1; - desc.ArraySize = 1; - desc.Usage = D3D11_USAGE_DEFAULT; - desc.Width = mode.resolution.x; - desc.Height = mode.resolution.y; - desc.SampleDesc.Count =1; - desc.SampleDesc.Quality =0; - desc.MiscFlags = 0; - - HRESULT hr = mD3DDevice->CreateTexture2D(&desc, NULL, &mDeviceDepthStencil); - if(FAILED(hr)) - { - AssertFatal(false, "GFXD3D11Device::init - couldn't create device's depth-stencil surface."); - } - - D3D11_DEPTH_STENCIL_VIEW_DESC depthDesc; - depthDesc.Format = GFXD3D11TextureFormat[GFXFormatD24S8]; - depthDesc.Flags =0 ; - depthDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; - depthDesc.Texture2D.MipSlice = 0; - - hr = mD3DDevice->CreateDepthStencilView(mDeviceDepthStencil, &depthDesc, &mDeviceDepthStencilView); - - if(FAILED(hr)) - { - AssertFatal(false, "GFXD3D11Device::init - couldn't create depth stencil view"); - } - - hr = mSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&mDeviceBackbuffer); - if(FAILED(hr)) - AssertFatal(false, "GFXD3D11Device::init - coudln't retrieve backbuffer ref"); - - //create back buffer view - D3D11_RENDER_TARGET_VIEW_DESC RTDesc; - - RTDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; - RTDesc.Texture2D.MipSlice = 0; - RTDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; - - hr = mD3DDevice->CreateRenderTargetView(mDeviceBackbuffer, &RTDesc, &mDeviceBackBufferView); - - if(FAILED(hr)) - AssertFatal(false, "GFXD3D11Device::init - couldn't create back buffer target view"); - -#ifdef TORQUE_DEBUG - String backBufferName = "MainBackBuffer"; - String depthSteniclName = "MainDepthStencil"; - String backBuffViewName = "MainBackBuffView"; - String depthStencViewName = "MainDepthView"; - mDeviceBackbuffer->SetPrivateData(WKPDID_D3DDebugObjectName, backBufferName.size(), backBufferName.c_str()); - mDeviceDepthStencil->SetPrivateData(WKPDID_D3DDebugObjectName, depthSteniclName.size(), depthSteniclName.c_str()); - mDeviceDepthStencilView->SetPrivateData(WKPDID_D3DDebugObjectName, depthStencViewName.size(), depthStencViewName.c_str()); - mDeviceBackBufferView->SetPrivateData(WKPDID_D3DDebugObjectName, backBuffViewName.size(), backBuffViewName.c_str()); - - _suppressDebugMessages(); - -#endif - gScreenShot = new ScreenShotD3D11; mInitialized = true; @@ -466,14 +390,35 @@ GFXWindowTarget * GFXD3D11Device::allocWindowTarget(PlatformWindow *window) { AssertFatal(window,"GFXD3D11Device::allocWindowTarget - no window provided!"); - // Allocate the device. - init(window->getVideoMode(), window); - // Set up a new window target... GFXD3D11WindowTarget *gdwt = new GFXD3D11WindowTarget(); gdwt->mWindow = window; gdwt->mSize = window->getClientExtent(); - gdwt->initPresentationParams(); + + if (!mInitialized) + { + gdwt->mSecondaryWindow = false; + // Allocate the device. + init(window->getVideoMode(), window); + gdwt->initPresentationParams(); + gdwt->createSwapChain(); + gdwt->createBuffersAndViews(); + + mSwapChain = gdwt->getSwapChain(); + mDeviceBackbuffer = gdwt->getBackBuffer(); + mDeviceDepthStencil = gdwt->getDepthStencil(); + mDeviceBackBufferView = gdwt->getBackBufferView(); + mDeviceDepthStencilView = gdwt->getDepthStencilView(); + + } + else //additional window/s + { + gdwt->mSecondaryWindow = true; + gdwt->initPresentationParams(); + gdwt->createSwapChain(); + gdwt->createBuffersAndViews(); + } + gdwt->registerResourceWithDevice(this); return gdwt; @@ -487,13 +432,15 @@ GFXTextureTarget* GFXD3D11Device::allocRenderToTextureTarget() return targ; } -void GFXD3D11Device::reset(DXGI_SWAP_CHAIN_DESC &d3dpp) +void GFXD3D11Device::beginReset() { if (!mD3DDevice) return; mInitialized = false; + releaseDefaultPoolResources(); + // Clean up some commonly dangling state. This helps prevents issues with // items that are destroyed by the texture manager callbacks and recreated // later, but still left bound. @@ -504,117 +451,26 @@ void GFXD3D11Device::reset(DXGI_SWAP_CHAIN_DESC &d3dpp) mD3DDeviceContext->ClearState(); - DXGI_MODE_DESC displayModes; - displayModes.Format = d3dpp.BufferDesc.Format; - displayModes.Height = d3dpp.BufferDesc.Height; - displayModes.Width = d3dpp.BufferDesc.Width; - displayModes.RefreshRate = d3dpp.BufferDesc.RefreshRate; - displayModes.Scaling = d3dpp.BufferDesc.Scaling; - displayModes.ScanlineOrdering = d3dpp.BufferDesc.ScanlineOrdering; - - HRESULT hr; - if (!d3dpp.Windowed) - { - hr = mSwapChain->ResizeTarget(&displayModes); - - if (FAILED(hr)) - { - AssertFatal(false, "D3D11Device::reset - failed to resize target!"); - } - } - - // First release all the stuff we allocated from D3DPOOL_DEFAULT - releaseDefaultPoolResources(); - - //release the backbuffer, depthstencil, and their views - SAFE_RELEASE(mDeviceBackBufferView); - SAFE_RELEASE(mDeviceBackbuffer); + //release old buffers and views SAFE_RELEASE(mDeviceDepthStencilView); + SAFE_RELEASE(mDeviceBackBufferView); SAFE_RELEASE(mDeviceDepthStencil); + SAFE_RELEASE(mDeviceBackbuffer); +} - hr = mSwapChain->ResizeBuffers(d3dpp.BufferCount, d3dpp.BufferDesc.Width, d3dpp.BufferDesc.Height, d3dpp.BufferDesc.Format, d3dpp.Windowed ? 0 : DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH); - - if (FAILED(hr)) - { - AssertFatal(false, "D3D11Device::reset - failed to resize back buffer!"); - } - - //recreate backbuffer view. depth stencil view and texture - D3D11_TEXTURE2D_DESC desc; - desc.BindFlags = D3D11_BIND_DEPTH_STENCIL; - desc.CPUAccessFlags = 0; - desc.Format = GFXD3D11TextureFormat[GFXFormatD24S8]; - desc.MipLevels = 1; - desc.ArraySize = 1; - desc.Usage = D3D11_USAGE_DEFAULT; - desc.Width = d3dpp.BufferDesc.Width; - desc.Height = d3dpp.BufferDesc.Height; - desc.SampleDesc.Count = 1; - desc.SampleDesc.Quality = 0; - desc.MiscFlags = 0; - - hr = mD3DDevice->CreateTexture2D(&desc, NULL, &mDeviceDepthStencil); - if (FAILED(hr)) - { - AssertFatal(false, "GFXD3D11Device::reset - couldn't create device's depth-stencil surface."); - } - - D3D11_DEPTH_STENCIL_VIEW_DESC depthDesc; - depthDesc.Format = GFXD3D11TextureFormat[GFXFormatD24S8]; - depthDesc.Flags = 0; - depthDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; - depthDesc.Texture2D.MipSlice = 0; - - hr = mD3DDevice->CreateDepthStencilView(mDeviceDepthStencil, &depthDesc, &mDeviceDepthStencilView); - - if (FAILED(hr)) - { - AssertFatal(false, "GFXD3D11Device::reset - couldn't create depth stencil view"); - } - - hr = mSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&mDeviceBackbuffer); - if (FAILED(hr)) - AssertFatal(false, "GFXD3D11Device::reset - coudln't retrieve backbuffer ref"); - - //create back buffer view - D3D11_RENDER_TARGET_VIEW_DESC RTDesc; - - RTDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; - RTDesc.Texture2D.MipSlice = 0; - RTDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; - - hr = mD3DDevice->CreateRenderTargetView(mDeviceBackbuffer, &RTDesc, &mDeviceBackBufferView); - - if (FAILED(hr)) - AssertFatal(false, "GFXD3D11Device::reset - couldn't create back buffer target view"); +void GFXD3D11Device::endReset(GFXD3D11WindowTarget *windowTarget) +{ + //grab new references + mDeviceBackbuffer = windowTarget->getBackBuffer(); + mDeviceDepthStencil = windowTarget->getDepthStencil(); + mDeviceBackBufferView = windowTarget->getBackBufferView(); + mDeviceDepthStencilView = windowTarget->getDepthStencilView(); mD3DDeviceContext->OMSetRenderTargets(1, &mDeviceBackBufferView, mDeviceDepthStencilView); - hr = mSwapChain->SetFullscreenState(!d3dpp.Windowed, NULL); - - if (FAILED(hr)) - { - AssertFatal(false, "D3D11Device::reset - failed to change screen states!"); - } - - //Microsoft recommend this, see DXGI documentation - if (!d3dpp.Windowed) - { - displayModes.RefreshRate.Numerator = 0; - displayModes.RefreshRate.Denominator = 0; - hr = mSwapChain->ResizeTarget(&displayModes); - - if (FAILED(hr)) - { - AssertFatal(false, "D3D11Device::reset - failed to resize target!"); - } - } - - mInitialized = true; - - // Now re aquire all the resources we trashed earlier + // Now reacquire all the resources we trashed earlier reacquireDefaultPoolResources(); - + mInitialized = true; // Mark everything dirty and flush to card, for sanity. updateStates(true); } diff --git a/Engine/source/gfx/D3D11/gfxD3D11Device.h b/Engine/source/gfx/D3D11/gfxD3D11Device.h index 8640c8b68..726dce42f 100644 --- a/Engine/source/gfx/D3D11/gfxD3D11Device.h +++ b/Engine/source/gfx/D3D11/gfxD3D11Device.h @@ -146,7 +146,6 @@ protected: virtual GFXD3D11VertexBuffer* findVBPool( const GFXVertexFormat *vertexFormat, U32 numVertsNeeded ); virtual GFXD3D11VertexBuffer* createVBPool( const GFXVertexFormat *vertexFormat, U32 vertSize ); - IDXGISwapChain* getSwapChain(); // State overrides // { @@ -281,7 +280,8 @@ public: ID3D11Device* getDevice(){ return mD3DDevice; } /// Reset - void reset( DXGI_SWAP_CHAIN_DESC &d3dpp ); + void beginReset(); + void endReset(GFXD3D11WindowTarget *windowTarget); virtual void setupGenericShaders( GenericShaderType type = GSColor ); diff --git a/Engine/source/gfx/D3D11/gfxD3D11Target.cpp b/Engine/source/gfx/D3D11/gfxD3D11Target.cpp index 2260ff841..33c5d9ef2 100644 --- a/Engine/source/gfx/D3D11/gfxD3D11Target.cpp +++ b/Engine/source/gfx/D3D11/gfxD3D11Target.cpp @@ -314,21 +314,34 @@ void GFXD3D11TextureTarget::resurrect() GFXD3D11WindowTarget::GFXD3D11WindowTarget() { - mWindow = NULL; - mBackbuffer = NULL; + mWindow = NULL; + mBackBuffer = NULL; + mDepthStencilView = NULL; + mDepthStencil = NULL; + mBackBufferView = NULL; + mSecondaryWindow = false; } GFXD3D11WindowTarget::~GFXD3D11WindowTarget() { - SAFE_RELEASE(mBackbuffer); + SAFE_RELEASE(mDepthStencilView) + SAFE_RELEASE(mDepthStencil); + SAFE_RELEASE(mBackBufferView); + SAFE_RELEASE(mBackBuffer); + SAFE_RELEASE(mSwapChain); } void GFXD3D11WindowTarget::initPresentationParams() { // Get some video mode related info. - GFXVideoMode vm = mWindow->getVideoMode(); - Win32Window* win = static_cast(mWindow); - HWND hwnd = win->getHWND(); + const GFXVideoMode &vm = mWindow->getVideoMode(); + HWND hwnd = (HWND)mWindow->getSystemWindow(PlatformWindow::WindowSystem_Windows); + + // Do some validation... + if (vm.fullScreen && mSecondaryWindow) + { + AssertFatal(false, "GFXD3D11WindowTarget::initPresentationParams - Cannot go fullscreen with secondary window!"); + } mPresentationParams = D3D11->setupPresentParams(vm, hwnd); } @@ -347,40 +360,178 @@ GFXFormat GFXD3D11WindowTarget::getFormat() bool GFXD3D11WindowTarget::present() { - return (D3D11->getSwapChain()->Present(!D3D11->smDisableVSync, 0) == S_OK); + return (mSwapChain->Present(!D3D11->smDisableVSync, 0) == S_OK); } -void GFXD3D11WindowTarget::setImplicitSwapChain() +void GFXD3D11WindowTarget::createSwapChain() { - if (!mBackbuffer) - D3D11->mSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&mBackbuffer); + //create dxgi factory & swapchain + IDXGIFactory1* DXGIFactory; + HRESULT hr = CreateDXGIFactory1(__uuidof(IDXGIFactory1), reinterpret_cast(&DXGIFactory)); + if (FAILED(hr)) + AssertFatal(false, "GFXD3D11WindowTarget::createSwapChain - couldn't create dxgi factory."); + + hr = DXGIFactory->CreateSwapChain(D3D11DEVICE, &mPresentationParams, &mSwapChain); + + if (FAILED(hr)) + AssertFatal(false, "GFXD3D11WindowTarget::createSwapChain - couldn't create swap chain."); + + SAFE_RELEASE(DXGIFactory); +} + +void GFXD3D11WindowTarget::createBuffersAndViews() +{ + //release old if they exist + SAFE_RELEASE(mDepthStencilView); + SAFE_RELEASE(mDepthStencil); + SAFE_RELEASE(mBackBufferView); + SAFE_RELEASE(mBackBuffer); + + //grab video mode + const GFXVideoMode &vm = mWindow->getVideoMode(); + //create depth/stencil + D3D11_TEXTURE2D_DESC desc; + desc.BindFlags = D3D11_BIND_DEPTH_STENCIL; + desc.CPUAccessFlags = 0; + desc.Format = GFXD3D11TextureFormat[GFXFormatD24S8]; + desc.MipLevels = 1; + desc.ArraySize = 1; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.Width = vm.resolution.x; + desc.Height = vm.resolution.y; + desc.SampleDesc.Count = 1; + desc.SampleDesc.Quality = 0; + desc.MiscFlags = 0; + + HRESULT hr = D3D11DEVICE->CreateTexture2D(&desc, NULL, &mDepthStencil); + if (FAILED(hr)) + AssertFatal(false, "GFXD3D11WindowTarget::createBuffersAndViews - couldn't create device's depth-stencil surface."); + + D3D11_DEPTH_STENCIL_VIEW_DESC depthDesc; + depthDesc.Format = GFXD3D11TextureFormat[GFXFormatD24S8]; + depthDesc.Flags = 0; + depthDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; + depthDesc.Texture2D.MipSlice = 0; + + hr = D3D11DEVICE->CreateDepthStencilView(mDepthStencil, &depthDesc, &mDepthStencilView); + if (FAILED(hr)) + AssertFatal(false, "GFXD3D11WindowTarget::createBuffersAndViews - couldn't create depth stencil view"); + + setBackBuffer(); + + //create back buffer view + D3D11_RENDER_TARGET_VIEW_DESC RTDesc; + RTDesc.Format = GFXD3D11TextureFormat[GFXFormatR8G8B8A8]; + RTDesc.Texture2D.MipSlice = 0; + RTDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; + + hr = D3D11DEVICE->CreateRenderTargetView(mBackBuffer, &RTDesc, &mBackBufferView); + + if (FAILED(hr)) + AssertFatal(false, "GFXD3D11WindowTarget::createBuffersAndViews - couldn't create back buffer target view"); + + //debug names +#ifdef TORQUE_DEBUG + if (!mSecondaryWindow) + { + String backBufferName = "MainBackBuffer"; + String depthSteniclName = "MainDepthStencil"; + String backBuffViewName = "MainBackBuffView"; + String depthStencViewName = "MainDepthView"; + mBackBuffer->SetPrivateData(WKPDID_D3DDebugObjectName, backBufferName.size(), backBufferName.c_str()); + mDepthStencil->SetPrivateData(WKPDID_D3DDebugObjectName, depthSteniclName.size(), depthSteniclName.c_str()); + mDepthStencilView->SetPrivateData(WKPDID_D3DDebugObjectName, depthStencViewName.size(), depthStencViewName.c_str()); + mBackBufferView->SetPrivateData(WKPDID_D3DDebugObjectName, backBuffViewName.size(), backBuffViewName.c_str()); + } +#endif } void GFXD3D11WindowTarget::resetMode() { + HRESULT hr; + if (mSwapChain) + { + // The current video settings. + DXGI_SWAP_CHAIN_DESC desc; + hr = mSwapChain->GetDesc(&desc); + if (FAILED(hr)) + AssertFatal(false, "GFXD3D11WindowTarget::resetMode - failed to get swap chain description!"); + + bool fullscreen = !desc.Windowed; + Point2I backbufferSize(desc.BufferDesc.Width, desc.BufferDesc.Height); + + // The settings we are now applying. + const GFXVideoMode &vm = mWindow->getVideoMode(); + + // Early out if none of the settings which require a device reset + // have changed. + if (backbufferSize == vm.resolution && + fullscreen == vm.fullScreen) + return; + } + + //release old buffers and views + SAFE_RELEASE(mDepthStencilView) + SAFE_RELEASE(mDepthStencil); + SAFE_RELEASE(mBackBufferView); + SAFE_RELEASE(mBackBuffer); + + if(!mSecondaryWindow) + D3D11->beginReset(); + mWindow->setSuppressReset(true); // Setup our presentation params. initPresentationParams(); - // Otherwise, we have to reset the device, if we're the implicit swapchain. - D3D11->reset(mPresentationParams); + if (!mPresentationParams.Windowed) + { + mPresentationParams.BufferDesc.RefreshRate.Numerator = 0; + mPresentationParams.BufferDesc.RefreshRate.Denominator = 0; + hr = mSwapChain->ResizeTarget(&mPresentationParams.BufferDesc); + + if (FAILED(hr)) + AssertFatal(false, "GFXD3D11WindowTarget::resetMode - failed to resize target!"); + + } + + hr = mSwapChain->ResizeBuffers(mPresentationParams.BufferCount, mPresentationParams.BufferDesc.Width, mPresentationParams.BufferDesc.Height, + mPresentationParams.BufferDesc.Format, mPresentationParams.Windowed ? 0 : DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH); + + if (FAILED(hr)) + AssertFatal(false, "GFXD3D11WindowTarget::resetMode - failed to resize back buffer!"); + + hr = mSwapChain->SetFullscreenState(!mPresentationParams.Windowed, NULL); + + if (FAILED(hr)) + AssertFatal(false, "GFXD3D11WindowTarget::resetMode - failed to change screen states!"); // Update our size, too. mSize = Point2I(mPresentationParams.BufferDesc.Width, mPresentationParams.BufferDesc.Height); mWindow->setSuppressReset(false); - GFX->beginReset(); + + //re-create buffers and views + createBuffersAndViews(); + + if (!mSecondaryWindow) + D3D11->endReset(this); } void GFXD3D11WindowTarget::zombify() { - SAFE_RELEASE(mBackbuffer); + SAFE_RELEASE(mBackBuffer); } void GFXD3D11WindowTarget::resurrect() { - setImplicitSwapChain(); + setBackBuffer(); +} + +void GFXD3D11WindowTarget::setBackBuffer() +{ + if (!mBackBuffer) + mSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&mBackBuffer); } void GFXD3D11WindowTarget::activate() @@ -391,10 +542,10 @@ void GFXD3D11WindowTarget::activate() ID3D11RenderTargetView* rtViews[8] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; D3D11DEVICECONTEXT->OMSetRenderTargets(8, rtViews, NULL); - D3D11DEVICECONTEXT->OMSetRenderTargets(1, &D3D11->mDeviceBackBufferView, D3D11->mDeviceDepthStencilView); + D3D11DEVICECONTEXT->OMSetRenderTargets(1, &mBackBufferView, mDepthStencilView); DXGI_SWAP_CHAIN_DESC pp; - D3D11->mSwapChain->GetDesc(&pp); + mSwapChain->GetDesc(&pp); // Update our video mode here, too. GFXVideoMode vm; @@ -412,5 +563,35 @@ void GFXD3D11WindowTarget::resolveTo(GFXTextureObject *tex) D3D11_TEXTURE2D_DESC desc; ID3D11Texture2D* surf = ((GFXD3D11TextureObject*)(tex))->get2DTex(); surf->GetDesc(&desc); - D3D11DEVICECONTEXT->ResolveSubresource(surf, 0, D3D11->mDeviceBackbuffer, 0, desc.Format); + D3D11DEVICECONTEXT->ResolveSubresource(surf, 0, mBackBuffer, 0, desc.Format); +} + +IDXGISwapChain *GFXD3D11WindowTarget::getSwapChain() +{ + mSwapChain->AddRef(); + return mSwapChain; +} + +ID3D11Texture2D *GFXD3D11WindowTarget::getBackBuffer() +{ + mBackBuffer->AddRef(); + return mBackBuffer; +} + +ID3D11Texture2D *GFXD3D11WindowTarget::getDepthStencil() +{ + mDepthStencil->AddRef(); + return mDepthStencil; +} + +ID3D11RenderTargetView* GFXD3D11WindowTarget::getBackBufferView() +{ + mBackBufferView->AddRef(); + return mBackBufferView; +} + +ID3D11DepthStencilView* GFXD3D11WindowTarget::getDepthStencilView() +{ + mDepthStencilView->AddRef(); + return mDepthStencilView; } \ No newline at end of file diff --git a/Engine/source/gfx/D3D11/gfxD3D11Target.h b/Engine/source/gfx/D3D11/gfxD3D11Target.h index ff4b193d6..44233e0e2 100644 --- a/Engine/source/gfx/D3D11/gfxD3D11Target.h +++ b/Engine/source/gfx/D3D11/gfxD3D11Target.h @@ -76,17 +76,22 @@ class GFXD3D11WindowTarget : public GFXWindowTarget friend class GFXD3D11Device; /// Our backbuffer - ID3D11Texture2D *mBackbuffer; + ID3D11Texture2D *mBackBuffer; + ID3D11Texture2D *mDepthStencil; + ID3D11RenderTargetView* mBackBufferView; + ID3D11DepthStencilView* mDepthStencilView; + IDXGISwapChain *mSwapChain; /// Maximum size we can render to. Point2I mSize; - /// D3D presentation info. DXGI_SWAP_CHAIN_DESC mPresentationParams; - /// Internal interface that notifies us we need to reset our video mode. void resetMode(); + /// Is this a secondary window + bool mSecondaryWindow; + public: GFXD3D11WindowTarget(); @@ -97,7 +102,9 @@ public: virtual bool present(); void initPresentationParams(); - void setImplicitSwapChain(); + void createSwapChain(); + void createBuffersAndViews(); + void setBackBuffer(); virtual void activate(); @@ -105,6 +112,13 @@ public: void resurrect(); virtual void resolveTo( GFXTextureObject *tex ); + + // These are all reference counted and must be released by whomever uses the get* function + IDXGISwapChain *getSwapChain(); + ID3D11Texture2D *getBackBuffer(); + ID3D11Texture2D *getDepthStencil(); + ID3D11RenderTargetView* getBackBufferView(); + ID3D11DepthStencilView* getDepthStencilView(); }; #endif