Split Pipeline in Render and Compute, common part

This commit is contained in:
Corentin Wallez 2017-07-14 10:58:07 -04:00 committed by Corentin Wallez
parent 00349e6e36
commit 29ced285d4
20 changed files with 496 additions and 245 deletions

137
next.json
View File

@ -387,12 +387,15 @@
] ]
}, },
{ {
"name": "set pipeline", "name": "set compute pipeline",
"args": [ "args": [
{"name": "pipeline", "type": "pipeline"} {"name": "pipeline", "type": "compute pipeline"}
], ]
"notes": [ },
"Not specifying graphics or compute because we know from render pass" {
"name": "set render pipeline",
"args": [
{"name": "pipeline", "type": "render pipeline"}
] ]
}, },
{ {
@ -433,6 +436,32 @@
{"value": 7, "name": "always"} {"value": 7, "name": "always"}
] ]
}, },
"compute pipeline": {
"category": "object"
},
"compute pipeline builder": {
"category": "object",
"methods": [
{
"name": "get result",
"returns": "compute pipeline"
},
{
"name": "set layout",
"args": [
{"name": "layout", "type": "pipeline layout"}
]
},
{
"name": "set stage",
"args": [
{"name": "stage", "type": "shader stage"},
{"name": "module", "type": "shader module"},
{"name": "entry point", "type": "char", "annotation": "const*", "length": "strlen"}
]
}
]
},
"device": { "device": {
"category": "object", "category": "object",
"methods": [ "methods": [
@ -465,8 +494,12 @@
"returns": "input state builder" "returns": "input state builder"
}, },
{ {
"name": "create pipeline builder", "name": "create compute pipeline builder",
"returns": "pipeline builder" "returns": "compute pipeline builder"
},
{
"name": "create render pipeline builder",
"returns": "render pipeline builder"
}, },
{ {
"name": "create pipeline layout builder", "name": "create pipeline layout builder",
@ -639,51 +672,6 @@
{"value": 1, "name": "instance"} {"value": 1, "name": "instance"}
] ]
}, },
"pipeline": {
"category": "object"
},
"pipeline builder": {
"category": "object",
"methods": [
{
"name": "get result",
"returns": "pipeline"
},
{
"name": "set layout",
"args": [
{"name": "layout", "type": "pipeline layout"}
]
},
{
"name": "set subpass",
"args": [
{"name": "render pass", "type": "render pass"},
{"name": "subpass", "type": "uint32_t"}
]
},
{
"name": "set stage",
"args": [
{"name": "stage", "type": "shader stage"},
{"name": "module", "type": "shader module"},
{"name": "entry point", "type": "char", "annotation": "const*", "length": "strlen"}
]
},
{
"name": "set input state",
"args": [
{"name": "input", "type": "input state"}
]
},
{
"name": "set depth stencil state",
"args": [
{"name": "depth stencil state", "type": "depth stencil state"}
]
}
]
},
"pipeline layout": { "pipeline layout": {
"category": "object" "category": "object"
}, },
@ -775,6 +763,51 @@
"render pass": { "render pass": {
"category": "object" "category": "object"
}, },
"render pipeline": {
"category": "object"
},
"render pipeline builder": {
"category": "object",
"methods": [
{
"name": "get result",
"returns": "render pipeline"
},
{
"name": "set layout",
"args": [
{"name": "layout", "type": "pipeline layout"}
]
},
{
"name": "set subpass",
"args": [
{"name": "render pass", "type": "render pass"},
{"name": "subpass", "type": "uint32_t"}
]
},
{
"name": "set stage",
"args": [
{"name": "stage", "type": "shader stage"},
{"name": "module", "type": "shader module"},
{"name": "entry point", "type": "char", "annotation": "const*", "length": "strlen"}
]
},
{
"name": "set input state",
"args": [
{"name": "input", "type": "input state"}
]
},
{
"name": "set depth stencil state",
"args": [
{"name": "depth stencil state", "type": "depth stencil state"}
]
}
]
},
"sampler": { "sampler": {
"category": "object" "category": "object"
}, },

View File

