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:
parent
d5db214564
commit
0847cb4637
|
@ -64,10 +64,7 @@ namespace dawn_native {
|
|||
MaybeError ValidateTextureBinding(const DeviceBase* device,
|
||||
const BindGroupBinding& binding,
|
||||
wgpu::TextureUsage requiredUsage,
|
||||
bool multisampledBinding,
|
||||
wgpu::TextureComponentType requiredComponentType,
|
||||
wgpu::TextureViewDimension requiredDimension,
|
||||
wgpu::TextureFormat requiredStorageTextureFormat) {
|
||||
const BindGroupLayoutBase::BindingInfo& bindingInfo) {
|
||||
if (binding.textureView == nullptr || binding.sampler != nullptr ||
|
||||
binding.buffer != nullptr) {
|
||||
return DAWN_VALIDATION_ERROR("expected texture binding");
|
||||
|
@ -80,18 +77,18 @@ namespace dawn_native {
|
|||
return DAWN_VALIDATION_ERROR("texture binding usage mismatch");
|
||||
}
|
||||
|
||||
if (texture->IsMultisampledTexture() != multisampledBinding) {
|
||||
if (texture->IsMultisampledTexture() != bindingInfo.multisampled) {
|
||||
return DAWN_VALIDATION_ERROR("texture multisampling mismatch");
|
||||
}
|
||||
|
||||
switch (requiredUsage) {
|
||||
case wgpu::TextureUsage::Sampled: {
|
||||
if (!texture->GetFormat().HasComponentType(requiredComponentType)) {
|
||||
if (!texture->GetFormat().HasComponentType(bindingInfo.textureComponentType)) {
|
||||
return DAWN_VALIDATION_ERROR("texture component type usage mismatch");
|
||||
}
|
||||
} break;
|
||||
case wgpu::TextureUsage::Storage: {
|
||||
if (texture->GetFormat().format != requiredStorageTextureFormat) {
|
||||
if (texture->GetFormat().format != bindingInfo.storageTextureFormat) {
|
||||
return DAWN_VALIDATION_ERROR("storage texture format mismatch");
|
||||
}
|
||||
} break;
|
||||
|
@ -100,7 +97,7 @@ namespace dawn_native {
|
|||
break;
|
||||
}
|
||||
|
||||
if (binding.textureView->GetDimension() != requiredDimension) {
|
||||
if (binding.textureView->GetDimension() != bindingInfo.textureDimension) {
|
||||
return DAWN_VALIDATION_ERROR("texture view dimension mismatch");
|
||||
}
|
||||
|
||||
|
@ -127,16 +124,12 @@ namespace dawn_native {
|
|||
}
|
||||
|
||||
DAWN_TRY(device->ValidateObject(descriptor->layout));
|
||||
|
||||
const BindGroupLayoutBase::LayoutBindingInfo& layoutInfo =
|
||||
descriptor->layout->GetBindingInfo();
|
||||
|
||||
const BindGroupLayoutBase::BindingMap& bindingMap = descriptor->layout->GetBindingMap();
|
||||
|
||||
if (descriptor->bindingCount != bindingMap.size()) {
|
||||
if (descriptor->bindingCount != descriptor->layout->GetBindingCount()) {
|
||||
return DAWN_VALIDATION_ERROR("numBindings mismatch");
|
||||
}
|
||||
|
||||
const BindGroupLayoutBase::BindingMap& bindingMap = descriptor->layout->GetBindingMap();
|
||||
|
||||
std::bitset<kMaxBindingsPerGroup> bindingsSet;
|
||||
for (uint32_t i = 0; i < descriptor->bindingCount; ++i) {
|
||||
const BindGroupBinding& binding = descriptor->bindings[i];
|
||||
|
@ -146,15 +139,18 @@ namespace dawn_native {
|
|||
return DAWN_VALIDATION_ERROR("setting non-existent binding");
|
||||
}
|
||||
BindingIndex bindingIndex = it->second;
|
||||
ASSERT(bindingIndex < layoutInfo.bindingCount);
|
||||
ASSERT(bindingIndex < descriptor->layout->GetBindingCount());
|
||||
|
||||
if (bindingsSet[bindingIndex]) {
|
||||
return DAWN_VALIDATION_ERROR("binding set twice");
|
||||
}
|
||||
bindingsSet.set(bindingIndex);
|
||||
|
||||
const BindGroupLayoutBase::BindingInfo& bindingInfo =
|
||||
descriptor->layout->GetBindingInfo(bindingIndex);
|
||||
|
||||
// Perform binding-type specific validation.
|
||||
switch (layoutInfo.types[bindingIndex]) {
|
||||
switch (bindingInfo.type) {
|
||||
case wgpu::BindingType::UniformBuffer:
|
||||
DAWN_TRY(ValidateBufferBinding(device, binding, wgpu::BufferUsage::Uniform));
|
||||
break;
|
||||
|
@ -163,12 +159,8 @@ namespace dawn_native {
|
|||
DAWN_TRY(ValidateBufferBinding(device, binding, wgpu::BufferUsage::Storage));
|
||||
break;
|
||||
case wgpu::BindingType::SampledTexture:
|
||||
DAWN_TRY(
|
||||
ValidateTextureBinding(device, binding, wgpu::TextureUsage::Sampled,
|
||||
layoutInfo.multisampled[bindingIndex],
|
||||
layoutInfo.textureComponentTypes[bindingIndex],
|
||||
layoutInfo.textureDimensions[bindingIndex],
|
||||
layoutInfo.storageTextureFormats[bindingIndex]));
|
||||
DAWN_TRY(ValidateTextureBinding(device, binding, wgpu::TextureUsage::Sampled,
|
||||
bindingInfo));
|
||||
break;
|
||||
case wgpu::BindingType::Sampler:
|
||||
DAWN_TRY(ValidateSamplerBinding(device, binding));
|
||||
|
@ -177,12 +169,8 @@ namespace dawn_native {
|
|||
// write-only storage textures.
|
||||
case wgpu::BindingType::ReadonlyStorageTexture:
|
||||
case wgpu::BindingType::WriteonlyStorageTexture:
|
||||
DAWN_TRY(
|
||||
ValidateTextureBinding(device, binding, wgpu::TextureUsage::Storage,
|
||||
layoutInfo.multisampled[bindingIndex],
|
||||
layoutInfo.textureComponentTypes[bindingIndex],
|
||||
layoutInfo.textureDimensions[bindingIndex],
|
||||
layoutInfo.storageTextureFormats[bindingIndex]));
|
||||
DAWN_TRY(ValidateTextureBinding(device, binding, wgpu::TextureUsage::Storage,
|
||||
bindingInfo));
|
||||
break;
|
||||
case wgpu::BindingType::StorageTexture:
|
||||
UNREACHABLE();
|
||||
|
@ -274,9 +262,9 @@ namespace dawn_native {
|
|||
BufferBinding BindGroupBase::GetBindingAsBufferBinding(BindingIndex bindingIndex) {
|
||||
ASSERT(!IsError());
|
||||
ASSERT(bindingIndex < mLayout->GetBindingCount());
|
||||
ASSERT(mLayout->GetBindingInfo().types[bindingIndex] == wgpu::BindingType::UniformBuffer ||
|
||||
mLayout->GetBindingInfo().types[bindingIndex] == wgpu::BindingType::StorageBuffer ||
|
||||
mLayout->GetBindingInfo().types[bindingIndex] ==
|
||||
ASSERT(mLayout->GetBindingInfo(bindingIndex).type == wgpu::BindingType::UniformBuffer ||
|
||||
mLayout->GetBindingInfo(bindingIndex).type == wgpu::BindingType::StorageBuffer ||
|
||||
mLayout->GetBindingInfo(bindingIndex).type ==
|
||||
wgpu::BindingType::ReadonlyStorageBuffer);
|
||||
BufferBase* buffer = static_cast<BufferBase*>(mBindingData.bindings[bindingIndex].Get());
|
||||
return {buffer, mBindingData.bufferData[bindingIndex].offset,
|
||||
|
@ -286,14 +274,14 @@ namespace dawn_native {
|
|||
SamplerBase* BindGroupBase::GetBindingAsSampler(BindingIndex bindingIndex) {
|
||||
ASSERT(!IsError());
|
||||
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());
|
||||
}
|
||||
|
||||
TextureViewBase* BindGroupBase::GetBindingAsTextureView(BindingIndex bindingIndex) {
|
||||
ASSERT(!IsError());
|
||||
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());
|
||||
}
|
||||
|
||||
|
|
|
@ -38,16 +38,18 @@ namespace dawn_native {
|
|||
mBuffersNeedingBarrier[index] = {};
|
||||
|
||||
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) {
|
||||
if ((info.visibilities[bindingIndex] & wgpu::ShaderStage::Compute) == 0) {
|
||||
const BindGroupLayoutBase::BindingInfo& bindingInfo =
|
||||
layout->GetBindingInfo(bindingIndex);
|
||||
|
||||
if ((bindingInfo.visibility & wgpu::ShaderStage::Compute) == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
mBindingTypes[index][bindingIndex] = info.types[bindingIndex];
|
||||
switch (info.types[bindingIndex]) {
|
||||
mBindingTypes[index][bindingIndex] = bindingInfo.type;
|
||||
switch (bindingInfo.type) {
|
||||
case wgpu::BindingType::UniformBuffer:
|
||||
case wgpu::BindingType::ReadonlyStorageBuffer:
|
||||
case wgpu::BindingType::Sampler:
|
||||
|
|
|
@ -167,39 +167,25 @@ namespace dawn_native {
|
|||
}
|
||||
|
||||
return {};
|
||||
} // namespace dawn_native
|
||||
}
|
||||
|
||||
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) {
|
||||
HashCombine(&hash, info.visibilities[i], info.types[i],
|
||||
info.textureComponentTypes[i], info.textureDimensions[i],
|
||||
info.storageTextureFormats[i]);
|
||||
}
|
||||
|
||||
return hash;
|
||||
void HashCombineBindingInfo(size_t* hash, const BindGroupLayoutBase::BindingInfo& info) {
|
||||
HashCombine(hash, info.hasDynamicOffset, info.multisampled, info.visibility, info.type,
|
||||
info.textureComponentType, info.textureDimension,
|
||||
info.storageTextureFormat);
|
||||
}
|
||||
|
||||
bool operator==(const BindGroupLayoutBase::LayoutBindingInfo& a,
|
||||
const BindGroupLayoutBase::LayoutBindingInfo& b) {
|
||||
if (a.bindingCount != b.bindingCount || a.hasDynamicOffset != b.hasDynamicOffset ||
|
||||
a.multisampled != b.multisampled) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (BindingIndex i = 0; i < a.bindingCount; ++i) {
|
||||
if ((a.visibilities[i] != b.visibilities[i]) || (a.types[i] != b.types[i]) ||
|
||||
(a.textureComponentTypes[i] != b.textureComponentTypes[i]) ||
|
||||
(a.textureDimensions[i] != b.textureDimensions[i]) ||
|
||||
(a.storageTextureFormats[i] != b.storageTextureFormats[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
bool operator!=(const BindGroupLayoutBase::BindingInfo& a,
|
||||
const BindGroupLayoutBase::BindingInfo& b) {
|
||||
return a.hasDynamicOffset != b.hasDynamicOffset || //
|
||||
a.multisampled != b.multisampled || //
|
||||
a.visibility != b.visibility || //
|
||||
a.type != b.type || //
|
||||
a.textureComponentType != b.textureComponentType || //
|
||||
a.textureDimension != b.textureDimension || //
|
||||
a.storageTextureFormat != b.storageTextureFormat;
|
||||
}
|
||||
|
||||
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
|
||||
// first.
|
||||
bool CheckBufferBindingsFirst(const BindGroupLayoutBinding* bindings, size_t count) {
|
||||
bool CheckBufferBindingsFirst(const BindGroupLayoutBase::BindingInfo* bindings,
|
||||
BindingIndex count) {
|
||||
ASSERT(count <= kMaxBindingsPerGroup);
|
||||
|
||||
BindingIndex lastBufferIndex = 0;
|
||||
|
@ -269,21 +256,18 @@ namespace dawn_native {
|
|||
|
||||
BindGroupLayoutBase::BindGroupLayoutBase(DeviceBase* device,
|
||||
const BindGroupLayoutDescriptor* descriptor)
|
||||
: CachedObject(device) {
|
||||
mBindingInfo.bindingCount = descriptor->bindingCount;
|
||||
|
||||
: CachedObject(device), mBindingCount(descriptor->bindingCount) {
|
||||
std::vector<BindGroupLayoutBinding> sortedBindings(
|
||||
descriptor->bindings, descriptor->bindings + descriptor->bindingCount);
|
||||
|
||||
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];
|
||||
mBindingInfo.types[i] = binding.type;
|
||||
mBindingInfo.visibilities[i] = binding.visibility;
|
||||
mBindingInfo.textureComponentTypes[i] = binding.textureComponentType;
|
||||
mBindingInfo.storageTextureFormats[i] = binding.storageTextureFormat;
|
||||
mBindingInfo[i].type = binding.type;
|
||||
mBindingInfo[i].visibility = binding.visibility;
|
||||
mBindingInfo[i].textureComponentType = binding.textureComponentType;
|
||||
mBindingInfo[i].storageTextureFormat = binding.storageTextureFormat;
|
||||
|
||||
switch (binding.type) {
|
||||
case wgpu::BindingType::UniformBuffer:
|
||||
|
@ -298,13 +282,14 @@ namespace dawn_native {
|
|||
}
|
||||
|
||||
if (binding.textureDimension == wgpu::TextureViewDimension::Undefined) {
|
||||
mBindingInfo.textureDimensions[i] = wgpu::TextureViewDimension::e2D;
|
||||
mBindingInfo[i].textureDimension = wgpu::TextureViewDimension::e2D;
|
||||
} else {
|
||||
mBindingInfo.textureDimensions[i] = binding.textureDimension;
|
||||
mBindingInfo[i].textureDimension = binding.textureDimension;
|
||||
}
|
||||
|
||||
mBindingInfo[i].multisampled = binding.multisampled;
|
||||
mBindingInfo[i].hasDynamicOffset = binding.hasDynamicOffset;
|
||||
if (binding.hasDynamicOffset) {
|
||||
mBindingInfo.hasDynamicOffset.set(i);
|
||||
switch (binding.type) {
|
||||
case wgpu::BindingType::UniformBuffer:
|
||||
++mDynamicUniformBufferCount;
|
||||
|
@ -322,11 +307,11 @@ namespace dawn_native {
|
|||
break;
|
||||
}
|
||||
}
|
||||
mBindingInfo.multisampled.set(i, binding.multisampled);
|
||||
|
||||
const auto& it = mBindingMap.emplace(BindingNumber(binding.binding), i);
|
||||
ASSERT(it.second);
|
||||
}
|
||||
ASSERT(CheckBufferBindingsFirst(mBindingInfo.data(), mBindingCount));
|
||||
}
|
||||
|
||||
BindGroupLayoutBase::BindGroupLayoutBase(DeviceBase* device, ObjectBase::ErrorTag tag)
|
||||
|
@ -345,11 +330,6 @@ namespace dawn_native {
|
|||
return new BindGroupLayoutBase(device, ObjectBase::kError);
|
||||
}
|
||||
|
||||
const BindGroupLayoutBase::LayoutBindingInfo& BindGroupLayoutBase::GetBindingInfo() const {
|
||||
ASSERT(!IsError());
|
||||
return mBindingInfo;
|
||||
}
|
||||
|
||||
const BindGroupLayoutBase::BindingMap& BindGroupLayoutBase::GetBindingMap() const {
|
||||
ASSERT(!IsError());
|
||||
return mBindingMap;
|
||||
|
@ -363,22 +343,31 @@ namespace dawn_native {
|
|||
}
|
||||
|
||||
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
|
||||
// will still hash the same.
|
||||
for (const auto& it : bgl->mBindingMap) {
|
||||
HashCombine(&hash, it.first, it.second);
|
||||
HashCombineBindingInfo(&hash, bgl->mBindingInfo[it.second]);
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
bool BindGroupLayoutBase::EqualityFunc::operator()(const BindGroupLayoutBase* a,
|
||||
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 {
|
||||
return mBindingInfo.bindingCount;
|
||||
return mBindingCount;
|
||||
}
|
||||
|
||||
BindingIndex BindGroupLayoutBase::GetDynamicBufferCount() const {
|
||||
|
@ -398,7 +387,7 @@ namespace dawn_native {
|
|||
// | --- offsets + sizes -------------| --------------- Ref<ObjectBase> ----------|
|
||||
size_t objectPointerStart = mBufferCount * sizeof(BufferBindingData);
|
||||
ASSERT(IsAligned(objectPointerStart, alignof(Ref<ObjectBase>)));
|
||||
return objectPointerStart + mBindingInfo.bindingCount * sizeof(Ref<ObjectBase>);
|
||||
return objectPointerStart + mBindingCount * sizeof(Ref<ObjectBase>);
|
||||
}
|
||||
|
||||
BindGroupLayoutBase::BindingDataPointers BindGroupLayoutBase::ComputeBindingDataPointers(
|
||||
|
|
|
@ -51,22 +51,24 @@ namespace dawn_native {
|
|||
~BindGroupLayoutBase() override;
|
||||
|
||||
static BindGroupLayoutBase* MakeError(DeviceBase* device);
|
||||
|
||||
struct LayoutBindingInfo {
|
||||
std::array<wgpu::ShaderStage, kMaxBindingsPerGroup> visibilities;
|
||||
std::array<wgpu::BindingType, kMaxBindingsPerGroup> types;
|
||||
std::array<wgpu::TextureComponentType, kMaxBindingsPerGroup> textureComponentTypes;
|
||||
std::array<wgpu::TextureViewDimension, kMaxBindingsPerGroup> textureDimensions;
|
||||
std::array<wgpu::TextureFormat, kMaxBindingsPerGroup> storageTextureFormats;
|
||||
std::bitset<kMaxBindingsPerGroup> hasDynamicOffset;
|
||||
std::bitset<kMaxBindingsPerGroup> multisampled;
|
||||
BindingIndex bindingCount;
|
||||
struct BindingInfo {
|
||||
wgpu::ShaderStage visibility;
|
||||
wgpu::BindingType type;
|
||||
wgpu::TextureComponentType textureComponentType;
|
||||
wgpu::TextureViewDimension textureDimension;
|
||||
wgpu::TextureFormat storageTextureFormat;
|
||||
bool hasDynamicOffset;
|
||||
bool multisampled;
|
||||
};
|
||||
|
||||
// A map from the BindingNumber to its packed 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;
|
||||
BindingIndex GetBindingIndex(BindingNumber bindingNumber) const;
|
||||
|
||||
|
@ -117,10 +119,12 @@ namespace dawn_native {
|
|||
private:
|
||||
BindGroupLayoutBase(DeviceBase* device, ObjectBase::ErrorTag tag);
|
||||
|
||||
BindingIndex mBindingCount;
|
||||
BindingIndex mBufferCount = 0; // |BindingIndex| because buffers are packed at the front.
|
||||
uint32_t mDynamicUniformBufferCount = 0;
|
||||
uint32_t mDynamicStorageBufferCount = 0;
|
||||
LayoutBindingInfo mBindingInfo;
|
||||
|
||||
std::array<BindingInfo, kMaxBindingsPerGroup> mBindingInfo;
|
||||
|
||||
// Map from BindGroupLayoutEntry.binding to packed indices.
|
||||
BindingMap mBindingMap;
|
||||
|
|
|
@ -29,11 +29,9 @@ namespace dawn_native {
|
|||
namespace {
|
||||
void TrackBindGroupResourceUsage(PassResourceUsageTracker* usageTracker,
|
||||
BindGroupBase* group) {
|
||||
const BindGroupLayoutBase::LayoutBindingInfo& layoutInfo =
|
||||
group->GetLayout()->GetBindingInfo();
|
||||
for (BindingIndex bindingIndex = 0; bindingIndex < layoutInfo.bindingCount;
|
||||
++bindingIndex) {
|
||||
wgpu::BindingType type = layoutInfo.types[bindingIndex];
|
||||
for (BindingIndex bindingIndex = 0;
|
||||
bindingIndex < group->GetLayout()->GetBindingCount(); ++bindingIndex) {
|
||||
wgpu::BindingType type = group->GetLayout()->GetBindingInfo(bindingIndex).type;
|
||||
|
||||
switch (type) {
|
||||
case wgpu::BindingType::UniformBuffer: {
|
||||
|
@ -133,12 +131,13 @@ namespace dawn_native {
|
|||
return DAWN_VALIDATION_ERROR("dynamicOffset count mismatch");
|
||||
}
|
||||
|
||||
const BindGroupLayoutBase::LayoutBindingInfo& layoutInfo = layout->GetBindingInfo();
|
||||
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.
|
||||
// ASSERT that this true.
|
||||
ASSERT(layoutInfo.hasDynamicOffset[i]);
|
||||
switch (layoutInfo.types[i]) {
|
||||
ASSERT(bindingInfo.hasDynamicOffset);
|
||||
switch (bindingInfo.type) {
|
||||
case wgpu::BindingType::UniformBuffer:
|
||||
case wgpu::BindingType::StorageBuffer:
|
||||
case wgpu::BindingType::ReadonlyStorageBuffer:
|
||||
|
|
|
@ -741,7 +741,6 @@ namespace dawn_native {
|
|||
const BindGroupLayoutBase* layout) const {
|
||||
ASSERT(!IsError());
|
||||
|
||||
const BindGroupLayoutBase::LayoutBindingInfo& layoutInfo = layout->GetBindingInfo();
|
||||
const BindGroupLayoutBase::BindingMap& bindingMap = layout->GetBindingMap();
|
||||
|
||||
// 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);
|
||||
|
||||
const auto& layoutBindingType = layoutInfo.types[bindingIndex];
|
||||
const BindGroupLayoutBase::BindingInfo& bindingInfo =
|
||||
layout->GetBindingInfo(bindingIndex);
|
||||
const auto& layoutBindingType = bindingInfo.type;
|
||||
|
||||
if (layoutBindingType != moduleInfo.type) {
|
||||
// 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;
|
||||
}
|
||||
|
||||
switch (layoutBindingType) {
|
||||
case wgpu::BindingType::SampledTexture: {
|
||||
Format::Type layoutTextureComponentType =
|
||||
Format::TextureComponentTypeToFormatType(
|
||||
layoutInfo.textureComponentTypes[bindingIndex]);
|
||||
Format::TextureComponentTypeToFormatType(bindingInfo.textureComponentType);
|
||||
if (layoutTextureComponentType != moduleInfo.textureComponentType) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (layoutInfo.textureDimensions[bindingIndex] != moduleInfo.textureDimension) {
|
||||
if (bindingInfo.textureDimension != moduleInfo.textureDimension) {
|
||||
return false;
|
||||
}
|
||||
} break;
|
||||
|
||||
case wgpu::BindingType::ReadonlyStorageTexture:
|
||||
case wgpu::BindingType::WriteonlyStorageTexture: {
|
||||
ASSERT(layoutInfo.storageTextureFormats[bindingIndex] !=
|
||||
wgpu::TextureFormat::Undefined);
|
||||
ASSERT(bindingInfo.storageTextureFormat != wgpu::TextureFormat::Undefined);
|
||||
ASSERT(moduleInfo.storageTextureFormat != wgpu::TextureFormat::Undefined);
|
||||
if (layoutInfo.storageTextureFormats[bindingIndex] !=
|
||||
moduleInfo.storageTextureFormat) {
|
||||
if (bindingInfo.storageTextureFormat != moduleInfo.storageTextureFormat) {
|
||||
return false;
|
||||
}
|
||||
if (layoutInfo.textureDimensions[bindingIndex] != moduleInfo.textureDimension) {
|
||||
if (bindingInfo.textureDimension != moduleInfo.textureDimension) {
|
||||
return false;
|
||||
}
|
||||
} break;
|
||||
|
|
|
@ -81,21 +81,21 @@ namespace dawn_native { namespace d3d12 {
|
|||
mLastUsageSerial = pendingSerial;
|
||||
mHeapSerial = allocator->GetShaderVisibleHeapsSerial();
|
||||
|
||||
const BindGroupLayoutBase::LayoutBindingInfo& layout = bgl->GetBindingInfo();
|
||||
|
||||
const auto& bindingOffsets = bgl->GetBindingOffsets();
|
||||
|
||||
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
|
||||
// resources. So skip allocating descriptors in descriptor heaps for dynamic
|
||||
// buffers.
|
||||
if (layout.hasDynamicOffset[bindingIndex]) {
|
||||
if (bindingInfo.hasDynamicOffset) {
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (layout.types[bindingIndex]) {
|
||||
switch (bindingInfo.type) {
|
||||
case wgpu::BindingType::UniformBuffer: {
|
||||
BufferBinding binding = GetBindingAsBufferBinding(bindingIndex);
|
||||
|
||||
|
|
|
@ -45,18 +45,17 @@ namespace dawn_native { namespace d3d12 {
|
|||
: BindGroupLayoutBase(device, descriptor),
|
||||
mDescriptorCounts{},
|
||||
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.
|
||||
// So there is no need to allocate the descriptor from descriptor heap. Skip counting
|
||||
// dynamic resources for calculating size of descriptor heap.
|
||||
if (groupInfo.hasDynamicOffset[bindingIndex]) {
|
||||
continue;
|
||||
}
|
||||
// So there is no need to allocate the descriptor from descriptor heap.
|
||||
// This loop starts after the dynamic buffer indices to skip counting
|
||||
// dynamic resources in calculating the size of the descriptor heap.
|
||||
ASSERT(!bindingInfo.hasDynamicOffset);
|
||||
|
||||
DescriptorType descriptorType =
|
||||
WGPUBindingTypeToDescriptorType(groupInfo.types[bindingIndex]);
|
||||
DescriptorType descriptorType = WGPUBindingTypeToDescriptorType(bindingInfo.type);
|
||||
mBindingOffsets[bindingIndex] = mDescriptorCounts[descriptorType]++;
|
||||
}
|
||||
|
||||
|
@ -101,12 +100,14 @@ namespace dawn_native { namespace d3d12 {
|
|||
D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER);
|
||||
descriptorOffsets[Sampler] = 0;
|
||||
|
||||
for (BindingIndex bindingIndex = 0; bindingIndex < groupInfo.bindingCount; ++bindingIndex) {
|
||||
if (groupInfo.hasDynamicOffset[bindingIndex]) {
|
||||
for (BindingIndex bindingIndex = 0; bindingIndex < GetBindingCount(); ++bindingIndex) {
|
||||
const BindGroupLayoutBase::BindingInfo& bindingInfo = GetBindingInfo(bindingIndex);
|
||||
|
||||
if (bindingInfo.hasDynamicOffset) {
|
||||
// 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
|
||||
// generated HLSL shader.
|
||||
switch (groupInfo.types[bindingIndex]) {
|
||||
switch (bindingInfo.type) {
|
||||
case wgpu::BindingType::UniformBuffer:
|
||||
case wgpu::BindingType::StorageBuffer:
|
||||
case wgpu::BindingType::ReadonlyStorageBuffer:
|
||||
|
@ -124,8 +125,7 @@ namespace dawn_native { namespace d3d12 {
|
|||
}
|
||||
|
||||
// TODO(shaobo.yan@intel.com): Implement dynamic buffer offset.
|
||||
DescriptorType descriptorType =
|
||||
WGPUBindingTypeToDescriptorType(groupInfo.types[bindingIndex]);
|
||||
DescriptorType descriptorType = WGPUBindingTypeToDescriptorType(bindingInfo.type);
|
||||
mBindingOffsets[bindingIndex] += descriptorOffsets[descriptorType];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -196,28 +196,27 @@ namespace dawn_native { namespace d3d12 {
|
|||
BindGroup* group,
|
||||
uint32_t dynamicOffsetCount,
|
||||
const uint64_t* dynamicOffsets) {
|
||||
ASSERT(dynamicOffsetCount == group->GetLayout()->GetDynamicBufferCount());
|
||||
|
||||
// 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
|
||||
if (dynamicOffsetCount) {
|
||||
// Update dynamic offsets
|
||||
const BindGroupLayout::LayoutBindingInfo& layout =
|
||||
group->GetLayout()->GetBindingInfo();
|
||||
uint32_t currentDynamicBufferIndex = 0;
|
||||
|
||||
for (uint32_t bindingIndex : IterateBitSet(layout.hasDynamicOffset)) {
|
||||
ASSERT(dynamicOffsetCount > 0);
|
||||
if (dynamicOffsetCount != 0) {
|
||||
// Update dynamic offsets.
|
||||
// Dynamic buffer bindings are packed at the beginning of the layout.
|
||||
for (BindingIndex bindingIndex = 0; bindingIndex < dynamicOffsetCount;
|
||||
++bindingIndex) {
|
||||
uint32_t parameterIndex =
|
||||
pipelineLayout->GetDynamicRootParameterIndex(index, bindingIndex);
|
||||
BufferBinding binding = group->GetBindingAsBufferBinding(bindingIndex);
|
||||
|
||||
// Calculate buffer locations that root descriptors links to. The location
|
||||
// is (base buffer location + initial offset + dynamic offset)
|
||||
uint64_t dynamicOffset = dynamicOffsets[currentDynamicBufferIndex];
|
||||
uint64_t dynamicOffset = dynamicOffsets[bindingIndex];
|
||||
uint64_t offset = binding.offset + dynamicOffset;
|
||||
D3D12_GPU_VIRTUAL_ADDRESS bufferLocation =
|
||||
ToBackend(binding.buffer)->GetVA() + offset;
|
||||
|
||||
switch (layout.types[bindingIndex]) {
|
||||
switch (group->GetLayout()->GetBindingInfo(bindingIndex).type) {
|
||||
case wgpu::BindingType::UniformBuffer:
|
||||
if (mInCompute) {
|
||||
commandList->SetComputeRootConstantBufferView(parameterIndex,
|
||||
|
@ -253,8 +252,6 @@ namespace dawn_native { namespace d3d12 {
|
|||
UNREACHABLE();
|
||||
break;
|
||||
}
|
||||
|
||||
++currentDynamicBufferIndex;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -89,7 +89,6 @@ namespace dawn_native { namespace d3d12 {
|
|||
|
||||
for (uint32_t group : IterateBitSet(GetBindGroupLayoutsMask())) {
|
||||
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
|
||||
// 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
|
||||
const auto& shaderRegisters = bindGroupLayout->GetBindingOffsets();
|
||||
|
||||
// Init root descriptors in root signatures.
|
||||
for (uint32_t dynamicBinding : IterateBitSet(groupInfo.hasDynamicOffset)) {
|
||||
// Init root descriptors in root signatures for dynamic buffer bindings.
|
||||
// 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];
|
||||
|
||||
// Setup root descriptor.
|
||||
D3D12_ROOT_DESCRIPTOR rootDescriptor;
|
||||
rootDescriptor.ShaderRegister = shaderRegisters[dynamicBinding];
|
||||
rootDescriptor.ShaderRegister = shaderRegisters[dynamicBindingIndex];
|
||||
rootDescriptor.RegisterSpace = group;
|
||||
|
||||
// Set root descriptors in root signatures.
|
||||
rootParameter->Descriptor = rootDescriptor;
|
||||
mDynamicRootParameterIndices[group][dynamicBinding] = parameterIndex++;
|
||||
mDynamicRootParameterIndices[group][dynamicBindingIndex] = parameterIndex++;
|
||||
|
||||
// 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.
|
||||
rootParameter->ShaderVisibility =
|
||||
ShaderVisibilityType(groupInfo.visibilities[dynamicBinding]);
|
||||
rootParameter->ShaderVisibility = ShaderVisibilityType(bindingInfo.visibility);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -186,10 +190,11 @@ namespace dawn_native { namespace d3d12 {
|
|||
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(binding < kMaxBindingsPerGroup);
|
||||
ASSERT(GetBindGroupLayout(group)->GetBindingInfo().hasDynamicOffset[binding]);
|
||||
return mDynamicRootParameterIndices[group][binding];
|
||||
ASSERT(bindingIndex < kMaxBindingsPerGroup);
|
||||
ASSERT(GetBindGroupLayout(group)->GetBindingInfo(bindingIndex).hasDynamicOffset);
|
||||
return mDynamicRootParameterIndices[group][bindingIndex];
|
||||
}
|
||||
}} // namespace dawn_native::d3d12
|
||||
|
|
|
@ -15,8 +15,8 @@
|
|||
#ifndef DAWNNATIVE_D3D12_PIPELINELAYOUTD3D12_H_
|
||||
#define DAWNNATIVE_D3D12_PIPELINELAYOUTD3D12_H_
|
||||
|
||||
#include "dawn_native/IntegerTypes.h"
|
||||
#include "dawn_native/PipelineLayout.h"
|
||||
|
||||
#include "dawn_native/d3d12/d3d12_platform.h"
|
||||
|
||||
namespace dawn_native { namespace d3d12 {
|
||||
|
@ -32,7 +32,7 @@ namespace dawn_native { namespace d3d12 {
|
|||
uint32_t GetSamplerRootParameterIndex(uint32_t group) const;
|
||||
|
||||
// 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;
|
||||
|
||||
|
|
|
@ -493,19 +493,22 @@ namespace dawn_native { namespace metal {
|
|||
uint32_t dynamicOffsetCount,
|
||||
uint64_t* dynamicOffsets,
|
||||
PipelineLayout* pipelineLayout) {
|
||||
const BindGroupLayoutBase::LayoutBindingInfo& layout =
|
||||
group->GetLayout()->GetBindingInfo();
|
||||
uint32_t currentDynamicBufferIndex = 0;
|
||||
|
||||
// TODO(kainino@chromium.org): Maintain buffers and offsets arrays in BindGroup
|
||||
// so that we only have to do one setVertexBuffers and one setFragmentBuffers
|
||||
// call here.
|
||||
for (BindingIndex bindingIndex = 0; bindingIndex < layout.bindingCount;
|
||||
++bindingIndex) {
|
||||
auto stage = layout.visibilities[bindingIndex];
|
||||
bool hasVertStage = stage & wgpu::ShaderStage::Vertex && render != nil;
|
||||
bool hasFragStage = stage & wgpu::ShaderStage::Fragment && render != nil;
|
||||
bool hasComputeStage = stage & wgpu::ShaderStage::Compute && compute != nil;
|
||||
for (BindingIndex bindingIndex = 0;
|
||||
bindingIndex < group->GetLayout()->GetBindingCount(); ++bindingIndex) {
|
||||
const BindGroupLayoutBase::BindingInfo& bindingInfo =
|
||||
group->GetLayout()->GetBindingInfo(bindingIndex);
|
||||
|
||||
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 fragIndex = 0;
|
||||
|
@ -524,7 +527,7 @@ namespace dawn_native { namespace metal {
|
|||
SingleShaderStage::Compute)[index][bindingIndex];
|
||||
}
|
||||
|
||||
switch (layout.types[bindingIndex]) {
|
||||
switch (bindingInfo.type) {
|
||||
case wgpu::BindingType::UniformBuffer:
|
||||
case wgpu::BindingType::StorageBuffer:
|
||||
case wgpu::BindingType::ReadonlyStorageBuffer: {
|
||||
|
@ -535,7 +538,7 @@ namespace dawn_native { namespace metal {
|
|||
|
||||
// TODO(shaobo.yan@intel.com): Record bound buffer status to use
|
||||
// setBufferOffset to achieve better performance.
|
||||
if (layout.hasDynamicOffset[bindingIndex]) {
|
||||
if (bindingInfo.hasDynamicOffset) {
|
||||
offset += dynamicOffsets[currentDynamicBufferIndex];
|
||||
currentDynamicBufferIndex++;
|
||||
}
|
||||
|
|
|
@ -29,15 +29,15 @@ namespace dawn_native { namespace metal {
|
|||
uint32_t textureIndex = 0;
|
||||
|
||||
for (uint32_t group : IterateBitSet(GetBindGroupLayoutsMask())) {
|
||||
const BindGroupLayoutBase::LayoutBindingInfo& groupInfo =
|
||||
GetBindGroupLayout(group)->GetBindingInfo();
|
||||
for (BindingIndex bindingIndex = 0; bindingIndex < groupInfo.bindingCount;
|
||||
++bindingIndex) {
|
||||
if (!(groupInfo.visibilities[bindingIndex] & StageBit(stage))) {
|
||||
for (BindingIndex bindingIndex = 0;
|
||||
bindingIndex < GetBindGroupLayout(group)->GetBindingCount(); ++bindingIndex) {
|
||||
const BindGroupLayoutBase::BindingInfo& bindingInfo =
|
||||
GetBindGroupLayout(group)->GetBindingInfo(bindingIndex);
|
||||
if (!(bindingInfo.visibility & StageBit(stage))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (groupInfo.types[bindingIndex]) {
|
||||
switch (bindingInfo.type) {
|
||||
case wgpu::BindingType::UniformBuffer:
|
||||
case wgpu::BindingType::StorageBuffer:
|
||||
case wgpu::BindingType::ReadonlyStorageBuffer:
|
||||
|
|
|
@ -131,22 +131,23 @@ namespace dawn_native { namespace metal {
|
|||
|
||||
// Create one resource binding entry per stage per binding.
|
||||
for (uint32_t group : IterateBitSet(layout->GetBindGroupLayoutsMask())) {
|
||||
const BindGroupLayoutBase::LayoutBindingInfo& bgInfo =
|
||||
layout->GetBindGroupLayout(group)->GetBindingInfo();
|
||||
const BindGroupLayoutBase::BindingMap& bindingMap =
|
||||
layout->GetBindGroupLayout(group)->GetBindingMap();
|
||||
|
||||
for (const auto& it : bindingMap) {
|
||||
uint32_t binding = it.first;
|
||||
BindingNumber bindingNumber = it.first;
|
||||
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];
|
||||
if (GetDevice()->IsToggleEnabled(Toggle::UseSpvc)) {
|
||||
shaderc_spvc_msl_resource_binding mslBinding;
|
||||
mslBinding.stage = ToSpvcExecutionModel(stage);
|
||||
mslBinding.desc_set = group;
|
||||
mslBinding.binding = binding;
|
||||
mslBinding.binding = bindingNumber;
|
||||
mslBinding.msl_buffer = mslBinding.msl_texture = mslBinding.msl_sampler =
|
||||
shaderIndex;
|
||||
DAWN_TRY(CheckSpvcSuccess(mSpvcContext.AddMSLResourceBinding(mslBinding),
|
||||
|
@ -155,7 +156,7 @@ namespace dawn_native { namespace metal {
|
|||
spirv_cross::MSLResourceBinding mslBinding;
|
||||
mslBinding.stage = SpirvExecutionModelForStage(stage);
|
||||
mslBinding.desc_set = group;
|
||||
mslBinding.binding = binding;
|
||||
mslBinding.binding = bindingNumber;
|
||||
mslBinding.msl_buffer = mslBinding.msl_texture = mslBinding.msl_sampler =
|
||||
shaderIndex;
|
||||
|
||||
|
|
|
@ -239,28 +239,45 @@ namespace dawn_native { namespace opengl {
|
|||
uint32_t dynamicOffsetCount,
|
||||
uint64_t* dynamicOffsets) {
|
||||
const auto& indices = ToBackend(mPipelineLayout)->GetBindingIndexInfo()[index];
|
||||
const BindGroupLayoutBase::LayoutBindingInfo& layout =
|
||||
group->GetLayout()->GetBindingInfo();
|
||||
uint32_t currentDynamicIndex = 0;
|
||||
uint32_t currentDynamicOffsetIndex = 0;
|
||||
|
||||
for (BindingIndex bindingIndex = 0; bindingIndex < layout.bindingCount;
|
||||
++bindingIndex) {
|
||||
switch (layout.types[bindingIndex]) {
|
||||
for (BindingIndex bindingIndex = 0;
|
||||
bindingIndex < group->GetLayout()->GetBindingCount(); ++bindingIndex) {
|
||||
const BindGroupLayoutBase::BindingInfo& bindingInfo =
|
||||
group->GetLayout()->GetBindingInfo(bindingIndex);
|
||||
|
||||
switch (bindingInfo.type) {
|
||||
case wgpu::BindingType::UniformBuffer: {
|
||||
BufferBinding binding = group->GetBindingAsBufferBinding(bindingIndex);
|
||||
GLuint buffer = ToBackend(binding.buffer)->GetHandle();
|
||||
GLuint uboIndex = indices[bindingIndex];
|
||||
GLuint offset = binding.offset;
|
||||
|
||||
if (layout.hasDynamicOffset[bindingIndex]) {
|
||||
offset += dynamicOffsets[currentDynamicIndex];
|
||||
++currentDynamicIndex;
|
||||
if (bindingInfo.hasDynamicOffset) {
|
||||
offset += dynamicOffsets[currentDynamicOffsetIndex];
|
||||
++currentDynamicOffsetIndex;
|
||||
}
|
||||
|
||||
gl.BindBufferRange(GL_UNIFORM_BUFFER, uboIndex, buffer, offset,
|
||||
binding.size);
|
||||
} 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: {
|
||||
Sampler* sampler = ToBackend(group->GetBindingAsSampler(bindingIndex));
|
||||
GLuint samplerIndex = indices[bindingIndex];
|
||||
|
@ -290,22 +307,6 @@ namespace dawn_native { namespace opengl {
|
|||
}
|
||||
} 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::ReadonlyStorageTexture:
|
||||
case wgpu::BindingType::WriteonlyStorageTexture:
|
||||
|
|
|
@ -107,15 +107,14 @@ namespace dawn_native { namespace opengl {
|
|||
const auto& indices = layout->GetBindingIndexInfo();
|
||||
|
||||
for (uint32_t group : IterateBitSet(layout->GetBindGroupLayoutsMask())) {
|
||||
const BindGroupLayoutBase::LayoutBindingInfo& groupInfo =
|
||||
layout->GetBindGroupLayout(group)->GetBindingInfo();
|
||||
const BindGroupLayoutBase* bgl = layout->GetBindGroupLayout(group);
|
||||
|
||||
for (const auto& it : layout->GetBindGroupLayout(group)->GetBindingMap()) {
|
||||
for (const auto& it : bgl->GetBindingMap()) {
|
||||
BindingNumber bindingNumber = it.first;
|
||||
BindingIndex bindingIndex = it.second;
|
||||
|
||||
std::string name = GetBindingName(group, bindingNumber);
|
||||
switch (groupInfo.types[bindingIndex]) {
|
||||
switch (bgl->GetBindingInfo(bindingIndex).type) {
|
||||
case wgpu::BindingType::UniformBuffer: {
|
||||
GLint location = gl.GetUniformBlockIndex(mProgram, name.c_str());
|
||||
if (location != -1) {
|
||||
|
@ -178,10 +177,11 @@ namespace dawn_native { namespace opengl {
|
|||
indices[combined.textureLocation.group][combined.textureLocation.binding];
|
||||
mUnitsForTextures[textureIndex].push_back(textureUnit);
|
||||
|
||||
const BindGroupLayoutBase* bgl =
|
||||
layout->GetBindGroupLayout(combined.textureLocation.group);
|
||||
wgpu::TextureComponentType componentType =
|
||||
layout->GetBindGroupLayout(combined.textureLocation.group)
|
||||
->GetBindingInfo()
|
||||
.textureComponentTypes[combined.textureLocation.binding];
|
||||
bgl->GetBindingInfo(bgl->GetBindingIndex(combined.textureLocation.binding))
|
||||
.textureComponentType;
|
||||
bool shouldUseFiltering = componentType == wgpu::TextureComponentType::Float;
|
||||
|
||||
GLuint samplerIndex =
|
||||
|
|
|
@ -28,12 +28,11 @@ namespace dawn_native { namespace opengl {
|
|||
GLuint ssboIndex = 0;
|
||||
|
||||
for (uint32_t group : IterateBitSet(GetBindGroupLayoutsMask())) {
|
||||
const BindGroupLayoutBase::LayoutBindingInfo& groupInfo =
|
||||
GetBindGroupLayout(group)->GetBindingInfo();
|
||||
const BindGroupLayoutBase* bgl = GetBindGroupLayout(group);
|
||||
|
||||
for (BindingIndex bindingIndex = 0; bindingIndex < groupInfo.bindingCount;
|
||||
for (BindingIndex bindingIndex = 0; bindingIndex < bgl->GetBindingCount();
|
||||
++bindingIndex) {
|
||||
switch (groupInfo.types[bindingIndex]) {
|
||||
switch (bgl->GetBindingInfo(bindingIndex).type) {
|
||||
case wgpu::BindingType::UniformBuffer:
|
||||
mIndexInfo[group][bindingIndex] = uboIndex;
|
||||
uboIndex++;
|
||||
|
|
|
@ -82,8 +82,6 @@ namespace dawn_native { namespace vulkan {
|
|||
}
|
||||
|
||||
MaybeError BindGroupLayout::Initialize() {
|
||||
const LayoutBindingInfo& info = GetBindingInfo();
|
||||
|
||||
// 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
|
||||
// bindings of the same type.
|
||||
|
@ -92,13 +90,14 @@ namespace dawn_native { namespace vulkan {
|
|||
for (const auto& it : GetBindingMap()) {
|
||||
BindingNumber bindingNumber = it.first;
|
||||
BindingIndex bindingIndex = it.second;
|
||||
const BindingInfo& bindingInfo = GetBindingInfo(bindingIndex);
|
||||
|
||||
VkDescriptorSetLayoutBinding* vkBinding = &bindings[numBindings];
|
||||
vkBinding->binding = bindingNumber;
|
||||
vkBinding->descriptorType =
|
||||
VulkanDescriptorType(info.types[bindingIndex], info.hasDynamicOffset[bindingIndex]);
|
||||
VulkanDescriptorType(bindingInfo.type, bindingInfo.hasDynamicOffset);
|
||||
vkBinding->descriptorCount = 1;
|
||||
vkBinding->stageFlags = VulkanShaderStageFlags(info.visibilities[bindingIndex]);
|
||||
vkBinding->stageFlags = VulkanShaderStageFlags(bindingInfo.visibility);
|
||||
vkBinding->pImmutableSamplers = nullptr;
|
||||
|
||||
numBindings++;
|
||||
|
@ -119,9 +118,10 @@ namespace dawn_native { namespace vulkan {
|
|||
// Compute the size of descriptor pools used for this layout.
|
||||
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 =
|
||||
VulkanDescriptorType(info.types[bindingIndex], info.hasDynamicOffset[bindingIndex]);
|
||||
VulkanDescriptorType(bindingInfo.type, bindingInfo.hasDynamicOffset);
|
||||
|
||||
// map::operator[] will return 0 if the key doesn't exist.
|
||||
descriptorCountPerType[vulkanType]++;
|
||||
|
|
|
@ -43,10 +43,11 @@ namespace dawn_native { namespace vulkan {
|
|||
std::array<VkDescriptorBufferInfo, kMaxBindingsPerGroup> writeBufferInfo;
|
||||
std::array<VkDescriptorImageInfo, kMaxBindingsPerGroup> writeImageInfo;
|
||||
|
||||
const BindGroupLayoutBase::LayoutBindingInfo& layoutInfo = GetLayout()->GetBindingInfo();
|
||||
for (const auto& it : GetLayout()->GetBindingMap()) {
|
||||
BindingNumber bindingNumber = it.first;
|
||||
BindingIndex bindingIndex = it.second;
|
||||
const BindGroupLayoutBase::BindingInfo& bindingInfo =
|
||||
GetLayout()->GetBindingInfo(bindingIndex);
|
||||
|
||||
auto& write = writes[numWrites];
|
||||
write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
||||
|
@ -55,10 +56,10 @@ namespace dawn_native { namespace vulkan {
|
|||
write.dstBinding = bindingNumber;
|
||||
write.dstArrayElement = 0;
|
||||
write.descriptorCount = 1;
|
||||
write.descriptorType = VulkanDescriptorType(layoutInfo.types[bindingIndex],
|
||||
layoutInfo.hasDynamicOffset[bindingIndex]);
|
||||
write.descriptorType =
|
||||
VulkanDescriptorType(bindingInfo.type, bindingInfo.hasDynamicOffset);
|
||||
|
||||
switch (layoutInfo.types[bindingIndex]) {
|
||||
switch (bindingInfo.type) {
|
||||
case wgpu::BindingType::UniformBuffer:
|
||||
case wgpu::BindingType::StorageBuffer:
|
||||
case wgpu::BindingType::ReadonlyStorageBuffer: {
|
||||
|
|
Loading…
Reference in New Issue