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