summaryrefslogtreecommitdiffstats
path: root/gfx/angle/checkout/src/libANGLE/renderer/RenderTargetCache.h
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/angle/checkout/src/libANGLE/renderer/RenderTargetCache.h')
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/RenderTargetCache.h186
1 files changed, 186 insertions, 0 deletions
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/RenderTargetCache.h b/gfx/angle/checkout/src/libANGLE/renderer/RenderTargetCache.h
new file mode 100644
index 0000000000..ffc2a04492
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/RenderTargetCache.h
@@ -0,0 +1,186 @@
+//
+// Copyright 2018 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// RenderTargetCache:
+// The RenderTargetCache pattern is used in the D3D9, D3D11 and Vulkan back-ends. It is a
+// cache of the various back-end objects (RenderTargets) associated with each Framebuffer
+// attachment, be they Textures, Renderbuffers, or Surfaces. The cache is updated in Framebuffer's
+// syncState method.
+//
+
+#ifndef LIBANGLE_RENDERER_RENDER_TARGET_CACHE_H_
+#define LIBANGLE_RENDERER_RENDER_TARGET_CACHE_H_
+
+#include "libANGLE/Framebuffer.h"
+#include "libANGLE/FramebufferAttachment.h"
+
+namespace rx
+{
+
+template <typename RenderTargetT>
+class RenderTargetCache final : angle::NonCopyable
+{
+ public:
+ RenderTargetCache();
+ ~RenderTargetCache();
+
+ // Update all RenderTargets from the dirty bits.
+ angle::Result update(const gl::Context *context,
+ const gl::FramebufferState &state,
+ const gl::Framebuffer::DirtyBits &dirtyBits);
+
+ // Update individual RenderTargets.
+ angle::Result updateReadColorRenderTarget(const gl::Context *context,
+ const gl::FramebufferState &state);
+ angle::Result updateColorRenderTarget(const gl::Context *context,
+ const gl::FramebufferState &state,
+ size_t colorIndex);
+ angle::Result updateDepthStencilRenderTarget(const gl::Context *context,
+ const gl::FramebufferState &state);
+
+ using RenderTargetArray = gl::AttachmentArray<RenderTargetT *>;
+
+ const RenderTargetArray &getColors() const;
+ RenderTargetT *getDepthStencil() const;
+
+ RenderTargetT *getColorDraw(const gl::FramebufferState &state, size_t colorIndex) const;
+ RenderTargetT *getColorRead(const gl::FramebufferState &state) const;
+
+ private:
+ angle::Result updateCachedRenderTarget(const gl::Context *context,
+ const gl::FramebufferAttachment *attachment,
+ RenderTargetT **cachedRenderTarget);
+
+ RenderTargetT *mReadRenderTarget = nullptr;
+ gl::AttachmentArray<RenderTargetT *> mColorRenderTargets = {};
+ // We only support a single Depth/Stencil RenderTarget currently.
+ RenderTargetT *mDepthStencilRenderTarget = nullptr;
+};
+
+template <typename RenderTargetT>
+RenderTargetCache<RenderTargetT>::RenderTargetCache() = default;
+
+template <typename RenderTargetT>
+RenderTargetCache<RenderTargetT>::~RenderTargetCache() = default;
+
+template <typename RenderTargetT>
+angle::Result RenderTargetCache<RenderTargetT>::update(const gl::Context *context,
+ const gl::FramebufferState &state,
+ const gl::Framebuffer::DirtyBits &dirtyBits)
+{
+ for (auto dirtyBit : dirtyBits)
+ {
+ switch (dirtyBit)
+ {
+ case gl::Framebuffer::DIRTY_BIT_DEPTH_ATTACHMENT:
+ case gl::Framebuffer::DIRTY_BIT_STENCIL_ATTACHMENT:
+ ANGLE_TRY(updateDepthStencilRenderTarget(context, state));
+ break;
+ case gl::Framebuffer::DIRTY_BIT_READ_BUFFER:
+ ANGLE_TRY(updateReadColorRenderTarget(context, state));
+ break;
+ case gl::Framebuffer::DIRTY_BIT_DRAW_BUFFERS:
+ case gl::Framebuffer::DIRTY_BIT_DEFAULT_WIDTH:
+ case gl::Framebuffer::DIRTY_BIT_DEFAULT_HEIGHT:
+ case gl::Framebuffer::DIRTY_BIT_DEFAULT_SAMPLES:
+ case gl::Framebuffer::DIRTY_BIT_DEFAULT_FIXED_SAMPLE_LOCATIONS:
+ break;
+ default:
+ {
+ static_assert(gl::Framebuffer::DIRTY_BIT_COLOR_ATTACHMENT_0 == 0, "FB dirty bits");
+ if (dirtyBit < gl::Framebuffer::DIRTY_BIT_COLOR_ATTACHMENT_MAX)
+ {
+ size_t colorIndex = static_cast<size_t>(
+ dirtyBit - gl::Framebuffer::DIRTY_BIT_COLOR_ATTACHMENT_0);
+ ANGLE_TRY(updateColorRenderTarget(context, state, colorIndex));
+ }
+ break;
+ }
+ }
+ }
+
+ return angle::Result::Continue;
+}
+
+template <typename RenderTargetT>
+const gl::AttachmentArray<RenderTargetT *> &RenderTargetCache<RenderTargetT>::getColors() const
+{
+ return mColorRenderTargets;
+}
+
+template <typename RenderTargetT>
+RenderTargetT *RenderTargetCache<RenderTargetT>::getDepthStencil() const
+{
+ return mDepthStencilRenderTarget;
+}
+
+template <typename RenderTargetT>
+angle::Result RenderTargetCache<RenderTargetT>::updateReadColorRenderTarget(
+ const gl::Context *context,
+ const gl::FramebufferState &state)
+{
+ return updateCachedRenderTarget(context, state.getReadAttachment(), &mReadRenderTarget);
+}
+
+template <typename RenderTargetT>
+angle::Result RenderTargetCache<RenderTargetT>::updateColorRenderTarget(
+ const gl::Context *context,
+ const gl::FramebufferState &state,
+ size_t colorIndex)
+{
+ // If the color render target we're updating is also the read buffer, make sure we update the
+ // read render target also so it's not stale.
+ if (state.getReadBufferState() != GL_NONE && state.getReadIndex() == colorIndex)
+ {
+ ANGLE_TRY(updateReadColorRenderTarget(context, state));
+ }
+
+ return updateCachedRenderTarget(context, state.getColorAttachment(colorIndex),
+ &mColorRenderTargets[colorIndex]);
+}
+
+template <typename RenderTargetT>
+angle::Result RenderTargetCache<RenderTargetT>::updateDepthStencilRenderTarget(
+ const gl::Context *context,
+ const gl::FramebufferState &state)
+{
+ return updateCachedRenderTarget(context, state.getDepthOrStencilAttachment(),
+ &mDepthStencilRenderTarget);
+}
+
+template <typename RenderTargetT>
+angle::Result RenderTargetCache<RenderTargetT>::updateCachedRenderTarget(
+ const gl::Context *context,
+ const gl::FramebufferAttachment *attachment,
+ RenderTargetT **cachedRenderTarget)
+{
+ RenderTargetT *newRenderTarget = nullptr;
+ if (attachment)
+ {
+ ASSERT(attachment->isAttached());
+ ANGLE_TRY(attachment->getRenderTarget(context, attachment->getRenderToTextureSamples(),
+ &newRenderTarget));
+ }
+ *cachedRenderTarget = newRenderTarget;
+ return angle::Result::Continue;
+}
+
+template <typename RenderTargetT>
+RenderTargetT *RenderTargetCache<RenderTargetT>::getColorDraw(const gl::FramebufferState &state,
+ size_t colorIndex) const
+{
+ return mColorRenderTargets[colorIndex];
+}
+
+template <typename RenderTargetT>
+RenderTargetT *RenderTargetCache<RenderTargetT>::getColorRead(
+ const gl::FramebufferState &state) const
+{
+ return mReadRenderTarget;
+}
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_RENDER_TARGET_CACHE_H_