57 #include <d3dcommon.h> 60 #include "STDAllocator.h" 65 static const Char* D3DSamplerSuffix =
"_sampler";
69 return ((1 << VarType) & AllowedTypeBits) != 0;
74 if(AllowedVarTypes ==
nullptr)
77 Uint32 AllowedTypeBits = 0;
78 for(
Uint32 i=0; i < NumAllowedTypes; ++i)
79 AllowedTypeBits |= 1 << AllowedVarTypes[i];
80 return AllowedTypeBits;
84 struct D3DShaderResourceAttribs
86 D3DShaderResourceAttribs(
String &&_Name,
89 D3D_SHADER_INPUT_TYPE _InputType,
91 D3D_SRV_DIMENSION SRVDimension,
93 bool _IsStaticSampler) :
94 Name(
std::move(_Name)),
95 BindPoint(static_cast<
Uint16>(_BindPoint)),
96 BindCount(static_cast<
Uint16>(_BindCount)),
97 PackedAttribs( PackAttribs(_InputType, _VariableType, SRVDimension, SamplerId, _IsStaticSampler) )
99 VERIFY( static_cast<Uint32>(_InputType) <= ShaderInputTypeMask,
"Shader input type is out of expected range");
100 VERIFY( static_cast<Uint32>(_VariableType) <= VariableTypeMask,
"Variable type is out of expected range");
101 VERIFY( static_cast<Uint32>(SRVDimension) <= SRVDimMask,
"SRV dimensions is out of expected range");
102 VERIFY(SamplerId <= SamplerIdMask,
"Sampler Id is out of allowed range" );
103 VERIFY_EXPR(GetInputType() == _InputType);
104 VERIFY_EXPR(GetVariableType() == _VariableType);
105 VERIFY(_BindPoint <= MaxBindPoint || _BindPoint == InvalidBindPoint,
"Bind Point is out of allowed range" );
106 VERIFY(_BindCount <= MaxBindCount,
"Bind Count is out of allowed range" );
108 if(_InputType==D3D_SIT_SAMPLER)
110 VERIFY_EXPR(IsStaticSampler() == _IsStaticSampler);
114 VERIFY(!_IsStaticSampler,
"Only samplers can be marked as static");
117 if (_InputType == D3D_SIT_TEXTURE)
119 VERIFY_EXPR(GetSamplerId() == SamplerId);
123 VERIFY(SamplerId == InvalidSamplerId,
"Only textures can be assigned valid texture sampler");
128 VERIFY( _InputType == D3D_SIT_SAMPLER,
"Invalid input type: D3D_SIT_SAMPLER is expected" );
133 D3DShaderResourceAttribs(
const D3DShaderResourceAttribs& rhs) =
default;
135 D3DShaderResourceAttribs(
const D3DShaderResourceAttribs& rhs,
Uint32 SamplerId)noexcept :
137 BindPoint(rhs.BindPoint),
138 BindCount(rhs.BindCount),
139 PackedAttribs( PackAttribs(rhs.GetInputType(), rhs.GetVariableType(), rhs.GetSRVDimension(), SamplerId,
false) )
141 VERIFY(GetInputType() == D3D_SIT_TEXTURE,
"Only textures can be assigned a texture sampler");
143 VERIFY_EXPR(GetInputType() == rhs.GetInputType());
144 VERIFY_EXPR(GetVariableType() == rhs.GetVariableType());
145 VERIFY_EXPR(GetSamplerId() == SamplerId);
148 D3DShaderResourceAttribs(D3DShaderResourceAttribs&& rhs,
Uint32 SamplerId)noexcept :
149 Name(std::move(rhs.Name)),
150 BindPoint(rhs.BindPoint),
151 BindCount(rhs.BindCount),
152 PackedAttribs( PackAttribs(rhs.GetInputType(), rhs.GetVariableType(), rhs.GetSRVDimension(), SamplerId,
false) )
154 VERIFY(GetInputType() == D3D_SIT_TEXTURE,
"Only textures can be assigned a texture sampler");
156 VERIFY_EXPR(GetInputType() == rhs.GetInputType());
157 VERIFY_EXPR(GetVariableType() == rhs.GetVariableType());
158 VERIFY_EXPR(GetSamplerId() == SamplerId);
161 D3DShaderResourceAttribs(D3DShaderResourceAttribs&& rhs)noexcept :
162 Name(std::move(rhs.Name)),
163 BindPoint(rhs.BindPoint),
164 BindCount(rhs.BindCount),
165 PackedAttribs( rhs.PackedAttribs )
169 D3D_SHADER_INPUT_TYPE GetInputType()
const 171 return static_cast<D3D_SHADER_INPUT_TYPE
>( (PackedAttribs >> ShaderInputTypeBitOffset) & ShaderInputTypeMask );
176 return static_cast<SHADER_VARIABLE_TYPE>( (PackedAttribs >> VariableTypeBitOffset) & VariableTypeMask );
179 D3D_SRV_DIMENSION GetSRVDimension()
const 181 return static_cast<D3D_SRV_DIMENSION
>( (PackedAttribs >> SRVDimBitOffset) & SRVDimMask );
184 Uint32 GetSamplerId()
const 186 VERIFY( GetInputType() == D3D_SIT_TEXTURE,
"Invalid input type: D3D_SIT_TEXTURE is expected" );
187 return (PackedAttribs >> SamplerIdBitOffset) & SamplerIdMask;
190 bool IsStaticSampler()
const 192 VERIFY( GetInputType() == D3D_SIT_SAMPLER,
"Invalid input type: D3D_SIT_SAMPLER is expected" );
193 return (PackedAttribs & (1 << IsStaticSamplerFlagBitOffset)) != 0;
196 bool IsValidSampler()
const 198 VERIFY( GetInputType() == D3D_SIT_TEXTURE,
"Invalid input type: D3D_SIT_TEXTURE is expected" );
199 return GetSamplerId() != InvalidSamplerId;
202 bool IsValidBindPoint()
const 204 return BindPoint != InvalidBindPoint;
207 static constexpr
Uint16 InvalidBindPoint = std::numeric_limits<Uint16>::max();
215 VERIFY_EXPR(ArrayInd < BindCount);
217 return String(Name) +
'[' + std::to_string(ArrayInd) +
']';
222 static constexpr
Uint16 MaxBindPoint = InvalidBindPoint-1;
223 static constexpr
Uint16 MaxBindCount = std::numeric_limits<Uint16>::max();
225 static constexpr
Uint32 ShaderInputTypeBits = 4;
226 static constexpr
Uint32 ShaderInputTypeMask = (1 << ShaderInputTypeBits)-1;
227 static constexpr
Uint32 ShaderInputTypeBitOffset = 0;
228 static_assert( D3D_SIT_UAV_RWSTRUCTURED_WITH_COUNTER <= ShaderInputTypeMask,
"Not enough bits to represent D3D_SHADER_INPUT_TYPE" );
230 static constexpr
Uint32 VariableTypeBits = 3;
231 static constexpr
Uint32 VariableTypeMask = (1<<VariableTypeBits)-1;
232 static constexpr
Uint32 VariableTypeBitOffset = ShaderInputTypeBitOffset + ShaderInputTypeBits;
235 static constexpr
Uint32 SRVDimBits = 4;
236 static constexpr
Uint32 SRVDimMask = (1<<SRVDimBits)-1;
237 static constexpr
Uint32 SRVDimBitOffset = VariableTypeBitOffset + VariableTypeBits;
238 static_assert( D3D_SRV_DIMENSION_BUFFEREX <= SRVDimMask,
"Not enough bits to represent D3D_SRV_DIMENSION" );
240 static constexpr
Uint32 SamplerIdBits = 32 - 1 - ShaderInputTypeBits - VariableTypeBits - SRVDimBits;
241 static constexpr
Uint32 SamplerIdMask = (1 << SamplerIdBits) - 1;
242 static constexpr
Uint32 SamplerIdBitOffset = SRVDimBitOffset + SRVDimBits;
244 static constexpr
Uint32 InvalidSamplerId = SamplerIdMask;
247 static constexpr
Uint32 IsStaticSamplerFlagBits = 1;
248 static constexpr
Uint32 IsStaticSamplerFlagMask = (1 << IsStaticSamplerFlagBits) - 1;
249 static constexpr
Uint32 IsStaticSamplerFlagBitOffset = SamplerIdBitOffset + SamplerIdBits;
250 static_assert(IsStaticSamplerFlagBitOffset == 31,
"Unexpected static sampler flag offset");
252 static Uint32 PackAttribs(D3D_SHADER_INPUT_TYPE _InputType,
SHADER_VARIABLE_TYPE _VariableType, D3D_SRV_DIMENSION SRVDimension,
Uint32 SamplerId,
bool _IsStaticSampler)
254 return ((static_cast<Uint32>(_InputType) & ShaderInputTypeMask) << ShaderInputTypeBitOffset) |
255 ((
static_cast<Uint32>(_VariableType) & VariableTypeMask) << VariableTypeBitOffset ) |
256 ((static_cast<Uint32>(SRVDimension) & SRVDimMask) << SRVDimBitOffset) |
257 ((SamplerId & SamplerIdMask) << SamplerIdBitOffset) |
258 ((_IsStaticSampler ? 1 : 0) << IsStaticSamplerFlagBitOffset);
265 const Uint32 PackedAttribs;
289 Uint32 GetNumCBs()
const noexcept{
return (m_TexSRVOffset - 0); }
290 Uint32 GetNumTexSRV()
const noexcept{
return (m_TexUAVOffset - m_TexSRVOffset); }
291 Uint32 GetNumTexUAV()
const noexcept{
return (m_BufSRVOffset - m_TexUAVOffset); }
292 Uint32 GetNumBufSRV()
const noexcept{
return (m_BufUAVOffset - m_BufSRVOffset); }
293 Uint32 GetNumBufUAV()
const noexcept{
return (m_SamplersOffset - m_BufUAVOffset); }
294 Uint32 GetNumSamplers()
const noexcept{
return (m_BufferEndOffset- m_SamplersOffset); }
296 const D3DShaderResourceAttribs& GetCB (
Uint32 n)
const noexcept{
return GetResAttribs(n, GetNumCBs(), 0); }
297 const D3DShaderResourceAttribs& GetTexSRV (
Uint32 n)
const noexcept{
return GetResAttribs(n, GetNumTexSRV(), m_TexSRVOffset); }
298 const D3DShaderResourceAttribs& GetTexUAV (
Uint32 n)
const noexcept{
return GetResAttribs(n, GetNumTexUAV(), m_TexUAVOffset); }
299 const D3DShaderResourceAttribs& GetBufSRV (
Uint32 n)
const noexcept{
return GetResAttribs(n, GetNumBufSRV(), m_BufSRVOffset); }
300 const D3DShaderResourceAttribs& GetBufUAV (
Uint32 n)
const noexcept{
return GetResAttribs(n, GetNumBufUAV(), m_BufUAVOffset); }
301 const D3DShaderResourceAttribs& GetSampler(
Uint32 n)
const noexcept{
return GetResAttribs(n, GetNumSamplers(), m_SamplersOffset); }
308 SHADER_TYPE GetShaderType()
const noexcept{
return m_ShaderType;}
311 template<
typename THandleCB,
312 typename THandleTexSRV,
313 typename THandleTexUAV,
314 typename THandleBufSRV,
315 typename THandleBufUAV>
319 THandleTexSRV HandleTexSRV,
320 THandleTexUAV HandleTexUAV,
321 THandleBufSRV HandleBufSRV,
322 THandleBufUAV HandleBufUAV)
const 324 Uint32 AllowedTypeBits = GetAllowedTypeBits(AllowedVarTypes, NumAllowedTypes);
326 for(
Uint32 n=0; n < GetNumCBs(); ++n)
328 const auto& CB = GetCB(n);
329 if( IsAllowedType(CB.GetVariableType(), AllowedTypeBits) )
333 for(
Uint32 n=0; n < GetNumTexSRV(); ++n)
335 const auto &TexSRV = GetTexSRV(n);
336 if( IsAllowedType(TexSRV.GetVariableType(), AllowedTypeBits) )
337 HandleTexSRV(TexSRV);
340 for(
Uint32 n=0; n < GetNumTexUAV(); ++n)
342 const auto &TexUAV = GetTexUAV(n);
343 if( IsAllowedType(TexUAV.GetVariableType(), AllowedTypeBits) )
344 HandleTexUAV(TexUAV);
347 for(
Uint32 n=0; n < GetNumBufSRV(); ++n)
349 const auto &BufSRV = GetBufSRV(n);
350 if( IsAllowedType(BufSRV.GetVariableType(), AllowedTypeBits) )
351 HandleBufSRV(BufSRV);
354 for(
Uint32 n=0; n < GetNumBufUAV(); ++n)
356 const auto& BufUAV = GetBufUAV(n);
357 if( IsAllowedType(BufUAV.GetVariableType(), AllowedTypeBits) )
358 HandleBufUAV(BufUAV);
365 __forceinline D3DShaderResourceAttribs& GetResAttribs(
Uint32 n,
Uint32 NumResources,
Uint32 Offset)noexcept
367 VERIFY(n < NumResources,
"Resource index (", n,
") is out of range. Max allowed index: ", NumResources-1);
368 VERIFY_EXPR(Offset + n < m_BufferEndOffset);
369 return reinterpret_cast<D3DShaderResourceAttribs*
>(m_MemoryBuffer.get())[Offset + n];
372 __forceinline
const D3DShaderResourceAttribs& GetResAttribs(
Uint32 n,
Uint32 NumResources,
Uint32 Offset)
const noexcept
374 VERIFY(n < NumResources,
"Resource index (", n,
") is out of range. Max allowed index: ", NumResources-1);
375 VERIFY_EXPR(Offset + n < m_BufferEndOffset);
376 return reinterpret_cast<D3DShaderResourceAttribs*
>(m_MemoryBuffer.get())[Offset + n];
379 D3DShaderResourceAttribs& GetCB (
Uint32 n)noexcept{
return GetResAttribs(n, GetNumCBs(), 0); }
380 D3DShaderResourceAttribs& GetTexSRV (
Uint32 n)noexcept{
return GetResAttribs(n, GetNumTexSRV(), m_TexSRVOffset); }
381 D3DShaderResourceAttribs& GetTexUAV (
Uint32 n)noexcept{
return GetResAttribs(n, GetNumTexUAV(), m_TexUAVOffset); }
382 D3DShaderResourceAttribs& GetBufSRV (
Uint32 n)noexcept{
return GetResAttribs(n, GetNumBufSRV(), m_BufSRVOffset); }
383 D3DShaderResourceAttribs& GetBufUAV (
Uint32 n)noexcept{
return GetResAttribs(n, GetNumBufUAV(), m_BufUAVOffset); }
384 D3DShaderResourceAttribs& GetSampler(
Uint32 n)noexcept{
return GetResAttribs(n, GetNumSamplers(), m_SamplersOffset); }
386 Uint32 FindAssignedSamplerId(
const D3DShaderResourceAttribs& TexSRV)
const;
391 std::unique_ptr< void, STDDeleterRawMem<void> > m_MemoryBuffer;
394 typedef Uint16 OffsetType;
395 OffsetType m_TexSRVOffset = 0;
396 OffsetType m_TexUAVOffset = 0;
397 OffsetType m_BufSRVOffset = 0;
398 OffsetType m_BufUAVOffset = 0;
399 OffsetType m_SamplersOffset = 0;
400 OffsetType m_BufferEndOffset = 0;
SHADER_TYPE
Describes the shader type.
Definition: Shader.h:46
Graphics engine namespace.
Definition: AdaptiveFixedBlockAllocator.h:30
Definition: AdvancedMath.h:316
Diligent::ShaderResources class.
Definition: ShaderResources.h:270
Base interface for a raw memory allocator.
Definition: MemoryAllocator.h:35
SHADER_VARIABLE_TYPE
Describes shader variable type that is used by ShaderVariableDesc.
Definition: Shader.h:100
std::basic_string< Char > String
String variable.
Definition: BasicTypes.h:51
Unknown shader type.
Definition: Shader.h:48
uint16_t Uint16
16-bit unsigned integer
Definition: BasicTypes.h:40
uint32_t Uint32
32-bit unsigned integer
Definition: BasicTypes.h:39
Total number of shader variable types.
Definition: Shader.h:117