Split Pipeline in Render and Compute, OpenGL part
diff --git a/src/backend/CMakeLists.txt b/src/backend/CMakeLists.txt
index e94e605..eb4681c 100644
--- a/src/backend/CMakeLists.txt
+++ b/src/backend/CMakeLists.txt
@@ -42,6 +42,8 @@
${OPENGL_DIR}/BufferGL.h
${OPENGL_DIR}/CommandBufferGL.cpp
${OPENGL_DIR}/CommandBufferGL.h
+ ${OPENGL_DIR}/ComputePipelineGL.cpp
+ ${OPENGL_DIR}/ComputePipelineGL.h
${OPENGL_DIR}/DepthStencilStateGL.cpp
${OPENGL_DIR}/DepthStencilStateGL.h
${OPENGL_DIR}/OpenGLBackend.cpp
@@ -52,6 +54,8 @@
${OPENGL_DIR}/PipelineGL.h
${OPENGL_DIR}/PipelineLayoutGL.cpp
${OPENGL_DIR}/PipelineLayoutGL.h
+ ${OPENGL_DIR}/RenderPipelineGL.cpp
+ ${OPENGL_DIR}/RenderPipelineGL.h
${OPENGL_DIR}/SamplerGL.cpp
${OPENGL_DIR}/SamplerGL.h
${OPENGL_DIR}/ShaderModuleGL.cpp
diff --git a/src/backend/opengl/CommandBufferGL.cpp b/src/backend/opengl/CommandBufferGL.cpp
index 5470895..53c371b 100644
--- a/src/backend/opengl/CommandBufferGL.cpp
+++ b/src/backend/opengl/CommandBufferGL.cpp
@@ -16,10 +16,11 @@
#include "backend/Commands.h"
#include "backend/opengl/BufferGL.h"
+#include "backend/opengl/ComputePipelineGL.h"
#include "backend/opengl/OpenGLBackend.h"
#include "backend/opengl/PersistentPipelineStateGL.h"
-#include "backend/opengl/PipelineGL.h"
#include "backend/opengl/PipelineLayoutGL.h"
+#include "backend/opengl/RenderPipelineGL.h"
#include "backend/opengl/SamplerGL.h"
#include "backend/opengl/TextureGL.h"
@@ -61,7 +62,9 @@
void CommandBuffer::Execute() {
Command type;
- Pipeline* lastPipeline = nullptr;
+ PipelineBase* lastPipeline = nullptr;
+ PipelineGL* lastGLPipeline = nullptr;
+ RenderPipeline* lastRenderPipeline = nullptr;
uint32_t indexBufferOffset = 0;
nxt::IndexFormat indexBufferFormat = nxt::IndexFormat::Uint16;
@@ -281,10 +284,21 @@
}
break;
- case Command::SetPipeline:
+ case Command::SetComputePipeline:
{
- SetPipelineCmd* cmd = commands.NextCommand<SetPipelineCmd>();
+ SetComputePipelineCmd* cmd = commands.NextCommand<SetComputePipelineCmd>();
+ ToBackend(cmd->pipeline)->ApplyNow();
+ lastGLPipeline = ToBackend(cmd->pipeline).Get();
+ lastPipeline = ToBackend(cmd->pipeline).Get();
+ }
+ break;
+
+ case Command::SetRenderPipeline:
+ {
+ SetRenderPipelineCmd* cmd = commands.NextCommand<SetRenderPipelineCmd>();
ToBackend(cmd->pipeline)->ApplyNow(persistentPipelineState);
+ lastRenderPipeline = ToBackend(cmd->pipeline).Get();
+ lastGLPipeline = ToBackend(cmd->pipeline).Get();
lastPipeline = ToBackend(cmd->pipeline).Get();
}
break;
@@ -298,7 +312,7 @@
for (auto stage : IterateStages(cmd->stage)) {
const auto& pushConstants = lastPipeline->GetPushConstants(stage);
- const auto& glPushConstants = lastPipeline->GetGLPushConstants(stage);
+ const auto& glPushConstants = lastGLPipeline->GetGLPushConstants(stage);
for (size_t i = 0; i < cmd->count; i++) {
GLint location = glPushConstants[cmd->offset + i];
@@ -356,7 +370,7 @@
GLuint sampler = ToBackend(group->GetBindingAsSampler(binding))->GetHandle();
GLuint samplerIndex = indices[binding];
- for (auto unit : lastPipeline->GetTextureUnitsForSampler(samplerIndex)) {
+ for (auto unit : lastGLPipeline->GetTextureUnitsForSampler(samplerIndex)) {
glBindSampler(unit, sampler);
}
}
@@ -370,7 +384,7 @@
GLenum target = texture->GetGLTarget();
GLuint textureIndex = indices[binding];
- for (auto unit : lastPipeline->GetTextureUnitsForTexture(textureIndex)) {
+ for (auto unit : lastGLPipeline->GetTextureUnitsForTexture(textureIndex)) {
glActiveTexture(GL_TEXTURE0 + unit);
glBindTexture(target, handle);
}
@@ -408,7 +422,7 @@
auto buffers = commands.NextData<Ref<BufferBase>>(cmd->count);
auto offsets = commands.NextData<uint32_t>(cmd->count);
- auto inputState = lastPipeline->GetInputState();
+ auto inputState = lastRenderPipeline->GetInputState();
auto& attributesSetMask = inputState->GetAttributesSetMask();
for (uint32_t location = 0; location < attributesSetMask.size(); ++location) {
diff --git a/src/backend/opengl/ComputePipelineGL.cpp b/src/backend/opengl/ComputePipelineGL.cpp
new file mode 100644
index 0000000..d2fd8ad
--- /dev/null
+++ b/src/backend/opengl/ComputePipelineGL.cpp
@@ -0,0 +1,29 @@
+// 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/opengl/ComputePipelineGL.h"
+
+namespace backend {
+namespace opengl {
+
+ ComputePipeline::ComputePipeline(ComputePipelineBuilder* builder)
+ : ComputePipelineBase(builder), PipelineGL(this, builder) {
+ }
+
+ void ComputePipeline::ApplyNow() {
+ PipelineGL::ApplyNow();
+ }
+
+}
+}
diff --git a/src/backend/opengl/ComputePipelineGL.h b/src/backend/opengl/ComputePipelineGL.h
new file mode 100644
index 0000000..c0678c3
--- /dev/null
+++ b/src/backend/opengl/ComputePipelineGL.h
@@ -0,0 +1,37 @@
+// 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_OPENGL_COMPUTEPIPELINEGL_H_
+#define BACKEND_OPENGL_COMPUTEPIPELINEGL_H_
+
+#include "backend/ComputePipeline.h"
+
+#include "backend/opengl/PipelineGL.h"
+
+#include "glad/glad.h"
+
+namespace backend {
+namespace opengl {
+
+ class ComputePipeline : public ComputePipelineBase, public PipelineGL {
+ public:
+ ComputePipeline(ComputePipelineBuilder* builder);
+
+ void ApplyNow();
+ };
+
+}
+}
+
+#endif // BACKEND_OPENGL_COMPUTEPIPELINEGL_H_
diff --git a/src/backend/opengl/GeneratedCodeIncludes.h b/src/backend/opengl/GeneratedCodeIncludes.h
index 1ee13ad..f6330b7 100644
--- a/src/backend/opengl/GeneratedCodeIncludes.h
+++ b/src/backend/opengl/GeneratedCodeIncludes.h
@@ -15,10 +15,11 @@
#include "backend/opengl/OpenGLBackend.h"
#include "backend/opengl/BufferGL.h"
#include "backend/opengl/CommandBufferGL.h"
+#include "backend/opengl/ComputePipelineGL.h"
#include "backend/opengl/DepthStencilStateGL.h"
#include "backend/opengl/PersistentPipelineStateGL.h"
-#include "backend/opengl/PipelineGL.h"
#include "backend/opengl/PipelineLayoutGL.h"
+#include "backend/opengl/RenderPipelineGL.h"
#include "backend/opengl/SamplerGL.h"
#include "backend/opengl/ShaderModuleGL.h"
#include "backend/opengl/TextureGL.h"
diff --git a/src/backend/opengl/OpenGLBackend.cpp b/src/backend/opengl/OpenGLBackend.cpp
index 6426d9f..59fbe34 100644
--- a/src/backend/opengl/OpenGLBackend.cpp
+++ b/src/backend/opengl/OpenGLBackend.cpp
@@ -16,9 +16,10 @@
#include "backend/opengl/BufferGL.h"
#include "backend/opengl/CommandBufferGL.h"
+#include "backend/opengl/ComputePipelineGL.h"
#include "backend/opengl/DepthStencilStateGL.h"
-#include "backend/opengl/PipelineGL.h"
#include "backend/opengl/PipelineLayoutGL.h"
+#include "backend/opengl/RenderPipelineGL.h"
#include "backend/opengl/ShaderModuleGL.h"
#include "backend/opengl/SamplerGL.h"
#include "backend/opengl/TextureGL.h"
@@ -72,6 +73,9 @@
CommandBufferBase* Device::CreateCommandBuffer(CommandBufferBuilder* builder) {
return new CommandBuffer(builder);
}
+ ComputePipelineBase* Device::CreateComputePipeline(ComputePipelineBuilder* builder) {
+ return new ComputePipeline(builder);
+ }
DepthStencilStateBase* Device::CreateDepthStencilState(DepthStencilStateBuilder* builder) {
return new DepthStencilState(builder);
}
@@ -81,9 +85,6 @@
FramebufferBase* Device::CreateFramebuffer(FramebufferBuilder* builder) {
return new Framebuffer(builder);
}
- PipelineBase* Device::CreatePipeline(PipelineBuilder* builder) {
- return new Pipeline(builder);
- }
PipelineLayoutBase* Device::CreatePipelineLayout(PipelineLayoutBuilder* builder) {
return new PipelineLayout(builder);
}
@@ -93,6 +94,9 @@
RenderPassBase* Device::CreateRenderPass(RenderPassBuilder* builder) {
return new RenderPass(builder);
}
+ RenderPipelineBase* Device::CreateRenderPipeline(RenderPipelineBuilder* builder) {
+ return new RenderPipeline(builder);
+ }
SamplerBase* Device::CreateSampler(SamplerBuilder* builder) {
return new Sampler(builder);
}
diff --git a/src/backend/opengl/OpenGLBackend.h b/src/backend/opengl/OpenGLBackend.h
index 80097ae..0d23285 100644
--- a/src/backend/opengl/OpenGLBackend.h
+++ b/src/backend/opengl/OpenGLBackend.h
@@ -38,19 +38,20 @@
class Buffer;
class BufferView;
class CommandBuffer;
+ class ComputePipeline;
class DepthStencilState;
class Device;
+ class Framebuffer;
class InputState;
class PersistentPipelineState;
- class Pipeline;
class PipelineLayout;
class Queue;
+ class RenderPass;
+ class RenderPipeline;
class Sampler;
class ShaderModule;
class Texture;
class TextureView;
- class Framebuffer;
- class RenderPass;
struct OpenGLBackendTraits {
using BindGroupType = BindGroup;
@@ -58,18 +59,19 @@
using BufferType = Buffer;
using BufferViewType = BufferView;
using CommandBufferType = CommandBuffer;
+ using ComputePipelineType = ComputePipeline;
using DepthStencilStateType = DepthStencilState;
using DeviceType = Device;
+ using FramebufferType = Framebuffer;
using InputStateType = InputState;
- using PipelineType = Pipeline;
using PipelineLayoutType = PipelineLayout;
using QueueType = Queue;
+ using RenderPassType = RenderPass;
+ using RenderPipelineType = RenderPipeline;
using SamplerType = Sampler;
using ShaderModuleType = ShaderModule;
using TextureType = Texture;
using TextureViewType = TextureView;
- using FramebufferType = Framebuffer;
- using RenderPassType = RenderPass;
};
template<typename T>
@@ -85,13 +87,14 @@
BufferBase* CreateBuffer(BufferBuilder* builder) override;
BufferViewBase* CreateBufferView(BufferViewBuilder* builder) override;
CommandBufferBase* CreateCommandBuffer(CommandBufferBuilder* builder) override;
+ ComputePipelineBase* CreateComputePipeline(ComputePipelineBuilder* builder) override;
DepthStencilStateBase* CreateDepthStencilState(DepthStencilStateBuilder* builder) override;
InputStateBase* CreateInputState(InputStateBuilder* builder) override;
FramebufferBase* CreateFramebuffer(FramebufferBuilder* builder) override;
- PipelineBase* CreatePipeline(PipelineBuilder* builder) override;
PipelineLayoutBase* CreatePipelineLayout(PipelineLayoutBuilder* builder) override;
QueueBase* CreateQueue(QueueBuilder* builder) override;
RenderPassBase* CreateRenderPass(RenderPassBuilder* builder) override;
+ RenderPipelineBase* CreateRenderPipeline(RenderPipelineBuilder* builder) override;
SamplerBase* CreateSampler(SamplerBuilder* builder) override;
ShaderModuleBase* CreateShaderModule(ShaderModuleBuilder* builder) override;
TextureBase* CreateTexture(TextureBuilder* builder) override;
diff --git a/src/backend/opengl/PipelineGL.cpp b/src/backend/opengl/PipelineGL.cpp
index 1fb4746..e029784 100644
--- a/src/backend/opengl/PipelineGL.cpp
+++ b/src/backend/opengl/PipelineGL.cpp
@@ -14,7 +14,6 @@
#include "backend/opengl/PipelineGL.h"
-#include "backend/opengl/DepthStencilStateGL.h"
#include "backend/opengl/OpenGLBackend.h"
#include "backend/opengl/PersistentPipelineStateGL.h"
#include "backend/opengl/PipelineLayoutGL.h"
@@ -43,7 +42,7 @@
}
- Pipeline::Pipeline(PipelineBuilder* builder) : PipelineBase(builder) {
+ PipelineGL::PipelineGL(PipelineBase* parent, PipelineBuilder* builder) {
auto CreateShader = [](GLenum type, const char* source) -> GLuint {
GLuint shader = glCreateShader(type);
glShaderSource(shader, 1, &source, nullptr);
@@ -90,7 +89,7 @@
program = glCreateProgram();
- for (auto stage : IterateStages(GetStageMask())) {
+ for (auto stage : IterateStages(parent->GetStageMask())) {
const ShaderModule* module = ToBackend(builder->GetStageInfo(stage).module.Get());
GLuint shader = CreateShader(GLShaderType(stage), module->GetSource());
@@ -113,7 +112,7 @@
}
}
- for (auto stage : IterateStages(GetStageMask())) {
+ for (auto stage : IterateStages(parent->GetStageMask())) {
const ShaderModule* module = ToBackend(builder->GetStageInfo(stage).module.Get());
FillPushConstants(module, &glPushConstants[stage], program);
}
@@ -121,7 +120,7 @@
glUseProgram(program);
// The uniforms are part of the program state so we can pre-bind buffer units, texture units etc.
- const auto& layout = ToBackend(GetLayout());
+ const auto& layout = ToBackend(parent->GetLayout());
const auto& indices = layout->GetBindingIndexInfo();
for (uint32_t group = 0; group < kMaxBindGroups; ++group) {
@@ -160,7 +159,7 @@
// Compute links between stages for combined samplers, then bind them to texture units
{
std::set<CombinedSampler> combinedSamplersSet;
- for (auto stage : IterateStages(GetStageMask())) {
+ for (auto stage : IterateStages(parent->GetStageMask())) {
const auto& module = ToBackend(builder->GetStageInfo(stage).module);
for (const auto& combined : module->GetCombinedSamplerInfo()) {
@@ -188,32 +187,26 @@
}
}
- const Pipeline::GLPushConstantInfo& Pipeline::GetGLPushConstants(nxt::ShaderStage stage) const {
+ const PipelineGL::GLPushConstantInfo& PipelineGL::GetGLPushConstants(nxt::ShaderStage stage) const {
return glPushConstants[stage];
}
- const std::vector<GLuint>& Pipeline::GetTextureUnitsForSampler(GLuint index) const {
+ const std::vector<GLuint>& PipelineGL::GetTextureUnitsForSampler(GLuint index) const {
ASSERT(index >= 0 && index < unitsForSamplers.size());
return unitsForSamplers[index];
}
- const std::vector<GLuint>& Pipeline::GetTextureUnitsForTexture(GLuint index) const {
+ const std::vector<GLuint>& PipelineGL::GetTextureUnitsForTexture(GLuint index) const {
ASSERT(index >= 0 && index < unitsForSamplers.size());
return unitsForTextures[index];
}
- GLuint Pipeline::GetProgramHandle() const {
+ GLuint PipelineGL::GetProgramHandle() const {
return program;
}
- void Pipeline::ApplyNow(PersistentPipelineState &persistentPipelineState) {
+ void PipelineGL::ApplyNow() {
glUseProgram(program);
-
- auto inputState = ToBackend(GetInputState());
- glBindVertexArray(inputState->GetVAO());
-
- auto depthStencilState = ToBackend(GetDepthStencilState());
- depthStencilState->ApplyNow(persistentPipelineState);
}
}
diff --git a/src/backend/opengl/PipelineGL.h b/src/backend/opengl/PipelineGL.h
index 1dc8af6..f6fe63c 100644
--- a/src/backend/opengl/PipelineGL.h
+++ b/src/backend/opengl/PipelineGL.h
@@ -28,9 +28,9 @@
class PersistentPipelineState;
class ShaderModule;
- class Pipeline : public PipelineBase {
+ class PipelineGL {
public:
- Pipeline(PipelineBuilder* builder);
+ PipelineGL(PipelineBase* parent, PipelineBuilder* builder);
using GLPushConstantInfo = std::array<GLint, kMaxPushConstants>;
using BindingLocations = std::array<std::array<GLint, kMaxBindingsPerGroup>, kMaxBindGroups>;
@@ -40,7 +40,7 @@
const std::vector<GLuint>& GetTextureUnitsForTexture(GLuint index) const;
GLuint GetProgramHandle() const;
- void ApplyNow(PersistentPipelineState &persistentPipelineState);
+ void ApplyNow();
private:
GLuint program;
diff --git a/src/backend/opengl/RenderPipelineGL.cpp b/src/backend/opengl/RenderPipelineGL.cpp
new file mode 100644
index 0000000..1492b4f
--- /dev/null
+++ b/src/backend/opengl/RenderPipelineGL.cpp
@@ -0,0 +1,39 @@
+// 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/opengl/RenderPipelineGL.h"
+
+#include "backend/opengl/DepthStencilStateGL.h"
+#include "backend/opengl/PersistentPipelineStateGL.h"
+#include "backend/opengl/OpenGLBackend.h"
+
+namespace backend {
+namespace opengl {
+
+ RenderPipeline::RenderPipeline(RenderPipelineBuilder* builder)
+ : RenderPipelineBase(builder), PipelineGL(this, builder) {
+ }
+
+ void RenderPipeline::ApplyNow(PersistentPipelineState &persistentPipelineState) {
+ PipelineGL::ApplyNow();
+
+ auto inputState = ToBackend(GetInputState());
+ glBindVertexArray(inputState->GetVAO());
+
+ auto depthStencilState = ToBackend(GetDepthStencilState());
+ depthStencilState->ApplyNow(persistentPipelineState);
+ }
+
+}
+}
diff --git a/src/backend/opengl/RenderPipelineGL.h b/src/backend/opengl/RenderPipelineGL.h
new file mode 100644
index 0000000..3c5edde
--- /dev/null
+++ b/src/backend/opengl/RenderPipelineGL.h
@@ -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.
+
+#ifndef BACKEND_OPENGL_RENDERPIPELINEGL_H_
+#define BACKEND_OPENGL_RENDERPIPELINEGL_H_
+
+#include "backend/RenderPipeline.h"
+
+#include "backend/opengl/PipelineGL.h"
+
+#include "glad/glad.h"
+
+#include <vector>
+
+namespace backend {
+namespace opengl {
+
+ class PersistentPipelineState;
+
+ class RenderPipeline : public RenderPipelineBase, public PipelineGL {
+ public:
+ RenderPipeline(RenderPipelineBuilder* builder);
+
+ void ApplyNow(PersistentPipelineState &persistentPipelineState);
+ };
+
+}
+}
+
+#endif // BACKEND_OPENGL_RENDERPIPELINEGL_H_