@ -253,6 +253,8 @@ list(APPEND BACKEND_SOURCES
${BACKEND_DIR}/CommandAllocator.h ${BACKEND_DIR}/CommandAllocator.h
${BACKEND_DIR}/CommandBuffer.cpp ${BACKEND_DIR}/CommandBuffer.cpp
${BACKEND_DIR}/CommandBuffer.h ${BACKEND_DIR}/CommandBuffer.h
${BACKEND_DIR}/ComputePipeline.cpp
${BACKEND_DIR}/ComputePipeline.h
${BACKEND_DIR}/DepthStencilState.cpp ${BACKEND_DIR}/DepthStencilState.cpp
${BACKEND_DIR}/DepthStencilState.h ${BACKEND_DIR}/DepthStencilState.h
${BACKEND_DIR}/CommandBufferStateTracker.cpp ${BACKEND_DIR}/CommandBufferStateTracker.cpp
@ -264,6 +266,8 @@ list(APPEND BACKEND_SOURCES
${BACKEND_DIR}/Framebuffer.h ${BACKEND_DIR}/Framebuffer.h
${BACKEND_DIR}/InputState.cpp ${BACKEND_DIR}/InputState.cpp
${BACKEND_DIR}/InputState.h ${BACKEND_DIR}/InputState.h
${BACKEND_DIR}/RenderPipeline.cpp
${BACKEND_DIR}/RenderPipeline.h
${BACKEND_DIR}/PerStage.cpp ${BACKEND_DIR}/PerStage.cpp
${BACKEND_DIR}/PerStage.h ${BACKEND_DIR}/PerStage.h
${BACKEND_DIR}/Pipeline.cpp ${BACKEND_DIR}/Pipeline.cpp

View File

@ -18,10 +18,11 @@
#include "backend/Buffer.h" #include "backend/Buffer.h"
#include "backend/Commands.h" #include "backend/Commands.h"
#include "backend/CommandBufferStateTracker.h" #include "backend/CommandBufferStateTracker.h"
#include "backend/ComputePipeline.h"
#include "backend/Device.h" #include "backend/Device.h"
#include "backend/InputState.h" #include "backend/InputState.h"
#include "backend/Pipeline.h"
#include "backend/PipelineLayout.h" #include "backend/PipelineLayout.h"
#include "backend/RenderPipeline.h"
#include "backend/Texture.h" #include "backend/Texture.h"
#include <cstring> #include <cstring>
@ -181,10 +182,16 @@ namespace backend {
cmd->~EndRenderSubpassCmd(); cmd->~EndRenderSubpassCmd();
} }
break; break;
case Command::SetPipeline: case Command::SetComputePipeline:
{ {
SetPipelineCmd* cmd = commands->NextCommand<SetPipelineCmd>(); SetComputePipelineCmd* cmd = commands->NextCommand<SetComputePipelineCmd>();
cmd->~SetPipelineCmd(); cmd->~SetComputePipelineCmd();
}
break;
case Command::SetRenderPipeline:
{
SetRenderPipelineCmd* cmd = commands->NextCommand<SetRenderPipelineCmd>();
cmd->~SetRenderPipelineCmd();
} }
break; break;
case Command::SetPushConstants: case Command::SetPushConstants:
@ -290,8 +297,12 @@ namespace backend {
commands->NextCommand<EndRenderSubpassCmd>(); commands->NextCommand<EndRenderSubpassCmd>();
break; break;
case Command::SetPipeline: case Command::SetComputePipeline:
commands->NextCommand<SetPipelineCmd>(); commands->NextCommand<SetComputePipelineCmd>();
break;
case Command::SetRenderPipeline:
commands->NextCommand<SetRenderPipelineCmd>();
break; break;
case Command::SetPushConstants: case Command::SetPushConstants:
@ -484,11 +495,21 @@ namespace backend {
} }
break; break;
case Command::SetPipeline: case Command::SetComputePipeline:
{ {
SetPipelineCmd* cmd = iterator.NextCommand<SetPipelineCmd>(); SetComputePipelineCmd* cmd = iterator.NextCommand<SetComputePipelineCmd>();
PipelineBase* pipeline = cmd->pipeline.Get(); ComputePipelineBase* pipeline = cmd->pipeline.Get();
if (!state->SetPipeline(pipeline)) { if (!state->SetComputePipeline(pipeline)) {
return false;
}
}
break;
case Command::SetRenderPipeline:
{
SetRenderPipelineCmd* cmd = iterator.NextCommand<SetRenderPipelineCmd>();
RenderPipelineBase* pipeline = cmd->pipeline.Get();
if (!state->SetRenderPipeline(pipeline)) {
return false; return false;
} }
} }
@ -681,9 +702,15 @@ namespace backend {
allocator.Allocate<EndRenderSubpassCmd>(Command::EndRenderSubpass); allocator.Allocate<EndRenderSubpassCmd>(Command::EndRenderSubpass);
} }
void CommandBufferBuilder::SetPipeline(PipelineBase* pipeline) { void CommandBufferBuilder::SetComputePipeline(ComputePipelineBase* pipeline) {
SetPipelineCmd* cmd = allocator.Allocate<SetPipelineCmd>(Command::SetPipeline); SetComputePipelineCmd* cmd = allocator.Allocate<SetComputePipelineCmd>(Command::SetComputePipeline);
new(cmd) SetPipelineCmd; new(cmd) SetComputePipelineCmd;
cmd->pipeline = pipeline;
}
void CommandBufferBuilder::SetRenderPipeline(RenderPipelineBase* pipeline) {
SetRenderPipelineCmd* cmd = allocator.Allocate<SetRenderPipelineCmd>(Command::SetRenderPipeline);
new(cmd) SetRenderPipelineCmd;
cmd->pipeline = pipeline; cmd->pipeline = pipeline;
} }

View File

@ -78,7 +78,8 @@ namespace backend {
void EndRenderPass(); void EndRenderPass();
void EndRenderSubpass(); void EndRenderSubpass();
void SetPushConstants(nxt::ShaderStageBit stage, uint32_t offset, uint32_t count, const void* data); void SetPushConstants(nxt::ShaderStageBit stage, uint32_t offset, uint32_t count, const void* data);
void SetPipeline(PipelineBase* pipeline); void SetComputePipeline(ComputePipelineBase* pipeline);
void SetRenderPipeline(RenderPipelineBase* pipeline);
void SetStencilReference(uint32_t reference); void SetStencilReference(uint32_t reference);
void SetBindGroup(uint32_t groupIndex, BindGroupBase* group); void SetBindGroup(uint32_t groupIndex, BindGroupBase* group);
void SetIndexBuffer(BufferBase* buffer, uint32_t offset, nxt::IndexFormat format); void SetIndexBuffer(BufferBase* buffer, uint32_t offset, nxt::IndexFormat format);

View File

@ -18,11 +18,12 @@
#include "backend/BindGroup.h" #include "backend/BindGroup.h"
#include "backend/BindGroupLayout.h" #include "backend/BindGroupLayout.h"
#include "backend/Buffer.h" #include "backend/Buffer.h"
#include "backend/ComputePipeline.h"
#include "backend/Framebuffer.h" #include "backend/Framebuffer.h"
#include "backend/InputState.h" #include "backend/InputState.h"
#include "backend/Pipeline.h"
#include "backend/PipelineLayout.h" #include "backend/PipelineLayout.h"
#include "backend/RenderPass.h" #include "backend/RenderPass.h"
#include "backend/RenderPipeline.h"
#include "backend/Texture.h" #include "backend/Texture.h"
#include "common/Assert.h" #include "common/Assert.h"
#include "common/BitSetIterator.h" #include "common/BitSetIterator.h"
@ -257,47 +258,33 @@ namespace backend {
return true; return true;
} }
bool CommandBufferStateTracker::SetPipeline(PipelineBase* pipeline) { bool CommandBufferStateTracker::SetComputePipeline(ComputePipelineBase* pipeline) {
PipelineLayoutBase* layout = pipeline->GetLayout(); if (!aspects[VALIDATION_ASPECT_COMPUTE_PASS]) {
builder->HandleError("A compute pass must be active when a compute pipeline is set");
if (pipeline->IsCompute()) { return false;
if (!aspects[VALIDATION_ASPECT_COMPUTE_PASS]) {
builder->HandleError("A compute pass must be active when a compute pipeline is set");
return false;
}
if (currentRenderPass) {
builder->HandleError("Can't use a compute pipeline while a render pass is active");
return false;
}
aspects.set(VALIDATION_ASPECT_COMPUTE_PIPELINE);
} else {
if (!aspects[VALIDATION_ASPECT_RENDER_SUBPASS]) {
builder->HandleError("A render subpass must be active when a render pipeline is set");
return false;
}
if (!pipeline->GetRenderPass()->IsCompatibleWith(currentRenderPass)) {
builder->HandleError("Pipeline is incompatible with this render pass");
return false;
}
aspects.set(VALIDATION_ASPECT_RENDER_PIPELINE);
} }
aspects.reset(VALIDATION_ASPECT_BIND_GROUPS); if (currentRenderPass) {
bindgroupsSet = ~layout->GetBindGroupsLayoutMask(); builder->HandleError("Can't use a compute pipeline while a render pass is active");
return false;
// Only bindgroups that were not the same layout in the last pipeline need to be set again.
if (lastPipeline) {
PipelineLayoutBase* lastLayout = lastPipeline->GetLayout();
for (uint32_t i = 0; i < kMaxBindGroups; ++i) {
if (lastLayout->GetBindGroupLayout(i) == layout->GetBindGroupLayout(i)) {
bindgroupsSet |= uint64_t(1) << i;
} else {
break;
}
}
} }
aspects.set(VALIDATION_ASPECT_COMPUTE_PIPELINE);
lastPipeline = pipeline; return SetPipelineCommon(pipeline);
return true; }
bool CommandBufferStateTracker::SetRenderPipeline(RenderPipelineBase* pipeline) {
if (!aspects[VALIDATION_ASPECT_RENDER_SUBPASS]) {
builder->HandleError("A render subpass must be active when a render pipeline is set");
return false;
}
if (!pipeline->GetRenderPass()->IsCompatibleWith(currentRenderPass)) {
builder->HandleError("Pipeline is incompatible with this render pass");
return false;
}
aspects.set(VALIDATION_ASPECT_RENDER_PIPELINE);
lastRenderPipeline = pipeline;
return SetPipelineCommon(pipeline);
} }
bool CommandBufferStateTracker::SetBindGroup(uint32_t index, BindGroupBase* bindgroup) { bool CommandBufferStateTracker::SetBindGroup(uint32_t index, BindGroupBase* bindgroup) {
@ -450,7 +437,7 @@ namespace backend {
return true; return true;
} }
// Assumes we have a pipeline already // Assumes we have a pipeline already
auto requiredInputs = lastPipeline->GetInputState()->GetInputsSetMask(); auto requiredInputs = lastRenderPipeline->GetInputState()->GetInputsSetMask();
if ((inputsSet & ~requiredInputs).none()) { if ((inputsSet & ~requiredInputs).none()) {
aspects.set(VALIDATION_ASPECT_VERTEX_BUFFERS); aspects.set(VALIDATION_ASPECT_VERTEX_BUFFERS);
return true; return true;
@ -533,6 +520,29 @@ namespace backend {
return true; return true;
} }
bool CommandBufferStateTracker::SetPipelineCommon(PipelineBase* pipeline) {
PipelineLayoutBase* layout = pipeline->GetLayout();
aspects.reset(VALIDATION_ASPECT_BIND_GROUPS);
bindgroupsSet = ~layout->GetBindGroupsLayoutMask();
// Only bindgroups that were not the same layout in the last pipeline need to be set again.
if (lastPipeline) {
PipelineLayoutBase* lastLayout = lastPipeline->GetLayout();
for (uint32_t i = 0; i < kMaxBindGroups; ++i) {
if (lastLayout->GetBindGroupLayout(i) == layout->GetBindGroupLayout(i)) {
bindgroupsSet |= uint64_t(1) << i;
} else {
break;
}
}
}
lastPipeline = pipeline;
return true;
}
void CommandBufferStateTracker::UnsetPipeline() { void CommandBufferStateTracker::UnsetPipeline() {
constexpr ValidationAspects pipelineDependentAspects = constexpr ValidationAspects pipelineDependentAspects =
1 << VALIDATION_ASPECT_RENDER_PIPELINE | 1 << VALIDATION_ASPECT_RENDER_PIPELINE |

View File

@ -45,7 +45,8 @@ namespace backend {
bool EndSubpass(); bool EndSubpass();
bool BeginRenderPass(RenderPassBase* renderPass, FramebufferBase* framebuffer); bool BeginRenderPass(RenderPassBase* renderPass, FramebufferBase* framebuffer);
bool EndRenderPass(); bool EndRenderPass();
bool SetPipeline(PipelineBase* pipeline); bool SetComputePipeline(ComputePipelineBase* pipeline);
bool SetRenderPipeline(RenderPipelineBase* pipeline);
bool SetBindGroup(uint32_t index, BindGroupBase* bindgroup); bool SetBindGroup(uint32_t index, BindGroupBase* bindgroup);
bool SetIndexBuffer(BufferBase* buffer); bool SetIndexBuffer(BufferBase* buffer);
bool SetVertexBuffer(uint32_t index, BufferBase* buffer); bool SetVertexBuffer(uint32_t index, BufferBase* buffer);
@ -88,6 +89,7 @@ namespace backend {
bool ValidateBindGroupUsages(BindGroupBase* group) const; bool ValidateBindGroupUsages(BindGroupBase* group) const;
bool RevalidateCanDraw(); bool RevalidateCanDraw();
bool SetPipelineCommon(PipelineBase* pipeline);
void UnsetPipeline(); void UnsetPipeline();
CommandBufferBuilder* builder; CommandBufferBuilder* builder;
@ -98,6 +100,7 @@ namespace backend {
std::array<BindGroupBase*, kMaxBindGroups> bindgroups = {}; std::array<BindGroupBase*, kMaxBindGroups> bindgroups = {};
std::bitset<kMaxVertexInputs> inputsSet; std::bitset<kMaxVertexInputs> inputsSet;
PipelineBase* lastPipeline = nullptr; PipelineBase* lastPipeline = nullptr;
RenderPipelineBase* lastRenderPipeline = nullptr;
std::map<BufferBase*, nxt::BufferUsageBit> mostRecentBufferUsages; std::map<BufferBase*, nxt::BufferUsageBit> mostRecentBufferUsages;
std::map<TextureBase*, nxt::TextureUsageBit> mostRecentTextureUsages; std::map<TextureBase*, nxt::TextureUsageBit> mostRecentTextureUsages;

View File

@ -40,7 +40,8 @@ namespace backend {
EndComputePass, EndComputePass,
EndRenderPass, EndRenderPass,
EndRenderSubpass, EndRenderSubpass,
SetPipeline, SetComputePipeline,
SetRenderPipeline,
SetPushConstants, SetPushConstants,
SetStencilReference, SetStencilReference,
SetBindGroup, SetBindGroup,
@ -118,8 +119,12 @@ namespace backend {
struct EndRenderSubpassCmd { struct EndRenderSubpassCmd {
}; };
struct SetPipelineCmd { struct SetComputePipelineCmd {
Ref<PipelineBase> pipeline; Ref<ComputePipelineBase> pipeline;
};
struct SetRenderPipelineCmd {
Ref<RenderPipelineBase> pipeline;
}; };
struct SetPushConstantsCmd { struct SetPushConstantsCmd {

View File

@ -0,0 +1,41 @@
// Copyright 2017 The NXT Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "backend/ComputePipeline.h"
#include "backend/Device.h"
namespace backend {
// ComputePipelineBase
ComputePipelineBase::ComputePipelineBase(ComputePipelineBuilder* builder)
: PipelineBase(builder) {
if (GetStageMask() != nxt::ShaderStageBit::Compute) {
builder->HandleError("Compute pipeline should have exactly a compute stage");
return;
}
}
// ComputePipelineBuilder
ComputePipelineBuilder::ComputePipelineBuilder(DeviceBase* device)
: Builder(device), PipelineBuilder(this) {
}
ComputePipelineBase* ComputePipelineBuilder::GetResultImpl() {
return device->CreateComputePipeline(this);
}
}

View File

@ -0,0 +1,38 @@
// Copyright 2017 The NXT Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef BACKEND_COMPUTEPIPELINE_H_
#define BACKEND_COMPUTEPIPELINE_H_
#include "backend/Pipeline.h"
namespace backend {
class ComputePipelineBase : public RefCounted, public PipelineBase {
public:
ComputePipelineBase(ComputePipelineBuilder* builder);
};
class ComputePipelineBuilder : public Builder<ComputePipelineBase>, public PipelineBuilder {
public:
ComputePipelineBuilder(DeviceBase* device);
private:
ComputePipelineBase* GetResultImpl() override;
};
}
#endif // BACKEND_COMPUTEPIPELINE_H_

View File

@ -18,13 +18,14 @@
#include "backend/BindGroupLayout.h" #include "backend/BindGroupLayout.h"
#include "backend/Buffer.h" #include "backend/Buffer.h"
#include "backend/CommandBuffer.h" #include "backend/CommandBuffer.h"
#include "backend/ComputePipeline.h"
#include "backend/DepthStencilState.h" #include "backend/DepthStencilState.h"
#include "backend/Framebuffer.h" #include "backend/Framebuffer.h"
#include "backend/InputState.h" #include "backend/InputState.h"
#include "backend/Pipeline.h"
#include "backend/PipelineLayout.h" #include "backend/PipelineLayout.h"
#include "backend/Queue.h" #include "backend/Queue.h"
#include "backend/RenderPass.h" #include "backend/RenderPass.h"
#include "backend/RenderPipeline.h"
#include "backend/Sampler.h" #include "backend/Sampler.h"
#include "backend/ShaderModule.h" #include "backend/ShaderModule.h"
#include "backend/Texture.h" #include "backend/Texture.h"
@ -99,6 +100,9 @@ namespace backend {
CommandBufferBuilder* DeviceBase::CreateCommandBufferBuilder() { CommandBufferBuilder* DeviceBase::CreateCommandBufferBuilder() {
return new CommandBufferBuilder(this); return new CommandBufferBuilder(this);
} }
ComputePipelineBuilder* DeviceBase::CreateComputePipelineBuilder() {
return new ComputePipelineBuilder(this);
}
DepthStencilStateBuilder* DeviceBase::CreateDepthStencilStateBuilder() { DepthStencilStateBuilder* DeviceBase::CreateDepthStencilStateBuilder() {
return new DepthStencilStateBuilder(this); return new DepthStencilStateBuilder(this);
} }
@ -108,9 +112,6 @@ namespace backend {
InputStateBuilder* DeviceBase::CreateInputStateBuilder() { InputStateBuilder* DeviceBase::CreateInputStateBuilder() {
return new InputStateBuilder(this); return new InputStateBuilder(this);
} }
PipelineBuilder* DeviceBase::CreatePipelineBuilder() {
return new PipelineBuilder(this);
}
PipelineLayoutBuilder* DeviceBase::CreatePipelineLayoutBuilder() { PipelineLayoutBuilder* DeviceBase::CreatePipelineLayoutBuilder() {
return new PipelineLayoutBuilder(this); return new PipelineLayoutBuilder(this);
} }
@ -120,6 +121,9 @@ namespace backend {
RenderPassBuilder* DeviceBase::CreateRenderPassBuilder() { RenderPassBuilder* DeviceBase::CreateRenderPassBuilder() {
return new RenderPassBuilder(this); return new RenderPassBuilder(this);
} }
RenderPipelineBuilder* DeviceBase::CreateRenderPipelineBuilder() {
return new RenderPipelineBuilder(this);
}
SamplerBuilder* DeviceBase::CreateSamplerBuilder() { SamplerBuilder* DeviceBase::CreateSamplerBuilder() {
return new SamplerBuilder(this); return new SamplerBuilder(this);
} }

View File

@ -39,13 +39,14 @@ namespace backend {
virtual BufferBase* CreateBuffer(BufferBuilder* builder) = 0; virtual BufferBase* CreateBuffer(BufferBuilder* 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;
virtual ComputePipelineBase* CreateComputePipeline(ComputePipelineBuilder* builder) = 0;
virtual DepthStencilStateBase* CreateDepthStencilState(DepthStencilStateBuilder* builder) = 0; virtual DepthStencilStateBase* CreateDepthStencilState(DepthStencilStateBuilder* builder) = 0;
virtual FramebufferBase* CreateFramebuffer(FramebufferBuilder* builder) = 0; virtual FramebufferBase* CreateFramebuffer(FramebufferBuilder* builder) = 0;
virtual InputStateBase* CreateInputState(InputStateBuilder* builder) = 0; virtual InputStateBase* CreateInputState(InputStateBuilder* builder) = 0;
virtual PipelineBase* CreatePipeline(PipelineBuilder* builder) = 0;
virtual PipelineLayoutBase* CreatePipelineLayout(PipelineLayoutBuilder* builder) = 0; virtual PipelineLayoutBase* CreatePipelineLayout(PipelineLayoutBuilder* builder) = 0;
virtual QueueBase* CreateQueue(QueueBuilder* builder) = 0; virtual QueueBase* CreateQueue(QueueBuilder* builder) = 0;
virtual RenderPassBase* CreateRenderPass(RenderPassBuilder* builder) = 0; virtual RenderPassBase* CreateRenderPass(RenderPassBuilder* builder) = 0;
virtual RenderPipelineBase* CreateRenderPipeline(RenderPipelineBuilder* builder) = 0;
virtual SamplerBase* CreateSampler(SamplerBuilder* builder) = 0; virtual SamplerBase* CreateSampler(SamplerBuilder* builder) = 0;
virtual ShaderModuleBase* CreateShaderModule(ShaderModuleBuilder* builder) = 0; virtual ShaderModuleBase* CreateShaderModule(ShaderModuleBuilder* builder) = 0;
virtual TextureBase* CreateTexture(TextureBuilder* builder) = 0; virtual TextureBase* CreateTexture(TextureBuilder* builder) = 0;
@ -76,13 +77,14 @@ namespace backend {
BufferBuilder* CreateBufferBuilder(); BufferBuilder* CreateBufferBuilder();
BufferViewBuilder* CreateBufferViewBuilder(); BufferViewBuilder* CreateBufferViewBuilder();
CommandBufferBuilder* CreateCommandBufferBuilder(); CommandBufferBuilder* CreateCommandBufferBuilder();
ComputePipelineBuilder* CreateComputePipelineBuilder();
DepthStencilStateBuilder* CreateDepthStencilStateBuilder(); DepthStencilStateBuilder* CreateDepthStencilStateBuilder();
FramebufferBuilder* CreateFramebufferBuilder(); FramebufferBuilder* CreateFramebufferBuilder();
InputStateBuilder* CreateInputStateBuilder(); InputStateBuilder* CreateInputStateBuilder();
PipelineBuilder* CreatePipelineBuilder();
PipelineLayoutBuilder* CreatePipelineLayoutBuilder(); PipelineLayoutBuilder* CreatePipelineLayoutBuilder();
QueueBuilder* CreateQueueBuilder(); QueueBuilder* CreateQueueBuilder();
RenderPassBuilder* CreateRenderPassBuilder(); RenderPassBuilder* CreateRenderPassBuilder();
RenderPipelineBuilder* CreateRenderPipelineBuilder();
SamplerBuilder* CreateSamplerBuilder(); SamplerBuilder* CreateSamplerBuilder();
ShaderModuleBuilder* CreateShaderModuleBuilder(); ShaderModuleBuilder* CreateShaderModuleBuilder();
TextureBuilder* CreateTextureBuilder(); TextureBuilder* CreateTextureBuilder();

View File

@ -27,6 +27,8 @@ namespace backend {
class BufferBuilder; class BufferBuilder;
class BufferViewBase; class BufferViewBase;
class BufferViewBuilder; class BufferViewBuilder;
class ComputePipelineBase;
class ComputePipelineBuilder;
class CommandBufferBase; class CommandBufferBase;
class CommandBufferBuilder; class CommandBufferBuilder;
class DepthStencilStateBase; class DepthStencilStateBase;
@ -35,14 +37,14 @@ namespace backend {
class FramebufferBuilder; class FramebufferBuilder;
class InputStateBase; class InputStateBase;
class InputStateBuilder; class InputStateBuilder;
class PipelineBase;
class PipelineBuilder;
class PipelineLayoutBase; class PipelineLayoutBase;
class PipelineLayoutBuilder; class PipelineLayoutBuilder;
class QueueBase; class QueueBase;
class QueueBuilder; class QueueBuilder;
class RenderPassBase; class RenderPassBase;
class RenderPassBuilder; class RenderPassBuilder;
class RenderPipelineBase;
class RenderPipelineBuilder;
class SamplerBase; class SamplerBase;
class SamplerBuilder; class SamplerBuilder;
class ShaderModuleBase; class ShaderModuleBase;

View File

@ -0,0 +1,95 @@
// Copyright 2017 The NXT Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "backend/RenderPipeline.h"
#include "backend/Device.h"
#include "backend/DepthStencilState.h"
#include "backend/InputState.h"
#include "backend/RenderPass.h"
namespace backend {
// RenderPipelineBase
RenderPipelineBase::RenderPipelineBase(RenderPipelineBuilder* builder)
: PipelineBase(builder), renderPass(std::move(builder->renderPass)), subpass(builder->subpass),
inputState(std::move(builder->inputState)), depthStencilState(std::move(builder->depthStencilState)) {
if (GetStageMask() != (nxt::ShaderStageBit::Vertex | nxt::ShaderStageBit::Fragment)) {
builder->HandleError("Render pipeline should have exactly a vertex and fragment stage");
return;
}
if (!renderPass) {
builder->HandleError("Pipeline render pass not set");
return;
}
// TODO(kainino@chromium.org): Need to verify the pipeline against its render subpass.
if ((builder->GetStageInfo(nxt::ShaderStage::Vertex).module->GetUsedVertexAttributes() & ~inputState->GetAttributesSetMask()).any()) {
builder->HandleError("Pipeline vertex stage uses inputs not in the input state");
return;
}
}
RenderPassBase* RenderPipelineBase::GetRenderPass() {
return renderPass.Get();
}
uint32_t RenderPipelineBase::GetSubPass() {
return subpass;
}
InputStateBase* RenderPipelineBase::GetInputState() {
return inputState.Get();
}
DepthStencilStateBase* RenderPipelineBase::GetDepthStencilState() {
return depthStencilState.Get();
}
// RenderPipelineBuilder
RenderPipelineBuilder::RenderPipelineBuilder(DeviceBase* device)
: Builder(device), PipelineBuilder(this) {
}
RenderPipelineBase* RenderPipelineBuilder::GetResultImpl() {
// TODO(cwallez@chromium.org): the layout should be required, and put the default objects in the device
if (!inputState) {
inputState = device->CreateInputStateBuilder()->GetResult();
}
if (!depthStencilState) {
depthStencilState = device->CreateDepthStencilStateBuilder()->GetResult();
}
return device->CreateRenderPipeline(this);
}
void RenderPipelineBuilder::SetSubpass(RenderPassBase* renderPass, uint32_t subpass) {
this->renderPass = renderPass;
this->subpass = subpass;
}
void RenderPipelineBuilder::SetInputState(InputStateBase* inputState) {
this->inputState = inputState;
}
void RenderPipelineBuilder::SetDepthStencilState(DepthStencilStateBase* depthStencilState) {
this->depthStencilState = depthStencilState;
}
}

View File

@ -0,0 +1,62 @@
// Copyright 2017 The NXT Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef BACKEND_RENDERPIPELINE_H_
#define BACKEND_RENDERPIPELINE_H_
#include "backend/Pipeline.h"
#include "nxt/nxtcpp.h"
namespace backend {
class RenderPipelineBase : public RefCounted, public PipelineBase {
public:
RenderPipelineBase(RenderPipelineBuilder* builder);
RenderPassBase* GetRenderPass();
uint32_t GetSubPass();
InputStateBase* GetInputState();
DepthStencilStateBase* GetDepthStencilState();
private:
Ref<RenderPassBase> renderPass;
uint32_t subpass;
Ref<InputStateBase> inputState;
Ref<DepthStencilStateBase> depthStencilState;
};
class RenderPipelineBuilder : public Builder<RenderPipelineBase>, public PipelineBuilder {
public:
RenderPipelineBuilder(DeviceBase* device);
// NXT API
void SetSubpass(RenderPassBase* renderPass, uint32_t subpass);
void SetInputState(InputStateBase* inputState);
void SetDepthStencilState(DepthStencilStateBase* depthStencilState);
private:
friend class RenderPipelineBase;
RenderPipelineBase* GetResultImpl() override;
Ref<RenderPassBase> renderPass;
uint32_t subpass;
Ref<InputStateBase> inputState;
Ref<DepthStencilStateBase> depthStencilState;
};
}
#endif // BACKEND_RENDERPIPELINE_H_

View File

@ -26,27 +26,11 @@ namespace backend {
// PipelineBase // PipelineBase
PipelineBase::PipelineBase(PipelineBuilder* builder) PipelineBase::PipelineBase(PipelineBuilder* builder)
: stageMask(builder->stageMask), layout(std::move(builder->layout)), : stageMask(builder->stageMask), layout(std::move(builder->layout)) {
renderPass(std::move(builder->renderPass)), subpass(builder->subpass), if (!layout) {
inputState(std::move(builder->inputState)), depthStencilState(std::move(builder->depthStencilState)) { layout = builder->GetParentBuilder()->GetDevice()->CreatePipelineLayoutBuilder()->GetResult();
if (stageMask != (nxt::ShaderStageBit::Vertex | nxt::ShaderStageBit::Fragment) &&
stageMask != nxt::ShaderStageBit::Compute) {
builder->HandleError("Wrong combination of stage for pipeline");
return;
} }
if (IsCompute() && depthStencilState) {
builder->HandleError("Compute pipeline cannot have depth stencil state");
return;
}
if (!IsCompute() && !renderPass) {
builder->HandleError("Pipeline render pass not set");
return;
}
// TODO(kainino@chromium.org): Need to verify the pipeline against its render subpass.
auto FillPushConstants = [](const ShaderModuleBase* module, PushConstantInfo* info) { auto FillPushConstants = [](const ShaderModuleBase* module, PushConstantInfo* info) {
const auto& moduleInfo = module->GetPushConstants(); const auto& moduleInfo = module->GetPushConstants();
info->mask = moduleInfo.mask; info->mask = moduleInfo.mask;
@ -66,19 +50,12 @@ namespace backend {
for (auto stageBit : IterateStages(builder->stageMask)) { for (auto stageBit : IterateStages(builder->stageMask)) {
if (!builder->stages[stageBit].module->IsCompatibleWithPipelineLayout(layout.Get())) { if (!builder->stages[stageBit].module->IsCompatibleWithPipelineLayout(layout.Get())) {
builder->HandleError("Stage not compatible with layout"); builder->GetParentBuilder()->HandleError("Stage not compatible with layout");
return; return;
} }
FillPushConstants(builder->stages[stageBit].module.Get(), &pushConstants[stageBit]); FillPushConstants(builder->stages[stageBit].module.Get(), &pushConstants[stageBit]);
} }
if (!IsCompute()) {
if ((builder->stages[nxt::ShaderStage::Vertex].module->GetUsedVertexAttributes() & ~inputState->GetAttributesSetMask()).any()) {
builder->HandleError("Pipeline vertex stage uses inputs not in the input state");
return;
}
}
} }
const PipelineBase::PushConstantInfo& PipelineBase::GetPushConstants(nxt::ShaderStage stage) const { const PipelineBase::PushConstantInfo& PipelineBase::GetPushConstants(nxt::ShaderStage stage) const {
@ -93,30 +70,10 @@ namespace backend {
return layout.Get(); return layout.Get();
} }
RenderPassBase* PipelineBase::GetRenderPass() {
return renderPass.Get();
}
uint32_t PipelineBase::GetSubPass() {
return subpass;
}
InputStateBase* PipelineBase::GetInputState() {
return inputState.Get();
}
DepthStencilStateBase* PipelineBase::GetDepthStencilState() {
return depthStencilState.Get();
}
bool PipelineBase::IsCompute() const {
return stageMask == nxt::ShaderStageBit::Compute;
}
// PipelineBuilder // PipelineBuilder
PipelineBuilder::PipelineBuilder(DeviceBase* device) PipelineBuilder::PipelineBuilder(BuilderBase* parentBuilder)
: Builder(device), stageMask(static_cast<nxt::ShaderStageBit>(0)) { : parentBuilder(parentBuilder), stageMask(static_cast<nxt::ShaderStageBit>(0)) {
} }
const PipelineBuilder::StageInfo& PipelineBuilder::GetStageInfo(nxt::ShaderStage stage) const { const PipelineBuilder::StageInfo& PipelineBuilder::GetStageInfo(nxt::ShaderStage stage) const {
@ -124,48 +81,28 @@ namespace backend {
return stages[stage]; return stages[stage];
} }
PipelineBase* PipelineBuilder::GetResultImpl() { BuilderBase* PipelineBuilder::GetParentBuilder() const {
// TODO(cwallez@chromium.org): the layout should be required, and put the default objects in the device return parentBuilder;
if (!layout) {
layout = device->CreatePipelineLayoutBuilder()->GetResult();
}
if (!inputState && !IsCompute()) {
inputState = device->CreateInputStateBuilder()->GetResult();
}
if (!depthStencilState && !IsCompute()) {
depthStencilState = device->CreateDepthStencilStateBuilder()->GetResult();
}
return device->CreatePipeline(this);
}
bool PipelineBuilder::IsCompute() const {
return stageMask == nxt::ShaderStageBit::Compute;
} }
void PipelineBuilder::SetLayout(PipelineLayoutBase* layout) { void PipelineBuilder::SetLayout(PipelineLayoutBase* layout) {
this->layout = layout; this->layout = layout;
} }
void PipelineBuilder::SetSubpass(RenderPassBase* renderPass, uint32_t subpass) {
this->renderPass = renderPass;
this->subpass = subpass;
}
void PipelineBuilder::SetStage(nxt::ShaderStage stage, ShaderModuleBase* module, const char* entryPoint) { void PipelineBuilder::SetStage(nxt::ShaderStage stage, ShaderModuleBase* module, const char* entryPoint) {
if (entryPoint != std::string("main")) { if (entryPoint != std::string("main")) {
HandleError("Currently the entry point has to be main()"); parentBuilder->HandleError("Currently the entry point has to be main()");
return; return;
} }
if (stage != module->GetExecutionModel()) { if (stage != module->GetExecutionModel()) {
HandleError("Setting module with wrong execution model"); parentBuilder->HandleError("Setting module with wrong execution model");
return; return;
} }
nxt::ShaderStageBit bit = StageBit(stage); nxt::ShaderStageBit bit = StageBit(stage);
if (stageMask & bit) { if (stageMask & bit) {
HandleError("Setting already set stage"); parentBuilder->HandleError("Setting already set stage");
return; return;
} }
stageMask |= bit; stageMask |= bit;
@ -174,13 +111,4 @@ namespace backend {
stages[stage].entryPoint = entryPoint; stages[stage].entryPoint = entryPoint;
} }
void PipelineBuilder::SetInputState(InputStateBase* inputState) {
this->inputState = inputState;
}
void PipelineBuilder::SetDepthStencilState(DepthStencilStateBase* depthStencilState) {
this->depthStencilState = depthStencilState;
}
} }

View File

@ -18,7 +18,9 @@
#include "backend/Forward.h" #include "backend/Forward.h"
#include "backend/Builder.h" #include "backend/Builder.h"
#include "backend/PerStage.h" #include "backend/PerStage.h"
#include "backend/PipelineLayout.h"
#include "backend/RefCounted.h" #include "backend/RefCounted.h"
#include "backend/ShaderModule.h"
#include "nxt/nxtcpp.h" #include "nxt/nxtcpp.h"
@ -33,7 +35,9 @@ namespace backend {
Float, Float,
}; };
class PipelineBase : public RefCounted { class PipelineBuilder;
class PipelineBase {
public: public:
PipelineBase(PipelineBuilder* builder); PipelineBase(PipelineBuilder* builder);
@ -45,55 +49,35 @@ namespace backend {
nxt::ShaderStageBit GetStageMask() const; nxt::ShaderStageBit GetStageMask() const;
PipelineLayoutBase* GetLayout(); PipelineLayoutBase* GetLayout();
RenderPassBase* GetRenderPass();
uint32_t GetSubPass();
InputStateBase* GetInputState();
DepthStencilStateBase* GetDepthStencilState();
// TODO(cwallez@chromium.org): split compute and render pipelines
bool IsCompute() const;
private: private:
nxt::ShaderStageBit stageMask; nxt::ShaderStageBit stageMask;
Ref<PipelineLayoutBase> layout; Ref<PipelineLayoutBase> layout;
Ref<RenderPassBase> renderPass;
uint32_t subpass;
PerStage<PushConstantInfo> pushConstants; PerStage<PushConstantInfo> pushConstants;
Ref<InputStateBase> inputState;
Ref<DepthStencilStateBase> depthStencilState;
}; };
class PipelineBuilder : public Builder<PipelineBase> { class PipelineBuilder {
public: public:
PipelineBuilder(DeviceBase* device); PipelineBuilder(BuilderBase* parentBuilder);
struct StageInfo { struct StageInfo {
std::string entryPoint; std::string entryPoint;
Ref<ShaderModuleBase> module; Ref<ShaderModuleBase> module;
}; };
const StageInfo& GetStageInfo(nxt::ShaderStage stage) const; const StageInfo& GetStageInfo(nxt::ShaderStage stage) const;
BuilderBase* GetParentBuilder() const;
// NXT API // NXT API
void SetLayout(PipelineLayoutBase* layout); void SetLayout(PipelineLayoutBase* layout);
void SetSubpass(RenderPassBase* renderPass, uint32_t subpass);
void SetStage(nxt::ShaderStage stage, ShaderModuleBase* module, const char* entryPoint); void SetStage(nxt::ShaderStage stage, ShaderModuleBase* module, const char* entryPoint);
void SetInputState(InputStateBase* inputState);
void SetDepthStencilState(DepthStencilStateBase* depthStencilState);
private: private:
friend class PipelineBase; friend class PipelineBase;
PipelineBase* GetResultImpl() override; BuilderBase* parentBuilder;
bool IsCompute() const;
Ref<PipelineLayoutBase> layout; Ref<PipelineLayoutBase> layout;
Ref<RenderPassBase> renderPass;
uint32_t subpass;
nxt::ShaderStageBit stageMask; nxt::ShaderStageBit stageMask;
PerStage<StageInfo> stages; PerStage<StageInfo> stages;
Ref<InputStateBase> inputState;
Ref<DepthStencilStateBase> depthStencilState;
}; };
} }

View File

@ -48,6 +48,11 @@ namespace backend {
using BackendType = typename BackendTraits::CommandBufferType; using BackendType = typename BackendTraits::CommandBufferType;
}; };
template<typename BackendTraits>
struct ToBackendTraits<ComputePipelineBase, BackendTraits> {
using BackendType = typename BackendTraits::ComputePipelineType;
};
template<typename BackendTraits> template<typename BackendTraits>
struct ToBackendTraits<DepthStencilStateBase, BackendTraits> { struct ToBackendTraits<DepthStencilStateBase, BackendTraits> {
using BackendType = typename BackendTraits::DepthStencilStateType; using BackendType = typename BackendTraits::DepthStencilStateType;
@ -68,11 +73,6 @@ namespace backend {
using BackendType = typename BackendTraits::InputStateType; using BackendType = typename BackendTraits::InputStateType;
}; };
template<typename BackendTraits>
struct ToBackendTraits<PipelineBase, BackendTraits> {
using BackendType = typename BackendTraits::PipelineType;
};
template<typename BackendTraits> template<typename BackendTraits>
struct ToBackendTraits<PipelineLayoutBase, BackendTraits> { struct ToBackendTraits<PipelineLayoutBase, BackendTraits> {
using BackendType = typename BackendTraits::PipelineLayoutType; using BackendType = typename BackendTraits::PipelineLayoutType;
@ -88,6 +88,11 @@ namespace backend {
using BackendType = typename BackendTraits::RenderPassType; using BackendType = typename BackendTraits::RenderPassType;
}; };
template<typename BackendTraits>
struct ToBackendTraits<RenderPipelineBase, BackendTraits> {
using BackendType = typename BackendTraits::RenderPipelineType;
};
template<typename BackendTraits> template<typename BackendTraits>
struct ToBackendTraits<SamplerBase, BackendTraits> { struct ToBackendTraits<SamplerBase, BackendTraits> {
using BackendType = typename BackendTraits::SamplerType; using BackendType = typename BackendTraits::SamplerType;

View File

@ -162,7 +162,7 @@ namespace d3d12 {
descriptor.RTVFormats[0] = DXGI_FORMAT_R8G8B8A8_UNORM; descriptor.RTVFormats[0] = DXGI_FORMAT_R8G8B8A8_UNORM;
descriptor.SampleDesc.Count = 1; descriptor.SampleDesc.Count = 1;
ASSERT_SUCCESS(device->GetD3D12Device()->CreateGraphicsPipelineState(&descriptor, IID_PPV_ARGS(&renderPipelineState))); ASSERT_SUCCESS(device->GetD3D12Device()->CreateRenderPipelineState(&descriptor, IID_PPV_ARGS(&renderPipelineState)));
} }
} }

View File

@ -52,17 +52,17 @@ namespace null {
CommandBufferBase* Device::CreateCommandBuffer(CommandBufferBuilder* builder) { CommandBufferBase* Device::CreateCommandBuffer(CommandBufferBuilder* builder) {
return new CommandBuffer(builder); return new CommandBuffer(builder);
} }
ComputePipelineBase* Device::CreateComputePipeline(ComputePipelineBuilder* builder) {
return new ComputePipeline(builder);
}
DepthStencilStateBase* Device::CreateDepthStencilState(DepthStencilStateBuilder* builder) { DepthStencilStateBase* Device::CreateDepthStencilState(DepthStencilStateBuilder* builder) {
return new DepthStencilState(builder); return new DepthStencilState(builder);
} }
InputStateBase* Device::CreateInputState(InputStateBuilder* builder) {
return new InputState(builder);
}
FramebufferBase* Device::CreateFramebuffer(FramebufferBuilder* builder) { FramebufferBase* Device::CreateFramebuffer(FramebufferBuilder* builder) {
return new Framebuffer(builder); return new Framebuffer(builder);
} }
PipelineBase* Device::CreatePipeline(PipelineBuilder* builder) { InputStateBase* Device::CreateInputState(InputStateBuilder* builder) {
return new Pipeline(builder); return new InputState(builder);
} }
PipelineLayoutBase* Device::CreatePipelineLayout(PipelineLayoutBuilder* builder) { PipelineLayoutBase* Device::CreatePipelineLayout(PipelineLayoutBuilder* builder) {
return new PipelineLayout(builder); return new PipelineLayout(builder);
@ -73,6 +73,9 @@ namespace null {
RenderPassBase* Device::CreateRenderPass(RenderPassBuilder* builder) { RenderPassBase* Device::CreateRenderPass(RenderPassBuilder* builder) {
return new RenderPass(builder); return new RenderPass(builder);
} }
RenderPipelineBase* Device::CreateRenderPipeline(RenderPipelineBuilder* builder) {
return new RenderPipeline(builder);
}
SamplerBase* Device::CreateSampler(SamplerBuilder* builder) { SamplerBase* Device::CreateSampler(SamplerBuilder* builder) {
return new Sampler(builder); return new Sampler(builder);
} }

View File

@ -22,13 +22,14 @@
#include "backend/BindGroupLayout.h" #include "backend/BindGroupLayout.h"
#include "backend/Device.h" #include "backend/Device.h"
#include "backend/CommandBuffer.h" #include "backend/CommandBuffer.h"
#include "backend/ComputePipeline.h"
#include "backend/DepthStencilState.h" #include "backend/DepthStencilState.h"
#include "backend/InputState.h"
#include "backend/Framebuffer.h" #include "backend/Framebuffer.h"
#include "backend/Pipeline.h" #include "backend/InputState.h"
#include "backend/PipelineLayout.h" #include "backend/PipelineLayout.h"
#include "backend/Queue.h" #include "backend/Queue.h"
#include "backend/RenderPass.h" #include "backend/RenderPass.h"
#include "backend/RenderPipeline.h"
#include "backend/Sampler.h" #include "backend/Sampler.h"
#include "backend/ShaderModule.h" #include "backend/ShaderModule.h"
#include "backend/Texture.h" #include "backend/Texture.h"
@ -42,14 +43,15 @@ namespace null {
class Buffer; class Buffer;
using BufferView = BufferViewBase; using BufferView = BufferViewBase;
class CommandBuffer; class CommandBuffer;
using ComputePipeline = ComputePipelineBase;
using DepthStencilState = DepthStencilStateBase; using DepthStencilState = DepthStencilStateBase;
class Device; class Device;
using InputState = InputStateBase;
using Framebuffer = FramebufferBase; using Framebuffer = FramebufferBase;
using Pipeline = PipelineBase; using InputState = InputStateBase;
using PipelineLayout = PipelineLayoutBase; using PipelineLayout = PipelineLayoutBase;
class Queue; class Queue;
using RenderPass = RenderPassBase; using RenderPass = RenderPassBase;
using RenderPipeline = RenderPipelineBase;
using Sampler = SamplerBase; using Sampler = SamplerBase;
using ShaderModule = ShaderModuleBase; using ShaderModule = ShaderModuleBase;
class Texture; class Texture;
@ -61,14 +63,15 @@ namespace null {
using BufferType = Buffer; using BufferType = Buffer;
using BufferViewType = BufferView; using BufferViewType = BufferView;
using CommandBufferType = CommandBuffer; using CommandBufferType = CommandBuffer;
using ComputePipelineType = ComputePipeline;
using DepthStencilStateType = DepthStencilState; using DepthStencilStateType = DepthStencilState;
using DeviceType = Device; using DeviceType = Device;
using InputStateType = InputState;
using FramebufferType = Framebuffer; using FramebufferType = Framebuffer;
using PipelineType = Pipeline; using InputStateType = InputState;
using PipelineLayoutType = PipelineLayout; using PipelineLayoutType = PipelineLayout;
using QueueType = Queue; using QueueType = Queue;
using RenderPassType = RenderPass; using RenderPassType = RenderPass;
using RenderPipelineType = RenderPipeline;
using SamplerType = Sampler; using SamplerType = Sampler;
using ShaderModuleType = ShaderModule; using ShaderModuleType = ShaderModule;
using TextureType = Texture; using TextureType = Texture;
@ -95,13 +98,14 @@ namespace null {
BufferBase* CreateBuffer(BufferBuilder* builder) override; BufferBase* CreateBuffer(BufferBuilder* builder) override;
BufferViewBase* CreateBufferView(BufferViewBuilder* builder) override; BufferViewBase* CreateBufferView(BufferViewBuilder* builder) override;
CommandBufferBase* CreateCommandBuffer(CommandBufferBuilder* builder) override; CommandBufferBase* CreateCommandBuffer(CommandBufferBuilder* builder) override;
ComputePipelineBase* CreateComputePipeline(ComputePipelineBuilder* builder) override;
DepthStencilStateBase* CreateDepthStencilState(DepthStencilStateBuilder* builder) override; DepthStencilStateBase* CreateDepthStencilState(DepthStencilStateBuilder* builder) override;
InputStateBase* CreateInputState(InputStateBuilder* builder) override;
FramebufferBase* CreateFramebuffer(FramebufferBuilder* builder) override; FramebufferBase* CreateFramebuffer(FramebufferBuilder* builder) override;
PipelineBase* CreatePipeline(PipelineBuilder* builder) override; InputStateBase* CreateInputState(InputStateBuilder* builder) override;
PipelineLayoutBase* CreatePipelineLayout(PipelineLayoutBuilder* builder) override; PipelineLayoutBase* CreatePipelineLayout(PipelineLayoutBuilder* builder) override;
QueueBase* CreateQueue(QueueBuilder* builder) override; QueueBase* CreateQueue(QueueBuilder* builder) override;
RenderPassBase* CreateRenderPass(RenderPassBuilder* builder) override; RenderPassBase* CreateRenderPass(RenderPassBuilder* builder) override;
RenderPipelineBase* CreateRenderPipeline(RenderPipelineBuilder* builder) override;
SamplerBase* CreateSampler(SamplerBuilder* builder) override; SamplerBase* CreateSampler(SamplerBuilder* builder) override;
ShaderModuleBase* CreateShaderModule(ShaderModuleBuilder* builder) override; ShaderModuleBase* CreateShaderModule(ShaderModuleBuilder* builder) override;
TextureBase* CreateTexture(TextureBuilder* builder) override; TextureBase* CreateTexture(TextureBuilder* builder) override;