Browse Source

Direct3D11 GFX device.

rextimmy 9 years ago
parent
commit
1ff6f221fb
28 changed files with 7847 additions and 0 deletions
  1. 72 0
      Engine/source/gfx/D3D11/gfxD3D11CardProfiler.cpp
  2. 46 0
      Engine/source/gfx/D3D11/gfxD3D11CardProfiler.h
  3. 352 0
      Engine/source/gfx/D3D11/gfxD3D11Cubemap.cpp
  4. 80 0
      Engine/source/gfx/D3D11/gfxD3D11Cubemap.h
  5. 1721 0
      Engine/source/gfx/D3D11/gfxD3D11Device.cpp
  6. 295 0
      Engine/source/gfx/D3D11/gfxD3D11Device.h
  7. 155 0
      Engine/source/gfx/D3D11/gfxD3D11EnumTranslate.cpp
  8. 51 0
      Engine/source/gfx/D3D11/gfxD3D11EnumTranslate.h
  9. 177 0
      Engine/source/gfx/D3D11/gfxD3D11OcclusionQuery.cpp
  10. 58 0
      Engine/source/gfx/D3D11/gfxD3D11OcclusionQuery.h
  11. 222 0
      Engine/source/gfx/D3D11/gfxD3D11PrimitiveBuffer.cpp
  12. 83 0
      Engine/source/gfx/D3D11/gfxD3D11PrimitiveBuffer.h
  13. 110 0
      Engine/source/gfx/D3D11/gfxD3D11QueryFence.cpp
  14. 49 0
      Engine/source/gfx/D3D11/gfxD3D11QueryFence.h
  15. 1542 0
      Engine/source/gfx/D3D11/gfxD3D11Shader.cpp
  16. 471 0
      Engine/source/gfx/D3D11/gfxD3D11Shader.h
  17. 285 0
      Engine/source/gfx/D3D11/gfxD3D11StateBlock.cpp
  18. 76 0
      Engine/source/gfx/D3D11/gfxD3D11StateBlock.h
  19. 409 0
      Engine/source/gfx/D3D11/gfxD3D11Target.cpp
  20. 110 0
      Engine/source/gfx/D3D11/gfxD3D11Target.h
  21. 587 0
      Engine/source/gfx/D3D11/gfxD3D11TextureManager.cpp
  22. 62 0
      Engine/source/gfx/D3D11/gfxD3D11TextureManager.h
  23. 280 0
      Engine/source/gfx/D3D11/gfxD3D11TextureObject.cpp
  24. 89 0
      Engine/source/gfx/D3D11/gfxD3D11TextureObject.h
  25. 233 0
      Engine/source/gfx/D3D11/gfxD3D11VertexBuffer.cpp
  26. 95 0
      Engine/source/gfx/D3D11/gfxD3D11VertexBuffer.h
  27. 98 0
      Engine/source/gfx/D3D11/screenshotD3D11.cpp
  28. 39 0
      Engine/source/gfx/D3D11/screenshotD3D11.h

+ 72 - 0
Engine/source/gfx/D3D11/gfxD3D11CardProfiler.cpp

@@ -0,0 +1,72 @@
+//-----------------------------------------------------------------------------
+// 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 "gfx/D3D11/gfxD3D11CardProfiler.h"
+#include "gfx/D3D11/gfxD3D11Device.h"
+#include "gfx/D3D11/gfxD3D11EnumTranslate.h"
+#include "platformWin32/videoInfo/wmiVideoInfo.h"
+#include "console/console.h"
+#include "gfx/primBuilder.h"
+
+
+GFXD3D11CardProfiler::GFXD3D11CardProfiler() : GFXCardProfiler()
+{
+}
+
+GFXD3D11CardProfiler::~GFXD3D11CardProfiler()
+{
+
+}
+
+void GFXD3D11CardProfiler::init()
+{
+   U32 adapterIndex = D3D11->getAdaterIndex();
+   WMIVideoInfo wmiVidInfo;
+   if (wmiVidInfo.profileAdapters())
+   {
+      const PlatformVideoInfo::PVIAdapter &adapter = wmiVidInfo.getAdapterInformation(adapterIndex);
+
+      mCardDescription = adapter.description;
+      mChipSet = adapter.chipSet;
+      mVersionString = adapter.driverVersion;
+      mVideoMemory = adapter.vram;
+   }
+   Parent::init();
+}
+
+void GFXD3D11CardProfiler::setupCardCapabilities()
+{
+   setCapability("maxTextureWidth", D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION);
+   setCapability("maxTextureHeight", D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION);
+   setCapability("maxTextureSize", D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION);
+}
+
+bool GFXD3D11CardProfiler::_queryCardCap(const String &query, U32 &foundResult)
+{
+	return false;
+}
+
+bool GFXD3D11CardProfiler::_queryFormat( const GFXFormat fmt, const GFXTextureProfile *profile, bool &inOutAutogenMips )
+{
+   // D3D11 feature level should guarantee that any format is valid!
+   return GFXD3D11TextureFormat[fmt] != DXGI_FORMAT_UNKNOWN;
+}

+ 46 - 0
Engine/source/gfx/D3D11/gfxD3D11CardProfiler.h

@@ -0,0 +1,46 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+#ifndef _GFXD3D11CARDPROFILER_H_
+#define _GFXD3D11CARDPROFILER_H_
+
+#include "gfx/gfxCardProfile.h"
+
+class GFXD3D11CardProfiler : public GFXCardProfiler
+{
+private:
+   typedef GFXCardProfiler Parent;
+
+public:
+   GFXD3D11CardProfiler();
+   ~GFXD3D11CardProfiler();
+   void init();
+
+protected:
+   const String &getRendererString() const { static String sRS("Direct3D11"); return sRS; }
+
+   void setupCardCapabilities();
+   bool _queryCardCap(const String &query, U32 &foundResult);
+   bool _queryFormat(const GFXFormat fmt, const GFXTextureProfile *profile, bool &inOutAutogenMips);
+};
+
+#endif

+ 352 - 0
Engine/source/gfx/D3D11/gfxD3D11Cubemap.cpp

@@ -0,0 +1,352 @@
+//-----------------------------------------------------------------------------
+// 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 "gfx/D3D11/gfxD3D11Cubemap.h"
+#include "gfx/gfxCardProfile.h"
+#include "gfx/gfxTextureManager.h"
+#include "gfx/D3D11/gfxD3D11EnumTranslate.h"
+
+GFXD3D11Cubemap::GFXD3D11Cubemap() : mTexture(NULL), mSRView(NULL), mDSView(NULL)
+{
+	mDynamic = false;
+   mAutoGenMips = false;
+	mFaceFormat = GFXFormatR8G8B8A8;
+
+   for (U32 i = 0; i < CubeFaces; i++)
+	{
+      mRTView[i] = NULL;
+	}
+}
+
+GFXD3D11Cubemap::~GFXD3D11Cubemap()
+{
+	releaseSurfaces();
+}
+
+void GFXD3D11Cubemap::releaseSurfaces()
+{
+   if (mDynamic)
+		GFXTextureManager::removeEventDelegate(this, &GFXD3D11Cubemap::_onTextureEvent);
+
+   for (U32 i = 0; i < CubeFaces; i++)
+	{
+      SAFE_RELEASE(mRTView[i]);
+	}
+
+   SAFE_RELEASE(mDSView);
+   SAFE_RELEASE(mSRView);
+	SAFE_RELEASE(mTexture);
+}
+
+void GFXD3D11Cubemap::_onTextureEvent(GFXTexCallbackCode code)
+{
+   if (code == GFXZombify)
+      releaseSurfaces();
+   else if (code == GFXResurrect)
+      initDynamic(mTexSize);
+}
+
+bool GFXD3D11Cubemap::isCompressed(GFXFormat format)
+{
+   if (format >= GFXFormatDXT1 && format <= GFXFormatDXT5)
+      return true;
+
+   return false;
+}
+
+void GFXD3D11Cubemap::initStatic(GFXTexHandle *faces)
+{
+   AssertFatal( faces, "GFXD3D11Cubemap::initStatic - Got null GFXTexHandle!" );
+	AssertFatal( *faces, "empty texture passed to CubeMap::create" );
+  
+	// NOTE - check tex sizes on all faces - they MUST be all same size
+	mTexSize = faces->getWidth();
+	mFaceFormat = faces->getFormat();
+   bool compressed = isCompressed(mFaceFormat);
+
+   UINT bindFlags = D3D11_BIND_SHADER_RESOURCE;
+   UINT miscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE;
+   if (!compressed)
+   {
+      bindFlags |= D3D11_BIND_RENDER_TARGET;
+      miscFlags |= D3D11_RESOURCE_MISC_GENERATE_MIPS;
+   }
+
+   U32 mipLevels = faces->getPointer()->getMipLevels();
+   if (mipLevels > 1)
+      mAutoGenMips = true;
+
+	D3D11_TEXTURE2D_DESC desc;
+	ZeroMemory(&desc, sizeof(D3D11_TEXTURE2D_DESC));
+	desc.Width = mTexSize;
+	desc.Height = mTexSize;
+   desc.MipLevels = mAutoGenMips ? 0 : mipLevels;
+	desc.ArraySize = 6;
+	desc.Format = GFXD3D11TextureFormat[mFaceFormat];
+	desc.SampleDesc.Count = 1;
+	desc.SampleDesc.Quality = 0;
+	desc.Usage = D3D11_USAGE_DEFAULT;
+	desc.BindFlags = bindFlags;
+	desc.MiscFlags = miscFlags;
+	desc.CPUAccessFlags = 0;
+
+	HRESULT hr = D3D11DEVICE->CreateTexture2D(&desc, NULL, &mTexture);
+
+	if (FAILED(hr))
+	{
+		AssertFatal(false, "GFXD3D11Cubemap:initStatic(GFXTexhandle *faces) - failed to create texcube texture");
+	}
+
+   for (U32 i = 0; i < CubeFaces; i++)
+   {
+      GFXD3D11TextureObject *texObj = static_cast<GFXD3D11TextureObject*>((GFXTextureObject*)faces[i]);
+      U32 subResource = D3D11CalcSubresource(0, i, mipLevels);
+      D3D11DEVICECONTEXT->CopySubresourceRegion(mTexture, subResource, 0, 0, 0, texObj->get2DTex(), 0, NULL);
+   }
+   
+	D3D11_SHADER_RESOURCE_VIEW_DESC SMViewDesc;
+	SMViewDesc.Format = GFXD3D11TextureFormat[mFaceFormat];
+	SMViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
+   SMViewDesc.TextureCube.MipLevels = mAutoGenMips ? -1 : mipLevels;
+	SMViewDesc.TextureCube.MostDetailedMip = 0;
+
+	hr = D3D11DEVICE->CreateShaderResourceView(mTexture, &SMViewDesc, &mSRView);
+	if (FAILED(hr))
+	{
+		AssertFatal(false, "GFXD3D11Cubemap::initStatic(GFXTexHandle *faces) - texcube shader resource view  creation failure");
+	} 
+
+   if (mAutoGenMips && !compressed)
+      D3D11DEVICECONTEXT->GenerateMips(mSRView);
+}
+
+void GFXD3D11Cubemap::initStatic(DDSFile *dds)
+{
+   AssertFatal(dds, "GFXD3D11Cubemap::initStatic - Got null DDS file!");
+   AssertFatal(dds->isCubemap(), "GFXD3D11Cubemap::initStatic - Got non-cubemap DDS file!");
+   AssertFatal(dds->mSurfaces.size() == 6, "GFXD3D11Cubemap::initStatic - DDS has less than 6 surfaces!");  
+   
+   // NOTE - check tex sizes on all faces - they MUST be all same size
+   mTexSize = dds->getWidth();
+   mFaceFormat = dds->getFormat();
+   U32 levels = dds->getMipLevels();
+
+	D3D11_TEXTURE2D_DESC desc;
+
+	desc.Width = mTexSize;
+	desc.Height = mTexSize;
+	desc.MipLevels = levels;
+	desc.ArraySize = 6;
+	desc.Format = GFXD3D11TextureFormat[mFaceFormat];
+	desc.SampleDesc.Count = 1;
+	desc.SampleDesc.Quality = 0;
+	desc.Usage = D3D11_USAGE_IMMUTABLE;
+	desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
+	desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
+	desc.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE | D3D11_RESOURCE_MISC_GENERATE_MIPS;
+
+	D3D11_SUBRESOURCE_DATA* pData = new D3D11_SUBRESOURCE_DATA[6 + levels];
+
+   for (U32 i = 0; i<CubeFaces; i++)
+	{
+		if (!dds->mSurfaces[i])
+			continue;
+
+		for(U32 j = 0; j < levels; j++)
+		{
+			pData[i + j].pSysMem = dds->mSurfaces[i]->mMips[j];
+			pData[i + j].SysMemPitch = dds->getSurfacePitch(j);
+			pData[i + j].SysMemSlicePitch = dds->getSurfaceSize(j);
+		}
+	}
+
+	HRESULT hr = D3D11DEVICE->CreateTexture2D(&desc, pData, &mTexture);
+
+	delete [] pData;
+
+	D3D11_SHADER_RESOURCE_VIEW_DESC SMViewDesc;
+	SMViewDesc.Format = GFXD3D11TextureFormat[mFaceFormat];
+	SMViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
+	SMViewDesc.TextureCube.MipLevels =  levels;
+	SMViewDesc.TextureCube.MostDetailedMip = 0;
+
+	hr = D3D11DEVICE->CreateShaderResourceView(mTexture, &SMViewDesc, &mSRView);
+
+	if(FAILED(hr)) 
+	{
+		AssertFatal(false, "GFXD3D11Cubemap::initStatic(DDSFile *dds) - CreateTexture2D call failure");
+	}
+}
+
+void GFXD3D11Cubemap::initDynamic(U32 texSize, GFXFormat faceFormat)
+{
+	if(!mDynamic)
+		GFXTextureManager::addEventDelegate(this, &GFXD3D11Cubemap::_onTextureEvent);
+
+	mDynamic = true;
+   mAutoGenMips = true;
+	mTexSize = texSize;
+	mFaceFormat = faceFormat;
+   bool compressed = isCompressed(mFaceFormat);
+
+   UINT bindFlags = D3D11_BIND_SHADER_RESOURCE;
+   UINT miscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE;
+   if (!compressed)
+   {
+      bindFlags |= D3D11_BIND_RENDER_TARGET;
+      miscFlags |= D3D11_RESOURCE_MISC_GENERATE_MIPS;
+   }
+
+	D3D11_TEXTURE2D_DESC desc;
+
+	desc.Width = mTexSize;
+	desc.Height = mTexSize;
+	desc.MipLevels = 0;
+	desc.ArraySize = 6;
+	desc.Format = GFXD3D11TextureFormat[mFaceFormat];
+	desc.SampleDesc.Count = 1;
+	desc.SampleDesc.Quality = 0;
+	desc.Usage = D3D11_USAGE_DEFAULT;
+   desc.BindFlags = bindFlags;
+	desc.CPUAccessFlags = 0;
+   desc.MiscFlags = miscFlags;
+
+
+	HRESULT hr = D3D11DEVICE->CreateTexture2D(&desc, NULL, &mTexture);
+
+	D3D11_SHADER_RESOURCE_VIEW_DESC SMViewDesc;
+	SMViewDesc.Format = GFXD3D11TextureFormat[mFaceFormat];
+	SMViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
+   SMViewDesc.TextureCube.MipLevels = -1;
+	SMViewDesc.TextureCube.MostDetailedMip = 0;
+
+	hr = D3D11DEVICE->CreateShaderResourceView(mTexture, &SMViewDesc, &mSRView);
+
+
+	if(FAILED(hr)) 
+	{
+		AssertFatal(false, "GFXD3D11Cubemap::initDynamic - CreateTexture2D call failure");
+	}
+
+   D3D11_RENDER_TARGET_VIEW_DESC viewDesc;
+	viewDesc.Format = desc.Format;
+	viewDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
+	viewDesc.Texture2DArray.ArraySize = 1;
+	viewDesc.Texture2DArray.MipSlice = 0;
+
+   for (U32 i = 0; i < CubeFaces; i++)
+	{
+		viewDesc.Texture2DArray.FirstArraySlice = i;
+      hr = D3D11DEVICE->CreateRenderTargetView(mTexture, &viewDesc, &mRTView[i]);
+
+		if(FAILED(hr)) 
+		{
+			AssertFatal(false, "GFXD3D11Cubemap::initDynamic - CreateRenderTargetView call failure");
+		}
+	}
+
+   D3D11_TEXTURE2D_DESC depthTexDesc;
+   depthTexDesc.Width = mTexSize;
+   depthTexDesc.Height = mTexSize;
+   depthTexDesc.MipLevels = 1;
+   depthTexDesc.ArraySize = 1;
+   depthTexDesc.SampleDesc.Count = 1;
+   depthTexDesc.SampleDesc.Quality = 0;
+   depthTexDesc.Format = DXGI_FORMAT_D32_FLOAT;
+   depthTexDesc.Usage = D3D11_USAGE_DEFAULT;
+   depthTexDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
+   depthTexDesc.CPUAccessFlags = 0;
+   depthTexDesc.MiscFlags = 0;
+
+   ID3D11Texture2D* depthTex = 0;
+   hr = D3D11DEVICE->CreateTexture2D(&depthTexDesc, 0, &depthTex);
+
+	if(FAILED(hr)) 
+	{
+		AssertFatal(false, "GFXD3D11Cubemap::initDynamic - CreateTexture2D for depth stencil call failure");
+	}
+
+   // Create the depth stencil view for the entire cube
+   D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
+   dsvDesc.Format = depthTexDesc.Format; //The format must match the depth texture we created above
+   dsvDesc.Flags  = 0;
+   dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
+   dsvDesc.Texture2D.MipSlice = 0;
+   hr = D3D11DEVICE->CreateDepthStencilView(depthTex, &dsvDesc, &mDSView);
+
+	if(FAILED(hr)) 
+	{
+      AssertFatal(false, "GFXD3D11Cubemap::initDynamic - CreateDepthStencilView call failure");
+	}
+
+   SAFE_RELEASE(depthTex);
+
+}
+
+//-----------------------------------------------------------------------------
+// Set the cubemap to the specified texture unit num
+//-----------------------------------------------------------------------------
+void GFXD3D11Cubemap::setToTexUnit(U32 tuNum)
+{
+   D3D11DEVICECONTEXT->PSSetShaderResources(tuNum, 1, &mSRView);
+}
+
+void GFXD3D11Cubemap::zombify()
+{
+   // Static cubemaps are handled by D3D
+   if( mDynamic )
+      releaseSurfaces();
+}
+
+void GFXD3D11Cubemap::resurrect()
+{
+   // Static cubemaps are handled by D3D
+   if( mDynamic )
+      initDynamic( mTexSize, mFaceFormat );
+}
+
+ID3D11ShaderResourceView* GFXD3D11Cubemap::getSRView()
+{
+   return mSRView;
+}
+
+ID3D11RenderTargetView* GFXD3D11Cubemap::getRTView(U32 faceIdx)
+{
+   AssertFatal(faceIdx < CubeFaces, "GFXD3D11Cubemap::getRTView - face index out of bounds");
+
+   return mRTView[faceIdx];
+}
+
+ID3D11RenderTargetView** GFXD3D11Cubemap::getRTViewArray()
+{
+   return mRTView;
+}
+
+ID3D11DepthStencilView* GFXD3D11Cubemap::getDSView()
+{
+   return mDSView;
+}
+
+ID3D11Texture2D* GFXD3D11Cubemap::get2DTex()
+{
+   return mTexture;
+}

+ 80 - 0
Engine/source/gfx/D3D11/gfxD3D11Cubemap.h

@@ -0,0 +1,80 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+#ifndef _GFXD3D11CUBEMAP_H_
+#define _GFXD3D11CUBEMAP_H_
+
+#include "gfx/D3D11/gfxD3D11Device.h"
+#include "gfx/gfxCubemap.h"
+#include "gfx/gfxResource.h"
+#include "gfx/gfxTarget.h"
+
+const U32 CubeFaces = 6;
+
+class GFXD3D11Cubemap : public GFXCubemap
+{
+public:
+   virtual void initStatic( GFXTexHandle *faces );
+   virtual void initStatic( DDSFile *dds );
+   virtual void initDynamic( U32 texSize, GFXFormat faceFormat = GFXFormatR8G8B8A8 );
+   virtual void setToTexUnit( U32 tuNum );
+   virtual U32 getSize() const { return mTexSize; }
+   virtual GFXFormat getFormat() const { return mFaceFormat; }
+
+   GFXD3D11Cubemap();
+   virtual ~GFXD3D11Cubemap();
+
+   // GFXResource interface
+   virtual void zombify();
+   virtual void resurrect();
+
+   // Get functions
+   ID3D11ShaderResourceView* getSRView();
+   ID3D11RenderTargetView* getRTView(U32 faceIdx);
+   ID3D11RenderTargetView** getRTViewArray();
+   ID3D11DepthStencilView* getDSView();
+   ID3D11Texture2D* get2DTex();
+
+private:
+
+   friend class GFXD3D11TextureTarget;
+   friend class GFXD3D11Device;
+
+   ID3D11Texture2D* mTexture;
+   ID3D11ShaderResourceView* mSRView; // for shader resource input
+   ID3D11RenderTargetView* mRTView[CubeFaces]; // for render targets, 6 faces of the cubemap
+   ID3D11DepthStencilView* mDSView; //render target view for depth stencil
+
+   bool mAutoGenMips;
+   bool mDynamic;
+   U32  mTexSize;
+   GFXFormat mFaceFormat;
+   
+   void releaseSurfaces();
+
+   bool isCompressed(GFXFormat format);
+   /// The callback used to get texture events.
+   /// @see GFXTextureManager::addEventDelegate
+   void _onTextureEvent(GFXTexCallbackCode code);
+};
+
+#endif

+ 1721 - 0
Engine/source/gfx/D3D11/gfxD3D11Device.cpp

