Use a descriptor for PipelineLayout (#206)
Adds support for structures inside descriptors.
This commit is contained in:
parent
a2f9277dac
commit
f53f98bf86
|
@ -228,9 +228,7 @@ void initSim() {
|
||||||
.SetBindingsType(nxt::ShaderStageBit::Compute, nxt::BindingType::StorageBuffer, 1, 2)
|
.SetBindingsType(nxt::ShaderStageBit::Compute, nxt::BindingType::StorageBuffer, 1, 2)
|
||||||
.GetResult();
|
.GetResult();
|
||||||
|
|
||||||
nxt::PipelineLayout pl = device.CreatePipelineLayoutBuilder()
|
nxt::PipelineLayout pl = utils::MakeBasicPipelineLayout(device, &bgl);
|
||||||
.SetBindGroupLayout(0, bgl)
|
|
||||||
.GetResult();
|
|
||||||
|
|
||||||
updatePipeline = device.CreateComputePipelineBuilder()
|
updatePipeline = device.CreateComputePipelineBuilder()
|
||||||
.SetLayout(pl)
|
.SetLayout(pl)
|
||||||
|
|
|
@ -67,9 +67,7 @@ void init() {
|
||||||
.SetBindingsType(nxt::ShaderStageBit::Compute, nxt::BindingType::StorageBuffer, 0, 1)
|
.SetBindingsType(nxt::ShaderStageBit::Compute, nxt::BindingType::StorageBuffer, 0, 1)
|
||||||
.GetResult();
|
.GetResult();
|
||||||
|
|
||||||
nxt::PipelineLayout pl = device.CreatePipelineLayoutBuilder()
|
nxt::PipelineLayout pl = utils::MakeBasicPipelineLayout(device, &bgl);
|
||||||
.SetBindGroupLayout(0, bgl)
|
|
||||||
.GetResult();
|
|
||||||
|
|
||||||
computePipeline = device.CreateComputePipelineBuilder()
|
computePipeline = device.CreateComputePipelineBuilder()
|
||||||
.SetLayout(pl)
|
.SetLayout(pl)
|
||||||
|
@ -108,9 +106,7 @@ void init() {
|
||||||
.SetBindingsType(nxt::ShaderStageBit::Fragment, nxt::BindingType::UniformBuffer, 0, 1)
|
.SetBindingsType(nxt::ShaderStageBit::Fragment, nxt::BindingType::UniformBuffer, 0, 1)
|
||||||
.GetResult();
|
.GetResult();
|
||||||
|
|
||||||
nxt::PipelineLayout pl = device.CreatePipelineLayoutBuilder()
|
nxt::PipelineLayout pl = utils::MakeBasicPipelineLayout(device, &bgl);
|
||||||
.SetBindGroupLayout(0, bgl)
|
|
||||||
.GetResult();
|
|
||||||
|
|
||||||
depthStencilView = CreateDefaultDepthStencilView(device);
|
depthStencilView = CreateDefaultDepthStencilView(device);
|
||||||
|
|
||||||
|
|
|
@ -165,9 +165,7 @@ void init() {
|
||||||
.SetBindingsType(nxt::ShaderStageBit::Vertex, nxt::BindingType::UniformBuffer, 0, 2)
|
.SetBindingsType(nxt::ShaderStageBit::Vertex, nxt::BindingType::UniformBuffer, 0, 2)
|
||||||
.GetResult();
|
.GetResult();
|
||||||
|
|
||||||
nxt::PipelineLayout pl = device.CreatePipelineLayoutBuilder()
|
nxt::PipelineLayout pl = utils::MakeBasicPipelineLayout(device, &bgl);
|
||||||
.SetBindGroupLayout(0, bgl)
|
|
||||||
.GetResult();
|
|
||||||
|
|
||||||
cameraBuffer = device.CreateBufferBuilder()
|
cameraBuffer = device.CreateBufferBuilder()
|
||||||
.SetAllowedUsage(nxt::BufferUsageBit::TransferDst | nxt::BufferUsageBit::Uniform)
|
.SetAllowedUsage(nxt::BufferUsageBit::TransferDst | nxt::BufferUsageBit::Uniform)
|
||||||
|
|
|
@ -115,9 +115,7 @@ void init() {
|
||||||
.SetBindingsType(nxt::ShaderStageBit::Fragment, nxt::BindingType::SampledTexture, 1, 1)
|
.SetBindingsType(nxt::ShaderStageBit::Fragment, nxt::BindingType::SampledTexture, 1, 1)
|
||||||
.GetResult();
|
.GetResult();
|
||||||
|
|
||||||
nxt::PipelineLayout pl = device.CreatePipelineLayoutBuilder()
|
nxt::PipelineLayout pl = utils::MakeBasicPipelineLayout(device, &bgl);
|
||||||
.SetBindGroupLayout(0, bgl)
|
|
||||||
.GetResult();
|
|
||||||
|
|
||||||
depthStencilView = CreateDefaultDepthStencilView(device);
|
depthStencilView = CreateDefaultDepthStencilView(device);
|
||||||
|
|
||||||
|
|
|
@ -58,9 +58,7 @@ void init() {
|
||||||
.SetBindingsType(nxt::ShaderStageBit::Fragment, nxt::BindingType::UniformBuffer, 0, 1)
|
.SetBindingsType(nxt::ShaderStageBit::Fragment, nxt::BindingType::UniformBuffer, 0, 1)
|
||||||
.GetResult();
|
.GetResult();
|
||||||
|
|
||||||
nxt::PipelineLayout pl = device.CreatePipelineLayoutBuilder()
|
nxt::PipelineLayout pl = utils::MakeBasicPipelineLayout(device, &bgl);
|
||||||
.SetBindGroupLayout(0, bgl)
|
|
||||||
.GetResult();
|
|
||||||
|
|
||||||
depthStencilView = CreateDefaultDepthStencilView(device);
|
depthStencilView = CreateDefaultDepthStencilView(device);
|
||||||
|
|
||||||
|
|
|
@ -127,9 +127,7 @@ void initPipelinePost() {
|
||||||
.SetBindingsType(nxt::ShaderStageBit::Fragment, nxt::BindingType::SampledTexture, 1, 1)
|
.SetBindingsType(nxt::ShaderStageBit::Fragment, nxt::BindingType::SampledTexture, 1, 1)
|
||||||
.GetResult();
|
.GetResult();
|
||||||
|
|
||||||
nxt::PipelineLayout pl = device.CreatePipelineLayoutBuilder()
|
nxt::PipelineLayout pl = utils::MakeBasicPipelineLayout(device, &bgl);
|
||||||
.SetBindGroupLayout(0, bgl)
|
|
||||||
.GetResult();
|
|
||||||
|
|
||||||
pipelinePost = device.CreateRenderPipelineBuilder()
|
pipelinePost = device.CreateRenderPipelineBuilder()
|
||||||
.SetColorAttachmentFormat(0, nxt::TextureFormat::R8G8B8A8Unorm)
|
.SetColorAttachmentFormat(0, nxt::TextureFormat::R8G8B8A8Unorm)
|
||||||
|
|
|
@ -286,9 +286,7 @@ namespace {
|
||||||
.SetDepthWriteEnabled(true)
|
.SetDepthWriteEnabled(true)
|
||||||
.GetResult();
|
.GetResult();
|
||||||
|
|
||||||
auto pipelineLayout = device.CreatePipelineLayoutBuilder()
|
auto pipelineLayout = utils::MakeBasicPipelineLayout(device, &bindGroupLayout);
|
||||||
.SetBindGroupLayout(0, bindGroupLayout)
|
|
||||||
.GetResult();
|
|
||||||
auto pipeline = device.CreateRenderPipelineBuilder()
|
auto pipeline = device.CreateRenderPipelineBuilder()
|
||||||
.SetColorAttachmentFormat(0, GetPreferredSwapChainTextureFormat())
|
.SetColorAttachmentFormat(0, GetPreferredSwapChainTextureFormat())
|
||||||
.SetDepthStencilAttachmentFormat(nxt::TextureFormat::D32FloatS8Uint)
|
.SetDepthStencilAttachmentFormat(nxt::TextureFormat::D32FloatS8Uint)
|
||||||
|
|
|
@ -155,8 +155,18 @@ def link_structure(struct, types):
|
||||||
def make_member(m):
|
def make_member(m):
|
||||||
return StructureMember(Name(m['name']), types[m['type']], m.get('annotation', 'value'))
|
return StructureMember(Name(m['name']), types[m['type']], m.get('annotation', 'value'))
|
||||||
|
|
||||||
# TODO(cwallez@chromium.org): Handle pointer members and their length
|
members = []
|
||||||
struct.members = [make_member(m) for m in struct.record['members']]
|
members_by_name = {}
|
||||||
|
for m in struct.record['members']:
|
||||||
|
member = make_member(m)
|
||||||
|
members.append(member)
|
||||||
|
members_by_name[member.name.canonical_case()] = member
|
||||||
|
struct.members = members
|
||||||
|
|
||||||
|
for (member, m) in zip(members, struct.record['members']):
|
||||||
|
# TODO(kainino@chromium.org): More robust pointer/length handling?
|
||||||
|
if 'length' in m:
|
||||||
|
member.length = members_by_name[m['length']]
|
||||||
|
|
||||||
def parse_json(json):
|
def parse_json(json):
|
||||||
category_to_parser = {
|
category_to_parser = {
|
||||||
|
|
|
@ -176,10 +176,10 @@
|
||||||
size_t memberLength = {{member_length(member, "record.")}};
|
size_t memberLength = {{member_length(member, "record.")}};
|
||||||
auto memberBuffer = reinterpret_cast<{{member_transfer_type(member)}}*>(buffer);
|
auto memberBuffer = reinterpret_cast<{{member_transfer_type(member)}}*>(buffer);
|
||||||
|
|
||||||
|
buffer += memberLength * {{member_transfer_sizeof(member)}};
|
||||||
for (size_t i = 0; i < memberLength; ++i) {
|
for (size_t i = 0; i < memberLength; ++i) {
|
||||||
{{serialize_member(member, "record." + memberName + "[i]", "memberBuffer[i]" )}}
|
{{serialize_member(member, "record." + memberName + "[i]", "memberBuffer[i]" )}}
|
||||||
}
|
}
|
||||||
buffer += memberLength * {{member_transfer_sizeof(member)}};
|
|
||||||
}
|
}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
}
|
}
|
||||||
|
|
27
next.json
27
next.json
|
@ -608,8 +608,11 @@
|
||||||
"returns": "render pipeline builder"
|
"returns": "render pipeline builder"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "create pipeline layout builder",
|
"name": "create pipeline layout",
|
||||||
"returns": "pipeline layout builder"
|
"returns": "pipeline layout",
|
||||||
|
"args": [
|
||||||
|
{"name": "descriptor", "type": "pipeline layout descriptor", "annotation": "const*"}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "create queue",
|
"name": "create queue",
|
||||||
|
@ -770,20 +773,12 @@
|
||||||
"pipeline layout": {
|
"pipeline layout": {
|
||||||
"category": "object"
|
"category": "object"
|
||||||
},
|
},
|
||||||
"pipeline layout builder": {
|
"pipeline layout descriptor": {
|
||||||
"category": "object",
|
"category": "structure",
|
||||||
"methods": [
|
"extensible": true,
|
||||||
{
|
"members": [
|
||||||
"name": "get result",
|
{"name": "num bind group layouts", "type": "uint32_t"},
|
||||||
"returns": "pipeline layout"
|
{"name": "bind group layouts", "type": "bind group layout", "annotation": "const*", "length": "num bind group layouts"}
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "set bind group layout",
|
|
||||||
"args": [
|
|
||||||
{"name": "group index", "type": "uint32_t"},
|
|
||||||
{"name": "layout", "type": "bind group layout"}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"primitive topology": {
|
"primitive topology": {
|
||||||
|
|
|
@ -395,7 +395,8 @@ namespace backend {
|
||||||
for (size_t i = 0; i < mBindgroups.size(); ++i) {
|
for (size_t i = 0; i < mBindgroups.size(); ++i) {
|
||||||
if (auto* bindgroup = mBindgroups[i]) {
|
if (auto* bindgroup = mBindgroups[i]) {
|
||||||
// TODO(kainino@chromium.org): bind group compatibility
|
// TODO(kainino@chromium.org): bind group compatibility
|
||||||
if (bindgroup->GetLayout() != mLastPipeline->GetLayout()->GetBindGroupLayout(i)) {
|
auto* pipelineBGL = mLastPipeline->GetLayout()->GetBindGroupLayout(i);
|
||||||
|
if (pipelineBGL && bindgroup->GetLayout() != pipelineBGL) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -119,8 +119,23 @@ namespace backend {
|
||||||
InputStateBuilder* DeviceBase::CreateInputStateBuilder() {
|
InputStateBuilder* DeviceBase::CreateInputStateBuilder() {
|
||||||
return new InputStateBuilder(this);
|
return new InputStateBuilder(this);
|
||||||
}
|
}
|
||||||
PipelineLayoutBuilder* DeviceBase::CreatePipelineLayoutBuilder() {
|
PipelineLayoutBase* DeviceBase::CreatePipelineLayout(
|
||||||
return new PipelineLayoutBuilder(this);
|
const nxt::PipelineLayoutDescriptor* descriptor) {
|
||||||
|
MaybeError validation = ValidatePipelineLayoutDescriptor(this, descriptor);
|
||||||
|
if (validation.IsError()) {
|
||||||
|
// TODO(cwallez@chromium.org): Implement the WebGPU error handling mechanism.
|
||||||
|
delete validation.AcquireError();
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
ResultOrError<PipelineLayoutBase*> maybePipelineLayout =
|
||||||
|
CreatePipelineLayoutImpl(descriptor);
|
||||||
|
if (maybePipelineLayout.IsError()) {
|
||||||
|
// TODO(cwallez@chromium.org): Implement the WebGPU error handling mechanism.
|
||||||
|
delete maybePipelineLayout.AcquireError();
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return maybePipelineLayout.AcquireSuccess();
|
||||||
}
|
}
|
||||||
QueueBase* DeviceBase::CreateQueue() {
|
QueueBase* DeviceBase::CreateQueue() {
|
||||||
ResultOrError<QueueBase*> maybeQueue = CreateQueueImpl();
|
ResultOrError<QueueBase*> maybeQueue = CreateQueueImpl();
|
||||||
|
|
|
@ -45,7 +45,6 @@ namespace backend {
|
||||||
virtual DepthStencilStateBase* CreateDepthStencilState(
|
virtual DepthStencilStateBase* CreateDepthStencilState(
|
||||||
DepthStencilStateBuilder* builder) = 0;
|
DepthStencilStateBuilder* builder) = 0;
|
||||||
virtual InputStateBase* CreateInputState(InputStateBuilder* builder) = 0;
|
virtual InputStateBase* CreateInputState(InputStateBuilder* builder) = 0;
|
||||||
virtual PipelineLayoutBase* CreatePipelineLayout(PipelineLayoutBuilder* builder) = 0;
|
|
||||||
virtual RenderPassDescriptorBase* CreateRenderPassDescriptor(
|
virtual RenderPassDescriptorBase* CreateRenderPassDescriptor(
|
||||||
RenderPassDescriptorBuilder* builder) = 0;
|
RenderPassDescriptorBuilder* builder) = 0;
|
||||||
virtual RenderPipelineBase* CreateRenderPipeline(RenderPipelineBuilder* builder) = 0;
|
virtual RenderPipelineBase* CreateRenderPipeline(RenderPipelineBuilder* builder) = 0;
|
||||||
|
@ -83,7 +82,7 @@ namespace backend {
|
||||||
ComputePipelineBuilder* CreateComputePipelineBuilder();
|
ComputePipelineBuilder* CreateComputePipelineBuilder();
|
||||||
DepthStencilStateBuilder* CreateDepthStencilStateBuilder();
|
DepthStencilStateBuilder* CreateDepthStencilStateBuilder();
|
||||||
InputStateBuilder* CreateInputStateBuilder();
|
InputStateBuilder* CreateInputStateBuilder();
|
||||||
PipelineLayoutBuilder* CreatePipelineLayoutBuilder();
|
PipelineLayoutBase* CreatePipelineLayout(const nxt::PipelineLayoutDescriptor* descriptor);
|
||||||
QueueBase* CreateQueue();
|
QueueBase* CreateQueue();
|
||||||
RenderPassDescriptorBuilder* CreateRenderPassDescriptorBuilder();
|
RenderPassDescriptorBuilder* CreateRenderPassDescriptorBuilder();
|
||||||
RenderPipelineBuilder* CreateRenderPipelineBuilder();
|
RenderPipelineBuilder* CreateRenderPipelineBuilder();
|
||||||
|
@ -98,6 +97,8 @@ namespace backend {
|
||||||
void Release();
|
void Release();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
virtual ResultOrError<PipelineLayoutBase*> CreatePipelineLayoutImpl(
|
||||||
|
const nxt::PipelineLayoutDescriptor* descriptor) = 0;
|
||||||
virtual ResultOrError<QueueBase*> CreateQueueImpl() = 0;
|
virtual ResultOrError<QueueBase*> CreateQueueImpl() = 0;
|
||||||
virtual ResultOrError<SamplerBase*> CreateSamplerImpl(
|
virtual ResultOrError<SamplerBase*> CreateSamplerImpl(
|
||||||
const nxt::SamplerDescriptor* descriptor) = 0;
|
const nxt::SamplerDescriptor* descriptor) = 0;
|
||||||
|
|
|
@ -36,7 +36,15 @@ namespace backend {
|
||||||
//
|
//
|
||||||
// Returning an error is done via:
|
// Returning an error is done via:
|
||||||
// NXT_RETURN_ERROR("My error message");
|
// NXT_RETURN_ERROR("My error message");
|
||||||
#define NXT_RETURN_ERROR(EXPR) return MakeError(EXPR, __FILE__, __func__, __LINE__)
|
#define NXT_RETURN_ERROR(MESSAGE) return MakeError(MESSAGE, __FILE__, __func__, __LINE__)
|
||||||
|
#define NXT_TRY_ASSERT(EXPR, MESSAGE) \
|
||||||
|
{ \
|
||||||
|
if (!(EXPR)) { \
|
||||||
|
NXT_RETURN_ERROR(MESSAGE); \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
for (;;) \
|
||||||
|
break
|
||||||
|
|
||||||
#define NXT_CONCAT1(x, y) x##y
|
#define NXT_CONCAT1(x, y) x##y
|
||||||
#define NXT_CONCAT2(x, y) NXT_CONCAT1(x, y)
|
#define NXT_CONCAT2(x, y) NXT_CONCAT1(x, y)
|
||||||
|
|
|
@ -27,10 +27,10 @@ namespace backend {
|
||||||
PipelineBase::PipelineBase(PipelineBuilder* builder)
|
PipelineBase::PipelineBase(PipelineBuilder* builder)
|
||||||
: mStageMask(builder->mStageMask), mLayout(std::move(builder->mLayout)) {
|
: mStageMask(builder->mStageMask), mLayout(std::move(builder->mLayout)) {
|
||||||
if (!mLayout) {
|
if (!mLayout) {
|
||||||
mLayout = builder->GetParentBuilder()
|
nxt::PipelineLayoutDescriptor descriptor;
|
||||||
->GetDevice()
|
descriptor.numBindGroupLayouts = 0;
|
||||||
->CreatePipelineLayoutBuilder()
|
descriptor.bindGroupLayouts = nullptr;
|
||||||
->GetResult();
|
mLayout = builder->GetParentBuilder()->GetDevice()->CreatePipelineLayout(&descriptor);
|
||||||
// Remove the external ref objects are created with
|
// Remove the external ref objects are created with
|
||||||
mLayout->Release();
|
mLayout->Release();
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,10 +20,37 @@
|
||||||
|
|
||||||
namespace backend {
|
namespace backend {
|
||||||
|
|
||||||
|
MaybeError ValidatePipelineLayoutDescriptor(DeviceBase*,
|
||||||
|
const nxt::PipelineLayoutDescriptor* descriptor) {
|
||||||
|
NXT_TRY_ASSERT(descriptor->nextInChain == nullptr, "nextInChain must be nullptr");
|
||||||
|
NXT_TRY_ASSERT(descriptor->numBindGroupLayouts <= kMaxBindGroups,
|
||||||
|
"too many bind group layouts");
|
||||||
|
for (uint32_t i = 0; i < descriptor->numBindGroupLayouts; ++i) {
|
||||||
|
NXT_TRY_ASSERT(descriptor->bindGroupLayouts[i].Get() != nullptr,
|
||||||
|
"bind group layouts may not be null");
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
// PipelineLayoutBase
|
// PipelineLayoutBase
|
||||||
|
|
||||||
PipelineLayoutBase::PipelineLayoutBase(PipelineLayoutBuilder* builder)
|
PipelineLayoutBase::PipelineLayoutBase(DeviceBase* device,
|
||||||
: mBindGroupLayouts(std::move(builder->mBindGroupLayouts)), mMask(builder->mMask) {
|
const nxt::PipelineLayoutDescriptor* descriptor) {
|
||||||
|
ASSERT(descriptor->numBindGroupLayouts <= kMaxBindGroups);
|
||||||
|
for (uint32_t group = 0; group < descriptor->numBindGroupLayouts; ++group) {
|
||||||
|
mBindGroupLayouts[group] =
|
||||||
|
reinterpret_cast<BindGroupLayoutBase*>(descriptor->bindGroupLayouts[group].Get());
|
||||||
|
mMask.set(group);
|
||||||
|
}
|
||||||
|
// TODO(kainino@chromium.org): It shouldn't be necessary to construct default bind
|
||||||
|
// group layouts here. Remove these and fix things so that they are not needed.
|
||||||
|
for (uint32_t group = descriptor->numBindGroupLayouts; group < kMaxBindGroups; ++group) {
|
||||||
|
auto builder = device->CreateBindGroupLayoutBuilder();
|
||||||
|
mBindGroupLayouts[group] = builder->GetResult();
|
||||||
|
// Remove the external ref objects are created with
|
||||||
|
mBindGroupLayouts[group]->Release();
|
||||||
|
builder->Release();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const BindGroupLayoutBase* PipelineLayoutBase::GetBindGroupLayout(size_t group) const {
|
const BindGroupLayoutBase* PipelineLayoutBase::GetBindGroupLayout(size_t group) const {
|
||||||
|
@ -49,40 +76,4 @@ namespace backend {
|
||||||
return kMaxBindGroups + 1;
|
return kMaxBindGroups + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// PipelineLayoutBuilder
|
|
||||||
|
|
||||||
PipelineLayoutBuilder::PipelineLayoutBuilder(DeviceBase* device) : Builder(device) {
|
|
||||||
}
|
|
||||||
|
|
||||||
PipelineLayoutBase* PipelineLayoutBuilder::GetResultImpl() {
|
|
||||||
// TODO(cwallez@chromium.org): this is a hack, have the null bind group layout somewhere in
|
|
||||||
// the device once we have a cache of BGL
|
|
||||||
for (size_t group = 0; group < kMaxBindGroups; ++group) {
|
|
||||||
if (!mBindGroupLayouts[group]) {
|
|
||||||
auto builder = mDevice->CreateBindGroupLayoutBuilder();
|
|
||||||
mBindGroupLayouts[group] = builder->GetResult();
|
|
||||||
// Remove the external ref objects are created with
|
|
||||||
mBindGroupLayouts[group]->Release();
|
|
||||||
builder->Release();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return mDevice->CreatePipelineLayout(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
void PipelineLayoutBuilder::SetBindGroupLayout(uint32_t groupIndex,
|
|
||||||
BindGroupLayoutBase* layout) {
|
|
||||||
if (groupIndex >= kMaxBindGroups) {
|
|
||||||
HandleError("groupIndex is over the maximum allowed");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (mMask[groupIndex]) {
|
|
||||||
HandleError("Bind group layout already specified");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
mBindGroupLayouts[groupIndex] = layout;
|
|
||||||
mMask.set(groupIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace backend
|
} // namespace backend
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
#ifndef BACKEND_PIPELINELAYOUT_H_
|
#ifndef BACKEND_PIPELINELAYOUT_H_
|
||||||
#define BACKEND_PIPELINELAYOUT_H_
|
#define BACKEND_PIPELINELAYOUT_H_
|
||||||
|
|
||||||
#include "backend/Builder.h"
|
#include "backend/Error.h"
|
||||||
#include "backend/Forward.h"
|
#include "backend/Forward.h"
|
||||||
#include "backend/RefCounted.h"
|
#include "backend/RefCounted.h"
|
||||||
#include "common/Constants.h"
|
#include "common/Constants.h"
|
||||||
|
@ -27,11 +27,14 @@
|
||||||
|
|
||||||
namespace backend {
|
namespace backend {
|
||||||
|
|
||||||
|
MaybeError ValidatePipelineLayoutDescriptor(DeviceBase*,
|
||||||
|
const nxt::PipelineLayoutDescriptor* descriptor);
|
||||||
|
|
||||||
using BindGroupLayoutArray = std::array<Ref<BindGroupLayoutBase>, kMaxBindGroups>;
|
using BindGroupLayoutArray = std::array<Ref<BindGroupLayoutBase>, kMaxBindGroups>;
|
||||||
|
|
||||||
class PipelineLayoutBase : public RefCounted {
|
class PipelineLayoutBase : public RefCounted {
|
||||||
public:
|
public:
|
||||||
PipelineLayoutBase(PipelineLayoutBuilder* builder);
|
PipelineLayoutBase(DeviceBase* device, const nxt::PipelineLayoutDescriptor* descriptor);
|
||||||
|
|
||||||
const BindGroupLayoutBase* GetBindGroupLayout(size_t group) const;
|
const BindGroupLayoutBase* GetBindGroupLayout(size_t group) const;
|
||||||
const std::bitset<kMaxBindGroups> GetBindGroupsLayoutMask() const;
|
const std::bitset<kMaxBindGroups> GetBindGroupsLayoutMask() const;
|
||||||
|
@ -49,22 +52,6 @@ namespace backend {
|
||||||
std::bitset<kMaxBindGroups> mMask;
|
std::bitset<kMaxBindGroups> mMask;
|
||||||
};
|
};
|
||||||
|
|
||||||
class PipelineLayoutBuilder : public Builder<PipelineLayoutBase> {
|
|
||||||
public:
|
|
||||||
PipelineLayoutBuilder(DeviceBase* device);
|
|
||||||
|
|
||||||
// NXT API
|
|
||||||
void SetBindGroupLayout(uint32_t groupIndex, BindGroupLayoutBase* layout);
|
|
||||||
|
|
||||||
private:
|
|
||||||
friend class PipelineLayoutBase;
|
|
||||||
|
|
||||||
PipelineLayoutBase* GetResultImpl() override;
|
|
||||||
|
|
||||||
BindGroupLayoutArray mBindGroupLayouts;
|
|
||||||
std::bitset<kMaxBindGroups> mMask;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace backend
|
} // namespace backend
|
||||||
|
|
||||||
#endif // BACKEND_PIPELINELAYOUT_H_
|
#endif // BACKEND_PIPELINELAYOUT_H_
|
||||||
|
|
|
@ -20,16 +20,13 @@
|
||||||
namespace backend {
|
namespace backend {
|
||||||
|
|
||||||
MaybeError ValidateSamplerDescriptor(DeviceBase*, const nxt::SamplerDescriptor* descriptor) {
|
MaybeError ValidateSamplerDescriptor(DeviceBase*, const nxt::SamplerDescriptor* descriptor) {
|
||||||
|
NXT_TRY_ASSERT(descriptor->nextInChain == nullptr, "nextInChain must be nullptr");
|
||||||
NXT_TRY(ValidateFilterMode(descriptor->minFilter));
|
NXT_TRY(ValidateFilterMode(descriptor->minFilter));
|
||||||
NXT_TRY(ValidateFilterMode(descriptor->magFilter));
|
NXT_TRY(ValidateFilterMode(descriptor->magFilter));
|
||||||
NXT_TRY(ValidateFilterMode(descriptor->mipmapFilter));
|
NXT_TRY(ValidateFilterMode(descriptor->mipmapFilter));
|
||||||
NXT_TRY(ValidateAddressMode(descriptor->addressModeU));
|
NXT_TRY(ValidateAddressMode(descriptor->addressModeU));
|
||||||
NXT_TRY(ValidateAddressMode(descriptor->addressModeV));
|
NXT_TRY(ValidateAddressMode(descriptor->addressModeV));
|
||||||
NXT_TRY(ValidateAddressMode(descriptor->addressModeW));
|
NXT_TRY(ValidateAddressMode(descriptor->addressModeW));
|
||||||
|
|
||||||
if (descriptor->nextInChain != nullptr) {
|
|
||||||
NXT_RETURN_ERROR("nextInChain must be nullptr");
|
|
||||||
}
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -285,8 +285,9 @@ namespace backend { namespace d3d12 {
|
||||||
InputStateBase* Device::CreateInputState(InputStateBuilder* builder) {
|
InputStateBase* Device::CreateInputState(InputStateBuilder* builder) {
|
||||||
return new InputState(this, builder);
|
return new InputState(this, builder);
|
||||||
}
|
}
|
||||||
PipelineLayoutBase* Device::CreatePipelineLayout(PipelineLayoutBuilder* builder) {
|
ResultOrError<PipelineLayoutBase*> Device::CreatePipelineLayoutImpl(
|
||||||
return new PipelineLayout(this, builder);
|
const nxt::PipelineLayoutDescriptor* descriptor) {
|
||||||
|
return new PipelineLayout(this, descriptor);
|
||||||
}
|
}
|
||||||
ResultOrError<QueueBase*> Device::CreateQueueImpl() {
|
ResultOrError<QueueBase*> Device::CreateQueueImpl() {
|
||||||
return new Queue(this);
|
return new Queue(this);
|
||||||
|
|
|
@ -47,7 +47,6 @@ namespace backend { namespace d3d12 {
|
||||||
ComputePipelineBase* CreateComputePipeline(ComputePipelineBuilder* builder) override;
|
ComputePipelineBase* CreateComputePipeline(ComputePipelineBuilder* builder) override;
|
||||||
DepthStencilStateBase* CreateDepthStencilState(DepthStencilStateBuilder* builder) override;
|
DepthStencilStateBase* CreateDepthStencilState(DepthStencilStateBuilder* builder) override;
|
||||||
InputStateBase* CreateInputState(InputStateBuilder* builder) override;
|
InputStateBase* CreateInputState(InputStateBuilder* builder) override;
|
||||||
PipelineLayoutBase* CreatePipelineLayout(PipelineLayoutBuilder* builder) override;
|
|
||||||
RenderPassDescriptorBase* CreateRenderPassDescriptor(
|
RenderPassDescriptorBase* CreateRenderPassDescriptor(
|
||||||
RenderPassDescriptorBuilder* builder) override;
|
RenderPassDescriptorBuilder* builder) override;
|
||||||
RenderPipelineBase* CreateRenderPipeline(RenderPipelineBuilder* builder) override;
|
RenderPipelineBase* CreateRenderPipeline(RenderPipelineBuilder* builder) override;
|
||||||
|
@ -79,6 +78,8 @@ namespace backend { namespace d3d12 {
|
||||||
void ExecuteCommandLists(std::initializer_list<ID3D12CommandList*> commandLists);
|
void ExecuteCommandLists(std::initializer_list<ID3D12CommandList*> commandLists);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
ResultOrError<PipelineLayoutBase*> CreatePipelineLayoutImpl(
|
||||||
|
const nxt::PipelineLayoutDescriptor* descriptor) override;
|
||||||
ResultOrError<QueueBase*> CreateQueueImpl() override;
|
ResultOrError<QueueBase*> CreateQueueImpl() override;
|
||||||
ResultOrError<SamplerBase*> CreateSamplerImpl(
|
ResultOrError<SamplerBase*> CreateSamplerImpl(
|
||||||
const nxt::SamplerDescriptor* descriptor) override;
|
const nxt::SamplerDescriptor* descriptor) override;
|
||||||
|
|
|
@ -22,8 +22,8 @@ using Microsoft::WRL::ComPtr;
|
||||||
|
|
||||||
namespace backend { namespace d3d12 {
|
namespace backend { namespace d3d12 {
|
||||||
|
|
||||||
PipelineLayout::PipelineLayout(Device* device, PipelineLayoutBuilder* builder)
|
PipelineLayout::PipelineLayout(Device* device, const nxt::PipelineLayoutDescriptor* descriptor)
|
||||||
: PipelineLayoutBase(builder), mDevice(device) {
|
: PipelineLayoutBase(device, descriptor) {
|
||||||
D3D12_ROOT_PARAMETER rootParameters[kMaxBindGroups * 2];
|
D3D12_ROOT_PARAMETER rootParameters[kMaxBindGroups * 2];
|
||||||
|
|
||||||
// A root parameter is one of these types
|
// A root parameter is one of these types
|
||||||
|
|
|
@ -25,7 +25,7 @@ namespace backend { namespace d3d12 {
|
||||||
|
|
||||||
class PipelineLayout : public PipelineLayoutBase {
|
class PipelineLayout : public PipelineLayoutBase {
|
||||||
public:
|
public:
|
||||||
PipelineLayout(Device* device, PipelineLayoutBuilder* builder);
|
PipelineLayout(Device* device, const nxt::PipelineLayoutDescriptor* descriptor);
|
||||||
|
|
||||||
uint32_t GetCbvUavSrvRootParameterIndex(uint32_t group) const;
|
uint32_t GetCbvUavSrvRootParameterIndex(uint32_t group) const;
|
||||||
uint32_t GetSamplerRootParameterIndex(uint32_t group) const;
|
uint32_t GetSamplerRootParameterIndex(uint32_t group) const;
|
||||||
|
@ -33,8 +33,6 @@ namespace backend { namespace d3d12 {
|
||||||
ComPtr<ID3D12RootSignature> GetRootSignature();
|
ComPtr<ID3D12RootSignature> GetRootSignature();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Device* mDevice;
|
|
||||||
|
|
||||||
std::array<uint32_t, kMaxBindGroups> mCbvUavSrvRootParameterInfo;
|
std::array<uint32_t, kMaxBindGroups> mCbvUavSrvRootParameterInfo;
|
||||||
std::array<uint32_t, kMaxBindGroups> mSamplerRootParameterInfo;
|
std::array<uint32_t, kMaxBindGroups> mSamplerRootParameterInfo;
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,6 @@ namespace backend { namespace metal {
|
||||||
ComputePipelineBase* CreateComputePipeline(ComputePipelineBuilder* builder) override;
|
ComputePipelineBase* CreateComputePipeline(ComputePipelineBuilder* builder) override;
|
||||||
DepthStencilStateBase* CreateDepthStencilState(DepthStencilStateBuilder* builder) override;
|
DepthStencilStateBase* CreateDepthStencilState(DepthStencilStateBuilder* builder) override;
|
||||||
InputStateBase* CreateInputState(InputStateBuilder* builder) override;
|
InputStateBase* CreateInputState(InputStateBuilder* builder) override;
|
||||||
PipelineLayoutBase* CreatePipelineLayout(PipelineLayoutBuilder* builder) override;
|
|
||||||
RenderPassDescriptorBase* CreateRenderPassDescriptor(
|
RenderPassDescriptorBase* CreateRenderPassDescriptor(
|
||||||
RenderPassDescriptorBuilder* builder) override;
|
RenderPassDescriptorBuilder* builder) override;
|
||||||
RenderPipelineBase* CreateRenderPipeline(RenderPipelineBuilder* builder) override;
|
RenderPipelineBase* CreateRenderPipeline(RenderPipelineBuilder* builder) override;
|
||||||
|
@ -65,6 +64,8 @@ namespace backend { namespace metal {
|
||||||
ResourceUploader* GetResourceUploader() const;
|
ResourceUploader* GetResourceUploader() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
ResultOrError<PipelineLayoutBase*> CreatePipelineLayoutImpl(
|
||||||
|
const nxt::PipelineLayoutDescriptor* descriptor) override;
|
||||||
ResultOrError<QueueBase*> CreateQueueImpl() override;
|
ResultOrError<QueueBase*> CreateQueueImpl() override;
|
||||||
ResultOrError<SamplerBase*> CreateSamplerImpl(
|
ResultOrError<SamplerBase*> CreateSamplerImpl(
|
||||||
const nxt::SamplerDescriptor* descriptor) override;
|
const nxt::SamplerDescriptor* descriptor) override;
|
||||||
|
|
|
@ -108,8 +108,9 @@ namespace backend { namespace metal {
|
||||||
InputStateBase* Device::CreateInputState(InputStateBuilder* builder) {
|
InputStateBase* Device::CreateInputState(InputStateBuilder* builder) {
|
||||||
return new InputState(builder);
|
return new InputState(builder);
|
||||||
}
|
}
|
||||||
PipelineLayoutBase* Device::CreatePipelineLayout(PipelineLayoutBuilder* builder) {
|
ResultOrError<PipelineLayoutBase*> Device::CreatePipelineLayoutImpl(
|
||||||
return new PipelineLayout(builder);
|
const nxt::PipelineLayoutDescriptor* descriptor) {
|
||||||
|
return new PipelineLayout(this, descriptor);
|
||||||
}
|
}
|
||||||
RenderPassDescriptorBase* Device::CreateRenderPassDescriptor(
|
RenderPassDescriptorBase* Device::CreateRenderPassDescriptor(
|
||||||
RenderPassDescriptorBuilder* builder) {
|
RenderPassDescriptorBuilder* builder) {
|
||||||
|
|
|
@ -27,9 +27,11 @@ namespace spirv_cross {
|
||||||
|
|
||||||
namespace backend { namespace metal {
|
namespace backend { namespace metal {
|
||||||
|
|
||||||
|
class Device;
|
||||||
|
|
||||||
class PipelineLayout : public PipelineLayoutBase {
|
class PipelineLayout : public PipelineLayoutBase {
|
||||||
public:
|
public:
|
||||||
PipelineLayout(PipelineLayoutBuilder* builder);
|
PipelineLayout(Device* device, const nxt::PipelineLayoutDescriptor* descriptor);
|
||||||
|
|
||||||
using BindingIndexInfo =
|
using BindingIndexInfo =
|
||||||
std::array<std::array<uint32_t, kMaxBindingsPerGroup>, kMaxBindGroups>;
|
std::array<std::array<uint32_t, kMaxBindingsPerGroup>, kMaxBindGroups>;
|
||||||
|
|
|
@ -15,10 +15,12 @@
|
||||||
#include "backend/metal/PipelineLayoutMTL.h"
|
#include "backend/metal/PipelineLayoutMTL.h"
|
||||||
|
|
||||||
#include "backend/BindGroupLayout.h"
|
#include "backend/BindGroupLayout.h"
|
||||||
|
#include "backend/metal/DeviceMTL.h"
|
||||||
|
|
||||||
namespace backend { namespace metal {
|
namespace backend { namespace metal {
|
||||||
|
|
||||||
PipelineLayout::PipelineLayout(PipelineLayoutBuilder* builder) : PipelineLayoutBase(builder) {
|
PipelineLayout::PipelineLayout(Device* device, const nxt::PipelineLayoutDescriptor* descriptor)
|
||||||
|
: PipelineLayoutBase(device, descriptor) {
|
||||||
// Each stage has its own numbering namespace in CompilerMSL.
|
// Each stage has its own numbering namespace in CompilerMSL.
|
||||||
for (auto stage : IterateStages(kAllStages)) {
|
for (auto stage : IterateStages(kAllStages)) {
|
||||||
// Buffer number 0 is reserved for push constants
|
// Buffer number 0 is reserved for push constants
|
||||||
|
|
|
@ -63,8 +63,9 @@ namespace backend { namespace null {
|
||||||
InputStateBase* Device::CreateInputState(InputStateBuilder* builder) {
|
InputStateBase* Device::CreateInputState(InputStateBuilder* builder) {
|
||||||
return new InputState(builder);
|
return new InputState(builder);
|
||||||
}
|
}
|
||||||
PipelineLayoutBase* Device::CreatePipelineLayout(PipelineLayoutBuilder* builder) {
|
ResultOrError<PipelineLayoutBase*> Device::CreatePipelineLayoutImpl(
|
||||||
return new PipelineLayout(builder);
|
const nxt::PipelineLayoutDescriptor* descriptor) {
|
||||||
|
return new PipelineLayout(this, descriptor);
|
||||||
}
|
}
|
||||||
ResultOrError<QueueBase*> Device::CreateQueueImpl() {
|
ResultOrError<QueueBase*> Device::CreateQueueImpl() {
|
||||||
return new Queue(this);
|
return new Queue(this);
|
||||||
|
|
|
@ -104,7 +104,6 @@ namespace backend { namespace null {
|
||||||
ComputePipelineBase* CreateComputePipeline(ComputePipelineBuilder* builder) override;
|
ComputePipelineBase* CreateComputePipeline(ComputePipelineBuilder* builder) override;
|
||||||
DepthStencilStateBase* CreateDepthStencilState(DepthStencilStateBuilder* builder) override;
|
DepthStencilStateBase* CreateDepthStencilState(DepthStencilStateBuilder* builder) override;
|
||||||
InputStateBase* CreateInputState(InputStateBuilder* builder) override;
|
InputStateBase* CreateInputState(InputStateBuilder* builder) override;
|
||||||
PipelineLayoutBase* CreatePipelineLayout(PipelineLayoutBuilder* builder) override;
|
|
||||||
RenderPassDescriptorBase* CreateRenderPassDescriptor(
|
RenderPassDescriptorBase* CreateRenderPassDescriptor(
|
||||||
RenderPassDescriptorBuilder* builder) override;
|
RenderPassDescriptorBuilder* builder) override;
|
||||||
RenderPipelineBase* CreateRenderPipeline(RenderPipelineBuilder* builder) override;
|
RenderPipelineBase* CreateRenderPipeline(RenderPipelineBuilder* builder) override;
|
||||||
|
@ -119,6 +118,8 @@ namespace backend { namespace null {
|
||||||
std::vector<std::unique_ptr<PendingOperation>> AcquirePendingOperations();
|
std::vector<std::unique_ptr<PendingOperation>> AcquirePendingOperations();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
ResultOrError<PipelineLayoutBase*> CreatePipelineLayoutImpl(
|
||||||
|
const nxt::PipelineLayoutDescriptor* descriptor) override;
|
||||||
ResultOrError<QueueBase*> CreateQueueImpl() override;
|
ResultOrError<QueueBase*> CreateQueueImpl() override;
|
||||||
ResultOrError<SamplerBase*> CreateSamplerImpl(
|
ResultOrError<SamplerBase*> CreateSamplerImpl(
|
||||||
const nxt::SamplerDescriptor* descriptor) override;
|
const nxt::SamplerDescriptor* descriptor) override;
|
||||||
|
|
|
@ -77,8 +77,9 @@ namespace backend { namespace opengl {
|
||||||
InputStateBase* Device::CreateInputState(InputStateBuilder* builder) {
|
InputStateBase* Device::CreateInputState(InputStateBuilder* builder) {
|
||||||
return new InputState(builder);
|
return new InputState(builder);
|
||||||
}
|
}
|
||||||
PipelineLayoutBase* Device::CreatePipelineLayout(PipelineLayoutBuilder* builder) {
|
ResultOrError<PipelineLayoutBase*> Device::CreatePipelineLayoutImpl(
|
||||||
return new PipelineLayout(builder);
|
const nxt::PipelineLayoutDescriptor* descriptor) {
|
||||||
|
return new PipelineLayout(this, descriptor);
|
||||||
}
|
}
|
||||||
ResultOrError<QueueBase*> Device::CreateQueueImpl() {
|
ResultOrError<QueueBase*> Device::CreateQueueImpl() {
|
||||||
return new Queue(this);
|
return new Queue(this);
|
||||||
|
|
|
@ -35,7 +35,6 @@ namespace backend { namespace opengl {
|
||||||
ComputePipelineBase* CreateComputePipeline(ComputePipelineBuilder* builder) override;
|
ComputePipelineBase* CreateComputePipeline(ComputePipelineBuilder* builder) override;
|
||||||
DepthStencilStateBase* CreateDepthStencilState(DepthStencilStateBuilder* builder) override;
|
DepthStencilStateBase* CreateDepthStencilState(DepthStencilStateBuilder* builder) override;
|
||||||
InputStateBase* CreateInputState(InputStateBuilder* builder) override;
|
InputStateBase* CreateInputState(InputStateBuilder* builder) override;
|
||||||
PipelineLayoutBase* CreatePipelineLayout(PipelineLayoutBuilder* builder) override;
|
|
||||||
RenderPassDescriptorBase* CreateRenderPassDescriptor(
|
RenderPassDescriptorBase* CreateRenderPassDescriptor(
|
||||||
RenderPassDescriptorBuilder* builder) override;
|
RenderPassDescriptorBuilder* builder) override;
|
||||||
RenderPipelineBase* CreateRenderPipeline(RenderPipelineBuilder* builder) override;
|
RenderPipelineBase* CreateRenderPipeline(RenderPipelineBuilder* builder) override;
|
||||||
|
@ -47,6 +46,8 @@ namespace backend { namespace opengl {
|
||||||
void TickImpl() override;
|
void TickImpl() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
ResultOrError<PipelineLayoutBase*> CreatePipelineLayoutImpl(
|
||||||
|
const nxt::PipelineLayoutDescriptor* descriptor) override;
|
||||||
ResultOrError<QueueBase*> CreateQueueImpl() override;
|
ResultOrError<QueueBase*> CreateQueueImpl() override;
|
||||||
ResultOrError<SamplerBase*> CreateSamplerImpl(
|
ResultOrError<SamplerBase*> CreateSamplerImpl(
|
||||||
const nxt::SamplerDescriptor* descriptor) override;
|
const nxt::SamplerDescriptor* descriptor) override;
|
||||||
|
|
|
@ -15,10 +15,12 @@
|
||||||
#include "backend/opengl/PipelineLayoutGL.h"
|
#include "backend/opengl/PipelineLayoutGL.h"
|
||||||
|
|
||||||
#include "backend/BindGroupLayout.h"
|
#include "backend/BindGroupLayout.h"
|
||||||
|
#include "backend/opengl/DeviceGL.h"
|
||||||
|
|
||||||
namespace backend { namespace opengl {
|
namespace backend { namespace opengl {
|
||||||
|
|
||||||
PipelineLayout::PipelineLayout(PipelineLayoutBuilder* builder) : PipelineLayoutBase(builder) {
|
PipelineLayout::PipelineLayout(Device* device, const nxt::PipelineLayoutDescriptor* descriptor)
|
||||||
|
: PipelineLayoutBase(device, descriptor) {
|
||||||
GLuint uboIndex = 0;
|
GLuint uboIndex = 0;
|
||||||
GLuint samplerIndex = 0;
|
GLuint samplerIndex = 0;
|
||||||
GLuint sampledTextureIndex = 0;
|
GLuint sampledTextureIndex = 0;
|
||||||
|
|
|
@ -25,7 +25,7 @@ namespace backend { namespace opengl {
|
||||||
|
|
||||||
class PipelineLayout : public PipelineLayoutBase {
|
class PipelineLayout : public PipelineLayoutBase {
|
||||||
public:
|
public:
|
||||||
PipelineLayout(PipelineLayoutBuilder* builder);
|
PipelineLayout(Device* device, const nxt::PipelineLayoutDescriptor* descriptor);
|
||||||
|
|
||||||
using BindingIndexInfo =
|
using BindingIndexInfo =
|
||||||
std::array<std::array<GLuint, kMaxBindingsPerGroup>, kMaxBindGroups>;
|
std::array<std::array<GLuint, kMaxBindingsPerGroup>, kMaxBindGroups>;
|
||||||
|
|
|
@ -21,8 +21,6 @@
|
||||||
|
|
||||||
namespace backend { namespace opengl {
|
namespace backend { namespace opengl {
|
||||||
|
|
||||||
class Device;
|
|
||||||
|
|
||||||
struct TextureFormatInfo {
|
struct TextureFormatInfo {
|
||||||
GLenum internalFormat;
|
GLenum internalFormat;
|
||||||
GLenum format;
|
GLenum format;
|
||||||
|
|
|
@ -241,8 +241,9 @@ namespace backend { namespace vulkan {
|
||||||
InputStateBase* Device::CreateInputState(InputStateBuilder* builder) {
|
InputStateBase* Device::CreateInputState(InputStateBuilder* builder) {
|
||||||
return new InputState(builder);
|
return new InputState(builder);
|
||||||
}
|
}
|
||||||
PipelineLayoutBase* Device::CreatePipelineLayout(PipelineLayoutBuilder* builder) {
|
ResultOrError<PipelineLayoutBase*> Device::CreatePipelineLayoutImpl(
|
||||||
return new PipelineLayout(builder);
|
const nxt::PipelineLayoutDescriptor* descriptor) {
|
||||||
|
return new PipelineLayout(this, descriptor);
|
||||||
}
|
}
|
||||||
ResultOrError<QueueBase*> Device::CreateQueueImpl() {
|
ResultOrError<QueueBase*> Device::CreateQueueImpl() {
|
||||||
return new Queue(this);
|
return new Queue(this);
|
||||||
|
|
|
@ -72,7 +72,6 @@ namespace backend { namespace vulkan {
|
||||||
ComputePipelineBase* CreateComputePipeline(ComputePipelineBuilder* builder) override;
|
ComputePipelineBase* CreateComputePipeline(ComputePipelineBuilder* builder) override;
|
||||||
DepthStencilStateBase* CreateDepthStencilState(DepthStencilStateBuilder* builder) override;
|
DepthStencilStateBase* CreateDepthStencilState(DepthStencilStateBuilder* builder) override;
|
||||||
InputStateBase* CreateInputState(InputStateBuilder* builder) override;
|
InputStateBase* CreateInputState(InputStateBuilder* builder) override;
|
||||||
PipelineLayoutBase* CreatePipelineLayout(PipelineLayoutBuilder* builder) override;
|
|
||||||
RenderPassDescriptorBase* CreateRenderPassDescriptor(
|
RenderPassDescriptorBase* CreateRenderPassDescriptor(
|
||||||
RenderPassDescriptorBuilder* builder) override;
|
RenderPassDescriptorBuilder* builder) override;
|
||||||
RenderPipelineBase* CreateRenderPipeline(RenderPipelineBuilder* builder) override;
|
RenderPipelineBase* CreateRenderPipeline(RenderPipelineBuilder* builder) override;
|
||||||
|
@ -84,6 +83,8 @@ namespace backend { namespace vulkan {
|
||||||
void TickImpl() override;
|
void TickImpl() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
ResultOrError<PipelineLayoutBase*> CreatePipelineLayoutImpl(
|
||||||
|
const nxt::PipelineLayoutDescriptor* descriptor) override;
|
||||||
ResultOrError<QueueBase*> CreateQueueImpl() override;
|
ResultOrError<QueueBase*> CreateQueueImpl() override;
|
||||||
ResultOrError<SamplerBase*> CreateSamplerImpl(
|
ResultOrError<SamplerBase*> CreateSamplerImpl(
|
||||||
const nxt::SamplerDescriptor* descriptor) override;
|
const nxt::SamplerDescriptor* descriptor) override;
|
||||||
|
|
|
@ -22,8 +22,8 @@
|
||||||
|
|
||||||
namespace backend { namespace vulkan {
|
namespace backend { namespace vulkan {
|
||||||
|
|
||||||
PipelineLayout::PipelineLayout(PipelineLayoutBuilder* builder)
|
PipelineLayout::PipelineLayout(Device* device, const nxt::PipelineLayoutDescriptor* descriptor)
|
||||||
: PipelineLayoutBase(builder), mDevice(ToBackend(builder->GetDevice())) {
|
: PipelineLayoutBase(device, descriptor), mDevice(device) {
|
||||||
// Compute the array of VkDescriptorSetLayouts that will be chained in the create info.
|
// Compute the array of VkDescriptorSetLayouts that will be chained in the create info.
|
||||||
// TODO(cwallez@chromium.org) Vulkan doesn't allow holes in this array, should we expose
|
// TODO(cwallez@chromium.org) Vulkan doesn't allow holes in this array, should we expose
|
||||||
// this constraints at the NXT level?
|
// this constraints at the NXT level?
|
||||||
|
|
|
@ -25,7 +25,7 @@ namespace backend { namespace vulkan {
|
||||||
|
|
||||||
class PipelineLayout : public PipelineLayoutBase {
|
class PipelineLayout : public PipelineLayoutBase {
|
||||||
public:
|
public:
|
||||||
PipelineLayout(PipelineLayoutBuilder* builder);
|
PipelineLayout(Device* device, const nxt::PipelineLayoutDescriptor* descriptor);
|
||||||
~PipelineLayout();
|
~PipelineLayout();
|
||||||
|
|
||||||
VkPipelineLayout GetHandle() const;
|
VkPipelineLayout GetHandle() const;
|
||||||
|
|
|
@ -41,9 +41,7 @@ class BlendStateTest : public NXTTest {
|
||||||
.SetBindingsType(nxt::ShaderStageBit::Fragment, nxt::BindingType::UniformBuffer, 0, 1)
|
.SetBindingsType(nxt::ShaderStageBit::Fragment, nxt::BindingType::UniformBuffer, 0, 1)
|
||||||
.GetResult();
|
.GetResult();
|
||||||
|
|
||||||
pipelineLayout = device.CreatePipelineLayoutBuilder()
|
pipelineLayout = utils::MakeBasicPipelineLayout(device, &bindGroupLayout);
|
||||||
.SetBindGroupLayout(0, bindGroupLayout)
|
|
||||||
.GetResult();
|
|
||||||
|
|
||||||
renderPass = utils::CreateBasicRenderPass(device, kRTSize, kRTSize);
|
renderPass = utils::CreateBasicRenderPass(device, kRTSize, kRTSize);
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,9 +82,7 @@ class DepthStencilStateTest : public NXTTest {
|
||||||
.SetBindingsType(nxt::ShaderStageBit::Vertex | nxt::ShaderStageBit::Fragment, nxt::BindingType::UniformBuffer, 0, 1)
|
.SetBindingsType(nxt::ShaderStageBit::Vertex | nxt::ShaderStageBit::Fragment, nxt::BindingType::UniformBuffer, 0, 1)
|
||||||
.GetResult();
|
.GetResult();
|
||||||
|
|
||||||
pipelineLayout = device.CreatePipelineLayoutBuilder()
|
pipelineLayout = utils::MakeBasicPipelineLayout(device, &bindGroupLayout);
|
||||||
.SetBindGroupLayout(0, bindGroupLayout)
|
|
||||||
.GetResult();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct TestSpec {
|
struct TestSpec {
|
||||||
|
|
|
@ -49,9 +49,7 @@ class PushConstantTest: public NXTTest {
|
||||||
.SetBindingsType(kAllStages, nxt::BindingType::StorageBuffer, 0, extraBuffer ? 2 : 1)
|
.SetBindingsType(kAllStages, nxt::BindingType::StorageBuffer, 0, extraBuffer ? 2 : 1)
|
||||||
.GetResult();
|
.GetResult();
|
||||||
|
|
||||||
nxt::PipelineLayout pl = device.CreatePipelineLayoutBuilder()
|
nxt::PipelineLayout pl = utils::MakeBasicPipelineLayout(device, &bgl);
|
||||||
.SetBindGroupLayout(0, bgl)
|
|
||||||
.GetResult();
|
|
||||||
|
|
||||||
nxt::BufferView views[2] = {
|
nxt::BufferView views[2] = {
|
||||||
buf1.CreateBufferViewBuilder().SetExtent(0, 4).GetResult(),
|
buf1.CreateBufferViewBuilder().SetExtent(0, 4).GetResult(),
|
||||||
|
@ -155,7 +153,7 @@ class PushConstantTest: public NXTTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
nxt::PipelineLayout MakeEmptyLayout() {
|
nxt::PipelineLayout MakeEmptyLayout() {
|
||||||
return device.CreatePipelineLayoutBuilder().GetResult();
|
return utils::MakeBasicPipelineLayout(device, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// The render pipeline adds one to the red channel for successful vertex push constant test
|
// The render pipeline adds one to the red channel for successful vertex push constant test
|
||||||
|
|
|
@ -28,8 +28,7 @@ class DrawQuad {
|
||||||
vsModule = utils::CreateShaderModule(*device, nxt::ShaderStage::Vertex, vsSource);
|
vsModule = utils::CreateShaderModule(*device, nxt::ShaderStage::Vertex, vsSource);
|
||||||
fsModule = utils::CreateShaderModule(*device, nxt::ShaderStage::Fragment, fsSource);
|
fsModule = utils::CreateShaderModule(*device, nxt::ShaderStage::Fragment, fsSource);
|
||||||
|
|
||||||
pipelineLayout = device->CreatePipelineLayoutBuilder()
|
pipelineLayout = utils::MakeBasicPipelineLayout(*device, nullptr);
|
||||||
.GetResult();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Draw(nxt::CommandBufferBuilder* builder) {
|
void Draw(nxt::CommandBufferBuilder* builder) {
|
||||||
|
|
|
@ -48,9 +48,7 @@ protected:
|
||||||
.SetBindingsType(nxt::ShaderStageBit::Fragment, nxt::BindingType::SampledTexture, 1, 1)
|
.SetBindingsType(nxt::ShaderStageBit::Fragment, nxt::BindingType::SampledTexture, 1, 1)
|
||||||
.GetResult();
|
.GetResult();
|
||||||
|
|
||||||
auto pipelineLayout = device.CreatePipelineLayoutBuilder()
|
auto pipelineLayout = utils::MakeBasicPipelineLayout(device, &mBindGroupLayout);
|
||||||
.SetBindGroupLayout(0, mBindGroupLayout)
|
|
||||||
.GetResult();
|
|
||||||
|
|
||||||
auto vsModule = utils::CreateShaderModule(device, nxt::ShaderStage::Vertex, R"(
|
auto vsModule = utils::CreateShaderModule(device, nxt::ShaderStage::Vertex, R"(
|
||||||
#version 450
|
#version 450
|
||||||
|
|
|
@ -408,6 +408,34 @@ TEST_F(WireTests, StructureOfValuesArgument) {
|
||||||
FlushClient();
|
FlushClient();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Test that the wire is able to send structures that contain objects
|
||||||
|
TEST_F(WireTests, StructureOfObjectArrayArgument) {
|
||||||
|
nxtBindGroupLayoutBuilder bglBuilder = nxtDeviceCreateBindGroupLayoutBuilder(device);
|
||||||
|
nxtBindGroupLayout bgl = nxtBindGroupLayoutBuilderGetResult(bglBuilder);
|
||||||
|
|
||||||
|
nxtBindGroupLayoutBuilder apiBglBuilder = api.GetNewBindGroupLayoutBuilder();
|
||||||
|
EXPECT_CALL(api, DeviceCreateBindGroupLayoutBuilder(apiDevice))
|
||||||
|
.WillOnce(Return(apiBglBuilder));
|
||||||
|
nxtBindGroupLayout apiBgl = api.GetNewBindGroupLayout();
|
||||||
|
EXPECT_CALL(api, BindGroupLayoutBuilderGetResult(apiBglBuilder))
|
||||||
|
.WillOnce(Return(apiBgl));
|
||||||
|
|
||||||
|
nxtPipelineLayoutDescriptor descriptor;
|
||||||
|
descriptor.nextInChain = nullptr;
|
||||||
|
descriptor.numBindGroupLayouts = 1;
|
||||||
|
descriptor.bindGroupLayouts = &bgl;
|
||||||
|
|
||||||
|
nxtDeviceCreatePipelineLayout(device, &descriptor);
|
||||||
|
EXPECT_CALL(api, DeviceCreatePipelineLayout(apiDevice, MatchesLambda([apiBgl](const nxtPipelineLayoutDescriptor* desc) -> bool {
|
||||||
|
return desc->nextInChain == nullptr &&
|
||||||
|
desc->numBindGroupLayouts == 1 &&
|
||||||
|
desc->bindGroupLayouts[0] == apiBgl;
|
||||||
|
})))
|
||||||
|
.WillOnce(Return(nullptr));
|
||||||
|
|
||||||
|
FlushClient();
|
||||||
|
}
|
||||||
|
|
||||||
// Test that the server doesn't forward calls to error objects or with error objects
|
// Test that the server doesn't forward calls to error objects or with error objects
|
||||||
// Also test that when GetResult is called on an error builder, the error callback is fired
|
// Also test that when GetResult is called on an error builder, the error callback is fired
|
||||||
TEST_F(WireTests, CallsSkippedAfterBuilderError) {
|
TEST_F(WireTests, CallsSkippedAfterBuilderError) {
|
||||||
|
|
|
@ -24,7 +24,7 @@ class RenderPipelineValidationTest : public ValidationTest {
|
||||||
|
|
||||||
renderpass = CreateSimpleRenderPass();
|
renderpass = CreateSimpleRenderPass();
|
||||||
|
|
||||||
pipelineLayout = device.CreatePipelineLayoutBuilder().GetResult();
|
nxt::PipelineLayout pl = utils::MakeBasicPipelineLayout(device, nullptr);
|
||||||
|
|
||||||
inputState = device.CreateInputStateBuilder().GetResult();
|
inputState = device.CreateInputStateBuilder().GetResult();
|
||||||
|
|
||||||
|
|
|
@ -149,5 +149,17 @@ namespace utils {
|
||||||
|
|
||||||
return desc;
|
return desc;
|
||||||
}
|
}
|
||||||
|
nxt::PipelineLayout MakeBasicPipelineLayout(const nxt::Device& device,
|
||||||
|
const nxt::BindGroupLayout* bindGroupLayout) {
|
||||||
|
nxt::PipelineLayoutDescriptor descriptor;
|
||||||
|
if (bindGroupLayout) {
|
||||||
|
descriptor.numBindGroupLayouts = 1;
|
||||||
|
descriptor.bindGroupLayouts = bindGroupLayout;
|
||||||
|
} else {
|
||||||
|
descriptor.numBindGroupLayouts = 0;
|
||||||
|
descriptor.bindGroupLayouts = nullptr;
|
||||||
|
}
|
||||||
|
return device.CreatePipelineLayout(&descriptor);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace utils
|
} // namespace utils
|
||||||
|
|
|
@ -49,5 +49,7 @@ namespace utils {
|
||||||
uint32_t height);
|
uint32_t height);
|
||||||
|
|
||||||
nxt::SamplerDescriptor GetDefaultSamplerDescriptor();
|
nxt::SamplerDescriptor GetDefaultSamplerDescriptor();
|
||||||
|
nxt::PipelineLayout MakeBasicPipelineLayout(const nxt::Device& device,
|
||||||
|
const nxt::BindGroupLayout* bindGroupLayout);
|
||||||
|
|
||||||
} // namespace utils
|
} // namespace utils
|
||||||
|
|
Loading…
Reference in New Issue