mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-12-14 15:46:28 +00:00
Change render passes from multi to single pass.
This as an API change to get closer to the direction in which WebGPU is headed. The API change in next.json caused a ton of files to be changed in the same commit to keep things compiling. API: the Framebuffer and RenderPass objects are now merged in a single RenderPassInfo that contains the attachments, loadOps and clear values for a BeginRenderPass command. The concept of subpass is removed. The RenderPass creation argument to RenderPipelines is replaced by explicitly setting the format of attachments for RenderPipeline. Validation: SetPipeline checks are changed to check that the attachments info set on a RenderPipeline matches the attachments of the render pass. Backends: Most changes are simplifications of the backends that no longer require and indirection to query the current subpass out of the render pass in BeginSubpass, and don't need to get the attachment info from a RenderPass when creating RenderPipelines. In the Vulkan backend, a VkRenderPass cache is added to reuse VkRenderPasses between RenderPassInfos and RenderPipelines. Tests and examples: they are updated with the simplified API. Tests specific to the Framebuffer and RenderPass objects were removed and validation tests for RenderPassInfo were added. Tested by running CppHelloTriangle on all backends, end2end tests on all platforms and all examples on the GL backend.
This commit is contained in:
committed by
Corentin Wallez
parent
87ec361cc2
commit
6f7749cce9
@@ -254,9 +254,6 @@ namespace backend { namespace opengl {
|
||||
PushConstantTracker pushConstants;
|
||||
InputBufferTracker inputBuffers;
|
||||
|
||||
RenderPass* currentRenderPass = nullptr;
|
||||
Framebuffer* currentFramebuffer = nullptr;
|
||||
uint32_t currentSubpass = 0;
|
||||
GLuint currentFBO = 0;
|
||||
|
||||
while (mCommands.NextCommandId(&type)) {
|
||||
@@ -268,13 +265,8 @@ namespace backend { namespace opengl {
|
||||
|
||||
case Command::BeginRenderPass: {
|
||||
auto* cmd = mCommands.NextCommand<BeginRenderPassCmd>();
|
||||
currentRenderPass = ToBackend(cmd->renderPass.Get());
|
||||
currentFramebuffer = ToBackend(cmd->framebuffer.Get());
|
||||
currentSubpass = 0;
|
||||
} break;
|
||||
RenderPassInfo* info = ToBackend(cmd->info.Get());
|
||||
|
||||
case Command::BeginRenderSubpass: {
|
||||
mCommands.NextCommand<BeginRenderSubpassCmd>();
|
||||
pushConstants.OnBeginPass();
|
||||
inputBuffers.OnBeginPass();
|
||||
|
||||
@@ -292,8 +284,6 @@ namespace backend { namespace opengl {
|
||||
glGenFramebuffers(1, ¤tFBO);
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, currentFBO);
|
||||
|
||||
const auto& subpass = currentRenderPass->GetSubpassInfo(currentSubpass);
|
||||
|
||||
// Mapping from attachmentSlot to GL framebuffer
|
||||
// attachment points. Defaults to zero (GL_NONE).
|
||||
std::array<GLenum, kMaxColorAttachments> drawBuffers = {};
|
||||
@@ -301,17 +291,15 @@ namespace backend { namespace opengl {
|
||||
// Construct GL framebuffer
|
||||
|
||||
unsigned int attachmentCount = 0;
|
||||
for (unsigned int location : IterateBitSet(subpass.colorAttachmentsSet)) {
|
||||
uint32_t attachment = subpass.colorAttachments[location];
|
||||
|
||||
auto textureView = currentFramebuffer->GetTextureView(attachment);
|
||||
for (uint32_t i : IterateBitSet(info->GetColorAttachmentMask())) {
|
||||
TextureViewBase* textureView = info->GetColorAttachment(i).view.Get();
|
||||
GLuint texture = ToBackend(textureView->GetTexture())->GetHandle();
|
||||
|
||||
// Attach color buffers.
|
||||
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + location,
|
||||
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i,
|
||||
GL_TEXTURE_2D, texture, 0);
|
||||
drawBuffers[location] = GL_COLOR_ATTACHMENT0 + location;
|
||||
attachmentCount = location + 1;
|
||||
drawBuffers[i] = GL_COLOR_ATTACHMENT0 + i;
|
||||
attachmentCount = i + 1;
|
||||
|
||||
// TODO(kainino@chromium.org): the color clears (later in
|
||||
// this function) may be undefined for non-normalized integer formats.
|
||||
@@ -323,10 +311,8 @@ namespace backend { namespace opengl {
|
||||
}
|
||||
glDrawBuffers(attachmentCount, drawBuffers.data());
|
||||
|
||||
if (subpass.depthStencilAttachmentSet) {
|
||||
uint32_t attachmentSlot = subpass.depthStencilAttachment;
|
||||
|
||||
auto textureView = currentFramebuffer->GetTextureView(attachmentSlot);
|
||||
if (info->HasDepthStencilAttachment()) {
|
||||
TextureViewBase* textureView = info->GetDepthStencilAttachment().view.Get();
|
||||
GLuint texture = ToBackend(textureView->GetTexture())->GetHandle();
|
||||
nxt::TextureFormat format = textureView->GetTexture()->GetFormat();
|
||||
|
||||
@@ -354,52 +340,39 @@ namespace backend { namespace opengl {
|
||||
|
||||
// Clear framebuffer attachments as needed
|
||||
|
||||
for (unsigned int location : IterateBitSet(subpass.colorAttachmentsSet)) {
|
||||
uint32_t attachmentSlot = subpass.colorAttachments[location];
|
||||
const auto& attachmentInfo =
|
||||
currentRenderPass->GetAttachmentInfo(attachmentSlot);
|
||||
for (uint32_t i : IterateBitSet(info->GetColorAttachmentMask())) {
|
||||
const auto& attachmentInfo = info->GetColorAttachment(i);
|
||||
|
||||
// Only perform load op on first use
|
||||
if (attachmentInfo.firstSubpass == currentSubpass) {
|
||||
// Load op - color
|
||||
if (attachmentInfo.colorLoadOp == nxt::LoadOp::Clear) {
|
||||
const auto& clear = currentFramebuffer->GetClearColor(location);
|
||||
glClearBufferfv(GL_COLOR, location, clear.color);
|
||||
}
|
||||
// Load op - color
|
||||
if (attachmentInfo.loadOp == nxt::LoadOp::Clear) {
|
||||
glClearBufferfv(GL_COLOR, i, attachmentInfo.clearColor.data());
|
||||
}
|
||||
}
|
||||
|
||||
if (subpass.depthStencilAttachmentSet) {
|
||||
uint32_t attachmentSlot = subpass.depthStencilAttachment;
|
||||
const auto& attachmentInfo =
|
||||
currentRenderPass->GetAttachmentInfo(attachmentSlot);
|
||||
if (info->HasDepthStencilAttachment()) {
|
||||
const auto& attachmentInfo = info->GetDepthStencilAttachment();
|
||||
nxt::TextureFormat attachmentFormat =
|
||||
attachmentInfo.view->GetTexture()->GetFormat();
|
||||
|
||||
// Only perform load op on first use
|
||||
if (attachmentInfo.firstSubpass == currentSubpass) {
|
||||
// Load op - depth/stencil
|
||||
const auto& clear = currentFramebuffer->GetClearDepthStencil(
|
||||
subpass.depthStencilAttachment);
|
||||
bool doDepthClear = TextureFormatHasDepth(attachmentInfo.format) &&
|
||||
(attachmentInfo.depthLoadOp == nxt::LoadOp::Clear);
|
||||
bool doStencilClear =
|
||||
TextureFormatHasStencil(attachmentInfo.format) &&
|
||||
(attachmentInfo.stencilLoadOp == nxt::LoadOp::Clear);
|
||||
if (doDepthClear && doStencilClear) {
|
||||
glClearBufferfi(GL_DEPTH_STENCIL, 0, clear.depth, clear.stencil);
|
||||
} else if (doDepthClear) {
|
||||
glClearBufferfv(GL_DEPTH, 0, &clear.depth);
|
||||
} else if (doStencilClear) {
|
||||
const GLint clearStencil = clear.stencil;
|
||||
glClearBufferiv(GL_STENCIL, 0, &clearStencil);
|
||||
}
|
||||
// Load op - depth/stencil
|
||||
bool doDepthClear = TextureFormatHasDepth(attachmentFormat) &&
|
||||
(attachmentInfo.depthLoadOp == nxt::LoadOp::Clear);
|
||||
bool doStencilClear = TextureFormatHasStencil(attachmentFormat) &&
|
||||
(attachmentInfo.stencilLoadOp == nxt::LoadOp::Clear);
|
||||
if (doDepthClear && doStencilClear) {
|
||||
glClearBufferfi(GL_DEPTH_STENCIL, 0, attachmentInfo.clearDepth,
|
||||
attachmentInfo.clearStencil);
|
||||
} else if (doDepthClear) {
|
||||
glClearBufferfv(GL_DEPTH, 0, &attachmentInfo.clearDepth);
|
||||
} else if (doStencilClear) {
|
||||
const GLint clearStencil = attachmentInfo.clearStencil;
|
||||
glClearBufferiv(GL_STENCIL, 0, &clearStencil);
|
||||
}
|
||||
}
|
||||
|
||||
glBlendColor(0, 0, 0, 0);
|
||||
glViewport(0, 0, currentFramebuffer->GetWidth(),
|
||||
currentFramebuffer->GetHeight());
|
||||
glScissor(0, 0, currentFramebuffer->GetWidth(),
|
||||
currentFramebuffer->GetHeight());
|
||||
glViewport(0, 0, info->GetWidth(), info->GetHeight());
|
||||
glScissor(0, 0, info->GetWidth(), info->GetHeight());
|
||||
} break;
|
||||
|
||||
case Command::CopyBufferToBuffer: {
|
||||
@@ -530,13 +503,8 @@ namespace backend { namespace opengl {
|
||||
|
||||
case Command::EndRenderPass: {
|
||||
mCommands.NextCommand<EndRenderPassCmd>();
|
||||
} break;
|
||||
|
||||
case Command::EndRenderSubpass: {
|
||||
mCommands.NextCommand<EndRenderSubpassCmd>();
|
||||
glDeleteFramebuffers(1, ¤tFBO);
|
||||
currentFBO = 0;
|
||||
currentSubpass += 1;
|
||||
} break;
|
||||
|
||||
case Command::SetComputePipeline: {
|
||||
|
||||
@@ -73,17 +73,14 @@ namespace backend { namespace opengl {
|
||||
InputStateBase* Device::CreateInputState(InputStateBuilder* builder) {
|
||||
return new InputState(builder);
|
||||
}
|
||||
FramebufferBase* Device::CreateFramebuffer(FramebufferBuilder* builder) {
|
||||
return new Framebuffer(builder);
|
||||
}
|
||||
PipelineLayoutBase* Device::CreatePipelineLayout(PipelineLayoutBuilder* builder) {
|
||||
return new PipelineLayout(builder);
|
||||
}
|
||||
QueueBase* Device::CreateQueue(QueueBuilder* builder) {
|
||||
return new Queue(builder);
|
||||
}
|
||||
RenderPassBase* Device::CreateRenderPass(RenderPassBuilder* builder) {
|
||||
return new RenderPass(builder);
|
||||
RenderPassInfoBase* Device::CreateRenderPassInfo(RenderPassInfoBuilder* builder) {
|
||||
return new RenderPassInfo(builder);
|
||||
}
|
||||
RenderPipelineBase* Device::CreateRenderPipeline(RenderPipelineBuilder* builder) {
|
||||
return new RenderPipeline(builder);
|
||||
@@ -118,11 +115,6 @@ namespace backend { namespace opengl {
|
||||
: BindGroupLayoutBase(builder) {
|
||||
}
|
||||
|
||||
// Framebuffer
|
||||
|
||||
Framebuffer::Framebuffer(FramebufferBuilder* builder) : FramebufferBase(builder) {
|
||||
}
|
||||
|
||||
// Queue
|
||||
|
||||
Queue::Queue(QueueBuilder* builder) : QueueBase(builder) {
|
||||
@@ -134,9 +126,9 @@ namespace backend { namespace opengl {
|
||||
}
|
||||
}
|
||||
|
||||
// RenderPass
|
||||
// RenderPassInfo
|
||||
|
||||
RenderPass::RenderPass(RenderPassBuilder* builder) : RenderPassBase(builder) {
|
||||
RenderPassInfo::RenderPassInfo(RenderPassInfoBuilder* builder) : RenderPassInfoBase(builder) {
|
||||
}
|
||||
|
||||
}} // namespace backend::opengl
|
||||
|
||||
@@ -23,10 +23,9 @@
|
||||
#include "backend/Buffer.h"
|
||||
#include "backend/DepthStencilState.h"
|
||||
#include "backend/Device.h"
|
||||
#include "backend/Framebuffer.h"
|
||||
#include "backend/InputState.h"
|
||||
#include "backend/Queue.h"
|
||||
#include "backend/RenderPass.h"
|
||||
#include "backend/RenderPassInfo.h"
|
||||
#include "backend/ToBackend.h"
|
||||
|
||||
#include "glad/glad.h"
|
||||
@@ -42,12 +41,11 @@ namespace backend { namespace opengl {
|
||||
class ComputePipeline;
|
||||
class DepthStencilState;
|
||||
class Device;
|
||||
class Framebuffer;
|
||||
class InputState;
|
||||
class PersistentPipelineState;
|
||||
class PipelineLayout;
|
||||
class Queue;
|
||||
class RenderPass;
|
||||
class RenderPassInfo;
|
||||
class RenderPipeline;
|
||||
class Sampler;
|
||||
class ShaderModule;
|
||||
@@ -65,11 +63,10 @@ namespace backend { namespace opengl {
|
||||
using ComputePipelineType = ComputePipeline;
|
||||
using DepthStencilStateType = DepthStencilState;
|
||||
using DeviceType = Device;
|
||||
using FramebufferType = Framebuffer;
|
||||
using InputStateType = InputState;
|
||||
using PipelineLayoutType = PipelineLayout;
|
||||
using QueueType = Queue;
|
||||
using RenderPassType = RenderPass;
|
||||
using RenderPassInfoType = RenderPassInfo;
|
||||
using RenderPipelineType = RenderPipeline;
|
||||
using SamplerType = Sampler;
|
||||
using ShaderModuleType = ShaderModule;
|
||||
@@ -95,10 +92,9 @@ namespace backend { namespace opengl {
|
||||
ComputePipelineBase* CreateComputePipeline(ComputePipelineBuilder* builder) override;
|
||||
DepthStencilStateBase* CreateDepthStencilState(DepthStencilStateBuilder* builder) override;
|
||||
InputStateBase* CreateInputState(InputStateBuilder* builder) override;
|
||||
FramebufferBase* CreateFramebuffer(FramebufferBuilder* builder) override;
|
||||
PipelineLayoutBase* CreatePipelineLayout(PipelineLayoutBuilder* builder) override;
|
||||
QueueBase* CreateQueue(QueueBuilder* builder) override;
|
||||
RenderPassBase* CreateRenderPass(RenderPassBuilder* builder) override;
|
||||
RenderPassInfoBase* CreateRenderPassInfo(RenderPassInfoBuilder* builder) override;
|
||||
RenderPipelineBase* CreateRenderPipeline(RenderPipelineBuilder* builder) override;
|
||||
SamplerBase* CreateSampler(SamplerBuilder* builder) override;
|
||||
ShaderModuleBase* CreateShaderModule(ShaderModuleBuilder* builder) override;
|
||||
@@ -119,11 +115,6 @@ namespace backend { namespace opengl {
|
||||
BindGroupLayout(BindGroupLayoutBuilder* builder);
|
||||
};
|
||||
|
||||
class Framebuffer : public FramebufferBase {
|
||||
public:
|
||||
Framebuffer(FramebufferBuilder* builder);
|
||||
};
|
||||
|
||||
class Queue : public QueueBase {
|
||||
public:
|
||||
Queue(QueueBuilder* builder);
|
||||
@@ -132,9 +123,9 @@ namespace backend { namespace opengl {
|
||||
void Submit(uint32_t numCommands, CommandBuffer* const* commands);
|
||||
};
|
||||
|
||||
class RenderPass : public RenderPassBase {
|
||||
class RenderPassInfo : public RenderPassInfoBase {
|
||||
public:
|
||||
RenderPass(RenderPassBuilder* builder);
|
||||
RenderPassInfo(RenderPassInfoBuilder* builder);
|
||||
};
|
||||
|
||||
}} // namespace backend::opengl
|
||||
|
||||
@@ -60,10 +60,7 @@ namespace backend { namespace opengl {
|
||||
auto depthStencilState = ToBackend(GetDepthStencilState());
|
||||
depthStencilState->ApplyNow(persistentPipelineState);
|
||||
|
||||
RenderPass* renderPass = ToBackend(GetRenderPass());
|
||||
auto& subpassInfo = renderPass->GetSubpassInfo(GetSubPass());
|
||||
|
||||
for (uint32_t attachmentSlot : IterateBitSet(subpassInfo.colorAttachmentsSet)) {
|
||||
for (uint32_t attachmentSlot : IterateBitSet(GetColorAttachmentsMask())) {
|
||||
ToBackend(GetBlendState(attachmentSlot))->ApplyNow(attachmentSlot);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user