From 48dc2551c4a5c13d16e8f26a1d645ed7a21e7939 Mon Sep 17 00:00:00 2001 From: rextimmy Date: Fri, 23 Dec 2016 15:08:23 +1000 Subject: [PATCH] GFXD3D11StateBlock improvements --- Engine/source/gfx/D3D11/gfxD3D11Device.cpp | 5 + Engine/source/gfx/D3D11/gfxD3D11Device.h | 11 + .../source/gfx/D3D11/gfxD3D11StateBlock.cpp | 381 +++++++++--------- Engine/source/gfx/D3D11/gfxD3D11StateBlock.h | 5 + 4 files changed, 203 insertions(+), 199 deletions(-) diff --git a/Engine/source/gfx/D3D11/gfxD3D11Device.cpp b/Engine/source/gfx/D3D11/gfxD3D11Device.cpp index 476fbac9d..bc162437b 100644 --- a/Engine/source/gfx/D3D11/gfxD3D11Device.cpp +++ b/Engine/source/gfx/D3D11/gfxD3D11Device.cpp @@ -140,6 +140,11 @@ GFXD3D11Device::~GFXD3D11Device() 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++) diff --git a/Engine/source/gfx/D3D11/gfxD3D11Device.h b/Engine/source/gfx/D3D11/gfxD3D11Device.h index c0024e9d2..3b98e763c 100644 --- a/Engine/source/gfx/D3D11/gfxD3D11Device.h +++ b/Engine/source/gfx/D3D11/gfxD3D11Device.h @@ -49,6 +49,10 @@ class D3D11OculusTexture; class GFXD3D11Device : public GFXDevice { +public: + typedef Map SamplerMap; +private: + friend class GFXResource; friend class GFXD3D11PrimitiveBuffer; friend class GFXD3D11VertexBuffer; @@ -98,6 +102,9 @@ protected: typedef Map VertexDeclMap; VertexDeclMap mVertexDecls; + /// Used to lookup sampler state for a given hash key + SamplerMap mSamplersMap; + ID3D11RenderTargetView* mDeviceBackBufferView; ID3D11DepthStencilView* mDeviceDepthStencilView; @@ -303,6 +310,10 @@ public: // 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 diff --git a/Engine/source/gfx/D3D11/gfxD3D11StateBlock.cpp b/Engine/source/gfx/D3D11/gfxD3D11StateBlock.cpp index fb5f43936..9686f12e2 100644 --- a/Engine/source/gfx/D3D11/gfxD3D11StateBlock.cpp +++ b/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(); + AssertFatal(D3D11DEVICE, "Invalid D3DDevice!"); + PROFILE_SCOPE(GFXD3D11StateBlock_CreateStateBlock); - // 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); + mDesc = desc; + mCachedHashValue = desc.getHashValue(); - mBlendState = NULL; - for (U32 i = 0; i < GFX->getNumSamplers(); i++) - { - mSamplerStates[i] = NULL; - } + // 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; + 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; + 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); + HRESULT hr = D3D11DEVICE->CreateBlendState(&mBlendDesc, &mBlendState); - if(FAILED(hr)) - { - AssertFatal(false, "GFXD3D11StateBlock::GFXD3D11StateBlock - CreateBlendState call failure."); - } + 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; + 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]; - mDepthStencilDesc.BackFace = mDepthStencilDesc.FrontFace; + mDepthStencilDesc.FrontFace.StencilFunc = GFXD3D11CmpFunc[mDesc.stencilFunc]; + mDepthStencilDesc.FrontFace.StencilFailOp = GFXD3D11StencilOp[mDesc.stencilFailOp]; + mDepthStencilDesc.FrontFace.StencilDepthFailOp = GFXD3D11StencilOp[mDesc.stencilZFailOp]; + mDepthStencilDesc.FrontFace.StencilPassOp = GFXD3D11StencilOp[mDesc.stencilPassOp]; - hr = D3D11DEVICE->CreateDepthStencilState(&mDepthStencilDesc, &mDepthStencilState); + 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]; + } - if(FAILED(hr)) - { - AssertFatal(false, "GFXD3D11StateBlock::GFXD3D11StateBlock - CreateDepthStencilState call failure."); - } + hr = D3D11DEVICE->CreateDepthStencilState(&mDepthStencilDesc, &mDepthStencilState); - 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; + if (FAILED(hr)) + { + AssertFatal(false, "GFXD3D11StateBlock::GFXD3D11StateBlock - CreateDepthStencilState call failure."); + } - hr = D3D11DEVICE->CreateRasterizerState(&mRasterizerDesc, &mRasterizerState); + 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(FAILED(hr)) - { - AssertFatal(false, "GFXD3D11StateBlock::GFXD3D11StateBlock - CreateDepthStencilState call failure."); - } + if (mDesc.zEnable) + mRasterizerDesc.DepthClipEnable = true; + else + mRasterizerDesc.DepthClipEnable = false; - 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; + hr = D3D11DEVICE->CreateRasterizerState(&mRasterizerDesc, &mRasterizerState); - mSamplerDesc[i].MipLODBias = mDesc.samplers[i].mipLODBias; - mSamplerDesc[i].MinLOD = 0; - mSamplerDesc[i].MaxLOD = FLT_MAX; + if (FAILED(hr)) + { + AssertFatal(false, "GFXD3D11StateBlock::GFXD3D11StateBlock - CreateDepthStencilState call failure."); + } - 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; + ZeroMemory(&mSamplerDesc, sizeof(D3D11_SAMPLER_DESC) * 16); - hr = D3D11DEVICE->CreateSamplerState(&mSamplerDesc[i], &mSamplerStates[i]); + GFXD3D11Device::SamplerMap &dx11SamplerMap = D3D11->getSamplersMap(); - if(FAILED(hr)) - { - AssertFatal(false, "GFXD3D11StateBlock::GFXD3D11StateBlock - CreateSamplerState call failure."); - } - } + 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 ); + PROFILE_SCOPE(GFXD3D11StateBlock_Activate); - ID3D11DeviceContext* pDevCxt = D3D11DEVICECONTEXT; + if (!oldState || (mBlendState != oldState->mBlendState)) + { + F32 blendFactor[] = { 1.0f, 1.0f, 1.0f, 1.0f }; + D3D11DEVICECONTEXT->OMSetBlendState(mBlendState, blendFactor, 0xFFFFFFFF); + } - mBlendDesc.AlphaToCoverageEnable = false; - mBlendDesc.IndependentBlendEnable = mDesc.separateAlphaBlendEnable; + if (!oldState || (mDepthStencilState != oldState->mDepthStencilState)) + D3D11DEVICECONTEXT->OMSetDepthStencilState(mDepthStencilState, mDesc.stencilRef); - 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); + 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; + U32 samplerUpdateStartSlot = 0; - 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; + //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; + } - 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]); + //D3D11DEVICECONTEXT->VSSetSamplers(0, numSamplers, &mSamplerStates[0]); + + if (numSamplersChanged > 0) + D3D11DEVICECONTEXT->PSSetSamplers(samplerUpdateStartSlot, numSamplersChanged, &mSamplerStates[samplerUpdateStartSlot]); } + + + + + diff --git a/Engine/source/gfx/D3D11/gfxD3D11StateBlock.h b/Engine/source/gfx/D3D11/gfxD3D11StateBlock.h index 6e55b962f..d6988dead 100644 --- a/Engine/source/gfx/D3D11/gfxD3D11StateBlock.h +++ b/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: