Pipeline caching: refactor object hashing

Dawn's object-based cache creates keys from memory
addresses. These keys cannot be used in a persistent
cache. This change modifies the keys to only
use hashes so they can be re-used for caching
pipelines.

BUG=dawn:549

Change-Id: Ica64d58ae6a3c6266435cfc3f776c820190f7895
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/30740
Reviewed-by: Austin Eng <enga@chromium.org>
Commit-Queue: Bryan Bernhart <bryan.bernhart@intel.com>
This commit is contained in:
Bryan Bernhart 2020-12-03 18:42:13 +00:00 committed by Commit Bot service account
parent fe129405cf
commit 24bf7a4fbb
23 changed files with 272 additions and 135 deletions

View File

@ -15,8 +15,8 @@
#include "dawn_native/AttachmentState.h"
#include "common/BitSetIterator.h"
#include "common/HashUtils.h"
#include "dawn_native/Device.h"
#include "dawn_native/ObjectContentHasher.h"
#include "dawn_native/Texture.h"
namespace dawn_native {
@ -130,6 +130,11 @@ namespace dawn_native {
GetDevice()->UncacheAttachmentState(this);
}
size_t AttachmentState::ComputeContentHash() {
// TODO(dawn:549): skip this traversal and reuse the blueprint.
return AttachmentStateBlueprint::HashFunc()(this);
}
ityp::bitset<ColorAttachmentIndex, kMaxColorAttachments>
AttachmentState::GetColorAttachmentsMask() const {
return mColorAttachmentsSet;

View File

@ -69,6 +69,8 @@ namespace dawn_native {
wgpu::TextureFormat GetDepthStencilFormat() const;
uint32_t GetSampleCount() const;
size_t ComputeContentHash() override;
private:
~AttachmentState() override;
};

View File

@ -218,6 +218,8 @@ source_set("dawn_native_sources") {
"InternalPipelineStore.h",
"ObjectBase.cpp",
"ObjectBase.h",
"ObjectContentHasher.cpp",
"ObjectContentHasher.h",
"PassResourceUsage.h",
"PassResourceUsageTracker.cpp",
"PassResourceUsageTracker.h",

View File

@ -15,8 +15,8 @@
#include "dawn_native/BindGroupLayout.h"
#include "common/BitSetIterator.h"
#include "common/HashUtils.h"
#include "dawn_native/Device.h"
#include "dawn_native/ObjectContentHasher.h"
#include "dawn_native/PerStage.h"
#include "dawn_native/ValidationUtils_autogen.h"
@ -152,11 +152,6 @@ namespace dawn_native {
namespace {
void HashCombineBindingInfo(size_t* hash, const BindingInfo& info) {
HashCombine(hash, info.hasDynamicOffset, info.visibility, info.type,
info.textureComponentType, info.viewDimension, info.storageTextureFormat,
info.minBufferBindingSize);
}
bool operator!=(const BindingInfo& a, const BindingInfo& b) {
return a.hasDynamicOffset != b.hasDynamicOffset || //
@ -319,15 +314,20 @@ namespace dawn_native {
return it->second;
}
size_t BindGroupLayoutBase::HashFunc::operator()(const BindGroupLayoutBase* bgl) const {
size_t hash = 0;
size_t BindGroupLayoutBase::ComputeContentHash() {
ObjectContentHasher recorder;
// std::map is sorted by key, so two BGLs constructed in different orders
// will still hash the same.
for (const auto& it : bgl->mBindingMap) {
HashCombine(&hash, it.first, it.second);
HashCombineBindingInfo(&hash, bgl->mBindingInfo[it.second]);
// will still record the same.
for (const auto& it : mBindingMap) {
recorder.Record(it.first, it.second);
const BindingInfo& info = mBindingInfo[it.second];
recorder.Record(info.hasDynamicOffset, info.visibility, info.type,
info.textureComponentType, info.viewDimension,
info.storageTextureFormat, info.minBufferBindingSize);
}
return hash;
return recorder.GetContentHash();
}
bool BindGroupLayoutBase::EqualityFunc::operator()(const BindGroupLayoutBase* a,

View File

@ -56,10 +56,9 @@ namespace dawn_native {
const BindingMap& GetBindingMap() const;
BindingIndex GetBindingIndex(BindingNumber bindingNumber) const;
// Functors necessary for the unordered_set<BGLBase*>-based cache.
struct HashFunc {
size_t operator()(const BindGroupLayoutBase* bgl) const;
};
// Functions necessary for the unordered_set<BGLBase*>-based cache.
size_t ComputeContentHash() override;
struct EqualityFunc {
bool operator()(const BindGroupLayoutBase* a, const BindGroupLayoutBase* b) const;
};

View File

@ -94,6 +94,8 @@ target_sources(dawn_native PRIVATE
"ErrorScopeTracker.h"
"Extensions.cpp"
"Extensions.h"
"ObjectContentHasher.cpp"
"ObjectContentHasher.h"
"Fence.cpp"
"Fence.h"
"Format.cpp"

View File

@ -14,6 +14,8 @@
#include "dawn_native/CachedObject.h"
#include "common/Assert.h"
namespace dawn_native {
bool CachedObject::IsCachedReference() const {
@ -24,4 +26,19 @@ namespace dawn_native {
mIsCachedReference = true;
}
size_t CachedObject::HashFunc::operator()(const CachedObject* obj) const {
return obj->GetContentHash();
}
size_t CachedObject::GetContentHash() const {
ASSERT(mIsContentHashInitialized);
return mContentHash;
}
void CachedObject::SetContentHash(size_t contentHash) {
ASSERT(!mIsContentHashInitialized);
mContentHash = contentHash;
mIsContentHashInitialized = true;
}
} // namespace dawn_native

View File

@ -29,11 +29,25 @@ namespace dawn_native {
bool IsCachedReference() const;
// Functor necessary for the unordered_set<CachedObject*>-based cache.
struct HashFunc {
size_t operator()(const CachedObject* obj) const;
};
size_t GetContentHash() const;
void SetContentHash(size_t contentHash);
private:
friend class DeviceBase;
void SetIsCachedReference();
bool mIsCachedReference = false;
// Called by ObjectContentHasher upon creation to record the object.
virtual size_t ComputeContentHash() = 0;
size_t mContentHash = 0;
bool mIsContentHashInitialized = false;
};
} // namespace dawn_native

View File

@ -14,8 +14,8 @@
#include "dawn_native/ComputePipeline.h"
#include "common/HashUtils.h"
#include "dawn_native/Device.h"
#include "dawn_native/ObjectContentHasher.h"
namespace dawn_native {
@ -59,10 +59,6 @@ namespace dawn_native {
return new ComputePipelineBase(device, ObjectBase::kError);
}
size_t ComputePipelineBase::HashFunc::operator()(const ComputePipelineBase* pipeline) const {
return PipelineBase::HashForCache(pipeline);
}
bool ComputePipelineBase::EqualityFunc::operator()(const ComputePipelineBase* a,
const ComputePipelineBase* b) const {
return PipelineBase::EqualForCache(a, b);

View File

@ -35,9 +35,6 @@ namespace dawn_native {
const EntryPointMetadata& GetMetadata() const;
// Functors necessary for the unordered_set<ComputePipelineBase*>-based cache.
struct HashFunc {
size_t operator()(const ComputePipelineBase* pipeline) const;
};
struct EqualityFunc {
bool operator()(const ComputePipelineBase* a, const ComputePipelineBase* b) const;
};

View File

@ -437,6 +437,9 @@ namespace dawn_native {
const BindGroupLayoutDescriptor* descriptor) {
BindGroupLayoutBase blueprint(this, descriptor);
const size_t blueprintHash = blueprint.ComputeContentHash();
blueprint.SetContentHash(blueprintHash);
Ref<BindGroupLayoutBase> result = nullptr;
auto iter = mCaches->bindGroupLayouts.find(&blueprint);
if (iter != mCaches->bindGroupLayouts.end()) {
@ -445,6 +448,7 @@ namespace dawn_native {
BindGroupLayoutBase* backendObj;
DAWN_TRY_ASSIGN(backendObj, CreateBindGroupLayoutImpl(descriptor));
backendObj->SetIsCachedReference();
backendObj->SetContentHash(blueprintHash);
mCaches->bindGroupLayouts.insert(backendObj);
result = AcquireRef(backendObj);
}
@ -475,6 +479,9 @@ namespace dawn_native {
const ComputePipelineDescriptor* descriptor) {
ComputePipelineBase blueprint(this, descriptor);
const size_t blueprintHash = blueprint.ComputeContentHash();
blueprint.SetContentHash(blueprintHash);
auto iter = mCaches->computePipelines.find(&blueprint);
if (iter != mCaches->computePipelines.end()) {
(*iter)->Reference();
@ -484,6 +491,7 @@ namespace dawn_native {
ComputePipelineBase* backendObj;
DAWN_TRY_ASSIGN(backendObj, CreateComputePipelineImpl(descriptor));
backendObj->SetIsCachedReference();
backendObj->SetContentHash(blueprintHash);
mCaches->computePipelines.insert(backendObj);
return backendObj;
}
@ -498,6 +506,9 @@ namespace dawn_native {
const PipelineLayoutDescriptor* descriptor) {
PipelineLayoutBase blueprint(this, descriptor);
const size_t blueprintHash = blueprint.ComputeContentHash();
blueprint.SetContentHash(blueprintHash);
auto iter = mCaches->pipelineLayouts.find(&blueprint);
if (iter != mCaches->pipelineLayouts.end()) {
(*iter)->Reference();
@ -507,6 +518,7 @@ namespace dawn_native {
PipelineLayoutBase* backendObj;
DAWN_TRY_ASSIGN(backendObj, CreatePipelineLayoutImpl(descriptor));
backendObj->SetIsCachedReference();
backendObj->SetContentHash(blueprintHash);
mCaches->pipelineLayouts.insert(backendObj);
return backendObj;
}
@ -521,6 +533,9 @@ namespace dawn_native {
const RenderPipelineDescriptor* descriptor) {
RenderPipelineBase blueprint(this, descriptor);
const size_t blueprintHash = blueprint.ComputeContentHash();
blueprint.SetContentHash(blueprintHash);
auto iter = mCaches->renderPipelines.find(&blueprint);
if (iter != mCaches->renderPipelines.end()) {
(*iter)->Reference();
@ -530,6 +545,7 @@ namespace dawn_native {
RenderPipelineBase* backendObj;
DAWN_TRY_ASSIGN(backendObj, CreateRenderPipelineImpl(descriptor));
backendObj->SetIsCachedReference();
backendObj->SetContentHash(blueprintHash);
mCaches->renderPipelines.insert(backendObj);
return backendObj;
}
@ -544,6 +560,9 @@ namespace dawn_native {
const SamplerDescriptor* descriptor) {
SamplerBase blueprint(this, descriptor);
const size_t blueprintHash = blueprint.ComputeContentHash();
blueprint.SetContentHash(blueprintHash);
auto iter = mCaches->samplers.find(&blueprint);
if (iter != mCaches->samplers.end()) {
(*iter)->Reference();
@ -553,6 +572,7 @@ namespace dawn_native {
SamplerBase* backendObj;
DAWN_TRY_ASSIGN(backendObj, CreateSamplerImpl(descriptor));
backendObj->SetIsCachedReference();
backendObj->SetContentHash(blueprintHash);
mCaches->samplers.insert(backendObj);
return backendObj;
}
@ -567,6 +587,9 @@ namespace dawn_native {
const ShaderModuleDescriptor* descriptor) {
ShaderModuleBase blueprint(this, descriptor);
const size_t blueprintHash = blueprint.ComputeContentHash();
blueprint.SetContentHash(blueprintHash);
auto iter = mCaches->shaderModules.find(&blueprint);
if (iter != mCaches->shaderModules.end()) {
(*iter)->Reference();
@ -576,6 +599,7 @@ namespace dawn_native {
ShaderModuleBase* backendObj;
DAWN_TRY_ASSIGN(backendObj, CreateShaderModuleImpl(descriptor));
backendObj->SetIsCachedReference();
backendObj->SetContentHash(blueprintHash);
mCaches->shaderModules.insert(backendObj);
return backendObj;
}
@ -595,6 +619,7 @@ namespace dawn_native {
Ref<AttachmentState> attachmentState = AcquireRef(new AttachmentState(this, *blueprint));
attachmentState->SetIsCachedReference();
attachmentState->SetContentHash(attachmentState->ComputeContentHash());
mCaches->attachmentStates.insert(attachmentState.Get());
return attachmentState;
}

View File

@ -0,0 +1,22 @@
// Copyright 2020 The Dawn Authors
//
// 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.
#include "dawn_native/ObjectContentHasher.h"
namespace dawn_native {
size_t ObjectContentHasher::GetContentHash() const {
return mContentHash;
}
} // namespace dawn_native

View File

@ -0,0 +1,81 @@
// Copyright 2020 The Dawn Authors
//
// 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.
#ifndef DAWNNATIVE_OBJECT_CONTENT_HASHER_H_
#define DAWNNATIVE_OBJECT_CONTENT_HASHER_H_
#include "common/HashUtils.h"
#include <string>
#include <vector>
namespace dawn_native {
// ObjectContentHasher records a hash that can be used as a key to lookup a cached object in a
// cache.
class ObjectContentHasher {
public:
// Record calls the appropriate record function based on the type.
template <typename T, typename... Args>
void Record(const T& value, const Args&... args) {
RecordImpl<T, Args...>::Call(this, value, args...);
}
size_t GetContentHash() const;
private:
template <typename T, typename... Args>
struct RecordImpl {
static constexpr void Call(ObjectContentHasher* recorder,
const T& value,
const Args&... args) {
HashCombine(&recorder->mContentHash, value, args...);
}
};
template <typename T>
struct RecordImpl<T*> {
static constexpr void Call(ObjectContentHasher* recorder, T* obj) {
// Calling Record(objPtr) is not allowed. This check exists to only prevent such
// mistakes.
static_assert(obj == nullptr, "");
}
};
template <>
struct RecordImpl<std::string> {
static constexpr void Call(ObjectContentHasher* recorder, const std::string& str) {
recorder->RecordIterable<std::string>(str);
}
};
template <typename T>
struct RecordImpl<std::vector<T>> {
static constexpr void Call(ObjectContentHasher* recorder, const std::vector<T>& vec) {
recorder->RecordIterable<std::vector<T>>(vec);
}
};
template <typename IteratorT>
void RecordIterable(const IteratorT& iterable) {
for (auto it = iterable.begin(); it != iterable.end(); ++it) {
Record(*it);
}
}
size_t mContentHash = 0;
};
} // namespace dawn_native
#endif // DAWNNATIVE_OBJECT_CONTENT_HASHER_H_

View File

@ -14,9 +14,9 @@
#include "dawn_native/Pipeline.h"
#include "common/HashUtils.h"
#include "dawn_native/BindGroupLayout.h"
#include "dawn_native/Device.h"
#include "dawn_native/ObjectContentHasher.h"
#include "dawn_native/PipelineLayout.h"
#include "dawn_native/ShaderModule.h"
@ -142,21 +142,17 @@ namespace dawn_native {
return bgl;
}
// static
size_t PipelineBase::HashForCache(const PipelineBase* pipeline) {
size_t hash = 0;
size_t PipelineBase::ComputeContentHash() {
ObjectContentHasher recorder;
recorder.Record(mLayout->GetContentHash());
// The layout is deduplicated so it can be hashed by pointer.
HashCombine(&hash, pipeline->mLayout.Get());
HashCombine(&hash, pipeline->mStageMask);
for (SingleShaderStage stage : IterateStages(pipeline->mStageMask)) {
// The module is deduplicated so it can be hashed by pointer.
HashCombine(&hash, pipeline->mStages[stage].module.Get());
HashCombine(&hash, pipeline->mStages[stage].entryPoint);
recorder.Record(mStageMask);
for (SingleShaderStage stage : IterateStages(mStageMask)) {
recorder.Record(mStages[stage].module->GetContentHash());
recorder.Record(mStages[stage].entryPoint);
}
return hash;
return recorder.GetContentHash();
}
// static

View File

@ -51,8 +51,8 @@ namespace dawn_native {
BindGroupLayoutBase* GetBindGroupLayout(uint32_t groupIndex);
// Helper function for the functors for std::unordered_map-based pipeline caches.
static size_t HashForCache(const PipelineBase* pipeline);
// Helper functions for std::unordered_map-based pipeline caches.
size_t ComputeContentHash() override;
static bool EqualForCache(const PipelineBase* a, const PipelineBase* b);
protected:

View File

@ -16,10 +16,10 @@
#include "common/Assert.h"
#include "common/BitSetIterator.h"
#include "common/HashUtils.h"
#include "common/ityp_stack_vec.h"
#include "dawn_native/BindGroupLayout.h"
#include "dawn_native/Device.h"
#include "dawn_native/ObjectContentHasher.h"
#include "dawn_native/ShaderModule.h"
namespace dawn_native {
@ -253,14 +253,15 @@ namespace dawn_native {
return kMaxBindGroupsTyped;
}
size_t PipelineLayoutBase::HashFunc::operator()(const PipelineLayoutBase* pl) const {
size_t hash = Hash(pl->mMask);
size_t PipelineLayoutBase::ComputeContentHash() {
ObjectContentHasher recorder;
recorder.Record(mMask);
for (BindGroupIndex group : IterateBitSet(pl->mMask)) {
HashCombine(&hash, pl->GetBindGroupLayout(group));
for (BindGroupIndex group : IterateBitSet(mMask)) {
recorder.Record(GetBindGroupLayout(group)->GetContentHash());
}
return hash;
return recorder.GetContentHash();
}
bool PipelineLayoutBase::EqualityFunc::operator()(const PipelineLayoutBase* a,

View File

@ -61,10 +61,9 @@ namespace dawn_native {
// [0, kMaxBindGroups]
BindGroupIndex GroupsInheritUpTo(const PipelineLayoutBase* other) const;
// Functors necessary for the unordered_set<PipelineLayoutBase*>-based cache.
struct HashFunc {
size_t operator()(const PipelineLayoutBase* pl) const;
};
// Functions necessary for the unordered_set<PipelineLayoutBase*>-based cache.
size_t ComputeContentHash() override;
struct EqualityFunc {
bool operator()(const PipelineLayoutBase* a, const PipelineLayoutBase* b) const;
};

View File

@ -15,9 +15,9 @@
#include "dawn_native/RenderPipeline.h"
#include "common/BitSetIterator.h"
#include "common/HashUtils.h"
#include "dawn_native/Commands.h"
#include "dawn_native/Device.h"
#include "dawn_native/ObjectContentHasher.h"
#include "dawn_native/ValidationUtils_autogen.h"
#include <cmath>
@ -607,63 +607,62 @@ namespace dawn_native {
return mAttachmentState.Get();
}
size_t RenderPipelineBase::HashFunc::operator()(const RenderPipelineBase* pipeline) const {
// Hash modules and layout
size_t hash = PipelineBase::HashForCache(pipeline);
size_t RenderPipelineBase::ComputeContentHash() {
ObjectContentHasher recorder;
// Hierarchically hash the attachment state.
// Record modules and layout
recorder.Record(PipelineBase::ComputeContentHash());
// Hierarchically record the attachment state.
// It contains the attachments set, texture formats, and sample count.
HashCombine(&hash, pipeline->mAttachmentState.Get());
recorder.Record(mAttachmentState->GetContentHash());
// Hash attachments
for (ColorAttachmentIndex i :
IterateBitSet(pipeline->mAttachmentState->GetColorAttachmentsMask())) {
const ColorStateDescriptor& desc = *pipeline->GetColorStateDescriptor(i);
HashCombine(&hash, desc.writeMask);
HashCombine(&hash, desc.colorBlend.operation, desc.colorBlend.srcFactor,
desc.colorBlend.dstFactor);
HashCombine(&hash, desc.alphaBlend.operation, desc.alphaBlend.srcFactor,
desc.alphaBlend.dstFactor);
// Record attachments
for (ColorAttachmentIndex i : IterateBitSet(mAttachmentState->GetColorAttachmentsMask())) {
const ColorStateDescriptor& desc = *GetColorStateDescriptor(i);
recorder.Record(desc.writeMask);
recorder.Record(desc.colorBlend.operation, desc.colorBlend.srcFactor,
desc.colorBlend.dstFactor);
recorder.Record(desc.alphaBlend.operation, desc.alphaBlend.srcFactor,
desc.alphaBlend.dstFactor);
}
if (pipeline->mAttachmentState->HasDepthStencilAttachment()) {
const DepthStencilStateDescriptor& desc = pipeline->mDepthStencilState;
HashCombine(&hash, desc.depthWriteEnabled, desc.depthCompare);
HashCombine(&hash, desc.stencilReadMask, desc.stencilWriteMask);
HashCombine(&hash, desc.stencilFront.compare, desc.stencilFront.failOp,
desc.stencilFront.depthFailOp, desc.stencilFront.passOp);
HashCombine(&hash, desc.stencilBack.compare, desc.stencilBack.failOp,
desc.stencilBack.depthFailOp, desc.stencilBack.passOp);
if (mAttachmentState->HasDepthStencilAttachment()) {
const DepthStencilStateDescriptor& desc = mDepthStencilState;
recorder.Record(desc.depthWriteEnabled, desc.depthCompare);
recorder.Record(desc.stencilReadMask, desc.stencilWriteMask);
recorder.Record(desc.stencilFront.compare, desc.stencilFront.failOp,
desc.stencilFront.depthFailOp, desc.stencilFront.passOp);
recorder.Record(desc.stencilBack.compare, desc.stencilBack.failOp,
desc.stencilBack.depthFailOp, desc.stencilBack.passOp);
}
// Hash vertex state
HashCombine(&hash, pipeline->mAttributeLocationsUsed);
for (VertexAttributeLocation location : IterateBitSet(pipeline->mAttributeLocationsUsed)) {
const VertexAttributeInfo& desc = pipeline->GetAttribute(location);
HashCombine(&hash, desc.shaderLocation, desc.vertexBufferSlot, desc.offset,
desc.format);
// Record vertex state
recorder.Record(mAttributeLocationsUsed);
for (VertexAttributeLocation location : IterateBitSet(mAttributeLocationsUsed)) {
const VertexAttributeInfo& desc = GetAttribute(location);
recorder.Record(desc.shaderLocation, desc.vertexBufferSlot, desc.offset, desc.format);
}
HashCombine(&hash, pipeline->mVertexBufferSlotsUsed);
for (VertexBufferSlot slot : IterateBitSet(pipeline->mVertexBufferSlotsUsed)) {
const VertexBufferInfo& desc = pipeline->GetVertexBuffer(slot);
HashCombine(&hash, desc.arrayStride, desc.stepMode);
recorder.Record(mVertexBufferSlotsUsed);
for (VertexBufferSlot slot : IterateBitSet(mVertexBufferSlotsUsed)) {
const VertexBufferInfo& desc = GetVertexBuffer(slot);
recorder.Record(desc.arrayStride, desc.stepMode);
}
HashCombine(&hash, pipeline->mVertexState.indexFormat);
recorder.Record(mVertexState.indexFormat);
// Hash rasterization state
// Record rasterization state
{
const RasterizationStateDescriptor& desc = pipeline->mRasterizationState;
HashCombine(&hash, desc.frontFace, desc.cullMode);
HashCombine(&hash, desc.depthBias, desc.depthBiasSlopeScale, desc.depthBiasClamp);
const RasterizationStateDescriptor& desc = mRasterizationState;
recorder.Record(desc.frontFace, desc.cullMode);
recorder.Record(desc.depthBias, desc.depthBiasSlopeScale, desc.depthBiasClamp);
}
// Hash other state
HashCombine(&hash, pipeline->mPrimitiveTopology, pipeline->mSampleMask,
pipeline->mAlphaToCoverageEnabled);
// Record other state
recorder.Record(mPrimitiveTopology, mSampleMask, mAlphaToCoverageEnabled);
return hash;
return recorder.GetContentHash();
}
bool RenderPipelineBase::EqualityFunc::operator()(const RenderPipelineBase* a,

View File

@ -91,10 +91,9 @@ namespace dawn_native {
const AttachmentState* GetAttachmentState() const;
// Functors necessary for the unordered_set<RenderPipelineBase*>-based cache.
struct HashFunc {
size_t operator()(const RenderPipelineBase* pipeline) const;
};
// Functions necessary for the unordered_set<RenderPipelineBase*>-based cache.
size_t ComputeContentHash() override;
struct EqualityFunc {
bool operator()(const RenderPipelineBase* a, const RenderPipelineBase* b) const;
};

View File

@ -14,8 +14,8 @@
#include "dawn_native/Sampler.h"
#include "common/HashUtils.h"
#include "dawn_native/Device.h"
#include "dawn_native/ObjectContentHasher.h"
#include "dawn_native/ValidationUtils_autogen.h"
#include <cmath>
@ -84,20 +84,11 @@ namespace dawn_native {
return mCompareFunction != wgpu::CompareFunction::Undefined;
}
size_t SamplerBase::HashFunc::operator()(const SamplerBase* module) const {
size_t hash = 0;
HashCombine(&hash, module->mAddressModeU);
HashCombine(&hash, module->mAddressModeV);
HashCombine(&hash, module->mAddressModeW);
HashCombine(&hash, module->mMagFilter);
HashCombine(&hash, module->mMinFilter);
HashCombine(&hash, module->mMipmapFilter);
HashCombine(&hash, module->mLodMinClamp);
HashCombine(&hash, module->mLodMaxClamp);
HashCombine(&hash, module->mCompareFunction);
return hash;
size_t SamplerBase::ComputeContentHash() {
ObjectContentHasher recorder;
recorder.Record(mAddressModeU, mAddressModeV, mAddressModeW, mMagFilter, mMinFilter,
mMipmapFilter, mLodMinClamp, mLodMaxClamp, mCompareFunction);
return recorder.GetContentHash();
}
bool SamplerBase::EqualityFunc::operator()(const SamplerBase* a, const SamplerBase* b) const {

View File

@ -35,10 +35,9 @@ namespace dawn_native {
bool HasCompareFunction() const;
// Functors necessary for the unordered_set<SamplerBase*>-based cache.
struct HashFunc {
size_t operator()(const SamplerBase* module) const;
};
// Functions necessary for the unordered_set<SamplerBase*>-based cache.
size_t ComputeContentHash() override;
struct EqualityFunc {
bool operator()(const SamplerBase* a, const SamplerBase* b) const;
};

View File

@ -14,9 +14,9 @@
#include "dawn_native/ShaderModule.h"
#include "common/HashUtils.h"
#include "dawn_native/BindGroupLayout.h"
#include "dawn_native/Device.h"
#include "dawn_native/ObjectContentHasher.h"
#include "dawn_native/Pipeline.h"
#include "dawn_native/PipelineLayout.h"
#include "dawn_native/SpirvUtils.h"
@ -975,20 +975,12 @@ namespace dawn_native {
return *mEntryPoints.at(entryPoint);
}
size_t ShaderModuleBase::HashFunc::operator()(const ShaderModuleBase* module) const {
size_t hash = 0;
HashCombine(&hash, module->mType);
for (uint32_t word : module->mOriginalSpirv) {
HashCombine(&hash, word);
}
for (char c : module->mWgsl) {
HashCombine(&hash, c);
}
return hash;
size_t ShaderModuleBase::ComputeContentHash() {
ObjectContentHasher recorder;
recorder.Record(mType);
recorder.Record(mOriginalSpirv);
recorder.Record(mWgsl);
return recorder.GetContentHash();
}
bool ShaderModuleBase::EqualityFunc::operator()(const ShaderModuleBase* a,

View File

@ -105,10 +105,9 @@ namespace dawn_native {
// must be true.
const EntryPointMetadata& GetEntryPoint(const std::string& entryPoint) const;
// Functors necessary for the unordered_set<ShaderModuleBase*>-based cache.
struct HashFunc {
size_t operator()(const ShaderModuleBase* module) const;
};
// Functions necessary for the unordered_set<ShaderModuleBase*>-based cache.
size_t ComputeContentHash() override;
struct EqualityFunc {
bool operator()(const ShaderModuleBase* a, const ShaderModuleBase* b) const;
};