Descriptorize BindGroups.
This commit adds utils::MakeBindGroup to make code craeting bind groups nicer to read. Additional tests are added that give 100% coverage of ValidateBindGroupDescriptor. BUG=dawn:3 Change-Id: I56e1da8c2952306ad233845b0ec3ec32aef793d9 Reviewed-on: https://dawn-review.googlesource.com/c/2802 Reviewed-by: Jiawei Shao <jiawei.shao@intel.com> Commit-Queue: Corentin Wallez <cwallez@chromium.org>
This commit is contained in:
parent
006f218392
commit
6f9d21e805
60
dawn.json
60
dawn.json
|
@ -25,46 +25,23 @@
|
||||||
"bind group": {
|
"bind group": {
|
||||||
"category": "object"
|
"category": "object"
|
||||||
},
|
},
|
||||||
"bind group builder": {
|
"bind group binding": {
|
||||||
"category": "object",
|
"category": "structure",
|
||||||
"methods": [
|
"extensible": false,
|
||||||
{
|
"members": [
|
||||||
"name": "get result",
|
{"name": "binding", "type": "uint32_t"},
|
||||||
"returns": "bind group"
|
{"name": "buffer view", "type": "buffer view", "optional": true},
|
||||||
},
|
{"name": "sampler", "type": "sampler", "optional": true},
|
||||||
{
|
{"name": "texture view", "type": "texture view", "optional": true}
|
||||||
"name": "set layout",
|
|
||||||
"args": [
|
|
||||||
{"name": "layout", "type": "bind group layout"}
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
"bind group descriptor": {
|
||||||
"name": "set buffer views",
|
"category": "structure",
|
||||||
"args": [
|
"extensible": true,
|
||||||
{"name": "start", "type": "uint32_t"},
|
"members": [
|
||||||
{"name": "count", "type": "uint32_t"},
|
{"name": "layout", "type": "bind group layout"},
|
||||||
{"name": "buffer views", "type": "buffer view", "annotation": "const*", "length": "count"}
|
{"name": "num bindings", "type": "uint32_t"},
|
||||||
]
|
{"name": "bindings", "type": "bind group binding", "annotation": "const*", "length": "num bindings"}
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "set samplers",
|
|
||||||
"args": [
|
|
||||||
{"name": "start", "type": "uint32_t"},
|
|
||||||
{"name": "count", "type": "uint32_t"},
|
|
||||||
{"name": "samplers", "type": "sampler", "annotation": "const*", "length": "count"}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "set texture views",
|
|
||||||
"args": [
|
|
||||||
{"name": "start", "type": "uint32_t"},
|
|
||||||
{"name": "count", "type": "uint32_t"},
|
|
||||||
{"name": "texture views", "type": "texture view", "annotation": "const*", "length": "count"}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"TODO": [
|
|
||||||
"When resource are added, add methods for setting the content of the bind group"
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"bind group layout": {
|
"bind group layout": {
|
||||||
|
@ -448,8 +425,11 @@
|
||||||
"category": "object",
|
"category": "object",
|
||||||
"methods": [
|
"methods": [
|
||||||
{
|
{
|
||||||
"name": "create bind group builder",
|
"name": "create bind group",
|
||||||
"returns": "bind group builder"
|
"returns": "bind group",
|
||||||
|
"args": [
|
||||||
|
{"name": "descriptor", "type": "bind group descriptor", "annotation": "const*"}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "create bind group layout",
|
"name": "create bind group layout",
|
||||||
|
|
|
@ -249,12 +249,11 @@ void initSim() {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint32_t i = 0; i < 2; ++i) {
|
for (uint32_t i = 0; i < 2; ++i) {
|
||||||
updateBGs[i] = device.CreateBindGroupBuilder()
|
updateBGs[i] = utils::MakeBindGroup(device, bgl, {
|
||||||
.SetLayout(bgl)
|
{0, updateParamsView},
|
||||||
.SetBufferViews(0, 1, &updateParamsView)
|
{1, views[i]},
|
||||||
.SetBufferViews(1, 1, &views[i])
|
{2, views[(i + 1) % 2]}
|
||||||
.SetBufferViews(2, 1, &views[(i + 1) % 2])
|
});
|
||||||
.GetResult();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -137,11 +137,10 @@ void init() {
|
||||||
|
|
||||||
dawn::TextureView view = texture.CreateDefaultTextureView();
|
dawn::TextureView view = texture.CreateDefaultTextureView();
|
||||||
|
|
||||||
bindGroup = device.CreateBindGroupBuilder()
|
bindGroup = utils::MakeBindGroup(device, bgl, {
|
||||||
.SetLayout(bgl)
|
{0, sampler},
|
||||||
.SetSamplers(0, 1, &sampler)
|
{1, view}
|
||||||
.SetTextureViews(1, 1, &view)
|
});
|
||||||
.GetResult();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct {uint32_t a; float b;} s;
|
struct {uint32_t a; float b;} s;
|
||||||
|
|
|
@ -193,17 +193,15 @@ void init() {
|
||||||
.GetResult(),
|
.GetResult(),
|
||||||
};
|
};
|
||||||
|
|
||||||
bindGroup[0] = device.CreateBindGroupBuilder()
|
bindGroup[0] = utils::MakeBindGroup(device, bgl, {
|
||||||
.SetLayout(bgl)
|
{0, cameraBufferView},
|
||||||
.SetBufferViews(0, 1, &cameraBufferView)
|
{1, transformBufferView[0]}
|
||||||
.SetBufferViews(1, 1, &transformBufferView[0])
|
});
|
||||||
.GetResult();
|
|
||||||
|
|
||||||
bindGroup[1] = device.CreateBindGroupBuilder()
|
bindGroup[1] = utils::MakeBindGroup(device, bgl, {
|
||||||
.SetLayout(bgl)
|
{0, cameraBufferView},
|
||||||
.SetBufferViews(0, 1, &cameraBufferView)
|
{1, transformBufferView[1]}
|
||||||
.SetBufferViews(1, 1, &transformBufferView[1])
|
});
|
||||||
.GetResult();
|
|
||||||
|
|
||||||
depthStencilView = CreateDefaultDepthStencilView(device);
|
depthStencilView = CreateDefaultDepthStencilView(device);
|
||||||
|
|
||||||
|
|
|
@ -298,19 +298,22 @@ namespace {
|
||||||
.SetDepthStencilState(depthStencilState)
|
.SetDepthStencilState(depthStencilState)
|
||||||
.GetResult();
|
.GetResult();
|
||||||
|
|
||||||
auto bindGroupBuilder = device.CreateBindGroupBuilder();
|
dawn::BindGroup bindGroup;
|
||||||
bindGroupBuilder.SetLayout(bindGroupLayout);
|
|
||||||
|
|
||||||
if (hasTexture) {
|
if (hasTexture) {
|
||||||
const auto& textureView = textures[iTextureID];
|
const auto& textureView = textures[iTextureID];
|
||||||
const auto& iSamplerID = scene.textures[iTextureID].sampler;
|
const auto& iSamplerID = scene.textures[iTextureID].sampler;
|
||||||
bindGroupBuilder.SetSamplers(0, 1, &samplers[iSamplerID]);
|
bindGroup = utils::MakeBindGroup(device, bindGroupLayout, {
|
||||||
bindGroupBuilder.SetTextureViews(1, 1, &textureView);
|
{0, samplers[iSamplerID]},
|
||||||
|
{1, textureView}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
bindGroup = utils::MakeBindGroup(device, bindGroupLayout, {});
|
||||||
}
|
}
|
||||||
|
|
||||||
MaterialInfo material = {
|
MaterialInfo material = {
|
||||||
pipeline.Get(),
|
pipeline,
|
||||||
bindGroupBuilder.GetResult(),
|
bindGroup,
|
||||||
std::map<uint32_t, std::string>(),
|
std::map<uint32_t, std::string>(),
|
||||||
};
|
};
|
||||||
materials[key] = std::move(material);
|
materials[key] = std::move(material);
|
||||||
|
|
|
@ -19,16 +19,147 @@
|
||||||
#include "dawn_native/BindGroupLayout.h"
|
#include "dawn_native/BindGroupLayout.h"
|
||||||
#include "dawn_native/Buffer.h"
|
#include "dawn_native/Buffer.h"
|
||||||
#include "dawn_native/Device.h"
|
#include "dawn_native/Device.h"
|
||||||
|
#include "dawn_native/Sampler.h"
|
||||||
#include "dawn_native/Texture.h"
|
#include "dawn_native/Texture.h"
|
||||||
|
|
||||||
namespace dawn_native {
|
namespace dawn_native {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
// Helper functions to perform binding-type specific validation
|
||||||
|
|
||||||
|
MaybeError ValidateBufferBinding(const BindGroupBinding& binding,
|
||||||
|
dawn::BufferUsageBit requiredUsage) {
|
||||||
|
if (binding.bufferView == 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");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(binding.bufferView->GetBuffer()->GetUsage() & requiredUsage)) {
|
||||||
|
return DAWN_VALIDATION_ERROR("buffer binding usage mismatch");
|
||||||
|
}
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
MaybeError ValidateTextureBinding(const BindGroupBinding& binding,
|
||||||
|
dawn::TextureUsageBit requiredUsage) {
|
||||||
|
if (binding.textureView == nullptr || binding.sampler != nullptr ||
|
||||||
|
binding.bufferView != nullptr) {
|
||||||
|
return DAWN_VALIDATION_ERROR("expected texture binding");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(binding.textureView->GetTexture()->GetUsage() & requiredUsage)) {
|
||||||
|
return DAWN_VALIDATION_ERROR("texture binding usage mismatch");
|
||||||
|
}
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
MaybeError ValidateSamplerBinding(const BindGroupBinding& binding) {
|
||||||
|
if (binding.sampler == nullptr || binding.textureView != nullptr ||
|
||||||
|
binding.bufferView != nullptr) {
|
||||||
|
return DAWN_VALIDATION_ERROR("expected sampler binding");
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
} // anonymous namespace
|
||||||
|
|
||||||
|
MaybeError ValidateBindGroupDescriptor(DeviceBase*, const BindGroupDescriptor* descriptor) {
|
||||||
|
if (descriptor->nextInChain != nullptr) {
|
||||||
|
return DAWN_VALIDATION_ERROR("nextInChain must be nullptr");
|
||||||
|
}
|
||||||
|
|
||||||
|
const BindGroupLayoutBase::LayoutBindingInfo& layoutInfo =
|
||||||
|
descriptor->layout->GetBindingInfo();
|
||||||
|
|
||||||
|
if (descriptor->numBindings != layoutInfo.mask.count()) {
|
||||||
|
return DAWN_VALIDATION_ERROR("numBindings mismatch");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::bitset<kMaxBindingsPerGroup> bindingsSet;
|
||||||
|
for (uint32_t i = 0; i < descriptor->numBindings; ++i) {
|
||||||
|
const BindGroupBinding& binding = descriptor->bindings[i];
|
||||||
|
uint32_t bindingIndex = binding.binding;
|
||||||
|
|
||||||
|
// Check that we can set this binding.
|
||||||
|
if (bindingIndex >= kMaxBindingsPerGroup) {
|
||||||
|
return DAWN_VALIDATION_ERROR("binding index too high");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!layoutInfo.mask[bindingIndex]) {
|
||||||
|
return DAWN_VALIDATION_ERROR("setting non-existent binding");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bindingsSet[bindingIndex]) {
|
||||||
|
return DAWN_VALIDATION_ERROR("binding set twice");
|
||||||
|
}
|
||||||
|
bindingsSet.set(bindingIndex);
|
||||||
|
|
||||||
|
// Perform binding-type specific validation.
|
||||||
|
switch (layoutInfo.types[bindingIndex]) {
|
||||||
|
case dawn::BindingType::UniformBuffer:
|
||||||
|
DAWN_TRY(ValidateBufferBinding(binding, dawn::BufferUsageBit::Uniform));
|
||||||
|
break;
|
||||||
|
case dawn::BindingType::StorageBuffer:
|
||||||
|
DAWN_TRY(ValidateBufferBinding(binding, dawn::BufferUsageBit::Storage));
|
||||||
|
break;
|
||||||
|
case dawn::BindingType::SampledTexture:
|
||||||
|
DAWN_TRY(ValidateTextureBinding(binding, dawn::TextureUsageBit::Sampled));
|
||||||
|
break;
|
||||||
|
case dawn::BindingType::Sampler:
|
||||||
|
DAWN_TRY(ValidateSamplerBinding(binding));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// This should always be true because
|
||||||
|
// - numBindings has to match between the bind group and its layout.
|
||||||
|
// - Each binding must be set at most once
|
||||||
|
//
|
||||||
|
// We don't validate the equality because it wouldn't be possible to cover it with a test.
|
||||||
|
ASSERT(bindingsSet == layoutInfo.mask);
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
// BindGroup
|
// BindGroup
|
||||||
|
|
||||||
BindGroupBase::BindGroupBase(BindGroupBuilder* builder)
|
BindGroupBase::BindGroupBase(DeviceBase* device, const BindGroupDescriptor* descriptor)
|
||||||
: ObjectBase(builder->GetDevice()),
|
: ObjectBase(device), mLayout(descriptor->layout) {
|
||||||
mLayout(std::move(builder->mLayout)),
|
for (uint32_t i = 0; i < descriptor->numBindings; ++i) {
|
||||||
mBindings(std::move(builder->mBindings)) {
|
const BindGroupBinding& binding = descriptor->bindings[i];
|
||||||
|
|
||||||
|
uint32_t bindingIndex = binding.binding;
|
||||||
|
ASSERT(bindingIndex < kMaxBindingsPerGroup);
|
||||||
|
|
||||||
|
// 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) {
|
||||||
|
ASSERT(mBindings[bindingIndex].Get() == nullptr);
|
||||||
|
mBindings[bindingIndex] = binding.bufferView;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (binding.textureView != nullptr) {
|
||||||
|
ASSERT(mBindings[bindingIndex].Get() == nullptr);
|
||||||
|
mBindings[bindingIndex] = binding.textureView;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (binding.sampler != nullptr) {
|
||||||
|
ASSERT(mBindings[bindingIndex].Get() == nullptr);
|
||||||
|
mBindings[bindingIndex] = binding.sampler;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const BindGroupLayoutBase* BindGroupBase::GetLayout() const {
|
const BindGroupLayoutBase* BindGroupBase::GetLayout() const {
|
||||||
|
@ -56,154 +187,4 @@ namespace dawn_native {
|
||||||
ASSERT(mLayout->GetBindingInfo().types[binding] == dawn::BindingType::SampledTexture);
|
ASSERT(mLayout->GetBindingInfo().types[binding] == dawn::BindingType::SampledTexture);
|
||||||
return reinterpret_cast<TextureViewBase*>(mBindings[binding].Get());
|
return reinterpret_cast<TextureViewBase*>(mBindings[binding].Get());
|
||||||
}
|
}
|
||||||
|
|
||||||
// BindGroupBuilder
|
|
||||||
|
|
||||||
enum BindGroupSetProperties {
|
|
||||||
BINDGROUP_PROPERTY_LAYOUT = 0x1,
|
|
||||||
};
|
|
||||||
|
|
||||||
BindGroupBuilder::BindGroupBuilder(DeviceBase* device) : Builder(device) {
|
|
||||||
}
|
|
||||||
|
|
||||||
BindGroupBase* BindGroupBuilder::GetResultImpl() {
|
|
||||||
constexpr int allProperties = BINDGROUP_PROPERTY_LAYOUT;
|
|
||||||
if ((mPropertiesSet & allProperties) != allProperties) {
|
|
||||||
HandleError("Bindgroup missing properties");
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mSetMask != mLayout->GetBindingInfo().mask) {
|
|
||||||
HandleError("Bindgroup missing bindings");
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
return GetDevice()->CreateBindGroup(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
void BindGroupBuilder::SetLayout(BindGroupLayoutBase* layout) {
|
|
||||||
if ((mPropertiesSet & BINDGROUP_PROPERTY_LAYOUT) != 0) {
|
|
||||||
HandleError("Bindgroup layout property set multiple times");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
mLayout = layout;
|
|
||||||
mPropertiesSet |= BINDGROUP_PROPERTY_LAYOUT;
|
|
||||||
}
|
|
||||||
|
|
||||||
void BindGroupBuilder::SetBufferViews(uint32_t start,
|
|
||||||
uint32_t count,
|
|
||||||
BufferViewBase* const* bufferViews) {
|
|
||||||
if (!SetBindingsValidationBase(start, count)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto& layoutInfo = mLayout->GetBindingInfo();
|
|
||||||
for (size_t i = start, j = 0; i < start + count; ++i, ++j) {
|
|
||||||
dawn::BufferUsageBit requiredBit = dawn::BufferUsageBit::None;
|
|
||||||
switch (layoutInfo.types[i]) {
|
|
||||||
case dawn::BindingType::UniformBuffer:
|
|
||||||
requiredBit = dawn::BufferUsageBit::Uniform;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case dawn::BindingType::StorageBuffer:
|
|
||||||
requiredBit = dawn::BufferUsageBit::Storage;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case dawn::BindingType::Sampler:
|
|
||||||
case dawn::BindingType::SampledTexture:
|
|
||||||
HandleError("Setting buffer for a wrong binding type");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(bufferViews[j]->GetBuffer()->GetUsage() & requiredBit)) {
|
|
||||||
HandleError("Buffer needs to allow the correct usage bit");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!IsAligned(bufferViews[j]->GetOffset(), 256)) {
|
|
||||||
HandleError("Buffer view offset for bind group needs to be 256-byte aligned");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SetBindingsBase(start, count, reinterpret_cast<ObjectBase* const*>(bufferViews));
|
|
||||||
}
|
|
||||||
|
|
||||||
void BindGroupBuilder::SetSamplers(uint32_t start,
|
|
||||||
uint32_t count,
|
|
||||||
SamplerBase* const* samplers) {
|
|
||||||
if (!SetBindingsValidationBase(start, count)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto& layoutInfo = mLayout->GetBindingInfo();
|
|
||||||
for (size_t i = start, j = 0; i < start + count; ++i, ++j) {
|
|
||||||
if (layoutInfo.types[i] != dawn::BindingType::Sampler) {
|
|
||||||
HandleError("Setting binding for a wrong layout binding type");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SetBindingsBase(start, count, reinterpret_cast<ObjectBase* const*>(samplers));
|
|
||||||
}
|
|
||||||
|
|
||||||
void BindGroupBuilder::SetTextureViews(uint32_t start,
|
|
||||||
uint32_t count,
|
|
||||||
TextureViewBase* const* textureViews) {
|
|
||||||
if (!SetBindingsValidationBase(start, count)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto& layoutInfo = mLayout->GetBindingInfo();
|
|
||||||
for (size_t i = start, j = 0; i < start + count; ++i, ++j) {
|
|
||||||
if (layoutInfo.types[i] != dawn::BindingType::SampledTexture) {
|
|
||||||
HandleError("Setting binding for a wrong layout binding type");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(textureViews[j]->GetTexture()->GetUsage() & dawn::TextureUsageBit::Sampled)) {
|
|
||||||
HandleError("Texture needs to allow the sampled usage bit");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SetBindingsBase(start, count, reinterpret_cast<ObjectBase* const*>(textureViews));
|
|
||||||
}
|
|
||||||
|
|
||||||
void BindGroupBuilder::SetBindingsBase(uint32_t start,
|
|
||||||
uint32_t count,
|
|
||||||
ObjectBase* const* objects) {
|
|
||||||
for (size_t i = start, j = 0; i < start + count; ++i, ++j) {
|
|
||||||
mSetMask.set(i);
|
|
||||||
mBindings[i] = objects[j];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BindGroupBuilder::SetBindingsValidationBase(uint32_t start, uint32_t count) {
|
|
||||||
if (start + count > kMaxBindingsPerGroup) {
|
|
||||||
HandleError("Setting bindings type over maximum number of bindings");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((mPropertiesSet & BINDGROUP_PROPERTY_LAYOUT) == 0) {
|
|
||||||
HandleError("Bindgroup layout must be set before views");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto& layoutInfo = mLayout->GetBindingInfo();
|
|
||||||
for (size_t i = start, j = 0; i < start + count; ++i, ++j) {
|
|
||||||
if (mSetMask[i]) {
|
|
||||||
HandleError("Setting already set binding");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!layoutInfo.mask[i]) {
|
|
||||||
HandleError("Setting binding that isn't present in the layout");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
} // namespace dawn_native
|
} // namespace dawn_native
|
||||||
|
|
|
@ -17,20 +17,24 @@
|
||||||
|
|
||||||
#include "common/Constants.h"
|
#include "common/Constants.h"
|
||||||
#include "dawn_native/BindGroupLayout.h"
|
#include "dawn_native/BindGroupLayout.h"
|
||||||
#include "dawn_native/Builder.h"
|
#include "dawn_native/Error.h"
|
||||||
#include "dawn_native/Forward.h"
|
#include "dawn_native/Forward.h"
|
||||||
#include "dawn_native/ObjectBase.h"
|
#include "dawn_native/ObjectBase.h"
|
||||||
|
|
||||||
#include "dawn_native/dawn_platform.h"
|
#include "dawn_native/dawn_platform.h"
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <bitset>
|
|
||||||
|
|
||||||
namespace dawn_native {
|
namespace dawn_native {
|
||||||
|
|
||||||
|
class DeviceBase;
|
||||||
|
|
||||||
|
MaybeError ValidateBindGroupDescriptor(DeviceBase* device,
|
||||||
|
const BindGroupDescriptor* descriptor);
|
||||||
|
|
||||||
class BindGroupBase : public ObjectBase {
|
class BindGroupBase : public ObjectBase {
|
||||||
public:
|
public:
|
||||||
BindGroupBase(BindGroupBuilder* builder);
|
BindGroupBase(DeviceBase* device, const BindGroupDescriptor* descriptor);
|
||||||
|
|
||||||
const BindGroupLayoutBase* GetLayout() const;
|
const BindGroupLayoutBase* GetLayout() const;
|
||||||
BufferViewBase* GetBindingAsBufferView(size_t binding);
|
BufferViewBase* GetBindingAsBufferView(size_t binding);
|
||||||
|
@ -42,31 +46,6 @@ namespace dawn_native {
|
||||||
std::array<Ref<ObjectBase>, kMaxBindingsPerGroup> mBindings;
|
std::array<Ref<ObjectBase>, kMaxBindingsPerGroup> mBindings;
|
||||||
};
|
};
|
||||||
|
|
||||||
class BindGroupBuilder : public Builder<BindGroupBase> {
|
|
||||||
public:
|
|
||||||
BindGroupBuilder(DeviceBase* device);
|
|
||||||
|
|
||||||
// Dawn API
|
|
||||||
void SetLayout(BindGroupLayoutBase* layout);
|
|
||||||
|
|
||||||
void SetBufferViews(uint32_t start, uint32_t count, BufferViewBase* const* bufferViews);
|
|
||||||
void SetSamplers(uint32_t start, uint32_t count, SamplerBase* const* samplers);
|
|
||||||
void SetTextureViews(uint32_t start, uint32_t count, TextureViewBase* const* textureViews);
|
|
||||||
|
|
||||||
private:
|
|
||||||
friend class BindGroupBase;
|
|
||||||
|
|
||||||
BindGroupBase* GetResultImpl() override;
|
|
||||||
void SetBindingsBase(uint32_t start, uint32_t count, ObjectBase* const* objects);
|
|
||||||
bool SetBindingsValidationBase(uint32_t start, uint32_t count);
|
|
||||||
|
|
||||||
std::bitset<kMaxBindingsPerGroup> mSetMask;
|
|
||||||
int mPropertiesSet = 0;
|
|
||||||
|
|
||||||
Ref<BindGroupLayoutBase> mLayout;
|
|
||||||
std::array<Ref<ObjectBase>, kMaxBindingsPerGroup> mBindings;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace dawn_native
|
} // namespace dawn_native
|
||||||
|
|
||||||
#endif // DAWNNATIVE_BINDGROUP_H_
|
#endif // DAWNNATIVE_BINDGROUP_H_
|
||||||
|
|
|
@ -101,8 +101,14 @@ namespace dawn_native {
|
||||||
|
|
||||||
// Object creation API methods
|
// Object creation API methods
|
||||||
|
|
||||||
BindGroupBuilder* DeviceBase::CreateBindGroupBuilder() {
|
BindGroupBase* DeviceBase::CreateBindGroup(const BindGroupDescriptor* descriptor) {
|
||||||
return new BindGroupBuilder(this);
|
BindGroupBase* result = nullptr;
|
||||||
|
|
||||||
|
if (ConsumedError(CreateBindGroupInternal(&result, descriptor))) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
BindGroupLayoutBase* DeviceBase::CreateBindGroupLayout(
|
BindGroupLayoutBase* DeviceBase::CreateBindGroupLayout(
|
||||||
const BindGroupLayoutDescriptor* descriptor) {
|
const BindGroupLayoutDescriptor* descriptor) {
|
||||||
|
@ -240,6 +246,13 @@ namespace dawn_native {
|
||||||
|
|
||||||
// Implementation details of object creation
|
// Implementation details of object creation
|
||||||
|
|
||||||
|
MaybeError DeviceBase::CreateBindGroupInternal(BindGroupBase** result,
|
||||||
|
const BindGroupDescriptor* descriptor) {
|
||||||
|
DAWN_TRY(ValidateBindGroupDescriptor(this, descriptor));
|
||||||
|
DAWN_TRY_ASSIGN(*result, CreateBindGroupImpl(descriptor));
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
MaybeError DeviceBase::CreateBindGroupLayoutInternal(
|
MaybeError DeviceBase::CreateBindGroupLayoutInternal(
|
||||||
BindGroupLayoutBase** result,
|
BindGroupLayoutBase** result,
|
||||||
const BindGroupLayoutDescriptor* descriptor) {
|
const BindGroupLayoutDescriptor* descriptor) {
|
||||||
|
|
|
@ -51,7 +51,6 @@ namespace dawn_native {
|
||||||
|
|
||||||
FenceSignalTracker* GetFenceSignalTracker() const;
|
FenceSignalTracker* GetFenceSignalTracker() const;
|
||||||
|
|
||||||
virtual BindGroupBase* CreateBindGroup(BindGroupBuilder* builder) = 0;
|
|
||||||
virtual BlendStateBase* CreateBlendState(BlendStateBuilder* builder) = 0;
|
virtual BlendStateBase* CreateBlendState(BlendStateBuilder* builder) = 0;
|
||||||
virtual BufferViewBase* CreateBufferView(BufferViewBuilder* builder) = 0;
|
virtual BufferViewBase* CreateBufferView(BufferViewBuilder* builder) = 0;
|
||||||
virtual CommandBufferBase* CreateCommandBuffer(CommandBufferBuilder* builder) = 0;
|
virtual CommandBufferBase* CreateCommandBuffer(CommandBufferBuilder* builder) = 0;
|
||||||
|
@ -86,7 +85,7 @@ namespace dawn_native {
|
||||||
void UncacheBindGroupLayout(BindGroupLayoutBase* obj);
|
void UncacheBindGroupLayout(BindGroupLayoutBase* obj);
|
||||||
|
|
||||||
// Dawn API
|
// Dawn API
|
||||||
BindGroupBuilder* CreateBindGroupBuilder();
|
BindGroupBase* CreateBindGroup(const BindGroupDescriptor* descriptor);
|
||||||
BindGroupLayoutBase* CreateBindGroupLayout(const BindGroupLayoutDescriptor* descriptor);
|
BindGroupLayoutBase* CreateBindGroupLayout(const BindGroupLayoutDescriptor* descriptor);
|
||||||
BlendStateBuilder* CreateBlendStateBuilder();
|
BlendStateBuilder* CreateBlendStateBuilder();
|
||||||
BufferBase* CreateBuffer(const BufferDescriptor* descriptor);
|
BufferBase* CreateBuffer(const BufferDescriptor* descriptor);
|
||||||
|
@ -119,6 +118,8 @@ namespace dawn_native {
|
||||||
virtual const PCIInfo& GetPCIInfo() const = 0;
|
virtual const PCIInfo& GetPCIInfo() const = 0;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
virtual ResultOrError<BindGroupBase*> CreateBindGroupImpl(
|
||||||
|
const BindGroupDescriptor* descriptor) = 0;
|
||||||
virtual ResultOrError<BindGroupLayoutBase*> CreateBindGroupLayoutImpl(
|
virtual ResultOrError<BindGroupLayoutBase*> CreateBindGroupLayoutImpl(
|
||||||
const BindGroupLayoutDescriptor* descriptor) = 0;
|
const BindGroupLayoutDescriptor* descriptor) = 0;
|
||||||
virtual ResultOrError<BufferBase*> CreateBufferImpl(const BufferDescriptor* descriptor) = 0;
|
virtual ResultOrError<BufferBase*> CreateBufferImpl(const BufferDescriptor* descriptor) = 0;
|
||||||
|
@ -137,6 +138,8 @@ namespace dawn_native {
|
||||||
TextureBase* texture,
|
TextureBase* texture,
|
||||||
const TextureViewDescriptor* descriptor) = 0;
|
const TextureViewDescriptor* descriptor) = 0;
|
||||||
|
|
||||||
|
MaybeError CreateBindGroupInternal(BindGroupBase** result,
|
||||||
|
const BindGroupDescriptor* descriptor);
|
||||||
MaybeError CreateBindGroupLayoutInternal(BindGroupLayoutBase** result,
|
MaybeError CreateBindGroupLayoutInternal(BindGroupLayoutBase** result,
|
||||||
const BindGroupLayoutDescriptor* descriptor);
|
const BindGroupLayoutDescriptor* descriptor);
|
||||||
MaybeError CreateBufferInternal(BufferBase** result, const BufferDescriptor* descriptor);
|
MaybeError CreateBufferInternal(BufferBase** result, const BufferDescriptor* descriptor);
|
||||||
|
|
|
@ -23,7 +23,8 @@
|
||||||
|
|
||||||
namespace dawn_native { namespace d3d12 {
|
namespace dawn_native { namespace d3d12 {
|
||||||
|
|
||||||
BindGroup::BindGroup(BindGroupBuilder* builder) : BindGroupBase(builder) {
|
BindGroup::BindGroup(Device* device, const BindGroupDescriptor* descriptor)
|
||||||
|
: BindGroupBase(device, descriptor) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void BindGroup::RecordDescriptors(const DescriptorHeapHandle& cbvUavSrvHeapStart,
|
void BindGroup::RecordDescriptors(const DescriptorHeapHandle& cbvUavSrvHeapStart,
|
||||||
|
|
|
@ -27,7 +27,7 @@ namespace dawn_native { namespace d3d12 {
|
||||||
|
|
||||||
class BindGroup : public BindGroupBase {
|
class BindGroup : public BindGroupBase {
|
||||||
public:
|
public:
|
||||||
BindGroup(BindGroupBuilder* builder);
|
BindGroup(Device* device, const BindGroupDescriptor* descriptor);
|
||||||
|
|
||||||
void RecordDescriptors(const DescriptorHeapHandle& cbvSrvUavHeapStart,
|
void RecordDescriptors(const DescriptorHeapHandle& cbvSrvUavHeapStart,
|
||||||
uint32_t* cbvUavSrvHeapOffset,
|
uint32_t* cbvUavSrvHeapOffset,
|
||||||
|
|
|
@ -286,8 +286,9 @@ namespace dawn_native { namespace d3d12 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BindGroupBase* Device::CreateBindGroup(BindGroupBuilder* builder) {
|
ResultOrError<BindGroupBase*> Device::CreateBindGroupImpl(
|
||||||
return new BindGroup(builder);
|
const BindGroupDescriptor* descriptor) {
|
||||||
|
return new BindGroup(this, descriptor);
|
||||||
}
|
}
|
||||||
ResultOrError<BindGroupLayoutBase*> Device::CreateBindGroupLayoutImpl(
|
ResultOrError<BindGroupLayoutBase*> Device::CreateBindGroupLayoutImpl(
|
||||||
const BindGroupLayoutDescriptor* descriptor) {
|
const BindGroupLayoutDescriptor* descriptor) {
|
||||||
|
|
|
@ -41,7 +41,6 @@ namespace dawn_native { namespace d3d12 {
|
||||||
Device();
|
Device();
|
||||||
~Device();
|
~Device();
|
||||||
|
|
||||||
BindGroupBase* CreateBindGroup(BindGroupBuilder* builder) override;
|
|
||||||
BlendStateBase* CreateBlendState(BlendStateBuilder* builder) override;
|
BlendStateBase* CreateBlendState(BlendStateBuilder* builder) override;
|
||||||
BufferViewBase* CreateBufferView(BufferViewBuilder* builder) override;
|
BufferViewBase* CreateBufferView(BufferViewBuilder* builder) override;
|
||||||
CommandBufferBase* CreateCommandBuffer(CommandBufferBuilder* builder) override;
|
CommandBufferBase* CreateCommandBuffer(CommandBufferBuilder* builder) override;
|
||||||
|
@ -80,6 +79,8 @@ namespace dawn_native { namespace d3d12 {
|
||||||
void ExecuteCommandLists(std::initializer_list<ID3D12CommandList*> commandLists);
|
void ExecuteCommandLists(std::initializer_list<ID3D12CommandList*> commandLists);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
ResultOrError<BindGroupBase*> CreateBindGroupImpl(
|
||||||
|
const BindGroupDescriptor* descriptor) override;
|
||||||
ResultOrError<BindGroupLayoutBase*> CreateBindGroupLayoutImpl(
|
ResultOrError<BindGroupLayoutBase*> CreateBindGroupLayoutImpl(
|
||||||
const BindGroupLayoutDescriptor* descriptor) override;
|
const BindGroupLayoutDescriptor* descriptor) override;
|
||||||
ResultOrError<BufferBase*> CreateBufferImpl(const BufferDescriptor* descriptor) override;
|
ResultOrError<BufferBase*> CreateBufferImpl(const BufferDescriptor* descriptor) override;
|
||||||
|
|
|
@ -37,7 +37,6 @@ namespace dawn_native { namespace metal {
|
||||||
Device(id<MTLDevice> mtlDevice);
|
Device(id<MTLDevice> mtlDevice);
|
||||||
~Device();
|
~Device();
|
||||||
|
|
||||||
BindGroupBase* CreateBindGroup(BindGroupBuilder* builder) override;
|
|
||||||
BlendStateBase* CreateBlendState(BlendStateBuilder* builder) override;
|
BlendStateBase* CreateBlendState(BlendStateBuilder* builder) override;
|
||||||
BufferViewBase* CreateBufferView(BufferViewBuilder* builder) override;
|
BufferViewBase* CreateBufferView(BufferViewBuilder* builder) override;
|
||||||
CommandBufferBase* CreateCommandBuffer(CommandBufferBuilder* builder) override;
|
CommandBufferBase* CreateCommandBuffer(CommandBufferBuilder* builder) override;
|
||||||
|
@ -64,6 +63,8 @@ namespace dawn_native { namespace metal {
|
||||||
ResourceUploader* GetResourceUploader() const;
|
ResourceUploader* GetResourceUploader() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
ResultOrError<BindGroupBase*> CreateBindGroupImpl(
|
||||||
|
const BindGroupDescriptor* descriptor) override;
|
||||||
ResultOrError<BindGroupLayoutBase*> CreateBindGroupLayoutImpl(
|
ResultOrError<BindGroupLayoutBase*> CreateBindGroupLayoutImpl(
|
||||||
const BindGroupLayoutDescriptor* descriptor) override;
|
const BindGroupLayoutDescriptor* descriptor) override;
|
||||||
ResultOrError<BufferBase*> CreateBufferImpl(const BufferDescriptor* descriptor) override;
|
ResultOrError<BufferBase*> CreateBufferImpl(const BufferDescriptor* descriptor) override;
|
||||||
|
|
|
@ -162,8 +162,9 @@ namespace dawn_native { namespace metal {
|
||||||
mCommandQueue = nil;
|
mCommandQueue = nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
BindGroupBase* Device::CreateBindGroup(BindGroupBuilder* builder) {
|
ResultOrError<BindGroupBase*> Device::CreateBindGroupImpl(
|
||||||
return new BindGroup(builder);
|
const BindGroupDescriptor* descriptor) {
|
||||||
|
return new BindGroup(this, descriptor);
|
||||||
}
|
}
|
||||||
ResultOrError<BindGroupLayoutBase*> Device::CreateBindGroupLayoutImpl(
|
ResultOrError<BindGroupLayoutBase*> Device::CreateBindGroupLayoutImpl(
|
||||||
const BindGroupLayoutDescriptor* descriptor) {
|
const BindGroupLayoutDescriptor* descriptor) {
|
||||||
|
|
|
@ -34,8 +34,9 @@ namespace dawn_native { namespace null {
|
||||||
Device::~Device() {
|
Device::~Device() {
|
||||||
}
|
}
|
||||||
|
|
||||||
BindGroupBase* Device::CreateBindGroup(BindGroupBuilder* builder) {
|
ResultOrError<BindGroupBase*> Device::CreateBindGroupImpl(
|
||||||
return new BindGroup(builder);
|
const BindGroupDescriptor* descriptor) {
|
||||||
|
return new BindGroup(this, descriptor);
|
||||||
}
|
}
|
||||||
ResultOrError<BindGroupLayoutBase*> Device::CreateBindGroupLayoutImpl(
|
ResultOrError<BindGroupLayoutBase*> Device::CreateBindGroupLayoutImpl(
|
||||||
const BindGroupLayoutDescriptor* descriptor) {
|
const BindGroupLayoutDescriptor* descriptor) {
|
||||||
|
|
|
@ -95,7 +95,6 @@ namespace dawn_native { namespace null {
|
||||||
Device();
|
Device();
|
||||||
~Device();
|
~Device();
|
||||||
|
|
||||||
BindGroupBase* CreateBindGroup(BindGroupBuilder* builder) override;
|
|
||||||
BlendStateBase* CreateBlendState(BlendStateBuilder* builder) override;
|
BlendStateBase* CreateBlendState(BlendStateBuilder* builder) override;
|
||||||
BufferViewBase* CreateBufferView(BufferViewBuilder* builder) override;
|
BufferViewBase* CreateBufferView(BufferViewBuilder* builder) override;
|
||||||
CommandBufferBase* CreateCommandBuffer(CommandBufferBuilder* builder) override;
|
CommandBufferBase* CreateCommandBuffer(CommandBufferBuilder* builder) override;
|
||||||
|
@ -116,6 +115,8 @@ namespace dawn_native { namespace null {
|
||||||
void SubmitPendingOperations();
|
void SubmitPendingOperations();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
ResultOrError<BindGroupBase*> CreateBindGroupImpl(
|
||||||
|
const BindGroupDescriptor* descriptor) override;
|
||||||
ResultOrError<BindGroupLayoutBase*> CreateBindGroupLayoutImpl(
|
ResultOrError<BindGroupLayoutBase*> CreateBindGroupLayoutImpl(
|
||||||
const BindGroupLayoutDescriptor* descriptor) override;
|
const BindGroupLayoutDescriptor* descriptor) override;
|
||||||
ResultOrError<BufferBase*> CreateBufferImpl(const BufferDescriptor* descriptor) override;
|
ResultOrError<BufferBase*> CreateBufferImpl(const BufferDescriptor* descriptor) override;
|
||||||
|
|
|
@ -61,8 +61,9 @@ namespace dawn_native { namespace opengl {
|
||||||
Tick();
|
Tick();
|
||||||
}
|
}
|
||||||
|
|
||||||
BindGroupBase* Device::CreateBindGroup(BindGroupBuilder* builder) {
|
ResultOrError<BindGroupBase*> Device::CreateBindGroupImpl(
|
||||||
return new BindGroup(builder);
|
const BindGroupDescriptor* descriptor) {
|
||||||
|
return new BindGroup(this, descriptor);
|
||||||
}
|
}
|
||||||
ResultOrError<BindGroupLayoutBase*> Device::CreateBindGroupLayoutImpl(
|
ResultOrError<BindGroupLayoutBase*> Device::CreateBindGroupLayoutImpl(
|
||||||
const BindGroupLayoutDescriptor* descriptor) {
|
const BindGroupLayoutDescriptor* descriptor) {
|
||||||
|
|
|
@ -40,7 +40,6 @@ namespace dawn_native { namespace opengl {
|
||||||
void SubmitFenceSync();
|
void SubmitFenceSync();
|
||||||
|
|
||||||
// Dawn API
|
// Dawn API
|
||||||
BindGroupBase* CreateBindGroup(BindGroupBuilder* builder) override;
|
|
||||||
BlendStateBase* CreateBlendState(BlendStateBuilder* builder) override;
|
BlendStateBase* CreateBlendState(BlendStateBuilder* builder) override;
|
||||||
BufferViewBase* CreateBufferView(BufferViewBuilder* builder) override;
|
BufferViewBase* CreateBufferView(BufferViewBuilder* builder) override;
|
||||||
CommandBufferBase* CreateCommandBuffer(CommandBufferBuilder* builder) override;
|
CommandBufferBase* CreateCommandBuffer(CommandBufferBuilder* builder) override;
|
||||||
|
@ -58,6 +57,8 @@ namespace dawn_native { namespace opengl {
|
||||||
const dawn_native::PCIInfo& GetPCIInfo() const override;
|
const dawn_native::PCIInfo& GetPCIInfo() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
ResultOrError<BindGroupBase*> CreateBindGroupImpl(
|
||||||
|
const BindGroupDescriptor* descriptor) override;
|
||||||
ResultOrError<BindGroupLayoutBase*> CreateBindGroupLayoutImpl(
|
ResultOrError<BindGroupLayoutBase*> CreateBindGroupLayoutImpl(
|
||||||
const BindGroupLayoutDescriptor* descriptor) override;
|
const BindGroupLayoutDescriptor* descriptor) override;
|
||||||
ResultOrError<BufferBase*> CreateBufferImpl(const BufferDescriptor* descriptor) override;
|
ResultOrError<BufferBase*> CreateBufferImpl(const BufferDescriptor* descriptor) override;
|
||||||
|
|
|
@ -25,7 +25,8 @@
|
||||||
|
|
||||||
namespace dawn_native { namespace vulkan {
|
namespace dawn_native { namespace vulkan {
|
||||||
|
|
||||||
BindGroup::BindGroup(BindGroupBuilder* builder) : BindGroupBase(builder) {
|
BindGroup::BindGroup(Device* device, const BindGroupDescriptor* descriptor)
|
||||||
|
: BindGroupBase(device, descriptor) {
|
||||||
// Create a pool to hold our descriptor set.
|
// Create a pool to hold our descriptor set.
|
||||||
// TODO(cwallez@chromium.org): This horribly inefficient, find a way to be better, for
|
// TODO(cwallez@chromium.org): This horribly inefficient, find a way to be better, for
|
||||||
// example by having one pool per bind group layout instead.
|
// example by having one pool per bind group layout instead.
|
||||||
|
@ -40,7 +41,6 @@ namespace dawn_native { namespace vulkan {
|
||||||
createInfo.poolSizeCount = numPoolSizes;
|
createInfo.poolSizeCount = numPoolSizes;
|
||||||
createInfo.pPoolSizes = poolSizes.data();
|
createInfo.pPoolSizes = poolSizes.data();
|
||||||
|
|
||||||
Device* device = ToBackend(GetDevice());
|
|
||||||
if (device->fn.CreateDescriptorPool(device->GetVkDevice(), &createInfo, nullptr, &mPool) !=
|
if (device->fn.CreateDescriptorPool(device->GetVkDevice(), &createInfo, nullptr, &mPool) !=
|
||||||
VK_SUCCESS) {
|
VK_SUCCESS) {
|
||||||
ASSERT(false);
|
ASSERT(false);
|
||||||
|
|
|
@ -25,7 +25,7 @@ namespace dawn_native { namespace vulkan {
|
||||||
|
|
||||||
class BindGroup : public BindGroupBase {
|
class BindGroup : public BindGroupBase {
|
||||||
public:
|
public:
|
||||||
BindGroup(BindGroupBuilder* builder);
|
BindGroup(Device* device, const BindGroupDescriptor* descriptor);
|
||||||
~BindGroup();
|
~BindGroup();
|
||||||
|
|
||||||
VkDescriptorSet GetHandle() const;
|
VkDescriptorSet GetHandle() const;
|
||||||
|
|
|
@ -212,8 +212,9 @@ namespace dawn_native { namespace vulkan {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BindGroupBase* Device::CreateBindGroup(BindGroupBuilder* builder) {
|
ResultOrError<BindGroupBase*> Device::CreateBindGroupImpl(
|
||||||
return new BindGroup(builder);
|
const BindGroupDescriptor* descriptor) {
|
||||||
|
return new BindGroup(this, descriptor);
|
||||||
}
|
}
|
||||||
ResultOrError<BindGroupLayoutBase*> Device::CreateBindGroupLayoutImpl(
|
ResultOrError<BindGroupLayoutBase*> Device::CreateBindGroupLayoutImpl(
|
||||||
const BindGroupLayoutDescriptor* descriptor) {
|
const BindGroupLayoutDescriptor* descriptor) {
|
||||||
|
|
|
@ -63,7 +63,6 @@ namespace dawn_native { namespace vulkan {
|
||||||
void AddWaitSemaphore(VkSemaphore semaphore);
|
void AddWaitSemaphore(VkSemaphore semaphore);
|
||||||
|
|
||||||
// Dawn API
|
// Dawn API
|
||||||
BindGroupBase* CreateBindGroup(BindGroupBuilder* builder) override;
|
|
||||||
BlendStateBase* CreateBlendState(BlendStateBuilder* builder) override;
|
BlendStateBase* CreateBlendState(BlendStateBuilder* builder) override;
|
||||||
BufferViewBase* CreateBufferView(BufferViewBuilder* builder) override;
|
BufferViewBase* CreateBufferView(BufferViewBuilder* builder) override;
|
||||||
CommandBufferBase* CreateCommandBuffer(CommandBufferBuilder* builder) override;
|
CommandBufferBase* CreateCommandBuffer(CommandBufferBuilder* builder) override;
|
||||||
|
@ -81,6 +80,8 @@ namespace dawn_native { namespace vulkan {
|
||||||
const dawn_native::PCIInfo& GetPCIInfo() const override;
|
const dawn_native::PCIInfo& GetPCIInfo() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
ResultOrError<BindGroupBase*> CreateBindGroupImpl(
|
||||||
|
const BindGroupDescriptor* descriptor) override;
|
||||||
ResultOrError<BindGroupLayoutBase*> CreateBindGroupLayoutImpl(
|
ResultOrError<BindGroupLayoutBase*> CreateBindGroupLayoutImpl(
|
||||||
const BindGroupLayoutDescriptor* descriptor) override;
|
const BindGroupLayoutDescriptor* descriptor) override;
|
||||||
ResultOrError<BufferBase*> CreateBufferImpl(const BufferDescriptor* descriptor) override;
|
ResultOrError<BufferBase*> CreateBufferImpl(const BufferDescriptor* descriptor) override;
|
||||||
|
|
|
@ -68,10 +68,7 @@ TEST_P(BindGroupTests, ReusedBindGroupSingleSubmit) {
|
||||||
dawn::Buffer buffer = device.CreateBuffer(&bufferDesc);
|
dawn::Buffer buffer = device.CreateBuffer(&bufferDesc);
|
||||||
dawn::BufferView bufferView =
|
dawn::BufferView bufferView =
|
||||||
buffer.CreateBufferViewBuilder().SetExtent(0, sizeof(float)).GetResult();
|
buffer.CreateBufferViewBuilder().SetExtent(0, sizeof(float)).GetResult();
|
||||||
dawn::BindGroup bindGroup = device.CreateBindGroupBuilder()
|
dawn::BindGroup bindGroup = utils::MakeBindGroup(device, bgl, {{0, bufferView}});
|
||||||
.SetLayout(bgl)
|
|
||||||
.SetBufferViews(0, 1, &bufferView)
|
|
||||||
.GetResult();
|
|
||||||
|
|
||||||
dawn::CommandBuffer cb[2];
|
dawn::CommandBuffer cb[2];
|
||||||
cb[0] = CreateSimpleComputeCommandBuffer(cp, bindGroup);
|
cb[0] = CreateSimpleComputeCommandBuffer(cp, bindGroup);
|
||||||
|
@ -143,11 +140,10 @@ TEST_P(BindGroupTests, ReusedUBO) {
|
||||||
buffer.CreateBufferViewBuilder().SetExtent(0, sizeof(Data::transform)).GetResult();
|
buffer.CreateBufferViewBuilder().SetExtent(0, sizeof(Data::transform)).GetResult();
|
||||||
dawn::BufferView fragUBOBufferView =
|
dawn::BufferView fragUBOBufferView =
|
||||||
buffer.CreateBufferViewBuilder().SetExtent(256, sizeof(Data::color)).GetResult();
|
buffer.CreateBufferViewBuilder().SetExtent(256, sizeof(Data::color)).GetResult();
|
||||||
dawn::BindGroup bindGroup = device.CreateBindGroupBuilder()
|
dawn::BindGroup bindGroup = utils::MakeBindGroup(device, bgl, {
|
||||||
.SetLayout(bgl)
|
{0, vertUBOBufferView},
|
||||||
.SetBufferViews(0, 1, &vertUBOBufferView)
|
{1, fragUBOBufferView}
|
||||||
.SetBufferViews(1, 1, &fragUBOBufferView)
|
});
|
||||||
.GetResult();
|
|
||||||
|
|
||||||
dawn::CommandBufferBuilder builder = device.CreateCommandBufferBuilder();
|
dawn::CommandBufferBuilder builder = device.CreateCommandBufferBuilder();
|
||||||
dawn::RenderPassEncoder pass = builder.BeginRenderPass(renderPass.renderPassInfo);
|
dawn::RenderPassEncoder pass = builder.BeginRenderPass(renderPass.renderPassInfo);
|
||||||
|
@ -250,12 +246,11 @@ TEST_P(BindGroupTests, UBOSamplerAndTexture) {
|
||||||
data[i] = RGBA8(0, 255, 0, 255);
|
data[i] = RGBA8(0, 255, 0, 255);
|
||||||
}
|
}
|
||||||
dawn::Buffer stagingBuffer = utils::CreateBufferFromData(device, data.data(), sizeInBytes, dawn::BufferUsageBit::TransferSrc);
|
dawn::Buffer stagingBuffer = utils::CreateBufferFromData(device, data.data(), sizeInBytes, dawn::BufferUsageBit::TransferSrc);
|
||||||
dawn::BindGroup bindGroup = device.CreateBindGroupBuilder()
|
dawn::BindGroup bindGroup = utils::MakeBindGroup(device, bgl, {
|
||||||
.SetLayout(bgl)
|
{0, vertUBOBufferView},
|
||||||
.SetBufferViews(0, 1, &vertUBOBufferView)
|
{1, sampler},
|
||||||
.SetSamplers(1, 1, &sampler)
|
{2, textureView}
|
||||||
.SetTextureViews(2, 1, &textureView)
|
});
|
||||||
.GetResult();
|
|
||||||
|
|
||||||
dawn::CommandBufferBuilder builder = device.CreateCommandBufferBuilder();
|
dawn::CommandBufferBuilder builder = device.CreateCommandBufferBuilder();
|
||||||
dawn::BufferCopyView bufferCopyView =
|
dawn::BufferCopyView bufferCopyView =
|
||||||
|
|
|
@ -101,10 +101,7 @@ class BlendStateTest : public DawnTest {
|
||||||
.SetExtent(0, bufferSize)
|
.SetExtent(0, bufferSize)
|
||||||
.GetResult();
|
.GetResult();
|
||||||
|
|
||||||
return device.CreateBindGroupBuilder()
|
return utils::MakeBindGroup(device, bindGroupLayout, {{0, view}});
|
||||||
.SetLayout(bindGroupLayout)
|
|
||||||
.SetBufferViews(0, 1, &view)
|
|
||||||
.GetResult();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test that after drawing a triangle with the base color, and then the given triangle spec, the color is as expected
|
// Test that after drawing a triangle with the base color, and then the given triangle spec, the color is as expected
|
||||||
|
|
|
@ -73,11 +73,10 @@ void ComputeCopyStorageBufferTests::BasicTest(const char* shader) {
|
||||||
dst.CreateBufferViewBuilder().SetExtent(0, kNumUints * sizeof(uint32_t)).GetResult();
|
dst.CreateBufferViewBuilder().SetExtent(0, kNumUints * sizeof(uint32_t)).GetResult();
|
||||||
|
|
||||||
// Set up bind group and issue dispatch
|
// Set up bind group and issue dispatch
|
||||||
auto bindGroup = device.CreateBindGroupBuilder()
|
dawn::BindGroup bindGroup = utils::MakeBindGroup(device, bgl, {
|
||||||
.SetLayout(bgl)
|
{0, srcView},
|
||||||
.SetBufferViews(0, 1, &srcView)
|
{1, dstView},
|
||||||
.SetBufferViews(1, 1, &dstView)
|
});
|
||||||
.GetResult();
|
|
||||||
|
|
||||||
dawn::CommandBuffer commands;
|
dawn::CommandBuffer commands;
|
||||||
{
|
{
|
||||||
|
|
|
@ -214,10 +214,7 @@ class DepthStencilStateTest : public DawnTest {
|
||||||
.GetResult();
|
.GetResult();
|
||||||
|
|
||||||
// Create a bind group for the data
|
// Create a bind group for the data
|
||||||
dawn::BindGroup bindGroup = device.CreateBindGroupBuilder()
|
dawn::BindGroup bindGroup = utils::MakeBindGroup(device, bindGroupLayout, {{0, view}});
|
||||||
.SetLayout(bindGroupLayout)
|
|
||||||
.SetBufferViews(0, 1, &view)
|
|
||||||
.GetResult();
|
|
||||||
|
|
||||||
// Create a pipeline for the triangles with the test spec's depth stencil state
|
// Create a pipeline for the triangles with the test spec's depth stencil state
|
||||||
dawn::RenderPipeline pipeline = device.CreateRenderPipelineBuilder()
|
dawn::RenderPipeline pipeline = device.CreateRenderPipelineBuilder()
|
||||||
|
|
|
@ -56,10 +56,17 @@ class PushConstantTest: public DawnTest {
|
||||||
buf2.CreateBufferViewBuilder().SetExtent(0, 4).GetResult(),
|
buf2.CreateBufferViewBuilder().SetExtent(0, 4).GetResult(),
|
||||||
};
|
};
|
||||||
|
|
||||||
dawn::BindGroup bg = device.CreateBindGroupBuilder()
|
dawn::BindGroup bg;
|
||||||
.SetLayout(bgl)
|
if (extraBuffer) {
|
||||||
.SetBufferViews(0, extraBuffer ? 2 : 1, views)
|
bg = utils::MakeBindGroup(device, bgl, {
|
||||||
.GetResult();
|
{0, views[0]},
|
||||||
|
{1, views[1]},
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
bg = utils::MakeBindGroup(device, bgl, {
|
||||||
|
{0, views[0]},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return {std::move(pl), std::move(bg), std::move(buf1)};
|
return {std::move(pl), std::move(bg), std::move(buf1)};
|
||||||
}
|
}
|
||||||
|
|
|
@ -126,11 +126,10 @@ protected:
|
||||||
sampler = device.CreateSampler(&descriptor);
|
sampler = device.CreateSampler(&descriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto bindGroup = device.CreateBindGroupBuilder()
|
dawn::BindGroup bindGroup = utils::MakeBindGroup(device, mBindGroupLayout, {
|
||||||
.SetLayout(mBindGroupLayout)
|
{0, sampler},
|
||||||
.SetSamplers(0, 1, &sampler)
|
{1, mTextureView}
|
||||||
.SetTextureViews(1, 1, &mTextureView)
|
});
|
||||||
.GetResult();
|
|
||||||
|
|
||||||
dawn::CommandBufferBuilder builder = device.CreateCommandBufferBuilder();
|
dawn::CommandBufferBuilder builder = device.CreateCommandBufferBuilder();
|
||||||
{
|
{
|
||||||
|
|
|
@ -155,11 +155,10 @@ protected:
|
||||||
}
|
}
|
||||||
|
|
||||||
void Verify(const dawn::TextureView &textureView, const char* fragmentShader, int expected) {
|
void Verify(const dawn::TextureView &textureView, const char* fragmentShader, int expected) {
|
||||||
dawn::BindGroup bindGroup = device.CreateBindGroupBuilder()
|
dawn::BindGroup bindGroup = utils::MakeBindGroup(device, mBindGroupLayout, {
|
||||||
.SetLayout(mBindGroupLayout)
|
{0, mSampler},
|
||||||
.SetSamplers(0, 1, &mSampler)
|
{1, textureView}
|
||||||
.SetTextureViews(1, 1, &textureView)
|
});
|
||||||
.GetResult();
|
|
||||||
|
|
||||||
dawn::ShaderModule fsModule =
|
dawn::ShaderModule fsModule =
|
||||||
utils::CreateShaderModule(device, dawn::ShaderStage::Fragment, fragmentShader);
|
utils::CreateShaderModule(device, dawn::ShaderStage::Fragment, fragmentShader);
|
||||||
|
|
|
@ -494,21 +494,39 @@ TEST_F(WireTests, StructureOfStructureArrayArgument) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test passing nullptr instead of objects - object as value version
|
// Test passing nullptr instead of objects - object as value version
|
||||||
TEST_F(WireTests, DISABLED_NullptrAsValue) {
|
TEST_F(WireTests, OptionalObjectValue) {
|
||||||
dawnCommandBufferBuilder builder = dawnDeviceCreateCommandBufferBuilder(device);
|
dawnBindGroupLayoutDescriptor bglDesc;
|
||||||
dawnComputePassEncoder pass = dawnCommandBufferBuilderBeginComputePass(builder);
|
bglDesc.nextInChain = nullptr;
|
||||||
dawnComputePassEncoderSetComputePipeline(pass, nullptr);
|
bglDesc.numBindings = 0;
|
||||||
|
dawnBindGroupLayout bgl = dawnDeviceCreateBindGroupLayout(device, &bglDesc);
|
||||||
|
|
||||||
dawnCommandBufferBuilder apiBuilder = api.GetNewCommandBufferBuilder();
|
dawnBindGroupLayout apiBindGroupLayout = api.GetNewBindGroupLayout();
|
||||||
EXPECT_CALL(api, DeviceCreateCommandBufferBuilder(apiDevice))
|
EXPECT_CALL(api, DeviceCreateBindGroupLayout(apiDevice, _))
|
||||||
.WillOnce(Return(apiBuilder));
|
.WillOnce(Return(apiBindGroupLayout));
|
||||||
|
|
||||||
dawnComputePassEncoder apiPass = api.GetNewComputePassEncoder();
|
// The `sampler`, `textureView` and `bufferView` members of a binding are optional.
|
||||||
EXPECT_CALL(api, CommandBufferBuilderBeginComputePass(apiBuilder))
|
dawnBindGroupBinding binding;
|
||||||
.WillOnce(Return(apiPass));
|
binding.binding = 0;
|
||||||
|
binding.sampler = nullptr;
|
||||||
|
binding.textureView = nullptr;
|
||||||
|
binding.bufferView = nullptr;
|
||||||
|
|
||||||
EXPECT_CALL(api, ComputePassEncoderSetComputePipeline(apiPass, nullptr))
|
dawnBindGroupDescriptor bgDesc;
|
||||||
.Times(1);
|
bgDesc.nextInChain = nullptr;
|
||||||
|
bgDesc.layout = bgl;
|
||||||
|
bgDesc.numBindings = 1;
|
||||||
|
bgDesc.bindings = &binding;
|
||||||
|
|
||||||
|
dawnDeviceCreateBindGroup(device, &bgDesc);
|
||||||
|
EXPECT_CALL(api, DeviceCreateBindGroup(apiDevice, MatchesLambda([](const dawnBindGroupDescriptor* desc) -> bool {
|
||||||
|
return desc->nextInChain == nullptr &&
|
||||||
|
desc->numBindings == 1 &&
|
||||||
|
desc->bindings[0].binding == 0 &&
|
||||||
|
desc->bindings[0].sampler == nullptr &&
|
||||||
|
desc->bindings[0].bufferView == nullptr &&
|
||||||
|
desc->bindings[0].textureView == nullptr;
|
||||||
|
})))
|
||||||
|
.WillOnce(Return(nullptr));
|
||||||
|
|
||||||
FlushClient();
|
FlushClient();
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,98 +18,350 @@
|
||||||
#include "utils/DawnHelpers.h"
|
#include "utils/DawnHelpers.h"
|
||||||
|
|
||||||
class BindGroupValidationTest : public ValidationTest {
|
class BindGroupValidationTest : public ValidationTest {
|
||||||
|
public:
|
||||||
|
void SetUp() override {
|
||||||
|
// Create objects to use as resources inside test bind groups.
|
||||||
|
{
|
||||||
|
dawn::BufferDescriptor descriptor;
|
||||||
|
descriptor.size = 1024;
|
||||||
|
descriptor.usage = dawn::BufferUsageBit::Uniform;
|
||||||
|
mUBO = device.CreateBuffer(&descriptor);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
dawn::BufferDescriptor descriptor;
|
||||||
|
descriptor.size = 1024;
|
||||||
|
descriptor.usage = dawn::BufferUsageBit::Storage;
|
||||||
|
mSSBO = device.CreateBuffer(&descriptor);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
dawn::SamplerDescriptor descriptor = utils::GetDefaultSamplerDescriptor();
|
||||||
|
mSampler = device.CreateSampler(&descriptor);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
dawn::TextureDescriptor descriptor;
|
||||||
|
descriptor.dimension = dawn::TextureDimension::e2D;
|
||||||
|
descriptor.size = {16, 16, 1};
|
||||||
|
descriptor.arrayLayer = 1;
|
||||||
|
descriptor.format = dawn::TextureFormat::R8G8B8A8Unorm;
|
||||||
|
descriptor.levelCount = 1;
|
||||||
|
descriptor.usage = dawn::TextureUsageBit::Sampled;
|
||||||
|
mSampledTexture = device.CreateTexture(&descriptor);
|
||||||
|
mSampledTextureView = mSampledTexture.CreateDefaultTextureView();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
dawn::Buffer mUBO;
|
||||||
|
dawn::Buffer mSSBO;
|
||||||
|
dawn::Sampler mSampler;
|
||||||
|
dawn::Texture mSampledTexture;
|
||||||
|
dawn::TextureView mSampledTextureView;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Test the validation of BindGroupDescriptor::nextInChain
|
||||||
|
TEST_F(BindGroupValidationTest, NextInChainNullptr) {
|
||||||
|
dawn::BindGroupLayout layout = utils::MakeBindGroupLayout(device, {});
|
||||||
|
|
||||||
|
dawn::BindGroupDescriptor descriptor;
|
||||||
|
descriptor.layout = layout;
|
||||||
|
descriptor.numBindings = 0;
|
||||||
|
descriptor.bindings = nullptr;
|
||||||
|
|
||||||
|
// Control case: check that nextInChain = nullptr is valid
|
||||||
|
descriptor.nextInChain = nullptr;
|
||||||
|
device.CreateBindGroup(&descriptor);
|
||||||
|
|
||||||
|
// Check that nextInChain != nullptr is an error.
|
||||||
|
descriptor.nextInChain = static_cast<void*>(&descriptor);
|
||||||
|
ASSERT_DEVICE_ERROR(device.CreateBindGroup(&descriptor));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check constraints on numBindings
|
||||||
|
TEST_F(BindGroupValidationTest, NumBindingsMismatch) {
|
||||||
|
dawn::BindGroupLayout layout = utils::MakeBindGroupLayout(device, {
|
||||||
|
{0, dawn::ShaderStageBit::Fragment, dawn::BindingType::Sampler}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Control case: check that a descriptor with one binding is ok
|
||||||
|
utils::MakeBindGroup(device, layout, {{0, mSampler}});
|
||||||
|
|
||||||
|
// Check that numBindings != layout.numBindings fails.
|
||||||
|
ASSERT_DEVICE_ERROR(utils::MakeBindGroup(device, layout, {}));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check constraints on BindGroupBinding::binding
|
||||||
|
TEST_F(BindGroupValidationTest, WrongBindings) {
|
||||||
|
dawn::BindGroupLayout layout = utils::MakeBindGroupLayout(device, {
|
||||||
|
{0, dawn::ShaderStageBit::Fragment, dawn::BindingType::Sampler}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Control case: check that a descriptor with a binding matching the layout's is ok
|
||||||
|
utils::MakeBindGroup(device, layout, {{0, mSampler}});
|
||||||
|
|
||||||
|
// Check that binding must be present in the layout
|
||||||
|
ASSERT_DEVICE_ERROR(utils::MakeBindGroup(device, layout, {{1, mSampler}}));
|
||||||
|
|
||||||
|
// Check that binding >= kMaxBindingsPerGroup fails.
|
||||||
|
ASSERT_DEVICE_ERROR(utils::MakeBindGroup(device, layout, {{kMaxBindingsPerGroup, mSampler}}));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check that the same binding cannot be set twice
|
||||||
|
TEST_F(BindGroupValidationTest, BindingSetTwice) {
|
||||||
|
dawn::BindGroupLayout layout = utils::MakeBindGroupLayout(device, {
|
||||||
|
{0, dawn::ShaderStageBit::Fragment, dawn::BindingType::Sampler},
|
||||||
|
{1, dawn::ShaderStageBit::Fragment, dawn::BindingType::Sampler}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Control case: check that different bindings work
|
||||||
|
utils::MakeBindGroup(device, layout, {
|
||||||
|
{0, mSampler},
|
||||||
|
{1, mSampler}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Check that setting the same binding twice is invalid
|
||||||
|
ASSERT_DEVICE_ERROR(utils::MakeBindGroup(device, layout, {
|
||||||
|
{0, mSampler},
|
||||||
|
{0, mSampler}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check that a sampler binding must contain exactly one sampler
|
||||||
|
TEST_F(BindGroupValidationTest, SamplerBindingType) {
|
||||||
|
dawn::BindGroupLayout layout = utils::MakeBindGroupLayout(device, {
|
||||||
|
{0, dawn::ShaderStageBit::Fragment, dawn::BindingType::Sampler}
|
||||||
|
});
|
||||||
|
|
||||||
|
dawn::BindGroupBinding binding;
|
||||||
|
binding.binding = 0;
|
||||||
|
binding.sampler = nullptr;
|
||||||
|
binding.textureView = nullptr;
|
||||||
|
binding.bufferView = nullptr;
|
||||||
|
|
||||||
|
dawn::BindGroupDescriptor descriptor;
|
||||||
|
descriptor.nextInChain = nullptr;
|
||||||
|
descriptor.layout = layout;
|
||||||
|
descriptor.numBindings = 1;
|
||||||
|
descriptor.bindings = &binding;
|
||||||
|
|
||||||
|
// Not setting anything fails
|
||||||
|
ASSERT_DEVICE_ERROR(device.CreateBindGroup(&descriptor));
|
||||||
|
|
||||||
|
// Control case: setting just the sampler works
|
||||||
|
binding.sampler = mSampler;
|
||||||
|
device.CreateBindGroup(&descriptor);
|
||||||
|
|
||||||
|
// Setting the texture view as well is an error
|
||||||
|
binding.textureView = mSampledTextureView;
|
||||||
|
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();
|
||||||
|
ASSERT_DEVICE_ERROR(device.CreateBindGroup(&descriptor));
|
||||||
|
binding.bufferView = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check that a texture binding must contain exactly a texture view
|
||||||
|
TEST_F(BindGroupValidationTest, TextureBindingType) {
|
||||||
|
dawn::BindGroupLayout layout = utils::MakeBindGroupLayout(device, {
|
||||||
|
{0, dawn::ShaderStageBit::Fragment, dawn::BindingType::SampledTexture}
|
||||||
|
});
|
||||||
|
|
||||||
|
dawn::BindGroupBinding binding;
|
||||||
|
binding.binding = 0;
|
||||||
|
binding.sampler = nullptr;
|
||||||
|
binding.textureView = nullptr;
|
||||||
|
binding.bufferView = nullptr;
|
||||||
|
|
||||||
|
dawn::BindGroupDescriptor descriptor;
|
||||||
|
descriptor.nextInChain = nullptr;
|
||||||
|
descriptor.layout = layout;
|
||||||
|
descriptor.numBindings = 1;
|
||||||
|
descriptor.bindings = &binding;
|
||||||
|
|
||||||
|
// Not setting anything fails
|
||||||
|
ASSERT_DEVICE_ERROR(device.CreateBindGroup(&descriptor));
|
||||||
|
|
||||||
|
// Control case: setting just the texture view works
|
||||||
|
binding.textureView = mSampledTextureView;
|
||||||
|
device.CreateBindGroup(&descriptor);
|
||||||
|
|
||||||
|
// Setting the sampler as well is an error
|
||||||
|
binding.sampler = mSampler;
|
||||||
|
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();
|
||||||
|
ASSERT_DEVICE_ERROR(device.CreateBindGroup(&descriptor));
|
||||||
|
binding.bufferView = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check that a buffer binding must contain exactly a buffer view
|
||||||
|
TEST_F(BindGroupValidationTest, BufferBindingType) {
|
||||||
|
dawn::BindGroupLayout layout = utils::MakeBindGroupLayout(device, {
|
||||||
|
{0, dawn::ShaderStageBit::Fragment, dawn::BindingType::UniformBuffer}
|
||||||
|
});
|
||||||
|
|
||||||
|
dawn::BindGroupBinding binding;
|
||||||
|
binding.binding = 0;
|
||||||
|
binding.sampler = nullptr;
|
||||||
|
binding.textureView = nullptr;
|
||||||
|
binding.bufferView = nullptr;
|
||||||
|
|
||||||
|
dawn::BindGroupDescriptor descriptor;
|
||||||
|
descriptor.nextInChain = nullptr;
|
||||||
|
descriptor.layout = layout;
|
||||||
|
descriptor.numBindings = 1;
|
||||||
|
descriptor.bindings = &binding;
|
||||||
|
|
||||||
|
// 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();
|
||||||
|
device.CreateBindGroup(&descriptor);
|
||||||
|
|
||||||
|
// Setting the texture view as well is an error
|
||||||
|
binding.textureView = mSampledTextureView;
|
||||||
|
ASSERT_DEVICE_ERROR(device.CreateBindGroup(&descriptor));
|
||||||
|
binding.textureView = nullptr;
|
||||||
|
|
||||||
|
// Setting the sampler as well is an error
|
||||||
|
binding.sampler = mSampler;
|
||||||
|
ASSERT_DEVICE_ERROR(device.CreateBindGroup(&descriptor));
|
||||||
|
binding.sampler = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check that a texture must have the correct usage
|
||||||
|
TEST_F(BindGroupValidationTest, TextureUsage) {
|
||||||
|
dawn::BindGroupLayout layout = utils::MakeBindGroupLayout(device, {
|
||||||
|
{0, dawn::ShaderStageBit::Fragment, dawn::BindingType::SampledTexture}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Control case: setting a sampleable texture view works.
|
||||||
|
utils::MakeBindGroup(device, layout, {{0, mSampledTextureView}});
|
||||||
|
|
||||||
|
// Make an output attachment texture and try to set it for a SampledTexture binding
|
||||||
|
dawn::TextureDescriptor descriptor;
|
||||||
|
descriptor.dimension = dawn::TextureDimension::e2D;
|
||||||
|
descriptor.size = {16, 16, 1};
|
||||||
|
descriptor.arrayLayer = 1;
|
||||||
|
descriptor.format = dawn::TextureFormat::R8G8B8A8Unorm;
|
||||||
|
descriptor.levelCount = 1;
|
||||||
|
descriptor.usage = dawn::TextureUsageBit::OutputAttachment;
|
||||||
|
dawn::Texture outputTexture = device.CreateTexture(&descriptor);
|
||||||
|
dawn::TextureView outputTextureView = outputTexture.CreateDefaultTextureView();
|
||||||
|
ASSERT_DEVICE_ERROR(utils::MakeBindGroup(device, layout, {{0, outputTextureView}}));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check that a UBO must have the correct usage
|
||||||
|
TEST_F(BindGroupValidationTest, BufferUsageUBO) {
|
||||||
|
dawn::BindGroupLayout layout = utils::MakeBindGroupLayout(device, {
|
||||||
|
{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}});
|
||||||
|
|
||||||
|
// Using a buffer without the uniform usage fails
|
||||||
|
ASSERT_DEVICE_ERROR(utils::MakeBindGroup(device, layout, {{0, ssboView}}));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check that a SSBO must have the correct usage
|
||||||
|
TEST_F(BindGroupValidationTest, BufferUsageSSBO) {
|
||||||
|
dawn::BindGroupLayout layout = utils::MakeBindGroupLayout(device, {
|
||||||
|
{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}});
|
||||||
|
|
||||||
|
// Using a buffer without the storage usage fails
|
||||||
|
ASSERT_DEVICE_ERROR(utils::MakeBindGroup(device, layout, {{0, uboView}}));
|
||||||
|
}
|
||||||
|
|
||||||
// Tests constraints on the buffer view offset for bind groups.
|
// Tests constraints on the buffer view offset for bind groups.
|
||||||
TEST_F(BindGroupValidationTest, BufferViewOffset) {
|
TEST_F(BindGroupValidationTest, BufferViewOffset) {
|
||||||
auto layout = utils::MakeBindGroupLayout(
|
dawn::BindGroupLayout layout = utils::MakeBindGroupLayout(device, {
|
||||||
device, {
|
|
||||||
{0, dawn::ShaderStageBit::Vertex, dawn::BindingType::UniformBuffer},
|
{0, dawn::ShaderStageBit::Vertex, dawn::BindingType::UniformBuffer},
|
||||||
});
|
});
|
||||||
|
|
||||||
dawn::Buffer buffer;
|
|
||||||
{
|
|
||||||
dawn::BufferDescriptor descriptor;
|
|
||||||
descriptor.size = 512;
|
|
||||||
descriptor.usage = dawn::BufferUsageBit::Uniform;
|
|
||||||
buffer = device.CreateBuffer(&descriptor);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check that offset 0 is valid
|
// Check that offset 0 is valid
|
||||||
{
|
{
|
||||||
auto bufferView = buffer.CreateBufferViewBuilder()
|
dawn::BufferView bufferView = mUBO.CreateBufferViewBuilder()
|
||||||
.SetExtent(0, 512)
|
.SetExtent(0, 512)
|
||||||
.GetResult();
|
.GetResult();
|
||||||
|
utils::MakeBindGroup(device, layout, {{0, bufferView}});
|
||||||
auto bindGroup = AssertWillBeSuccess(device.CreateBindGroupBuilder())
|
|
||||||
.SetLayout(layout)
|
|
||||||
.SetBufferViews(0, 1, &bufferView)
|
|
||||||
.GetResult();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check that offset 256 (aligned) is valid
|
// Check that offset 256 (aligned) is valid
|
||||||
{
|
{
|
||||||
auto bufferView = buffer.CreateBufferViewBuilder()
|
dawn::BufferView bufferView = mUBO.CreateBufferViewBuilder()
|
||||||
.SetExtent(256, 256)
|
.SetExtent(256, 256)
|
||||||
.GetResult();
|
.GetResult();
|
||||||
|
utils::MakeBindGroup(device, layout, {{0, bufferView}});
|
||||||
auto bindGroup = AssertWillBeSuccess(device.CreateBindGroupBuilder())
|
|
||||||
.SetLayout(layout)
|
|
||||||
.SetBufferViews(0, 1, &bufferView)
|
|
||||||
.GetResult();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check cases where unaligned buffer view offset is invalid
|
// Check cases where unaligned buffer view offset is invalid
|
||||||
{
|
{
|
||||||
auto bufferView = buffer.CreateBufferViewBuilder()
|
dawn::BufferView bufferView = mUBO.CreateBufferViewBuilder()
|
||||||
.SetExtent(1, 256)
|
.SetExtent(1, 256)
|
||||||
.GetResult();
|
.GetResult();
|
||||||
|
ASSERT_DEVICE_ERROR(utils::MakeBindGroup(device, layout, {{0, bufferView}}));
|
||||||
auto bindGroup = AssertWillBeError(device.CreateBindGroupBuilder())
|
|
||||||
.SetLayout(layout)
|
|
||||||
.SetBufferViews(0, 1, &bufferView)
|
|
||||||
.GetResult();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
auto bufferView = buffer.CreateBufferViewBuilder()
|
dawn::BufferView bufferView = mUBO.CreateBufferViewBuilder()
|
||||||
.SetExtent(64, 256)
|
|
||||||
.GetResult();
|
|
||||||
|
|
||||||
auto bindGroup = AssertWillBeError(device.CreateBindGroupBuilder())
|
|
||||||
.SetLayout(layout)
|
|
||||||
.SetBufferViews(0, 1, &bufferView)
|
|
||||||
.GetResult();
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
auto bufferView = buffer.CreateBufferViewBuilder()
|
|
||||||
.SetExtent(128, 256)
|
.SetExtent(128, 256)
|
||||||
.GetResult();
|
.GetResult();
|
||||||
|
ASSERT_DEVICE_ERROR(utils::MakeBindGroup(device, layout, {{0, bufferView}}));
|
||||||
auto bindGroup = AssertWillBeError(device.CreateBindGroupBuilder())
|
|
||||||
.SetLayout(layout)
|
|
||||||
.SetBufferViews(0, 1, &bufferView)
|
|
||||||
.GetResult();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
auto bufferView = buffer.CreateBufferViewBuilder()
|
dawn::BufferView bufferView = mUBO.CreateBufferViewBuilder()
|
||||||
.SetExtent(255, 256)
|
.SetExtent(255, 256)
|
||||||
.GetResult();
|
.GetResult();
|
||||||
|
ASSERT_DEVICE_ERROR(utils::MakeBindGroup(device, layout, {{0, bufferView}}));
|
||||||
auto bindGroup = AssertWillBeError(device.CreateBindGroupBuilder())
|
|
||||||
.SetLayout(layout)
|
|
||||||
.SetBufferViews(0, 1, &bufferView)
|
|
||||||
.GetResult();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class BindGroupLayoutValidationTest : public ValidationTest {
|
||||||
|
};
|
||||||
|
|
||||||
|
// Tests setting OOB checks for kMaxBindingsPerGroup in bind group layouts.
|
||||||
|
TEST_F(BindGroupLayoutValidationTest, BindGroupLayoutBindingOOB) {
|
||||||
|
// Checks that kMaxBindingsPerGroup - 1 is valid.
|
||||||
|
utils::MakeBindGroupLayout(device, {
|
||||||
|
{kMaxBindingsPerGroup - 1, dawn::ShaderStageBit::Vertex, dawn::BindingType::UniformBuffer}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Checks that kMaxBindingsPerGroup is OOB
|
||||||
|
ASSERT_DEVICE_ERROR(utils::MakeBindGroupLayout(device, {
|
||||||
|
{kMaxBindingsPerGroup, dawn::ShaderStageBit::Vertex, dawn::BindingType::UniformBuffer}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
// This test verifies that the BindGroupLayout bindings are correctly validated, even if the
|
||||||
|
// binding ids are out-of-order.
|
||||||
|
TEST_F(BindGroupLayoutValidationTest, BindGroupBinding) {
|
||||||
|
auto layout = utils::MakeBindGroupLayout(
|
||||||
|
device, {
|
||||||
|
{1, dawn::ShaderStageBit::Vertex, dawn::BindingType::UniformBuffer},
|
||||||
|
{0, dawn::ShaderStageBit::Vertex, dawn::BindingType::UniformBuffer},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// This test verifies that the BindGroupLayout cache is successfully caching/deduplicating objects.
|
// This test verifies that the BindGroupLayout cache is successfully caching/deduplicating objects.
|
||||||
//
|
//
|
||||||
// NOTE: This test only works currently because unittests are run without the wire - so the returned
|
// NOTE: This test only works currently because unittests are run without the wire - so the returned
|
||||||
// BindGroupLayout pointers are actually visibly equivalent. With the wire, this would not be true.
|
// BindGroupLayout pointers are actually visibly equivalent. With the wire, this would not be true.
|
||||||
TEST_F(BindGroupValidationTest, BindGroupLayoutCache) {
|
TEST_F(BindGroupLayoutValidationTest, BindGroupLayoutCache) {
|
||||||
auto layout1 = utils::MakeBindGroupLayout(
|
auto layout1 = utils::MakeBindGroupLayout(
|
||||||
device, {
|
device, {
|
||||||
{0, dawn::ShaderStageBit::Vertex, dawn::BindingType::UniformBuffer},
|
{0, dawn::ShaderStageBit::Vertex, dawn::BindingType::UniformBuffer},
|
||||||
|
@ -122,26 +374,3 @@ TEST_F(BindGroupValidationTest, BindGroupLayoutCache) {
|
||||||
// Caching should cause these to be the same.
|
// Caching should cause these to be the same.
|
||||||
ASSERT_EQ(layout1.Get(), layout2.Get());
|
ASSERT_EQ(layout1.Get(), layout2.Get());
|
||||||
}
|
}
|
||||||
|
|
||||||
// This test verifies that the BindGroupLayout bindings are correctly validated, even if the
|
|
||||||
// binding ids are out-of-order.
|
|
||||||
TEST_F(BindGroupValidationTest, BindGroupBinding) {
|
|
||||||
auto layout = utils::MakeBindGroupLayout(
|
|
||||||
device, {
|
|
||||||
{1, dawn::ShaderStageBit::Vertex, dawn::BindingType::UniformBuffer},
|
|
||||||
{0, dawn::ShaderStageBit::Vertex, dawn::BindingType::UniformBuffer},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Tests setting OOB checks for kMaxBindingsPerGroup in bind group layouts.
|
|
||||||
TEST_F(BindGroupValidationTest, BindGroupLayoutBindingOOB) {
|
|
||||||
// Checks that kMaxBindingsPerGroup - 1 is valid.
|
|
||||||
utils::MakeBindGroupLayout(device, {
|
|
||||||
{kMaxBindingsPerGroup - 1, dawn::ShaderStageBit::Vertex, dawn::BindingType::UniformBuffer}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Checks that kMaxBindingsPerGroup is OOB
|
|
||||||
ASSERT_DEVICE_ERROR(utils::MakeBindGroupLayout(device, {
|
|
||||||
{kMaxBindingsPerGroup, dawn::ShaderStageBit::Vertex, dawn::BindingType::UniformBuffer}
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
|
@ -75,10 +75,7 @@ TEST_F(CommandBufferValidationTest, BufferWithReadAndWriteUsage) {
|
||||||
0, dawn::ShaderStageBit::Vertex, dawn::BindingType::StorageBuffer
|
0, dawn::ShaderStageBit::Vertex, dawn::BindingType::StorageBuffer
|
||||||
}});
|
}});
|
||||||
dawn::BufferView view = buffer.CreateBufferViewBuilder().SetExtent(0, 4).GetResult();
|
dawn::BufferView view = buffer.CreateBufferViewBuilder().SetExtent(0, 4).GetResult();
|
||||||
dawn::BindGroup bg = device.CreateBindGroupBuilder()
|
dawn::BindGroup bg = utils::MakeBindGroup(device, bgl, {{0, view}});
|
||||||
.SetLayout(bgl)
|
|
||||||
.SetBufferViews(0, 1, &view)
|
|
||||||
.GetResult();
|
|
||||||
|
|
||||||
// Use the buffer as both index and storage in the same pass
|
// Use the buffer as both index and storage in the same pass
|
||||||
dawn::CommandBufferBuilder builder = AssertWillBeError(device.CreateCommandBufferBuilder());
|
dawn::CommandBufferBuilder builder = AssertWillBeError(device.CreateCommandBufferBuilder());
|
||||||
|
@ -107,10 +104,7 @@ TEST_F(CommandBufferValidationTest, TextureWithReadAndWriteUsage) {
|
||||||
dawn::BindGroupLayout bgl = utils::MakeBindGroupLayout(device, {{
|
dawn::BindGroupLayout bgl = utils::MakeBindGroupLayout(device, {{
|
||||||
0, dawn::ShaderStageBit::Vertex, dawn::BindingType::SampledTexture
|
0, dawn::ShaderStageBit::Vertex, dawn::BindingType::SampledTexture
|
||||||
}});
|
}});
|
||||||
dawn::BindGroup bg = device.CreateBindGroupBuilder()
|
dawn::BindGroup bg = utils::MakeBindGroup(device, bgl, {{0, view}});
|
||||||
.SetLayout(bgl)
|
|
||||||
.SetTextureViews(0, 1, &view)
|
|
||||||
.GetResult();
|
|
||||||
|
|
||||||
// Create the render pass that will use the texture as an output attachment
|
// Create the render pass that will use the texture as an output attachment
|
||||||
dawn::RenderPassDescriptor renderPass = device.CreateRenderPassDescriptorBuilder()
|
dawn::RenderPassDescriptor renderPass = device.CreateRenderPassDescriptorBuilder()
|
||||||
|
|
|
@ -225,4 +225,47 @@ namespace utils {
|
||||||
return device.CreateBindGroupLayout(&descriptor);
|
return device.CreateBindGroupLayout(&descriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BindingInitializationHelper::BindingInitializationHelper(uint32_t binding,
|
||||||
|
const dawn::Sampler& sampler)
|
||||||
|
: binding(binding), sampler(sampler) {
|
||||||
|
}
|
||||||
|
|
||||||
|
BindingInitializationHelper::BindingInitializationHelper(uint32_t binding,
|
||||||
|
const dawn::TextureView& textureView)
|
||||||
|
: binding(binding), textureView(textureView) {
|
||||||
|
}
|
||||||
|
|
||||||
|
BindingInitializationHelper::BindingInitializationHelper(uint32_t binding,
|
||||||
|
const dawn::BufferView& bufferView)
|
||||||
|
: binding(binding), bufferView(bufferView) {
|
||||||
|
}
|
||||||
|
|
||||||
|
dawn::BindGroupBinding BindingInitializationHelper::GetAsBinding() const {
|
||||||
|
dawn::BindGroupBinding result;
|
||||||
|
|
||||||
|
result.binding = binding;
|
||||||
|
result.sampler = sampler;
|
||||||
|
result.textureView = textureView;
|
||||||
|
result.bufferView = bufferView;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
dawn::BindGroup MakeBindGroup(
|
||||||
|
const dawn::Device& device,
|
||||||
|
const dawn::BindGroupLayout& layout,
|
||||||
|
std::initializer_list<BindingInitializationHelper> bindingsInitializer) {
|
||||||
|
std::vector<dawn::BindGroupBinding> bindings;
|
||||||
|
for (const BindingInitializationHelper& helper : bindingsInitializer) {
|
||||||
|
bindings.push_back(helper.GetAsBinding());
|
||||||
|
}
|
||||||
|
|
||||||
|
dawn::BindGroupDescriptor descriptor;
|
||||||
|
descriptor.layout = layout;
|
||||||
|
descriptor.numBindings = bindings.size();
|
||||||
|
descriptor.bindings = bindings.data();
|
||||||
|
|
||||||
|
return device.CreateBindGroup(&descriptor);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace utils
|
} // namespace utils
|
||||||
|
|
|
@ -65,4 +65,32 @@ namespace utils {
|
||||||
const dawn::Device& device,
|
const dawn::Device& device,
|
||||||
std::initializer_list<dawn::BindGroupLayoutBinding> bindingsInitializer);
|
std::initializer_list<dawn::BindGroupLayoutBinding> bindingsInitializer);
|
||||||
|
|
||||||
|
// Helpers to make creating bind groups look nicer:
|
||||||
|
//
|
||||||
|
// utils::MakeBindGroup(device, layout, {
|
||||||
|
// {0, mySampler},
|
||||||
|
// {1, myBufferView},
|
||||||
|
// {3, myTexture}
|
||||||
|
// });
|
||||||
|
|
||||||
|
// Structure with one constructor per-type of bindings, so that the initializer_list accepts
|
||||||
|
// bindings with the right type and no extra information.
|
||||||
|
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);
|
||||||
|
|
||||||
|
dawn::BindGroupBinding GetAsBinding() const;
|
||||||
|
|
||||||
|
uint32_t binding;
|
||||||
|
dawn::Sampler sampler;
|
||||||
|
dawn::TextureView textureView;
|
||||||
|
dawn::BufferView bufferView;
|
||||||
|
};
|
||||||
|
|
||||||
|
dawn::BindGroup MakeBindGroup(
|
||||||
|
const dawn::Device& device,
|
||||||
|
const dawn::BindGroupLayout& layout,
|
||||||
|
std::initializer_list<BindingInitializationHelper> bindingsInitializer);
|
||||||
|
|
||||||
} // namespace utils
|
} // namespace utils
|
||||||
|
|
Loading…
Reference in New Issue