Ver código fonte

Adding proper caps support for D3D11 feature levels.

Mike Popoloski 10 anos atrás
pai
commit
3ed95c81f2
1 arquivos alterados com 145 adições e 41 exclusões
  1. 145 41
      src/renderer_d3d11.cpp

+ 145 - 41
src/renderer_d3d11.cpp

@@ -584,8 +584,6 @@ namespace bgfx { namespace d3d11
 				| (BX_ENABLED(BGFX_CONFIG_DEBUG) ? D3D11_CREATE_DEVICE_DEBUG : 0)
 				| (BX_ENABLED(BGFX_CONFIG_DEBUG) ? D3D11_CREATE_DEVICE_DEBUG : 0)
 				;
 				;
 
 
-			D3D_FEATURE_LEVEL featureLevel;
-
 			hr = E_FAIL;
 			hr = E_FAIL;
 			for (uint32_t ii = 0; ii < 3 && FAILED(hr);)
 			for (uint32_t ii = 0; ii < 3 && FAILED(hr);)
 			{
 			{
@@ -597,7 +595,7 @@ namespace bgfx { namespace d3d11
 					, BX_COUNTOF(features)-ii
 					, BX_COUNTOF(features)-ii
 					, D3D11_SDK_VERSION
 					, D3D11_SDK_VERSION
 					, &m_device
 					, &m_device
-					, &featureLevel
+					, &m_featureLevel
 					, &m_deviceCtx
 					, &m_deviceCtx
 					);
 					);
 				if (FAILED(hr)
 				if (FAILED(hr)
@@ -759,21 +757,84 @@ BX_PRAGMA_DIAGNOSTIC_POP();
 				m_uniformReg.add(handle, getPredefinedUniformName(PredefinedUniform::Enum(ii) ), &m_predefinedUniforms[ii]);
 				m_uniformReg.add(handle, getPredefinedUniformName(PredefinedUniform::Enum(ii) ), &m_predefinedUniforms[ii]);
 			}
 			}
 
 
-			g_caps.supported |= ( 0
-								| BGFX_CAPS_TEXTURE_3D
-								| BGFX_CAPS_TEXTURE_COMPARE_ALL
-								| BGFX_CAPS_INSTANCING
-								| BGFX_CAPS_VERTEX_ATTRIB_HALF
-								| BGFX_CAPS_FRAGMENT_DEPTH
-								| BGFX_CAPS_BLEND_INDEPENDENT
-								| BGFX_CAPS_COMPUTE
-								| (getIntelExtensions(m_device) ? BGFX_CAPS_FRAGMENT_ORDERING : 0)
-								| BGFX_CAPS_SWAP_CHAIN
-								| (m_ovr.isInitialized() ? BGFX_CAPS_HMD : 0)
-								| BGFX_CAPS_INDEX32
-								);
-			g_caps.maxTextureSize   = D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION;
-			g_caps.maxFBAttachments = uint8_t(bx::uint32_min(D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT, BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS) );
+			g_caps.supported |= (0
+				| BGFX_CAPS_TEXTURE_3D
+				| BGFX_CAPS_VERTEX_ATTRIB_HALF
+				| BGFX_CAPS_FRAGMENT_DEPTH
+				| (getIntelExtensions(m_device) ? BGFX_CAPS_FRAGMENT_ORDERING : 0)
+				| BGFX_CAPS_SWAP_CHAIN
+				| (m_ovr.isInitialized() ? BGFX_CAPS_HMD : 0)
+				);
+
+			if (m_featureLevel <= D3D_FEATURE_LEVEL_9_2)
+			{
+				g_caps.maxTextureSize = D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION;
+				g_caps.maxFBAttachments = uint8_t(bx::uint32_min(D3D_FL9_1_SIMULTANEOUS_RENDER_TARGET_COUNT, BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS));
+			}
+			else if (m_featureLevel == D3D_FEATURE_LEVEL_9_3)
+			{
+				g_caps.maxTextureSize = D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION;
+				g_caps.maxFBAttachments = uint8_t(bx::uint32_min(D3D_FL9_3_SIMULTANEOUS_RENDER_TARGET_COUNT, BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS));
+			}
+			else
+			{
+				g_caps.supported |= BGFX_CAPS_TEXTURE_COMPARE_ALL;
+				g_caps.maxTextureSize = D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION;
+				g_caps.maxFBAttachments = uint8_t(bx::uint32_min(D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT, BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS));
+			}
+
+			// 32-bit indices only supported on 9_2+
+			if (m_featureLevel >= D3D_FEATURE_LEVEL_9_2)
+			{
+				g_caps.supported |= BGFX_CAPS_INDEX32;
+			}
+
+			// independent blend only supported on 10_1+
+			if (m_featureLevel >= D3D_FEATURE_LEVEL_10_1)
+			{
+				g_caps.supported |= BGFX_CAPS_BLEND_INDEPENDENT;
+			}
+
+			// compute support is optional on 10_0 and 10_1 targets
+			if (m_featureLevel == D3D_FEATURE_LEVEL_10_0 || m_featureLevel == D3D_FEATURE_LEVEL_10_1)
+			{
+				D3D11_FEATURE_DATA_D3D10_X_HARDWARE_OPTIONS data;
+				hr = m_device->CheckFeatureSupport(D3D11_FEATURE_D3D10_X_HARDWARE_OPTIONS, &data, sizeof(data) );
+				if (SUCCEEDED(hr) && data.ComputeShaders_Plus_RawAndStructuredBuffers_Via_Shader_4_x)
+				{
+					g_caps.supported |= BGFX_CAPS_COMPUTE;
+				}
+			}
+			else if (m_featureLevel >= D3D_FEATURE_LEVEL_11_0)
+			{
+				g_caps.supported |= BGFX_CAPS_COMPUTE;
+			}
+
+			// instancing fully supported on 9_3+, optionally partially supported at lower levels
+			if (m_featureLevel >= D3D_FEATURE_LEVEL_9_3)
+			{
+				g_caps.supported |= BGFX_CAPS_INSTANCING;
+			}
+			else
+			{
+				D3D11_FEATURE_DATA_D3D9_SIMPLE_INSTANCING_SUPPORT data;
+				hr = m_device->CheckFeatureSupport(D3D11_FEATURE_D3D9_SIMPLE_INSTANCING_SUPPORT, &data, sizeof(data) );
+				if (SUCCEEDED(hr) && data.SimpleInstancingSupported)
+				{
+					g_caps.supported |= BGFX_CAPS_INSTANCING;
+				}
+			}
+
+			// shadow compare is optional on 9_1 through 9_3 targets
+			if (m_featureLevel <= D3D_FEATURE_LEVEL_9_3)
+			{
+				D3D11_FEATURE_DATA_D3D9_SHADOW_SUPPORT data;
+				hr = m_device->CheckFeatureSupport(D3D11_FEATURE_D3D9_SHADOW_SUPPORT, &data, sizeof(data) );
+				if (SUCCEEDED(hr) && data.SupportsDepthAsTextureWithLessEqualComparisonFilter)
+				{
+					g_caps.supported |= BGFX_CAPS_TEXTURE_COMPARE_LEQUAL;
+				}
+			}
 
 
 			for (uint32_t ii = 0; ii < TextureFormat::Count; ++ii)
 			for (uint32_t ii = 0; ii < TextureFormat::Count; ++ii)
 			{
 			{
@@ -1381,10 +1442,19 @@ BX_PRAGMA_DIAGNOSTIC_POP();
 		void updateResolution(const Resolution& _resolution)
 		void updateResolution(const Resolution& _resolution)
 		{
 		{
 			bool recenter   = !!(_resolution.m_flags & BGFX_RESET_HMD_RECENTER);
 			bool recenter   = !!(_resolution.m_flags & BGFX_RESET_HMD_RECENTER);
-			m_maxAnisotropy = !!(_resolution.m_flags & BGFX_RESET_MAXANISOTROPY)
-				? D3D11_REQ_MAXANISOTROPY
-				: 1
+
+			if (!!(_resolution.m_flags & BGFX_RESET_MAXANISOTROPY) )
+			{
+				m_maxAnisotropy = (m_featureLevel == D3D_FEATURE_LEVEL_9_1)
+				? D3D_FL9_1_DEFAULT_MAX_ANISOTROPY
+				: D3D11_REQ_MAXANISOTROPY
 				;
 				;
+			}
+			else
+			{
+				m_maxAnisotropy = 1;
+			}
+
 			uint32_t flags = _resolution.m_flags & ~(BGFX_RESET_HMD_RECENTER | BGFX_RESET_MAXANISOTROPY);
 			uint32_t flags = _resolution.m_flags & ~(BGFX_RESET_HMD_RECENTER | BGFX_RESET_MAXANISOTROPY);
 
 
 			if ( getBufferWidth()  != _resolution.m_width
 			if ( getBufferWidth()  != _resolution.m_width
@@ -1821,7 +1891,7 @@ BX_PRAGMA_DIAGNOSTIC_POP();
 				desc.DepthBias = 0;
 				desc.DepthBias = 0;
 				desc.DepthBiasClamp = 0.0f;
 				desc.DepthBiasClamp = 0.0f;
 				desc.SlopeScaledDepthBias = 0.0f;
 				desc.SlopeScaledDepthBias = 0.0f;
-				desc.DepthClipEnable = false;
+				desc.DepthClipEnable = m_featureLevel <= D3D_FEATURE_LEVEL_9_3;	// disabling depth clip is only supported on 10_0+
 				desc.ScissorEnable = _scissor;
 				desc.ScissorEnable = _scissor;
 				desc.MultisampleEnable = !!(_state&BGFX_STATE_MSAA);
 				desc.MultisampleEnable = !!(_state&BGFX_STATE_MSAA);
 				desc.AntialiasedLineEnable = false;
 				desc.AntialiasedLineEnable = false;
@@ -1910,8 +1980,12 @@ BX_PRAGMA_DIAGNOSTIC_POP();
 
 
 		void commitTextureStage()
 		void commitTextureStage()
 		{
 		{
-			m_deviceCtx->VSSetShaderResources(0, BGFX_CONFIG_MAX_TEXTURE_SAMPLERS, m_textureStage.m_srv);
-			m_deviceCtx->VSSetSamplers(0, BGFX_CONFIG_MAX_TEXTURE_SAMPLERS, m_textureStage.m_sampler);
+			// vertex texture fetch not supported on 9_1 through 9_3
+			if (m_featureLevel > D3D_FEATURE_LEVEL_9_3)
+			{
+				m_deviceCtx->VSSetShaderResources(0, BGFX_CONFIG_MAX_TEXTURE_SAMPLERS, m_textureStage.m_srv);
+				m_deviceCtx->VSSetSamplers(0, BGFX_CONFIG_MAX_TEXTURE_SAMPLERS, m_textureStage.m_sampler);
+			}
 
 
 			m_deviceCtx->PSSetShaderResources(0, BGFX_CONFIG_MAX_TEXTURE_SAMPLERS, m_textureStage.m_srv);
 			m_deviceCtx->PSSetShaderResources(0, BGFX_CONFIG_MAX_TEXTURE_SAMPLERS, m_textureStage.m_srv);
 			m_deviceCtx->PSSetSamplers(0, BGFX_CONFIG_MAX_TEXTURE_SAMPLERS, m_textureStage.m_sampler);
 			m_deviceCtx->PSSetSamplers(0, BGFX_CONFIG_MAX_TEXTURE_SAMPLERS, m_textureStage.m_sampler);
@@ -2314,6 +2388,7 @@ BX_PRAGMA_DIAGNOSTIC_POP();
 		void* m_renderdocdll;
 		void* m_renderdocdll;
 
 
 		D3D_DRIVER_TYPE m_driverType;
 		D3D_DRIVER_TYPE m_driverType;
+		D3D_FEATURE_LEVEL m_featureLevel;
 		IDXGIAdapter* m_adapter;
 		IDXGIAdapter* m_adapter;
 		DXGI_ADAPTER_DESC m_adapterDesc;
 		DXGI_ADAPTER_DESC m_adapterDesc;
 #if BX_PLATFORM_WINRT
 #if BX_PLATFORM_WINRT
@@ -3786,12 +3861,22 @@ BX_PRAGMA_DIAGNOSTIC_POP();
 							numInstances      = draw.m_numInstances;
 							numInstances      = draw.m_numInstances;
 							numPrimsRendered  = numPrimsSubmitted*draw.m_numInstances;
 							numPrimsRendered  = numPrimsSubmitted*draw.m_numInstances;
 
 
-							deviceCtx->DrawIndexedInstanced(numIndices
-								, draw.m_numInstances
-								, 0
-								, draw.m_startVertex
-								, 0
-								);
+							if (numInstances > 1)
+							{
+								deviceCtx->DrawIndexedInstanced(numIndices
+									, draw.m_numInstances
+									, 0
+									, draw.m_startVertex
+									, 0
+									);
+							}
+							else
+							{
+								deviceCtx->DrawIndexed(numIndices
+									, 0
+									, draw.m_startVertex
+									);
+							}
 						}
 						}
 						else if (prim.m_min <= draw.m_numIndices)
 						else if (prim.m_min <= draw.m_numIndices)
 						{
 						{
@@ -3800,12 +3885,22 @@ BX_PRAGMA_DIAGNOSTIC_POP();
 							numInstances = draw.m_numInstances;
 							numInstances = draw.m_numInstances;
 							numPrimsRendered = numPrimsSubmitted*draw.m_numInstances;
 							numPrimsRendered = numPrimsSubmitted*draw.m_numInstances;
 
 
-							deviceCtx->DrawIndexedInstanced(numIndices
-								, draw.m_numInstances
-								, draw.m_startIndex
-								, draw.m_startVertex
-								, 0
-								);
+							if (numInstances > 1)
+							{
+								deviceCtx->DrawIndexedInstanced(numIndices
+									, draw.m_numInstances
+									, draw.m_startIndex
+									, draw.m_startVertex
+									, 0
+									);
+							}
+							else
+							{
+								deviceCtx->DrawIndexed(numIndices
+									, draw.m_startIndex
+									, draw.m_startVertex
+									);
+							}
 						}
 						}
 					}
 					}
 					else
 					else
@@ -3814,11 +3909,20 @@ BX_PRAGMA_DIAGNOSTIC_POP();
 						numInstances = draw.m_numInstances;
 						numInstances = draw.m_numInstances;
 						numPrimsRendered = numPrimsSubmitted*draw.m_numInstances;
 						numPrimsRendered = numPrimsSubmitted*draw.m_numInstances;
 
 
-						deviceCtx->DrawInstanced(numVertices
-							, draw.m_numInstances
-							, draw.m_startVertex
-							, 0
-							);
+						if (numInstances > 1)
+						{
+							deviceCtx->DrawInstanced(numVertices
+								, draw.m_numInstances
+								, draw.m_startVertex
+								, 0
+								);
+						}
+						else
+						{
+							deviceCtx->Draw(numVertices
+								, draw.m_startVertex
+								);
+						}
 					}
 					}
 
 
 					statsNumPrimsSubmitted[primIndex] += numPrimsSubmitted;
 					statsNumPrimsSubmitted[primIndex] += numPrimsSubmitted;