Browse Source

Merge pull request #1883 from rextimmy/dx11_updates

DX11 updates
Areloch 9 years ago
parent
commit
7d60b2109e

+ 223 - 131
Engine/source/gfx/D3D11/gfxD3D11Device.cpp

@@ -37,6 +37,7 @@
 #include "windowManager/platformWindow.h"
 #include "gfx/D3D11/screenshotD3D11.h"
 #include "materials/shaderData.h"
+#include <d3d9.h> //ok now stressing out folks, this is just for debug events(D3DPER) :)
 
 #ifdef TORQUE_DEBUG
 #include "d3d11sdklayers.h"
@@ -53,6 +54,132 @@ GFXDevice *GFXD3D11Device::createInstance(U32 adapterIndex)
    return dev;
 }
 
+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;
+
+   mVertexShaderTarget = String::EmptyString;
+   mPixelShaderTarget = String::EmptyString;
+
+   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 sampler states
+   SamplerMap::Iterator sampIter = mSamplersMap.begin();
+   for (; sampIter != mSamplersMap.end(); ++sampIter)
+      SAFE_RELEASE(sampIter->value);
+
+   // 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);
+}
+
 GFXFormat GFXD3D11Device::selectSupportedFormat(GFXTextureProfile *profile, const Vector<GFXFormat> &formats, bool texture, bool mustblend, bool mustfilter)
 {
    U32 features = 0;
@@ -186,10 +313,47 @@ void GFXD3D11Device::enumerateAdapters(Vector<GFXAdapter*> &adapterList)
          toAdd->mAvailableModes.push_back(vmAdd);
       }
 
+      //Check adapater can handle feature level 10
+      D3D_FEATURE_LEVEL deviceFeature;
+      ID3D11Device *pTmpDevice = nullptr;
+      // Create temp Direct3D11 device.
+      bool suitable = true;
+      UINT createDeviceFlags = D3D11_CREATE_DEVICE_SINGLETHREADED | D3D11_CREATE_DEVICE_BGRA_SUPPORT;
+      hr = D3D11CreateDevice(EnumAdapter, D3D_DRIVER_TYPE_UNKNOWN, NULL, createDeviceFlags, NULL, 0, D3D11_SDK_VERSION, &pTmpDevice, &deviceFeature, NULL);
+
+      if (FAILED(hr))
+         suitable = false;
+
+      if (deviceFeature < D3D_FEATURE_LEVEL_10_0)
+         suitable = false;
+
+      //double check we support required bgra format for LEVEL_10_0 & LEVEL_10_1
+      if (deviceFeature == D3D_FEATURE_LEVEL_10_0 || deviceFeature == D3D_FEATURE_LEVEL_10_1)
+      {
+         U32 formatSupported = 0;
+         pTmpDevice->CheckFormatSupport(DXGI_FORMAT_B8G8R8A8_UNORM, &formatSupported);
+         U32 flagsRequired = D3D11_FORMAT_SUPPORT_RENDER_TARGET | D3D11_FORMAT_SUPPORT_DISPLAY;
+         if (!(formatSupported && flagsRequired))
+         {
+            Con::printf("DXGI adapter: %s does not support BGRA", Description.c_str());
+            suitable = false;
+         }
+      }
+
       delete[] displayModes;
+      SAFE_RELEASE(pTmpDevice);
       SAFE_RELEASE(pOutput);
       SAFE_RELEASE(EnumAdapter);
-      adapterList.push_back(toAdd);
+
+      if (suitable)
+      {
+         adapterList.push_back(toAdd);
+      }
+      else
+      {
+         Con::printf("DXGI adapter: %s does not support D3D11 feature level 10 or better", Description.c_str());
+         delete toAdd;
+      }
    }
 
    SAFE_RELEASE(DXGIFactory);
