Convert LayoutBindingInfo to an array of BindingInfos

This makes accessing per-index data simpler, and now that dynamic
buffer bindings are packed at the front, the old IterateBitset on
the dynamic buffer binding mask can be replaced with a simple loop
over the beginning bindings.

Bug: dawn:354
Change-Id: I1adf371c3228690758f90ab1f0de88ad8d0f950d
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/17681
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Kai Ninomiya <kainino@chromium.org>
Commit-Queue: Austin Eng <enga@chromium.org>
This commit is contained in:
Austin Eng 2020-03-26 17:22:14 +00:00 committed by Commit Bot service account
parent d5db214564
commit 0847cb4637
19 changed files with 221 additions and 234 deletions

View File

@ -64,10 +64,7 @@ namespace dawn_native {
MaybeError ValidateTextureBinding(const DeviceBase* device, MaybeError ValidateTextureBinding(const DeviceBase* device,
const BindGroupBinding& binding, const BindGroupBinding& binding,
wgpu::TextureUsage requiredUsage, wgpu::TextureUsage requiredUsage,
bool multisampledBinding, const BindGroupLayoutBase::BindingInfo& bindingInfo) {
wgpu::TextureComponentType requiredComponentType,
wgpu::TextureViewDimension requiredDimension,
wgpu::TextureFormat requiredStorageTextureFormat) {
if (binding.textureView == nullptr || binding.sampler != nullptr || if (binding.textureView == nullptr || binding.sampler != nullptr ||
binding.buffer != nullptr) { binding.buffer != nullptr) {
return DAWN_VALIDATION_ERROR("expected texture binding"); return DAWN_VALIDATION_ERROR("expected texture binding");
@ -80,18 +77,18 @@ namespace dawn_native {
return DAWN_VALIDATION_ERROR("texture binding usage mismatch"); return DAWN_VALIDATION_ERROR("texture binding usage mismatch");
} }
if (texture->IsMultisampledTexture() != multisampledBinding) { if (texture->IsMultisampledTexture() != bindingInfo.multisampled) {
return DAWN_VALIDATION_ERROR("texture multisampling mismatch"); return DAWN_VALIDATION_ERROR("texture multisampling mismatch");
} }
switch (requiredUsage) { switch (requiredUsage) {
case wgpu::TextureUsage::Sampled: { case wgpu::TextureUsage::Sampled: {
if (!texture->GetFormat().HasComponentType(requiredComponentType)) { if (!texture->GetFormat().HasComponentType(bindingInfo.textureComponentType)) {
return DAWN_VALIDATION_ERROR("texture component type usage mismatch"); return DAWN_VALIDATION_ERROR("texture component type usage mismatch");
} }
} break; } break;
case wgpu::TextureUsage::Storage: { case wgpu::TextureUsage::Storage: {
if (texture->GetFormat().format != requiredStorageTextureFormat) { if (texture->GetFormat().format != bindingInfo.storageTextureFormat) {
return DAWN_VALIDATION_ERROR("storage texture format mismatch"); return DAWN_VALIDATION_ERROR("storage texture format mismatch");
} }
} break; } break;
@ -100,7 +97,7 @@ namespace dawn_native {
break; break;
} }
if (binding.textureView->GetDimension() != requiredDimension) { if (binding.textureView->GetDimension() != bindingInfo.textureDimension) {
return DAWN_VALIDATION_ERROR("texture view dimension mismatch"); return DAWN_VALIDATION_ERROR("texture view dimension mismatch");
} }
@ -127,16 +124,12 @@ namespace dawn_native {
} }
DAWN_TRY(device->ValidateObject(descriptor->layout)); DAWN_TRY(device->ValidateObject(descriptor->layout));
if (descriptor->bindingCount != descriptor->layout->GetBindingCount()) {
const BindGroupLayoutBase::LayoutBindingInfo& layoutInfo =
descriptor->layout->GetBindingInfo();
const BindGroupLayoutBase::BindingMap& bindingMap = descriptor->layout->GetBindingMap();
if (descriptor->bindingCount != bindingMap.size()) {
return DAWN_VALIDATION_ERROR("numBindings mismatch"); return DAWN_VALIDATION_ERROR("numBindings mismatch");
} }
const BindGroupLayoutBase::BindingMap& bindingMap = descriptor->layout->GetBindingMap();
std::bitset<kMaxBindingsPerGroup> bindingsSet; std::bitset<kMaxBindingsPerGroup> bindingsSet;
for (uint32_t i = 0; i < descriptor->bindingCount; ++i) { for (uint32_t i = 0; i < descriptor->bindingCount; ++i) {
const BindGroupBinding& binding = descriptor->bindings[i]; const BindGroupBinding& binding = descriptor->bindings[i];
@ -146,15 +139,18 @@ namespace dawn_native {
return DAWN_VALIDATION_ERROR("setting non-existent binding"); return DAWN_VALIDATION_ERROR("setting non-existent binding");
} }
BindingIndex bindingIndex = it->second; BindingIndex bindingIndex = it->second;
ASSERT(bindingIndex < layoutInfo.bindingCount); ASSERT(bindingIndex < descriptor->layout->GetBindingCount());
if (bindingsSet[bindingIndex]) { if (bindingsSet[bindingIndex]) {
return DAWN_VALIDATION_ERROR("binding set twice"); return DAWN_VALIDATION_ERROR("binding set twice");
} }
bindingsSet.set(bindingIndex); bindingsSet.set(bindingIndex);
const BindGroupLayoutBase::BindingInfo& bindingInfo =
descriptor->layout->GetBindingInfo(bindingIndex);
// Perform binding-type specific validation. // Perform binding-type specific validation.
switch (layoutInfo.types[bindingIndex]) { switch (bindingInfo.type) {
case wgpu::BindingType::UniformBuffer: case wgpu::BindingType::UniformBuffer:
DAWN_TRY(ValidateBufferBinding(device, binding, wgpu::BufferUsage::Uniform)); DAWN_TRY(ValidateBufferBinding(device, binding, wgpu::BufferUsage::Uniform));
break; break;
@ -163,12 +159,8 @@ namespace dawn_native {
DAWN_TRY(ValidateBufferBinding(device, binding, wgpu::BufferUsage::Storage)); DAWN_TRY(ValidateBufferBinding(device, binding, wgpu::BufferUsage::Storage));
break; break;
case wgpu::BindingType::SampledTexture: case wgpu::BindingType::SampledTexture:
DAWN_TRY( DAWN_TRY(ValidateTextureBinding(device, binding, wgpu::TextureUsage::Sampled,
ValidateTextureBinding(device, binding, wgpu::TextureUsage::Sampled, bindingInfo));
layoutInfo.multisampled[bindingIndex],
layoutInfo.textureComponentTypes[bindingIndex],
layoutInfo.textureDimensions[bindingIndex],
layoutInfo.storageTextureFormats[bindingIndex]));
break; break;
case wgpu::BindingType::Sampler: case wgpu::BindingType::Sampler:
DAWN_TRY(ValidateSamplerBinding(device, binding)); DAWN_TRY(ValidateSamplerBinding(device, binding));
@ -177,12 +169,8 @@ namespace dawn_native {
// write-only storage textures. // write-only storage textures.
case wgpu::BindingType::ReadonlyStorageTexture: case wgpu::BindingType::ReadonlyStorageTexture:
case wgpu::BindingType::WriteonlyStorageTexture: case wgpu::BindingType::WriteonlyStorageTexture:
DAWN_TRY( DAWN_TRY(ValidateTextureBinding(device, binding, wgpu::TextureUsage::Storage,
ValidateTextureBinding(device, binding, wgpu::TextureUsage::Storage, bindingInfo));
layoutInfo.multisampled[bindingIndex],
layoutInfo.textureComponentTypes[bindingIndex],
layoutInfo.textureDimensions[bindingIndex],
layoutInfo.storageTextureFormats[bindingIndex]));
break; break;
case wgpu::BindingType::StorageTexture: case wgpu::BindingType::StorageTexture:
UNREACHABLE(); UNREACHABLE();
@ -274,9 +262,9 @@ namespace dawn_native {
BufferBinding BindGroupBase::GetBindingAsBufferBinding(BindingIndex bindingIndex) { BufferBinding BindGroupBase::GetBindingAsBufferBinding(BindingIndex bindingIndex) {
ASSERT(!IsError()); ASSERT(!IsError());
ASSERT(bindingIndex < mLayout->GetBindingCount()); ASSERT(bindingIndex < mLayout->GetBindingCount());
ASSERT(mLayout->GetBindingInfo().types[bindingIndex] == wgpu::BindingType::UniformBuffer || ASSERT(mLayout->GetBindingInfo(bindingIndex).type == wgpu::BindingType::UniformBuffer ||
mLayout->GetBindingInfo().types[bindingIndex] == wgpu::BindingType::StorageBuffer || mLayout->GetBindingInfo(bindingIndex).type == wgpu::BindingType::StorageBuffer ||
mLayout->GetBindingInfo().types[bindingIndex] == mLayout->GetBindingInfo(bindingIndex).type ==
wgpu::BindingType::ReadonlyStorageBuffer); wgpu::BindingType::ReadonlyStorageBuffer);
BufferBase* buffer = static_cast<BufferBase*>(mBindingData.bindings[bindingIndex].Get()); BufferBase* buffer = static_cast<BufferBase*>(mBindingData.bindings[bindingIndex].Get());
return {buffer, mBindingData.bufferData[bindingIndex].offset, return {buffer, mBindingData.bufferData[bindingIndex].offset,
@ -286,14 +274,14 @@ namespace dawn_native {
SamplerBase* BindGroupBase::GetBindingAsSampler(BindingIndex bindingIndex) { SamplerBase* BindGroupBase::GetBindingAsSampler(BindingIndex bindingIndex) {
ASSERT(!IsError()); ASSERT(!IsError());
ASSERT(bindingIndex < mLayout->GetBindingCount()); ASSERT(bindingIndex < mLayout->GetBindingCount());
ASSERT(mLayout->GetBindingInfo().types[bindingIndex] == wgpu::BindingType::Sampler); ASSERT(mLayout->GetBindingInfo(bindingIndex).type == wgpu::BindingType::Sampler);
return static_cast<SamplerBase*>(mBindingData.bindings[bindingIndex].Get()); return static_cast<SamplerBase*>(mBindingData.bindings[bindingIndex].Get());
} }
TextureViewBase* BindGroupBase::GetBindingAsTextureView(BindingIndex bindingIndex) { TextureViewBase* BindGroupBase::GetBindingAsTextureView(BindingIndex bindingIndex) {
ASSERT(!IsError()); ASSERT(!IsError());
ASSERT(bindingIndex < mLayout->GetBindingCount()); ASSERT(bindingIndex < mLayout->GetBindingCount());
ASSERT(mLayout->GetBindingInfo().types[bindingIndex] == wgpu::BindingType::SampledTexture); ASSERT(mLayout->GetBindingInfo(bindingIndex).type == wgpu::BindingType::SampledTexture);
return static_cast<TextureViewBase*>(mBindingData.bindings[bindingIndex].Get()); return static_cast<TextureViewBase*>(mBindingData.bindings[bindingIndex].Get());
} }

View File

@ -38,16 +38,18 @@ namespace dawn_native {
mBuffersNeedingBarrier[index] = {}; mBuffersNeedingBarrier[index] = {};
const BindGroupLayoutBase* layout = bindGroup->GetLayout(); const BindGroupLayoutBase* layout = bindGroup->GetLayout();
const BindGroupLayoutBase::LayoutBindingInfo& info = layout->GetBindingInfo();
for (BindingIndex bindingIndex = 0; bindingIndex < info.bindingCount; for (BindingIndex bindingIndex = 0; bindingIndex < layout->GetBindingCount();
++bindingIndex) { ++bindingIndex) {
if ((info.visibilities[bindingIndex] & wgpu::ShaderStage::Compute) == 0) { const BindGroupLayoutBase::BindingInfo& bindingInfo =
layout->GetBindingInfo(bindingIndex);
if ((bindingInfo.visibility & wgpu::ShaderStage::Compute) == 0) {
continue; continue;
} }
mBindingTypes[index][bindingIndex] = info.types[bindingIndex]; mBindingTypes[index][bindingIndex] = bindingInfo.type;
switch (info.types[bindingIndex]) { switch (bindingInfo.type) {
case wgpu::BindingType::UniformBuffer: case wgpu::BindingType::UniformBuffer:
case wgpu::BindingType::ReadonlyStorageBuffer: case wgpu::BindingType::ReadonlyStorageBuffer:
case wgpu::BindingType::Sampler: case wgpu::BindingType::Sampler:

View File

@ -167,39 +167,25 @@ namespace dawn_native {
} }
return {}; return {};
} // namespace dawn_native }
namespace { namespace {
size_t HashBindingInfo(const BindGroupLayoutBase::LayoutBindingInfo& info) {
size_t hash = 0;
HashCombine(&hash, info.hasDynamicOffset, info.multisampled);
for (BindingIndex i = 0; i < info.bindingCount; ++i) { void HashCombineBindingInfo(size_t* hash, const BindGroupLayoutBase::BindingInfo& info) {
HashCombine(&hash, info.visibilities[i], info.types[i], HashCombine(hash, info.hasDynamicOffset, info.multisampled, info.visibility, info.type,
info.textureComponentTypes[i], info.textureDimensions[i], info.textureComponentType, info.textureDimension,
info.storageTextureFormats[i]); info.storageTextureFormat);
}
return hash;
} }
bool operator==(const BindGroupLayoutBase::LayoutBindingInfo& a, bool operator!=(const BindGroupLayoutBase::BindingInfo& a,
const BindGroupLayoutBase::LayoutBindingInfo& b) { const BindGroupLayoutBase::BindingInfo& b) {
if (a.bindingCount != b.bindingCount || a.hasDynamicOffset != b.hasDynamicOffset || return a.hasDynamicOffset != b.hasDynamicOffset || //
a.multisampled != b.multisampled) { a.multisampled != b.multisampled || //
return false; a.visibility != b.visibility || //
} a.type != b.type || //
a.textureComponentType != b.textureComponentType || //
for (BindingIndex i = 0; i < a.bindingCount; ++i) { a.textureDimension != b.textureDimension || //
if ((a.visibilities[i] != b.visibilities[i]) || (a.types[i] != b.types[i]) || a.storageTextureFormat != b.storageTextureFormat;
(a.textureComponentTypes[i] != b.textureComponentTypes[i]) ||
(a.textureDimensions[i] != b.textureDimensions[i]) ||
(a.storageTextureFormats[i] != b.storageTextureFormats[i])) {
return false;
}
}
return true;
} }
bool SortBindingsCompare(const BindGroupLayoutBinding& a, const BindGroupLayoutBinding& b) { bool SortBindingsCompare(const BindGroupLayoutBinding& a, const BindGroupLayoutBinding& b) {
@ -233,7 +219,8 @@ namespace dawn_native {
// This is a utility function to help ASSERT that the BGL-binding comparator places buffers // This is a utility function to help ASSERT that the BGL-binding comparator places buffers
// first. // first.
bool CheckBufferBindingsFirst(const BindGroupLayoutBinding* bindings, size_t count) { bool CheckBufferBindingsFirst(const BindGroupLayoutBase::BindingInfo* bindings,
BindingIndex count) {
ASSERT(count <= kMaxBindingsPerGroup); ASSERT(count <= kMaxBindingsPerGroup);
BindingIndex lastBufferIndex = 0; BindingIndex lastBufferIndex = 0;
@ -269,21 +256,18 @@ namespace dawn_native {
BindGroupLayoutBase::BindGroupLayoutBase(DeviceBase* device, BindGroupLayoutBase::BindGroupLayoutBase(DeviceBase* device,
const BindGroupLayoutDescriptor* descriptor) const BindGroupLayoutDescriptor* descriptor)
: CachedObject(device) { : CachedObject(device), mBindingCount(descriptor->bindingCount) {
mBindingInfo.bindingCount = descriptor->bindingCount;
std::vector<BindGroupLayoutBinding> sortedBindings( std::vector<BindGroupLayoutBinding> sortedBindings(
descriptor->bindings, descriptor->bindings + descriptor->bindingCount); descriptor->bindings, descriptor->bindings + descriptor->bindingCount);
std::sort(sortedBindings.begin(), sortedBindings.end(), SortBindingsCompare); std::sort(sortedBindings.begin(), sortedBindings.end(), SortBindingsCompare);
ASSERT(CheckBufferBindingsFirst(sortedBindings.data(), sortedBindings.size()));
for (BindingIndex i = 0; i < mBindingInfo.bindingCount; ++i) { for (BindingIndex i = 0; i < mBindingCount; ++i) {
const BindGroupLayoutBinding& binding = sortedBindings[i]; const BindGroupLayoutBinding& binding = sortedBindings[i];
mBindingInfo.types[i] = binding.type; mBindingInfo[i].type = binding.type;
mBindingInfo.visibilities[i] = binding.visibility; mBindingInfo[i].visibility = binding.visibility;
mBindingInfo.textureComponentTypes[i] = binding.textureComponentType; mBindingInfo[i].textureComponentType = binding.textureComponentType;
mBindingInfo.storageTextureFormats[i] = binding.storageTextureFormat; mBindingInfo[i].storageTextureFormat = binding.storageTextureFormat;
switch (binding.type) { switch (binding.type) {
case wgpu::BindingType::UniformBuffer: case wgpu::BindingType::UniformBuffer:
@ -298,13 +282,14 @@ namespace dawn_native {
} }
if (binding.textureDimension == wgpu::TextureViewDimension::Undefined) { if (binding.textureDimension == wgpu::TextureViewDimension::Undefined) {
mBindingInfo.textureDimensions[i] = wgpu::TextureViewDimension::e2D; mBindingInfo[i].textureDimension = wgpu::TextureViewDimension::e2D;
} else { } else {
mBindingInfo.textureDimensions[i] = binding.textureDimension; mBindingInfo[i].textureDimension = binding.textureDimension;
} }
mBindingInfo[i].multisampled = binding.multisampled;
mBindingInfo[i].hasDynamicOffset = binding.hasDynamicOffset;
if (binding.hasDynamicOffset) { if (binding.hasDynamicOffset) {
mBindingInfo.hasDynamicOffset.set(i);
switch (binding.type) { switch (binding.type) {
case wgpu::BindingType::UniformBuffer: case wgpu::BindingType::UniformBuffer:
++mDynamicUniformBufferCount; ++mDynamicUniformBufferCount;
@ -322,11 +307,11 @@ namespace dawn_native {
break; break;
} }
} }
mBindingInfo.multisampled.set(i, binding.multisampled);
const auto& it = mBindingMap.emplace(BindingNumber(binding.binding), i); const auto& it = mBindingMap.emplace(BindingNumber(binding.binding), i);
ASSERT(it.second); ASSERT(it.second);
} }
ASSERT(CheckBufferBindingsFirst(mBindingInfo.data(), mBindingCount));
} }
BindGroupLayoutBase::BindGroupLayoutBase(DeviceBase* device, ObjectBase::ErrorTag tag) BindGroupLayoutBase::BindGroupLayoutBase(DeviceBase* device, ObjectBase::ErrorTag tag)
@ -345,11 +330,6 @@ namespace dawn_native {
return new BindGroupLayoutBase(device, ObjectBase::kError); return new BindGroupLayoutBase(device, ObjectBase::kError);
} }
const BindGroupLayoutBase::LayoutBindingInfo& BindGroupLayoutBase::GetBindingInfo() const {
ASSERT(!IsError());
return mBindingInfo;
}
const BindGroupLayoutBase::BindingMap& BindGroupLayoutBase::GetBindingMap() const { const BindGroupLayoutBase::BindingMap& BindGroupLayoutBase::GetBindingMap() const {
ASSERT(!IsError()); ASSERT(!IsError());
return mBindingMap; return mBindingMap;
@ -363,22 +343,31 @@ namespace dawn_native {
} }
size_t BindGroupLayoutBase::HashFunc::operator()(const BindGroupLayoutBase* bgl) const { size_t BindGroupLayoutBase::HashFunc::operator()(const BindGroupLayoutBase* bgl) const {
size_t hash = HashBindingInfo(bgl->mBindingInfo); size_t hash = 0;
// std::map is sorted by key, so two BGLs constructed in different orders // std::map is sorted by key, so two BGLs constructed in different orders
// will still hash the same. // will still hash the same.
for (const auto& it : bgl->mBindingMap) { for (const auto& it : bgl->mBindingMap) {
HashCombine(&hash, it.first, it.second); HashCombine(&hash, it.first, it.second);
HashCombineBindingInfo(&hash, bgl->mBindingInfo[it.second]);
} }
return hash; return hash;
} }
bool BindGroupLayoutBase::EqualityFunc::operator()(const BindGroupLayoutBase* a, bool BindGroupLayoutBase::EqualityFunc::operator()(const BindGroupLayoutBase* a,
const BindGroupLayoutBase* b) const { const BindGroupLayoutBase* b) const {
return a->mBindingInfo == b->mBindingInfo && a->mBindingMap == b->mBindingMap; 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;
} }
BindingIndex BindGroupLayoutBase::GetBindingCount() const { BindingIndex BindGroupLayoutBase::GetBindingCount() const {
return mBindingInfo.bindingCount; return mBindingCount;
} }
BindingIndex BindGroupLayoutBase::GetDynamicBufferCount() const { BindingIndex BindGroupLayoutBase::GetDynamicBufferCount() const {
@ -398,7 +387,7 @@ namespace dawn_native {
// | --- offsets + sizes -------------| --------------- Ref<ObjectBase> ----------| // | --- offsets + sizes -------------| --------------- Ref<ObjectBase> ----------|
size_t objectPointerStart = mBufferCount * sizeof(BufferBindingData); size_t objectPointerStart = mBufferCount * sizeof(BufferBindingData);
ASSERT(IsAligned(objectPointerStart, alignof(Ref<ObjectBase>))); ASSERT(IsAligned(objectPointerStart, alignof(Ref<ObjectBase>)));
return objectPointerStart + mBindingInfo.bindingCount * sizeof(Ref<ObjectBase>); return objectPointerStart + mBindingCount * sizeof(Ref<ObjectBase>);
} }
BindGroupLayoutBase::BindingDataPointers BindGroupLayoutBase::ComputeBindingDataPointers( BindGroupLayoutBase::BindingDataPointers BindGroupLayoutBase::ComputeBindingDataPointers(

View File

@ -51,22 +51,24 @@ namespace dawn_native {
~BindGroupLayoutBase() override; ~BindGroupLayoutBase() override;
static BindGroupLayoutBase* MakeError(DeviceBase* device); static BindGroupLayoutBase* MakeError(DeviceBase* device);
struct BindingInfo {
struct LayoutBindingInfo { wgpu::ShaderStage visibility;
std::array<wgpu::ShaderStage, kMaxBindingsPerGroup> visibilities; wgpu::BindingType type;
std::array<wgpu::BindingType, kMaxBindingsPerGroup> types; wgpu::TextureComponentType textureComponentType;
std::array<wgpu::TextureComponentType, kMaxBindingsPerGroup> textureComponentTypes; wgpu::TextureViewDimension textureDimension;
std::array<wgpu::TextureViewDimension, kMaxBindingsPerGroup> textureDimensions; wgpu::TextureFormat storageTextureFormat;
std::array<wgpu::TextureFormat, kMaxBindingsPerGroup> storageTextureFormats; bool hasDynamicOffset;
std::bitset<kMaxBindingsPerGroup> hasDynamicOffset; bool multisampled;
std::bitset<kMaxBindingsPerGroup> multisampled;
BindingIndex bindingCount;
}; };
// A map from the BindingNumber to its packed BindingIndex. // A map from the BindingNumber to its packed BindingIndex.
using BindingMap = std::map<BindingNumber, BindingIndex>; using BindingMap = std::map<BindingNumber, BindingIndex>;
const LayoutBindingInfo& GetBindingInfo() const; const BindingInfo& GetBindingInfo(BindingIndex bindingIndex) const {
ASSERT(!IsError());
ASSERT(bindingIndex < kMaxBindingsPerGroup);
return mBindingInfo[bindingIndex];
}
const BindingMap& GetBindingMap() const; const BindingMap& GetBindingMap() const;
BindingIndex GetBindingIndex(BindingNumber bindingNumber) const; BindingIndex GetBindingIndex(BindingNumber bindingNumber) const;
@ -117,10 +119,12 @@ namespace dawn_native {
private: private:
BindGroupLayoutBase(DeviceBase* device, ObjectBase::ErrorTag tag); BindGroupLayoutBase(DeviceBase* device, ObjectBase::ErrorTag tag);
BindingIndex mBindingCount;
BindingIndex mBufferCount = 0; // |BindingIndex| because buffers are packed at the front. BindingIndex mBufferCount = 0; // |BindingIndex| because buffers are packed at the front.
uint32_t mDynamicUniformBufferCount = 0; uint32_t mDynamicUniformBufferCount = 0;
uint32_t mDynamicStorageBufferCount = 0; uint32_t mDynamicStorageBufferCount = 0;
LayoutBindingInfo mBindingInfo;
std::array<BindingInfo, kMaxBindingsPerGroup> mBindingInfo;
// Map from BindGroupLayoutEntry.binding to packed indices. // Map from BindGroupLayoutEntry.binding to packed indices.
BindingMap mBindingMap; BindingMap mBindingMap;

View File

@ -29,11 +29,9 @@ namespace dawn_native {
namespace { namespace {
void TrackBindGroupResourceUsage(PassResourceUsageTracker* usageTracker, void TrackBindGroupResourceUsage(PassResourceUsageTracker* usageTracker,
BindGroupBase* group) { BindGroupBase* group) {
const BindGroupLayoutBase::LayoutBindingInfo& layoutInfo = for (BindingIndex bindingIndex = 0;
group->GetLayout()->GetBindingInfo(); bindingIndex < group->GetLayout()->GetBindingCount(); ++bindingIndex) {
for (BindingIndex bindingIndex = 0; bindingIndex < layoutInfo.bindingCount; wgpu::BindingType type = group->GetLayout()->GetBindingInfo(bindingIndex).type;
++bindingIndex) {
wgpu::BindingType type = layoutInfo.types[bindingIndex];
switch (type) { switch (type) {
case wgpu::BindingType::UniformBuffer: { case wgpu::BindingType::UniformBuffer: {
@ -133,12 +131,13 @@ namespace dawn_native {
return DAWN_VALIDATION_ERROR("dynamicOffset count mismatch"); return DAWN_VALIDATION_ERROR("dynamicOffset count mismatch");
} }
const BindGroupLayoutBase::LayoutBindingInfo& layoutInfo = layout->GetBindingInfo();
for (BindingIndex i = 0; i < dynamicOffsetCount; ++i) { for (BindingIndex i = 0; i < dynamicOffsetCount; ++i) {
const BindGroupLayoutBase::BindingInfo& bindingInfo = layout->GetBindingInfo(i);
// BGL creation sorts bindings such that the dynamic buffer bindings are first. // BGL creation sorts bindings such that the dynamic buffer bindings are first.
// ASSERT that this true. // ASSERT that this true.
ASSERT(layoutInfo.hasDynamicOffset[i]); ASSERT(bindingInfo.hasDynamicOffset);
switch (layoutInfo.types[i]) { switch (bindingInfo.type) {
case wgpu::BindingType::UniformBuffer: case wgpu::BindingType::UniformBuffer:
case wgpu::BindingType::StorageBuffer: case wgpu::BindingType::StorageBuffer:
case wgpu::BindingType::ReadonlyStorageBuffer: case wgpu::BindingType::ReadonlyStorageBuffer:

View File

@ -741,7 +741,6 @@ namespace dawn_native {
const BindGroupLayoutBase* layout) const { const BindGroupLayoutBase* layout) const {
ASSERT(!IsError()); ASSERT(!IsError());
const BindGroupLayoutBase::LayoutBindingInfo& layoutInfo = layout->GetBindingInfo();
const BindGroupLayoutBase::BindingMap& bindingMap = layout->GetBindingMap(); const BindGroupLayoutBase::BindingMap& bindingMap = layout->GetBindingMap();
// Iterate over all bindings used by this group in the shader, and find the // Iterate over all bindings used by this group in the shader, and find the
@ -756,7 +755,9 @@ namespace dawn_native {
} }
BindingIndex bindingIndex(bindingIt->second); BindingIndex bindingIndex(bindingIt->second);
const auto& layoutBindingType = layoutInfo.types[bindingIndex]; const BindGroupLayoutBase::BindingInfo& bindingInfo =
layout->GetBindingInfo(bindingIndex);
const auto& layoutBindingType = bindingInfo.type;
if (layoutBindingType != moduleInfo.type) { if (layoutBindingType != moduleInfo.type) {
// Binding mismatch between shader and bind group is invalid. For example, a // Binding mismatch between shader and bind group is invalid. For example, a
@ -771,34 +772,31 @@ namespace dawn_native {
} }
} }
if ((layoutInfo.visibilities[bindingIndex] & StageBit(mExecutionModel)) == 0) { if ((bindingInfo.visibility & StageBit(mExecutionModel)) == 0) {
return false; return false;
} }
switch (layoutBindingType) { switch (layoutBindingType) {
case wgpu::BindingType::SampledTexture: { case wgpu::BindingType::SampledTexture: {
Format::Type layoutTextureComponentType = Format::Type layoutTextureComponentType =
Format::TextureComponentTypeToFormatType( Format::TextureComponentTypeToFormatType(bindingInfo.textureComponentType);
layoutInfo.textureComponentTypes[bindingIndex]);
if (layoutTextureComponentType != moduleInfo.textureComponentType) { if (layoutTextureComponentType != moduleInfo.textureComponentType) {
return false; return false;
} }
if (layoutInfo.textureDimensions[bindingIndex] != moduleInfo.textureDimension) { if (bindingInfo.textureDimension != moduleInfo.textureDimension) {
return false; return false;
} }
} break; } break;
case wgpu::BindingType::ReadonlyStorageTexture: case wgpu::BindingType::ReadonlyStorageTexture:
case wgpu::BindingType::WriteonlyStorageTexture: { case wgpu::BindingType::WriteonlyStorageTexture: {
ASSERT(layoutInfo.storageTextureFormats[bindingIndex] != ASSERT(bindingInfo.storageTextureFormat != wgpu::TextureFormat::Undefined);
wgpu::TextureFormat::Undefined);
ASSERT(moduleInfo.storageTextureFormat != wgpu::TextureFormat::Undefined); ASSERT(moduleInfo.storageTextureFormat != wgpu::TextureFormat::Undefined);
if (layoutInfo.storageTextureFormats[bindingIndex] != if (bindingInfo.storageTextureFormat != moduleInfo.storageTextureFormat) {
moduleInfo.storageTextureFormat) {
return false; return false;
} }
if (layoutInfo.textureDimensions[bindingIndex] != moduleInfo.textureDimension) { if (bindingInfo.textureDimension != moduleInfo.textureDimension) {
return false; return false;
} }
} break; } break;

View File

@ -81,21 +81,21 @@ namespace dawn_native { namespace d3d12 {
mLastUsageSerial = pendingSerial; mLastUsageSerial = pendingSerial;
mHeapSerial = allocator->GetShaderVisibleHeapsSerial(); mHeapSerial = allocator->GetShaderVisibleHeapsSerial();
const BindGroupLayoutBase::LayoutBindingInfo& layout = bgl->GetBindingInfo();
const auto& bindingOffsets = bgl->GetBindingOffsets(); const auto& bindingOffsets = bgl->GetBindingOffsets();
ID3D12Device* d3d12Device = device->GetD3D12Device().Get(); ID3D12Device* d3d12Device = device->GetD3D12Device().Get();
for (BindingIndex bindingIndex = 0; bindingIndex < layout.bindingCount; ++bindingIndex) { for (BindingIndex bindingIndex = 0; bindingIndex < bgl->GetBindingCount(); ++bindingIndex) {
const BindGroupLayoutBase::BindingInfo& bindingInfo = bgl->GetBindingInfo(bindingIndex);
// It's not necessary to create descriptors in descriptor heap for dynamic // It's not necessary to create descriptors in descriptor heap for dynamic
// resources. So skip allocating descriptors in descriptor heaps for dynamic // resources. So skip allocating descriptors in descriptor heaps for dynamic
// buffers. // buffers.
if (layout.hasDynamicOffset[bindingIndex]) { if (bindingInfo.hasDynamicOffset) {
continue; continue;
} }
switch (layout.types[bindingIndex]) { switch (bindingInfo.type) {
case wgpu::BindingType::UniformBuffer: { case wgpu::BindingType::UniformBuffer: {
BufferBinding binding = GetBindingAsBufferBinding(bindingIndex); BufferBinding binding = GetBindingAsBufferBinding(bindingIndex);

View File

@ -45,18 +45,17 @@ namespace dawn_native { namespace d3d12 {
: BindGroupLayoutBase(device, descriptor), : BindGroupLayoutBase(device, descriptor),
mDescriptorCounts{}, mDescriptorCounts{},
mBindGroupAllocator(MakeFrontendBindGroupAllocator<BindGroup>(4096)) { mBindGroupAllocator(MakeFrontendBindGroupAllocator<BindGroup>(4096)) {
const BindGroupLayoutBase::LayoutBindingInfo& groupInfo = GetBindingInfo(); for (BindingIndex bindingIndex = GetDynamicBufferCount(); bindingIndex < GetBindingCount();
++bindingIndex) {
const BindGroupLayoutBase::BindingInfo& bindingInfo = GetBindingInfo(bindingIndex);
for (BindingIndex bindingIndex = 0; bindingIndex < groupInfo.bindingCount; ++bindingIndex) {
// For dynamic resources, Dawn uses root descriptor in D3D12 backend. // For dynamic resources, Dawn uses root descriptor in D3D12 backend.
// So there is no need to allocate the descriptor from descriptor heap. Skip counting // So there is no need to allocate the descriptor from descriptor heap.
// dynamic resources for calculating size of descriptor heap. // This loop starts after the dynamic buffer indices to skip counting
if (groupInfo.hasDynamicOffset[bindingIndex]) { // dynamic resources in calculating the size of the descriptor heap.
continue; ASSERT(!bindingInfo.hasDynamicOffset);
}
DescriptorType descriptorType = DescriptorType descriptorType = WGPUBindingTypeToDescriptorType(bindingInfo.type);
WGPUBindingTypeToDescriptorType(groupInfo.types[bindingIndex]);
mBindingOffsets[bindingIndex] = mDescriptorCounts[descriptorType]++; mBindingOffsets[bindingIndex] = mDescriptorCounts[descriptorType]++;
} }
@ -101,12 +100,14 @@ namespace dawn_native { namespace d3d12 {
D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER); D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER);
descriptorOffsets[Sampler] = 0; descriptorOffsets[Sampler] = 0;
for (BindingIndex bindingIndex = 0; bindingIndex < groupInfo.bindingCount; ++bindingIndex) { for (BindingIndex bindingIndex = 0; bindingIndex < GetBindingCount(); ++bindingIndex) {
if (groupInfo.hasDynamicOffset[bindingIndex]) { const BindGroupLayoutBase::BindingInfo& bindingInfo = GetBindingInfo(bindingIndex);
if (bindingInfo.hasDynamicOffset) {
// Dawn is using values in mBindingOffsets to decide register number in HLSL. // Dawn is using values in mBindingOffsets to decide register number in HLSL.
// Root descriptor needs to set this value to set correct register number in // Root descriptor needs to set this value to set correct register number in
// generated HLSL shader. // generated HLSL shader.
switch (groupInfo.types[bindingIndex]) { switch (bindingInfo.type) {
case wgpu::BindingType::UniformBuffer: case wgpu::BindingType::UniformBuffer:
case wgpu::BindingType::StorageBuffer: case wgpu::BindingType::StorageBuffer:
case wgpu::BindingType::ReadonlyStorageBuffer: case wgpu::BindingType::ReadonlyStorageBuffer:
@ -124,8 +125,7 @@ namespace dawn_native { namespace d3d12 {
} }
// TODO(shaobo.yan@intel.com): Implement dynamic buffer offset. // TODO(shaobo.yan@intel.com): Implement dynamic buffer offset.
DescriptorType descriptorType = DescriptorType descriptorType = WGPUBindingTypeToDescriptorType(bindingInfo.type);
WGPUBindingTypeToDescriptorType(groupInfo.types[bindingIndex]);
mBindingOffsets[bindingIndex] += descriptorOffsets[descriptorType]; mBindingOffsets[bindingIndex] += descriptorOffsets[descriptorType];
} }
} }

View File

@ -196,28 +196,27 @@ namespace dawn_native { namespace d3d12 {
BindGroup* group, BindGroup* group,
uint32_t dynamicOffsetCount, uint32_t dynamicOffsetCount,
const uint64_t* dynamicOffsets) { const uint64_t* dynamicOffsets) {
ASSERT(dynamicOffsetCount == group->GetLayout()->GetDynamicBufferCount());
// Usually, the application won't set the same offsets many times, // Usually, the application won't set the same offsets many times,
// so always try to apply dynamic offsets even if the offsets stay the same // so always try to apply dynamic offsets even if the offsets stay the same
if (dynamicOffsetCount) { if (dynamicOffsetCount != 0) {
// Update dynamic offsets // Update dynamic offsets.
const BindGroupLayout::LayoutBindingInfo& layout = // Dynamic buffer bindings are packed at the beginning of the layout.
group->GetLayout()->GetBindingInfo(); for (BindingIndex bindingIndex = 0; bindingIndex < dynamicOffsetCount;
uint32_t currentDynamicBufferIndex = 0; ++bindingIndex) {
for (uint32_t bindingIndex : IterateBitSet(layout.hasDynamicOffset)) {
ASSERT(dynamicOffsetCount > 0);
uint32_t parameterIndex = uint32_t parameterIndex =
pipelineLayout->GetDynamicRootParameterIndex(index, bindingIndex); pipelineLayout->GetDynamicRootParameterIndex(index, bindingIndex);
BufferBinding binding = group->GetBindingAsBufferBinding(bindingIndex); BufferBinding binding = group->GetBindingAsBufferBinding(bindingIndex);
// Calculate buffer locations that root descriptors links to. The location // Calculate buffer locations that root descriptors links to. The location
// is (base buffer location + initial offset + dynamic offset) // is (base buffer location + initial offset + dynamic offset)
uint64_t dynamicOffset = dynamicOffsets[currentDynamicBufferIndex]; uint64_t dynamicOffset = dynamicOffsets[bindingIndex];
uint64_t offset = binding.offset + dynamicOffset; uint64_t offset = binding.offset + dynamicOffset;
D3D12_GPU_VIRTUAL_ADDRESS bufferLocation = D3D12_GPU_VIRTUAL_ADDRESS bufferLocation =
ToBackend(binding.buffer)->GetVA() + offset; ToBackend(binding.buffer)->GetVA() + offset;
switch (layout.types[bindingIndex]) { switch (group->GetLayout()->GetBindingInfo(bindingIndex).type) {
case wgpu::BindingType::UniformBuffer: case wgpu::BindingType::UniformBuffer:
if (mInCompute) { if (mInCompute) {
commandList->SetComputeRootConstantBufferView(parameterIndex, commandList->SetComputeRootConstantBufferView(parameterIndex,
@ -253,8 +252,6 @@ namespace dawn_native { namespace d3d12 {
UNREACHABLE(); UNREACHABLE();
break; break;
} }
++currentDynamicBufferIndex;
} }
} }

View File

@ -89,7 +89,6 @@ namespace dawn_native { namespace d3d12 {
for (uint32_t group : IterateBitSet(GetBindGroupLayoutsMask())) { for (uint32_t group : IterateBitSet(GetBindGroupLayoutsMask())) {
const BindGroupLayout* bindGroupLayout = ToBackend(GetBindGroupLayout(group)); const BindGroupLayout* bindGroupLayout = ToBackend(GetBindGroupLayout(group));
const BindGroupLayout::LayoutBindingInfo& groupInfo = bindGroupLayout->GetBindingInfo();
// Set the root descriptor table parameter and copy ranges. Ranges are offset by the // Set the root descriptor table parameter and copy ranges. Ranges are offset by the
// bind group index Returns whether or not the parameter was set. A root parameter is // bind group index Returns whether or not the parameter was set. A root parameter is
@ -129,25 +128,30 @@ namespace dawn_native { namespace d3d12 {
// Get calculated shader register for root descriptors // Get calculated shader register for root descriptors
const auto& shaderRegisters = bindGroupLayout->GetBindingOffsets(); const auto& shaderRegisters = bindGroupLayout->GetBindingOffsets();
// Init root descriptors in root signatures. // Init root descriptors in root signatures for dynamic buffer bindings.
for (uint32_t dynamicBinding : IterateBitSet(groupInfo.hasDynamicOffset)) { // These are packed at the beginning of the layout binding info.
for (BindingIndex dynamicBindingIndex = 0;
dynamicBindingIndex < bindGroupLayout->GetDynamicBufferCount();
++dynamicBindingIndex) {
const BindGroupLayoutBase::BindingInfo& bindingInfo =
bindGroupLayout->GetBindingInfo(dynamicBindingIndex);
D3D12_ROOT_PARAMETER* rootParameter = &rootParameters[parameterIndex]; D3D12_ROOT_PARAMETER* rootParameter = &rootParameters[parameterIndex];
// Setup root descriptor. // Setup root descriptor.
D3D12_ROOT_DESCRIPTOR rootDescriptor; D3D12_ROOT_DESCRIPTOR rootDescriptor;
rootDescriptor.ShaderRegister = shaderRegisters[dynamicBinding]; rootDescriptor.ShaderRegister = shaderRegisters[dynamicBindingIndex];
rootDescriptor.RegisterSpace = group; rootDescriptor.RegisterSpace = group;
// Set root descriptors in root signatures. // Set root descriptors in root signatures.
rootParameter->Descriptor = rootDescriptor; rootParameter->Descriptor = rootDescriptor;
mDynamicRootParameterIndices[group][dynamicBinding] = parameterIndex++; mDynamicRootParameterIndices[group][dynamicBindingIndex] = parameterIndex++;
// Set parameter types according to bind group layout descriptor. // Set parameter types according to bind group layout descriptor.
rootParameter->ParameterType = RootParameterType(groupInfo.types[dynamicBinding]); rootParameter->ParameterType = RootParameterType(bindingInfo.type);
// Set visibilities according to bind group layout descriptor. // Set visibilities according to bind group layout descriptor.
rootParameter->ShaderVisibility = rootParameter->ShaderVisibility = ShaderVisibilityType(bindingInfo.visibility);
ShaderVisibilityType(groupInfo.visibilities[dynamicBinding]);
} }
} }
@ -186,10 +190,11 @@ namespace dawn_native { namespace d3d12 {
return mRootSignature; return mRootSignature;
} }
uint32_t PipelineLayout::GetDynamicRootParameterIndex(uint32_t group, uint32_t binding) const { uint32_t PipelineLayout::GetDynamicRootParameterIndex(uint32_t group,
BindingIndex bindingIndex) const {
ASSERT(group < kMaxBindGroups); ASSERT(group < kMaxBindGroups);
ASSERT(binding < kMaxBindingsPerGroup); ASSERT(bindingIndex < kMaxBindingsPerGroup);
ASSERT(GetBindGroupLayout(group)->GetBindingInfo().hasDynamicOffset[binding]); ASSERT(GetBindGroupLayout(group)->GetBindingInfo(bindingIndex).hasDynamicOffset);
return mDynamicRootParameterIndices[group][binding]; return mDynamicRootParameterIndices[group][bindingIndex];
} }
}} // namespace dawn_native::d3d12 }} // namespace dawn_native::d3d12

View File

@ -15,8 +15,8 @@
#ifndef DAWNNATIVE_D3D12_PIPELINELAYOUTD3D12_H_ #ifndef DAWNNATIVE_D3D12_PIPELINELAYOUTD3D12_H_
#define DAWNNATIVE_D3D12_PIPELINELAYOUTD3D12_H_ #define DAWNNATIVE_D3D12_PIPELINELAYOUTD3D12_H_
#include "dawn_native/IntegerTypes.h"
#include "dawn_native/PipelineLayout.h" #include "dawn_native/PipelineLayout.h"
#include "dawn_native/d3d12/d3d12_platform.h" #include "dawn_native/d3d12/d3d12_platform.h"
namespace dawn_native { namespace d3d12 { namespace dawn_native { namespace d3d12 {
@ -32,7 +32,7 @@ namespace dawn_native { namespace d3d12 {
uint32_t GetSamplerRootParameterIndex(uint32_t group) const; uint32_t GetSamplerRootParameterIndex(uint32_t group) const;
// Returns the index of the root parameter reserved for a dynamic buffer binding // Returns the index of the root parameter reserved for a dynamic buffer binding
uint32_t GetDynamicRootParameterIndex(uint32_t group, uint32_t binding) const; uint32_t GetDynamicRootParameterIndex(uint32_t group, BindingIndex bindingIndex) const;
ComPtr<ID3D12RootSignature> GetRootSignature() const; ComPtr<ID3D12RootSignature> GetRootSignature() const;

View File

@ -493,19 +493,22 @@ namespace dawn_native { namespace metal {
uint32_t dynamicOffsetCount, uint32_t dynamicOffsetCount,
uint64_t* dynamicOffsets, uint64_t* dynamicOffsets,
PipelineLayout* pipelineLayout) { PipelineLayout* pipelineLayout) {
const BindGroupLayoutBase::LayoutBindingInfo& layout =
group->GetLayout()->GetBindingInfo();
uint32_t currentDynamicBufferIndex = 0; uint32_t currentDynamicBufferIndex = 0;
// TODO(kainino@chromium.org): Maintain buffers and offsets arrays in BindGroup // TODO(kainino@chromium.org): Maintain buffers and offsets arrays in BindGroup
// so that we only have to do one setVertexBuffers and one setFragmentBuffers // so that we only have to do one setVertexBuffers and one setFragmentBuffers
// call here. // call here.
for (BindingIndex bindingIndex = 0; bindingIndex < layout.bindingCount; for (BindingIndex bindingIndex = 0;
++bindingIndex) { bindingIndex < group->GetLayout()->GetBindingCount(); ++bindingIndex) {
auto stage = layout.visibilities[bindingIndex]; const BindGroupLayoutBase::BindingInfo& bindingInfo =
bool hasVertStage = stage & wgpu::ShaderStage::Vertex && render != nil; group->GetLayout()->GetBindingInfo(bindingIndex);
bool hasFragStage = stage & wgpu::ShaderStage::Fragment && render != nil;
bool hasComputeStage = stage & wgpu::ShaderStage::Compute && compute != nil; bool hasVertStage =
bindingInfo.visibility & wgpu::ShaderStage::Vertex && render != nil;
bool hasFragStage =
bindingInfo.visibility & wgpu::ShaderStage::Fragment && render != nil;
bool hasComputeStage =
bindingInfo.visibility & wgpu::ShaderStage::Compute && compute != nil;
uint32_t vertIndex = 0; uint32_t vertIndex = 0;
uint32_t fragIndex = 0; uint32_t fragIndex = 0;
@ -524,7 +527,7 @@ namespace dawn_native { namespace metal {
SingleShaderStage::Compute)[index][bindingIndex]; SingleShaderStage::Compute)[index][bindingIndex];
} }
switch (layout.types[bindingIndex]) { switch (bindingInfo.type) {
case wgpu::BindingType::UniformBuffer: case wgpu::BindingType::UniformBuffer:
case wgpu::BindingType::StorageBuffer: case wgpu::BindingType::StorageBuffer:
case wgpu::BindingType::ReadonlyStorageBuffer: { case wgpu::BindingType::ReadonlyStorageBuffer: {
@ -535,7 +538,7 @@ namespace dawn_native { namespace metal {
// TODO(shaobo.yan@intel.com): Record bound buffer status to use // TODO(shaobo.yan@intel.com): Record bound buffer status to use
// setBufferOffset to achieve better performance. // setBufferOffset to achieve better performance.
if (layout.hasDynamicOffset[bindingIndex]) { if (bindingInfo.hasDynamicOffset) {
offset += dynamicOffsets[currentDynamicBufferIndex]; offset += dynamicOffsets[currentDynamicBufferIndex];
currentDynamicBufferIndex++; currentDynamicBufferIndex++;
} }

View File

@ -29,15 +29,15 @@ namespace dawn_native { namespace metal {
uint32_t textureIndex = 0; uint32_t textureIndex = 0;
for (uint32_t group : IterateBitSet(GetBindGroupLayoutsMask())) { for (uint32_t group : IterateBitSet(GetBindGroupLayoutsMask())) {
const BindGroupLayoutBase::LayoutBindingInfo& groupInfo = for (BindingIndex bindingIndex = 0;
GetBindGroupLayout(group)->GetBindingInfo(); bindingIndex < GetBindGroupLayout(group)->GetBindingCount(); ++bindingIndex) {
for (BindingIndex bindingIndex = 0; bindingIndex < groupInfo.bindingCount; const BindGroupLayoutBase::BindingInfo& bindingInfo =
++bindingIndex) { GetBindGroupLayout(group)->GetBindingInfo(bindingIndex);
if (!(groupInfo.visibilities[bindingIndex] & StageBit(stage))) { if (!(bindingInfo.visibility & StageBit(stage))) {
continue; continue;
} }
switch (groupInfo.types[bindingIndex]) { switch (bindingInfo.type) {
case wgpu::BindingType::UniformBuffer: case wgpu::BindingType::UniformBuffer:
case wgpu::BindingType::StorageBuffer: case wgpu::BindingType::StorageBuffer:
case wgpu::BindingType::ReadonlyStorageBuffer: case wgpu::BindingType::ReadonlyStorageBuffer:

View File

@ -131,22 +131,23 @@ namespace dawn_native { namespace metal {
// Create one resource binding entry per stage per binding. // Create one resource binding entry per stage per binding.
for (uint32_t group : IterateBitSet(layout->GetBindGroupLayoutsMask())) { for (uint32_t group : IterateBitSet(layout->GetBindGroupLayoutsMask())) {
const BindGroupLayoutBase::LayoutBindingInfo& bgInfo =
layout->GetBindGroupLayout(group)->GetBindingInfo();
const BindGroupLayoutBase::BindingMap& bindingMap = const BindGroupLayoutBase::BindingMap& bindingMap =
layout->GetBindGroupLayout(group)->GetBindingMap(); layout->GetBindGroupLayout(group)->GetBindingMap();
for (const auto& it : bindingMap) { for (const auto& it : bindingMap) {
uint32_t binding = it.first; BindingNumber bindingNumber = it.first;
BindingIndex bindingIndex = it.second; BindingIndex bindingIndex = it.second;
for (auto stage : IterateStages(bgInfo.visibilities[bindingIndex])) { const BindGroupLayoutBase::BindingInfo& bindingInfo =
layout->GetBindGroupLayout(group)->GetBindingInfo(bindingIndex);
for (auto stage : IterateStages(bindingInfo.visibility)) {
uint32_t shaderIndex = layout->GetBindingIndexInfo(stage)[group][bindingIndex]; uint32_t shaderIndex = layout->GetBindingIndexInfo(stage)[group][bindingIndex];
if (GetDevice()->IsToggleEnabled(Toggle::UseSpvc)) { if (GetDevice()->IsToggleEnabled(Toggle::UseSpvc)) {
shaderc_spvc_msl_resource_binding mslBinding; shaderc_spvc_msl_resource_binding mslBinding;
mslBinding.stage = ToSpvcExecutionModel(stage); mslBinding.stage = ToSpvcExecutionModel(stage);
mslBinding.desc_set = group; mslBinding.desc_set = group;
mslBinding.binding = binding; mslBinding.binding = bindingNumber;
mslBinding.msl_buffer = mslBinding.msl_texture = mslBinding.msl_sampler = mslBinding.msl_buffer = mslBinding.msl_texture = mslBinding.msl_sampler =
shaderIndex; shaderIndex;
DAWN_TRY(CheckSpvcSuccess(mSpvcContext.AddMSLResourceBinding(mslBinding), DAWN_TRY(CheckSpvcSuccess(mSpvcContext.AddMSLResourceBinding(mslBinding),
@ -155,7 +156,7 @@ namespace dawn_native { namespace metal {
spirv_cross::MSLResourceBinding mslBinding; spirv_cross::MSLResourceBinding mslBinding;
mslBinding.stage = SpirvExecutionModelForStage(stage); mslBinding.stage = SpirvExecutionModelForStage(stage);
mslBinding.desc_set = group; mslBinding.desc_set = group;
mslBinding.binding = binding; mslBinding.binding = bindingNumber;
mslBinding.msl_buffer = mslBinding.msl_texture = mslBinding.msl_sampler = mslBinding.msl_buffer = mslBinding.msl_texture = mslBinding.msl_sampler =
shaderIndex; shaderIndex;

View File

@ -239,28 +239,45 @@ namespace dawn_native { namespace opengl {
uint32_t dynamicOffsetCount, uint32_t dynamicOffsetCount,
uint64_t* dynamicOffsets) { uint64_t* dynamicOffsets) {
const auto& indices = ToBackend(mPipelineLayout)->GetBindingIndexInfo()[index]; const auto& indices = ToBackend(mPipelineLayout)->GetBindingIndexInfo()[index];
const BindGroupLayoutBase::LayoutBindingInfo& layout = uint32_t currentDynamicOffsetIndex = 0;
group->GetLayout()->GetBindingInfo();
uint32_t currentDynamicIndex = 0;
for (BindingIndex bindingIndex = 0; bindingIndex < layout.bindingCount; for (BindingIndex bindingIndex = 0;
++bindingIndex) { bindingIndex < group->GetLayout()->GetBindingCount(); ++bindingIndex) {
switch (layout.types[bindingIndex]) { const BindGroupLayoutBase::BindingInfo& bindingInfo =
group->GetLayout()->GetBindingInfo(bindingIndex);
switch (bindingInfo.type) {
case wgpu::BindingType::UniformBuffer: { case wgpu::BindingType::UniformBuffer: {
BufferBinding binding = group->GetBindingAsBufferBinding(bindingIndex); BufferBinding binding = group->GetBindingAsBufferBinding(bindingIndex);
GLuint buffer = ToBackend(binding.buffer)->GetHandle(); GLuint buffer = ToBackend(binding.buffer)->GetHandle();
GLuint uboIndex = indices[bindingIndex]; GLuint uboIndex = indices[bindingIndex];
GLuint offset = binding.offset; GLuint offset = binding.offset;
if (layout.hasDynamicOffset[bindingIndex]) { if (bindingInfo.hasDynamicOffset) {
offset += dynamicOffsets[currentDynamicIndex]; offset += dynamicOffsets[currentDynamicOffsetIndex];
++currentDynamicIndex; ++currentDynamicOffsetIndex;
} }
gl.BindBufferRange(GL_UNIFORM_BUFFER, uboIndex, buffer, offset, gl.BindBufferRange(GL_UNIFORM_BUFFER, uboIndex, buffer, offset,
binding.size); binding.size);
} break; } break;
case wgpu::BindingType::StorageBuffer:
case wgpu::BindingType::ReadonlyStorageBuffer: {
BufferBinding binding = group->GetBindingAsBufferBinding(bindingIndex);
GLuint buffer = ToBackend(binding.buffer)->GetHandle();
GLuint ssboIndex = indices[bindingIndex];
GLuint offset = binding.offset;
if (bindingInfo.hasDynamicOffset) {
offset += dynamicOffsets[currentDynamicOffsetIndex];
++currentDynamicOffsetIndex;
}
gl.BindBufferRange(GL_SHADER_STORAGE_BUFFER, ssboIndex, buffer, offset,
binding.size);
} break;
case wgpu::BindingType::Sampler: { case wgpu::BindingType::Sampler: {
Sampler* sampler = ToBackend(group->GetBindingAsSampler(bindingIndex)); Sampler* sampler = ToBackend(group->GetBindingAsSampler(bindingIndex));
GLuint samplerIndex = indices[bindingIndex]; GLuint samplerIndex = indices[bindingIndex];
@ -290,22 +307,6 @@ namespace dawn_native { namespace opengl {
} }
} break; } break;
case wgpu::BindingType::StorageBuffer:
case wgpu::BindingType::ReadonlyStorageBuffer: {
BufferBinding binding = group->GetBindingAsBufferBinding(bindingIndex);
GLuint buffer = ToBackend(binding.buffer)->GetHandle();
GLuint ssboIndex = indices[bindingIndex];
GLuint offset = binding.offset;
if (layout.hasDynamicOffset[bindingIndex]) {
offset += dynamicOffsets[currentDynamicIndex];
++currentDynamicIndex;
}
gl.BindBufferRange(GL_SHADER_STORAGE_BUFFER, ssboIndex, buffer, offset,
binding.size);
} break;
case wgpu::BindingType::StorageTexture: case wgpu::BindingType::StorageTexture:
case wgpu::BindingType::ReadonlyStorageTexture: case wgpu::BindingType::ReadonlyStorageTexture:
case wgpu::BindingType::WriteonlyStorageTexture: case wgpu::BindingType::WriteonlyStorageTexture:

View File

@ -107,15 +107,14 @@ namespace dawn_native { namespace opengl {
const auto& indices = layout->GetBindingIndexInfo(); const auto& indices = layout->GetBindingIndexInfo();
for (uint32_t group : IterateBitSet(layout->GetBindGroupLayoutsMask())) { for (uint32_t group : IterateBitSet(layout->GetBindGroupLayoutsMask())) {
const BindGroupLayoutBase::LayoutBindingInfo& groupInfo = const BindGroupLayoutBase* bgl = layout->GetBindGroupLayout(group);
layout->GetBindGroupLayout(group)->GetBindingInfo();
for (const auto& it : layout->GetBindGroupLayout(group)->GetBindingMap()) { for (const auto& it : bgl->GetBindingMap()) {
BindingNumber bindingNumber = it.first; BindingNumber bindingNumber = it.first;
BindingIndex bindingIndex = it.second; BindingIndex bindingIndex = it.second;
std::string name = GetBindingName(group, bindingNumber); std::string name = GetBindingName(group, bindingNumber);
switch (groupInfo.types[bindingIndex]) { switch (bgl->GetBindingInfo(bindingIndex).type) {
case wgpu::BindingType::UniformBuffer: { case wgpu::BindingType::UniformBuffer: {
GLint location = gl.GetUniformBlockIndex(mProgram, name.c_str()); GLint location = gl.GetUniformBlockIndex(mProgram, name.c_str());
if (location != -1) { if (location != -1) {
@ -178,10 +177,11 @@ namespace dawn_native { namespace opengl {
indices[combined.textureLocation.group][combined.textureLocation.binding]; indices[combined.textureLocation.group][combined.textureLocation.binding];
mUnitsForTextures[textureIndex].push_back(textureUnit); mUnitsForTextures[textureIndex].push_back(textureUnit);
const BindGroupLayoutBase* bgl =
layout->GetBindGroupLayout(combined.textureLocation.group);
wgpu::TextureComponentType componentType = wgpu::TextureComponentType componentType =
layout->GetBindGroupLayout(combined.textureLocation.group) bgl->GetBindingInfo(bgl->GetBindingIndex(combined.textureLocation.binding))
->GetBindingInfo() .textureComponentType;
.textureComponentTypes[combined.textureLocation.binding];
bool shouldUseFiltering = componentType == wgpu::TextureComponentType::Float; bool shouldUseFiltering = componentType == wgpu::TextureComponentType::Float;
GLuint samplerIndex = GLuint samplerIndex =

View File

@ -28,12 +28,11 @@ namespace dawn_native { namespace opengl {
GLuint ssboIndex = 0; GLuint ssboIndex = 0;
for (uint32_t group : IterateBitSet(GetBindGroupLayoutsMask())) { for (uint32_t group : IterateBitSet(GetBindGroupLayoutsMask())) {
const BindGroupLayoutBase::LayoutBindingInfo& groupInfo = const BindGroupLayoutBase* bgl = GetBindGroupLayout(group);
GetBindGroupLayout(group)->GetBindingInfo();
for (BindingIndex bindingIndex = 0; bindingIndex < groupInfo.bindingCount; for (BindingIndex bindingIndex = 0; bindingIndex < bgl->GetBindingCount();
++bindingIndex) { ++bindingIndex) {
switch (groupInfo.types[bindingIndex]) { switch (bgl->GetBindingInfo(bindingIndex).type) {
case wgpu::BindingType::UniformBuffer: case wgpu::BindingType::UniformBuffer:
mIndexInfo[group][bindingIndex] = uboIndex; mIndexInfo[group][bindingIndex] = uboIndex;
uboIndex++; uboIndex++;

View File

@ -82,8 +82,6 @@ namespace dawn_native { namespace vulkan {
} }
MaybeError BindGroupLayout::Initialize() { MaybeError BindGroupLayout::Initialize() {
const LayoutBindingInfo& info = GetBindingInfo();
// Compute the bindings that will be chained in the DescriptorSetLayout create info. We add // Compute the bindings that will be chained in the DescriptorSetLayout create info. We add
// one entry per binding set. This might be optimized by computing continuous ranges of // one entry per binding set. This might be optimized by computing continuous ranges of
// bindings of the same type. // bindings of the same type.
@ -92,13 +90,14 @@ namespace dawn_native { namespace vulkan {
for (const auto& it : GetBindingMap()) { for (const auto& it : GetBindingMap()) {
BindingNumber bindingNumber = it.first; BindingNumber bindingNumber = it.first;
BindingIndex bindingIndex = it.second; BindingIndex bindingIndex = it.second;
const BindingInfo& bindingInfo = GetBindingInfo(bindingIndex);
VkDescriptorSetLayoutBinding* vkBinding = &bindings[numBindings]; VkDescriptorSetLayoutBinding* vkBinding = &bindings[numBindings];
vkBinding->binding = bindingNumber; vkBinding->binding = bindingNumber;
vkBinding->descriptorType = vkBinding->descriptorType =
VulkanDescriptorType(info.types[bindingIndex], info.hasDynamicOffset[bindingIndex]); VulkanDescriptorType(bindingInfo.type, bindingInfo.hasDynamicOffset);
vkBinding->descriptorCount = 1; vkBinding->descriptorCount = 1;
vkBinding->stageFlags = VulkanShaderStageFlags(info.visibilities[bindingIndex]); vkBinding->stageFlags = VulkanShaderStageFlags(bindingInfo.visibility);
vkBinding->pImmutableSamplers = nullptr; vkBinding->pImmutableSamplers = nullptr;
numBindings++; numBindings++;
@ -119,9 +118,10 @@ namespace dawn_native { namespace vulkan {
// Compute the size of descriptor pools used for this layout. // Compute the size of descriptor pools used for this layout.
std::map<VkDescriptorType, uint32_t> descriptorCountPerType; std::map<VkDescriptorType, uint32_t> descriptorCountPerType;
for (BindingIndex bindingIndex = 0; bindingIndex < info.bindingCount; ++bindingIndex) { for (BindingIndex bindingIndex = 0; bindingIndex < GetBindingCount(); ++bindingIndex) {
const BindingInfo& bindingInfo = GetBindingInfo(bindingIndex);
VkDescriptorType vulkanType = VkDescriptorType vulkanType =
VulkanDescriptorType(info.types[bindingIndex], info.hasDynamicOffset[bindingIndex]); VulkanDescriptorType(bindingInfo.type, bindingInfo.hasDynamicOffset);
// map::operator[] will return 0 if the key doesn't exist. // map::operator[] will return 0 if the key doesn't exist.
descriptorCountPerType[vulkanType]++; descriptorCountPerType[vulkanType]++;

View File

@ -43,10 +43,11 @@ namespace dawn_native { namespace vulkan {
std::array<VkDescriptorBufferInfo, kMaxBindingsPerGroup> writeBufferInfo; std::array<VkDescriptorBufferInfo, kMaxBindingsPerGroup> writeBufferInfo;
std::array<VkDescriptorImageInfo, kMaxBindingsPerGroup> writeImageInfo; std::array<VkDescriptorImageInfo, kMaxBindingsPerGroup> writeImageInfo;
const BindGroupLayoutBase::LayoutBindingInfo& layoutInfo = GetLayout()->GetBindingInfo();
for (const auto& it : GetLayout()->GetBindingMap()) { for (const auto& it : GetLayout()->GetBindingMap()) {
BindingNumber bindingNumber = it.first; BindingNumber bindingNumber = it.first;
BindingIndex bindingIndex = it.second; BindingIndex bindingIndex = it.second;
const BindGroupLayoutBase::BindingInfo& bindingInfo =
GetLayout()->GetBindingInfo(bindingIndex);
auto& write = writes[numWrites]; auto& write = writes[numWrites];
write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
@ -55,10 +56,10 @@ namespace dawn_native { namespace vulkan {
write.dstBinding = bindingNumber; write.dstBinding = bindingNumber;
write.dstArrayElement = 0; write.dstArrayElement = 0;
write.descriptorCount = 1; write.descriptorCount = 1;
write.descriptorType = VulkanDescriptorType(layoutInfo.types[bindingIndex], write.descriptorType =
layoutInfo.hasDynamicOffset[bindingIndex]); VulkanDescriptorType(bindingInfo.type, bindingInfo.hasDynamicOffset);
switch (layoutInfo.types[bindingIndex]) { switch (bindingInfo.type) {
case wgpu::BindingType::UniformBuffer: case wgpu::BindingType::UniformBuffer:
case wgpu::BindingType::StorageBuffer: case wgpu::BindingType::StorageBuffer:
case wgpu::BindingType::ReadonlyStorageBuffer: { case wgpu::BindingType::ReadonlyStorageBuffer: {