@@ -0,0 +1,1721 @@
+//-----------------------------------------------------------------------------
+// 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 "console/console.h"
+#include "core/stream/fileStream.h"
+#include "core/strings/unicode.h"
+#include "core/util/journal/process.h"
+#include "gfx/D3D11/gfxD3D11Device.h"
+#include "gfx/D3D11/gfxD3D11CardProfiler.h"
+#include "gfx/D3D11/gfxD3D11VertexBuffer.h"
+#include "gfx/D3D11/gfxD3D11EnumTranslate.h"
+#include "gfx/D3D11/gfxD3D11QueryFence.h"
+#include "gfx/D3D11/gfxD3D11OcclusionQuery.h"
+#include "gfx/D3D11/gfxD3D11Shader.h"
+#include "gfx/D3D11/gfxD3D11Target.h"
+#include "platformWin32/platformWin32.h"
+#include "windowManager/win32/win32Window.h"
+#include "windowManager/platformWindow.h"
+#include "gfx/D3D11/screenshotD3D11.h"
+#include "materials/shaderData.h"
+
+#ifdef TORQUE_DEBUG
+#include "d3d11sdklayers.h"
+#endif
+
+#pragma comment(lib, "dxgi.lib")
+#pragma comment(lib, "d3d11.lib")
+
+GFXAdapter::CreateDeviceInstanceDelegate GFXD3D11Device::mCreateDeviceInstance(GFXD3D11Device::createInstance);
+
+GFXDevice *GFXD3D11Device::createInstance(U32 adapterIndex)
+{
+   GFXD3D11Device* dev = new GFXD3D11Device(adapterIndex);
+   return dev;
+}
+
+GFXFormat GFXD3D11Device::selectSupportedFormat(GFXTextureProfile *profile, const Vector<GFXFormat> &formats, bool texture, bool mustblend, bool mustfilter)
+{
+   U32 features = 0;
+   if(texture)
+       features |= D3D11_FORMAT_SUPPORT_TEXTURE2D;
+   if(mustblend)
+       features |= D3D11_FORMAT_SUPPORT_BLENDABLE;
+   if(mustfilter)
+       features |= D3D11_FORMAT_SUPPORT_SHADER_SAMPLE;
+   
+   for(U32 i = 0; i < formats.size(); i++)
+   {
+      if(GFXD3D11TextureFormat[formats[i]] == DXGI_FORMAT_UNKNOWN)
+         continue;
+
+      U32 supportFlag = 0;
+      mD3DDevice->CheckFormatSupport(GFXD3D11TextureFormat[formats[i]],&supportFlag);
+      if(supportFlag & features)
+         return formats[i];
+   }
+   
+   return GFXFormatR8G8B8A8;
+}
+
+DXGI_SWAP_CHAIN_DESC GFXD3D11Device::setupPresentParams(const GFXVideoMode &mode, const HWND &hwnd)
+{
+   DXGI_SWAP_CHAIN_DESC d3dpp;
+   ZeroMemory(&d3dpp, sizeof(d3dpp));
+
+   DXGI_SAMPLE_DESC sampleDesc;
+   sampleDesc.Count = 1;
+   sampleDesc.Quality = 0;
+
+   mMultisampleDesc = sampleDesc;
+
+   d3dpp.BufferCount = !smDisableVSync ? 2 : 1; // triple buffering when vsync is on.
+   d3dpp.BufferDesc.Width = mode.resolution.x;
+   d3dpp.BufferDesc.Height = mode.resolution.y;
+   d3dpp.BufferDesc.Format = GFXD3D11TextureFormat[GFXFormatR8G8B8A8];
+   d3dpp.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
+   d3dpp.OutputWindow = hwnd;
+   d3dpp.SampleDesc = sampleDesc;
+   d3dpp.Windowed = !mode.fullScreen;
+   d3dpp.BufferDesc.RefreshRate.Numerator = mode.refreshRate;
+   d3dpp.BufferDesc.RefreshRate.Denominator = 1;
+   d3dpp.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
+
+   if (mode.fullScreen)
+   {
+      d3dpp.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
+      d3dpp.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
+      d3dpp.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
+   }
+
+   return d3dpp;
+}
+
+void GFXD3D11Device::enumerateAdapters(Vector<GFXAdapter*> &adapterList)
+{
+   IDXGIAdapter1* EnumAdapter;
+   IDXGIFactory1* DXGIFactory;
+
+   CreateDXGIFactory1(__uuidof(IDXGIFactory1), reinterpret_cast<void**>(&DXGIFactory));
+
+   for(U32 adapterIndex = 0; DXGIFactory->EnumAdapters1(adapterIndex, &EnumAdapter) != DXGI_ERROR_NOT_FOUND; ++adapterIndex) 
+   {
+		GFXAdapter *toAdd = new GFXAdapter;
+		toAdd->mType  = Direct3D11;
+		toAdd->mIndex = adapterIndex;
+		toAdd->mCreateDeviceInstanceDelegate = mCreateDeviceInstance;
+
+		toAdd->mShaderModel = 5.0f;
+		DXGI_ADAPTER_DESC1 desc;
+		EnumAdapter->GetDesc1(&desc);
+
+		size_t size=wcslen(desc.Description);
+		char *str = new char[size+1];
+
+		wcstombs(str, desc.Description,size);
+		str[size]='\0';
+		String Description=str;
+      SAFE_DELETE_ARRAY(str);
+
+		dStrncpy(toAdd->mName, Description.c_str(), GFXAdapter::MaxAdapterNameLen);
+		dStrncat(toAdd->mName, " (D3D11)", GFXAdapter::MaxAdapterNameLen);
+
+		IDXGIOutput* pOutput = NULL; 
+		HRESULT hr;
+
+		hr = EnumAdapter->EnumOutputs(adapterIndex, &pOutput);
+
+		if(hr == DXGI_ERROR_NOT_FOUND)
+		{
+         SAFE_RELEASE(EnumAdapter);
+			break;
+		}
+
+		if(FAILED(hr))
+			AssertFatal(false, "GFXD3D11Device::enumerateAdapters -> EnumOutputs call failure");
+
+		UINT numModes = 0;
+		DXGI_MODE_DESC* displayModes = NULL;
+		DXGI_FORMAT format = DXGI_FORMAT_B8G8R8A8_UNORM;
+
+		// Get the number of elements
+		hr = pOutput->GetDisplayModeList(format, 0, &numModes, NULL);
+
+		if(FAILED(hr))
+			AssertFatal(false, "GFXD3D11Device::enumerateAdapters -> GetDisplayModeList call failure");
+
+		displayModes = new DXGI_MODE_DESC[numModes]; 
+
+		// Get the list
+		hr = pOutput->GetDisplayModeList(format, 0, &numModes, displayModes);
+
+		if(FAILED(hr))
+			AssertFatal(false, "GFXD3D11Device::enumerateAdapters -> GetDisplayModeList call failure");
+
+		for(U32 numMode = 0; numMode < numModes; ++numMode)
+		{
+			GFXVideoMode vmAdd;
+
+			vmAdd.fullScreen = true;
+			vmAdd.bitDepth = 32;
+			vmAdd.refreshRate = displayModes[numMode].RefreshRate.Numerator / displayModes[numMode].RefreshRate.Denominator;
+			vmAdd.resolution.x = displayModes[numMode].Width;
+			vmAdd.resolution.y = displayModes[numMode].Height;
+			toAdd->mAvailableModes.push_back(vmAdd);
+		}
+
+		delete[] displayModes;
+      SAFE_RELEASE(pOutput);
+      SAFE_RELEASE(EnumAdapter);
+	   adapterList.push_back(toAdd);
+   }
+
+   SAFE_RELEASE(DXGIFactory);
+}
+
+void GFXD3D11Device::enumerateVideoModes() 
+{
+   mVideoModes.clear();
+
+   IDXGIAdapter1* EnumAdapter;
+   IDXGIFactory1* DXGIFactory;
+   HRESULT hr;
+
+   hr = CreateDXGIFactory1(__uuidof(IDXGIFactory1), reinterpret_cast<void**>(&DXGIFactory));
+
+   if (FAILED(hr))
+      AssertFatal(false, "GFXD3D11Device::enumerateVideoModes -> CreateDXGIFactory1 call failure");
+
+   for(U32 adapterIndex = 0; DXGIFactory->EnumAdapters1(adapterIndex, &EnumAdapter) != DXGI_ERROR_NOT_FOUND; ++adapterIndex) 
+   {
+		IDXGIOutput* pOutput = NULL;		
+
+		hr = EnumAdapter->EnumOutputs(adapterIndex, &pOutput);
+
+		if(hr == DXGI_ERROR_NOT_FOUND)
+		{
+         SAFE_RELEASE(EnumAdapter);
+			break;
+		}
+
+		if(FAILED(hr))
+			AssertFatal(false, "GFXD3D11Device::enumerateVideoModes -> EnumOutputs call failure");
+
+		UINT numModes = 0;
+		DXGI_MODE_DESC* displayModes = NULL;
+		DXGI_FORMAT format = GFXD3D11TextureFormat[GFXFormatR8G8B8A8];
+
+		// Get the number of elements
+		hr = pOutput->GetDisplayModeList(format, 0, &numModes, NULL);
+
+		if(FAILED(hr))
+			AssertFatal(false, "GFXD3D11Device::enumerateVideoModes -> GetDisplayModeList call failure");
+
+		displayModes = new DXGI_MODE_DESC[numModes]; 
+
+		// Get the list
+		hr = pOutput->GetDisplayModeList(format, 0, &numModes, displayModes);
+
+		if(FAILED(hr))
+			AssertFatal(false, "GFXD3D11Device::enumerateVideoModes -> GetDisplayModeList call failure");
+
+		for(U32 numMode = 0; numMode < numModes; ++numMode)
+		{
+			GFXVideoMode toAdd;
+
+			toAdd.fullScreen = false;
+			toAdd.bitDepth = 32;
+			toAdd.refreshRate = displayModes[numMode].RefreshRate.Numerator / displayModes[numMode].RefreshRate.Denominator;
+			toAdd.resolution.x = displayModes[numMode].Width;
+			toAdd.resolution.y = displayModes[numMode].Height;
+			mVideoModes.push_back(toAdd);
+		}
+
+		delete[] displayModes;
+      SAFE_RELEASE(pOutput);
+      SAFE_RELEASE(EnumAdapter);
+   }
+
+   SAFE_RELEASE(DXGIFactory);
+}
+
+IDXGISwapChain* GFXD3D11Device::getSwapChain()
+{
+	return mSwapChain;
+}
+
+void GFXD3D11Device::init(const GFXVideoMode &mode, PlatformWindow *window)
+{
+   AssertFatal(window, "GFXD3D11Device::init - must specify a window!");
+
+   HWND winHwnd = (HWND)window->getSystemWindow( PlatformWindow::WindowSystem_Windows );
+
+   UINT createDeviceFlags = D3D11_CREATE_DEVICE_SINGLETHREADED | D3D11_CREATE_DEVICE_BGRA_SUPPORT;
+#ifdef TORQUE_DEBUG
+   createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
+   mDebugLayers = true;
+#endif
+
+   DXGI_SWAP_CHAIN_DESC d3dpp = setupPresentParams(mode, winHwnd);
+
+   D3D_FEATURE_LEVEL deviceFeature;
+   D3D_DRIVER_TYPE driverType = D3D_DRIVER_TYPE_HARDWARE;// use D3D_DRIVER_TYPE_REFERENCE for reference device
+   // create a device, device context and swap chain using the information in the d3dpp struct
+   HRESULT hres = D3D11CreateDeviceAndSwapChain(NULL,
+                                 driverType,
+											NULL,
+											createDeviceFlags,
+											NULL,
+											0,
+											D3D11_SDK_VERSION,
+											&d3dpp,
+											&mSwapChain,
+											&mD3DDevice,
+											&deviceFeature,
+											&mD3DDeviceContext);
+
+	if(FAILED(hres))
+	{
+      #ifdef TORQUE_DEBUG
+      //try again without debug device layer enabled
+      createDeviceFlags &= ~D3D11_CREATE_DEVICE_DEBUG;
+      HRESULT hres = D3D11CreateDeviceAndSwapChain(NULL, driverType,NULL,createDeviceFlags,NULL, 0,
+         D3D11_SDK_VERSION,
+         &d3dpp,
+         &mSwapChain,
+         &mD3DDevice,
+         &deviceFeature,
+         &mD3DDeviceContext);
+      //if we failed again than we definitely have a problem
+      if (FAILED(hres))
+         AssertFatal(false, "GFXD3D11Device::init - D3D11CreateDeviceAndSwapChain failed!");
+
+      Con::warnf("GFXD3D11Device::init - Debug layers not detected!");
+      mDebugLayers = false;
+      #else
+		AssertFatal(false, "GFXD3D11Device::init - D3D11CreateDeviceAndSwapChain failed!");
+      #endif
+	}
+
+   //set the fullscreen state here if we need to
+   if(mode.fullScreen)
+   {
+      hres = mSwapChain->SetFullscreenState(TRUE, NULL);
+      if(FAILED(hres))
+      {
+         AssertFatal(false, "GFXD3D11Device::init- Failed to set fullscreen state!");
+      }
+   }
+
+	mTextureManager = new GFXD3D11TextureManager();
+
+	// Now reacquire all the resources we trashed earlier
+	reacquireDefaultPoolResources();
+   //TODO implement feature levels?
+	if (deviceFeature >= D3D_FEATURE_LEVEL_11_0)
+		mPixVersion = 5.0f;
+	else
+		AssertFatal(false, "GFXD3D11Device::init - We don't support anything below feature level 11.");
+
+	D3D11_QUERY_DESC queryDesc;
+   queryDesc.Query = D3D11_QUERY_OCCLUSION;
+   queryDesc.MiscFlags = 0;
+
+	ID3D11Query *testQuery = NULL;
+
+	// detect occlusion query support
+	if (SUCCEEDED(mD3DDevice->CreateQuery(&queryDesc, &testQuery))) mOcclusionQuerySupported = true;
+
+   SAFE_RELEASE(testQuery);
+
+	Con::printf("Hardware occlusion query detected: %s", mOcclusionQuerySupported ? "Yes" : "No");
+   
+	mCardProfiler = new GFXD3D11CardProfiler();
+	mCardProfiler->init();
+
+	D3D11_TEXTURE2D_DESC desc;
+	desc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
+	desc.CPUAccessFlags = 0;
+	desc.Format = GFXD3D11TextureFormat[GFXFormatD24S8];
+	desc.MipLevels = 1;
+	desc.ArraySize = 1;
+	desc.Usage = D3D11_USAGE_DEFAULT;
+	desc.Width = mode.resolution.x;
+	desc.Height = mode.resolution.y;
+	desc.SampleDesc.Count =1;
+	desc.SampleDesc.Quality =0;
+	desc.MiscFlags = 0;
+
+	HRESULT hr = mD3DDevice->CreateTexture2D(&desc, NULL, &mDeviceDepthStencil);
+	if(FAILED(hr)) 
+	{
+		AssertFatal(false, "GFXD3D11Device::init - couldn't create device's depth-stencil surface.");
+	}
+
+	D3D11_DEPTH_STENCIL_VIEW_DESC depthDesc;
+	depthDesc.Format = GFXD3D11TextureFormat[GFXFormatD24S8];
+	depthDesc.Flags =0 ;
+	depthDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
+	depthDesc.Texture2D.MipSlice = 0;
+
+	hr = mD3DDevice->CreateDepthStencilView(mDeviceDepthStencil, &depthDesc, &mDeviceDepthStencilView);
+
+	if(FAILED(hr))
+	{
+		AssertFatal(false, "GFXD3D11Device::init - couldn't create depth stencil view");
+	}
+
+	hr = mSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&mDeviceBackbuffer);
+	if(FAILED(hr))
+	  AssertFatal(false, "GFXD3D11Device::init - coudln't retrieve backbuffer ref");
+
+	//create back buffer view
+	D3D11_RENDER_TARGET_VIEW_DESC RTDesc;
+
+	RTDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
+	RTDesc.Texture2D.MipSlice = 0;
+	RTDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
+
+	hr = mD3DDevice->CreateRenderTargetView(mDeviceBackbuffer, &RTDesc, &mDeviceBackBufferView);
+
+	if(FAILED(hr))
+		 AssertFatal(false, "GFXD3D11Device::init - couldn't create back buffer target view");
+
+#ifdef TORQUE_DEBUG
+   String backBufferName = "MainBackBuffer";
+   String depthSteniclName = "MainDepthStencil";
+   String backBuffViewName = "MainBackBuffView";
+   String depthStencViewName = "MainDepthView";
+   mDeviceBackbuffer->SetPrivateData(WKPDID_D3DDebugObjectName, backBufferName.size(), backBufferName.c_str());
+   mDeviceDepthStencil->SetPrivateData(WKPDID_D3DDebugObjectName, depthSteniclName.size(), depthSteniclName.c_str());
+   mDeviceDepthStencilView->SetPrivateData(WKPDID_D3DDebugObjectName, depthStencViewName.size(), depthStencViewName.c_str());
+   mDeviceBackBufferView->SetPrivateData(WKPDID_D3DDebugObjectName, backBuffViewName.size(), backBuffViewName.c_str());
+
+   _suppressDebugMessages();
+
+#endif
+
+   gScreenShot = new ScreenShotD3D11;
+
+	mInitialized = true;
+	deviceInited();
+}
+
+// Supress any debug layer messages we don't want to see
+void GFXD3D11Device::_suppressDebugMessages()
+{
+   if (mDebugLayers)
+   {
+      ID3D11Debug *pDebug = NULL;
+      if (SUCCEEDED(mD3DDevice->QueryInterface(__uuidof(ID3D11Debug), (void**)&pDebug)))
+      {
+         ID3D11InfoQueue *pInfoQueue = NULL;
+         if (SUCCEEDED(pDebug->QueryInterface(__uuidof(ID3D11InfoQueue), (void**)&pInfoQueue)))
+         {
+            //Disable breaking on error or corruption, this can be handy when using VS graphics debugging
+            pInfoQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_CORRUPTION, false);
+            pInfoQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_ERROR, false);
+
+            D3D11_MESSAGE_ID hide[] =
+            {
+               //this is harmless and no need to spam the console
+               D3D11_MESSAGE_ID_QUERY_BEGIN_ABANDONING_PREVIOUS_RESULTS
+            };
+
+            D3D11_INFO_QUEUE_FILTER filter;
+            memset(&filter, 0, sizeof(filter));
+            filter.DenyList.NumIDs = _countof(hide);
+            filter.DenyList.pIDList = hide;
+            pInfoQueue->AddStorageFilterEntries(&filter);
+            SAFE_RELEASE(pInfoQueue);
+         }
+         SAFE_RELEASE(pDebug);
+      }
+   }
+}
+
+bool GFXD3D11Device::beginSceneInternal() 
+{
+   mCanCurrentlyRender = true;
+   return mCanCurrentlyRender;  
+}
+
+GFXWindowTarget * GFXD3D11Device::allocWindowTarget(PlatformWindow *window)
+{
+   AssertFatal(window,"GFXD3D11Device::allocWindowTarget - no window provided!");
+
+   // Allocate the device.
+   init(window->getVideoMode(), window);
+
+   // Set up a new window target...
+   GFXD3D11WindowTarget *gdwt = new GFXD3D11WindowTarget();
+   gdwt->mWindow = window;
+   gdwt->mSize = window->getClientExtent();
+   gdwt->initPresentationParams();
+   gdwt->registerResourceWithDevice(this);
+
+   return gdwt;
+}
+
+GFXTextureTarget* GFXD3D11Device::allocRenderToTextureTarget()
+{
+   GFXD3D11TextureTarget *targ = new GFXD3D11TextureTarget();
+   targ->registerResourceWithDevice(this);
+
+   return targ;
+}
+
+void GFXD3D11Device::reset(DXGI_SWAP_CHAIN_DESC &d3dpp)
+{
+	if (!mD3DDevice)
+		return;
+
+	mInitialized = false;
+
+	// Clean up some commonly dangling state. This helps prevents issues with
+	// items that are destroyed by the texture manager callbacks and recreated
+	// later, but still left bound.
+	setVertexBuffer(NULL);
+	setPrimitiveBuffer(NULL);
+	for (S32 i = 0; i<getNumSamplers(); i++)
+		setTexture(i, NULL);
+
+	mD3DDeviceContext->ClearState();
+
+	DXGI_MODE_DESC displayModes;
+	displayModes.Format = d3dpp.BufferDesc.Format;
+	displayModes.Height = d3dpp.BufferDesc.Height;
+	displayModes.Width = d3dpp.BufferDesc.Width;
+	displayModes.RefreshRate = d3dpp.BufferDesc.RefreshRate;
+	displayModes.Scaling = d3dpp.BufferDesc.Scaling;
+	displayModes.ScanlineOrdering = d3dpp.BufferDesc.ScanlineOrdering;
+
+   HRESULT hr;
+   if (!d3dpp.Windowed)
+   {
+      hr = mSwapChain->ResizeTarget(&displayModes);
+
+      if (FAILED(hr))
+      {
+         AssertFatal(false, "D3D11Device::reset - failed to resize target!");
+      }
+   }
+
+	// First release all the stuff we allocated from D3DPOOL_DEFAULT
+	releaseDefaultPoolResources();
+
+	//release the backbuffer, depthstencil, and their views
+	SAFE_RELEASE(mDeviceBackBufferView);
+	SAFE_RELEASE(mDeviceBackbuffer);
+	SAFE_RELEASE(mDeviceDepthStencilView);
+	SAFE_RELEASE(mDeviceDepthStencil);
+
+   hr = mSwapChain->ResizeBuffers(d3dpp.BufferCount, d3dpp.BufferDesc.Width, d3dpp.BufferDesc.Height, d3dpp.BufferDesc.Format, d3dpp.Windowed ? 0 : DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH);
+
+	if (FAILED(hr))
+	{
+		AssertFatal(false, "D3D11Device::reset - failed to resize back buffer!");
+	}
+
+	//recreate backbuffer view. depth stencil view and texture
+	D3D11_TEXTURE2D_DESC desc;
+	desc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
+	desc.CPUAccessFlags = 0;
+	desc.Format = GFXD3D11TextureFormat[GFXFormatD24S8];
+	desc.MipLevels = 1;
+	desc.ArraySize = 1;
+	desc.Usage = D3D11_USAGE_DEFAULT;
+	desc.Width = d3dpp.BufferDesc.Width;
+	desc.Height = d3dpp.BufferDesc.Height;
+	desc.SampleDesc.Count = 1;
+	desc.SampleDesc.Quality = 0;
+	desc.MiscFlags = 0;
+
+	hr = mD3DDevice->CreateTexture2D(&desc, NULL, &mDeviceDepthStencil);
+	if (FAILED(hr))
+	{
+		AssertFatal(false, "GFXD3D11Device::reset - couldn't create device's depth-stencil surface.");
+	}
+
+	D3D11_DEPTH_STENCIL_VIEW_DESC depthDesc;
+	depthDesc.Format = GFXD3D11TextureFormat[GFXFormatD24S8];
+	depthDesc.Flags = 0;
+	depthDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
+	depthDesc.Texture2D.MipSlice = 0;
+
+	hr = mD3DDevice->CreateDepthStencilView(mDeviceDepthStencil, &depthDesc, &mDeviceDepthStencilView);
+
+	if (FAILED(hr))
+	{
+		AssertFatal(false, "GFXD3D11Device::reset - couldn't create depth stencil view");
+	}
+
+	hr = mSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&mDeviceBackbuffer);
+	if (FAILED(hr))
+		AssertFatal(false, "GFXD3D11Device::reset - coudln't retrieve backbuffer ref");
+
+	//create back buffer view
+	D3D11_RENDER_TARGET_VIEW_DESC RTDesc;
+
+	RTDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
+	RTDesc.Texture2D.MipSlice = 0;
+	RTDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
+
+	hr = mD3DDevice->CreateRenderTargetView(mDeviceBackbuffer, &RTDesc, &mDeviceBackBufferView);
+
+	if (FAILED(hr))
+		AssertFatal(false, "GFXD3D11Device::reset - couldn't create back buffer target view");
+
+   mD3DDeviceContext->OMSetRenderTargets(1, &mDeviceBackBufferView, mDeviceDepthStencilView);
+
+	hr = mSwapChain->SetFullscreenState(!d3dpp.Windowed, NULL);
+
+	if (FAILED(hr))
+	{
+      AssertFatal(false, "D3D11Device::reset - failed to change screen states!");
+	}
+
+   //Microsoft recommend this, see DXGI documentation
+   if (!d3dpp.Windowed)
+   {
+      displayModes.RefreshRate.Numerator = 0;
+      displayModes.RefreshRate.Denominator = 0;
+      hr = mSwapChain->ResizeTarget(&displayModes);
+
+      if (FAILED(hr))
+      {
+         AssertFatal(false, "D3D11Device::reset - failed to resize target!");
+      }
+   }
+
+	mInitialized = true;
+
+	// Now re aquire all the resources we trashed earlier
+	reacquireDefaultPoolResources();
+
+	// Mark everything dirty and flush to card, for sanity.
+	updateStates(true);
+}
+
+class GFXPCD3D11RegisterDevice
+{
+public:
+   GFXPCD3D11RegisterDevice()
+   {
+      GFXInit::getRegisterDeviceSignal().notify(&GFXD3D11Device::enumerateAdapters);
+   }
+};
+
+static GFXPCD3D11RegisterDevice pPCD3D11RegisterDevice;
+
+//-----------------------------------------------------------------------------
+/// Parse command line arguments for window creation
+//-----------------------------------------------------------------------------
+static void sgPCD3D11DeviceHandleCommandLine(S32 argc, const char **argv)
+{
+   // useful to pass parameters by command line for d3d (e.g. -dx9 -dx11)
+   for (U32 i = 1; i < argc; i++)
+   {
+      argv[i];
+   }   
+}
+
+// Register the command line parsing hook
+static ProcessRegisterCommandLine sgCommandLine( sgPCD3D11DeviceHandleCommandLine );
+
+GFXD3D11Device::GFXD3D11Device(U32 index)
+{
+   mDeviceSwizzle32 = &Swizzles::bgra;
+   GFXVertexColor::setSwizzle( mDeviceSwizzle32 );
+
+   mDeviceSwizzle24 = &Swizzles::bgr;
+
+   mAdapterIndex = index;
+   mD3DDevice = NULL;
+   mVolatileVB = NULL;
+
+   mCurrentPB = NULL;
+   mDynamicPB = NULL;
+
+   mLastVertShader = NULL;
+   mLastPixShader = NULL;
+
+   mCanCurrentlyRender = false;
+   mTextureManager = NULL;
+   mCurrentStateBlock = NULL;
+   mResourceListHead = NULL;
+
+   mPixVersion = 0.0;
+
+   mDrawInstancesCount = 0;
+
+   mCardProfiler = NULL;
+
+   mDeviceDepthStencil = NULL;
+   mDeviceBackbuffer = NULL;
+   mDeviceBackBufferView = NULL;
+   mDeviceDepthStencilView = NULL;
+
+   mCreateFenceType = -1; // Unknown, test on first allocate
+
+   mCurrentConstBuffer = NULL;
+
+   mOcclusionQuerySupported = false;
+
+   mDebugLayers = false;
+
+   for(U32 i = 0; i < GS_COUNT; ++i)
+      mModelViewProjSC[i] = NULL;
+
+   // Set up the Enum translation tables
+   GFXD3D11EnumTranslate::init();
+}
+
+GFXD3D11Device::~GFXD3D11Device() 
+{
+   // Release our refcount on the current stateblock object
+   mCurrentStateBlock = NULL;
+
+   releaseDefaultPoolResources();
+
+   mD3DDeviceContext->ClearState();
+   mD3DDeviceContext->Flush();
+
+   // Free the vertex declarations.
+   VertexDeclMap::Iterator iter = mVertexDecls.begin();
+   for ( ; iter != mVertexDecls.end(); iter++ )
+      delete iter->value;
+
+   // Forcibly clean up the pools
+   mVolatileVBList.setSize(0);
+   mDynamicPB = NULL;
+
+   // And release our D3D resources.
+   SAFE_RELEASE(mDeviceDepthStencilView);
+   SAFE_RELEASE(mDeviceBackBufferView);
+   SAFE_RELEASE(mDeviceDepthStencil);
+   SAFE_RELEASE(mDeviceBackbuffer);
+   SAFE_RELEASE(mD3DDeviceContext);
+
+   SAFE_DELETE(mCardProfiler);
+   SAFE_DELETE(gScreenShot);
+
+#ifdef TORQUE_DEBUG
+   if (mDebugLayers)
+   {
+      ID3D11Debug *pDebug = NULL;
+      mD3DDevice->QueryInterface(IID_PPV_ARGS(&pDebug));
+      AssertFatal(pDebug, "~GFXD3D11Device- Failed to get debug layer");
+      pDebug->ReportLiveDeviceObjects(D3D11_RLDO_DETAIL);
+      SAFE_RELEASE(pDebug);
+   }
+#endif
+   
+   SAFE_RELEASE(mSwapChain);
+   SAFE_RELEASE(mD3DDevice);
+}
+
+void GFXD3D11Device::setupGenericShaders(GenericShaderType type)
+{
+   AssertFatal(type != GSTargetRestore, ""); //not used
+
+   if(mGenericShader[GSColor] == NULL)
+   {
+      ShaderData *shaderData;
+
+      shaderData = new ShaderData();
+      shaderData->setField("DXVertexShaderFile", "shaders/common/fixedFunction/colorV.hlsl");
+      shaderData->setField("DXPixelShaderFile", "shaders/common/fixedFunction/colorP.hlsl");
+      shaderData->setField("pixVersion", "5.0");
+      shaderData->registerObject();
+      mGenericShader[GSColor] =  shaderData->getShader();
+      mGenericShaderBuffer[GSColor] = mGenericShader[GSColor]->allocConstBuffer();
+      mModelViewProjSC[GSColor] = mGenericShader[GSColor]->getShaderConstHandle("$modelView");
+      Sim::getRootGroup()->addObject(shaderData);
+
+      shaderData = new ShaderData();
+      shaderData->setField("DXVertexShaderFile", "shaders/common/fixedFunction/modColorTextureV.hlsl");
+      shaderData->setField("DXPixelShaderFile", "shaders/common/fixedFunction/modColorTextureP.hlsl");
+      shaderData->setField("pixVersion", "5.0");
+      shaderData->registerObject();
+      mGenericShader[GSModColorTexture] = shaderData->getShader();
+      mGenericShaderBuffer[GSModColorTexture] = mGenericShader[GSModColorTexture]->allocConstBuffer();
+      mModelViewProjSC[GSModColorTexture] = mGenericShader[GSModColorTexture]->getShaderConstHandle("$modelView");
+      Sim::getRootGroup()->addObject(shaderData);
+
+      shaderData = new ShaderData();
+      shaderData->setField("DXVertexShaderFile", "shaders/common/fixedFunction/addColorTextureV.hlsl");
+      shaderData->setField("DXPixelShaderFile", "shaders/common/fixedFunction/addColorTextureP.hlsl");
+      shaderData->setField("pixVersion", "5.0");
+      shaderData->registerObject();
+      mGenericShader[GSAddColorTexture] = shaderData->getShader();
+      mGenericShaderBuffer[GSAddColorTexture] = mGenericShader[GSAddColorTexture]->allocConstBuffer();
+      mModelViewProjSC[GSAddColorTexture] = mGenericShader[GSAddColorTexture]->getShaderConstHandle("$modelView");
+      Sim::getRootGroup()->addObject(shaderData);
+
+      shaderData = new ShaderData();
+      shaderData->setField("DXVertexShaderFile", "shaders/common/fixedFunction/textureV.hlsl");
+      shaderData->setField("DXPixelShaderFile", "shaders/common/fixedFunction/textureP.hlsl");
+      shaderData->setField("pixVersion", "5.0");
+      shaderData->registerObject();
+      mGenericShader[GSTexture] = shaderData->getShader();
+      mGenericShaderBuffer[GSTexture] = mGenericShader[GSTexture]->allocConstBuffer();
+      mModelViewProjSC[GSTexture] = mGenericShader[GSTexture]->getShaderConstHandle("$modelView");
+      Sim::getRootGroup()->addObject(shaderData);
+
+      //Force an update
+      mViewportDirty = true;
+      _updateRenderTargets();
+   }
+
+   MatrixF tempMatrix =  mProjectionMatrix * mViewMatrix * mWorldMatrix[mWorldStackSize];  
+   mGenericShaderBuffer[type]->setSafe(mModelViewProjSC[type], tempMatrix);
+
+   setShader(mGenericShader[type]);
+   setShaderConstBuffer(mGenericShaderBuffer[type]);
+}
+
+//-----------------------------------------------------------------------------
+/// Creates a state block object based on the desc passed in.  This object
+/// represents an immutable state.
+GFXStateBlockRef GFXD3D11Device::createStateBlockInternal(const GFXStateBlockDesc& desc)
+{
+   return GFXStateBlockRef(new GFXD3D11StateBlock(desc));
+}
+
+/// Activates a stateblock
+void GFXD3D11Device::setStateBlockInternal(GFXStateBlock* block, bool force)
+{
+   AssertFatal(static_cast<GFXD3D11StateBlock*>(block), "Incorrect stateblock type for this device!");
+   GFXD3D11StateBlock* d3dBlock = static_cast<GFXD3D11StateBlock*>(block);
+   GFXD3D11StateBlock* d3dCurrent = static_cast<GFXD3D11StateBlock*>(mCurrentStateBlock.getPointer());
+
+   if (force)
+      d3dCurrent = NULL;
+
+   d3dBlock->activate(d3dCurrent);   
+}
+
+/// Called by base GFXDevice to actually set a const buffer
+void GFXD3D11Device::setShaderConstBufferInternal(GFXShaderConstBuffer* buffer)
+{
+   if (buffer)
+   {
+      PROFILE_SCOPE(GFXD3D11Device_setShaderConstBufferInternal);
+      AssertFatal(static_cast<GFXD3D11ShaderConstBuffer*>(buffer), "Incorrect shader const buffer type for this device!");
+      GFXD3D11ShaderConstBuffer* d3dBuffer = static_cast<GFXD3D11ShaderConstBuffer*>(buffer);
+
+      d3dBuffer->activate(mCurrentConstBuffer);
+      mCurrentConstBuffer = d3dBuffer;
+   }
+   else
+   {
+      mCurrentConstBuffer = NULL;
+   }
+}
+
+//-----------------------------------------------------------------------------
+
+void GFXD3D11Device::clear(U32 flags, ColorI color, F32 z, U32 stencil)
+{
+   // Make sure we have flushed our render target state.
+   _updateRenderTargets();
+
+   UINT depthstencilFlag = 0;
+
+   ID3D11RenderTargetView* rtView = NULL;
+   ID3D11DepthStencilView* dsView = NULL;
+
+   mD3DDeviceContext->OMGetRenderTargets(1, &rtView, &dsView);
+
+   const FLOAT clearColor[4] = {
+      static_cast<F32>(color.red) * (1.0f / 255.0f),
+      static_cast<F32>(color.green) * (1.0f / 255.0f),
+      static_cast<F32>(color.blue) * (1.0f / 255.0f),
+      static_cast<F32>(color.alpha) * (1.0f / 255.0f)
+   };
+
+   if (flags & GFXClearTarget && rtView)
+      mD3DDeviceContext->ClearRenderTargetView(rtView, clearColor);
+
+   if (flags & GFXClearZBuffer)
+      depthstencilFlag |= D3D11_CLEAR_DEPTH;
+
+   if (flags & GFXClearStencil)
+      depthstencilFlag |= D3D11_CLEAR_STENCIL;
+
+   if (depthstencilFlag && dsView)
+      mD3DDeviceContext->ClearDepthStencilView(dsView, depthstencilFlag, z, stencil);
+
+   SAFE_RELEASE(rtView);
+   SAFE_RELEASE(dsView);
+}
+
+void GFXD3D11Device::endSceneInternal() 
+{
+   mCanCurrentlyRender = false;
+}
+
+void GFXD3D11Device::_updateRenderTargets()
+{
+   if (mRTDirty || (mCurrentRT && mCurrentRT->isPendingState()))
+   {
+      if (mRTDeactivate)
+      {
+         mRTDeactivate->deactivate();
+         mRTDeactivate = NULL;   
+      }
+
+      // NOTE: The render target changes are not really accurate
+      // as the GFXTextureTarget supports MRT internally.  So when
+      // we activate a GFXTarget it could result in multiple calls
+      // to SetRenderTarget on the actual device.
+      mDeviceStatistics.mRenderTargetChanges++;
+
+      mCurrentRT->activate();
+
+      mRTDirty = false;
+   }  
+
+	if (mViewportDirty)
+	{
+		D3D11_VIEWPORT viewport;
+
+		viewport.TopLeftX = mViewport.point.x;
+		viewport.TopLeftY = mViewport.point.y;
+		viewport.Width = mViewport.extent.x;
+		viewport.Height = mViewport.extent.y;
+		viewport.MinDepth	= 0.0f;
+		viewport.MaxDepth	= 1.0f;
+
+		mD3DDeviceContext->RSSetViewports(1, &viewport);
+
+		mViewportDirty = false;
+   }
+}
+
+void GFXD3D11Device::releaseDefaultPoolResources() 
+{
+   // Release all the dynamic vertex buffer arrays
+   // Forcibly clean up the pools
+   for(U32 i=0; i<mVolatileVBList.size(); i++)
+   {
+      SAFE_RELEASE(mVolatileVBList[i]->vb);
+      mVolatileVBList[i] = NULL;
+   }
+   mVolatileVBList.setSize(0);
+
+   // We gotta clear the current const buffer else the next
+   // activate may erroneously think the device is still holding
+   // this state and fail to set it.   
+   mCurrentConstBuffer = NULL;
+
+   // Set current VB to NULL and set state dirty
+   for (U32 i=0; i < VERTEX_STREAM_COUNT; i++)
+   {
+      mCurrentVertexBuffer[i] = NULL;
+      mVertexBufferDirty[i] = true;
+      mVertexBufferFrequency[i] = 0;
+      mVertexBufferFrequencyDirty[i] = true;
+   }
+
+   // Release dynamic index buffer
+   if(mDynamicPB != NULL)
+   {
+      SAFE_RELEASE(mDynamicPB->ib);
+   }
+
+   // Set current PB/IB to NULL and set state dirty
+   mCurrentPrimitiveBuffer = NULL;
+   mCurrentPB = NULL;
+   mPrimitiveBufferDirty = true;
+
+   // Zombify texture manager (for D3D this only modifies default pool textures)
+   if( mTextureManager ) 
+      mTextureManager->zombify();
+
+   // Set global dirty state so the IB/PB and VB get reset
+   mStateDirty = true;
+
+   // Walk the resource list and zombify everything.
+   GFXResource *walk = mResourceListHead;
+   while(walk)
+   {
+      walk->zombify();
+      walk = walk->getNextResource();
+   }
+}
+
+void GFXD3D11Device::reacquireDefaultPoolResources() 
+{
+	// Now do the dynamic index buffers
+	if( mDynamicPB == NULL )
+		mDynamicPB = new GFXD3D11PrimitiveBuffer(this, 0, 0, GFXBufferTypeDynamic);
+
+	D3D11_BUFFER_DESC desc;
+	desc.ByteWidth = sizeof(U16) * MAX_DYNAMIC_INDICES;
+	desc.Usage = D3D11_USAGE_DYNAMIC;
+	desc.BindFlags = D3D11_BIND_INDEX_BUFFER;
+	desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
+	desc.MiscFlags = 0;
+	desc.StructureByteStride = 0;
+
+	HRESULT hr = D3D11DEVICE->CreateBuffer(&desc, NULL, &mDynamicPB->ib);
+
+	if(FAILED(hr)) 
+	{
+		AssertFatal(false, "Failed to allocate dynamic IB");
+	}
+
+	// Walk the resource list and zombify everything.
+	GFXResource *walk = mResourceListHead;
+	while(walk)
+	{
+		walk->resurrect();
+		walk = walk->getNextResource();
+	}
+
+	if(mTextureManager)
+		mTextureManager->resurrect();
+}
+
+GFXD3D11VertexBuffer* GFXD3D11Device::findVBPool( const GFXVertexFormat *vertexFormat, U32 vertsNeeded )
+{
+   PROFILE_SCOPE( GFXD3D11Device_findVBPool );
+
+   for( U32 i=0; i<mVolatileVBList.size(); i++ )
+      if( mVolatileVBList[i]->mVertexFormat.isEqual( *vertexFormat ) )
+         return mVolatileVBList[i];
+
+   return NULL;
+}
+
+GFXD3D11VertexBuffer * GFXD3D11Device::createVBPool( const GFXVertexFormat *vertexFormat, U32 vertSize )
+{
+	PROFILE_SCOPE( GFXD3D11Device_createVBPool );
+
+	// this is a bit funky, but it will avoid problems with (lack of) copy constructors
+	//    with a push_back() situation
+	mVolatileVBList.increment();
+	StrongRefPtr<GFXD3D11VertexBuffer> newBuff;
+	mVolatileVBList.last() = new GFXD3D11VertexBuffer();
+	newBuff = mVolatileVBList.last();
+
+	newBuff->mNumVerts   = 0;
+	newBuff->mBufferType = GFXBufferTypeVolatile;
+	newBuff->mVertexFormat.copy( *vertexFormat );
+	newBuff->mVertexSize = vertSize;
+	newBuff->mDevice = this;
+
+	// Requesting it will allocate it.
+	vertexFormat->getDecl(); 
+
+	D3D11_BUFFER_DESC desc;
+	desc.ByteWidth = vertSize * MAX_DYNAMIC_VERTS;
+	desc.Usage = D3D11_USAGE_DYNAMIC;
+	desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
+	desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
+	desc.MiscFlags = 0;
+	desc.StructureByteStride = 0;
+
+	HRESULT hr = D3D11DEVICE->CreateBuffer(&desc, NULL, &newBuff->vb);
+
+	if(FAILED(hr)) 
+	{
+		AssertFatal(false, "Failed to allocate dynamic VB");
+	}
+
+	return newBuff;
+}
+
+//-----------------------------------------------------------------------------
+
+void GFXD3D11Device::setClipRect( const RectI &inRect ) 
+{
+   // We transform the incoming rect by the view 
+   // matrix first, so that it can be used to pan
+   // and scale the clip rect.
+   //
+   // This is currently used to take tiled screenshots.
+   Point3F pos( inRect.point.x, inRect.point.y, 0.0f );
+   Point3F extent( inRect.extent.x, inRect.extent.y, 0.0f );
+   getViewMatrix().mulP( pos );
+   getViewMatrix().mulV( extent );  
+   RectI rect( pos.x, pos.y, extent.x, extent.y );
+
+   // Clip the rect against the renderable size.
+   Point2I size = mCurrentRT->getSize();
+
+   RectI maxRect(Point2I(0,0), size);
+   rect.intersect(maxRect);
+
+   mClipRect = rect;
+
+   F32 l = F32( mClipRect.point.x );
+   F32 r = F32( mClipRect.point.x + mClipRect.extent.x );
+   F32 b = F32( mClipRect.point.y + mClipRect.extent.y );
+   F32 t = F32( mClipRect.point.y );
+
+   // Set up projection matrix, 
+   static Point4F pt;   
+   pt.set(2.0f / (r - l), 0.0f, 0.0f, 0.0f);
+   mTempMatrix.setColumn(0, pt);
+
+   pt.set(0.0f, 2.0f/(t - b), 0.0f, 0.0f);
+   mTempMatrix.setColumn(1, pt);
+
+   pt.set(0.0f, 0.0f, 1.0f, 0.0f);
+   mTempMatrix.setColumn(2, pt);
+
+   pt.set((l+r)/(l-r), (t+b)/(b-t), 1.0f, 1.0f);
+   mTempMatrix.setColumn(3, pt);
+
+   setProjectionMatrix( mTempMatrix );
+
+   // Set up world/view matrix
+   mTempMatrix.identity();   
+   setWorldMatrix( mTempMatrix );
+
+   setViewport( mClipRect );
+}
+
+void GFXD3D11Device::setVertexStream( U32 stream, GFXVertexBuffer *buffer )
+{
+	GFXD3D11VertexBuffer *d3dBuffer = static_cast<GFXD3D11VertexBuffer*>( buffer );
+
+	if ( stream == 0 )
+	{
+		// Set the volatile buffer which is used to 
+		// offset the start index when doing draw calls.
+		if ( d3dBuffer && d3dBuffer->mVolatileStart > 0 )
+			mVolatileVB = d3dBuffer;
+		else
+			mVolatileVB = NULL;
+	}
+
+	// NOTE: We do not use the stream offset here for stream 0
+	// as that feature is *supposedly* not as well supported as 
+	// using the start index in drawPrimitive.
+	//
+	// If we can verify that this is not the case then we should
+	// start using this method exclusively for all streams.
+
+	U32 strides[1] = { d3dBuffer ? d3dBuffer->mVertexSize : 0 };
+	U32 offset = d3dBuffer && stream != 0 ? d3dBuffer->mVolatileStart * d3dBuffer->mVertexSize : 0;
+	ID3D11Buffer* buff = d3dBuffer ? d3dBuffer->vb : NULL;
+
+	getDeviceContext()->IASetVertexBuffers(stream, 1, &buff, strides, &offset);
+}
+
+void GFXD3D11Device::setVertexStreamFrequency( U32 stream, U32 frequency )
+{
+   if (stream == 0)
+      mDrawInstancesCount = frequency; // instances count
+}
+
+void GFXD3D11Device::_setPrimitiveBuffer( GFXPrimitiveBuffer *buffer ) 
+{
+   mCurrentPB = static_cast<GFXD3D11PrimitiveBuffer *>( buffer );
+
+   mD3DDeviceContext->IASetIndexBuffer(mCurrentPB->ib, DXGI_FORMAT_R16_UINT, 0);
+}
+
+U32 GFXD3D11Device::primCountToIndexCount(GFXPrimitiveType primType, U32 primitiveCount)
+{
+   switch (primType)
+   {
+   case GFXPointList:
+      return primitiveCount;
+      break;
+   case GFXLineList:
+      return primitiveCount * 2;
+      break;
+   case GFXLineStrip:
+      return primitiveCount + 1;
+      break;
+   case GFXTriangleList:
+      return primitiveCount * 3;
+      break;
+   case GFXTriangleStrip:
+      return 2 + primitiveCount;
+      break;
+   default:
+      AssertFatal(false, "GFXGLDevice::primCountToIndexCount - unrecognized prim type");
+      break;
+
+   }
+   return 0;
+}
+
+
+void GFXD3D11Device::drawPrimitive( GFXPrimitiveType primType, U32 vertexStart, U32 primitiveCount ) 
+{
+   // This is done to avoid the function call overhead if possible
+   if( mStateDirty )
+      updateStates();
+   if (mCurrentShaderConstBuffer)
+      setShaderConstBufferInternal(mCurrentShaderConstBuffer);
+
+   if ( mVolatileVB )
+	    vertexStart += mVolatileVB->mVolatileStart;
+
+   mD3DDeviceContext->IASetPrimitiveTopology(GFXD3D11PrimType[primType]);
+   
+   if ( mDrawInstancesCount )
+      mD3DDeviceContext->DrawInstanced(primCountToIndexCount(primType, primitiveCount), mDrawInstancesCount, vertexStart, 0);
+   else
+      mD3DDeviceContext->Draw(primCountToIndexCount(primType, primitiveCount), vertexStart);
+  
+   mDeviceStatistics.mDrawCalls++;
+   if ( mVertexBufferFrequency[0] > 1 )
+      mDeviceStatistics.mPolyCount += primitiveCount * mVertexBufferFrequency[0];
+   else
+      mDeviceStatistics.mPolyCount += primitiveCount;
+}
+
+void GFXD3D11Device::drawIndexedPrimitive( GFXPrimitiveType primType, 
+                                          U32 startVertex, 
+                                          U32 minIndex, 
+                                          U32 numVerts, 
+                                          U32 startIndex, 
+                                          U32 primitiveCount ) 
+{
+   // This is done to avoid the function call overhead if possible
+   if( mStateDirty )
+      updateStates();
+   if (mCurrentShaderConstBuffer)
+      setShaderConstBufferInternal(mCurrentShaderConstBuffer);
+
+   AssertFatal( mCurrentPB != NULL, "Trying to call drawIndexedPrimitive with no current index buffer, call setIndexBuffer()" );
+
+   if ( mVolatileVB )
+      startVertex += mVolatileVB->mVolatileStart;
+
+   mD3DDeviceContext->IASetPrimitiveTopology(GFXD3D11PrimType[primType]);
+  
+   if ( mDrawInstancesCount )
+      mD3DDeviceContext->DrawIndexedInstanced(primCountToIndexCount(primType, primitiveCount), mDrawInstancesCount, mCurrentPB->mVolatileStart + startIndex, startVertex, 0);
+   else
+      mD3DDeviceContext->DrawIndexed(primCountToIndexCount(primType,primitiveCount), mCurrentPB->mVolatileStart + startIndex, startVertex);   
+
+   mDeviceStatistics.mDrawCalls++;
+   if ( mVertexBufferFrequency[0] > 1 )
+      mDeviceStatistics.mPolyCount += primitiveCount * mVertexBufferFrequency[0];
+   else
+      mDeviceStatistics.mPolyCount += primitiveCount;
+}
+
+GFXShader* GFXD3D11Device::createShader()
+{
+   GFXD3D11Shader* shader = new GFXD3D11Shader();
+   shader->registerResourceWithDevice( this );
+   return shader;
+}
+
+//-----------------------------------------------------------------------------
+// Set shader - this function exists to make sure this is done in one place,
+//              and to make sure redundant shader states are not being
+//              sent to the card.
+//-----------------------------------------------------------------------------
+void GFXD3D11Device::setShader(GFXShader *shader, bool force)
+{
+   if(shader)
+   {
+	   GFXD3D11Shader *d3dShader = static_cast<GFXD3D11Shader*>(shader);
+
+      if (d3dShader->mPixShader != mLastPixShader || force)
+	   {
+		  mD3DDeviceContext->PSSetShader( d3dShader->mPixShader, NULL, 0);
+		  mLastPixShader = d3dShader->mPixShader;
+	   }
+
+      if (d3dShader->mVertShader != mLastVertShader || force)
+	   {
+		  mD3DDeviceContext->VSSetShader( d3dShader->mVertShader, NULL, 0);
+		  mLastVertShader = d3dShader->mVertShader;
+	   }     
+   }
+   else
+   {
+	   setupGenericShaders();
+   }
+}
+
+GFXPrimitiveBuffer * GFXD3D11Device::allocPrimitiveBuffer(U32 numIndices, U32 numPrimitives, GFXBufferType bufferType, void *data )
+{
+   // Allocate a buffer to return
+   GFXD3D11PrimitiveBuffer * res = new GFXD3D11PrimitiveBuffer(this, numIndices, numPrimitives, bufferType);
+
+   // Determine usage flags
+   D3D11_USAGE usage = D3D11_USAGE_DEFAULT;
+
+   // Assumptions:
+   //    - static buffers are write once, use many
+   //    - dynamic buffers are write many, use many
+   //    - volatile buffers are write once, use once
+   // You may never read from a buffer.
+   //TODO: enable proper support for D3D11_USAGE_IMMUTABLE
+   switch(bufferType)
+   {
+   case GFXBufferTypeImmutable:
+   case GFXBufferTypeStatic:
+      usage = D3D11_USAGE_DEFAULT; //D3D11_USAGE_IMMUTABLE;
+      break;
+
+   case GFXBufferTypeDynamic:
+   case GFXBufferTypeVolatile:
+	  usage = D3D11_USAGE_DYNAMIC;
+      break;
+   }
+
+   // Register resource
+   res->registerResourceWithDevice(this);
+
+   // Create d3d index buffer
+   if(bufferType == GFXBufferTypeVolatile)
+   {
+        // Get it from the pool if it's a volatile...
+        AssertFatal(numIndices < MAX_DYNAMIC_INDICES, "Cannot allocate that many indices in a volatile buffer, increase MAX_DYNAMIC_INDICES.");
+
+        res->ib = mDynamicPB->ib;
+        res->mVolatileBuffer = mDynamicPB;
+   }
+   else
+   {
+		// Otherwise, get it as a seperate buffer...
+		D3D11_BUFFER_DESC desc;
+		desc.ByteWidth = sizeof(U16) * numIndices;
+		desc.Usage = usage;
+		if(bufferType == GFXBufferTypeDynamic)
+			desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; // We never allow reading from a primitive buffer.
+		else
+			desc.CPUAccessFlags = 0;
+		desc.BindFlags = D3D11_BIND_INDEX_BUFFER;
+		desc.MiscFlags = 0;
+		desc.StructureByteStride = 0;
+
+		HRESULT hr = D3D11DEVICE->CreateBuffer(&desc, NULL, &res->ib);
+
+		if(FAILED(hr)) 
+		{
+			AssertFatal(false, "Failed to allocate an index buffer.");
+		}
+   }
+
+   if (data)
+   {
+      void* dest;
+      res->lock(0, numIndices, &dest);
+      dMemcpy(dest, data, sizeof(U16) * numIndices);
+      res->unlock();
+   }
+
+   return res;
+}
+
+GFXVertexBuffer * GFXD3D11Device::allocVertexBuffer(U32 numVerts, const GFXVertexFormat *vertexFormat, U32 vertSize, GFXBufferType bufferType, void *data)
+{
+   PROFILE_SCOPE( GFXD3D11Device_allocVertexBuffer );
+
+   GFXD3D11VertexBuffer *res = new GFXD3D11VertexBuffer(   this, 
+                                                         numVerts, 
+                                                         vertexFormat, 
+                                                         vertSize, 
+                                                         bufferType );
+   
+   // Determine usage flags
+   D3D11_USAGE usage = D3D11_USAGE_DEFAULT;
+
+   res->mNumVerts = 0;
+
+   // Assumptions:
+   //    - static buffers are write once, use many
+   //    - dynamic buffers are write many, use many
+   //    - volatile buffers are write once, use once
+   // You may never read from a buffer.
+   //TODO: enable proper support for D3D11_USAGE_IMMUTABLE
+   switch(bufferType)
+   {
+   case GFXBufferTypeImmutable:
+   case GFXBufferTypeStatic:
+      usage = D3D11_USAGE_DEFAULT;
+      break;
+
+   case GFXBufferTypeDynamic:
+   case GFXBufferTypeVolatile:
+	  usage = D3D11_USAGE_DYNAMIC;
+      break;
+   }
+
+   // Register resource
+   res->registerResourceWithDevice(this);
+
+   // Create vertex buffer
+   if(bufferType == GFXBufferTypeVolatile)
+   {
+        // NOTE: Volatile VBs are pooled and will be allocated at lock time.
+        AssertFatal(numVerts <= MAX_DYNAMIC_VERTS, "GFXD3D11Device::allocVertexBuffer - Volatile vertex buffer is too big... see MAX_DYNAMIC_VERTS!");
+   }
+   else
+   {
+		// Requesting it will allocate it.
+		vertexFormat->getDecl(); //-ALEX disabled to postpone until after shader is actually set...
+
+		// Get a new buffer...
+		D3D11_BUFFER_DESC desc;
+		desc.ByteWidth = vertSize * numVerts;
+		desc.Usage = usage;
+		desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
+		if(bufferType == GFXBufferTypeDynamic)
+			desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; // We never allow reading from a vertex buffer.
+		else
+			desc.CPUAccessFlags = 0;
+		desc.MiscFlags = 0;
+		desc.StructureByteStride = 0;
+
+		HRESULT hr = D3D11DEVICE->CreateBuffer(&desc, NULL, &res->vb);
+
+		if(FAILED(hr)) 
+		{
+			AssertFatal(false, "Failed to allocate VB");
+		}
+   }
+
+   res->mNumVerts = numVerts;
+
+   if (data)
+   {
+      void* dest;
+      res->lock(0, numVerts, &dest);
+      dMemcpy(dest, data, vertSize * numVerts);
+      res->unlock();
+   }
+
+   return res;
+}
+
+String GFXD3D11Device::_createTempShaderInternal(const GFXVertexFormat *vertexFormat)
+{
+   U32 elemCount = vertexFormat->getElementCount();
+   //Input data
+   StringBuilder inputData;
+   inputData.append("struct VertIn {");
+   //Output data
+   StringBuilder outputData;
+   outputData.append("struct VertOut {");
+   // Shader main body data
+   StringBuilder mainBodyData;
+   //make shader
+   mainBodyData.append("VertOut main(VertIn IN){VertOut OUT;");
+   for (U32 i = 0; i < elemCount; i++)
+   {
+      const GFXVertexElement &element = vertexFormat->getElement(i);
+      String semantic = element.getSemantic();
+      String semanticOut = semantic;
+      String type;
+
+      if (element.isSemantic(GFXSemantic::POSITION))
+      {
+         semantic = "POSITION";
+         semanticOut = "SV_Position";
+      }
+      else if (element.isSemantic(GFXSemantic::NORMAL))
+      {
+         semantic = "NORMAL";
+         semanticOut = semantic;
+      }
+      else if (element.isSemantic(GFXSemantic::COLOR))
+      {
+         semantic = "COLOR";
+         semanticOut = semantic;
+      }
+      else if (element.isSemantic(GFXSemantic::TANGENT))
+      {
+         semantic = "TANGENT";
+         semanticOut = semantic;
+      }
+      else if (element.isSemantic(GFXSemantic::BINORMAL))
+      {
+         semantic = "BINORMAL";
+         semanticOut = semantic;
+      }
+      else
+      {
+         //Anything that falls thru to here will be a texture coord.
+         semantic = String::ToString("TEXCOORD%d", element.getSemanticIndex());
+         semanticOut = semantic;
+      }
+
+      switch (GFXD3D11DeclType[element.getType()])
+      {
+      case DXGI_FORMAT_R32_FLOAT:
+         type = "float";
+         break;
+      case DXGI_FORMAT_R32G32_FLOAT:
+         type = "float2";
+         break;
+      case DXGI_FORMAT_R32G32B32_FLOAT:
+         type = "float3";
+         break;
+      case DXGI_FORMAT_R32G32B32A32_FLOAT:
+      case DXGI_FORMAT_B8G8R8A8_UNORM:
+      case DXGI_FORMAT_R8G8B8A8_UNORM:
+         type = "float4";
+         break;
+      }
+
+      StringBuilder in;
+      in.format("%s %s%d : %s;", type.c_str(), "var", i, semantic.c_str());
+      inputData.append(in.data());
+
+      //SV_Position must be float4
+      if (semanticOut == String("SV_Position"))
+      {
+         StringBuilder out;
+         out.format("float4 %s%d : %s;", "var", i, semanticOut.c_str());
+         outputData.append(out.data());
+         StringBuilder body;
+         body.format("OUT.%s%d = float4(IN.%s%d.xyz,1);", "var", i, "var", i);
+         mainBodyData.append(body.data());
+      }
+      else
+      {
+         StringBuilder out;
+         out.format("%s %s%d : %s;", type.c_str(), "var", i, semanticOut.c_str());
+         outputData.append(out.data());
+         StringBuilder body;
+         body.format("OUT.%s%d = IN.%s%d;", "var", i, "var", i);
+         mainBodyData.append(body.data());
+      }
+   }
+
+   inputData.append("};");
+   outputData.append("};");
+   mainBodyData.append("return OUT;}");
+
+   //final data
+   StringBuilder finalData;
+   finalData.append(inputData.data());
+   finalData.append(outputData.data());
+   finalData.append(mainBodyData.data());
+
+   return String(finalData.data());
+}
+
+GFXVertexDecl* GFXD3D11Device::allocVertexDecl( const GFXVertexFormat *vertexFormat )
+{
+   PROFILE_SCOPE( GFXD3D11Device_allocVertexDecl );
+
+   // First check the map... you shouldn't allocate VBs very often
+   // if you want performance.  The map lookup should never become
+   // a performance bottleneck.
+   D3D11VertexDecl *decl = mVertexDecls[vertexFormat->getDescription()];
+   if ( decl )
+      return decl;
+
+   U32 elemCount = vertexFormat->getElementCount();
+ 
+   ID3DBlob* code = NULL;
+  
+   // We have to generate a temporary shader here for now since the input layout creation
+   // expects a shader to be already compiled to verify the vertex layout structure. The problem
+   // is that most of the time the regular shaders are compiled AFTER allocVertexDecl is called.
+   if(!decl)
+   {
+      //TODO: Perhaps save/cache the ID3DBlob for later use on identical vertex formats,save creating/compiling the temp shader everytime
+      String shaderData = _createTempShaderInternal(vertexFormat);     
+
+#ifdef TORQUE_DEBUG
+      U32 flags = D3DCOMPILE_DEBUG | D3DCOMPILE_ENABLE_STRICTNESS | D3DCOMPILE_WARNINGS_ARE_ERRORS;
+#else
+      U32 flags = D3DCOMPILE_ENABLE_STRICTNESS;
+#endif
+
+      ID3DBlob *errorBlob = NULL;
+      HRESULT hr = D3DCompile(shaderData.c_str(), shaderData.length(), NULL, NULL, NULL, "main", "vs_5_0", flags, 0, &code, &errorBlob);
+      StringBuilder error;
+
+      if(errorBlob)
+      {
+         error.append((char*)errorBlob->GetBufferPointer(), errorBlob->GetBufferSize());
+         AssertFatal(hr, error.data());
+      }
+
+      SAFE_RELEASE(errorBlob);
+   }
+   
+   AssertFatal(code, "D3D11Device::allocVertexDecl - compiled vert shader code missing!");
+
+   // Setup the declaration struct.
+   
+   U32 stream;
+   D3D11_INPUT_ELEMENT_DESC *vd = new D3D11_INPUT_ELEMENT_DESC[ elemCount];
+
+   for ( U32 i=0; i < elemCount; i++ )
+   {
+	   
+      const GFXVertexElement &element = vertexFormat->getElement( i );
+      
+      stream = element.getStreamIndex();
+
+      vd[i].InputSlot = stream;
+	 
+      vd[i].AlignedByteOffset =  D3D11_APPEND_ALIGNED_ELEMENT;
+      vd[i].Format = GFXD3D11DeclType[element.getType()];
+      // If instancing is enabled, the per instance data is only used on stream 1.
+      if (vertexFormat->hasInstancing() && stream == 1)
+      {
+         vd[i].InputSlotClass = D3D11_INPUT_PER_INSTANCE_DATA;
+         vd[i].InstanceDataStepRate = 1;
+      }
+      else
+      {
+         vd[i].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
+         vd[i].InstanceDataStepRate = 0;
+      }
+      // We force the usage index of 0 for everything but 
+      // texture coords for now... this may change later.
+      vd[i].SemanticIndex = 0;
+
+      if ( element.isSemantic( GFXSemantic::POSITION ) )
+         vd[i].SemanticName = "POSITION";
+      else if ( element.isSemantic( GFXSemantic::NORMAL ) )
+         vd[i].SemanticName = "NORMAL";
+      else if ( element.isSemantic( GFXSemantic::COLOR ) )
+         vd[i].SemanticName = "COLOR";
+      else if ( element.isSemantic( GFXSemantic::TANGENT ) )
+         vd[i].SemanticName = "TANGENT";
+      else if ( element.isSemantic( GFXSemantic::BINORMAL ) )
+         vd[i].SemanticName = "BINORMAL";
+      else
+      {
+          //Anything that falls thru to here will be a texture coord.
+         vd[i].SemanticName = "TEXCOORD";
+         vd[i].SemanticIndex = element.getSemanticIndex();
+      }
+
+   }
+
+   decl = new D3D11VertexDecl();
+   HRESULT hr = mD3DDevice->CreateInputLayout(vd, elemCount,code->GetBufferPointer(), code->GetBufferSize(), &decl->decl);
+   
+   if (FAILED(hr))
+   {
+      AssertFatal(false, "GFXD3D11Device::allocVertexDecl - Failed to create vertex input layout!");
+   }
+
+   delete [] vd;
+   SAFE_RELEASE(code);
+
+   // Store it in the cache.
+   mVertexDecls[vertexFormat->getDescription()] = decl;
+
+   return decl;
+}
+
+void GFXD3D11Device::setVertexDecl( const GFXVertexDecl *decl )
+{
+   ID3D11InputLayout *dx11Decl = NULL;
+   if (decl)
+      dx11Decl = static_cast<const D3D11VertexDecl*>(decl)->decl;
+   
+   mD3DDeviceContext->IASetInputLayout(dx11Decl);
+}
+
+//-----------------------------------------------------------------------------
+// This function should ONLY be called from GFXDevice::updateStates() !!!
+//-----------------------------------------------------------------------------
+void GFXD3D11Device::setTextureInternal( U32 textureUnit, const GFXTextureObject *texture)
+{
+   if( texture == NULL )
+   {
+		ID3D11ShaderResourceView *pView = NULL;
+		mD3DDeviceContext->PSSetShaderResources(textureUnit, 1, &pView);
+		return;
+   }
+
+   GFXD3D11TextureObject  *tex = (GFXD3D11TextureObject*)(texture);
+   mD3DDeviceContext->PSSetShaderResources(textureUnit, 1, tex->getSRViewPtr());
+}
+
+GFXFence *GFXD3D11Device::createFence()
+{
+   // Figure out what fence type we should be making if we don't know
+   if( mCreateFenceType == -1 )
+   {
+	  D3D11_QUERY_DESC desc;
+	  desc.MiscFlags = 0;
+	  desc.Query = D3D11_QUERY_EVENT;
+
+	  ID3D11Query *testQuery = NULL;
+
+	  HRESULT hRes = mD3DDevice->CreateQuery(&desc, &testQuery);
+
+	  if(FAILED(hRes))
+	  {
+		  mCreateFenceType = true;
+	  }
+
+	  else
+	  {
+		  mCreateFenceType = false;
+	  }
+
+      SAFE_RELEASE(testQuery);
+   }
+
+   // Cool, use queries
+   if(!mCreateFenceType)
+   {
+      GFXFence* fence = new GFXD3D11QueryFence( this );
+      fence->registerResourceWithDevice(this);
+      return fence;
+   }
+
+   // CodeReview: At some point I would like a specialized implementation of
+   // the method used by the general fence, only without the overhead incurred 
+   // by using the GFX constructs. Primarily the lock() method on texture handles
+   // will do a data copy, and this method doesn't require a copy, just a lock
+   // [5/10/2007 Pat]
+   GFXFence* fence = new GFXGeneralFence( this );
+   fence->registerResourceWithDevice(this);
+   return fence;
+}
+
+GFXOcclusionQuery* GFXD3D11Device::createOcclusionQuery()
+{  
+   GFXOcclusionQuery *query;
+   if (mOcclusionQuerySupported)
+      query = new GFXD3D11OcclusionQuery( this );
+   else
+      return NULL;      
+
+   query->registerResourceWithDevice(this);
+   return query;
+}
+
+GFXCubemap * GFXD3D11Device::createCubemap()
+{
+   GFXD3D11Cubemap* cube = new GFXD3D11Cubemap();
+   cube->registerResourceWithDevice(this);
+   return cube;
+}

