Skip to content

Commit

Permalink
Add ContextWgpu methods for managing current render pass
Browse files Browse the repository at this point in the history
For simplicity ensureRenderPassStarted() just ends the current
render pass and starts a new one.

Bug: angleproject:8582
Change-Id: I929526cf2574fa33309310e7f60191c10ab3bf7a
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/5388075
Commit-Queue: Matthew Denton <[email protected]>
Reviewed-by: Liza Burakova <[email protected]>
Reviewed-by: Shahbaz Youssefi <[email protected]>
  • Loading branch information
mdenton8 authored and Angle LUCI CQ committed Apr 4, 2024
1 parent 103c1b5 commit 5c6a531
Show file tree
Hide file tree
Showing 4 changed files with 135 additions and 0 deletions.
113 changes: 113 additions & 0 deletions src/libANGLE/renderer/wgpu/ContextWgpu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,82 @@
#include "libANGLE/renderer/wgpu/TextureWgpu.h"
#include "libANGLE/renderer/wgpu/TransformFeedbackWgpu.h"
#include "libANGLE/renderer/wgpu/VertexArrayWgpu.h"
#include "libANGLE/renderer/wgpu/wgpu_utils.h"

namespace rx
{

namespace
{

constexpr angle::PackedEnumMap<webgpu::RenderPassClosureReason, const char *>
kRenderPassClosureReason = {{
{webgpu::RenderPassClosureReason::NewRenderPass,
"Render pass closed due to starting a new render pass"},
}};

bool RenderPassColorAttachmentEqual(const wgpu::RenderPassColorAttachment &attachment1,
const wgpu::RenderPassColorAttachment &attachment2)
{

if (attachment1.nextInChain != nullptr || attachment2.nextInChain != nullptr)
{
return false;
}

return attachment1.view.Get() == attachment2.view.Get() &&
attachment1.depthSlice == attachment2.depthSlice &&
attachment1.resolveTarget.Get() == attachment2.resolveTarget.Get() &&
attachment1.loadOp == attachment2.loadOp && attachment1.storeOp == attachment2.storeOp &&
attachment1.clearValue.r == attachment2.clearValue.r &&
attachment1.clearValue.g == attachment2.clearValue.g &&
attachment1.clearValue.b == attachment2.clearValue.b &&
attachment1.clearValue.a == attachment2.clearValue.a;
}

bool RenderPassDepthStencilAttachmentEqual(
const wgpu::RenderPassDepthStencilAttachment &attachment1,
const wgpu::RenderPassDepthStencilAttachment &attachment2)
{
return attachment1.view.Get() == attachment2.view.Get() &&
attachment1.depthLoadOp == attachment2.depthLoadOp &&
attachment1.depthStoreOp == attachment2.depthStoreOp &&
attachment1.depthClearValue == attachment2.depthClearValue &&
attachment1.stencilLoadOp == attachment2.stencilLoadOp &&
attachment1.stencilStoreOp == attachment2.stencilStoreOp &&
attachment1.stencilClearValue == attachment2.stencilClearValue &&
attachment1.stencilReadOnly == attachment2.stencilReadOnly;
}

bool RenderPassDescEqual(const wgpu::RenderPassDescriptor &desc1,
const wgpu::RenderPassDescriptor &desc2)
{

if (desc1.nextInChain != nullptr || desc2.nextInChain != nullptr)
{
return false;
}

if (desc1.colorAttachmentCount != desc2.colorAttachmentCount)
{
return false;
}

for (uint32_t i = 0; i < desc1.colorAttachmentCount; ++i)
{
if (!RenderPassColorAttachmentEqual(desc1.colorAttachments[i], desc2.colorAttachments[i]))
{
return false;
}
}

// TODO(anglebug.com/8582): for now ignore `occlusionQuerySet` and `timestampWrites`.

return RenderPassDepthStencilAttachmentEqual(*desc1.depthStencilAttachment,
*desc2.depthStencilAttachment);
}
} // namespace

ContextWgpu::ContextWgpu(const gl::State &state, gl::ErrorSet *errorSet, DisplayWgpu *display)
: ContextImpl(state, errorSet), mDisplay(display)
{
Expand Down Expand Up @@ -524,4 +596,45 @@ void ContextWgpu::handleError(GLenum errorCode,
errorStream << "Internal Wgpu back-end error: " << message << ".";
mErrors->handleError(errorCode, errorStream.str().c_str(), file, function, line);
}

angle::Result ContextWgpu::ensureRenderPassStarted(const wgpu::RenderPassDescriptor &desc)
{
if (!mCurrentCommandEncoder)
{
mCurrentCommandEncoder = getDevice().CreateCommandEncoder(nullptr);
}
if (mCurrentRenderPass)
{
// TODO(anglebug.com/8582): this should eventually ignore load and store operations so we
// can avoid starting a new render pass in more situations.
if (RenderPassDescEqual(mCurrentRenderPassDesc, desc))
{
return angle::Result::Continue;
}
ANGLE_TRY(endRenderPass(webgpu::RenderPassClosureReason::NewRenderPass));
}
mCurrentRenderPass = mCurrentCommandEncoder.BeginRenderPass(&desc);
mCurrentRenderPassDesc = desc;

return angle::Result::Continue;
}

angle::Result ContextWgpu::endRenderPass(webgpu::RenderPassClosureReason closure_reason)
{

const char *reasonText = kRenderPassClosureReason[closure_reason];
INFO() << reasonText;
mCurrentRenderPass.End();
mCurrentRenderPass = nullptr;
return angle::Result::Continue;
}

angle::Result ContextWgpu::flush()
{
wgpu::CommandBuffer command_buffer = mCurrentCommandEncoder.Finish();
getQueue().Submit(1, &command_buffer);
mCurrentCommandEncoder = nullptr;
return angle::Result::Continue;
}

} // namespace rx
13 changes: 13 additions & 0 deletions src/libANGLE/renderer/wgpu/ContextWgpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,12 @@
#ifndef LIBANGLE_RENDERER_WGPU_CONTEXTWGPU_H_
#define LIBANGLE_RENDERER_WGPU_CONTEXTWGPU_H_

#include <dawn/webgpu_cpp.h>

#include "image_util/loadimage.h"
#include "libANGLE/renderer/ContextImpl.h"
#include "libANGLE/renderer/wgpu/DisplayWgpu.h"
#include "libANGLE/renderer/wgpu/wgpu_utils.h"

namespace rx
{
Expand Down Expand Up @@ -256,6 +259,12 @@ class ContextWgpu : public ContextImpl
const angle::ImageLoadContext &getImageLoadContext() const { return mImageLoadContext; }

DisplayWgpu *getDisplay() { return mDisplay; }
wgpu::Device &getDevice() { return mDisplay->getDevice(); }
wgpu::Queue &getQueue() { return mDisplay->getQueue(); }
angle::Result ensureRenderPassStarted(const wgpu::RenderPassDescriptor &desc);
angle::Result endRenderPass(webgpu::RenderPassClosureReason closure_reason);

angle::Result flush();

private:
gl::Caps mCaps;
Expand All @@ -267,6 +276,10 @@ class ContextWgpu : public ContextImpl
angle::ImageLoadContext mImageLoadContext;

DisplayWgpu *mDisplay;

wgpu::CommandEncoder mCurrentCommandEncoder;
wgpu::RenderPassEncoder mCurrentRenderPass;
wgpu::RenderPassDescriptor mCurrentRenderPassDesc;
};

} // namespace rx
Expand Down
1 change: 1 addition & 0 deletions src/libANGLE/renderer/wgpu/DisplayWgpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ class DisplayWgpu : public DisplayImpl
void populateFeatureList(angle::FeatureList *features) override {}

wgpu::Device &getDevice() { return mDevice; }
wgpu::Queue &getQueue() { return mQueue; }

private:
void generateExtensions(egl::DisplayExtensions *outExtensions) const override;
Expand Down
8 changes: 8 additions & 0 deletions src/libANGLE/renderer/wgpu/wgpu_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,14 @@ namespace webgpu
// WebGPU image level index.
using LevelIndex = gl::LevelIndexWrapper<uint32_t>;

enum class RenderPassClosureReason
{
NewRenderPass,

InvalidEnum,
EnumCount = InvalidEnum,
};

} // namespace webgpu

namespace wgpu_gl
Expand Down

0 comments on commit 5c6a531

Please sign in to comment.