Torque3D Documentation / _generateds / gfxD3D11Target.cpp

gfxD3D11Target.cpp

Engine/source/gfx/D3D11/gfxD3D11Target.cpp

More...

Detailed Description

  1
  2//-----------------------------------------------------------------------------
  3// Copyright (c) 2015 GarageGames, LLC
  4//
  5// Permission is hereby granted, free of charge, to any person obtaining a copy
  6// of this software and associated documentation files (the "Software"), to
  7// deal in the Software without restriction, including without limitation the
  8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  9// sell copies of the Software, and to permit persons to whom the Software is
 10// furnished to do so, subject to the following conditions:
 11//
 12// The above copyright notice and this permission notice shall be included in
 13// all copies or substantial portions of the Software.
 14//
 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 21// IN THE SOFTWARE.
 22//-----------------------------------------------------------------------------
 23
 24#include "platform/platform.h"
 25#include "gfx/D3D11/gfxD3D11Target.h"
 26#include "gfx/D3D11/gfxD3D11Cubemap.h"
 27#include "gfx/D3D11/gfxD3D11EnumTranslate.h"
 28#include "gfx/gfxDebugEvent.h"
 29#include "gfx/gfxStringEnumTranslate.h"
 30#include "windowManager/win32/win32Window.h"
 31
 32GFXD3D11TextureTarget::GFXD3D11TextureTarget(bool genMips) 
 33   :  mTargetSize( Point2I::Zero ),
 34      mTargetFormat( GFXFormatR8G8B8A8 )
 35{
 36   for(S32 i=0; i<MaxRenderSlotId; i++)
 37   {
 38      mTargets[i] = NULL;
 39      mResolveTargets[i] = NULL;
 40      mTargetViews[i] = NULL;
 41      mTargetSRViews[i] = NULL;
 42   }
 43
 44   mGenMips = genMips;
 45}
 46
 47GFXD3D11TextureTarget::~GFXD3D11TextureTarget()
 48{
 49   // Release anything we might be holding.
 50   for(S32 i=0; i<MaxRenderSlotId; i++)
 51   {
 52      mResolveTargets[i] = NULL;
 53      SAFE_RELEASE(mTargetViews[i]);
 54      SAFE_RELEASE(mTargets[i]);
 55      SAFE_RELEASE(mTargetSRViews[i]);      
 56   }
 57
 58   zombify();
 59}
 60
 61void GFXD3D11TextureTarget::attachTexture( RenderSlot slot, GFXTextureObject *tex, U32 mipLevel/*=0*/, U32 zOffset /*= 0*/ )
 62{
 63   GFXDEBUGEVENT_SCOPE( GFXPCD3D11TextureTarget_attachTexture, ColorI::RED );
 64
 65   AssertFatal(slot < MaxRenderSlotId, "GFXD3D11TextureTarget::attachTexture - out of range slot.");
 66
 67   // TODO:  The way this is implemented... you can attach a texture 
 68   // object multiple times and it will release and reset it.
 69   //
 70   // We should rework this to detect when no change has occured
 71   // and skip out early.
 72
 73   // Mark state as dirty so device can know to update.
 74   invalidateState();
 75
 76   // Release what we had, it's definitely going to change.
 77   SAFE_RELEASE(mTargetViews[slot]);
 78   SAFE_RELEASE(mTargets[slot]);
 79   SAFE_RELEASE(mTargetSRViews[slot]);
 80   
 81   mResolveTargets[slot] = NULL;
 82
 83   if(slot == Color0)
 84   {
 85      mTargetSize = Point2I::Zero;
 86      mTargetFormat = GFXFormatR8G8B8A8;
 87   }
 88
 89   // Are we clearing?
 90   if(!tex)
 91   {
 92      // Yup - just exit, it'll stay NULL.      
 93      return;
 94   }
 95
 96   // TODO: Mip map generation currently only supported on dynamic cubemaps
 97   mTargetSRViews[slot] = NULL;
 98
 99   // Take care of default targets
100   if( tex == GFXTextureTarget::sDefaultDepthStencil )
101   {
102      mTargets[slot] = D3D11->mDeviceDepthStencil;
103      mTargetViews[slot] = D3D11->mDeviceDepthStencilView;
104      mTargets[slot]->AddRef();
105      mTargetViews[slot]->AddRef();
106   }
107   else
108   {
109      // Cast the texture object to D3D...
110      AssertFatal(static_cast<GFXD3D11TextureObject*>(tex), "GFXD3D11TextureTarget::attachTexture - invalid texture object.");
111
112      GFXD3D11TextureObject *d3dto = static_cast<GFXD3D11TextureObject*>(tex);
113
114      // Grab the surface level.
115      if( slot == DepthStencil )
116      {       
117         mTargets[slot] = d3dto->getSurface();
118         if ( mTargets[slot] )
119            mTargets[slot]->AddRef();
120
121         mTargetViews[slot] = d3dto->getDSView();
122         if( mTargetViews[slot])
123            mTargetViews[slot]->AddRef();         
124
125      }
126      else
127      {         
128         // getSurface will almost always return NULL. It will only return non-NULL
129         // if the surface that it needs to render to is different than the mip level
130         // in the actual texture. This will happen with MSAA.
131         if( d3dto->getSurface() == NULL )
132         {
133            
134            mTargets[slot] = d3dto->get2DTex();
135            mTargets[slot]->AddRef();
136            mTargetViews[slot] = d3dto->getRTView();
137            mTargetViews[slot]->AddRef();         
138         } 
139         else 
140         {
141            mTargets[slot] = d3dto->getSurface();
142            mTargets[slot]->AddRef();
143            mTargetViews[slot]->AddRef();
144            // Only assign resolve target if d3dto has a surface to give us.
145            //
146            // That usually means there is an MSAA target involved, which is why
147            // the resolve is needed to get the data out of the target.
148            mResolveTargets[slot] = d3dto;
149
150            if ( tex && slot == Color0 )
151            {
152               mTargetSize.set( tex->getSize().x, tex->getSize().y );
153               mTargetFormat = tex->getFormat();
154            }
155         }           
156      }
157
158      // Update surface size
159      if(slot == Color0)
160      {
161         ID3D11Texture2D *surface = mTargets[Color0];
162         if ( surface )
163         {
164            D3D11_TEXTURE2D_DESC sd;
165            surface->GetDesc(&sd);
166            mTargetSize = Point2I(sd.Width, sd.Height);
167
168            S32 format = sd.Format;
169
170            if (format == DXGI_FORMAT_R8G8B8A8_TYPELESS || format == DXGI_FORMAT_B8G8R8A8_TYPELESS)
171            {
172               mTargetFormat = GFXFormatR8G8B8A8;
173               return;
174            }
175
176            GFXREVERSE_LOOKUP( GFXD3D11TextureFormat, GFXFormat, format );
177            mTargetFormat = (GFXFormat)format;
178         }
179      }
180   }
181
182}
183
184
185void GFXD3D11TextureTarget::attachTexture( RenderSlot slot, GFXCubemap *tex, U32 face, U32 mipLevel/*=0*/ )
186{
187   GFXDEBUGEVENT_SCOPE( GFXPCD3D11TextureTarget_attachTexture_Cubemap, ColorI::RED );
188
189   AssertFatal(slot < MaxRenderSlotId, "GFXD3D11TextureTarget::attachTexture - out of range slot.");
190
191   // Mark state as dirty so device can know to update.
192   invalidateState();
193
194   // Release what we had, it's definitely going to change.
195   SAFE_RELEASE(mTargetViews[slot]);
196   SAFE_RELEASE(mTargets[slot]);
197   SAFE_RELEASE(mTargetSRViews[slot]);
198
199   mResolveTargets[slot] = NULL;
200
201   // Cast the texture object to D3D...
202   AssertFatal(!tex || static_cast<GFXD3D11Cubemap*>(tex), "GFXD3DTextureTarget::attachTexture - invalid cubemap object.");
203
204   if(slot == Color0)
205   {
206      mTargetSize = Point2I::Zero;
207      mTargetFormat = GFXFormatR8G8B8A8;
208   }
209
210   // Are we clearing?
211   if(!tex)
212   {
213      // Yup - just exit, it'll stay NULL.      
214      return;
215   }
216
217   GFXD3D11Cubemap *cube = static_cast<GFXD3D11Cubemap*>(tex);
218
219   mTargets[slot] = cube->get2DTex();
220   mTargets[slot]->AddRef();
221   mTargetViews[slot] = cube->getRTView(face, mipLevel);
222   mTargetViews[slot]->AddRef();
223   mTargetSRViews[slot] = cube->getSRView();
224   mTargetSRViews[slot]->AddRef();
225   
226   // Update surface size
227   if(slot == Color0)
228   {
229      ID3D11Texture2D *surface = mTargets[Color0];
230      if ( surface )
231      {
232         D3D11_TEXTURE2D_DESC sd;
233         surface->GetDesc(&sd);
234         mTargetSize = Point2I(sd.Width, sd.Height);
235
236         S32 format = sd.Format;
237         GFXREVERSE_LOOKUP( GFXD3D11TextureFormat, GFXFormat, format );
238         mTargetFormat = (GFXFormat)format;
239      }
240   }
241
242}
243
244void GFXD3D11TextureTarget::activate()
245{
246   GFXDEBUGEVENT_SCOPE( GFXPCD3D11TextureTarget_activate, ColorI::RED );
247
248   AssertFatal( mTargets[GFXTextureTarget::Color0], "GFXD3D11TextureTarget::activate() - You can never have a NULL primary render target!" );
249  
250   // Clear the state indicator.
251   stateApplied();
252   
253   // Now set all the new surfaces into the appropriate slots.
254   ID3D11RenderTargetView* rtViews[MaxRenderSlotId] = { NULL, NULL, NULL, NULL, NULL, NULL };
255
256   ID3D11DepthStencilView* dsView = (ID3D11DepthStencilView*)(mTargetViews[GFXTextureTarget::DepthStencil]);
257   for (U32 i = 0; i < 6; i++)
258   {
259      rtViews[i] = (ID3D11RenderTargetView*)mTargetViews[GFXTextureTarget::Color0 + i];
260   }
261
262   D3D11DEVICECONTEXT->OMSetRenderTargets(MaxRenderSlotId, rtViews, dsView);
263
264}
265
266void GFXD3D11TextureTarget::deactivate()
267{
268   if (!mGenMips)
269      return;
270
271   //re-gen mip maps
272   for (U32 i = 0; i < 6; i++)
273   {
274      ID3D11ShaderResourceView* pSRView = mTargetSRViews[GFXTextureTarget::Color0 + i];
275      if (pSRView)
276         D3D11DEVICECONTEXT->GenerateMips(pSRView);
277   }
278   
279}
280
281void GFXD3D11TextureTarget::resolve()
282{
283   GFXDEBUGEVENT_SCOPE( GFXPCD3D11TextureTarget_resolve, ColorI::RED );
284
285   for (U32 i = 0; i < MaxRenderSlotId; i++)
286   {
287      // We use existance @ mResolveTargets as a flag that we need to copy
288      // data from the rendertarget into the texture.
289      if (mResolveTargets[i])
290      {
291         D3D11_TEXTURE2D_DESC desc;
292         mTargets[i]->GetDesc(&desc);
293         D3D11DEVICECONTEXT->CopySubresourceRegion(mResolveTargets[i]->get2DTex(), 0, 0, 0, 0, mTargets[i], 0, NULL);
294      }
295   }
296}
297
298void GFXD3D11TextureTarget::resolveTo( GFXTextureObject *tex )
299{
300   GFXDEBUGEVENT_SCOPE( GFXPCD3D11TextureTarget_resolveTo, ColorI::RED );
301
302   if ( mTargets[Color0] == NULL )
303      return;
304
305   D3D11_TEXTURE2D_DESC desc;
306   mTargets[Color0]->GetDesc(&desc);
307   D3D11DEVICECONTEXT->CopySubresourceRegion(((GFXD3D11TextureObject*)(tex))->get2DTex(), 0, 0, 0, 0, mTargets[Color0], 0, NULL);
308      
309}
310
311void GFXD3D11TextureTarget::zombify()
312{
313   for(U32 i = 0; i < MaxRenderSlotId; i++)
314      attachTexture(RenderSlot(i), NULL);
315}
316
317void GFXD3D11TextureTarget::resurrect()
318{
319}
320
321GFXD3D11WindowTarget::GFXD3D11WindowTarget()
322{
323   mWindow = NULL;
324   mBackBuffer = NULL;
325   mDepthStencilView = NULL;
326   mDepthStencil = NULL;
327   mBackBufferView = NULL;
328   mSwapChain = NULL;
329   dMemset(&mPresentationParams, 0, sizeof(mPresentationParams));
330   mSecondaryWindow = false;
331}
332
333GFXD3D11WindowTarget::~GFXD3D11WindowTarget()
334{
335   SAFE_RELEASE(mDepthStencilView)
336      SAFE_RELEASE(mDepthStencil);
337   SAFE_RELEASE(mBackBufferView);
338   SAFE_RELEASE(mBackBuffer);
339   SAFE_RELEASE(mSwapChain);
340}
341
342void GFXD3D11WindowTarget::initPresentationParams()
343{
344   // Get some video mode related info.
345   const GFXVideoMode& vm = mWindow->getVideoMode();
346   HWND hwnd = (HWND)mWindow->getSystemWindow(PlatformWindow::WindowSystem_Windows);
347
348   // Do some validation...
349   if (vm.fullScreen && mSecondaryWindow)
350   {
351      AssertFatal(false, "GFXD3D11WindowTarget::initPresentationParams - Cannot go fullscreen with secondary window!");
352   }
353
354   mPresentationParams = D3D11->setupPresentParams(vm, hwnd);
355}
356
357const Point2I GFXD3D11WindowTarget::getSize()
358{
359   return mWindow->getVideoMode().resolution; 
360}
361
362GFXFormat GFXD3D11WindowTarget::getFormat()
363{ 
364   S32 format = mPresentationParams.BufferDesc.Format;
365   GFXREVERSE_LOOKUP( GFXD3D11TextureFormat, GFXFormat, format );
366   return (GFXFormat)format;
367}
368
369bool GFXD3D11WindowTarget::present()
370{
371   HRESULT hr = mSwapChain->Present(!D3D11->smDisableVSync, 0);
372   if (hr == DXGI_ERROR_DEVICE_REMOVED)
373   {
374      HRESULT result = D3D11->getDevice()->GetDeviceRemovedReason();
375      if (result == DXGI_ERROR_DEVICE_HUNG)
376         AssertFatal(false,"DXGI_ERROR_DEVICE_HUNG");
377      else if (result == DXGI_ERROR_DEVICE_REMOVED)
378         AssertFatal(false, "DXGI_ERROR_DEVICE_REMOVED");
379      else if (result == DXGI_ERROR_DEVICE_RESET)
380         AssertFatal(false, "DXGI_ERROR_DEVICE_RESET");
381      else if (result == DXGI_ERROR_DRIVER_INTERNAL_ERROR)
382         AssertFatal(false, "DXGI_ERROR_DRIVER_INTERNAL_ERROR");
383      else if (result == DXGI_ERROR_INVALID_CALL)
384         AssertFatal(false, "DXGI_ERROR_INVALID_CALL");
385   }
386
387   return (hr == S_OK);
388}
389
390void GFXD3D11WindowTarget::createSwapChain()
391{
392   //create dxgi factory & swapchain
393   IDXGIFactory1* DXGIFactory;
394   HRESULT hr = CreateDXGIFactory1(__uuidof(IDXGIFactory1), reinterpret_cast<void**>(&DXGIFactory));
395   if (FAILED(hr))
396      AssertFatal(false, "GFXD3D11WindowTarget::createSwapChain - couldn't create dxgi factory.");
397
398   hr = DXGIFactory->CreateSwapChain(D3D11DEVICE, &mPresentationParams, &mSwapChain);
399
400   if (FAILED(hr))
401      AssertFatal(false, "GFXD3D11WindowTarget::createSwapChain - couldn't create swap chain.");
402
403   SAFE_RELEASE(DXGIFactory);
404}
405
406void GFXD3D11WindowTarget::createBuffersAndViews()
407{
408   //release old if they exist
409   SAFE_RELEASE(mDepthStencilView);
410   SAFE_RELEASE(mDepthStencil);
411   SAFE_RELEASE(mBackBufferView);
412   SAFE_RELEASE(mBackBuffer);
413
414   //grab video mode
415   const GFXVideoMode& vm = mWindow->getVideoMode();
416   //create depth/stencil
417   D3D11_TEXTURE2D_DESC desc;
418   desc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
419   desc.CPUAccessFlags = 0;
420   desc.Format = GFXD3D11TextureFormat[GFXFormatD24S8];
421   desc.MipLevels = 1;
422   desc.ArraySize = 1;
423   desc.Usage = D3D11_USAGE_DEFAULT;
424   desc.Width = vm.resolution.x;
425   desc.Height = vm.resolution.y;
426   desc.SampleDesc.Count = 1;
427   desc.SampleDesc.Quality = 0;
428   desc.MiscFlags = 0;
429
430   HRESULT hr = D3D11DEVICE->CreateTexture2D(&desc, NULL, &mDepthStencil);
431   if (FAILED(hr))
432      AssertFatal(false, "GFXD3D11WindowTarget::createBuffersAndViews - couldn't create device's depth-stencil surface.");
433
434   D3D11_DEPTH_STENCIL_VIEW_DESC depthDesc;
435   depthDesc.Format = GFXD3D11TextureFormat[GFXFormatD24S8];
436   depthDesc.Flags = 0;
437   depthDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
438   depthDesc.Texture2D.MipSlice = 0;
439
440   hr = D3D11DEVICE->CreateDepthStencilView(mDepthStencil, &depthDesc, &mDepthStencilView);
441   if (FAILED(hr))
442      AssertFatal(false, "GFXD3D11WindowTarget::createBuffersAndViews - couldn't create depth stencil view");
443
444   setBackBuffer();
445
446   //create back buffer view
447   D3D11_RENDER_TARGET_VIEW_DESC RTDesc;
448   RTDesc.Format = GFXD3D11TextureFormat[GFXFormatR8G8B8A8_SRGB];
449   RTDesc.Texture2D.MipSlice = 0;
450   RTDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
451
452   hr = D3D11DEVICE->CreateRenderTargetView(mBackBuffer, &RTDesc, &mBackBufferView);
453
454   if (FAILED(hr))
455      AssertFatal(false, "GFXD3D11WindowTarget::createBuffersAndViews - couldn't create back buffer target view");
456
457   //debug names
458#ifdef TORQUE_DEBUG
459   if (!mSecondaryWindow)
460   {
461      String backBufferName = "MainBackBuffer";
462      String depthSteniclName = "MainDepthStencil";
463      String backBuffViewName = "MainBackBuffView";
464      String depthStencViewName = "MainDepthView";
465      mBackBuffer->SetPrivateData(WKPDID_D3DDebugObjectName, backBufferName.size(), backBufferName.c_str());
466      mDepthStencil->SetPrivateData(WKPDID_D3DDebugObjectName, depthSteniclName.size(), depthSteniclName.c_str());
467      mDepthStencilView->SetPrivateData(WKPDID_D3DDebugObjectName, depthStencViewName.size(), depthStencViewName.c_str());
468      mBackBufferView->SetPrivateData(WKPDID_D3DDebugObjectName, backBuffViewName.size(), backBuffViewName.c_str());
469   }
470#endif
471}
472
473void GFXD3D11WindowTarget::resetMode()
474{
475   HRESULT hr;
476   if (mSwapChain)
477   {
478      // The current video settings.
479      DXGI_SWAP_CHAIN_DESC desc;
480      hr = mSwapChain->GetDesc(&desc);
481      if (FAILED(hr))
482         AssertFatal(false, "GFXD3D11WindowTarget::resetMode - failed to get swap chain description!");
483
484      bool fullscreen = !desc.Windowed;
485      Point2I backbufferSize(desc.BufferDesc.Width, desc.BufferDesc.Height);
486
487      // The settings we are now applying.
488      const GFXVideoMode& vm = mWindow->getVideoMode();
489
490      // Early out if none of the settings which require a device reset
491      // have changed.      
492      if (backbufferSize == vm.resolution &&
493         fullscreen == vm.fullScreen)
494         return;
495   }
496
497   //release old buffers and views
498   SAFE_RELEASE(mDepthStencilView)
499      SAFE_RELEASE(mDepthStencil);
500   SAFE_RELEASE(mBackBufferView);
501   SAFE_RELEASE(mBackBuffer);
502
503   if (!mSecondaryWindow)
504      D3D11->beginReset();
505
506   mWindow->setSuppressReset(true);
507
508   // Setup our presentation params.
509   initPresentationParams();
510
511   if (!mPresentationParams.Windowed)
512   {
513      mPresentationParams.BufferDesc.RefreshRate.Numerator = 0;
514      mPresentationParams.BufferDesc.RefreshRate.Denominator = 0;
515      hr = mSwapChain->ResizeTarget(&mPresentationParams.BufferDesc);
516
517      if (FAILED(hr))
518         AssertFatal(false, "GFXD3D11WindowTarget::resetMode - failed to resize target!");
519
520   }
521
522   hr = mSwapChain->ResizeBuffers(mPresentationParams.BufferCount, mPresentationParams.BufferDesc.Width, mPresentationParams.BufferDesc.Height,
523      mPresentationParams.BufferDesc.Format, mPresentationParams.Windowed ? 0 : DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH);
524
525   if (FAILED(hr))
526      AssertFatal(false, "GFXD3D11WindowTarget::resetMode - failed to resize back buffer!");
527
528   hr = mSwapChain->SetFullscreenState(!mPresentationParams.Windowed, NULL);
529
530   if (FAILED(hr))
531      AssertFatal(false, "GFXD3D11WindowTarget::resetMode - failed to change screen states!");
532
533   // Update our size, too.
534   mSize = Point2I(mPresentationParams.BufferDesc.Width, mPresentationParams.BufferDesc.Height);
535
536   mWindow->setSuppressReset(false);
537
538   //re-create buffers and views
539   createBuffersAndViews();
540
541   if (!mSecondaryWindow)
542      D3D11->endReset(this);
543}
544
545void GFXD3D11WindowTarget::zombify()
546{
547   SAFE_RELEASE(mBackBuffer);
548}
549
550void GFXD3D11WindowTarget::resurrect()
551{
552   setBackBuffer();
553}
554
555void GFXD3D11WindowTarget::setBackBuffer()
556{
557   if (!mBackBuffer)
558      mSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)& mBackBuffer);
559}
560
561void GFXD3D11WindowTarget::activate()
562{
563   GFXDEBUGEVENT_SCOPE(GFXPCD3D11WindowTarget_activate, ColorI::RED);
564
565   //clear ther rendertargets first
566   ID3D11RenderTargetView* rtViews[8] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
567
568   D3D11DEVICECONTEXT->OMSetRenderTargets(8, rtViews, NULL);
569   D3D11DEVICECONTEXT->OMSetRenderTargets(1, &mBackBufferView, mDepthStencilView);
570
571   DXGI_SWAP_CHAIN_DESC pp;
572   mSwapChain->GetDesc(&pp);
573
574   // Update our video mode here, too.
575   GFXVideoMode vm;
576   vm = mWindow->getVideoMode();
577   vm.resolution.x = pp.BufferDesc.Width;
578   vm.resolution.y = pp.BufferDesc.Height;
579   vm.fullScreen = !pp.Windowed;
580   mSize = vm.resolution;
581}
582
583void GFXD3D11WindowTarget::resolveTo(GFXTextureObject *tex)
584{
585   GFXDEBUGEVENT_SCOPE(GFXPCD3D11WindowTarget_resolveTo, ColorI::RED);
586
587   D3D11_TEXTURE2D_DESC desc;
588   ID3D11Texture2D* surf = ((GFXD3D11TextureObject*)(tex))->get2DTex();
589   surf->GetDesc(&desc);
590   D3D11DEVICECONTEXT->ResolveSubresource(surf, 0, mBackBuffer, 0, desc.Format);
591}
592
593IDXGISwapChain* GFXD3D11WindowTarget::getSwapChain()
594{
595   mSwapChain->AddRef();
596   return mSwapChain;
597}
598
599ID3D11Texture2D* GFXD3D11WindowTarget::getBackBuffer()
600{
601   mBackBuffer->AddRef();
602   return mBackBuffer;
603}
604
605ID3D11Texture2D* GFXD3D11WindowTarget::getDepthStencil()
606{
607   mDepthStencil->AddRef();
608   return mDepthStencil;
609}
610
611ID3D11RenderTargetView* GFXD3D11WindowTarget::getBackBufferView()
612{
613   mBackBufferView->AddRef();
614   return mBackBufferView;
615}
616
617ID3D11DepthStencilView* GFXD3D11WindowTarget::getDepthStencilView()
618{
619   mDepthStencilView->AddRef();
620   return mDepthStencilView;
621}
622