+ 295 - 0
Engine/source/gfx/D3D11/gfxD3D11Device.h

@@ -0,0 +1,295 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+#ifndef _GFXD3D11DEVICE_H_
+#define _GFXD3D11DEVICE_H_
+
+#include <d3d11.h>
+
+#include "platform/tmm_off.h"
+#include "platformWin32/platformWin32.h"
+#include "gfx/D3D11/gfxD3D11Shader.h"
+#include "gfx/D3D11/gfxD3D11StateBlock.h"
+#include "gfx/D3D11/gfxD3D11TextureManager.h"
+#include "gfx/D3D11/gfxD3D11Cubemap.h"
+#include "gfx/D3D11/gfxD3D11PrimitiveBuffer.h"
+#include "gfx/gfxInit.h"
+#include "gfx/gfxResource.h"
+#include "platform/tmm_on.h"
+
+#define D3D11 static_cast<GFXD3D11Device*>(GFX)
+#define D3D11DEVICE D3D11->getDevice()
+#define D3D11DEVICECONTEXT D3D11->getDeviceContext()
+
+class PlatformWindow;
+class GFXD3D11ShaderConstBuffer;
+
+//------------------------------------------------------------------------------
+
+class GFXD3D11Device : public GFXDevice
+{
+   friend class GFXResource;
+   friend class GFXD3D11PrimitiveBuffer;
+   friend class GFXD3D11VertexBuffer;
+   friend class GFXD3D11TextureObject;
+   friend class GFXD3D11TextureTarget;
+   friend class GFXD3D11WindowTarget;
+
+   virtual GFXFormat selectSupportedFormat(GFXTextureProfile *profile,
+   const Vector<GFXFormat> &formats, bool texture, bool mustblend, bool mustfilter);
+
+   virtual void enumerateVideoModes();
+
+   virtual GFXWindowTarget *allocWindowTarget(PlatformWindow *window);
+   virtual GFXTextureTarget *allocRenderToTextureTarget();
+
+   virtual void enterDebugEvent(ColorI color, const char *name){};
+   virtual void leaveDebugEvent(){};
+   virtual void setDebugMarker(ColorI color, const char *name){};
+
+protected:
+
+   class D3D11VertexDecl : public GFXVertexDecl
+   {
+   public:
+      virtual ~D3D11VertexDecl()
+      {
+         SAFE_RELEASE( decl );
+      }
+
+      ID3D11InputLayout *decl;
+   };
+
+   virtual void initStates() { };
+
+   static GFXAdapter::CreateDeviceInstanceDelegate mCreateDeviceInstance;
+
+   MatrixF mTempMatrix;    ///< Temporary matrix, no assurances on value at all
+   RectI mClipRect;
+
+   typedef StrongRefPtr<GFXD3D11VertexBuffer> RPGDVB;
+   Vector<RPGDVB> mVolatileVBList;
+
+   /// Used to lookup a vertex declaration for the vertex format.
+   /// @see allocVertexDecl
+   typedef Map<String,D3D11VertexDecl*> VertexDeclMap;
+   VertexDeclMap mVertexDecls;
+
+   ID3D11RenderTargetView* mDeviceBackBufferView;
+   ID3D11DepthStencilView* mDeviceDepthStencilView;
+
+   ID3D11Texture2D *mDeviceBackbuffer;
+   ID3D11Texture2D *mDeviceDepthStencil;
+
+   /// The stream 0 vertex buffer used for volatile VB offseting.
+   GFXD3D11VertexBuffer *mVolatileVB;
+
+   //-----------------------------------------------------------------------
+   StrongRefPtr<GFXD3D11PrimitiveBuffer> mDynamicPB;
+   GFXD3D11PrimitiveBuffer *mCurrentPB;
+
+   ID3D11VertexShader *mLastVertShader;
+   ID3D11PixelShader *mLastPixShader;
+
+   S32 mCreateFenceType;
+
+   IDXGISwapChain *mSwapChain;
+   ID3D11Device* mD3DDevice;
+   ID3D11DeviceContext* mD3DDeviceContext;
+
+   GFXShader* mCurrentShader;
+   GFXShaderRef mGenericShader[GS_COUNT];
+   GFXShaderConstBufferRef mGenericShaderBuffer[GS_COUNT];
+   GFXShaderConstHandle *mModelViewProjSC[GS_COUNT];
+
+   U32  mAdapterIndex;
+
+   F32 mPixVersion;
+
+   bool mDebugLayers;
+
+   DXGI_SAMPLE_DESC mMultisampleDesc;
+
+   bool mOcclusionQuerySupported;
+
+   U32 mDrawInstancesCount;   
+
+   /// To manage creating and re-creating of these when device is aquired
+   void reacquireDefaultPoolResources();
+
+   /// To release all resources we control from D3DPOOL_DEFAULT
+   void releaseDefaultPoolResources();
+
+   virtual GFXD3D11VertexBuffer* findVBPool( const GFXVertexFormat *vertexFormat, U32 numVertsNeeded );
+   virtual GFXD3D11VertexBuffer* createVBPool( const GFXVertexFormat *vertexFormat, U32 vertSize );
+
+   IDXGISwapChain* getSwapChain();
+   // State overrides
+   // {
+
+   ///
+   virtual void setTextureInternal(U32 textureUnit, const GFXTextureObject* texture);
+
+   /// Called by GFXDevice to create a device specific stateblock
+   virtual GFXStateBlockRef createStateBlockInternal(const GFXStateBlockDesc& desc);
+   /// Called by GFXDevice to actually set a stateblock.
+   virtual void setStateBlockInternal(GFXStateBlock* block, bool force);
+
+   /// Track the last const buffer we've used.  Used to notify new constant buffers that
+   /// they should send all of their constants up
+   StrongRefPtr<GFXD3D11ShaderConstBuffer> mCurrentConstBuffer;
+   /// Called by base GFXDevice to actually set a const buffer
+   virtual void setShaderConstBufferInternal(GFXShaderConstBuffer* buffer);
+
+   virtual void setMatrix( GFXMatrixType /*mtype*/, const MatrixF &/*mat*/ ) { };
+   virtual void setLightInternal(U32 /*lightStage*/, const GFXLightInfo /*light*/, bool /*lightEnable*/) { };
+   virtual void setLightMaterialInternal(const GFXLightMaterial /*mat*/) { };
+   virtual void setGlobalAmbientInternal(ColorF /*color*/) { };
+
+   // }
+
+   // Index buffer management
+   // {
+   virtual void _setPrimitiveBuffer( GFXPrimitiveBuffer *buffer );
+   virtual void drawIndexedPrimitive(  GFXPrimitiveType primType, 
+                                       U32 startVertex, 
+                                       U32 minIndex, 
+                                       U32 numVerts, 
+                                       U32 startIndex, 
+                                       U32 primitiveCount );
+   // }
+
+   virtual GFXShader* createShader();
+
+   /// Device helper function
+   virtual DXGI_SWAP_CHAIN_DESC setupPresentParams( const GFXVideoMode &mode, const HWND &hwnd );
+
+   String _createTempShaderInternal(const GFXVertexFormat *vertexFormat);
+   // Supress any debug layer messages we don't want to see
+   void _suppressDebugMessages();
+   
+public:
+
+   static GFXDevice *createInstance( U32 adapterIndex );
+
+   static void enumerateAdapters( Vector<GFXAdapter*> &adapterList );
+
+   GFXTextureObject* createRenderSurface( U32 width, U32 height, GFXFormat format, U32 mipLevel );
+
+   ID3D11DepthStencilView* getDepthStencilView() { return mDeviceDepthStencilView; }
+   ID3D11RenderTargetView* getRenderTargetView() { return mDeviceBackBufferView; }
+   ID3D11Texture2D* getBackBufferTexture() { return mDeviceBackbuffer; }
+
+   /// Constructor
+   /// @param   d3d   Direct3D object to instantiate this device with
+   /// @param   index   Adapter index since D3D can use multiple graphics adapters
+   GFXD3D11Device( U32 index );
+   virtual ~GFXD3D11Device();
+
+   // Activate/deactivate
+   // {
+   virtual void init( const GFXVideoMode &mode, PlatformWindow *window = NULL );
+
+   virtual void preDestroy() { GFXDevice::preDestroy(); if(mTextureManager) mTextureManager->kill(); }
+
+   GFXAdapterType getAdapterType(){ return Direct3D11; }
+
+   U32 getAdaterIndex() const { return mAdapterIndex; }
+
+   virtual GFXCubemap *createCubemap();
+
+   virtual F32  getPixelShaderVersion() const { return mPixVersion; }
+   virtual void setPixelShaderVersion( F32 version ){ mPixVersion = version;} 
+
+   virtual void setShader(GFXShader *shader, bool force = false);
+   virtual U32  getNumSamplers() const { return 16; }
+   virtual U32  getNumRenderTargets() const { return 8; }
+   // }
+
+   // Misc rendering control
+   // {
+   virtual void clear( U32 flags, ColorI color, F32 z, U32 stencil );
+   virtual bool beginSceneInternal();
+   virtual void endSceneInternal();
+
+   virtual void setClipRect( const RectI &rect );
+   virtual const RectI& getClipRect() const { return mClipRect; }
+
+   // }
+
+
+   
+   /// @name Render Targets
+   /// @{
+   virtual void _updateRenderTargets();
+   /// @}
+
+   // Vertex/Index buffer management
+   // {
+   virtual GFXVertexBuffer* allocVertexBuffer(  U32 numVerts, 
+                                                const GFXVertexFormat *vertexFormat,
+                                                U32 vertSize,
+                                                GFXBufferType bufferType,
+                                                void* data = NULL);
+
+   virtual GFXPrimitiveBuffer *allocPrimitiveBuffer(  U32 numIndices, 
+                                                      U32 numPrimitives, 
+                                                      GFXBufferType bufferType,
+                                                      void* data = NULL);
+
+   virtual GFXVertexDecl* allocVertexDecl( const GFXVertexFormat *vertexFormat );
+   virtual void setVertexDecl( const GFXVertexDecl *decl );
+
+   virtual void setVertexStream( U32 stream, GFXVertexBuffer *buffer );
+   virtual void setVertexStreamFrequency( U32 stream, U32 frequency );
+   // }
+
+   virtual U32 getMaxDynamicVerts() { return MAX_DYNAMIC_VERTS; }
+   virtual U32 getMaxDynamicIndices() { return MAX_DYNAMIC_INDICES; }
+
+   inline U32 primCountToIndexCount(GFXPrimitiveType primType, U32 primitiveCount);
+
+   // Rendering
+   // {
+   virtual void drawPrimitive( GFXPrimitiveType primType, U32 vertexStart, U32 primitiveCount );
+   // }
+
+   ID3D11DeviceContext* getDeviceContext(){ return mD3DDeviceContext; }
+   ID3D11Device* getDevice(){ return mD3DDevice; }
+
+   /// Reset
+   void reset( DXGI_SWAP_CHAIN_DESC &d3dpp );
+
+   virtual void setupGenericShaders( GenericShaderType type  = GSColor );
+
+   inline virtual F32 getFillConventionOffset() const { return 0.0f; }
+   virtual void doParanoidStateCheck() {};
+
+   GFXFence *createFence();
+
+   GFXOcclusionQuery* createOcclusionQuery();   
+
+   // Default multisample parameters
+   DXGI_SAMPLE_DESC getMultisampleType() const { return mMultisampleDesc; }
+};
+
+#endif

+ 155 - 0
Engine/source/gfx/D3D11/gfxD3D11EnumTranslate.cpp

@@ -0,0 +1,155 @@
+//-----------------------------------------------------------------------------
+// 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 "gfx/D3D11/gfxD3D11Device.h"
+#include "gfx/D3D11/gfxD3D11EnumTranslate.h"
+#include "console/console.h"
+
+//------------------------------------------------------------------------------
+
+DXGI_FORMAT GFXD3D11TextureFormat[GFXFormat_COUNT];
+D3D11_FILTER GFXD3D11TextureFilter[GFXTextureFilter_COUNT];
+D3D11_BLEND GFXD3D11Blend[GFXBlend_COUNT];
+D3D11_BLEND_OP GFXD3D11BlendOp[GFXBlendOp_COUNT];
+D3D11_STENCIL_OP GFXD3D11StencilOp[GFXStencilOp_COUNT];
+D3D11_COMPARISON_FUNC GFXD3D11CmpFunc[GFXCmp_COUNT];
+D3D11_CULL_MODE GFXD3D11CullMode[GFXCull_COUNT];
+D3D11_FILL_MODE GFXD3D11FillMode[GFXFill_COUNT];
+D3D11_PRIMITIVE_TOPOLOGY GFXD3D11PrimType[GFXPT_COUNT];
+D3D11_TEXTURE_ADDRESS_MODE GFXD3D11TextureAddress[GFXAddress_COUNT];
+DXGI_FORMAT GFXD3D11DeclType[GFXDeclType_COUNT];
+
+//------------------------------------------------------------------------------
+
+void GFXD3D11EnumTranslate::init()
+{
+   GFXD3D11TextureFormat[GFXFormatR8G8B8] = DXGI_FORMAT_B8G8R8X8_UNORM;
+   GFXD3D11TextureFormat[GFXFormatR8G8B8A8] = DXGI_FORMAT_B8G8R8A8_UNORM;
+   GFXD3D11TextureFormat[GFXFormatR8G8B8X8] = DXGI_FORMAT_B8G8R8X8_UNORM;
+   GFXD3D11TextureFormat[GFXFormatB8G8R8A8] = DXGI_FORMAT_B8G8R8A8_UNORM;
+   GFXD3D11TextureFormat[GFXFormatR5G6B5] = DXGI_FORMAT_B5G6R5_UNORM;
+   GFXD3D11TextureFormat[GFXFormatR5G5B5A1] = DXGI_FORMAT_B5G5R5A1_UNORM;
+   GFXD3D11TextureFormat[GFXFormatR5G5B5X1] = DXGI_FORMAT_UNKNOWN;
+   GFXD3D11TextureFormat[GFXFormatR32F] = DXGI_FORMAT_R32_FLOAT;
+   GFXD3D11TextureFormat[GFXFormatA4L4] = DXGI_FORMAT_UNKNOWN;
+   GFXD3D11TextureFormat[GFXFormatA8L8] = DXGI_FORMAT_R8G8_UNORM;
+   GFXD3D11TextureFormat[GFXFormatA8] = DXGI_FORMAT_A8_UNORM;
+   GFXD3D11TextureFormat[GFXFormatL8] = DXGI_FORMAT_R8_UNORM;
+   GFXD3D11TextureFormat[GFXFormatDXT1] = DXGI_FORMAT_BC1_UNORM;
+   GFXD3D11TextureFormat[GFXFormatDXT2] = DXGI_FORMAT_BC1_UNORM;
+   GFXD3D11TextureFormat[GFXFormatDXT3] = DXGI_FORMAT_BC2_UNORM;
+   GFXD3D11TextureFormat[GFXFormatDXT4] = DXGI_FORMAT_BC2_UNORM;
+   GFXD3D11TextureFormat[GFXFormatDXT5] = DXGI_FORMAT_BC3_UNORM;
+   GFXD3D11TextureFormat[GFXFormatR32G32B32A32F] = DXGI_FORMAT_R32G32B32A32_FLOAT;
+   GFXD3D11TextureFormat[GFXFormatR16G16B16A16F] = DXGI_FORMAT_R16G16B16A16_FLOAT;
+   GFXD3D11TextureFormat[GFXFormatL16] = DXGI_FORMAT_R16_UNORM;
+   GFXD3D11TextureFormat[GFXFormatR16G16B16A16] = DXGI_FORMAT_R16G16B16A16_UNORM;
+   GFXD3D11TextureFormat[GFXFormatR16G16] = DXGI_FORMAT_R16G16_UNORM;
+   GFXD3D11TextureFormat[GFXFormatR16F] = DXGI_FORMAT_R16_FLOAT;
+   GFXD3D11TextureFormat[GFXFormatR16G16F] = DXGI_FORMAT_R16G16_FLOAT;
+   GFXD3D11TextureFormat[GFXFormatR10G10B10A2] = DXGI_FORMAT_R10G10B10A2_UNORM;
+   GFXD3D11TextureFormat[GFXFormatD32] = DXGI_FORMAT_UNKNOWN;
+   GFXD3D11TextureFormat[GFXFormatD24X8] = DXGI_FORMAT_UNKNOWN;
+   GFXD3D11TextureFormat[GFXFormatD24S8] = DXGI_FORMAT_D24_UNORM_S8_UINT;
+   GFXD3D11TextureFormat[GFXFormatD24FS8] = DXGI_FORMAT_UNKNOWN;
+   GFXD3D11TextureFormat[GFXFormatD16] = DXGI_FORMAT_D16_UNORM;
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+   GFXD3D11TextureFilter[GFXTextureFilterNone] = D3D11_FILTER_MIN_MAG_MIP_POINT;
+   GFXD3D11TextureFilter[GFXTextureFilterPoint] = D3D11_FILTER_MIN_MAG_MIP_POINT;
+   GFXD3D11TextureFilter[GFXTextureFilterLinear] = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
+   GFXD3D11TextureFilter[GFXTextureFilterAnisotropic] = D3D11_FILTER_ANISOTROPIC;
+   GFXD3D11TextureFilter[GFXTextureFilterPyramidalQuad] = D3D11_FILTER_ANISOTROPIC;
+   GFXD3D11TextureFilter[GFXTextureFilterGaussianQuad] = D3D11_FILTER_ANISOTROPIC;
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+   GFXD3D11Blend[GFXBlendZero] = D3D11_BLEND_ZERO;
+   GFXD3D11Blend[GFXBlendOne] = D3D11_BLEND_ONE;
+   GFXD3D11Blend[GFXBlendSrcColor] = D3D11_BLEND_SRC_COLOR;
+   GFXD3D11Blend[GFXBlendInvSrcColor] = D3D11_BLEND_INV_SRC_COLOR;
+   GFXD3D11Blend[GFXBlendSrcAlpha] = D3D11_BLEND_SRC_ALPHA;
+   GFXD3D11Blend[GFXBlendInvSrcAlpha] = D3D11_BLEND_INV_SRC_ALPHA;
+   GFXD3D11Blend[GFXBlendDestAlpha] = D3D11_BLEND_DEST_ALPHA;
+   GFXD3D11Blend[GFXBlendInvDestAlpha] = D3D11_BLEND_INV_DEST_ALPHA;
+   GFXD3D11Blend[GFXBlendDestColor] = D3D11_BLEND_DEST_COLOR;
+   GFXD3D11Blend[GFXBlendInvDestColor] = D3D11_BLEND_INV_DEST_COLOR;
+   GFXD3D11Blend[GFXBlendSrcAlphaSat] = D3D11_BLEND_SRC_ALPHA_SAT;
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+   GFXD3D11BlendOp[GFXBlendOpAdd] = D3D11_BLEND_OP_ADD;
+   GFXD3D11BlendOp[GFXBlendOpSubtract] = D3D11_BLEND_OP_SUBTRACT;
+   GFXD3D11BlendOp[GFXBlendOpRevSubtract] = D3D11_BLEND_OP_REV_SUBTRACT;
+   GFXD3D11BlendOp[GFXBlendOpMin] = D3D11_BLEND_OP_MIN;
+   GFXD3D11BlendOp[GFXBlendOpMax] = D3D11_BLEND_OP_MAX;
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+   GFXD3D11StencilOp[GFXStencilOpKeep] = D3D11_STENCIL_OP_KEEP;
+   GFXD3D11StencilOp[GFXStencilOpZero] = D3D11_STENCIL_OP_ZERO;
+   GFXD3D11StencilOp[GFXStencilOpReplace] = D3D11_STENCIL_OP_REPLACE;
+   GFXD3D11StencilOp[GFXStencilOpIncrSat] = D3D11_STENCIL_OP_INCR_SAT;
+   GFXD3D11StencilOp[GFXStencilOpDecrSat] = D3D11_STENCIL_OP_DECR_SAT;
+   GFXD3D11StencilOp[GFXStencilOpInvert] = D3D11_STENCIL_OP_INVERT;
+   GFXD3D11StencilOp[GFXStencilOpIncr] = D3D11_STENCIL_OP_INCR;
+   GFXD3D11StencilOp[GFXStencilOpDecr] = D3D11_STENCIL_OP_DECR;
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+   GFXD3D11CmpFunc[GFXCmpNever] = D3D11_COMPARISON_NEVER;
+   GFXD3D11CmpFunc[GFXCmpLess] = D3D11_COMPARISON_LESS;
+   GFXD3D11CmpFunc[GFXCmpEqual] = D3D11_COMPARISON_EQUAL;
+   GFXD3D11CmpFunc[GFXCmpLessEqual] = D3D11_COMPARISON_LESS_EQUAL;
+   GFXD3D11CmpFunc[GFXCmpGreater] = D3D11_COMPARISON_GREATER;
+   GFXD3D11CmpFunc[GFXCmpNotEqual] = D3D11_COMPARISON_NOT_EQUAL;
+   GFXD3D11CmpFunc[GFXCmpGreaterEqual] = D3D11_COMPARISON_GREATER_EQUAL;
+   GFXD3D11CmpFunc[GFXCmpAlways] = D3D11_COMPARISON_ALWAYS;
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+   GFXD3D11CullMode[GFXCullNone] = D3D11_CULL_NONE;
+   GFXD3D11CullMode[GFXCullCW] = D3D11_CULL_FRONT;
+   GFXD3D11CullMode[GFXCullCCW] = D3D11_CULL_BACK;
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+   GFXD3D11FillMode[GFXFillPoint] = D3D11_FILL_SOLID;
+   GFXD3D11FillMode[GFXFillWireframe] = D3D11_FILL_WIREFRAME;
+   GFXD3D11FillMode[GFXFillSolid] = D3D11_FILL_SOLID;
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+   GFXD3D11PrimType[GFXPointList] = D3D_PRIMITIVE_TOPOLOGY_POINTLIST;
+   GFXD3D11PrimType[GFXLineList] = D3D_PRIMITIVE_TOPOLOGY_LINELIST;
+   GFXD3D11PrimType[GFXLineStrip] = D3D_PRIMITIVE_TOPOLOGY_LINESTRIP;
+   GFXD3D11PrimType[GFXTriangleList] = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
+   GFXD3D11PrimType[GFXTriangleStrip] = D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP;
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+   GFXD3D11TextureAddress[GFXAddressWrap] = D3D11_TEXTURE_ADDRESS_WRAP;
+   GFXD3D11TextureAddress[GFXAddressMirror] = D3D11_TEXTURE_ADDRESS_MIRROR;
+   GFXD3D11TextureAddress[GFXAddressClamp] = D3D11_TEXTURE_ADDRESS_CLAMP;
+   GFXD3D11TextureAddress[GFXAddressBorder] = D3D11_TEXTURE_ADDRESS_BORDER;
+   GFXD3D11TextureAddress[GFXAddressMirrorOnce] = D3D11_TEXTURE_ADDRESS_MIRROR_ONCE;
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+   GFXD3D11DeclType[GFXDeclType_Float] = DXGI_FORMAT_R32_FLOAT;
+   GFXD3D11DeclType[GFXDeclType_Float2] = DXGI_FORMAT_R32G32_FLOAT;
+   GFXD3D11DeclType[GFXDeclType_Float3] = DXGI_FORMAT_R32G32B32_FLOAT;
+   GFXD3D11DeclType[GFXDeclType_Float4] = DXGI_FORMAT_R32G32B32A32_FLOAT;
+   GFXD3D11DeclType[GFXDeclType_Color] =  DXGI_FORMAT_B8G8R8A8_UNORM; // DXGI_FORMAT_R8G8B8A8_UNORM;
+}
+

