From 121cc748c25376a2af7cd08edb99b37b961c76c0 Mon Sep 17 00:00:00 2001 From: Mike Popoloski Date: Wed, 15 Apr 2015 22:53:09 -0400 Subject: [PATCH 1/3] Fixing a shader linkage crash in D3D11 for 10level9 targets Lower feature level targets in D3D11 also require SV_Position as an input param to the pixel shader, otherwise there are linkage mismatches between the vertex and pixel shaders. --- tools/shaderc/shaderc.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/shaderc/shaderc.cpp b/tools/shaderc/shaderc.cpp index 1388385f..f902ea07 100644 --- a/tools/shaderc/shaderc.cpp +++ b/tools/shaderc/shaderc.cpp @@ -1390,7 +1390,7 @@ int main(int _argc, const char* _argv[]) strins(const_cast(brace+1), "\nvec4 bgfx_VoidFrag;\n"); } - const bool hasFragCoord = NULL != strstr(input, "gl_FragCoord") || hlsl > 3; + const bool hasFragCoord = NULL != strstr(input, "gl_FragCoord") || hlsl > 3 || hlsl == 2; const bool hasFragDepth = NULL != strstr(input, "gl_FragDepth"); const bool hasFrontFacing = NULL != strstr(input, "gl_FrontFacing"); const bool hasPrimitiveId = NULL != strstr(input, "gl_PrimitiveID"); From b234364df96f806fea2e48ebc0ee5c73b50a8250 Mon Sep 17 00:00:00 2001 From: Mike Popoloski Date: Wed, 15 Apr 2015 22:54:19 -0400 Subject: [PATCH 2/3] Special casing texture2DLod for SM 2.0 targets tex2Dlod and related functions are not supported in shader model 2.0 (or D3D11 feature level 9_x). This commit just aliases them to a straight texture lookup, which doesn't do the same thing but at least it won't fail to compile. --- src/bgfx_shader.sh | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/bgfx_shader.sh b/src/bgfx_shader.sh index 52de12e8..79f593d3 100644 --- a/src/bgfx_shader.sh +++ b/src/bgfx_shader.sh @@ -199,7 +199,6 @@ float bgfxShadow2DProj(sampler2DShadow _sampler, vec4 _coord) # define SAMPLER2D(_name, _reg) uniform sampler2D _name : register(s ## _reg) # define texture2D(_sampler, _coord) tex2D(_sampler, _coord) -# define texture2DLod(_sampler, _coord, _level) tex2Dlod(_sampler, vec4( (_coord).xy, 0.0, _level) ) # define texture2DProj(_sampler, _coord) bgfxTexture2DProj(_sampler, _coord) # define SAMPLER2DSHADOW(_name, _reg) uniform sampler2DShadow _name : register(s ## _reg) @@ -208,11 +207,20 @@ float bgfxShadow2DProj(sampler2DShadow _sampler, vec4 _coord) # define SAMPLER3D(_name, _reg) uniform sampler3D _name : register(s ## _reg) # define texture3D(_sampler, _coord) tex3D(_sampler, _coord) -# define texture3DLod(_sampler, _coord, _level) tex3Dlod(_sampler, vec4( (_coord).xyz, _level) ) # define SAMPLERCUBE(_name, _reg) uniform samplerCUBE _name : register(s[_reg]) # define textureCube(_sampler, _coord) texCUBE(_sampler, _coord) -# define textureCubeLod(_sampler, _coord, _level) texCUBElod(_sampler, vec4( (_coord).xyz, _level) ) + +# if BGFX_SHADER_LANGUAGE_HLSL == 2 +# define texture2DLod(_sampler, _coord, _level) tex2D(_sampler, (_coord).xy) +# define texture3DLod(_sampler, _coord, _level) tex3D(_sampler, (_coord).xyz) +# define textureCubeLod(_sampler, _coord, _level) texCUBE(_sampler, (_coord).xyz) +# else +# define texture2DLod(_sampler, _coord, _level) tex2Dlod(_sampler, vec4( (_coord).xy, 0.0, _level) ) +# define texture3DLod(_sampler, _coord, _level) tex3Dlod(_sampler, vec4( (_coord).xyz, _level) ) +# define textureCubeLod(_sampler, _coord, _level) texCUBElod(_sampler, vec4( (_coord).xyz, _level) ) +# endif + # endif // vec2 vec2_splat(float _x) { return vec2(_x, _x); } From 3ed95c81f2b6ff1d9c4f43047b43cd7619cd0ee5 Mon Sep 17 00:00:00 2001 From: Mike Popoloski Date: Thu, 16 Apr 2015 19:24:05 -0400 Subject: [PATCH 3/3] Adding proper caps support for D3D11 feature levels. --- src/renderer_d3d11.cpp | 186 ++++++++++++++++++++++++++++++++--------- 1 file changed, 145 insertions(+), 41 deletions(-) diff --git a/src/renderer_d3d11.cpp b/src/renderer_d3d11.cpp index 24df2fd7..c6d018ae 100644 --- a/src/renderer_d3d11.cpp +++ b/src/renderer_d3d11.cpp @@ -584,8 +584,6 @@ namespace bgfx { namespace d3d11 | (BX_ENABLED(BGFX_CONFIG_DEBUG) ? D3D11_CREATE_DEVICE_DEBUG : 0) ; - D3D_FEATURE_LEVEL featureLevel; - hr = E_FAIL; for (uint32_t ii = 0; ii < 3 && FAILED(hr);) { @@ -597,7 +595,7 @@ namespace bgfx { namespace d3d11 , BX_COUNTOF(features)-ii , D3D11_SDK_VERSION , &m_device - , &featureLevel + , &m_featureLevel , &m_deviceCtx ); if (FAILED(hr) @@ -759,21 +757,84 @@ BX_PRAGMA_DIAGNOSTIC_POP(); 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) { @@ -1381,10 +1442,19 @@ BX_PRAGMA_DIAGNOSTIC_POP(); void updateResolution(const Resolution& _resolution) { 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); if ( getBufferWidth() != _resolution.m_width @@ -1821,7 +1891,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); desc.DepthBias = 0; desc.DepthBiasClamp = 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.MultisampleEnable = !!(_state&BGFX_STATE_MSAA); desc.AntialiasedLineEnable = false; @@ -1910,8 +1980,12 @@ BX_PRAGMA_DIAGNOSTIC_POP(); 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->PSSetSamplers(0, BGFX_CONFIG_MAX_TEXTURE_SAMPLERS, m_textureStage.m_sampler); @@ -2314,6 +2388,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); void* m_renderdocdll; D3D_DRIVER_TYPE m_driverType; + D3D_FEATURE_LEVEL m_featureLevel; IDXGIAdapter* m_adapter; DXGI_ADAPTER_DESC m_adapterDesc; #if BX_PLATFORM_WINRT @@ -3786,12 +3861,22 @@ BX_PRAGMA_DIAGNOSTIC_POP(); numInstances = 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) { @@ -3800,12 +3885,22 @@ BX_PRAGMA_DIAGNOSTIC_POP(); numInstances = 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 @@ -3814,11 +3909,20 @@ BX_PRAGMA_DIAGNOSTIC_POP(); numInstances = 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;