Update default pipeline layout compatibility rules

Prevents bind group layouts created by a default pipeline layout from
being reusable with any other pipelines or layouts, as detailed in
https://github.com/gpuweb/gpuweb/pull/2068

Change-Id: Ic398eb6c6e089ac63ce6650f125dd20a9dfc8862
Bug: dawn:1094
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/63220
Commit-Queue: Brandon Jones <bajones@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
This commit is contained in:
Brandon Jones 2021-09-01 22:15:41 +00:00 committed by Dawn LUCI CQ
parent baf8df396c
commit 1f48c97353
31 changed files with 336 additions and 127 deletions

View File

@ -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<BindGroupLayoutEntry> 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<ObjectBase> ----------|

View File

@ -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

View File

@ -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<const BufferBase*>(buffer)->GetAllocatedSize();
}
bool BindGroupLayoutBindingsEqualForTesting(WGPUBindGroupLayout a, WGPUBindGroupLayout b) {
BindGroupLayoutBase* aBase = reinterpret_cast<BindGroupLayoutBase*>(a);
BindGroupLayoutBase* bBase = reinterpret_cast<BindGroupLayoutBase*>(b);
bool excludePipelineCompatibiltyToken = true;
return aBase->IsLayoutEqual(bBase, excludePipelineCompatibiltyToken);
}
} // namespace dawn_native

View File

@ -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<Ref<BindGroupLayoutBase>> 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

View File