+ 51 - 0
Engine/source/gfx/D3D11/gfxD3D11EnumTranslate.h

@@ -0,0 +1,51 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+
+#ifndef _GFXD3D11ENUMTRANSLATE_H_
+#define _GFXD3D11ENUMTRANSLATE_H_
+
+#include "gfx/D3D11/gfxD3D11Shader.h"
+#include "gfx/gfxEnums.h"
+
+//------------------------------------------------------------------------------
+
+namespace GFXD3D11EnumTranslate
+{
+   void init();
+};
+
+//------------------------------------------------------------------------------
+
+extern DXGI_FORMAT GFXD3D11TextureFormat[GFXFormat_COUNT];
+extern D3D11_FILTER GFXD3D11TextureFilter[GFXTextureFilter_COUNT];
+extern D3D11_BLEND GFXD3D11Blend[GFXBlend_COUNT];
+extern D3D11_BLEND_OP GFXD3D11BlendOp[GFXBlendOp_COUNT];
+extern D3D11_STENCIL_OP GFXD3D11StencilOp[GFXStencilOp_COUNT];
+extern D3D11_COMPARISON_FUNC GFXD3D11CmpFunc[GFXCmp_COUNT];
+extern D3D11_CULL_MODE GFXD3D11CullMode[GFXCull_COUNT];
+extern D3D11_FILL_MODE GFXD3D11FillMode[GFXFill_COUNT];
+extern D3D11_PRIMITIVE_TOPOLOGY GFXD3D11PrimType[GFXPT_COUNT];
+extern D3D11_TEXTURE_ADDRESS_MODE GFXD3D11TextureAddress[GFXAddress_COUNT];
+extern DXGI_FORMAT GFXD3D11DeclType[GFXDeclType_COUNT];
+
+#endif

+ 177 - 0
Engine/source/gfx/D3D11/gfxD3D11OcclusionQuery.cpp

@@ -0,0 +1,177 @@
+//-----------------------------------------------------------------------------
+// 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 "gfx/D3D11/gfxD3D11Device.h"
+#include "gfx/D3D11/gfxD3D11OcclusionQuery.h"
+
+#include "gui/3d/guiTSControl.h"
+
+#ifdef TORQUE_GATHER_METRICS
+// For TickMs define
+#include "T3D/gameBase/processList.h"
+#endif
+
+GFXD3D11OcclusionQuery::GFXD3D11OcclusionQuery(GFXDevice *device)
+ : GFXOcclusionQuery(device), 
+   mQuery(NULL)   
+{
+#ifdef TORQUE_GATHER_METRICS
+   mTimer = PlatformTimer::create();
+   mTimer->getElapsedMs();
+
+   mTimeSinceEnd = 0;
+   mBeginFrame = 0;
+#endif
+}
+
+GFXD3D11OcclusionQuery::~GFXD3D11OcclusionQuery()
+{
+   SAFE_RELEASE(mQuery);
+
+#ifdef TORQUE_GATHER_METRICS
+   SAFE_DELETE(mTimer);
+#endif
+}
+
+bool GFXD3D11OcclusionQuery::begin()
+{
+   if(GFXDevice::getDisableOcclusionQuery())
+      return true;
+
+   if (mQuery == NULL)
+   {
+      D3D11_QUERY_DESC queryDesc;
+      queryDesc.Query = D3D11_QUERY_OCCLUSION;
+      queryDesc.MiscFlags = 0;
+
+      HRESULT hRes = D3D11DEVICE->CreateQuery(&queryDesc, &mQuery);
+
+      if(FAILED(hRes))
+      {
+         AssertFatal(false, "GFXD3D11OcclusionQuery::begin - Hardware does not support D3D11 Occlusion-Queries, this should be caught before this type is created");
+      }
+
+      AssertISV(hRes != E_OUTOFMEMORY, "GFXD3D11OcclusionQuery::begin - Out of memory");
+   }
+
+   // Add a begin marker to the command buffer queue.
+   D3D11DEVICECONTEXT->Begin(mQuery);
+
+#ifdef TORQUE_GATHER_METRICS
+   mBeginFrame = GuiTSCtrl::getFrameCount();
+#endif
+
+   return true;
+}
+
+void GFXD3D11OcclusionQuery::end()
+{
+   if (GFXDevice::getDisableOcclusionQuery())
+      return;
+
+   // Add an end marker to the command buffer queue.
+   D3D11DEVICECONTEXT->End(mQuery);
+
+#ifdef TORQUE_GATHER_METRICS
+   AssertFatal( mBeginFrame == GuiTSCtrl::getFrameCount(), "GFXD3D11OcclusionQuery::end - ended query on different frame than begin!" );   
+   mTimer->getElapsedMs();
+   mTimer->reset();
+#endif
+}
+
+GFXD3D11OcclusionQuery::OcclusionQueryStatus GFXD3D11OcclusionQuery::getStatus(bool block, U32 *data)
+{
+   // If this ever shows up near the top of a profile then your system is 
+   // GPU bound or you are calling getStatus too soon after submitting it.
+   //
+   // To test if you are GPU bound resize your window very small and see if
+   // this profile no longer appears at the top.
+   //
+   // To test if you are calling getStatus to soon after submitting it,
+   // check the value of mTimeSinceEnd in a debug build. If it is < half the length
+   // of time to render an individual frame you could have problems.
+   PROFILE_SCOPE(GFXD3D11OcclusionQuery_getStatus);
+
+   if ( GFXDevice::getDisableOcclusionQuery() )
+      return NotOccluded;
+
+   if ( mQuery == NULL )
+      return Unset;
+
+#ifdef TORQUE_GATHER_METRICS
+   //AssertFatal( mBeginFrame < GuiTSCtrl::getFrameCount(), "GFXD3D11OcclusionQuery::getStatus - called on the same frame as begin!" );
+
+   //U32 mTimeSinceEnd = mTimer->getElapsedMs();
+   //AssertFatal( mTimeSinceEnd >= 5, "GFXD3DOcculsionQuery::getStatus - less than TickMs since called ::end!" );
+#endif
+
+   HRESULT hRes;
+   U64 dwOccluded = 0;
+
+   if ( block )
+   {      
+      while ((hRes = D3D11DEVICECONTEXT->GetData(mQuery, &dwOccluded, sizeof(U64), 0)) == S_FALSE);
+   }
+   else
+   {
+      hRes = D3D11DEVICECONTEXT->GetData(mQuery, &dwOccluded, sizeof(U64), 0);
+   }
+
+   if (hRes == S_OK)   
+   {
+      if (data != NULL)
+         *data = (U32)dwOccluded;
+
+      return dwOccluded > 0 ? NotOccluded : Occluded;   
+   }
+
+   if (hRes == S_FALSE)
+      return Waiting;
+
+   return Error;   
+}
+
+void GFXD3D11OcclusionQuery::zombify()
+{
+   SAFE_RELEASE( mQuery );
+}
+
+void GFXD3D11OcclusionQuery::resurrect()
+{
+	// Recreate the query 
+	if( mQuery == NULL ) 
+	{ 
+      D3D11_QUERY_DESC queryDesc;
+      queryDesc.Query = D3D11_QUERY_OCCLUSION;
+      queryDesc.MiscFlags = 0;
+
+      HRESULT hRes = D3D11DEVICE->CreateQuery(&queryDesc, &mQuery); 
+	
+      AssertISV( hRes != E_OUTOFMEMORY, "GFXD3D9QueryFence::resurrect - Out of memory" ); 
+   } 
+}
+
+const String GFXD3D11OcclusionQuery::describeSelf() const
+{
+   // We've got nothing
+   return String();
+}

+ 58 - 0
Engine/source/gfx/D3D11/gfxD3D11OcclusionQuery.h

@@ -0,0 +1,58 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+#ifndef _GFX_D3D11_OCCLUSIONQUERY_H_
+#define _GFX_D3D11_OCCLUSIONQUERY_H_
+
+#include "gfx/D3D11/gfxD3D11Device.h"
+#include "gfx/gfxOcclusionQuery.h"
+
+#ifdef TORQUE_GATHER_METRICS
+   #include "platform/platformTimer.h"
+#endif
+
+class GFXD3D11OcclusionQuery : public GFXOcclusionQuery
+{
+private:
+   mutable ID3D11Query *mQuery;
+
+#ifdef TORQUE_GATHER_METRICS
+   U32 mBeginFrame;
+   U32 mTimeSinceEnd;
+   PlatformTimer *mTimer;
+#endif
+
+public:
+   GFXD3D11OcclusionQuery(GFXDevice *device);
+   virtual ~GFXD3D11OcclusionQuery();
+
+   virtual bool begin();
+   virtual void end();   
+   virtual OcclusionQueryStatus getStatus(bool block, U32 *data = NULL);
+
+   // GFXResource
+   virtual void zombify();   
+   virtual void resurrect();
+   virtual const String describeSelf() const;
+};
+
+#endif

+ 222 - 0
Engine/source/gfx/D3D11/gfxD3D11PrimitiveBuffer.cpp

@@ -0,0 +1,222 @@
+//-----------------------------------------------------------------------------
+// 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 "gfx/D3D11/gfxD3D11Device.h"
+#include "gfx/D3D11/gfxD3D11EnumTranslate.h"
+#include "gfx/D3D11/gfxD3D11PrimitiveBuffer.h"
+#include "core/util/safeRelease.h"
+
+void GFXD3D11PrimitiveBuffer::prepare()
+{
+	D3D11->_setPrimitiveBuffer(this);
+}
+
+void GFXD3D11PrimitiveBuffer::lock(U32 indexStart, U32 indexEnd, void **indexPtr)
+{
+	AssertFatal(!mLocked, "GFXD3D11PrimitiveBuffer::lock - Can't lock a primitive buffer more than once!");
+
+	mLocked = true;
+	D3D11_MAP flags = D3D11_MAP_WRITE_DISCARD;
+
+	switch(mBufferType)
+	{
+   case GFXBufferTypeImmutable:
+	case GFXBufferTypeStatic:
+	case GFXBufferTypeDynamic:
+		flags = D3D11_MAP_WRITE_DISCARD;
+		break;
+
+	case GFXBufferTypeVolatile:
+		// Get our range now...
+		AssertFatal(indexStart == 0,                "Cannot get a subrange on a volatile buffer.");
+		AssertFatal(indexEnd < MAX_DYNAMIC_INDICES, "Cannot get more than MAX_DYNAMIC_INDICES in a volatile buffer. Up the constant!");
+
+		// Get the primtive buffer
+		mVolatileBuffer = D3D11->mDynamicPB;
+
+		AssertFatal( mVolatileBuffer, "GFXD3D11PrimitiveBuffer::lock - No dynamic primitive buffer was available!");
+
+		// We created the pool when we requested this volatile buffer, so assume it exists...
+		if(mVolatileBuffer->mIndexCount + indexEnd > MAX_DYNAMIC_INDICES) 
+		{
+			flags = D3D11_MAP_WRITE_DISCARD;
+			mVolatileStart = indexStart  = 0;
+			indexEnd       = indexEnd;
+		}
+		else 
+		{
+			flags = D3D11_MAP_WRITE_NO_OVERWRITE;
+			mVolatileStart = indexStart  = mVolatileBuffer->mIndexCount;
+			indexEnd                    += mVolatileBuffer->mIndexCount;
+		}
+
+		mVolatileBuffer->mIndexCount = indexEnd + 1;
+		ib = mVolatileBuffer->ib;
+
+		break;
+	}
+
+	
+	mIndexStart = indexStart;
+   mIndexEnd = indexEnd;
+	
+   if (mBufferType == GFXBufferTypeStatic || mBufferType == GFXBufferTypeImmutable)
+   {
+      U32 sizeToLock = (indexEnd - indexStart) * sizeof(U16);
+		*indexPtr = new U8[sizeToLock];
+		mLockedBuffer = *indexPtr;
+   }
+	else
+	{
+		D3D11_MAPPED_SUBRESOURCE pIndexData;
+      ZeroMemory(&pIndexData, sizeof(D3D11_MAPPED_SUBRESOURCE));
+
+		HRESULT hr = D3D11DEVICECONTEXT->Map(ib, 0, flags, 0, &pIndexData);
+
+		if(FAILED(hr)) 
+		{
+			AssertFatal(false, "GFXD3D11PrimitiveBuffer::lock - Could not lock primitive buffer.");
+		}
+
+		*indexPtr = (U8*)pIndexData.pData + (indexStart * sizeof(U16)) ;		
+   }
+
+	#ifdef TORQUE_DEBUG
+   
+		// Allocate a debug buffer large enough for the lock
+		// plus space for over and under run guard strings.
+		mLockedSize = (indexEnd - indexStart) * sizeof(U16);
+		const U32 guardSize = sizeof( _PBGuardString );
+		mDebugGuardBuffer = new U8[mLockedSize+(guardSize*2)];
+
+		// Setup the guard strings.
+		dMemcpy( mDebugGuardBuffer, _PBGuardString, guardSize ); 
+		dMemcpy( mDebugGuardBuffer + mLockedSize + guardSize, _PBGuardString, guardSize ); 
+
+		// Store the real lock pointer and return our debug pointer.
+		mLockedBuffer = *indexPtr;
+		*indexPtr = (U16*)( mDebugGuardBuffer + guardSize );
+
+	#endif // TORQUE_DEBUG
+}
+
+void GFXD3D11PrimitiveBuffer::unlock()
+{
+   #ifdef TORQUE_DEBUG
+   
+      if ( mDebugGuardBuffer )
+      {
+         const U32 guardSize = sizeof( _PBGuardString );
+
+         // First check the guard areas for overwrites.
+         AssertFatal( dMemcmp( mDebugGuardBuffer, _PBGuardString, guardSize ) == 0,
+            "GFXD3D11PrimitiveBuffer::unlock - Caught lock memory underrun!" );
+         AssertFatal( dMemcmp( mDebugGuardBuffer + mLockedSize + guardSize, _PBGuardString, guardSize ) == 0,
+            "GFXD3D11PrimitiveBuffer::unlock - Caught lock memory overrun!" );
+
+         // Copy the debug content down to the real PB.
+         dMemcpy( mLockedBuffer, mDebugGuardBuffer + guardSize, mLockedSize );
+
+         // Cleanup.
+         delete [] mDebugGuardBuffer;
+         mDebugGuardBuffer = NULL;
+         //mLockedBuffer = NULL;
+         mLockedSize = 0;
+      }
+
+   #endif // TORQUE_DEBUG
+    
+   const U32 totalSize = this->mIndexCount * sizeof(U16);
+	  
+   if (mBufferType == GFXBufferTypeStatic || mBufferType == GFXBufferTypeImmutable)
+   {
+      //set up the update region of the buffer
+      D3D11_BOX box;
+      box.back  = 1;
+      box.front = 0;
+      box.top = 0;
+      box.bottom =1;
+      box.left = mIndexStart *sizeof(U16);
+      box.right = mIndexEnd * sizeof(U16);
+      //update the real ib buffer
+      D3D11DEVICECONTEXT->UpdateSubresource(ib, 0, &box,mLockedBuffer,totalSize, 0);
+      //clean up the old buffer
+      delete[] mLockedBuffer;
+      mLockedBuffer = NULL;
+   }
+   else
+   {		 
+      D3D11DEVICECONTEXT->Unmap(ib,0);   
+   }
+  
+   mLocked = false;
+   mIsFirstLock = false;
+   mVolatileBuffer = NULL;
+}
+
+GFXD3D11PrimitiveBuffer::~GFXD3D11PrimitiveBuffer() 
+{
+   if( mBufferType != GFXBufferTypeVolatile )
+   {
+      SAFE_RELEASE(ib);
+   }
+}
+
+void GFXD3D11PrimitiveBuffer::zombify()
+{
+   if (mBufferType == GFXBufferTypeStatic || mBufferType == GFXBufferTypeImmutable)
+      return;
+            
+   AssertFatal(!mLocked, "GFXD3D11PrimitiveBuffer::zombify - Cannot zombify a locked buffer!");
+
+   if (mBufferType == GFXBufferTypeVolatile)
+   {
+      // We must null the volatile buffer else we're holding
+      // a dead pointer which can be set on the device.      
+      ib = NULL;
+      return;
+   }
+
+   // Dynamic buffers get released.
+   SAFE_RELEASE(ib);
+}
+
+void GFXD3D11PrimitiveBuffer::resurrect()
+{
+	if ( mBufferType != GFXBufferTypeDynamic )
+		return;
+
+	D3D11_BUFFER_DESC desc;
+	desc.ByteWidth = sizeof(U16) * mIndexCount;
+	desc.Usage = D3D11_USAGE_DYNAMIC;
+	desc.BindFlags = D3D11_BIND_INDEX_BUFFER;
+	desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
+	desc.MiscFlags = 0;
+	desc.StructureByteStride = 0;
+
+	HRESULT hr = D3D11DEVICE->CreateBuffer(&desc, NULL, &ib);
+
+	if(FAILED(hr)) 
+	{
+		AssertFatal(false, "GFXD3D11PrimitiveBuffer::resurrect - Failed to allocate an index buffer.");
+	}
+}

+ 83 - 0
Engine/source/gfx/D3D11/gfxD3D11PrimitiveBuffer.h

@@ -0,0 +1,83 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+#ifndef _GFXD3D11PRIMITIVEBUFFER_H_
+#define _GFXD3D11PRIMITIVEBUFFER_H_
+
+#include "gfx/gfxPrimitiveBuffer.h"
+
+class GFXD3D11PrimitiveBuffer : public GFXPrimitiveBuffer
+{
+public:
+   ID3D11Buffer *ib;
+   StrongRefPtr<GFXD3D11PrimitiveBuffer> mVolatileBuffer;
+   U32 mVolatileStart;
+   U32 mIndexStart;
+   U32 mIndexEnd;
+
+#ifdef TORQUE_DEBUG
+   #define _PBGuardString "GFX_PRIMTIVE_BUFFER_GUARD_STRING"
+   U8 *mDebugGuardBuffer;   
+   U32 mLockedSize;
+#endif TORQUE_DEBUG
+
+   void *mLockedBuffer;
+   bool mLocked;
+   bool mIsFirstLock;
+
+   GFXD3D11PrimitiveBuffer( GFXDevice *device, 
+                              U32 indexCount, 
+                              U32 primitiveCount, 
+                              GFXBufferType bufferType );
+
+   virtual ~GFXD3D11PrimitiveBuffer();
+
+   virtual void lock(U32 indexStart, U32 indexEnd, void **indexPtr);
+   virtual void unlock();
+
+   virtual void prepare();      
+
+   // GFXResource interface
+   virtual void zombify();
+   virtual void resurrect();
+};
+
+inline GFXD3D11PrimitiveBuffer::GFXD3D11PrimitiveBuffer(   GFXDevice *device, 
+                                                         U32 indexCount, 
+                                                         U32 primitiveCount, 
+                                                         GFXBufferType bufferType ) 
+   : GFXPrimitiveBuffer( device, indexCount, primitiveCount, bufferType )
+{
+   mVolatileStart = 0;
+   ib             = NULL;
+   mIsFirstLock   = true;
+   mLocked = false;
+#ifdef TORQUE_DEBUG
+   mDebugGuardBuffer = NULL;
+   mLockedBuffer = NULL;
+   mLockedSize = 0;
+   mIndexStart = 0;
+   mIndexEnd = 0;
+#endif
+}
+
+#endif

+ 110 - 0
Engine/source/gfx/D3D11/gfxD3D11QueryFence.cpp

@@ -0,0 +1,110 @@
+//-----------------------------------------------------------------------------
+// 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 "gfx/D3D11/gfxD3D11Device.h"
+#include "gfx/D3D11/gfxD3D11QueryFence.h"
+
+GFXD3D11QueryFence::~GFXD3D11QueryFence()
+{
+   SAFE_RELEASE(mQuery);
+}
+
+void GFXD3D11QueryFence::issue()
+{
+   PROFILE_START(GFXD3D11QueryFence_issue);
+
+   // Create the query if we need to
+   if(mQuery == NULL)
+   {
+      D3D11_QUERY_DESC QueryDesc;
+      QueryDesc.Query = D3D11_QUERY_EVENT;
+      QueryDesc.MiscFlags = 0;
+
+      HRESULT hRes = D3D11DEVICE->CreateQuery(&QueryDesc, &mQuery);
+
+      if(FAILED(hRes))
+      {
+         AssertFatal(false, "Hardware does not support D3D11 Queries, this should be caught before this fence type is created" );
+      }
+
+      AssertISV(hRes != E_OUTOFMEMORY, "Out of memory");
+   }
+
+   // Issue the query
+   D3D11DEVICECONTEXT->End(mQuery);
+   PROFILE_END();
+}
+
+GFXFence::FenceStatus GFXD3D11QueryFence::getStatus() const
+{
+   if(mQuery == NULL)
+      return GFXFence::Unset;
+
+   HRESULT hRes = D3D11DEVICECONTEXT->GetData(mQuery, NULL, 0, 0);
+
+   return (hRes == S_OK ? GFXFence::Processed : GFXFence::Pending);
+}
+
+void GFXD3D11QueryFence::block()
+{
+   PROFILE_SCOPE(GFXD3D11QueryFence_block);
+
+   // Calling block() before issue() is valid, catch this case
+   if( mQuery == NULL )
+      return;
+
+   HRESULT hRes;
+   while((hRes = D3D11DEVICECONTEXT->GetData(mQuery, NULL, 0, 0)) == S_FALSE); //D3DGETDATA_FLUSH
+
+}
+
+void GFXD3D11QueryFence::zombify()
+{
+   // Release our query
+   SAFE_RELEASE( mQuery );
+}
+
+void GFXD3D11QueryFence::resurrect()
+{
+   // Recreate the query
+   if(mQuery == NULL)
+   {
+      D3D11_QUERY_DESC QueryDesc;
+      QueryDesc.Query = D3D11_QUERY_EVENT;
+      QueryDesc.MiscFlags = 0;
+
+      HRESULT hRes = D3D11DEVICE->CreateQuery(&QueryDesc, &mQuery);
+
+      if(FAILED(hRes))
+      {
+         AssertFatal(false, "GFXD3D11QueryFence::resurrect - Hardware does not support D3D11 Queries, this should be caught before this fence type is created");
+      }
+
+      AssertISV(hRes != E_OUTOFMEMORY, "GFXD3D11QueryFence::resurrect - Out of memory");
+   }
+}
+
+const String GFXD3D11QueryFence::describeSelf() const
+{
+   // We've got nothing
+   return String();
+}

+ 49 - 0
Engine/source/gfx/D3D11/gfxD3D11QueryFence.h

@@ -0,0 +1,49 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+#ifndef _GFX_D3D11_QUERYFENCE_H_
+#define _GFX_D3D11_QUERYFENCE_H_
+
+#include "gfx/gfxFence.h"
+#include "gfx/gfxResource.h"
+#include "gfx/D3D11/gfxD3D11Device.h"
+
+class GFXD3D11QueryFence : public GFXFence
+{
+private:
+   mutable ID3D11Query *mQuery;
+
+public:
+   GFXD3D11QueryFence( GFXDevice *device ) : GFXFence( device ), mQuery( NULL ) {};
+   virtual ~GFXD3D11QueryFence();
+
+   virtual void issue();
+   virtual FenceStatus getStatus() const;
+   virtual void block();
+
+   // GFXResource interface
+   virtual void zombify();
+   virtual void resurrect();
+   virtual const String describeSelf() const;
+};
+
+#endif

+ 1542 - 0
Engine/source/gfx/D3D11/gfxD3D11Shader.cpp

@@ -0,0 +1,1542 @@
+//-----------------------------------------------------------------------------
+// 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/gfxD3D11Shader.h"
+#include "core/frameAllocator.h"
+#include "core/stream/fileStream.h"
+#include "core/util/safeDelete.h"
+#include "console/console.h"
+
+extern bool gDisassembleAllShaders;
+
+#pragma comment(lib, "d3dcompiler.lib")
+
+gfxD3DIncludeRef GFXD3D11Shader::smD3DInclude = NULL;
+
+class gfxD3D11Include : public ID3DInclude, public StrongRefBase
+{
+private:
+
+   Vector<String> mLastPath;
+
+public:
+
+   void setPath(const String &path)
+   {
+      mLastPath.clear();
+      mLastPath.push_back(path);
+   }
+
+   gfxD3D11Include() {}
+   virtual ~gfxD3D11Include() {}
+
+   STDMETHOD(Open)(THIS_ D3D_INCLUDE_TYPE IncludeType, LPCSTR pFileName, LPCVOID pParentData, LPCVOID *ppData, UINT *pBytes);
+   STDMETHOD(Close)(THIS_ LPCVOID pData);
+};
+
+HRESULT gfxD3D11Include::Open(THIS_ D3D_INCLUDE_TYPE IncludeType, LPCSTR pFileName, LPCVOID pParentData, LPCVOID *ppData, UINT *pBytes)
+{
+   using namespace Torque;
+   // First try making the path relative to the parent.
+   Torque::Path path = Torque::Path::Join( mLastPath.last(), '/', pFileName );
+   path = Torque::Path::CompressPath( path );
+
+   if ( !Torque::FS::ReadFile( path, (void *&)*ppData, *pBytes, true ) )
+   {
+      // Ok... now try using the path as is.
+      path = String( pFileName );
+      path = Torque::Path::CompressPath( path );
+
+      if ( !Torque::FS::ReadFile( path, (void *&)*ppData, *pBytes, true ) )
+      {
+         AssertISV(false, avar( "Failed to open include '%s'.", pFileName));
+         return E_FAIL;
+      }
+   }
+
+   // If the data was of zero size then we cannot recurse
+   // into this file and DX won't call Close() below.
+   //
+   // So in this case don't push on the path.
+   if ( *pBytes > 0 )
+      mLastPath.push_back( path.getRootAndPath() );
+
+   return S_OK;
+}
+
+HRESULT gfxD3D11Include::Close( THIS_ LPCVOID pData )
+{
+   // Free the data file and pop its path off the stack.
+   delete [] (U8*)pData;
+   mLastPath.pop_back();
+
+   return S_OK;
+}
+
+GFXD3D11ShaderConstHandle::GFXD3D11ShaderConstHandle()
+{
+   clear();
+}
+
+const String& GFXD3D11ShaderConstHandle::getName() const
+{
+   if ( mVertexConstant )
+      return mVertexHandle.name;
+   else
+      return mPixelHandle.name;
+}
+
+GFXShaderConstType GFXD3D11ShaderConstHandle::getType() const
+{
+   if ( mVertexConstant )
+      return mVertexHandle.constType;
+   else
+      return mPixelHandle.constType;
+}
+
+U32 GFXD3D11ShaderConstHandle::getArraySize() const
+{
+   if ( mVertexConstant )
+      return mVertexHandle.arraySize;
+   else
+      return mPixelHandle.arraySize;
+}
+
+S32 GFXD3D11ShaderConstHandle::getSamplerRegister() const
+{
+   if ( !mValid || !isSampler() )
+      return -1;
+
+   // We always store sampler type and register index in the pixelHandle,
+   // sampler registers are shared between vertex and pixel shaders anyway.
+
+   return mPixelHandle.offset;   
+}
+
+GFXD3D11ConstBufferLayout::GFXD3D11ConstBufferLayout()
+{
+   mSubBuffers.reserve(CBUFFER_MAX);
+}
+
+bool GFXD3D11ConstBufferLayout::set(const ParamDesc& pd, const GFXShaderConstType constType, const U32 inSize, const void* data, U8* basePointer)
+{
+   PROFILE_SCOPE(GenericConstBufferLayout_set);
+   S32 size = inSize;
+   // Shader compilers like to optimize float4x4 uniforms into float3x3s.
+   // So long as the real paramater is a matrix of-some-type and the data
+   // passed in is a MatrixF ( which is will be ), we DO NOT have a
+   // mismatched const type.
+   AssertFatal(pd.constType == constType ||
+      (
+      (pd.constType == GFXSCT_Float2x2 ||
+      pd.constType == GFXSCT_Float3x3 ||
+      pd.constType == GFXSCT_Float4x4) &&
+      (constType == GFXSCT_Float2x2 ||
+      constType == GFXSCT_Float3x3 ||
+      constType == GFXSCT_Float4x4)
+      ), "Mismatched const type!");
+
+   // This "cute" bit of code allows us to support 2x3 and 3x3 matrices in shader constants but use our MatrixF class.  Yes, a hack. -BTR
+   switch (pd.constType)
+   {
+   case GFXSCT_Float2x2:
+   case GFXSCT_Float3x3:
+   case GFXSCT_Float4x4:
+      return setMatrix(pd, constType, size, data, basePointer);
+      break;
+      // TODO add other AlignedVector here
+   case GFXSCT_Float2:
+      if (size > sizeof(Point2F))
+         size = pd.size;
+   default:
+      break;
+   }
+
+   AssertFatal(pd.size >= size, "Not enough room in the buffer for this data!");
+
+   // Ok, we only set data if it's different than the data we already have, this maybe more expensive than just setting the data, but 
+   // we'll have to do some timings to see.  For example, the lighting shader constants rarely change, but we can't assume that at the
+   // renderInstMgr level, but we can check down here. -BTR
+   if (dMemcmp(basePointer + pd.offset, data, size) != 0)
+   {
+      dMemcpy(basePointer + pd.offset, data, size);
+      return true;
+   }
+   return false;
+}
+
+bool GFXD3D11ConstBufferLayout::setMatrix(const ParamDesc& pd, const GFXShaderConstType constType, const U32 size, const void* data, U8* basePointer)
+{
+   PROFILE_SCOPE(GFXD3D11ConstBufferLayout_setMatrix);
+
+   if (pd.constType == GFXSCT_Float4x4)
+   {
+      // Special case, we can just blast this guy.
+      AssertFatal(pd.size >= size, "Not enough room in the buffer for this data!");
+      if (dMemcmp(basePointer+pd.offset, data, size) != 0)
+      {
+         dMemcpy(basePointer+pd.offset, data, size);         
+         return true;
+      }
+
+      return false;
+   }
+   else
+   {
+      PROFILE_SCOPE(GFXD3D11ConstBufferLayout_setMatrix_not4x4);
+
+      // Figure out how big of a chunk we are copying.  We're going to copy 4 columns by N rows of data
+      U32 csize;
+      switch (pd.constType)
+      {
+      case GFXSCT_Float2x2 :
+         csize = 24; //this takes up 16+8
+         break;
+      case GFXSCT_Float3x3 : 
+         csize = 44; //This takes up 16+16+12
+         break;
+      default:
+         AssertFatal(false, "Unhandled case!");
+         return false;
+         break;
+      }
+
+      // Loop through and copy 
+      bool ret = false;
+      U8* currDestPointer = basePointer+pd.offset;
+      const U8* currSourcePointer = static_cast<const U8*>(data);
+      const U8* endData = currSourcePointer + size;
+      while (currSourcePointer < endData)
+      {
+         if (dMemcmp(currDestPointer, currSourcePointer, csize) != 0)
+         {
+            dMemcpy(currDestPointer, currSourcePointer, csize);            
+            ret = true;
+         }
+
+         currDestPointer += csize;
+         currSourcePointer += sizeof(MatrixF);
+      }
+
+      return ret;
+   }
+}
+
+//------------------------------------------------------------------------------
+GFXD3D11ShaderConstBuffer::GFXD3D11ShaderConstBuffer( GFXD3D11Shader* shader, 
+                                                      GFXD3D11ConstBufferLayout* vertexLayout,
+                                                      GFXD3D11ConstBufferLayout* pixelLayout)
+{
+    AssertFatal( shader, "GFXD3D11ShaderConstBuffer() - Got a null shader!" );
+
+    // We hold on to this so we don't have to call
+    // this virtual method during activation.
+    mShader = shader;
+
+    for (U32 i = 0; i < CBUFFER_MAX; ++i)
+    {
+       mConstantBuffersV[i] = NULL;
+       mConstantBuffersP[i] = NULL;
+    }
+
+    // TODO: Remove buffers and layouts that don't exist for performance?
+    //Mandatory
+    mVertexConstBufferLayout = vertexLayout;
+    mVertexConstBuffer = new GenericConstBuffer(vertexLayout);
+    
+    mPixelConstBufferLayout = pixelLayout;
+    mPixelConstBuffer = new GenericConstBuffer(pixelLayout);
+
+    _createBuffers();
+	
+}
+
+GFXD3D11ShaderConstBuffer::~GFXD3D11ShaderConstBuffer()
+{   
+   // release constant buffer
+   for (U32 i = 0; i < CBUFFER_MAX; ++i)
+   {
+      SAFE_RELEASE(mConstantBuffersP[i]);
+      SAFE_RELEASE(mConstantBuffersV[i]);
+   }
+
+   SAFE_DELETE(mVertexConstBuffer);
+   SAFE_DELETE(mPixelConstBuffer);
+
+
+   if ( mShader )
+      mShader->_unlinkBuffer( this );
+}
+
+void GFXD3D11ShaderConstBuffer::_createBuffers()
+{
+   HRESULT hr;
+   // Create a vertex constant buffer
+   if (mVertexConstBufferLayout->getBufferSize() > 0)
+   {
+      const Vector<ConstSubBufferDesc> &subBuffers = mVertexConstBufferLayout->getSubBufferDesc();
+      for (U32 i = 0; i < subBuffers.size(); ++i)
+      {
+         D3D11_BUFFER_DESC cbDesc;
+         cbDesc.ByteWidth = subBuffers[i].size;
+         cbDesc.Usage = D3D11_USAGE_DEFAULT;
+         cbDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
+         cbDesc.CPUAccessFlags = 0;
+         cbDesc.MiscFlags = 0;
+         cbDesc.StructureByteStride = 0;
+
+         hr = D3D11DEVICE->CreateBuffer(&cbDesc, NULL, &mConstantBuffersV[i]);
+
+         if (FAILED(hr))
+         {
+            AssertFatal(false, "can't create constant mConstantBuffersV!");
+         }
+      }
+   }
+
+   // Create a pixel constant buffer
+   if (mPixelConstBufferLayout->getBufferSize())
+   {
+      const Vector<ConstSubBufferDesc> &subBuffers = mPixelConstBufferLayout->getSubBufferDesc();
+      for (U32 i = 0; i < subBuffers.size(); ++i)
+      {
+         // Create a pixel float constant buffer
+         D3D11_BUFFER_DESC cbDesc;
+         cbDesc.ByteWidth = subBuffers[i].size;
+         cbDesc.Usage = D3D11_USAGE_DEFAULT;
+         cbDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
+         cbDesc.CPUAccessFlags = 0;
+         cbDesc.MiscFlags = 0;
+         cbDesc.StructureByteStride = 0;
+
+         hr = D3D11DEVICE->CreateBuffer(&cbDesc, NULL, &mConstantBuffersP[i]);
+
+         if (FAILED(hr))
+         {
+            AssertFatal(false, "can't create constant mConstantBuffersP!");
+         }
+      }
+   }
+}
+
+GFXShader* GFXD3D11ShaderConstBuffer::getShader()
+{
+   return mShader;
+}
+
+// This is kind of cheesy, but I don't think templates would work well here because 
+// these functions potentially need to be handled differently by other derived types
+template<class T>
+inline void GFXD3D11ShaderConstBuffer::SET_CONSTANT(  GFXShaderConstHandle* handle, const T& fv,
+                                                      GenericConstBuffer *vBuffer, GenericConstBuffer *pBuffer )
+{
+   AssertFatal(static_cast<const GFXD3D11ShaderConstHandle*>(handle), "Incorrect const buffer type!");
+   const GFXD3D11ShaderConstHandle* h = static_cast<const GFXD3D11ShaderConstHandle*>(handle);
+   AssertFatal(h, "Handle is NULL!" );
+   AssertFatal(h->isValid(), "Handle is not valid!" );
+   AssertFatal(!h->isSampler(), "Handle is sampler constant!" );
+   AssertFatal(!mShader.isNull(), "Buffer's shader is null!" );
+   AssertFatal(!h->mShader.isNull(), "Handle's shader is null!" );
+   AssertFatal(h->mShader.getPointer() == mShader.getPointer(), "Mismatched shaders!");
+
+   if ( h->mInstancingConstant )
+   {
+      dMemcpy( mInstPtr+h->mPixelHandle.offset, &fv, sizeof( fv ) );
+      return;
+   }
+   if (h->mVertexConstant)
+      vBuffer->set(h->mVertexHandle, fv);
+   if (h->mPixelConstant)
+      pBuffer->set(h->mPixelHandle, fv);
+}
+
+void GFXD3D11ShaderConstBuffer::set(GFXShaderConstHandle* handle, const F32 fv) 
+{
+   SET_CONSTANT(handle, fv, mVertexConstBuffer, mPixelConstBuffer);
+}
+
+void GFXD3D11ShaderConstBuffer::set(GFXShaderConstHandle* handle, const Point2F& fv) 
+{ 
+   SET_CONSTANT(handle, fv, mVertexConstBuffer, mPixelConstBuffer);
+}
+
+void GFXD3D11ShaderConstBuffer::set(GFXShaderConstHandle* handle, const Point3F& fv) 
+{ 
+   SET_CONSTANT(handle, fv, mVertexConstBuffer, mPixelConstBuffer);
+}
+
+void GFXD3D11ShaderConstBuffer::set(GFXShaderConstHandle* handle, const Point4F& fv) 
+{ 
+   SET_CONSTANT(handle, fv, mVertexConstBuffer, mPixelConstBuffer);
+}
+
+void GFXD3D11ShaderConstBuffer::set(GFXShaderConstHandle* handle, const PlaneF& fv) 
+{ 
+   SET_CONSTANT(handle, fv, mVertexConstBuffer, mPixelConstBuffer);
+}
+
+void GFXD3D11ShaderConstBuffer::set(GFXShaderConstHandle* handle, const ColorF& fv)
+{ 
+   SET_CONSTANT(handle, fv, mVertexConstBuffer, mPixelConstBuffer);
+}
+
+void GFXD3D11ShaderConstBuffer::set(GFXShaderConstHandle* handle, const S32 f)
+{ 
+   // This is the only type that is allowed to be used
+   // with a sampler shader constant type, but it is only
+   // allowed to be set from GLSL.
+   //
+   // So we ignore it here... all other cases will assert.
+   //
+   if ( ((GFXD3D11ShaderConstHandle*)handle)->isSampler() )
+      return;
+
+   SET_CONSTANT(handle, f, mVertexConstBuffer, mPixelConstBuffer);
+}
+
+void GFXD3D11ShaderConstBuffer::set(GFXShaderConstHandle* handle, const Point2I& fv)
+{ 
+   SET_CONSTANT(handle, fv, mVertexConstBuffer, mPixelConstBuffer);
+}
+
+void GFXD3D11ShaderConstBuffer::set(GFXShaderConstHandle* handle, const Point3I& fv)
+{ 
+   SET_CONSTANT(handle, fv, mVertexConstBuffer, mPixelConstBuffer);
+}
+
+void GFXD3D11ShaderConstBuffer::set(GFXShaderConstHandle* handle, const Point4I& fv)
+{ 
+   SET_CONSTANT(handle, fv, mVertexConstBuffer, mPixelConstBuffer);
+}
+
+void GFXD3D11ShaderConstBuffer::set(GFXShaderConstHandle* handle, const AlignedArray<F32>& fv)
+{ 
+   SET_CONSTANT(handle, fv, mVertexConstBuffer, mPixelConstBuffer);
+}
+
+void GFXD3D11ShaderConstBuffer::set(GFXShaderConstHandle* handle, const AlignedArray<Point2F>& fv)
+{ 
+   SET_CONSTANT(handle, fv, mVertexConstBuffer, mPixelConstBuffer);
+}
+
+void GFXD3D11ShaderConstBuffer::set(GFXShaderConstHandle* handle, const AlignedArray<Point3F>& fv)
+{ 
+   SET_CONSTANT(handle, fv, mVertexConstBuffer, mPixelConstBuffer);
+}
+
+void GFXD3D11ShaderConstBuffer::set(GFXShaderConstHandle* handle, const AlignedArray<Point4F>& fv)
+{ 
+   SET_CONSTANT(handle, fv, mVertexConstBuffer, mPixelConstBuffer);
+}
+
+void GFXD3D11ShaderConstBuffer::set(GFXShaderConstHandle* handle, const AlignedArray<S32>& fv)
+{ 
+   SET_CONSTANT(handle, fv, mVertexConstBuffer, mPixelConstBuffer);
+}
+
+void GFXD3D11ShaderConstBuffer::set(GFXShaderConstHandle* handle, const AlignedArray<Point2I>& fv)
+{ 
+   SET_CONSTANT(handle, fv, mVertexConstBuffer, mPixelConstBuffer);
+}
+
+void GFXD3D11ShaderConstBuffer::set(GFXShaderConstHandle* handle, const AlignedArray<Point3I>& fv)
+{ 
+   SET_CONSTANT(handle, fv, mVertexConstBuffer, mPixelConstBuffer);
+}
+
+void GFXD3D11ShaderConstBuffer::set(GFXShaderConstHandle* handle, const AlignedArray<Point4I>& fv)
+{ 
+   SET_CONSTANT(handle, fv, mVertexConstBuffer, mPixelConstBuffer);
+}
+#undef SET_CONSTANT
+
+void GFXD3D11ShaderConstBuffer::set(GFXShaderConstHandle* handle, const MatrixF& mat, const GFXShaderConstType matrixType) 
+{    
+   AssertFatal(handle, "Handle is NULL!" );
+   AssertFatal(handle->isValid(), "Handle is not valid!" );
+
+   AssertFatal(static_cast<const GFXD3D11ShaderConstHandle*>(handle), "Incorrect const buffer type!"); 
+   const GFXD3D11ShaderConstHandle* h = static_cast<const GFXD3D11ShaderConstHandle*>(handle); 
+   AssertFatal(!h->isSampler(), "Handle is sampler constant!" );
+   AssertFatal(h->mShader == mShader, "Mismatched shaders!"); 
+
+   MatrixF transposed;   
+   mat.transposeTo(transposed);
+
+   if (h->mInstancingConstant) 
+   {
+      if ( matrixType == GFXSCT_Float4x4 )
+         dMemcpy( mInstPtr+h->mPixelHandle.offset, mat, sizeof( mat ) );
+         
+      // TODO: Support 3x3 and 2x2 matricies?      
+      return;
+   }
+
+   if (h->mVertexConstant) 
+      mVertexConstBuffer->set(h->mVertexHandle, transposed, matrixType); 
+   if (h->mPixelConstant) 
+      mPixelConstBuffer->set(h->mPixelHandle, transposed, matrixType);
+}
+
+void GFXD3D11ShaderConstBuffer::set(GFXShaderConstHandle* handle, const MatrixF* mat, const U32 arraySize, const GFXShaderConstType matrixType)
+{
+   AssertFatal(handle, "Handle is NULL!" );
+   AssertFatal(handle->isValid(), "Handle is not valid!" );
+
+   AssertFatal(static_cast<const GFXD3D11ShaderConstHandle*>(handle), "Incorrect const buffer type!"); 
+   const GFXD3D11ShaderConstHandle* h = static_cast<const GFXD3D11ShaderConstHandle*>(handle); 
+   AssertFatal(!h->isSampler(), "Handle is sampler constant!" );
+   AssertFatal(h->mShader == mShader, "Mismatched shaders!"); 
+
+   static Vector<MatrixF> transposed;
+   if (arraySize > transposed.size())
+      transposed.setSize(arraySize);   
+   for (U32 i = 0; i < arraySize; i++)
+      mat[i].transposeTo(transposed[i]);
+
+   // TODO: Maybe support this in the future?
+   if (h->mInstancingConstant) 
+      return;
+
+   if (h->mVertexConstant) 
+      mVertexConstBuffer->set(h->mVertexHandle, transposed.begin(), arraySize, matrixType);
+   if (h->mPixelConstant) 
+      mPixelConstBuffer->set(h->mPixelHandle, transposed.begin(), arraySize, matrixType);
+}
+
+const String GFXD3D11ShaderConstBuffer::describeSelf() const
+{
+   String ret;
+   ret = String("   GFXD3D11ShaderConstBuffer\n");
+
+   for (U32 i = 0; i < mVertexConstBufferLayout->getParameterCount(); i++)
+   {
+      GenericConstBufferLayout::ParamDesc pd;
+      mVertexConstBufferLayout->getDesc(i, pd);
+
+      ret += String::ToString("      Constant name: %s", pd.name);
+   }
+
+   return ret;
+}
+
+void GFXD3D11ShaderConstBuffer::zombify()
+{
+}
+
+void GFXD3D11ShaderConstBuffer::resurrect()
+{
+}
+
+bool GFXD3D11ShaderConstBuffer::isDirty()
+{
+   bool ret = mVertexConstBuffer->isDirty();
+   ret |= mPixelConstBuffer->isDirty();
+ 
+   return ret;
+}
+
+void GFXD3D11ShaderConstBuffer::activate( GFXD3D11ShaderConstBuffer *prevShaderBuffer )
+{
+   PROFILE_SCOPE(GFXD3D11ShaderConstBuffer_activate);
+
+   // NOTE: This is a really critical function as it gets
+   // called between every draw call to update the constants.
+   //
+   // Alot of the calls here are inlined... be careful 
+   // what you change.
+
+   // If the buffer has changed we need to compare it
+   // with the new buffer to see if we can skip copying
+   // equal buffer content.
+   //
+   // If the buffer hasn't changed then we only will
+   // be copying the changes that have occured since
+   // the last activate call.
+   if ( prevShaderBuffer != this )
+   {
+      // If the previous buffer is dirty, than we can't compare 
+      // against it, because it hasn't sent its contents to the
+      // card yet and must be copied.
+      if ( prevShaderBuffer && !prevShaderBuffer->isDirty() )
+      {
+         PROFILE_SCOPE(GFXD3D11ShaderConstBuffer_activate_dirty_check_1);
+         // If the buffer content is equal then we set the dirty
+         // flag to false knowing the current state of the card matches
+         // the new buffer.
+         //
+         // If the content is not equal we set the dirty flag to
+         // true which causes the full content of the buffer to be
+         // copied to the card.
+         //
+         mVertexConstBuffer->setDirty( !prevShaderBuffer->mVertexConstBuffer->isEqual( mVertexConstBuffer ) );
+         mPixelConstBuffer->setDirty( !prevShaderBuffer->mPixelConstBuffer->isEqual( mPixelConstBuffer ) ); 
+      } 
+      else
+      {
+         // This happens rarely... but it can happen.
+         // We copy the entire dirty state to the card.
+         PROFILE_SCOPE(GFXD3D11ShaderConstBuffer_activate_dirty_check_2);
+
+         mVertexConstBuffer->setDirty( true );
+         mPixelConstBuffer->setDirty( true );
+      }      
+   }
+
+   ID3D11DeviceContext* devCtx = D3D11DEVICECONTEXT;
+
+   D3D11_MAPPED_SUBRESOURCE pConstData;
+   ZeroMemory(&pConstData, sizeof(D3D11_MAPPED_SUBRESOURCE));
+   
+   const U8* buf;
+   HRESULT hr;
+   U32 nbBuffers = 0;
+   if(mVertexConstBuffer->isDirty())
+   {
+      const Vector<ConstSubBufferDesc> &subBuffers = mVertexConstBufferLayout->getSubBufferDesc();
+      // TODO: This is not very effecient updating the whole lot, re-implement the dirty system to work with multiple constant buffers.
+      // TODO: Implement DX 11.1 UpdateSubresource1 which supports updating ranges with constant buffers
+      buf = mVertexConstBuffer->getEntireBuffer();
+      for (U32 i = 0; i < subBuffers.size(); ++i)
+      {
+         const ConstSubBufferDesc &desc = subBuffers[i];
+         devCtx->UpdateSubresource(mConstantBuffersV[i], 0, NULL, buf + desc.start, desc.size, 0);
+         nbBuffers++;
+      }
+
+      devCtx->VSSetConstantBuffers(0, nbBuffers, mConstantBuffersV);
+   }
+
+   nbBuffers = 0;
+
+   if(mPixelConstBuffer->isDirty())    
+   {
+      const Vector<ConstSubBufferDesc> &subBuffers = mPixelConstBufferLayout->getSubBufferDesc();
+      // TODO: This is not very effecient updating the whole lot, re-implement the dirty system to work with multiple constant buffers.
+      // TODO: Implement DX 11.1 UpdateSubresource1 which supports updating ranges with constant buffers
+      buf = mPixelConstBuffer->getEntireBuffer();
+      for (U32 i = 0; i < subBuffers.size(); ++i)
+      {
+         const ConstSubBufferDesc &desc = subBuffers[i];
+         devCtx->UpdateSubresource(mConstantBuffersP[i], 0, NULL, buf + desc.start, desc.size, 0);
+         nbBuffers++;
+      }
+
+      devCtx->PSSetConstantBuffers(0, nbBuffers, mConstantBuffersP);
+   }
+
+   #ifdef TORQUE_DEBUG
+      // Make sure all the constants for this buffer were assigned.
+      if(mWasLost)
+      {
+         mVertexConstBuffer->assertUnassignedConstants( mShader->getVertexShaderFile().c_str() );
+         mPixelConstBuffer->assertUnassignedConstants( mShader->getPixelShaderFile().c_str() );        
+      }
+   #endif
+
+   // Clear the lost state.
+   mWasLost = false;
+}
+
+void GFXD3D11ShaderConstBuffer::onShaderReload( GFXD3D11Shader *shader )
+{
+   AssertFatal( shader == mShader, "GFXD3D11ShaderConstBuffer::onShaderReload is hosed!" );
+
+   // release constant buffers
+   for (U32 i = 0; i < CBUFFER_MAX; ++i)
+   {
+      SAFE_RELEASE(mConstantBuffersP[i]);
+      SAFE_RELEASE(mConstantBuffersV[i]);
+   }
+
+   SAFE_DELETE( mVertexConstBuffer );
+   SAFE_DELETE( mPixelConstBuffer );
+        
+   AssertFatal( mVertexConstBufferLayout == shader->mVertexConstBufferLayout, "GFXD3D11ShaderConstBuffer::onShaderReload is hosed!" );
+   AssertFatal( mPixelConstBufferLayout == shader->mPixelConstBufferLayout, "GFXD3D11ShaderConstBuffer::onShaderReload is hosed!" );
+
+   mVertexConstBuffer = new GenericConstBuffer( mVertexConstBufferLayout );      
+   mPixelConstBuffer = new GenericConstBuffer( mPixelConstBufferLayout ); 
+  
+   _createBuffers();
+	
+   // Set the lost state.
+   mWasLost = true;
+}
+
+//------------------------------------------------------------------------------
+
+GFXD3D11Shader::GFXD3D11Shader()
+{
+   VECTOR_SET_ASSOCIATION( mShaderConsts );
+
+   AssertFatal(D3D11DEVICE, "Invalid device for shader.");
+   mVertShader = NULL;
+   mPixShader = NULL;
+   mVertexConstBufferLayout = NULL;
+   mPixelConstBufferLayout = NULL;
+
+   if( smD3DInclude == NULL )
+      smD3DInclude = new gfxD3D11Include;
+}
+
+//------------------------------------------------------------------------------
+
+GFXD3D11Shader::~GFXD3D11Shader()
+{
+   for (HandleMap::Iterator i = mHandles.begin(); i != mHandles.end(); i++)
+      delete i->value;
+
+   // delete const buffer layouts
+   SAFE_DELETE(mVertexConstBufferLayout);
+   SAFE_DELETE(mPixelConstBufferLayout);
+
+   // release shaders
+   SAFE_RELEASE(mVertShader);
+   SAFE_RELEASE(mPixShader);
+   //maybe add SAFE_RELEASE(mVertexCode) ?
+}
+
+bool GFXD3D11Shader::_init()
+{
+   PROFILE_SCOPE( GFXD3D11Shader_Init );
+
+   SAFE_RELEASE(mVertShader);
+   SAFE_RELEASE(mPixShader);
+
+   // Create the macro array including the system wide macros.
+   const U32 macroCount = smGlobalMacros.size() + mMacros.size() + 2;
+   FrameTemp<D3D_SHADER_MACRO> d3dMacros( macroCount );
+
+   for ( U32 i=0; i < smGlobalMacros.size(); i++ )
+   {
+      d3dMacros[i].Name = smGlobalMacros[i].name.c_str();
+      d3dMacros[i].Definition = smGlobalMacros[i].value.c_str();
+   }
+
+   for ( U32 i=0; i < mMacros.size(); i++ )
+   {
+      d3dMacros[i+smGlobalMacros.size()].Name = mMacros[i].name.c_str();
+      d3dMacros[i+smGlobalMacros.size()].Definition = mMacros[i].value.c_str();
+   }
+
+   //TODO support D3D_FEATURE_LEVEL properly with shaders instead of hard coding at hlsl 5
+   d3dMacros[macroCount - 2].Name = "TORQUE_SM";
+   d3dMacros[macroCount - 2].Definition = "50";
+
+   memset(&d3dMacros[macroCount - 1], 0, sizeof(D3D_SHADER_MACRO));
+
+   if ( !mVertexConstBufferLayout )
+      mVertexConstBufferLayout = new GFXD3D11ConstBufferLayout();
+   else
+      mVertexConstBufferLayout->clear();
+
+   if ( !mPixelConstBufferLayout )
+      mPixelConstBufferLayout = new GFXD3D11ConstBufferLayout();
+   else
+      mPixelConstBufferLayout->clear(); 
+
+   
+   mSamplerDescriptions.clear();
+   mShaderConsts.clear();
+
+   if ( !Con::getBoolVariable( "$shaders::forceLoadCSF", false ) )
+   {
+      if (!mVertexFile.isEmpty() && !_compileShader( mVertexFile, "vs_5_0", d3dMacros, mVertexConstBufferLayout, mSamplerDescriptions ) )
+         return false;
+
+      if (!mPixelFile.isEmpty() && !_compileShader( mPixelFile, "ps_5_0", d3dMacros, mPixelConstBufferLayout, mSamplerDescriptions ) )
+         return false;
+
+   } 
+   else 
+   {
+      if ( !_loadCompiledOutput( mVertexFile, "vs_5_0", mVertexConstBufferLayout, mSamplerDescriptions ) )
+      {
+         if ( smLogErrors )
+            Con::errorf( "GFXD3D11Shader::init - Unable to load precompiled vertex shader for '%s'.",  mVertexFile.getFullPath().c_str() );
+
+         return false;
+      }
+
+      if ( !_loadCompiledOutput( mPixelFile, "ps_5_0", mPixelConstBufferLayout, mSamplerDescriptions ) )
+      {
+         if ( smLogErrors )
+            Con::errorf( "GFXD3D11Shader::init - Unable to load precompiled pixel shader for '%s'.",  mPixelFile.getFullPath().c_str() );
+
+         return false;
+      }
+   }
+
+   // Existing handles are resored to an uninitialized state.
+   // Those that are found when parsing the layout parameters
+   // will then be re-initialized.
+   HandleMap::Iterator iter = mHandles.begin();
+   for ( ; iter != mHandles.end(); iter++ )        
+      (iter->value)->clear();      
+
+   _buildShaderConstantHandles(mVertexConstBufferLayout, true);
+   _buildShaderConstantHandles(mPixelConstBufferLayout, false);
+
+   _buildSamplerShaderConstantHandles( mSamplerDescriptions );
+   _buildInstancingShaderConstantHandles();
+
+   // Notify any existing buffers that the buffer 
+   // layouts have changed and they need to update.
+   Vector<GFXShaderConstBuffer*>::iterator biter = mActiveBuffers.begin();
+   for ( ; biter != mActiveBuffers.end(); biter++ )
+      ((GFXD3D11ShaderConstBuffer*)(*biter))->onShaderReload( this );
+
+   return true;
+}
+
+bool GFXD3D11Shader::_compileShader( const Torque::Path &filePath, 
+                                    const String& target,                                  
+                                    const D3D_SHADER_MACRO *defines, 
+                                    GenericConstBufferLayout* bufferLayout,
+                                    Vector<GFXShaderConstDesc> &samplerDescriptions )
+{
+   PROFILE_SCOPE( GFXD3D11Shader_CompileShader );
+
+   using namespace Torque;
+
+   HRESULT res = E_FAIL;
+   ID3DBlob* code = NULL;
+   ID3DBlob* errorBuff = NULL;
+   ID3D11ShaderReflection* reflectionTable = NULL;
+
+#ifdef TORQUE_DEBUG
+	U32 flags = D3DCOMPILE_DEBUG | D3DCOMPILE_ENABLE_STRICTNESS | D3DCOMPILE_WARNINGS_ARE_ERRORS;
+#else
+   U32 flags = D3DCOMPILE_ENABLE_STRICTNESS | D3DCOMPILE_OPTIMIZATION_LEVEL3; //TODO double check load times with D3DCOMPILE_OPTIMIZATION_LEVEL3
+   //recommended flags for NSight, uncomment to use. NSight should be used in release mode only. *Still works with above flags however
+   //flags = D3DCOMPILE_DEBUG | D3DCOMPILE_ENABLE_STRICTNESS | D3DCOMPILE_PREFER_FLOW_CONTROL | D3DCOMPILE_SKIP_OPTIMIZATION;
+#endif
+
+#ifdef D3D11_DEBUG_SPEW
+   Con::printf( "Compiling Shader: '%s'", filePath.getFullPath().c_str() );
+#endif
+
+   // Is it an HLSL shader?
+   if(filePath.getExtension().equal("hlsl", String::NoCase))   
+   {
+      // Set this so that the D3DInclude::Open will have this 
+      // information for relative paths.
+      smD3DInclude->setPath(filePath.getRootAndPath());
+
+      FileStream s;
+      if (!s.open(filePath, Torque::FS::File::Read))
+      {
+         AssertISV(false, avar("GFXD3D11Shader::initShader - failed to open shader '%s'.", filePath.getFullPath().c_str()));
+
+         if ( smLogErrors )
+            Con::errorf( "GFXD3D11Shader::_compileShader - Failed to open shader file '%s'.", filePath.getFullPath().c_str() );
+
+         return false;
+      }
+
+      // Convert the path which might have virtualized
+      // mount paths to a real file system path.
+      Torque::Path realPath;
+      if (!FS::GetFSPath( filePath, realPath))
+         realPath = filePath;
+
+      U32 bufSize = s.getStreamSize();
+
+      FrameAllocatorMarker fam;
+      char *buffer = NULL;
+
+      buffer = (char*)fam.alloc(bufSize + 1);
+      s.read(bufSize, buffer);
+      buffer[bufSize] = 0;
+
+      res = D3DCompile(buffer, bufSize, realPath.getFullPath().c_str(), defines, smD3DInclude, "main", target, flags, 0, &code, &errorBuff);
+      
+   }
+
+   // Is it a precompiled obj shader?
+   else if(filePath.getExtension().equal("obj", String::NoCase))
+   {     
+      FileStream  s;
+      if(!s.open(filePath, Torque::FS::File::Read))
+      {
+         AssertISV(false, avar("GFXD3D11Shader::initShader - failed to open shader '%s'.", filePath.getFullPath().c_str()));
+
+         if ( smLogErrors )
+            Con::errorf( "GFXD3D11Shader::_compileShader - Failed to open shader file '%s'.", filePath.getFullPath().c_str() );
+
+         return false;
+      }
+
+	  res = D3DCreateBlob(s.getStreamSize(), &code);
+      AssertISV(SUCCEEDED(res), "Unable to create buffer!");
+      s.read(s.getStreamSize(), code->GetBufferPointer());
+   }
+   else
+   {
+      if (smLogErrors)
+         Con::errorf("GFXD3D11Shader::_compileShader - Unsupported shader file type '%s'.", filePath.getFullPath().c_str());
+
+      return false;
+   }  
+
+   if(errorBuff)
+   {
+      // remove \n at end of buffer
+      U8 *buffPtr = (U8*) errorBuff->GetBufferPointer();
+      U32 len = dStrlen( (const char*) buffPtr );
+      buffPtr[len-1] = '\0';
+
+      if(FAILED(res))
+      {
+         if(smLogErrors)
+          Con::errorf("failed to compile shader: %s", buffPtr);
+      }
+      else
+      {
+         if(smLogWarnings)
+            Con::errorf("shader compiled with warning(s): %s", buffPtr);
+      }
+   }
+   else if (code == NULL && smLogErrors)
+      Con::errorf( "GFXD3D11Shader::_compileShader - no compiled code produced; possibly missing file '%s'.", filePath.getFullPath().c_str() );
+
+   AssertISV(SUCCEEDED(res), "Unable to compile shader!");
+
+   if(code != NULL)
+   {
+#ifndef TORQUE_SHIPPING         
+
+         if(gDisassembleAllShaders)
+         {
+            ID3DBlob* disassem = NULL;
+            D3DDisassemble(code->GetBufferPointer(), code->GetBufferSize(), 0, NULL, &disassem);
+            mDissasembly = (const char*)disassem->GetBufferPointer();
+
+            String filename = filePath.getFullPath();
+            filename.replace( ".hlsl", "_dis.txt" );
+
+            FileStream *fstream = FileStream::createAndOpen( filename, Torque::FS::File::Write );
+            if ( fstream )
+            {            
+               fstream->write( mDissasembly );
+               fstream->close();
+               delete fstream;   
+            }
+
+            SAFE_RELEASE(disassem);
+         }         
+
+#endif
+
+         if (target.compare("ps_", 3) == 0)      
+            res = D3D11DEVICE->CreatePixelShader(code->GetBufferPointer(), code->GetBufferSize(), NULL,  &mPixShader);
+         else if (target.compare("vs_", 3) == 0)
+            res = D3D11DEVICE->CreateVertexShader(code->GetBufferPointer(), code->GetBufferSize(), NULL, &mVertShader);
+         
+         if (FAILED(res))
+         {
+            AssertFatal(false, "D3D11Shader::_compilershader- failed to create shader");
+         }
+
+	      if(res == S_OK){
+		      HRESULT reflectionResult = D3DReflect(code->GetBufferPointer(), code->GetBufferSize(), IID_ID3D11ShaderReflection, (void**)&reflectionTable);
+		   if(FAILED(reflectionResult))
+		      AssertFatal(false, "D3D11Shader::_compilershader - Failed to get shader reflection table interface");
+	  }
+
+	  if(res == S_OK)
+		_getShaderConstants(reflectionTable, bufferLayout, samplerDescriptions);	  
+
+#ifdef TORQUE_ENABLE_CSF_GENERATION
+
+      // Ok, we've got a valid shader and constants, let's write them all out.
+      if (!_saveCompiledOutput(filePath, code, bufferLayout) && smLogErrors)
+         Con::errorf( "GFXD3D11Shader::_compileShader - Unable to save shader compile output for: %s", 
+            filePath.getFullPath().c_str());
+#endif
+
+      if(FAILED(res) && smLogErrors)
+         Con::errorf("GFXD3D11Shader::_compileShader - Unable to create shader for '%s'.", filePath.getFullPath().c_str());
+   }
+
+   //bool result = code && SUCCEEDED(res) && HasValidConstants;
+   bool result = code && SUCCEEDED(res);
+
+#ifdef TORQUE_DEBUG
+   if (target.compare("vs_", 3) == 0)
+   {
+      String vertShader = mVertexFile.getFileName();
+      mVertShader->SetPrivateData(WKPDID_D3DDebugObjectName, vertShader.size(), vertShader.c_str());
+   }
+   else if (target.compare("ps_", 3) == 0)
+   {
+      String pixelShader = mPixelFile.getFileName();
+      mPixShader->SetPrivateData(WKPDID_D3DDebugObjectName, pixelShader.size(), pixelShader.c_str());
+   }
+#endif
+  
+   SAFE_RELEASE(code); 
+   SAFE_RELEASE(reflectionTable);
+   SAFE_RELEASE(errorBuff);
+
+   return result;
+}
+void GFXD3D11Shader::_getShaderConstants( ID3D11ShaderReflection *table, 
+                                         GenericConstBufferLayout *bufferLayoutIn,
+                                         Vector<GFXShaderConstDesc> &samplerDescriptions )
+{
+   PROFILE_SCOPE( GFXD3D11Shader_GetShaderConstants );
+
+   AssertFatal(table, "NULL constant table not allowed, is this an assembly shader?");
+
+   GFXD3D11ConstBufferLayout *bufferLayout = (GFXD3D11ConstBufferLayout*)bufferLayoutIn;
+   Vector<ConstSubBufferDesc> &subBuffers = bufferLayout->getSubBufferDesc();
+   subBuffers.clear();
+
+   D3D11_SHADER_DESC tableDesc;
+   HRESULT hr = table->GetDesc(&tableDesc);
+   if (FAILED(hr))
+   {
+	   AssertFatal(false, "Shader Reflection table unable to be created");
+   }
+   
+   //offset for sub constant buffers
+   U32 bufferOffset = 0;
+   for (U32 i = 0; i < tableDesc.ConstantBuffers; i++)
+   {
+	   ID3D11ShaderReflectionConstantBuffer* constantBuffer = table->GetConstantBufferByIndex(i);
+	   D3D11_SHADER_BUFFER_DESC constantBufferDesc;
+
+      if (constantBuffer->GetDesc(&constantBufferDesc) == S_OK)
+      {
+
+   #ifdef TORQUE_DEBUG
+         AssertFatal(constantBufferDesc.Type == D3D_CT_CBUFFER, "Only scalar cbuffers supported for now.");
+
+         if (dStrcmp(constantBufferDesc.Name, "$Globals") != 0 && dStrcmp(constantBufferDesc.Name, "$Params") != 0)
+            AssertFatal(false, "Only $Global and $Params cbuffer supported for now.");
+   #endif
+   #ifdef D3D11_DEBUG_SPEW
+         Con::printf("Constant Buffer Name: %s", constantBufferDesc.Name);
+   #endif 
+         
+         for(U32 j =0; j< constantBufferDesc.Variables; j++)
+		   {
+            GFXShaderConstDesc desc;
+			   ID3D11ShaderReflectionVariable* variable = constantBuffer->GetVariableByIndex(j); 
+			   D3D11_SHADER_VARIABLE_DESC variableDesc;
+			   D3D11_SHADER_TYPE_DESC variableTypeDesc;
+
+			   variable->GetDesc(&variableDesc);
+
+			   ID3D11ShaderReflectionType* variableType =variable->GetType();
+
+			   variableType->GetDesc(&variableTypeDesc);
+			   desc.name = String(variableDesc.Name);
+			   // Prepend a "$" if it doesn't exist.  Just to make things consistent.
+			   if (desc.name.find("$") != 0)
+			      desc.name = String::ToString("$%s", desc.name.c_str());
+
+            bool unusedVar = variableDesc.uFlags & D3D_SVF_USED ? false : true;
+
+            if (variableTypeDesc.Elements == 0)
+               desc.arraySize = 1;
+            else
+               desc.arraySize = variableTypeDesc.Elements;
+
+   #ifdef D3D11_DEBUG_SPEW
+            Con::printf("Variable Name %s:, offset: %d, size: %d, constantDesc.Elements: %d", desc.name.c_str(), variableDesc.StartOffset, variableDesc.Size, desc.arraySize);
+   #endif           
+            if (_convertShaderVariable(variableTypeDesc, desc))
+            {
+               //The HLSL compiler for 4.0 and above doesn't strip out unused registered constants. We'll have to do it manually
+               if (!unusedVar)
+               {
+                  mShaderConsts.push_back(desc);
+                  U32 alignBytes = getAlignmentValue(desc.constType);
+                  U32 paramSize = variableDesc.Size;
+                  bufferLayout->addParameter(   desc.name,
+                                                desc.constType,
+                                                variableDesc.StartOffset + bufferOffset,
+                                                paramSize,
+                                                desc.arraySize,
+                                                alignBytes);
+
+               } //unusedVar
+            } //_convertShaderVariable
+		   } //constantBufferDesc.Variables
+
+         // fill out our const sub buffer sizes etc
+         ConstSubBufferDesc subBufferDesc;
+         subBufferDesc.size = constantBufferDesc.Size;
+         subBufferDesc.start = bufferOffset;
+         subBuffers.push_back(subBufferDesc);
+         // increase our bufferOffset by the constant buffer size
+         bufferOffset += constantBufferDesc.Size;
+
+      }
+      else
+         AssertFatal(false, "Unable to get shader constant description! (may need more elements of constantDesc");	
+   }
+
+   // Set buffer size to the aligned size
+   bufferLayout->setSize(bufferOffset);
+
+
+   //get the sampler descriptions from the resource binding description
+   U32 resourceCount = tableDesc.BoundResources;
+   for (U32 i = 0; i < resourceCount; i++)
+   {
+      GFXShaderConstDesc desc;
+      D3D11_SHADER_INPUT_BIND_DESC bindDesc;
+      table->GetResourceBindingDesc(i, &bindDesc);
+
+      switch (bindDesc.Type)
+      {
+      case D3D_SIT_SAMPLER:
+         // Prepend a "$" if it doesn't exist.  Just to make things consistent.
+         desc.name = String(bindDesc.Name);
+         if (desc.name.find("$") != 0)
+            desc.name = String::ToString("$%s", desc.name.c_str());
+         desc.constType = GFXSCT_Sampler;
+         desc.arraySize = bindDesc.BindPoint;
+         samplerDescriptions.push_back(desc);
+         break;
+
+      }
+   }
+
+}
+
+bool GFXD3D11Shader::_convertShaderVariable(const D3D11_SHADER_TYPE_DESC &typeDesc, GFXShaderConstDesc &desc)
+{
+   switch (typeDesc.Type)
+   {
+   case D3D_SVT_INT:
+   {
+      switch (typeDesc.Class)
+      {
+      case D3D_SVC_SCALAR:
+         desc.constType = GFXSCT_Int;
+         break;
+      case D3D_SVC_VECTOR:
+      {
+         switch (typeDesc.Columns)
+         {
+         case 1:
+            desc.constType = GFXSCT_Int;
+            break;
+         case 2:
+            desc.constType = GFXSCT_Int2;
+            break;
+         case 3:
+            desc.constType = GFXSCT_Int3;
+            break;
+         case 4:
+            desc.constType = GFXSCT_Int4;
+            break;
+         }
+      }
+      break;
+      }
+      break;
+   }   
+   case D3D_SVT_FLOAT:
+   {
+      switch (typeDesc.Class)
+      {
+      case D3D_SVC_SCALAR:
+         desc.constType = GFXSCT_Float;
+         break;
+      case D3D_SVC_VECTOR:
+      {
+         switch (typeDesc.Columns)
+         {
+         case 1:
+            desc.constType = GFXSCT_Float;
+            break;
+         case 2:
+            desc.constType = GFXSCT_Float2;
+            break;
+         case 3:
+            desc.constType = GFXSCT_Float3;
+            break;
+         case 4:
+            desc.constType = GFXSCT_Float4;
+            break;
+         }
+      }
+      break;
+      case D3D_SVC_MATRIX_ROWS:
+      case D3D_SVC_MATRIX_COLUMNS:
+      {
+         switch (typeDesc.Columns)
+         {
+         case 3:
+            if (typeDesc.Rows == 3)
+            {
+               desc.constType = GFXSCT_Float3x3;
+            }
+            break;
+         case 4:
+            if (typeDesc.Rows == 4)
+            {
+               desc.constType = GFXSCT_Float4x4;
+            }
+            break;
+         }
+      }
+      break;
+      case D3D_SVC_OBJECT:
+      case D3D_SVC_STRUCT:
+         return false;
+      }
+   }
+   break;
+
+   default:
+      AssertFatal(false, "Unknown shader constant class enum");
+      break;
+   }
+
+   return true;
+}
+
+const U32 GFXD3D11Shader::smCompiledShaderTag = MakeFourCC('t','c','s','f');
+
+bool GFXD3D11Shader::_saveCompiledOutput( const Torque::Path &filePath, 
+                                         ID3DBlob *buffer, 
+                                         GenericConstBufferLayout *bufferLayout,
+                                         Vector<GFXShaderConstDesc> &samplerDescriptions )
+{
+   Torque::Path outputPath(filePath);
+   outputPath.setExtension("csf");     // "C"ompiled "S"hader "F"ile (fancy!)
+
+   FileStream f;
+   if (!f.open(outputPath, Torque::FS::File::Write))
+      return false;
+   if (!f.write(smCompiledShaderTag))
+      return false;
+   // We could reverse engineer the structure in the compiled output, but this
+   // is a bit easier because we can just read it into the struct that we want.
+   if (!bufferLayout->write(&f))
+      return false;
+
+   U32 bufferSize = buffer->GetBufferSize();
+   if (!f.write(bufferSize))
+      return false;
+   if (!f.write(bufferSize, buffer->GetBufferPointer()))
+      return false;
+
+   // Write out sampler descriptions.
+
+   f.write( samplerDescriptions.size() );   
+
+   for ( U32 i = 0; i < samplerDescriptions.size(); i++ )
+   {
+      f.write( samplerDescriptions[i].name );
+      f.write( (U32)(samplerDescriptions[i].constType) );
+      f.write( samplerDescriptions[i].arraySize );
+   }
+
+   f.close();
+
+   return true;
+}
+
+bool GFXD3D11Shader::_loadCompiledOutput( const Torque::Path &filePath, 
+                                         const String &target, 
+                                         GenericConstBufferLayout *bufferLayout,
+                                         Vector<GFXShaderConstDesc> &samplerDescriptions )
+{
+   Torque::Path outputPath(filePath);
+   outputPath.setExtension("csf");     // "C"ompiled "S"hader "F"ile (fancy!)
+
+   FileStream f;
+   if (!f.open(outputPath, Torque::FS::File::Read))
+      return false;
+   U32 fileTag;
+   if (!f.read(&fileTag))
+      return false;
+   if (fileTag != smCompiledShaderTag)
+      return false;
+   if (!bufferLayout->read(&f))
+      return false;
+   U32 bufferSize;
+   if (!f.read(&bufferSize))
+      return false;
+   U32 waterMark = FrameAllocator::getWaterMark();
+   DWORD* buffer = static_cast<DWORD*>(FrameAllocator::alloc(bufferSize));
+   if (!f.read(bufferSize, buffer))
+      return false;
+
+   // Read sampler descriptions.
+
+   U32 samplerCount;
+   f.read( &samplerCount );   
+
+   for ( U32 i = 0; i < samplerCount; i++ )
+   {
+      GFXShaderConstDesc samplerDesc;
+      f.read( &(samplerDesc.name) );
+      f.read( (U32*)&(samplerDesc.constType) );
+      f.read( &(samplerDesc.arraySize) );
+
+      samplerDescriptions.push_back( samplerDesc );
+   }
+
+   f.close();
+
+   HRESULT res;
+   if (target.compare("ps_", 3) == 0)      
+      res = D3D11DEVICE->CreatePixelShader(buffer, bufferSize, NULL, &mPixShader);
+   else
+      res = D3D11DEVICE->CreateVertexShader(buffer, bufferSize, NULL, &mVertShader);
+   AssertFatal(SUCCEEDED(res), "Unable to load shader!");
+
+   FrameAllocator::setWaterMark(waterMark);
+   return SUCCEEDED(res);
+}
+
+void GFXD3D11Shader::_buildShaderConstantHandles(GenericConstBufferLayout* layout, bool vertexConst)
+{                     
+   for (U32 i = 0; i < layout->getParameterCount(); i++)
+   {
+      GenericConstBufferLayout::ParamDesc pd;
+      layout->getDesc(i, pd);
+
+      GFXD3D11ShaderConstHandle* handle;
+      HandleMap::Iterator j = mHandles.find(pd.name);
+
+      if (j != mHandles.end())
+      {
+         handle = j->value;         
+         handle->mShader = this;
+         handle->setValid( true );
+      } 
+      else
+      {
+         handle = new GFXD3D11ShaderConstHandle();
+         handle->mShader = this;
+         mHandles[pd.name] = handle;
+         handle->setValid( true );
+      }
+
+      if (vertexConst)
+      {
+         handle->mVertexConstant = true;
+         handle->mVertexHandle = pd;
+      }
+      else
+      {
+         handle->mPixelConstant = true;
+         handle->mPixelHandle = pd;
+      }
+   }
+}
+
+void GFXD3D11Shader::_buildSamplerShaderConstantHandles( Vector<GFXShaderConstDesc> &samplerDescriptions )
+{                     
+   Vector<GFXShaderConstDesc>::iterator iter = samplerDescriptions.begin();
+   for ( ; iter != samplerDescriptions.end(); iter++ )
+   {
+      const GFXShaderConstDesc &desc = *iter;
+
+      AssertFatal(   desc.constType == GFXSCT_Sampler || 
+                     desc.constType == GFXSCT_SamplerCube, 
+                     "GFXD3D11Shader::_buildSamplerShaderConstantHandles - Invalid samplerDescription type!" );
+
+      GFXD3D11ShaderConstHandle *handle;
+      HandleMap::Iterator j = mHandles.find(desc.name);
+
+      if ( j != mHandles.end() )
+         handle = j->value;
+      else
+      {
+         handle = new GFXD3D11ShaderConstHandle();
+         mHandles[desc.name] = handle;         
+      }
+
+      handle->mShader = this;         
+      handle->setValid( true );         
+      handle->mPixelConstant = true;
+      handle->mPixelHandle.name = desc.name;
+      handle->mPixelHandle.constType = desc.constType;
+      handle->mPixelHandle.offset = desc.arraySize;         
+   }
+}
+
+void GFXD3D11Shader::_buildInstancingShaderConstantHandles()
+{
+   // If we have no instancing than just return
+   if (!mInstancingFormat)
+      return;
+
+   U32 offset = 0;
+   for ( U32 i=0; i < mInstancingFormat->getElementCount(); i++ )
+   {
+      const GFXVertexElement &element = mInstancingFormat->getElement( i );
+      
+      String constName = String::ToString( "$%s", element.getSemantic().c_str() );
+
+      GFXD3D11ShaderConstHandle *handle;
+      HandleMap::Iterator j = mHandles.find( constName );
+
+      if ( j != mHandles.end() )
+         handle = j->value; 
+      else
+      {
+         handle = new GFXD3D11ShaderConstHandle();
+         mHandles[ constName ] = handle;         
+      }
+
+      handle->mShader = this;
+      handle->setValid( true );         
+      handle->mInstancingConstant = true;
+
+      // We shouldn't have an instancing constant that is also 
+      // a vertex or pixel constant!  This means the shader features
+      // are confused as to what is instanced.
+      //
+      AssertFatal(   !handle->mVertexConstant &&
+                     !handle->mPixelConstant,
+                     "GFXD3D11Shader::_buildInstancingShaderConstantHandles - Bad instanced constant!" );
+
+      // HACK:  The GFXD3D11ShaderConstHandle will check mVertexConstant then
+      // fall back to reading the mPixelHandle values.  We depend on this here
+      // and store the data we need in the mPixelHandle constant although its
+      // not a pixel shader constant.
+      //
+      handle->mPixelHandle.name = constName;
+      handle->mPixelHandle.offset = offset;
+
+      // If this is a matrix we will have 2 or 3 more of these
+      // semantics with the same name after it.
+      for ( ; i < mInstancingFormat->getElementCount(); i++ )
+      {
+         const GFXVertexElement &nextElement = mInstancingFormat->getElement( i );
+         if ( nextElement.getSemantic() != element.getSemantic() )
+         {
+            i--;
+            break;
+         }
+         offset += nextElement.getSizeInBytes();
+      }
+   }
+}
+
+GFXShaderConstBufferRef GFXD3D11Shader::allocConstBuffer()
+{
+   if (mVertexConstBufferLayout && mPixelConstBufferLayout)
+   {
+      GFXD3D11ShaderConstBuffer* buffer = new GFXD3D11ShaderConstBuffer(this, mVertexConstBufferLayout, mPixelConstBufferLayout);
+      mActiveBuffers.push_back( buffer );
+      buffer->registerResourceWithDevice(getOwningDevice());
+      return buffer;
+   } 
+
+   return NULL;
+}
+
+/// Returns a shader constant handle for name, if the variable doesn't exist NULL is returned.
+GFXShaderConstHandle* GFXD3D11Shader::getShaderConstHandle(const String& name)
+{
+   HandleMap::Iterator i = mHandles.find(name);   
+   if ( i != mHandles.end() )
+   {
+      return i->value;
+   } 
+   else 
+   {     
+      GFXD3D11ShaderConstHandle *handle = new GFXD3D11ShaderConstHandle();
+      handle->setValid( false );
+      handle->mShader = this;
+      mHandles[name] = handle;
+
+      return handle;      
+   }      
+}
+
+GFXShaderConstHandle* GFXD3D11Shader::findShaderConstHandle(const String& name)
+{
+   HandleMap::Iterator i = mHandles.find(name);
+   if(i != mHandles.end())
+      return i->value;
+   else
+   {
+      return NULL;
+   }
+}
+
+const Vector<GFXShaderConstDesc>& GFXD3D11Shader::getShaderConstDesc() const
+{
+   return mShaderConsts;
+}
+
+U32 GFXD3D11Shader::getAlignmentValue(const GFXShaderConstType constType) const
+{   
+   const U32 mRowSizeF = 16;
+   const U32 mRowSizeI = 16;
+
+   switch (constType)
+   {
+      case GFXSCT_Float :
+      case GFXSCT_Float2 :
+      case GFXSCT_Float3 : 
+      case GFXSCT_Float4 :
+         return mRowSizeF;
+         break;
+         // Matrices
+      case GFXSCT_Float2x2 :
+         return mRowSizeF * 2;
+         break;
+      case GFXSCT_Float3x3 : 
+         return mRowSizeF * 3;
+         break;
+      case GFXSCT_Float4x4 :
+         return mRowSizeF * 4;
+         break;   
+      //// Scalar
+      case GFXSCT_Int :
+      case GFXSCT_Int2 :
+      case GFXSCT_Int3 : 
+      case GFXSCT_Int4 :
+         return mRowSizeI;
+         break;
+      default:
+         AssertFatal(false, "Unsupported type!");
+         return 0;
+         break;
+   }
+}
+
+void GFXD3D11Shader::zombify()
+{
+   // Shaders don't need zombification
+}
+
+void GFXD3D11Shader::resurrect()
+{
+   // Shaders are never zombies, and therefore don't have to be brought back.
+}

