GFXD3D11StateBlock improvements

This commit is contained in:
rextimmy 2016-12-23 15:08:23 +10:00
parent 983b3211ed
commit 48dc2551c4
4 changed files with 203 additions and 199 deletions

View file

@ -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++)

View file

@ -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

View file

@ -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!"); AssertFatal(D3D11DEVICE, "Invalid D3DDevice!");
PROFILE_SCOPE(GFXD3D11StateBlock_CreateStateBlock);
mDesc = desc; mDesc = desc;
mCachedHashValue = desc.getHashValue(); mCachedHashValue = desc.getHashValue();
// Color writes // Color writes
mColorMask = 0; mColorMask = 0;
mColorMask |= (mDesc.colorWriteRed ? D3D11_COLOR_WRITE_ENABLE_RED : 0); mColorMask |= (mDesc.colorWriteRed ? D3D11_COLOR_WRITE_ENABLE_RED : 0);
mColorMask |= (mDesc.colorWriteGreen ? D3D11_COLOR_WRITE_ENABLE_GREEN : 0); mColorMask |= (mDesc.colorWriteGreen ? D3D11_COLOR_WRITE_ENABLE_GREEN : 0);
mColorMask |= (mDesc.colorWriteBlue ? D3D11_COLOR_WRITE_ENABLE_BLUE : 0); mColorMask |= (mDesc.colorWriteBlue ? D3D11_COLOR_WRITE_ENABLE_BLUE : 0);
mColorMask |= (mDesc.colorWriteAlpha ? D3D11_COLOR_WRITE_ENABLE_ALPHA : 0); mColorMask |= (mDesc.colorWriteAlpha ? D3D11_COLOR_WRITE_ENABLE_ALPHA : 0);
mBlendState = NULL; mBlendState = NULL;
for (U32 i = 0; i < GFX->getNumSamplers(); i++) for (U32 i = 0; i < 16; i++)
{ {
mSamplerStates[i] = NULL; mSamplerStates[i] = NULL;
} }
mDepthStencilState = NULL; mDepthStencilState = NULL;
mRasterizerState = NULL; mRasterizerState = NULL;
mBlendDesc.AlphaToCoverageEnable = false; ZeroMemory(&mBlendDesc, sizeof(D3D11_BLEND_DESC));
mBlendDesc.IndependentBlendEnable = false; mBlendDesc.AlphaToCoverageEnable = false;
mBlendDesc.IndependentBlendEnable = mDesc.separateAlphaBlendEnable;
mBlendDesc.RenderTarget[0].BlendEnable = mDesc.blendEnable; mBlendDesc.RenderTarget[0].BlendEnable = mDesc.blendEnable;
mBlendDesc.RenderTarget[0].BlendOp = GFXD3D11BlendOp[mDesc.blendOp]; mBlendDesc.RenderTarget[0].BlendOp = GFXD3D11BlendOp[mDesc.blendOp];
mBlendDesc.RenderTarget[0].BlendOpAlpha = GFXD3D11BlendOp[mDesc.separateAlphaBlendOp]; mBlendDesc.RenderTarget[0].BlendOpAlpha = GFXD3D11BlendOp[mDesc.separateAlphaBlendOp];
mBlendDesc.RenderTarget[0].DestBlend = GFXD3D11Blend[mDesc.blendDest]; mBlendDesc.RenderTarget[0].DestBlend = GFXD3D11Blend[mDesc.blendDest];
mBlendDesc.RenderTarget[0].DestBlendAlpha = GFXD3D11Blend[mDesc.separateAlphaBlendDest]; mBlendDesc.RenderTarget[0].DestBlendAlpha = GFXD3D11Blend[mDesc.separateAlphaBlendDest];
mBlendDesc.RenderTarget[0].SrcBlend = GFXD3D11Blend[mDesc.blendSrc]; mBlendDesc.RenderTarget[0].SrcBlend = GFXD3D11Blend[mDesc.blendSrc];
mBlendDesc.RenderTarget[0].SrcBlendAlpha = GFXD3D11Blend[mDesc.separateAlphaBlendSrc]; mBlendDesc.RenderTarget[0].SrcBlendAlpha = GFXD3D11Blend[mDesc.separateAlphaBlendSrc];
mBlendDesc.RenderTarget[0].RenderTargetWriteMask = mColorMask; mBlendDesc.RenderTarget[0].RenderTargetWriteMask = mColorMask;
HRESULT hr = D3D11DEVICE->CreateBlendState(&mBlendDesc, &mBlendState); HRESULT hr = D3D11DEVICE->CreateBlendState(&mBlendDesc, &mBlendState);
if(FAILED(hr)) if (FAILED(hr))
{ {
AssertFatal(false, "GFXD3D11StateBlock::GFXD3D11StateBlock - CreateBlendState call failure."); AssertFatal(false, "GFXD3D11StateBlock::GFXD3D11StateBlock - CreateBlendState call failure.");
} }
mDepthStencilDesc.DepthWriteMask = mDesc.zWriteEnable ? D3D11_DEPTH_WRITE_MASK_ALL : D3D11_DEPTH_WRITE_MASK_ZERO; ZeroMemory(&mDepthStencilDesc, sizeof(D3D11_DEPTH_STENCIL_DESC));
mDepthStencilDesc.DepthEnable = mDesc.zEnable; mDepthStencilDesc.DepthWriteMask = mDesc.zWriteEnable ? D3D11_DEPTH_WRITE_MASK_ALL : D3D11_DEPTH_WRITE_MASK_ZERO;
mDepthStencilDesc.DepthFunc = GFXD3D11CmpFunc[mDesc.zFunc]; mDepthStencilDesc.DepthEnable = mDesc.zEnable;
mDepthStencilDesc.StencilWriteMask = mDesc.stencilWriteMask; mDepthStencilDesc.DepthFunc = GFXD3D11CmpFunc[mDesc.zFunc];
mDepthStencilDesc.StencilReadMask = mDesc.stencilMask; mDepthStencilDesc.StencilWriteMask = mDesc.stencilWriteMask;
mDepthStencilDesc.StencilEnable = mDesc.stencilEnable; mDepthStencilDesc.StencilReadMask = mDesc.stencilMask;
mDepthStencilDesc.StencilEnable = mDesc.stencilEnable;
mDepthStencilDesc.FrontFace.StencilFunc = GFXD3D11CmpFunc[mDesc.stencilFunc]; mDepthStencilDesc.FrontFace.StencilFunc = GFXD3D11CmpFunc[mDesc.stencilFunc];
mDepthStencilDesc.FrontFace.StencilFailOp = GFXD3D11StencilOp[mDesc.stencilFailOp]; mDepthStencilDesc.FrontFace.StencilFailOp = GFXD3D11StencilOp[mDesc.stencilFailOp];
mDepthStencilDesc.FrontFace.StencilDepthFailOp = GFXD3D11StencilOp[mDesc.stencilZFailOp]; mDepthStencilDesc.FrontFace.StencilDepthFailOp = GFXD3D11StencilOp[mDesc.stencilZFailOp];
mDepthStencilDesc.FrontFace.StencilPassOp = GFXD3D11StencilOp[mDesc.stencilPassOp]; mDepthStencilDesc.FrontFace.StencilPassOp = GFXD3D11StencilOp[mDesc.stencilPassOp];
mDepthStencilDesc.BackFace = mDepthStencilDesc.FrontFace;
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)) hr = D3D11DEVICE->CreateDepthStencilState(&mDepthStencilDesc, &mDepthStencilState);
{
AssertFatal(false, "GFXD3D11StateBlock::GFXD3D11StateBlock - CreateDepthStencilState call failure.");
}
mRasterizerDesc.CullMode = GFXD3D11CullMode[mDesc.cullMode]; if (FAILED(hr))
mRasterizerDesc.FillMode = GFXD3D11FillMode[mDesc.fillMode]; {
mRasterizerDesc.DepthBias = mDesc.zBias; AssertFatal(false, "GFXD3D11StateBlock::GFXD3D11StateBlock - CreateDepthStencilState call failure.");
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); 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)) if (mDesc.zEnable)
{ mRasterizerDesc.DepthClipEnable = true;
AssertFatal(false, "GFXD3D11StateBlock::GFXD3D11StateBlock - CreateDepthStencilState call failure."); else
} mRasterizerDesc.DepthClipEnable = false;
for ( U32 i = 0; i < GFX->getNumSamplers(); i++ ) hr = D3D11DEVICE->CreateRasterizerState(&mRasterizerDesc, &mRasterizerState);
{
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; if (FAILED(hr))
mSamplerDesc[i].MinLOD = 0; {
mSamplerDesc[i].MaxLOD = FLT_MAX; AssertFatal(false, "GFXD3D11StateBlock::GFXD3D11StateBlock - CreateDepthStencilState call failure.");
}
if(mDesc.samplers[i].magFilter == GFXTextureFilterPoint && mDesc.samplers[i].minFilter == GFXTextureFilterPoint && mDesc.samplers[i].mipFilter == GFXTextureFilterPoint) ZeroMemory(&mSamplerDesc, sizeof(D3D11_SAMPLER_DESC) * 16);
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; GFXD3D11Device::SamplerMap &dx11SamplerMap = D3D11->getSamplersMap();
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]); 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(FAILED(hr)) if (itr == dx11SamplerMap.end())
{ {
AssertFatal(false, "GFXD3D11StateBlock::GFXD3D11StateBlock - CreateSamplerState call failure."); 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 < 16; ++i)
for (U32 i = 0; i < TEXTURE_STAGE_COUNT; ++i)
{ {
SAFE_RELEASE(mSamplerStates[i]); mSamplerStates[i] = NULL;
} }
} }
@ -178,108 +219,50 @@ const GFXStateBlockDesc& GFXD3D11StateBlock::getDesc() const
/// @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 ); 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; if (!oldState || (mDepthStencilState != oldState->mDepthStencilState))
mBlendDesc.IndependentBlendEnable = mDesc.separateAlphaBlendEnable; D3D11DEVICECONTEXT->OMSetDepthStencilState(mDepthStencilState, mDesc.stencilRef);
mBlendDesc.RenderTarget[0].BlendEnable = mDesc.blendEnable; if (!oldState || (mRasterizerState != oldState->mRasterizerState))
mBlendDesc.RenderTarget[0].BlendOp = GFXD3D11BlendOp[mDesc.blendOp]; D3D11DEVICECONTEXT->RSSetState(mRasterizerState);
mBlendDesc.RenderTarget[0].BlendOpAlpha = GFXD3D11BlendOp[mDesc.separateAlphaBlendOp];
mBlendDesc.RenderTarget[0].DestBlend = GFXD3D11Blend[mDesc.blendDest];
mBlendDesc.RenderTarget[0].DestBlendAlpha = GFXD3D11Blend[mDesc.separateAlphaBlendDest];
mBlendDesc.RenderTarget[0].SrcBlend = GFXD3D11Blend[mDesc.blendSrc];
mBlendDesc.RenderTarget[0].SrcBlendAlpha = GFXD3D11Blend[mDesc.separateAlphaBlendSrc];
mBlendDesc.RenderTarget[0].RenderTargetWriteMask = mColorMask;
float blendFactor[] = { 1.0f, 1.0f, 1.0f, 1.0f };
pDevCxt->OMSetBlendState(mBlendState, blendFactor, 0xFFFFFFFF);
mDepthStencilDesc.DepthWriteMask = mDesc.zWriteEnable ? D3D11_DEPTH_WRITE_MASK_ALL : D3D11_DEPTH_WRITE_MASK_ZERO;
mDepthStencilDesc.DepthEnable = mDesc.zEnable;
mDepthStencilDesc.DepthFunc = GFXD3D11CmpFunc[mDesc.zFunc];
mDepthStencilDesc.StencilWriteMask = mDesc.stencilWriteMask;
mDepthStencilDesc.StencilReadMask = mDesc.stencilMask;
mDepthStencilDesc.StencilEnable = mDesc.stencilEnable;
mDepthStencilDesc.FrontFace.StencilFunc = GFXD3D11CmpFunc[mDesc.stencilFunc];
mDepthStencilDesc.FrontFace.StencilFailOp = GFXD3D11StencilOp[mDesc.stencilFailOp];
mDepthStencilDesc.FrontFace.StencilDepthFailOp = GFXD3D11StencilOp[mDesc.stencilZFailOp];
mDepthStencilDesc.FrontFace.StencilPassOp = GFXD3D11StencilOp[mDesc.stencilPassOp];
if (mDesc.stencilEnable)
mDepthStencilDesc.BackFace = mDepthStencilDesc.FrontFace;
else
{
mDepthStencilDesc.BackFace.StencilFunc = GFXD3D11CmpFunc[GFXCmpAlways];
mDepthStencilDesc.BackFace.StencilFailOp = GFXD3D11StencilOp[GFXStencilOpKeep];
mDepthStencilDesc.BackFace.StencilDepthFailOp = GFXD3D11StencilOp[GFXStencilOpKeep];
mDepthStencilDesc.BackFace.StencilPassOp = GFXD3D11StencilOp[GFXStencilOpKeep];
}
pDevCxt->OMSetDepthStencilState(mDepthStencilState, mDesc.stencilRef);
mRasterizerDesc.CullMode = GFXD3D11CullMode[mDesc.cullMode];
mRasterizerDesc.FillMode = GFXD3D11FillMode[mDesc.fillMode];
mRasterizerDesc.DepthBias = mDesc.zBias;
mRasterizerDesc.SlopeScaledDepthBias = mDesc.zSlopeBias;
mRasterizerDesc.AntialiasedLineEnable = FALSE;
mRasterizerDesc.MultisampleEnable = FALSE;
mRasterizerDesc.ScissorEnable = FALSE;
if (mDesc.zEnable)
mRasterizerDesc.DepthClipEnable = true;
else
mRasterizerDesc.DepthClipEnable = false;
mRasterizerDesc.FrontCounterClockwise = FALSE;
mRasterizerDesc.DepthBiasClamp = 0.0f;
pDevCxt->RSSetState(mRasterizerState);
U32 numSamplersChanged = 0;
U32 numSamplers = GFX->getNumSamplers(); U32 numSamplers = GFX->getNumSamplers();
for (U32 i = 0; i < numSamplers; i++) U32 samplerUpdateStartSlot = 0;
{
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; //figure out which range of samplers changed.
mSamplerDesc[i].MinLOD = 0; for (U32 samplerSlot = 0; samplerSlot < numSamplers; samplerSlot++)
mSamplerDesc[i].MaxLOD = FLT_MAX; {
if(mDesc.samplers[i].magFilter == GFXTextureFilterPoint && mDesc.samplers[i].minFilter == GFXTextureFilterPoint && mDesc.samplers[i].mipFilter == GFXTextureFilterPoint) if (oldState && (oldState->mSamplerStates[samplerSlot] == mSamplerStates[samplerSlot]))
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) //only change the update start slot when there hasn't been any samplers changed so far
mSamplerDesc[i].Filter = D3D11_FILTER_MIN_MAG_POINT_MIP_LINEAR; if (numSamplersChanged == 0) {
else if(mDesc.samplers[i].magFilter == GFXTextureFilterLinear && mDesc.samplers[i].minFilter == GFXTextureFilterPoint && mDesc.samplers[i].mipFilter == GFXTextureFilterPoint) samplerUpdateStartSlot++;
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; continue;
mSamplerDesc[i].BorderColor[1] = 0.0f; }
mSamplerDesc[i].BorderColor[2] = 0.0f;
mSamplerDesc[i].BorderColor[3] = 0.0f; numSamplersChanged = (samplerSlot - samplerUpdateStartSlot) + 1;
mSamplerDesc[i].ComparisonFunc = D3D11_COMPARISON_NEVER; }
}
//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]); //D3D11DEVICECONTEXT->VSSetSamplers(0, numSamplers, &mSamplerStates[0]);
pDevCxt->PSSetSamplers(0, numSamplers, &mSamplerStates[0]);
if (numSamplersChanged > 0)
D3D11DEVICECONTEXT->PSSetSamplers(samplerUpdateStartSlot, numSamplersChanged, &mSamplerStates[samplerUpdateStartSlot]);
} }

View file

@ -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: