mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-01-28 08:34:44 +00:00
Swapped the water's disableTrueReflections variable to be enableTrueReflections for simplicity and consistency(also fixed a persistent typo) Swapped disableVerticalSync to be enableVerticalSync for simplicity and consistency Swapped disableParallaxMapping to be enableParallaxMapping for simplicity and consistency Fix click detection on slider mode entries for guiGameSettingsCtrl so the click position correctly matches the percentage Fixed problem where postFX initialization would always exec default.postfxpreset.tscript, even if a level's got it's own preset, which can cause problems Fixed range field type behavior so that editing the values applies in real time, and also consistently applies between slider and text field
621 lines
19 KiB
C++
621 lines
19 KiB
C++
//-----------------------------------------------------------------------------
|
|
// Copyright (c) 2015 GarageGames, LLC
|
|
//
|
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
// of this software and associated documentation files (the "Software"), to
|
|
// deal in the Software without restriction, including without limitation the
|
|
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
|
// sell copies of the Software, and to permit persons to whom the Software is
|
|
// furnished to do so, subject to the following conditions:
|
|
//
|
|
// The above copyright notice and this permission notice shall be included in
|
|
// all copies or substantial portions of the Software.
|
|
//
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
|
// IN THE SOFTWARE.
|
|
//-----------------------------------------------------------------------------
|
|
|
|
#include "platform/platform.h"
|
|
#include "gfx/D3D11/gfxD3D11Target.h"
|
|
#include "gfx/D3D11/gfxD3D11Cubemap.h"
|
|
#include "gfx/D3D11/gfxD3D11EnumTranslate.h"
|
|
#include "gfx/gfxDebugEvent.h"
|
|
#include "gfx/gfxStringEnumTranslate.h"
|
|
#include "windowManager/win32/win32Window.h"
|
|
|
|
GFXD3D11TextureTarget::GFXD3D11TextureTarget(bool genMips)
|
|
: mTargetSize( Point2I::Zero ),
|
|
mTargetFormat( GFXFormatR8G8B8A8 )
|
|
{
|
|
for(S32 i=0; i<MaxRenderSlotId; i++)
|
|
{
|
|
mTargets[i] = NULL;
|
|
mResolveTargets[i] = NULL;
|
|
mTargetViews[i] = NULL;
|
|
mTargetSRViews[i] = NULL;
|
|
}
|
|
|
|
mGenMips = genMips;
|
|
}
|
|
|
|
GFXD3D11TextureTarget::~GFXD3D11TextureTarget()
|
|
{
|
|
// Release anything we might be holding.
|
|
for(S32 i=0; i<MaxRenderSlotId; i++)
|
|
{
|
|
mResolveTargets[i] = NULL;
|
|
SAFE_RELEASE(mTargetViews[i]);
|
|
SAFE_RELEASE(mTargets[i]);
|
|
SAFE_RELEASE(mTargetSRViews[i]);
|
|
}
|
|
|
|
zombify();
|
|
}
|
|
|
|
void GFXD3D11TextureTarget::attachTexture( RenderSlot slot, GFXTextureObject *tex, U32 mipLevel/*=0*/, U32 zOffset /*= 0*/ )
|
|
{
|
|
GFXDEBUGEVENT_SCOPE( GFXPCD3D11TextureTarget_attachTexture, ColorI::RED );
|
|
|
|
AssertFatal(slot < MaxRenderSlotId, "GFXD3D11TextureTarget::attachTexture - out of range slot.");
|
|
|
|
// TODO: The way this is implemented... you can attach a texture
|
|
// object multiple times and it will release and reset it.
|
|
//
|
|
// We should rework this to detect when no change has occured
|
|
// and skip out early.
|
|
|
|
// Mark state as dirty so device can know to update.
|
|
invalidateState();
|
|
|
|
// Release what we had, it's definitely going to change.
|
|
SAFE_RELEASE(mTargetViews[slot]);
|
|
SAFE_RELEASE(mTargets[slot]);
|
|
SAFE_RELEASE(mTargetSRViews[slot]);
|
|
|
|
mResolveTargets[slot] = NULL;
|
|
|
|
if(slot == Color0)
|
|
{
|
|
mTargetSize = Point2I::Zero;
|
|
mTargetFormat = GFXFormatR8G8B8A8;
|
|
}
|
|
|
|
// Are we clearing?
|
|
if(!tex)
|
|
{
|
|
// Yup - just exit, it'll stay NULL.
|
|
return;
|
|
}
|
|
|
|
// TODO: Mip map generation currently only supported on dynamic cubemaps
|
|
mTargetSRViews[slot] = NULL;
|
|
|
|
// Take care of default targets
|
|
if( tex == GFXTextureTarget::sDefaultDepthStencil )
|
|
{
|
|
mTargets[slot] = D3D11->mDeviceDepthStencil;
|
|
mTargetViews[slot] = D3D11->mDeviceDepthStencilView;
|
|
mTargets[slot]->AddRef();
|
|
mTargetViews[slot]->AddRef();
|
|
}
|
|
else
|
|
{
|
|
// Cast the texture object to D3D...
|
|
AssertFatal(static_cast<GFXD3D11TextureObject*>(tex), "GFXD3D11TextureTarget::attachTexture - invalid texture object.");
|
|
|
|
GFXD3D11TextureObject *d3dto = static_cast<GFXD3D11TextureObject*>(tex);
|
|
|
|
// Grab the surface level.
|
|
if( slot == DepthStencil )
|
|
{
|
|
mTargets[slot] = d3dto->getSurface();
|
|
if ( mTargets[slot] )
|
|
mTargets[slot]->AddRef();
|
|
|
|
mTargetViews[slot] = d3dto->getDSView();
|
|
if( mTargetViews[slot])
|
|
mTargetViews[slot]->AddRef();
|
|
|
|
}
|
|
else
|
|
{
|
|
// getSurface will almost always return NULL. It will only return non-NULL
|
|
// if the surface that it needs to render to is different than the mip level
|
|
// in the actual texture. This will happen with MSAA.
|
|
if( d3dto->getSurface() == NULL )
|
|
{
|
|
|
|
mTargets[slot] = d3dto->get2DTex();
|
|
mTargets[slot]->AddRef();
|
|
mTargetViews[slot] = d3dto->getRTView();
|
|
mTargetViews[slot]->AddRef();
|
|
}
|
|
else
|
|
{
|
|
mTargets[slot] = d3dto->getSurface();
|
|
mTargets[slot]->AddRef();
|
|
mTargetViews[slot]->AddRef();
|
|
// Only assign resolve target if d3dto has a surface to give us.
|
|
//
|
|
// That usually means there is an MSAA target involved, which is why
|
|
// the resolve is needed to get the data out of the target.
|
|
mResolveTargets[slot] = d3dto;
|
|
|
|
if ( tex && slot == Color0 )
|
|
{
|
|
mTargetSize.set( tex->getSize().x, tex->getSize().y );
|
|
mTargetFormat = tex->getFormat();
|
|
}
|
|
}
|
|
}
|
|
|
|
// Update surface size
|
|
if(slot == Color0)
|
|
{
|
|
ID3D11Texture2D *surface = mTargets[Color0];
|
|
if ( surface )
|
|
{
|
|
D3D11_TEXTURE2D_DESC sd;
|
|
surface->GetDesc(&sd);
|
|
mTargetSize = Point2I(sd.Width, sd.Height);
|
|
|
|
S32 format = sd.Format;
|
|
|
|
if (format == DXGI_FORMAT_R8G8B8A8_TYPELESS || format == DXGI_FORMAT_B8G8R8A8_TYPELESS)
|
|
{
|
|
mTargetFormat = GFXFormatR8G8B8A8;
|
|
return;
|
|
}
|
|
|
|
GFXREVERSE_LOOKUP( GFXD3D11TextureFormat, GFXFormat, format );
|
|
mTargetFormat = (GFXFormat)format;
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
void GFXD3D11TextureTarget::attachTexture( RenderSlot slot, GFXCubemap *tex, U32 face, U32 mipLevel/*=0*/ )
|
|
{
|
|
GFXDEBUGEVENT_SCOPE( GFXPCD3D11TextureTarget_attachTexture_Cubemap, ColorI::RED );
|
|
|
|
AssertFatal(slot < MaxRenderSlotId, "GFXD3D11TextureTarget::attachTexture - out of range slot.");
|
|
|
|
// Mark state as dirty so device can know to update.
|
|
invalidateState();
|
|
|
|
// Release what we had, it's definitely going to change.
|
|
SAFE_RELEASE(mTargetViews[slot]);
|
|
SAFE_RELEASE(mTargets[slot]);
|
|
SAFE_RELEASE(mTargetSRViews[slot]);
|
|
|
|
mResolveTargets[slot] = NULL;
|
|
|
|
// Cast the texture object to D3D...
|
|
AssertFatal(!tex || static_cast<GFXD3D11Cubemap*>(tex), "GFXD3DTextureTarget::attachTexture - invalid cubemap object.");
|
|
|
|
if(slot == Color0)
|
|
{
|
|
mTargetSize = Point2I::Zero;
|
|
mTargetFormat = GFXFormatR8G8B8A8;
|
|
}
|
|
|
|
// Are we clearing?
|
|
if(!tex)
|
|
{
|
|
// Yup - just exit, it'll stay NULL.
|
|
return;
|
|
}
|
|
|
|
GFXD3D11Cubemap *cube = static_cast<GFXD3D11Cubemap*>(tex);
|
|
|
|
mTargets[slot] = cube->get2DTex();
|
|
mTargets[slot]->AddRef();
|
|
mTargetViews[slot] = cube->getRTView(face, mipLevel);
|
|
mTargetViews[slot]->AddRef();
|
|
mTargetSRViews[slot] = cube->getSRView();
|
|
mTargetSRViews[slot]->AddRef();
|
|
|
|
// Update surface size
|
|
if(slot == Color0)
|
|
{
|
|
ID3D11Texture2D *surface = mTargets[Color0];
|
|
if ( surface )
|
|
{
|
|
D3D11_TEXTURE2D_DESC sd;
|
|
surface->GetDesc(&sd);
|
|
mTargetSize = Point2I(sd.Width, sd.Height);
|
|
|
|
S32 format = sd.Format;
|
|
GFXREVERSE_LOOKUP( GFXD3D11TextureFormat, GFXFormat, format );
|
|
mTargetFormat = (GFXFormat)format;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
void GFXD3D11TextureTarget::activate()
|
|
{
|
|
GFXDEBUGEVENT_SCOPE( GFXPCD3D11TextureTarget_activate, ColorI::RED );
|
|
|
|
AssertFatal( mTargets[GFXTextureTarget::Color0], "GFXD3D11TextureTarget::activate() - You can never have a NULL primary render target!" );
|
|
|
|
// Clear the state indicator.
|
|
stateApplied();
|
|
|
|
// Now set all the new surfaces into the appropriate slots.
|
|
ID3D11RenderTargetView* rtViews[MaxRenderSlotId] = { NULL, NULL, NULL, NULL, NULL, NULL };
|
|
|
|
ID3D11DepthStencilView* dsView = (ID3D11DepthStencilView*)(mTargetViews[GFXTextureTarget::DepthStencil]);
|
|
for (U32 i = 0; i < 6; i++)
|
|
{
|
|
rtViews[i] = (ID3D11RenderTargetView*)mTargetViews[GFXTextureTarget::Color0 + i];
|
|
}
|
|
|
|
D3D11DEVICECONTEXT->OMSetRenderTargets(MaxRenderSlotId, rtViews, dsView);
|
|
|
|
}
|
|
|
|
void GFXD3D11TextureTarget::deactivate()
|
|
{
|
|
if (!mGenMips)
|
|
return;
|
|
|
|
//re-gen mip maps
|
|
for (U32 i = 0; i < 6; i++)
|
|
{
|
|
ID3D11ShaderResourceView* pSRView = mTargetSRViews[GFXTextureTarget::Color0 + i];
|
|
if (pSRView)
|
|
D3D11DEVICECONTEXT->GenerateMips(pSRView);
|
|
}
|
|
|
|
}
|
|
|
|
void GFXD3D11TextureTarget::resolve()
|
|
{
|
|
GFXDEBUGEVENT_SCOPE( GFXPCD3D11TextureTarget_resolve, ColorI::RED );
|
|
|
|
for (U32 i = 0; i < MaxRenderSlotId; i++)
|
|
{
|
|
// We use existance @ mResolveTargets as a flag that we need to copy
|
|
// data from the rendertarget into the texture.
|
|
if (mResolveTargets[i])
|
|
{
|
|
D3D11_TEXTURE2D_DESC desc;
|
|
mTargets[i]->GetDesc(&desc);
|
|
D3D11DEVICECONTEXT->CopySubresourceRegion(mResolveTargets[i]->get2DTex(), 0, 0, 0, 0, mTargets[i], 0, NULL);
|
|
}
|
|
}
|
|
}
|
|
|
|
void GFXD3D11TextureTarget::resolveTo( GFXTextureObject *tex )
|
|
{
|
|
GFXDEBUGEVENT_SCOPE( GFXPCD3D11TextureTarget_resolveTo, ColorI::RED );
|
|
|
|
if ( mTargets[Color0] == NULL )
|
|
return;
|
|
|
|
D3D11_TEXTURE2D_DESC desc;
|
|
mTargets[Color0]->GetDesc(&desc);
|
|
D3D11DEVICECONTEXT->CopySubresourceRegion(((GFXD3D11TextureObject*)(tex))->get2DTex(), 0, 0, 0, 0, mTargets[Color0], 0, NULL);
|
|
|
|
}
|
|
|
|
void GFXD3D11TextureTarget::zombify()
|
|
{
|
|
for(U32 i = 0; i < MaxRenderSlotId; i++)
|
|
attachTexture(RenderSlot(i), NULL);
|
|
}
|
|
|
|
void GFXD3D11TextureTarget::resurrect()
|
|
{
|
|
}
|
|
|
|
GFXD3D11WindowTarget::GFXD3D11WindowTarget()
|
|
{
|
|
mWindow = NULL;
|
|
mBackBuffer = NULL;
|
|
mDepthStencilView = NULL;
|
|
mDepthStencil = NULL;
|
|
mBackBufferView = NULL;
|
|
mSwapChain = NULL;
|
|
dMemset(&mPresentationParams, 0, sizeof(mPresentationParams));
|
|
mSecondaryWindow = false;
|
|
}
|
|
|
|
GFXD3D11WindowTarget::~GFXD3D11WindowTarget()
|
|
{
|
|
SAFE_RELEASE(mDepthStencilView)
|
|
SAFE_RELEASE(mDepthStencil);
|
|
SAFE_RELEASE(mBackBufferView);
|
|
SAFE_RELEASE(mBackBuffer);
|
|
SAFE_RELEASE(mSwapChain);
|
|
}
|
|
|
|
void GFXD3D11WindowTarget::initPresentationParams()
|
|
{
|
|
// Get some video mode related info.
|
|
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);
|
|
}
|
|
|
|
const Point2I GFXD3D11WindowTarget::getSize()
|
|
{
|
|
return mWindow->getVideoMode().resolution;
|
|
}
|
|
|
|
GFXFormat GFXD3D11WindowTarget::getFormat()
|
|
{
|
|
S32 format = mPresentationParams.BufferDesc.Format;
|
|
GFXREVERSE_LOOKUP( GFXD3D11TextureFormat, GFXFormat, format );
|
|
return (GFXFormat)format;
|
|
}
|
|
|
|
bool GFXD3D11WindowTarget::present()
|
|
{
|
|
HRESULT hr = mSwapChain->Present(D3D11->smEnableVSync, 0);
|
|
if (hr == DXGI_ERROR_DEVICE_REMOVED)
|
|
{
|
|
HRESULT result = D3D11->getDevice()->GetDeviceRemovedReason();
|
|
if (result == DXGI_ERROR_DEVICE_HUNG)
|
|
AssertFatal(false,"DXGI_ERROR_DEVICE_HUNG");
|
|
else if (result == DXGI_ERROR_DEVICE_REMOVED)
|
|
AssertFatal(false, "DXGI_ERROR_DEVICE_REMOVED");
|
|
else if (result == DXGI_ERROR_DEVICE_RESET)
|
|
AssertFatal(false, "DXGI_ERROR_DEVICE_RESET");
|
|
else if (result == DXGI_ERROR_DRIVER_INTERNAL_ERROR)
|
|
AssertFatal(false, "DXGI_ERROR_DRIVER_INTERNAL_ERROR");
|
|
else if (result == DXGI_ERROR_INVALID_CALL)
|
|
AssertFatal(false, "DXGI_ERROR_INVALID_CALL");
|
|
}
|
|
|
|
return (hr == S_OK);
|
|
}
|
|
|
|
void GFXD3D11WindowTarget::createSwapChain()
|
|
{
|
|
//create dxgi factory & swapchain
|
|
IDXGIFactory1* DXGIFactory;
|
|
HRESULT hr = CreateDXGIFactory1(__uuidof(IDXGIFactory1), reinterpret_cast<void**>(&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_SRGB];
|
|
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();
|
|
|
|
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);
|
|
|
|
//re-create buffers and views
|
|
createBuffersAndViews();
|
|
|
|
if (!mSecondaryWindow)
|
|
D3D11->endReset(this);
|
|
}
|
|
|
|
void GFXD3D11WindowTarget::zombify()
|
|
{
|
|
SAFE_RELEASE(mBackBuffer);
|
|
}
|
|
|
|
void GFXD3D11WindowTarget::resurrect()
|
|
{
|
|
setBackBuffer();
|
|
}
|
|
|
|
void GFXD3D11WindowTarget::setBackBuffer()
|
|
{
|
|
if (!mBackBuffer)
|
|
mSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)& mBackBuffer);
|
|
}
|
|
|
|
void GFXD3D11WindowTarget::activate()
|
|
{
|
|
GFXDEBUGEVENT_SCOPE(GFXPCD3D11WindowTarget_activate, ColorI::RED);
|
|
|
|
//clear ther rendertargets first
|
|
ID3D11RenderTargetView* rtViews[8] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
|
|
|
|
D3D11DEVICECONTEXT->OMSetRenderTargets(8, rtViews, NULL);
|
|
D3D11DEVICECONTEXT->OMSetRenderTargets(1, &mBackBufferView, mDepthStencilView);
|
|
|
|
DXGI_SWAP_CHAIN_DESC pp;
|
|
mSwapChain->GetDesc(&pp);
|
|
|
|
// Update our video mode here, too.
|
|
GFXVideoMode vm;
|
|
vm = mWindow->getVideoMode();
|
|
vm.resolution.x = pp.BufferDesc.Width;
|
|
vm.resolution.y = pp.BufferDesc.Height;
|
|
vm.fullScreen = !pp.Windowed;
|
|
mSize = vm.resolution;
|
|
}
|
|
|
|
void GFXD3D11WindowTarget::resolveTo(GFXTextureObject *tex)
|
|
{
|
|
GFXDEBUGEVENT_SCOPE(GFXPCD3D11WindowTarget_resolveTo, ColorI::RED);
|
|
|
|
D3D11_TEXTURE2D_DESC desc;
|
|
ID3D11Texture2D* surf = ((GFXD3D11TextureObject*)(tex))->get2DTex();
|
|
surf->GetDesc(&desc);
|
|
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;
|
|
}
|