+ 471 - 0
Engine/source/gfx/D3D11/gfxD3D11Shader.h

@@ -0,0 +1,471 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+#ifndef _GFXD3D11SHADER_H_
+#define _GFXD3D11SHADER_H_
+
+#include <d3dcompiler.h>
+
+#include "core/util/path.h"
+#include "core/util/tDictionary.h"
+#include "gfx/gfxShader.h"
+#include "gfx/gfxResource.h"
+#include "gfx/genericConstBuffer.h"
+#include "gfx/D3D11/gfxD3D11Device.h"
+
+class GFXD3D11Shader;
+
+enum CONST_CLASS
+{
+	D3DPC_SCALAR,
+	D3DPC_VECTOR,
+	D3DPC_MATRIX_ROWS,
+	D3DPC_MATRIX_COLUMNS,
+	D3DPC_OBJECT,
+	D3DPC_STRUCT
+};
+
+enum CONST_TYPE 
+{ 
+   D3DPT_VOID, 
+   D3DPT_BOOL, 
+   D3DPT_INT, 
+   D3DPT_FLOAT, 
+   D3DPT_STRING, 
+   D3DPT_TEXTURE, 
+   D3DPT_TEXTURE1D, 
+   D3DPT_TEXTURE2D, 
+   D3DPT_TEXTURE3D, 
+   D3DPT_TEXTURECUBE, 
+   D3DPT_SAMPLER, 
+   D3DPT_SAMPLER1D, 
+   D3DPT_SAMPLER2D, 
+   D3DPT_SAMPLER3D, 
+   D3DPT_SAMPLERCUBE, 
+   D3DPT_PIXELSHADER, 
+   D3DPT_VERTEXSHADER, 
+   D3DPT_PIXELFRAGMENT, 
+   D3DPT_VERTEXFRAGMENT
+};
+
+enum REGISTER_TYPE
+{
+	D3DRS_BOOL,
+	D3DRS_INT4,
+	D3DRS_FLOAT4,
+	D3DRS_SAMPLER
+};
+
+struct ConstantDesc
+{
+   String Name;
+   S32 RegisterIndex;
+   S32 RegisterCount;
+   S32 Rows;
+   S32 Columns;
+   S32 Elements;
+   S32 StructMembers;
+   REGISTER_TYPE RegisterSet;
+   CONST_CLASS Class;
+   CONST_TYPE Type;
+   U32 Bytes;
+};
+
+class ConstantTable
+{
+public:
+   bool Create(const void* data);
+
+   U32 GetConstantCount() const { return m_constants.size(); }
+   const String& GetCreator() const { return m_creator; } 
+
+   const ConstantDesc* GetConstantByIndex(U32 i) const { return &m_constants[i]; }
+   const ConstantDesc* GetConstantByName(const String& name) const;
+
+   void ClearConstants() { m_constants.clear(); }
+
+private:
+   Vector<ConstantDesc> m_constants;
+   String m_creator;
+};
+
+// Structs
+struct CTHeader
+{
+   U32 Size;
+   U32 Creator;
+   U32 Version;
+   U32 Constants;
+   U32 ConstantInfo;
+   U32 Flags;
+   U32 Target;
+};
+
+struct CTInfo
+{
+   U32 Name;
+   U16 RegisterSet;
+   U16 RegisterIndex;
+   U16 RegisterCount;
+   U16 Reserved;
+   U32 TypeInfo;
+   U32 DefaultValue;
+};
+
+struct CTType
+{
+   U16 Class;
+   U16 Type;
+   U16 Rows;
+   U16 Columns;
+   U16 Elements;
+   U16 StructMembers;
+   U32 StructMemberInfo;
+};
+
+// Shader instruction opcodes
+const U32 SIO_COMMENT = 0x0000FFFE;
+const U32 SIO_END = 0x0000FFFF;
+const U32 SI_OPCODE_MASK = 0x0000FFFF;
+const U32 SI_COMMENTSIZE_MASK = 0x7FFF0000;
+const U32 CTAB_CONSTANT = 0x42415443;
+
+// Member functions
+inline bool ConstantTable::Create(const void* data)
+{
+   const U32* ptr = static_cast<const U32*>(data);
+   while(*++ptr != SIO_END)
+   {
+      if((*ptr & SI_OPCODE_MASK) == SIO_COMMENT)
+      {
+         // Check for CTAB comment
+         U32 comment_size = (*ptr & SI_COMMENTSIZE_MASK) >> 16;
+         if(*(ptr+1) != CTAB_CONSTANT)
+         {
+            ptr += comment_size;
+            continue;
+         }
+
+         // Read header
+         const char* ctab = reinterpret_cast<const char*>(ptr+2);
+         size_t ctab_size = (comment_size-1)*4;
+
+         const CTHeader* header = reinterpret_cast<const CTHeader*>(ctab);
+         if(ctab_size < sizeof(*header) || header->Size != sizeof(*header))
+            return false;
+         m_creator = ctab + header->Creator;
+
+         // Read constants
+         m_constants.reserve(header->Constants);
+         const CTInfo* info = reinterpret_cast<const CTInfo*>(ctab + header->ConstantInfo);
+         for(U32 i = 0; i < header->Constants; ++i)
+         {
+            const CTType* type = reinterpret_cast<const CTType*>(ctab + info[i].TypeInfo);
+
+            // Fill struct
+            ConstantDesc desc;
+            desc.Name = ctab + info[i].Name;
+            desc.RegisterSet = static_cast<REGISTER_TYPE>(info[i].RegisterSet);
+            desc.RegisterIndex = info[i].RegisterIndex;
+            desc.RegisterCount = info[i].RegisterCount;
+            desc.Rows = type->Rows;
+            desc.Class = static_cast<CONST_CLASS>(type->Class);
+            desc.Type = static_cast<CONST_TYPE>(type->Type);
+            desc.Columns = type->Columns;
+            desc.Elements = type->Elements;
+            desc.StructMembers = type->StructMembers;
+            desc.Bytes = 4 * desc.Elements * desc.Rows * desc.Columns;
+            m_constants.push_back(desc);
+         }
+
+         return true;
+      }
+   }
+   return false;
+}
+
+inline const ConstantDesc* ConstantTable::GetConstantByName(const String& name) const
+{
+   Vector<ConstantDesc>::const_iterator it;
+   for(it = m_constants.begin(); it != m_constants.end(); ++it)
+   {
+      if(it->Name == name)
+         return &(*it);
+   }
+   return NULL;
+}
+
+/////////////////// Constant Buffers /////////////////////////////
+
+// Maximum number of CBuffers ($Globals & $Params)
+const U32 CBUFFER_MAX = 2;
+
+struct ConstSubBufferDesc
+{
+   U32 start;
+   U32 size;
+
+   ConstSubBufferDesc() : start(0), size(0){}
+};
+
+class GFXD3D11ConstBufferLayout : public GenericConstBufferLayout
+{
+public:
+   GFXD3D11ConstBufferLayout();
+   /// Get our constant sub buffer data
+   Vector<ConstSubBufferDesc> &getSubBufferDesc(){ return mSubBuffers; }
+   
+   /// We need to manually set the size due to D3D11 alignment
+   void setSize(U32 size){ mBufferSize = size;}
+
+   /// Set a parameter, given a base pointer
+   virtual bool set(const ParamDesc& pd, const GFXShaderConstType constType, const U32 size, const void* data, U8* basePointer);
+
+protected:
+   /// Set a matrix, given a base pointer
+   virtual bool setMatrix(const ParamDesc& pd, const GFXShaderConstType constType, const U32 size, const void* data, U8* basePointer);
+
+   Vector<ConstSubBufferDesc> mSubBuffers;
+};
+
+class GFXD3D11ShaderConstHandle : public GFXShaderConstHandle
+{
+public:   
+
+   // GFXShaderConstHandle
+   const String& getName() const;
+   GFXShaderConstType getType() const;
+   U32 getArraySize() const;
+
+   WeakRefPtr<GFXD3D11Shader> mShader;
+
+   bool mVertexConstant;
+   GenericConstBufferLayout::ParamDesc mVertexHandle;
+   bool mPixelConstant;
+   GenericConstBufferLayout::ParamDesc mPixelHandle;
+   
+   /// Is true if this constant is for hardware mesh instancing.
+   ///
+   /// Note: We currently store its settings in mPixelHandle.
+   ///
+   bool mInstancingConstant;
+
+   void setValid( bool valid ) { mValid = valid; }
+   S32 getSamplerRegister() const;
+
+   // Returns true if this is a handle to a sampler register.
+   bool isSampler() const 
+   {
+      return ( mPixelConstant && mPixelHandle.constType >= GFXSCT_Sampler ) || ( mVertexConstant && mVertexHandle.constType >= GFXSCT_Sampler );
+   }
+
+   /// Restore to uninitialized state.
+   void clear()
+   {
+      mShader = NULL;
+      mVertexConstant = false;
+      mPixelConstant = false;
+      mInstancingConstant = false;
+      mVertexHandle.clear();
+      mPixelHandle.clear();
+      mValid = false;
+   }
+
+   GFXD3D11ShaderConstHandle();
+};
+
+/// The D3D11 implementation of a shader constant buffer.
+class GFXD3D11ShaderConstBuffer : public GFXShaderConstBuffer
+{
+   friend class GFXD3D11Shader;
+
+public:
+
+   GFXD3D11ShaderConstBuffer(GFXD3D11Shader* shader,
+      GFXD3D11ConstBufferLayout* vertexLayout,
+      GFXD3D11ConstBufferLayout* pixelLayout);
+
+   virtual ~GFXD3D11ShaderConstBuffer();
+
+   /// Called by GFXD3D11Device to activate this buffer.
+   /// @param mPrevShaderBuffer The previously active buffer
+   void activate(GFXD3D11ShaderConstBuffer *prevShaderBuffer);
+
+   /// Used internally by GXD3D11ShaderConstBuffer to determine if it's dirty.
+   bool isDirty();
+
+   /// Called from GFXD3D11Shader when constants have changed and need
+   /// to be the shader this buffer references is reloaded.
+   void onShaderReload(GFXD3D11Shader *shader);
+
+   // GFXShaderConstBuffer
+   virtual GFXShader* getShader();
+   virtual void set(GFXShaderConstHandle* handle, const F32 fv);
+   virtual void set(GFXShaderConstHandle* handle, const Point2F& fv);
+   virtual void set(GFXShaderConstHandle* handle, const Point3F& fv);
+   virtual void set(GFXShaderConstHandle* handle, const Point4F& fv);
+   virtual void set(GFXShaderConstHandle* handle, const PlaneF& fv);
+   virtual void set(GFXShaderConstHandle* handle, const ColorF& fv);
+   virtual void set(GFXShaderConstHandle* handle, const S32 f);
+   virtual void set(GFXShaderConstHandle* handle, const Point2I& fv);
+   virtual void set(GFXShaderConstHandle* handle, const Point3I& fv);
+   virtual void set(GFXShaderConstHandle* handle, const Point4I& fv);
+   virtual void set(GFXShaderConstHandle* handle, const AlignedArray<F32>& fv);
+   virtual void set(GFXShaderConstHandle* handle, const AlignedArray<Point2F>& fv);
+   virtual void set(GFXShaderConstHandle* handle, const AlignedArray<Point3F>& fv);
+   virtual void set(GFXShaderConstHandle* handle, const AlignedArray<Point4F>& fv);
+   virtual void set(GFXShaderConstHandle* handle, const AlignedArray<S32>& fv);
+   virtual void set(GFXShaderConstHandle* handle, const AlignedArray<Point2I>& fv);
+   virtual void set(GFXShaderConstHandle* handle, const AlignedArray<Point3I>& fv);
+   virtual void set(GFXShaderConstHandle* handle, const AlignedArray<Point4I>& fv);
+   virtual void set(GFXShaderConstHandle* handle, const MatrixF& mat, const GFXShaderConstType matType = GFXSCT_Float4x4);
+   virtual void set(GFXShaderConstHandle* handle, const MatrixF* mat, const U32 arraySize, const GFXShaderConstType matrixType = GFXSCT_Float4x4);
+
+   // GFXResource
+   virtual const String describeSelf() const;
+   virtual void zombify();
+   virtual void resurrect();
+
+protected:
+
+   void _createBuffers();
+
+   template<class T>
+   inline void SET_CONSTANT(GFXShaderConstHandle* handle,
+      const T& fv,
+      GenericConstBuffer *vBuffer,
+      GenericConstBuffer *pBuffer);
+
+   // Constant buffers, VSSetConstantBuffers1 has issues on win 7. So unfortunately for now we have multiple constant buffers
+   ID3D11Buffer* mConstantBuffersV[CBUFFER_MAX];
+   ID3D11Buffer* mConstantBuffersP[CBUFFER_MAX];
+
+   /// We keep a weak reference to the shader 
+   /// because it will often be deleted.
+   WeakRefPtr<GFXD3D11Shader> mShader;
+
+   //vertex
+   GFXD3D11ConstBufferLayout* mVertexConstBufferLayout;
+   GenericConstBuffer* mVertexConstBuffer;
+   //pixel
+   GFXD3D11ConstBufferLayout* mPixelConstBufferLayout;
+   GenericConstBuffer* mPixelConstBuffer;
+};
+
+class gfxD3D11Include;
+typedef StrongRefPtr<gfxD3D11Include> gfxD3DIncludeRef;
+
+/////////////////// GFXShader implementation /////////////////////////////
+
+class GFXD3D11Shader : public GFXShader
+{
+   friend class GFXD3D11Device;
+   friend class GFXD3D11ShaderConstBuffer;
+
+public:
+   typedef Map<String, GFXD3D11ShaderConstHandle*> HandleMap;
+
+   GFXD3D11Shader();
+   virtual ~GFXD3D11Shader();   
+
+   // GFXShader
+   virtual GFXShaderConstBufferRef allocConstBuffer();
+   virtual const Vector<GFXShaderConstDesc>& getShaderConstDesc() const;
+   virtual GFXShaderConstHandle* getShaderConstHandle(const String& name); 
+   virtual GFXShaderConstHandle* findShaderConstHandle(const String& name);
+   virtual U32 getAlignmentValue(const GFXShaderConstType constType) const;
+   virtual bool getDisassembly( String &outStr ) const;
+
+   // GFXResource
+   virtual void zombify();
+   virtual void resurrect();
+
+protected:
+
+   virtual bool _init();   
+
+   static const U32 smCompiledShaderTag;
+
+   ConstantTable table;
+
+   ID3D11VertexShader *mVertShader;
+   ID3D11PixelShader *mPixShader;
+
+   GFXD3D11ConstBufferLayout* mVertexConstBufferLayout;
+   GFXD3D11ConstBufferLayout* mPixelConstBufferLayout;   
+
+   static gfxD3DIncludeRef smD3DInclude;
+
+   HandleMap mHandles;
+
+   /// The shader disassembly from DX when this shader is compiled.
+   /// We only store this data in non-release builds.
+   String mDissasembly;
+
+   /// Vector of sampler type descriptions consolidated from _compileShader.
+   Vector<GFXShaderConstDesc> mSamplerDescriptions;
+
+   /// Vector of descriptions (consolidated for the getShaderConstDesc call)
+   Vector<GFXShaderConstDesc> mShaderConsts;
+   
+   // These two functions are used when compiling shaders from hlsl
+   virtual bool _compileShader( const Torque::Path &filePath, 
+                                const String &target, 
+                                const D3D_SHADER_MACRO *defines, 
+                                GenericConstBufferLayout *bufferLayout, 
+                                Vector<GFXShaderConstDesc> &samplerDescriptions );
+
+   void _getShaderConstants( ID3D11ShaderReflection* table, 
+	                         GenericConstBufferLayout *bufferLayout,
+                             Vector<GFXShaderConstDesc> &samplerDescriptions );
+
+   bool _convertShaderVariable(const D3D11_SHADER_TYPE_DESC &typeDesc, GFXShaderConstDesc &desc);
+
+
+   bool _saveCompiledOutput( const Torque::Path &filePath, 
+                             ID3DBlob *buffer, 
+                             GenericConstBufferLayout *bufferLayout,
+                             Vector<GFXShaderConstDesc> &samplerDescriptions );
+
+   // Loads precompiled shaders
+   bool _loadCompiledOutput( const Torque::Path &filePath, 
+                             const String &target, 
+                             GenericConstBufferLayout *bufferLayoutF, 
+                             Vector<GFXShaderConstDesc> &samplerDescriptions );
+  
+   // This is used in both cases
+   virtual void _buildShaderConstantHandles(GenericConstBufferLayout *layout, bool vertexConst);
+   
+   virtual void _buildSamplerShaderConstantHandles( Vector<GFXShaderConstDesc> &samplerDescriptions );
+
+   /// Used to build the instancing shader constants from 
+   /// the instancing vertex format.
+   void _buildInstancingShaderConstantHandles();
+};
+
+inline bool GFXD3D11Shader::getDisassembly(String &outStr) const
+{
+   outStr = mDissasembly;
+   return (outStr.isNotEmpty());
+}
+
+#endif

+ 285 - 0
Engine/source/gfx/D3D11/gfxD3D11StateBlock.cpp

