From b085eecb31624faf84a8be017a31a111f8cc3d3b Mon Sep 17 00:00:00 2001 From: Corentin Wallez Date: Fri, 14 Jul 2017 14:04:52 -0400 Subject: [PATCH] Split Pipeline in Render and Compute, OpenGL part --- src/backend/CMakeLists.txt | 4 +++ src/backend/opengl/CommandBufferGL.cpp | 30 +++++++++++----- src/backend/opengl/ComputePipelineGL.cpp | 29 +++++++++++++++ src/backend/opengl/ComputePipelineGL.h | 37 +++++++++++++++++++ src/backend/opengl/GeneratedCodeIncludes.h | 3 +- src/backend/opengl/OpenGLBackend.cpp | 12 ++++--- src/backend/opengl/OpenGLBackend.h | 17 +++++---- src/backend/opengl/PipelineGL.cpp | 27 ++++++-------- src/backend/opengl/PipelineGL.h | 6 ++-- src/backend/opengl/RenderPipelineGL.cpp | 39 ++++++++++++++++++++ src/backend/opengl/RenderPipelineGL.h | 41 ++++++++++++++++++++++ 11 files changed, 205 insertions(+), 40 deletions(-) create mode 100644 src/backend/opengl/ComputePipelineGL.cpp create mode 100644 src/backend/opengl/ComputePipelineGL.h create mode 100644 src/backend/opengl/RenderPipelineGL.cpp create mode 100644 src/backend/opengl/RenderPipelineGL.h diff --git a/src/backend/CMakeLists.txt b/src/backend/CMakeLists.txt index e94e6055db..eb4681cc3c 100644 --- a/src/backend/CMakeLists.txt +++ b/src/backend/CMakeLists.txt @@ -42,6 +42,8 @@ if (NXT_ENABLE_OPENGL) ${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 @@ if (NXT_ENABLE_OPENGL) ${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 5470895ab6..53c371b723 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 @@ namespace opengl { 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 @@ namespace opengl { } break; - case Command::SetPipeline: + case Command::SetComputePipeline: { - SetPipelineCmd* cmd = commands.NextCommand(); + SetComputePipelineCmd* cmd = commands.NextCommand(); + ToBackend(cmd->pipeline)->ApplyNow(); + lastGLPipeline = ToBackend(cmd->pipeline).Get(); + lastPipeline = ToBackend(cmd->pipeline).Get(); + } + break; + + case Command::SetRenderPipeline: + { + SetRenderPipelineCmd* cmd = commands.NextCommand(); 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 @@ namespace opengl { 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 @@ namespace opengl { 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 @@ namespace opengl { 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 @@ namespace opengl { auto buffers = commands.NextData>(cmd->count); auto offsets = commands.NextData(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 0000000000..d2fd8ad0fb --- /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 0000000000..c0678c3db1 --- /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 1ee13ade1d..f6330b7ce0 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 6426d9fd8b..59fbe3415f 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 @@ namespace opengl { 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 @@ namespace opengl { 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 @@ namespace opengl { 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 80097aedad..0d23285a04 100644 --- a/src/backend/opengl/OpenGLBackend.h +++ b/src/backend/opengl/OpenGLBackend.h @@ -38,19 +38,20 @@ namespace opengl { 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 @@ namespace opengl { 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 @@ -85,13 +87,14 @@ namespace opengl { 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 1fb474635e..e029784903 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 @@ namespace opengl { } - 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 @@ namespace opengl { 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 @@ namespace opengl { } } - 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 @@ namespace opengl { 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 @@ namespace opengl { // Compute links between stages for combined samplers, then bind them to texture units { std::set 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 @@ namespace opengl { } } - const Pipeline::GLPushConstantInfo& Pipeline::GetGLPushConstants(nxt::ShaderStage stage) const { + const PipelineGL::GLPushConstantInfo& PipelineGL::GetGLPushConstants(nxt::ShaderStage stage) const { return glPushConstants[stage]; } - const std::vector& Pipeline::GetTextureUnitsForSampler(GLuint index) const { + const std::vector& PipelineGL::GetTextureUnitsForSampler(GLuint index) const { ASSERT(index >= 0 && index < unitsForSamplers.size()); return unitsForSamplers[index]; } - const std::vector& Pipeline::GetTextureUnitsForTexture(GLuint index) const { + const std::vector& 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 1dc8af69bd..f6fe63cd25 100644 --- a/src/backend/opengl/PipelineGL.h +++ b/src/backend/opengl/PipelineGL.h @@ -28,9 +28,9 @@ namespace opengl { class PersistentPipelineState; class ShaderModule; - class Pipeline : public PipelineBase { + class PipelineGL { public: - Pipeline(PipelineBuilder* builder); + PipelineGL(PipelineBase* parent, PipelineBuilder* builder); using GLPushConstantInfo = std::array; using BindingLocations = std::array, kMaxBindGroups>; @@ -40,7 +40,7 @@ namespace opengl { const std::vector& 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 0000000000..1492b4f616 --- /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 0000000000..3c5eddeaf0 --- /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 + +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_