summaryrefslogtreecommitdiffstats
path: root/Graphics/GraphicsEngineD3DBase
diff options
context:
space:
mode:
authorEgor Yusov <egor.yusov@gmail.com>2018-10-17 16:26:27 +0000
committerEgor Yusov <egor.yusov@gmail.com>2018-10-17 16:26:27 +0000
commit435f70be7aebd9a669d6a276df67e8eb814a45e3 (patch)
tree040377c1ac3201fef75c01e9e3535a172babbcb1 /Graphics/GraphicsEngineD3DBase
parentImproved StrCmpSuff() to allow optional suffix (diff)
downloadDiligentCore-435f70be7aebd9a669d6a276df67e8eb814a45e3.tar.gz
DiligentCore-435f70be7aebd9a669d6a276df67e8eb814a45e3.zip
Implemented separate samplers in D3D11
Diffstat (limited to 'Graphics/GraphicsEngineD3DBase')
-rw-r--r--Graphics/GraphicsEngineD3DBase/include/D3DShaderResourceLoader.h36
-rw-r--r--Graphics/GraphicsEngineD3DBase/include/ShaderResources.h293
-rw-r--r--Graphics/GraphicsEngineD3DBase/src/ShaderResources.cpp78
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);
}