@@ -0,0 +1,285 @@
+//-----------------------------------------------------------------------------
+// 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 "gfx/gfxDevice.h"
+#include "gfx/D3D11/gfxD3D11StateBlock.h"
+#include "gfx/D3D11/gfxD3D11EnumTranslate.h"
+
+GFXD3D11StateBlock::GFXD3D11StateBlock(const GFXStateBlockDesc& desc)
+{
+	AssertFatal(D3D11DEVICE, "Invalid D3DDevice!");
+	
+	mDesc = desc;
+	mCachedHashValue = desc.getHashValue();
+
+	// Color writes
+	mColorMask = 0; 
+	mColorMask |= (mDesc.colorWriteRed ? D3D11_COLOR_WRITE_ENABLE_RED : 0);
+	mColorMask |= (mDesc.colorWriteGreen ? D3D11_COLOR_WRITE_ENABLE_GREEN : 0);
+	mColorMask |= (mDesc.colorWriteBlue ? D3D11_COLOR_WRITE_ENABLE_BLUE : 0);
+	mColorMask |= (mDesc.colorWriteAlpha ? D3D11_COLOR_WRITE_ENABLE_ALPHA : 0);
+
+	mBlendState = NULL;
+	for (U32 i = 0; i < GFX->getNumSamplers(); i++)
+	{
+		mSamplerStates[i] = NULL;
+	}
+
+   mDepthStencilState = NULL;
+   mRasterizerState = NULL;
+
+	mBlendDesc.AlphaToCoverageEnable = false;
+	mBlendDesc.IndependentBlendEnable = false;
+
+	mBlendDesc.RenderTarget[0].BlendEnable = mDesc.blendEnable;
+	mBlendDesc.RenderTarget[0].BlendOp = GFXD3D11BlendOp[mDesc.blendOp];
+	mBlendDesc.RenderTarget[0].BlendOpAlpha = GFXD3D11BlendOp[mDesc.separateAlphaBlendOp];
+	mBlendDesc.RenderTarget[0].DestBlend = GFXD3D11Blend[mDesc.blendDest];
+	mBlendDesc.RenderTarget[0].DestBlendAlpha = GFXD3D11Blend[mDesc.separateAlphaBlendDest];
+	mBlendDesc.RenderTarget[0].SrcBlend = GFXD3D11Blend[mDesc.blendSrc];
+	mBlendDesc.RenderTarget[0].SrcBlendAlpha = GFXD3D11Blend[mDesc.separateAlphaBlendSrc];
+	mBlendDesc.RenderTarget[0].RenderTargetWriteMask = mColorMask;
+
+	HRESULT hr = D3D11DEVICE->CreateBlendState(&mBlendDesc, &mBlendState);
+
+	if(FAILED(hr))
+	{
+		AssertFatal(false, "GFXD3D11StateBlock::GFXD3D11StateBlock - CreateBlendState call failure.");
+	}
+
+	mDepthStencilDesc.DepthWriteMask = mDesc.zWriteEnable ? D3D11_DEPTH_WRITE_MASK_ALL : D3D11_DEPTH_WRITE_MASK_ZERO;
+	mDepthStencilDesc.DepthEnable = mDesc.zEnable;
+	mDepthStencilDesc.DepthFunc = GFXD3D11CmpFunc[mDesc.zFunc];
+	mDepthStencilDesc.StencilWriteMask = mDesc.stencilWriteMask;
+	mDepthStencilDesc.StencilReadMask = mDesc.stencilMask;
+	mDepthStencilDesc.StencilEnable = mDesc.stencilEnable;
+
+	mDepthStencilDesc.FrontFace.StencilFunc = GFXD3D11CmpFunc[mDesc.stencilFunc];
+	mDepthStencilDesc.FrontFace.StencilFailOp = GFXD3D11StencilOp[mDesc.stencilFailOp];
+	mDepthStencilDesc.FrontFace.StencilDepthFailOp = GFXD3D11StencilOp[mDesc.stencilZFailOp];
+	mDepthStencilDesc.FrontFace.StencilPassOp = GFXD3D11StencilOp[mDesc.stencilPassOp];
+	mDepthStencilDesc.BackFace = mDepthStencilDesc.FrontFace;
+
+	hr = D3D11DEVICE->CreateDepthStencilState(&mDepthStencilDesc, &mDepthStencilState);
+
+	if(FAILED(hr))
+	{
+		AssertFatal(false, "GFXD3D11StateBlock::GFXD3D11StateBlock - CreateDepthStencilState call failure.");
+	}
+
+	mRasterizerDesc.CullMode = GFXD3D11CullMode[mDesc.cullMode];
+	mRasterizerDesc.FillMode = GFXD3D11FillMode[mDesc.fillMode];
+	mRasterizerDesc.DepthBias = mDesc.zBias;
+	mRasterizerDesc.SlopeScaledDepthBias = mDesc.zSlopeBias;
+	mRasterizerDesc.AntialiasedLineEnable = FALSE;
+	mRasterizerDesc.MultisampleEnable = FALSE;
+	mRasterizerDesc.ScissorEnable = FALSE;
+	mRasterizerDesc.DepthClipEnable = TRUE;
+	mRasterizerDesc.FrontCounterClockwise = FALSE;
+	mRasterizerDesc.DepthBiasClamp = D3D11_DEFAULT_DEPTH_BIAS_CLAMP;
+
+	hr = D3D11DEVICE->CreateRasterizerState(&mRasterizerDesc, &mRasterizerState);
+
+	if(FAILED(hr))
+	{
+		AssertFatal(false, "GFXD3D11StateBlock::GFXD3D11StateBlock - CreateDepthStencilState call failure.");
+	}
+
+	for ( U32 i = 0; i < GFX->getNumSamplers(); i++ )
+	{
+		mSamplerDesc[i].AddressU = GFXD3D11TextureAddress[mDesc.samplers[i].addressModeU];
+		mSamplerDesc[i].AddressV = GFXD3D11TextureAddress[mDesc.samplers[i].addressModeV];
+		mSamplerDesc[i].AddressW = GFXD3D11TextureAddress[mDesc.samplers[i].addressModeW];
+		mSamplerDesc[i].MaxAnisotropy = mDesc.samplers[i].maxAnisotropy;
+
+		mSamplerDesc[i].MipLODBias = mDesc.samplers[i].mipLODBias;
+		mSamplerDesc[i].MinLOD = 0;
+		mSamplerDesc[i].MaxLOD = FLT_MAX;
+
+		if(mDesc.samplers[i].magFilter == GFXTextureFilterPoint && mDesc.samplers[i].minFilter == GFXTextureFilterPoint && mDesc.samplers[i].mipFilter == GFXTextureFilterPoint)
+			mSamplerDesc[i].Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
+		else if(mDesc.samplers[i].magFilter == GFXTextureFilterPoint && mDesc.samplers[i].minFilter == GFXTextureFilterPoint && mDesc.samplers[i].mipFilter == GFXTextureFilterLinear)
+			mSamplerDesc[i].Filter = D3D11_FILTER_MIN_MAG_POINT_MIP_LINEAR;
+		else if(mDesc.samplers[i].magFilter == GFXTextureFilterLinear && mDesc.samplers[i].minFilter == GFXTextureFilterPoint && mDesc.samplers[i].mipFilter == GFXTextureFilterPoint)
+			mSamplerDesc[i].Filter = D3D11_FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT;
+		else if(mDesc.samplers[i].magFilter == GFXTextureFilterLinear && mDesc.samplers[i].minFilter == GFXTextureFilterPoint && mDesc.samplers[i].mipFilter == GFXTextureFilterLinear)
+			mSamplerDesc[i].Filter = D3D11_FILTER_MIN_POINT_MAG_MIP_LINEAR;
+		else if(mDesc.samplers[i].magFilter == GFXTextureFilterPoint && mDesc.samplers[i].minFilter == GFXTextureFilterLinear && mDesc.samplers[i].mipFilter == GFXTextureFilterPoint)
+			mSamplerDesc[i].Filter =  D3D11_FILTER_MIN_LINEAR_MAG_MIP_POINT;
+		else if(mDesc.samplers[i].magFilter == GFXTextureFilterPoint && mDesc.samplers[i].minFilter == GFXTextureFilterLinear && mDesc.samplers[i].mipFilter == GFXTextureFilterLinear)
+			mSamplerDesc[i].Filter =  D3D11_FILTER_MIN_LINEAR_MAG_POINT_MIP_LINEAR;
+		else if(mDesc.samplers[i].magFilter == GFXTextureFilterLinear && mDesc.samplers[i].minFilter == GFXTextureFilterLinear && mDesc.samplers[i].mipFilter == GFXTextureFilterPoint)
+			mSamplerDesc[i].Filter =  D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT;
+		else if(mDesc.samplers[i].magFilter == GFXTextureFilterLinear && mDesc.samplers[i].minFilter == GFXTextureFilterLinear && mDesc.samplers[i].mipFilter == GFXTextureFilterLinear)
+			mSamplerDesc[i].Filter =  D3D11_FILTER_MIN_MAG_MIP_LINEAR;
+		else 
+			mSamplerDesc[i].Filter = D3D11_FILTER_ANISOTROPIC;
+		
+		mSamplerDesc[i].BorderColor[0] = 1.0f;
+		mSamplerDesc[i].BorderColor[1] = 1.0f;
+		mSamplerDesc[i].BorderColor[2] = 1.0f;
+		mSamplerDesc[i].BorderColor[3] = 1.0f;
+		mSamplerDesc[i].ComparisonFunc = D3D11_COMPARISON_NEVER;
+
+		hr = D3D11DEVICE->CreateSamplerState(&mSamplerDesc[i], &mSamplerStates[i]);
+
+		if(FAILED(hr))
+		{
+			AssertFatal(false, "GFXD3D11StateBlock::GFXD3D11StateBlock - CreateSamplerState call failure.");
+		}
+	}
+}
+
+GFXD3D11StateBlock::~GFXD3D11StateBlock()
+{
+   SAFE_RELEASE(mBlendState);
+   SAFE_RELEASE(mRasterizerState);
+   SAFE_RELEASE(mDepthStencilState);
+
+   //Use TEXTURE_STAGE_COUNT here, not safe to rely on GFX pointer
+   for (U32 i = 0; i < TEXTURE_STAGE_COUNT; ++i)
+   {
+      SAFE_RELEASE(mSamplerStates[i]);
+   }
+}
+
+/// Returns the hash value of the desc that created this block
+U32 GFXD3D11StateBlock::getHashValue() const
+{
+   return mCachedHashValue;
+}
+
+/// Returns a GFXStateBlockDesc that this block represents
+const GFXStateBlockDesc& GFXD3D11StateBlock::getDesc() const
+{
+   return mDesc;      
+}
+
+/// Called by D3D11 device to active this state block.
+/// @param oldState  The current state, used to make sure we don't set redundant states on the device.  Pass NULL to reset all states.
+void GFXD3D11StateBlock::activate(GFXD3D11StateBlock* oldState)
+{
+	PROFILE_SCOPE( GFXD3D11StateBlock_Activate );
+
+   ID3D11DeviceContext* pDevCxt = D3D11DEVICECONTEXT;
+
+	mBlendDesc.AlphaToCoverageEnable = false;
+	mBlendDesc.IndependentBlendEnable = mDesc.separateAlphaBlendEnable;
+
+	mBlendDesc.RenderTarget[0].BlendEnable = mDesc.blendEnable;
+	mBlendDesc.RenderTarget[0].BlendOp = GFXD3D11BlendOp[mDesc.blendOp];
+	mBlendDesc.RenderTarget[0].BlendOpAlpha = GFXD3D11BlendOp[mDesc.separateAlphaBlendOp];
+	mBlendDesc.RenderTarget[0].DestBlend = GFXD3D11Blend[mDesc.blendDest];
+	mBlendDesc.RenderTarget[0].DestBlendAlpha = GFXD3D11Blend[mDesc.separateAlphaBlendDest];
+	mBlendDesc.RenderTarget[0].SrcBlend = GFXD3D11Blend[mDesc.blendSrc];
+	mBlendDesc.RenderTarget[0].SrcBlendAlpha = GFXD3D11Blend[mDesc.separateAlphaBlendSrc];
+	mBlendDesc.RenderTarget[0].RenderTargetWriteMask = mColorMask;
+
+	float blendFactor[] = { 1.0f, 1.0f, 1.0f, 1.0f };
+
+   pDevCxt->OMSetBlendState(mBlendState, blendFactor, 0xFFFFFFFF);
+   
+	mDepthStencilDesc.DepthWriteMask = mDesc.zWriteEnable ? D3D11_DEPTH_WRITE_MASK_ALL : D3D11_DEPTH_WRITE_MASK_ZERO;
+	mDepthStencilDesc.DepthEnable = mDesc.zEnable;
+	mDepthStencilDesc.DepthFunc = GFXD3D11CmpFunc[mDesc.zFunc];
+	mDepthStencilDesc.StencilWriteMask = mDesc.stencilWriteMask;
+	mDepthStencilDesc.StencilReadMask = mDesc.stencilMask;
+	mDepthStencilDesc.StencilEnable = mDesc.stencilEnable;
+
+	mDepthStencilDesc.FrontFace.StencilFunc = GFXD3D11CmpFunc[mDesc.stencilFunc];
+	mDepthStencilDesc.FrontFace.StencilFailOp = GFXD3D11StencilOp[mDesc.stencilFailOp];
+	mDepthStencilDesc.FrontFace.StencilDepthFailOp = GFXD3D11StencilOp[mDesc.stencilZFailOp];
+	mDepthStencilDesc.FrontFace.StencilPassOp = GFXD3D11StencilOp[mDesc.stencilPassOp];
+
+	if (mDesc.stencilEnable)
+		mDepthStencilDesc.BackFace = mDepthStencilDesc.FrontFace;
+	else
+	{
+		mDepthStencilDesc.BackFace.StencilFunc = GFXD3D11CmpFunc[GFXCmpAlways];
+		mDepthStencilDesc.BackFace.StencilFailOp = GFXD3D11StencilOp[GFXStencilOpKeep];
+		mDepthStencilDesc.BackFace.StencilDepthFailOp = GFXD3D11StencilOp[GFXStencilOpKeep];
+		mDepthStencilDesc.BackFace.StencilPassOp = GFXD3D11StencilOp[GFXStencilOpKeep];
+	}
+
+   pDevCxt->OMSetDepthStencilState(mDepthStencilState, mDesc.stencilRef);
+
+	mRasterizerDesc.CullMode = GFXD3D11CullMode[mDesc.cullMode];
+	mRasterizerDesc.FillMode = GFXD3D11FillMode[mDesc.fillMode];
+	mRasterizerDesc.DepthBias = mDesc.zBias;
+	mRasterizerDesc.SlopeScaledDepthBias = mDesc.zSlopeBias;
+	mRasterizerDesc.AntialiasedLineEnable = FALSE;
+	mRasterizerDesc.MultisampleEnable = FALSE;
+	mRasterizerDesc.ScissorEnable = FALSE;
+   
+	if (mDesc.zEnable)
+		mRasterizerDesc.DepthClipEnable = true;
+	else
+		mRasterizerDesc.DepthClipEnable = false;
+  
+	mRasterizerDesc.FrontCounterClockwise = FALSE;
+	mRasterizerDesc.DepthBiasClamp = 0.0f;
+
+   pDevCxt->RSSetState(mRasterizerState);
+
+   U32 numSamplers = GFX->getNumSamplers();
+   for (U32 i = 0; i < numSamplers; i++)
+	{
+		mSamplerDesc[i].AddressU = GFXD3D11TextureAddress[mDesc.samplers[i].addressModeU];
+		mSamplerDesc[i].AddressV = GFXD3D11TextureAddress[mDesc.samplers[i].addressModeV];
+		mSamplerDesc[i].AddressW = GFXD3D11TextureAddress[mDesc.samplers[i].addressModeW];
+		mSamplerDesc[i].MaxAnisotropy = mDesc.samplers[i].maxAnisotropy;
+
+		mSamplerDesc[i].MipLODBias = mDesc.samplers[i].mipLODBias;
+		mSamplerDesc[i].MinLOD = 0;
+		mSamplerDesc[i].MaxLOD = FLT_MAX;
+		
+		if(mDesc.samplers[i].magFilter == GFXTextureFilterPoint && mDesc.samplers[i].minFilter == GFXTextureFilterPoint && mDesc.samplers[i].mipFilter == GFXTextureFilterPoint)
+			mSamplerDesc[i].Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
+		else if(mDesc.samplers[i].magFilter == GFXTextureFilterPoint && mDesc.samplers[i].minFilter == GFXTextureFilterPoint && mDesc.samplers[i].mipFilter == GFXTextureFilterLinear)
+			mSamplerDesc[i].Filter = D3D11_FILTER_MIN_MAG_POINT_MIP_LINEAR;
+		else if(mDesc.samplers[i].magFilter == GFXTextureFilterLinear && mDesc.samplers[i].minFilter == GFXTextureFilterPoint && mDesc.samplers[i].mipFilter == GFXTextureFilterPoint)
+			mSamplerDesc[i].Filter = D3D11_FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT;
+		else if(mDesc.samplers[i].magFilter == GFXTextureFilterLinear && mDesc.samplers[i].minFilter == GFXTextureFilterPoint && mDesc.samplers[i].mipFilter == GFXTextureFilterLinear)
+			mSamplerDesc[i].Filter = D3D11_FILTER_MIN_POINT_MAG_MIP_LINEAR;
+		else if(mDesc.samplers[i].magFilter == GFXTextureFilterPoint && mDesc.samplers[i].minFilter == GFXTextureFilterLinear && mDesc.samplers[i].mipFilter == GFXTextureFilterPoint)
+			mSamplerDesc[i].Filter =  D3D11_FILTER_MIN_LINEAR_MAG_MIP_POINT;
+		else if(mDesc.samplers[i].magFilter == GFXTextureFilterPoint && mDesc.samplers[i].minFilter == GFXTextureFilterLinear && mDesc.samplers[i].mipFilter == GFXTextureFilterLinear)
+			mSamplerDesc[i].Filter =  D3D11_FILTER_MIN_LINEAR_MAG_POINT_MIP_LINEAR;
+		else if(mDesc.samplers[i].magFilter == GFXTextureFilterLinear && mDesc.samplers[i].minFilter == GFXTextureFilterLinear && mDesc.samplers[i].mipFilter == GFXTextureFilterPoint)
+			mSamplerDesc[i].Filter =  D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT;
+		else if(mDesc.samplers[i].magFilter == GFXTextureFilterLinear && mDesc.samplers[i].minFilter == GFXTextureFilterLinear && mDesc.samplers[i].mipFilter == GFXTextureFilterLinear)
+			mSamplerDesc[i].Filter =  D3D11_FILTER_MIN_MAG_MIP_LINEAR;
+		else 
+			mSamplerDesc[i].Filter = D3D11_FILTER_ANISOTROPIC;
+
+		mSamplerDesc[i].BorderColor[0] = 0.0f;
+		mSamplerDesc[i].BorderColor[1] = 0.0f;
+		mSamplerDesc[i].BorderColor[2] = 0.0f;
+		mSamplerDesc[i].BorderColor[3] = 0.0f;
+		mSamplerDesc[i].ComparisonFunc = D3D11_COMPARISON_NEVER;
+	}
+   
+   //TODO samplers for vertex shader
+   // Set all the samplers with one call
+   //pDevCxt->VSSetSamplers(0, numSamplers, &mSamplerStates[0]);
+   pDevCxt->PSSetSamplers(0, numSamplers, &mSamplerStates[0]);
+}

+ 76 - 0
Engine/source/gfx/D3D11/gfxD3D11StateBlock.h

@@ -0,0 +1,76 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+#ifndef _GFXD3D11STATEBLOCK_H_
+#define _GFXD3D11STATEBLOCK_H_
+
+#include "gfx/D3D11/gfxD3D11Device.h"
+#include "gfx/gfxStateBlock.h"
+
+class GFXD3D11StateBlock : public GFXStateBlock
+{   
+public:
+
+   GFXD3D11StateBlock(const GFXStateBlockDesc& desc);
+   virtual ~GFXD3D11StateBlock();
+
+   /// Called by D3D11 device to active this state block.
+   /// @param oldState  The current state, used to make sure we don't set redundant states on the device.  Pass NULL to reset all states.
+   void activate(GFXD3D11StateBlock* oldState);
+
+   // 
+   // GFXStateBlock interface
+   //
+
+   /// Returns the hash value of the desc that created this block
+   virtual U32 getHashValue() const;
+
+   /// Returns a GFXStateBlockDesc that this block represents
+   virtual const GFXStateBlockDesc& getDesc() const;
+
+   //
+   // GFXResource
+   //
+   virtual void zombify() { }
+   /// When called the resource should restore all device sensitive information destroyed by zombify()
+   virtual void resurrect() { }
+private:
+
+   D3D11_BLEND_DESC mBlendDesc;
+   D3D11_RASTERIZER_DESC mRasterizerDesc;
+   D3D11_DEPTH_STENCIL_DESC mDepthStencilDesc; 
+   D3D11_SAMPLER_DESC mSamplerDesc[TEXTURE_STAGE_COUNT];
+
+   ID3D11BlendState* mBlendState;
+   ID3D11DepthStencilState* mDepthStencilState;
+   ID3D11RasterizerState* mRasterizerState;
+   ID3D11SamplerState* mSamplerStates[TEXTURE_STAGE_COUNT];
+
+   GFXStateBlockDesc mDesc;
+   U32 mCachedHashValue;
+   // Cached D3D specific things, these are "calculated" from GFXStateBlock
+   U32 mColorMask; 
+};
+
+typedef StrongRefPtr<GFXD3D11StateBlock> GFXD3D11StateBlockRef;
+
+#endif

+ 409 - 0
Engine/source/gfx/D3D11/gfxD3D11Target.cpp

@@ -0,0 +1,409 @@
+//-----------------------------------------------------------------------------
+// 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() 
+   :  mTargetSize( Point2I::Zero ),
+      mTargetFormat( GFXFormatR8G8B8A8 )
+{
+   for(S32 i=0; i<MaxRenderSlotId; i++)
+   {
+      mTargets[i] = NULL;
+      mResolveTargets[i] = NULL;
+      mTargetViews[i] = NULL;
+      mTargetSRViews[i] = NULL;
+   }
+}
+
+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;
+            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);
+   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 < 4; i++)
+   {
+      rtViews[i] = (ID3D11RenderTargetView*)mTargetViews[GFXTextureTarget::Color0 + i];
+   }
+
+   D3D11DEVICECONTEXT->OMSetRenderTargets(MaxRenderSlotId, rtViews, dsView);
+
+}
+
+void GFXD3D11TextureTarget::deactivate()
+{
+   //re-gen mip maps
+   for (U32 i = 0; i < 4; 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;
+}
+
+GFXD3D11WindowTarget::~GFXD3D11WindowTarget()
+{
+   SAFE_RELEASE(mBackbuffer);
+}
+
+void GFXD3D11WindowTarget::initPresentationParams()
+{
+   // Get some video mode related info.
+   GFXVideoMode vm = mWindow->getVideoMode();
+   Win32Window* win = static_cast<Win32Window*>(mWindow);
+   HWND hwnd = win->getHWND();
+
+   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()
+{
+   return (D3D11->getSwapChain()->Present(!D3D11->smDisableVSync, 0) == S_OK);
+}
+
+void GFXD3D11WindowTarget::setImplicitSwapChain()
+{
+   if (!mBackbuffer)      
+      D3D11->mSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&mBackbuffer);
+}
+
+void GFXD3D11WindowTarget::resetMode()
+{
+   mWindow->setSuppressReset(true);
+
+   // Setup our presentation params.
+   initPresentationParams();
+
+   // Otherwise, we have to reset the device, if we're the implicit swapchain.
+   D3D11->reset(mPresentationParams);
+
+   // Update our size, too.
+   mSize = Point2I(mPresentationParams.BufferDesc.Width, mPresentationParams.BufferDesc.Height);
+
+   mWindow->setSuppressReset(false);
+   GFX->beginReset();
+}
+
+void GFXD3D11WindowTarget::zombify()
+{
+   SAFE_RELEASE(mBackbuffer);
+}
+
+void GFXD3D11WindowTarget::resurrect()
+{
+   setImplicitSwapChain();
+}
+
+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, &D3D11->mDeviceBackBufferView, D3D11->mDeviceDepthStencilView);
+
+   DXGI_SWAP_CHAIN_DESC pp;
+   D3D11->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, D3D11->mDeviceBackbuffer, 0, desc.Format);
+}

+ 110 - 0
Engine/source/gfx/D3D11/gfxD3D11Target.h

@@ -0,0 +1,110 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+#ifndef _GFX_D3D_GFXD3D11TARGET_H_
+#define _GFX_D3D_GFXD3D11TARGET_H_
+
+#include "gfx/D3D11/gfxD3D11Device.h"
+#include "gfx/D3D11/gfxD3D11TextureObject.h"
+#include "gfx/gfxTarget.h"
+#include "math/mPoint3.h"
+#include "math/mPoint2.h"
+
+class GFXD3D11TextureTarget : public GFXTextureTarget
+{
+   friend class GFXD3D11Device;
+
+   // Array of target surfaces, this is given to us by attachTexture
+   ID3D11Texture2D* mTargets[MaxRenderSlotId];
+
+   // Array of shader resource views
+   ID3D11ShaderResourceView* mTargetSRViews[MaxRenderSlotId];
+   
+   //ID3D11DepthStencilView* mDepthTargetView;
+   ID3D11View* mTargetViews[MaxRenderSlotId];
+   // Array of texture objects which correspond to the target surfaces above,
+   // needed for copy from RenderTarget to texture situations.  Current only valid in those situations
+   GFXD3D11TextureObject* mResolveTargets[MaxRenderSlotId];
+
+   Point2I mTargetSize;
+
+   GFXFormat mTargetFormat;
+
+public:
+
+   GFXD3D11TextureTarget();
+   ~GFXD3D11TextureTarget();
+
+   // Public interface.
+   virtual const Point2I getSize() { return mTargetSize; }
+   virtual GFXFormat getFormat() { return mTargetFormat; }
+   virtual void attachTexture(RenderSlot slot, GFXTextureObject *tex, U32 mipLevel=0, U32 zOffset = 0);
+   virtual void attachTexture(RenderSlot slot, GFXCubemap *tex, U32 face, U32 mipLevel=0);
+   virtual void resolve();
+
+   /// Note we always copy the Color0 RenderSlot.
+   virtual void resolveTo( GFXTextureObject *tex );
+
+   virtual void activate();
+   virtual void deactivate();
+
+   void zombify();
+   void resurrect();
+};
+
+class GFXD3D11WindowTarget : public GFXWindowTarget
+{
+   friend class GFXD3D11Device;
+
+   /// Our backbuffer
+   ID3D11Texture2D *mBackbuffer;
+
+   /// Maximum size we can render to.
+   Point2I mSize;
+
+   /// D3D presentation info.
+   DXGI_SWAP_CHAIN_DESC mPresentationParams;
+
+   /// Internal interface that notifies us we need to reset our video mode.
+   void resetMode();
+
+public:
+
+   GFXD3D11WindowTarget();
+   ~GFXD3D11WindowTarget();
+ 
+   virtual const Point2I getSize();
+   virtual GFXFormat getFormat();
+   virtual bool present();
+
+   void initPresentationParams();
+   void setImplicitSwapChain();
+
+   virtual void activate();   
+
+   void zombify();
+   void resurrect();
+
+   virtual void resolveTo( GFXTextureObject *tex );
+};
+
+#endif

+ 587 - 0
Engine/source/gfx/D3D11/gfxD3D11TextureManager.cpp

@@ -0,0 +1,587 @@
+//-----------------------------------------------------------------------------
+// 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 "gfx/D3D11/gfxD3D11Device.h"
+#include "gfx/D3D11/gfxD3D11EnumTranslate.h"
+#include "gfx/bitmap/bitmapUtils.h"
+#include "gfx/gfxCardProfile.h"
+#include "gfx/gfxStringEnumTranslate.h"
+#include "core/strings/unicode.h"
+#include "core/util/swizzle.h"
+#include "core/util/safeDelete.h"
+#include "console/console.h"
+#include "core/resourceManager.h"
+
+GFXD3D11TextureManager::GFXD3D11TextureManager()
+{
+   ZeroMemory(mCurTexSet, sizeof(mCurTexSet));
+}
+
+GFXD3D11TextureManager::~GFXD3D11TextureManager()
+{
+   // Destroy texture table now so just in case some texture objects
+   // are still left, we don't crash on a pure virtual method call.
+   SAFE_DELETE_ARRAY( mHashTable );
+}
+
+void GFXD3D11TextureManager::_innerCreateTexture( GFXD3D11TextureObject *retTex, 
+                                               U32 height, 
+                                               U32 width, 
+                                               U32 depth,
+                                               GFXFormat format, 
+                                               GFXTextureProfile *profile, 
+                                               U32 numMipLevels,
+                                               bool forceMips,
+                                               S32 antialiasLevel)
+{
+   U32 usage = 0;
+   U32 bindFlags = 0;
+   U32 miscFlags = 0;
+   
+   if(!retTex->mProfile->isZTarget() && !retTex->mProfile->isSystemMemory())
+      bindFlags =  D3D11_BIND_SHADER_RESOURCE;
+   
+   U32 cpuFlags = 0;
+
+   retTex->mProfile = profile;
+   retTex->isManaged = false;
+   DXGI_FORMAT d3dTextureFormat = GFXD3D11TextureFormat[format];
+
+   if( retTex->mProfile->isDynamic() )
+   {
+      usage = D3D11_USAGE_DYNAMIC;
+      cpuFlags |= D3D11_CPU_ACCESS_WRITE;
+      retTex->isManaged = false;      
+   }
+   else if ( retTex->mProfile->isSystemMemory() )
+   {
+      usage |= D3D11_USAGE_STAGING;
+      cpuFlags |= D3D11_CPU_ACCESS_READ;
+   }
+   else
+   {
+      usage = D3D11_USAGE_DEFAULT;
+      retTex->isManaged = true;
+   }
+
+   if( retTex->mProfile->isRenderTarget() )
+   {
+      bindFlags |= D3D11_BIND_RENDER_TARGET;
+      //need to check to make sure this format supports render targets
+      U32 supportFlag = 0;
+      
+      D3D11DEVICE->CheckFormatSupport(d3dTextureFormat, &supportFlag);
+      //if it doesn't support render targets then default to R8G8B8A8
+      if(!(supportFlag & D3D11_FORMAT_SUPPORT_RENDER_TARGET))
+         d3dTextureFormat = DXGI_FORMAT_R8G8B8A8_UNORM;
+
+      retTex->isManaged =false;
+   }
+
+   if( retTex->mProfile->isZTarget() )
+   {
+      bindFlags |= D3D11_BIND_DEPTH_STENCIL;
+      retTex->isManaged = false;
+   }
+
+   if( !forceMips && !retTex->mProfile->isSystemMemory() &&
+       numMipLevels == 0 &&
+       !(depth > 0) )
+   {
+      miscFlags |= D3D11_RESOURCE_MISC_GENERATE_MIPS;
+      bindFlags |= D3D11_BIND_RENDER_TARGET; // in order to automatically generate mips. Resource needs to be a rendertarget and shader resource
+   }
+
+   if( depth > 0 )
+   {
+      D3D11_TEXTURE3D_DESC desc;
+      ZeroMemory(&desc, sizeof(D3D11_TEXTURE3D_DESC));
+
+		desc.BindFlags = bindFlags;
+		desc.CPUAccessFlags = cpuFlags;
+		desc.Depth = depth;
+		desc.Width = width;
+		desc.Height = height;
+		desc.Format = d3dTextureFormat;
+		desc.Usage = (D3D11_USAGE)usage;
+		desc.MipLevels = numMipLevels;
+
+		HRESULT hr = D3D11DEVICE->CreateTexture3D(&desc, NULL, retTex->get3DTexPtr());
+
+      if(FAILED(hr)) 
+      {
+         AssertFatal(false, "GFXD3D11TextureManager::_createTexture - failed to create volume texture!");
+      }
+
+      retTex->mTextureSize.set(width, height, depth);
+      retTex->get3DTex()->GetDesc(&desc);
+      retTex->mMipLevels = numMipLevels;
+      retTex->mFormat = format;
+   }
+   else
+   {
+		UINT numQualityLevels = 0;
+
+		switch (antialiasLevel)
+		{
+			case 0:
+			case AA_MATCH_BACKBUFFER:
+				antialiasLevel = 1;
+				break;
+
+			default:
+			{
+				antialiasLevel = 0;
+				UINT numQualityLevels;
+				D3D11DEVICE->CheckMultisampleQualityLevels(d3dTextureFormat, antialiasLevel, &numQualityLevels);
+				AssertFatal(numQualityLevels, "Invalid AA level!");
+				break;
+			}
+		}
+
+		if(retTex->mProfile->isZTarget())
+		{
+			D3D11_TEXTURE2D_DESC desc;
+		  
+			ZeroMemory(&desc, sizeof(D3D11_TEXTURE2D_DESC));
+			desc.ArraySize = 1;
+			desc.BindFlags = bindFlags;
+			desc.CPUAccessFlags = cpuFlags;
+			//depth stencil must be a typeless format if it is bound on render target and shader resource simultaneously
+			// we'll send the real format for the creation of the views
+			desc.Format =  DXGI_FORMAT_R24G8_TYPELESS; 
+			desc.MipLevels = numMipLevels;
+			desc.SampleDesc.Count = antialiasLevel;
+			desc.SampleDesc.Quality = numQualityLevels;
+			desc.Height = height;
+			desc.Width = width;
+			desc.Usage = (D3D11_USAGE)usage;
+			HRESULT hr = D3D11DEVICE->CreateTexture2D(&desc, NULL, retTex->getSurfacePtr());
+		   
+			if(FAILED(hr)) 
+			{
+				AssertFatal(false, "Failed to create Zbuffer texture");
+			}
+
+			retTex->mFormat = format; // Assigning format like this should be fine.
+		}
+		else
+		{
+			D3D11_TEXTURE2D_DESC desc;
+		  
+			ZeroMemory(&desc, sizeof(D3D11_TEXTURE2D_DESC));
+			desc.ArraySize = 1;
+			desc.BindFlags = bindFlags;
+			desc.CPUAccessFlags = cpuFlags;
+			desc.Format = d3dTextureFormat;
+			desc.MipLevels = numMipLevels;
+			desc.SampleDesc.Count = antialiasLevel;
+			desc.SampleDesc.Quality = numQualityLevels;
+			desc.Height = height;
+			desc.Width = width;
+			desc.Usage = (D3D11_USAGE)usage;
+			desc.MiscFlags = miscFlags;
+			HRESULT hr = D3D11DEVICE->CreateTexture2D(&desc, NULL, retTex->get2DTexPtr());
+
+			if(FAILED(hr)) 
+			{
+				AssertFatal(false, "GFXD3D11TextureManager::_createTexture - failed to create texture!");
+			}
+
+			retTex->get2DTex()->GetDesc(&desc);
+			retTex->mMipLevels = desc.MipLevels;
+		}
+
+		// start creating the resource views...
+		// don't bother creating views for system memory/staging textures 
+		// they are just used for copying
+
+		if (!retTex->mProfile->isSystemMemory())
+		{
+         createResourceView(height, width, depth, d3dTextureFormat, numMipLevels, bindFlags, retTex);
+		}
+
+		// Get the actual size of the texture...
+		D3D11_TEXTURE2D_DESC probeDesc;
+		ZeroMemory(&probeDesc, sizeof(D3D11_TEXTURE2D_DESC));
+	  
+		if( retTex->get2DTex() != NULL )
+		{
+			retTex->get2DTex()->GetDesc(&probeDesc);
+		}
+		else if( retTex->getSurface() != NULL )
+		{
+			retTex->getSurface()->GetDesc(&probeDesc);
+		}
+
+		retTex->mTextureSize.set(probeDesc.Width, probeDesc.Height, 0);
+		S32 fmt = 0;
+
+		if(!profile->isZTarget())
+		   fmt = probeDesc.Format;
+		else
+		   fmt = DXGI_FORMAT_D24_UNORM_S8_UINT; // we need to assign this manually.
+
+		GFXREVERSE_LOOKUP( GFXD3D11TextureFormat, GFXFormat, fmt );
+		retTex->mFormat = (GFXFormat)fmt;
+	}
+}
+
+//-----------------------------------------------------------------------------
+// createTexture
+//-----------------------------------------------------------------------------
+GFXTextureObject *GFXD3D11TextureManager::_createTextureObject( U32 height, 
+                                                               U32 width,
+                                                               U32 depth,
+                                                               GFXFormat format, 
+                                                               GFXTextureProfile *profile, 
+                                                               U32 numMipLevels,
+                                                               bool forceMips, 
+                                                               S32 antialiasLevel,
+                                                               GFXTextureObject *inTex )
+{
+   GFXD3D11TextureObject *retTex;
+   if ( inTex )
+   {
+      AssertFatal(static_cast<GFXD3D11TextureObject*>( inTex ), "GFXD3D11TextureManager::_createTexture() - Bad inTex type!");
+      retTex = static_cast<GFXD3D11TextureObject*>( inTex );
+      retTex->release();
+   }      
+   else
+   {
+      retTex = new GFXD3D11TextureObject(GFX, profile);
+      retTex->registerResourceWithDevice(GFX);
+   }
+
+   _innerCreateTexture(retTex, height, width, depth, format, profile, numMipLevels, forceMips, antialiasLevel);
+
+   return retTex;
+}
+
+bool GFXD3D11TextureManager::_loadTexture(GFXTextureObject *aTexture, GBitmap *pDL)
+{
+   PROFILE_SCOPE(GFXD3D11TextureManager_loadTexture);
+
+   GFXD3D11TextureObject *texture = static_cast<GFXD3D11TextureObject*>(aTexture);
+
+   // Check with profiler to see if we can do automatic mipmap generation.
+   const bool supportsAutoMips = GFX->getCardProfiler()->queryProfile("autoMipMapLevel", true);
+
+   // Helper bool
+   const bool isCompressedTexFmt = aTexture->mFormat >= GFXFormatDXT1 && aTexture->mFormat <= GFXFormatDXT5;
+
+   // Settings for mipmap generation
+   U32 maxDownloadMip = pDL->getNumMipLevels();
+   U32 nbMipMapLevel  = pDL->getNumMipLevels();
+
+   if( supportsAutoMips && !isCompressedTexFmt )
+   {
+      maxDownloadMip = 1;
+      nbMipMapLevel  = aTexture->mMipLevels;
+   }
+   GFXD3D11Device* dev = D3D11;
+
+   bool isDynamic = texture->mProfile->isDynamic();
+   // Fill the texture...
+   for( U32 i = 0; i < maxDownloadMip; i++ )
+   {
+	   U32 subResource = D3D11CalcSubresource(i, 0, aTexture->mMipLevels);
+
+	   if(!isDynamic)
+	   {
+		   U8* copyBuffer = NULL;
+
+		   switch(texture->mFormat)
+			{
+				case GFXFormatR8G8B8:
+				{
+					PROFILE_SCOPE(Swizzle24_Upload);
+					AssertFatal(pDL->getFormat() == GFXFormatR8G8B8, "Assumption failed");
+
+					U8* Bits = new U8[pDL->getWidth(i) * pDL->getHeight(i) * 4];
+					dMemcpy(Bits, pDL->getBits(i), pDL->getWidth(i) * pDL->getHeight(i) * 3);
+					bitmapConvertRGB_to_RGBX(&Bits, pDL->getWidth(i) * pDL->getHeight(i));
+					copyBuffer = new U8[pDL->getWidth(i) * pDL->getHeight(i) * 4];
+					
+					dev->getDeviceSwizzle32()->ToBuffer(copyBuffer, Bits, pDL->getWidth(i) * pDL->getHeight(i) * 4);
+					dev->getDeviceContext()->UpdateSubresource(texture->get2DTex(), subResource, NULL, copyBuffer, pDL->getWidth() * 4, pDL->getHeight() *4);
+               SAFE_DELETE_ARRAY(Bits);
+					break;
+				}
+
+				case GFXFormatR8G8B8A8:
+				case GFXFormatR8G8B8X8:
+				{
+               PROFILE_SCOPE(Swizzle32_Upload);
+               copyBuffer = new U8[pDL->getWidth(i) * pDL->getHeight(i) * pDL->getBytesPerPixel()];
+               dev->getDeviceSwizzle32()->ToBuffer(copyBuffer, pDL->getBits(i), pDL->getWidth(i) * pDL->getHeight(i) * pDL->getBytesPerPixel());
+               dev->getDeviceContext()->UpdateSubresource(texture->get2DTex(), subResource, NULL, copyBuffer, pDL->getWidth() * pDL->getBytesPerPixel(), pDL->getHeight() *pDL->getBytesPerPixel());
+					break;
+				}
+
+				default:
+				{
+               // Just copy the bits in no swizzle or padding
+               PROFILE_SCOPE(SwizzleNull_Upload);
+               AssertFatal( pDL->getFormat() == texture->mFormat, "Format mismatch");
+               dev->getDeviceContext()->UpdateSubresource(texture->get2DTex(), subResource, NULL, pDL->getBits(i), pDL->getWidth() *pDL->getBytesPerPixel(), pDL->getHeight() *pDL->getBytesPerPixel());
+				}
+			}
+
+         SAFE_DELETE_ARRAY(copyBuffer);
+	    }
+	  
+	   else
+	   {
+			D3D11_MAPPED_SUBRESOURCE mapping;
+			HRESULT res =  dev->getDeviceContext()->Map(texture->get2DTex(), subResource, D3D11_MAP_WRITE, 0, &mapping);
+
+			AssertFatal(res, "tex2d map call failure");
+
+			switch( texture->mFormat )
+			{
+				case GFXFormatR8G8B8:
+				{
+					PROFILE_SCOPE(Swizzle24_Upload);
+					AssertFatal(pDL->getFormat() == GFXFormatR8G8B8, "Assumption failed");
+
+					U8* Bits = new U8[pDL->getWidth(i) * pDL->getHeight(i) * 4];
+					dMemcpy(Bits, pDL->getBits(i), pDL->getWidth(i) * pDL->getHeight(i) * 3);
+					bitmapConvertRGB_to_RGBX(&Bits, pDL->getWidth(i) * pDL->getHeight(i));					
+
+					dev->getDeviceSwizzle32()->ToBuffer(mapping.pData, Bits, pDL->getWidth(i) * pDL->getHeight(i) * 4);
+               SAFE_DELETE_ARRAY(Bits);
+				}
+				break;
+
+            case GFXFormatR8G8B8A8:
+            case GFXFormatR8G8B8X8:
+            {
+               PROFILE_SCOPE(Swizzle32_Upload);
+               dev->getDeviceSwizzle32()->ToBuffer(mapping.pData, pDL->getBits(i), pDL->getWidth(i) * pDL->getHeight(i) * pDL->getBytesPerPixel());
+            }
+				break;
+
+				default:
+				{
+               // Just copy the bits in no swizzle or padding
+               PROFILE_SCOPE(SwizzleNull_Upload);
+               AssertFatal( pDL->getFormat() == texture->mFormat, "Format mismatch");
+               dMemcpy(mapping.pData, pDL->getBits(i), pDL->getWidth(i) * pDL->getHeight(i) * pDL->getBytesPerPixel());
+				}
+			}
+
+			dev->getDeviceContext()->Unmap(texture->get2DTex(), subResource);
+	   }
+   }
+
+   D3D11_TEXTURE2D_DESC desc;
+   // if the texture asked for mip generation. lets generate it.
+   texture->get2DTex()->GetDesc(&desc);
+   if (desc.MiscFlags &D3D11_RESOURCE_MISC_GENERATE_MIPS)
+   {
+      dev->getDeviceContext()->GenerateMips(texture->getSRView());
+      //texture->mMipLevels = desc.MipLevels;
+   }
+
+   return true;          
+}
+
+bool GFXD3D11TextureManager::_loadTexture(GFXTextureObject *inTex, void *raw)
+{
+   PROFILE_SCOPE(GFXD3D11TextureManager_loadTextureRaw);
+
+   GFXD3D11TextureObject *texture = (GFXD3D11TextureObject *) inTex;
+   GFXD3D11Device* dev = static_cast<GFXD3D11Device *>(GFX);
+   // currently only for volume textures...
+   if(texture->getDepth() < 1) return false;
+
+   U8* Bits = NULL;
+  
+   if(texture->mFormat == GFXFormatR8G8B8)
+   {
+	   // convert 24 bit to 32 bit
+	   Bits = new U8[texture->getWidth() * texture->getHeight() * texture->getDepth() * 4];
+	   dMemcpy(Bits, raw, texture->getWidth() * texture->getHeight() * texture->getDepth() * 3);
+	   bitmapConvertRGB_to_RGBX(&Bits, texture->getWidth() * texture->getHeight() * texture->getDepth());      
+   }
+
+   U32 bytesPerPix = 1;
+
+   switch(texture->mFormat)
+   {
+      case GFXFormatR8G8B8:
+      case GFXFormatR8G8B8A8:
+      case GFXFormatR8G8B8X8:
+         bytesPerPix = 4;
+         break;
+   }
+
+   D3D11_BOX box;
+   box.left    = 0;
+   box.right   = texture->getWidth();
+   box.front   = 0;
+   box.back    = texture->getDepth();
+   box.top     = 0;
+   box.bottom  = texture->getHeight();
+
+   if(texture->mFormat == GFXFormatR8G8B8) // converted format also for volume textures
+		dev->getDeviceContext()->UpdateSubresource(texture->get3DTex(), 0, &box, Bits, texture->getWidth() * bytesPerPix, texture->getHeight() * bytesPerPix);
+   else
+		dev->getDeviceContext()->UpdateSubresource(texture->get3DTex(), 0, &box, raw, texture->getWidth() * bytesPerPix, texture->getHeight() * bytesPerPix);
+
+   SAFE_DELETE_ARRAY(Bits);
+
+   return true;
+}
+
+bool GFXD3D11TextureManager::_refreshTexture(GFXTextureObject *texture)
+{
+   U32 usedStrategies = 0;
+   GFXD3D11TextureObject *realTex = static_cast<GFXD3D11TextureObject *>(texture);
+
+   if(texture->mProfile->doStoreBitmap())
+   {
+      if(texture->mBitmap)
+         _loadTexture(texture, texture->mBitmap);
+
+      if(texture->mDDS)
+         _loadTexture(texture, texture->mDDS);
+
+      usedStrategies++;
+   }
+
+   if(texture->mProfile->isRenderTarget() || texture->mProfile->isDynamic() || texture->mProfile->isZTarget())
+   {
+      realTex->release();
+      _innerCreateTexture(realTex, texture->getHeight(), texture->getWidth(), texture->getDepth(), texture->mFormat, texture->mProfile, texture->mMipLevels, false, texture->mAntialiasLevel);
+      usedStrategies++;
+   }
+
+   AssertFatal(usedStrategies < 2, "GFXD3D11TextureManager::_refreshTexture - Inconsistent profile flags!");
+
+   return true;
+}
+
+bool GFXD3D11TextureManager::_freeTexture(GFXTextureObject *texture, bool zombify)
+{
+   AssertFatal(dynamic_cast<GFXD3D11TextureObject *>(texture),"Not an actual d3d texture object!");
+   GFXD3D11TextureObject *tex = static_cast<GFXD3D11TextureObject *>( texture );
+
+   // If it's a managed texture and we're zombifying, don't blast it, D3D allows
+   // us to keep it.
+   if(zombify && tex->isManaged)
+     return true;
+
+   tex->release();
+
+   return true;
+}
+
+/// Load a texture from a proper DDSFile instance.
+bool GFXD3D11TextureManager::_loadTexture(GFXTextureObject *aTexture, DDSFile *dds)
+{
+   PROFILE_SCOPE(GFXD3D11TextureManager_loadTextureDDS);
+
+   GFXD3D11TextureObject *texture = static_cast<GFXD3D11TextureObject*>(aTexture);
+   GFXD3D11Device* dev = static_cast<GFXD3D11Device *>(GFX);
+   // Fill the texture...
+   for( U32 i = 0; i < aTexture->mMipLevels; i++ )
+   {
+      PROFILE_SCOPE(GFXD3DTexMan_loadSurface);
+
+		AssertFatal( dds->mSurfaces.size() > 0, "Assumption failed. DDSFile has no surfaces." );
+
+		U32 subresource = D3D11CalcSubresource(i, 0, aTexture->mMipLevels);
+		dev->getDeviceContext()->UpdateSubresource(texture->get2DTex(), subresource, 0, dds->mSurfaces[0]->mMips[i], dds->getSurfacePitch(i), 0);
+   }
+
+   D3D11_TEXTURE2D_DESC desc;
+   // if the texture asked for mip generation. lets generate it.
+   texture->get2DTex()->GetDesc(&desc);
+   if (desc.MiscFlags & D3D11_RESOURCE_MISC_GENERATE_MIPS)
+      dev->getDeviceContext()->GenerateMips(texture->getSRView());
+
+   return true;
+}
+
+void GFXD3D11TextureManager::createResourceView(U32 height, U32 width, U32 depth, DXGI_FORMAT format, U32 numMipLevels,U32 usageFlags, GFXTextureObject *inTex)
+{
+	GFXD3D11TextureObject *tex = static_cast<GFXD3D11TextureObject*>(inTex);
+	ID3D11Resource* resource = NULL;
+	
+	if(tex->get2DTex())
+		resource = tex->get2DTex();
+	else if(tex->getSurface())
+		resource = tex->getSurface();
+	else
+		resource = tex->get3DTex();
+
+	HRESULT hr;
+	//TODO: add MSAA support later.
+	if(usageFlags & D3D11_BIND_SHADER_RESOURCE)
+	{
+      D3D11_SHADER_RESOURCE_VIEW_DESC desc;
+
+      if(usageFlags & D3D11_BIND_DEPTH_STENCIL)
+         desc.Format = DXGI_FORMAT_R24_UNORM_X8_TYPELESS; // reads the depth
+      else
+         desc.Format = format;
+	
+		if(depth > 0)
+		{
+			desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D;
+			desc.Texture3D.MipLevels = -1;
+			desc.Texture3D.MostDetailedMip = 0;
+		}
+		else
+		{
+			desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
+			desc.Texture2D.MipLevels = -1;
+			desc.Texture2D.MostDetailedMip = 0;
+		}
+		
+		hr = D3D11DEVICE->CreateShaderResourceView(resource,&desc, tex->getSRViewPtr());
+		AssertFatal(SUCCEEDED(hr), "CreateShaderResourceView:: failed to create view!");
+	}
+
+	if(usageFlags & D3D11_BIND_RENDER_TARGET)
+	{
+		D3D11_RENDER_TARGET_VIEW_DESC desc;
+		desc.Format = format;
+		desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
+		desc.Texture2D.MipSlice = 0;
+		hr = D3D11DEVICE->CreateRenderTargetView(resource, &desc, tex->getRTViewPtr());
+		AssertFatal(SUCCEEDED(hr), "CreateRenderTargetView:: failed to create view!");
+	}
+
+	if(usageFlags & D3D11_BIND_DEPTH_STENCIL)
+	{
+		D3D11_DEPTH_STENCIL_VIEW_DESC desc;
+		desc.Format = format;
+		desc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
+		desc.Texture2D.MipSlice = 0;
+		desc.Flags = 0;
+		hr = D3D11DEVICE->CreateDepthStencilView(resource,&desc, tex->getDSViewPtr());
+		AssertFatal(SUCCEEDED(hr), "CreateDepthStencilView:: failed to create view!");
+	}
+}

