Add dynamic attribute in bind group layout binding

WebGPU remove dynamic-uniform-buffer and dynamic-storage-buffer but add a new attribute in
BindgroupLayoutBinding to record whether a buffer resource is dynamic.
Dawn need to align with this change.

BUG=dawn:180

Change-Id: I873ad2ec75575e72d184f89a6e3698dff6df50d7
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/8520
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
This commit is contained in:
Yan, Shaobo 2019-07-09 07:58:57 +00:00 committed by Commit Bot service account
parent 8f93871dff
commit f697fe3b7d
19 changed files with 48 additions and 107 deletions

View File

@ -55,7 +55,8 @@
"members": [
{"name": "binding", "type": "uint32_t"},
{"name": "visibility", "type": "shader stage bit"},
{"name": "type", "type": "binding type"}
{"name": "type", "type": "binding type"},
{"name": "dynamic", "type": "bool", "default": "false" }
]
},
"bind group layout descriptor": {
@ -70,11 +71,9 @@
"category": "enum",
"values": [
{"value": 0, "name": "uniform buffer"},
{"value": 1, "name": "sampler"},
{"value": 2, "name": "sampled texture"},
{"value": 3, "name": "storage buffer"},
{"value": 4, "name": "dynamic uniform buffer"},
{"value": 5, "name": "dynamic storage buffer"}
{"value": 1, "name": "storage buffer"},
{"value": 2, "name": "sampler"},
{"value": 3, "name": "sampled texture"}
]
},
"blend descriptor": {

View File

@ -111,7 +111,7 @@ void init() {
})");
dawn::BindGroupLayout bgl = utils::MakeBindGroupLayout(
device, {{0, dawn::ShaderStageBit::Vertex, dawn::BindingType::DynamicUniformBuffer}});
device, {{0, dawn::ShaderStageBit::Vertex, dawn::BindingType::UniformBuffer, true}});
utils::ComboRenderPipelineDescriptor descriptor(device);
descriptor.layout = utils::MakeBasicPipelineLayout(device, &bgl);

View File

@ -126,18 +126,23 @@ namespace dawn_native {
// Perform binding-type specific validation.
switch (layoutInfo.types[bindingIndex]) {
case dawn::BindingType::UniformBuffer:
case dawn::BindingType::DynamicUniformBuffer:
DAWN_TRY(ValidateBufferBinding(device, binding, dawn::BufferUsageBit::Uniform));
break;
case dawn::BindingType::StorageBuffer:
case dawn::BindingType::DynamicStorageBuffer:
DAWN_TRY(ValidateBufferBinding(device, binding, dawn::BufferUsageBit::Storage));
break;
case dawn::BindingType::SampledTexture:
if (layoutInfo.dynamic[bindingIndex]) {
return DAWN_VALIDATION_ERROR(
"SampledTextures are expected to be not dynamic");
}
DAWN_TRY(
ValidateTextureBinding(device, binding, dawn::TextureUsageBit::Sampled));
break;
case dawn::BindingType::Sampler:
if (layoutInfo.dynamic[bindingIndex]) {
return DAWN_VALIDATION_ERROR("Samplers are expected to be not dynamic");
}
DAWN_TRY(ValidateSamplerBinding(device, binding));
break;
}
@ -207,10 +212,7 @@ namespace dawn_native {
ASSERT(binding < kMaxBindingsPerGroup);
ASSERT(mLayout->GetBindingInfo().mask[binding]);
ASSERT(mLayout->GetBindingInfo().types[binding] == dawn::BindingType::UniformBuffer ||
mLayout->GetBindingInfo().types[binding] == dawn::BindingType::StorageBuffer ||
mLayout->GetBindingInfo().types[binding] ==
dawn::BindingType::DynamicUniformBuffer ||
mLayout->GetBindingInfo().types[binding] == dawn::BindingType::DynamicStorageBuffer);
mLayout->GetBindingInfo().types[binding] == dawn::BindingType::StorageBuffer);
BufferBase* buffer = static_cast<BufferBase*>(mBindings[binding].Get());
return {buffer, mOffsets[binding], mSizes[binding]};
}

View File

