Remove BufferView and inline offset/size in BindGroup

BUG=dawn:2

Change-Id: I811024c4ac3a6167dd0caff05eca3fbb2640e862
Reviewed-on: https://dawn-review.googlesource.com/c/2941
Reviewed-by: Kai Ninomiya <kainino@chromium.org>
Reviewed-by: Jiawei Shao <jiawei.shao@intel.com>
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
This commit is contained in:
Corentin Wallez 2018-12-07 12:31:53 +00:00 committed by Commit Bot service account
parent 0f50114b3c
commit 6f0e1f9d82
47 changed files with 206 additions and 420 deletions

View File

@ -30,7 +30,9 @@
"extensible": false,
"members": [
{"name": "binding", "type": "uint32_t"},
{"name": "buffer view", "type": "buffer view", "optional": true},
{"name": "buffer", "type": "buffer", "optional": true},
{"name": "offset", "type": "uint32_t"},
{"name": "size", "type": "uint32_t"},
{"name": "sampler", "type": "sampler", "optional": true},
{"name": "texture view", "type": "texture view", "optional": true}
]
@ -164,10 +166,6 @@
"buffer": {
"category": "object",
"methods": [
{
"name": "create buffer view builder",
"returns": "buffer view builder"
},
{
"name": "set sub data",
"args": [
@ -264,25 +262,6 @@
{"value": 128, "name": "storage"}
]
},
"buffer view": {
"category": "object"
},
"buffer view builder": {
"category": "object",
"methods": [
{
"name": "get result",
"returns": "buffer view"
},
{
"name": "set extent",
"args": [
{"name": "offset", "type": "uint32_t"},
{"name": "size", "type": "uint32_t"}
]
}
]
},
"callback userdata": {
"category": "natively defined"
},

View File

@ -237,22 +237,11 @@ void initSim() {
csDesc.layout = pl;
updatePipeline = device.CreateComputePipeline(&csDesc);
dawn::BufferView updateParamsView = updateParams.CreateBufferViewBuilder()
.SetExtent(0, sizeof(SimParams))
.GetResult();
std::array<dawn::BufferView, 2> views;
for (uint32_t i = 0; i < 2; ++i) {
views[i] = particleBuffers[i].CreateBufferViewBuilder()
.SetExtent(0, kNumParticles * sizeof(Particle))
.GetResult();
}
for (uint32_t i = 0; i < 2; ++i) {
updateBGs[i] = utils::MakeBindGroup(device, bgl, {
{0, updateParamsView},
{1, views[i]},
{2, views[(i + 1) % 2]}
{0, updateParams, 0, sizeof(SimParams)},
{1, particleBuffers[i], 0, kNumParticles * sizeof(Particle)},
{2, particleBuffers[(i + 1) % 2], 0, kNumParticles * sizeof(Particle)},
});
}
}

View File

@ -180,27 +180,14 @@ void init() {
transform = glm::translate(transform, glm::vec3(0.f, -2.f, 0.f));
transformBuffer[1] = utils::CreateBufferFromData(device, &transform, sizeof(glm::mat4), dawn::BufferUsageBit::Uniform);
dawn::BufferView cameraBufferView = cameraBuffer.CreateBufferViewBuilder()
.SetExtent(0, sizeof(CameraData))
.GetResult();
dawn::BufferView transformBufferView[2] = {
transformBuffer[0].CreateBufferViewBuilder()
.SetExtent(0, sizeof(glm::mat4))
.GetResult(),
transformBuffer[1].CreateBufferViewBuilder()
.SetExtent(0, sizeof(glm::mat4))
.GetResult(),
};
bindGroup[0] = utils::MakeBindGroup(device, bgl, {
{0, cameraBufferView},
{1, transformBufferView[0]}
{0, cameraBuffer, 0, sizeof(CameraData)},
{1, transformBuffer[0], 0, sizeof(glm::mat4)}
});
bindGroup[1] = utils::MakeBindGroup(device, bgl, {
{0, cameraBufferView},
{1, transformBufferView[1]}
{0, cameraBuffer, 0, sizeof(CameraData)},
{1, transformBuffer[1], 0, sizeof(glm::mat4)}
});
depthStencilView = CreateDefaultDepthStencilView(device);

View File

@ -20,7 +20,7 @@
#include "dawn_native/ValidationUtils_autogen.h"
{% for type in by_category["object"] %}
{% if not type.is_builder and type.name.canonical_case() not in ["buffer view", "texture view"] %}
{% if not type.is_builder and type.name.canonical_case() not in ["texture view"] %}
#include "dawn_native/{{type.name.CamelCase()}}.h"
{% endif %}
{% endfor %}

View File

@ -30,17 +30,28 @@ namespace dawn_native {
MaybeError ValidateBufferBinding(const BindGroupBinding& binding,
dawn::BufferUsageBit requiredUsage) {
if (binding.bufferView == nullptr || binding.sampler != nullptr ||
if (binding.buffer == nullptr || binding.sampler != nullptr ||
binding.textureView != nullptr) {
return DAWN_VALIDATION_ERROR("expected buffer binding");
}
if (!IsAligned(binding.bufferView->GetOffset(), 256)) {
return DAWN_VALIDATION_ERROR(
"Buffer view offset for bind group needs to be 256-byte aligned");
uint32_t bufferSize = binding.buffer->GetSize();
if (binding.size > bufferSize) {
return DAWN_VALIDATION_ERROR("Buffer binding size larger than the buffer");
}
if (!(binding.bufferView->GetBuffer()->GetUsage() & requiredUsage)) {
// Note that no overflow can happen because we already checked that
// bufferSize >= binding.size
if (binding.offset > bufferSize - binding.size) {
return DAWN_VALIDATION_ERROR("Buffer binding doesn't fit in the buffer");
}
if (!IsAligned(binding.offset, 256)) {
return DAWN_VALIDATION_ERROR(
"Buffer offset for bind group needs to be 256-byte aligned");
}
if (!(binding.buffer->GetUsage() & requiredUsage)) {
return DAWN_VALIDATION_ERROR("buffer binding usage mismatch");
}
@ -50,7 +61,7 @@ namespace dawn_native {
MaybeError ValidateTextureBinding(const BindGroupBinding& binding,
dawn::TextureUsageBit requiredUsage) {
if (binding.textureView == nullptr || binding.sampler != nullptr ||
binding.bufferView != nullptr) {
binding.buffer != nullptr) {
return DAWN_VALIDATION_ERROR("expected texture binding");
}
@ -63,7 +74,7 @@ namespace dawn_native {
MaybeError ValidateSamplerBinding(const BindGroupBinding& binding) {
if (binding.sampler == nullptr || binding.textureView != nullptr ||
binding.bufferView != nullptr) {
binding.buffer != nullptr) {
return DAWN_VALIDATION_ERROR("expected sampler binding");
}
return {};
@ -142,9 +153,11 @@ namespace dawn_native {
// Only a single binding type should be set, so once we found it we can skip to the
// next loop iteration.
if (binding.bufferView != nullptr) {
if (binding.buffer != nullptr) {
ASSERT(mBindings[bindingIndex].Get() == nullptr);
mBindings[bindingIndex] = binding.bufferView;
mBindings[bindingIndex] = binding.buffer;
mOffsets[bindingIndex] = binding.offset;
mSizes[bindingIndex] = binding.size;
continue;
}
@ -166,12 +179,13 @@ namespace dawn_native {
return mLayout.Get();
}
BufferViewBase* BindGroupBase::GetBindingAsBufferView(size_t binding) {
BufferBinding BindGroupBase::GetBindingAsBufferBinding(size_t binding) {
ASSERT(binding < kMaxBindingsPerGroup);
ASSERT(mLayout->GetBindingInfo().mask[binding]);
ASSERT(mLayout->GetBindingInfo().types[binding] == dawn::BindingType::UniformBuffer ||
mLayout->GetBindingInfo().types[binding] == dawn::BindingType::StorageBuffer);
return reinterpret_cast<BufferViewBase*>(mBindings[binding].Get());
BufferBase* buffer = reinterpret_cast<BufferBase*>(mBindings[binding].Get());
return {buffer, mOffsets[binding], mSizes[binding]};
}
SamplerBase* BindGroupBase::GetBindingAsSampler(size_t binding) {

View File

@ -32,18 +32,26 @@ namespace dawn_native {
MaybeError ValidateBindGroupDescriptor(DeviceBase* device,
const BindGroupDescriptor* descriptor);
struct BufferBinding {
BufferBase* buffer;
uint32_t offset;
uint32_t size;
};
class BindGroupBase : public ObjectBase {
public:
BindGroupBase(DeviceBase* device, const BindGroupDescriptor* descriptor);
const BindGroupLayoutBase* GetLayout() const;
BufferViewBase* GetBindingAsBufferView(size_t binding);
BufferBinding GetBindingAsBufferBinding(size_t binding);
SamplerBase* GetBindingAsSampler(size_t binding);
TextureViewBase* GetBindingAsTextureView(size_t binding);
private:
Ref<BindGroupLayoutBase> mLayout;
std::array<Ref<ObjectBase>, kMaxBindingsPerGroup> mBindings;
std::array<uint32_t, kMaxBindingsPerGroup> mOffsets;
std::array<uint32_t, kMaxBindingsPerGroup> mSizes;
};
} // namespace dawn_native

View File

@ -60,10 +60,6 @@ namespace dawn_native {
}
}
BufferViewBuilder* BufferBase::CreateBufferViewBuilder() {
return new BufferViewBuilder(GetDevice(), this);
}
uint32_t BufferBase::GetSize() const {
return mSize;
}
@ -209,62 +205,4 @@ namespace dawn_native {
return {};
}
// BufferViewBase
BufferViewBase::BufferViewBase(BufferViewBuilder* builder)
: ObjectBase(builder->GetDevice()),
mBuffer(std::move(builder->mBuffer)),
mSize(builder->mSize),
mOffset(builder->mOffset) {
}
BufferBase* BufferViewBase::GetBuffer() {
return mBuffer.Get();
}
uint32_t BufferViewBase::GetSize() const {
return mSize;
}
uint32_t BufferViewBase::GetOffset() const {
return mOffset;
}
// BufferViewBuilder
enum BufferViewSetProperties {
BUFFER_VIEW_PROPERTY_EXTENT = 0x1,
};
BufferViewBuilder::BufferViewBuilder(DeviceBase* device, BufferBase* buffer)
: Builder(device), mBuffer(buffer) {
}
BufferViewBase* BufferViewBuilder::GetResultImpl() {
constexpr int allProperties = BUFFER_VIEW_PROPERTY_EXTENT;
if ((mPropertiesSet & allProperties) != allProperties) {
HandleError("Buffer view missing properties");
return nullptr;
}
return GetDevice()->CreateBufferView(this);
}
void BufferViewBuilder::SetExtent(uint32_t offset, uint32_t size) {
if ((mPropertiesSet & BUFFER_VIEW_PROPERTY_EXTENT) != 0) {
HandleError("Buffer view extent property set multiple times");
return;
}
uint64_t viewEnd = static_cast<uint64_t>(offset) + static_cast<uint64_t>(size);
if (viewEnd > static_cast<uint64_t>(mBuffer->GetSize())) {
HandleError("Buffer view end is OOB");
return;
}
mOffset = offset;
mSize = size;
mPropertiesSet |= BUFFER_VIEW_PROPERTY_EXTENT;
}
} // namespace dawn_native

View File

@ -45,7 +45,6 @@ namespace dawn_native {
MaybeError ValidateCanUseInSubmitNow() const;
// Dawn API
BufferViewBuilder* CreateBufferViewBuilder();
void SetSubData(uint32_t start, uint32_t count, const uint8_t* data);
void MapReadAsync(uint32_t start,
uint32_t size,
@ -86,40 +85,8 @@ namespace dawn_native {
bool mIsMapped = false;
};
class BufferViewBase : public ObjectBase {
public:
BufferViewBase(BufferViewBuilder* builder);
BufferBase* GetBuffer();
uint32_t GetSize() const;
uint32_t GetOffset() const;
private:
Ref<BufferBase> mBuffer;
uint32_t mSize;
uint32_t mOffset;
};
class BufferViewBuilder : public Builder<BufferViewBase> {
public:
BufferViewBuilder(DeviceBase* device, BufferBase* buffer);
// Dawn API
void SetExtent(uint32_t offset, uint32_t size);
private:
friend class BufferViewBase;
BufferViewBase* GetResultImpl() override;
Ref<BufferBase> mBuffer;
uint32_t mOffset = 0;
uint32_t mSize = 0;
int mPropertiesSet = 0;
};
// This builder class is kept around purely for testing but should not be used.
class BufferBuilder : public Builder<BufferViewBase> {
class BufferBuilder : public Builder<BufferBase> {
public:
BufferBuilder(DeviceBase* device) : Builder(device) {
UNREACHABLE();

View File

@ -255,12 +255,12 @@ namespace dawn_native {
switch (type) {
case dawn::BindingType::UniformBuffer: {
BufferBase* buffer = group->GetBindingAsBufferView(i)->GetBuffer();
BufferBase* buffer = group->GetBindingAsBufferBinding(i).buffer;
tracker->BufferUsedAs(buffer, dawn::BufferUsageBit::Uniform);
} break;
case dawn::BindingType::StorageBuffer: {
BufferBase* buffer = group->GetBindingAsBufferView(i)->GetBuffer();
BufferBase* buffer = group->GetBindingAsBufferBinding(i).buffer;
tracker->BufferUsedAs(buffer, dawn::BufferUsageBit::Storage);
} break;

View File

@ -52,7 +52,6 @@ namespace dawn_native {
FenceSignalTracker* GetFenceSignalTracker() const;
virtual BlendStateBase* CreateBlendState(BlendStateBuilder* builder) = 0;
virtual BufferViewBase* CreateBufferView(BufferViewBuilder* builder) = 0;
virtual CommandBufferBase* CreateCommandBuffer(CommandBufferBuilder* builder) = 0;
virtual DepthStencilStateBase* CreateDepthStencilState(
DepthStencilStateBuilder* builder) = 0;

View File

@ -27,8 +27,6 @@ namespace dawn_native {
class BlendStateBuilder;
class BufferBase;
class BufferBuilder;
class BufferViewBase;
class BufferViewBuilder;
class ComputePipelineBase;
class ComputePipelineBuilder;
class CommandBufferBase;

View File

@ -43,11 +43,6 @@ namespace dawn_native {
using BackendType = typename BackendTraits::BufferType;
};
template <typename BackendTraits>
struct ToBackendTraits<BufferViewBase, BackendTraits> {
using BackendType = typename BackendTraits::BufferViewType;
};
template <typename BackendTraits>
struct ToBackendTraits<CommandBufferBase, BackendTraits> {
using BackendType = typename BackendTraits::CommandBufferType;

View File

@ -46,37 +46,54 @@ namespace dawn_native { namespace d3d12 {
const auto& bindingOffsets = bgl->GetBindingOffsets();
auto d3d12Device = ToBackend(GetDevice())->GetD3D12Device();
for (uint32_t binding : IterateBitSet(layout.mask)) {
switch (layout.types[binding]) {
for (uint32_t bindingIndex : IterateBitSet(layout.mask)) {
switch (layout.types[bindingIndex]) {
case dawn::BindingType::UniformBuffer: {
auto* view = ToBackend(GetBindingAsBufferView(binding));
auto& cbv = view->GetCBVDescriptor();
BufferBinding binding = GetBindingAsBufferBinding(bindingIndex);
D3D12_CONSTANT_BUFFER_VIEW_DESC desc;
// TODO(enga@google.com): investigate if this needs to be a constraint at the
// API level
desc.SizeInBytes = Align(binding.size, 256);
desc.BufferLocation = ToBackend(binding.buffer)->GetVA() + binding.offset;
d3d12Device->CreateConstantBufferView(
&cbv, cbvUavSrvHeapStart.GetCPUHandle(*cbvUavSrvHeapOffset +
bindingOffsets[binding]));
&desc, cbvUavSrvHeapStart.GetCPUHandle(*cbvUavSrvHeapOffset +
bindingOffsets[bindingIndex]));
} break;
case dawn::BindingType::StorageBuffer: {
auto* view = ToBackend(GetBindingAsBufferView(binding));
auto& uav = view->GetUAVDescriptor();
BufferBinding binding = GetBindingAsBufferBinding(bindingIndex);
D3D12_UNORDERED_ACCESS_VIEW_DESC desc;
// TODO(enga@google.com): investigate if this needs to be a constraint at the
// API level
desc.Buffer.NumElements = Align(binding.size, 256);
desc.Format = DXGI_FORMAT_UNKNOWN;
desc.ViewDimension = D3D12_UAV_DIMENSION_BUFFER;
desc.Buffer.FirstElement = binding.offset;
desc.Buffer.StructureByteStride = 1;
desc.Buffer.CounterOffsetInBytes = 0;
desc.Buffer.Flags = D3D12_BUFFER_UAV_FLAG_NONE;
d3d12Device->CreateUnorderedAccessView(
ToBackend(view->GetBuffer())->GetD3D12Resource().Get(), nullptr, &uav,
ToBackend(binding.buffer)->GetD3D12Resource().Get(), nullptr, &desc,
cbvUavSrvHeapStart.GetCPUHandle(*cbvUavSrvHeapOffset +
bindingOffsets[binding]));
bindingOffsets[bindingIndex]));
} break;
case dawn::BindingType::SampledTexture: {
auto* view = ToBackend(GetBindingAsTextureView(binding));
auto* view = ToBackend(GetBindingAsTextureView(bindingIndex));
auto& srv = view->GetSRVDescriptor();
d3d12Device->CreateShaderResourceView(
ToBackend(view->GetTexture())->GetD3D12Resource(), &srv,
cbvUavSrvHeapStart.GetCPUHandle(*cbvUavSrvHeapOffset +
bindingOffsets[binding]));
bindingOffsets[bindingIndex]));
} break;
case dawn::BindingType::Sampler: {
auto* sampler = ToBackend(GetBindingAsSampler(binding));
auto* sampler = ToBackend(GetBindingAsSampler(bindingIndex));
auto& samplerDesc = sampler->GetSamplerDescriptor();
d3d12Device->CreateSampler(
&samplerDesc, samplerHeapStart.GetCPUHandle(*samplerHeapOffset +
bindingOffsets[binding]));
bindingOffsets[bindingIndex]));
} break;
}
}

View File

@ -197,32 +197,6 @@ namespace dawn_native { namespace d3d12 {
mWrittenMappedRange = {};
}
BufferView::BufferView(BufferViewBuilder* builder) : BufferViewBase(builder) {
mCbvDesc.BufferLocation = ToBackend(GetBuffer())->GetVA() + GetOffset();
mCbvDesc.SizeInBytes = GetD3D12Size();
mUavDesc.Format = DXGI_FORMAT_UNKNOWN;
mUavDesc.ViewDimension = D3D12_UAV_DIMENSION_BUFFER;
mUavDesc.Buffer.FirstElement = GetOffset();
mUavDesc.Buffer.NumElements = GetD3D12Size();
mUavDesc.Buffer.StructureByteStride = 1;
mUavDesc.Buffer.CounterOffsetInBytes = 0;
mUavDesc.Buffer.Flags = D3D12_BUFFER_UAV_FLAG_NONE;
}
uint32_t BufferView::GetD3D12Size() const {
// TODO(enga@google.com): TODO investigate if this needs to be a constraint at the API level
return Align(GetSize(), 256);
}
const D3D12_CONSTANT_BUFFER_VIEW_DESC& BufferView::GetCBVDescriptor() const {
return mCbvDesc;
}
const D3D12_UNORDERED_ACCESS_VIEW_DESC& BufferView::GetUAVDescriptor() const {
return mUavDesc;
}
MapRequestTracker::MapRequestTracker(Device* device) : mDevice(device) {
}

View File

@ -50,19 +50,6 @@ namespace dawn_native { namespace d3d12 {
D3D12_RANGE mWrittenMappedRange;
};
class BufferView : public BufferViewBase {
public:
BufferView(BufferViewBuilder* builder);
uint32_t GetD3D12Size() const;
const D3D12_CONSTANT_BUFFER_VIEW_DESC& GetCBVDescriptor() const;
const D3D12_UNORDERED_ACCESS_VIEW_DESC& GetUAVDescriptor() const;
private:
D3D12_CONSTANT_BUFFER_VIEW_DESC mCbvDesc;
D3D12_UNORDERED_ACCESS_VIEW_DESC mUavDesc;
};
class MapRequestTracker {
public:
MapRequestTracker(Device* device);

View File

@ -300,9 +300,6 @@ namespace dawn_native { namespace d3d12 {
ResultOrError<BufferBase*> Device::CreateBufferImpl(const BufferDescriptor* descriptor) {
return new Buffer(this, descriptor);
}
BufferViewBase* Device::CreateBufferView(BufferViewBuilder* builder) {
return new BufferView(builder);
}
CommandBufferBase* Device::CreateCommandBuffer(CommandBufferBuilder* builder) {
return new CommandBuffer(builder);
}

View File

@ -42,7 +42,6 @@ namespace dawn_native { namespace d3d12 {
~Device();
BlendStateBase* CreateBlendState(BlendStateBuilder* builder) override;
BufferViewBase* CreateBufferView(BufferViewBuilder* builder) override;
CommandBufferBase* CreateCommandBuffer(CommandBufferBuilder* builder) override;
DepthStencilStateBase* CreateDepthStencilState(DepthStencilStateBuilder* builder) override;
InputStateBase* CreateInputState(InputStateBuilder* builder) override;

View File

@ -23,7 +23,6 @@ namespace dawn_native { namespace d3d12 {
class BindGroupLayout;
class BlendState;
class Buffer;
class BufferView;
class CommandBuffer;
class ComputePipeline;
class DepthStencilState;
@ -44,7 +43,6 @@ namespace dawn_native { namespace d3d12 {
using BindGroupLayoutType = BindGroupLayout;
using BlendStateType = BlendState;
using BufferType = Buffer;
using BufferViewType = BufferView;
using CommandBufferType = CommandBuffer;
using ComputePipelineType = ComputePipeline;
using DepthStencilStateType = DepthStencilState;

View File

@ -42,11 +42,6 @@ namespace dawn_native { namespace metal {
id<MTLBuffer> mMtlBuffer = nil;
};
class BufferView : public BufferViewBase {
public:
BufferView(BufferViewBuilder* builder);
};
class MapRequestTracker {
public:
MapRequestTracker(Device* device);

View File

@ -68,9 +68,6 @@ namespace dawn_native { namespace metal {
// Nothing to do, Metal StorageModeShared buffers are always mapped.
}
BufferView::BufferView(BufferViewBuilder* builder) : BufferViewBase(builder) {
}
MapRequestTracker::MapRequestTracker(Device* device) : mDevice(device) {
}

View File

@ -118,12 +118,8 @@ namespace dawn_native { namespace metal {
// 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 (size_t binding = 0; binding < layout.mask.size(); ++binding) {
if (!layout.mask[binding]) {
continue;
}
auto stage = layout.visibilities[binding];
for (uint32_t bindingIndex : IterateBitSet(layout.mask)) {
auto stage = layout.visibilities[bindingIndex];
bool hasVertStage = stage & dawn::ShaderStageBit::Vertex && render != nil;
bool hasFragStage = stage & dawn::ShaderStageBit::Fragment && render != nil;
bool hasComputeStage = stage & dawn::ShaderStageBit::Compute && compute != nil;
@ -134,24 +130,23 @@ namespace dawn_native { namespace metal {
if (hasVertStage) {
vertIndex = pipelineLayout->GetBindingIndexInfo(
dawn::ShaderStage::Vertex)[index][binding];
dawn::ShaderStage::Vertex)[index][bindingIndex];
}
if (hasFragStage) {
fragIndex = pipelineLayout->GetBindingIndexInfo(
dawn::ShaderStage::Fragment)[index][binding];
dawn::ShaderStage::Fragment)[index][bindingIndex];
}
if (hasComputeStage) {
computeIndex = pipelineLayout->GetBindingIndexInfo(
dawn::ShaderStage::Compute)[index][binding];
dawn::ShaderStage::Compute)[index][bindingIndex];
}
switch (layout.types[binding]) {
switch (layout.types[bindingIndex]) {
case dawn::BindingType::UniformBuffer:
case dawn::BindingType::StorageBuffer: {
BufferView* view = ToBackend(group->GetBindingAsBufferView(binding));
auto b = ToBackend(view->GetBuffer());
const id<MTLBuffer> buffer = b->GetMTLBuffer();
const NSUInteger offset = view->GetOffset();
BufferBinding binding = group->GetBindingAsBufferBinding(bindingIndex);
const id<MTLBuffer> buffer = ToBackend(binding.buffer)->GetMTLBuffer();
const NSUInteger offset = binding.offset;
if (hasVertStage) {
[render setVertexBuffers:&buffer
@ -172,7 +167,7 @@ namespace dawn_native { namespace metal {
} break;
case dawn::BindingType::Sampler: {
auto sampler = ToBackend(group->GetBindingAsSampler(binding));
auto sampler = ToBackend(group->GetBindingAsSampler(bindingIndex));
if (hasVertStage) {
[render setVertexSamplerState:sampler->GetMTLSamplerState()
atIndex:vertIndex];
@ -188,7 +183,7 @@ namespace dawn_native { namespace metal {
} break;
case dawn::BindingType::SampledTexture: {
auto textureView = ToBackend(group->GetBindingAsTextureView(binding));
auto textureView = ToBackend(group->GetBindingAsTextureView(bindingIndex));
if (hasVertStage) {
[render setVertexTexture:textureView->GetMTLTexture()
atIndex:vertIndex];

View File

@ -38,7 +38,6 @@ namespace dawn_native { namespace metal {
~Device();
BlendStateBase* CreateBlendState(BlendStateBuilder* builder) override;
BufferViewBase* CreateBufferView(BufferViewBuilder* builder) override;
CommandBufferBase* CreateCommandBuffer(CommandBufferBuilder* builder) override;
DepthStencilStateBase* CreateDepthStencilState(DepthStencilStateBuilder* builder) override;
InputStateBase* CreateInputState(InputStateBuilder* builder) override;

View File

@ -176,9 +176,6 @@ namespace dawn_native { namespace metal {
ResultOrError<BufferBase*> Device::CreateBufferImpl(const BufferDescriptor* descriptor) {
return new Buffer(this, descriptor);
}
BufferViewBase* Device::CreateBufferView(BufferViewBuilder* builder) {
return new BufferView(builder);
}
CommandBufferBase* Device::CreateCommandBuffer(CommandBufferBuilder* builder) {
return new CommandBuffer(builder);
}

View File

@ -29,7 +29,6 @@ namespace dawn_native { namespace metal {
using BindGroupLayout = BindGroupLayoutBase;
class BlendState;
class Buffer;
class BufferView;
class CommandBuffer;
class ComputePipeline;
class DepthStencilState;
@ -51,7 +50,6 @@ namespace dawn_native { namespace metal {
using BindGroupLayoutType = BindGroupLayout;
using BlendStateType = BlendState;
using BufferType = Buffer;
using BufferViewType = BufferView;
using CommandBufferType = CommandBuffer;
using ComputePipelineType = ComputePipeline;
using DepthStencilStateType = DepthStencilState;

View File

@ -48,9 +48,6 @@ namespace dawn_native { namespace null {
ResultOrError<BufferBase*> Device::CreateBufferImpl(const BufferDescriptor* descriptor) {
return new Buffer(this, descriptor);
}
BufferViewBase* Device::CreateBufferView(BufferViewBuilder* builder) {
return new BufferView(builder);
}
CommandBufferBase* Device::CreateCommandBuffer(CommandBufferBuilder* builder) {
return new CommandBuffer(builder);
}

View File

@ -42,7 +42,6 @@ namespace dawn_native { namespace null {
using BindGroupLayout = BindGroupLayoutBase;
using BlendState = BlendStateBase;
class Buffer;
using BufferView = BufferViewBase;
class CommandBuffer;
using ComputePipeline = ComputePipelineBase;
using DepthStencilState = DepthStencilStateBase;
@ -63,7 +62,6 @@ namespace dawn_native { namespace null {
using BindGroupLayoutType = BindGroupLayout;
using BlendStateType = BlendState;
using BufferType = Buffer;
using BufferViewType = BufferView;
using CommandBufferType = CommandBuffer;
using ComputePipelineType = ComputePipeline;
using DepthStencilStateType = DepthStencilState;
@ -96,7 +94,6 @@ namespace dawn_native { namespace null {
~Device();
BlendStateBase* CreateBlendState(BlendStateBuilder* builder) override;
BufferViewBase* CreateBufferView(BufferViewBuilder* builder) override;
CommandBufferBase* CreateCommandBuffer(CommandBufferBuilder* builder) override;
DepthStencilStateBase* CreateDepthStencilState(DepthStencilStateBuilder* builder) override;
InputStateBase* CreateInputState(InputStateBuilder* builder) override;

View File

@ -57,9 +57,4 @@ namespace dawn_native { namespace opengl {
glUnmapBuffer(GL_ARRAY_BUFFER);
}
// BufferView
BufferView::BufferView(BufferViewBuilder* builder) : BufferViewBase(builder) {
}
}} // namespace dawn_native::opengl

View File

@ -38,11 +38,6 @@ namespace dawn_native { namespace opengl {
GLuint mBuffer = 0;
};
class BufferView : public BufferViewBase {
public:
BufferView(BufferViewBuilder* builder);
};
}} // namespace dawn_native::opengl
#endif // DAWNNATIVE_OPENGL_BUFFERGL_H_

View File

@ -235,21 +235,21 @@ namespace dawn_native { namespace opengl {
const auto& indices = pipelineLayout->GetBindingIndexInfo()[index];
const auto& layout = group->GetLayout()->GetBindingInfo();
for (uint32_t binding : IterateBitSet(layout.mask)) {
switch (layout.types[binding]) {
for (uint32_t bindingIndex : IterateBitSet(layout.mask)) {
switch (layout.types[bindingIndex]) {
case dawn::BindingType::UniformBuffer: {
BufferView* view = ToBackend(group->GetBindingAsBufferView(binding));
GLuint buffer = ToBackend(view->GetBuffer())->GetHandle();
GLuint uboIndex = indices[binding];
BufferBinding binding = group->GetBindingAsBufferBinding(bindingIndex);
GLuint buffer = ToBackend(binding.buffer)->GetHandle();
GLuint uboIndex = indices[bindingIndex];
glBindBufferRange(GL_UNIFORM_BUFFER, uboIndex, buffer, view->GetOffset(),
view->GetSize());
glBindBufferRange(GL_UNIFORM_BUFFER, uboIndex, buffer, binding.offset,
binding.size);
} break;
case dawn::BindingType::Sampler: {
GLuint sampler =
ToBackend(group->GetBindingAsSampler(binding))->GetHandle();
GLuint samplerIndex = indices[binding];
ToBackend(group->GetBindingAsSampler(bindingIndex))->GetHandle();
GLuint samplerIndex = indices[bindingIndex];
for (auto unit : pipeline->GetTextureUnitsForSampler(samplerIndex)) {
glBindSampler(unit, sampler);
@ -257,10 +257,10 @@ namespace dawn_native { namespace opengl {
} break;
case dawn::BindingType::SampledTexture: {
TextureView* view = ToBackend(group->GetBindingAsTextureView(binding));
TextureView* view = ToBackend(group->GetBindingAsTextureView(bindingIndex));
GLuint handle = view->GetHandle();
GLenum target = view->GetGLTarget();
GLuint viewIndex = indices[binding];
GLuint viewIndex = indices[bindingIndex];
for (auto unit : pipeline->GetTextureUnitsForTextureView(viewIndex)) {
glActiveTexture(GL_TEXTURE0 + unit);
@ -269,12 +269,12 @@ namespace dawn_native { namespace opengl {
} break;
case dawn::BindingType::StorageBuffer: {
BufferView* view = ToBackend(group->GetBindingAsBufferView(binding));
GLuint buffer = ToBackend(view->GetBuffer())->GetHandle();
GLuint ssboIndex = indices[binding];
BufferBinding binding = group->GetBindingAsBufferBinding(bindingIndex);
GLuint buffer = ToBackend(binding.buffer)->GetHandle();
GLuint ssboIndex = indices[bindingIndex];
glBindBufferRange(GL_SHADER_STORAGE_BUFFER, ssboIndex, buffer,
view->GetOffset(), view->GetSize());
binding.offset, binding.size);
} break;
}
}

View File

@ -75,9 +75,6 @@ namespace dawn_native { namespace opengl {
ResultOrError<BufferBase*> Device::CreateBufferImpl(const BufferDescriptor* descriptor) {
return new Buffer(this, descriptor);
}
BufferViewBase* Device::CreateBufferView(BufferViewBuilder* builder) {
return new BufferView(builder);
}
CommandBufferBase* Device::CreateCommandBuffer(CommandBufferBuilder* builder) {
return new CommandBuffer(builder);
}

View File

@ -41,7 +41,6 @@ namespace dawn_native { namespace opengl {
// Dawn API
BlendStateBase* CreateBlendState(BlendStateBuilder* builder) override;
BufferViewBase* CreateBufferView(BufferViewBuilder* builder) override;
CommandBufferBase* CreateCommandBuffer(CommandBufferBuilder* builder) override;
DepthStencilStateBase* CreateDepthStencilState(DepthStencilStateBuilder* builder) override;
InputStateBase* CreateInputState(InputStateBuilder* builder) override;

View File

@ -29,7 +29,6 @@ namespace dawn_native { namespace opengl {
using BindGroupLayout = BindGroupLayoutBase;
class BlendState;
class Buffer;
class BufferView;
class CommandBuffer;
class ComputePipeline;
class DepthStencilState;
@ -51,7 +50,6 @@ namespace dawn_native { namespace opengl {
using BindGroupLayoutType = BindGroupLayout;
using BlendStateType = BlendState;
using BufferType = Buffer;
using BufferViewType = BufferView;
using CommandBufferType = CommandBuffer;
using ComputePipelineType = ComputePipeline;
using DepthStencilStateType = DepthStencilState;

View File

@ -82,12 +82,11 @@ namespace dawn_native { namespace vulkan {
switch (layoutInfo.types[bindingIndex]) {
case dawn::BindingType::UniformBuffer:
case dawn::BindingType::StorageBuffer: {
BufferViewBase* view = GetBindingAsBufferView(bindingIndex);
Buffer* buffer = ToBackend(view->GetBuffer());
BufferBinding binding = GetBindingAsBufferBinding(bindingIndex);
writeBufferInfo[numWrites].buffer = buffer->GetHandle();
writeBufferInfo[numWrites].offset = view->GetOffset();
writeBufferInfo[numWrites].range = view->GetSize();
writeBufferInfo[numWrites].buffer = ToBackend(binding.buffer)->GetHandle();
writeBufferInfo[numWrites].offset = binding.offset;
writeBufferInfo[numWrites].range = binding.size;
write.pBufferInfo = &writeBufferInfo[numWrites];
} break;

View File

@ -52,8 +52,6 @@ namespace dawn_native { namespace vulkan {
dawn::BufferUsageBit mLastUsage = dawn::BufferUsageBit::None;
};
using BufferView = BufferViewBase;
class MapRequestTracker {
public:
MapRequestTracker(Device* device);

View File

@ -226,9 +226,6 @@ namespace dawn_native { namespace vulkan {
ResultOrError<BufferBase*> Device::CreateBufferImpl(const BufferDescriptor* descriptor) {
return new Buffer(this, descriptor);
}
BufferViewBase* Device::CreateBufferView(BufferViewBuilder* builder) {
return new BufferView(builder);
}
CommandBufferBase* Device::CreateCommandBuffer(CommandBufferBuilder* builder) {
return new CommandBuffer(builder);
}

View File

@ -64,7 +64,6 @@ namespace dawn_native { namespace vulkan {
// Dawn API
BlendStateBase* CreateBlendState(BlendStateBuilder* builder) override;
BufferViewBase* CreateBufferView(BufferViewBuilder* builder) override;
CommandBufferBase* CreateCommandBuffer(CommandBufferBuilder* builder) override;
DepthStencilStateBase* CreateDepthStencilState(DepthStencilStateBuilder* builder) override;
InputStateBase* CreateInputState(InputStateBuilder* builder) override;

View File

@ -17,17 +17,12 @@
#include "dawn_native/ToBackend.h"
namespace dawn_native {
class BufferViewBase;
}
namespace dawn_native { namespace vulkan {
class BindGroup;
class BindGroupLayout;
class BlendState;
class Buffer;
using BufferView = BufferViewBase;
class CommandBuffer;
class ComputePipeline;
class DepthStencilState;
@ -48,7 +43,6 @@ namespace dawn_native { namespace vulkan {
using BindGroupLayoutType = BindGroupLayout;
using BlendStateType = BlendState;
using BufferType = Buffer;
using BufferViewType = BufferView;
using CommandBufferType = CommandBuffer;
using ComputePipelineType = ComputePipeline;
using DepthStencilStateType = DepthStencilState;

View File

@ -66,9 +66,7 @@ TEST_P(BindGroupTests, ReusedBindGroupSingleSubmit) {
bufferDesc.usage = dawn::BufferUsageBit::TransferDst |
dawn::BufferUsageBit::Uniform;
dawn::Buffer buffer = device.CreateBuffer(&bufferDesc);
dawn::BufferView bufferView =
buffer.CreateBufferViewBuilder().SetExtent(0, sizeof(float)).GetResult();
dawn::BindGroup bindGroup = utils::MakeBindGroup(device, bgl, {{0, bufferView}});
dawn::BindGroup bindGroup = utils::MakeBindGroup(device, bgl, {{0, buffer, 0, sizeof(float)}});
dawn::CommandBuffer cb[2];
cb[0] = CreateSimpleComputeCommandBuffer(cp, bindGroup);
@ -136,13 +134,9 @@ TEST_P(BindGroupTests, ReusedUBO) {
{ 0.f, 1.f, 0.f, 1.f },
};
dawn::Buffer buffer = utils::CreateBufferFromData(device, &data, sizeof(data), dawn::BufferUsageBit::Uniform);
dawn::BufferView vertUBOBufferView =
buffer.CreateBufferViewBuilder().SetExtent(0, sizeof(Data::transform)).GetResult();
dawn::BufferView fragUBOBufferView =
buffer.CreateBufferViewBuilder().SetExtent(256, sizeof(Data::color)).GetResult();
dawn::BindGroup bindGroup = utils::MakeBindGroup(device, bgl, {
{0, vertUBOBufferView},
{1, fragUBOBufferView}
{0, buffer, 0, sizeof(Data::transform)},
{1, buffer, 256, sizeof(Data::color)}
});
dawn::CommandBufferBuilder builder = device.CreateCommandBufferBuilder();
@ -214,8 +208,7 @@ TEST_P(BindGroupTests, UBOSamplerAndTexture) {
constexpr float dummy = 0.0f;
constexpr float transform[] = { 1.f, 0.f, dummy, dummy, 0.f, 1.f, dummy, dummy };
dawn::Buffer buffer = utils::CreateBufferFromData(device, &transform, sizeof(transform), dawn::BufferUsageBit::Uniform);
dawn::BufferView vertUBOBufferView =
buffer.CreateBufferViewBuilder().SetExtent(0, sizeof(transform)).GetResult();
dawn::SamplerDescriptor samplerDescriptor;
samplerDescriptor.minFilter = dawn::FilterMode::Nearest;
samplerDescriptor.magFilter = dawn::FilterMode::Nearest;
@ -236,6 +229,7 @@ TEST_P(BindGroupTests, UBOSamplerAndTexture) {
descriptor.usage = dawn::TextureUsageBit::TransferDst | dawn::TextureUsageBit::Sampled;
dawn::Texture texture = device.CreateTexture(&descriptor);
dawn::TextureView textureView = texture.CreateDefaultTextureView();
int width = kRTSize, height = kRTSize;
int widthInBytes = width * sizeof(RGBA8);
widthInBytes = (widthInBytes + 255) & ~255;
@ -246,8 +240,9 @@ TEST_P(BindGroupTests, UBOSamplerAndTexture) {
data[i] = RGBA8(0, 255, 0, 255);
}
dawn::Buffer stagingBuffer = utils::CreateBufferFromData(device, data.data(), sizeInBytes, dawn::BufferUsageBit::TransferSrc);
dawn::BindGroup bindGroup = utils::MakeBindGroup(device, bgl, {
{0, vertUBOBufferView},
{0, buffer, 0, sizeof(transform)},
{1, sampler},
{2, textureView}
});

View File

@ -96,12 +96,7 @@ class BlendStateTest : public DawnTest {
uint32_t bufferSize = static_cast<uint32_t>(4 * N * sizeof(float));
dawn::Buffer buffer = utils::CreateBufferFromData(device, &data, bufferSize, dawn::BufferUsageBit::Uniform);
dawn::BufferView view = buffer.CreateBufferViewBuilder()
.SetExtent(0, bufferSize)
.GetResult();
return utils::MakeBindGroup(device, bindGroupLayout, {{0, view}});
return utils::MakeBindGroup(device, bindGroupLayout, {{0, buffer, 0, bufferSize}});
}
// Test that after drawing a triangle with the base color, and then the given triangle spec, the color is as expected

View File

@ -57,8 +57,6 @@ void ComputeCopyStorageBufferTests::BasicTest(const char* shader) {
}
src.SetSubData(0, sizeof(expected), reinterpret_cast<const uint8_t*>(expected.data()));
EXPECT_BUFFER_U32_RANGE_EQ(expected.data(), src, 0, kNumUints);
auto srcView =
src.CreateBufferViewBuilder().SetExtent(0, kNumUints * sizeof(uint32_t)).GetResult();
// Set up dst storage buffer
dawn::BufferDescriptor dstDesc;
@ -69,13 +67,11 @@ void ComputeCopyStorageBufferTests::BasicTest(const char* shader) {
std::array<uint32_t, kNumUints> zero{};
dst.SetSubData(0, sizeof(zero), reinterpret_cast<const uint8_t*>(zero.data()));
auto dstView =
dst.CreateBufferViewBuilder().SetExtent(0, kNumUints * sizeof(uint32_t)).GetResult();
// Set up bind group and issue dispatch
dawn::BindGroup bindGroup = utils::MakeBindGroup(device, bgl, {
{0, srcView},
{1, dstView},
{0, src, 0, kNumUints * sizeof(uint32_t)},
{1, dst, 0, kNumUints * sizeof(uint32_t)},
});
dawn::CommandBuffer commands;

View File

@ -209,12 +209,8 @@ class DepthStencilStateTest : public DawnTest {
// Upload a buffer for each triangle's depth and color data
dawn::Buffer buffer = utils::CreateBufferFromData(device, &data, sizeof(TriangleData), dawn::BufferUsageBit::Uniform);
dawn::BufferView view = buffer.CreateBufferViewBuilder()
.SetExtent(0, sizeof(TriangleData))
.GetResult();
// Create a bind group for the data
dawn::BindGroup bindGroup = utils::MakeBindGroup(device, bindGroupLayout, {{0, view}});
dawn::BindGroup bindGroup = utils::MakeBindGroup(device, bindGroupLayout, {{0, buffer, 0, sizeof(TriangleData)}});
// Create a pipeline for the triangles with the test spec's depth stencil state
dawn::RenderPipeline pipeline = device.CreateRenderPipelineBuilder()

View File

@ -51,20 +51,15 @@ class PushConstantTest: public DawnTest {
dawn::PipelineLayout pl = utils::MakeBasicPipelineLayout(device, &bgl);
dawn::BufferView views[2] = {
buf1.CreateBufferViewBuilder().SetExtent(0, 4).GetResult(),
buf2.CreateBufferViewBuilder().SetExtent(0, 4).GetResult(),
};
dawn::BindGroup bg;
if (extraBuffer) {
bg = utils::MakeBindGroup(device, bgl, {
{0, views[0]},
{1, views[1]},
{0, buf1, 0, 4},
{1, buf2, 0, 4},
});
} else {
bg = utils::MakeBindGroup(device, bgl, {
{0, views[0]},
{0, buf1, 0, 4},
});
}

View File

@ -504,12 +504,12 @@ TEST_F(WireTests, OptionalObjectValue) {
EXPECT_CALL(api, DeviceCreateBindGroupLayout(apiDevice, _))
.WillOnce(Return(apiBindGroupLayout));
// The `sampler`, `textureView` and `bufferView` members of a binding are optional.
// The `sampler`, `textureView` and `buffer` members of a binding are optional.
dawnBindGroupBinding binding;
binding.binding = 0;
binding.sampler = nullptr;
binding.textureView = nullptr;
binding.bufferView = nullptr;
binding.buffer = nullptr;
dawnBindGroupDescriptor bgDesc;
bgDesc.nextInChain = nullptr;
@ -523,7 +523,7 @@ TEST_F(WireTests, OptionalObjectValue) {
desc->numBindings == 1 &&
desc->bindings[0].binding == 0 &&
desc->bindings[0].sampler == nullptr &&
desc->bindings[0].bufferView == nullptr &&
desc->bindings[0].buffer == nullptr &&
desc->bindings[0].textureView == nullptr;
})))
.WillOnce(Return(nullptr));

View File

@ -135,7 +135,9 @@ TEST_F(BindGroupValidationTest, SamplerBindingType) {
binding.binding = 0;
binding.sampler = nullptr;
binding.textureView = nullptr;
binding.bufferView = nullptr;
binding.buffer = nullptr;
binding.offset = 0;
binding.size = 0;
dawn::BindGroupDescriptor descriptor;
descriptor.nextInChain = nullptr;
@ -155,10 +157,10 @@ TEST_F(BindGroupValidationTest, SamplerBindingType) {
ASSERT_DEVICE_ERROR(device.CreateBindGroup(&descriptor));
binding.textureView = nullptr;
// Setting the buffer view as well is an error
binding.bufferView = mUBO.CreateBufferViewBuilder().SetExtent(0, 256).GetResult();
// Setting the buffer as well is an error
binding.buffer = mUBO;
ASSERT_DEVICE_ERROR(device.CreateBindGroup(&descriptor));
binding.bufferView = nullptr;
binding.buffer = nullptr;
}
// Check that a texture binding must contain exactly a texture view
@ -171,7 +173,9 @@ TEST_F(BindGroupValidationTest, TextureBindingType) {
binding.binding = 0;
binding.sampler = nullptr;
binding.textureView = nullptr;
binding.bufferView = nullptr;
binding.buffer = nullptr;
binding.offset = 0;
binding.size = 0;
dawn::BindGroupDescriptor descriptor;
descriptor.nextInChain = nullptr;
@ -191,13 +195,13 @@ TEST_F(BindGroupValidationTest, TextureBindingType) {
ASSERT_DEVICE_ERROR(device.CreateBindGroup(&descriptor));
binding.textureView = nullptr;
// Setting the buffer view as well is an error
binding.bufferView = mUBO.CreateBufferViewBuilder().SetExtent(0, 256).GetResult();
// Setting the buffer as well is an error
binding.buffer = mUBO;
ASSERT_DEVICE_ERROR(device.CreateBindGroup(&descriptor));
binding.bufferView = nullptr;
binding.buffer = nullptr;
}
// Check that a buffer binding must contain exactly a buffer view
// Check that a buffer binding must contain exactly a buffer
TEST_F(BindGroupValidationTest, BufferBindingType) {
dawn::BindGroupLayout layout = utils::MakeBindGroupLayout(device, {
{0, dawn::ShaderStageBit::Fragment, dawn::BindingType::UniformBuffer}
@ -207,7 +211,9 @@ TEST_F(BindGroupValidationTest, BufferBindingType) {
binding.binding = 0;
binding.sampler = nullptr;
binding.textureView = nullptr;
binding.bufferView = nullptr;
binding.buffer = nullptr;
binding.offset = 0;
binding.size = 0;
dawn::BindGroupDescriptor descriptor;
descriptor.nextInChain = nullptr;
@ -218,8 +224,8 @@ TEST_F(BindGroupValidationTest, BufferBindingType) {
// Not setting anything fails
ASSERT_DEVICE_ERROR(device.CreateBindGroup(&descriptor));
// Control case: setting just the buffer view works
binding.bufferView = mUBO.CreateBufferViewBuilder().SetExtent(0, 256).GetResult();
// Control case: setting just the buffer works
binding.buffer = mUBO;
device.CreateBindGroup(&descriptor);
// Setting the texture view as well is an error
@ -261,14 +267,11 @@ TEST_F(BindGroupValidationTest, BufferUsageUBO) {
{0, dawn::ShaderStageBit::Fragment, dawn::BindingType::UniformBuffer}
});
dawn::BufferView uboView = mUBO.CreateBufferViewBuilder().SetExtent(0, 256).GetResult();
dawn::BufferView ssboView = mSSBO.CreateBufferViewBuilder().SetExtent(0, 256).GetResult();
// Control case: using a buffer with the uniform usage works
utils::MakeBindGroup(device, layout, {{0, uboView}});
utils::MakeBindGroup(device, layout, {{0, mUBO, 0, 256}});
// Using a buffer without the uniform usage fails
ASSERT_DEVICE_ERROR(utils::MakeBindGroup(device, layout, {{0, ssboView}}));
ASSERT_DEVICE_ERROR(utils::MakeBindGroup(device, layout, {{0, mSSBO, 0, 256}}));
}
// Check that a SSBO must have the correct usage
@ -277,57 +280,63 @@ TEST_F(BindGroupValidationTest, BufferUsageSSBO) {
{0, dawn::ShaderStageBit::Fragment, dawn::BindingType::StorageBuffer}
});
dawn::BufferView uboView = mUBO.CreateBufferViewBuilder().SetExtent(0, 256).GetResult();
dawn::BufferView ssboView = mSSBO.CreateBufferViewBuilder().SetExtent(0, 256).GetResult();
// Control case: using a buffer with the storage usage works
utils::MakeBindGroup(device, layout, {{0, ssboView}});
utils::MakeBindGroup(device, layout, {{0, mSSBO, 0, 256}});
// Using a buffer without the storage usage fails
ASSERT_DEVICE_ERROR(utils::MakeBindGroup(device, layout, {{0, uboView}}));
ASSERT_DEVICE_ERROR(utils::MakeBindGroup(device, layout, {{0, mUBO, 0, 256}}));
}
// Tests constraints on the buffer view offset for bind groups.
TEST_F(BindGroupValidationTest, BufferViewOffset) {
// Tests constraints on the buffer offset for bind groups.
TEST_F(BindGroupValidationTest, BufferOffsetAlignment) {
dawn::BindGroupLayout layout = utils::MakeBindGroupLayout(device, {
{0, dawn::ShaderStageBit::Vertex, dawn::BindingType::UniformBuffer},
});
// Check that offset 0 is valid
{
dawn::BufferView bufferView = mUBO.CreateBufferViewBuilder()
.SetExtent(0, 512)
.GetResult();
utils::MakeBindGroup(device, layout, {{0, bufferView}});
}
utils::MakeBindGroup(device, layout, {{0, mUBO, 0, 512}});
// Check that offset 256 (aligned) is valid
{
dawn::BufferView bufferView = mUBO.CreateBufferViewBuilder()
.SetExtent(256, 256)
.GetResult();
utils::MakeBindGroup(device, layout, {{0, bufferView}});
}
utils::MakeBindGroup(device, layout, {{0, mUBO, 256, 256}});
// Check cases where unaligned buffer view offset is invalid
{
dawn::BufferView bufferView = mUBO.CreateBufferViewBuilder()
.SetExtent(1, 256)
.GetResult();
ASSERT_DEVICE_ERROR(utils::MakeBindGroup(device, layout, {{0, bufferView}}));
}
{
dawn::BufferView bufferView = mUBO.CreateBufferViewBuilder()
.SetExtent(128, 256)
.GetResult();
ASSERT_DEVICE_ERROR(utils::MakeBindGroup(device, layout, {{0, bufferView}}));
}
{
dawn::BufferView bufferView = mUBO.CreateBufferViewBuilder()
.SetExtent(255, 256)
.GetResult();
ASSERT_DEVICE_ERROR(utils::MakeBindGroup(device, layout, {{0, bufferView}}));
}
// Check cases where unaligned buffer offset is invalid
ASSERT_DEVICE_ERROR(utils::MakeBindGroup(device, layout, {{0, mUBO, 1, 256}}));
ASSERT_DEVICE_ERROR(utils::MakeBindGroup(device, layout, {{0, mUBO, 128, 256}}));
ASSERT_DEVICE_ERROR(utils::MakeBindGroup(device, layout, {{0, mUBO, 255, 256}}));
}
// Tests constraints to be sure the buffer binding fits in the buffer
TEST_F(BindGroupValidationTest, BufferBindingOOB) {
dawn::BindGroupLayout layout = utils::MakeBindGroupLayout(device, {
{0, dawn::ShaderStageBit::Vertex, dawn::BindingType::UniformBuffer},
});
dawn::BufferDescriptor descriptor;
descriptor.size = 1024;
descriptor.usage = dawn::BufferUsageBit::Uniform;
dawn::Buffer buffer = device.CreateBuffer(&descriptor);
// Success case, touching the start of the buffer works
utils::MakeBindGroup(device, layout, {{0, buffer, 0, 256}});
// Success case, touching the end of the buffer works
utils::MakeBindGroup(device, layout, {{0, buffer, 3*256, 256}});
utils::MakeBindGroup(device, layout, {{0, buffer, 1024, 0}});
// Success case, touching the full buffer works
utils::MakeBindGroup(device, layout, {{0, buffer, 0, 1024}});
// Error case, offset is OOB
ASSERT_DEVICE_ERROR(utils::MakeBindGroup(device, layout, {{0, buffer, 256*5, 0}}));
// Error case, size is OOB
ASSERT_DEVICE_ERROR(utils::MakeBindGroup(device, layout, {{0, buffer, 0, 256*5}}));
// Error case, offset+size is OOB
ASSERT_DEVICE_ERROR(utils::MakeBindGroup(device, layout, {{0, buffer, 1024, 1}}));
// Error case, offset+size overflows to be 0
ASSERT_DEVICE_ERROR(utils::MakeBindGroup(device, layout, {{0, buffer, 256, uint32_t(0) - uint32_t(256)}}));
}
class BindGroupLayoutValidationTest : public ValidationTest {

View File

@ -74,8 +74,7 @@ TEST_F(CommandBufferValidationTest, BufferWithReadAndWriteUsage) {
dawn::BindGroupLayout bgl = utils::MakeBindGroupLayout(device, {{
0, dawn::ShaderStageBit::Vertex, dawn::BindingType::StorageBuffer
}});
dawn::BufferView view = buffer.CreateBufferViewBuilder().SetExtent(0, 4).GetResult();
dawn::BindGroup bg = utils::MakeBindGroup(device, bgl, {{0, view}});
dawn::BindGroup bg = utils::MakeBindGroup(device, bgl, {{0, buffer, 0, 4}});
// Use the buffer as both index and storage in the same pass
dawn::CommandBufferBuilder builder = AssertWillBeError(device.CreateCommandBufferBuilder());

View File

@ -236,8 +236,10 @@ namespace utils {
}
BindingInitializationHelper::BindingInitializationHelper(uint32_t binding,
const dawn::BufferView& bufferView)
: binding(binding), bufferView(bufferView) {
const dawn::Buffer& buffer,
uint32_t offset,
uint32_t size)
: binding(binding), buffer(buffer), offset(offset), size(size) {
}
dawn::BindGroupBinding BindingInitializationHelper::GetAsBinding() const {
@ -246,7 +248,9 @@ namespace utils {
result.binding = binding;
result.sampler = sampler;
result.textureView = textureView;
result.bufferView = bufferView;
result.buffer = buffer;
result.offset = offset;
result.size = size;
return result;
}

View File

@ -69,7 +69,7 @@ namespace utils {
//
// utils::MakeBindGroup(device, layout, {
// {0, mySampler},
// {1, myBufferView},
// {1, myBuffer, offset, size},
// {3, myTexture}
// });
@ -78,14 +78,19 @@ namespace utils {
struct BindingInitializationHelper {
BindingInitializationHelper(uint32_t binding, const dawn::Sampler& sampler);
BindingInitializationHelper(uint32_t binding, const dawn::TextureView& textureView);
BindingInitializationHelper(uint32_t binding, const dawn::BufferView& bufferView);
BindingInitializationHelper(uint32_t binding,
const dawn::Buffer& buffer,
uint32_t offset,
uint32_t size);
dawn::BindGroupBinding GetAsBinding() const;
uint32_t binding;
dawn::Sampler sampler;
dawn::TextureView textureView;
dawn::BufferView bufferView;
dawn::Buffer buffer;
uint32_t offset = 0;
uint32_t size = 0;
};
dawn::BindGroup MakeBindGroup(