Skip to content

Commit 82963fe

Browse files
jiangzhaomingDawn LUCI CQ
authored andcommitted
Dawn: Make shader module reflection serializable
This CL make shader module reflection data, i.e. EntryPointMetadataTable serializable, so we can cache it into on-disk blob cache. With this CL it is possible to create a shader module with reflection data but without calling Tint at all. This CL also make macro DAWN_SERIALIZABLE to generate default equality comparison for the serializable struct, and also add default equality comparison operator in necessary structs to achieve that. Bug: 402772740, 42240459 Change-Id: Icf7b2d3d2e1fa427f2bd9e1db4f6410ff842c08c Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/241494 Reviewed-by: Geoff Lang <geofflang@chromium.org> Commit-Queue: Zhaoming Jiang <zhaoming.jiang@microsoft.com>
1 parent 37c8193 commit 82963fe

File tree

15 files changed

+265
-230
lines changed

15 files changed

+265
-230
lines changed

src/dawn/native/BindGroupLayoutInternal.cpp

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -379,12 +379,11 @@ BindingInfo CreateSampledTextureBindingForExternalTexture(BindingNumber binding,
379379
return {
380380
.binding = binding,
381381
.visibility = visibility,
382-
.bindingLayout =
383-
TextureBindingInfo{
384-
.sampleType = wgpu::TextureSampleType::Float,
385-
.viewDimension = wgpu::TextureViewDimension::e2D,
386-
.multisampled = false,
387-
},
382+
.bindingLayout = TextureBindingInfo{{
383+
.sampleType = wgpu::TextureSampleType::Float,
384+
.viewDimension = wgpu::TextureViewDimension::e2D,
385+
.multisampled = false,
386+
}},
388387
};
389388
}
390389

@@ -393,12 +392,11 @@ BindingInfo CreateUniformBindingForExternalTexture(BindingNumber binding,
393392
return {
394393
.binding = binding,
395394
.visibility = visibility,
396-
.bindingLayout =
397-
BufferBindingInfo{
398-
.type = wgpu::BufferBindingType::Uniform,
399-
.minBindingSize = 0,
400-
.hasDynamicOffset = false,
401-
},
395+
.bindingLayout = BufferBindingInfo{{
396+
.type = wgpu::BufferBindingType::Uniform,
397+
.minBindingSize = 0,
398+
.hasDynamicOffset = false,
399+
}},
402400
};
403401
}
404402

