diff --git a/src/dawn_native/BindGroupLayout.cpp b/src/dawn_native/BindGroupLayout.cpp index cd6a7aa496..6aafe84062 100644 --- a/src/dawn_native/BindGroupLayout.cpp +++ b/src/dawn_native/BindGroupLayout.cpp @@ -362,9 +362,11 @@ namespace dawn_native { // BindGroupLayoutBase BindGroupLayoutBase::BindGroupLayoutBase(DeviceBase* device, - const BindGroupLayoutDescriptor* descriptor) + const BindGroupLayoutDescriptor* descriptor, + PipelineCompatibilityToken pipelineCompatibilityToken) : CachedObject(device, kLabelNotImplemented), - mBindingInfo(BindingIndex(descriptor->entryCount)) { + mBindingInfo(BindingIndex(descriptor->entryCount)), + mPipelineCompatibilityToken(pipelineCompatibilityToken) { std::vector sortedBindings( descriptor->entries, descriptor->entries + descriptor->entryCount); @@ -422,6 +424,8 @@ namespace dawn_native { size_t BindGroupLayoutBase::ComputeContentHash() { ObjectContentHasher recorder; + recorder.Record(mPipelineCompatibilityToken); + // std::map is sorted by key, so two BGLs constructed in different orders // will still record the same. for (const auto& it : mBindingMap) { @@ -441,15 +445,7 @@ namespace dawn_native { bool BindGroupLayoutBase::EqualityFunc::operator()(const BindGroupLayoutBase* a, const BindGroupLayoutBase* b) const { - if (a->GetBindingCount() != b->GetBindingCount()) { - return false; - } - for (BindingIndex i{0}; i < a->GetBindingCount(); ++i) { - if (a->mBindingInfo[i] != b->mBindingInfo[i]) { - return false; - } - } - return a->mBindingMap == b->mBindingMap; + return a->IsLayoutEqual(b); } BindingIndex BindGroupLayoutBase::GetBindingCount() const { @@ -475,6 +471,27 @@ namespace dawn_native { return mBindingCounts; } + bool BindGroupLayoutBase::IsLayoutEqual(const BindGroupLayoutBase* other, + bool excludePipelineCompatibiltyToken) const { + if (!excludePipelineCompatibiltyToken && + GetPipelineCompatibilityToken() != other->GetPipelineCompatibilityToken()) { + return false; + } + if (GetBindingCount() != other->GetBindingCount()) { + return false; + } + for (BindingIndex i{0}; i < GetBindingCount(); ++i) { + if (mBindingInfo[i] != other->mBindingInfo[i]) { + return false; + } + } + return mBindingMap == other->mBindingMap; + } + + PipelineCompatibilityToken BindGroupLayoutBase::GetPipelineCompatibilityToken() const { + return mPipelineCompatibilityToken; + } + size_t BindGroupLayoutBase::GetBindingDataSize() const { // | ------ buffer-specific ----------| ------------ object pointers -------------| // | --- offsets + sizes -------------| --------------- Ref ----------| diff --git a/src/dawn_native/BindGroupLayout.h b/src/dawn_native/BindGroupLayout.h index 8db649252d..728e641fb0 100644 --- a/src/dawn_native/BindGroupLayout.h +++ b/src/dawn_native/BindGroupLayout.h @@ -41,7 +41,9 @@ namespace dawn_native { // into a packed range of |BindingIndex| integers. class BindGroupLayoutBase : public CachedObject { public: - BindGroupLayoutBase(DeviceBase* device, const BindGroupLayoutDescriptor* descriptor); + BindGroupLayoutBase(DeviceBase* device, + const BindGroupLayoutDescriptor* descriptor, + PipelineCompatibilityToken pipelineCompatibilityToken); ~BindGroupLayoutBase() override; static BindGroupLayoutBase* MakeError(DeviceBase* device); @@ -76,6 +78,13 @@ namespace dawn_native { // should be used to get typed integer counts. const BindingCounts& GetBindingCountInfo() const; + // Tests that the BindingInfo of two bind groups are equal, + // ignoring their compatibility groups. + bool IsLayoutEqual(const BindGroupLayoutBase* other, + bool excludePipelineCompatibiltyToken = false) const; + + PipelineCompatibilityToken GetPipelineCompatibilityToken() const; + struct BufferBindingData { uint64_t offset; uint64_t size; @@ -115,6 +124,10 @@ namespace dawn_native { // Map from BindGroupLayoutEntry.binding to packed indices. BindingMap mBindingMap; + + // Non-0 if this BindGroupLayout was created as part of a default PipelineLayout. + const PipelineCompatibilityToken mPipelineCompatibilityToken = + PipelineCompatibilityToken(0); }; } // namespace dawn_native diff --git a/src/dawn_native/DawnNative.cpp b/src/dawn_native/DawnNative.cpp index b5e1ba40fa..3cdea5425f 100644 --- a/src/dawn_native/DawnNative.cpp +++ b/src/dawn_native/DawnNative.cpp @@ -14,6 +14,7 @@ #include "dawn_native/DawnNative.h" +#include "dawn_native/BindGroupLayout.h" #include "dawn_native/Buffer.h" #include "dawn_native/Device.h" #include "dawn_native/Instance.h" @@ -236,4 +237,11 @@ namespace dawn_native { return reinterpret_cast(buffer)->GetAllocatedSize(); } + bool BindGroupLayoutBindingsEqualForTesting(WGPUBindGroupLayout a, WGPUBindGroupLayout b) { + BindGroupLayoutBase* aBase = reinterpret_cast(a); + BindGroupLayoutBase* bBase = reinterpret_cast(b); + bool excludePipelineCompatibiltyToken = true; + return aBase->IsLayoutEqual(bBase, excludePipelineCompatibiltyToken); + } + } // namespace dawn_native diff --git a/src/dawn_native/Device.cpp b/src/dawn_native/Device.cpp index 834ff00844..7fa05a8aa0 100644 --- a/src/dawn_native/Device.cpp +++ b/src/dawn_native/Device.cpp @@ -126,7 +126,7 @@ namespace dawn_native { // DeviceBase DeviceBase::DeviceBase(AdapterBase* adapter, const DeviceDescriptor* descriptor) - : mInstance(adapter->GetInstance()), mAdapter(adapter) { + : mInstance(adapter->GetInstance()), mAdapter(adapter), mNextPipelineCompatibilityToken(1) { if (descriptor != nullptr) { ApplyToggleOverrides(descriptor); ApplyExtensions(descriptor); @@ -520,8 +520,9 @@ namespace dawn_native { } ResultOrError> DeviceBase::GetOrCreateBindGroupLayout( - const BindGroupLayoutDescriptor* descriptor) { - BindGroupLayoutBase blueprint(this, descriptor); + const BindGroupLayoutDescriptor* descriptor, + PipelineCompatibilityToken pipelineCompatibilityToken) { + BindGroupLayoutBase blueprint(this, descriptor, pipelineCompatibilityToken); const size_t blueprintHash = blueprint.ComputeContentHash(); blueprint.SetContentHash(blueprintHash); @@ -531,7 +532,8 @@ namespace dawn_native { if (iter != mCaches->bindGroupLayouts.end()) { result = *iter; } else { - DAWN_TRY_ASSIGN(result, CreateBindGroupLayoutImpl(descriptor)); + DAWN_TRY_ASSIGN(result, + CreateBindGroupLayoutImpl(descriptor, pipelineCompatibilityToken)); result->SetIsCachedReference(); result->SetContentHash(blueprintHash); mCaches->bindGroupLayouts.insert(result.Get()); @@ -1519,4 +1521,8 @@ namespace dawn_native { std::move(pipeline), errorMessage, callback, userdata, blueprintHash)); } + PipelineCompatibilityToken DeviceBase::GetNextPipelineCompatibilityToken() { + return PipelineCompatibilityToken(mNextPipelineCompatibilityToken++); + } + } // namespace dawn_native diff --git a/src/dawn_native/Device.h b/src/dawn_native/Device.h index 603298836f..0cd06eb3b4 100644 --- a/src/dawn_native/Device.h +++ b/src/dawn_native/Device.h @@ -113,7 +113,8 @@ namespace dawn_native { // instead of a backend Foo object. If the blueprint doesn't match an object in the // cache, then the descriptor is used to make a new object. ResultOrError> GetOrCreateBindGroupLayout( - const BindGroupLayoutDescriptor* descriptor); + const BindGroupLayoutDescriptor* descriptor, + PipelineCompatibilityToken pipelineCompatibilityToken = PipelineCompatibilityToken(0)); void UncacheBindGroupLayout(BindGroupLayoutBase* obj); BindGroupLayoutBase* GetEmptyBindGroupLayout(); @@ -298,6 +299,8 @@ namespace dawn_native { void* userdata, size_t blueprintHash); + PipelineCompatibilityToken GetNextPipelineCompatibilityToken(); + protected: void SetToggle(Toggle toggle, bool isEnabled); void ForceSetToggle(Toggle toggle, bool isEnabled); @@ -312,7 +315,8 @@ namespace dawn_native { virtual ResultOrError> CreateBindGroupImpl( const BindGroupDescriptor* descriptor) = 0; virtual ResultOrError> CreateBindGroupLayoutImpl( - const BindGroupLayoutDescriptor* descriptor) = 0; + const BindGroupLayoutDescriptor* descriptor, + PipelineCompatibilityToken pipelineCompatibilityToken) = 0; virtual ResultOrError> CreateBufferImpl( const BufferDescriptor* descriptor) = 0; virtual ResultOrError> CreateComputePipelineImpl( @@ -449,6 +453,7 @@ namespace dawn_native { TogglesSet mEnabledToggles; TogglesSet mOverridenToggles; size_t mLazyClearCountForTesting = 0; + std::atomic_uint64_t mNextPipelineCompatibilityToken; ExtensionsSet mEnabledExtensions; diff --git a/src/dawn_native/IntegerTypes.h b/src/dawn_native/IntegerTypes.h index 55d9edf43e..fbbaf4ed1a 100644 --- a/src/dawn_native/IntegerTypes.h +++ b/src/dawn_native/IntegerTypes.h @@ -64,6 +64,12 @@ namespace dawn_native { using ExecutionSerial = TypedInteger; constexpr ExecutionSerial kMaxExecutionSerial = ExecutionSerial(~uint64_t(0)); + // An identifier that indicates which Pipeline a BindGroupLayout is compatible with. Pipelines + // created with a default layout will produce BindGroupLayouts with a non-zero compatibility + // token, which prevents them (and any BindGroups created with them) from being used with any + // other pipelines. + using PipelineCompatibilityToken = TypedInteger; + } // namespace dawn_native #endif // DAWNNATIVE_INTEGERTYPES_H_ diff --git a/src/dawn_native/PipelineLayout.cpp b/src/dawn_native/PipelineLayout.cpp index e99ad2279e..b2a22c623d 100644 --- a/src/dawn_native/PipelineLayout.cpp +++ b/src/dawn_native/PipelineLayout.cpp @@ -24,8 +24,10 @@ namespace dawn_native { - MaybeError ValidatePipelineLayoutDescriptor(DeviceBase* device, - const PipelineLayoutDescriptor* descriptor) { + MaybeError ValidatePipelineLayoutDescriptor( + DeviceBase* device, + const PipelineLayoutDescriptor* descriptor, + PipelineCompatibilityToken pipelineCompatibilityToken) { if (descriptor->nextInChain != nullptr) { return DAWN_VALIDATION_ERROR("nextInChain must be nullptr"); } @@ -37,6 +39,12 @@ namespace dawn_native { BindingCounts bindingCounts = {}; for (uint32_t i = 0; i < descriptor->bindGroupLayoutCount; ++i) { DAWN_TRY(device->ValidateObject(descriptor->bindGroupLayouts[i])); + if (descriptor->bindGroupLayouts[i]->GetPipelineCompatibilityToken() != + pipelineCompatibilityToken) { + return DAWN_VALIDATION_ERROR( + "cannot create a pipeline layout using a bind group layout that was created as " + "part of a pipeline's default layout"); + } AccumulateBindingCounts(&bindingCounts, descriptor->bindGroupLayouts[i]->GetBindingCountInfo()); } @@ -203,9 +211,13 @@ namespace dawn_native { return entry; }; + PipelineCompatibilityToken pipelineCompatibilityToken = + device->GetNextPipelineCompatibilityToken(); + // Creates the BGL from the entries for a stage, checking it is valid. - auto CreateBGL = [](DeviceBase* device, - const EntryMap& entries) -> ResultOrError> { + auto CreateBGL = [](DeviceBase* device, const EntryMap& entries, + PipelineCompatibilityToken pipelineCompatibilityToken) + -> ResultOrError> { std::vector entryVec; entryVec.reserve(entries.size()); for (auto& it : entries) { @@ -219,7 +231,7 @@ namespace dawn_native { if (device->IsValidationEnabled()) { DAWN_TRY(ValidateBindGroupLayoutDescriptor(device, &desc)); } - return device->GetOrCreateBindGroupLayout(&desc); + return device->GetOrCreateBindGroupLayout(&desc, pipelineCompatibilityToken); }; ASSERT(!stages.empty()); @@ -276,7 +288,8 @@ namespace dawn_native { BindGroupIndex pipelineBGLCount = BindGroupIndex(0); ityp::array, kMaxBindGroups> bindGroupLayouts = {}; for (BindGroupIndex group(0); group < kMaxBindGroupsTyped; ++group) { - DAWN_TRY_ASSIGN(bindGroupLayouts[group], CreateBGL(device, entryData[group])); + DAWN_TRY_ASSIGN(bindGroupLayouts[group], + CreateBGL(device, entryData[group], pipelineCompatibilityToken)); if (entryData[group].size() != 0) { pipelineBGLCount = group + BindGroupIndex(1); } @@ -292,7 +305,7 @@ namespace dawn_native { desc.bindGroupLayouts = bgls.data(); desc.bindGroupLayoutCount = static_cast(pipelineBGLCount); - DAWN_TRY(ValidatePipelineLayoutDescriptor(device, &desc)); + DAWN_TRY(ValidatePipelineLayoutDescriptor(device, &desc, pipelineCompatibilityToken)); Ref result; DAWN_TRY_ASSIGN(result, device->GetOrCreatePipelineLayout(&desc)); diff --git a/src/dawn_native/PipelineLayout.h b/src/dawn_native/PipelineLayout.h index 0c1b5d74da..a9ee34988a 100644 --- a/src/dawn_native/PipelineLayout.h +++ b/src/dawn_native/PipelineLayout.h @@ -30,8 +30,10 @@ namespace dawn_native { - MaybeError ValidatePipelineLayoutDescriptor(DeviceBase*, - const PipelineLayoutDescriptor* descriptor); + MaybeError ValidatePipelineLayoutDescriptor( + DeviceBase*, + const PipelineLayoutDescriptor* descriptor, + PipelineCompatibilityToken pipelineCompatibilityToken = PipelineCompatibilityToken(0)); using BindGroupLayoutArray = ityp::array, kMaxBindGroups>; diff --git a/src/dawn_native/d3d12/BindGroupLayoutD3D12.cpp b/src/dawn_native/d3d12/BindGroupLayoutD3D12.cpp index 30b5a54d54..dd191e1cb3 100644 --- a/src/dawn_native/d3d12/BindGroupLayoutD3D12.cpp +++ b/src/dawn_native/d3d12/BindGroupLayoutD3D12.cpp @@ -59,13 +59,17 @@ namespace dawn_native { namespace d3d12 { } // anonymous namespace // static - Ref BindGroupLayout::Create(Device* device, - const BindGroupLayoutDescriptor* descriptor) { - return AcquireRef(new BindGroupLayout(device, descriptor)); + Ref BindGroupLayout::Create( + Device* device, + const BindGroupLayoutDescriptor* descriptor, + PipelineCompatibilityToken pipelineCompatibilityToken) { + return AcquireRef(new BindGroupLayout(device, descriptor, pipelineCompatibilityToken)); } - BindGroupLayout::BindGroupLayout(Device* device, const BindGroupLayoutDescriptor* descriptor) - : BindGroupLayoutBase(device, descriptor), + BindGroupLayout::BindGroupLayout(Device* device, + const BindGroupLayoutDescriptor* descriptor, + PipelineCompatibilityToken pipelineCompatibilityToken) + : BindGroupLayoutBase(device, descriptor, pipelineCompatibilityToken), mDescriptorHeapOffsets(GetBindingCount()), mShaderRegisters(GetBindingCount()), mCbvUavSrvDescriptorCount(0), diff --git a/src/dawn_native/d3d12/BindGroupLayoutD3D12.h b/src/dawn_native/d3d12/BindGroupLayoutD3D12.h index eb7b313ea6..abf67021a0 100644 --- a/src/dawn_native/d3d12/BindGroupLayoutD3D12.h +++ b/src/dawn_native/d3d12/BindGroupLayoutD3D12.h @@ -38,7 +38,8 @@ namespace dawn_native { namespace d3d12 { class BindGroupLayout final : public BindGroupLayoutBase { public: static Ref Create(Device* device, - const BindGroupLayoutDescriptor* descriptor); + const BindGroupLayoutDescriptor* descriptor, + PipelineCompatibilityToken pipelineCompatibilityToken); ResultOrError> AllocateBindGroup(Device* device, const BindGroupDescriptor* descriptor); @@ -60,7 +61,9 @@ namespace dawn_native { namespace d3d12 { const std::vector& GetSamplerDescriptorRanges() const; private: - BindGroupLayout(Device* device, const BindGroupLayoutDescriptor* descriptor); + BindGroupLayout(Device* device, + const BindGroupLayoutDescriptor* descriptor, + PipelineCompatibilityToken pipelineCompatibilityToken); ~BindGroupLayout() override = default; // Contains the offset into the descriptor heap for the given resource view. Samplers and diff --git a/src/dawn_native/d3d12/DeviceD3D12.cpp b/src/dawn_native/d3d12/DeviceD3D12.cpp index f34ac637f5..ab53a76e37 100644 --- a/src/dawn_native/d3d12/DeviceD3D12.cpp +++ b/src/dawn_native/d3d12/DeviceD3D12.cpp @@ -319,8 +319,9 @@ namespace dawn_native { namespace d3d12 { return BindGroup::Create(this, descriptor); } ResultOrError> Device::CreateBindGroupLayoutImpl( - const BindGroupLayoutDescriptor* descriptor) { - return BindGroupLayout::Create(this, descriptor); + const BindGroupLayoutDescriptor* descriptor, + PipelineCompatibilityToken pipelineCompatibilityToken) { + return BindGroupLayout::Create(this, descriptor, pipelineCompatibilityToken); } ResultOrError> Device::CreateBufferImpl(const BufferDescriptor* descriptor) { return Buffer::Create(this, descriptor); diff --git a/src/dawn_native/d3d12/DeviceD3D12.h b/src/dawn_native/d3d12/DeviceD3D12.h index e4d5cb0d84..84309699f1 100644 --- a/src/dawn_native/d3d12/DeviceD3D12.h +++ b/src/dawn_native/d3d12/DeviceD3D12.h @@ -145,7 +145,8 @@ namespace dawn_native { namespace d3d12 { ResultOrError> CreateBindGroupImpl( const BindGroupDescriptor* descriptor) override; ResultOrError> CreateBindGroupLayoutImpl( - const BindGroupLayoutDescriptor* descriptor) override; + const BindGroupLayoutDescriptor* descriptor, + PipelineCompatibilityToken pipelineCompatibilityToken) override; ResultOrError> CreateBufferImpl( const BufferDescriptor* descriptor) override; ResultOrError> CreateComputePipelineImpl( diff --git a/src/dawn_native/metal/BindGroupLayoutMTL.h b/src/dawn_native/metal/BindGroupLayoutMTL.h index edd9c35b1c..1d2c2a9334 100644 --- a/src/dawn_native/metal/BindGroupLayoutMTL.h +++ b/src/dawn_native/metal/BindGroupLayoutMTL.h @@ -26,13 +26,16 @@ namespace dawn_native { namespace metal { class BindGroupLayout final : public BindGroupLayoutBase { public: static Ref Create(DeviceBase* device, - const BindGroupLayoutDescriptor* descriptor); + const BindGroupLayoutDescriptor* descriptor, + PipelineCompatibilityToken pipelineCompatibilityToken); Ref AllocateBindGroup(Device* device, const BindGroupDescriptor* descriptor); void DeallocateBindGroup(BindGroup* bindGroup); private: - BindGroupLayout(DeviceBase* device, const BindGroupLayoutDescriptor* descriptor); + BindGroupLayout(DeviceBase* device, + const BindGroupLayoutDescriptor* descriptor, + PipelineCompatibilityToken pipelineCompatibilityToken); ~BindGroupLayout() override = default; SlabAllocator mBindGroupAllocator; diff --git a/src/dawn_native/metal/BindGroupLayoutMTL.mm b/src/dawn_native/metal/BindGroupLayoutMTL.mm index 535979bb83..5d748c1f78 100644 --- a/src/dawn_native/metal/BindGroupLayoutMTL.mm +++ b/src/dawn_native/metal/BindGroupLayoutMTL.mm @@ -19,14 +19,17 @@ namespace dawn_native { namespace metal { // static - Ref BindGroupLayout::Create(DeviceBase* device, - const BindGroupLayoutDescriptor* descriptor) { - return AcquireRef(new BindGroupLayout(device, descriptor)); + Ref BindGroupLayout::Create( + DeviceBase* device, + const BindGroupLayoutDescriptor* descriptor, + PipelineCompatibilityToken pipelineCompatibilityToken) { + return AcquireRef(new BindGroupLayout(device, descriptor, pipelineCompatibilityToken)); } BindGroupLayout::BindGroupLayout(DeviceBase* device, - const BindGroupLayoutDescriptor* descriptor) - : BindGroupLayoutBase(device, descriptor), + const BindGroupLayoutDescriptor* descriptor, + PipelineCompatibilityToken pipelineCompatibilityToken) + : BindGroupLayoutBase(device, descriptor, pipelineCompatibilityToken), mBindGroupAllocator(MakeFrontendBindGroupAllocator(4096)) { } diff --git a/src/dawn_native/metal/DeviceMTL.h b/src/dawn_native/metal/DeviceMTL.h index d1881e51e6..19b900b755 100644 --- a/src/dawn_native/metal/DeviceMTL.h +++ b/src/dawn_native/metal/DeviceMTL.h @@ -82,7 +82,8 @@ namespace dawn_native { namespace metal { ResultOrError> CreateBindGroupImpl( const BindGroupDescriptor* descriptor) override; ResultOrError> CreateBindGroupLayoutImpl( - const BindGroupLayoutDescriptor* descriptor) override; + const BindGroupLayoutDescriptor* descriptor, + PipelineCompatibilityToken pipelineCompatibilityToken) override; ResultOrError> CreateBufferImpl( const BufferDescriptor* descriptor) override; ResultOrError> CreateCommandBuffer( diff --git a/src/dawn_native/metal/DeviceMTL.mm b/src/dawn_native/metal/DeviceMTL.mm index 17c6ba98f1..348f5db312 100644 --- a/src/dawn_native/metal/DeviceMTL.mm +++ b/src/dawn_native/metal/DeviceMTL.mm @@ -213,8 +213,9 @@ namespace dawn_native { namespace metal { return BindGroup::Create(this, descriptor); } ResultOrError> Device::CreateBindGroupLayoutImpl( - const BindGroupLayoutDescriptor* descriptor) { - return BindGroupLayout::Create(this, descriptor); + const BindGroupLayoutDescriptor* descriptor, + PipelineCompatibilityToken pipelineCompatibilityToken) { + return BindGroupLayout::Create(this, descriptor, pipelineCompatibilityToken); } ResultOrError> Device::CreateBufferImpl(const BufferDescriptor* descriptor) { return Buffer::Create(this, descriptor); diff --git a/src/dawn_native/null/DeviceNull.cpp b/src/dawn_native/null/DeviceNull.cpp index 0c0b0d3d2e..d6b4d999b3 100644 --- a/src/dawn_native/null/DeviceNull.cpp +++ b/src/dawn_native/null/DeviceNull.cpp @@ -99,8 +99,9 @@ namespace dawn_native { namespace null { return AcquireRef(new BindGroup(this, descriptor)); } ResultOrError> Device::CreateBindGroupLayoutImpl( - const BindGroupLayoutDescriptor* descriptor) { - return AcquireRef(new BindGroupLayout(this, descriptor)); + const BindGroupLayoutDescriptor* descriptor, + PipelineCompatibilityToken pipelineCompatibilityToken) { + return AcquireRef(new BindGroupLayout(this, descriptor, pipelineCompatibilityToken)); } ResultOrError> Device::CreateBufferImpl(const BufferDescriptor* descriptor) { DAWN_TRY(IncrementMemoryUsage(descriptor->size)); diff --git a/src/dawn_native/null/DeviceNull.h b/src/dawn_native/null/DeviceNull.h index 0021056ccb..15bc75953a 100644 --- a/src/dawn_native/null/DeviceNull.h +++ b/src/dawn_native/null/DeviceNull.h @@ -125,7 +125,8 @@ namespace dawn_native { namespace null { ResultOrError> CreateBindGroupImpl( const BindGroupDescriptor* descriptor) override; ResultOrError> CreateBindGroupLayoutImpl( - const BindGroupLayoutDescriptor* descriptor) override; + const BindGroupLayoutDescriptor* descriptor, + PipelineCompatibilityToken pipelineCompatibilityToken) override; ResultOrError> CreateBufferImpl( const BufferDescriptor* descriptor) override; ResultOrError> CreateComputePipelineImpl( diff --git a/src/dawn_native/opengl/BindGroupLayoutGL.cpp b/src/dawn_native/opengl/BindGroupLayoutGL.cpp index 619e4e62ee..d008b1d48a 100644 --- a/src/dawn_native/opengl/BindGroupLayoutGL.cpp +++ b/src/dawn_native/opengl/BindGroupLayoutGL.cpp @@ -19,8 +19,9 @@ namespace dawn_native { namespace opengl { BindGroupLayout::BindGroupLayout(DeviceBase* device, - const BindGroupLayoutDescriptor* descriptor) - : BindGroupLayoutBase(device, descriptor), + const BindGroupLayoutDescriptor* descriptor, + PipelineCompatibilityToken pipelineCompatibilityToken) + : BindGroupLayoutBase(device, descriptor, pipelineCompatibilityToken), mBindGroupAllocator(MakeFrontendBindGroupAllocator(4096)) { } diff --git a/src/dawn_native/opengl/BindGroupLayoutGL.h b/src/dawn_native/opengl/BindGroupLayoutGL.h index edd1dd050b..136bd0a7e5 100644 --- a/src/dawn_native/opengl/BindGroupLayoutGL.h +++ b/src/dawn_native/opengl/BindGroupLayoutGL.h @@ -25,7 +25,9 @@ namespace dawn_native { namespace opengl { class BindGroupLayout final : public BindGroupLayoutBase { public: - BindGroupLayout(DeviceBase* device, const BindGroupLayoutDescriptor* descriptor); + BindGroupLayout(DeviceBase* device, + const BindGroupLayoutDescriptor* descriptor, + PipelineCompatibilityToken pipelineCompatibilityToken); Ref AllocateBindGroup(Device* device, const BindGroupDescriptor* descriptor); void DeallocateBindGroup(BindGroup* bindGroup); diff --git a/src/dawn_native/opengl/DeviceGL.cpp b/src/dawn_native/opengl/DeviceGL.cpp index 5d9ef310be..5f9a078af2 100644 --- a/src/dawn_native/opengl/DeviceGL.cpp +++ b/src/dawn_native/opengl/DeviceGL.cpp @@ -116,8 +116,9 @@ namespace dawn_native { namespace opengl { return BindGroup::Create(this, descriptor); } ResultOrError> Device::CreateBindGroupLayoutImpl( - const BindGroupLayoutDescriptor* descriptor) { - return AcquireRef(new BindGroupLayout(this, descriptor)); + const BindGroupLayoutDescriptor* descriptor, + PipelineCompatibilityToken pipelineCompatibilityToken) { + return AcquireRef(new BindGroupLayout(this, descriptor, pipelineCompatibilityToken)); } ResultOrError> Device::CreateBufferImpl(const BufferDescriptor* descriptor) { return AcquireRef(new Buffer(this, descriptor)); diff --git a/src/dawn_native/opengl/DeviceGL.h b/src/dawn_native/opengl/DeviceGL.h index 1bb16bc771..2a191fc364 100644 --- a/src/dawn_native/opengl/DeviceGL.h +++ b/src/dawn_native/opengl/DeviceGL.h @@ -87,7 +87,8 @@ namespace dawn_native { namespace opengl { ResultOrError> CreateBindGroupImpl( const BindGroupDescriptor* descriptor) override; ResultOrError> CreateBindGroupLayoutImpl( - const BindGroupLayoutDescriptor* descriptor) override; + const BindGroupLayoutDescriptor* descriptor, + PipelineCompatibilityToken pipelineCompatibilityToken) override; ResultOrError> CreateBufferImpl( const BufferDescriptor* descriptor) override; ResultOrError> CreateComputePipelineImpl( diff --git a/src/dawn_native/vulkan/BindGroupLayoutVk.cpp b/src/dawn_native/vulkan/BindGroupLayoutVk.cpp index 1e1b673c0d..53e636c604 100644 --- a/src/dawn_native/vulkan/BindGroupLayoutVk.cpp +++ b/src/dawn_native/vulkan/BindGroupLayoutVk.cpp @@ -78,8 +78,10 @@ namespace dawn_native { namespace vulkan { // static ResultOrError> BindGroupLayout::Create( Device* device, - const BindGroupLayoutDescriptor* descriptor) { - Ref bgl = AcquireRef(new BindGroupLayout(device, descriptor)); + const BindGroupLayoutDescriptor* descriptor, + PipelineCompatibilityToken pipelineCompatibilityToken) { + Ref bgl = + AcquireRef(new BindGroupLayout(device, descriptor, pipelineCompatibilityToken)); DAWN_TRY(bgl->Initialize()); return bgl; } @@ -139,8 +141,9 @@ namespace dawn_native { namespace vulkan { } BindGroupLayout::BindGroupLayout(DeviceBase* device, - const BindGroupLayoutDescriptor* descriptor) - : BindGroupLayoutBase(device, descriptor), + const BindGroupLayoutDescriptor* descriptor, + PipelineCompatibilityToken pipelineCompatibilityToken) + : BindGroupLayoutBase(device, descriptor, pipelineCompatibilityToken), mBindGroupAllocator(MakeFrontendBindGroupAllocator(4096)) { } diff --git a/src/dawn_native/vulkan/BindGroupLayoutVk.h b/src/dawn_native/vulkan/BindGroupLayoutVk.h index 72f8b698d7..0956b8ce33 100644 --- a/src/dawn_native/vulkan/BindGroupLayoutVk.h +++ b/src/dawn_native/vulkan/BindGroupLayoutVk.h @@ -47,9 +47,12 @@ namespace dawn_native { namespace vulkan { public: static ResultOrError> Create( Device* device, - const BindGroupLayoutDescriptor* descriptor); + const BindGroupLayoutDescriptor* descriptor, + PipelineCompatibilityToken pipelineCompatibilityToken); - BindGroupLayout(DeviceBase* device, const BindGroupLayoutDescriptor* descriptor); + BindGroupLayout(DeviceBase* device, + const BindGroupLayoutDescriptor* descriptor, + PipelineCompatibilityToken pipelineCompatibilityToken); VkDescriptorSetLayout GetHandle() const; diff --git a/src/dawn_native/vulkan/DeviceVk.cpp b/src/dawn_native/vulkan/DeviceVk.cpp index 9a2cf96575..0f368b89fc 100644 --- a/src/dawn_native/vulkan/DeviceVk.cpp +++ b/src/dawn_native/vulkan/DeviceVk.cpp @@ -108,8 +108,9 @@ namespace dawn_native { namespace vulkan { return BindGroup::Create(this, descriptor); } ResultOrError> Device::CreateBindGroupLayoutImpl( - const BindGroupLayoutDescriptor* descriptor) { - return BindGroupLayout::Create(this, descriptor); + const BindGroupLayoutDescriptor* descriptor, + PipelineCompatibilityToken pipelineCompatibilityToken) { + return BindGroupLayout::Create(this, descriptor, pipelineCompatibilityToken); } ResultOrError> Device::CreateBufferImpl(const BufferDescriptor* descriptor) { return Buffer::Create(this, descriptor); diff --git a/src/dawn_native/vulkan/DeviceVk.h b/src/dawn_native/vulkan/DeviceVk.h index d28cec3f13..e053ebf1c2 100644 --- a/src/dawn_native/vulkan/DeviceVk.h +++ b/src/dawn_native/vulkan/DeviceVk.h @@ -109,7 +109,8 @@ namespace dawn_native { namespace vulkan { ResultOrError> CreateBindGroupImpl( const BindGroupDescriptor* descriptor) override; ResultOrError> CreateBindGroupLayoutImpl( - const BindGroupLayoutDescriptor* descriptor) override; + const BindGroupLayoutDescriptor* descriptor, + PipelineCompatibilityToken pipelineCompatibilityToken) override; ResultOrError> CreateBufferImpl( const BufferDescriptor* descriptor) override; ResultOrError> CreateComputePipelineImpl( diff --git a/src/include/dawn_native/DawnNative.h b/src/include/dawn_native/DawnNative.h index 4281e0559a..77f46d740a 100644 --- a/src/include/dawn_native/DawnNative.h +++ b/src/include/dawn_native/DawnNative.h @@ -252,6 +252,9 @@ namespace dawn_native { DAWN_NATIVE_EXPORT uint64_t GetAllocatedSizeForTesting(WGPUBuffer buffer); + DAWN_NATIVE_EXPORT bool BindGroupLayoutBindingsEqualForTesting(WGPUBindGroupLayout a, + WGPUBindGroupLayout b); + } // namespace dawn_native #endif // DAWNNATIVE_DAWNNATIVE_H_ diff --git a/src/tests/end2end/ColorStateTests.cpp b/src/tests/end2end/ColorStateTests.cpp index fb7fe64985..478d61a491 100644 --- a/src/tests/end2end/ColorStateTests.cpp +++ b/src/tests/end2end/ColorStateTests.cpp @@ -30,6 +30,10 @@ class ColorStateTest : public DawnTest { void SetUp() override { DawnTest::SetUp(); + wgpu::BindGroupLayout bindGroupLayout = utils::MakeBindGroupLayout( + device, {{0, wgpu::ShaderStage::Fragment, wgpu::BufferBindingType::Uniform}}); + pipelineLayout = utils::MakePipelineLayout(device, {bindGroupLayout}); + // TODO(crbug.com/dawn/489): D3D12_Microsoft_Basic_Render_Driver_CPU // produces invalid results for these tests. DAWN_SUPPRESS_TEST_IF(IsD3D12() && IsWARP()); @@ -69,6 +73,7 @@ class ColorStateTest : public DawnTest { )"); utils::ComboRenderPipelineDescriptor baseDescriptor; + baseDescriptor.layout = pipelineLayout; baseDescriptor.vertex.module = vsModule; baseDescriptor.cFragment.module = fsModule; baseDescriptor.cTargets[0].format = renderPass.colorFormat; @@ -76,6 +81,7 @@ class ColorStateTest : public DawnTest { basePipeline = device.CreateRenderPipeline(&baseDescriptor); utils::ComboRenderPipelineDescriptor testDescriptor; + testDescriptor.layout = pipelineLayout; testDescriptor.vertex.module = vsModule; testDescriptor.cFragment.module = fsModule; testDescriptor.cTargets[0] = colorTargetState; @@ -205,6 +211,7 @@ class ColorStateTest : public DawnTest { alphaFactor, tests); } + wgpu::PipelineLayout pipelineLayout; utils::BasicRenderPass renderPass; wgpu::RenderPipeline basePipeline; wgpu::RenderPipeline testPipeline; @@ -811,6 +818,7 @@ TEST_P(ColorStateTest, IndependentColorState) { )"); utils::ComboRenderPipelineDescriptor baseDescriptor; + baseDescriptor.layout = pipelineLayout; baseDescriptor.vertex.module = vsModule; baseDescriptor.cFragment.module = fsModule; baseDescriptor.cFragment.targetCount = 4; @@ -818,6 +826,7 @@ TEST_P(ColorStateTest, IndependentColorState) { basePipeline = device.CreateRenderPipeline(&baseDescriptor); utils::ComboRenderPipelineDescriptor testDescriptor; + testDescriptor.layout = pipelineLayout; testDescriptor.vertex.module = vsModule; testDescriptor.cFragment.module = fsModule; testDescriptor.cFragment.targetCount = 4; @@ -918,6 +927,7 @@ TEST_P(ColorStateTest, DefaultBlendColor) { )"); utils::ComboRenderPipelineDescriptor baseDescriptor; + baseDescriptor.layout = pipelineLayout; baseDescriptor.vertex.module = vsModule; baseDescriptor.cFragment.module = fsModule; baseDescriptor.cTargets[0].format = renderPass.colorFormat; @@ -925,6 +935,7 @@ TEST_P(ColorStateTest, DefaultBlendColor) { basePipeline = device.CreateRenderPipeline(&baseDescriptor); utils::ComboRenderPipelineDescriptor testDescriptor; + testDescriptor.layout = pipelineLayout; testDescriptor.vertex.module = vsModule; testDescriptor.cFragment.module = fsModule; testDescriptor.cTargets[0].format = renderPass.colorFormat; @@ -1042,6 +1053,7 @@ TEST_P(ColorStateTest, ColorWriteMaskDoesNotAffectRenderPassLoadOpClear) { )"); utils::ComboRenderPipelineDescriptor baseDescriptor; + baseDescriptor.layout = pipelineLayout; baseDescriptor.vertex.module = vsModule; baseDescriptor.cFragment.module = fsModule; baseDescriptor.cTargets[0].format = renderPass.colorFormat; @@ -1049,6 +1061,7 @@ TEST_P(ColorStateTest, ColorWriteMaskDoesNotAffectRenderPassLoadOpClear) { basePipeline = device.CreateRenderPipeline(&baseDescriptor); utils::ComboRenderPipelineDescriptor testDescriptor; + testDescriptor.layout = pipelineLayout; testDescriptor.vertex.module = vsModule; testDescriptor.cFragment.module = fsModule; testDescriptor.cTargets[0].format = renderPass.colorFormat; diff --git a/src/tests/end2end/CreatePipelineAsyncTests.cpp b/src/tests/end2end/CreatePipelineAsyncTests.cpp index 2023884b56..e209ebac8c 100644 --- a/src/tests/end2end/CreatePipelineAsyncTests.cpp +++ b/src/tests/end2end/CreatePipelineAsyncTests.cpp @@ -348,7 +348,25 @@ TEST_P(CreatePipelineAsyncTest, CreateSameComputePipelineTwice) { // Verify creating compute pipeline with same descriptor and CreateComputePipelineAsync() at the // same time works correctly. TEST_P(CreatePipelineAsyncTest, CreateSamePipelineTwiceAtSameTime) { + wgpu::BindGroupLayoutEntry binding = {}; + binding.binding = 0; + binding.buffer.type = wgpu::BufferBindingType::Storage; + binding.visibility = wgpu::ShaderStage::Compute; + + wgpu::BindGroupLayoutDescriptor desc = {}; + desc.entryCount = 1; + desc.entries = &binding; + + wgpu::BindGroupLayout bindGroupLayout = device.CreateBindGroupLayout(&desc); + + wgpu::PipelineLayoutDescriptor pipelineLayoutDesc = {}; + pipelineLayoutDesc.bindGroupLayoutCount = 1; + pipelineLayoutDesc.bindGroupLayouts = &bindGroupLayout; + + wgpu::PipelineLayout pipelineLayout = device.CreatePipelineLayout(&pipelineLayoutDesc); + wgpu::ComputePipelineDescriptor csDesc; + csDesc.layout = pipelineLayout; csDesc.compute.module = utils::CreateShaderModule(device, R"( [[block]] struct SSBO { value : u32; diff --git a/src/tests/end2end/EntryPointTests.cpp b/src/tests/end2end/EntryPointTests.cpp index b951341ce8..5b760c5d17 100644 --- a/src/tests/end2end/EntryPointTests.cpp +++ b/src/tests/end2end/EntryPointTests.cpp @@ -60,6 +60,23 @@ TEST_P(EntryPointTests, FragAndVertexSameModule) { // Test creating two compute pipelines from the same module. TEST_P(EntryPointTests, TwoComputeInModule) { + wgpu::BindGroupLayoutEntry binding = {}; + binding.binding = 0; + binding.buffer.type = wgpu::BufferBindingType::Storage; + binding.visibility = wgpu::ShaderStage::Compute; + + wgpu::BindGroupLayoutDescriptor desc = {}; + desc.entryCount = 1; + desc.entries = &binding; + + wgpu::BindGroupLayout bindGroupLayout = device.CreateBindGroupLayout(&desc); + + wgpu::PipelineLayoutDescriptor pipelineLayoutDesc = {}; + pipelineLayoutDesc.bindGroupLayoutCount = 1; + pipelineLayoutDesc.bindGroupLayouts = &bindGroupLayout; + + wgpu::PipelineLayout pipelineLayout = device.CreatePipelineLayout(&pipelineLayoutDesc); + wgpu::ShaderModule module = utils::CreateShaderModule(device, R"( [[block]] struct Data { data : u32; @@ -79,6 +96,7 @@ TEST_P(EntryPointTests, TwoComputeInModule) { // Create both pipelines from the module. wgpu::ComputePipelineDescriptor pipelineDesc; + pipelineDesc.layout = pipelineLayout; pipelineDesc.compute.module = module; pipelineDesc.compute.entryPoint = "write1"; @@ -93,8 +111,7 @@ TEST_P(EntryPointTests, TwoComputeInModule) { bufferDesc.usage = wgpu::BufferUsage::Storage | wgpu::BufferUsage::CopySrc; wgpu::Buffer buffer = device.CreateBuffer(&bufferDesc); - wgpu::BindGroup group = - utils::MakeBindGroup(device, write1.GetBindGroupLayout(0), {{0, buffer}}); + wgpu::BindGroup group = utils::MakeBindGroup(device, bindGroupLayout, {{0, buffer}}); // Use the first pipeline and check it wrote 1. { diff --git a/src/tests/unittests/validation/GetBindGroupLayoutValidationTests.cpp b/src/tests/unittests/validation/GetBindGroupLayoutValidationTests.cpp index 7fddceade2..45ef7c8edb 100644 --- a/src/tests/unittests/validation/GetBindGroupLayoutValidationTests.cpp +++ b/src/tests/unittests/validation/GetBindGroupLayoutValidationTests.cpp @@ -95,6 +95,21 @@ TEST_F(GetBindGroupLayoutTests, SameObject) { EXPECT_NE(pipeline.GetBindGroupLayout(0).Get(), pipeline.GetBindGroupLayout(2).Get()); } +// Test that default BindGroupLayouts cannot be used in the creation of a new PipelineLayout +TEST_F(GetBindGroupLayoutTests, DefaultBindGroupLayoutPipelineCompatibility) { + wgpu::RenderPipeline pipeline = RenderPipelineFromFragmentShader(R"( + [[block]] struct S { + pos : vec4; + }; + [[group(0), binding(0)]] var uniforms : S; + + [[stage(fragment)]] fn main() { + var pos : vec4 = uniforms.pos; + })"); + + ASSERT_DEVICE_ERROR(utils::MakePipelineLayout(device, {pipeline.GetBindGroupLayout(0)})); +} + // Test that getBindGroupLayout defaults are correct // - shader stage visibility is the stage that adds the binding. // - dynamic offsets is false @@ -123,10 +138,11 @@ TEST_F(GetBindGroupLayoutTests, DefaultShaderStageAndDynamicOffsets) { desc.entryCount = 1; desc.entries = &binding; - // Check that visibility and dynamic offsets match + // Check that an otherwise compatible bind group layout doesn't match one created as part of a + // default pipeline layout. binding.buffer.hasDynamicOffset = false; binding.visibility = wgpu::ShaderStage::Fragment; - EXPECT_EQ(device.CreateBindGroupLayout(&desc).Get(), pipeline.GetBindGroupLayout(0).Get()); + EXPECT_NE(device.CreateBindGroupLayout(&desc).Get(), pipeline.GetBindGroupLayout(0).Get()); // Check that any change in visibility doesn't match. binding.visibility = wgpu::ShaderStage::Vertex; @@ -220,42 +236,52 @@ TEST_F(GetBindGroupLayoutTests, DefaultTextureSampleType) { }; // Textures not used default to non-filtering - EXPECT_EQ(BGLFromModules(emptyVertexModule, unusedTextureFragmentModule).Get(), - nonFilteringBGL.Get()); - EXPECT_NE(BGLFromModules(emptyVertexModule, unusedTextureFragmentModule).Get(), - filteringBGL.Get()); + EXPECT_TRUE(dawn_native::BindGroupLayoutBindingsEqualForTesting( + BGLFromModules(emptyVertexModule, unusedTextureFragmentModule).Get(), + nonFilteringBGL.Get())); + EXPECT_FALSE(dawn_native::BindGroupLayoutBindingsEqualForTesting( + BGLFromModules(emptyVertexModule, unusedTextureFragmentModule).Get(), filteringBGL.Get())); // Textures used with textureLoad default to non-filtering - EXPECT_EQ(BGLFromModules(emptyVertexModule, textureLoadFragmentModule).Get(), - nonFilteringBGL.Get()); - EXPECT_NE(BGLFromModules(emptyVertexModule, textureLoadFragmentModule).Get(), - filteringBGL.Get()); + EXPECT_TRUE(dawn_native::BindGroupLayoutBindingsEqualForTesting( + BGLFromModules(emptyVertexModule, textureLoadFragmentModule).Get(), nonFilteringBGL.Get())); + EXPECT_FALSE(dawn_native::BindGroupLayoutBindingsEqualForTesting( + BGLFromModules(emptyVertexModule, textureLoadFragmentModule).Get(), filteringBGL.Get())); // Textures used with textureLoad on both stages default to non-filtering - EXPECT_EQ(BGLFromModules(textureLoadVertexModule, textureLoadFragmentModule).Get(), - nonFilteringBGL.Get()); - EXPECT_NE(BGLFromModules(textureLoadVertexModule, textureLoadFragmentModule).Get(), - filteringBGL.Get()); + EXPECT_TRUE(dawn_native::BindGroupLayoutBindingsEqualForTesting( + BGLFromModules(textureLoadVertexModule, textureLoadFragmentModule).Get(), + nonFilteringBGL.Get())); + EXPECT_FALSE(dawn_native::BindGroupLayoutBindingsEqualForTesting( + BGLFromModules(textureLoadVertexModule, textureLoadFragmentModule).Get(), + filteringBGL.Get())); // Textures used with textureSample default to filtering - EXPECT_NE(BGLFromModules(emptyVertexModule, textureSampleFragmentModule).Get(), - nonFilteringBGL.Get()); - EXPECT_EQ(BGLFromModules(emptyVertexModule, textureSampleFragmentModule).Get(), - filteringBGL.Get()); - EXPECT_NE(BGLFromModules(textureSampleVertexModule, unusedTextureFragmentModule).Get(), - nonFilteringBGL.Get()); - EXPECT_EQ(BGLFromModules(textureSampleVertexModule, unusedTextureFragmentModule).Get(), - filteringBGL.Get()); + EXPECT_FALSE(dawn_native::BindGroupLayoutBindingsEqualForTesting( + BGLFromModules(emptyVertexModule, textureSampleFragmentModule).Get(), + nonFilteringBGL.Get())); + EXPECT_TRUE(dawn_native::BindGroupLayoutBindingsEqualForTesting( + BGLFromModules(emptyVertexModule, textureSampleFragmentModule).Get(), filteringBGL.Get())); + EXPECT_FALSE(dawn_native::BindGroupLayoutBindingsEqualForTesting( + BGLFromModules(textureSampleVertexModule, unusedTextureFragmentModule).Get(), + nonFilteringBGL.Get())); + EXPECT_TRUE(dawn_native::BindGroupLayoutBindingsEqualForTesting( + BGLFromModules(textureSampleVertexModule, unusedTextureFragmentModule).Get(), + filteringBGL.Get())); // Textures used with both textureLoad and textureSample default to filtering - EXPECT_NE(BGLFromModules(textureLoadVertexModule, textureSampleFragmentModule).Get(), - nonFilteringBGL.Get()); - EXPECT_EQ(BGLFromModules(textureLoadVertexModule, textureSampleFragmentModule).Get(), - filteringBGL.Get()); - EXPECT_NE(BGLFromModules(textureSampleVertexModule, textureLoadFragmentModule).Get(), - nonFilteringBGL.Get()); - EXPECT_EQ(BGLFromModules(textureSampleVertexModule, textureLoadFragmentModule).Get(), - filteringBGL.Get()); + EXPECT_FALSE(dawn_native::BindGroupLayoutBindingsEqualForTesting( + BGLFromModules(textureLoadVertexModule, textureSampleFragmentModule).Get(), + nonFilteringBGL.Get())); + EXPECT_TRUE(dawn_native::BindGroupLayoutBindingsEqualForTesting( + BGLFromModules(textureLoadVertexModule, textureSampleFragmentModule).Get(), + filteringBGL.Get())); + EXPECT_FALSE(dawn_native::BindGroupLayoutBindingsEqualForTesting( + BGLFromModules(textureSampleVertexModule, textureLoadFragmentModule).Get(), + nonFilteringBGL.Get())); + EXPECT_TRUE(dawn_native::BindGroupLayoutBindingsEqualForTesting( + BGLFromModules(textureSampleVertexModule, textureLoadFragmentModule).Get(), + filteringBGL.Get())); } // Test GetBindGroupLayout works with a compute pipeline @@ -293,7 +319,8 @@ TEST_F(GetBindGroupLayoutTests, ComputePipeline) { desc.entryCount = 1; desc.entries = &binding; - EXPECT_EQ(device.CreateBindGroupLayout(&desc).Get(), pipeline.GetBindGroupLayout(0).Get()); + EXPECT_TRUE(dawn_native::BindGroupLayoutBindingsEqualForTesting( + device.CreateBindGroupLayout(&desc).Get(), pipeline.GetBindGroupLayout(0).Get())); } // Test that the binding type matches the shader. @@ -326,7 +353,8 @@ TEST_F(GetBindGroupLayoutTests, BindingType) { [[stage(fragment)]] fn main() { var pos : vec4 = ssbo.pos; })"); - EXPECT_EQ(device.CreateBindGroupLayout(&desc).Get(), pipeline.GetBindGroupLayout(0).Get()); + EXPECT_TRUE(dawn_native::BindGroupLayoutBindingsEqualForTesting( + device.CreateBindGroupLayout(&desc).Get(), pipeline.GetBindGroupLayout(0).Get())); } { binding.buffer.type = wgpu::BufferBindingType::Uniform; @@ -339,7 +367,8 @@ TEST_F(GetBindGroupLayoutTests, BindingType) { [[stage(fragment)]] fn main() { var pos : vec4 = uniforms.pos; })"); - EXPECT_EQ(device.CreateBindGroupLayout(&desc).Get(), pipeline.GetBindGroupLayout(0).Get()); + EXPECT_TRUE(dawn_native::BindGroupLayoutBindingsEqualForTesting( + device.CreateBindGroupLayout(&desc).Get(), pipeline.GetBindGroupLayout(0).Get())); } { @@ -353,7 +382,8 @@ TEST_F(GetBindGroupLayoutTests, BindingType) { [[stage(fragment)]] fn main() { var pos : vec4 = ssbo.pos; })"); - EXPECT_EQ(device.CreateBindGroupLayout(&desc).Get(), pipeline.GetBindGroupLayout(0).Get()); + EXPECT_TRUE(dawn_native::BindGroupLayoutBindingsEqualForTesting( + device.CreateBindGroupLayout(&desc).Get(), pipeline.GetBindGroupLayout(0).Get())); } binding.buffer.type = wgpu::BufferBindingType::Undefined; @@ -366,7 +396,8 @@ TEST_F(GetBindGroupLayoutTests, BindingType) { [[stage(fragment)]] fn main() { ignore(textureDimensions(myTexture)); })"); - EXPECT_EQ(device.CreateBindGroupLayout(&desc).Get(), pipeline.GetBindGroupLayout(0).Get()); + EXPECT_TRUE(dawn_native::BindGroupLayoutBindingsEqualForTesting( + device.CreateBindGroupLayout(&desc).Get(), pipeline.GetBindGroupLayout(0).Get())); } { @@ -377,7 +408,8 @@ TEST_F(GetBindGroupLayoutTests, BindingType) { [[stage(fragment)]] fn main() { ignore(textureDimensions(myTexture)); })"); - EXPECT_EQ(device.CreateBindGroupLayout(&desc).Get(), pipeline.GetBindGroupLayout(0).Get()); + EXPECT_TRUE(dawn_native::BindGroupLayoutBindingsEqualForTesting( + device.CreateBindGroupLayout(&desc).Get(), pipeline.GetBindGroupLayout(0).Get())); } binding.texture.sampleType = wgpu::TextureSampleType::Undefined; @@ -389,7 +421,8 @@ TEST_F(GetBindGroupLayoutTests, BindingType) { [[stage(fragment)]] fn main() { ignore(mySampler); })"); - EXPECT_EQ(device.CreateBindGroupLayout(&desc).Get(), pipeline.GetBindGroupLayout(0).Get()); + EXPECT_TRUE(dawn_native::BindGroupLayoutBindingsEqualForTesting( + device.CreateBindGroupLayout(&desc).Get(), pipeline.GetBindGroupLayout(0).Get())); } } @@ -416,7 +449,8 @@ TEST_F(GetBindGroupLayoutTests, ExternalTextureBindingType) { [[stage(fragment)]] fn main() { ignore(myExternalTexture); })"); - EXPECT_EQ(device.CreateBindGroupLayout(&desc).Get(), pipeline.GetBindGroupLayout(0).Get()); + EXPECT_TRUE(dawn_native::BindGroupLayoutBindingsEqualForTesting( + device.CreateBindGroupLayout(&desc).Get(), pipeline.GetBindGroupLayout(0).Get())); } // Test that texture view dimension matches the shader. @@ -443,7 +477,8 @@ TEST_F(GetBindGroupLayoutTests, ViewDimension) { [[stage(fragment)]] fn main() { ignore(textureDimensions(myTexture)); })"); - EXPECT_EQ(device.CreateBindGroupLayout(&desc).Get(), pipeline.GetBindGroupLayout(0).Get()); + EXPECT_TRUE(dawn_native::BindGroupLayoutBindingsEqualForTesting( + device.CreateBindGroupLayout(&desc).Get(), pipeline.GetBindGroupLayout(0).Get())); } { @@ -454,7 +489,8 @@ TEST_F(GetBindGroupLayoutTests, ViewDimension) { [[stage(fragment)]] fn main() { ignore(textureDimensions(myTexture)); })"); - EXPECT_EQ(device.CreateBindGroupLayout(&desc).Get(), pipeline.GetBindGroupLayout(0).Get()); + EXPECT_TRUE(dawn_native::BindGroupLayoutBindingsEqualForTesting( + device.CreateBindGroupLayout(&desc).Get(), pipeline.GetBindGroupLayout(0).Get())); } { @@ -465,7 +501,8 @@ TEST_F(GetBindGroupLayoutTests, ViewDimension) { [[stage(fragment)]] fn main() { ignore(textureDimensions(myTexture)); })"); - EXPECT_EQ(device.CreateBindGroupLayout(&desc).Get(), pipeline.GetBindGroupLayout(0).Get()); + EXPECT_TRUE(dawn_native::BindGroupLayoutBindingsEqualForTesting( + device.CreateBindGroupLayout(&desc).Get(), pipeline.GetBindGroupLayout(0).Get())); } { @@ -476,7 +513,8 @@ TEST_F(GetBindGroupLayoutTests, ViewDimension) { [[stage(fragment)]] fn main() { ignore(textureDimensions(myTexture)); })"); - EXPECT_EQ(device.CreateBindGroupLayout(&desc).Get(), pipeline.GetBindGroupLayout(0).Get()); + EXPECT_TRUE(dawn_native::BindGroupLayoutBindingsEqualForTesting( + device.CreateBindGroupLayout(&desc).Get(), pipeline.GetBindGroupLayout(0).Get())); } { @@ -487,7 +525,8 @@ TEST_F(GetBindGroupLayoutTests, ViewDimension) { [[stage(fragment)]] fn main() { ignore(textureDimensions(myTexture)); })"); - EXPECT_EQ(device.CreateBindGroupLayout(&desc).Get(), pipeline.GetBindGroupLayout(0).Get()); + EXPECT_TRUE(dawn_native::BindGroupLayoutBindingsEqualForTesting( + device.CreateBindGroupLayout(&desc).Get(), pipeline.GetBindGroupLayout(0).Get())); } { @@ -498,7 +537,8 @@ TEST_F(GetBindGroupLayoutTests, ViewDimension) { [[stage(fragment)]] fn main() { ignore(textureDimensions(myTexture)); })"); - EXPECT_EQ(device.CreateBindGroupLayout(&desc).Get(), pipeline.GetBindGroupLayout(0).Get()); + EXPECT_TRUE(dawn_native::BindGroupLayoutBindingsEqualForTesting( + device.CreateBindGroupLayout(&desc).Get(), pipeline.GetBindGroupLayout(0).Get())); } } @@ -525,7 +565,8 @@ TEST_F(GetBindGroupLayoutTests, TextureComponentType) { [[stage(fragment)]] fn main() { ignore(textureDimensions(myTexture)); })"); - EXPECT_EQ(device.CreateBindGroupLayout(&desc).Get(), pipeline.GetBindGroupLayout(0).Get()); + EXPECT_TRUE(dawn_native::BindGroupLayoutBindingsEqualForTesting( + device.CreateBindGroupLayout(&desc).Get(), pipeline.GetBindGroupLayout(0).Get())); } { @@ -536,7 +577,8 @@ TEST_F(GetBindGroupLayoutTests, TextureComponentType) { [[stage(fragment)]] fn main() { ignore(textureDimensions(myTexture)); })"); - EXPECT_EQ(device.CreateBindGroupLayout(&desc).Get(), pipeline.GetBindGroupLayout(0).Get()); + EXPECT_TRUE(dawn_native::BindGroupLayoutBindingsEqualForTesting( + device.CreateBindGroupLayout(&desc).Get(), pipeline.GetBindGroupLayout(0).Get())); } { @@ -547,7 +589,8 @@ TEST_F(GetBindGroupLayoutTests, TextureComponentType) { [[stage(fragment)]] fn main() { ignore(textureDimensions(myTexture)); })"); - EXPECT_EQ(device.CreateBindGroupLayout(&desc).Get(), pipeline.GetBindGroupLayout(0).Get()); + EXPECT_TRUE(dawn_native::BindGroupLayoutBindingsEqualForTesting( + device.CreateBindGroupLayout(&desc).Get(), pipeline.GetBindGroupLayout(0).Get())); } } @@ -579,7 +622,8 @@ TEST_F(GetBindGroupLayoutTests, BindingIndices) { [[stage(fragment)]] fn main() { var pos : vec4 = uniforms.pos; })"); - EXPECT_EQ(device.CreateBindGroupLayout(&desc).Get(), pipeline.GetBindGroupLayout(0).Get()); + EXPECT_TRUE(dawn_native::BindGroupLayoutBindingsEqualForTesting( + device.CreateBindGroupLayout(&desc).Get(), pipeline.GetBindGroupLayout(0).Get())); } { @@ -593,7 +637,8 @@ TEST_F(GetBindGroupLayoutTests, BindingIndices) { [[stage(fragment)]] fn main() { var pos : vec4 = uniforms.pos; })"); - EXPECT_EQ(device.CreateBindGroupLayout(&desc).Get(), pipeline.GetBindGroupLayout(0).Get()); + EXPECT_TRUE(dawn_native::BindGroupLayoutBindingsEqualForTesting( + device.CreateBindGroupLayout(&desc).Get(), pipeline.GetBindGroupLayout(0).Get())); } { @@ -607,7 +652,8 @@ TEST_F(GetBindGroupLayoutTests, BindingIndices) { [[stage(fragment)]] fn main() { var pos : vec4 = uniforms.pos; })"); - EXPECT_NE(device.CreateBindGroupLayout(&desc).Get(), pipeline.GetBindGroupLayout(0).Get()); + EXPECT_FALSE(dawn_native::BindGroupLayoutBindingsEqualForTesting( + device.CreateBindGroupLayout(&desc).Get(), pipeline.GetBindGroupLayout(0).Get())); } } @@ -718,7 +764,8 @@ TEST_F(GetBindGroupLayoutTests, MinBufferSize) { descriptor.vertex.module = vsModule4; descriptor.cFragment.module = fsModule4; wgpu::RenderPipeline pipeline = device.CreateRenderPipeline(&descriptor); - EXPECT_EQ(pipeline.GetBindGroupLayout(0).Get(), bgl4.Get()); + EXPECT_TRUE(dawn_native::BindGroupLayoutBindingsEqualForTesting( + pipeline.GetBindGroupLayout(0).Get(), bgl4.Get())); } // Check that the max is taken between 4 and 64. @@ -726,7 +773,8 @@ TEST_F(GetBindGroupLayoutTests, MinBufferSize) { descriptor.vertex.module = vsModule64; descriptor.cFragment.module = fsModule4; wgpu::RenderPipeline pipeline = device.CreateRenderPipeline(&descriptor); - EXPECT_EQ(pipeline.GetBindGroupLayout(0).Get(), bgl64.Get()); + EXPECT_TRUE(dawn_native::BindGroupLayoutBindingsEqualForTesting( + pipeline.GetBindGroupLayout(0).Get(), bgl64.Get())); } // Check that the order doesn't change that the max is taken. @@ -734,7 +782,8 @@ TEST_F(GetBindGroupLayoutTests, MinBufferSize) { descriptor.vertex.module = vsModule4; descriptor.cFragment.module = fsModule64; wgpu::RenderPipeline pipeline = device.CreateRenderPipeline(&descriptor); - EXPECT_EQ(pipeline.GetBindGroupLayout(0).Get(), bgl64.Get()); + EXPECT_TRUE(dawn_native::BindGroupLayoutBindingsEqualForTesting( + pipeline.GetBindGroupLayout(0).Get(), bgl64.Get())); } } @@ -787,7 +836,8 @@ TEST_F(GetBindGroupLayoutTests, StageAggregation) { wgpu::RenderPipeline pipeline = device.CreateRenderPipeline(&descriptor); binding.visibility = wgpu::ShaderStage::Vertex; - EXPECT_EQ(pipeline.GetBindGroupLayout(0).Get(), device.CreateBindGroupLayout(&desc).Get()); + EXPECT_TRUE(dawn_native::BindGroupLayoutBindingsEqualForTesting( + pipeline.GetBindGroupLayout(0).Get(), device.CreateBindGroupLayout(&desc).Get())); } // Check with only the fragment shader using the sampler @@ -797,7 +847,8 @@ TEST_F(GetBindGroupLayoutTests, StageAggregation) { wgpu::RenderPipeline pipeline = device.CreateRenderPipeline(&descriptor); binding.visibility = wgpu::ShaderStage::Fragment; - EXPECT_EQ(pipeline.GetBindGroupLayout(0).Get(), device.CreateBindGroupLayout(&desc).Get()); + EXPECT_TRUE(dawn_native::BindGroupLayoutBindingsEqualForTesting( + pipeline.GetBindGroupLayout(0).Get(), device.CreateBindGroupLayout(&desc).Get())); } // Check with both shaders using the sampler @@ -807,7 +858,8 @@ TEST_F(GetBindGroupLayoutTests, StageAggregation) { wgpu::RenderPipeline pipeline = device.CreateRenderPipeline(&descriptor); binding.visibility = wgpu::ShaderStage::Fragment | wgpu::ShaderStage::Vertex; - EXPECT_EQ(pipeline.GetBindGroupLayout(0).Get(), device.CreateBindGroupLayout(&desc).Get()); + EXPECT_TRUE(dawn_native::BindGroupLayoutBindingsEqualForTesting( + pipeline.GetBindGroupLayout(0).Get(), device.CreateBindGroupLayout(&desc).Get())); } } @@ -955,10 +1007,14 @@ TEST_F(GetBindGroupLayoutTests, UnusedIndex) { wgpu::BindGroupLayout emptyBindGroupLayout = device.CreateBindGroupLayout(&desc); - EXPECT_NE(pipeline.GetBindGroupLayout(0).Get(), emptyBindGroupLayout.Get()); // Used - EXPECT_EQ(pipeline.GetBindGroupLayout(1).Get(), emptyBindGroupLayout.Get()); // Not Used. - EXPECT_NE(pipeline.GetBindGroupLayout(2).Get(), emptyBindGroupLayout.Get()); // Used. - EXPECT_EQ(pipeline.GetBindGroupLayout(3).Get(), emptyBindGroupLayout.Get()); // Not used + EXPECT_FALSE(dawn_native::BindGroupLayoutBindingsEqualForTesting( + pipeline.GetBindGroupLayout(0).Get(), emptyBindGroupLayout.Get())); // Used + EXPECT_TRUE(dawn_native::BindGroupLayoutBindingsEqualForTesting( + pipeline.GetBindGroupLayout(1).Get(), emptyBindGroupLayout.Get())); // Not Used. + EXPECT_FALSE(dawn_native::BindGroupLayoutBindingsEqualForTesting( + pipeline.GetBindGroupLayout(2).Get(), emptyBindGroupLayout.Get())); // Used. + EXPECT_TRUE(dawn_native::BindGroupLayoutBindingsEqualForTesting( + pipeline.GetBindGroupLayout(3).Get(), emptyBindGroupLayout.Get())); // Not used } // Test that after explicitly creating a pipeline with a pipeline layout, calling