Split Pipeline in Render and Compute, OpenGL part

This commit is contained in:
Corentin Wallez 2017-07-14 14:04:52 -04:00 committed by Corentin Wallez
parent 494a157f66
commit b085eecb31
11 changed files with 205 additions and 40 deletions

View File

@ -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

View File

@ -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<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 @@ 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<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) {

View File

@ -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();
}
}
}

View File

@ -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_

View File

@ -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"

View File

@ -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);
}

View File

@ -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<typename T>
@ -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;

View File

@ -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<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 @@ 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<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);
}
}

View File

@ -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<GLint, kMaxPushConstants>;
using BindingLocations = std::array<std::array<GLint, kMaxBindingsPerGroup>, kMaxBindGroups>;
@ -40,7 +40,7 @@ namespace opengl {
const std::vector<GLuint>& GetTextureUnitsForTexture(GLuint index) const;
GLuint GetProgramHandle() const;
void ApplyNow(PersistentPipelineState &persistentPipelineState);
void ApplyNow();
private:
GLuint program;

View File

@ -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);
}
}
}

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.
#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_