@ -87,8 +87,8 @@ namespace dawn_native {
mBindingInfo.visibilities[index] = binding.visibility;
mBindingInfo.types[index] = binding.type;
if (binding.type == dawn::BindingType::DynamicUniformBuffer ||
binding.type == dawn::BindingType::DynamicStorageBuffer) {
if (binding.dynamic) {
mBindingInfo.dynamic.set(index);
mDynamicBufferCount++;
}

View File

@ -42,6 +42,7 @@ namespace dawn_native {
struct LayoutBindingInfo {
std::array<dawn::ShaderStageBit, kMaxBindingsPerGroup> visibilities;
std::array<dawn::BindingType, kMaxBindingsPerGroup> types;
std::bitset<kMaxBindingsPerGroup> dynamic;
std::bitset<kMaxBindingsPerGroup> mask;
};
const LayoutBindingInfo& GetBindingInfo() const;

View File

@ -588,14 +588,12 @@ namespace dawn_native {
dawn::BindingType type = layoutInfo.types[i];
switch (type) {
case dawn::BindingType::UniformBuffer:
case dawn::BindingType::DynamicUniformBuffer: {
case dawn::BindingType::UniformBuffer: {
BufferBase* buffer = group->GetBindingAsBufferBinding(i).buffer;
tracker->BufferUsedAs(buffer, dawn::BufferUsageBit::Uniform);
} break;
case dawn::BindingType::StorageBuffer:
case dawn::BindingType::DynamicStorageBuffer: {
case dawn::BindingType::StorageBuffer: {
BufferBase* buffer = group->GetBindingAsBufferBinding(i).buffer;
tracker->BufferUsedAs(buffer, dawn::BufferUsageBit::Storage);
} break;

View File

@ -66,17 +66,6 @@ namespace dawn_native {
return {};
}
dawn::BindingType NonDynamicBindingType(dawn::BindingType type) {
switch (type) {
case dawn::BindingType::DynamicUniformBuffer:
return dawn::BindingType::UniformBuffer;
case dawn::BindingType::DynamicStorageBuffer:
return dawn::BindingType::StorageBuffer;
default:
return type;
}
}
// ShaderModuleBase
ShaderModuleBase::ShaderModuleBase(DeviceBase* device,
@ -247,9 +236,7 @@ namespace dawn_native {
continue;
}
// DynamicUniformBuffer and DynamicStorageBuffer are uniform buffer and
// storage buffer in shader. Need to translate them.
if (NonDynamicBindingType(layoutBindingType) != moduleInfo.type) {
if (layoutBindingType != moduleInfo.type) {
return false;
}

View File

@ -97,10 +97,6 @@ namespace dawn_native { namespace d3d12 {
} break;
// TODO(shaobo.yan@intel.com): Implement dynamic buffer offset.
case dawn::BindingType::DynamicUniformBuffer:
case dawn::BindingType::DynamicStorageBuffer:
UNREACHABLE();
break;
}
}

View File

@ -38,10 +38,6 @@ namespace dawn_native { namespace d3d12 {
mBindingOffsets[binding] = mDescriptorCounts[Sampler]++;
break;
// TODO(shaobo.yan@intel.com): Implement dynamic buffer offset.
case dawn::BindingType::DynamicUniformBuffer:
case dawn::BindingType::DynamicStorageBuffer:
UNREACHABLE();
break;
}
}
@ -101,10 +97,6 @@ namespace dawn_native { namespace d3d12 {
mBindingOffsets[binding] += descriptorOffsets[Sampler];
break;
// TODO(shaobo.yan@intel.com): Implement dynamic buffer offset.
case dawn::BindingType::DynamicUniformBuffer:
case dawn::BindingType::DynamicStorageBuffer:
UNREACHABLE();
break;
}
}
}

View File

@ -235,7 +235,14 @@ namespace dawn_native { namespace metal {
case dawn::BindingType::StorageBuffer: {
BufferBinding binding = group->GetBindingAsBufferBinding(bindingIndex);
const id<MTLBuffer> buffer = ToBackend(binding.buffer)->GetMTLBuffer();
const NSUInteger offset = binding.offset;
NSUInteger offset = binding.offset;
// TODO(shaobo.yan@intel.com): Record bound buffer status to use
// setBufferOffset to achieve better performance.
if (layout.dynamic[bindingIndex]) {
offset += dynamicOffsets[currentDynamicBufferIndex];
currentDynamicBufferIndex++;
}
if (hasVertStage) {
[render setVertexBuffers:&buffer
@ -285,34 +292,6 @@ namespace dawn_native { namespace metal {
[compute setTexture:textureView->GetMTLTexture() atIndex:computeIndex];
}
} break;
// TODO(shaobo.yan@intel.com): Record bound buffer status to use setBufferOffset
// to achieve better performance.
case dawn::BindingType::DynamicUniformBuffer:
case dawn::BindingType::DynamicStorageBuffer: {
ASSERT(currentDynamicBufferIndex < dynamicOffsetCount);
BufferBinding binding = group->GetBindingAsBufferBinding(bindingIndex);
const id<MTLBuffer> buffer = ToBackend(binding.buffer)->GetMTLBuffer();
NSUInteger offset =
binding.offset + dynamicOffsets[currentDynamicBufferIndex];
currentDynamicBufferIndex += 1;
if (hasVertStage) {
[render setVertexBuffers:&buffer
offsets:&offset
withRange:NSMakeRange(vertIndex, 1)];
}
if (hasFragStage) {
[render setFragmentBuffers:&buffer
offsets:&offset
withRange:NSMakeRange(fragIndex, 1)];
}
if (hasComputeStage) {
[compute setBuffers:&buffer
offsets:&offset
withRange:NSMakeRange(computeIndex, 1)];
}
} break;
}
}
}

View File

@ -42,8 +42,6 @@ namespace dawn_native { namespace metal {
switch (groupInfo.types[binding]) {
case dawn::BindingType::UniformBuffer:
case dawn::BindingType::StorageBuffer:
case dawn::BindingType::DynamicUniformBuffer:
case dawn::BindingType::DynamicStorageBuffer:
mIndexInfo[stage][group][binding] = bufferIndex;
bufferIndex++;
break;

View File

@ -266,11 +266,7 @@ namespace dawn_native { namespace opengl {
binding.offset, binding.size);
} break;
// TODO(shaobo.yan@intel.com): Implement dynamic buffer offset.
case dawn::BindingType::DynamicUniformBuffer:
case dawn::BindingType::DynamicStorageBuffer:
UNREACHABLE();
break;
// TODO(shaobo.yan@intel.com): Implement dynamic buffer offset.
}
}
}

View File

@ -136,10 +136,6 @@ namespace dawn_native { namespace opengl {
break;
// TODO(shaobo.yan@intel.com): Implement dynamic buffer offset.
case dawn::BindingType::DynamicUniformBuffer:
case dawn::BindingType::DynamicStorageBuffer:
UNREACHABLE();
break;
}
}
}

View File

@ -55,10 +55,6 @@ namespace dawn_native { namespace opengl {
break;
// TODO(shaobo.yan@intel.com): Implement dynamic buffer offset
case dawn::BindingType::DynamicUniformBuffer:
case dawn::BindingType::DynamicStorageBuffer:
UNREACHABLE();
break;
}
}
}

View File

@ -39,20 +39,22 @@ namespace dawn_native { namespace vulkan {
} // anonymous namespace
VkDescriptorType VulkanDescriptorType(dawn::BindingType type) {
VkDescriptorType VulkanDescriptorType(dawn::BindingType type, bool isDynamic) {
switch (type) {
case dawn::BindingType::UniformBuffer:
if (isDynamic) {
return VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
}
return VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
case dawn::BindingType::Sampler:
return VK_DESCRIPTOR_TYPE_SAMPLER;
case dawn::BindingType::SampledTexture:
return VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
case dawn::BindingType::StorageBuffer:
if (isDynamic) {
return VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC;
}
return VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
case dawn::BindingType::DynamicUniformBuffer:
return VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
case dawn::BindingType::DynamicStorageBuffer:
return VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC;
default:
UNREACHABLE();
}
@ -70,7 +72,8 @@ namespace dawn_native { namespace vulkan {
for (uint32_t bindingIndex : IterateBitSet(info.mask)) {
auto& binding = bindings[numBindings];
binding.binding = bindingIndex;
binding.descriptorType = VulkanDescriptorType(info.types[bindingIndex]);
binding.descriptorType =
VulkanDescriptorType(info.types[bindingIndex], info.dynamic[bindingIndex]);
binding.descriptorCount = 1;
binding.stageFlags = VulkanShaderStageFlags(info.visibilities[bindingIndex]);
binding.pImmutableSamplers = nullptr;
@ -122,14 +125,12 @@ namespace dawn_native { namespace vulkan {
auto ToDescriptorType = [](dawn::BindingType type) -> DescriptorType {
switch (type) {
case dawn::BindingType::UniformBuffer:
case dawn::BindingType::DynamicUniformBuffer:
return UNIFORM_BUFFER;
case dawn::BindingType::Sampler:
return SAMPLER;
case dawn::BindingType::SampledTexture:
return SAMPLED_IMAGE;
case dawn::BindingType::StorageBuffer:
case dawn::BindingType::DynamicStorageBuffer:
return STORAGE_BUFFER;
default:
UNREACHABLE();
@ -145,7 +146,8 @@ namespace dawn_native { namespace vulkan {
if (descriptorTypeIndex[type] == -1) {
descriptorTypeIndex[type] = numSizes;
result[numSizes].type = VulkanDescriptorType(info.types[bindingIndex]);
result[numSizes].type =
VulkanDescriptorType(info.types[bindingIndex], info.dynamic[bindingIndex]);
result[numSizes].descriptorCount = 1;
numSizes++;
} else {

View File

@ -23,7 +23,7 @@ namespace dawn_native { namespace vulkan {
class Device;
VkDescriptorType VulkanDescriptorType(dawn::BindingType type);
VkDescriptorType VulkanDescriptorType(dawn::BindingType type, bool isDynamic);
class BindGroupLayout : public BindGroupLayoutBase {
public:

View File

@ -77,13 +77,12 @@ namespace dawn_native { namespace vulkan {
write.dstBinding = bindingIndex;
write.dstArrayElement = 0;
write.descriptorCount = 1;
write.descriptorType = VulkanDescriptorType(layoutInfo.types[bindingIndex]);
write.descriptorType = VulkanDescriptorType(layoutInfo.types[bindingIndex],
layoutInfo.dynamic[bindingIndex]);
switch (layoutInfo.types[bindingIndex]) {
case dawn::BindingType::UniformBuffer:
case dawn::BindingType::StorageBuffer:
case dawn::BindingType::DynamicUniformBuffer:
case dawn::BindingType::DynamicStorageBuffer: {
case dawn::BindingType::StorageBuffer: {
BufferBinding binding = GetBindingAsBufferBinding(bindingIndex);
writeBufferInfo[numWrites].buffer = ToBackend(binding.buffer)->GetHandle();

View File

@ -47,9 +47,9 @@ class DynamicBufferOffsetTests : public DawnTest {
mBindGroupLayout = utils::MakeBindGroupLayout(
device, {{0, dawn::ShaderStageBit::Compute | dawn::ShaderStageBit::Fragment,
dawn::BindingType::DynamicUniformBuffer},
dawn::BindingType::UniformBuffer, true},
{1, dawn::ShaderStageBit::Compute | dawn::ShaderStageBit::Fragment,
dawn::BindingType::DynamicStorageBuffer}});
dawn::BindingType::StorageBuffer, true}});
mBindGroup = utils::MakeBindGroup(
device, mBindGroupLayout,

View File

@ -456,9 +456,9 @@ class SetBindGroupValidationTest : public ValidationTest {
void SetUp() override {
mBindGroupLayout = utils::MakeBindGroupLayout(
device, {{0, dawn::ShaderStageBit::Compute | dawn::ShaderStageBit::Fragment,
dawn::BindingType::DynamicUniformBuffer},
dawn::BindingType::UniformBuffer, true},
{1, dawn::ShaderStageBit::Compute | dawn::ShaderStageBit::Fragment,
dawn::BindingType::DynamicStorageBuffer}});
dawn::BindingType::StorageBuffer, true}});
}
dawn::Buffer CreateBuffer(uint64_t bufferSize, dawn::BufferUsageBit usage) {