@@ -414,7 +412,7 @@ BindingInfo ConvertToBindingInfoNoArray(const UnpackedPtr<BindGroupLayoutEntry>&
414412
} else if (binding->texture.sampleType != wgpu::TextureSampleType::BindingNotUsed) {
415413
auto textureBindingInfo = TextureBindingInfo::From(binding->texture);
416414
if (binding->texture.viewDimension == kInternalInputAttachmentDim) {
417-
bindingInfo.bindingLayout = InputAttachmentBindingInfo{textureBindingInfo.sampleType};
415+
bindingInfo.bindingLayout = InputAttachmentBindingInfo{{textureBindingInfo.sampleType}};
418416
} else {
419417
bindingInfo.bindingLayout = textureBindingInfo;
420418
}

src/dawn/native/BindingInfo.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -302,23 +302,23 @@ MaybeError ValidateBindingCounts(const CombinedLimits& limits,
302302
// static
303303
BufferBindingInfo BufferBindingInfo::From(const BufferBindingLayout& layout) {
304304
BufferBindingLayout defaultedLayout = layout.WithTrivialFrontendDefaults();
305-
return {
305+
return {{
306306
.type = defaultedLayout.type,
307307
.minBindingSize = defaultedLayout.minBindingSize,
308308
.hasDynamicOffset = defaultedLayout.hasDynamicOffset,
309-
};
309+
}};
310310
}
311311

312312
// TextureBindingInfo
313313

314314
// static
315315
TextureBindingInfo TextureBindingInfo::From(const TextureBindingLayout& layout) {
316316
TextureBindingLayout defaultedLayout = layout.WithTrivialFrontendDefaults();
317-
return {
317+
return {{
318318
.sampleType = defaultedLayout.sampleType,
319319
.viewDimension = defaultedLayout.viewDimension,
320320
.multisampled = defaultedLayout.multisampled,
321-
};
321+
}};
322322
}
323323

324324
// StorageTextureBindingInfo
@@ -327,21 +327,21 @@ TextureBindingInfo TextureBindingInfo::From(const TextureBindingLayout& layout)
327327
StorageTextureBindingInfo StorageTextureBindingInfo::From(
328328
const StorageTextureBindingLayout& layout) {
329329
StorageTextureBindingLayout defaultedLayout = layout.WithTrivialFrontendDefaults();
330-
return {
330+
return {{
331331
.format = defaultedLayout.format,
332332
.viewDimension = defaultedLayout.viewDimension,
333333
.access = defaultedLayout.access,
334-
};
334+
}};
335335
}
336336

337337
// SamplerBindingInfo
338338

339339
// static
340340
SamplerBindingInfo SamplerBindingInfo::From(const SamplerBindingLayout& layout) {
341341
SamplerBindingLayout defaultedLayout = layout.WithTrivialFrontendDefaults();
342-
return {
342+
return {{
343343
.type = defaultedLayout.type,
344-
};
344+
}};
345345
}
346346

347347
// SamplerBindingInfo

src/dawn/native/BindingInfo.h

Lines changed: 42 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
#include "dawn/native/Format.h"
4040
#include "dawn/native/IntegerTypes.h"
4141
#include "dawn/native/PerStage.h"
42+
#include "dawn/native/Serializable.h"
4243

4344
#include "dawn/native/dawn_platform.h"
4445

@@ -69,51 +70,57 @@ enum class BindingInfoType {
6970
};
7071

7172
// A mirror of wgpu::BufferBindingLayout for use inside dawn::native.
72-
struct BufferBindingInfo {
73+
#define BUFFER_BINDING_INFO_MEMBER(X) \
74+
X(wgpu::BufferBindingType, type) \
75+
X(uint64_t, minBindingSize) \
76+
/* hasDynamicOffset is always false in shader reflection */ \
77+
X(bool, hasDynamicOffset)
78+
DAWN_SERIALIZABLE(struct, BufferBindingInfo, BUFFER_BINDING_INFO_MEMBER) {
7379
static BufferBindingInfo From(const BufferBindingLayout& layout);
74-
75-
wgpu::BufferBindingType type;
76-
uint64_t minBindingSize;
77-
78-
// Always false in shader reflection.
79-
bool hasDynamicOffset = false;
80-
81-
bool operator==(const BufferBindingInfo& other) const = default;
8280
};
81+
#undef BUFFER_BINDING_INFO_MEMBER
8382

8483
// A mirror of wgpu::TextureBindingLayout for use inside dawn::native.
85-
struct TextureBindingInfo {
84+
#define TEXTURE_BINDING_INFO_MEMBER(X) \
85+
/* For shader reflection UnfilterableFloat is never used and the sample type is Float */ \
86+
/* for any texture_Nd<f32>. */ \
87+
X(wgpu::TextureSampleType, sampleType) \
88+
X(wgpu::TextureViewDimension, viewDimension) \
89+
X(bool, multisampled)
90+
DAWN_SERIALIZABLE(struct, TextureBindingInfo, TEXTURE_BINDING_INFO_MEMBER) {
8691
static TextureBindingInfo From(const TextureBindingLayout& layout);
87-
88-
// For shader reflection UnfilterableFloat is never used and the sample type is Float for any
89-
// texture_Nd<f32>.
90-
wgpu::TextureSampleType sampleType;
91-
wgpu::TextureViewDimension viewDimension;
92-
bool multisampled;
93-
94-
bool operator==(const TextureBindingInfo& other) const = default;
9592
};
93+
#undef TEXTURE_BINDING_INFO_MEMBER
9694

9795
// A mirror of wgpu::StorageTextureBindingLayout for use inside dawn::native.
98-
struct StorageTextureBindingInfo {
96+
#define STORAGE_TEXTURE_BINDING_INFO_MEMBER(X) \
97+
X(wgpu::TextureFormat, format) \
98+
X(wgpu::TextureViewDimension, viewDimension) \
99+
X(wgpu::StorageTextureAccess, access)
100+
DAWN_SERIALIZABLE(struct, StorageTextureBindingInfo, STORAGE_TEXTURE_BINDING_INFO_MEMBER) {
99101
static StorageTextureBindingInfo From(const StorageTextureBindingLayout& layout);
100-
101-
wgpu::TextureFormat format;
102-
wgpu::TextureViewDimension viewDimension;
103-
wgpu::StorageTextureAccess access;
104-
105-
bool operator==(const StorageTextureBindingInfo& other) const = default;
106102
};
103+
#undef STORAGE_TEXTURE_BINDING_INFO_MEMBER
107104

108105
// A mirror of wgpu::SamplerBindingLayout for use inside dawn::native.
109-
struct SamplerBindingInfo {
106+
#define SAMPLER_BINDING_INFO_MEMBER(X) \
107+
/* For shader reflection NonFiltering is never used and Filtering is used for */ \
108+
/* any `sampler`. */ \
109+
X(wgpu::SamplerBindingType, type)
110+
DAWN_SERIALIZABLE(struct, SamplerBindingInfo, SAMPLER_BINDING_INFO_MEMBER) {
110111
static SamplerBindingInfo From(const SamplerBindingLayout& layout);
112+
};
113+
#undef SAMPLER_BINDING_INFO_MEMBER
111114

112-
// For shader reflection NonFiltering is never used and Filtering is used for any `sampler`.
113-
wgpu::SamplerBindingType type;
115+
// A mirror of wgpu::ExternalTextureBindingLayout for use inside dawn::native.
116+
#define EXTERNAL_TEXTURE_BINDING_INFO_MEMBER(X) // ExternalTextureBindingInfo has no member
117+
DAWN_SERIALIZABLE(struct, ExternalTextureBindingInfo, EXTERNAL_TEXTURE_BINDING_INFO_MEMBER){};
118+
#undef EXTERNAL_TEXTURE_BINDING_INFO_MEMBER
114119

115-
bool operator==(const SamplerBindingInfo& other) const = default;
116-
};
120+
// Internal to vulkan only.
121+
#define INPUT_ATTACHMENT_BINDING_INFO_MEMBER(X) X(wgpu::TextureSampleType, sampleType)
122+
DAWN_SERIALIZABLE(struct, InputAttachmentBindingInfo, INPUT_ATTACHMENT_BINDING_INFO_MEMBER){};
123+
#undef INPUT_ATTACHMENT_BINDING_INFO_MEMBER
117124

118125
// A mirror of wgpu::StaticSamplerBindingLayout for use inside dawn::native.
119126
struct StaticSamplerBindingInfo {
@@ -130,18 +137,6 @@ struct StaticSamplerBindingInfo {
130137
bool operator==(const StaticSamplerBindingInfo& other) const = default;
131138
};
132139

133-
// A mirror of wgpu::ExternalTextureBindingLayout for use inside dawn::native.
134-
struct ExternalTextureBindingInfo {
135-
bool operator==(const ExternalTextureBindingInfo& other) const = default;
136-
};
137-
138-
// Internal to vulkan only.
139-
struct InputAttachmentBindingInfo {
140-
wgpu::TextureSampleType sampleType;
141-
142-
bool operator==(const InputAttachmentBindingInfo& other) const = default;
143-
};
144-
145140
struct BindingInfo {
146141
BindingNumber binding;
147142
wgpu::ShaderStage visibility;
@@ -165,12 +160,11 @@ struct BindingInfo {
165160
BindingInfoType GetBindingInfoType(const BindingInfo& bindingInfo);
166161

167162
// Match tint::BindingPoint, can convert to/from tint::BindingPoint using ToTint and FromTint.
168-
struct BindingSlot {
169-
BindGroupIndex group;
170-
BindingNumber binding;
171-
172-
constexpr bool operator==(const BindingSlot& rhs) const = default;
173-
};
163+
#define BINDING_SLOT_MEMBER(X) \
164+
X(BindGroupIndex, group) \
165+
X(BindingNumber, binding)
166+
DAWN_SERIALIZABLE(struct, BindingSlot, BINDING_SLOT_MEMBER){};
167+
#undef BINDING_SLOT_MEMBER
174168

175169
struct PerStageBindingCounts {
176170
uint32_t sampledTextureCount;

src/dawn/native/Blob.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,13 @@ size_t Blob::Size() const {
9797
return mSize;
9898
}
9999

100+
bool Blob::operator==(const Blob& other) const {
101+
if (other.Size() != Size()) {
102+
return false;
103+
}
104+
return 0 == memcmp(Data(), other.Data(), Size());
105+
}
106+
100107
template <>
101108
void stream::Stream<Blob>::Write(stream::Sink* s, const Blob& b) {
102109
size_t size = b.Size();

src/dawn/native/Blob.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ class Blob {
6161
uint8_t* Data();
6262
size_t Size() const;
6363

64+
bool operator==(const Blob& other) const;
65+
6466
private:
6567
// The constructor should be responsible to take ownership of |data| and releases ownership by
6668
// calling |deleter|. The deleter function is called at ~Blob() and during std::move.

src/dawn/native/CacheKey.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,10 @@ class CacheKey : public stream::ByteVectorSink {
5454
// stream::StreamIn<T>.
5555
friend constexpr void StreamIn(stream::Sink*, const UnsafeUnkeyedValue&) {}
5656

57+
// Enabling DAWN_SERIALIZABLE classes with UnsafeUnkeyedValue member to use default equality
58+
// operator. Equality comparison always returns true for the same type UnsafeUnkeyedValues.
59+
bool operator==(const UnsafeUnkeyedValue<T>& other) const { return true; }
60+
5761
private:
5862
T mValue;
5963
};

src/dawn/native/Limits.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ CombinedLimits ApplyLimitTiers(const CombinedLimits& limits);
8585
struct LimitsForCompilationRequest {
8686
static LimitsForCompilationRequest Create(const Limits& limits);
8787
DAWN_VISITABLE_MEMBERS(LIMITS_FOR_COMPILATION_REQUEST_MEMBERS)
88+
bool operator==(const LimitsForCompilationRequest& other) const = default;
8889
};
8990

9091
// Enforce restriction for limit values, including:

src/dawn/native/Serializable.h

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,8 @@ class Serializable {
6767

6868
// Helper macro to define a struct or class along with VisitAll methods to call
6969
// a functor on all members. Derives from Visitable which provides
70-
// implementations of StreamIn/StreamOut/FromBlob/ToBlob.
71-
// Example usage:
70+
// implementations of StreamIn/StreamOut/FromBlob/ToBlob, and provides a default equality
71+
// comparison. Example usage:
7272
// #define MEMBERS(X) \
7373
// X(int, a) \
7474
// X(float, b) \
@@ -78,10 +78,11 @@ class Serializable {
7878
// void SomeAdditionalMethod();
7979
// };
8080
// #undef MEMBERS
81-
#define DAWN_SERIALIZABLE(qualifier, Name, MEMBERS) \
82-
struct Name##__Contents { \
83-
DAWN_VISITABLE_MEMBERS(MEMBERS) \
84-
}; \
81+
#define DAWN_SERIALIZABLE(qualifier, Name, MEMBERS) \
82+
struct Name##__Contents { \
83+
DAWN_VISITABLE_MEMBERS(MEMBERS) \
84+
bool operator==(const Name##__Contents& other) const = default; \
85+
}; \
8586
qualifier Name : Name##__Contents, public ::dawn::native::Serializable<Name>
8687

8788
#endif // SRC_DAWN_NATIVE_SERIALIZABLE_H_

src/dawn/native/ShaderModule.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,10 @@ ResultOrError<InterpolationSampling> TintInterpolationSamplingToInterpolationSam
320320
DAWN_UNREACHABLE();
321321
}
322322

323+
EntryPointMetadata::OverrideId FromTintOverrideId(tint::OverrideId id) {
324+
return EntryPointMetadata::OverrideId{{id.value}};
325+
}
326+
323327
EntryPointMetadata::Override::Type FromTintOverrideType(tint::inspector::Override::Type type) {
324328
switch (type) {
325329
case tint::inspector::Override::Type::kBool:
@@ -677,8 +681,8 @@ ResultOrError<std::unique_ptr<EntryPointMetadata>> ReflectEntryPointUsingTint(
677681
if (!entryPoint.overrides.empty()) {
678682
for (auto& c : entryPoint.overrides) {
679683
auto id = name2Id.at(c.name);
680-
EntryPointMetadata::Override override = {id, FromTintOverrideType(c.type),
681-
c.is_initialized};
684+
EntryPointMetadata::Override override = {
685+
{FromTintOverrideId(id), FromTintOverrideType(c.type), c.is_initialized}};
682686

683687
std::string identifier = c.is_id_specified ? std::to_string(override.id.value) : c.name;
684688
metadata->overrides[identifier] = override;
@@ -705,8 +709,9 @@ ResultOrError<std::unique_ptr<EntryPointMetadata>> ReflectEntryPointUsingTint(
705709
}
706710

707711
auto id = name2Id.at(o.name);
708-
EntryPointMetadata::Override override = {id, FromTintOverrideType(o.type), o.is_initialized,
709-
/* isUsed */ false};
712+
EntryPointMetadata::Override override = {{FromTintOverrideId(id),
713+
FromTintOverrideType(o.type), o.is_initialized,
714+
/* isUsed */ false}};
710715
metadata->overrides[identifier] = override;
711716
}
712717

0 commit comments

Comments
 (0)