@@ -264,6 +428,8 @@ void GFXD3D11Device::enumerateVideoModes()
 void GFXD3D11Device::init(const GFXVideoMode &mode, PlatformWindow *window)
 {
    AssertFatal(window, "GFXD3D11Device::init - must specify a window!");
+   HWND hwnd = (HWND)window->getSystemWindow(PlatformWindow::WindowSystem_Windows);
+   SetFocus(hwnd);//ensure window has focus
 
    UINT createDeviceFlags = D3D11_CREATE_DEVICE_SINGLETHREADED | D3D11_CREATE_DEVICE_BGRA_SUPPORT;
 #ifdef TORQUE_DEBUG
@@ -271,7 +437,6 @@ void GFXD3D11Device::init(const GFXVideoMode &mode, PlatformWindow *window)
    mDebugLayers = true;
 #endif
 
-   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
    HRESULT hres = D3D11CreateDevice(NULL,
@@ -282,7 +447,7 @@ void GFXD3D11Device::init(const GFXVideoMode &mode, PlatformWindow *window)
                                     0,
                                     D3D11_SDK_VERSION,
                                     &mD3DDevice,
-                                    &deviceFeature,
+                                    &mFeatureLevel,
                                     &mD3DDeviceContext);
 
    if(FAILED(hres))
@@ -298,7 +463,7 @@ void GFXD3D11Device::init(const GFXVideoMode &mode, PlatformWindow *window)
                                   0,
                                   D3D11_SDK_VERSION,
                                   &mD3DDevice,
-                                  &deviceFeature,
+                                  &mFeatureLevel,
                                   &mD3DDeviceContext);
          //if we failed again than we definitely have a problem
          if (FAILED(hres))
@@ -319,11 +484,27 @@ void GFXD3D11Device::init(const GFXVideoMode &mode, PlatformWindow *window)
 
    // Now reacquire all the resources we trashed earlier
    reacquireDefaultPoolResources();
-   //TODO implement feature levels?
-   if (deviceFeature >= D3D_FEATURE_LEVEL_11_0)
+   //set vert/pixel shader targets
+   switch (mFeatureLevel)
+   {
+   case D3D_FEATURE_LEVEL_11_0:
+      mVertexShaderTarget = "vs_5_0";
+      mPixelShaderTarget = "ps_5_0";
       mPixVersion = 5.0f;
-   else
-      AssertFatal(false, "GFXD3D11Device::init - We don't support anything below feature level 11.");
+      break;
+   case D3D_FEATURE_LEVEL_10_1:
+      mVertexShaderTarget = "vs_4_1";
+      mPixelShaderTarget = "ps_4_1";
+      mPixVersion = 4.1f;
+      break;
+   case D3D_FEATURE_LEVEL_10_0:
+      mVertexShaderTarget = "vs_4_0";
+      mPixelShaderTarget = "ps_4_0";
+      mPixVersion = 4.0f;
+      break;
+   default:
+      AssertFatal(false, "GFXD3D11Device::init - We don't support this feature level");
+   }
 
    D3D11_QUERY_DESC queryDesc;
    queryDesc.Query = D3D11_QUERY_OCCLUSION;
@@ -475,124 +656,6 @@ void GFXD3D11Device::endReset(GFXD3D11WindowTarget *windowTarget)
    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
