GFXGLStateBlock::GFXGLStateBlock(const GFXStateBlockDesc& desc) : mDesc(desc), mCachedHashValue(desc.getHashValue()) { if( !gglHasExtension(ARB_sampler_objects) ) return; static Map<GFXSamplerStateDesc, U32> mSamplersMap; for(int i = 0; i < TEXTURE_STAGE_COUNT; ++i) { GLuint &id = mSamplerObjects[i]; GFXSamplerStateDesc &ssd = mDesc.samplers[i]; Map<GFXSamplerStateDesc, U32>::Iterator itr = mSamplersMap.find(ssd); if(itr == mSamplersMap.end()) { glGenSamplers(1, &id); glSamplerParameteri(id, GL_TEXTURE_MIN_FILTER, minificationFilter(ssd.minFilter, ssd.mipFilter, 1) ); glSamplerParameteri(id, GL_TEXTURE_MAG_FILTER, GFXGLTextureFilter[ssd.magFilter]); glSamplerParameteri(id, GL_TEXTURE_WRAP_S, GFXGLTextureAddress[ssd.addressModeU]); glSamplerParameteri(id, GL_TEXTURE_WRAP_T, GFXGLTextureAddress[ssd.addressModeV]); glSamplerParameteri(id, GL_TEXTURE_WRAP_R, GFXGLTextureAddress[ssd.addressModeW]); if(static_cast< GFXGLDevice* >( GFX )->supportsAnisotropic() ) glSamplerParameterf(id, GL_TEXTURE_MAX_ANISOTROPY_EXT, ssd.maxAnisotropy); mSamplersMap[ssd] = id; } else id = itr->value; } }
GFXStateBlockRef GFXDevice::createStateBlock(const GFXStateBlockDesc& desc) { PROFILE_SCOPE( GFXDevice_CreateStateBlock ); U32 hashValue = desc.getHashValue(); if (mCurrentStateBlocks[hashValue]) return mCurrentStateBlocks[hashValue]; GFXStateBlockRef result = createStateBlockInternal(desc); result->registerResourceWithDevice(this); mCurrentStateBlocks[hashValue] = result; return result; }
GFXD3D9StateBlock::GFXD3D9StateBlock(const GFXStateBlockDesc& desc, LPDIRECT3DDEVICE9 d3dDevice) { AssertFatal(d3dDevice, "Invalid mD3DDevice!"); mDesc = desc; mCachedHashValue = desc.getHashValue(); mD3DDevice = d3dDevice; // Color writes mColorMask = 0; mColorMask |= ( mDesc.colorWriteRed ? GFXCOLORWRITEENABLE_RED : 0 ); mColorMask |= ( mDesc.colorWriteGreen ? GFXCOLORWRITEENABLE_GREEN : 0 ); mColorMask |= ( mDesc.colorWriteBlue ? GFXCOLORWRITEENABLE_BLUE : 0 ); mColorMask |= ( mDesc.colorWriteAlpha ? GFXCOLORWRITEENABLE_ALPHA : 0 ); // Z*bias mZBias = *((U32*)&mDesc.zBias); mZSlopeBias = *((U32*)&mDesc.zSlopeBias); }
GFXD3D11StateBlock::GFXD3D11StateBlock(const GFXStateBlockDesc& desc) { AssertFatal(D3D11DEVICE, "Invalid D3DDevice!"); mDesc = desc; mCachedHashValue = desc.getHashValue(); // Color writes mColorMask = 0; mColorMask |= (mDesc.colorWriteRed ? D3D11_COLOR_WRITE_ENABLE_RED : 0); mColorMask |= (mDesc.colorWriteGreen ? D3D11_COLOR_WRITE_ENABLE_GREEN : 0); mColorMask |= (mDesc.colorWriteBlue ? D3D11_COLOR_WRITE_ENABLE_BLUE : 0); mColorMask |= (mDesc.colorWriteAlpha ? D3D11_COLOR_WRITE_ENABLE_ALPHA : 0); mBlendState = NULL; for (U32 i = 0; i < GFX->getNumSamplers(); i++) { mSamplerStates[i] = NULL; } mDepthStencilState = NULL; mRasterizerState = NULL; mBlendDesc.AlphaToCoverageEnable = false; mBlendDesc.IndependentBlendEnable = false; mBlendDesc.RenderTarget[0].BlendEnable = mDesc.blendEnable; mBlendDesc.RenderTarget[0].BlendOp = GFXD3D11BlendOp[mDesc.blendOp]; mBlendDesc.RenderTarget[0].BlendOpAlpha = GFXD3D11BlendOp[mDesc.separateAlphaBlendOp]; mBlendDesc.RenderTarget[0].DestBlend = GFXD3D11Blend[mDesc.blendDest]; mBlendDesc.RenderTarget[0].DestBlendAlpha = GFXD3D11Blend[mDesc.separateAlphaBlendDest]; mBlendDesc.RenderTarget[0].SrcBlend = GFXD3D11Blend[mDesc.blendSrc]; mBlendDesc.RenderTarget[0].SrcBlendAlpha = GFXD3D11Blend[mDesc.separateAlphaBlendSrc]; mBlendDesc.RenderTarget[0].RenderTargetWriteMask = mColorMask; HRESULT hr = D3D11DEVICE->CreateBlendState(&mBlendDesc, &mBlendState); if(FAILED(hr)) { AssertFatal(false, "GFXD3D11StateBlock::GFXD3D11StateBlock - CreateBlendState call failure."); } mDepthStencilDesc.DepthWriteMask = mDesc.zWriteEnable ? D3D11_DEPTH_WRITE_MASK_ALL : D3D11_DEPTH_WRITE_MASK_ZERO; mDepthStencilDesc.DepthEnable = mDesc.zEnable; mDepthStencilDesc.DepthFunc = GFXD3D11CmpFunc[mDesc.zFunc]; mDepthStencilDesc.StencilWriteMask = mDesc.stencilWriteMask; mDepthStencilDesc.StencilReadMask = mDesc.stencilMask; mDepthStencilDesc.StencilEnable = mDesc.stencilEnable; mDepthStencilDesc.FrontFace.StencilFunc = GFXD3D11CmpFunc[mDesc.stencilFunc]; mDepthStencilDesc.FrontFace.StencilFailOp = GFXD3D11StencilOp[mDesc.stencilFailOp]; mDepthStencilDesc.FrontFace.StencilDepthFailOp = GFXD3D11StencilOp[mDesc.stencilZFailOp]; mDepthStencilDesc.FrontFace.StencilPassOp = GFXD3D11StencilOp[mDesc.stencilPassOp]; mDepthStencilDesc.BackFace = mDepthStencilDesc.FrontFace; hr = D3D11DEVICE->CreateDepthStencilState(&mDepthStencilDesc, &mDepthStencilState); if(FAILED(hr)) { AssertFatal(false, "GFXD3D11StateBlock::GFXD3D11StateBlock - CreateDepthStencilState call failure."); } mRasterizerDesc.CullMode = GFXD3D11CullMode[mDesc.cullMode]; mRasterizerDesc.FillMode = GFXD3D11FillMode[mDesc.fillMode]; mRasterizerDesc.DepthBias = mDesc.zBias; mRasterizerDesc.SlopeScaledDepthBias = mDesc.zSlopeBias; mRasterizerDesc.AntialiasedLineEnable = FALSE; mRasterizerDesc.MultisampleEnable = FALSE; mRasterizerDesc.ScissorEnable = FALSE; mRasterizerDesc.DepthClipEnable = TRUE; mRasterizerDesc.FrontCounterClockwise = FALSE; mRasterizerDesc.DepthBiasClamp = D3D11_DEFAULT_DEPTH_BIAS_CLAMP; hr = D3D11DEVICE->CreateRasterizerState(&mRasterizerDesc, &mRasterizerState); if(FAILED(hr)) { AssertFatal(false, "GFXD3D11StateBlock::GFXD3D11StateBlock - CreateDepthStencilState call failure."); } for ( U32 i = 0; i < GFX->getNumSamplers(); i++ ) { mSamplerDesc[i].AddressU = GFXD3D11TextureAddress[mDesc.samplers[i].addressModeU]; mSamplerDesc[i].AddressV = GFXD3D11TextureAddress[mDesc.samplers[i].addressModeV]; mSamplerDesc[i].AddressW = GFXD3D11TextureAddress[mDesc.samplers[i].addressModeW]; mSamplerDesc[i].MaxAnisotropy = mDesc.samplers[i].maxAnisotropy; mSamplerDesc[i].MipLODBias = mDesc.samplers[i].mipLODBias; mSamplerDesc[i].MinLOD = 0; mSamplerDesc[i].MaxLOD = FLT_MAX; if(mDesc.samplers[i].magFilter == GFXTextureFilterPoint && mDesc.samplers[i].minFilter == GFXTextureFilterPoint && mDesc.samplers[i].mipFilter == GFXTextureFilterPoint) mSamplerDesc[i].Filter = D3D11_FILTER_MIN_MAG_MIP_POINT; else if(mDesc.samplers[i].magFilter == GFXTextureFilterPoint && mDesc.samplers[i].minFilter == GFXTextureFilterPoint && mDesc.samplers[i].mipFilter == GFXTextureFilterLinear) mSamplerDesc[i].Filter = D3D11_FILTER_MIN_MAG_POINT_MIP_LINEAR; else if(mDesc.samplers[i].magFilter == GFXTextureFilterLinear && mDesc.samplers[i].minFilter == GFXTextureFilterPoint && mDesc.samplers[i].mipFilter == GFXTextureFilterPoint) mSamplerDesc[i].Filter = D3D11_FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT; else if(mDesc.samplers[i].magFilter == GFXTextureFilterLinear && mDesc.samplers[i].minFilter == GFXTextureFilterPoint && mDesc.samplers[i].mipFilter == GFXTextureFilterLinear) mSamplerDesc[i].Filter = D3D11_FILTER_MIN_POINT_MAG_MIP_LINEAR; else if(mDesc.samplers[i].magFilter == GFXTextureFilterPoint && mDesc.samplers[i].minFilter == GFXTextureFilterLinear && mDesc.samplers[i].mipFilter == GFXTextureFilterPoint) mSamplerDesc[i].Filter = D3D11_FILTER_MIN_LINEAR_MAG_MIP_POINT; else if(mDesc.samplers[i].magFilter == GFXTextureFilterPoint && mDesc.samplers[i].minFilter == GFXTextureFilterLinear && mDesc.samplers[i].mipFilter == GFXTextureFilterLinear) mSamplerDesc[i].Filter = D3D11_FILTER_MIN_LINEAR_MAG_POINT_MIP_LINEAR; else if(mDesc.samplers[i].magFilter == GFXTextureFilterLinear && mDesc.samplers[i].minFilter == GFXTextureFilterLinear && mDesc.samplers[i].mipFilter == GFXTextureFilterPoint) mSamplerDesc[i].Filter = D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT; else if(mDesc.samplers[i].magFilter == GFXTextureFilterLinear && mDesc.samplers[i].minFilter == GFXTextureFilterLinear && mDesc.samplers[i].mipFilter == GFXTextureFilterLinear) mSamplerDesc[i].Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR; else mSamplerDesc[i].Filter = D3D11_FILTER_ANISOTROPIC; mSamplerDesc[i].BorderColor[0] = 1.0f; mSamplerDesc[i].BorderColor[1] = 1.0f; mSamplerDesc[i].BorderColor[2] = 1.0f; mSamplerDesc[i].BorderColor[3] = 1.0f; mSamplerDesc[i].ComparisonFunc = D3D11_COMPARISON_NEVER; hr = D3D11DEVICE->CreateSamplerState(&mSamplerDesc[i], &mSamplerStates[i]); if(FAILED(hr)) { AssertFatal(false, "GFXD3D11StateBlock::GFXD3D11StateBlock - CreateSamplerState call failure."); } } }