forked from DiligentGraphics/DiligentCore
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathPipelineResourceSignatureWebGPUImpl.hpp
More file actions
225 lines (178 loc) · 10.6 KB
/
PipelineResourceSignatureWebGPUImpl.hpp
File metadata and controls
225 lines (178 loc) · 10.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
/*
* Copyright 2023-2026 Diligent Graphics LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* In no event and under no legal theory, whether in tort (including negligence),
* contract, or otherwise, unless required by applicable law (such as deliberate
* and grossly negligent acts) or agreed to in writing, shall any Contributor be
* liable for any damages, including any direct, indirect, special, incidental,
* or consequential damages of any character arising as a result of this License or
* out of the use or inability to use the software (including but not limited to damages
* for loss of goodwill, work stoppage, computer failure or malfunction, or any and
* all other commercial damages or losses), even if such Contributor has been advised
* of the possibility of such damages.
*/
#pragma once
/// \file
/// Declaration of Diligent::PipelineResourceSignatureWebGPUImpl class
#include <array>
#include <memory>
#include "EngineWebGPUImplTraits.hpp"
#include "PipelineResourceSignatureBase.hpp"
// ShaderResourceCacheWebGPU, ShaderVariableManagerWebGPU, and ShaderResourceBindingWebGPUImpl
// are required by PipelineResourceSignatureBase
#include "ShaderResourceCacheWebGPU.hpp"
#include "ShaderVariableManagerWebGPU.hpp"
#include "ShaderResourceBindingWebGPUImpl.hpp"
#include "PipelineResourceAttribsWebGPU.hpp"
#include "WebGPUObjectWrappers.hpp"
#include "SamplerWebGPUImpl.hpp"
namespace Diligent
{
struct WGSLShaderResourceAttribs;
class DeviceContextWebGPUImpl;
class BufferWebGPUImpl;
struct ImmutableSamplerAttribsWebGPU
{
public:
Uint32 BindGroup = ~0u;
Uint32 BindingIndex = ~0u;
Uint32 CacheOffset = 0; // Offset in the SRB resource cache
Uint32 ArraySize = 1;
ImmutableSamplerAttribsWebGPU() noexcept {}
bool IsAllocated() const { return BindingIndex != ~0u; }
};
ASSERT_SIZEOF(ImmutableSamplerAttribsWebGPU, 16, "The struct is used in serialization and must be tightly packed");
/// Inline constant buffer attributes for WebGPU backend.
/// Similar to Vulkan's InlineConstantBufferAttribsVk.
struct InlineConstantBufferAttribsWebGPU
{
Uint32 BindGroup = 0; // Bind group index (similar to Vulkan's DescrSet)
Uint32 CacheOffset = 0; // Offset within bind group (similar to Vulkan's SRBCacheOffset)
Uint32 NumConstants = 0; // Number of 32-bit constants (= ResDesc.ArraySize)
// Shared dynamic UBO created in the Signature.
// All SRBs reference this same buffer to reduce memory usage.
RefCntAutoPtr<BufferWebGPUImpl> pBuffer;
};
struct PipelineResourceSignatureInternalDataWebGPU : PipelineResourceSignatureInternalData<PipelineResourceAttribsWebGPU, ImmutableSamplerAttribsWebGPU>
{
PipelineResourceSignatureInternalDataWebGPU() noexcept = default;
explicit PipelineResourceSignatureInternalDataWebGPU(const PipelineResourceSignatureInternalData& InternalData) noexcept :
PipelineResourceSignatureInternalData{InternalData}
{}
};
/// Implementation of the Diligent::PipelineResourceSignatureWebGPUImpl class
class PipelineResourceSignatureWebGPUImpl final : public PipelineResourceSignatureBase<EngineWebGPUImplTraits>
{
public:
using TPipelineResourceSignatureBase = PipelineResourceSignatureBase<EngineWebGPUImplTraits>;
using ResourceAttribs = TPipelineResourceSignatureBase::PipelineResourceAttribsType;
// Bind group identifier (this is not the bind group index in the layout!)
enum BIND_GROUP_ID : size_t
{
// Static/mutable variables bind group id
BIND_GROUP_ID_STATIC_MUTABLE = 0,
// Dynamic variables bind group id
BIND_GROUP_ID_DYNAMIC,
BIND_GROUP_ID_NUM_GROUPS
};
// Static/mutable and dynamic bind groups
static constexpr Uint32 MAX_BIND_GROUPS = BIND_GROUP_ID_NUM_GROUPS;
static_assert(ResourceAttribs::MaxBindGroups >= MAX_BIND_GROUPS, "Not enough bits to store bind group index");
PipelineResourceSignatureWebGPUImpl(IReferenceCounters* pRefCounters,
RenderDeviceWebGPUImpl* pDevice,
const PipelineResourceSignatureDesc& Desc,
SHADER_TYPE ShaderStages = SHADER_TYPE_UNKNOWN,
bool bIsDeviceInternal = false);
PipelineResourceSignatureWebGPUImpl(IReferenceCounters* pRefCounters,
RenderDeviceWebGPUImpl* pDevice,
const PipelineResourceSignatureDesc& Desc,
const PipelineResourceSignatureInternalDataWebGPU& InternalData);
~PipelineResourceSignatureWebGPUImpl();
Uint32 GetNumBindGroups() const
{
static_assert(BIND_GROUP_ID_NUM_GROUPS == 2, "Please update this method with new bind group id");
return (HasBindGroup(BIND_GROUP_ID_STATIC_MUTABLE) ? 1 : 0) + (HasBindGroup(BIND_GROUP_ID_DYNAMIC) ? 1 : 0);
}
WGPUBindGroupLayout GetWGPUBindGroupLayout(BIND_GROUP_ID GroupId);
bool HasBindGroup(BIND_GROUP_ID GroupId) const { return m_BindGroupSizes[GroupId] != ~0u && m_BindGroupSizes[GroupId] > 0; }
Uint32 GetBindGroupSize(BIND_GROUP_ID GroupId) const { return m_BindGroupSizes[GroupId]; }
Uint32 GetDynamicOffsetCount(BIND_GROUP_ID GroupId) const { return m_DynamicOffsetCounts[GroupId]; }
Uint32 GetDynamicUniformBufferCount() const { return m_DynamicUniformBufferCount; }
Uint32 GetDynamicStorageBufferCount() const { return m_DynamicStorageBufferCount; }
void InitSRBResourceCache(ShaderResourceCacheWebGPU& ResourceCache);
void CopyStaticResources(ShaderResourceCacheWebGPU& ResourceCache) const;
// Make the base class method visible
using TPipelineResourceSignatureBase::CopyStaticResources;
// Updates inline constant buffers before draw/dispatch.
// Must be called when SRB is stale or DRAW_FLAG_INLINE_CONSTANTS_INTACT is not set.
void UpdateInlineConstantBuffers(const ShaderResourceCacheWebGPU& ResourceCache,
DeviceContextWebGPUImpl* pCtx) const;
// Returns the bind group index in the resource cache
template <BIND_GROUP_ID GroupId>
Uint32 GetBindGroupIndex() const;
#ifdef DILIGENT_DEVELOPMENT
/// Verifies committed resource using the WGSL resource attributes from the PSO.
bool DvpValidateCommittedResource(const DeviceContextWebGPUImpl* pDeviceCtx,
const WGSLShaderResourceAttribs& WGSLAttribs,
Uint32 ResIndex,
const ShaderResourceCacheWebGPU& ResourceCache,
const char* ShaderName,
const char* PSOName) const;
bool DvpValidateImmutableSampler(const WGSLShaderResourceAttribs& WGSLAttribs,
Uint32 ImtblSamIndex,
const ShaderResourceCacheWebGPU& ResourceCache,
const char* ShaderName,
const char* PSOName) const;
#endif
private:
void CreateBindGroupLayouts(bool IsSerialized);
// Resource cache group identifier
enum CACHE_GROUP : size_t
{
CACHE_GROUP_DYN_UB = 0, // Uniform buffer with dynamic offset
CACHE_GROUP_DYN_SB, // Storage buffer with dynamic offset
CACHE_GROUP_OTHER, // Other resource type
CACHE_GROUP_COUNT_PER_VAR_TYPE, // Cache group count per shader variable type
CACHE_GROUP_DYN_UB_STAT_VAR = CACHE_GROUP_DYN_UB, // Uniform buffer with dynamic offset, static variable
CACHE_GROUP_DYN_SB_STAT_VAR = CACHE_GROUP_DYN_SB, // Storage buffer with dynamic offset, static variable
CACHE_GROUP_OTHER_STAT_VAR = CACHE_GROUP_OTHER, // Other resource type, static variable
CACHE_GROUP_DYN_UB_DYN_VAR, // Uniform buffer with dynamic offset, dynamic variable
CACHE_GROUP_DYN_SB_DYN_VAR, // Storage buffer with dynamic offset, dynamic variable
CACHE_GROUP_OTHER_DYN_VAR, // Other resource type, dynamic variable
CACHE_GROUP_COUNT
};
static_assert(CACHE_GROUP_COUNT == CACHE_GROUP_COUNT_PER_VAR_TYPE * MAX_BIND_GROUPS, "Inconsistent cache group count");
using CacheOffsetsType = std::array<Uint32, CACHE_GROUP_COUNT>; // [Dynamic UBs, Dynamic SBs, Other] x [bind group]
using BindingCountType = std::array<Uint32, CACHE_GROUP_COUNT>; // [Dynamic UBs, Dynamic SBs, Other] x [bind group]
static inline CACHE_GROUP GetResourceCacheGroup(const PipelineResourceDesc& Res);
static inline BIND_GROUP_ID VarTypeToBindGroupId(SHADER_RESOURCE_VARIABLE_TYPE VarType);
private:
struct WGPUBindGroupLayoutsCreateInfo;
std::unique_ptr<WGPUBindGroupLayoutsCreateInfo> m_BindGroupLayoutsCreateInfo;
std::array<WebGPUBindGroupLayoutWrapper, BIND_GROUP_ID_NUM_GROUPS> m_wgpuBindGroupLayouts;
// Bind group sizes indexed by the group index in the layout (not BIND_GROUP_ID!)
std::array<Uint32, MAX_BIND_GROUPS> m_BindGroupSizes = {~0U, ~0U};
// The total number of uniform and storage buffers with dynamic offsets in each bind group.
std::array<Uint32, MAX_BIND_GROUPS> m_DynamicOffsetCounts = {0, 0};
// The total number of uniform buffers with dynamic offsets in both bind groups,
// accounting for array size.
Uint16 m_DynamicUniformBufferCount = 0;
// The total number storage buffers with dynamic offsets in both bind groups,
// accounting for array size.
Uint16 m_DynamicStorageBufferCount = 0;
};
template <> Uint32 PipelineResourceSignatureWebGPUImpl::GetBindGroupIndex<PipelineResourceSignatureWebGPUImpl::BIND_GROUP_ID_STATIC_MUTABLE>() const;
template <> Uint32 PipelineResourceSignatureWebGPUImpl::GetBindGroupIndex<PipelineResourceSignatureWebGPUImpl::BIND_GROUP_ID_DYNAMIC>() const;
} // namespace Diligent