@@ -600,11 +663,12 @@ void GFXD3D11Device::setupGenericShaders(GenericShaderType type)
    if(mGenericShader[GSColor] == NULL)
    {
       ShaderData *shaderData;
-
+      //shader model 4.0 is enough for the generic shaders
+      const char* shaderModel = "4.0";
       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->setField("pixVersion", shaderModel);
       shaderData->registerObject();
       mGenericShader[GSColor] =  shaderData->getShader();
       mGenericShaderBuffer[GSColor] = mGenericShader[GSColor]->allocConstBuffer();
@@ -614,7 +678,7 @@ void GFXD3D11Device::setupGenericShaders(GenericShaderType type)
       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->setField("pixVersion", shaderModel);
       shaderData->registerObject();
       mGenericShader[GSModColorTexture] = shaderData->getShader();
       mGenericShaderBuffer[GSModColorTexture] = mGenericShader[GSModColorTexture]->allocConstBuffer();
@@ -624,7 +688,7 @@ void GFXD3D11Device::setupGenericShaders(GenericShaderType type)
       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->setField("pixVersion", shaderModel);
       shaderData->registerObject();
       mGenericShader[GSAddColorTexture] = shaderData->getShader();
       mGenericShaderBuffer[GSAddColorTexture] = mGenericShader[GSAddColorTexture]->allocConstBuffer();
@@ -634,7 +698,7 @@ void GFXD3D11Device::setupGenericShaders(GenericShaderType type)
       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->setField("pixVersion", shaderModel);
       shaderData->registerObject();
       mGenericShader[GSTexture] = shaderData->getShader();
       mGenericShaderBuffer[GSTexture] = mGenericShader[GSTexture]->allocConstBuffer();
@@ -1615,4 +1679,32 @@ GFXCubemap * GFXD3D11Device::createCubemap()
    GFXD3D11Cubemap* cube = new GFXD3D11Cubemap();
    cube->registerResourceWithDevice(this);
    return cube;
+}
+
+//------------------------------------------------------------------------------
+void GFXD3D11Device::enterDebugEvent(ColorI color, const char *name)
+{
+   // BJGFIX
+   WCHAR  eventName[260];
+   MultiByteToWideChar(CP_ACP, 0, name, -1, eventName, 260);
+
+   D3DPERF_BeginEvent(D3DCOLOR_ARGB(color.alpha, color.red, color.green, color.blue),
+      (LPCWSTR)&eventName);
+}
+
+//------------------------------------------------------------------------------
+void GFXD3D11Device::leaveDebugEvent()
+{
+   D3DPERF_EndEvent();
+}
+
+//------------------------------------------------------------------------------
+void GFXD3D11Device::setDebugMarker(ColorI color, const char *name)
+{
+   // BJGFIX
+   WCHAR  eventName[260];
+   MultiByteToWideChar(CP_ACP, 0, name, -1, eventName, 260);
+
+   D3DPERF_SetMarker(D3DCOLOR_ARGB(color.alpha, color.red, color.green, color.blue),
+      (LPCWSTR)&eventName);
 }

+ 25 - 5
Engine/source/gfx/D3D11/gfxD3D11Device.h

@@ -49,6 +49,10 @@ class D3D11OculusTexture;
 
 class GFXD3D11Device : public GFXDevice
 {
+public:
+   typedef Map<U32, ID3D11SamplerState*> SamplerMap;
+private:
+
    friend class GFXResource;
    friend class GFXD3D11PrimitiveBuffer;
    friend class GFXD3D11VertexBuffer;
@@ -66,9 +70,9 @@ class GFXD3D11Device : public GFXDevice
    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){};
+   virtual void enterDebugEvent(ColorI color, const char *name);
+   virtual void leaveDebugEvent();
+   virtual void setDebugMarker(ColorI color, const char *name);
 
 protected:
 
@@ -98,6 +102,9 @@ protected:
    typedef Map<String,D3D11VertexDecl*> VertexDeclMap;
    VertexDeclMap mVertexDecls;
 
+   /// Used to lookup sampler state for a given hash key
+   SamplerMap mSamplersMap;
+
    ID3D11RenderTargetView* mDeviceBackBufferView;
    ID3D11DepthStencilView* mDeviceDepthStencilView;
 
@@ -129,6 +136,11 @@ protected:
 
    F32 mPixVersion;
 
+   D3D_FEATURE_LEVEL mFeatureLevel;
+   // Shader Model targers
+   String mVertexShaderTarget;
+   String mPixelShaderTarget;
+
    bool mDebugLayers;
 
    DXGI_SAMPLE_DESC mMultisampleDesc;
@@ -196,8 +208,6 @@ public:
 
    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; }
@@ -294,6 +304,16 @@ public:
 
    // Default multisample parameters
    DXGI_SAMPLE_DESC getMultisampleType() const { return mMultisampleDesc; }