@ -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<Ref<BindGroupLayoutBase>> 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<Ref<BindGroupBase>> CreateBindGroupImpl(
const BindGroupDescriptor* descriptor) = 0;
virtual ResultOrError<Ref<BindGroupLayoutBase>> CreateBindGroupLayoutImpl(
const BindGroupLayoutDescriptor* descriptor) = 0;
const BindGroupLayoutDescriptor* descriptor,
PipelineCompatibilityToken pipelineCompatibilityToken) = 0;
virtual ResultOrError<Ref<BufferBase>> CreateBufferImpl(
const BufferDescriptor* descriptor) = 0;
virtual ResultOrError<Ref<ComputePipelineBase>> CreateComputePipelineImpl(
@ -449,6 +453,7 @@ namespace dawn_native {
TogglesSet mEnabledToggles;
TogglesSet mOverridenToggles;
size_t mLazyClearCountForTesting = 0;
std::atomic_uint64_t mNextPipelineCompatibilityToken;
ExtensionsSet mEnabledExtensions;

View File

@ -64,6 +64,12 @@ namespace dawn_native {
using ExecutionSerial = TypedInteger<struct QueueSerialT, uint64_t>;
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<struct PipelineCompatibilityTokenT, uint64_t>;
} // namespace dawn_native
#endif // DAWNNATIVE_INTEGERTYPES_H_

View File

@ -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<Ref<BindGroupLayoutBase>> {
auto CreateBGL = [](DeviceBase* device, const EntryMap& entries,
PipelineCompatibilityToken pipelineCompatibilityToken)
-> ResultOrError<Ref<BindGroupLayoutBase>> {
std::vector<BindGroupLayoutEntry> 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<BindGroupIndex, Ref<BindGroupLayoutBase>, 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<uint32_t>(pipelineBGLCount);
DAWN_TRY(ValidatePipelineLayoutDescriptor(device, &desc));
DAWN_TRY(ValidatePipelineLayoutDescriptor(device, &desc, pipelineCompatibilityToken));
Ref<PipelineLayoutBase> result;
DAWN_TRY_ASSIGN(result, device->GetOrCreatePipelineLayout(&desc));

View File

@ -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<BindGroupIndex, Ref<BindGroupLayoutBase>, kMaxBindGroups>;

View File

@ -59,13 +59,17 @@ namespace dawn_native { namespace d3d12 {
} // anonymous namespace
// static
Ref<BindGroupLayout> BindGroupLayout::Create(Device* device,
const BindGroupLayoutDescriptor* descriptor) {
return AcquireRef(new BindGroupLayout(device, descriptor));
Ref<BindGroupLayout> 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),

View File

@ -38,7 +38,8 @@ namespace dawn_native { namespace d3d12 {
class BindGroupLayout final : public BindGroupLayoutBase {
public:
static Ref<BindGroupLayout> Create(Device* device,
const BindGroupLayoutDescriptor* descriptor);
const BindGroupLayoutDescriptor* descriptor,
PipelineCompatibilityToken pipelineCompatibilityToken);
ResultOrError<Ref<BindGroup>> AllocateBindGroup(Device* device,
const BindGroupDescriptor* descriptor);
@ -60,7 +61,9 @@ namespace dawn_native { namespace d3d12 {
const std::vector<D3D12_DESCRIPTOR_RANGE>& 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

View File

@ -319,8 +319,9 @@ namespace dawn_native { namespace d3d12 {
return BindGroup::Create(this, descriptor);
}
ResultOrError<Ref<BindGroupLayoutBase>> Device::CreateBindGroupLayoutImpl(
const BindGroupLayoutDescriptor* descriptor) {
return BindGroupLayout::Create(this, descriptor);
const BindGroupLayoutDescriptor* descriptor,
PipelineCompatibilityToken pipelineCompatibilityToken) {
return BindGroupLayout::Create(this, descriptor, pipelineCompatibilityToken);
}
ResultOrError<Ref<BufferBase>> Device::CreateBufferImpl(const BufferDescriptor* descriptor) {
return Buffer::Create(this, descriptor);

View File

@ -145,7 +145,8 @@ namespace dawn_native { namespace d3d12 {
ResultOrError<Ref<BindGroupBase>> CreateBindGroupImpl(
const BindGroupDescriptor* descriptor) override;
ResultOrError<Ref<BindGroupLayoutBase>> CreateBindGroupLayoutImpl(
const BindGroupLayoutDescriptor* descriptor) override;
const BindGroupLayoutDescriptor* descriptor,
PipelineCompatibilityToken pipelineCompatibilityToken) override;
ResultOrError<Ref<BufferBase>> CreateBufferImpl(
const BufferDescriptor* descriptor) override;
ResultOrError<Ref<ComputePipelineBase>> CreateComputePipelineImpl(

View File

@ -26,13 +26,16 @@ namespace dawn_native { namespace metal {
class BindGroupLayout final : public BindGroupLayoutBase {
public:
static Ref<BindGroupLayout> Create(DeviceBase* device,
const BindGroupLayoutDescriptor* descriptor);
const BindGroupLayoutDescriptor* descriptor,
PipelineCompatibilityToken pipelineCompatibilityToken);
Ref<BindGroup> 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<BindGroup> mBindGroupAllocator;

View File

@ -19,14 +19,17 @@
namespace dawn_native { namespace metal {
// static
Ref<BindGroupLayout> BindGroupLayout::Create(DeviceBase* device,
const BindGroupLayoutDescriptor* descriptor) {
return AcquireRef(new BindGroupLayout(device, descriptor));
Ref<BindGroupLayout> 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<BindGroup>(4096)) {
}

View File

@ -82,7 +82,8 @@ namespace dawn_native { namespace metal {
ResultOrError<Ref<BindGroupBase>> CreateBindGroupImpl(
const BindGroupDescriptor* descriptor) override;
ResultOrError<Ref<BindGroupLayoutBase>> CreateBindGroupLayoutImpl(
const BindGroupLayoutDescriptor* descriptor) override;
const BindGroupLayoutDescriptor* descriptor,
PipelineCompatibilityToken pipelineCompatibilityToken) override;
ResultOrError<Ref<BufferBase>> CreateBufferImpl(
const BufferDescriptor* descriptor) override;
ResultOrError<Ref<CommandBufferBase>> CreateCommandBuffer(

View File

@ -213,8 +213,9 @@ namespace dawn_native { namespace metal {
return BindGroup::Create(this, descriptor);
}
ResultOrError<Ref<BindGroupLayoutBase>> Device::CreateBindGroupLayoutImpl(
const BindGroupLayoutDescriptor* descriptor) {
return BindGroupLayout::Create(this, descriptor);
const BindGroupLayoutDescriptor* descriptor,
PipelineCompatibilityToken pipelineCompatibilityToken) {
return BindGroupLayout::Create(this, descriptor, pipelineCompatibilityToken);
}
ResultOrError<Ref<BufferBase>> Device::CreateBufferImpl(const BufferDescriptor* descriptor) {
return Buffer::Create(this, descriptor);

View File

@ -99,8 +99,9 @@ namespace dawn_native { namespace null {
return AcquireRef(new BindGroup(this, descriptor));
}
ResultOrError<Ref<BindGroupLayoutBase>> Device::CreateBindGroupLayoutImpl(
const BindGroupLayoutDescriptor* descriptor) {
return AcquireRef(new BindGroupLayout(this, descriptor));
const BindGroupLayoutDescriptor* descriptor,
PipelineCompatibilityToken pipelineCompatibilityToken) {
return AcquireRef(new BindGroupLayout(this, descriptor, pipelineCompatibilityToken));
}
ResultOrError<Ref<BufferBase>> Device::CreateBufferImpl(const BufferDescriptor* descriptor) {
DAWN_TRY(IncrementMemoryUsage(descriptor->size));

View File

@ -125,7 +125,8 @@ namespace dawn_native { namespace null {
ResultOrError<Ref<BindGroupBase>> CreateBindGroupImpl(
const BindGroupDescriptor* descriptor) override;
ResultOrError<Ref<BindGroupLayoutBase>> CreateBindGroupLayoutImpl(
const BindGroupLayoutDescriptor* descriptor) override;
const BindGroupLayoutDescriptor* descriptor,
PipelineCompatibilityToken pipelineCompatibilityToken) override;
ResultOrError<Ref<BufferBase>> CreateBufferImpl(
const BufferDescriptor* descriptor) override;
ResultOrError<Ref<ComputePipelineBase>> CreateComputePipelineImpl(

View File

@ -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<BindGroup>(4096)) {
}

View File

@ -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<BindGroup> AllocateBindGroup(Device* device, const BindGroupDescriptor* descriptor);
void DeallocateBindGroup(BindGroup* bindGroup);

View File

@ -116,8 +116,9 @@ namespace dawn_native { namespace opengl {
return BindGroup::Create(this, descriptor);
}
ResultOrError<Ref<BindGroupLayoutBase>> Device::CreateBindGroupLayoutImpl(
const BindGroupLayoutDescriptor* descriptor) {
return AcquireRef(new BindGroupLayout(this, descriptor));
const BindGroupLayoutDescriptor* descriptor,
PipelineCompatibilityToken pipelineCompatibilityToken) {
return AcquireRef(new BindGroupLayout(this, descriptor, pipelineCompatibilityToken));
}
ResultOrError<Ref<BufferBase>> Device::CreateBufferImpl(const BufferDescriptor* descriptor) {
return AcquireRef(new Buffer(this, descriptor));

View File

@ -87,7 +87,8 @@ namespace dawn_native { namespace opengl {
ResultOrError<Ref<BindGroupBase>> CreateBindGroupImpl(
const BindGroupDescriptor* descriptor) override;
ResultOrError<Ref<BindGroupLayoutBase>> CreateBindGroupLayoutImpl(
const BindGroupLayoutDescriptor* descriptor) override;
const BindGroupLayoutDescriptor* descriptor,
PipelineCompatibilityToken pipelineCompatibilityToken) override;
ResultOrError<Ref<BufferBase>> CreateBufferImpl(
const BufferDescriptor* descriptor) override;
ResultOrError<Ref<ComputePipelineBase>> CreateComputePipelineImpl(

View File

@ -78,8 +78,10 @@ namespace dawn_native { namespace vulkan {
// static
ResultOrError<Ref<BindGroupLayout>> BindGroupLayout::Create(
Device* device,
const BindGroupLayoutDescriptor* descriptor) {
Ref<BindGroupLayout> bgl = AcquireRef(new BindGroupLayout(device, descriptor));
const BindGroupLayoutDescriptor* descriptor,
PipelineCompatibilityToken pipelineCompatibilityToken) {
Ref<BindGroupLayout> 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<BindGroup>(4096)) {
}

View File

@ -47,9 +47,12 @@ namespace dawn_native { namespace vulkan {
public:
static ResultOrError<Ref<BindGroupLayout>> 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;

View File

@ -108,8 +108,9 @@ namespace dawn_native { namespace vulkan {
return BindGroup::Create(this, descriptor);
}
ResultOrError<Ref<BindGroupLayoutBase>> Device::CreateBindGroupLayoutImpl(
const BindGroupLayoutDescriptor* descriptor) {
return BindGroupLayout::Create(this, descriptor);
const BindGroupLayoutDescriptor* descriptor,
PipelineCompatibilityToken pipelineCompatibilityToken) {
return BindGroupLayout::Create(this, descriptor, pipelineCompatibilityToken);
}
ResultOrError<Ref<BufferBase>> Device::CreateBufferImpl(const BufferDescriptor* descriptor) {
return Buffer::Create(this, descriptor);

View File

@ -109,7 +109,8 @@ namespace dawn_native { namespace vulkan {
ResultOrError<Ref<BindGroupBase>> CreateBindGroupImpl(
const BindGroupDescriptor* descriptor) override;
ResultOrError<Ref<BindGroupLayoutBase>> CreateBindGroupLayoutImpl(
const BindGroupLayoutDescriptor* descriptor) override;
const BindGroupLayoutDescriptor* descriptor,
PipelineCompatibilityToken pipelineCompatibilityToken) override;
ResultOrError<Ref<BufferBase>> CreateBufferImpl(
const BufferDescriptor* descriptor) override;
ResultOrError<Ref<ComputePipelineBase>> CreateComputePipelineImpl(

View File

@ -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_

View File

@ -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;

View File

@ -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;

View File

@ -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.
{

View File

@ -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<f32>;
};
[[group(0), binding(0)]] var<uniform> uniforms : S;
[[stage(fragment)]] fn main() {
var pos : vec4<f32> = 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<f32> = 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<f32> = 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<f32> = 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<f32> = 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<f32> = 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<f32> = 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