Torque3D Documentation / _generateds / gfxD3D11Device.cpp

gfxD3D11Device.cpp

Engine/source/gfx/D3D11/gfxD3D11Device.cpp

More...

Classes:

Public Functions

Parse command line arguments for window creation.

Detailed Description

Public Variables

GFXPCD3D11RegisterDevice pPCD3D11RegisterDevice 
ProcessRegisterCommandLine sgCommandLine (sgPCD3D11DeviceHandleCommandLine)

Public Functions

sgPCD3D11DeviceHandleCommandLine(S32 argc, const char ** argv)

Parse command line arguments for window creation.

   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 "console/console.h"
  25#include "core/stream/fileStream.h"
  26#include "core/strings/unicode.h"
  27#include "core/util/journal/process.h"
  28#include "gfx/D3D11/gfxD3D11Device.h"
  29#include "gfx/D3D11/gfxD3D11CardProfiler.h"
  30#include "gfx/D3D11/gfxD3D11VertexBuffer.h"
  31#include "gfx/D3D11/gfxD3D11EnumTranslate.h"
  32#include "gfx/D3D11/gfxD3D11QueryFence.h"
  33#include "gfx/D3D11/gfxD3D11OcclusionQuery.h"
  34#include "gfx/D3D11/gfxD3D11Shader.h"
  35#include "gfx/D3D11/gfxD3D11Target.h"
  36#include "platformWin32/platformWin32.h"
  37#include "windowManager/win32/win32Window.h"
  38#include "windowManager/platformWindow.h"
  39#include "gfx/D3D11/screenshotD3D11.h"
  40#include "materials/shaderData.h"
  41
  42#ifdef TORQUE_DEBUG
  43#include "d3d11sdklayers.h"
  44#endif
  45
  46#pragma comment(lib, "dxgi.lib")
  47#pragma comment(lib, "d3d11.lib")
  48
  49GFXAdapter::CreateDeviceInstanceDelegate GFXD3D11Device::mCreateDeviceInstance(GFXD3D11Device::createInstance);
  50
  51GFXDevice *GFXD3D11Device::createInstance(U32 adapterIndex)
  52{
  53   GFXD3D11Device* dev = new GFXD3D11Device(adapterIndex);
  54   return dev;
  55}
  56
  57GFXFormat GFXD3D11Device::selectSupportedFormat(GFXTextureProfile *profile, const Vector<GFXFormat> &formats, bool texture, bool mustblend, bool mustfilter)
  58{
  59   U32 features = 0;
  60   if(texture)
  61       features |= D3D11_FORMAT_SUPPORT_TEXTURE2D;
  62   if(mustblend)
  63       features |= D3D11_FORMAT_SUPPORT_BLENDABLE;
  64   if(mustfilter)
  65       features |= D3D11_FORMAT_SUPPORT_SHADER_SAMPLE;
  66   
  67   for(U32 i = 0; i < formats.size(); i++)
  68   {
  69      if(GFXD3D11TextureFormat[formats[i]] == DXGI_FORMAT_UNKNOWN)
  70         continue;
  71
  72      U32 supportFlag = 0;
  73      mD3DDevice->CheckFormatSupport(GFXD3D11TextureFormat[formats[i]],&supportFlag);
  74      if(supportFlag & features)
  75         return formats[i];
  76   }
  77   
  78   return GFXFormatR8G8B8A8;
  79}
  80
  81DXGI_SWAP_CHAIN_DESC GFXD3D11Device::setupPresentParams(const GFXVideoMode &mode, const HWND &hwnd)
  82{
  83   DXGI_SWAP_CHAIN_DESC d3dpp;
  84   ZeroMemory(&d3dpp, sizeof(d3dpp));
  85
  86   DXGI_SAMPLE_DESC sampleDesc;
  87   sampleDesc.Count = 1;
  88   sampleDesc.Quality = 0;
  89
  90   mMultisampleDesc = sampleDesc;
  91
  92   d3dpp.BufferCount = !smDisableVSync ? 2 : 1; // triple buffering when vsync is on.
  93   d3dpp.BufferDesc.Width = mode.resolution.x;
  94   d3dpp.BufferDesc.Height = mode.resolution.y;
  95   d3dpp.BufferDesc.Format = GFXD3D11TextureFormat[GFXFormatR8G8B8A8];
  96   d3dpp.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
  97   d3dpp.OutputWindow = hwnd;
  98   d3dpp.SampleDesc = sampleDesc;
  99   d3dpp.Windowed = !mode.fullScreen;
 100   d3dpp.BufferDesc.RefreshRate.Numerator = mode.refreshRate;
 101   d3dpp.BufferDesc.RefreshRate.Denominator = 1;
 102   d3dpp.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
 103
 104   if (mode.fullScreen)
 105   {
 106      d3dpp.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
 107      d3dpp.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
 108      d3dpp.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
 109   }
 110
 111   return d3dpp;
 112}
 113
 114void GFXD3D11Device::enumerateAdapters(Vector<GFXAdapter*> &adapterList)
 115{
 116   IDXGIAdapter1* EnumAdapter;
 117   IDXGIFactory1* DXGIFactory;
 118
 119   CreateDXGIFactory1(__uuidof(IDXGIFactory1), reinterpret_cast<void**>(&DXGIFactory));
 120
 121   for(U32 adapterIndex = 0; DXGIFactory->EnumAdapters1(adapterIndex, &EnumAdapter) != DXGI_ERROR_NOT_FOUND; ++adapterIndex) 
 122   {
 123      GFXAdapter *toAdd = new GFXAdapter;
 124      toAdd->mType  = Direct3D11;
 125      toAdd->mIndex = adapterIndex;
 126      toAdd->mCreateDeviceInstanceDelegate = mCreateDeviceInstance;
 127
 128      toAdd->mShaderModel = 5.0f;
 129      DXGI_ADAPTER_DESC1 desc;
 130      EnumAdapter->GetDesc1(&desc);
 131
 132      // LUID identifies adapter for oculus rift
 133      dMemcpy(&toAdd->mLUID, &desc.AdapterLuid, sizeof(toAdd->mLUID));
 134
 135      size_t size=wcslen(desc.Description);
 136      char *str = new char[size+1];
 137
 138      wcstombs(str, desc.Description,size);
 139      str[size]='\0';
 140      String Description=str;
 141      SAFE_DELETE_ARRAY(str);
 142
 143      dStrncpy(toAdd->mName, Description.c_str(), GFXAdapter::MaxAdapterNameLen);
 144      dStrncat(toAdd->mName, " (D3D11)", GFXAdapter::MaxAdapterNameLen);
 145
 146      IDXGIOutput* pOutput = NULL; 
 147      HRESULT hr;
 148
 149      hr = EnumAdapter->EnumOutputs(adapterIndex, &pOutput);
 150
 151      if(hr == DXGI_ERROR_NOT_FOUND)
 152      {
 153         SAFE_RELEASE(EnumAdapter);
 154         break;
 155      }
 156
 157      if(FAILED(hr))
 158         AssertFatal(false, "GFXD3D11Device::enumerateAdapters -> EnumOutputs call failure");
 159
 160      UINT numModes = 0;
 161      DXGI_MODE_DESC* displayModes = NULL;
 162      DXGI_FORMAT format = DXGI_FORMAT_B8G8R8A8_UNORM;
 163
 164      // Get the number of elements
 165      hr = pOutput->GetDisplayModeList(format, 0, &numModes, NULL);
 166
 167      if(FAILED(hr))
 168         AssertFatal(false, "GFXD3D11Device::enumerateAdapters -> GetDisplayModeList call failure");
 169
 170      displayModes = new DXGI_MODE_DESC[numModes]; 
 171
 172      // Get the list
 173      hr = pOutput->GetDisplayModeList(format, 0, &numModes, displayModes);
 174
 175      if(FAILED(hr))
 176         AssertFatal(false, "GFXD3D11Device::enumerateAdapters -> GetDisplayModeList call failure");
 177
 178      for(U32 numMode = 0; numMode < numModes; ++numMode)
 179      {
 180         GFXVideoMode vmAdd;
 181
 182         vmAdd.fullScreen = true;
 183         vmAdd.bitDepth = 32;
 184         vmAdd.refreshRate = displayModes[numMode].RefreshRate.Numerator / displayModes[numMode].RefreshRate.Denominator;
 185         vmAdd.resolution.x = displayModes[numMode].Width;
 186         vmAdd.resolution.y = displayModes[numMode].Height;
 187         toAdd->mAvailableModes.push_back(vmAdd);
 188      }
 189
 190      delete[] displayModes;
 191      SAFE_RELEASE(pOutput);
 192      SAFE_RELEASE(EnumAdapter);
 193      adapterList.push_back(toAdd);
 194   }
 195
 196   SAFE_RELEASE(DXGIFactory);
 197}
 198
 199void GFXD3D11Device::enumerateVideoModes() 
 200{
 201   mVideoModes.clear();
 202
 203   IDXGIAdapter1* EnumAdapter;
 204   IDXGIFactory1* DXGIFactory;
 205   HRESULT hr;
 206
 207   hr = CreateDXGIFactory1(__uuidof(IDXGIFactory1), reinterpret_cast<void**>(&DXGIFactory));
 208
 209   if (FAILED(hr))
 210      AssertFatal(false, "GFXD3D11Device::enumerateVideoModes -> CreateDXGIFactory1 call failure");
 211
 212   for(U32 adapterIndex = 0; DXGIFactory->EnumAdapters1(adapterIndex, &EnumAdapter) != DXGI_ERROR_NOT_FOUND; ++adapterIndex) 
 213   {
 214      IDXGIOutput* pOutput = NULL;      
 215
 216      hr = EnumAdapter->EnumOutputs(adapterIndex, &pOutput);
 217
 218      if(hr == DXGI_ERROR_NOT_FOUND)
 219      {
 220         SAFE_RELEASE(EnumAdapter);
 221         break;
 222      }
 223
 224      if(FAILED(hr))
 225         AssertFatal(false, "GFXD3D11Device::enumerateVideoModes -> EnumOutputs call failure");
 226
 227      UINT numModes = 0;
 228      DXGI_MODE_DESC* displayModes = NULL;
 229      DXGI_FORMAT format = GFXD3D11TextureFormat[GFXFormatR8G8B8A8];
 230
 231      // Get the number of elements
 232      hr = pOutput->GetDisplayModeList(format, 0, &numModes, NULL);
 233
 234      if(FAILED(hr))
 235         AssertFatal(false, "GFXD3D11Device::enumerateVideoModes -> GetDisplayModeList call failure");
 236
 237      displayModes = new DXGI_MODE_DESC[numModes]; 
 238
 239      // Get the list
 240      hr = pOutput->GetDisplayModeList(format, 0, &numModes, displayModes);
 241
 242      if(FAILED(hr))
 243         AssertFatal(false, "GFXD3D11Device::enumerateVideoModes -> GetDisplayModeList call failure");
 244
 245      for(U32 numMode = 0; numMode < numModes; ++numMode)
 246      {
 247         GFXVideoMode toAdd;
 248
 249         toAdd.fullScreen = false;
 250         toAdd.bitDepth = 32;
 251         toAdd.refreshRate = displayModes[numMode].RefreshRate.Numerator / displayModes[numMode].RefreshRate.Denominator;
 252         toAdd.resolution.x = displayModes[numMode].Width;
 253         toAdd.resolution.y = displayModes[numMode].Height;
 254         mVideoModes.push_back(toAdd);
 255      }
 256
 257      delete[] displayModes;
 258      SAFE_RELEASE(pOutput);
 259      SAFE_RELEASE(EnumAdapter);
 260   }
 261
 262   SAFE_RELEASE(DXGIFactory);
 263}
 264
 265IDXGISwapChain* GFXD3D11Device::getSwapChain()
 266{
 267   return mSwapChain;
 268}
 269
 270void GFXD3D11Device::init(const GFXVideoMode &mode, PlatformWindow *window)
 271{
 272   AssertFatal(window, "GFXD3D11Device::init - must specify a window!");
 273
 274   HWND winHwnd = (HWND)window->getSystemWindow( PlatformWindow::WindowSystem_Windows );
 275
 276   UINT createDeviceFlags = D3D11_CREATE_DEVICE_SINGLETHREADED | D3D11_CREATE_DEVICE_BGRA_SUPPORT;
 277#ifdef TORQUE_DEBUG
 278   createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
 279   mDebugLayers = true;
 280#endif
 281
 282   DXGI_SWAP_CHAIN_DESC d3dpp = setupPresentParams(mode, winHwnd);
 283
 284   D3D_FEATURE_LEVEL deviceFeature;
 285   D3D_DRIVER_TYPE driverType = D3D_DRIVER_TYPE_HARDWARE;// use D3D_DRIVER_TYPE_REFERENCE for reference device
 286   // create a device, device context and swap chain using the information in the d3dpp struct
 287   HRESULT hres = D3D11CreateDeviceAndSwapChain(NULL,
 288                                 driverType,
 289                                 NULL,
 290                                 createDeviceFlags,
 291                                 NULL,
 292                                 0,
 293                                 D3D11_SDK_VERSION,
 294                                 &d3dpp,
 295                                 &mSwapChain,
 296                                 &mD3DDevice,
 297                                 &deviceFeature,
 298                                 &mD3DDeviceContext);
 299
 300   if(FAILED(hres))
 301   {
 302      #ifdef TORQUE_DEBUG
 303      //try again without debug device layer enabled
 304      createDeviceFlags &= ~D3D11_CREATE_DEVICE_DEBUG;
 305      HRESULT hres = D3D11CreateDeviceAndSwapChain(NULL, driverType,NULL,createDeviceFlags,NULL, 0,
 306         D3D11_SDK_VERSION,
 307         &d3dpp,
 308         &mSwapChain,
 309         &mD3DDevice,
 310         &deviceFeature,
 311         &mD3DDeviceContext);
 312      //if we failed again than we definitely have a problem
 313      if (FAILED(hres))
 314         AssertFatal(false, "GFXD3D11Device::init - D3D11CreateDeviceAndSwapChain failed!");
 315
 316      Con::warnf("GFXD3D11Device::init - Debug layers not detected!");
 317      mDebugLayers = false;
 318      #else
 319      AssertFatal(false, "GFXD3D11Device::init - D3D11CreateDeviceAndSwapChain failed!");
 320      #endif
 321   }
 322
 323   //set the fullscreen state here if we need to
 324   if(mode.fullScreen)
 325   {
 326      hres = mSwapChain->SetFullscreenState(TRUE, NULL);
 327      if(FAILED(hres))
 328      {
 329         AssertFatal(false, "GFXD3D11Device::init- Failed to set fullscreen state!");
 330      }
 331   }
 332
 333   mTextureManager = new GFXD3D11TextureManager();
 334
 335   // Now reacquire all the resources we trashed earlier
 336   reacquireDefaultPoolResources();
 337   //TODO implement feature levels?
 338   if (deviceFeature >= D3D_FEATURE_LEVEL_11_0)
 339      mPixVersion = 5.0f;
 340   else
 341      AssertFatal(false, "GFXD3D11Device::init - We don't support anything below feature level 11.");
 342
 343   D3D11_QUERY_DESC queryDesc;
 344   queryDesc.Query = D3D11_QUERY_OCCLUSION;
 345   queryDesc.MiscFlags = 0;
 346
 347   ID3D11Query *testQuery = NULL;
 348
 349   // detect occlusion query support
 350   if (SUCCEEDED(mD3DDevice->CreateQuery(&queryDesc, &testQuery))) mOcclusionQuerySupported = true;
 351
 352   SAFE_RELEASE(testQuery);
 353
 354   Con::printf("Hardware occlusion query detected: %s", mOcclusionQuerySupported ? "Yes" : "No");
 355   
 356   mCardProfiler = new GFXD3D11CardProfiler();
 357   mCardProfiler->init();
 358
 359   D3D11_TEXTURE2D_DESC desc;
 360   desc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
 361   desc.CPUAccessFlags = 0;
 362   desc.Format = GFXD3D11TextureFormat[GFXFormatD24S8];
 363   desc.MipLevels = 1;
 364   desc.ArraySize = 1;
 365   desc.Usage = D3D11_USAGE_DEFAULT;
 366   desc.Width = mode.resolution.x;
 367   desc.Height = mode.resolution.y;
 368   desc.SampleDesc.Count =1;
 369   desc.SampleDesc.Quality =0;
 370   desc.MiscFlags = 0;
 371
 372   HRESULT hr = mD3DDevice->CreateTexture2D(&desc, NULL, &mDeviceDepthStencil);
 373   if(FAILED(hr)) 
 374   {
 375      AssertFatal(false, "GFXD3D11Device::init - couldn't create device's depth-stencil surface.");
 376   }
 377
 378   D3D11_DEPTH_STENCIL_VIEW_DESC depthDesc;
 379   depthDesc.Format = GFXD3D11TextureFormat[GFXFormatD24S8];
 380   depthDesc.Flags =0 ;
 381   depthDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
 382   depthDesc.Texture2D.MipSlice = 0;
 383
 384   hr = mD3DDevice->CreateDepthStencilView(mDeviceDepthStencil, &depthDesc, &mDeviceDepthStencilView);
 385
 386   if(FAILED(hr))
 387   {
 388      AssertFatal(false, "GFXD3D11Device::init - couldn't create depth stencil view");
 389   }
 390
 391   hr = mSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&mDeviceBackbuffer);
 392   if(FAILED(hr))
 393     AssertFatal(false, "GFXD3D11Device::init - coudln't retrieve backbuffer ref");
 394
 395   //create back buffer view
 396   D3D11_RENDER_TARGET_VIEW_DESC RTDesc;
 397
 398   RTDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
 399   RTDesc.Texture2D.MipSlice = 0;
 400   RTDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
 401
 402   hr = mD3DDevice->CreateRenderTargetView(mDeviceBackbuffer, &RTDesc, &mDeviceBackBufferView);
 403
 404   if(FAILED(hr))
 405       AssertFatal(false, "GFXD3D11Device::init - couldn't create back buffer target view");
 406
 407#ifdef TORQUE_DEBUG
 408   String backBufferName = "MainBackBuffer";
 409   String depthSteniclName = "MainDepthStencil";
 410   String backBuffViewName = "MainBackBuffView";
 411   String depthStencViewName = "MainDepthView";
 412   mDeviceBackbuffer->SetPrivateData(WKPDID_D3DDebugObjectName, backBufferName.size(), backBufferName.c_str());
 413   mDeviceDepthStencil->SetPrivateData(WKPDID_D3DDebugObjectName, depthSteniclName.size(), depthSteniclName.c_str());
 414   mDeviceDepthStencilView->SetPrivateData(WKPDID_D3DDebugObjectName, depthStencViewName.size(), depthStencViewName.c_str());
 415   mDeviceBackBufferView->SetPrivateData(WKPDID_D3DDebugObjectName, backBuffViewName.size(), backBuffViewName.c_str());
 416
 417   _suppressDebugMessages();
 418
 419#endif
 420
 421   gScreenShot = new ScreenShotD3D11;
 422
 423   mInitialized = true;
 424   deviceInited();
 425}
 426
 427// Supress any debug layer messages we don't want to see
 428void GFXD3D11Device::_suppressDebugMessages()
 429{
 430   if (mDebugLayers)
 431   {
 432      ID3D11Debug *pDebug = NULL;
 433      if (SUCCEEDED(mD3DDevice->QueryInterface(__uuidof(ID3D11Debug), (void**)&pDebug)))
 434      {
 435         ID3D11InfoQueue *pInfoQueue = NULL;
 436         if (SUCCEEDED(pDebug->QueryInterface(__uuidof(ID3D11InfoQueue), (void**)&pInfoQueue)))
 437         {
 438            //Disable breaking on error or corruption, this can be handy when using VS graphics debugging
 439            pInfoQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_CORRUPTION, false);
 440            pInfoQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_ERROR, false);
 441
 442            D3D11_MESSAGE_ID hide[] =
 443            {
 444               //this is harmless and no need to spam the console
 445               D3D11_MESSAGE_ID_QUERY_BEGIN_ABANDONING_PREVIOUS_RESULTS
 446            };
 447
 448            D3D11_INFO_QUEUE_FILTER filter;
 449            memset(&filter, 0, sizeof(filter));
 450            filter.DenyList.NumIDs = _countof(hide);
 451            filter.DenyList.pIDList = hide;
 452            pInfoQueue->AddStorageFilterEntries(&filter);
 453            SAFE_RELEASE(pInfoQueue);
 454         }
 455         SAFE_RELEASE(pDebug);
 456      }
 457   }
 458}
 459
 460bool GFXD3D11Device::beginSceneInternal() 
 461{
 462   mCanCurrentlyRender = true;
 463   return mCanCurrentlyRender;  
 464}
 465
 466GFXWindowTarget * GFXD3D11Device::allocWindowTarget(PlatformWindow *window)
 467{
 468   AssertFatal(window,"GFXD3D11Device::allocWindowTarget - no window provided!");
 469
 470   // Allocate the device.
 471   init(window->getVideoMode(), window);
 472
 473   // Set up a new window target...
 474   GFXD3D11WindowTarget *gdwt = new GFXD3D11WindowTarget();
 475   gdwt->mWindow = window;
 476   gdwt->mSize = window->getClientExtent();
 477   gdwt->initPresentationParams();
 478   gdwt->registerResourceWithDevice(this);
 479
 480   return gdwt;
 481}
 482
 483GFXTextureTarget* GFXD3D11Device::allocRenderToTextureTarget()
 484{
 485   GFXD3D11TextureTarget *targ = new GFXD3D11TextureTarget();
 486   targ->registerResourceWithDevice(this);
 487
 488   return targ;
 489}
 490
 491void GFXD3D11Device::reset(DXGI_SWAP_CHAIN_DESC &d3dpp)
 492{
 493   if (!mD3DDevice)
 494      return;
 495
 496   mInitialized = false;
 497
 498   // Clean up some commonly dangling state. This helps prevents issues with
 499   // items that are destroyed by the texture manager callbacks and recreated
 500   // later, but still left bound.
 501   setVertexBuffer(NULL);
 502   setPrimitiveBuffer(NULL);
 503   for (S32 i = 0; i<getNumSamplers(); i++)
 504      setTexture(i, NULL);
 505
 506   mD3DDeviceContext->ClearState();
 507
 508   DXGI_MODE_DESC displayModes;
 509   displayModes.Format = d3dpp.BufferDesc.Format;
 510   displayModes.Height = d3dpp.BufferDesc.Height;
 511   displayModes.Width = d3dpp.BufferDesc.Width;
 512   displayModes.RefreshRate = d3dpp.BufferDesc.RefreshRate;
 513   displayModes.Scaling = d3dpp.BufferDesc.Scaling;
 514   displayModes.ScanlineOrdering = d3dpp.BufferDesc.ScanlineOrdering;
 515
 516   HRESULT hr;
 517   if (!d3dpp.Windowed)
 518   {
 519      hr = mSwapChain->ResizeTarget(&displayModes);
 520
 521      if (FAILED(hr))
 522      {
 523         AssertFatal(false, "D3D11Device::reset - failed to resize target!");
 524      }
 525   }
 526
 527   // First release all the stuff we allocated from D3DPOOL_DEFAULT
 528   releaseDefaultPoolResources();
 529
 530   //release the backbuffer, depthstencil, and their views
 531   SAFE_RELEASE(mDeviceBackBufferView);
 532   SAFE_RELEASE(mDeviceBackbuffer);
 533   SAFE_RELEASE(mDeviceDepthStencilView);
 534   SAFE_RELEASE(mDeviceDepthStencil);
 535
 536   hr = mSwapChain->ResizeBuffers(d3dpp.BufferCount, d3dpp.BufferDesc.Width, d3dpp.BufferDesc.Height, d3dpp.BufferDesc.Format, d3dpp.Windowed ? 0 : DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH);
 537
 538   if (FAILED(hr))
 539   {
 540      AssertFatal(false, "D3D11Device::reset - failed to resize back buffer!");
 541   }
 542
 543   //recreate backbuffer view. depth stencil view and texture
 544   D3D11_TEXTURE2D_DESC desc;
 545   desc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
 546   desc.CPUAccessFlags = 0;
 547   desc.Format = GFXD3D11TextureFormat[GFXFormatD24S8];
 548   desc.MipLevels = 1;
 549   desc.ArraySize = 1;
 550   desc.Usage = D3D11_USAGE_DEFAULT;
 551   desc.Width = d3dpp.BufferDesc.Width;
 552   desc.Height = d3dpp.BufferDesc.Height;
 553   desc.SampleDesc.Count = 1;
 554   desc.SampleDesc.Quality = 0;
 555   desc.MiscFlags = 0;
 556
 557   hr = mD3DDevice->CreateTexture2D(&desc, NULL, &mDeviceDepthStencil);
 558   if (FAILED(hr))
 559   {
 560      AssertFatal(false, "GFXD3D11Device::reset - couldn't create device's depth-stencil surface.");
 561   }
 562
 563   D3D11_DEPTH_STENCIL_VIEW_DESC depthDesc;
 564   depthDesc.Format = GFXD3D11TextureFormat[GFXFormatD24S8];
 565   depthDesc.Flags = 0;
 566   depthDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
 567   depthDesc.Texture2D.MipSlice = 0;
 568
 569   hr = mD3DDevice->CreateDepthStencilView(mDeviceDepthStencil, &depthDesc, &mDeviceDepthStencilView);
 570
 571   if (FAILED(hr))
 572   {
 573      AssertFatal(false, "GFXD3D11Device::reset - couldn't create depth stencil view");
 574   }
 575
 576   hr = mSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&mDeviceBackbuffer);
 577   if (FAILED(hr))
 578      AssertFatal(false, "GFXD3D11Device::reset - coudln't retrieve backbuffer ref");
 579
 580   //create back buffer view
 581   D3D11_RENDER_TARGET_VIEW_DESC RTDesc;
 582
 583   RTDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
 584   RTDesc.Texture2D.MipSlice = 0;
 585   RTDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
 586
 587   hr = mD3DDevice->CreateRenderTargetView(mDeviceBackbuffer, &RTDesc, &mDeviceBackBufferView);
 588
 589   if (FAILED(hr))
 590      AssertFatal(false, "GFXD3D11Device::reset - couldn't create back buffer target view");
 591
 592   mD3DDeviceContext->OMSetRenderTargets(1, &mDeviceBackBufferView, mDeviceDepthStencilView);
 593
 594   hr = mSwapChain->SetFullscreenState(!d3dpp.Windowed, NULL);
 595
 596   if (FAILED(hr))
 597   {
 598      AssertFatal(false, "D3D11Device::reset - failed to change screen states!");
 599   }
 600
 601   //Microsoft recommend this, see DXGI documentation
 602   if (!d3dpp.Windowed)
 603   {
 604      displayModes.RefreshRate.Numerator = 0;
 605      displayModes.RefreshRate.Denominator = 0;
 606      hr = mSwapChain->ResizeTarget(&displayModes);
 607
 608      if (FAILED(hr))
 609      {
 610         AssertFatal(false, "D3D11Device::reset - failed to resize target!");
 611      }
 612   }
 613
 614   mInitialized = true;
 615
 616   // Now re aquire all the resources we trashed earlier
 617   reacquireDefaultPoolResources();
 618
 619   // Mark everything dirty and flush to card, for sanity.
 620   updateStates(true);
 621}
 622
 623class GFXPCD3D11RegisterDevice
 624{
 625public:
 626   GFXPCD3D11RegisterDevice()
 627   {
 628      GFXInit::getRegisterDeviceSignal().notify(&GFXD3D11Device::enumerateAdapters);
 629   }
 630};
 631
 632static GFXPCD3D11RegisterDevice pPCD3D11RegisterDevice;
 633
 634//-----------------------------------------------------------------------------
 635/// Parse command line arguments for window creation
 636//-----------------------------------------------------------------------------
 637static void sgPCD3D11DeviceHandleCommandLine(S32 argc, const char **argv)
 638{
 639   // useful to pass parameters by command line for d3d (e.g. -dx9 -dx11)
 640   for (U32 i = 1; i < argc; i++)
 641   {
 642      argv[i];
 643   }   
 644}
 645
 646// Register the command line parsing hook
 647static ProcessRegisterCommandLine sgCommandLine( sgPCD3D11DeviceHandleCommandLine );
 648
 649GFXD3D11Device::GFXD3D11Device(U32 index)
 650{
 651   mDeviceSwizzle32 = &Swizzles::bgra;
 652   GFXVertexColor::setSwizzle( mDeviceSwizzle32 );
 653
 654   mDeviceSwizzle24 = &Swizzles::bgr;
 655
 656   mAdapterIndex = index;
 657   mD3DDevice = NULL;
 658   mVolatileVB = NULL;
 659
 660   mCurrentPB = NULL;
 661   mDynamicPB = NULL;
 662
 663   mLastVertShader = NULL;
 664   mLastPixShader = NULL;
 665
 666   mCanCurrentlyRender = false;
 667   mTextureManager = NULL;
 668   mCurrentStateBlock = NULL;
 669   mResourceListHead = NULL;
 670
 671   mPixVersion = 0.0;
 672
 673   mDrawInstancesCount = 0;
 674
 675   mCardProfiler = NULL;
 676
 677   mDeviceDepthStencil = NULL;
 678   mDeviceBackbuffer = NULL;
 679   mDeviceBackBufferView = NULL;
 680   mDeviceDepthStencilView = NULL;
 681
 682   mCreateFenceType = -1; // Unknown, test on first allocate
 683
 684   mCurrentConstBuffer = NULL;
 685
 686   mOcclusionQuerySupported = false;
 687
 688   mDebugLayers = false;
 689
 690   for(U32 i = 0; i < GS_COUNT; ++i)
 691      mModelViewProjSC[i] = NULL;
 692
 693   // Set up the Enum translation tables
 694   GFXD3D11EnumTranslate::init();
 695}
 696
 697GFXD3D11Device::~GFXD3D11Device() 
 698{
 699   // Release our refcount on the current stateblock object
 700   mCurrentStateBlock = NULL;
 701
 702   releaseDefaultPoolResources();
 703
 704   mD3DDeviceContext->ClearState();
 705   mD3DDeviceContext->Flush();
 706
 707   // Free the vertex declarations.
 708   VertexDeclMap::Iterator iter = mVertexDecls.begin();
 709   for ( ; iter != mVertexDecls.end(); iter++ )
 710      delete iter->value;
 711
 712   // Forcibly clean up the pools
 713   mVolatileVBList.setSize(0);
 714   mDynamicPB = NULL;
 715
 716   // And release our D3D resources.
 717   SAFE_RELEASE(mDeviceDepthStencilView);
 718   SAFE_RELEASE(mDeviceBackBufferView);
 719   SAFE_RELEASE(mDeviceDepthStencil);
 720   SAFE_RELEASE(mDeviceBackbuffer);
 721   SAFE_RELEASE(mD3DDeviceContext);
 722
 723   SAFE_DELETE(mCardProfiler);
 724   SAFE_DELETE(gScreenShot);
 725
 726#ifdef TORQUE_DEBUG
 727   if (mDebugLayers)
 728   {
 729      ID3D11Debug *pDebug = NULL;
 730      mD3DDevice->QueryInterface(IID_PPV_ARGS(&pDebug));
 731      AssertFatal(pDebug, "~GFXD3D11Device- Failed to get debug layer");
 732      pDebug->ReportLiveDeviceObjects(D3D11_RLDO_DETAIL);
 733      SAFE_RELEASE(pDebug);
 734   }
 735#endif
 736   
 737   SAFE_RELEASE(mSwapChain);
 738   SAFE_RELEASE(mD3DDevice);
 739}
 740
 741void GFXD3D11Device::setupGenericShaders(GenericShaderType type)
 742{
 743   AssertFatal(type != GSTargetRestore, ""); //not used
 744
 745   if(mGenericShader[GSColor] == NULL)
 746   {
 747      ShaderData *shaderData;
 748
 749      shaderData = new ShaderData();
 750      shaderData->setField("DXVertexShaderFile", "shaders/common/fixedFunction/colorV.hlsl");
 751      shaderData->setField("DXPixelShaderFile", "shaders/common/fixedFunction/colorP.hlsl");
 752      shaderData->setField("pixVersion", "5.0");
 753      shaderData->registerObject();
 754      mGenericShader[GSColor] =  shaderData->getShader();
 755      mGenericShaderBuffer[GSColor] = mGenericShader[GSColor]->allocConstBuffer();
 756      mModelViewProjSC[GSColor] = mGenericShader[GSColor]->getShaderConstHandle("$modelView");
 757      Sim::getRootGroup()->addObject(shaderData);
 758
 759      shaderData = new ShaderData();
 760      shaderData->setField("DXVertexShaderFile", "shaders/common/fixedFunction/modColorTextureV.hlsl");
 761      shaderData->setField("DXPixelShaderFile", "shaders/common/fixedFunction/modColorTextureP.hlsl");
 762      shaderData->setField("pixVersion", "5.0");
 763      shaderData->registerObject();
 764      mGenericShader[GSModColorTexture] = shaderData->getShader();
 765      mGenericShaderBuffer[GSModColorTexture] = mGenericShader[GSModColorTexture]->allocConstBuffer();
 766      mModelViewProjSC[GSModColorTexture] = mGenericShader[GSModColorTexture]->getShaderConstHandle("$modelView");
 767      Sim::getRootGroup()->addObject(shaderData);
 768
 769      shaderData = new ShaderData();
 770      shaderData->setField("DXVertexShaderFile", "shaders/common/fixedFunction/addColorTextureV.hlsl");
 771      shaderData->setField("DXPixelShaderFile", "shaders/common/fixedFunction/addColorTextureP.hlsl");
 772      shaderData->setField("pixVersion", "5.0");
 773      shaderData->registerObject();
 774      mGenericShader[GSAddColorTexture] = shaderData->getShader();
 775      mGenericShaderBuffer[GSAddColorTexture] = mGenericShader[GSAddColorTexture]->allocConstBuffer();
 776      mModelViewProjSC[GSAddColorTexture] = mGenericShader[GSAddColorTexture]->getShaderConstHandle("$modelView");
 777      Sim::getRootGroup()->addObject(shaderData);
 778
 779      shaderData = new ShaderData();
 780      shaderData->setField("DXVertexShaderFile", "shaders/common/fixedFunction/textureV.hlsl");
 781      shaderData->setField("DXPixelShaderFile", "shaders/common/fixedFunction/textureP.hlsl");
 782      shaderData->setField("pixVersion", "5.0");
 783      shaderData->registerObject();
 784      mGenericShader[GSTexture] = shaderData->getShader();
 785      mGenericShaderBuffer[GSTexture] = mGenericShader[GSTexture]->allocConstBuffer();
 786      mModelViewProjSC[GSTexture] = mGenericShader[GSTexture]->getShaderConstHandle("$modelView");
 787      Sim::getRootGroup()->addObject(shaderData);
 788
 789      //Force an update
 790      mViewportDirty = true;
 791      _updateRenderTargets();
 792   }
 793
 794   MatrixF tempMatrix =  mProjectionMatrix * mViewMatrix * mWorldMatrix[mWorldStackSize];  
 795   mGenericShaderBuffer[type]->setSafe(mModelViewProjSC[type], tempMatrix);
 796
 797   setShader(mGenericShader[type]);
 798   setShaderConstBuffer(mGenericShaderBuffer[type]);
 799}
 800
 801//-----------------------------------------------------------------------------
 802/// Creates a state block object based on the desc passed in.  This object
 803/// represents an immutable state.
 804GFXStateBlockRef GFXD3D11Device::createStateBlockInternal(const GFXStateBlockDesc& desc)
 805{
 806   return GFXStateBlockRef(new GFXD3D11StateBlock(desc));
 807}
 808
 809/// Activates a stateblock
 810void GFXD3D11Device::setStateBlockInternal(GFXStateBlock* block, bool force)
 811{
 812   AssertFatal(static_cast<GFXD3D11StateBlock*>(block), "Incorrect stateblock type for this device!");
 813   GFXD3D11StateBlock* d3dBlock = static_cast<GFXD3D11StateBlock*>(block);
 814   GFXD3D11StateBlock* d3dCurrent = static_cast<GFXD3D11StateBlock*>(mCurrentStateBlock.getPointer());
 815
 816   if (force)
 817      d3dCurrent = NULL;
 818
 819   d3dBlock->activate(d3dCurrent);   
 820}
 821
 822/// Called by base GFXDevice to actually set a const buffer
 823void GFXD3D11Device::setShaderConstBufferInternal(GFXShaderConstBuffer* buffer)
 824{
 825   if (buffer)
 826   {
 827      PROFILE_SCOPE(GFXD3D11Device_setShaderConstBufferInternal);
 828      AssertFatal(static_cast<GFXD3D11ShaderConstBuffer*>(buffer), "Incorrect shader const buffer type for this device!");
 829      GFXD3D11ShaderConstBuffer* d3dBuffer = static_cast<GFXD3D11ShaderConstBuffer*>(buffer);
 830
 831      d3dBuffer->activate(mCurrentConstBuffer);
 832      mCurrentConstBuffer = d3dBuffer;
 833   }
 834   else
 835   {
 836      mCurrentConstBuffer = NULL;
 837   }
 838}
 839
 840//-----------------------------------------------------------------------------
 841
 842void GFXD3D11Device::clear(U32 flags, ColorI color, F32 z, U32 stencil)
 843{
 844   // Make sure we have flushed our render target state.
 845   _updateRenderTargets();
 846
 847   UINT depthstencilFlag = 0;
 848
 849   ID3D11RenderTargetView* rtView = NULL;
 850   ID3D11DepthStencilView* dsView = NULL;
 851
 852   mD3DDeviceContext->OMGetRenderTargets(1, &rtView, &dsView);
 853
 854   const FLOAT clearColor[4] = {
 855      static_cast<F32>(color.red) * (1.0f / 255.0f),
 856      static_cast<F32>(color.green) * (1.0f / 255.0f),
 857      static_cast<F32>(color.blue) * (1.0f / 255.0f),
 858      static_cast<F32>(color.alpha) * (1.0f / 255.0f)
 859   };
 860
 861   if (flags & GFXClearTarget && rtView)
 862      mD3DDeviceContext->ClearRenderTargetView(rtView, clearColor);
 863
 864   if (flags & GFXClearZBuffer)
 865      depthstencilFlag |= D3D11_CLEAR_DEPTH;
 866
 867   if (flags & GFXClearStencil)
 868      depthstencilFlag |= D3D11_CLEAR_STENCIL;
 869
 870   if (depthstencilFlag && dsView)
 871      mD3DDeviceContext->ClearDepthStencilView(dsView, depthstencilFlag, z, stencil);
 872
 873   SAFE_RELEASE(rtView);
 874   SAFE_RELEASE(dsView);
 875}
 876
 877void GFXD3D11Device::endSceneInternal() 
 878{
 879   mCanCurrentlyRender = false;
 880}
 881
 882void GFXD3D11Device::_updateRenderTargets()
 883{
 884   if (mRTDirty || (mCurrentRT && mCurrentRT->isPendingState()))
 885   {
 886      if (mRTDeactivate)
 887      {
 888         mRTDeactivate->deactivate();
 889         mRTDeactivate = NULL;   
 890      }
 891
 892      // NOTE: The render target changes are not really accurate
 893      // as the GFXTextureTarget supports MRT internally.  So when
 894      // we activate a GFXTarget it could result in multiple calls
 895      // to SetRenderTarget on the actual device.
 896      mDeviceStatistics.mRenderTargetChanges++;
 897
 898      mCurrentRT->activate();
 899
 900      mRTDirty = false;
 901   }  
 902
 903   if (mViewportDirty)
 904   {
 905      D3D11_VIEWPORT viewport;
 906
 907      viewport.TopLeftX = mViewport.point.x;
 908      viewport.TopLeftY = mViewport.point.y;
 909      viewport.Width = mViewport.extent.x;
 910      viewport.Height = mViewport.extent.y;
 911      viewport.MinDepth   = 0.0f;
 912      viewport.MaxDepth   = 1.0f;
 913
 914      mD3DDeviceContext->RSSetViewports(1, &viewport);
 915
 916      mViewportDirty = false;
 917   }
 918}
 919
 920void GFXD3D11Device::releaseDefaultPoolResources() 
 921{
 922   // Release all the dynamic vertex buffer arrays
 923   // Forcibly clean up the pools
 924   for(U32 i=0; i<mVolatileVBList.size(); i++)
 925   {
 926      SAFE_RELEASE(mVolatileVBList[i]->vb);
 927      mVolatileVBList[i] = NULL;
 928   }
 929   mVolatileVBList.setSize(0);
 930
 931   // We gotta clear the current const buffer else the next
 932   // activate may erroneously think the device is still holding
 933   // this state and fail to set it.   
 934   mCurrentConstBuffer = NULL;
 935
 936   // Set current VB to NULL and set state dirty
 937   for (U32 i=0; i < VERTEX_STREAM_COUNT; i++)
 938   {
 939      mCurrentVertexBuffer[i] = NULL;
 940      mVertexBufferDirty[i] = true;
 941      mVertexBufferFrequency[i] = 0;
 942      mVertexBufferFrequencyDirty[i] = true;
 943   }
 944
 945   // Release dynamic index buffer
 946   if(mDynamicPB != NULL)
 947   {
 948      SAFE_RELEASE(mDynamicPB->ib);
 949   }
 950
 951   // Set current PB/IB to NULL and set state dirty
 952   mCurrentPrimitiveBuffer = NULL;
 953   mCurrentPB = NULL;
 954   mPrimitiveBufferDirty = true;
 955
 956   // Zombify texture manager (for D3D this only modifies default pool textures)
 957   if( mTextureManager ) 
 958      mTextureManager->zombify();
 959
 960   // Set global dirty state so the IB/PB and VB get reset
 961   mStateDirty = true;
 962
 963   // Walk the resource list and zombify everything.
 964   GFXResource *walk = mResourceListHead;
 965   while(walk)
 966   {
 967      walk->zombify();
 968      walk = walk->getNextResource();
 969   }
 970}
 971
 972void GFXD3D11Device::reacquireDefaultPoolResources() 
 973{
 974   // Now do the dynamic index buffers
 975   if( mDynamicPB == NULL )
 976      mDynamicPB = new GFXD3D11PrimitiveBuffer(this, 0, 0, GFXBufferTypeDynamic);
 977
 978   D3D11_BUFFER_DESC desc;
 979   desc.ByteWidth = sizeof(U16) * MAX_DYNAMIC_INDICES;
 980   desc.Usage = D3D11_USAGE_DYNAMIC;
 981   desc.BindFlags = D3D11_BIND_INDEX_BUFFER;
 982   desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
 983   desc.MiscFlags = 0;
 984   desc.StructureByteStride = 0;
 985
 986   HRESULT hr = D3D11DEVICE->CreateBuffer(&desc, NULL, &mDynamicPB->ib);
 987
 988   if(FAILED(hr)) 
 989   {
 990      AssertFatal(false, "Failed to allocate dynamic IB");
 991   }
 992
 993   // Walk the resource list and zombify everything.
 994   GFXResource *walk = mResourceListHead;
 995   while(walk)
 996   {
 997      walk->resurrect();
 998      walk = walk->getNextResource();
 999   }
1000
1001   if(mTextureManager)
1002      mTextureManager->resurrect();
1003}
1004
1005GFXD3D11VertexBuffer* GFXD3D11Device::findVBPool( const GFXVertexFormat *vertexFormat, U32 vertsNeeded )
1006{
1007   PROFILE_SCOPE( GFXD3D11Device_findVBPool );
1008
1009   for( U32 i=0; i<mVolatileVBList.size(); i++ )
1010      if( mVolatileVBList[i]->mVertexFormat.isEqual( *vertexFormat ) )
1011         return mVolatileVBList[i];
1012
1013   return NULL;
1014}
1015
1016GFXD3D11VertexBuffer * GFXD3D11Device::createVBPool( const GFXVertexFormat *vertexFormat, U32 vertSize )
1017{
1018   PROFILE_SCOPE( GFXD3D11Device_createVBPool );
1019
1020   // this is a bit funky, but it will avoid problems with (lack of) copy constructors
1021   //    with a push_back() situation
1022   mVolatileVBList.increment();
1023   StrongRefPtr<GFXD3D11VertexBuffer> newBuff;
1024   mVolatileVBList.last() = new GFXD3D11VertexBuffer();
1025   newBuff = mVolatileVBList.last();
1026
1027   newBuff->mNumVerts   = 0;
1028   newBuff->mBufferType = GFXBufferTypeVolatile;
1029   newBuff->mVertexFormat.copy( *vertexFormat );
1030   newBuff->mVertexSize = vertSize;
1031   newBuff->mDevice = this;
1032
1033   // Requesting it will allocate it.
1034   vertexFormat->getDecl(); 
1035
1036   D3D11_BUFFER_DESC desc;
1037   desc.ByteWidth = vertSize * MAX_DYNAMIC_VERTS;
1038   desc.Usage = D3D11_USAGE_DYNAMIC;
1039   desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
1040   desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
1041   desc.MiscFlags = 0;
1042   desc.StructureByteStride = 0;
1043
1044   HRESULT hr = D3D11DEVICE->CreateBuffer(&desc, NULL, &newBuff->vb);
1045
1046   if(FAILED(hr)) 
1047   {
1048      AssertFatal(false, "Failed to allocate dynamic VB");
1049   }
1050
1051   return newBuff;
1052}
1053
1054//-----------------------------------------------------------------------------
1055
1056void GFXD3D11Device::setClipRect( const RectI &inRect ) 
1057{
1058   // We transform the incoming rect by the view 
1059   // matrix first, so that it can be used to pan
1060   // and scale the clip rect.
1061   //
1062   // This is currently used to take tiled screenshots.
1063   Point3F pos( inRect.point.x, inRect.point.y, 0.0f );
1064   Point3F extent( inRect.extent.x, inRect.extent.y, 0.0f );
1065   getViewMatrix().mulP( pos );
1066   getViewMatrix().mulV( extent );  
1067   RectI rect( pos.x, pos.y, extent.x, extent.y );
1068
1069   // Clip the rect against the renderable size.
1070   Point2I size = mCurrentRT->getSize();
1071
1072   RectI maxRect(Point2I(0,0), size);
1073   rect.intersect(maxRect);
1074
1075   mClipRect = rect;
1076
1077   F32 l = F32( mClipRect.point.x );
1078   F32 r = F32( mClipRect.point.x + mClipRect.extent.x );
1079   F32 b = F32( mClipRect.point.y + mClipRect.extent.y );
1080   F32 t = F32( mClipRect.point.y );
1081
1082   // Set up projection matrix, 
1083   static Point4F pt;   
1084   pt.set(2.0f / (r - l), 0.0f, 0.0f, 0.0f);
1085   mTempMatrix.setColumn(0, pt);
1086
1087   pt.set(0.0f, 2.0f/(t - b), 0.0f, 0.0f);
1088   mTempMatrix.setColumn(1, pt);
1089
1090   pt.set(0.0f, 0.0f, 1.0f, 0.0f);
1091   mTempMatrix.setColumn(2, pt);
1092
1093   pt.set((l+r)/(l-r), (t+b)/(b-t), 1.0f, 1.0f);
1094   mTempMatrix.setColumn(3, pt);
1095
1096   setProjectionMatrix( mTempMatrix );
1097
1098   // Set up world/view matrix
1099   mTempMatrix.identity();   
1100   setWorldMatrix( mTempMatrix );
1101
1102   setViewport( mClipRect );
1103}
1104
1105void GFXD3D11Device::setVertexStream( U32 stream, GFXVertexBuffer *buffer )
1106{
1107   GFXD3D11VertexBuffer *d3dBuffer = static_cast<GFXD3D11VertexBuffer*>( buffer );
1108
1109   if ( stream == 0 )
1110   {
1111      // Set the volatile buffer which is used to 
1112      // offset the start index when doing draw calls.
1113      if ( d3dBuffer && d3dBuffer->mVolatileStart > 0 )
1114         mVolatileVB = d3dBuffer;
1115      else
1116         mVolatileVB = NULL;
1117   }
1118
1119   // NOTE: We do not use the stream offset here for stream 0
1120   // as that feature is *supposedly* not as well supported as 
1121   // using the start index in drawPrimitive.
1122   //
1123   // If we can verify that this is not the case then we should
1124   // start using this method exclusively for all streams.
1125
1126   U32 strides[1] = { d3dBuffer ? d3dBuffer->mVertexSize : 0 };
1127   U32 offset = d3dBuffer && stream != 0 ? d3dBuffer->mVolatileStart * d3dBuffer->mVertexSize : 0;
1128   ID3D11Buffer* buff = d3dBuffer ? d3dBuffer->vb : NULL;
1129
1130   getDeviceContext()->IASetVertexBuffers(stream, 1, &buff, strides, &offset);
1131}
1132
1133void GFXD3D11Device::setVertexStreamFrequency( U32 stream, U32 frequency )
1134{
1135   if (stream == 0)
1136      mDrawInstancesCount = frequency; // instances count
1137}
1138
1139void GFXD3D11Device::_setPrimitiveBuffer( GFXPrimitiveBuffer *buffer ) 
1140{
1141   mCurrentPB = static_cast<GFXD3D11PrimitiveBuffer *>( buffer );
1142
1143   mD3DDeviceContext->IASetIndexBuffer(mCurrentPB->ib, DXGI_FORMAT_R16_UINT, 0);
1144}
1145
1146U32 GFXD3D11Device::primCountToIndexCount(GFXPrimitiveType primType, U32 primitiveCount)
1147{
1148   switch (primType)
1149   {
1150   case GFXPointList:
1151      return primitiveCount;
1152      break;
1153   case GFXLineList:
1154      return primitiveCount * 2;
1155      break;
1156   case GFXLineStrip:
1157      return primitiveCount + 1;
1158      break;
1159   case GFXTriangleList:
1160      return primitiveCount * 3;
1161      break;
1162   case GFXTriangleStrip:
1163      return 2 + primitiveCount;
1164      break;
1165   default:
1166      AssertFatal(false, "GFXGLDevice::primCountToIndexCount - unrecognized prim type");
1167      break;
1168
1169   }
1170   return 0;
1171}
1172
1173
1174void GFXD3D11Device::drawPrimitive( GFXPrimitiveType primType, U32 vertexStart, U32 primitiveCount ) 
1175{
1176   // This is done to avoid the function call overhead if possible
1177   if( mStateDirty )
1178      updateStates();
1179   if (mCurrentShaderConstBuffer)
1180      setShaderConstBufferInternal(mCurrentShaderConstBuffer);
1181
1182   if ( mVolatileVB )
1183       vertexStart += mVolatileVB->mVolatileStart;
1184
1185   mD3DDeviceContext->IASetPrimitiveTopology(GFXD3D11PrimType[primType]);
1186   
1187   if ( mDrawInstancesCount )
1188      mD3DDeviceContext->DrawInstanced(primCountToIndexCount(primType, primitiveCount), mDrawInstancesCount, vertexStart, 0);
1189   else
1190      mD3DDeviceContext->Draw(primCountToIndexCount(primType, primitiveCount), vertexStart);
1191  
1192   mDeviceStatistics.mDrawCalls++;
1193   if ( mVertexBufferFrequency[0] > 1 )
1194      mDeviceStatistics.mPolyCount += primitiveCount * mVertexBufferFrequency[0];
1195   else
1196      mDeviceStatistics.mPolyCount += primitiveCount;
1197}
1198
1199void GFXD3D11Device::drawIndexedPrimitive( GFXPrimitiveType primType, 
1200                                          U32 startVertex, 
1201                                          U32 minIndex, 
1202                                          U32 numVerts, 
1203                                          U32 startIndex, 
1204                                          U32 primitiveCount ) 
1205{
1206   // This is done to avoid the function call overhead if possible
1207   if( mStateDirty )
1208      updateStates();
1209   if (mCurrentShaderConstBuffer)
1210      setShaderConstBufferInternal(mCurrentShaderConstBuffer);
1211
1212   AssertFatal( mCurrentPB != NULL, "Trying to call drawIndexedPrimitive with no current index buffer, call setIndexBuffer()" );
1213
1214   if ( mVolatileVB )
1215      startVertex += mVolatileVB->mVolatileStart;
1216
1217   mD3DDeviceContext->IASetPrimitiveTopology(GFXD3D11PrimType[primType]);
1218  
1219   if ( mDrawInstancesCount )
1220      mD3DDeviceContext->DrawIndexedInstanced(primCountToIndexCount(primType, primitiveCount), mDrawInstancesCount, mCurrentPB->mVolatileStart + startIndex, startVertex, 0);
1221   else
1222      mD3DDeviceContext->DrawIndexed(primCountToIndexCount(primType,primitiveCount), mCurrentPB->mVolatileStart + startIndex, startVertex);   
1223
1224   mDeviceStatistics.mDrawCalls++;
1225   if ( mVertexBufferFrequency[0] > 1 )
1226      mDeviceStatistics.mPolyCount += primitiveCount * mVertexBufferFrequency[0];
1227   else
1228      mDeviceStatistics.mPolyCount += primitiveCount;
1229}
1230
1231GFXShader* GFXD3D11Device::createShader()
1232{
1233   GFXD3D11Shader* shader = new GFXD3D11Shader();
1234   shader->registerResourceWithDevice( this );
1235   return shader;
1236}
1237
1238//-----------------------------------------------------------------------------
1239// Set shader - this function exists to make sure this is done in one place,
1240//              and to make sure redundant shader states are not being
1241//              sent to the card.
1242//-----------------------------------------------------------------------------
1243void GFXD3D11Device::setShader(GFXShader *shader, bool force)
1244{
1245   if(shader)
1246   {
1247      GFXD3D11Shader *d3dShader = static_cast<GFXD3D11Shader*>(shader);
1248
1249      if (d3dShader->mPixShader != mLastPixShader || force)
1250      {
1251        mD3DDeviceContext->PSSetShader( d3dShader->mPixShader, NULL, 0);
1252        mLastPixShader = d3dShader->mPixShader;
1253      }
1254
1255      if (d3dShader->mVertShader != mLastVertShader || force)
1256      {
1257        mD3DDeviceContext->VSSetShader( d3dShader->mVertShader, NULL, 0);
1258        mLastVertShader = d3dShader->mVertShader;
1259      }     
1260   }
1261   else
1262   {
1263      setupGenericShaders();
1264   }
1265}
1266
1267GFXPrimitiveBuffer * GFXD3D11Device::allocPrimitiveBuffer(U32 numIndices, U32 numPrimitives, GFXBufferType bufferType, void *data )
1268{
1269   // Allocate a buffer to return
1270   GFXD3D11PrimitiveBuffer * res = new GFXD3D11PrimitiveBuffer(this, numIndices, numPrimitives, bufferType);
1271
1272   // Determine usage flags
1273   D3D11_USAGE usage = D3D11_USAGE_DEFAULT;
1274
1275   // Assumptions:
1276   //    - static buffers are write once, use many
1277   //    - dynamic buffers are write many, use many
1278   //    - volatile buffers are write once, use once
1279   // You may never read from a buffer.
1280   //TODO: enable proper support for D3D11_USAGE_IMMUTABLE
1281   switch(bufferType)
1282   {
1283   case GFXBufferTypeImmutable:
1284   case GFXBufferTypeStatic:
1285      usage = D3D11_USAGE_DEFAULT; //D3D11_USAGE_IMMUTABLE;
1286      break;
1287
1288   case GFXBufferTypeDynamic:
1289   case GFXBufferTypeVolatile:
1290     usage = D3D11_USAGE_DYNAMIC;
1291      break;
1292   }
1293
1294   // Register resource
1295   res->registerResourceWithDevice(this);
1296
1297   // Create d3d index buffer
1298   if(bufferType == GFXBufferTypeVolatile)
1299   {
1300        // Get it from the pool if it's a volatile...
1301        AssertFatal(numIndices < MAX_DYNAMIC_INDICES, "Cannot allocate that many indices in a volatile buffer, increase MAX_DYNAMIC_INDICES.");
1302
1303        res->ib = mDynamicPB->ib;
1304        res->mVolatileBuffer = mDynamicPB;
1305   }
1306   else
1307   {
1308      // Otherwise, get it as a seperate buffer...
1309      D3D11_BUFFER_DESC desc;
1310      desc.ByteWidth = sizeof(U16) * numIndices;
1311      desc.Usage = usage;
1312      if(bufferType == GFXBufferTypeDynamic)
1313         desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; // We never allow reading from a primitive buffer.
1314      else
1315         desc.CPUAccessFlags = 0;
1316      desc.BindFlags = D3D11_BIND_INDEX_BUFFER;
1317      desc.MiscFlags = 0;
1318      desc.StructureByteStride = 0;
1319
1320      HRESULT hr = D3D11DEVICE->CreateBuffer(&desc, NULL, &res->ib);
1321
1322      if(FAILED(hr)) 
1323      {
1324         AssertFatal(false, "Failed to allocate an index buffer.");
1325      }
1326   }
1327
1328   if (data)
1329   {
1330      void* dest;
1331      res->lock(0, numIndices, &dest);
1332      dMemcpy(dest, data, sizeof(U16) * numIndices);
1333      res->unlock();
1334   }
1335
1336   return res;
1337}
1338
1339GFXVertexBuffer * GFXD3D11Device::allocVertexBuffer(U32 numVerts, const GFXVertexFormat *vertexFormat, U32 vertSize, GFXBufferType bufferType, void *data)
1340{
1341   PROFILE_SCOPE( GFXD3D11Device_allocVertexBuffer );
1342
1343   GFXD3D11VertexBuffer *res = new GFXD3D11VertexBuffer(   this, 
1344                                                         numVerts, 
1345                                                         vertexFormat, 
1346                                                         vertSize, 
1347                                                         bufferType );
1348   
1349   // Determine usage flags
1350   D3D11_USAGE usage = D3D11_USAGE_DEFAULT;
1351
1352   res->mNumVerts = 0;
1353
1354   // Assumptions:
1355   //    - static buffers are write once, use many
1356   //    - dynamic buffers are write many, use many
1357   //    - volatile buffers are write once, use once
1358   // You may never read from a buffer.
1359   //TODO: enable proper support for D3D11_USAGE_IMMUTABLE
1360   switch(bufferType)
1361   {
1362   case GFXBufferTypeImmutable:
1363   case GFXBufferTypeStatic:
1364      usage = D3D11_USAGE_DEFAULT;
1365      break;
1366
1367   case GFXBufferTypeDynamic:
1368   case GFXBufferTypeVolatile:
1369     usage = D3D11_USAGE_DYNAMIC;
1370      break;
1371   }
1372
1373   // Register resource
1374   res->registerResourceWithDevice(this);
1375
1376   // Create vertex buffer
1377   if(bufferType == GFXBufferTypeVolatile)
1378   {
1379        // NOTE: Volatile VBs are pooled and will be allocated at lock time.
1380        AssertFatal(numVerts <= MAX_DYNAMIC_VERTS, "GFXD3D11Device::allocVertexBuffer - Volatile vertex buffer is too big... see MAX_DYNAMIC_VERTS!");
1381   }
1382   else
1383   {
1384      // Requesting it will allocate it.
1385      vertexFormat->getDecl(); //-ALEX disabled to postpone until after shader is actually set...
1386
1387      // Get a new buffer...
1388      D3D11_BUFFER_DESC desc;
1389      desc.ByteWidth = vertSize * numVerts;
1390      desc.Usage = usage;
1391      desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
1392      if(bufferType == GFXBufferTypeDynamic)
1393         desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; // We never allow reading from a vertex buffer.
1394      else
1395         desc.CPUAccessFlags = 0;
1396      desc.MiscFlags = 0;
1397      desc.StructureByteStride = 0;
1398
1399      HRESULT hr = D3D11DEVICE->CreateBuffer(&desc, NULL, &res->vb);
1400
1401      if(FAILED(hr)) 
1402      {
1403         AssertFatal(false, "Failed to allocate VB");
1404      }
1405   }
1406
1407   res->mNumVerts = numVerts;
1408
1409   if (data)
1410   {
1411      void* dest;
1412      res->lock(0, numVerts, &dest);
1413      dMemcpy(dest, data, vertSize * numVerts);
1414      res->unlock();
1415   }
1416
1417   return res;
1418}
1419
1420String GFXD3D11Device::_createTempShaderInternal(const GFXVertexFormat *vertexFormat)
1421{
1422   U32 elemCount = vertexFormat->getElementCount();
1423   //Input data
1424   StringBuilder inputData;
1425   inputData.append("struct VertIn {");
1426   //Output data
1427   StringBuilder outputData;
1428   outputData.append("struct VertOut {");
1429   // Shader main body data
1430   StringBuilder mainBodyData;
1431   //make shader
1432   mainBodyData.append("VertOut main(VertIn IN){VertOut OUT;");
1433
1434   bool addedPadding = false;
1435   for (U32 i = 0; i < elemCount; i++)
1436   {
1437      const GFXVertexElement &element = vertexFormat->getElement(i);
1438      String semantic = element.getSemantic();
1439      String semanticOut = semantic;
1440      String type;
1441
1442      AssertFatal(!(addedPadding && !element.isSemantic(GFXSemantic::PADDING)), "Padding added before data");
1443
1444      if (element.isSemantic(GFXSemantic::POSITION))
1445      {
1446         semantic = "POSITION";
1447         semanticOut = "SV_Position";
1448      }
1449      else if (element.isSemantic(GFXSemantic::NORMAL))
1450      {
1451         semantic = "NORMAL";
1452         semanticOut = semantic;
1453      }
1454      else if (element.isSemantic(GFXSemantic::COLOR))
1455      {
1456         semantic = "COLOR";
1457         semanticOut = semantic;
1458      }
1459      else if (element.isSemantic(GFXSemantic::TANGENT))
1460      {
1461         semantic = "TANGENT";
1462         semanticOut = semantic;
1463      }
1464      else if (element.isSemantic(GFXSemantic::BINORMAL))
1465      {
1466         semantic = "BINORMAL";
1467         semanticOut = semantic;
1468      }
1469      else if (element.isSemantic(GFXSemantic::BLENDINDICES))
1470      {
1471         semantic = String::ToString("BLENDINDICES%d", element.getSemanticIndex());
1472         semanticOut = semantic;
1473      }
1474      else if (element.isSemantic(GFXSemantic::BLENDWEIGHT))
1475      {
1476         semantic = String::ToString("BLENDWEIGHT%d", element.getSemanticIndex());
1477         semanticOut = semantic;
1478      }
1479      else if (element.isSemantic(GFXSemantic::PADDING))
1480      {
1481         addedPadding = true;
1482         continue;
1483      }
1484      else
1485      {
1486         //Anything that falls thru to here will be a texture coord.
1487         semantic = String::ToString("TEXCOORD%d", element.getSemanticIndex());
1488         semanticOut = semantic;
1489      }
1490
1491      switch (GFXD3D11DeclType[element.getType()])
1492      {
1493      case DXGI_FORMAT_R32_FLOAT:
1494         type = "float";
1495         break;
1496      case DXGI_FORMAT_R32G32_FLOAT:
1497         type = "float2";
1498         break;
1499      case DXGI_FORMAT_R32G32B32_FLOAT:
1500         type = "float3";
1501         break;
1502      case DXGI_FORMAT_R32G32B32A32_FLOAT:
1503      case DXGI_FORMAT_B8G8R8A8_UNORM:
1504      case DXGI_FORMAT_R8G8B8A8_UNORM:
1505         type = "float4";
1506         break;
1507      case DXGI_FORMAT_R8G8B8A8_UINT:
1508         type = "uint4";
1509         break;
1510      }
1511
1512      StringBuilder in;
1513      in.format("%s %s%d : %s;", type.c_str(), "var", i, semantic.c_str());
1514      inputData.append(in.data());
1515
1516      //SV_Position must be float4
1517      if (semanticOut == String("SV_Position"))
1518      {
1519         StringBuilder out;
1520         out.format("float4 %s%d : %s;", "var", i, semanticOut.c_str());
1521         outputData.append(out.data());
1522         StringBuilder body;
1523         body.format("OUT.%s%d = float4(IN.%s%d.xyz,1);", "var", i, "var", i);
1524         mainBodyData.append(body.data());
1525      }
1526      else
1527      {
1528         StringBuilder out;
1529         out.format("%s %s%d : %s;", type.c_str(), "var", i, semanticOut.c_str());
1530         outputData.append(out.data());
1531         StringBuilder body;
1532         body.format("OUT.%s%d = IN.%s%d;", "var", i, "var", i);
1533         mainBodyData.append(body.data());
1534      }
1535   }
1536
1537   inputData.append("};");
1538   outputData.append("};");
1539   mainBodyData.append("return OUT;}");
1540
1541   //final data
1542   StringBuilder finalData;
1543   finalData.append(inputData.data());
1544   finalData.append(outputData.data());
1545   finalData.append(mainBodyData.data());
1546
1547   return String(finalData.data());
1548}
1549
1550GFXVertexDecl* GFXD3D11Device::allocVertexDecl( const GFXVertexFormat *vertexFormat )
1551{
1552   PROFILE_SCOPE( GFXD3D11Device_allocVertexDecl );
1553
1554   // First check the map... you shouldn't allocate VBs very often
1555   // if you want performance.  The map lookup should never become
1556   // a performance bottleneck.
1557   D3D11VertexDecl *decl = mVertexDecls[vertexFormat->getDescription()];
1558   if ( decl )
1559      return decl;
1560
1561   U32 elemCount = vertexFormat->getElementCount();
1562 
1563   ID3DBlob* code = NULL;
1564  
1565   // We have to generate a temporary shader here for now since the input layout creation
1566   // expects a shader to be already compiled to verify the vertex layout structure. The problem
1567   // is that most of the time the regular shaders are compiled AFTER allocVertexDecl is called.
1568   if(!decl)
1569   {
1570      //TODO: Perhaps save/cache the ID3DBlob for later use on identical vertex formats,save creating/compiling the temp shader everytime
1571      String shaderData = _createTempShaderInternal(vertexFormat);     
1572
1573#ifdef TORQUE_DEBUG
1574      U32 flags = D3DCOMPILE_DEBUG | D3DCOMPILE_ENABLE_STRICTNESS | D3DCOMPILE_WARNINGS_ARE_ERRORS;
1575#else
1576      U32 flags = D3DCOMPILE_ENABLE_STRICTNESS;
1577#endif
1578
1579      ID3DBlob *errorBlob = NULL;
1580      HRESULT hr = D3DCompile(shaderData.c_str(), shaderData.length(), NULL, NULL, NULL, "main", "vs_5_0", flags, 0, &code, &errorBlob);
1581      StringBuilder error;
1582
1583      if(errorBlob)
1584      {
1585         error.append((char*)errorBlob->GetBufferPointer(), errorBlob->GetBufferSize());
1586         AssertFatal(hr, error.data());
1587      }
1588
1589      SAFE_RELEASE(errorBlob);
1590   }
1591   
1592   AssertFatal(code, "D3D11Device::allocVertexDecl - compiled vert shader code missing!");
1593
1594   // Setup the declaration struct.
1595   
1596   U32 stream;
1597   D3D11_INPUT_ELEMENT_DESC *vd = new D3D11_INPUT_ELEMENT_DESC[ elemCount];
1598
1599   S32 elemIndex = 0;
1600   for (S32 i = 0; i < elemCount; i++, elemIndex++)
1601   {
1602      const GFXVertexElement &element = vertexFormat->getElement(elemIndex);
1603
1604      stream = element.getStreamIndex();
1605
1606      vd[i].InputSlot = stream;
1607
1608      vd[i].AlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT;
1609      vd[i].Format = GFXD3D11DeclType[element.getType()];
1610      // If instancing is enabled, the per instance data is only used on stream 1.
1611      if (vertexFormat->hasInstancing() && stream == 1)
1612      {
1613         vd[i].InputSlotClass = D3D11_INPUT_PER_INSTANCE_DATA;
1614         vd[i].InstanceDataStepRate = 1;
1615      }
1616      else
1617      {
1618         vd[i].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
1619         vd[i].InstanceDataStepRate = 0;
1620      }
1621      // We force the usage index of 0 for everything but 
1622      // texture coords for now... this may change later.
1623      vd[i].SemanticIndex = 0;
1624
1625      if (element.isSemantic(GFXSemantic::POSITION))
1626         vd[i].SemanticName = "POSITION";
1627      else if (element.isSemantic(GFXSemantic::NORMAL))
1628         vd[i].SemanticName = "NORMAL";
1629      else if (element.isSemantic(GFXSemantic::COLOR))
1630         vd[i].SemanticName = "COLOR";
1631      else if (element.isSemantic(GFXSemantic::TANGENT))
1632         vd[i].SemanticName = "TANGENT";
1633      else if (element.isSemantic(GFXSemantic::BINORMAL))
1634         vd[i].SemanticName = "BINORMAL";
1635      else if (element.isSemantic(GFXSemantic::BLENDWEIGHT))
1636      {
1637         vd[i].SemanticName = "BLENDWEIGHT";
1638         vd[i].SemanticIndex = element.getSemanticIndex();
1639      }
1640      else if (element.isSemantic(GFXSemantic::BLENDINDICES))
1641      {
1642         vd[i].SemanticName = "BLENDINDICES";
1643         vd[i].SemanticIndex = element.getSemanticIndex();
1644      }
1645      else if (element.isSemantic(GFXSemantic::PADDING))
1646      {
1647         i--;
1648         elemCount--;
1649         continue;
1650      }
1651      else
1652      {
1653          //Anything that falls thru to here will be a texture coord.
1654         vd[i].SemanticName = "TEXCOORD";
1655         vd[i].SemanticIndex = element.getSemanticIndex();
1656      }
1657
1658   }
1659
1660   decl = new D3D11VertexDecl();
1661   HRESULT hr = mD3DDevice->CreateInputLayout(vd, elemCount,code->GetBufferPointer(), code->GetBufferSize(), &decl->decl);
1662   
1663   if (FAILED(hr))
1664   {
1665      AssertFatal(false, "GFXD3D11Device::allocVertexDecl - Failed to create vertex input layout!");
1666   }
1667
1668   delete [] vd;
1669   SAFE_RELEASE(code);
1670
1671   // Store it in the cache.
1672   mVertexDecls[vertexFormat->getDescription()] = decl;
1673
1674   return decl;
1675}
1676
1677void GFXD3D11Device::setVertexDecl( const GFXVertexDecl *decl )
1678{
1679   ID3D11InputLayout *dx11Decl = NULL;
1680   if (decl)
1681      dx11Decl = static_cast<const D3D11VertexDecl*>(decl)->decl;
1682   
1683   mD3DDeviceContext->IASetInputLayout(dx11Decl);
1684}
1685
1686//-----------------------------------------------------------------------------
1687// This function should ONLY be called from GFXDevice::updateStates() !!!
1688//-----------------------------------------------------------------------------
1689void GFXD3D11Device::setTextureInternal( U32 textureUnit, const GFXTextureObject *texture)
1690{
1691   if( texture == NULL )
1692   {
1693      ID3D11ShaderResourceView *pView = NULL;
1694      mD3DDeviceContext->PSSetShaderResources(textureUnit, 1, &pView);
1695      return;
1696   }
1697
1698   GFXD3D11TextureObject  *tex = (GFXD3D11TextureObject*)(texture);
1699   mD3DDeviceContext->PSSetShaderResources(textureUnit, 1, tex->getSRViewPtr());
1700}
1701
1702GFXFence *GFXD3D11Device::createFence()
1703{
1704   // Figure out what fence type we should be making if we don't know
1705   if( mCreateFenceType == -1 )
1706   {
1707     D3D11_QUERY_DESC desc;
1708     desc.MiscFlags = 0;
1709     desc.Query = D3D11_QUERY_EVENT;
1710
1711     ID3D11Query *testQuery = NULL;
1712
1713     HRESULT hRes = mD3DDevice->CreateQuery(&desc, &testQuery);
1714
1715     if(FAILED(hRes))
1716     {
1717        mCreateFenceType = true;
1718     }
1719
1720     else
1721     {
1722        mCreateFenceType = false;
1723     }
1724
1725      SAFE_RELEASE(testQuery);
1726   }
1727
1728   // Cool, use queries
1729   if(!mCreateFenceType)
1730   {
1731      GFXFence* fence = new GFXD3D11QueryFence( this );
1732      fence->registerResourceWithDevice(this);
1733      return fence;
1734   }
1735
1736   // CodeReview: At some point I would like a specialized implementation of
1737   // the method used by the general fence, only without the overhead incurred 
1738   // by using the GFX constructs. Primarily the lock() method on texture handles
1739   // will do a data copy, and this method doesn't require a copy, just a lock
1740   // [5/10/2007 Pat]
1741   GFXFence* fence = new GFXGeneralFence( this );
1742   fence->registerResourceWithDevice(this);
1743   return fence;
1744}
1745
1746GFXOcclusionQuery* GFXD3D11Device::createOcclusionQuery()
1747{  
1748   GFXOcclusionQuery *query;
1749   if (mOcclusionQuerySupported)
1750      query = new GFXD3D11OcclusionQuery( this );
1751   else
1752      return NULL;      
1753
1754   query->registerResourceWithDevice(this);
1755   return query;
1756}
1757
1758GFXCubemap * GFXD3D11Device::createCubemap()
1759{
1760   GFXD3D11Cubemap* cube = new GFXD3D11Cubemap();
1761   cube->registerResourceWithDevice(this);
1762   return cube;
1763}
1764