+
+   // Get feature level this gfx device supports
+   D3D_FEATURE_LEVEL getFeatureLevel() const { mFeatureLevel; }
+   // Shader Model targers
+   const String &getVertexShaderTarget() const { return mVertexShaderTarget; }
+   const String &getPixelShaderTarget() const { return mPixelShaderTarget; }
+
+   // grab the sampler map
+   const SamplerMap &getSamplersMap() const { return mSamplersMap; }
+   SamplerMap &getSamplersMap() { return mSamplersMap; }
 };
 
 #endif

+ 12 - 10
Engine/source/gfx/D3D11/gfxD3D11Shader.cpp

@@ -206,7 +206,6 @@ bool GFXD3D11ConstBufferLayout::setMatrix(const ParamDesc& pd, const GFXShaderCo
    }
    else if (pd.constType == GFXSCT_Float4x3)
    {
-      F32 buffer[4 * 4];
       const U32 csize = 48;
 
       // Loop through and copy 
@@ -811,18 +810,21 @@ bool GFXD3D11Shader::_init()
    mSamplerDescriptions.clear();
    mShaderConsts.clear();
 
+   String vertTarget = D3D11->getVertexShaderTarget();
+   String pixTarget = D3D11->getPixelShaderTarget();
+
    if ( !Con::getBoolVariable( "$shaders::forceLoadCSF", false ) )
    {
-      if (!mVertexFile.isEmpty() && !_compileShader( mVertexFile, "vs_5_0", d3dMacros, mVertexConstBufferLayout, mSamplerDescriptions ) )
+      if (!mVertexFile.isEmpty() && !_compileShader( mVertexFile, vertTarget, d3dMacros, mVertexConstBufferLayout, mSamplerDescriptions ) )
          return false;
 
-      if (!mPixelFile.isEmpty() && !_compileShader( mPixelFile, "ps_5_0", d3dMacros, mPixelConstBufferLayout, mSamplerDescriptions ) )
+      if (!mPixelFile.isEmpty() && !_compileShader( mPixelFile, pixTarget, d3dMacros, mPixelConstBufferLayout, mSamplerDescriptions ) )
          return false;
 
    } 
    else 
    {
-      if ( !_loadCompiledOutput( mVertexFile, "vs_5_0", mVertexConstBufferLayout, mSamplerDescriptions ) )
+      if ( !_loadCompiledOutput( mVertexFile, vertTarget, mVertexConstBufferLayout, mSamplerDescriptions ) )
       {
          if ( smLogErrors )
             Con::errorf( "GFXD3D11Shader::init - Unable to load precompiled vertex shader for '%s'.",  mVertexFile.getFullPath().c_str() );
@@ -830,7 +832,7 @@ bool GFXD3D11Shader::_init()
          return false;
       }
 
-      if ( !_loadCompiledOutput( mPixelFile, "ps_5_0", mPixelConstBufferLayout, mSamplerDescriptions ) )
+      if ( !_loadCompiledOutput( mPixelFile, pixTarget, mPixelConstBufferLayout, mSamplerDescriptions ) )
       {
          if ( smLogErrors )
             Con::errorf( "GFXD3D11Shader::init - Unable to load precompiled pixel shader for '%s'.",  mPixelFile.getFullPath().c_str() );
@@ -1053,20 +1055,20 @@ bool GFXD3D11Shader::_compileShader( const Torque::Path &filePath,
 
    return result;
 }
-void GFXD3D11Shader::_getShaderConstants( ID3D11ShaderReflection *table, 
+void GFXD3D11Shader::_getShaderConstants( ID3D11ShaderReflection *pTable, 
                                          GenericConstBufferLayout *bufferLayoutIn,
                                          Vector<GFXShaderConstDesc> &samplerDescriptions )
 {
    PROFILE_SCOPE( GFXD3D11Shader_GetShaderConstants );
 
-   AssertFatal(table, "NULL constant table not allowed, is this an assembly shader?");
+   AssertFatal(pTable, "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);
+   HRESULT hr = pTable->GetDesc(&tableDesc);
    if (FAILED(hr))
    {
 	   AssertFatal(false, "Shader Reflection table unable to be created");
@@ -1076,7 +1078,7 @@ void GFXD3D11Shader::_getShaderConstants( ID3D11ShaderReflection *table,
    U32 bufferOffset = 0;
    for (U32 i = 0; i < tableDesc.ConstantBuffers; i++)
    {
-	   ID3D11ShaderReflectionConstantBuffer* constantBuffer = table->GetConstantBufferByIndex(i);
+	   ID3D11ShaderReflectionConstantBuffer* constantBuffer = pTable->GetConstantBufferByIndex(i);
 	   D3D11_SHADER_BUFFER_DESC constantBufferDesc;
 
       if (constantBuffer->GetDesc(&constantBufferDesc) == S_OK)
@@ -1161,7 +1163,7 @@ void GFXD3D11Shader::_getShaderConstants( ID3D11ShaderReflection *table,
    {
       GFXShaderConstDesc desc;
       D3D11_SHADER_INPUT_BIND_DESC bindDesc;
-      table->GetResourceBindingDesc(i, &bindDesc);
+      pTable->GetResourceBindingDesc(i, &bindDesc);
 
       switch (bindDesc.Type)
       {

+ 1 - 1
Engine/source/gfx/D3D11/gfxD3D11Shader.h

@@ -434,7 +434,7 @@ protected:
                                 GenericConstBufferLayout *bufferLayout, 
                                 Vector<GFXShaderConstDesc> &samplerDescriptions );
 
-   void _getShaderConstants( ID3D11ShaderReflection* table, 
+   void _getShaderConstants( ID3D11ShaderReflection* pTable, 
 	                         GenericConstBufferLayout *bufferLayout,
                              Vector<GFXShaderConstDesc> &samplerDescriptions );
 

+ 204 - 221
Engine/source/gfx/D3D11/gfxD3D11StateBlock.cpp

@@ -23,130 +23,172 @@
 #include "gfx/gfxDevice.h"
 #include "gfx/D3D11/gfxD3D11StateBlock.h"
 #include "gfx/D3D11/gfxD3D11EnumTranslate.h"
+#include "core/crc.h"
+
+namespace DictHash
+{
+   inline U32 hash(const GFXSamplerStateDesc &data)
+   {
+      return CRC::calculateCRC(&data, sizeof(GFXSamplerStateDesc));;
+   }
+}
 
 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;
-	}
+   AssertFatal(D3D11DEVICE, "Invalid D3DDevice!");
+   PROFILE_SCOPE(GFXD3D11StateBlock_CreateStateBlock);
+
+   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 < 16; 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.");
-		}
-	}
+   ZeroMemory(&mBlendDesc, sizeof(D3D11_BLEND_DESC));
+   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;
+
+   HRESULT hr = D3D11DEVICE->CreateBlendState(&mBlendDesc, &mBlendState);
+
+   if (FAILED(hr))
+   {
+      AssertFatal(false, "GFXD3D11StateBlock::GFXD3D11StateBlock - CreateBlendState call failure.");
+   }
+
+   ZeroMemory(&mDepthStencilDesc, sizeof(D3D11_DEPTH_STENCIL_DESC));
+   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];
+   }
+
+   hr = D3D11DEVICE->CreateDepthStencilState(&mDepthStencilDesc, &mDepthStencilState);
+
+   if (FAILED(hr))
+   {
+      AssertFatal(false, "GFXD3D11StateBlock::GFXD3D11StateBlock - CreateDepthStencilState call failure.");
+   }
+
+   ZeroMemory(&mRasterizerDesc, sizeof(D3D11_RASTERIZER_DESC));
+   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.FrontCounterClockwise = FALSE;
+   mRasterizerDesc.DepthBiasClamp = D3D11_DEFAULT_DEPTH_BIAS_CLAMP;
+
+   if (mDesc.zEnable)
+      mRasterizerDesc.DepthClipEnable = true;
+   else
+      mRasterizerDesc.DepthClipEnable = false;
+
+   hr = D3D11DEVICE->CreateRasterizerState(&mRasterizerDesc, &mRasterizerState);
+
+   if (FAILED(hr))
+   {
+      AssertFatal(false, "GFXD3D11StateBlock::GFXD3D11StateBlock - CreateDepthStencilState call failure.");
+   }
+
+   ZeroMemory(&mSamplerDesc, sizeof(D3D11_SAMPLER_DESC) * 16);
+
+   GFXD3D11Device::SamplerMap &dx11SamplerMap = D3D11->getSamplersMap();
+
+   for (U32 i = 0; i < GFX->getNumSamplers(); i++)
+   {
+      GFXSamplerStateDesc &gfxSamplerState = mDesc.samplers[i];
+      U32 hash = DictHash::hash(gfxSamplerState);
+      GFXD3D11Device::SamplerMap::Iterator itr = dx11SamplerMap.find(hash);
+
+      if (itr == dx11SamplerMap.end())
+      {
+         mSamplerDesc[i].AddressU = GFXD3D11TextureAddress[gfxSamplerState.addressModeU];
+         mSamplerDesc[i].AddressV = GFXD3D11TextureAddress[gfxSamplerState.addressModeV];
+         mSamplerDesc[i].AddressW = GFXD3D11TextureAddress[gfxSamplerState.addressModeW];
+         mSamplerDesc[i].MaxAnisotropy = gfxSamplerState.maxAnisotropy;
+
+         mSamplerDesc[i].MipLODBias = gfxSamplerState.mipLODBias;
+         mSamplerDesc[i].MinLOD = 0;
+         mSamplerDesc[i].MaxLOD = FLT_MAX;
+
+         if (gfxSamplerState.magFilter == GFXTextureFilterPoint && gfxSamplerState.minFilter == GFXTextureFilterPoint && gfxSamplerState.mipFilter == GFXTextureFilterPoint)
+            mSamplerDesc[i].Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
+         else if (gfxSamplerState.magFilter == GFXTextureFilterPoint && gfxSamplerState.minFilter == GFXTextureFilterPoint && gfxSamplerState.mipFilter == GFXTextureFilterLinear)
+            mSamplerDesc[i].Filter = D3D11_FILTER_MIN_MAG_POINT_MIP_LINEAR;
+         else if (gfxSamplerState.magFilter == GFXTextureFilterLinear && gfxSamplerState.minFilter == GFXTextureFilterPoint && gfxSamplerState.mipFilter == GFXTextureFilterPoint)
+            mSamplerDesc[i].Filter = D3D11_FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT;
+         else if (gfxSamplerState.magFilter == GFXTextureFilterLinear && gfxSamplerState.minFilter == GFXTextureFilterPoint && gfxSamplerState.mipFilter == GFXTextureFilterLinear)
+            mSamplerDesc[i].Filter = D3D11_FILTER_MIN_POINT_MAG_MIP_LINEAR;
+         else if (gfxSamplerState.magFilter == GFXTextureFilterPoint && gfxSamplerState.minFilter == GFXTextureFilterLinear && gfxSamplerState.mipFilter == GFXTextureFilterPoint)
+            mSamplerDesc[i].Filter = D3D11_FILTER_MIN_LINEAR_MAG_MIP_POINT;
+         else if (gfxSamplerState.magFilter == GFXTextureFilterPoint && gfxSamplerState.minFilter == GFXTextureFilterLinear && gfxSamplerState.mipFilter == GFXTextureFilterLinear)
+            mSamplerDesc[i].Filter = D3D11_FILTER_MIN_LINEAR_MAG_POINT_MIP_LINEAR;
+         else if (gfxSamplerState.magFilter == GFXTextureFilterLinear && gfxSamplerState.minFilter == GFXTextureFilterLinear && gfxSamplerState.mipFilter == GFXTextureFilterPoint)
+            mSamplerDesc[i].Filter = D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT;
+         else if (gfxSamplerState.magFilter == GFXTextureFilterLinear && gfxSamplerState.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;
+
+         hr = D3D11DEVICE->CreateSamplerState(&mSamplerDesc[i], &mSamplerStates[i]);
+         if (FAILED(hr))
+         {
+            AssertFatal(false, "GFXD3D11StateBlock::GFXD3D11StateBlock - CreateSamplerState call failure.");
+         }
+
+         // add sampler state to the map
+         dx11SamplerMap.insert(hash, mSamplerStates[i]);
+      }
+      else
+      {
+         mSamplerStates[i] = itr->value;
+      }
+   }
 }
 
 GFXD3D11StateBlock::~GFXD3D11StateBlock()
@@ -155,10 +197,9 @@ GFXD3D11StateBlock::~GFXD3D11StateBlock()
    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)
+   for (U32 i = 0; i < 16; ++i)
    {
-      SAFE_RELEASE(mSamplerStates[i]);
+      mSamplerStates[i] = NULL;
    }
 }
 
@@ -171,115 +212,57 @@ U32 GFXD3D11StateBlock::getHashValue() const
 /// Returns a GFXStateBlockDesc that this block represents
 const GFXStateBlockDesc& GFXD3D11StateBlock::getDesc() const
 {
-   return mDesc;      
+   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);
+   PROFILE_SCOPE(GFXD3D11StateBlock_Activate);
+
+   if (!oldState || (mBlendState != oldState->mBlendState))
+   {
+      F32 blendFactor[] = { 1.0f, 1.0f, 1.0f, 1.0f };
+      D3D11DEVICECONTEXT->OMSetBlendState(mBlendState, blendFactor, 0xFFFFFFFF);
+   }
+
+   if (!oldState || (mDepthStencilState != oldState->mDepthStencilState))
+      D3D11DEVICECONTEXT->OMSetDepthStencilState(mDepthStencilState, mDesc.stencilRef);
+
+   if (!oldState || (mRasterizerState != oldState->mRasterizerState))
+      D3D11DEVICECONTEXT->RSSetState(mRasterizerState);
 
+   U32 numSamplersChanged = 0;
    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;
-	}
-   
+   U32 samplerUpdateStartSlot = 0;
+
+   //figure out which range of samplers changed.
+   for (U32 samplerSlot = 0; samplerSlot < numSamplers; samplerSlot++)
+   {
+
+      if (oldState && (oldState->mSamplerStates[samplerSlot] == mSamplerStates[samplerSlot]))
+      {
+         //only change the update start slot when there hasn't been any samplers changed so far
+         if (numSamplersChanged == 0) {
+            samplerUpdateStartSlot++;
+         }
+         
+         continue;
+      }
+
+      numSamplersChanged = (samplerSlot - samplerUpdateStartSlot) + 1;
+   }
+
    //TODO samplers for vertex shader
    // Set all the samplers with one call
-   //pDevCxt->VSSetSamplers(0, numSamplers, &mSamplerStates[0]);
-   pDevCxt->PSSetSamplers(0, numSamplers, &mSamplerStates[0]);
+   //D3D11DEVICECONTEXT->VSSetSamplers(0, numSamplers, &mSamplerStates[0]);
+
+   if (numSamplersChanged > 0)
+      D3D11DEVICECONTEXT->PSSetSamplers(samplerUpdateStartSlot, numSamplersChanged, &mSamplerStates[samplerUpdateStartSlot]);
 }
+
+
+
+
+

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

@@ -26,6 +26,11 @@
 #include "gfx/D3D11/gfxD3D11Device.h"
 #include "gfx/gfxStateBlock.h"
 
+namespace DictHash
+{
+   U32 hash(const GFXSamplerStateDesc &data);
+}
+
 class GFXD3D11StateBlock : public GFXStateBlock
 {   
 public: