Use TypedInteger for BindGroupIndex

Bug: dawn:442
Change-Id: I889a943cbaf2d349c31a15fdf126d66964bdd0a7
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/23247
Commit-Queue: Austin Eng <enga@chromium.org>
Reviewed-by: Stephen White <senorblanco@chromium.org>
This commit is contained in:
Austin Eng 2020-06-20 01:30:32 +00:00 committed by Commit Bot service account
parent e5d94c31a0
commit 250f26229b
33 changed files with 218 additions and 149 deletions

View File

@ -17,6 +17,7 @@
#include "common/Platform.h" #include "common/Platform.h"
#include "common/TypedInteger.h" #include "common/TypedInteger.h"
#include "common/ityp_bitset.h"
#include <bitset> #include <bitset>
#include <functional> #include <functional>
@ -87,4 +88,14 @@ size_t Hash(const std::bitset<N>& value) {
} }
#endif #endif
namespace std {
template <typename Index, size_t N>
class hash<ityp::bitset<Index, N>> {
public:
size_t operator()(const ityp::bitset<Index, N>& value) const {
return Hash(static_cast<const std::bitset<N>&>(value));
}
};
} // namespace std
#endif // COMMON_HASHUTILS_H_ #endif // COMMON_HASHUTILS_H_

View File

@ -62,12 +62,14 @@ using TypedInteger = T;
namespace detail { namespace detail {
template <typename Tag, typename T> template <typename Tag, typename T>
class TypedIntegerImpl { class alignas(T) TypedIntegerImpl {
static_assert(std::is_integral<T>::value, "TypedInteger must be integral"); static_assert(std::is_integral<T>::value, "TypedInteger must be integral");
T mValue; T mValue;
public: public:
constexpr TypedIntegerImpl() : mValue(0) { constexpr TypedIntegerImpl() : mValue(0) {
static_assert(alignof(TypedIntegerImpl) == alignof(T), "");
static_assert(sizeof(TypedIntegerImpl) == sizeof(T), "");
} }
// Construction from non-narrowing integral types. // Construction from non-narrowing integral types.

View File

@ -58,6 +58,14 @@ namespace ityp {
using Base::none; using Base::none;
using Base::size; using Base::size;
bool operator==(const bitset& other) const noexcept {
return Base::operator==(static_cast<const Base&>(other));
}
bool operator!=(const bitset& other) const noexcept {
return Base::operator!=(static_cast<const Base&>(other));
}
bitset& operator&=(const bitset& other) noexcept { bitset& operator&=(const bitset& other) noexcept {
return static_cast<bitset&>(Base::operator&=(static_cast<const Base&>(other))); return static_cast<bitset&>(Base::operator&=(static_cast<const Base&>(other)));
} }
@ -117,6 +125,8 @@ namespace ityp {
friend BitSetIterator<N, Index> IterateBitSet(const bitset& bitset) { friend BitSetIterator<N, Index> IterateBitSet(const bitset& bitset) {
return BitSetIterator<N, Index>(static_cast<const Base&>(bitset)); return BitSetIterator<N, Index>(static_cast<const Base&>(bitset));
} }
friend class std::hash<bitset>;
}; };
} // namespace ityp } // namespace ityp

View File

@ -32,10 +32,12 @@ namespace dawn_native {
public: public:
BindGroupAndStorageBarrierTrackerBase() = default; BindGroupAndStorageBarrierTrackerBase() = default;
void OnSetBindGroup(uint32_t index, void OnSetBindGroup(BindGroupIndex index,
BindGroupBase* bindGroup, BindGroupBase* bindGroup,
uint32_t dynamicOffsetCount, uint32_t dynamicOffsetCount,
uint32_t* dynamicOffsets) { uint32_t* dynamicOffsets) {
ASSERT(index < kMaxBindGroupsTyped);
if (this->mBindGroups[index] != bindGroup) { if (this->mBindGroups[index] != bindGroup) {
mBindings[index] = {}; mBindings[index] = {};
mBindingsNeedingBarrier[index] = {}; mBindingsNeedingBarrier[index] = {};
@ -89,12 +91,16 @@ namespace dawn_native {
} }
protected: protected:
std::array<ityp::bitset<BindingIndex, kMaxBindingsPerGroup>, kMaxBindGroups> ityp::
mBindingsNeedingBarrier = {}; array<BindGroupIndex, ityp::bitset<BindingIndex, kMaxBindingsPerGroup>, kMaxBindGroups>
std::array<ityp::array<BindingIndex, wgpu::BindingType, kMaxBindingsPerGroup>, mBindingsNeedingBarrier = {};
kMaxBindGroups> ityp::array<BindGroupIndex,
ityp::array<BindingIndex, wgpu::BindingType, kMaxBindingsPerGroup>,
kMaxBindGroups>
mBindingTypes = {}; mBindingTypes = {};
std::array<ityp::array<BindingIndex, ObjectBase*, kMaxBindingsPerGroup>, kMaxBindGroups> ityp::array<BindGroupIndex,
ityp::array<BindingIndex, ObjectBase*, kMaxBindingsPerGroup>,
kMaxBindGroups>
mBindings = {}; mBindings = {};
}; };

View File

@ -32,11 +32,11 @@ namespace dawn_native {
template <bool CanInheritBindGroups, typename DynamicOffset> template <bool CanInheritBindGroups, typename DynamicOffset>
class BindGroupTrackerBase { class BindGroupTrackerBase {
public: public:
void OnSetBindGroup(uint32_t index, void OnSetBindGroup(BindGroupIndex index,
BindGroupBase* bindGroup, BindGroupBase* bindGroup,
uint32_t dynamicOffsetCount, uint32_t dynamicOffsetCount,
uint32_t* dynamicOffsets) { uint32_t* dynamicOffsets) {
ASSERT(index < kMaxBindGroups); ASSERT(index < kMaxBindGroupsTyped);
if (mBindGroupLayoutsMask[index]) { if (mBindGroupLayoutsMask[index]) {
// It is okay to only dirty bind groups that are used by the current pipeline // It is okay to only dirty bind groups that are used by the current pipeline
@ -73,7 +73,7 @@ namespace dawn_native {
// the first |k| matching bind groups may be inherited. // the first |k| matching bind groups may be inherited.
if (CanInheritBindGroups && mLastAppliedPipelineLayout != nullptr) { if (CanInheritBindGroups && mLastAppliedPipelineLayout != nullptr) {
// Dirty bind groups that cannot be inherited. // Dirty bind groups that cannot be inherited.
std::bitset<kMaxBindGroups> dirtiedGroups = BindGroupLayoutMask dirtiedGroups =
~mPipelineLayout->InheritedGroupsMask(mLastAppliedPipelineLayout); ~mPipelineLayout->InheritedGroupsMask(mLastAppliedPipelineLayout);
mDirtyBindGroups |= dirtiedGroups; mDirtyBindGroups |= dirtiedGroups;
@ -98,12 +98,12 @@ namespace dawn_native {
mLastAppliedPipelineLayout = mPipelineLayout; mLastAppliedPipelineLayout = mPipelineLayout;
} }
std::bitset<kMaxBindGroups> mDirtyBindGroups = 0; BindGroupLayoutMask mDirtyBindGroups = 0;
std::bitset<kMaxBindGroups> mDirtyBindGroupsObjectChangedOrIsDynamic = 0; BindGroupLayoutMask mDirtyBindGroupsObjectChangedOrIsDynamic = 0;
std::bitset<kMaxBindGroups> mBindGroupLayoutsMask = 0; BindGroupLayoutMask mBindGroupLayoutsMask = 0;
std::array<BindGroupBase*, kMaxBindGroups> mBindGroups = {}; ityp::array<BindGroupIndex, BindGroupBase*, kMaxBindGroups> mBindGroups = {};
std::array<uint32_t, kMaxBindGroups> mDynamicOffsetCounts = {}; ityp::array<BindGroupIndex, uint32_t, kMaxBindGroups> mDynamicOffsetCounts = {};
std::array<std::array<DynamicOffset, kMaxBindingsPerGroup>, kMaxBindGroups> ityp::array<BindGroupIndex, std::array<DynamicOffset, kMaxBindingsPerGroup>, kMaxBindGroups>
mDynamicOffsets = {}; mDynamicOffsets = {};
// |mPipelineLayout| is the current pipeline layout set on the command buffer. // |mPipelineLayout| is the current pipeline layout set on the command buffer.

View File

@ -17,6 +17,7 @@
#include "common/Constants.h" #include "common/Constants.h"
#include "common/TypedInteger.h" #include "common/TypedInteger.h"
#include "common/ityp_array.h"
#include "dawn_native/Format.h" #include "dawn_native/Format.h"
#include "dawn_native/dawn_platform.h" #include "dawn_native/dawn_platform.h"
@ -30,7 +31,10 @@ namespace dawn_native {
// Binding numbers get mapped to a packed range of indices // Binding numbers get mapped to a packed range of indices
using BindingIndex = TypedInteger<struct BindingIndexT, uint32_t>; using BindingIndex = TypedInteger<struct BindingIndexT, uint32_t>;
using BindGroupIndex = TypedInteger<struct BindGroupIndexT, uint32_t>;
static constexpr BindingIndex kMaxBindingsPerGroupTyped = BindingIndex(kMaxBindingsPerGroup); static constexpr BindingIndex kMaxBindingsPerGroupTyped = BindingIndex(kMaxBindingsPerGroup);
static constexpr BindGroupIndex kMaxBindGroupsTyped = BindGroupIndex(kMaxBindGroups);
struct BindingInfo { struct BindingInfo {
BindingNumber binding; BindingNumber binding;
@ -45,7 +49,7 @@ namespace dawn_native {
}; };
// For buffer size validation // For buffer size validation
using RequiredBufferSizes = std::array<std::vector<uint64_t>, kMaxBindGroups>; using RequiredBufferSizes = ityp::array<BindGroupIndex, std::vector<uint64_t>, kMaxBindGroups>;
} // namespace dawn_native } // namespace dawn_native

View File

@ -100,7 +100,7 @@ namespace dawn_native {
if (aspects[VALIDATION_ASPECT_BIND_GROUPS]) { if (aspects[VALIDATION_ASPECT_BIND_GROUPS]) {
bool matches = true; bool matches = true;
for (uint32_t i : IterateBitSet(mLastPipelineLayout->GetBindGroupLayoutsMask())) { for (BindGroupIndex i : IterateBitSet(mLastPipelineLayout->GetBindGroupLayoutsMask())) {
if (mBindgroups[i] == nullptr || if (mBindgroups[i] == nullptr ||
mLastPipelineLayout->GetBindGroupLayout(i) != mBindgroups[i]->GetLayout() || mLastPipelineLayout->GetBindGroupLayout(i) != mBindgroups[i]->GetLayout() ||
!BufferSizesAtLeastAsBig(mBindgroups[i]->GetUnverifiedBufferSizes(), !BufferSizesAtLeastAsBig(mBindgroups[i]->GetUnverifiedBufferSizes(),
@ -140,18 +140,19 @@ namespace dawn_native {
} }
if (aspects[VALIDATION_ASPECT_BIND_GROUPS]) { if (aspects[VALIDATION_ASPECT_BIND_GROUPS]) {
for (uint32_t i : IterateBitSet(mLastPipelineLayout->GetBindGroupLayoutsMask())) { for (BindGroupIndex i : IterateBitSet(mLastPipelineLayout->GetBindGroupLayoutsMask())) {
if (mBindgroups[i] == nullptr) { if (mBindgroups[i] == nullptr) {
return DAWN_VALIDATION_ERROR("Missing bind group " + std::to_string(i)); return DAWN_VALIDATION_ERROR("Missing bind group " +
std::to_string(static_cast<uint32_t>(i)));
} else if (mLastPipelineLayout->GetBindGroupLayout(i) != } else if (mLastPipelineLayout->GetBindGroupLayout(i) !=
mBindgroups[i]->GetLayout()) { mBindgroups[i]->GetLayout()) {
return DAWN_VALIDATION_ERROR( return DAWN_VALIDATION_ERROR(
"Pipeline and bind group layout doesn't match for bind group " + "Pipeline and bind group layout doesn't match for bind group " +
std::to_string(i)); std::to_string(static_cast<uint32_t>(i)));
} else if (!BufferSizesAtLeastAsBig(mBindgroups[i]->GetUnverifiedBufferSizes(), } else if (!BufferSizesAtLeastAsBig(mBindgroups[i]->GetUnverifiedBufferSizes(),
(*mMinimumBufferSizes)[i])) { (*mMinimumBufferSizes)[i])) {
return DAWN_VALIDATION_ERROR("Binding sizes too small for bind group " + return DAWN_VALIDATION_ERROR("Binding sizes too small for bind group " +
std::to_string(i)); std::to_string(static_cast<uint32_t>(i)));
} }
} }
@ -179,7 +180,7 @@ namespace dawn_native {
SetPipelineCommon(pipeline); SetPipelineCommon(pipeline);
} }
void CommandBufferStateTracker::SetBindGroup(uint32_t index, BindGroupBase* bindgroup) { void CommandBufferStateTracker::SetBindGroup(BindGroupIndex index, BindGroupBase* bindgroup) {
mBindgroups[index] = bindgroup; mBindgroups[index] = bindgroup;
mAspects.reset(VALIDATION_ASPECT_BIND_GROUPS); mAspects.reset(VALIDATION_ASPECT_BIND_GROUPS);
} }

View File

@ -16,11 +16,11 @@
#define DAWNNATIVE_COMMANDBUFFERSTATETRACKER_H #define DAWNNATIVE_COMMANDBUFFERSTATETRACKER_H
#include "common/Constants.h" #include "common/Constants.h"
#include "common/ityp_array.h"
#include "dawn_native/BindingInfo.h" #include "dawn_native/BindingInfo.h"
#include "dawn_native/Error.h" #include "dawn_native/Error.h"
#include "dawn_native/Forward.h" #include "dawn_native/Forward.h"
#include <array>
#include <bitset> #include <bitset>
#include <map> #include <map>
#include <set> #include <set>
@ -37,7 +37,7 @@ namespace dawn_native {
// State-modifying methods // State-modifying methods
void SetComputePipeline(ComputePipelineBase* pipeline); void SetComputePipeline(ComputePipelineBase* pipeline);
void SetRenderPipeline(RenderPipelineBase* pipeline); void SetRenderPipeline(RenderPipelineBase* pipeline);
void SetBindGroup(uint32_t index, BindGroupBase* bindgroup); void SetBindGroup(BindGroupIndex index, BindGroupBase* bindgroup);
void SetIndexBuffer(); void SetIndexBuffer();
void SetVertexBuffer(uint32_t slot); void SetVertexBuffer(uint32_t slot);
@ -53,7 +53,7 @@ namespace dawn_native {
ValidationAspects mAspects; ValidationAspects mAspects;
std::array<BindGroupBase*, kMaxBindGroups> mBindgroups = {}; ityp::array<BindGroupIndex, BindGroupBase*, kMaxBindGroups> mBindgroups = {};
std::bitset<kMaxVertexBuffers> mVertexBufferSlotsUsed; std::bitset<kMaxVertexBuffers> mVertexBufferSlotsUsed;
PipelineLayoutBase* mLastPipelineLayout = nullptr; PipelineLayoutBase* mLastPipelineLayout = nullptr;

View File

@ -18,6 +18,7 @@
#include "common/Constants.h" #include "common/Constants.h"
#include "dawn_native/AttachmentState.h" #include "dawn_native/AttachmentState.h"
#include "dawn_native/BindingInfo.h"
#include "dawn_native/Texture.h" #include "dawn_native/Texture.h"
#include "dawn_native/dawn_platform.h" #include "dawn_native/dawn_platform.h"
@ -210,7 +211,7 @@ namespace dawn_native {
}; };
struct SetBindGroupCmd { struct SetBindGroupCmd {
uint32_t index; BindGroupIndex index;
Ref<BindGroupBase> group; Ref<BindGroupBase> group;
uint32_t dynamicOffsetCount; uint32_t dynamicOffsetCount;
}; };

View File

@ -85,11 +85,12 @@ namespace dawn_native {
return {}; return {};
} }
BindGroupLayoutBase* PipelineBase::GetBindGroupLayout(uint32_t groupIndex) { BindGroupLayoutBase* PipelineBase::GetBindGroupLayout(uint32_t groupIndexIn) {
if (GetDevice()->ConsumedError(ValidateGetBindGroupLayout(groupIndex))) { if (GetDevice()->ConsumedError(ValidateGetBindGroupLayout(groupIndexIn))) {
return BindGroupLayoutBase::MakeError(GetDevice()); return BindGroupLayoutBase::MakeError(GetDevice());
} }
BindGroupIndex groupIndex(groupIndexIn);
if (!mLayout->GetBindGroupLayoutsMask()[groupIndex]) { if (!mLayout->GetBindGroupLayoutsMask()[groupIndex]) {
// Get or create an empty bind group layout. // Get or create an empty bind group layout.
// TODO(enga): Consider caching this object on the Device and reusing it. // TODO(enga): Consider caching this object on the Device and reusing it.

View File

@ -97,8 +97,9 @@ namespace dawn_native {
const PipelineLayoutDescriptor* descriptor) const PipelineLayoutDescriptor* descriptor)
: CachedObject(device) { : CachedObject(device) {
ASSERT(descriptor->bindGroupLayoutCount <= kMaxBindGroups); ASSERT(descriptor->bindGroupLayoutCount <= kMaxBindGroups);
for (uint32_t group = 0; group < descriptor->bindGroupLayoutCount; ++group) { for (BindGroupIndex group(0); group < BindGroupIndex(descriptor->bindGroupLayoutCount);
mBindGroupLayouts[group] = descriptor->bindGroupLayouts[group]; ++group) {
mBindGroupLayouts[group] = descriptor->bindGroupLayouts[static_cast<uint32_t>(group)];
mMask.set(group); mMask.set(group);
} }
} }
@ -127,22 +128,24 @@ namespace dawn_native {
ASSERT(count > 0); ASSERT(count > 0);
// Data which BindGroupLayoutDescriptor will point to for creation // Data which BindGroupLayoutDescriptor will point to for creation
std::array<ityp::array<BindingIndex, BindGroupLayoutEntry, kMaxBindingsPerGroup>, ityp::array<BindGroupIndex,
kMaxBindGroups> ityp::array<BindingIndex, BindGroupLayoutEntry, kMaxBindingsPerGroup>,
kMaxBindGroups>
entryData = {}; entryData = {};
// A map of bindings to the index in |entryData| // A map of bindings to the index in |entryData|
std::array<std::map<BindingNumber, BindingIndex>, kMaxBindGroups> usedBindingsMap = {}; ityp::array<BindGroupIndex, std::map<BindingNumber, BindingIndex>, kMaxBindGroups>
usedBindingsMap = {};
// A counter of how many bindings we've populated in |entryData| // A counter of how many bindings we've populated in |entryData|
std::array<BindingIndex, kMaxBindGroups> entryCounts = {}; ityp::array<BindGroupIndex, BindingIndex, kMaxBindGroups> entryCounts = {};
uint32_t bindGroupLayoutCount = 0; BindGroupIndex bindGroupLayoutCount(0);
for (uint32_t moduleIndex = 0; moduleIndex < count; ++moduleIndex) { for (uint32_t moduleIndex = 0; moduleIndex < count; ++moduleIndex) {
const ShaderModuleBase* module = modules[moduleIndex]; const ShaderModuleBase* module = modules[moduleIndex];
const ShaderModuleBase::ModuleBindingInfo& info = module->GetBindingInfo(); const ShaderModuleBase::ModuleBindingInfo& info = module->GetBindingInfo();
for (uint32_t group = 0; group < info.size(); ++group) { for (BindGroupIndex group(0); group < info.size(); ++group) {
for (const auto& it : info[group]) { for (const auto& it : info[group]) {
BindingNumber bindingNumber = it.first; BindingNumber bindingNumber = it.first;
const ShaderModuleBase::ShaderBindingInfo& bindingInfo = it.second; const ShaderModuleBase::ShaderBindingInfo& bindingInfo = it.second;
@ -205,13 +208,14 @@ namespace dawn_native {
entryCounts[group]++; entryCounts[group]++;
bindGroupLayoutCount = std::max(bindGroupLayoutCount, group + 1); bindGroupLayoutCount =
std::max(bindGroupLayoutCount, group + BindGroupIndex(1));
} }
} }
} }
std::array<BindGroupLayoutBase*, kMaxBindGroups> bindGroupLayouts = {}; ityp::array<BindGroupIndex, BindGroupLayoutBase*, kMaxBindGroups> bindGroupLayouts = {};
for (uint32_t group = 0; group < bindGroupLayoutCount; ++group) { for (BindGroupIndex group(0); group < bindGroupLayoutCount; ++group) {
BindGroupLayoutDescriptor desc = {}; BindGroupLayoutDescriptor desc = {};
desc.entries = entryData[group].data(); desc.entries = entryData[group].data();
desc.entryCount = static_cast<uint32_t>(entryCounts[group]); desc.entryCount = static_cast<uint32_t>(entryCounts[group]);
@ -223,13 +227,13 @@ namespace dawn_native {
PipelineLayoutDescriptor desc = {}; PipelineLayoutDescriptor desc = {};
desc.bindGroupLayouts = bindGroupLayouts.data(); desc.bindGroupLayouts = bindGroupLayouts.data();
desc.bindGroupLayoutCount = bindGroupLayoutCount; desc.bindGroupLayoutCount = static_cast<uint32_t>(bindGroupLayoutCount);
PipelineLayoutBase* pipelineLayout = device->CreatePipelineLayout(&desc); PipelineLayoutBase* pipelineLayout = device->CreatePipelineLayout(&desc);
ASSERT(!pipelineLayout->IsError()); ASSERT(!pipelineLayout->IsError());
// These bind group layouts are created internally and referenced by the pipeline layout. // These bind group layouts are created internally and referenced by the pipeline layout.
// Release the external refcount. // Release the external refcount.
for (uint32_t group = 0; group < bindGroupLayoutCount; ++group) { for (BindGroupIndex group(0); group < bindGroupLayoutCount; ++group) {
if (bindGroupLayouts[group] != nullptr) { if (bindGroupLayouts[group] != nullptr) {
bindGroupLayouts[group]->Release(); bindGroupLayouts[group]->Release();
} }
@ -244,50 +248,50 @@ namespace dawn_native {
return pipelineLayout; return pipelineLayout;
} }
const BindGroupLayoutBase* PipelineLayoutBase::GetBindGroupLayout(uint32_t group) const { const BindGroupLayoutBase* PipelineLayoutBase::GetBindGroupLayout(BindGroupIndex group) const {
ASSERT(!IsError()); ASSERT(!IsError());
ASSERT(group < kMaxBindGroups); ASSERT(group < kMaxBindGroupsTyped);
ASSERT(mMask[group]); ASSERT(mMask[group]);
const BindGroupLayoutBase* bgl = mBindGroupLayouts[group].Get(); const BindGroupLayoutBase* bgl = mBindGroupLayouts[group].Get();
ASSERT(bgl != nullptr); ASSERT(bgl != nullptr);
return bgl; return bgl;
} }
BindGroupLayoutBase* PipelineLayoutBase::GetBindGroupLayout(uint32_t group) { BindGroupLayoutBase* PipelineLayoutBase::GetBindGroupLayout(BindGroupIndex group) {
ASSERT(!IsError()); ASSERT(!IsError());
ASSERT(group < kMaxBindGroups); ASSERT(group < kMaxBindGroupsTyped);
ASSERT(mMask[group]); ASSERT(mMask[group]);
BindGroupLayoutBase* bgl = mBindGroupLayouts[group].Get(); BindGroupLayoutBase* bgl = mBindGroupLayouts[group].Get();
ASSERT(bgl != nullptr); ASSERT(bgl != nullptr);
return bgl; return bgl;
} }
const std::bitset<kMaxBindGroups> PipelineLayoutBase::GetBindGroupLayoutsMask() const { const BindGroupLayoutMask& PipelineLayoutBase::GetBindGroupLayoutsMask() const {
ASSERT(!IsError()); ASSERT(!IsError());
return mMask; return mMask;
} }
std::bitset<kMaxBindGroups> PipelineLayoutBase::InheritedGroupsMask( BindGroupLayoutMask PipelineLayoutBase::InheritedGroupsMask(
const PipelineLayoutBase* other) const { const PipelineLayoutBase* other) const {
ASSERT(!IsError()); ASSERT(!IsError());
return {(1 << GroupsInheritUpTo(other)) - 1u}; return {(1 << static_cast<uint32_t>(GroupsInheritUpTo(other))) - 1u};
} }
uint32_t PipelineLayoutBase::GroupsInheritUpTo(const PipelineLayoutBase* other) const { BindGroupIndex PipelineLayoutBase::GroupsInheritUpTo(const PipelineLayoutBase* other) const {
ASSERT(!IsError()); ASSERT(!IsError());
for (uint32_t i = 0; i < kMaxBindGroups; ++i) { for (BindGroupIndex i(0); i < kMaxBindGroupsTyped; ++i) {
if (!mMask[i] || mBindGroupLayouts[i].Get() != other->mBindGroupLayouts[i].Get()) { if (!mMask[i] || mBindGroupLayouts[i].Get() != other->mBindGroupLayouts[i].Get()) {
return i; return i;
} }
} }
return kMaxBindGroups; return kMaxBindGroupsTyped;
} }
size_t PipelineLayoutBase::HashFunc::operator()(const PipelineLayoutBase* pl) const { size_t PipelineLayoutBase::HashFunc::operator()(const PipelineLayoutBase* pl) const {
size_t hash = Hash(pl->mMask); size_t hash = Hash(pl->mMask);
for (uint32_t group : IterateBitSet(pl->mMask)) { for (BindGroupIndex group : IterateBitSet(pl->mMask)) {
HashCombine(&hash, pl->GetBindGroupLayout(group)); HashCombine(&hash, pl->GetBindGroupLayout(group));
} }
@ -300,7 +304,7 @@ namespace dawn_native {
return false; return false;
} }
for (uint32_t group : IterateBitSet(a->mMask)) { for (BindGroupIndex group : IterateBitSet(a->mMask)) {
if (a->GetBindGroupLayout(group) != b->GetBindGroupLayout(group)) { if (a->GetBindGroupLayout(group) != b->GetBindGroupLayout(group)) {
return false; return false;
} }

View File

@ -16,6 +16,9 @@
#define DAWNNATIVE_PIPELINELAYOUT_H_ #define DAWNNATIVE_PIPELINELAYOUT_H_
#include "common/Constants.h" #include "common/Constants.h"
#include "common/ityp_array.h"
#include "common/ityp_bitset.h"
#include "dawn_native/BindingInfo.h"
#include "dawn_native/CachedObject.h" #include "dawn_native/CachedObject.h"
#include "dawn_native/Error.h" #include "dawn_native/Error.h"
#include "dawn_native/Forward.h" #include "dawn_native/Forward.h"
@ -30,7 +33,9 @@ namespace dawn_native {
MaybeError ValidatePipelineLayoutDescriptor(DeviceBase*, MaybeError ValidatePipelineLayoutDescriptor(DeviceBase*,
const PipelineLayoutDescriptor* descriptor); const PipelineLayoutDescriptor* descriptor);
using BindGroupLayoutArray = std::array<Ref<BindGroupLayoutBase>, kMaxBindGroups>; using BindGroupLayoutArray =
ityp::array<BindGroupIndex, Ref<BindGroupLayoutBase>, kMaxBindGroups>;
using BindGroupLayoutMask = ityp::bitset<BindGroupIndex, kMaxBindGroups>;
class PipelineLayoutBase : public CachedObject { class PipelineLayoutBase : public CachedObject {
public: public:
@ -41,17 +46,17 @@ namespace dawn_native {
static ResultOrError<PipelineLayoutBase*> static ResultOrError<PipelineLayoutBase*>
CreateDefault(DeviceBase* device, const ShaderModuleBase* const* modules, uint32_t count); CreateDefault(DeviceBase* device, const ShaderModuleBase* const* modules, uint32_t count);
const BindGroupLayoutBase* GetBindGroupLayout(uint32_t group) const; const BindGroupLayoutBase* GetBindGroupLayout(BindGroupIndex group) const;
BindGroupLayoutBase* GetBindGroupLayout(uint32_t group); BindGroupLayoutBase* GetBindGroupLayout(BindGroupIndex group);
const std::bitset<kMaxBindGroups> GetBindGroupLayoutsMask() const; const BindGroupLayoutMask& GetBindGroupLayoutsMask() const;
// Utility functions to compute inherited bind groups. // Utility functions to compute inherited bind groups.
// Returns the inherited bind groups as a mask. // Returns the inherited bind groups as a mask.
std::bitset<kMaxBindGroups> InheritedGroupsMask(const PipelineLayoutBase* other) const; BindGroupLayoutMask InheritedGroupsMask(const PipelineLayoutBase* other) const;
// Returns the index of the first incompatible bind group in the range // Returns the index of the first incompatible bind group in the range
// [1, kMaxBindGroups + 1] // [0, kMaxBindGroups]
uint32_t GroupsInheritUpTo(const PipelineLayoutBase* other) const; BindGroupIndex GroupsInheritUpTo(const PipelineLayoutBase* other) const;
// Functors necessary for the unordered_set<PipelineLayoutBase*>-based cache. // Functors necessary for the unordered_set<PipelineLayoutBase*>-based cache.
struct HashFunc { struct HashFunc {
@ -65,7 +70,7 @@ namespace dawn_native {
PipelineLayoutBase(DeviceBase* device, ObjectBase::ErrorTag tag); PipelineLayoutBase(DeviceBase* device, ObjectBase::ErrorTag tag);
BindGroupLayoutArray mBindGroupLayouts; BindGroupLayoutArray mBindGroupLayouts;
std::bitset<kMaxBindGroups> mMask; BindGroupLayoutMask mMask;
}; };
} // namespace dawn_native } // namespace dawn_native

View File

@ -130,15 +130,17 @@ namespace dawn_native {
}); });
} }
void ProgrammablePassEncoder::SetBindGroup(uint32_t groupIndex, void ProgrammablePassEncoder::SetBindGroup(uint32_t groupIndexIn,
BindGroupBase* group, BindGroupBase* group,
uint32_t dynamicOffsetCountIn, uint32_t dynamicOffsetCountIn,
const uint32_t* dynamicOffsetsIn) { const uint32_t* dynamicOffsetsIn) {
mEncodingContext->TryEncode(this, [&](CommandAllocator* allocator) -> MaybeError { mEncodingContext->TryEncode(this, [&](CommandAllocator* allocator) -> MaybeError {
BindGroupIndex groupIndex(groupIndexIn);
if (GetDevice()->IsValidationEnabled()) { if (GetDevice()->IsValidationEnabled()) {
DAWN_TRY(GetDevice()->ValidateObject(group)); DAWN_TRY(GetDevice()->ValidateObject(group));
if (groupIndex >= kMaxBindGroups) { if (groupIndex >= kMaxBindGroupsTyped) {
return DAWN_VALIDATION_ERROR("Setting bind group over the max"); return DAWN_VALIDATION_ERROR("Setting bind group over the max");
} }

View File

@ -194,7 +194,7 @@ namespace dawn_native {
descriptor->fragmentStage->module->ComputeRequiredBufferSizesForLayout( descriptor->fragmentStage->module->ComputeRequiredBufferSizesForLayout(
descriptor->layout); descriptor->layout);
for (uint32_t group = 0; group < bufferSizes.size(); ++group) { for (BindGroupIndex group(0); group < bufferSizes.size(); ++group) {
ASSERT(bufferSizes[group].size() == fragmentSizes[group].size()); ASSERT(bufferSizes[group].size() == fragmentSizes[group].size());
for (size_t i = 0; i < bufferSizes[group].size(); ++i) { for (size_t i = 0; i < bufferSizes[group].size(); ++i) {
bufferSizes[group][i] = bufferSizes[group][i] =

View File

@ -289,10 +289,10 @@ namespace dawn_native {
} }
} }
std::string GetShaderDeclarationString(size_t group, BindingNumber binding) { std::string GetShaderDeclarationString(BindGroupIndex group, BindingNumber binding) {
std::ostringstream ostream; std::ostringstream ostream;
ostream << "the shader module declaration at set " << group << " binding " ostream << "the shader module declaration at set " << static_cast<uint32_t>(group)
<< static_cast<uint32_t>(binding); << " binding " << static_cast<uint32_t>(binding);
return ostream.str(); return ostream.str();
} }
} // anonymous namespace } // anonymous namespace
@ -515,12 +515,14 @@ namespace dawn_native {
auto ExtractResourcesBinding = auto ExtractResourcesBinding =
[this](std::vector<shaderc_spvc_binding_info> bindings) -> MaybeError { [this](std::vector<shaderc_spvc_binding_info> bindings) -> MaybeError {
for (const auto& binding : bindings) { for (const auto& binding : bindings) {
if (binding.set >= kMaxBindGroups) { BindGroupIndex bindGroupIndex(binding.set);
if (bindGroupIndex >= kMaxBindGroupsTyped) {
return DAWN_VALIDATION_ERROR("Bind group index over limits in the SPIRV"); return DAWN_VALIDATION_ERROR("Bind group index over limits in the SPIRV");
} }
const auto& it = mBindingInfo[binding.set].emplace(BindingNumber(binding.binding), const auto& it = mBindingInfo[bindGroupIndex].emplace(
ShaderBindingInfo{}); BindingNumber(binding.binding), ShaderBindingInfo{});
if (!it.second) { if (!it.second) {
return DAWN_VALIDATION_ERROR("Shader has duplicate bindings"); return DAWN_VALIDATION_ERROR("Shader has duplicate bindings");
} }
@ -702,13 +704,15 @@ namespace dawn_native {
BindingNumber bindingNumber( BindingNumber bindingNumber(
compiler.get_decoration(resource.id, spv::DecorationBinding)); compiler.get_decoration(resource.id, spv::DecorationBinding));
uint32_t set = compiler.get_decoration(resource.id, spv::DecorationDescriptorSet); BindGroupIndex bindGroupIndex(
compiler.get_decoration(resource.id, spv::DecorationDescriptorSet));
if (set >= kMaxBindGroups) { if (bindGroupIndex >= kMaxBindGroupsTyped) {
return DAWN_VALIDATION_ERROR("Bind group index over limits in the SPIRV"); return DAWN_VALIDATION_ERROR("Bind group index over limits in the SPIRV");
} }
const auto& it = mBindingInfo[set].emplace(bindingNumber, ShaderBindingInfo{}); const auto& it =
mBindingInfo[bindGroupIndex].emplace(bindingNumber, ShaderBindingInfo{});
if (!it.second) { if (!it.second) {
return DAWN_VALIDATION_ERROR("Shader has duplicate bindings"); return DAWN_VALIDATION_ERROR("Shader has duplicate bindings");
} }
@ -884,7 +888,7 @@ namespace dawn_native {
RequiredBufferSizes ShaderModuleBase::ComputeRequiredBufferSizesForLayout( RequiredBufferSizes ShaderModuleBase::ComputeRequiredBufferSizesForLayout(
const PipelineLayoutBase* layout) const { const PipelineLayoutBase* layout) const {
RequiredBufferSizes bufferSizes; RequiredBufferSizes bufferSizes;
for (uint32_t group : IterateBitSet(layout->GetBindGroupLayoutsMask())) { for (BindGroupIndex group : IterateBitSet(layout->GetBindGroupLayoutsMask())) {
bufferSizes[group] = bufferSizes[group] =
GetBindGroupMinBufferSizes(mBindingInfo[group], layout->GetBindGroupLayout(group)); GetBindGroupMinBufferSizes(mBindingInfo[group], layout->GetBindGroupLayout(group));
} }
@ -926,16 +930,16 @@ namespace dawn_native {
const PipelineLayoutBase* layout) const { const PipelineLayoutBase* layout) const {
ASSERT(!IsError()); ASSERT(!IsError());
for (uint32_t group : IterateBitSet(layout->GetBindGroupLayoutsMask())) { for (BindGroupIndex group : IterateBitSet(layout->GetBindGroupLayoutsMask())) {
DAWN_TRY( DAWN_TRY(
ValidateCompatibilityWithBindGroupLayout(group, layout->GetBindGroupLayout(group))); ValidateCompatibilityWithBindGroupLayout(group, layout->GetBindGroupLayout(group)));
} }
for (uint32_t group : IterateBitSet(~layout->GetBindGroupLayoutsMask())) { for (BindGroupIndex group : IterateBitSet(~layout->GetBindGroupLayoutsMask())) {
if (mBindingInfo[group].size() > 0) { if (mBindingInfo[group].size() > 0) {
std::ostringstream ostream; std::ostringstream ostream;
ostream << "No bind group layout entry matches the declaration set " << group ostream << "No bind group layout entry matches the declaration set "
<< " in the shader module"; << static_cast<uint32_t>(group) << " in the shader module";
return DAWN_VALIDATION_ERROR(ostream.str()); return DAWN_VALIDATION_ERROR(ostream.str());
} }
} }
@ -944,7 +948,7 @@ namespace dawn_native {
} }
MaybeError ShaderModuleBase::ValidateCompatibilityWithBindGroupLayout( MaybeError ShaderModuleBase::ValidateCompatibilityWithBindGroupLayout(
uint32_t group, BindGroupIndex group,
const BindGroupLayoutBase* layout) const { const BindGroupLayoutBase* layout) const {
ASSERT(!IsError()); ASSERT(!IsError());

View File

@ -16,6 +16,7 @@
#define DAWNNATIVE_SHADERMODULE_H_ #define DAWNNATIVE_SHADERMODULE_H_
#include "common/Constants.h" #include "common/Constants.h"
#include "common/ityp_array.h"
#include "dawn_native/BindingInfo.h" #include "dawn_native/BindingInfo.h"
#include "dawn_native/CachedObject.h" #include "dawn_native/CachedObject.h"
#include "dawn_native/Error.h" #include "dawn_native/Error.h"
@ -27,7 +28,6 @@
#include "spvc/spvc.hpp" #include "spvc/spvc.hpp"
#include <array>
#include <bitset> #include <bitset>
#include <map> #include <map>
#include <vector> #include <vector>
@ -64,7 +64,7 @@ namespace dawn_native {
}; };
using BindingInfoMap = std::map<BindingNumber, ShaderBindingInfo>; using BindingInfoMap = std::map<BindingNumber, ShaderBindingInfo>;
using ModuleBindingInfo = std::array<BindingInfoMap, kMaxBindGroups>; using ModuleBindingInfo = ityp::array<BindGroupIndex, BindingInfoMap, kMaxBindGroups>;
const ModuleBindingInfo& GetBindingInfo() const; const ModuleBindingInfo& GetBindingInfo() const;
const std::bitset<kMaxVertexAttributes>& GetUsedVertexAttributes() const; const std::bitset<kMaxVertexAttributes>& GetUsedVertexAttributes() const;
@ -102,7 +102,7 @@ namespace dawn_native {
ShaderModuleBase(DeviceBase* device, ObjectBase::ErrorTag tag); ShaderModuleBase(DeviceBase* device, ObjectBase::ErrorTag tag);
MaybeError ValidateCompatibilityWithBindGroupLayout( MaybeError ValidateCompatibilityWithBindGroupLayout(
uint32_t group, BindGroupIndex group,
const BindGroupLayoutBase* layout) const; const BindGroupLayoutBase* layout) const;
std::vector<uint64_t> GetBindGroupMinBufferSizes(const BindingInfoMap& shaderMap, std::vector<uint64_t> GetBindGroupMinBufferSizes(const BindingInfoMap& shaderMap,

View File

@ -106,7 +106,7 @@ namespace dawn_native { namespace d3d12 {
// TODO(bryan.bernhart@intel.com): Consider further optimization. // TODO(bryan.bernhart@intel.com): Consider further optimization.
bool didCreateBindGroupViews = true; bool didCreateBindGroupViews = true;
bool didCreateBindGroupSamplers = true; bool didCreateBindGroupSamplers = true;
for (uint32_t index : IterateBitSet(mDirtyBindGroups)) { for (BindGroupIndex index : IterateBitSet(mDirtyBindGroups)) {
BindGroup* group = ToBackend(mBindGroups[index]); BindGroup* group = ToBackend(mBindGroups[index]);
didCreateBindGroupViews = group->PopulateViews(mViewAllocator); didCreateBindGroupViews = group->PopulateViews(mViewAllocator);
didCreateBindGroupSamplers = group->PopulateSamplers(mDevice, mSamplerAllocator); didCreateBindGroupSamplers = group->PopulateSamplers(mDevice, mSamplerAllocator);
@ -132,7 +132,7 @@ namespace dawn_native { namespace d3d12 {
// Must be called before applying the bindgroups. // Must be called before applying the bindgroups.
SetID3D12DescriptorHeaps(commandList); SetID3D12DescriptorHeaps(commandList);
for (uint32_t index : IterateBitSet(mBindGroupLayoutsMask)) { for (BindGroupIndex index : IterateBitSet(mBindGroupLayoutsMask)) {
BindGroup* group = ToBackend(mBindGroups[index]); BindGroup* group = ToBackend(mBindGroups[index]);
didCreateBindGroupViews = group->PopulateViews(mViewAllocator); didCreateBindGroupViews = group->PopulateViews(mViewAllocator);
didCreateBindGroupSamplers = didCreateBindGroupSamplers =
@ -142,14 +142,14 @@ namespace dawn_native { namespace d3d12 {
} }
} }
for (uint32_t index : IterateBitSet(mDirtyBindGroupsObjectChangedOrIsDynamic)) { for (BindGroupIndex index : IterateBitSet(mDirtyBindGroupsObjectChangedOrIsDynamic)) {
BindGroup* group = ToBackend(mBindGroups[index]); BindGroup* group = ToBackend(mBindGroups[index]);
ApplyBindGroup(commandList, ToBackend(mPipelineLayout), index, group, ApplyBindGroup(commandList, ToBackend(mPipelineLayout), index, group,
mDynamicOffsetCounts[index], mDynamicOffsets[index].data()); mDynamicOffsetCounts[index], mDynamicOffsets[index].data());
} }
if (mInCompute) { if (mInCompute) {
for (uint32_t index : IterateBitSet(mBindGroupLayoutsMask)) { for (BindGroupIndex index : IterateBitSet(mBindGroupLayoutsMask)) {
for (BindingIndex binding : IterateBitSet(mBindingsNeedingBarrier[index])) { for (BindingIndex binding : IterateBitSet(mBindingsNeedingBarrier[index])) {
wgpu::BindingType bindingType = mBindingTypes[index][binding]; wgpu::BindingType bindingType = mBindingTypes[index][binding];
switch (bindingType) { switch (bindingType) {
@ -211,7 +211,7 @@ namespace dawn_native { namespace d3d12 {
private: private:
void ApplyBindGroup(ID3D12GraphicsCommandList* commandList, void ApplyBindGroup(ID3D12GraphicsCommandList* commandList,
const PipelineLayout* pipelineLayout, const PipelineLayout* pipelineLayout,
uint32_t index, BindGroupIndex index,
BindGroup* group, BindGroup* group,
uint32_t dynamicOffsetCountIn, uint32_t dynamicOffsetCountIn,
const uint64_t* dynamicOffsetsIn) { const uint64_t* dynamicOffsetsIn) {

View File

@ -79,7 +79,7 @@ namespace dawn_native { namespace d3d12 {
uint32_t rangeIndex = 0; uint32_t rangeIndex = 0;
for (uint32_t group : IterateBitSet(GetBindGroupLayoutsMask())) { for (BindGroupIndex group : IterateBitSet(GetBindGroupLayoutsMask())) {
const BindGroupLayout* bindGroupLayout = ToBackend(GetBindGroupLayout(group)); const BindGroupLayout* bindGroupLayout = ToBackend(GetBindGroupLayout(group));
// 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
@ -99,7 +99,7 @@ namespace dawn_native { namespace d3d12 {
for (uint32_t i = 0; i < rangeCount; ++i) { for (uint32_t i = 0; i < rangeCount; ++i) {
ranges[rangeIndex] = descriptorRanges[i]; ranges[rangeIndex] = descriptorRanges[i];
ranges[rangeIndex].RegisterSpace = group; ranges[rangeIndex].RegisterSpace = static_cast<uint32_t>(group);
rangeIndex++; rangeIndex++;
} }
@ -140,7 +140,7 @@ namespace dawn_native { namespace d3d12 {
// Setup root descriptor. // Setup root descriptor.
D3D12_ROOT_DESCRIPTOR rootDescriptor; D3D12_ROOT_DESCRIPTOR rootDescriptor;
rootDescriptor.ShaderRegister = shaderRegisters[dynamicBindingIndex]; rootDescriptor.ShaderRegister = shaderRegisters[dynamicBindingIndex];
rootDescriptor.RegisterSpace = group; rootDescriptor.RegisterSpace = static_cast<uint32_t>(group);
// Set root descriptors in root signatures. // Set root descriptors in root signatures.
rootParameter.Descriptor = rootDescriptor; rootParameter.Descriptor = rootDescriptor;
@ -177,13 +177,13 @@ namespace dawn_native { namespace d3d12 {
return {}; return {};
} }
uint32_t PipelineLayout::GetCbvUavSrvRootParameterIndex(uint32_t group) const { uint32_t PipelineLayout::GetCbvUavSrvRootParameterIndex(BindGroupIndex group) const {
ASSERT(group < kMaxBindGroups); ASSERT(group < kMaxBindGroupsTyped);
return mCbvUavSrvRootParameterInfo[group]; return mCbvUavSrvRootParameterInfo[group];
} }
uint32_t PipelineLayout::GetSamplerRootParameterIndex(uint32_t group) const { uint32_t PipelineLayout::GetSamplerRootParameterIndex(BindGroupIndex group) const {
ASSERT(group < kMaxBindGroups); ASSERT(group < kMaxBindGroupsTyped);
return mSamplerRootParameterInfo[group]; return mSamplerRootParameterInfo[group];
} }
@ -191,9 +191,9 @@ namespace dawn_native { namespace d3d12 {
return mRootSignature.Get(); return mRootSignature.Get();
} }
uint32_t PipelineLayout::GetDynamicRootParameterIndex(uint32_t group, uint32_t PipelineLayout::GetDynamicRootParameterIndex(BindGroupIndex group,
BindingIndex bindingIndex) const { BindingIndex bindingIndex) const {
ASSERT(group < kMaxBindGroups); ASSERT(group < kMaxBindGroupsTyped);
ASSERT(bindingIndex < kMaxBindingsPerGroupTyped); ASSERT(bindingIndex < kMaxBindingsPerGroupTyped);
ASSERT(GetBindGroupLayout(group)->GetBindingInfo(bindingIndex).hasDynamicOffset); ASSERT(GetBindGroupLayout(group)->GetBindingInfo(bindingIndex).hasDynamicOffset);
ASSERT(GetBindGroupLayout(group)->GetBindingInfo(bindingIndex).visibility != ASSERT(GetBindGroupLayout(group)->GetBindingInfo(bindingIndex).visibility !=

View File

@ -29,11 +29,12 @@ namespace dawn_native { namespace d3d12 {
static ResultOrError<PipelineLayout*> Create(Device* device, static ResultOrError<PipelineLayout*> Create(Device* device,
const PipelineLayoutDescriptor* descriptor); const PipelineLayoutDescriptor* descriptor);
uint32_t GetCbvUavSrvRootParameterIndex(uint32_t group) const; uint32_t GetCbvUavSrvRootParameterIndex(BindGroupIndex group) const;
uint32_t GetSamplerRootParameterIndex(uint32_t group) const; uint32_t GetSamplerRootParameterIndex(BindGroupIndex 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, BindingIndex bindingIndex) const; uint32_t GetDynamicRootParameterIndex(BindGroupIndex group,
BindingIndex bindingIndex) const;
ID3D12RootSignature* GetRootSignature() const; ID3D12RootSignature* GetRootSignature() const;
@ -41,9 +42,11 @@ namespace dawn_native { namespace d3d12 {
~PipelineLayout() override = default; ~PipelineLayout() override = default;
using PipelineLayoutBase::PipelineLayoutBase; using PipelineLayoutBase::PipelineLayoutBase;
MaybeError Initialize(); MaybeError Initialize();
std::array<uint32_t, kMaxBindGroups> mCbvUavSrvRootParameterInfo; ityp::array<BindGroupIndex, uint32_t, kMaxBindGroups> mCbvUavSrvRootParameterInfo;
std::array<uint32_t, kMaxBindGroups> mSamplerRootParameterInfo; ityp::array<BindGroupIndex, uint32_t, kMaxBindGroups> mSamplerRootParameterInfo;
std::array<ityp::array<BindingIndex, uint32_t, kMaxBindingsPerGroup>, kMaxBindGroups> ityp::array<BindGroupIndex,
ityp::array<BindingIndex, uint32_t, kMaxBindingsPerGroup>,
kMaxBindGroups>
mDynamicRootParameterIndices; mDynamicRootParameterIndices;
ComPtr<ID3D12RootSignature> mRootSignature; ComPtr<ID3D12RootSignature> mRootSignature;
}; };

View File

@ -155,7 +155,7 @@ namespace dawn_native { namespace d3d12 {
} }
const ModuleBindingInfo& moduleBindingInfo = GetBindingInfo(); const ModuleBindingInfo& moduleBindingInfo = GetBindingInfo();
for (uint32_t group : IterateBitSet(layout->GetBindGroupLayoutsMask())) { for (BindGroupIndex group : IterateBitSet(layout->GetBindGroupLayoutsMask())) {
const BindGroupLayout* bgl = ToBackend(layout->GetBindGroupLayout(group)); const BindGroupLayout* bgl = ToBackend(layout->GetBindGroupLayout(group));
const auto& bindingOffsets = bgl->GetBindingOffsets(); const auto& bindingOffsets = bgl->GetBindingOffsets();
const auto& groupBindingInfo = moduleBindingInfo[group]; const auto& groupBindingInfo = moduleBindingInfo[group];
@ -181,14 +181,14 @@ namespace dawn_native { namespace d3d12 {
if (forceStorageBufferAsUAV) { if (forceStorageBufferAsUAV) {
DAWN_TRY(CheckSpvcSuccess( DAWN_TRY(CheckSpvcSuccess(
mSpvcContext.SetHLSLForceStorageBufferAsUAV( mSpvcContext.SetHLSLForceStorageBufferAsUAV(
group, static_cast<uint32_t>(bindingNumber)), static_cast<uint32_t>(group), static_cast<uint32_t>(bindingNumber)),
"Unable to force read-only storage buffer as UAV w/ spvc")); "Unable to force read-only storage buffer as UAV w/ spvc"));
} }
} else { } else {
compiler->set_decoration(bindingInfo.id, spv::DecorationBinding, bindingOffset); compiler->set_decoration(bindingInfo.id, spv::DecorationBinding, bindingOffset);
if (forceStorageBufferAsUAV) { if (forceStorageBufferAsUAV) {
compiler->set_hlsl_force_storage_buffer_as_uav( compiler->set_hlsl_force_storage_buffer_as_uav(
group, static_cast<uint32_t>(bindingNumber)); static_cast<uint32_t>(group), static_cast<uint32_t>(bindingNumber));
} }
} }
} }

View File

@ -471,7 +471,8 @@ namespace dawn_native { namespace metal {
template <typename Encoder> template <typename Encoder>
void Apply(Encoder encoder) { void Apply(Encoder encoder) {
for (uint32_t index : IterateBitSet(mDirtyBindGroupsObjectChangedOrIsDynamic)) { for (BindGroupIndex index :
IterateBitSet(mDirtyBindGroupsObjectChangedOrIsDynamic)) {
ApplyBindGroup(encoder, index, ToBackend(mBindGroups[index]), ApplyBindGroup(encoder, index, ToBackend(mBindGroups[index]),
mDynamicOffsetCounts[index], mDynamicOffsets[index].data(), mDynamicOffsetCounts[index], mDynamicOffsets[index].data(),
ToBackend(mPipelineLayout)); ToBackend(mPipelineLayout));
@ -486,7 +487,7 @@ namespace dawn_native { namespace metal {
// two encoder types. // two encoder types.
void ApplyBindGroupImpl(id<MTLRenderCommandEncoder> render, void ApplyBindGroupImpl(id<MTLRenderCommandEncoder> render,
id<MTLComputeCommandEncoder> compute, id<MTLComputeCommandEncoder> compute,
uint32_t index, BindGroupIndex index,
BindGroup* group, BindGroup* group,
uint32_t dynamicOffsetCount, uint32_t dynamicOffsetCount,
uint64_t* dynamicOffsets, uint64_t* dynamicOffsets,

View File

@ -43,7 +43,9 @@ namespace dawn_native { namespace metal {
PipelineLayout(Device* device, const PipelineLayoutDescriptor* descriptor); PipelineLayout(Device* device, const PipelineLayoutDescriptor* descriptor);
using BindingIndexInfo = using BindingIndexInfo =
std::array<ityp::array<BindingIndex, uint32_t, kMaxBindingsPerGroup>, kMaxBindGroups>; ityp::array<BindGroupIndex,
ityp::array<BindingIndex, uint32_t, kMaxBindingsPerGroup>,
kMaxBindGroups>;
const BindingIndexInfo& GetBindingIndexInfo(SingleShaderStage stage) const; const BindingIndexInfo& GetBindingIndexInfo(SingleShaderStage stage) const;
// The number of Metal vertex stage buffers used for the whole pipeline layout. // The number of Metal vertex stage buffers used for the whole pipeline layout.

View File

@ -28,7 +28,7 @@ namespace dawn_native { namespace metal {
uint32_t samplerIndex = 0; uint32_t samplerIndex = 0;
uint32_t textureIndex = 0; uint32_t textureIndex = 0;
for (uint32_t group : IterateBitSet(GetBindGroupLayoutsMask())) { for (BindGroupIndex group : IterateBitSet(GetBindGroupLayoutsMask())) {
for (BindingIndex bindingIndex{0}; for (BindingIndex bindingIndex{0};
bindingIndex < GetBindGroupLayout(group)->GetBindingCount(); ++bindingIndex) { bindingIndex < GetBindGroupLayout(group)->GetBindingCount(); ++bindingIndex) {
const BindingInfo& bindingInfo = const BindingInfo& bindingInfo =

View File

@ -132,7 +132,7 @@ namespace dawn_native { namespace metal {
// a table of MSLResourceBinding to give to SPIRV-Cross. // a table of MSLResourceBinding to give to SPIRV-Cross.
// 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 (BindGroupIndex group : IterateBitSet(layout->GetBindGroupLayoutsMask())) {
const BindGroupLayoutBase::BindingMap& bindingMap = const BindGroupLayoutBase::BindingMap& bindingMap =
layout->GetBindGroupLayout(group)->GetBindingMap(); layout->GetBindGroupLayout(group)->GetBindingMap();
@ -148,7 +148,7 @@ namespace dawn_native { namespace metal {
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 = static_cast<uint32_t>(group);
mslBinding.binding = static_cast<uint32_t>(bindingNumber); mslBinding.binding = static_cast<uint32_t>(bindingNumber);
mslBinding.msl_buffer = mslBinding.msl_texture = mslBinding.msl_sampler = mslBinding.msl_buffer = mslBinding.msl_texture = mslBinding.msl_sampler =
shaderIndex; shaderIndex;
@ -157,7 +157,7 @@ namespace dawn_native { namespace metal {
} else { } else {
spirv_cross::MSLResourceBinding mslBinding; spirv_cross::MSLResourceBinding mslBinding;
mslBinding.stage = SpirvExecutionModelForStage(stage); mslBinding.stage = SpirvExecutionModelForStage(stage);
mslBinding.desc_set = group; mslBinding.desc_set = static_cast<uint32_t>(group);
mslBinding.binding = static_cast<uint32_t>(bindingNumber); mslBinding.binding = static_cast<uint32_t>(bindingNumber);
mslBinding.msl_buffer = mslBinding.msl_texture = mslBinding.msl_sampler = mslBinding.msl_buffer = mslBinding.msl_texture = mslBinding.msl_sampler =
shaderIndex; shaderIndex;

View File

@ -225,7 +225,8 @@ namespace dawn_native { namespace opengl {
} }
void Apply(const OpenGLFunctions& gl) { void Apply(const OpenGLFunctions& gl) {
for (uint32_t index : IterateBitSet(mDirtyBindGroupsObjectChangedOrIsDynamic)) { for (BindGroupIndex index :
IterateBitSet(mDirtyBindGroupsObjectChangedOrIsDynamic)) {
ApplyBindGroup(gl, index, mBindGroups[index], mDynamicOffsetCounts[index], ApplyBindGroup(gl, index, mBindGroups[index], mDynamicOffsetCounts[index],
mDynamicOffsets[index].data()); mDynamicOffsets[index].data());
} }
@ -234,7 +235,7 @@ namespace dawn_native { namespace opengl {
private: private:
void ApplyBindGroup(const OpenGLFunctions& gl, void ApplyBindGroup(const OpenGLFunctions& gl,
uint32_t index, BindGroupIndex index,
BindGroupBase* group, BindGroupBase* group,
uint32_t dynamicOffsetCount, uint32_t dynamicOffsetCount,
uint64_t* dynamicOffsets) { uint64_t* dynamicOffsets) {

View File

@ -106,7 +106,7 @@ namespace dawn_native { namespace opengl {
// etc. // etc.
const auto& indices = layout->GetBindingIndexInfo(); const auto& indices = layout->GetBindingIndexInfo();
for (uint32_t group : IterateBitSet(layout->GetBindGroupLayoutsMask())) { for (BindGroupIndex group : IterateBitSet(layout->GetBindGroupLayoutsMask())) {
const BindGroupLayoutBase* bgl = layout->GetBindGroupLayout(group); const BindGroupLayoutBase* bgl = layout->GetBindGroupLayout(group);
for (const auto& it : bgl->GetBindingMap()) { for (const auto& it : bgl->GetBindingMap()) {

View File

@ -36,8 +36,9 @@ namespace dawn_native { namespace opengl {
const PipelineLayout* layout, const PipelineLayout* layout,
const PerStage<const ShaderModule*>& modules); const PerStage<const ShaderModule*>& modules);
using BindingLocations = using BindingLocations = ityp::array<BindGroupIndex,
std::array<std::array<GLint, kMaxBindingsPerGroup>, kMaxBindGroups>; ityp::array<BindingIndex, GLint, kMaxBindingsPerGroup>,
kMaxBindGroups>;
// For each unit a sampler is bound to we need to know if we should use filtering or not // For each unit a sampler is bound to we need to know if we should use filtering or not
// because int and uint texture are only complete without filtering. // because int and uint texture are only complete without filtering.

View File

@ -28,7 +28,7 @@ namespace dawn_native { namespace opengl {
GLuint ssboIndex = 0; GLuint ssboIndex = 0;
GLuint storageTextureIndex = 0; GLuint storageTextureIndex = 0;
for (uint32_t group : IterateBitSet(GetBindGroupLayoutsMask())) { for (BindGroupIndex group : IterateBitSet(GetBindGroupLayoutsMask())) {
const BindGroupLayoutBase* bgl = GetBindGroupLayout(group); const BindGroupLayoutBase* bgl = GetBindGroupLayout(group);
for (BindingIndex bindingIndex{0}; bindingIndex < bgl->GetBindingCount(); for (BindingIndex bindingIndex{0}; bindingIndex < bgl->GetBindingCount();

View File

@ -30,7 +30,9 @@ namespace dawn_native { namespace opengl {
PipelineLayout(Device* device, const PipelineLayoutDescriptor* descriptor); PipelineLayout(Device* device, const PipelineLayoutDescriptor* descriptor);
using BindingIndexInfo = using BindingIndexInfo =
std::array<ityp::array<BindingIndex, GLuint, kMaxBindingsPerGroup>, kMaxBindGroups>; ityp::array<BindGroupIndex,
ityp::array<BindingIndex, GLuint, kMaxBindingsPerGroup>,
kMaxBindGroups>;
const BindingIndexInfo& GetBindingIndexInfo() const; const BindingIndexInfo& GetBindingIndexInfo() const;
GLuint GetTextureUnitsUsed() const; GLuint GetTextureUnitsUsed() const;

View File

@ -24,9 +24,10 @@
namespace dawn_native { namespace opengl { namespace dawn_native { namespace opengl {
std::string GetBindingName(uint32_t group, BindingNumber bindingNumber) { std::string GetBindingName(BindGroupIndex group, BindingNumber bindingNumber) {
std::ostringstream o; std::ostringstream o;
o << "dawn_binding_" << group << "_" << static_cast<uint32_t>(bindingNumber); o << "dawn_binding_" << static_cast<uint32_t>(group) << "_"
<< static_cast<uint32_t>(bindingNumber);
return o.str(); return o.str();
} }
@ -42,8 +43,9 @@ namespace dawn_native { namespace opengl {
std::string CombinedSampler::GetName() const { std::string CombinedSampler::GetName() const {
std::ostringstream o; std::ostringstream o;
o << "dawn_combined"; o << "dawn_combined";
o << "_" << samplerLocation.group << "_" << static_cast<uint32_t>(samplerLocation.binding); o << "_" << static_cast<uint32_t>(samplerLocation.group) << "_"
o << "_with_" << textureLocation.group << "_" << static_cast<uint32_t>(samplerLocation.binding);
o << "_with_" << static_cast<uint32_t>(textureLocation.group) << "_"
<< static_cast<uint32_t>(textureLocation.binding); << static_cast<uint32_t>(textureLocation.binding);
return o.str(); return o.str();
} }
@ -141,16 +143,20 @@ namespace dawn_native { namespace opengl {
mCombinedInfo.emplace_back(); mCombinedInfo.emplace_back();
auto& info = mCombinedInfo.back(); auto& info = mCombinedInfo.back();
uint32_t samplerGroup;
mSpvcContext.GetDecoration(sampler.sampler_id, mSpvcContext.GetDecoration(sampler.sampler_id,
shaderc_spvc_decoration_descriptorset, shaderc_spvc_decoration_descriptorset, &samplerGroup);
&info.samplerLocation.group); info.samplerLocation.group = BindGroupIndex(samplerGroup);
uint32_t samplerBinding; uint32_t samplerBinding;
mSpvcContext.GetDecoration(sampler.sampler_id, shaderc_spvc_decoration_binding, mSpvcContext.GetDecoration(sampler.sampler_id, shaderc_spvc_decoration_binding,
&samplerBinding); &samplerBinding);
info.samplerLocation.binding = BindingNumber(samplerBinding); info.samplerLocation.binding = BindingNumber(samplerBinding);
uint32_t textureGroup;
mSpvcContext.GetDecoration(sampler.image_id, shaderc_spvc_decoration_descriptorset, mSpvcContext.GetDecoration(sampler.image_id, shaderc_spvc_decoration_descriptorset,
&info.textureLocation.group); &textureGroup);
info.textureLocation.group = BindGroupIndex(textureGroup);
uint32_t textureBinding; uint32_t textureBinding;
mSpvcContext.GetDecoration(sampler.image_id, shaderc_spvc_decoration_binding, mSpvcContext.GetDecoration(sampler.image_id, shaderc_spvc_decoration_binding,
@ -164,12 +170,12 @@ namespace dawn_native { namespace opengl {
mCombinedInfo.emplace_back(); mCombinedInfo.emplace_back();
auto& info = mCombinedInfo.back(); auto& info = mCombinedInfo.back();
info.samplerLocation.group = info.samplerLocation.group = BindGroupIndex(
compiler->get_decoration(combined.sampler_id, spv::DecorationDescriptorSet); compiler->get_decoration(combined.sampler_id, spv::DecorationDescriptorSet));
info.samplerLocation.binding = BindingNumber( info.samplerLocation.binding = BindingNumber(
compiler->get_decoration(combined.sampler_id, spv::DecorationBinding)); compiler->get_decoration(combined.sampler_id, spv::DecorationBinding));
info.textureLocation.group = info.textureLocation.group = BindGroupIndex(
compiler->get_decoration(combined.image_id, spv::DecorationDescriptorSet); compiler->get_decoration(combined.image_id, spv::DecorationDescriptorSet));
info.textureLocation.binding = BindingNumber( info.textureLocation.binding = BindingNumber(
compiler->get_decoration(combined.image_id, spv::DecorationBinding)); compiler->get_decoration(combined.image_id, spv::DecorationBinding));
compiler->set_name(combined.combined_id, info.GetName()); compiler->set_name(combined.combined_id, info.GetName());
@ -179,7 +185,7 @@ namespace dawn_native { namespace opengl {
// Change binding names to be "dawn_binding_<group>_<binding>". // Change binding names to be "dawn_binding_<group>_<binding>".
// Also unsets the SPIRV "Binding" decoration as it outputs "layout(binding=)" which // Also unsets the SPIRV "Binding" decoration as it outputs "layout(binding=)" which
// isn't supported on OSX's OpenGL. // isn't supported on OSX's OpenGL.
for (uint32_t group = 0; group < kMaxBindGroups; ++group) { for (BindGroupIndex group(0); group < kMaxBindGroupsTyped; ++group) {
for (const auto& it : bindingInfo[group]) { for (const auto& it : bindingInfo[group]) {
BindingNumber bindingNumber = it.first; BindingNumber bindingNumber = it.first;
const auto& info = it.second; const auto& info = it.second;

View File

@ -23,10 +23,10 @@ namespace dawn_native { namespace opengl {
class Device; class Device;
std::string GetBindingName(uint32_t group, BindingNumber bindingNumber); std::string GetBindingName(BindGroupIndex group, BindingNumber bindingNumber);
struct BindingLocation { struct BindingLocation {
uint32_t group; BindGroupIndex group;
BindingNumber binding; BindingNumber binding;
}; };
bool operator<(const BindingLocation& a, const BindingLocation& b); bool operator<(const BindingLocation& a, const BindingLocation& b);

View File

@ -95,23 +95,25 @@ namespace dawn_native { namespace vulkan {
return region; return region;
} }
void ApplyDescriptorSets(Device* device, void ApplyDescriptorSets(
VkCommandBuffer commands, Device* device,
VkPipelineBindPoint bindPoint, VkCommandBuffer commands,
VkPipelineLayout pipelineLayout, VkPipelineBindPoint bindPoint,
const std::bitset<kMaxBindGroups>& bindGroupsToApply, VkPipelineLayout pipelineLayout,
const std::array<BindGroupBase*, kMaxBindGroups>& bindGroups, const BindGroupLayoutMask& bindGroupsToApply,
const std::array<uint32_t, kMaxBindGroups>& dynamicOffsetCounts, const ityp::array<BindGroupIndex, BindGroupBase*, kMaxBindGroups>& bindGroups,
const std::array<std::array<uint32_t, kMaxBindingsPerGroup>, const ityp::array<BindGroupIndex, uint32_t, kMaxBindGroups>& dynamicOffsetCounts,
kMaxBindGroups>& dynamicOffsets) { const ityp::array<BindGroupIndex,
for (uint32_t dirtyIndex : IterateBitSet(bindGroupsToApply)) { std::array<uint32_t, kMaxBindingsPerGroup>,
kMaxBindGroups>& dynamicOffsets) {
for (BindGroupIndex dirtyIndex : IterateBitSet(bindGroupsToApply)) {
VkDescriptorSet set = ToBackend(bindGroups[dirtyIndex])->GetHandle(); VkDescriptorSet set = ToBackend(bindGroups[dirtyIndex])->GetHandle();
const uint32_t* dynamicOffset = dynamicOffsetCounts[dirtyIndex] > 0 const uint32_t* dynamicOffset = dynamicOffsetCounts[dirtyIndex] > 0
? dynamicOffsets[dirtyIndex].data() ? dynamicOffsets[dirtyIndex].data()
: nullptr; : nullptr;
device->fn.CmdBindDescriptorSets(commands, bindPoint, pipelineLayout, dirtyIndex, 1, device->fn.CmdBindDescriptorSets(commands, bindPoint, pipelineLayout,
&*set, dynamicOffsetCounts[dirtyIndex], static_cast<uint32_t>(dirtyIndex), 1, &*set,
dynamicOffset); dynamicOffsetCounts[dirtyIndex], dynamicOffset);
} }
} }
@ -143,7 +145,7 @@ namespace dawn_native { namespace vulkan {
mDirtyBindGroupsObjectChangedOrIsDynamic, mBindGroups, mDirtyBindGroupsObjectChangedOrIsDynamic, mBindGroups,
mDynamicOffsetCounts, mDynamicOffsets); mDynamicOffsetCounts, mDynamicOffsets);
for (uint32_t index : IterateBitSet(mBindGroupLayoutsMask)) { for (BindGroupIndex index : IterateBitSet(mBindGroupLayoutsMask)) {
for (BindingIndex bindingIndex : for (BindingIndex bindingIndex :
IterateBitSet(mBindingsNeedingBarrier[index])) { IterateBitSet(mBindingsNeedingBarrier[index])) {
switch (mBindingTypes[index][bindingIndex]) { switch (mBindingTypes[index][bindingIndex]) {

View File

@ -37,7 +37,7 @@ namespace dawn_native { namespace vulkan {
// this constraints at the Dawn level? // this constraints at the Dawn level?
uint32_t numSetLayouts = 0; uint32_t numSetLayouts = 0;
std::array<VkDescriptorSetLayout, kMaxBindGroups> setLayouts; std::array<VkDescriptorSetLayout, kMaxBindGroups> setLayouts;
for (uint32_t setIndex : IterateBitSet(GetBindGroupLayoutsMask())) { for (BindGroupIndex setIndex : IterateBitSet(GetBindGroupLayoutsMask())) {
setLayouts[numSetLayouts] = ToBackend(GetBindGroupLayout(setIndex))->GetHandle(); setLayouts[numSetLayouts] = ToBackend(GetBindGroupLayout(setIndex))->GetHandle();
numSetLayouts++; numSetLayouts++;
} }