Przeglądaj źródła

GFXD3D11StateBlock improvements

rextimmy 8 lat temu
rodzic
commit
48dc2551c4

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

@@ -140,6 +140,11 @@ GFXD3D11Device::~GFXD3D11Device()
    mD3DDeviceContext->ClearState();
    mD3DDeviceContext->ClearState();
    mD3DDeviceContext->Flush();
    mD3DDeviceContext->Flush();
 
 
+   // Free the sampler states
+   SamplerMap::Iterator sampIter = mSamplersMap.begin();
+   for (; sampIter != mSamplersMap.end(); ++sampIter)
+      SAFE_RELEASE(sampIter->value);
+
    // Free the vertex declarations.
    // Free the vertex declarations.
    VertexDeclMap::Iterator iter = mVertexDecls.begin();
    VertexDeclMap::Iterator iter = mVertexDecls.begin();
    for (; iter != mVertexDecls.end(); iter++)
    for (; iter != mVertexDecls.end(); iter++)

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

@@ -49,6 +49,10 @@ class D3D11OculusTexture;
 
 
 class GFXD3D11Device : public GFXDevice
 class GFXD3D11Device : public GFXDevice
 {
 {
+public:
+   typedef Map<U32, ID3D11SamplerState*> SamplerMap;
+private:
+
    friend class GFXResource;
    friend class GFXResource;
    friend class GFXD3D11PrimitiveBuffer;
    friend class GFXD3D11PrimitiveBuffer;
    friend class GFXD3D11VertexBuffer;
    friend class GFXD3D11VertexBuffer;
@@ -98,6 +102,9 @@ protected:
    typedef Map<String,D3D11VertexDecl*> VertexDeclMap;
    typedef Map<String,D3D11VertexDecl*> VertexDeclMap;
    VertexDeclMap mVertexDecls;
    VertexDeclMap mVertexDecls;
 
 
+   /// Used to lookup sampler state for a given hash key
+   SamplerMap mSamplersMap;
+
    ID3D11RenderTargetView* mDeviceBackBufferView;
    ID3D11RenderTargetView* mDeviceBackBufferView;
    ID3D11DepthStencilView* mDeviceDepthStencilView;
    ID3D11DepthStencilView* mDeviceDepthStencilView;
 
 
@@ -303,6 +310,10 @@ public:
    // Shader Model targers
    // Shader Model targers
    const String &getVertexShaderTarget() const { return mVertexShaderTarget; }
    const String &getVertexShaderTarget() const { return mVertexShaderTarget; }
    const String &getPixelShaderTarget() const { return mPixelShaderTarget; }
    const String &getPixelShaderTarget() const { return mPixelShaderTarget; }
+
+   // grab the sampler map
+   const SamplerMap &getSamplersMap() const { return mSamplersMap; }
+   SamplerMap &getSamplersMap() { return mSamplersMap; }
 };
 };
 
 
 #endif
 #endif

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

@@ -23,130 +23,172 @@
 #include "gfx/gfxDevice.h"
 #include "gfx/gfxDevice.h"
 #include "gfx/D3D11/gfxD3D11StateBlock.h"
 #include "gfx/D3D11/gfxD3D11StateBlock.h"
 #include "gfx/D3D11/gfxD3D11EnumTranslate.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)
 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;
    mDepthStencilState = NULL;
    mRasterizerState = 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()
 GFXD3D11StateBlock::~GFXD3D11StateBlock()
@@ -155,10 +197,9 @@ GFXD3D11StateBlock::~GFXD3D11StateBlock()
    SAFE_RELEASE(mRasterizerState);
    SAFE_RELEASE(mRasterizerState);
    SAFE_RELEASE(mDepthStencilState);
    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
 /// Returns a GFXStateBlockDesc that this block represents
 const GFXStateBlockDesc& GFXD3D11StateBlock::getDesc() const
 const GFXStateBlockDesc& GFXD3D11StateBlock::getDesc() const
 {
 {
-   return mDesc;      
+   return mDesc;
 }
 }
 
 
 /// Called by D3D11 device to active this state block.
 /// 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.
 /// @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)
 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();
    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
    //TODO samplers for vertex shader
    // Set all the samplers with one call
    // 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/D3D11/gfxD3D11Device.h"
 #include "gfx/gfxStateBlock.h"
 #include "gfx/gfxStateBlock.h"
 
 
+namespace DictHash
+{
+   U32 hash(const GFXSamplerStateDesc &data);
+}
+
 class GFXD3D11StateBlock : public GFXStateBlock
 class GFXD3D11StateBlock : public GFXStateBlock
 {   
 {   
 public:
 public: