diff options
| author | Egor Yusov <egor.yusov@gmail.com> | 2018-10-17 16:26:27 +0000 |
|---|---|---|
| committer | Egor Yusov <egor.yusov@gmail.com> | 2018-10-17 16:26:27 +0000 |
| commit | 435f70be7aebd9a669d6a276df67e8eb814a45e3 (patch) | |
| tree | 040377c1ac3201fef75c01e9e3535a172babbcb1 /Graphics/GraphicsEngineD3DBase | |
| parent | Improved StrCmpSuff() to allow optional suffix (diff) | |
| download | DiligentCore-435f70be7aebd9a669d6a276df67e8eb814a45e3.tar.gz DiligentCore-435f70be7aebd9a669d6a276df67e8eb814a45e3.zip | |
Implemented separate samplers in D3D11
Diffstat (limited to 'Graphics/GraphicsEngineD3DBase')
3 files changed, 285 insertions, 122 deletions
diff --git a/Graphics/GraphicsEngineD3DBase/include/D3DShaderResourceLoader.h b/Graphics/GraphicsEngineD3DBase/include/D3DShaderResourceLoader.h index 75f880c0..1a256bce 100644 --- a/Graphics/GraphicsEngineD3DBase/include/D3DShaderResourceLoader.h +++ b/Graphics/GraphicsEngineD3DBase/include/D3DShaderResourceLoader.h @@ -70,6 +70,8 @@ namespace Diligent Resources.reserve(shaderDesc.BoundResources); std::unordered_set<std::string> ResourceNamesTmpPool; + const bool UseCombinedTextureSamplers = SamplerSuffix != nullptr; + Uint32 NumCBs = 0, NumTexSRVs = 0, NumTexUAVs = 0, NumBufSRVs = 0, NumBufUAVs = 0, NumSamplers = 0; size_t ResourceNamesPoolSize = 0; // Number of resources to skip (used for array resources) @@ -151,17 +153,17 @@ namespace Diligent { for (Uint32 s = 0; s < ShdrDesc.NumStaticSamplers; ++s) { - if( StrCmpSuff(Name.c_str(), ShdrDesc.StaticSamplers[s].TextureName, SamplerSuffix) ) + if (StrCmpSuff(Name.c_str(), ShdrDesc.StaticSamplers[s].SamplerOrTextureName, SamplerSuffix)) { IsStaticSampler = true; break; } } - // Use texture name to derive sampler type + // Use texture or sampler name to derive sampler type VarType = GetShaderVariableType(ShdrDesc.DefaultVariableType, ShdrDesc.VariableDesc, ShdrDesc.NumVariables, - [&](const char *TexName) + [&](const char* VarName) { - return StrCmpSuff(Name.c_str(), TexName, SamplerSuffix); + return StrCmpSuff(Name.c_str(), VarName, SamplerSuffix); }); } else @@ -201,7 +203,7 @@ namespace Diligent } -#ifdef _DEBUG +#ifdef DEVELOPMENT if(ShdrDesc.NumVariables != 0 || ShdrDesc.NumStaticSamplers != 0 ) { for (Uint32 v = 0; v < ShdrDesc.NumVariables; ++v) @@ -211,8 +213,9 @@ namespace Diligent for (const auto& Res : Resources) { - // Skip samplers as they are not handled as independent variables - if (Res.GetInputType() != D3D_SIT_SAMPLER && strcmp(Res.Name, VarName) == 0) + // 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; @@ -226,20 +229,25 @@ namespace Diligent for (Uint32 s = 0; s < ShdrDesc.NumStaticSamplers; ++s) { - bool TextureFound = false; - const auto *TexName = ShdrDesc.StaticSamplers[s].TextureName; + const auto* TexOrSamName = ShdrDesc.StaticSamplers[s].SamplerOrTextureName; + bool TextureOrSamplerFound = false; for (const auto& Res : Resources) { - if ( Res.GetInputType() == D3D_SIT_TEXTURE && Res.GetSRVDimension() != D3D_SRV_DIMENSION_BUFFER && strcmp(Res.Name, TexName) == 0) + if( UseCombinedTextureSamplers && Res.GetInputType() == D3D_SIT_TEXTURE && Res.GetSRVDimension() != D3D_SRV_DIMENSION_BUFFER || + !UseCombinedTextureSamplers && Res.GetInputType() == D3D_SIT_SAMPLER) { - TextureFound = true; - break; + TextureOrSamplerFound = (strcmp(Res.Name, TexOrSamName) == 0); + if (TextureOrSamplerFound) + break; } } - if(!TextureFound) + if (!TextureOrSamplerFound) { - LOG_WARNING_MESSAGE("Static sampler specifies a texture \"", TexName, "\" that is not found in shader \"", ShdrDesc.Name, '\"'); + 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, '\''); } } } diff --git a/Graphics/GraphicsEngineD3DBase/include/ShaderResources.h b/Graphics/GraphicsEngineD3DBase/include/ShaderResources.h index b49069dd..9c2278d4 100644 --- a/Graphics/GraphicsEngineD3DBase/include/ShaderResources.h +++ b/Graphics/GraphicsEngineD3DBase/include/ShaderResources.h @@ -42,13 +42,14 @@ // Nsam - number of samplers // // -// If texture SRV is assigned a sampler, it is referenced through SamplerId: +// If texture SRV is assigned a sampler, it is cross-referenced through SamplerOrTexSRVId: // -// _________________________SamplerId_______________________ +// _____________________SamplerOrTexSRVId___________________ // | | // | V // | CBs | ... TexSRV[n] ... | TexUAVs | BufSRVs | BufUAVs | Sam[0] ... Sam[SamplerId] ... | -// +// A | +// '---------------------SamplerOrTexSRVId-------------------' // #include <memory> @@ -71,11 +72,11 @@ inline bool IsAllowedType(SHADER_VARIABLE_TYPE VarType, Uint32 AllowedTypeBits)n inline Uint32 GetAllowedTypeBits(const SHADER_VARIABLE_TYPE *AllowedVarTypes, Uint32 NumAllowedTypes)noexcept { - if(AllowedVarTypes == nullptr) + if (AllowedVarTypes == nullptr) return 0xFFFFFFFF; Uint32 AllowedTypeBits = 0; - for(Uint32 i=0; i < NumAllowedTypes; ++i) + for (Uint32 i=0; i < NumAllowedTypes; ++i) AllowedTypeBits |= 1 << AllowedVarTypes[i]; return AllowedTypeBits; } @@ -89,16 +90,16 @@ struct D3DShaderResourceAttribs const Uint16 BindCount; private: - // 4 3 4 20 1 - // bit | 0 1 2 3 | 4 5 6 | 7 8 9 10 | 11 12 ... 30 | 31 | - // | | | | | | - // | InputType | VariableType | SRV Dim | SamplerId | StaticSamplerFlag | + // 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 | static constexpr const Uint32 ShaderInputTypeBits = 4; static constexpr const Uint32 VariableTypeBits = 3; static constexpr const Uint32 SRVDimBits = 4; - static constexpr const Uint32 SamplerIdBits = 20; + static constexpr const Uint32 SamplerOrTexSRVIdBits = 20; static constexpr const Uint32 StaticSamplerFlagBits = 1; - static_assert(ShaderInputTypeBits + VariableTypeBits + SRVDimBits + SamplerIdBits + StaticSamplerFlagBits == 32, "Attributes are better be packed into 32 bits"); + static_assert(ShaderInputTypeBits + VariableTypeBits + SRVDimBits + SamplerOrTexSRVIdBits + StaticSamplerFlagBits == 32, "Attributes are better be packed into 32 bits"); static_assert(D3D_SIT_UAV_RWSTRUCTURED_WITH_COUNTER < (1 << ShaderInputTypeBits), "Not enough bits to represent D3D_SHADER_INPUT_TYPE"); static_assert(SHADER_VARIABLE_TYPE_NUM_TYPES < (1 << VariableTypeBits), "Not enough bits to represent SHADER_VARIABLE_TYPE"); @@ -108,15 +109,16 @@ private: // There originally was a problem when the type of InputType was D3D_SHADER_INPUT_TYPE: // the value of D3D_SIT_UAV_RWBYTEADDRESS (8) was interpreted as -8 (as the underlying enum type // is signed) causing errors - const Uint32 InputType : ShaderInputTypeBits; // Max value: D3D_SIT_UAV_RWSTRUCTURED_WITH_COUNTER == 11 - const Uint32 VariableType : VariableTypeBits; // Max value: SHADER_VARIABLE_TYPE_DYNAMIC == 2 - const Uint32 SRVDimension : SRVDimBits; // Max value: D3D_SRV_DIMENSION_BUFFEREX == 11 - const Uint32 SamplerId : SamplerIdBits; // Max value: 1048575 - const Uint32 StaticSamplerFlag : StaticSamplerFlagBits; // Needs to be Uint32, otherwise sizeof(D3DShaderResourceAttribs)==24 + const Uint32 InputType : ShaderInputTypeBits; // Max value: D3D_SIT_UAV_RWSTRUCTURED_WITH_COUNTER == 11 + const Uint32 VariableType : VariableTypeBits; // Max value: SHADER_VARIABLE_TYPE_DYNAMIC == 2 + const Uint32 SRVDimension : SRVDimBits; // Max value: D3D_SRV_DIMENSION_BUFFEREX == 11 + Uint32 SamplerOrTexSRVId : SamplerOrTexSRVIdBits; // Max value: 1048575 + const Uint32 StaticSamplerFlag : StaticSamplerFlagBits; // Needs to be Uint32, otherwise sizeof(D3DShaderResourceAttribs)==24 // (https://stackoverflow.com/questions/308364/c-bitfield-packing-with-bools) public: - static constexpr const Uint32 InvalidSamplerId = (1 << SamplerIdBits) - 1; + static constexpr const Uint32 InvalidSamplerId = (1 << SamplerOrTexSRVIdBits) - 1; + static constexpr const Uint32 InvalidTexSRVId = (1 << SamplerOrTexSRVIdBits) - 1; static constexpr const Uint16 InvalidBindPoint = std::numeric_limits<Uint16>::max(); static constexpr const Uint16 MaxBindPoint = InvalidBindPoint - 1; static constexpr const Uint16 MaxBindCount = std::numeric_limits<Uint16>::max(); @@ -130,31 +132,32 @@ public: D3D_SRV_DIMENSION _SRVDimension, Uint32 _SamplerId, bool _IsStaticSampler)noexcept : - Name (_Name), - BindPoint (static_cast<decltype(BindPoint)> (_BindPoint)), - BindCount (static_cast<decltype(BindCount)> (_BindCount)), - InputType (static_cast<decltype(InputType)> (_InputType)), - VariableType (static_cast<decltype(VariableType)>(_VariableType)), - SRVDimension (static_cast<decltype(SRVDimension)>(_SRVDimension)), - SamplerId (_SamplerId), - StaticSamplerFlag(_IsStaticSampler ? 1 : 0) + Name (_Name), + BindPoint (static_cast<decltype(BindPoint)> (_BindPoint)), + BindCount (static_cast<decltype(BindCount)> (_BindCount)), + InputType (static_cast<decltype(InputType)> (_InputType)), + VariableType (static_cast<decltype(VariableType)>(_VariableType)), + SRVDimension (static_cast<decltype(SRVDimension)>(_SRVDimension)), + SamplerOrTexSRVId (_SamplerId), + StaticSamplerFlag (_IsStaticSampler ? 1 : 0) { +#ifdef _DEBUG VERIFY(_BindPoint <= MaxBindPoint || _BindPoint == InvalidBindPoint, "Bind Point is out of allowed range"); VERIFY(_BindCount <= MaxBindCount, "Bind Count is out of allowed range"); - VERIFY(_InputType < (1 << ShaderInputTypeBits), "Shader input type is out of expected range"); - VERIFY(_VariableType < (1 << VariableTypeBits), "Variable type is out of expected range"); - VERIFY(_SRVDimension < (1 << SRVDimBits), "SRV dimensions is out of expected range"); - VERIFY(_SamplerId < (1 << SamplerIdBits), "SamplerId is out of representable range"); -#ifdef _DEBUG + VERIFY(_InputType < (1 << ShaderInputTypeBits), "Shader input type is out of expected range"); + VERIFY(_VariableType < (1 << VariableTypeBits), "Variable type is out of expected range"); + VERIFY(_SRVDimension < (1 << SRVDimBits), "SRV dimensions is out of expected range"); + VERIFY(_SamplerId < (1 << SamplerOrTexSRVIdBits), "SamplerOrTexSRVId is out of representable range"); + if (_InputType==D3D_SIT_SAMPLER) VERIFY_EXPR(IsStaticSampler() == _IsStaticSampler); else - VERIFY(!_IsStaticSampler, "Only samplers can be marked as static"); + VERIFY(!_IsStaticSampler, "Only samplers can be labeled as static"); - if (_InputType == D3D_SIT_TEXTURE) - VERIFY_EXPR(SamplerId == _SamplerId); + if (_InputType == D3D_SIT_TEXTURE && _SRVDimension != D3D_SRV_DIMENSION_BUFFER) + VERIFY_EXPR(GetSamplerId() == _SamplerId); else - VERIFY(SamplerId == InvalidSamplerId, "Only textures can be assigned a valid texture sampler"); + VERIFY(_SamplerId == InvalidSamplerId, "Only texture SRV can be assigned a valid texture sampler"); if (_IsStaticSampler) VERIFY( _InputType == D3D_SIT_SAMPLER, "Invalid input type: D3D_SIT_SAMPLER is expected" ); @@ -174,7 +177,7 @@ public: false } { - VERIFY(InputType == D3D_SIT_TEXTURE, "Only textures can be assigned a texture sampler"); + VERIFY(GetInputType() == D3D_SIT_TEXTURE && GetSRVDimension() != D3D_SRV_DIMENSION_BUFFER, "Only texture SRV can be assigned a texture sampler"); } D3DShaderResourceAttribs(StringPool& NamesPool, const D3DShaderResourceAttribs& rhs)noexcept : @@ -186,7 +189,7 @@ public: rhs.GetInputType(), rhs.GetVariableType(), rhs.GetSRVDimension(), - rhs.SamplerId, + rhs.SamplerOrTexSRVId, rhs.StaticSamplerFlag !=0 ? true : false } { @@ -214,21 +217,39 @@ public: Uint32 GetSamplerId()const { - VERIFY( InputType == D3D_SIT_TEXTURE, "Invalid input type: D3D_SIT_TEXTURE is expected" ); - return SamplerId; + VERIFY(GetInputType() == D3D_SIT_TEXTURE && GetSRVDimension() != D3D_SRV_DIMENSION_BUFFER, "Invalid input type: D3D_SIT_TEXTURE is expected" ); + return SamplerOrTexSRVId; + } + + void SetTexSRVId(Uint32 TexSRVId) + { + VERIFY(GetInputType() == D3D_SIT_SAMPLER, "Invalid input type: D3D_SIT_SAMPLER is expected" ); + VERIFY(TexSRVId < (1 << SamplerOrTexSRVIdBits), "TexSRVId (", TexSRVId, ") is out of representable range"); + SamplerOrTexSRVId = TexSRVId; + } + + Uint32 GetTexSRVId()const + { + VERIFY(GetInputType() == D3D_SIT_SAMPLER, "Invalid input type: D3D_SIT_SAMPLER is expected" ); + return SamplerOrTexSRVId; } bool IsStaticSampler()const { - VERIFY( InputType == D3D_SIT_SAMPLER, "Invalid input type: D3D_SIT_SAMPLER is expected" ); + VERIFY(GetInputType() == D3D_SIT_SAMPLER, "Invalid input type: D3D_SIT_SAMPLER is expected" ); return StaticSamplerFlag != 0; } - bool IsValidSampler()const + bool ValidSamplerAssigned()const { return GetSamplerId() != InvalidSamplerId; } + bool ValidTexSRVAssigned()const + { + return GetTexSRVId() != InvalidTexSRVId; + } + bool IsValidBindPoint()const { return BindPoint != InvalidBindPoint; @@ -245,18 +266,18 @@ public: bool IsCompatibleWith(const D3DShaderResourceAttribs& Attribs)const { - return BindPoint == Attribs.BindPoint && - BindCount == Attribs.BindCount && - InputType == Attribs.InputType && - VariableType == Attribs.VariableType && - SRVDimension == Attribs.SRVDimension && - SamplerId == Attribs.SamplerId && - StaticSamplerFlag == Attribs.StaticSamplerFlag; + return BindPoint == Attribs.BindPoint && + BindCount == Attribs.BindCount && + InputType == Attribs.InputType && + VariableType == Attribs.VariableType && + SRVDimension == Attribs.SRVDimension && + SamplerOrTexSRVId == Attribs.SamplerOrTexSRVId && + StaticSamplerFlag == Attribs.StaticSamplerFlag; } size_t GetHash()const { - return ComputeHash(BindPoint, BindCount, InputType, VariableType, SRVDimension, SamplerId, StaticSamplerFlag); + return ComputeHash(BindPoint, BindCount, InputType, VariableType, SRVDimension, SamplerOrTexSRVId, StaticSamplerFlag); } bool IsAllowedType(Uint32 AllowedTypeBits)const @@ -295,25 +316,32 @@ public: const D3DShaderResourceAttribs& GetSampler(Uint32 n)const noexcept{ return GetResAttribs(n, GetNumSamplers(), m_SamplersOffset); } - void CountResources(const SHADER_VARIABLE_TYPE *AllowedVarTypes, Uint32 NumAllowedTypes, - Uint32& NumCBs, Uint32& NumTexSRVs, Uint32& NumTexUAVs, - Uint32& NumBufSRVs, Uint32& NumBufUAVs, Uint32& NumSamplers)const noexcept; + void CountResources(const SHADER_VARIABLE_TYPE* AllowedVarTypes, + Uint32 NumAllowedTypes, + Uint32& NumCBs, + Uint32& NumTexSRVs, + Uint32& NumTexUAVs, + Uint32& NumBufSRVs, + Uint32& NumBufUAVs, + Uint32& NumSamplers)const noexcept; SHADER_TYPE GetShaderType()const noexcept{return m_ShaderType;} - // Process only resources listed in AllowedVarTypes + // Processes only resources listed in AllowedVarTypes template<typename THandleCB, + typename THandleSampler, typename THandleTexSRV, typename THandleTexUAV, typename THandleBufSRV, typename THandleBufUAV> - void ProcessResources(const SHADER_VARIABLE_TYPE *AllowedVarTypes, - Uint32 NumAllowedTypes, - THandleCB HandleCB, - THandleTexSRV HandleTexSRV, - THandleTexUAV HandleTexUAV, - THandleBufSRV HandleBufSRV, - THandleBufUAV HandleBufUAV)const + void ProcessResources(const SHADER_VARIABLE_TYPE* AllowedVarTypes, + Uint32 NumAllowedTypes, + THandleCB HandleCB, + THandleSampler HandleSampler, + THandleTexSRV HandleTexSRV, + THandleTexUAV HandleTexUAV, + THandleBufSRV HandleBufSRV, + THandleBufUAV HandleBufUAV)const { Uint32 AllowedTypeBits = GetAllowedTypeBits(AllowedVarTypes, NumAllowedTypes); @@ -324,6 +352,13 @@ public: HandleCB(CB, n); } + for(Uint32 n=0; n < GetNumSamplers(); ++n) + { + const auto& Sampler = GetSampler(n); + if( Sampler.IsAllowedType(AllowedTypeBits) ) + HandleSampler(Sampler, n); + } + for(Uint32 n=0; n < GetNumTexSRV(); ++n) { const auto &TexSRV = GetTexSRV(n); @@ -353,19 +388,21 @@ public: } } - bool IsCompatibleWith(const ShaderResources &Resources)const; - + bool IsCompatibleWith(const ShaderResources& Resources) const; + bool IsUsingCombinedTextureSamplers() const {return m_UseCombinedTextureSamplers;} + size_t GetHash()const; protected: - void Initialize(IMemoryAllocator& Allocator, - Uint32 NumCBs, - Uint32 NumTexSRVs, - Uint32 NumTexUAVs, - Uint32 NumBufSRVs, - Uint32 NumBufUAVs, - Uint32 NumSamplers, - size_t ResourceNamesPoolSize); + template<typename D3D_SHADER_DESC, + typename D3D_SHADER_INPUT_BIND_DESC, + typename TShaderReflection, + typename TNewResourceHandler> + void Initialize(ID3DBlob* pShaderByteCode, + TNewResourceHandler NewResHandler, + const ShaderDesc& ShdrDesc, + const Char* SamplerSuffix); + __forceinline D3DShaderResourceAttribs& GetResAttribs(Uint32 n, Uint32 NumResources, Uint32 Offset)noexcept { @@ -388,29 +425,133 @@ protected: D3DShaderResourceAttribs& GetBufUAV (Uint32 n)noexcept{ return GetResAttribs(n, GetNumBufUAV(), m_BufUAVOffset); } D3DShaderResourceAttribs& GetSampler(Uint32 n)noexcept{ return GetResAttribs(n, GetNumSamplers(), m_SamplersOffset); } +private: + void AllocateMemory(IMemoryAllocator& Allocator, + Uint32 NumCBs, + Uint32 NumTexSRVs, + Uint32 NumTexUAVs, + Uint32 NumBufSRVs, + Uint32 NumBufUAVs, + Uint32 NumSamplers, + size_t ResourceNamesPoolSize); + Uint32 FindAssignedSamplerId(const D3DShaderResourceAttribs& TexSRV, const char* SamplerSuffix)const; -private: // Memory buffer that holds all resources as continuous chunk of memory: // | CBs | TexSRVs | TexUAVs | BufSRVs | BufUAVs | Samplers | Resource Names | std::unique_ptr< void, STDDeleterRawMem<void> > m_MemoryBuffer; -protected: StringPool m_ResourceNames; -private: // Offsets in elements of D3DShaderResourceAttribs typedef Uint16 OffsetType; - OffsetType m_TexSRVOffset = 0; - OffsetType m_TexUAVOffset = 0; - OffsetType m_BufSRVOffset = 0; - OffsetType m_BufUAVOffset = 0; + OffsetType m_TexSRVOffset = 0; + OffsetType m_TexUAVOffset = 0; + OffsetType m_BufSRVOffset = 0; + OffsetType m_BufUAVOffset = 0; OffsetType m_SamplersOffset = 0; OffsetType m_TotalResources = 0; + bool m_UseCombinedTextureSamplers = false; + SHADER_TYPE m_ShaderType = SHADER_TYPE_UNKNOWN; }; + +template<typename D3D_SHADER_DESC, + typename D3D_SHADER_INPUT_BIND_DESC, + typename TShaderReflection, + typename TNewResourceHandler> +void ShaderResources::Initialize(ID3DBlob* pShaderByteCode, + TNewResourceHandler NewResHandler, + const ShaderDesc& ShdrDesc, + const Char* CombinedSamplerSuffix) +{ + m_UseCombinedTextureSamplers = CombinedSamplerSuffix != nullptr; + + Uint32 CurrCB = 0, CurrTexSRV = 0, CurrTexUAV = 0, CurrBufSRV = 0, CurrBufUAV = 0, CurrSampler = 0; + LoadD3DShaderResources<D3D_SHADER_DESC, D3D_SHADER_INPUT_BIND_DESC, TShaderReflection>( + pShaderByteCode, + + [&](Uint32 NumCBs, Uint32 NumTexSRVs, Uint32 NumTexUAVs, Uint32 NumBufSRVs, Uint32 NumBufUAVs, Uint32 NumSamplers, size_t ResourceNamesPoolSize) + { + AllocateMemory(GetRawAllocator(), NumCBs, NumTexSRVs, NumTexUAVs, NumBufSRVs, NumBufUAVs, NumSamplers, ResourceNamesPoolSize); + }, + + [&](const D3DShaderResourceAttribs& CBAttribs) + { + VERIFY_EXPR(CBAttribs.GetInputType() == D3D_SIT_CBUFFER); + auto* pNewCB = new (&GetCB(CurrCB++)) D3DShaderResourceAttribs(m_ResourceNames, CBAttribs); + NewResHandler.OnNewCB(*pNewCB); + }, + + [&](const D3DShaderResourceAttribs& TexUAV) + { + VERIFY_EXPR(TexUAV.GetInputType() == D3D_SIT_UAV_RWTYPED && TexUAV.GetSRVDimension() != D3D_SRV_DIMENSION_BUFFER); + auto* pNewTexUAV = new (&GetTexUAV(CurrTexUAV++)) D3DShaderResourceAttribs(m_ResourceNames, TexUAV); + NewResHandler.OnNewTexUAV(*pNewTexUAV); + }, + + [&](const D3DShaderResourceAttribs& BuffUAV) + { + VERIFY_EXPR(BuffUAV.GetInputType() == D3D_SIT_UAV_RWTYPED && BuffUAV.GetSRVDimension() == D3D_SRV_DIMENSION_BUFFER || BuffUAV.GetInputType() == D3D_SIT_UAV_RWSTRUCTURED || BuffUAV.GetInputType() == D3D_SIT_UAV_RWBYTEADDRESS); + auto* pNewBufUAV = new (&GetBufUAV(CurrBufUAV++)) D3DShaderResourceAttribs(m_ResourceNames, BuffUAV); + NewResHandler.OnNewBuffUAV(*pNewBufUAV); + }, + + [&](const D3DShaderResourceAttribs& BuffSRV) + { + VERIFY_EXPR(BuffSRV.GetInputType() == D3D_SIT_TEXTURE && BuffSRV.GetSRVDimension() == D3D_SRV_DIMENSION_BUFFER || BuffSRV.GetInputType() == D3D_SIT_STRUCTURED || BuffSRV.GetInputType() == D3D_SIT_BYTEADDRESS); + auto* pNewBuffSRV = new (&GetBufSRV(CurrBufSRV++)) D3DShaderResourceAttribs(m_ResourceNames, BuffSRV); + NewResHandler.OnNewBuffSRV(*pNewBuffSRV); + }, + + [&](const D3DShaderResourceAttribs& SamplerAttribs) + { + VERIFY_EXPR(SamplerAttribs.GetInputType() == D3D_SIT_SAMPLER); + auto* pNewSampler = new (&GetSampler(CurrSampler++)) D3DShaderResourceAttribs(m_ResourceNames, SamplerAttribs); + NewResHandler.OnNewSampler(*pNewSampler); + }, + + [&](const D3DShaderResourceAttribs& TexAttribs) + { + VERIFY_EXPR(TexAttribs.GetInputType() == D3D_SIT_TEXTURE && TexAttribs.GetSRVDimension() != D3D_SRV_DIMENSION_BUFFER); + VERIFY(CurrSampler == GetNumSamplers(), "All samplers must be initialized before texture SRVs" ); + + auto SamplerId = CombinedSamplerSuffix != nullptr ? FindAssignedSamplerId(TexAttribs, CombinedSamplerSuffix) : D3DShaderResourceAttribs::InvalidSamplerId; + auto* pNewTexSRV = new (&GetTexSRV(CurrTexSRV)) D3DShaderResourceAttribs(m_ResourceNames, TexAttribs, SamplerId); + if (SamplerId != D3DShaderResourceAttribs::InvalidSamplerId) + { + GetSampler(SamplerId).SetTexSRVId(CurrTexSRV); + } + ++CurrTexSRV; + NewResHandler.OnNewTexSRV(*pNewTexSRV); + }, + + ShdrDesc, + CombinedSamplerSuffix); + +#ifdef DEVELOPMENT + if (CombinedSamplerSuffix != nullptr) + { + for (Uint32 n=0; n < GetNumSamplers(); ++n) + { + const auto& Sampler = GetSampler(n); + if (!Sampler.ValidTexSRVAssigned()) + LOG_ERROR_MESSAGE("Shader '", ShdrDesc.Name, "' uses combined texture samplers, but sampler '", Sampler.Name, "' is not assigned to any texture"); + } + } +#endif + + VERIFY_EXPR(m_ResourceNames.GetRemainingSize() == 0); + VERIFY(CurrCB == GetNumCBs(), "Not all CBs are initialized which will cause a crash when ~D3DShaderResourceAttribs() is called"); + VERIFY(CurrTexSRV == GetNumTexSRV(), "Not all Tex SRVs are initialized which will cause a crash when ~D3DShaderResourceAttribs() is called" ); + VERIFY(CurrTexUAV == GetNumTexUAV(), "Not all Tex UAVs are initialized which will cause a crash when ~D3DShaderResourceAttribs() is called" ); + VERIFY(CurrBufSRV == GetNumBufSRV(), "Not all Buf SRVs are initialized which will cause a crash when ~D3DShaderResourceAttribs() is called" ); + VERIFY(CurrBufUAV == GetNumBufUAV(), "Not all Buf UAVs are initialized which will cause a crash when ~D3DShaderResourceAttribs() is called" ); + VERIFY(CurrSampler == GetNumSamplers(), "Not all Samplers are initialized which will cause a crash when ~D3DShaderResourceAttribs() is called" ); +} + } namespace std diff --git a/Graphics/GraphicsEngineD3DBase/src/ShaderResources.cpp b/Graphics/GraphicsEngineD3DBase/src/ShaderResources.cpp index 3ad2dc76..52fc96d9 100644 --- a/Graphics/GraphicsEngineD3DBase/src/ShaderResources.cpp +++ b/Graphics/GraphicsEngineD3DBase/src/ShaderResources.cpp @@ -51,14 +51,14 @@ ShaderResources::~ShaderResources() GetSampler(n).~D3DShaderResourceAttribs(); } -void ShaderResources::Initialize(IMemoryAllocator& Allocator, - Uint32 NumCBs, - Uint32 NumTexSRVs, - Uint32 NumTexUAVs, - Uint32 NumBufSRVs, - Uint32 NumBufUAVs, - Uint32 NumSamplers, - size_t ResourceNamesPoolSize) +void ShaderResources::AllocateMemory(IMemoryAllocator& Allocator, + Uint32 NumCBs, + Uint32 NumTexSRVs, + Uint32 NumTexUAVs, + Uint32 NumBufSRVs, + Uint32 NumBufUAVs, + Uint32 NumSamplers, + size_t ResourceNamesPoolSize) { const auto MaxOffset = static_cast<Uint32>(std::numeric_limits<OffsetType>::max()); VERIFY(NumCBs <= MaxOffset, "Max offset exceeded"); @@ -102,17 +102,16 @@ ShaderResources::ShaderResources(SHADER_TYPE ShaderType): { } -void ShaderResources::CountResources(const SHADER_VARIABLE_TYPE *AllowedVarTypes, Uint32 NumAllowedTypes, - Uint32& NumCBs, Uint32& NumTexSRVs, Uint32& NumTexUAVs, - Uint32& NumBufSRVs, Uint32& NumBufUAVs, Uint32& NumSamplers)const noexcept +void ShaderResources::CountResources(const SHADER_VARIABLE_TYPE* AllowedVarTypes, + Uint32 NumAllowedTypes, + Uint32& NumCBs, + Uint32& NumTexSRVs, + Uint32& NumTexUAVs, + Uint32& NumBufSRVs, + Uint32& NumBufUAVs, + Uint32& NumSamplers)const noexcept { - // In release mode, MS compiler generates this false warning: - // Warning C4189 'AllowedTypeBits': local variable is initialized but not referenced - // Most likely it somehow gets confused by the variable being eliminated during function inlining -#pragma warning(push) -#pragma warning(disable : 4189) - Uint32 AllowedTypeBits = GetAllowedTypeBits(AllowedVarTypes, NumAllowedTypes); -#pragma warning (pop) + auto AllowedTypeBits = GetAllowedTypeBits(AllowedVarTypes, NumAllowedTypes); NumCBs = 0; NumTexSRVs = 0; @@ -123,28 +122,34 @@ void ShaderResources::CountResources(const SHADER_VARIABLE_TYPE *AllowedVarTypes ProcessResources( AllowedVarTypes, NumAllowedTypes, - [&](const D3DShaderResourceAttribs &CB, Uint32) + [&](const D3DShaderResourceAttribs& CB, Uint32) { VERIFY_EXPR(CB.IsAllowedType(AllowedTypeBits)); ++NumCBs; }, + [&](const D3DShaderResourceAttribs& Sam, Uint32) + { + VERIFY_EXPR(Sam.IsAllowedType(AllowedTypeBits)); + // Skip static samplers + if (!Sam.IsStaticSampler()) + ++NumSamplers; + }, [&](const D3DShaderResourceAttribs& TexSRV, Uint32) { VERIFY_EXPR(TexSRV.IsAllowedType(AllowedTypeBits)); ++NumTexSRVs; - NumSamplers += TexSRV.IsValidSampler() ? 1 : 0; }, - [&](const D3DShaderResourceAttribs &TexUAV, Uint32) + [&](const D3DShaderResourceAttribs& TexUAV, Uint32) { VERIFY_EXPR(TexUAV.IsAllowedType(AllowedTypeBits)); ++NumTexUAVs; }, - [&](const D3DShaderResourceAttribs &BufSRV, Uint32) + [&](const D3DShaderResourceAttribs& BufSRV, Uint32) { VERIFY_EXPR(BufSRV.IsAllowedType(AllowedTypeBits)); ++NumBufSRVs; }, - [&](const D3DShaderResourceAttribs &BufUAV, Uint32) + [&](const D3DShaderResourceAttribs& BufUAV, Uint32) { VERIFY_EXPR(BufUAV.IsAllowedType(AllowedTypeBits)); ++NumBufUAVs; @@ -184,27 +189,32 @@ bool ShaderResources::IsCompatibleWith(const ShaderResources &Res)const ProcessResources( nullptr, 0, - [&](const D3DShaderResourceAttribs &CB, Uint32 n) + [&](const D3DShaderResourceAttribs& CB, Uint32 n) { if(!CB.IsCompatibleWith(Res.GetCB(n))) IsCompatible = false; }, + [&](const D3DShaderResourceAttribs& Sam, Uint32 n) + { + if(!Sam.IsCompatibleWith(Res.GetSampler(n))) + IsCompatible = false; + }, [&](const D3DShaderResourceAttribs& TexSRV, Uint32 n) { if(!TexSRV.IsCompatibleWith(Res.GetTexSRV(n))) IsCompatible = false; }, - [&](const D3DShaderResourceAttribs &TexUAV, Uint32 n) + [&](const D3DShaderResourceAttribs& TexUAV, Uint32 n) { if(!TexUAV.IsCompatibleWith(Res.GetTexUAV(n))) IsCompatible = false; }, - [&](const D3DShaderResourceAttribs &BufSRV, Uint32 n) + [&](const D3DShaderResourceAttribs& BufSRV, Uint32 n) { if(!BufSRV.IsCompatibleWith(Res.GetBufSRV(n))) IsCompatible = false; }, - [&](const D3DShaderResourceAttribs &BufUAV, Uint32 n) + [&](const D3DShaderResourceAttribs& BufUAV, Uint32 n) { if(!BufUAV.IsCompatibleWith(Res.GetBufUAV(n))) IsCompatible = false; @@ -218,23 +228,27 @@ size_t ShaderResources::GetHash()const size_t hash = ComputeHash(GetNumCBs(), GetNumTexSRV(), GetNumTexUAV(), GetNumBufSRV(), GetNumBufUAV()); ProcessResources( nullptr, 0, - [&](const D3DShaderResourceAttribs &CB, Uint32) + [&](const D3DShaderResourceAttribs& CB, Uint32) { HashCombine(hash, CB); }, - [&](const D3DShaderResourceAttribs &TexSRV, Uint32) + [&](const D3DShaderResourceAttribs& Sam, Uint32) + { + HashCombine(hash, Sam); + }, + [&](const D3DShaderResourceAttribs& TexSRV, Uint32) { HashCombine(hash, TexSRV); }, - [&](const D3DShaderResourceAttribs &TexUAV, Uint32) + [&](const D3DShaderResourceAttribs& TexUAV, Uint32) { HashCombine(hash, TexUAV); }, - [&](const D3DShaderResourceAttribs &BufSRV, Uint32) + [&](const D3DShaderResourceAttribs& BufSRV, Uint32) { HashCombine(hash, BufSRV); }, - [&](const D3DShaderResourceAttribs &BufUAV, Uint32) + [&](const D3DShaderResourceAttribs& BufUAV, Uint32) { HashCombine(hash, BufUAV); } |