+ 62 - 0
Engine/source/gfx/D3D11/gfxD3D11TextureManager.h

@@ -0,0 +1,62 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+#ifndef _GFXD3DTEXTUREMANAGER_H_
+#define _GFXD3DTEXTUREMANAGER_H_
+
+#include "gfx/D3D11/gfxD3D11TextureObject.h"
+#include "core/util/safeRelease.h"
+
+class GFXD3D11TextureManager : public GFXTextureManager 
+{
+   friend class GFXD3D11TextureObject;
+
+public:
+   GFXD3D11TextureManager();
+   virtual ~GFXD3D11TextureManager();
+   void createResourceView(U32 height, U32 width, U32 depth, DXGI_FORMAT format, U32 numMipLevels,U32 usageFlags, GFXTextureObject *inTex);
+protected:
+
+   // GFXTextureManager
+   GFXTextureObject *_createTextureObject(   U32 height, 
+                                             U32 width,
+                                             U32 depth,
+                                             GFXFormat format,
+                                             GFXTextureProfile *profile,
+                                             U32 numMipLevels,
+                                             bool forceMips = false,
+                                             S32 antialiasLevel = 0,
+                                             GFXTextureObject *inTex = NULL );
+   
+   bool _loadTexture(GFXTextureObject *texture, DDSFile *dds);
+   bool _loadTexture(GFXTextureObject *texture, GBitmap *bmp);
+   bool _loadTexture(GFXTextureObject *texture, void *raw);
+   bool _refreshTexture(GFXTextureObject *texture);
+   bool _freeTexture(GFXTextureObject *texture, bool zombify = false);
+   
+private:
+   U32 mCurTexSet[TEXTURE_STAGE_COUNT];
+
+   void _innerCreateTexture(GFXD3D11TextureObject *obj, U32 height, U32 width, U32 depth, GFXFormat format, GFXTextureProfile *profile, U32 numMipLevels, bool forceMips = false, S32 antialiasLevel = 0);
+};
+
+#endif

+ 280 - 0
Engine/source/gfx/D3D11/gfxD3D11TextureObject.cpp

@@ -0,0 +1,280 @@
+//-----------------------------------------------------------------------------
+// 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 "gfx/D3D11/gfxD3D11Device.h"
+#include "gfx/D3D11/gfxD3D11TextureObject.h"
+#include "platform/profiler.h"
+#include "console/console.h"
+
+#ifdef TORQUE_DEBUG
+U32 GFXD3D11TextureObject::mTexCount = 0;
+#endif
+
+
+//	GFXFormatR8G8B8 has now the same behaviour as GFXFormatR8G8B8X8. 
+//	This is because 24 bit format are now deprecated by microsoft, for data alignment reason there's no changes beetween 24 and 32 bit formats.
+//	DirectX 10-11 both have 24 bit format no longer.
+
+
+GFXD3D11TextureObject::GFXD3D11TextureObject( GFXDevice * d, GFXTextureProfile *profile) : GFXTextureObject( d, profile )
+{
+#ifdef D3D11_DEBUG_SPEW
+   mTexCount++;
+   Con::printf("+ texMake %d %x", mTexCount, this);
+#endif
+
+   mD3DTexture = NULL;
+   mLocked = false;
+
+   mD3DSurface = NULL;
+   mLockedSubresource = 0;
+   mDSView = NULL;
+   mRTView = NULL;
+   mSRView = NULL;
+}
+
+GFXD3D11TextureObject::~GFXD3D11TextureObject()
+{
+   kill();
+#ifdef D3D11_DEBUG_SPEW
+   mTexCount--;
+   Con::printf("+ texkill %d %x", mTexCount, this);
+#endif
+}
+
+GFXLockedRect *GFXD3D11TextureObject::lock(U32 mipLevel /*= 0*/, RectI *inRect /*= NULL*/)
+{
+   AssertFatal( !mLocked, "GFXD3D11TextureObject::lock - The texture is already locked!" );
+
+   D3D11_MAPPED_SUBRESOURCE mapInfo;
+
+   if( mProfile->isRenderTarget() )
+   {
+      //AssertFatal( 0, "GFXD3D11TextureObject::lock - Need to handle mapping render targets" );
+      if( !mLockTex || 
+          mLockTex->getWidth() != getWidth() ||
+          mLockTex->getHeight() != getHeight() )
+      {
+         mLockTex.set( getWidth(), getHeight(), mFormat, &GFXSystemMemProfile, avar("%s() - mLockTex (line %d)", __FUNCTION__, __LINE__) );
+      }
+
+      PROFILE_START(GFXD3D11TextureObject_lockRT);
+
+      GFXD3D11Device* dev = D3D11;
+
+      GFXD3D11TextureObject* to = (GFXD3D11TextureObject*) &(*mLockTex);
+      dev->getDeviceContext()->CopyResource(to->get2DTex(), mD3DTexture);
+
+      mLockedSubresource = D3D11CalcSubresource(0, 0, 1);
+      HRESULT hr =  dev->getDeviceContext()->Map(to->get2DTex(), mLockedSubresource, D3D11_MAP_READ, 0, &mapInfo);
+      
+      if (FAILED(hr))
+         AssertFatal(false, "GFXD3D11TextureObject:lock- failed to map render target resource!");
+
+      mLocked = true;
+
+
+      PROFILE_END();
+   }
+   else
+   {
+      RECT r;
+
+      if(inRect)
+      {
+         r.top  = inRect->point.y;
+         r.left = inRect->point.x;
+         r.bottom = inRect->point.y + inRect->extent.y;
+         r.right  = inRect->point.x + inRect->extent.x;
+      }
+
+      mLockedSubresource = D3D11CalcSubresource(mipLevel, 0, getMipLevels());
+      HRESULT hr = D3D11DEVICECONTEXT->Map(mD3DTexture, mLockedSubresource, D3D11_MAP_WRITE_DISCARD, 0, &mapInfo);
+      
+      if ( FAILED(hr) )
+         AssertFatal(false, "GFXD3D11TextureObject::lock - Failed to map subresource.");
+
+      mLocked = true;
+
+   }
+
+   mLockRect.pBits = static_cast<U8*>(mapInfo.pData);
+   mLockRect.Pitch = mapInfo.RowPitch;
+
+   return (GFXLockedRect*)&mLockRect;
+}
+
+void GFXD3D11TextureObject::unlock(U32 mipLevel)
+{
+   AssertFatal( mLocked, "GFXD3D11TextureObject::unlock - Attempting to unlock a surface that has not been locked" );
+
+   if( mProfile->isRenderTarget() )
+   {
+      //AssertFatal( 0, "GFXD3D11TextureObject::unlock - Need to handle mapping render targets" );
+      GFXD3D11TextureObject* to = (GFXD3D11TextureObject*)&(*mLockTex);
+      
+      D3D11->getDeviceContext()->Unmap(to->get2DTex(), mLockedSubresource);
+      
+      mLockedSubresource = 0;
+      mLocked = false;
+   }
+   else
+   {
+      D3D11DEVICECONTEXT->Unmap(get2DTex(), mLockedSubresource);
+      mLockedSubresource = 0;
+      mLocked = false;
+   }
+}
+
+void GFXD3D11TextureObject::release()
+{
+   SAFE_RELEASE(mSRView);
+   SAFE_RELEASE(mRTView);
+   SAFE_RELEASE(mDSView);
+   SAFE_RELEASE(mD3DTexture);
+   SAFE_RELEASE(mD3DSurface);
+}
+
+void GFXD3D11TextureObject::zombify()
+{
+   // Managed textures are managed by D3D
+   AssertFatal(!mLocked, "GFXD3D11TextureObject::zombify - Cannot zombify a locked texture!");
+   if(isManaged)
+      return;
+   release();
+}
+
+void GFXD3D11TextureObject::resurrect()
+{
+	// Managed textures are managed by D3D
+   if(isManaged)
+      return;
+
+   static_cast<GFXD3D11TextureManager*>(TEXMGR)->refreshTexture(this);
+}
+
+bool GFXD3D11TextureObject::copyToBmp(GBitmap* bmp)
+{
+   if (!bmp)
+      return false;
+
+   // check format limitations
+   // at the moment we only support RGBA for the source (other 4 byte formats should
+   // be easy to add though)
+   AssertFatal(mFormat == GFXFormatR8G8B8A8, "copyToBmp: invalid format");
+   if (mFormat != GFXFormatR8G8B8A8)
+      return false;
+
+   PROFILE_START(GFXD3D11TextureObject_copyToBmp);
+
+   AssertFatal(bmp->getWidth() == getWidth(), "doh");
+   AssertFatal(bmp->getHeight() == getHeight(), "doh");
+   U32 width = getWidth();
+   U32 height = getHeight();
+
+   bmp->setHasTransparency(mHasTransparency);
+
+   // set some constants
+   const U32 sourceBytesPerPixel = 4;
+   U32 destBytesPerPixel = 0;
+
+   if(bmp->getFormat() == GFXFormatR8G8B8A8)
+      destBytesPerPixel = 4;
+   else if(bmp->getFormat() == GFXFormatR8G8B8)
+      destBytesPerPixel = 3;
+   else
+      // unsupported
+      AssertFatal(false, "unsupported bitmap format");
+
+
+   // lock the texture
+   DXGI_MAPPED_RECT* lockRect = (DXGI_MAPPED_RECT*) lock();
+
+   // set pointers
+   U8* srcPtr = (U8*)lockRect->pBits;
+   U8* destPtr = bmp->getWritableBits();
+
+   // we will want to skip over any D3D cache data in the source texture
+   const S32 sourceCacheSize = lockRect->Pitch - width * sourceBytesPerPixel;
+   AssertFatal(sourceCacheSize >= 0, "copyToBmp: cache size is less than zero?");
+
+   PROFILE_START(GFXD3D11TextureObject_copyToBmp_pixCopy);
+   // copy data into bitmap
+   for (U32 row = 0; row < height; ++row)
+   {
+      for (U32 col = 0; col < width; ++col)
+      {
+         destPtr[0] = srcPtr[2]; // red
+         destPtr[1] = srcPtr[1]; // green
+         destPtr[2] = srcPtr[0]; // blue 
+         if (destBytesPerPixel == 4)
+            destPtr[3] = srcPtr[3]; // alpha
+
+         // go to next pixel in src
+         srcPtr += sourceBytesPerPixel;
+
+         // go to next pixel in dest
+         destPtr += destBytesPerPixel;
+      }
+      // skip past the cache data for this row (if any)
+      srcPtr += sourceCacheSize;
+   }
+   PROFILE_END();
+
+   // assert if we stomped or underran memory
+   AssertFatal(U32(destPtr - bmp->getWritableBits()) == width * height * destBytesPerPixel, "copyToBmp: doh, memory error");
+   AssertFatal(U32(srcPtr - (U8*)lockRect->pBits) == height * lockRect->Pitch, "copyToBmp: doh, memory error");
+
+   // unlock
+   unlock();
+
+   PROFILE_END();
+
+   return true;
+}
+
+ID3D11ShaderResourceView* GFXD3D11TextureObject::getSRView()
+{
+	return mSRView;
+}
+ID3D11RenderTargetView* GFXD3D11TextureObject::getRTView()
+{
+	return mRTView;
+}
+ID3D11DepthStencilView* GFXD3D11TextureObject::getDSView()
+{
+	return mDSView;
+}
+
+ID3D11ShaderResourceView** GFXD3D11TextureObject::getSRViewPtr()
+{
+	return &mSRView;
+}
+ID3D11RenderTargetView** GFXD3D11TextureObject::getRTViewPtr()
+{
+	return &mRTView;
+}
+
+ID3D11DepthStencilView** GFXD3D11TextureObject::getDSViewPtr()
+{
+	return &mDSView;
+}

+ 89 - 0
Engine/source/gfx/D3D11/gfxD3D11TextureObject.h

@@ -0,0 +1,89 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+#ifndef _GFXD3D11TEXTUREOBJECT_H_
+#define _GFXD3D11TEXTUREOBJECT_H_
+
+#include "gfx/D3D11/gfxD3D11Device.h"
+#include "gfx/gfxTextureHandle.h"
+#include "gfx/gfxTextureManager.h"
+
+class GFXD3D11TextureObject : public GFXTextureObject
+{
+protected:
+   static U32 mTexCount;
+   GFXTexHandle mLockTex;
+   DXGI_MAPPED_RECT mLockRect;
+   bool mLocked;
+
+   U32 mLockedSubresource;
+   ID3D11Resource *mD3DTexture;
+
+   // used for z buffers...
+   ID3D11Texture2D *mD3DSurface;
+
+   ID3D11ShaderResourceView* mSRView; // for shader resource input
+   ID3D11RenderTargetView* mRTView; // for render targets
+   ID3D11DepthStencilView* mDSView; //render target view for depth stencil
+
+public:
+
+   GFXD3D11TextureObject( GFXDevice * d, GFXTextureProfile *profile);
+   ~GFXD3D11TextureObject();
+
+   ID3D11Resource*      getResource(){ return mD3DTexture; }
+   ID3D11Texture2D*     get2DTex(){ return (ID3D11Texture2D*) mD3DTexture; }
+   ID3D11Texture2D**    get2DTexPtr(){ return (ID3D11Texture2D**) &mD3DTexture; }
+   ID3D11Texture3D*		get3DTex(){ return (ID3D11Texture3D*) mD3DTexture; }
+   ID3D11Texture3D**	get3DTexPtr(){ return (ID3D11Texture3D**) &mD3DTexture; }
+   
+   ID3D11ShaderResourceView* getSRView();
+   ID3D11RenderTargetView* getRTView();
+   ID3D11DepthStencilView* getDSView();
+
+   ID3D11ShaderResourceView** getSRViewPtr();
+   ID3D11RenderTargetView** getRTViewPtr();
+   ID3D11DepthStencilView** getDSViewPtr();
+  
+
+   void release();
+
+   bool isManaged; //setting to true tells this texture not to be released from being zombify
+
+   virtual GFXLockedRect * lock(U32 mipLevel = 0, RectI *inRect = NULL);
+   virtual void unlock(U32 mipLevel = 0 );
+
+   virtual bool			copyToBmp(GBitmap* bmp);
+   ID3D11Texture2D*		getSurface() {return mD3DSurface;}
+   ID3D11Texture2D**	getSurfacePtr() {return &mD3DSurface;}
+
+   // GFXResource
+   void zombify();
+   void resurrect();
+
+#ifdef TORQUE_DEBUG
+   virtual void pureVirtualCrash() {};
+#endif
+};
+
+
+#endif

+ 233 - 0
Engine/source/gfx/D3D11/gfxD3D11VertexBuffer.cpp

@@ -0,0 +1,233 @@
+//-----------------------------------------------------------------------------
+// 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/gfxD3D11VertexBuffer.h"
+#include "console/console.h"
+
+GFXD3D11VertexBuffer::~GFXD3D11VertexBuffer() 
+{
+   if(getOwningDevice() != NULL)
+   {
+      if(mBufferType != GFXBufferTypeVolatile)
+      {
+         SAFE_RELEASE(vb);
+      }
+   }
+}
+
+void GFXD3D11VertexBuffer::lock(U32 vertexStart, U32 vertexEnd, void **vertexPtr)
+{
+   PROFILE_SCOPE(GFXD3D11VertexBuffer_lock);
+
+   AssertFatal(lockedVertexStart == 0 && lockedVertexEnd == 0, "Cannot lock a buffer more than once!");
+
+   D3D11_MAP flags = D3D11_MAP_WRITE_DISCARD;
+
+   switch(mBufferType)
+   {
+   case GFXBufferTypeStatic:
+   case GFXBufferTypeDynamic:
+      flags = D3D11_MAP_WRITE_DISCARD;
+      break;
+
+   case GFXBufferTypeVolatile:
+
+      // Get or create the volatile buffer...
+      mVolatileBuffer = D3D11->findVBPool( &mVertexFormat, vertexEnd );
+
+      if( !mVolatileBuffer )
+         mVolatileBuffer = D3D11->createVBPool( &mVertexFormat, mVertexSize );
+
+      vb = mVolatileBuffer->vb;
+
+      // Get our range now...
+      AssertFatal(vertexStart == 0,              "Cannot get a subrange on a volatile buffer.");
+      AssertFatal(vertexEnd <= MAX_DYNAMIC_VERTS, "Cannot get more than MAX_DYNAMIC_VERTS in a volatile buffer. Up the constant!");
+      AssertFatal(mVolatileBuffer->lockedVertexStart == 0 && mVolatileBuffer->lockedVertexEnd == 0, "Got more than one lock on the volatile pool.");
+
+      // We created the pool when we requested this volatile buffer, so assume it exists...
+      if( mVolatileBuffer->mNumVerts + vertexEnd > MAX_DYNAMIC_VERTS ) 
+      {
+         flags = D3D11_MAP_WRITE_DISCARD;
+         mVolatileStart = vertexStart  = 0;
+         vertexEnd      = vertexEnd;
+      }
+      else 
+      {
+         flags = D3D11_MAP_WRITE_NO_OVERWRITE;
+         mVolatileStart = vertexStart  = mVolatileBuffer->mNumVerts;
+         vertexEnd                    += mVolatileBuffer->mNumVerts;
+      }
+
+      mVolatileBuffer->mNumVerts = vertexEnd+1;
+
+      mVolatileBuffer->lockedVertexStart = vertexStart;
+      mVolatileBuffer->lockedVertexEnd   = vertexEnd;
+      break;
+   }
+
+   lockedVertexStart = vertexStart;
+   lockedVertexEnd   = vertexEnd;
+
+   // uncomment it for debugging purpose. called many times per frame... spammy! 
+   //Con::printf("%x: Locking %s range (%d, %d)", this, (mBufferType == GFXBufferTypeVolatile ? "volatile" : "static"), lockedVertexStart, lockedVertexEnd);
+
+   U32 sizeToLock = (vertexEnd - vertexStart) * mVertexSize;
+   if(mBufferType == GFXBufferTypeStatic)
+   {	   
+	   *vertexPtr = new U8[sizeToLock];
+	   mLockedBuffer = *vertexPtr;
+   }
+   else
+   {
+		D3D11_MAPPED_SUBRESOURCE pVertexData;
+		ZeroMemory(&pVertexData, sizeof(D3D11_MAPPED_SUBRESOURCE));
+
+		HRESULT hr = D3D11DEVICECONTEXT->Map(vb, 0, flags, 0, &pVertexData);
+
+		if(FAILED(hr)) 
+		{
+			AssertFatal(false, "Unable to lock vertex buffer.");
+		}
+
+		*vertexPtr = (U8*)pVertexData.pData + (vertexStart * mVertexSize);
+   }
+   
+  
+
+   #ifdef TORQUE_DEBUG
+   
+      // Allocate a debug buffer large enough for the lock
+      // plus space for over and under run guard strings.
+      const U32 guardSize = sizeof( _VBGuardString );
+      mDebugGuardBuffer = new U8[sizeToLock+(guardSize*2)];
+
+      // Setup the guard strings.
+      dMemcpy( mDebugGuardBuffer, _VBGuardString, guardSize ); 
+      dMemcpy( mDebugGuardBuffer + sizeToLock + guardSize, _VBGuardString, guardSize ); 
+
+      // Store the real lock pointer and return our debug pointer.
+      mLockedBuffer = *vertexPtr;
+      *vertexPtr = mDebugGuardBuffer + guardSize;
+
+   #endif // TORQUE_DEBUG
+}
+
+void GFXD3D11VertexBuffer::unlock()
+{
+   PROFILE_SCOPE(GFXD3D11VertexBuffer_unlock);
+   
+   #ifdef TORQUE_DEBUG
+   
+      if ( mDebugGuardBuffer )
+      {
+         const U32 guardSize = sizeof( _VBGuardString );
+		   const U32 sizeLocked = (lockedVertexEnd - lockedVertexStart) * mVertexSize;
+
+		   // First check the guard areas for overwrites.
+		   AssertFatal(dMemcmp( mDebugGuardBuffer, _VBGuardString, guardSize) == 0,
+		   "GFXD3D11VertexBuffer::unlock - Caught lock memory underrun!" );
+		   AssertFatal(dMemcmp( mDebugGuardBuffer + sizeLocked + guardSize, _VBGuardString, guardSize) == 0,
+		   "GFXD3D11VertexBuffer::unlock - Caught lock memory overrun!" );
+                        
+		   // Copy the debug content down to the real VB.
+		   dMemcpy(mLockedBuffer, mDebugGuardBuffer + guardSize, sizeLocked);
+
+		   // Cleanup.
+		   delete [] mDebugGuardBuffer;
+		   mDebugGuardBuffer = NULL;
+		   //mLockedBuffer = NULL;
+      }
+
+   #endif // TORQUE_DEBUG
+
+   if(mBufferType == GFXBufferTypeStatic)
+   {
+		const U32 sizeLocked = (lockedVertexEnd - lockedVertexStart) * mVertexSize;
+		//set up the update region of the buffer
+		D3D11_BOX box;
+		box.back  = 1;
+		box.front = 0;
+		box.top = 0;
+		box.bottom = 1;
+		box.left = lockedVertexStart * mVertexSize;
+		box.right = lockedVertexEnd * mVertexSize;
+		//update the real vb buffer
+		D3D11DEVICECONTEXT->UpdateSubresource(vb, 0, &box,mLockedBuffer,sizeLocked, 0);
+		//clean up the old buffer
+		delete[] mLockedBuffer;
+		mLockedBuffer = NULL;
+   }
+   else
+   {	 
+      D3D11DEVICECONTEXT->Unmap(vb,0);
+   }
+   
+
+   mIsFirstLock = false;
+
+   //uncomment it for debugging purpose. called many times per frame... spammy!
+   //Con::printf("%x: Unlocking %s range (%d, %d)", this, (mBufferType == GFXBufferTypeVolatile ? "volatile" : "static"), lockedVertexStart, lockedVertexEnd);
+
+   lockedVertexEnd = lockedVertexStart = 0;
+
+   if(mVolatileBuffer.isValid())
+   {
+      mVolatileBuffer->lockedVertexStart = 0;
+      mVolatileBuffer->lockedVertexEnd   = 0;
+      mVolatileBuffer = NULL;
+   }
+}
+
+void GFXD3D11VertexBuffer::zombify()
+{
+   AssertFatal(lockedVertexStart == 0 && lockedVertexEnd == 0, "GFXD3D11VertexBuffer::zombify - Cannot zombify a locked buffer!");
+   // Static buffers are managed by D3D11 so we don't deal with them.
+   if(mBufferType == GFXBufferTypeDynamic)
+   {
+      SAFE_RELEASE(vb);
+   }
+}
+
+void GFXD3D11VertexBuffer::resurrect()
+{
+   // Static buffers are managed by D3D11 so we don't deal with them.
+   if(mBufferType == GFXBufferTypeDynamic)
+   {
+		D3D11_BUFFER_DESC desc;
+		desc.ByteWidth = mVertexSize * mNumVerts;
+		desc.Usage = D3D11_USAGE_DYNAMIC;
+		desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
+		desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
+		desc.MiscFlags = 0;
+		desc.StructureByteStride = 0;
+
+		HRESULT hr = D3D11DEVICE->CreateBuffer(&desc, NULL, &vb);
+
+      if(FAILED(hr)) 
+      {
+		   AssertFatal(false, "GFXD3D11VertexBuffer::resurrect - Failed to allocate VB");
+      }
+   }
+}
+

+ 95 - 0
Engine/source/gfx/D3D11/gfxD3D11VertexBuffer.h

@@ -0,0 +1,95 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+#ifndef _GFXD3D_VERTEXBUFFER_H_
+#define _GFXD3D_VERTEXBUFFER_H_
+
+#include "gfx/D3D11/gfxD3D11Device.h"
+#include "core/util/safeDelete.h"
+
+class GFXD3D11VertexBuffer : public GFXVertexBuffer
+{
+public:
+   ID3D11Buffer *vb;
+   StrongRefPtr<GFXD3D11VertexBuffer> mVolatileBuffer;
+   void *mLockedBuffer;
+#ifdef TORQUE_DEBUG
+   #define _VBGuardString "GFX_VERTEX_BUFFER_GUARD_STRING"
+   U8 *mDebugGuardBuffer;
+   
+#endif TORQUE_DEBUG
+
+   bool mIsFirstLock;
+   bool mClearAtFrameEnd;
+
+   GFXD3D11VertexBuffer();
+   GFXD3D11VertexBuffer( GFXDevice *device, 
+                        U32 numVerts, 
+                        const GFXVertexFormat *vertexFormat,
+                        U32 vertexSize, 
+                        GFXBufferType bufferType );
+   virtual ~GFXD3D11VertexBuffer();
+
+   void lock(U32 vertexStart, U32 vertexEnd, void **vertexPtr);
+   void unlock();
+   void prepare() {}
+
+   // GFXResource interface
+   virtual void zombify();
+   virtual void resurrect();
+};
+
+//-----------------------------------------------------------------------------
+// This is for debugging vertex buffers and trying to track down which vbs
+// aren't getting free'd
+
+inline GFXD3D11VertexBuffer::GFXD3D11VertexBuffer() : GFXVertexBuffer(0,0,0,0,(GFXBufferType)0)
+{
+   vb = NULL;
+   mIsFirstLock = true;
+   lockedVertexEnd = lockedVertexStart = 0;
+   mClearAtFrameEnd = false;
+
+#ifdef TORQUE_DEBUG
+   mDebugGuardBuffer = NULL;
+   mLockedBuffer = NULL;
+#endif
+}
+
+inline GFXD3D11VertexBuffer::GFXD3D11VertexBuffer(   GFXDevice *device, 
+                                                   U32 numVerts, 
+                                                   const GFXVertexFormat *vertexFormat, 
+                                                   U32 vertexSize, 
+                                                   GFXBufferType bufferType )
+   : GFXVertexBuffer( device, numVerts, vertexFormat, vertexSize, bufferType )
+{
+   vb = NULL;
+   mIsFirstLock = true;
+   mClearAtFrameEnd = false;
+   lockedVertexEnd = lockedVertexStart = 0;
+   mLockedBuffer = NULL;
+#ifdef TORQUE_DEBUG
+   mDebugGuardBuffer = NULL;   
+#endif
+}
+
+#endif // _GFXD3D_VERTEXBUFFER_H_

+ 98 - 0
Engine/source/gfx/D3D11/screenshotD3D11.cpp

@@ -0,0 +1,98 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2016 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/screenshotD3D11.h"
+#include "gfx/D3D11/gfxD3D11Device.h"
+
+//Note if MSAA is ever enabled this will need fixing
+GBitmap* ScreenShotD3D11::_captureBackBuffer()
+{
+   ID3D11Texture2D* backBuf = D3D11->getBackBufferTexture();
+   D3D11_TEXTURE2D_DESC desc;
+   backBuf->GetDesc(&desc);
+   desc.BindFlags = 0;
+   desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
+   desc.Usage = D3D11_USAGE_STAGING;
+
+   //create temp texure
+   ID3D11Texture2D* pNewTexture = NULL;
+   HRESULT hr = D3D11DEVICE->CreateTexture2D(&desc, NULL, &pNewTexture);
+   if (FAILED(hr))
+      return NULL;
+
+   U32 width = desc.Width;
+   U32 height = desc.Height;
+   // pixel data
+   U8 *pData = new U8[width * height * 4];
+
+   D3D11DEVICECONTEXT->CopyResource(pNewTexture, backBuf);
+   D3D11_MAPPED_SUBRESOURCE Resource;
+
+   hr = D3D11DEVICECONTEXT->Map(pNewTexture, 0, D3D11_MAP_READ, 0, &Resource);
+   if (FAILED(hr))
+   {
+      //cleanup
+      SAFE_DELETE(pData);
+      SAFE_RELEASE(pNewTexture);
+      return NULL;
+   }
+
+   const U32 pitch = width << 2;
+   const U8* pSource = (U8*)Resource.pData;
+   U32 totalPitch = 0;
+   for (U32 i = 0; i < height; ++i)
+   {
+      dMemcpy(pData, pSource, width * 4);
+      pSource += Resource.RowPitch;
+      pData += pitch;
+      totalPitch += pitch;
+   }
+
+   D3D11DEVICECONTEXT->Unmap(pNewTexture, 0);  
+   pData -= totalPitch;
+   GBitmap *gb = new GBitmap(width, height);
+
+   //Set GBitmap data and convert from bgr to rgb
+   ColorI c;
+   for (S32 i = 0; i<height; i++)
+   {
+      const U8 *a = pData + i * width * 4;
+      for (S32 j = 0; j<width; j++)
+      {
+         c.blue = *(a++);
+         c.green = *(a++);
+         c.red = *(a++);
+         a++; // Ignore alpha.
+         gb->setColor(j, i, c);
+      }
+   }
+
+   //cleanup
+   SAFE_DELETE(pData);
+   SAFE_RELEASE(pNewTexture);
+   
+
+   return gb;
+
+}
+

+ 39 - 0
Engine/source/gfx/D3D11/screenshotD3D11.h

@@ -0,0 +1,39 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2016 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.
+//-----------------------------------------------------------------------------
+#ifndef _SCREENSHOTD3D11_H_
+#define _SCREENSHOTD3D11_H_
+
+#include "gfx/screenshot.h"
+
+//**************************************************************************
+// D3D implementation of screenshot
+//**************************************************************************
+class ScreenShotD3D11 : public ScreenShot
+{
+protected:
+
+   GBitmap* _captureBackBuffer();
+
+};
+
+
+#endif  // _SCREENSHOTD3D11_H_