From d3bba829acfb2eabce748220eff045ef0c6f7880 Mon Sep 17 00:00:00 2001 From: Egor Yusov Date: Sat, 20 Oct 2018 14:16:56 -0700 Subject: Multiple improvements to shader resource binding in D3D11 and D3D12 --- .../include/D3DShaderResourceLoader.h | 82 +++++++++++----------- .../include/ShaderResources.h | 21 +++--- .../GraphicsEngineD3DBase/src/ShaderResources.cpp | 38 +++++----- 3 files changed, 72 insertions(+), 69 deletions(-) (limited to 'Graphics/GraphicsEngineD3DBase') diff --git a/Graphics/GraphicsEngineD3DBase/include/D3DShaderResourceLoader.h b/Graphics/GraphicsEngineD3DBase/include/D3DShaderResourceLoader.h index bc6b19fe..c053d39e 100644 --- a/Graphics/GraphicsEngineD3DBase/include/D3DShaderResourceLoader.h +++ b/Graphics/GraphicsEngineD3DBase/include/D3DShaderResourceLoader.h @@ -113,7 +113,7 @@ namespace Diligent // Name == "g_tex2DDiffuse" VERIFY_EXPR(Name.length() == OpenBracketPos); #ifdef _DEBUG - for (const auto &ExistingRes : Resources) + for (const auto& ExistingRes : Resources) { VERIFY(Name.compare(ExistingRes.Name) != 0, "Resource with the same name has already been enumerated. All array elements are expected to be enumerated one after another"); } @@ -204,52 +204,50 @@ namespace Diligent #ifdef DEVELOPMENT - if(ShdrDesc.NumVariables != 0 || ShdrDesc.NumStaticSamplers != 0 ) + for (Uint32 v = 0; v < ShdrDesc.NumVariables; ++v) { - for (Uint32 v = 0; v < ShdrDesc.NumVariables; ++v) + bool VariableFound = false; + const auto* VarName = ShdrDesc.VariableDesc[v].Name; + + for (const auto& Res : Resources) { - bool VariableFound = false; - const auto* VarName = ShdrDesc.VariableDesc[v].Name; + // Skip samplers if combined texture samplers are used as + // in this case they are not treated as independent variables + if (UseCombinedTextureSamplers && Res.GetInputType() == D3D_SIT_SAMPLER) + continue; - for (const auto& Res : Resources) - { - // Skip samplers if combined texture samplers are used as - // in this case they are not treated as independent variables - if ( !(UseCombinedTextureSamplers && Res.GetInputType() == D3D_SIT_SAMPLER) && strcmp(Res.Name, VarName) == 0) - { - VariableFound = true; - break; - } - } - if(!VariableFound) - { - LOG_WARNING_MESSAGE("Variable \"", VarName, "\" not found in shader \"", ShdrDesc.Name, '\"'); - } + VariableFound = (strcmp(Res.Name, VarName) == 0); + if (VariableFound) + break; } - - for (Uint32 s = 0; s < ShdrDesc.NumStaticSamplers; ++s) + if(!VariableFound) { - const auto* TexOrSamName = ShdrDesc.StaticSamplers[s].SamplerOrTextureName; + LOG_WARNING_MESSAGE("Variable \"", VarName, "\" not found in shader \"", ShdrDesc.Name, '\"'); + } + } - bool TextureOrSamplerFound = false; - for (const auto& Res : Resources) - { - if( UseCombinedTextureSamplers && Res.GetInputType() == D3D_SIT_TEXTURE && Res.GetSRVDimension() != D3D_SRV_DIMENSION_BUFFER || - !UseCombinedTextureSamplers && Res.GetInputType() == D3D_SIT_SAMPLER) - { - TextureOrSamplerFound = (strcmp(Res.Name, TexOrSamName) == 0); - if (TextureOrSamplerFound) - break; - } - } - if (!TextureOrSamplerFound) + for (Uint32 s = 0; s < ShdrDesc.NumStaticSamplers; ++s) + { + const auto* TexOrSamName = ShdrDesc.StaticSamplers[s].SamplerOrTextureName; + + bool TextureOrSamplerFound = false; + for (const auto& Res : Resources) + { + if( UseCombinedTextureSamplers && Res.GetInputType() == D3D_SIT_TEXTURE && Res.GetSRVDimension() != D3D_SRV_DIMENSION_BUFFER || + !UseCombinedTextureSamplers && Res.GetInputType() == D3D_SIT_SAMPLER) { - if (UseCombinedTextureSamplers) - LOG_WARNING_MESSAGE("Static sampler specifies a texture '", TexOrSamName, "' that is not found in shader '", ShdrDesc.Name, '\''); - else - LOG_WARNING_MESSAGE("Static sampler '", TexOrSamName, "' is not found in shader '", ShdrDesc.Name, '\''); + TextureOrSamplerFound = (strcmp(Res.Name, TexOrSamName) == 0); + if (TextureOrSamplerFound) + break; } } + if (!TextureOrSamplerFound) + { + if (UseCombinedTextureSamplers) + LOG_WARNING_MESSAGE("Static sampler specifies a texture '", TexOrSamName, "' that is not found in shader '", ShdrDesc.Name, '\''); + else + LOG_WARNING_MESSAGE("Static sampler '", TexOrSamName, "' is not found in shader '", ShdrDesc.Name, '\''); + } } #endif @@ -261,7 +259,7 @@ namespace Diligent for(size_t ResInd = 0; ResInd < Resources.size(); ++ResInd) { const auto& Res = Resources[ResInd]; - switch( Res.GetInputType() ) + switch (Res.GetInputType()) { case D3D_SIT_CBUFFER: { @@ -277,7 +275,7 @@ namespace Diligent case D3D_SIT_TEXTURE: { - if( Res.GetSRVDimension() == D3D_SRV_DIMENSION_BUFFER ) + if (Res.GetSRVDimension() == D3D_SRV_DIMENSION_BUFFER) { OnNewBuffSRV( Res ); } @@ -297,7 +295,7 @@ namespace Diligent case D3D_SIT_UAV_RWTYPED: { - if( Res.GetSRVDimension() == D3D_SRV_DIMENSION_BUFFER ) + if (Res.GetSRVDimension() == D3D_SRV_DIMENSION_BUFFER) { OnNewBuffUAV( Res ); } @@ -358,7 +356,7 @@ namespace Diligent } // Process texture SRVs. We need to do this after all samplers are initialized - for( auto TexSRVInd : TexSRVInds ) + for (auto TexSRVInd : TexSRVInds) { OnNewTexSRV( Resources[TexSRVInd] ); } diff --git a/Graphics/GraphicsEngineD3DBase/include/ShaderResources.h b/Graphics/GraphicsEngineD3DBase/include/ShaderResources.h index 6cc30b55..ec016324 100644 --- a/Graphics/GraphicsEngineD3DBase/include/ShaderResources.h +++ b/Graphics/GraphicsEngineD3DBase/include/ShaderResources.h @@ -61,6 +61,7 @@ #include "STDAllocator.h" #include "HashUtils.h" #include "StringPool.h" +#include "D3DShaderResourceLoader.h" namespace Diligent { @@ -70,7 +71,7 @@ inline bool IsAllowedType(SHADER_VARIABLE_TYPE VarType, Uint32 AllowedTypeBits)n return ((1 << VarType) & AllowedTypeBits) != 0; } -inline Uint32 GetAllowedTypeBits(const SHADER_VARIABLE_TYPE *AllowedVarTypes, Uint32 NumAllowedTypes)noexcept +inline Uint32 GetAllowedTypeBits(const SHADER_VARIABLE_TYPE* AllowedVarTypes, Uint32 NumAllowedTypes)noexcept { if (AllowedVarTypes == nullptr) return 0xFFFFFFFF; @@ -90,7 +91,7 @@ struct D3DShaderResourceAttribs const Uint16 BindCount; private: - // 4 3 4 20 1 + // 4 3 4 20 1 // bit | 0 1 2 3 | 4 5 6 | 7 8 9 10 | 11 12 13 ... 30 | 31 | // | | | | | | // | InputType | VariableType | SRV Dim | SamplerOrTexSRVIdBits | StaticSamplerFlag | @@ -361,21 +362,21 @@ public: for(Uint32 n=0; n < GetNumTexSRV(); ++n) { - const auto &TexSRV = GetTexSRV(n); + const auto& TexSRV = GetTexSRV(n); if( TexSRV.IsAllowedType(AllowedTypeBits) ) HandleTexSRV(TexSRV, n); } for(Uint32 n=0; n < GetNumTexUAV(); ++n) { - const auto &TexUAV = GetTexUAV(n); + const auto& TexUAV = GetTexUAV(n); if( TexUAV.IsAllowedType(AllowedTypeBits) ) HandleTexUAV(TexUAV, n); } for(Uint32 n=0; n < GetNumBufSRV(); ++n) { - const auto &BufSRV = GetBufSRV(n); + const auto& BufSRV = GetBufSRV(n); if( BufSRV.IsAllowedType(AllowedTypeBits) ) HandleBufSRV(BufSRV, n); } @@ -419,11 +420,11 @@ protected: return reinterpret_cast(m_MemoryBuffer.get())[Offset + n]; } - D3DShaderResourceAttribs& GetCB (Uint32 n)noexcept{ return GetResAttribs(n, GetNumCBs(), 0); } - D3DShaderResourceAttribs& GetTexSRV (Uint32 n)noexcept{ return GetResAttribs(n, GetNumTexSRV(), m_TexSRVOffset); } - D3DShaderResourceAttribs& GetTexUAV (Uint32 n)noexcept{ return GetResAttribs(n, GetNumTexUAV(), m_TexUAVOffset); } - D3DShaderResourceAttribs& GetBufSRV (Uint32 n)noexcept{ return GetResAttribs(n, GetNumBufSRV(), m_BufSRVOffset); } - D3DShaderResourceAttribs& GetBufUAV (Uint32 n)noexcept{ return GetResAttribs(n, GetNumBufUAV(), m_BufUAVOffset); } + D3DShaderResourceAttribs& GetCB (Uint32 n)noexcept{ return GetResAttribs(n, GetNumCBs(), 0); } + D3DShaderResourceAttribs& GetTexSRV (Uint32 n)noexcept{ return GetResAttribs(n, GetNumTexSRV(), m_TexSRVOffset); } + D3DShaderResourceAttribs& GetTexUAV (Uint32 n)noexcept{ return GetResAttribs(n, GetNumTexUAV(), m_TexUAVOffset); } + D3DShaderResourceAttribs& GetBufSRV (Uint32 n)noexcept{ return GetResAttribs(n, GetNumBufSRV(), m_BufSRVOffset); } + D3DShaderResourceAttribs& GetBufUAV (Uint32 n)noexcept{ return GetResAttribs(n, GetNumBufUAV(), m_BufUAVOffset); } D3DShaderResourceAttribs& GetSampler(Uint32 n)noexcept{ return GetResAttribs(n, GetNumSamplers(), m_SamplersOffset); } private: diff --git a/Graphics/GraphicsEngineD3DBase/src/ShaderResources.cpp b/Graphics/GraphicsEngineD3DBase/src/ShaderResources.cpp index f31da6a0..52527697 100644 --- a/Graphics/GraphicsEngineD3DBase/src/ShaderResources.cpp +++ b/Graphics/GraphicsEngineD3DBase/src/ShaderResources.cpp @@ -161,15 +161,18 @@ void ShaderResources::CountResources(const SHADER_VARIABLE_TYPE* AllowedVarTypes Uint32 ShaderResources::FindAssignedSamplerId(const D3DShaderResourceAttribs& TexSRV, const char* SamplerSuffix)const { VERIFY_EXPR(SamplerSuffix != nullptr && *SamplerSuffix != 0); - VERIFY_EXPR(TexSRV.GetInputType() == D3D_SIT_TEXTURE); + VERIFY_EXPR(TexSRV.GetInputType() == D3D_SIT_TEXTURE && TexSRV.GetSRVDimension() != D3D_SRV_DIMENSION_BUFFER); auto NumSamplers = GetNumSamplers(); for (Uint32 s = 0; s < NumSamplers; ++s) { - const auto &Sampler = GetSampler(s); - if( StreqSuff(Sampler.Name, TexSRV.Name, SamplerSuffix) ) + const auto& Sampler = GetSampler(s); + if ( StreqSuff(Sampler.Name, TexSRV.Name, SamplerSuffix) ) { - VERIFY(Sampler.GetVariableType() == TexSRV.GetVariableType(), "Inconsistent texture and sampler variable types"); - VERIFY(Sampler.BindCount == TexSRV.BindCount || Sampler.BindCount == 1, "Sampler assigned to array \"", TexSRV.Name, "\" is expected to be scalar or have the same dimension (",TexSRV.BindCount,"). Actual sampler array dimension : ", Sampler.BindCount); + DEV_CHECK_ERR(Sampler.GetVariableType() == TexSRV.GetVariableType(), + "The type (", GetShaderVariableTypeLiteralName(TexSRV.GetVariableType()),") of texture SRV variable '", TexSRV.Name, + "' is not consistent with the type (", GetShaderVariableTypeLiteralName(Sampler.GetVariableType()), + ") of the sampler '", Sampler.Name, "' that is assigned to it"); + DEV_CHECK_ERR(Sampler.BindCount == TexSRV.BindCount || Sampler.BindCount == 1, "Sampler '", Sampler.Name, "' assigned to texture '", TexSRV.Name, "' must be scalar or have the same array dimension (", TexSRV.BindCount, "). Actual sampler array dimension : ", Sampler.BindCount); return s; } } @@ -178,11 +181,12 @@ Uint32 ShaderResources::FindAssignedSamplerId(const D3DShaderResourceAttribs& Te bool ShaderResources::IsCompatibleWith(const ShaderResources &Res)const { - if (GetNumCBs() != Res.GetNumCBs() || - GetNumTexSRV() != Res.GetNumTexSRV() || - GetNumTexUAV() != Res.GetNumTexUAV() || - GetNumBufSRV() != Res.GetNumBufSRV() || - GetNumBufUAV() != Res.GetNumBufUAV()) + if (GetNumCBs() != Res.GetNumCBs() || + GetNumTexSRV() != Res.GetNumTexSRV() || + GetNumTexUAV() != Res.GetNumTexUAV() || + GetNumBufSRV() != Res.GetNumBufSRV() || + GetNumBufUAV() != Res.GetNumBufUAV() || + GetNumSamplers() != Res.GetNumSamplers()) return false; bool IsCompatible = true; @@ -191,32 +195,32 @@ bool ShaderResources::IsCompatibleWith(const ShaderResources &Res)const [&](const D3DShaderResourceAttribs& CB, Uint32 n) { - if(!CB.IsCompatibleWith(Res.GetCB(n))) + if (!CB.IsCompatibleWith(Res.GetCB(n))) IsCompatible = false; }, [&](const D3DShaderResourceAttribs& Sam, Uint32 n) { - if(!Sam.IsCompatibleWith(Res.GetSampler(n))) + if (!Sam.IsCompatibleWith(Res.GetSampler(n))) IsCompatible = false; }, [&](const D3DShaderResourceAttribs& TexSRV, Uint32 n) { - if(!TexSRV.IsCompatibleWith(Res.GetTexSRV(n))) + if (!TexSRV.IsCompatibleWith(Res.GetTexSRV(n))) IsCompatible = false; }, [&](const D3DShaderResourceAttribs& TexUAV, Uint32 n) { - if(!TexUAV.IsCompatibleWith(Res.GetTexUAV(n))) + if (!TexUAV.IsCompatibleWith(Res.GetTexUAV(n))) IsCompatible = false; }, [&](const D3DShaderResourceAttribs& BufSRV, Uint32 n) { - if(!BufSRV.IsCompatibleWith(Res.GetBufSRV(n))) + if (!BufSRV.IsCompatibleWith(Res.GetBufSRV(n))) IsCompatible = false; }, [&](const D3DShaderResourceAttribs& BufUAV, Uint32 n) { - if(!BufUAV.IsCompatibleWith(Res.GetBufUAV(n))) + if (!BufUAV.IsCompatibleWith(Res.GetBufUAV(n))) IsCompatible = false; } ); @@ -225,7 +229,7 @@ bool ShaderResources::IsCompatibleWith(const ShaderResources &Res)const size_t ShaderResources::GetHash()const { - size_t hash = ComputeHash(GetNumCBs(), GetNumTexSRV(), GetNumTexUAV(), GetNumBufSRV(), GetNumBufUAV()); + size_t hash = ComputeHash(GetNumCBs(), GetNumTexSRV(), GetNumTexUAV(), GetNumBufSRV(), GetNumBufUAV(), GetNumSamplers()); ProcessResources( nullptr, 0, [&](const D3DShaderResourceAttribs& CB, Uint32) -- cgit v1.2.3