From 983b3211ed1f98ce99d9ff342395b44514d8239a Mon Sep 17 00:00:00 2001 From: rextimmy Date: Fri, 23 Dec 2016 15:00:07 +1000 Subject: [PATCH 1/4] D3D11 Feature level 10 support and D3D11 device cleanup. --- Engine/source/gfx/D3D11/gfxD3D11Device.cpp | 318 ++++++++++++--------- Engine/source/gfx/D3D11/gfxD3D11Device.h | 13 +- Engine/source/gfx/D3D11/gfxD3D11Shader.cpp | 22 +- Engine/source/gfx/D3D11/gfxD3D11Shader.h | 2 +- 4 files changed, 211 insertions(+), 144 deletions(-) diff --git a/Engine/source/gfx/D3D11/gfxD3D11Device.cpp b/Engine/source/gfx/D3D11/gfxD3D11Device.cpp index 352523f36..476fbac9d 100644 --- a/Engine/source/gfx/D3D11/gfxD3D11Device.cpp +++ b/Engine/source/gfx/D3D11/gfxD3D11Device.cpp @@ -53,6 +53,127 @@ 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 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 &formats, bool texture, bool mustblend, bool mustfilter) { U32 features = 0; @@ -186,10 +307,47 @@ void GFXD3D11Device::enumerateAdapters(Vector &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); @@ -271,7 +429,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 +439,7 @@ void GFXD3D11Device::init(const GFXVideoMode &mode, PlatformWindow *window) 0, D3D11_SDK_VERSION, &mD3DDevice, - &deviceFeature, + &mFeatureLevel, &mD3DDeviceContext); if(FAILED(hres)) @@ -298,7 +455,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 +476,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 +648,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 +655,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 +670,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 +680,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 +690,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(); diff --git a/Engine/source/gfx/D3D11/gfxD3D11Device.h b/Engine/source/gfx/D3D11/gfxD3D11Device.h index 726dce42f..c0024e9d2 100644 --- a/Engine/source/gfx/D3D11/gfxD3D11Device.h +++ b/Engine/source/gfx/D3D11/gfxD3D11Device.h @@ -129,6 +129,11 @@ protected: F32 mPixVersion; + D3D_FEATURE_LEVEL mFeatureLevel; + // Shader Model targers + String mVertexShaderTarget; + String mPixelShaderTarget; + bool mDebugLayers; DXGI_SAMPLE_DESC mMultisampleDesc; @@ -196,8 +201,6 @@ public: static void enumerateAdapters( Vector &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 +297,12 @@ 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; } }; #endif diff --git a/Engine/source/gfx/D3D11/gfxD3D11Shader.cpp b/Engine/source/gfx/D3D11/gfxD3D11Shader.cpp index 519c4645a..1e132534c 100644 --- a/Engine/source/gfx/D3D11/gfxD3D11Shader.cpp +++ b/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 &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 &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) { diff --git a/Engine/source/gfx/D3D11/gfxD3D11Shader.h b/Engine/source/gfx/D3D11/gfxD3D11Shader.h index 2e4074a8f..fc4cac62c 100644 --- a/Engine/source/gfx/D3D11/gfxD3D11Shader.h +++ b/Engine/source/gfx/D3D11/gfxD3D11Shader.h @@ -434,7 +434,7 @@ protected: GenericConstBufferLayout *bufferLayout, Vector &samplerDescriptions ); - void _getShaderConstants( ID3D11ShaderReflection* table, + void _getShaderConstants( ID3D11ShaderReflection* pTable, GenericConstBufferLayout *bufferLayout, Vector &samplerDescriptions ); From 48dc2551c4a5c13d16e8f26a1d645ed7a21e7939 Mon Sep 17 00:00:00 2001 From: rextimmy Date: Fri, 23 Dec 2016 15:08:23 +1000 Subject: [PATCH 2/4] 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: From 4857e89ca8063320af749fc0a6e5b9aa07b7271a Mon Sep 17 00:00:00 2001 From: rextimmy Date: Fri, 23 Dec 2016 15:43:45 +1000 Subject: [PATCH 3/4] D3D11 fullscreen fix --- Engine/source/gfx/D3D11/gfxD3D11Device.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Engine/source/gfx/D3D11/gfxD3D11Device.cpp b/Engine/source/gfx/D3D11/gfxD3D11Device.cpp index bc162437b..1fbe28a52 100644 --- a/Engine/source/gfx/D3D11/gfxD3D11Device.cpp +++ b/Engine/source/gfx/D3D11/gfxD3D11Device.cpp @@ -427,6 +427,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 From 46037622c9548d97f49f4eed13762990baccd8e6 Mon Sep 17 00:00:00 2001 From: rextimmy Date: Fri, 23 Dec 2016 15:59:32 +1000 Subject: [PATCH 4/4] D3DPER debug events for DX11 --- Engine/source/gfx/D3D11/gfxD3D11Device.cpp | 29 ++++++++++++++++++++++ Engine/source/gfx/D3D11/gfxD3D11Device.h | 6 ++--- 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/Engine/source/gfx/D3D11/gfxD3D11Device.cpp b/Engine/source/gfx/D3D11/gfxD3D11Device.cpp index 1fbe28a52..e25401085 100644 --- a/Engine/source/gfx/D3D11/gfxD3D11Device.cpp +++ b/Engine/source/gfx/D3D11/gfxD3D11Device.cpp @@ -37,6 +37,7 @@ #include "windowManager/platformWindow.h" #include "gfx/D3D11/screenshotD3D11.h" #include "materials/shaderData.h" +#include //ok now stressing out folks, this is just for debug events(D3DPER) :) #ifdef TORQUE_DEBUG #include "d3d11sdklayers.h" @@ -1678,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); } \ No newline at end of file diff --git a/Engine/source/gfx/D3D11/gfxD3D11Device.h b/Engine/source/gfx/D3D11/gfxD3D11Device.h index 3b98e763c..acb04c461 100644 --- a/Engine/source/gfx/D3D11/gfxD3D11Device.h +++ b/Engine/source/gfx/D3D11/gfxD3D11Device.h @@ -70,9 +70,9 @@ private: 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: